diff --git a/.gitignore b/.gitignore index 4130b92..5fbf5c9 100644 --- a/.gitignore +++ b/.gitignore
@@ -174,6 +174,7 @@ /chromecast/internal /chromeos/assistant/internal /chromeos/components/help_app_ui/resources/app +/chromeos/components/help_app_ui/resources/prod /chromeos/components/media_app_ui/resources/app /chromeos/components/media_app_ui/resources/pkg /chromeos/profiles/chromeos.orderfile.txt
diff --git a/DEPS b/DEPS index 021ed6d..bdc6d38f 100644 --- a/DEPS +++ b/DEPS
@@ -178,11 +178,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '25dc7ca1f314bfe250f32093d8c71b4d21fcee86', + 'skia_revision': 'be72c44ec3d893b67a75c5d4ff3e1173d9844318', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '0cc5899dfff453c41ee5370c5edd3be9d166cfe4', + 'v8_revision': 'e31b0cbef9d3c9a664c48cedac2a4db629dff529', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -190,11 +190,11 @@ # 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': 'a5750efe1eedf64d7a57a58998f15d440f28cd97', + 'angle_revision': 'fcfe7fad6f8039758f0e0b67d388f8e4fcfc5b53', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '64da65bd1bd54addc8ab0e74a946e299f16ffa4c', + 'swiftshader_revision': 'd748e1651af8254eec5d4f5c561713dc85d14ab6', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -241,7 +241,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': 'ca8802d27b8c8f8731db1cd488eab44ee9881266', + 'catapult_revision': '087cffcba472d70f3d0b1115d0b9100c365073d1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -249,7 +249,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': '6f60dca88247f77e4511c801a3908ce3f119e72f', + 'devtools_frontend_revision': 'bf20468f57c10589abcb0df9dd397af1719e289b', # 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. @@ -301,11 +301,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '60bb88d23c0538909f9d1186adb585b56c83392f', + 'dawn_revision': '20ed6f42b34f4989022a2a3c87f057d90a6618dd', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'quiche_revision': '37d11a026c8326893f4318e33f33ffabdbab40ae', + 'quiche_revision': '7ccff5893596bbe81c17e66b40753c6325082f96', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ios_webkit # and whatever else without interference from each other. @@ -851,7 +851,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '5ac14364328118b3e02ccf3af5147d011b98c38a', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '9963e1930e93c67b3653bd7997c535a16a5ffeea', 'condition': 'checkout_linux', }, @@ -1203,7 +1203,7 @@ Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + 'a5473711f3e20c6bd1c33d81b6c7b9a0618aa18f', 'src/third_party/openscreen/src': - Var('chromium_git') + '/openscreen' + '@' + '4410e8e8f34e0fd8029cea7543fd1f8a191e03d1', + Var('chromium_git') + '/openscreen' + '@' + 'c8465a614c309369dcb3f41bacadb48cb383e809', 'src/third_party/openxr/src': { 'url': Var('chromium_git') + '/external/github.com/KhronosGroup/OpenXR-SDK' + '@' + '9e97b73e7dd2bfc07745489d728f6a36665c648f', @@ -1220,7 +1220,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '974f915feb5c5577aab82ac92ba3dcff380e4b10', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'd8cb80d7a786d4896fd1ac22ff35470187d3a933', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1453,7 +1453,7 @@ }, 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '95d40ee0dfabe4e0a7926e359a385a35da4d6fb1', + Var('webrtc_git') + '/src.git' + '@' + 'da76ad3c490eed81ef5028252826ab2ab1e7402f', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1525,10 +1525,21 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@48c4843491b2d270104d5b93248150464acd66c4', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@fcbb1943453fb6ee34d935df920397eb211e97e5', 'condition': 'checkout_src_internal', }, + 'src/chromeos/components/help_app_ui/resources/prod': { + 'packages': [ + { + 'package': 'chromeos_internal/apps/help_app/app', + 'version': '4LNO2QORJBlLuLF5s9dotu4sFJmSIF4tM_K_Xa7AxcIC', + }, + ], + 'condition': 'checkout_chromeos and checkout_src_internal', + 'dep_type': 'cipd', + }, + 'src/third_party/google_android_play_core': { 'packages': [ {
diff --git a/android_webview/browser/icon_helper.cc b/android_webview/browser/icon_helper.cc index 0cb36f9..6b9489bb 100644 --- a/android_webview/browser/icon_helper.cc +++ b/android_webview/browser/icon_helper.cc
@@ -10,6 +10,7 @@ #include "base/hash/hash.h" #include "base/notreached.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/navigation_handle.h" #include "content/public/browser/web_contents.h" #include "third_party/blink/public/mojom/favicon/favicon_url.mojom.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -99,10 +100,8 @@ } } -void IconHelper::DidStartNavigationToPendingEntry( - const GURL& url, - content::ReloadType reload_type) { - if (reload_type == content::ReloadType::BYPASSING_CACHE) +void IconHelper::DidStartNavigation(content::NavigationHandle* navigation) { + if (navigation->GetReloadType() == content::ReloadType::BYPASSING_CACHE) ClearUnableToDownloadFavicons(); }
diff --git a/android_webview/browser/icon_helper.h b/android_webview/browser/icon_helper.h index 4d35dcc..b32155ce 100644 --- a/android_webview/browser/icon_helper.h +++ b/android_webview/browser/icon_helper.h
@@ -46,9 +46,7 @@ // From WebContentsObserver void DidUpdateFaviconURL( const std::vector<blink::mojom::FaviconURLPtr>& candidates) override; - void DidStartNavigationToPendingEntry( - const GURL& url, - content::ReloadType reload_type) override; + void DidStartNavigation(content::NavigationHandle* navigation) override; void DownloadFaviconCallback( int id,
diff --git a/android_webview/java/src/org/chromium/android_webview/common/metrics/AwNonembeddedUmaRecorder.java b/android_webview/java/src/org/chromium/android_webview/common/metrics/AwNonembeddedUmaRecorder.java index e177744..9a1c88c0 100644 --- a/android_webview/java/src/org/chromium/android_webview/common/metrics/AwNonembeddedUmaRecorder.java +++ b/android_webview/java/src/org/chromium/android_webview/common/metrics/AwNonembeddedUmaRecorder.java
@@ -123,8 +123,9 @@ IMetricsBridgeService metricsService = IMetricsBridgeService.Stub.asInterface(service); try { - // We are not punting this to a background thread since it should be a - // non-blocking call. + // We are not punting this to a background thread since the cost of IPC itself + // should be relatively cheap, and the remote method does its work + // asynchronously. metricsService.recordMetrics(methodCall.toByteArray()); } catch (RemoteException e) { Log.e(TAG, "Remote Exception calling IMetricsBridgeService#recordMetrics", e);
diff --git a/android_webview/java/src/org/chromium/android_webview/common/services/IMetricsBridgeService.aidl b/android_webview/java/src/org/chromium/android_webview/common/services/IMetricsBridgeService.aidl index 588b5863..31f7519 100644 --- a/android_webview/java/src/org/chromium/android_webview/common/services/IMetricsBridgeService.aidl +++ b/android_webview/java/src/org/chromium/android_webview/common/services/IMetricsBridgeService.aidl
@@ -13,12 +13,13 @@ interface IMetricsBridgeService { /** * Record a UMA API method call from a non-embedded WebView processes. This should only be - * called by WebView's non-embedded processes (which are trusted). This is a non-blocking - * call. + * called by WebView's non-embedded processes (which are trusted). This is a blocking IPC, + * although its work (including disk IO) happens asynchronously. + * * @param methodCall a byte array serialization of * org.chromium.android_webview.proto.HistogramRecord proto message object. */ - oneway void recordMetrics(in byte[] methodCall); + void recordMetrics(in byte[] methodCall); /** * Get a list of recorded UMA method calls through the callback. This a blocking call.
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/services/MetricsBridgeServiceTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/services/MetricsBridgeServiceTest.java index 3b35d5d..b6039723 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/services/MetricsBridgeServiceTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/services/MetricsBridgeServiceTest.java
@@ -15,7 +15,11 @@ import android.os.RemoteException; import android.support.test.filters.MediumTest; +import com.google.protobuf.InvalidProtocolBufferException; + +import org.junit.After; import org.junit.Assert; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -24,19 +28,129 @@ import org.chromium.android_webview.proto.MetricsBridgeRecords.HistogramRecord.RecordType; import org.chromium.android_webview.proto.MetricsBridgeRecords.HistogramRecordList; import org.chromium.android_webview.services.MetricsBridgeService; +import org.chromium.android_webview.test.AwActivityTestRule; import org.chromium.android_webview.test.AwJUnit4ClassRunner; import org.chromium.android_webview.test.OnlyRunIn; import org.chromium.base.ContextUtils; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.concurrent.FutureTask; + /** * Test MetricsBridgeService. */ @RunWith(AwJUnit4ClassRunner.class) @OnlyRunIn(SINGLE_PROCESS) -// TODO(hazems) test writing to the file public class MetricsBridgeServiceTest { private static final long BINDER_TIMEOUT_MILLIS = 10000; + private File mTempFile; + + @Before + public void setUp() throws IOException { + mTempFile = File.createTempFile("test_webview_metrics_bridge_logs", null); + } + + @After + public void tearDown() { + if (mTempFile.exists()) { + Assert.assertTrue("Failed to delete \"" + mTempFile + "\"", mTempFile.delete()); + } + } + + @Test + @MediumTest + // Test that the service saves metrics records to file + public void testSaveToFile() throws Throwable { + HistogramRecord recordBooleanProto = HistogramRecord.newBuilder() + .setRecordType(RecordType.HISTOGRAM_BOOLEAN) + .setHistogramName("testSaveToFile.boolean") + .setSample(1) + .build(); + HistogramRecord recordLinearProto = HistogramRecord.newBuilder() + .setRecordType(RecordType.HISTOGRAM_LINEAR) + .setHistogramName("testSaveToFile.linear") + .setSample(123) + .setMin(1) + .setMax(1000) + .setNumBuckets(50) + .build(); + HistogramRecordList expectedListProto = HistogramRecordList.newBuilder() + .addRecords(recordBooleanProto) + .addRecords(recordLinearProto) + .addRecords(recordBooleanProto) + .build(); + + // Cannot bind to service using real connection since we need to inject test file name. + MetricsBridgeService service = new MetricsBridgeService(mTempFile); + // Simulate starting the service by calling onCreate() + service.onCreate(); + + IBinder binder = service.onBind(null); + IMetricsBridgeService stub = IMetricsBridgeService.Stub.asInterface(binder); + stub.recordMetrics(recordBooleanProto.toByteArray()); + stub.recordMetrics(recordLinearProto.toByteArray()); + stub.recordMetrics(recordBooleanProto.toByteArray()); + + // Block until all tasks are finished to make sure all records are written to file. + FutureTask<Object> blockTask = service.addTaskToBlock(); + AwActivityTestRule.waitForFuture(blockTask); + + HistogramRecordList resultListProto = readProtoFromFile(mTempFile); + Assert.assertEquals( + "constructed list proto from file is different from the expected list proto", + resultListProto, expectedListProto); + } + + @Test + @MediumTest + // Test that service recovers saved data from file, appends new records to it and + // clears the file after a retrieve call. + public void testRetrieveFromFile() throws Throwable { + HistogramRecord recordBooleanProto = + HistogramRecord.newBuilder() + .setRecordType(RecordType.HISTOGRAM_BOOLEAN) + .setHistogramName("testRecoverFromFile.boolean") + .setSample(1) + .build(); + HistogramRecord recordLinearProto = HistogramRecord.newBuilder() + .setRecordType(RecordType.HISTOGRAM_LINEAR) + .setHistogramName("testRecoverFromFile.linear") + .setSample(123) + .setMin(1) + .setMax(1000) + .setNumBuckets(50) + .build(); + HistogramRecordList initialListProto = HistogramRecordList.newBuilder() + .addRecords(recordBooleanProto) + .addRecords(recordLinearProto) + .addRecords(recordBooleanProto) + .build(); + HistogramRecordList expectedListProto = + initialListProto.toBuilder().addRecords(recordBooleanProto).build(); + writeProtoToFile(initialListProto, mTempFile); + + // Cannot bind to service using real connection since we need to inject test file name. + MetricsBridgeService service = new MetricsBridgeService(mTempFile); + // Simulate starting the service by calling onCreate() + service.onCreate(); + + IBinder binder = service.onBind(null); + IMetricsBridgeService stub = IMetricsBridgeService.Stub.asInterface(binder); + stub.recordMetrics(recordBooleanProto.toByteArray()); + byte[] retrievedData = stub.retrieveNonembeddedMetrics(); + + // Assert file is deleted after the retrieve call + Assert.assertFalse( + "file should be deleted after retrieve metrics call", mTempFile.exists()); + Assert.assertNotNull("retrieved byte data from the service is null", retrievedData); + Assert.assertArrayEquals("retrieved byte data is different from the expected data", + expectedListProto.toByteArray(), retrievedData); + } + @Test @MediumTest // Test sending data to the service and retrieving it back. @@ -85,6 +199,28 @@ "metrics kept by the service hasn't been cleared", retrievedData.length == 0); } + private static void writeProtoToFile(HistogramRecordList recordList, File file) + throws IOException { + FileOutputStream out = new FileOutputStream(file); + for (HistogramRecord record : recordList.getRecordsList()) { + record.writeDelimitedTo(out); + } + out.close(); + } + + private static HistogramRecordList readProtoFromFile(File file) + throws IOException, InvalidProtocolBufferException { + FileInputStream in = new FileInputStream(file); + HistogramRecordList.Builder listBuilder = HistogramRecordList.newBuilder(); + HistogramRecord savedProto = HistogramRecord.parseDelimitedFrom(in); + while (savedProto != null) { + listBuilder.addRecords(savedProto); + savedProto = HistogramRecord.parseDelimitedFrom(in); + } + in.close(); + return listBuilder.build(); + } + // Connect to MetricsBridgeService and call recordMetrics with the given data, assert that // the method is called and returned. private void testRecordMetrics(byte[] data, boolean unbind) {
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/services/OWNERS b/android_webview/javatests/src/org/chromium/android_webview/test/services/OWNERS new file mode 100644 index 0000000..8dbd0dde --- /dev/null +++ b/android_webview/javatests/src/org/chromium/android_webview/test/services/OWNERS
@@ -0,0 +1 @@ +file://android_webview/nonembedded/OWNERS
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/MainActivity.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/MainActivity.java index adccf963..3ba7ac01 100644 --- a/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/MainActivity.java +++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/MainActivity.java
@@ -23,6 +23,7 @@ import androidx.fragment.app.FragmentTransaction; import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.base.metrics.RecordHistogram; import java.util.HashMap; import java.util.Map; @@ -85,6 +86,9 @@ } }, /* recursive */ false); + + // The boolean value doesn't matter, we only care about the total count. + RecordHistogram.recordBooleanHistogram("Android.WebView.DevUi.AppLaunch", true); } private void switchFragment(int chosenFragmentId) {
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/services/MetricsBridgeService.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/services/MetricsBridgeService.java index 41d74bd..e1150e19 100644 --- a/android_webview/nonembedded/java/src/org/chromium/android_webview/services/MetricsBridgeService.java +++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/services/MetricsBridgeService.java
@@ -9,6 +9,8 @@ import android.os.IBinder; import android.os.Process; +import androidx.annotation.VisibleForTesting; + import com.google.protobuf.InvalidProtocolBufferException; import org.chromium.android_webview.common.services.IMetricsBridgeService; @@ -38,6 +40,8 @@ private static final String LOG_FILE_NAME = "webview_metrics_bridge_logs"; + private final File mLogFile; + // Not guarded by a lock because it should only be accessed in a SequencedTaskRunner. private HistogramRecordList mRecordsList = HistogramRecordList.newBuilder().build(); @@ -54,9 +58,13 @@ File file = getMetricsLogFile(); if (!file.exists()) return; try (FileInputStream in = new FileInputStream(file)) { - HistogramRecordList savedProto = HistogramRecordList.parseFrom(in); - mRecordsList = - mRecordsList.toBuilder().addAllRecords(savedProto.getRecordsList()).build(); + HistogramRecordList.Builder listBuilder = HistogramRecordList.newBuilder(); + HistogramRecord savedProto = HistogramRecord.parseDelimitedFrom(in); + while (savedProto != null) { + listBuilder.addRecords(savedProto); + savedProto = HistogramRecord.parseDelimitedFrom(in); + } + mRecordsList = listBuilder.build(); } catch (InvalidProtocolBufferException e) { Log.e(TAG, "Malformed metrics log proto", e); deleteMetricsLogFile(); @@ -66,6 +74,16 @@ }); } + public MetricsBridgeService() { + this(new File(PathUtils.getDataDirectory(), LOG_FILE_NAME)); + } + + @VisibleForTesting + // Inject a logFile for testing. + public MetricsBridgeService(File logFile) { + mLogFile = logFile; + } + private final IMetricsBridgeService.Stub mBinder = new IMetricsBridgeService.Stub() { @Override public void recordMetrics(byte[] data) { @@ -83,17 +101,20 @@ Log.w(TAG, "retained records has reached the max capacity, dropping record"); return; } + + HistogramRecord proto = null; try { - HistogramRecord proto = HistogramRecord.parseFrom(data); + proto = HistogramRecord.parseFrom(data); mRecordsList = mRecordsList.toBuilder().addRecords(proto).build(); } catch (InvalidProtocolBufferException e) { Log.e(TAG, "Malformed metrics log proto", e); return; } - // Save all histograms including the incoming record to file. - try (FileOutputStream out = new FileOutputStream(getMetricsLogFile())) { - mRecordsList.writeTo(out); + // Append the histogram record to log file. + try (FileOutputStream out = + new FileOutputStream(getMetricsLogFile(), /* append */ true)) { + proto.writeDelimitedTo(out); } catch (IOException e) { Log.e(TAG, "Failed to write to file", e); } @@ -123,11 +144,23 @@ return mBinder; } - private static File getMetricsLogFile() { - return new File(PathUtils.getDataDirectory(), LOG_FILE_NAME); + private File getMetricsLogFile() { + return mLogFile; } - private static boolean deleteMetricsLogFile() { + private boolean deleteMetricsLogFile() { return getMetricsLogFile().delete(); } + + /** + * Block until all the tasks in the local {@code mSequencedTaskRunner} are finished. + * + * @param timeoutMillis timeout in milliseconds. + */ + @VisibleForTesting + public FutureTask addTaskToBlock() { + FutureTask<Object> blockTask = new FutureTask<Object>(() -> {}, new Object()); + mSequencedTaskRunner.postTask(blockTask); + return blockTask; + } } \ No newline at end of file
diff --git a/android_webview/support_library/boundary_interfaces/BUILD.gn b/android_webview/support_library/boundary_interfaces/BUILD.gn index 6d1ea3a..74b46f0e 100644 --- a/android_webview/support_library/boundary_interfaces/BUILD.gn +++ b/android_webview/support_library/boundary_interfaces/BUILD.gn
@@ -43,10 +43,18 @@ # core Android classes and other AndroidX classes (must be in the androidx.* # package name). deps = [ "//third_party/android_deps:androidx_annotation_annotation_java" ] +} - # This is to verify the boundary interfaces compile and lint correctly against - # the minSdkVersion of the webkit support library module. As the minSdkVersion - # of the support library increases, so should this value. See +android_apk("boundary_interface_example_apk") { + apk_name = "BoundaryInterfaceExample" + + # Use a dummy android manifest since this code is copied to androidx. + android_manifest = "//build/android/AndroidManifest.xml" + + # This is to verify that the boundary interfaces compile and lint correctly + # against the minSdkVersion of the webkit support library module. As the + # minSdkVersion of the support library increases, so should this value. See # http://crbug.com/828184 for more details. min_sdk_version = 14 + deps = [ ":boundary_interface_java" ] }
diff --git a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/util/BoundaryInterfaceReflectionUtil.java b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/util/BoundaryInterfaceReflectionUtil.java index 1c5f3692..c2dc6137 100644 --- a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/util/BoundaryInterfaceReflectionUtil.java +++ b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/util/BoundaryInterfaceReflectionUtil.java
@@ -3,12 +3,11 @@ // found in the LICENSE file. package org.chromium.support_lib_boundary.util; -import android.annotation.SuppressLint; -import android.annotation.TargetApi; import android.os.Build; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; @@ -22,7 +21,6 @@ */ // Although this is not enforced in chromium, this is a requirement enforced when this file is // mirrored into AndroidX. See http://b/120770118 for details. -@SuppressLint("BanTargetApiAnnotation") public class BoundaryInterfaceReflectionUtil { /** * Check if an object is an instance of {@code className}, resolving {@code className} in @@ -91,7 +89,7 @@ * method calls to. * @return an InvocationHandlerWithDelegateGetter wrapping {@code delegate} */ - @TargetApi(Build.VERSION_CODES.KITKAT) + @RequiresApi(Build.VERSION_CODES.KITKAT) @Nullable public static InvocationHandler createInvocationHandlerFor(@Nullable final Object delegate) { if (delegate == null) return null; @@ -111,7 +109,7 @@ * @return an array of InvocationHandlerWithDelegateGetter instances, each delegating to * the corresponding member of {@code delegates}. */ - @TargetApi(Build.VERSION_CODES.KITKAT) + @RequiresApi(Build.VERSION_CODES.KITKAT) @Nullable public static InvocationHandler[] createInvocationHandlersForArray( @Nullable final Object[] delegates) { @@ -148,7 +146,7 @@ * This allows us to pass InvocationHandlers across the support library boundary and later * unwrap the objects used as delegates within those InvocationHandlers. */ - @TargetApi(Build.VERSION_CODES.KITKAT) + @RequiresApi(Build.VERSION_CODES.KITKAT) private static class InvocationHandlerWithDelegateGetter implements InvocationHandler { private final Object mDelegate;
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 298bade..4a12f20 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -458,6 +458,8 @@ "login/parent_access_controller.h", "login/security_token_request_controller.cc", "login/security_token_request_controller.h", + "login/ui/access_code_input.cc", + "login/ui/access_code_input.h", "login/ui/animated_rounded_image_view.cc", "login/ui/animated_rounded_image_view.h", "login/ui/animation_frame.h",
diff --git a/ash/app_list/BUILD.gn b/ash/app_list/BUILD.gn index df53c2a..09a7b81c 100644 --- a/ash/app_list/BUILD.gn +++ b/ash/app_list/BUILD.gn
@@ -80,6 +80,8 @@ "views/search_result_container_view.h", "views/search_result_list_view.cc", "views/search_result_list_view.h", + "views/search_result_page_anchored_dialog.cc", + "views/search_result_page_anchored_dialog.h", "views/search_result_page_view.cc", "views/search_result_page_view.h", "views/search_result_suggestion_chip_view.cc",
diff --git a/ash/app_list/app_list_presenter_delegate_unittest.cc b/ash/app_list/app_list_presenter_delegate_unittest.cc index 2fdeaae..f65a606 100644 --- a/ash/app_list/app_list_presenter_delegate_unittest.cc +++ b/ash/app_list/app_list_presenter_delegate_unittest.cc
@@ -12,6 +12,7 @@ #include "ash/app_list/test/app_list_test_helper.h" #include "ash/app_list/test/app_list_test_model.h" #include "ash/app_list/test/app_list_test_view_delegate.h" +#include "ash/app_list/test/test_search_result.h" #include "ash/app_list/views/app_list_folder_view.h" #include "ash/app_list/views/app_list_item_view.h" #include "ash/app_list/views/app_list_main_view.h" @@ -21,9 +22,14 @@ #include "ash/app_list/views/contents_view.h" #include "ash/app_list/views/expand_arrow_view.h" #include "ash/app_list/views/search_box_view.h" +#include "ash/app_list/views/search_result_actions_view.h" +#include "ash/app_list/views/search_result_base_view.h" +#include "ash/app_list/views/search_result_list_view.h" +#include "ash/app_list/views/search_result_page_anchored_dialog.h" #include "ash/app_list/views/search_result_page_view.h" #include "ash/app_list/views/test/apps_grid_view_test_api.h" #include "ash/home_screen/home_screen_controller.h" +#include "ash/keyboard/keyboard_controller_impl.h" #include "ash/keyboard/ui/keyboard_ui_controller.h" #include "ash/keyboard/ui/test/keyboard_test_util.h" #include "ash/public/cpp/app_list/app_list_config.h" @@ -73,6 +79,7 @@ #include "ui/display/test/display_manager_test_api.h" #include "ui/events/test/event_generator.h" #include "ui/views/controls/textfield/textfield.h" +#include "ui/views/test/widget_test.h" #include "ui/wm/core/window_util.h" namespace ash { @@ -113,6 +120,21 @@ base::TimeDelta::FromMilliseconds(10), 2); } +std::unique_ptr<TestSearchResult> CreateOmniboxSuggestionResult( + const std::string& result_id) { + auto suggestion_result = std::make_unique<TestSearchResult>(); + suggestion_result->set_result_id(result_id); + suggestion_result->set_is_omnibox_search(true); + suggestion_result->set_display_type(ash::SearchResultDisplayType::kList); + SearchResultActions actions; + actions.push_back(SearchResultAction(gfx::ImageSkia(), + base::ASCIIToUTF16("Remove"), + true /*visible_on_hover*/)); + suggestion_result->SetActions(actions); + + return suggestion_result; +} + } // namespace class AppListPresenterDelegateZeroStateTest @@ -163,6 +185,82 @@ return GetAppListTestHelper()->GetAppListView(); } + SearchResultPageView* search_result_page() { + return GetAppListView() + ->app_list_main_view() + ->contents_view() + ->search_results_page_view(); + } + + void ShowZeroStateSearchInHalfState() { + GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId()); + GetEventGenerator()->GestureTapAt(GetPointInsideSearchbox()); + GetAppListTestHelper()->CheckState(AppListViewState::kHalf); + } + + SearchResultBaseView* GetSearchResultListViewItemAt(int index) { + return GetAppListView() + ->app_list_main_view() + ->contents_view() + ->search_result_list_view_for_test() + ->GetResultViewAt(index); + } + + void ClickMouseAt(const gfx::Point& point) { + ui::test::EventGenerator* generator = GetEventGenerator(); + generator->MoveMouseTo(point); + generator->PressLeftButton(); + generator->ReleaseLeftButton(); + } + + void LongPressAt(const gfx::Point& point) { + ui::TouchEvent long_press(ui::ET_GESTURE_LONG_PRESS, point, + base::TimeTicks::Now(), + ui::PointerDetails(ui::EventPointerType::kTouch)); + GetEventGenerator()->Dispatch(&long_press); + } + + views::DialogDelegate* GetSearchResultPageAnchoredDialog() { + return search_result_page() + ->anchored_dialog_for_test() + ->widget() + ->widget_delegate() + ->AsDialogDelegate(); + } + + // Verifies the current search result page anchored dialog bounds. + // The dialog is expected to be positioned horizontally centered within the + // search box bounds. + void SanityCheckSearchResultsAnchoredDialogBounds( + const views::Widget* dialog) { + auto horizontal_center_offset = [](const gfx::Rect& inner, + const gfx::Rect& outer) -> int { + return outer.CenterPoint().x() - inner.CenterPoint().x(); + }; + + const gfx::Rect dialog_bounds = dialog->GetWindowBoundsInScreen(); + const gfx::Rect search_box_bounds = GetAppListView() + ->search_box_view() + ->GetWidget() + ->GetWindowBoundsInScreen(); + // The dialog should be horizontally centered within the search box. + EXPECT_EQ(0, horizontal_center_offset(dialog_bounds, search_box_bounds)); + // Verify the confirmation dialog is positioned with the top within search + // box bounds. + EXPECT_GT(dialog_bounds.y(), search_box_bounds.y()); + EXPECT_LT(dialog_bounds.y(), search_box_bounds.bottom()); + } + + // Returns the |dialog| vertical offset from the top of the search box bounds. + int GetSearchResultsAnchoredDialogTopOffset(const views::Widget* dialog) { + const gfx::Rect dialog_bounds = dialog->GetWindowBoundsInScreen(); + const gfx::Rect search_box_bounds = GetAppListView() + ->search_box_view() + ->GetWidget() + ->GetWindowBoundsInScreen(); + return dialog_bounds.y() - search_box_bounds.y(); + } + private: DISALLOW_COPY_AND_ASSIGN(AppListPresenterDelegateZeroStateTest); }; @@ -207,7 +305,6 @@ UpdateDisplay("1024x768"); app_list_test_delegate_ = std::make_unique<test::AppListTestViewDelegate>(); - app_list_test_model_ = app_list_test_delegate_->GetTestModel(); } @@ -383,6 +480,331 @@ GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps); } +TEST_F(AppListPresenterDelegateZeroStateTest, + RemoveSuggestionShowsConfirmDialog) { + ShowZeroStateSearchInHalfState(); + + // Add a zero state suggestion results - the result that will be tested is in + // the second place. + Shell::Get()->app_list_controller()->GetSearchModel()->results()->Add( + CreateOmniboxSuggestionResult("Another suggestion")); + const std::string kTestResultId = "Test suggestion"; + Shell::Get()->app_list_controller()->GetSearchModel()->results()->Add( + CreateOmniboxSuggestionResult(kTestResultId)); + // The result list is updated asynchronously. + GetAppListTestHelper()->WaitUntilIdle(); + + SearchResultBaseView* result_view = GetSearchResultListViewItemAt(1); + ASSERT_TRUE(result_view); + ASSERT_TRUE(result_view->result()); + ASSERT_EQ(kTestResultId, result_view->result()->id()); + + // Make sure the search results page is laid out after adding result action + // buttons. + GetAppListView()->GetWidget()->LayoutRootViewIfNecessary(); + + ASSERT_TRUE(result_view->actions_view()); + EXPECT_EQ(1u, result_view->actions_view()->children().size()); + views::View* const action_view = result_view->actions_view()->children()[0]; + + // The remove action button is visible on hover only. + EXPECT_FALSE(action_view->GetVisible()); + + ui::test::EventGenerator* generator = GetEventGenerator(); + generator->MoveMouseTo(result_view->GetBoundsInScreen().CenterPoint()); + EXPECT_TRUE(action_view->GetVisible()); + + // Ensure layout after the action view visibility has been updated. + GetAppListView()->GetWidget()->LayoutRootViewIfNecessary(); + + // Click the remove action button, this should surface a confirmation dialog. + ClickMouseAt(action_view->GetBoundsInScreen().CenterPoint()); + + EXPECT_TRUE(GetAppListTestHelper() + ->app_list_client() + ->GetAndClearInvokedResultActions() + .empty()); + ASSERT_TRUE(search_result_page()->anchored_dialog_for_test()); + + // Cancel the dialog - the app list should remain in the search result page, + // the suggestion removal dialog should be hidden, and no result action should + // be invoked. + GetSearchResultPageAnchoredDialog()->CancelDialog(); + + GetAppListTestHelper()->CheckState(AppListViewState::kHalf); + EXPECT_FALSE(search_result_page()->anchored_dialog_for_test()); + EXPECT_TRUE(GetAppListTestHelper() + ->app_list_client() + ->GetAndClearInvokedResultActions() + .empty()); + + // Click remove suggestion action button again. + ClickMouseAt(action_view->GetBoundsInScreen().CenterPoint()); + + // Expect the removal confirmation dialog - this time, accept it. + ASSERT_TRUE(search_result_page()->anchored_dialog_for_test()); + GetSearchResultPageAnchoredDialog()->AcceptDialog(); + + // The app list should remain showing search results, the dialog should be + // closed, and result removal action should be invoked. + GetAppListTestHelper()->CheckState(AppListViewState::kHalf); + EXPECT_FALSE(search_result_page()->anchored_dialog_for_test()); + + std::vector<TestAppListClient::SearchResultActionId> expected_actions = { + {kTestResultId, OmniBoxZeroStateAction::kRemoveSuggestion}}; + std::vector<TestAppListClient::SearchResultActionId> invoked_actions = + GetAppListTestHelper() + ->app_list_client() + ->GetAndClearInvokedResultActions(); + EXPECT_EQ(expected_actions, invoked_actions); +} + +TEST_F(AppListPresenterDelegateZeroStateTest, RemoveSuggestionUsingLongTap) { + ShowZeroStateSearchInHalfState(); + + // Add a zero state suggestion results - the result that will be tested is in + // the second place. + Shell::Get()->app_list_controller()->GetSearchModel()->results()->Add( + CreateOmniboxSuggestionResult("Another suggestion")); + const std::string kTestResultId = "Test suggestion"; + Shell::Get()->app_list_controller()->GetSearchModel()->results()->Add( + CreateOmniboxSuggestionResult(kTestResultId)); + GetAppListTestHelper()->WaitUntilIdle(); + + SearchResultBaseView* result_view = GetSearchResultListViewItemAt(1); + ASSERT_TRUE(result_view); + ASSERT_TRUE(result_view->result()); + ASSERT_EQ(kTestResultId, result_view->result()->id()); + + // Make sure the search results page is laid out after adding result action + // buttons. + GetAppListView()->GetWidget()->LayoutRootViewIfNecessary(); + + // Long tap on the search result. This should show the removal confirmation + // dialog. + LongPressAt(result_view->GetBoundsInScreen().CenterPoint()); + + EXPECT_TRUE(result_view->selected()); + EXPECT_TRUE(GetAppListTestHelper() + ->app_list_client() + ->GetAndClearInvokedResultActions() + .empty()); + ASSERT_TRUE(search_result_page()->anchored_dialog_for_test()); + + // Cancel the dialog - the app list should remain in the search result page, + // the suggestion removal dialog should be hidden, and no result action should + // be invoked. + GetSearchResultPageAnchoredDialog()->CancelDialog(); + + GetAppListTestHelper()->CheckState(AppListViewState::kHalf); + EXPECT_FALSE(search_result_page()->anchored_dialog_for_test()); + EXPECT_TRUE(GetAppListTestHelper() + ->app_list_client() + ->GetAndClearInvokedResultActions() + .empty()); + EXPECT_FALSE(result_view->selected()); + + // Long tap on the result again. + LongPressAt(result_view->GetBoundsInScreen().CenterPoint()); + + // Expect the removal confirmation dialog - this time, accept it. + ASSERT_TRUE(search_result_page()->anchored_dialog_for_test()); + GetSearchResultPageAnchoredDialog()->AcceptDialog(); + + // The app list should remain showing search results, the dialog should be + // closed, and result removal action should be invoked. + GetAppListTestHelper()->CheckState(AppListViewState::kHalf); + EXPECT_FALSE(search_result_page()->anchored_dialog_for_test()); + EXPECT_FALSE(result_view->selected()); + + std::vector<TestAppListClient::SearchResultActionId> expected_actions = { + {kTestResultId, OmniBoxZeroStateAction::kRemoveSuggestion}}; + + std::vector<TestAppListClient::SearchResultActionId> invoked_actions = + GetAppListTestHelper() + ->app_list_client() + ->GetAndClearInvokedResultActions(); + EXPECT_EQ(expected_actions, invoked_actions); +} + +TEST_F(AppListPresenterDelegateZeroStateTest, + RemoveSuggestionDialogAnimatesWithAppListView) { + ShowZeroStateSearchInHalfState(); + + // Add a zero state suggestion result. + const std::string kTestResultId = "Test suggestion"; + Shell::Get()->app_list_controller()->GetSearchModel()->results()->Add( + CreateOmniboxSuggestionResult(kTestResultId)); + GetAppListTestHelper()->WaitUntilIdle(); + + SearchResultBaseView* result_view = GetSearchResultListViewItemAt(0); + ASSERT_TRUE(result_view); + ASSERT_TRUE(result_view->result()); + ASSERT_EQ(kTestResultId, result_view->result()->id()); + + // Show remove suggestion dialog. + LongPressAt(result_view->GetBoundsInScreen().CenterPoint()); + ASSERT_TRUE(search_result_page()->anchored_dialog_for_test()); + + views::Widget* const confirmation_dialog = + search_result_page()->anchored_dialog_for_test()->widget(); + ASSERT_TRUE(confirmation_dialog); + + SanityCheckSearchResultsAnchoredDialogBounds(confirmation_dialog); + const gfx::Rect initial_dialog_bounds = + confirmation_dialog->GetWindowBoundsInScreen(); + + ui::ScopedAnimationDurationScaleMode non_zero_duration_mode( + ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); + AppListView::SetShortAnimationForTesting(false); + + // Transition to fullscreen search state. + GetAppListView()->SetState(AppListViewState::kFullscreenSearch); + ASSERT_TRUE(search_result_page()->anchored_dialog_for_test()); + + EXPECT_NE(confirmation_dialog->GetLayer()->transform(), gfx::Transform()); + EXPECT_EQ(confirmation_dialog->GetLayer()->GetTargetTransform(), + gfx::Transform()); + + // Verify that the dialog position in screen does not change when the + // animation starts. + gfx::RectF current_bounds(confirmation_dialog->GetWindowBoundsInScreen()); + confirmation_dialog->GetLayer()->transform().TransformRect(¤t_bounds); + EXPECT_EQ(gfx::RectF(initial_dialog_bounds), current_bounds); +} + +TEST_F(AppListPresenterDelegateZeroStateTest, + RemoveSuggestionDialogBoundsUpdateWithAppListState) { + ShowZeroStateSearchInHalfState(); + + // Add a zero state suggestion result. + const std::string kTestResultId = "Test suggestion"; + Shell::Get()->app_list_controller()->GetSearchModel()->results()->Add( + CreateOmniboxSuggestionResult(kTestResultId)); + GetAppListTestHelper()->WaitUntilIdle(); + + SearchResultBaseView* result_view = GetSearchResultListViewItemAt(0); + ASSERT_TRUE(result_view); + ASSERT_TRUE(result_view->result()); + ASSERT_EQ(kTestResultId, result_view->result()->id()); + + // Show the remove suggestion dialog. + LongPressAt(result_view->GetBoundsInScreen().CenterPoint()); + ASSERT_TRUE(search_result_page()->anchored_dialog_for_test()); + + views::Widget* const confirmation_dialog = + search_result_page()->anchored_dialog_for_test()->widget(); + ASSERT_TRUE(confirmation_dialog); + + SCOPED_TRACE("Initial confirmation dialog bounds"); + SanityCheckSearchResultsAnchoredDialogBounds(confirmation_dialog); + const int dialog_margin = + GetSearchResultsAnchoredDialogTopOffset(confirmation_dialog); + + // Transition to fullscreen search state. + GetAppListView()->SetState(AppListViewState::kFullscreenSearch); + ASSERT_TRUE(search_result_page()->anchored_dialog_for_test()); + + // Verify that the confirmation dialog followed the search box widget. + SCOPED_TRACE("Confirmation dialog bounds after transition"); + SanityCheckSearchResultsAnchoredDialogBounds(confirmation_dialog); + EXPECT_EQ(dialog_margin, + GetSearchResultsAnchoredDialogTopOffset(confirmation_dialog)); +} + +TEST_F(AppListPresenterDelegateZeroStateTest, + TransitionToAppsContainerClosesRemoveSuggestionDialog) { + GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId()); + GetAppListView()->SetState(AppListViewState::kFullscreenAllApps); + ui::test::EventGenerator* generator = GetEventGenerator(); + generator->GestureTapAt(GetPointInsideSearchbox()); + GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenSearch); + + // Add a zero state suggestion result. + const std::string kTestResultId = "Test suggestion"; + Shell::Get()->app_list_controller()->GetSearchModel()->results()->Add( + CreateOmniboxSuggestionResult(kTestResultId)); + GetAppListTestHelper()->WaitUntilIdle(); + + SearchResultBaseView* result_view = GetSearchResultListViewItemAt(0); + ASSERT_TRUE(result_view); + ASSERT_TRUE(result_view->result()); + ASSERT_EQ(kTestResultId, result_view->result()->id()); + + // Show remove suggestion dialog. + ui::TouchEvent long_press( + ui::ET_GESTURE_LONG_PRESS, result_view->GetBoundsInScreen().CenterPoint(), + base::TimeTicks::Now(), ui::PointerDetails(ui::EventPointerType::kTouch)); + GetEventGenerator()->Dispatch(&long_press); + ASSERT_TRUE(search_result_page()->anchored_dialog_for_test()); + + views::Widget* const confirmation_dialog = + search_result_page()->anchored_dialog_for_test()->widget(); + ASSERT_TRUE(confirmation_dialog); + + SanityCheckSearchResultsAnchoredDialogBounds(confirmation_dialog); + + // Verify that transition to apps page hides the removal confirmation dialog. + views::test::WidgetClosingObserver widget_close_waiter(confirmation_dialog); + GetAppListView()->SetState(AppListViewState::kFullscreenAllApps); + + widget_close_waiter.Wait(); +} + +TEST_F(AppListPresenterDelegateZeroStateTest, + RemoveSuggestionDialogBoundsUpdateWhenVKHidden) { + // Enable virtual keyboard for this test. + KeyboardController* const keyboard_controller = + Shell::Get()->keyboard_controller(); + keyboard_controller->SetEnableFlag( + keyboard::KeyboardEnableFlag::kCommandLineEnabled); + + ShowZeroStateSearchInHalfState(); + + // Add a zero state suggestion result. + const std::string kTestResultId = "Test suggestion"; + Shell::Get()->app_list_controller()->GetSearchModel()->results()->Add( + CreateOmniboxSuggestionResult(kTestResultId)); + GetAppListTestHelper()->WaitUntilIdle(); + + SearchResultBaseView* result_view = GetSearchResultListViewItemAt(0); + ASSERT_TRUE(result_view); + ASSERT_TRUE(result_view->result()); + ASSERT_EQ(kTestResultId, result_view->result()->id()); + + auto* const keyboard_ui_controller = keyboard::KeyboardUIController::Get(); + keyboard_ui_controller->ShowKeyboard(false /* locked */); + ASSERT_TRUE(keyboard::WaitUntilShown()); + + // Show remove suggestion dialog. + LongPressAt(result_view->GetBoundsInScreen().CenterPoint()); + ASSERT_TRUE(search_result_page()->anchored_dialog_for_test()); + + // The search box should have lost the focus, which should have hidden the + // keyboard. + EXPECT_FALSE(keyboard_ui_controller->IsKeyboardVisible()); + + // Sanity check the confirmation dialog bounds (hiding the keyboard might have + // changed the position of the search box - the confirmation dialog should + // have followed it). + views::Widget* const confirmation_dialog = + search_result_page()->anchored_dialog_for_test()->widget(); + SanityCheckSearchResultsAnchoredDialogBounds(confirmation_dialog); + + views::test::WidgetClosingObserver widget_close_waiter(confirmation_dialog); + + // Go to peeking state, and verify the keyboard is not reshown. + GetAppListView()->SetState(AppListViewState::kPeeking); + GetAppListTestHelper()->WaitUntilIdle(); + // Exiting the search results page should close the dialog. + widget_close_waiter.Wait(); + EXPECT_FALSE(keyboard_controller->IsKeyboardVisible()); + + GetAppListTestHelper()->DismissAndRunLoop(); + GetAppListTestHelper()->CheckVisibility(false); + EXPECT_FALSE(keyboard_controller->IsKeyboardVisible()); +} + // Verifies that the downward mouse drag on AppsGridView's first page should // be handled by AppList. TEST_F(PopulatedAppListTest, MouseDragAppsGridViewHandledByAppList) { @@ -2527,13 +2949,6 @@ ->apps_grid_view(); } - SearchResultPageView* search_result_page() { - return GetAppListView() - ->app_list_main_view() - ->contents_view() - ->search_results_page_view(); - } - private: base::test::ScopedFeatureList scoped_feature_list_; };
diff --git a/ash/app_list/test/app_list_test_helper.h b/ash/app_list/test/app_list_test_helper.h index 006eb3b..4317b88 100644 --- a/ash/app_list/test/app_list_test_helper.h +++ b/ash/app_list/test/app_list_test_helper.h
@@ -58,6 +58,8 @@ AppListView* GetAppListView(); + TestAppListClient* app_list_client() { return app_list_client_.get(); } + private: AppListControllerImpl* app_list_controller_ = nullptr; std::unique_ptr<TestAppListClient> app_list_client_;
diff --git a/ash/app_list/test/test_app_list_client.cc b/ash/app_list/test/test_app_list_client.cc index edf2d9f..985d1e6 100644 --- a/ash/app_list/test/test_app_list_client.cc +++ b/ash/app_list/test/test_app_list_client.cc
@@ -11,6 +11,12 @@ TestAppListClient::TestAppListClient() = default; TestAppListClient::~TestAppListClient() = default; +void TestAppListClient::InvokeSearchResultAction(const std::string& result_id, + int action_index, + int event_flags) { + invoked_result_actions_.push_back(std::make_pair(result_id, action_index)); +} + void TestAppListClient::GetSearchResultContextMenuModel( const std::string& result_id, GetContextMenuModelCallback callback) { @@ -28,4 +34,11 @@ return nullptr; } +std::vector<TestAppListClient::SearchResultActionId> +TestAppListClient::GetAndClearInvokedResultActions() { + std::vector<SearchResultActionId> result; + result.swap(invoked_result_actions_); + return result; +} + } // namespace ash
diff --git a/ash/app_list/test/test_app_list_client.h b/ash/app_list/test/test_app_list_client.h index bbea106..541eb1ae 100644 --- a/ash/app_list/test/test_app_list_client.h +++ b/ash/app_list/test/test_app_list_client.h
@@ -5,6 +5,7 @@ #ifndef ASH_APP_LIST_TEST_TEST_APP_LIST_CLIENT_H_ #define ASH_APP_LIST_TEST_TEST_APP_LIST_CLIENT_H_ +#include <map> #include <memory> #include <string> #include <utility> @@ -33,7 +34,7 @@ bool launch_as_default) override {} void InvokeSearchResultAction(const std::string& result_id, int action_index, - int event_flags) override {} + int event_flags) override; void GetSearchResultContextMenuModel( const std::string& result_id, GetContextMenuModelCallback callback) override; @@ -71,7 +72,12 @@ int position_index) override {} AppListNotifier* GetNotifier() override; + using SearchResultActionId = std::pair<std::string, int>; + std::vector<SearchResultActionId> GetAndClearInvokedResultActions(); + private: + std::vector<SearchResultActionId> invoked_result_actions_; + DISALLOW_COPY_AND_ASSIGN(TestAppListClient); };
diff --git a/ash/app_list/views/app_list_folder_view.cc b/ash/app_list/views/app_list_folder_view.cc index 61dd5a31..6593ae50 100644 --- a/ash/app_list/views/app_list_folder_view.cc +++ b/ash/app_list/views/app_list_folder_view.cc
@@ -48,6 +48,7 @@ constexpr int kFolderHeaderPadding = 12; constexpr int kOnscreenKeyboardTopPadding = 16; +constexpr int kFolderHorizontalMargin = 8; // Indexes of interesting views in ViewModel of AppListFolderView. constexpr int kIndexBackground = 0; @@ -605,11 +606,18 @@ const gfx::Size search_box_size = contents_view_->GetSearchBoxSize(AppListState::kStateApps); // Adjust for apps container margins. - container_bounds.Inset(container_view_->CalculateMarginsForAvailableBounds( - container_bounds, search_box_size)); + gfx::Insets adjusted_margins = + container_view_->CalculateMarginsForAvailableBounds(container_bounds, + search_box_size); + // App list folders can open past the app list bounds and within + // |kFolderHorizontalMargin| px of the screen. + adjusted_margins.set_left(kFolderHorizontalMargin); + adjusted_margins.set_right(kFolderHorizontalMargin); + container_bounds.Inset(adjusted_margins); + // Avoid overlap with the search box widget. container_bounds.Inset( - 8, search_box_size.height() + SearchBoxView::GetFocusRingSpacing(), 8, 0); + 0, search_box_size.height() + SearchBoxView::GetFocusRingSpacing(), 0, 0); preferred_bounds_.AdjustToFit(container_bounds); // Calculate the folder icon's bounds relative to this view.
diff --git a/ash/app_list/views/app_list_page.h b/ash/app_list/views/app_list_page.h index 1315ff93..61286f2 100644 --- a/ash/app_list/views/app_list_page.h +++ b/ash/app_list/views/app_list_page.h
@@ -95,7 +95,7 @@ const gfx::Rect& contents_bounds, const gfx::Rect& search_box_bounds) const = 0; - const ContentsView* contents_view() const { return contents_view_; } + ContentsView* contents_view() { return contents_view_; } void set_contents_view(ContentsView* contents_view) { contents_view_ = contents_view; }
diff --git a/ash/app_list/views/app_list_view.cc b/ash/app_list/views/app_list_view.cc index 8f96ca4..4aca39e 100644 --- a/ash/app_list/views/app_list_view.cc +++ b/ash/app_list/views/app_list_view.cc
@@ -2173,14 +2173,12 @@ if (folder_offset != 0) { OffsetYPositionOfAppList(folder_offset); offset_to_show_folder_with_onscreen_keyboard_ = true; - app_list_main_view_->contents_view()->NotifySearchBoxBoundsUpdated(); } } else if (offset_to_show_folder_with_onscreen_keyboard_) { // If the keyboard is closing or a folder isn't being shown, reset // the app list's position OffsetYPositionOfAppList(0); offset_to_show_folder_with_onscreen_keyboard_ = false; - app_list_main_view_->contents_view()->NotifySearchBoxBoundsUpdated(); } if (!shown) {
diff --git a/ash/app_list/views/apps_container_view.cc b/ash/app_list/views/apps_container_view.cc index 5971a56..34cf177d3 100644 --- a/ash/app_list/views/apps_container_view.cc +++ b/ash/app_list/views/apps_container_view.cc
@@ -5,6 +5,8 @@ #include "ash/app_list/views/apps_container_view.h" #include <algorithm> +#include <memory> +#include <utility> #include <vector> #include "ash/app_list/views/app_list_folder_view.h" @@ -17,6 +19,7 @@ #include "ash/app_list/views/page_switcher.h" #include "ash/app_list/views/search_box_view.h" #include "ash/app_list/views/suggestion_chip_container_view.h" +#include "ash/keyboard/ui/keyboard_ui_controller.h" #include "ash/public/cpp/app_list/app_list_config.h" #include "ash/public/cpp/app_list/app_list_switches.h" #include "base/command_line.h" @@ -353,6 +356,16 @@ event->SetHandled(); } +void AppsContainerView::OnShown() { + // Explicitly hide the virtual keyboard before showing the apps container + // view. This prevents the virtual keyboard's "transient blur" feature from + // kicking in - if a text input loses focus, and a text input gains it within + // seconds, the virtual keyboard gets reshown. This is undesirable behavior + // for the app list (where search box gets focus by default). + if (keyboard::KeyboardUIController::HasInstance()) + keyboard::KeyboardUIController::Get()->HideKeyboardExplicitlyBySystem(); +} + void AppsContainerView::OnWillBeHidden() { if (show_state_ == SHOW_APPS || show_state_ == SHOW_ITEM_REPARENT) apps_grid_view_->EndDrag(true);
diff --git a/ash/app_list/views/apps_container_view.h b/ash/app_list/views/apps_container_view.h index e6e4625f..2969d77 100644 --- a/ash/app_list/views/apps_container_view.h +++ b/ash/app_list/views/apps_container_view.h
@@ -97,6 +97,7 @@ void OnGestureEvent(ui::GestureEvent* event) override; // AppListPage overrides: + void OnShown() override; void OnWillBeHidden() override; void OnAnimationStarted(AppListState from_state, AppListState to_state) override;
diff --git a/ash/app_list/views/contents_view.cc b/ash/app_list/views/contents_view.cc index 23cb5fa3..cab775e6 100644 --- a/ash/app_list/views/contents_view.cc +++ b/ash/app_list/views/contents_view.cc
@@ -598,8 +598,6 @@ case AppListState::kStateSearchResults: GetSearchBoxView()->ClearSearchAndDeactivateSearchBox(); ShowSearchResults(false); - for (auto& observer : search_box_observers_) - observer.OnSearchBoxClearAndDeactivated(); break; case AppListState::kStateEmbeddedAssistant: ShowEmbeddedAssistantUI(false); @@ -916,21 +914,6 @@ return settings; } -void ContentsView::NotifySearchBoxBoundsUpdated() { - for (auto& observer : search_box_observers_) - observer.OnSearchBoxBoundsUpdated(); -} - -void ContentsView::AddSearchBoxUpdateObserver( - SearchBoxUpdateObserver* observer) { - search_box_observers_.AddObserver(observer); -} - -void ContentsView::RemoveSearchBoxUpdateObserver( - SearchBoxUpdateObserver* observer) { - search_box_observers_.RemoveObserver(observer); -} - bool ContentsView::ShouldLayoutPage(AppListPage* page, AppListState current_state, AppListState target_state) const {
diff --git a/ash/app_list/views/contents_view.h b/ash/app_list/views/contents_view.h index 5b05193..f86881d 100644 --- a/ash/app_list/views/contents_view.h +++ b/ash/app_list/views/contents_view.h
@@ -56,16 +56,6 @@ class APP_LIST_EXPORT ContentsView : public views::View, public PaginationModelObserver { public: - // This class observes the search box Updates. - class SearchBoxUpdateObserver : public base::CheckedObserver { - public: - // Called when search box bounds is updated. - virtual void OnSearchBoxBoundsUpdated() = 0; - - // Called when the search box is cleaded and deactivated. - virtual void OnSearchBoxClearAndDeactivated() = 0; - }; - // Used to SetActiveState without animations. class ScopedSetActiveStateAnimationDisabler { public: @@ -223,11 +213,6 @@ std::unique_ptr<ui::ScopedLayerAnimationSettings> CreateTransitionAnimationSettings(ui::Layer* layer) const; - void NotifySearchBoxBoundsUpdated(); - - void AddSearchBoxUpdateObserver(SearchBoxUpdateObserver* observer); - void RemoveSearchBoxUpdateObserver(SearchBoxUpdateObserver* observer); - // Adjusts search box view size so it fits within the contents view margins // (when centered). gfx::Size AdjustSearchBoxSizeToFitMargins( @@ -328,8 +313,6 @@ base::Optional<AppListState> target_page_for_last_view_state_update_; base::Optional<AppListViewState> last_target_view_state_; - base::ObserverList<SearchBoxUpdateObserver> search_box_observers_; - DISALLOW_COPY_AND_ASSIGN(ContentsView); };
diff --git a/ash/app_list/views/folder_header_view_unittest.cc b/ash/app_list/views/folder_header_view_unittest.cc index f600f86..98f6f23 100644 --- a/ash/app_list/views/folder_header_view_unittest.cc +++ b/ash/app_list/views/folder_header_view_unittest.cc
@@ -188,6 +188,25 @@ EXPECT_FALSE(CanEditFolderName()); } +namespace { + +// Sends a tap gesture with events corresponding to touch-down and touch-up. +// This is a template to support a |handler| with an OnGestureEvent() method +// that isn't a ui::EventHandler implementation. +template <typename GestureHandler> +void SendTap(GestureHandler* handler, const gfx::Point& location) { + ui::GestureEvent tap_down( + location.x(), location.y(), 0, base::TimeTicks::Now(), + ui::GestureEventDetails(ui::EventType::ET_GESTURE_TAP_DOWN)); + handler->OnGestureEvent(&tap_down); + ui::GestureEvent tap_up( + location.x(), location.y(), 0, base::TimeTicks::Now(), + ui::GestureEventDetails(ui::EventType::ET_GESTURE_TAP)); + handler->OnGestureEvent(&tap_up); +} + +} // namespace + // Tests that folder name textfield is triggered when user touches on or near // the folder name. (see https://crbug.com/997364) TEST_F(FolderHeaderViewTest, TriggerFolderRenameAfterTappingNearFolderName) { @@ -200,11 +219,8 @@ folder_header_view_->GetFolderNameViewForTest()->GetBoundsInScreen(); // Tap folder name and check that folder renaming is triggered. - gfx::Point name_center_point = name_view_bounds.CenterPoint(); - ui::GestureEvent tap_center( - name_center_point.x(), name_center_point.y(), 0, base::TimeTicks::Now(), - ui::GestureEventDetails(ui::EventType::ET_GESTURE_TAP_DOWN)); - folder_header_view_->GetFolderNameViewForTest()->OnGestureEvent(&tap_center); + SendTap(folder_header_view_->GetFolderNameViewForTest(), + name_view_bounds.CenterPoint()); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(folder_header_view_->GetFolderNameViewForTest()->HasFocus()); @@ -215,12 +231,7 @@ // Test that tapping near (but not directly on) the folder name still // triggers folder rename. // Tap folder name and check that folder renaming is triggered. - ui::GestureEvent tap_near( - name_view_bounds.top_right().x(), name_view_bounds.top_right().y(), 0, - base::TimeTicks::Now(), - ui::GestureEventDetails(ui::EventType::ET_GESTURE_TAP_DOWN)); - widget_->OnGestureEvent(&tap_near); - + SendTap(widget_.get(), name_view_bounds.top_right()); EXPECT_TRUE(folder_header_view_->GetFolderNameViewForTest()->HasFocus()); }
diff --git a/ash/app_list/views/remove_query_confirmation_dialog.cc b/ash/app_list/views/remove_query_confirmation_dialog.cc index 4ef30484..8a2d3558 100644 --- a/ash/app_list/views/remove_query_confirmation_dialog.cc +++ b/ash/app_list/views/remove_query_confirmation_dialog.cc
@@ -4,6 +4,9 @@ #include "ash/app_list/views/remove_query_confirmation_dialog.h" +#include <memory> +#include <utility> + #include "ash/app_list/views/search_box_view.h" #include "ui/base/l10n/l10n_util.h" #include "ui/strings/grit/ui_strings.h" @@ -17,18 +20,13 @@ namespace { constexpr int kDialogWidth = 320; -constexpr int kDialogYOffset = 32; } // namespace RemoveQueryConfirmationDialog::RemoveQueryConfirmationDialog( const base::string16& query, - RemovalConfirmationCallback confirm_callback, - int event_flags, - ContentsView* contents_view) - : confirm_callback_(std::move(confirm_callback)), - event_flags_(event_flags), - contents_view_(contents_view) { + RemovalConfirmationCallback confirm_callback) + : confirm_callback_(std::move(confirm_callback)) { SetTitle(l10n_util::GetStringUTF16(IDS_REMOVE_ZERO_STATE_SUGGESTION_TITLE)); SetShowCloseButton(false); @@ -38,7 +36,7 @@ l10n_util::GetStringUTF16(IDS_APP_CANCEL)); auto run_callback = [](RemoveQueryConfirmationDialog* dialog, bool accept) { - std::move(dialog->confirm_callback_).Run(accept, dialog->event_flags_); + std::move(dialog->confirm_callback_).Run(accept); }; SetAcceptCallback(base::BindOnce(run_callback, base::Unretained(this), true)); SetCancelCallback( @@ -56,66 +54,21 @@ label->SetHorizontalAlignment(gfx::ALIGN_LEFT); label->SetAllowCharacterBreak(true); AddChildView(label); - - contents_view_->AddSearchBoxUpdateObserver(this); } -RemoveQueryConfirmationDialog::~RemoveQueryConfirmationDialog() { - contents_view_->RemoveSearchBoxUpdateObserver(this); -} - -void RemoveQueryConfirmationDialog::Show(gfx::NativeWindow parent) { - views::DialogDelegate::CreateDialogWidget(this, nullptr, parent); - UpdateBounds(); - GetWidget()->Show(); -} +RemoveQueryConfirmationDialog::~RemoveQueryConfirmationDialog() = default; const char* RemoveQueryConfirmationDialog::GetClassName() const { return "RemoveQueryConfirmationDialog"; } -ui::ModalType RemoveQueryConfirmationDialog::GetModalType() const { - return ui::MODAL_TYPE_WINDOW; -} - gfx::Size RemoveQueryConfirmationDialog::CalculatePreferredSize() const { const int default_width = kDialogWidth; return gfx::Size(default_width, GetHeightForWidth(default_width)); } -void RemoveQueryConfirmationDialog::OnSearchBoxBoundsUpdated() { - UpdateBounds(); -} - -void RemoveQueryConfirmationDialog::OnSearchBoxClearAndDeactivated() { - // In tablet mode, when the user opens uber tray, the search box will be - // cleared and deactivated while app list switches to full app mode. Close - // this dialog when receiving such notification. - // Note: When the dialog is closed, the focus manager will restore - // the focus to the previously focused view, i.e., SearchBoxView's - // text field, which will lead to the opening of virtual keyboard. In order to - // avoid this, we temporarily clear the stored focus view before closing - // the dialog, and restore it back right after. - views::FocusManager* focus_manager = - contents_view_->GetSearchBoxView()->GetWidget()->GetFocusManager(); - views::View* strored_focus_view = focus_manager->GetStoredFocusView(); - focus_manager->SetStoredFocusView(nullptr); - CancelDialog(); - focus_manager->SetStoredFocusView(strored_focus_view); -} - -void RemoveQueryConfirmationDialog::UpdateBounds() { - // Calculate confirmation dialog's origin in screen coordinates. - gfx::Rect anchor_rect = - contents_view_->GetSearchBoxView()->GetBoundsInScreen(); - gfx::Point origin(anchor_rect.CenterPoint().x() - kDialogWidth / 2, - anchor_rect.y() + kDialogYOffset); - - views::Widget* widget = GetWidget(); - DCHECK(widget); - gfx::Rect widget_rect = widget->GetWindowBoundsInScreen(); - widget_rect.set_origin(origin); - widget->SetBounds(widget_rect); +ui::ModalType RemoveQueryConfirmationDialog::GetModalType() const { + return ui::MODAL_TYPE_WINDOW; } } // namespace ash
diff --git a/ash/app_list/views/remove_query_confirmation_dialog.h b/ash/app_list/views/remove_query_confirmation_dialog.h index d7bae505..21c156a7 100644 --- a/ash/app_list/views/remove_query_confirmation_dialog.h +++ b/ash/app_list/views/remove_query_confirmation_dialog.h
@@ -5,7 +5,6 @@ #ifndef ASH_APP_LIST_VIEWS_REMOVE_QUERY_CONFIRMATION_DIALOG_H_ #define ASH_APP_LIST_VIEWS_REMOVE_QUERY_CONFIRMATION_DIALOG_H_ -#include "ash/app_list/views/contents_view.h" #include "base/callback.h" #include "ui/views/window/dialog_delegate.h" @@ -13,45 +12,28 @@ // RemoveQueryConfirmationDialog displays the confirmation dialog for removing // a recent query suggestion. -class RemoveQueryConfirmationDialog - : public views::DialogDelegateView, - public ContentsView::SearchBoxUpdateObserver { +class RemoveQueryConfirmationDialog : public views::DialogDelegateView { public: // Callback to notify user's confirmation for removing the zero state // suggestion query. Invoked with true if user confirms removing query // suggestion; and false for declining the removal. The second parameter is // the event flags of user action for invoking the removal action on the // associated result. - using RemovalConfirmationCallback = base::OnceCallback<void(bool, int)>; + using RemovalConfirmationCallback = base::OnceCallback<void(bool)>; RemoveQueryConfirmationDialog(const base::string16& query, - RemovalConfirmationCallback callback, - int event_flags, - ContentsView* contents_view); + RemovalConfirmationCallback callback); ~RemoveQueryConfirmationDialog() override; - // Shows the dialog with |parent|. - void Show(gfx::NativeWindow parent); - // views::View: const char* GetClassName() const override; + gfx::Size CalculatePreferredSize() const override; - private: // views::WidgetDelegate: ui::ModalType GetModalType() const override; - // views::View: - gfx::Size CalculatePreferredSize() const override; - - // ContentsView::SearchBoxUpdateObserver - void OnSearchBoxBoundsUpdated() override; - void OnSearchBoxClearAndDeactivated() override; - - void UpdateBounds(); - + private: RemovalConfirmationCallback confirm_callback_; - int event_flags_; - ContentsView* const contents_view_; // Owned by the views hierarchy DISALLOW_COPY_AND_ASSIGN(RemoveQueryConfirmationDialog); };
diff --git a/ash/app_list/views/search_result_base_view.h b/ash/app_list/views/search_result_base_view.h index 0b7ddc2..ef35eee 100644 --- a/ash/app_list/views/search_result_base_view.h +++ b/ash/app_list/views/search_result_base_view.h
@@ -89,6 +89,8 @@ // views::View: const char* GetClassName() const override; + SearchResultActionsView* actions_view() { return actions_view_; } + protected: ~SearchResultBaseView() override; @@ -98,8 +100,6 @@ actions_view_ = actions_view; } - SearchResultActionsView* actions_view() { return actions_view_; } - private: // Selects the initial action that should be associated with the result view, // notifying a11y hierarchy of the selection. If the result view does not
diff --git a/ash/app_list/views/search_result_page_anchored_dialog.cc b/ash/app_list/views/search_result_page_anchored_dialog.cc new file mode 100644 index 0000000..134a690 --- /dev/null +++ b/ash/app_list/views/search_result_page_anchored_dialog.cc
@@ -0,0 +1,99 @@ +// 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/app_list/views/search_result_page_anchored_dialog.h" + +#include <utility> + +#include "ui/gfx/geometry/point.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/geometry/size.h" +#include "ui/gfx/transform.h" +#include "ui/views/view.h" +#include "ui/views/window/dialog_delegate.h" +#include "ui/views/window/non_client_view.h" +#include "ui/wm/core/coordinate_conversion.h" + +namespace ash { + +namespace { + +// The intended offset the dialog should have from the top of the anchor view +// bounds. +constexpr int kDialogVerticalMargin = 32; + +} // namespace + +SearchResultPageAnchoredDialog::SearchResultPageAnchoredDialog( + std::unique_ptr<views::DialogDelegateView> dialog, + views::View* host_view, + base::OnceClosure callback) + : host_view_(host_view), callback_(std::move(callback)) { + DCHECK(!dialog->GetWidget()); + + views::Widget* const parent = host_view_->GetWidget(); + // The |dialog| ownership is passed to the window hierarchy. + widget_ = views::DialogDelegate::CreateDialogWidget( + dialog.release(), nullptr, parent->GetNativeWindow()); + widget_observer_.Add(widget_); + widget_observer_.Add(parent); +} + +SearchResultPageAnchoredDialog::~SearchResultPageAnchoredDialog() { + widget_observer_.RemoveAll(); + if (widget_) + widget_->Close(); +} + +void SearchResultPageAnchoredDialog::UpdateBounds( + const gfx::Rect& anchor_bounds) { + if (!widget_) + return; + + anchor_bounds_ = anchor_bounds; + + gfx::Point anchor_point_in_screen = anchor_bounds.CenterPoint(); + views::View::ConvertPointToScreen(host_view_, &anchor_point_in_screen); + + // Calculate dialog offset from the anchor view center so the dialog frame + // (ignoring borders) respects kDialogVerticalMargin. + const int vertical_offset = + kDialogVerticalMargin - anchor_bounds.height() / 2 - + widget_->non_client_view()->frame_view()->GetInsets().top(); + gfx::Size dialog_size = widget_->GetContentsView()->GetPreferredSize(); + widget_->SetBounds( + gfx::Rect(gfx::Point(anchor_point_in_screen.x() - dialog_size.width() / 2, + anchor_point_in_screen.y() + vertical_offset), + dialog_size)); +} + +float SearchResultPageAnchoredDialog::AdjustVerticalTransformOffset( + float default_offset) { + // In addition to the search box offset (in host view coordinates), the + // widget has to consider the parent (app list view) widget transform to + // correctly follow the anchor view animation. + const float parent_offset = + host_view_->GetWidget()->GetLayer()->transform().To2dTranslation().y(); + return default_offset + parent_offset; +} + +void SearchResultPageAnchoredDialog::OnWidgetClosing(views::Widget* widget) { + widget_ = nullptr; + widget_observer_.RemoveAll(); + if (callback_) + std::move(callback_).Run(); +} + +void SearchResultPageAnchoredDialog::OnWidgetBoundsChanged( + views::Widget* widget, + const gfx::Rect& new_bounds) { + // Reposition the dialog widget if the host widget bounds change (if the + // bounds size remained the same, the host widget bounds change may not cause + // app list layout, and thus the anchor bounds in the host view coordinates + // may not change). + if (widget == host_view_->GetWidget()) + UpdateBounds(anchor_bounds_); +} + +} // namespace ash
diff --git a/ash/app_list/views/search_result_page_anchored_dialog.h b/ash/app_list/views/search_result_page_anchored_dialog.h new file mode 100644 index 0000000..2e380a2 --- /dev/null +++ b/ash/app_list/views/search_result_page_anchored_dialog.h
@@ -0,0 +1,79 @@ +// 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 ASH_APP_LIST_VIEWS_SEARCH_RESULT_PAGE_ANCHORED_DIALOG_H_ +#define ASH_APP_LIST_VIEWS_SEARCH_RESULT_PAGE_ANCHORED_DIALOG_H_ + +#include <memory> + +#include "base/callback.h" +#include "base/scoped_observer.h" +#include "ui/views/widget/widget.h" +#include "ui/views/widget/widget_observer.h" + +namespace gfx { +class Rect; +} + +namespace views { +class DialogDelegateView; +} + +namespace ash { + +// A helper to keep track and manage bounds of a dialog window anchored within +// the search results app list page. +class SearchResultPageAnchoredDialog : public views::WidgetObserver { + public: + // Creates a widget for the provided dialog delegate view. + // |dialog| - The dialog delegate view whose widget this should manage. + // |host_view| - The view that is "hosting" the dialog - the dialog widget + // will be parented by the host view's widget, and anchor bounds provided + // to UpdateBounds() will be expected to be in host view bounds. + // |callback| - A closure called when the dialog widget gets closed. The + // callback will not be called when the SearchResultPageAnchoredDialog + // gets destroyed, + SearchResultPageAnchoredDialog( + std::unique_ptr<views::DialogDelegateView> dialog, + views::View* host_view, + base::OnceClosure callback); + SearchResultPageAnchoredDialog(const SearchResultPageAnchoredDialog& other) = + delete; + SearchResultPageAnchoredDialog& operator=( + const SearchResultPageAnchoredDialog& other) = delete; + ~SearchResultPageAnchoredDialog() override; + + // Repositions the dialog widget bounds relative to the provided anchor + // bounds. + // |anchor_bounds| are expected to be in |host_view_| coordinates. + void UpdateBounds(const gfx::Rect& anchor_bounds); + + // Adjusts the vertical translate offset to be used during search results page + // animation. The default offset follows the search box bounds translation + // within the host view bounds. + float AdjustVerticalTransformOffset(float default_offset); + + // views::WidgetObserver: + void OnWidgetClosing(views::Widget* widget) override; + void OnWidgetBoundsChanged(views::Widget* widget, + const gfx::Rect& new_bounds) override; + + views::Widget* widget() { return widget_; } + + private: + views::Widget* widget_ = nullptr; + + views::View* const host_view_; + + base::OnceClosure callback_; + + // Most recent anchor bounds (in |host_view_| coordinates). + gfx::Rect anchor_bounds_; + + ScopedObserver<views::Widget, views::WidgetObserver> widget_observer_{this}; +}; + +} // namespace ash + +#endif // ASH_APP_LIST_VIEWS_SEARCH_RESULT_PAGE_ANCHORED_DIALOG_H_
diff --git a/ash/app_list/views/search_result_page_view.cc b/ash/app_list/views/search_result_page_view.cc index 62948958..59155b1 100644 --- a/ash/app_list/views/search_result_page_view.cc +++ b/ash/app_list/views/search_result_page_view.cc
@@ -7,7 +7,7 @@ #include <stddef.h> #include <algorithm> -#include <memory> +#include <utility> #include "ash/app_list/app_list_util.h" #include "ash/app_list/app_list_view_delegate.h" @@ -17,6 +17,7 @@ #include "ash/app_list/views/search_box_view.h" #include "ash/app_list/views/search_result_base_view.h" #include "ash/app_list/views/search_result_list_view.h" +#include "ash/app_list/views/search_result_page_anchored_dialog.h" #include "ash/app_list/views/search_result_tile_item_list_view.h" #include "ash/public/cpp/app_list/app_list_config.h" #include "ash/public/cpp/app_list/app_list_features.h" @@ -42,6 +43,7 @@ #include "ui/views/focus/focus_manager.h" #include "ui/views/layout/box_layout.h" #include "ui/views/layout/fill_layout.h" +#include "ui/views/window/dialog_delegate.h" namespace ash { @@ -443,6 +445,27 @@ ReorderSearchResultContainers(); } +void SearchResultPageView::ShowAnchoredDialog( + std::unique_ptr<views::DialogDelegateView> dialog) { + ContentsView* const contents_view = AppListPage::contents_view(); + if (contents_view->GetActiveState() != AppListState::kStateSearchResults) + return; + + anchored_dialog_ = std::make_unique<SearchResultPageAnchoredDialog>( + std::move(dialog), contents_view, + base::BindOnce(&SearchResultPageView::OnAnchoredDialogClosed, + base::Unretained(this))); + const gfx::Rect anchor_bounds = + contents_view->GetSearchBoxBounds(AppListState::kStateSearchResults); + anchored_dialog_->UpdateBounds(anchor_bounds); + + anchored_dialog_->widget()->Show(); +} + +void SearchResultPageView::OnWillBeHidden() { + anchored_dialog_.reset(); +} + void SearchResultPageView::OnHidden() { // Hide the search results page when it is behind search box to avoid focus // being moved onto suggested apps when zero state is enabled. @@ -478,6 +501,11 @@ animator.Run(default_offset, layer(), this); animator.Run(default_offset, view_shadow_->shadow()->shadow_layer(), nullptr); + if (anchored_dialog_) { + const float offset = + anchored_dialog_->AdjustVerticalTransformOffset(default_offset); + animator.Run(offset, anchored_dialog_->widget()->GetLayer(), nullptr); + } } void SearchResultPageView::UpdatePageOpacityForState(AppListState state, @@ -486,6 +514,16 @@ layer()->SetOpacity(search_box_opacity); } +void SearchResultPageView::UpdatePageBoundsForState( + AppListState state, + const gfx::Rect& contents_bounds, + const gfx::Rect& search_box_bounds) { + AppListPage::UpdatePageBoundsForState(state, contents_bounds, + search_box_bounds); + if (anchored_dialog_) + anchored_dialog_->UpdateBounds(search_box_bounds); +} + gfx::Rect SearchResultPageView::GetPageBoundsForState( AppListState state, const gfx::Rect& contents_bounds, @@ -603,4 +641,8 @@ this, GetWidget(), true /* reverse */, false /* dont_loop */); } +void SearchResultPageView::OnAnchoredDialogClosed() { + anchored_dialog_.reset(); +} + } // namespace ash
diff --git a/ash/app_list/views/search_result_page_view.h b/ash/app_list/views/search_result_page_view.h index d1128d1..f660de8 100644 --- a/ash/app_list/views/search_result_page_view.h +++ b/ash/app_list/views/search_result_page_view.h
@@ -5,6 +5,7 @@ #ifndef ASH_APP_LIST_VIEWS_SEARCH_RESULT_PAGE_VIEW_H_ #define ASH_APP_LIST_VIEWS_SEARCH_RESULT_PAGE_VIEW_H_ +#include <memory> #include <vector> #include "ash/app_list/app_list_export.h" @@ -18,11 +19,16 @@ #include "base/memory/weak_ptr.h" #include "base/timer/timer.h" +namespace views { +class DialogDelegateView; +} + namespace ash { class AppListViewDelegate; class SearchResultBaseView; class ViewShadow; +class SearchResultPageAnchoredDialog; // The search results page for the app list. class APP_LIST_EXPORT SearchResultPageView @@ -51,6 +57,7 @@ void GetAccessibleNodeData(ui::AXNodeData* node_data) override; // AppListPage overrides: + void OnWillBeHidden() override; void OnHidden() override; void OnShown() override; void AnimateYPosition(AppListViewState target_view_state, @@ -59,6 +66,9 @@ void UpdatePageOpacityForState(AppListState state, float search_box_opacity, bool restore_opacity) override; + void UpdatePageBoundsForState(AppListState state, + const gfx::Rect& contents_bounds, + const gfx::Rect& search_box_bounds) override; gfx::Rect GetPageBoundsForState( AppListState state, const gfx::Rect& contents_bounds, @@ -86,6 +96,13 @@ void OnAssistantPrivacyInfoViewCloseButtonPressed(); + // 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 + // repositioned as the page layout changes. The dialog will be closed if the + // search results page gets hidden. + // |dialog| should not yet have a widget. + void ShowAnchoredDialog(std::unique_ptr<views::DialogDelegateView> dialog); + views::View* contents_view() { return contents_view_; } SearchResultBaseView* first_result_view() const { return first_result_view_; } @@ -93,6 +110,10 @@ return result_selection_controller_.get(); } + SearchResultPageAnchoredDialog* anchored_dialog_for_test() { + return anchored_dialog_.get(); + } + private: // Separator between SearchResultContainerView. class HorizontalSeparator; @@ -132,6 +153,9 @@ // selected search result view. void NotifySelectedResultChanged(); + // Called when the widget anchored in the search results page gets closed. + void OnAnchoredDialogClosed(); + AppListViewDelegate* view_delegate_; // The search model for which the results are displayed. @@ -168,6 +192,9 @@ std::unique_ptr<ViewShadow> view_shadow_; + // The dialog anchored within the search results page. + std::unique_ptr<SearchResultPageAnchoredDialog> anchored_dialog_; + ScopedObserver<SearchBoxModel, SearchBoxModelObserver> search_box_observer_{ this};
diff --git a/ash/app_list/views/search_result_view.cc b/ash/app_list/views/search_result_view.cc index cedcca5..42c02c26 100644 --- a/ash/app_list/views/search_result_view.cc +++ b/ash/app_list/views/search_result_view.cc
@@ -11,10 +11,12 @@ #include "ash/app_list/app_list_view_delegate.h" #include "ash/app_list/model/search/search_result.h" #include "ash/app_list/views/app_list_main_view.h" +#include "ash/app_list/views/contents_view.h" #include "ash/app_list/views/remove_query_confirmation_dialog.h" #include "ash/app_list/views/search_box_view.h" #include "ash/app_list/views/search_result_actions_view.h" #include "ash/app_list/views/search_result_list_view.h" +#include "ash/app_list/views/search_result_page_view.h" #include "ash/public/cpp/app_list/app_list_config.h" #include "ash/public/cpp/app_list/app_list_switches.h" #include "ash/public/cpp/app_list/app_list_types.h" @@ -155,7 +157,7 @@ details_text_ = std::move(render_text); } -void SearchResultView::OnQueryRemovalAccepted(bool accepted, int event_flags) { +void SearchResultView::OnQueryRemovalAccepted(int event_flags, bool accepted) { if (accepted) { list_view_->SearchResultActionActivated( this, OmniBoxZeroStateAction::kRemoveSuggestion, event_flags); @@ -411,13 +413,14 @@ if (button_action == OmniBoxZeroStateAction::kRemoveSuggestion) { RecordZeroStateSearchResultUserActionHistogram( ZeroStateSearchResultUserActionType::kRemoveResult); - RemoveQueryConfirmationDialog* dialog = new RemoveQueryConfirmationDialog( + auto dialog = std::make_unique<RemoveQueryConfirmationDialog>( result()->title(), base::BindOnce(&SearchResultView::OnQueryRemovalAccepted, - weak_ptr_factory_.GetWeakPtr()), - event_flags, list_view_->app_list_main_view()->contents_view()); - - dialog->Show(GetWidget()->GetNativeWindow()); + weak_ptr_factory_.GetWeakPtr(), event_flags)); + list_view_->app_list_main_view() + ->contents_view() + ->search_results_page_view() + ->ShowAnchoredDialog(std::move(dialog)); } else if (button_action == OmniBoxZeroStateAction::kAppendSuggestion) { RecordZeroStateSearchResultUserActionHistogram( ZeroStateSearchResultUserActionType::kAppendResult);
diff --git a/ash/app_list/views/search_result_view.h b/ash/app_list/views/search_result_view.h index 941348ae..e90a7a3 100644 --- a/ash/app_list/views/search_result_view.h +++ b/ash/app_list/views/search_result_view.h
@@ -67,7 +67,7 @@ void CreateDetailsRenderText(); // Callback for query suggstion removal confirmation. - void OnQueryRemovalAccepted(bool accepted, int event_flags); + void OnQueryRemovalAccepted(int event_flags, bool accepted); // views::View overrides: const char* GetClassName() const override;
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index a8bd315..84e16ce9 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -497,6 +497,19 @@ Floating accessibility menu </message> + <message name="IDS_ASH_FLOATING_ACCESSIBILITY_MAIN_MENU_MOVED_TOP_LEFT" desc="Accessibility event message that is triggered when the menu is moved to the top-left corner."> + Menu moved to the top-left corner of the screen. + </message> + <message name="IDS_ASH_FLOATING_ACCESSIBILITY_MAIN_MENU_MOVED_TOP_RIGHT" desc="Accessibility event message that is triggered when the menu is moved to the top-right corner."> + Menu moved to the top-right corner of the screen. + </message> + <message name="IDS_ASH_FLOATING_ACCESSIBILITY_MAIN_MENU_MOVED_BOTTOM_LEFT" desc="Accessibility event message that is triggered when the menu is moved to the bottom-left corner."> + Menu moved to the bottom-left corner of the screen. + </message> + <message name="IDS_ASH_FLOATING_ACCESSIBILITY_MAIN_MENU_MOVED_BOTTOM_RIGHT" desc="Accessibility event message that is triggered when the menu is moved to the bottom-right corner."> + Menu moved to the bottom-right corner of the screen. + </message> + <message name="IDS_ASH_STATUS_TRAY_MIC_GAIN" desc="The accessible text for the toggle mic muted button in the tray audio settings"> Toggle Mic. <ph name="STATE_TEXT">$1<ex>Mic is muted</ex></ph> </message> @@ -1947,6 +1960,9 @@ <message name="IDS_ASH_PIN_KEYBOARD_DELETE_ACCESSIBLE_NAME" desc="Text to be spoken when the focus is set to the delete button of the PIN keyboard."> Delete </message> + <message name="IDS_ASH_LOGIN_POD_MANAGED_ACCESSIBLE_NAME" desc="Text to be spoken when the focus is set to the user pod when the user is managed."> + <ph name="USER_EMAIL_ADDRESS">$1<ex>john.doe@example.com</ex></ph> Managed user + </message> <message name="IDS_ASH_LOGIN_POD_OWNER_USER" desc="Login/lock screen user pod menu title for a user who owns the device."> <ph name="USER_NAME">$1<ex>Ivan Arbuzov</ex></ph> (owner) </message>
diff --git a/ash/ash_strings_grd/IDS_ASH_LOGIN_POD_MANAGED_ACCESSIBLE_NAME.png.sha1 b/ash/ash_strings_grd/IDS_ASH_LOGIN_POD_MANAGED_ACCESSIBLE_NAME.png.sha1 new file mode 100644 index 0000000..f458d5c --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_LOGIN_POD_MANAGED_ACCESSIBLE_NAME.png.sha1
@@ -0,0 +1 @@ +642ee52e8185c2cf1523a63755ca31ac3de19c61 \ No newline at end of file
diff --git a/ash/assistant/assistant_alarm_timer_controller.cc b/ash/assistant/assistant_alarm_timer_controller.cc index a1717a6..585f292 100644 --- a/ash/assistant/assistant_alarm_timer_controller.cc +++ b/ash/assistant/assistant_alarm_timer_controller.cc
@@ -118,8 +118,8 @@ const std::string message = CreateTimerNotificationMessage(timer); base::Optional<GURL> stop_alarm_timer_action_url = - assistant::util::CreateAlarmTimerDeepLink(AlarmTimerAction::kRemove, - timer.id); + assistant::util::CreateAlarmTimerDeepLink( + AlarmTimerAction::kRemoveAlarmOrTimer, timer.id); base::Optional<GURL> add_time_to_timer_action_url = assistant::util::CreateAlarmTimerDeepLink( @@ -323,8 +323,17 @@ } assistant_->AddTimeToTimer(alarm_timer_id, duration.value()); break; - case AlarmTimerAction::kRemove: - assistant_->RemoveAlarmTimer(alarm_timer_id); + case AlarmTimerAction::kPauseTimer: + DCHECK(!duration.has_value()); + assistant_->PauseTimer(alarm_timer_id); + break; + case AlarmTimerAction::kRemoveAlarmOrTimer: + DCHECK(!duration.has_value()); + assistant_->RemoveAlarmOrTimer(alarm_timer_id); + break; + case AlarmTimerAction::kResumeTimer: + DCHECK(!duration.has_value()); + assistant_->ResumeTimer(alarm_timer_id); break; } }
diff --git a/ash/assistant/assistant_interaction_controller_impl.cc b/ash/assistant/assistant_interaction_controller_impl.cc index 14b3cca7..9afa6bac 100644 --- a/ash/assistant/assistant_interaction_controller_impl.cc +++ b/ash/assistant/assistant_interaction_controller_impl.cc
@@ -46,6 +46,7 @@ using assistant::ui::kWarmerWelcomesMaxTimesTriggered; using chromeos::assistant::features::IsResponseProcessingV2Enabled; using chromeos::assistant::features::IsTimersV2Enabled; +using chromeos::assistant::features::IsWaitSchedulingEnabled; // Android. constexpr char kAndroidIntentScheme[] = "intent://"; @@ -715,15 +716,12 @@ } void AssistantInteractionControllerImpl::OnWaitStarted() { + DCHECK(IsWaitSchedulingEnabled()); if (!HasActiveInteraction()) return; - // Commit the pending query in whatever state it's in. Note that the server - // guarantees that if a wait occurs, it is as part of a routine's execution - // and it will be the last event prior to the current interaction being - // finished and the response will not contain any TTS. Upon finishing - // execution of the current interaction, a new interaction will automatically - // be started for the next leg of the routine's execution. + // If necessary, commit the pending query in whatever state it's in. This is + // prerequisite to being able to commit a response. if (model_.pending_query().type() != AssistantQueryType::kNull) model_.CommitPendingQuery(); @@ -737,8 +735,7 @@ } // Commit the pending response so that the UI is flushed to the screen while - // the wait occurs, giving the user time to digest the current response before - // the routine begins its next leg in the next interaction. + // the wait occurs, giving the user time to digest the current response. OnProcessPendingResponse(); }
diff --git a/ash/assistant/model/ui/assistant_card_element.cc b/ash/assistant/model/ui/assistant_card_element.cc index 71bc5a9..95739b2a 100644 --- a/ash/assistant/model/ui/assistant_card_element.cc +++ b/ash/assistant/model/ui/assistant_card_element.cc
@@ -42,10 +42,9 @@ contents_params.max_size = gfx::Size(width_dip, INT_MAX); contents_params.suppress_navigation = true; - // Create |contents_view_| and retain ownership so that is properly cleaned - // up in the case where it is never added to the view hierarchy. + // Create |contents_view_| and retain ownership until it is added to the + // view hierarchy. If that never happens, it will be still be cleaned up. contents_view_ = AssistantWebViewFactory::Get()->Create(contents_params); - contents_view_->set_owned_by_client(); // Observe |contents_view_| so that we are notified when loading is // complete.
diff --git a/ash/assistant/model/ui/assistant_card_element.h b/ash/assistant/model/ui/assistant_card_element.h index dc52c26..e9b0c94 100644 --- a/ash/assistant/model/ui/assistant_card_element.h +++ b/ash/assistant/model/ui/assistant_card_element.h
@@ -28,7 +28,9 @@ const std::string& html() const { return html_; } const std::string& fallback() const { return fallback_; } - const AssistantWebView* contents_view() const { return contents_view_.get(); } + std::unique_ptr<AssistantWebView> MoveContentsView() { + return std::move(contents_view_); + } void set_contents_view(std::unique_ptr<AssistantWebView> contents_view) { contents_view_ = std::move(contents_view);
diff --git a/ash/assistant/test/test_assistant_service.cc b/ash/assistant/test/test_assistant_service.cc index 1258869..2d34a36 100644 --- a/ash/assistant/test/test_assistant_service.cc +++ b/ash/assistant/test/test_assistant_service.cc
@@ -278,7 +278,11 @@ base::TimeDelta duration) { } -void TestAssistantService::RemoveAlarmTimer(const std::string& id) {} +void TestAssistantService::PauseTimer(const std::string& id) {} + +void TestAssistantService::RemoveAlarmOrTimer(const std::string& id) {} + +void TestAssistantService::ResumeTimer(const std::string& id) {} void TestAssistantService::StartInteraction( chromeos::assistant::mojom::AssistantInteractionType type,
diff --git a/ash/assistant/test/test_assistant_service.h b/ash/assistant/test/test_assistant_service.h index d21d8f3..5d5e409 100644 --- a/ash/assistant/test/test_assistant_service.h +++ b/ash/assistant/test/test_assistant_service.h
@@ -112,7 +112,9 @@ void NotifyEntryIntoAssistantUi( chromeos::assistant::mojom::AssistantEntryPoint entry_point) override; void AddTimeToTimer(const std::string& id, base::TimeDelta duration) override; - void RemoveAlarmTimer(const std::string& id) override; + void PauseTimer(const std::string& id) override; + void RemoveAlarmOrTimer(const std::string& id) override; + void ResumeTimer(const std::string& id) override; private: void StartInteraction(
diff --git a/ash/assistant/ui/main_stage/assistant_card_element_view.cc b/ash/assistant/ui/main_stage/assistant_card_element_view.cc index f18031c5..492927f 100644 --- a/ash/assistant/ui/main_stage/assistant_card_element_view.cc +++ b/ash/assistant/ui/main_stage/assistant_card_element_view.cc
@@ -60,15 +60,15 @@ AssistantViewDelegate* delegate, const AssistantCardElement* card_element) : delegate_(delegate), card_element_(card_element) { - InitLayout(card_element); + InitLayout(); // We observe contents_view() to receive events pertaining to the underlying // WebContents including focus change and suppressed navigation events. - contents_view()->AddObserver(this); + contents_view_->AddObserver(this); } AssistantCardElementView::~AssistantCardElementView() { - contents_view()->RemoveObserver(this); + contents_view_->RemoveObserver(this); } const char* AssistantCardElementView::GetClassName() const { @@ -203,19 +203,15 @@ views::View::ScrollRectToVisible(focused_node_rect_); } -void AssistantCardElementView::InitLayout( - const AssistantCardElement* card_element) { +void AssistantCardElementView::InitLayout() { SetLayoutManager(std::make_unique<views::FillLayout>()); // Contents view. - AddChildView(contents_view()); + contents_view_ = AddChildView( + const_cast<AssistantCardElement*>(card_element_)->MoveContentsView()); // OverrideDescription() doesn't work. Only names are read automatically. - GetViewAccessibility().OverrideName(card_element->fallback()); -} - -AssistantWebView* AssistantCardElementView::contents_view() { - return const_cast<AssistantWebView*>(card_element_->contents_view()); + GetViewAccessibility().OverrideName(card_element_->fallback()); } } // namespace ash
diff --git a/ash/assistant/ui/main_stage/assistant_card_element_view.h b/ash/assistant/ui/main_stage/assistant_card_element_view.h index ab689ec..4d2d61a 100644 --- a/ash/assistant/ui/main_stage/assistant_card_element_view.h +++ b/ash/assistant/ui/main_stage/assistant_card_element_view.h
@@ -46,17 +46,17 @@ // contents. When animating AssistantCardElementView, we should animate the // layer for the native view as opposed to painting to and animating a layer // belonging to AssistantCardElementView. - gfx::NativeView native_view() { return contents_view()->GetNativeView(); } + gfx::NativeView native_view() { return contents_view_->GetNativeView(); } private: - void InitLayout(const AssistantCardElement* card_element); + void InitLayout(); - AssistantWebView* contents_view(); + AssistantWebView* contents_view_ = nullptr; AssistantViewDelegate* const delegate_; const AssistantCardElement* const card_element_; - // Rect of the focused node in the |contents_view()|. + // Rect of the focused node in the |contents_view_|. gfx::Rect focused_node_rect_; DISALLOW_COPY_AND_ASSIGN(AssistantCardElementView);
diff --git a/ash/assistant/util/deep_link_util.cc b/ash/assistant/util/deep_link_util.cc index d124c77..bdb45a0 100644 --- a/ash/assistant/util/deep_link_util.cc +++ b/ash/assistant/util/deep_link_util.cc
@@ -46,7 +46,9 @@ // Supported alarm/timer action deep link param values. constexpr char kAddTimeToTimer[] = "addTimeToTimer"; -constexpr char kRemoveAlarmTimer[] = "removeAlarmTimer"; +constexpr char kPauseTimer[] = "pauseTimer"; +constexpr char kRemoveAlarmOrTimer[] = "removeAlarmOrTimer"; +constexpr char kResumeTimer[] = "resumeTimer"; // Supported proactive suggestions action deep link param values. constexpr char kCardClick[] = "cardClick"; @@ -79,6 +81,21 @@ // Helpers --------------------------------------------------------------------- +std::string GetAlarmTimerActionParamValue(AlarmTimerAction action) { + switch (action) { + case AlarmTimerAction::kAddTimeToTimer: + return kAddTimeToTimer; + case AlarmTimerAction::kPauseTimer: + return kPauseTimer; + case AlarmTimerAction::kRemoveAlarmOrTimer: + return kRemoveAlarmOrTimer; + case AlarmTimerAction::kResumeTimer: + return kResumeTimer; + } + NOTREACHED(); + return std::string(); +} + std::string GetDeepLinkParamKey(DeepLinkParam param) { switch (param) { case DeepLinkParam::kAction: @@ -146,25 +163,25 @@ AlarmTimerAction action, base::Optional<std::string> alarm_timer_id, base::Optional<base::TimeDelta> duration) { - GURL url = GURL(kAssistantAlarmTimerPrefix); - switch (action) { case assistant::util::AlarmTimerAction::kAddTimeToTimer: DCHECK(alarm_timer_id.has_value() && duration.has_value()); if (!alarm_timer_id.has_value() || !duration.has_value()) return base::nullopt; - url = net::AppendOrReplaceQueryParameter(url, kActionParamKey, - kAddTimeToTimer); break; - case assistant::util::AlarmTimerAction::kRemove: + case assistant::util::AlarmTimerAction::kPauseTimer: + case assistant::util::AlarmTimerAction::kRemoveAlarmOrTimer: + case assistant::util::AlarmTimerAction::kResumeTimer: DCHECK(alarm_timer_id.has_value() && !duration.has_value()); if (!alarm_timer_id.has_value() || duration.has_value()) return base::nullopt; - url = net::AppendOrReplaceQueryParameter(url, kActionParamKey, - kRemoveAlarmTimer); break; } + GURL url = net::AppendOrReplaceQueryParameter( + GURL(kAssistantAlarmTimerPrefix), kActionParamKey, + GetAlarmTimerActionParamValue(action)); + if (alarm_timer_id.has_value()) { url = net::AppendOrReplaceQueryParameter(url, kIdParamKey, alarm_timer_id.value()); @@ -236,8 +253,14 @@ if (action_string_value.value() == kAddTimeToTimer) return AlarmTimerAction::kAddTimeToTimer; - if (action_string_value.value() == kRemoveAlarmTimer) - return AlarmTimerAction::kRemove; + if (action_string_value.value() == kPauseTimer) + return AlarmTimerAction::kPauseTimer; + + if (action_string_value.value() == kRemoveAlarmOrTimer) + return AlarmTimerAction::kRemoveAlarmOrTimer; + + if (action_string_value.value() == kResumeTimer) + return AlarmTimerAction::kResumeTimer; return base::nullopt; }
diff --git a/ash/assistant/util/deep_link_util.h b/ash/assistant/util/deep_link_util.h index 6daf4aa..9097e638 100644 --- a/ash/assistant/util/deep_link_util.h +++ b/ash/assistant/util/deep_link_util.h
@@ -69,7 +69,9 @@ // Enumeration of alarm/timer deep link actions. enum class AlarmTimerAction { kAddTimeToTimer, - kRemove, + kPauseTimer, + kRemoveAlarmOrTimer, + kResumeTimer, }; // Enumeration of proactive suggestions deep link actions.
diff --git a/ash/assistant/util/deep_link_util_unittest.cc b/ash/assistant/util/deep_link_util_unittest.cc index 2329ab19..35ed3de 100644 --- a/ash/assistant/util/deep_link_util_unittest.cc +++ b/ash/assistant/util/deep_link_util_unittest.cc
@@ -73,10 +73,18 @@ CreateAlarmTimerDeepLink(AlarmTimerAction::kAddTimeToTimer, "1", base::TimeDelta::FromMinutes(1)) .value()); - ASSERT_EQ( - "googleassistant://alarm-timer?action=removeAlarmTimer&id=1", - CreateAlarmTimerDeepLink(AlarmTimerAction::kRemove, "1", base::nullopt) - .value()); + ASSERT_EQ("googleassistant://alarm-timer?action=pauseTimer&id=1", + CreateAlarmTimerDeepLink(AlarmTimerAction::kPauseTimer, "1", + base::nullopt) + .value()); + ASSERT_EQ("googleassistant://alarm-timer?action=removeAlarmOrTimer&id=1", + CreateAlarmTimerDeepLink(AlarmTimerAction::kRemoveAlarmOrTimer, "1", + base::nullopt) + .value()); + ASSERT_EQ("googleassistant://alarm-timer?action=resumeTimer&id=1", + CreateAlarmTimerDeepLink(AlarmTimerAction::kResumeTimer, "1", + base::nullopt) + .value()); // For invalid deeplink params, we will hit DCHECK since this API isn't meant // to be used in such cases. We'll use a |ScopedLogAssertHandler| to safely @@ -86,16 +94,6 @@ const base::StringPiece stack_trace) {})); ASSERT_EQ(base::nullopt, - CreateAlarmTimerDeepLink(AlarmTimerAction::kRemove, base::nullopt, - base::nullopt)); - ASSERT_EQ(base::nullopt, - CreateAlarmTimerDeepLink(AlarmTimerAction::kRemove, base::nullopt, - base::TimeDelta::FromMinutes(1))); - ASSERT_EQ(base::nullopt, - CreateAlarmTimerDeepLink(AlarmTimerAction::kRemove, "1", - base::TimeDelta::FromMinutes(1))); - - ASSERT_EQ(base::nullopt, CreateAlarmTimerDeepLink(AlarmTimerAction::kAddTimeToTimer, "1", base::nullopt)); ASSERT_EQ(base::nullopt, CreateAlarmTimerDeepLink( @@ -104,6 +102,36 @@ ASSERT_EQ(base::nullopt, CreateAlarmTimerDeepLink(AlarmTimerAction::kAddTimeToTimer, base::nullopt, base::nullopt)); + + ASSERT_EQ(base::nullopt, + CreateAlarmTimerDeepLink(AlarmTimerAction::kPauseTimer, + base::nullopt, base::nullopt)); + ASSERT_EQ(base::nullopt, CreateAlarmTimerDeepLink( + AlarmTimerAction::kPauseTimer, base::nullopt, + base::TimeDelta::FromMinutes(1))); + ASSERT_EQ(base::nullopt, + CreateAlarmTimerDeepLink(AlarmTimerAction::kPauseTimer, "1", + base::TimeDelta::FromMinutes(1))); + + ASSERT_EQ(base::nullopt, + CreateAlarmTimerDeepLink(AlarmTimerAction::kRemoveAlarmOrTimer, + base::nullopt, base::nullopt)); + ASSERT_EQ(base::nullopt, CreateAlarmTimerDeepLink( + AlarmTimerAction::kRemoveAlarmOrTimer, + base::nullopt, base::TimeDelta::FromMinutes(1))); + ASSERT_EQ(base::nullopt, + CreateAlarmTimerDeepLink(AlarmTimerAction::kRemoveAlarmOrTimer, "1", + base::TimeDelta::FromMinutes(1))); + + ASSERT_EQ(base::nullopt, + CreateAlarmTimerDeepLink(AlarmTimerAction::kResumeTimer, + base::nullopt, base::nullopt)); + ASSERT_EQ(base::nullopt, CreateAlarmTimerDeepLink( + AlarmTimerAction::kResumeTimer, base::nullopt, + base::TimeDelta::FromMinutes(1))); + ASSERT_EQ(base::nullopt, + CreateAlarmTimerDeepLink(AlarmTimerAction::kResumeTimer, "1", + base::TimeDelta::FromMinutes(1))); } TEST_F(DeepLinkUtilTest, CreateAssistantQueryDeepLink) { @@ -228,8 +256,12 @@ // Case: Deep link parameter present, well formed. params["action"] = "addTimeToTimer"; AssertDeepLinkParamEq(AlarmTimerAction::kAddTimeToTimer); - params["action"] = "removeAlarmTimer"; - AssertDeepLinkParamEq(AlarmTimerAction::kRemove); + params["action"] = "pauseTimer"; + AssertDeepLinkParamEq(AlarmTimerAction::kPauseTimer); + params["action"] = "removeAlarmOrTimer"; + AssertDeepLinkParamEq(AlarmTimerAction::kRemoveAlarmOrTimer); + params["action"] = "resumeTimer"; + AssertDeepLinkParamEq(AlarmTimerAction::kResumeTimer); // Case: Deep link parameter present, non AlarmTimerAction value. params["action"] = "true";
diff --git a/ash/drag_drop/drag_drop_controller.cc b/ash/drag_drop/drag_drop_controller.cc index ef17cecb..5b8a762 100644 --- a/ash/drag_drop/drag_drop_controller.cc +++ b/ash/drag_drop/drag_drop_controller.cc
@@ -215,6 +215,7 @@ DCHECK(!tab_drag_drop_delegate_); tab_drag_drop_delegate_.emplace(root_window, drag_source_window_, start_location_); + drag_image_->SetTouchDragOperationHintOff(); } if (should_block_during_drag_drop_) { @@ -475,8 +476,6 @@ else if (op & ui::DragDropTypes::DRAG_MOVE) cursor = ui::mojom::CursorType::kGrabbing; - // TODO(https://crbug.com/1069869): don't show kNoDrop cursor for - // a tab drag that can drop into a new window. Shell::Get()->cursor_manager()->SetCursor(cursor); } }
diff --git a/ash/drag_drop/tab_drag_drop_delegate.cc b/ash/drag_drop/tab_drag_drop_delegate.cc index c24060d..af1aa55 100644 --- a/ash/drag_drop/tab_drag_drop_delegate.cc +++ b/ash/drag_drop/tab_drag_drop_delegate.cc
@@ -41,30 +41,7 @@ if (!features::IsWebUITabStripTabDragIntegrationEnabled()) return false; - base::Pickle pickle; - drag_data.GetPickledData(ui::ClipboardFormatType::GetWebCustomDataType(), - &pickle); - base::PickleIterator iter(pickle); - - uint32_t entry_count = 0; - if (!iter.ReadUInt32(&entry_count)) - return false; - - for (uint32_t i = 0; i < entry_count; ++i) { - base::StringPiece16 type; - base::StringPiece16 data; - if (!iter.ReadStringPiece16(&type) || !iter.ReadStringPiece16(&data)) - return false; - - // TODO(https://crbug.com/1069869): share this constant between Ash - // and Chrome instead of hardcoding it in both places. - static const base::NoDestructor<base::string16> chrome_tab_type( - base::ASCIIToUTF16("application/vnd.chromium.tab")); - if (type == *chrome_tab_type) - return true; - } - - return false; + return Shell::Get()->shell_delegate()->IsTabDrag(drag_data); } TabDragDropDelegate::TabDragDropDelegate(
diff --git a/ash/drag_drop/tab_drag_drop_delegate_unittest.cc b/ash/drag_drop/tab_drag_drop_delegate_unittest.cc index e96107d..a121ff03 100644 --- a/ash/drag_drop/tab_drag_drop_delegate_unittest.cc +++ b/ash/drag_drop/tab_drag_drop_delegate_unittest.cc
@@ -5,6 +5,7 @@ #include "ash/drag_drop/tab_drag_drop_delegate.h" #include <memory> +#include <utility> #include <vector> #include "ash/public/cpp/ash_features.h" @@ -29,40 +30,26 @@ #include "ui/gfx/geometry/vector2d.h" using ::testing::_; +using ::testing::NiceMock; using ::testing::Return; namespace ash { namespace { -std::unique_ptr<ui::OSExchangeData> MakeDragData(const std::string& mime_type, - const std::string& data) { - auto result = std::make_unique<ui::OSExchangeData>(); - - base::flat_map<base::string16, base::string16> data_map; - data_map.emplace(base::ASCIIToUTF16(mime_type), base::ASCIIToUTF16(data)); - - base::Pickle inner_data; - ui::WriteCustomDataToPickle(data_map, &inner_data); - - result->SetPickledData(ui::ClipboardFormatType::GetWebCustomDataType(), - inner_data); - return result; -} - class MockShellDelegate : public TestShellDelegate { public: MockShellDelegate() = default; ~MockShellDelegate() override = default; + MOCK_METHOD(bool, IsTabDrag, (const ui::OSExchangeData&), (override)); + MOCK_METHOD(aura::Window*, CreateBrowserForTabDrop, (aura::Window*, const ui::OSExchangeData&), (override)); }; -static constexpr char kTabMimeType[] = "application/vnd.chromium.tab"; - } // namespace class TabDragDropDelegateTest : public AshTestBase { @@ -75,7 +62,7 @@ // AshTestBase: void SetUp() override { - auto mock_shell_delegate = std::make_unique<MockShellDelegate>(); + auto mock_shell_delegate = std::make_unique<NiceMock<MockShellDelegate>>(); mock_shell_delegate_ = mock_shell_delegate.get(); AshTestBase::SetUp(std::move(mock_shell_delegate)); ash::TabletModeControllerTestApi().EnterTabletMode(); @@ -91,17 +78,15 @@ private: base::test::ScopedFeatureList scoped_feature_list_; - MockShellDelegate* mock_shell_delegate_ = nullptr; + NiceMock<MockShellDelegate>* mock_shell_delegate_ = nullptr; }; -TEST_F(TabDragDropDelegateTest, AcceptsValidDrags) { - EXPECT_TRUE( - TabDragDropDelegate::IsChromeTabDrag(*MakeDragData(kTabMimeType, "foo"))); -} +TEST_F(TabDragDropDelegateTest, ForwardsDragCheckToShellDelegate) { + ON_CALL(*mock_shell_delegate(), IsTabDrag(_)).WillByDefault(Return(false)); + EXPECT_FALSE(TabDragDropDelegate::IsChromeTabDrag(ui::OSExchangeData())); -TEST_F(TabDragDropDelegateTest, RejectsInvalidDrags) { - EXPECT_FALSE( - TabDragDropDelegate::IsChromeTabDrag(*MakeDragData("text/plain", "bar"))); + ON_CALL(*mock_shell_delegate(), IsTabDrag(_)).WillByDefault(Return(true)); + EXPECT_TRUE(TabDragDropDelegate::IsChromeTabDrag(ui::OSExchangeData())); } TEST_F(TabDragDropDelegateTest, DragToExistingTabStrip) { @@ -146,8 +131,8 @@ .Times(1) .WillOnce(Return(new_window.get())); - auto drop_data = MakeDragData(kTabMimeType, "fake_id"); - delegate.Drop(drag_start_location + gfx::Vector2d(2, 0), *drop_data); + delegate.Drop(drag_start_location + gfx::Vector2d(2, 0), + ui::OSExchangeData()); EXPECT_FALSE( SplitViewController::Get(source_window.get())->InTabletSplitViewMode()); @@ -176,8 +161,7 @@ .Times(1) .WillOnce(Return(new_window.get())); - auto drop_data = MakeDragData(kTabMimeType, "fake_id"); - delegate.Drop(drag_end_location, *drop_data); + delegate.Drop(drag_end_location, ui::OSExchangeData()); SplitViewController* const split_view_controller = SplitViewController::Get(source_window.get());
diff --git a/ash/home_screen/home_screen_controller.cc b/ash/home_screen/home_screen_controller.cc index 5eec280a..fb454a8 100644 --- a/ash/home_screen/home_screen_controller.cc +++ b/ash/home_screen/home_screen_controller.cc
@@ -341,10 +341,13 @@ IsHomeScreenVisible() && (overview_enter_type == OverviewEnterExitType::kSlideInEnter || overview_enter_type == OverviewEnterExitType::kFadeInEnter); + const bool use_scale_transition = + overview_enter_type == OverviewEnterExitType::kFadeInEnter || + (features::IsDragFromShelfToHomeOrOverviewEnabled() && + overview_enter_type != OverviewEnterExitType::kSlideInEnter); const HomeScreenPresenter::TransitionType transition = - overview_enter_type == OverviewEnterExitType::kFadeInEnter - ? HomeScreenPresenter::TransitionType::kScaleHomeOut - : HomeScreenPresenter::TransitionType::kSlideHomeOut; + use_scale_transition ? HomeScreenPresenter::TransitionType::kScaleHomeOut + : HomeScreenPresenter::TransitionType::kSlideHomeOut; home_screen_presenter_.ScheduleOverviewModeAnimation(transition, animate); } @@ -385,10 +388,13 @@ const bool animate = *overview_exit_type_ == OverviewEnterExitType::kSlideOutExit || *overview_exit_type_ == OverviewEnterExitType::kFadeOutExit; + const bool use_scale_transition = + *overview_exit_type_ == OverviewEnterExitType::kFadeOutExit || + (features::IsDragFromShelfToHomeOrOverviewEnabled() && + *overview_exit_type_ != OverviewEnterExitType::kSlideOutExit); const HomeScreenPresenter::TransitionType transition = - *overview_exit_type_ == OverviewEnterExitType::kFadeOutExit - ? HomeScreenPresenter::TransitionType::kScaleHomeIn - : HomeScreenPresenter::TransitionType::kSlideHomeIn; + use_scale_transition ? HomeScreenPresenter::TransitionType::kScaleHomeIn + : HomeScreenPresenter::TransitionType::kSlideHomeIn; overview_exit_type_ = base::nullopt; home_screen_presenter_.ScheduleOverviewModeAnimation(transition, animate);
diff --git a/ash/login/login_screen_test_api.cc b/ash/login/login_screen_test_api.cc index a9d329c..a9fa59aa 100644 --- a/ash/login/login_screen_test_api.cc +++ b/ash/login/login_screen_test_api.cc
@@ -14,6 +14,8 @@ #include "ash/login/ui/login_big_user_view.h" #include "ash/login/ui/login_expanded_public_account_view.h" #include "ash/login/ui/login_password_view.h" +#include "ash/login/ui/login_user_menu_view.h" +#include "ash/login/ui/login_user_view.h" #include "ash/shelf/login_shelf_view.h" #include "ash/shelf/shelf.h" #include "ash/shelf/shelf_widget.h" @@ -229,6 +231,38 @@ } // static +bool LoginScreenTestApi::IsManagedIconShown(const AccountId& account_id) { + LockScreen::TestApi lock_screen_test(LockScreen::Get()); + LockContentsView::TestApi lock_contents_test( + lock_screen_test.contents_view()); + LoginBigUserView* big_user_view = lock_contents_test.FindBigUser(account_id); + if (!big_user_view) { + ADD_FAILURE() << "Could not find user " << account_id.Serialize(); + return false; + } + LoginUserView::TestApi user_test(big_user_view->GetUserView()); + auto* enterprise_icon = user_test.enterprise_icon(); + return enterprise_icon->GetVisible(); +} + +// static +bool LoginScreenTestApi::IsManagedMessageInMenuShown( + const AccountId& account_id) { + LockScreen::TestApi lock_screen_test(LockScreen::Get()); + LockContentsView::TestApi lock_contents_test( + lock_screen_test.contents_view()); + LoginBigUserView* big_user_view = lock_contents_test.FindBigUser(account_id); + if (!big_user_view) { + ADD_FAILURE() << "Could not find user " << account_id.Serialize(); + return false; + } + LoginUserView::TestApi user_test(big_user_view->GetUserView()); + LoginUserMenuView::TestApi user_menu_test(user_test.menu()); + auto* managed_user_data = user_menu_test.managed_user_data(); + return managed_user_data && managed_user_data->GetVisible(); +} + +// static bool LoginScreenTestApi::IsForcedOnlineSignin(const AccountId& account_id) { LockScreen::TestApi lock_screen_test(LockScreen::Get()); LockContentsView::TestApi lock_contents_test(
diff --git a/ash/login/ui/access_code_input.cc b/ash/login/ui/access_code_input.cc new file mode 100644 index 0000000..bc794dc --- /dev/null +++ b/ash/login/ui/access_code_input.cc
@@ -0,0 +1,417 @@ +// 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/login/ui/access_code_input.h" + +#include "ash/public/cpp/login_constants.h" +#include "ash/strings/grit/ash_strings.h" +#include "base/strings/strcat.h" +#include "ui/accessibility/ax_enums.mojom.h" +#include "ui/accessibility/ax_node_data.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/events/keycodes/dom/dom_code.h" +#include "ui/views/layout/box_layout.h" +#include "ui/views/layout/fill_layout.h" + +namespace ash { + +namespace { +// Identifier for focus traversal. +constexpr int kFixedLengthInputGroup = 1; + +constexpr int kAccessCodeFlexLengthWidthDp = 192; +constexpr int kAccessCodeFlexUnderlineThicknessDp = 1; +constexpr int kAccessCodeFontSizeDeltaDp = 4; +constexpr int kObscuredGlyphSpacingDp = 6; + +constexpr int kAccessCodeInputFieldWidthDp = 24; +constexpr int kAccessCodeBetweenInputFieldsGapDp = 8; + +constexpr SkColor kTextColor = SK_ColorWHITE; +} // namespace + +FlexCodeInput::FlexCodeInput(OnInputChange on_input_change, + OnEnter on_enter, + OnEscape on_escape, + bool obscure_pin) + : on_input_change_(std::move(on_input_change)), + on_enter_(std::move(on_enter)), + on_escape_(std::move(on_escape)) { + DCHECK(on_input_change_); + DCHECK(on_enter_); + DCHECK(on_escape_); + + SetLayoutManager(std::make_unique<views::FillLayout>()); + + code_field_ = AddChildView(std::make_unique<views::Textfield>()); + code_field_->set_controller(this); + code_field_->SetTextColor(login_constants::kAuthMethodsTextColor); + code_field_->SetFontList(views::Textfield::GetDefaultFontList().Derive( + kAccessCodeFontSizeDeltaDp, gfx::Font::FontStyle::NORMAL, + gfx::Font::Weight::NORMAL)); + code_field_->SetBorder(views::CreateSolidSidedBorder( + 0, 0, kAccessCodeFlexUnderlineThicknessDp, 0, kTextColor)); + code_field_->SetBackgroundColor(SK_ColorTRANSPARENT); + code_field_->SetFocusBehavior(FocusBehavior::ALWAYS); + code_field_->SetPreferredSize( + gfx::Size(kAccessCodeFlexLengthWidthDp, kAccessCodeInputFieldHeightDp)); + + if (obscure_pin) { + code_field_->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD); + code_field_->SetObscuredGlyphSpacing(kObscuredGlyphSpacingDp); + } else { + code_field_->SetTextInputType(ui::TEXT_INPUT_TYPE_NUMBER); + } +} + +FlexCodeInput::~FlexCodeInput() = default; + +void FlexCodeInput::InsertDigit(int value) { + DCHECK_LE(0, value); + DCHECK_GE(9, value); + if (code_field_->GetEnabled()) { + code_field_->SetText(code_field_->GetText() + + base::NumberToString16(value)); + on_input_change_.Run(true); + } +} + +void FlexCodeInput::Backspace() { + // Instead of just adjusting code_field_ text directly, fire a backspace key + // event as this handles the various edge cases (ie, selected text). + + // views::Textfield::OnKeyPressed is private, so we call it via views::View. + auto* view = static_cast<views::View*>(code_field_); + view->OnKeyPressed(ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_BACK, + ui::DomCode::BACKSPACE, ui::EF_NONE)); + view->OnKeyPressed(ui::KeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_BACK, + ui::DomCode::BACKSPACE, ui::EF_NONE)); + // This triggers ContentsChanged(), which calls |on_input_change_|. +} + +base::Optional<std::string> FlexCodeInput::GetCode() const { + base::string16 code = code_field_->GetText(); + if (!code.length()) { + return base::nullopt; + } + return base::UTF16ToUTF8(code); +} + +void FlexCodeInput::SetInputColor(SkColor color) { + code_field_->SetTextColor(color); +} + +void FlexCodeInput::SetInputEnabled(bool input_enabled) { + code_field_->SetEnabled(input_enabled); +} + +void FlexCodeInput::ClearInput() { + code_field_->SetText(base::string16()); + on_input_change_.Run(false); +} + +void FlexCodeInput::RequestFocus() { + code_field_->RequestFocus(); +} + +void FlexCodeInput::ContentsChanged(views::Textfield* sender, + const base::string16& new_contents) { + const bool has_content = new_contents.length() > 0; + on_input_change_.Run(has_content); +} + +bool FlexCodeInput::HandleKeyEvent(views::Textfield* sender, + const ui::KeyEvent& key_event) { + // Only handle keys. + if (key_event.type() != ui::ET_KEY_PRESSED) + return false; + + // Default handling for events with Alt modifier like spoken feedback. + if (key_event.IsAltDown()) + return false; + + // FlexCodeInput class responds to a limited subset of key press events. + // All events not handled below are sent to |code_field_|. + const ui::KeyboardCode key_code = key_event.key_code(); + + // Allow using tab for keyboard navigation. + if (key_code == ui::VKEY_TAB || key_code == ui::VKEY_BACKTAB) + return false; + + if (key_code == ui::VKEY_RETURN) { + if (GetCode().has_value()) { + on_enter_.Run(); + } + return true; + } + + if (key_code == ui::VKEY_ESCAPE) { + on_escape_.Run(); + return true; + } + + // We only expect digits in the PIN, so we swallow all letters. + if (key_code >= ui::VKEY_A && key_code <= ui::VKEY_Z) + return true; + + return false; +} + +void AccessibleInputField::GetAccessibleNodeData(ui::AXNodeData* node_data) { + views::Textfield::GetAccessibleNodeData(node_data); + // The following property setup is needed to match the custom behavior of + // pin input. It results in the following a11y vocalizations: + // * when input field is empty: "Next number, {current field index} of + // {number of fields}" + // * when input field is populated: "{value}, {current field index} of + // {number of fields}" + node_data->RemoveState(ax::mojom::State::kEditable); + node_data->role = ax::mojom::Role::kListItem; + base::string16 description = + views::Textfield::GetText().empty() ? accessible_description_ : GetText(); + node_data->AddStringAttribute(ax::mojom::StringAttribute::kRoleDescription, + base::UTF16ToUTF8(description)); +} + +bool AccessibleInputField::IsGroupFocusTraversable() const { + return false; +} + +views::View* AccessibleInputField::GetSelectedViewForGroup(int group) { + return parent() ? parent()->GetSelectedViewForGroup(group) : nullptr; +} + +void AccessibleInputField::OnGestureEvent(ui::GestureEvent* event) { + if (event->type() == ui::ET_GESTURE_TAP_DOWN) { + RequestFocusWithPointer(event->details().primary_pointer_type()); + return; + } + + views::Textfield::OnGestureEvent(event); +} + +FixedLengthCodeInput::FixedLengthCodeInput(int length, + OnInputChange on_input_change, + OnEnter on_enter, + OnEscape on_escape, + bool obscure_pin) + : on_input_change_(std::move(on_input_change)), + on_enter_(std::move(on_enter)), + on_escape_(std::move(on_escape)) { + DCHECK_LT(0, length); + DCHECK(on_input_change_); + + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), + kAccessCodeBetweenInputFieldsGapDp)); + SetGroup(kFixedLengthInputGroup); + SetPaintToLayer(); + layer()->SetFillsBoundsOpaquely(false); + + for (int i = 0; i < length; ++i) { + auto* field = new AccessibleInputField(); + field->set_controller(this); + field->SetPreferredSize( + gfx::Size(kAccessCodeInputFieldWidthDp, kAccessCodeInputFieldHeightDp)); + field->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_CENTER); + field->SetBackgroundColor(SK_ColorTRANSPARENT); + if (obscure_pin) { + field->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD); + } else { + field->SetTextInputType(ui::TEXT_INPUT_TYPE_NUMBER); + } + field->SetTextColor(kTextColor); + field->SetFontList(views::Textfield::GetDefaultFontList().Derive( + kAccessCodeFontSizeDeltaDp, gfx::Font::FontStyle::NORMAL, + gfx::Font::Weight::NORMAL)); + field->SetBorder(views::CreateSolidSidedBorder( + 0, 0, kAccessCodeInputFieldUnderlineThicknessDp, 0, kTextColor)); + field->SetGroup(kFixedLengthInputGroup); + field->set_accessible_description(l10n_util::GetStringUTF16( + IDS_ASH_LOGIN_PIN_REQUEST_NEXT_NUMBER_PROMPT)); + input_fields_.push_back(field); + AddChildView(field); + } +} + +FixedLengthCodeInput::~FixedLengthCodeInput() = default; + +// Inserts |value| into the |active_field_| and moves focus to the next field +// if it exists. +void FixedLengthCodeInput::InsertDigit(int value) { + DCHECK_LE(0, value); + DCHECK_GE(9, value); + + ActiveField()->SetText(base::NumberToString16(value)); + bool was_last_field = IsLastFieldActive(); + + // Moving focus is delayed by using PostTask to allow for proper + // a11y announcements. Without that some of them are skipped. + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(&FixedLengthCodeInput::FocusNextField, + weak_ptr_factory_.GetWeakPtr())); + + on_input_change_.Run(was_last_field, GetCode().has_value()); +} + +// Clears input from the |active_field_|. If |active_field| is empty moves +// focus to the previous field (if exists) and clears input there. +void FixedLengthCodeInput::Backspace() { + if (ActiveInput().empty()) { + FocusPreviousField(); + } + + ActiveField()->SetText(base::string16()); + on_input_change_.Run(IsLastFieldActive(), false /*complete*/); +} + +// Returns access code as string if all fields contain input. +base::Optional<std::string> FixedLengthCodeInput::GetCode() const { + std::string result; + size_t length; + for (auto* field : input_fields_) { + length = field->GetText().length(); + if (!length) + return base::nullopt; + + DCHECK_EQ(1u, length); + base::StrAppend(&result, {base::UTF16ToUTF8(field->GetText())}); + } + return result; +} + +void FixedLengthCodeInput::SetInputColor(SkColor color) { + for (auto* field : input_fields_) { + field->SetTextColor(color); + } +} + +bool FixedLengthCodeInput::IsGroupFocusTraversable() const { + return false; +} + +views::View* FixedLengthCodeInput::GetSelectedViewForGroup(int group) { + return ActiveField(); +} + +void FixedLengthCodeInput::RequestFocus() { + ActiveField()->RequestFocus(); +} + +void FixedLengthCodeInput::GetAccessibleNodeData(ui::AXNodeData* node_data) { + views::View::GetAccessibleNodeData(node_data); + node_data->role = ax::mojom::Role::kGroup; +} + +bool FixedLengthCodeInput::HandleKeyEvent(views::Textfield* sender, + const ui::KeyEvent& key_event) { + if (key_event.type() != ui::ET_KEY_PRESSED) + return false; + + // Default handling for events with Alt modifier like spoken feedback. + if (key_event.IsAltDown()) + return false; + + // FixedLengthCodeInput class responds to limited subset of key press + // events. All key pressed events not handled below are ignored. + const ui::KeyboardCode key_code = key_event.key_code(); + if (key_code == ui::VKEY_TAB || key_code == ui::VKEY_BACKTAB) { + // Allow using tab for keyboard navigation. + return false; + } else if (key_code >= ui::VKEY_0 && key_code <= ui::VKEY_9) { + InsertDigit(key_code - ui::VKEY_0); + } else if (key_code >= ui::VKEY_NUMPAD0 && key_code <= ui::VKEY_NUMPAD9) { + InsertDigit(key_code - ui::VKEY_NUMPAD0); + } else if (key_code == ui::VKEY_LEFT) { + FocusPreviousField(); + } else if (key_code == ui::VKEY_RIGHT) { + // Do not allow to leave empty field when moving focus with arrow key. + if (!ActiveInput().empty()) + FocusNextField(); + } else if (key_code == ui::VKEY_BACK) { + Backspace(); + } else if (key_code == ui::VKEY_RETURN) { + if (GetCode().has_value()) + on_enter_.Run(); + } else if (key_code == ui::VKEY_ESCAPE) { + on_escape_.Run(); + } + + return true; +} + +bool FixedLengthCodeInput::HandleMouseEvent(views::Textfield* sender, + const ui::MouseEvent& mouse_event) { + if (!(mouse_event.IsOnlyLeftMouseButton() || + mouse_event.IsOnlyRightMouseButton())) { + return false; + } + + // Move focus to the field that was selected with mouse input. + for (size_t i = 0; i < input_fields_.size(); ++i) { + if (input_fields_[i] == sender) { + active_input_index_ = i; + RequestFocus(); + break; + } + } + + return true; +} + +bool FixedLengthCodeInput::HandleGestureEvent( + views::Textfield* sender, + const ui::GestureEvent& gesture_event) { + if (gesture_event.details().type() != ui::EventType::ET_GESTURE_TAP) + return false; + + // Move focus to the field that was selected with gesture. + for (size_t i = 0; i < input_fields_.size(); ++i) { + if (input_fields_[i] == sender) { + active_input_index_ = i; + RequestFocus(); + break; + } + } + + return true; +} + +void FixedLengthCodeInput::SetInputEnabled(bool input_enabled) { + NOTIMPLEMENTED(); +} + +void FixedLengthCodeInput::ClearInput() { + NOTIMPLEMENTED(); +} + +void FixedLengthCodeInput::FocusPreviousField() { + if (active_input_index_ == 0) + return; + + --active_input_index_; + ActiveField()->RequestFocus(); +} + +void FixedLengthCodeInput::FocusNextField() { + if (IsLastFieldActive()) + return; + + ++active_input_index_; + ActiveField()->RequestFocus(); +} + +bool FixedLengthCodeInput::IsLastFieldActive() const { + return active_input_index_ == (static_cast<int>(input_fields_.size()) - 1); +} + +AccessibleInputField* FixedLengthCodeInput::ActiveField() const { + return input_fields_[active_input_index_]; +} + +const base::string16& FixedLengthCodeInput::ActiveInput() const { + return ActiveField()->GetText(); +} + +} // namespace ash \ No newline at end of file
diff --git a/ash/login/ui/access_code_input.h b/ash/login/ui/access_code_input.h new file mode 100644 index 0000000..bdc7a94 --- /dev/null +++ b/ash/login/ui/access_code_input.h
@@ -0,0 +1,246 @@ +// 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 ASH_LOGIN_UI_ACCESS_CODE_INPUT_H_ +#define ASH_LOGIN_UI_ACCESS_CODE_INPUT_H_ + +#include "ui/views/controls/textfield/textfield.h" +#include "ui/views/controls/textfield/textfield_controller.h" + +namespace ash { + +class AccessCodeInput : public views::View, public views::TextfieldController { + public: + static constexpr int kAccessCodeInputFieldUnderlineThicknessDp = 2; + static constexpr int kAccessCodeInputFieldHeightDp = + 24 + kAccessCodeInputFieldUnderlineThicknessDp; + + AccessCodeInput() = default; + + ~AccessCodeInput() override = default; + + // Deletes the last character. + virtual void Backspace() = 0; + + // Appends a digit to the code. + virtual void InsertDigit(int value) = 0; + + // Returns access code as string. + virtual base::Optional<std::string> GetCode() const = 0; + + // Sets the color of the input text. + virtual void SetInputColor(SkColor color) = 0; + + virtual void SetInputEnabled(bool input_enabled) = 0; + + // Clears the input field(s). + virtual void ClearInput() = 0; +}; + +class FlexCodeInput : public AccessCodeInput { + public: + using OnInputChange = base::RepeatingCallback<void(bool enable_submit)>; + using OnEnter = base::RepeatingClosure; + using OnEscape = base::RepeatingClosure; + + // Builds the view for an access code that consists out of an unknown number + // of digits. |on_input_change| will be called upon digit insertion, deletion + // or change. |on_enter| will be called when code is complete and user presses + // enter to submit it for validation. |on_escape| will be called when pressing + // the escape key. |obscure_pin| determines whether the entered pin is + // displayed as clear text or as bullet points. + FlexCodeInput(OnInputChange on_input_change, + OnEnter on_enter, + OnEscape on_escape, + bool obscure_pin); + + FlexCodeInput(const FlexCodeInput&) = delete; + FlexCodeInput& operator=(const FlexCodeInput&) = delete; + ~FlexCodeInput() override; + + // Appends |value| to the code + void InsertDigit(int value) override; + + // Deletes the last character or the selected text. + void Backspace() override; + + // Returns access code as string if field contains input. + base::Optional<std::string> GetCode() const override; + + // Sets the color of the input text. + void SetInputColor(SkColor color) override; + + void SetInputEnabled(bool input_enabled) override; + + // Clears text in input text field. + void ClearInput() override; + + void RequestFocus() override; + + // views::TextfieldController + void ContentsChanged(views::Textfield* sender, + const base::string16& new_contents) override; + + // views::TextfieldController + bool HandleKeyEvent(views::Textfield* sender, + const ui::KeyEvent& key_event) override; + + private: + views::Textfield* code_field_; + + // To be called when access input code changes (digit is inserted, deleted or + // updated). Passes true when code non-empty. + OnInputChange on_input_change_; + + // To be called when user pressed enter to submit. + OnEnter on_enter_; + + // To be called when user presses escape to go back. + OnEscape on_escape_; +}; + +// Accessible input field for a single digit in fixed length codes. +// Customizes field description and focus behavior. +class AccessibleInputField : public views::Textfield { + public: + AccessibleInputField() = default; + ~AccessibleInputField() override = default; + + void set_accessible_description(const base::string16& description) { + accessible_description_ = description; + } + + // views::View: + void GetAccessibleNodeData(ui::AXNodeData* node_data) override; + bool IsGroupFocusTraversable() const override; + View* GetSelectedViewForGroup(int group) override; + void OnGestureEvent(ui::GestureEvent* event) override; + + private: + base::string16 accessible_description_; + + DISALLOW_COPY_AND_ASSIGN(AccessibleInputField); +}; + +// Digital access code input view for variable length of input codes. +// Displays a separate underscored field for every input code digit. +class FixedLengthCodeInput : public AccessCodeInput { + public: + using OnInputChange = + base::RepeatingCallback<void(bool last_field_active, bool complete)>; + using OnEnter = base::RepeatingClosure; + using OnEscape = base::RepeatingClosure; + + class TestApi { + public: + explicit TestApi(FixedLengthCodeInput* fixed_length_code_input) + : fixed_length_code_input_(fixed_length_code_input) {} + ~TestApi() = default; + + views::Textfield* GetInputTextField(int index) { + DCHECK_LT(static_cast<size_t>(index), + fixed_length_code_input_->input_fields_.size()); + return fixed_length_code_input_->input_fields_[index]; + } + + private: + FixedLengthCodeInput* fixed_length_code_input_; + }; + + // Builds the view for an access code that consists out of |length| digits. + // |on_input_change| will be called upon access code digit insertion, deletion + // or change. True will be passed if the current code is complete (all digits + // have input values) and false otherwise. |on_enter| will be called when code + // is complete and user presses enter to submit it for validation. |on_escape| + // will be called when pressing the escape key. |obscure_pin| determines + // whether the entered pin is displayed as clear text or as bullet points. + FixedLengthCodeInput(int length, + OnInputChange on_input_change, + OnEnter on_enter, + OnEscape on_escape, + bool obscure_pin); + + ~FixedLengthCodeInput() override; + FixedLengthCodeInput(const FixedLengthCodeInput&) = delete; + FixedLengthCodeInput& operator=(const FixedLengthCodeInput&) = delete; + + // Inserts |value| into the |active_field_| and moves focus to the next field + // if it exists. + void InsertDigit(int value) override; + + // Clears input from the |active_field_|. If |active_field| is empty moves + // focus to the previous field (if exists) and clears input there. + void Backspace() override; + + // Returns access code as string if all fields contain input. + base::Optional<std::string> GetCode() const override; + + // Sets the color of the input text. + void SetInputColor(SkColor color) override; + + // views::View: + bool IsGroupFocusTraversable() const override; + + View* GetSelectedViewForGroup(int group) override; + + void RequestFocus() override; + + void GetAccessibleNodeData(ui::AXNodeData* node_data) override; + + // views::TextfieldController: + bool HandleKeyEvent(views::Textfield* sender, + const ui::KeyEvent& key_event) override; + + bool HandleMouseEvent(views::Textfield* sender, + const ui::MouseEvent& mouse_event) override; + + bool HandleGestureEvent(views::Textfield* sender, + const ui::GestureEvent& gesture_event) override; + + // Enables/disables entering a PIN. Currently, there is no use-case the uses + // this with fixed length PINs. + void SetInputEnabled(bool input_enabled) override; + + // Clears the PIN fields. Currently, there is no use-case the uses this with + // fixed length PINs. + void ClearInput() override; + + private: + // Moves focus to the previous input field if it exists. + void FocusPreviousField(); + + // Moves focus to the next input field if it exists. + void FocusNextField(); + + // Returns whether last input field is currently active. + bool IsLastFieldActive() const; + + // Returns pointer to the active input field. + AccessibleInputField* ActiveField() const; + + // Returns text in the active input field. + const base::string16& ActiveInput() const; + + // To be called when access input code changes (digit is inserted, deleted or + // updated). Passes true when code is complete (all digits have input value) + // and false otherwise. + OnInputChange on_input_change_; + + // To be called when user pressed enter to submit. + OnEnter on_enter_; + // To be called when user pressed escape to close view. + OnEscape on_escape_; + + // An active/focused input field index. Incoming digit will be inserted here. + int active_input_index_ = 0; + + // Unowned input textfields ordered from the first to the last digit. + std::vector<AccessibleInputField*> input_fields_; + + base::WeakPtrFactory<FixedLengthCodeInput> weak_ptr_factory_{this}; +}; + +} // namespace ash + +#endif // ASH_LOGIN_UI_ACCESS_CODE_INPUT_H_ \ No newline at end of file
diff --git a/ash/login/ui/lock_contents_view.cc b/ash/login/ui/lock_contents_view.cc index a2dee96..39da93e8 100644 --- a/ash/login/ui/lock_contents_view.cc +++ b/ash/login/ui/lock_contents_view.cc
@@ -1289,6 +1289,31 @@ ShowAuthErrorMessage(); } +void LockContentsView::ToggleManagementForUserForDebug(const AccountId& user) { + auto replace = [](const LoginUserInfo& user_info) { + auto changed = user_info; + if (user_info.user_enterprise_domain) + changed.user_enterprise_domain.reset(); + else + changed.user_enterprise_domain = "example@example.com"; + return changed; + }; + + LoginBigUserView* big = TryToFindBigUser(user, false /*require_auth_active*/); + if (big) { + big->UpdateForUser(replace(big->GetCurrentUser())); + return; + } + + LoginUserView* user_view = + users_list_ ? users_list_->GetUserView(user) : nullptr; + if (user_view) { + user_view->UpdateForUser(replace(user_view->current_user()), + false /*animate*/); + return; + } +} + void LockContentsView::FocusNextWidget(bool reverse) { Shelf* shelf = Shelf::ForWindow(GetWidget()->GetNativeWindow()); // Tell the focus direction to the status area or the shelf so they can focus
diff --git a/ash/login/ui/lock_contents_view.h b/ash/login/ui/lock_contents_view.h index a43a6c1..0d5acb53 100644 --- a/ash/login/ui/lock_contents_view.h +++ b/ash/login/ui/lock_contents_view.h
@@ -223,6 +223,10 @@ void ShowAuthErrorMessageForDebug(int unlock_attempt); + // Called for debugging to make |user| managed and display an icon along with + // a note in the menu user view. + void ToggleManagementForUserForDebug(const AccountId& user); + // Called by LockScreenMediaControlsView. void CreateMediaControlsLayout(); void HideMediaControlsLayout();
diff --git a/ash/login/ui/lock_debug_view.cc b/ash/login/ui/lock_debug_view.cc index ebb89c0..5b4b65c 100644 --- a/ash/login/ui/lock_debug_view.cc +++ b/ash/login/ui/lock_debug_view.cc
@@ -68,6 +68,7 @@ kPerUserAuthFingerprintSuccessState, kPerUserAuthFingerprintFailState, kPerUserForceOnlineSignIn, + kPerUserToggleIsManaged, kPerUserToggleAuthEnabled, kPerUserUseDetachableBase, kPerUserTogglePublicAccount, @@ -150,7 +151,8 @@ if (is_public_account) { result.public_account_info.emplace(); - result.public_account_info->enterprise_domain = kDebugEnterpriseDomain; + result.public_account_info->device_enterprise_domain = + kDebugEnterpriseDomain; result.public_account_info->default_locale = kDebugDefaultLocaleCode; result.public_account_info->show_expanded_view = true; @@ -185,10 +187,12 @@ DebugDataDispatcherTransformer( mojom::TrayActionState initial_lock_screen_note_state, LoginDataDispatcher* dispatcher, - const base::RepeatingClosure& on_users_received) + const base::RepeatingClosure& on_users_received, + LockDebugView* lock_debug_view) : root_dispatcher_(dispatcher), lock_screen_note_state_(initial_lock_screen_note_state), - on_users_received_(on_users_received) { + on_users_received_(on_users_received), + lock_debug_view_(lock_debug_view) { root_dispatcher_->AddObserver(this); } ~DebugDataDispatcherTransformer() override { @@ -353,6 +357,13 @@ debug_users_[user_index].account_id); } + // Enables or disables user management for the user at |user_index|. + void ToggleManagementForUserIndex(size_t user_index) { + DCHECK(user_index >= 0 && user_index < debug_users_.size()); + lock_debug_view_->lock()->ToggleManagementForUserForDebug( + debug_users_[user_index].account_id); + } + // Updates |auth_disabled_reason_| with the next enum value in a cyclic // manner. void UpdateAuthDisabledReason() { @@ -526,6 +537,12 @@ // Called when a new user list has been received. base::RepeatingClosure on_users_received_; + // Called for testing functions not belonging to the login data dispatcher. + // In such a case, we want to bypass the event handling mechanism and do + // direct calls to the lock screen. We need either an instance of + // LockDebugView or LockContentsView in order to do so. + LockDebugView* const lock_debug_view_; + // When auth is disabled, this property is used to define the reason, which // customizes the UI accordingly. AuthDisabledReason auth_disabled_reason_ = @@ -667,7 +684,8 @@ Shell::Get()->login_screen_controller()->data_dispatcher(), base::BindRepeating( &LockDebugView::UpdatePerUserActionContainerAndLayout, - base::Unretained(this)))), + base::Unretained(this)), + this)), next_auth_error_type_(AuthErrorType::kFirstUnlockFailed) { SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kHorizontal)); @@ -1026,6 +1044,11 @@ if (sender->GetID() == ButtonId::kPerUserForceOnlineSignIn) debug_data_dispatcher_->ForceOnlineSignInForUserIndex(sender->tag()); + // Enable or disable user management. + if (sender->GetID() == ButtonId::kPerUserToggleIsManaged) { + debug_data_dispatcher_->ToggleManagementForUserIndex(sender->tag()); + } + // Enable or disable auth. if (sender->GetID() == ButtonId::kPerUserToggleAuthEnabled) debug_data_dispatcher_->ToggleAuthEnabledForUserIndex(sender->tag()); @@ -1083,6 +1106,8 @@ ->set_tag(i); AddButton("Force online sign-in", ButtonId::kPerUserForceOnlineSignIn, row) ->set_tag(i); + AddButton("Toggle user is managed", ButtonId::kPerUserToggleIsManaged, row) + ->set_tag(i); AddButton("Toggle auth enabled", ButtonId::kPerUserToggleAuthEnabled, row) ->set_tag(i);
diff --git a/ash/login/ui/login_auth_user_view.cc b/ash/login/ui/login_auth_user_view.cc index 3274905..fa9e054 100644 --- a/ash/login/ui/login_auth_user_view.cc +++ b/ash/login/ui/login_auth_user_view.cc
@@ -789,7 +789,7 @@ // Build child views. auto user_view = std::make_unique<LoginUserView>( - LoginDisplayStyle::kLarge, true /*show_dropdown*/, false /*show_domain*/, + LoginDisplayStyle::kLarge, true /*show_dropdown*/, base::BindRepeating(&LoginAuthUserView::OnUserViewTap, base::Unretained(this)), callbacks.on_remove_warning_shown, callbacks.on_remove);
diff --git a/ash/login/ui/login_expanded_public_account_view.cc b/ash/login/ui/login_expanded_public_account_view.cc index 544704e..b182e23 100644 --- a/ash/login/ui/login_expanded_public_account_view.cc +++ b/ash/login/ui/login_expanded_public_account_view.cc
@@ -246,7 +246,7 @@ enum class WarningType { kNone, kSoftWarning, kFullWarning }; void UpdateForUser(const LoginUserInfo& user) { - enterprise_domain_ = user.public_account_info->enterprise_domain; + enterprise_domain_ = user.public_account_info->device_enterprise_domain; UpdateLabel(); } @@ -785,8 +785,8 @@ SetPreferredSize(gfx::Size(kExpandedViewWidthDp, kExpandedViewHeightDp)); user_view_ = new LoginUserView( - LoginDisplayStyle::kLarge, false /*show_dropdown*/, true /*show_domain*/, - base::DoNothing(), base::RepeatingClosure(), base::RepeatingClosure()); + LoginDisplayStyle::kLarge, false /*show_dropdown*/, base::DoNothing(), + base::RepeatingClosure(), base::RepeatingClosure()); user_view_->SetForceOpaque(true); user_view_->SetTapEnabled(false);
diff --git a/ash/login/ui/login_expanded_public_account_view_unittest.cc b/ash/login/ui/login_expanded_public_account_view_unittest.cc index 4bf2c21..62bd2968 100644 --- a/ash/login/ui/login_expanded_public_account_view_unittest.cc +++ b/ash/login/ui/login_expanded_public_account_view_unittest.cc
@@ -308,7 +308,7 @@ public_account_->SetShowFullManagementDisclosure(false); EXPECT_EQ(label->GetText(), default_warning); const std::string domain = - user_.public_account_info->enterprise_domain.value(); + user_.public_account_info->device_enterprise_domain.value(); public_account_->UpdateForUser(user_); const base::string16 soft_warning = l10n_util::GetStringFUTF16( IDS_ASH_LOGIN_MANAGED_SESSION_MONITORING_SOFT_WARNING,
diff --git a/ash/login/ui/login_public_account_user_view.cc b/ash/login/ui/login_public_account_user_view.cc index e3f53a1..230efa8 100644 --- a/ash/login/ui/login_public_account_user_view.cc +++ b/ash/login/ui/login_public_account_user_view.cc
@@ -75,7 +75,7 @@ DCHECK(callbacks.on_public_account_tapped); auto user_view = std::make_unique<LoginUserView>( - LoginDisplayStyle::kLarge, false /*show_dropdown*/, true /*show_domain*/, + LoginDisplayStyle::kLarge, false /*show_dropdown*/, base::BindRepeating(&LoginPublicAccountUserView::OnUserViewTap, base::Unretained(this)), base::RepeatingClosure(), base::RepeatingClosure());
diff --git a/ash/login/ui/login_test_utils.cc b/ash/login/ui/login_test_utils.cc index eff688d0..553daf4 100644 --- a/ash/login/ui/login_test_utils.cc +++ b/ash/login/ui/login_test_utils.cc
@@ -80,7 +80,7 @@ user.basic_user_info.display_email = email; user.basic_user_info.type = user_manager::USER_TYPE_PUBLIC_ACCOUNT; user.public_account_info.emplace(); - user.public_account_info->enterprise_domain = email_parts[1]; + user.public_account_info->device_enterprise_domain = email_parts[1]; user.public_account_info->show_expanded_view = true; return user; }
diff --git a/ash/login/ui/login_user_menu_view.cc b/ash/login/ui/login_user_menu_view.cc index 172a9fd..21f5b9af 100644 --- a/ash/login/ui/login_user_menu_view.cc +++ b/ash/login/ui/login_user_menu_view.cc
@@ -6,10 +6,12 @@ #include "ash/login/ui/non_accessible_view.h" #include "ash/login/ui/system_label_button.h" #include "ash/login/ui/views_utils.h" +#include "ash/public/cpp/login_types.h" #include "ash/public/cpp/shelf_config.h" #include "ash/strings/grit/ash_strings.h" #include "base/strings/strcat.h" #include "base/strings/utf_string_conversions.h" +#include "chromeos/strings/grit/chromeos_strings.h" #include "ui/accessibility/ax_node_data.h" #include "ui/base/l10n/l10n_util.h" #include "ui/display/display.h" @@ -18,6 +20,7 @@ #include "ui/views/layout/box_layout.h" #include "ui/views/layout/fill_layout.h" +namespace ash { namespace { constexpr char kLegacySupervisedUserManagementDisplayURL[] = "www.chrome.com/manage"; @@ -36,9 +39,8 @@ // Font size delta from normal for the username headline. constexpr int kUserMenuFontSizeDeltaUsername = 2; -} // namespace -namespace ash { +} // namespace // A button that holds a child view. class RemoveUserButton : public SystemLabelButton { @@ -88,26 +90,32 @@ return bubble_->remove_user_confirm_data_; } +views::View* LoginUserMenuView::TestApi::managed_user_data() { + return bubble_->managed_user_data_; +} + views::Label* LoginUserMenuView::TestApi::username_label() { return bubble_->username_label_; } LoginUserMenuView::LoginUserMenuView( - const base::string16& username, - const base::string16& email, - user_manager::UserType type, - bool is_owner, + const LoginUserInfo& user, views::View* anchor_view, LoginButton* bubble_opener, - bool show_remove_user, base::RepeatingClosure on_remove_user_warning_shown, base::RepeatingClosure on_remove_user_requested) : LoginBaseBubbleView(anchor_view), bubble_opener_(bubble_opener), on_remove_user_warning_shown_(on_remove_user_warning_shown), on_remove_user_requested_(on_remove_user_requested) { + const base::string16& email = + base::UTF8ToUTF16(user.basic_user_info.display_email); + bool is_owner = user.is_device_owner; + // User information. { + const base::string16& username = + base::UTF8ToUTF16(user.basic_user_info.display_name); base::string16 display_username = is_owner ? l10n_util::GetStringFUTF16(IDS_ASH_LOGIN_POD_OWNER_USER, username) @@ -128,10 +136,24 @@ container->AddChildView(email_label); } - // Remove user. - if (show_remove_user) { - DCHECK(!is_owner); + // User is managed. + if (user.user_enterprise_domain) { + managed_user_data_ = new views::View(); + managed_user_data_->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); + base::string16 managed_text = l10n_util::GetStringFUTF16( + IDS_ASH_LOGIN_MANAGED_SESSION_MONITORING_USER_WARNING, + base::UTF8ToUTF16(user.user_enterprise_domain.value())); + views::Label* managed_label = login_views_utils::CreateBubbleLabel( + managed_text, gfx::kGoogleGrey200, this); + managed_user_data_->AddChildView(managed_label); + AddChildView(managed_user_data_); + } + // Remove user. + if (user.can_remove) { + DCHECK(!is_owner); + user_manager::UserType type = user.basic_user_info.type; base::string16 part1 = l10n_util::GetStringUTF16( IDS_ASH_LOGIN_POD_NON_OWNER_USER_REMOVE_WARNING_PART_1); if (type == user_manager::UserType::USER_TYPE_SUPERVISED) { @@ -169,6 +191,8 @@ LoginUserMenuView::~LoginUserMenuView() = default; void LoginUserMenuView::ResetState() { + if (managed_user_data_) + managed_user_data_->SetVisible(true); if (remove_user_confirm_data_) { remove_user_confirm_data_->SetVisible(false); remove_user_button_->SetDisplayType( @@ -189,6 +213,8 @@ // we actually allow the exit. if (!remove_user_confirm_data_->GetVisible()) { remove_user_confirm_data_->SetVisible(true); + if (managed_user_data_) + managed_user_data_->SetVisible(false); remove_user_button_->SetDisplayType( SystemLabelButton::DisplayType::ALERT_NO_ICON);
diff --git a/ash/login/ui/login_user_menu_view.h b/ash/login/ui/login_user_menu_view.h index cc418d98..238dc37 100644 --- a/ash/login/ui/login_user_menu_view.h +++ b/ash/login/ui/login_user_menu_view.h
@@ -15,6 +15,7 @@ namespace ash { +struct LoginUserInfo; class RemoveUserButton; class ASH_EXPORT LoginUserMenuView : public LoginBaseBubbleView, @@ -25,6 +26,7 @@ explicit TestApi(LoginUserMenuView* bubble); views::View* remove_user_button(); views::View* remove_user_confirm_data(); + views::View* managed_user_data(); views::Label* username_label(); private: @@ -33,13 +35,9 @@ DISALLOW_COPY_AND_ASSIGN(TestApi); }; - LoginUserMenuView(const base::string16& username, - const base::string16& email, - user_manager::UserType type, - bool is_owner, + LoginUserMenuView(const LoginUserInfo& user, views::View* anchor_view, LoginButton* bubble_opener, - bool show_remove_user, base::RepeatingClosure on_remove_user_warning_shown, base::RepeatingClosure on_remove_user_requested); @@ -64,6 +62,7 @@ LoginButton* bubble_opener_ = nullptr; base::RepeatingClosure on_remove_user_warning_shown_; base::RepeatingClosure on_remove_user_requested_; + views::View* managed_user_data_ = nullptr; views::View* remove_user_confirm_data_ = nullptr; RemoveUserButton* remove_user_button_ = nullptr; views::Label* username_label_ = nullptr;
diff --git a/ash/login/ui/login_user_menu_view_unittest.cc b/ash/login/ui/login_user_menu_view_unittest.cc index ba6e47c..911b760 100644 --- a/ash/login/ui/login_user_menu_view_unittest.cc +++ b/ash/login/ui/login_user_menu_view_unittest.cc
@@ -32,10 +32,10 @@ bool remove_warning_called = false; bool remove_called = false; + LoginUserInfo login_user_info; + login_user_info.can_remove = true; auto* bubble = new LoginUserMenuView( - base::string16(), base::string16(), user_manager::USER_TYPE_REGULAR, - false /*is_owner*/, anchor, nullptr /*bubble_opener*/, - true /*show_remove_user*/, + login_user_info, anchor, nullptr /*bubble_opener*/, base::BindRepeating([](bool* warning_called) { *warning_called = true; }, &remove_warning_called), base::BindRepeating([](bool* remove_called) { *remove_called = true; }, @@ -69,12 +69,17 @@ views::BoxLayout::Orientation::kVertical)); SetWidget(CreateWidgetWithContent(anchor)); - auto* bubble = new LoginUserMenuView( - base::UTF8ToUTF16("NedHasAReallyLongName StarkHasAReallyLongName"), - base::UTF8ToUTF16("reallyreallyextralonggaianame@gmail.com"), - user_manager::USER_TYPE_REGULAR, false /*is_owner*/, anchor, - nullptr /*bubble_opener*/, true /*show_remove_user*/, base::DoNothing(), - base::DoNothing()); + LoginUserInfo login_user_info; + login_user_info.basic_user_info.display_name = + "NedHasAReallyLongName StarkHasAReallyLongName"; + login_user_info.basic_user_info.display_email = + "reallyreallyextralonggaianame@gmail.com"; + login_user_info.basic_user_info.type = user_manager::USER_TYPE_REGULAR; + login_user_info.is_device_owner = false; + login_user_info.can_remove = true; + auto* bubble = + new LoginUserMenuView(login_user_info, anchor, nullptr /*bubble_opener*/, + base::DoNothing(), base::DoNothing()); anchor->AddChildView(bubble); bubble->Show(); @@ -122,10 +127,9 @@ views::InkDropHostView::InkDropMode::ON); EXPECT_TRUE(ink_drop_api.HasInkDrop()); - auto* bubble = new LoginUserMenuView( - base::string16(), base::string16(), user_manager::USER_TYPE_REGULAR, - false /*is_owner*/, container /*anchor*/, bubble_opener, - true /*show_remove_user*/, base::DoNothing(), base::DoNothing()); + auto* bubble = new LoginUserMenuView(LoginUserInfo(), container /*anchor*/, + bubble_opener, base::DoNothing(), + base::DoNothing()); container->AddChildView(bubble); @@ -149,10 +153,11 @@ views::BoxLayout::Orientation::kVertical)); SetWidget(CreateWidgetWithContent(container)); - auto* bubble = new LoginUserMenuView( - base::string16(), base::string16(), user_manager::USER_TYPE_REGULAR, - false /*is_owner*/, nullptr /*anchor*/, nullptr /*bubble_opener*/, - true /*show_remove_user*/, base::DoNothing(), base::DoNothing()); + LoginUserInfo login_user_info; + login_user_info.can_remove = true; + auto* bubble = new LoginUserMenuView(login_user_info, nullptr /*anchor*/, + nullptr /*bubble_opener*/, + base::DoNothing(), base::DoNothing()); container->AddChildView(bubble); bubble->Show();
diff --git a/ash/login/ui/login_user_view.cc b/ash/login/ui/login_user_view.cc index 6cdc688..900c991 100644 --- a/ash/login/ui/login_user_view.cc +++ b/ash/login/ui/login_user_view.cc
@@ -18,6 +18,7 @@ #include "ash/public/cpp/session/user_info.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/strings/grit/ash_strings.h" +#include "ash/style/ash_color_provider.h" #include "ash/system/user/rounded_image_view.h" #include "base/bind.h" #include "base/memory/weak_ptr.h" @@ -28,6 +29,7 @@ #include "ui/compositor/layer_animation_sequence.h" #include "ui/compositor/layer_animator.h" #include "ui/compositor/scoped_layer_animation_settings.h" +#include "ui/gfx/image/image_skia_operations.h" #include "ui/gfx/paint_vector_icon.h" #include "ui/gfx/text_elider.h" #include "ui/views/controls/button/image_button.h" @@ -61,6 +63,16 @@ constexpr int kSmallUserImageSizeDp = 74; constexpr int kExtraSmallUserImageSizeDp = 60; +// Width/height of the enterprise icon circle. +constexpr int kLargeUserIconSizeDp = 26; +constexpr int kSmallUserIconSizeDp = 26; +constexpr int kExtraSmallUserIconSizeDp = 22; + +// Size of the icon compared to the one of the white circle. +constexpr float kIconProportion = 0.55f; + +constexpr SkColor kIconBackgroundColor = SK_ColorWHITE; + // Opacity for when the user view is active/focused and inactive. constexpr float kOpaqueUserViewOpacity = 1.f; constexpr float kTransparentUserViewOpacity = 0.63f; @@ -72,21 +84,6 @@ constexpr char kLoginUserImageClassName[] = "LoginUserImage"; constexpr char kLoginUserLabelClassName[] = "LoginUserLabel"; -int GetImageSize(LoginDisplayStyle style) { - switch (style) { - case LoginDisplayStyle::kLarge: - return kLargeUserImageSizeDp; - case LoginDisplayStyle::kSmall: - return kSmallUserImageSizeDp; - case LoginDisplayStyle::kExtraSmall: - return kExtraSmallUserImageSizeDp; - break; - } - - NOTREACHED(); - return kLargeUserImageSizeDp; -} - // An animation decoder which does not rescale based on the current image_scale. class PassthroughAnimationDecoder : public AnimatedRoundedImageView::AnimationDecoder { @@ -103,17 +100,74 @@ DISALLOW_COPY_AND_ASSIGN(PassthroughAnimationDecoder); }; +class IconRoundedView : public views::View { + public: + IconRoundedView(int size) : radius_(size / 2) { + icon_ = gfx::ImageSkiaOperations::CreateResizedImage( + gfx::CreateVectorIcon(kLoginScreenEnterpriseIcon, gfx::kGoogleGrey500), + skia::ImageOperations::RESIZE_BEST, + gfx::Size(size * kIconProportion, size * kIconProportion)); + } + ~IconRoundedView() override = default; + + IconRoundedView(const IconRoundedView&) = delete; + IconRoundedView& operator=(const IconRoundedView&) = delete; + + void OnPaint(gfx::Canvas* canvas) override { + View::OnPaint(canvas); + const gfx::Rect content_bounds(GetContentsBounds()); + const gfx::Point center_circle(content_bounds.width() - radius_, + content_bounds.height() - radius_); + const gfx::Point left_corner_icon( + std::round(content_bounds.width() - radius_ * (1 + kIconProportion)), + std::round(content_bounds.height() - radius_ * (1 + kIconProportion))); + gfx::Rect image_bounds(left_corner_icon, icon_.size()); + SkPath path; + path.addRect(gfx::RectToSkRect(image_bounds)); + cc::PaintFlags flags; + flags.setAntiAlias(true); + flags.setColor(kIconBackgroundColor); + flags.setStyle(cc::PaintFlags::kFill_Style); + // The white circle on which we paint the icon. + canvas->DrawCircle(center_circle, radius_, flags); + canvas->DrawImageInPath(icon_, image_bounds.x(), image_bounds.y(), path, + flags); + } + + private: + gfx::ImageSkia icon_; + int radius_; +}; + } // namespace // Renders a user's profile icon. class LoginUserView::UserImage : public NonAccessibleView { public: - UserImage(int size) - : NonAccessibleView(kLoginUserImageClassName), size_(size) { + class ASH_EXPORT TestApi { + public: + explicit TestApi(LoginUserView::UserImage* view) : view_(view) {} + ~TestApi() = default; + + views::View* enterprise_icon() const { return view_->enterprise_icon_; } + + private: + LoginUserView::UserImage* const view_; + }; + + UserImage(LoginDisplayStyle style) + : NonAccessibleView(kLoginUserImageClassName) { SetLayoutManager(std::make_unique<views::FillLayout>()); - image_ = new AnimatedRoundedImageView(gfx::Size(size_, size_), size_ / 2); + const int image_size = GetImageSize(style); + image_ = new AnimatedRoundedImageView(gfx::Size(image_size, image_size), + image_size / 2); AddChildView(image_); + + const int icon_size = GetIconSize(style); + enterprise_icon_ = new IconRoundedView(icon_size); + enterprise_icon_->SetVisible(false); + AddChildView(enterprise_icon_); } ~UserImage() override = default; @@ -131,6 +185,11 @@ base::BindOnce(&LoginUserView::UserImage::OnImageDecoded, weak_factory_.GetWeakPtr())); } + + bool is_managed = + user.user_enterprise_domain || + user.basic_user_info.type == user_manager::USER_TYPE_PUBLIC_ACCOUNT; + enterprise_icon_->SetVisible(is_managed); } void SetAnimationEnabled(bool enable) { @@ -156,8 +215,30 @@ : AnimatedRoundedImageView::Playback::kFirstFrameOnly); } + static int GetImageSize(LoginDisplayStyle style) { + switch (style) { + case LoginDisplayStyle::kLarge: + return kLargeUserImageSizeDp; + case LoginDisplayStyle::kSmall: + return kSmallUserImageSizeDp; + case LoginDisplayStyle::kExtraSmall: + return kExtraSmallUserImageSizeDp; + } + } + + static int GetIconSize(LoginDisplayStyle style) { + switch (style) { + case LoginDisplayStyle::kLarge: + return kLargeUserIconSizeDp; + case LoginDisplayStyle::kSmall: + return kSmallUserIconSizeDp; + case LoginDisplayStyle::kExtraSmall: + return kExtraSmallUserIconSizeDp; + } + } + AnimatedRoundedImageView* image_ = nullptr; - int size_ = 0; + IconRoundedView* enterprise_icon_ = nullptr; bool animation_enabled_ = false; base::WeakPtrFactory<UserImage> weak_factory_{this}; @@ -280,10 +361,15 @@ return view_->dropdown_; } -LoginBaseBubbleView* LoginUserView::TestApi::menu() const { +LoginUserMenuView* LoginUserView::TestApi::menu() const { return view_->menu_; } +views::View* LoginUserView::TestApi::enterprise_icon() const { + return LoginUserView::UserImage::TestApi(view_->user_image_) + .enterprise_icon(); +} + void LoginUserView::TestApi::OnTap() const { view_->on_tap_.Run(); } @@ -302,19 +388,11 @@ case LoginDisplayStyle::kExtraSmall: return kExtraSmallUserViewWidthDp; } - - NOTREACHED(); - return 0; } LoginUserView::LoginUserView( LoginDisplayStyle style, bool show_dropdown, - // We keep show_domain variable - even if it useless for the moment - - // as it will be useful to implement account / profile level management. - // Note that it could be managed by a separate entity, different from - // device level management (indicated in the bottom). - bool show_domain, const OnTap& on_tap, const OnRemoveWarningShown& on_remove_warning_shown, const OnRemove& on_remove) @@ -325,13 +403,12 @@ // show_dropdown can only be true when the user view is rendering in large // mode. DCHECK(!show_dropdown || style == LoginDisplayStyle::kLarge); - DCHECK(!show_domain || style == LoginDisplayStyle::kLarge); // |on_remove_warning_shown| and |on_remove| is only available iff // |show_dropdown| is true. DCHECK(show_dropdown == !!on_remove_warning_shown); DCHECK(show_dropdown == !!on_remove); - user_image_ = new UserImage(GetImageSize(style)); + user_image_ = new UserImage(style); int label_width = WidthForLayoutStyle(style) - 2 * (kDistanceBetweenUsernameAndDropdownDp + kDropdownIconSizeDp); @@ -389,13 +466,9 @@ delete menu_; } - menu_ = new LoginUserMenuView( - base::UTF8ToUTF16(current_user_.basic_user_info.display_name), - base::UTF8ToUTF16(current_user_.basic_user_info.display_email), - current_user_.basic_user_info.type, current_user_.is_device_owner, - dropdown_ /*anchor_view*/, dropdown_ /*bubble_opener*/, - current_user_.can_remove /*show_remove_user*/, on_remove_warning_shown_, - on_remove_); + menu_ = new LoginUserMenuView(current_user_, dropdown_ /*anchor_view*/, + dropdown_ /*bubble_opener*/, + on_remove_warning_shown_, on_remove_); menu_->SetVisible(false); if (animate) { @@ -471,9 +544,6 @@ case LoginDisplayStyle::kExtraSmall: return gfx::Size(kExtraSmallUserViewWidthDp, kExtraSmallUserImageSizeDp); } - - NOTREACHED(); - return gfx::Size(); } void LoginUserView::Layout() { @@ -526,8 +596,20 @@ } void LoginUserView::UpdateCurrentUserState() { + base::string16 accessible_name; auto email = base::UTF8ToUTF16(current_user_.basic_user_info.display_email); - tap_button_->SetAccessibleName(email); + if (current_user_.user_enterprise_domain) { + accessible_name = l10n_util::GetStringFUTF16( + IDS_ASH_LOGIN_POD_MANAGED_ACCESSIBLE_NAME, email); + } else if (current_user_.basic_user_info.type == + user_manager::USER_TYPE_PUBLIC_ACCOUNT) { + accessible_name = l10n_util::GetStringFUTF16( + IDS_ASH_LOGIN_POD_MANAGED_ACCESSIBLE_NAME, + base::UTF8ToUTF16(current_user_.basic_user_info.display_name)); + } else { + accessible_name = email; + } + tap_button_->SetAccessibleName(accessible_name); if (dropdown_) { dropdown_->SetAccessibleName(l10n_util::GetStringFUTF16( IDS_ASH_LOGIN_POD_MENU_BUTTON_ACCESSIBLE_NAME, email));
diff --git a/ash/login/ui/login_user_view.h b/ash/login/ui/login_user_view.h index e369f8c..46938ff 100644 --- a/ash/login/ui/login_user_view.h +++ b/ash/login/ui/login_user_view.h
@@ -37,8 +37,8 @@ views::View* user_label() const; views::View* tap_button() const; views::View* dropdown() const; - LoginBaseBubbleView* menu() const; - views::View* user_domain() const; + LoginUserMenuView* menu() const; + views::View* enterprise_icon() const; void OnTap() const; @@ -59,7 +59,6 @@ // |show_dropdown| arg is false. LoginUserView(LoginDisplayStyle style, bool show_dropdown, - bool show_domain, const OnTap& on_tap, const OnRemoveWarningShown& on_remove_warning_shown, const OnRemove& on_remove);
diff --git a/ash/login/ui/login_user_view_unittest.cc b/ash/login/ui/login_user_view_unittest.cc index 88b2cda..2721e3fde 100644 --- a/ash/login/ui/login_user_view_unittest.cc +++ b/ash/login/ui/login_user_view_unittest.cc
@@ -36,7 +36,7 @@ } auto* view = - new LoginUserView(display_style, show_dropdown, public_account, + new LoginUserView(display_style, show_dropdown, base::BindRepeating(&LoginUserViewUnittest::OnTapped, base::Unretained(this)), on_remove_warning_shown, on_remove);
diff --git a/ash/login/ui/pin_request_view.cc b/ash/login/ui/pin_request_view.cc index 64805d3..dc5f1653 100644 --- a/ash/login/ui/pin_request_view.cc +++ b/ash/login/ui/pin_request_view.cc
@@ -4,56 +4,26 @@ #include "ash/login/ui/pin_request_view.h" -#include <algorithm> -#include <memory> -#include <utility> -#include <vector> - -#include "ash/login/login_screen_controller.h" #include "ash/login/ui/arrow_button_view.h" -#include "ash/login/ui/login_button.h" #include "ash/login/ui/login_pin_view.h" -#include "ash/login/ui/non_accessible_view.h" #include "ash/login/ui/pin_request_widget.h" -#include "ash/public/cpp/login_constants.h" -#include "ash/public/cpp/login_types.h" #include "ash/public/cpp/shelf_config.h" #include "ash/resources/vector_icons/vector_icons.h" -#include "ash/session/session_controller_impl.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" #include "ash/style/ash_color_provider.h" #include "ash/wallpaper/wallpaper_controller_impl.h" -#include "base/bind.h" -#include "base/logging.h" -#include "base/optional.h" -#include "base/strings/strcat.h" -#include "base/strings/string16.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/utf_string_conversions.h" -#include "base/task/post_task.h" -#include "base/threading/thread_task_runner_handle.h" -#include "components/session_manager/session_manager_types.h" #include "ui/accessibility/ax_enums.mojom.h" #include "ui/accessibility/ax_node_data.h" #include "ui/base/l10n/l10n_util.h" -#include "ui/events/event.h" -#include "ui/events/keycodes/dom/dom_code.h" #include "ui/gfx/canvas.h" #include "ui/gfx/color_analysis.h" -#include "ui/gfx/color_palette.h" #include "ui/gfx/color_utils.h" -#include "ui/gfx/font.h" -#include "ui/gfx/font_list.h" -#include "ui/gfx/geometry/size.h" #include "ui/gfx/paint_vector_icon.h" #include "ui/views/background.h" #include "ui/views/controls/button/label_button.h" #include "ui/views/controls/focus_ring.h" -#include "ui/views/controls/image_view.h" #include "ui/views/controls/label.h" -#include "ui/views/controls/textfield/textfield.h" -#include "ui/views/controls/textfield/textfield_controller.h" #include "ui/views/layout/box_layout.h" #include "ui/views/layout/fill_layout.h" #include "ui/views/vector_icons.h" @@ -62,9 +32,6 @@ namespace { -// Identifier of pin request input views group used for focus traversal. -constexpr int kPinRequestInputGroup = 1; - constexpr int kPinRequestViewWidthDp = 340; constexpr int kPinKeyboardHeightDp = 224; constexpr int kPinRequestViewRoundedCornerRadiusDp = 8; @@ -97,23 +64,13 @@ constexpr int kDescriptionTextLineHeightDp = 18; constexpr int kDescriptionMaxLines = 4; -constexpr int kAccessCodeFlexLengthWidthDp = 192; -constexpr int kAccessCodeFlexUnderlineThicknessDp = 1; -constexpr int kAccessCodeFontSizeDeltaDp = 4; -constexpr int kObscuredGlyphSpacingDp = 6; - -constexpr int kAccessCodeInputFieldWidthDp = 24; -constexpr int kAccessCodeInputFieldUnderlineThicknessDp = 2; -constexpr int kAccessCodeInputFieldHeightDp = - 24 + kAccessCodeInputFieldUnderlineThicknessDp; -constexpr int kAccessCodeBetweenInputFieldsGapDp = 8; - constexpr int kArrowButtonSizeDp = 48; constexpr int kPinRequestViewMinimumHeightDp = kPinRequestViewMainHorizontalInsetDp + kLockIconSizeDp + kIconToTitleDistanceDp + kTitleToDescriptionDistanceDp + - kDescriptionToAccessCodeDistanceDp + kAccessCodeInputFieldHeightDp + + kDescriptionToAccessCodeDistanceDp + + AccessCodeInput::kAccessCodeInputFieldHeightDp + kAccessCodeToPinKeyboardDistanceDp + kPinKeyboardToFooterDistanceDp + kArrowButtonSizeDp + kPinRequestViewMainHorizontalInsetDp; // = 266 @@ -150,518 +107,6 @@ ~FocusableLabelButton() override = default; }; -class PinRequestView::AccessCodeInput : public views::View, - public views::TextfieldController { - public: - AccessCodeInput() = default; - - ~AccessCodeInput() override = default; - - // Deletes the last character. - virtual void Backspace() = 0; - - // Appends a digit to the code. - virtual void InsertDigit(int value) = 0; - - // Returns access code as string. - virtual base::Optional<std::string> GetCode() const = 0; - - // Sets the color of the input text. - virtual void SetInputColor(SkColor color) = 0; - - virtual void SetInputEnabled(bool input_enabled) = 0; - - // Clears the input field(s). - virtual void ClearInput() = 0; -}; - -class PinRequestView::FlexCodeInput : public AccessCodeInput { - public: - using OnInputChange = base::RepeatingCallback<void(bool enable_submit)>; - using OnEnter = base::RepeatingClosure; - using OnEscape = base::RepeatingClosure; - - // Builds the view for an access code that consists out of an unknown number - // of digits. |on_input_change| will be called upon digit insertion, deletion - // or change. |on_enter| will be called when code is complete and user presses - // enter to submit it for validation. |on_escape| will be called when pressing - // the escape key. |obscure_pin| determines whether the entered pin is - // displayed as clear text or as bullet points. - FlexCodeInput(OnInputChange on_input_change, - OnEnter on_enter, - OnEscape on_escape, - bool obscure_pin) - : on_input_change_(std::move(on_input_change)), - on_enter_(std::move(on_enter)), - on_escape_(std::move(on_escape)) { - DCHECK(on_input_change_); - DCHECK(on_enter_); - DCHECK(on_escape_); - - SetLayoutManager(std::make_unique<views::FillLayout>()); - - code_field_ = AddChildView(std::make_unique<views::Textfield>()); - code_field_->set_controller(this); - code_field_->SetTextColor(login_constants::kAuthMethodsTextColor); - code_field_->SetFontList(views::Textfield::GetDefaultFontList().Derive( - kAccessCodeFontSizeDeltaDp, gfx::Font::FontStyle::NORMAL, - gfx::Font::Weight::NORMAL)); - code_field_->SetBorder(views::CreateSolidSidedBorder( - 0, 0, kAccessCodeFlexUnderlineThicknessDp, 0, kTextColor)); - code_field_->SetBackgroundColor(SK_ColorTRANSPARENT); - code_field_->SetFocusBehavior(FocusBehavior::ALWAYS); - code_field_->SetPreferredSize( - gfx::Size(kAccessCodeFlexLengthWidthDp, kAccessCodeInputFieldHeightDp)); - - if (obscure_pin) { - code_field_->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD); - code_field_->SetObscuredGlyphSpacing(kObscuredGlyphSpacingDp); - } else { - code_field_->SetTextInputType(ui::TEXT_INPUT_TYPE_NUMBER); - } - } - - FlexCodeInput(const FlexCodeInput&) = delete; - FlexCodeInput& operator=(const FlexCodeInput&) = delete; - ~FlexCodeInput() override = default; - - // Appends |value| to the code - void InsertDigit(int value) override { - DCHECK_LE(0, value); - DCHECK_GE(9, value); - if (code_field_->GetEnabled()) { - code_field_->SetText(code_field_->GetText() + - base::NumberToString16(value)); - on_input_change_.Run(true); - } - } - - // Deletes the last character or the selected text. - void Backspace() override { - // Instead of just adjusting code_field_ text directly, fire a backspace key - // event as this handles the various edge cases (ie, selected text). - - // views::Textfield::OnKeyPressed is private, so we call it via views::View. - auto* view = static_cast<views::View*>(code_field_); - view->OnKeyPressed(ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_BACK, - ui::DomCode::BACKSPACE, ui::EF_NONE)); - view->OnKeyPressed(ui::KeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_BACK, - ui::DomCode::BACKSPACE, ui::EF_NONE)); - // This triggers ContentsChanged(), which calls |on_input_change_|. - } - - // Returns access code as string if field contains input. - base::Optional<std::string> GetCode() const override { - base::string16 code = code_field_->GetText(); - if (!code.length()) { - return base::nullopt; - } - return base::UTF16ToUTF8(code); - } - - // Sets the color of the input text. - void SetInputColor(SkColor color) override { - code_field_->SetTextColor(color); - } - - void SetInputEnabled(bool input_enabled) override { - code_field_->SetEnabled(input_enabled); - } - - // Clears text in input text field. - void ClearInput() override { - code_field_->SetText(base::string16()); - on_input_change_.Run(false); - } - - void RequestFocus() override { code_field_->RequestFocus(); } - - // views::TextfieldController - void ContentsChanged(views::Textfield* sender, - const base::string16& new_contents) override { - const bool has_content = new_contents.length() > 0; - on_input_change_.Run(has_content); - } - - // views::TextfieldController - bool HandleKeyEvent(views::Textfield* sender, - const ui::KeyEvent& key_event) override { - // Only handle keys. - if (key_event.type() != ui::ET_KEY_PRESSED) - return false; - - // Default handling for events with Alt modifier like spoken feedback. - if (key_event.IsAltDown()) - return false; - - // FlexCodeInput class responds to a limited subset of key press events. - // All events not handled below are sent to |code_field_|. - const ui::KeyboardCode key_code = key_event.key_code(); - - // Allow using tab for keyboard navigation. - if (key_code == ui::VKEY_TAB || key_code == ui::VKEY_BACKTAB) - return false; - - if (key_code == ui::VKEY_RETURN) { - if (GetCode().has_value()) { - on_enter_.Run(); - } - return true; - } - - if (key_code == ui::VKEY_ESCAPE) { - on_escape_.Run(); - return true; - } - - // We only expect digits in the PIN, so we swallow all letters. - if (key_code >= ui::VKEY_A && key_code <= ui::VKEY_Z) - return true; - - return false; - } - - private: - views::Textfield* code_field_; - - // To be called when access input code changes (digit is inserted, deleted or - // updated). Passes true when code non-empty. - OnInputChange on_input_change_; - - // To be called when user pressed enter to submit. - OnEnter on_enter_; - - // To be called when user presses escape to go back. - OnEscape on_escape_; -}; - -// Accessible input field for a single digit in fixed length codes. -// Customizes field description and focus behavior. -class AccessibleInputField : public views::Textfield { - public: - AccessibleInputField() = default; - ~AccessibleInputField() override = default; - - void set_accessible_description(const base::string16& description) { - accessible_description_ = description; - } - - // views::View: - void GetAccessibleNodeData(ui::AXNodeData* node_data) override { - views::Textfield::GetAccessibleNodeData(node_data); - // The following property setup is needed to match the custom behavior of - // pin input. It results in the following a11y vocalizations: - // * when input field is empty: "Next number, {current field index} of - // {number of fields}" - // * when input field is populated: "{value}, {current field index} of - // {number of fields}" - node_data->RemoveState(ax::mojom::State::kEditable); - node_data->role = ax::mojom::Role::kListItem; - base::string16 description = views::Textfield::GetText().empty() - ? accessible_description_ - : GetText(); - node_data->AddStringAttribute(ax::mojom::StringAttribute::kRoleDescription, - base::UTF16ToUTF8(description)); - } - - bool IsGroupFocusTraversable() const override { return false; } - - View* GetSelectedViewForGroup(int group) override { - return parent() ? parent()->GetSelectedViewForGroup(group) : nullptr; - } - - void OnGestureEvent(ui::GestureEvent* event) override { - if (event->type() == ui::ET_GESTURE_TAP_DOWN) { - RequestFocusWithPointer(event->details().primary_pointer_type()); - return; - } - - views::Textfield::OnGestureEvent(event); - } - - private: - base::string16 accessible_description_; - - DISALLOW_COPY_AND_ASSIGN(AccessibleInputField); -}; - -// Digital access code input view for variable length of input codes. -// Displays a separate underscored field for every input code digit. -class PinRequestView::FixedLengthCodeInput : public AccessCodeInput { - public: - using OnInputChange = - base::RepeatingCallback<void(bool last_field_active, bool complete)>; - using OnEnter = base::RepeatingClosure; - using OnEscape = base::RepeatingClosure; - - class TestApi { - public: - explicit TestApi( - PinRequestView::FixedLengthCodeInput* fixed_length_code_input) - : fixed_length_code_input_(fixed_length_code_input) {} - ~TestApi() = default; - - views::Textfield* GetInputTextField(int index) { - DCHECK_LT(static_cast<size_t>(index), - fixed_length_code_input_->input_fields_.size()); - return fixed_length_code_input_->input_fields_[index]; - } - - private: - PinRequestView::FixedLengthCodeInput* fixed_length_code_input_; - }; - - // Builds the view for an access code that consists out of |length| digits. - // |on_input_change| will be called upon access code digit insertion, deletion - // or change. True will be passed if the current code is complete (all digits - // have input values) and false otherwise. |on_enter| will be called when code - // is complete and user presses enter to submit it for validation. |on_escape| - // will be called when pressing the escape key. |obscure_pin| determines - // whether the entered pin is displayed as clear text or as bullet points. - FixedLengthCodeInput(int length, - OnInputChange on_input_change, - OnEnter on_enter, - OnEscape on_escape, - bool obscure_pin) - : on_input_change_(std::move(on_input_change)), - on_enter_(std::move(on_enter)), - on_escape_(std::move(on_escape)) { - DCHECK_LT(0, length); - DCHECK(on_input_change_); - - SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), - kAccessCodeBetweenInputFieldsGapDp)); - SetGroup(kPinRequestInputGroup); - SetPaintToLayer(); - layer()->SetFillsBoundsOpaquely(false); - - for (int i = 0; i < length; ++i) { - auto* field = new AccessibleInputField(); - field->set_controller(this); - field->SetPreferredSize(gfx::Size(kAccessCodeInputFieldWidthDp, - kAccessCodeInputFieldHeightDp)); - field->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_CENTER); - field->SetBackgroundColor(SK_ColorTRANSPARENT); - if (obscure_pin) { - field->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD); - } else { - field->SetTextInputType(ui::TEXT_INPUT_TYPE_NUMBER); - } - field->SetTextColor(kTextColor); - field->SetFontList(views::Textfield::GetDefaultFontList().Derive( - kAccessCodeFontSizeDeltaDp, gfx::Font::FontStyle::NORMAL, - gfx::Font::Weight::NORMAL)); - field->SetBorder(views::CreateSolidSidedBorder( - 0, 0, kAccessCodeInputFieldUnderlineThicknessDp, 0, kTextColor)); - field->SetGroup(kPinRequestInputGroup); - field->set_accessible_description(l10n_util::GetStringUTF16( - IDS_ASH_LOGIN_PIN_REQUEST_NEXT_NUMBER_PROMPT)); - input_fields_.push_back(field); - AddChildView(field); - } - } - - ~FixedLengthCodeInput() override = default; - FixedLengthCodeInput(const FixedLengthCodeInput&) = delete; - FixedLengthCodeInput& operator=(const FixedLengthCodeInput&) = delete; - - // Inserts |value| into the |active_field_| and moves focus to the next field - // if it exists. - void InsertDigit(int value) override { - DCHECK_LE(0, value); - DCHECK_GE(9, value); - - ActiveField()->SetText(base::NumberToString16(value)); - bool was_last_field = IsLastFieldActive(); - - // Moving focus is delayed by using PostTask to allow for proper - // a11y announcements. Without that some of them are skipped. - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(&FixedLengthCodeInput::FocusNextField, - weak_ptr_factory_.GetWeakPtr())); - - on_input_change_.Run(was_last_field, GetCode().has_value()); - } - - // Clears input from the |active_field_|. If |active_field| is empty moves - // focus to the previous field (if exists) and clears input there. - void Backspace() override { - if (ActiveInput().empty()) { - FocusPreviousField(); - } - - ActiveField()->SetText(base::string16()); - on_input_change_.Run(IsLastFieldActive(), false /*complete*/); - } - - // Returns access code as string if all fields contain input. - base::Optional<std::string> GetCode() const override { - std::string result; - size_t length; - for (auto* field : input_fields_) { - length = field->GetText().length(); - if (!length) - return base::nullopt; - - DCHECK_EQ(1u, length); - base::StrAppend(&result, {base::UTF16ToUTF8(field->GetText())}); - } - return result; - } - - // Sets the color of the input text. - void SetInputColor(SkColor color) override { - for (auto* field : input_fields_) { - field->SetTextColor(color); - } - } - - // views::View: - bool IsGroupFocusTraversable() const override { return false; } - - View* GetSelectedViewForGroup(int group) override { return ActiveField(); } - - void RequestFocus() override { ActiveField()->RequestFocus(); } - - void GetAccessibleNodeData(ui::AXNodeData* node_data) override { - views::View::GetAccessibleNodeData(node_data); - node_data->role = ax::mojom::Role::kGroup; - } - - // views::TextfieldController: - bool HandleKeyEvent(views::Textfield* sender, - const ui::KeyEvent& key_event) override { - if (key_event.type() != ui::ET_KEY_PRESSED) - return false; - - // Default handling for events with Alt modifier like spoken feedback. - if (key_event.IsAltDown()) - return false; - - // FixedLengthCodeInput class responds to limited subset of key press - // events. All key pressed events not handled below are ignored. - const ui::KeyboardCode key_code = key_event.key_code(); - if (key_code == ui::VKEY_TAB || key_code == ui::VKEY_BACKTAB) { - // Allow using tab for keyboard navigation. - return false; - } else if (key_code >= ui::VKEY_0 && key_code <= ui::VKEY_9) { - InsertDigit(key_code - ui::VKEY_0); - } else if (key_code >= ui::VKEY_NUMPAD0 && key_code <= ui::VKEY_NUMPAD9) { - InsertDigit(key_code - ui::VKEY_NUMPAD0); - } else if (key_code == ui::VKEY_LEFT) { - FocusPreviousField(); - } else if (key_code == ui::VKEY_RIGHT) { - // Do not allow to leave empty field when moving focus with arrow key. - if (!ActiveInput().empty()) - FocusNextField(); - } else if (key_code == ui::VKEY_BACK) { - Backspace(); - } else if (key_code == ui::VKEY_RETURN) { - if (GetCode().has_value()) - on_enter_.Run(); - } else if (key_code == ui::VKEY_ESCAPE) { - on_escape_.Run(); - } - - return true; - } - - bool HandleMouseEvent(views::Textfield* sender, - const ui::MouseEvent& mouse_event) override { - if (!(mouse_event.IsOnlyLeftMouseButton() || - mouse_event.IsOnlyRightMouseButton())) { - return false; - } - - // Move focus to the field that was selected with mouse input. - for (size_t i = 0; i < input_fields_.size(); ++i) { - if (input_fields_[i] == sender) { - active_input_index_ = i; - RequestFocus(); - break; - } - } - - return true; - } - - bool HandleGestureEvent(views::Textfield* sender, - const ui::GestureEvent& gesture_event) override { - if (gesture_event.details().type() != ui::EventType::ET_GESTURE_TAP) - return false; - - // Move focus to the field that was selected with gesture. - for (size_t i = 0; i < input_fields_.size(); ++i) { - if (input_fields_[i] == sender) { - active_input_index_ = i; - RequestFocus(); - break; - } - } - - return true; - } - - // Enables/disables entering a PIN. Currently, there is no use-case the uses - // this with fixed length PINs. - void SetInputEnabled(bool input_enabled) override { NOTIMPLEMENTED(); } - - // Clears the PIN fields. Currently, there is no use-case the uses this with - // fixed length PINs. - void ClearInput() override { NOTIMPLEMENTED(); } - - private: - // Moves focus to the previous input field if it exists. - void FocusPreviousField() { - if (active_input_index_ == 0) - return; - - --active_input_index_; - ActiveField()->RequestFocus(); - } - - // Moves focus to the next input field if it exists. - void FocusNextField() { - if (IsLastFieldActive()) - return; - - ++active_input_index_; - ActiveField()->RequestFocus(); - } - - // Returns whether last input field is currently active. - bool IsLastFieldActive() const { - return active_input_index_ == (static_cast<int>(input_fields_.size()) - 1); - } - - // Returns pointer to the active input field. - AccessibleInputField* ActiveField() const { - return input_fields_[active_input_index_]; - } - - // Returns text in the active input field. - const base::string16& ActiveInput() const { return ActiveField()->GetText(); } - - // To be called when access input code changes (digit is inserted, deleted or - // updated). Passes true when code is complete (all digits have input value) - // and false otherwise. - OnInputChange on_input_change_; - - // To be called when user pressed enter to submit. - OnEnter on_enter_; - // To be called when user pressed escape to close view. - OnEscape on_escape_; - - // An active/focused input field index. Incoming digit will be inserted here. - int active_input_index_ = 0; - - // Unowned input textfields ordered from the first to the last digit. - std::vector<AccessibleInputField*> input_fields_; - - base::WeakPtrFactory<FixedLengthCodeInput> weak_ptr_factory_{this}; -}; - PinRequestView::TestApi::TestApi(PinRequestView* view) : view_(view) { DCHECK(view_); } @@ -697,9 +142,8 @@ } views::Textfield* PinRequestView::TestApi::GetInputTextField(int index) { - return PinRequestView::FixedLengthCodeInput::TestApi( - static_cast<PinRequestView::FixedLengthCodeInput*>( - view_->access_code_view_)) + return FixedLengthCodeInput::TestApi( + static_cast<FixedLengthCodeInput*>(view_->access_code_view_)) .GetInputTextField(index); }
diff --git a/ash/login/ui/pin_request_view.h b/ash/login/ui/pin_request_view.h index 0fc3110..612c301 100644 --- a/ash/login/ui/pin_request_view.h +++ b/ash/login/ui/pin_request_view.h
@@ -8,18 +8,10 @@ #include <string> #include "ash/ash_export.h" +#include "ash/login/ui/access_code_input.h" #include "ash/public/cpp/login_types.h" #include "ash/public/cpp/tablet_mode_observer.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" -#include "base/bind_helpers.h" -#include "base/callback.h" -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/optional.h" -#include "base/scoped_observer.h" -#include "base/time/time.h" -#include "components/account_id/account_id.h" -#include "third_party/skia/include/core/SkColor.h" #include "ui/views/controls/button/button.h" #include "ui/views/window/dialog_delegate.h" @@ -165,9 +157,6 @@ private: class FocusableLabelButton; - class AccessCodeInput; - class FlexCodeInput; - class FixedLengthCodeInput; // Submits access code for validation. void SubmitCode();
diff --git a/ash/login/ui/scrollable_users_list_view.cc b/ash/login/ui/scrollable_users_list_view.cc index fdb7c024..1796ad2 100644 --- a/ash/login/ui/scrollable_users_list_view.cc +++ b/ash/login/ui/scrollable_users_list_view.cc
@@ -306,10 +306,10 @@ views::BoxLayout::CrossAxisAlignment::kCenter); for (std::size_t i = 1u; i < users.size(); ++i) { - auto* view = new LoginUserView( - display_style, false /*show_dropdown*/, false /*show_domain*/, - base::BindRepeating(on_tap_user, i - 1), base::RepeatingClosure(), - base::RepeatingClosure()); + auto* view = + new LoginUserView(display_style, false /*show_dropdown*/, + base::BindRepeating(on_tap_user, i - 1), + base::RepeatingClosure(), base::RepeatingClosure()); user_views_.push_back(view); view->UpdateForUser(users[i], false /*animate*/); user_view_host_->AddChildView(view);
diff --git a/ash/public/cpp/login_screen_test_api.h b/ash/public/cpp/login_screen_test_api.h index 11728fc9..6b3366c4 100644 --- a/ash/public/cpp/login_screen_test_api.h +++ b/ash/public/cpp/login_screen_test_api.h
@@ -30,6 +30,8 @@ static bool IsWarningBubbleShown(); static bool IsSystemInfoShown(); static bool IsDisplayPasswordButtonShown(const AccountId& account_id); + static bool IsManagedIconShown(const AccountId& account_id); + static bool IsManagedMessageInMenuShown(const AccountId& account_id); static bool IsForcedOnlineSignin(const AccountId& account_id); static void SubmitPassword(const AccountId& account_id, const std::string& password,
diff --git a/ash/public/cpp/login_types.h b/ash/public/cpp/login_types.h index 67dda195..a2019eb 100644 --- a/ash/public/cpp/login_types.h +++ b/ash/public/cpp/login_types.h
@@ -206,8 +206,9 @@ PublicAccountInfo& operator=(const PublicAccountInfo& other); PublicAccountInfo& operator=(PublicAccountInfo&& other); - // The domain name displayed in the login screen UI. - base::Optional<std::string> enterprise_domain; + // The domain name displayed in the login screen UI for device-level + // management. + base::Optional<std::string> device_enterprise_domain; // A list of available user locales. std::vector<LocaleItem> available_locales; @@ -275,6 +276,10 @@ // screen for this user. bool show_display_password_button = false; + // The domain name displayed in the login screen UI for user-level + // management. This is only set if the relevant user is managed. + base::Optional<std::string> user_enterprise_domain; + // Contains the public account information if user type is PUBLIC_ACCOUNT. base::Optional<PublicAccountInfo> public_account_info; };
diff --git a/ash/quick_answers/quick_answers_ui_controller.cc b/ash/quick_answers/quick_answers_ui_controller.cc index 3c718ce..41bc6b4b 100644 --- a/ash/quick_answers/quick_answers_ui_controller.cc +++ b/ash/quick_answers/quick_answers_ui_controller.cc
@@ -108,6 +108,7 @@ } void QuickAnswersUiController::OnConsentGrantedButtonPressed() { + DCHECK(user_consent_view_); controller_->OnUserConsentGranted(); } @@ -116,6 +117,11 @@ } void QuickAnswersUiController::OnDogfoodButtonPressed() { + // Close Quick-Answers related views and open the Dogfood link. + if (quick_answers_view_) + CloseQuickAnswersView(); + if (user_consent_view_) + CloseUserConsentView(); controller_->OpenQuickAnswersDogfoodLink(); }
diff --git a/ash/quick_answers/ui/quick_answers_pre_target_handler.cc b/ash/quick_answers/ui/quick_answers_pre_target_handler.cc index 7c46395..3b97e2c5 100644 --- a/ash/quick_answers/ui/quick_answers_pre_target_handler.cc +++ b/ash/quick_answers/ui/quick_answers_pre_target_handler.cc
@@ -5,26 +5,39 @@ #include "ash/quick_answers/ui/quick_answers_pre_target_handler.h" #include "ash/quick_answers/ui/quick_answers_view.h" +#include "ash/quick_answers/ui/user_consent_view.h" #include "ash/shell.h" #include "base/containers/adapters.h" +#include "ui/views/controls/menu/menu_controller.h" #include "ui/views/widget/tooltip_manager.h" #include "ui/views/widget/widget.h" namespace ash { QuickAnswersPreTargetHandler::QuickAnswersPreTargetHandler( - QuickAnswersView* quick_answers_view) - : quick_answers_view_(quick_answers_view) { - // QuickAnswersView is a companion view of a menu. Menu host widget sets - // mouse capture as well as a pre-target handler, so we need to register one - // here as well to intercept events for QuickAnswersView. - Shell::Get()->AddPreTargetHandler(this, ui::EventTarget::Priority::kSystem); + QuickAnswersView* view) + : view_(view) { + Init(); +} + +QuickAnswersPreTargetHandler::QuickAnswersPreTargetHandler( + quick_answers::UserConsentView* view) + : view_(view) { + Init(); } QuickAnswersPreTargetHandler::~QuickAnswersPreTargetHandler() { Shell::Get()->RemovePreTargetHandler(this); } +void QuickAnswersPreTargetHandler::Init() { + // QuickAnswersView is a companion view of a menu. Menu host widget sets + // mouse capture as well as a pre-target handler, so we need to register one + // here as well to intercept events for QuickAnswersView. + Shell::Get()->AddPreTargetHandler(this, ui::EventTarget::Priority::kSystem); + view_->AddObserver(this); +} + void QuickAnswersPreTargetHandler::OnEvent(ui::Event* event) { if (!event->IsLocatedEvent()) return; @@ -37,14 +50,13 @@ // `ET_MOUSE_MOVED` events outside the top-view's bounds are also dispatched // to clear any set hover-state. - bool dispatch_event = - (quick_answers_view_->GetBoundsInScreen().Contains(location) || - to_dispatch->type() == ui::EventType::ET_MOUSE_MOVED); + bool dispatch_event = (view_->GetBoundsInScreen().Contains(location) || + to_dispatch->type() == ui::EventType::ET_MOUSE_MOVED); if (dispatch_event) { // Convert to local coordinates and forward to the top-view. - views::View::ConvertPointFromScreen(quick_answers_view_, &location); + views::View::ConvertPointFromScreen(view_, &location); to_dispatch->set_location(location); - ui::Event::DispatcherApi(to_dispatch).set_target(quick_answers_view_); + ui::Event::DispatcherApi(to_dispatch).set_target(view_); // Convert touch-event to gesture before dispatching since views do not // process touch-events. @@ -56,21 +68,36 @@ to_dispatch = gesture_event.get(); } - DoDispatchEvent(quick_answers_view_, to_dispatch); + DoDispatchEvent(view_, to_dispatch); - // Clicks outside menu-bounds (including those inside QuickAnswersView) - // can dismiss the menu. Some click-events, like those meant for the - // retry-button, should not be propagated to the menu to prevent so. - if (quick_answers_view_->preempt_last_click_event()) + // Clicks inside Quick-Answers views can dismiss the menu since they are + // outside menu-bounds and are thus not propagated to it to prevent so. + // Active menu instance will instead be cancelled when |view_| is deleted. + if (event->type() != ui::ET_MOUSE_MOVED) event->StopPropagation(); } // Show tooltips. - auto* tooltip_manager = quick_answers_view_->GetWidget()->GetTooltipManager(); + auto* tooltip_manager = view_->GetWidget()->GetTooltipManager(); if (tooltip_manager) tooltip_manager->UpdateTooltip(); } +void QuickAnswersPreTargetHandler::OnViewIsDeleting( + views::View* observed_view) { + DCHECK_EQ(observed_view, view_); + + // Cancel any active context-menus, the deleting Quick-Answers view is a + // companion-view of which, unless it requests otherwise for some cases. + if (dismiss_anchor_menu_on_view_closed_) { + auto* active_menu_instance = views::MenuController::GetActiveInstance(); + if (active_menu_instance) + active_menu_instance->Cancel(views::MenuController::ExitType::kAll); + } + view_->RemoveObserver(this); +} + +// TODO(siabhijeet): Investigate using SendEventsToSink() for dispatching. bool QuickAnswersPreTargetHandler::DoDispatchEvent(views::View* view, ui::LocatedEvent* event) { DCHECK(view && event);
diff --git a/ash/quick_answers/ui/quick_answers_pre_target_handler.h b/ash/quick_answers/ui/quick_answers_pre_target_handler.h index 0c9d28c..1f30e0eb 100644 --- a/ash/quick_answers/ui/quick_answers_pre_target_handler.h +++ b/ash/quick_answers/ui/quick_answers_pre_target_handler.h
@@ -6,6 +6,7 @@ #define ASH_QUICK_ANSWERS_UI_QUICK_ANSWERS_PRE_TARGET_HANDLER_H_ #include "ui/events/event_handler.h" +#include "ui/views/view_observer.h" namespace ui { class LocatedEvent; @@ -19,12 +20,18 @@ class QuickAnswersView; +namespace quick_answers { +class UserConsentView; +} // namespace quick_answers + // This class handles mouse events, and update background color or // dismiss quick answers view. // TODO (siabhijeet): Migrate to using two-phased event dispatching. -class QuickAnswersPreTargetHandler : public ui::EventHandler { +class QuickAnswersPreTargetHandler : public ui::EventHandler, + public views::ViewObserver { public: - explicit QuickAnswersPreTargetHandler(QuickAnswersView* quick_answers_view); + explicit QuickAnswersPreTargetHandler(QuickAnswersView* view); + explicit QuickAnswersPreTargetHandler(quick_answers::UserConsentView* view); // Disallow copy and assign. QuickAnswersPreTargetHandler(const QuickAnswersPreTargetHandler&) = delete; @@ -36,11 +43,25 @@ // ui::EventHandler: void OnEvent(ui::Event* event) override; + // views::ViewObserver: + void OnViewIsDeleting(views::View* observed_view) override; + + void set_dismiss_anchor_menu_on_view_closed(bool dismiss) { + dismiss_anchor_menu_on_view_closed_ = dismiss; + } + private: + void Init(); + // Returns true if event was consumed by |view| or its children. bool DoDispatchEvent(views::View* view, ui::LocatedEvent* event); - QuickAnswersView* quick_answers_view_; + // Associated view handled by this class. + views::View* const view_; + + // Whether any active menus, |view_| is a companion Quick-Answers related view + // of which, should be dismissed when it is deleted. + bool dismiss_anchor_menu_on_view_closed_ = true; }; } // namespace ash
diff --git a/ash/quick_answers/ui/quick_answers_view.cc b/ash/quick_answers/ui/quick_answers_view.cc index 92a22a82..be5d4ce5 100644 --- a/ash/quick_answers/ui/quick_answers_view.cc +++ b/ash/quick_answers/ui/quick_answers_view.cc
@@ -166,14 +166,12 @@ void QuickAnswersView::ButtonPressed(views::Button* sender, const ui::Event& event) { - preempt_last_click_event_ = false; if (sender == dogfood_button_) { controller_->OnDogfoodButtonPressed(); return; } if (sender == retry_label_) { controller_->OnRetryLabelPressed(); - preempt_last_click_event_ = true; return; } if (sender == this) {
diff --git a/ash/quick_answers/ui/quick_answers_view.h b/ash/quick_answers/ui/quick_answers_view.h index 61d17c5..cc62c1dc 100644 --- a/ash/quick_answers/ui/quick_answers_view.h +++ b/ash/quick_answers/ui/quick_answers_view.h
@@ -60,8 +60,6 @@ void ShowRetryView(); - bool preempt_last_click_event() const { return preempt_last_click_event_; } - private: void InitLayout(); void InitWidget(); @@ -79,7 +77,6 @@ gfx::Rect anchor_view_bounds_; QuickAnswersUiController* const controller_; bool has_second_row_answer_ = false; - bool preempt_last_click_event_ = false; std::string title_; views::View* main_view_ = nullptr; views::View* content_view_ = nullptr;
diff --git a/ash/quick_answers/ui/user_consent_view.cc b/ash/quick_answers/ui/user_consent_view.cc index b54b4dc3..859c4ce 100644 --- a/ash/quick_answers/ui/user_consent_view.cc +++ b/ash/quick_answers/ui/user_consent_view.cc
@@ -6,6 +6,7 @@ #include "ash/public/cpp/vector_icons/vector_icons.h" #include "ash/quick_answers/quick_answers_ui_controller.h" +#include "ash/quick_answers/ui/quick_answers_pre_target_handler.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" @@ -111,71 +112,12 @@ } // namespace -// UserConsentViewPreTargetHandler --------------------------------------------- - -// TODO(siabhijeet): Reuse pre-target handler for QuickAnswersView. -class UserConsentViewPreTargetHandler : public ui::EventHandler { - public: - explicit UserConsentViewPreTargetHandler(UserConsentView* view) - : view_(view) { - Shell::Get()->AddPreTargetHandler(this); - } - - ~UserConsentViewPreTargetHandler() override { - Shell::Get()->RemovePreTargetHandler(this); - } - - UserConsentViewPreTargetHandler(const UserConsentViewPreTargetHandler&) = - delete; - UserConsentViewPreTargetHandler& operator=( - const UserConsentViewPreTargetHandler&) = delete; - - // ui::EventHandler: - void OnEvent(ui::Event* event) override { - if (!event->IsLocatedEvent()) - return; - auto* located_event = event->AsLocatedEvent(); - auto location = located_event->target()->GetScreenLocation(*located_event); - if (view_->GetBoundsInScreen().Contains(location)) { - DoDispatchEvent(view_, located_event); - event->StopPropagation(); - auto* tooltip_manager = view_->GetWidget()->GetTooltipManager(); - if (tooltip_manager) - tooltip_manager->UpdateTooltip(); - } - } - - private: - // TODO(siabhijeet): Investigate using SendEventsToSink() instead. - bool DoDispatchEvent(views::View* view, ui::LocatedEvent* event) { - if (event->handled()) - return true; - - // Convert |event| to local coordinates of |view|. - gfx::Point location = event->target()->GetScreenLocation(*event); - views::View::ConvertPointFromScreen(view, &location); - event->set_location(location); - ui::Event::DispatcherApi(event).set_target(view); - - // Process event and dispatch on children recursively. - view->OnEvent(event); - for (auto* child : view->children()) { - if (DoDispatchEvent(child, event)) - return true; - } - return false; - } - - // Associated view handled by this class. - UserConsentView* const view_; -}; - // UserConsentView ------------------------------------------------------------- UserConsentView::UserConsentView(const gfx::Rect& anchor_view_bounds, QuickAnswersUiController* ui_controller) : anchor_view_bounds_(anchor_view_bounds), - event_handler_(std::make_unique<UserConsentViewPreTargetHandler>(this)), + event_handler_(std::make_unique<QuickAnswersPreTargetHandler>(this)), ui_controller_(ui_controller) { InitLayout(); InitWidget(); @@ -201,6 +143,9 @@ void UserConsentView::ButtonPressed(views::Button* sender, const ui::Event& event) { if (sender == consent_button_) { + // When user-consent is acknowledged, QuickAnswersView will be displayed + // instead of dismissing the menu. + event_handler_->set_dismiss_anchor_menu_on_view_closed(false); ui_controller_->OnConsentGrantedButtonPressed(); return; }
diff --git a/ash/quick_answers/ui/user_consent_view.h b/ash/quick_answers/ui/user_consent_view.h index c55b13d..9440de9 100644 --- a/ash/quick_answers/ui/user_consent_view.h +++ b/ash/quick_answers/ui/user_consent_view.h
@@ -18,6 +18,7 @@ namespace ash { class QuickAnswersUiController; +class QuickAnswersPreTargetHandler; namespace quick_answers { @@ -54,7 +55,7 @@ // Cached bounds of the anchor this view is tied to. gfx::Rect anchor_view_bounds_; - std::unique_ptr<EventHandler> event_handler_; + std::unique_ptr<QuickAnswersPreTargetHandler> event_handler_; QuickAnswersUiController* const ui_controller_; // Owned by view hierarchy.
diff --git a/ash/shelf/shelf_view.cc b/ash/shelf/shelf_view.cc index 1c5a5d7..b23535da 100644 --- a/ash/shelf/shelf_view.cc +++ b/ash/shelf/shelf_view.cc
@@ -672,10 +672,19 @@ last_pressed_index_ = view_model_->GetIndexOfView(sender); DCHECK_LT(-1, last_pressed_index_); - // Place new windows on the same display as the button. + // Place new windows on the same display as the button. Opening windows is + // usually an async operation so we wait until window activation changes + // (ShelfItemStatusChanged) before destroying the scoped object. Post a task + // to destroy the scoped object just in case the window activation event does + // not get fired. aura::Window* window = sender->GetWidget()->GetNativeWindow(); scoped_root_window_for_new_windows_ = std::make_unique<ScopedRootWindowForNewWindows>(window->GetRootWindow()); + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce(&ShelfView::DestroyScopedRootWindow, + weak_factory_.GetWeakPtr()), + base::TimeDelta::FromMilliseconds(100)); // Slow down activation animations if Control key is pressed. std::unique_ptr<ui::ScopedAnimationDurationScaleMode> slowing_animations; @@ -1920,6 +1929,8 @@ } void ShelfView::ShelfItemStatusChanged(const ShelfID& id) { + scoped_root_window_for_new_windows_.reset(); + int index = model_->ItemIndexByID(id); if (index < 0) return; @@ -2005,7 +2016,6 @@ } } shelf_->shelf_layout_manager()->OnShelfItemSelected(action); - scoped_root_window_for_new_windows_.reset(); } void ShelfView::ShowShelfContextMenu( @@ -2185,4 +2195,8 @@ last_visible_index_ = model_->item_count() - 1; } +void ShelfView::DestroyScopedRootWindow() { + scoped_root_window_for_new_windows_.reset(); +} + } // namespace ash
diff --git a/ash/shelf/shelf_view.h b/ash/shelf/shelf_view.h index 1c5176c0..e7579d34 100644 --- a/ash/shelf/shelf_view.h +++ b/ash/shelf/shelf_view.h
@@ -487,6 +487,8 @@ bool ShouldHandleGestures(const ui::GestureEvent& event) const; + void DestroyScopedRootWindow(); + // Different from GetTitleForView, |view| here must be a child view. base::string16 GetTitleForChildView(const views::View* view) const; @@ -542,6 +544,9 @@ // Responsible for building and running all menus. std::unique_ptr<ShelfMenuModelAdapter> shelf_menu_model_adapter_; + + // Created when a shelf icon is pressed, so that new windows will be on the + // same root window as the press event. std::unique_ptr<ScopedRootWindowForNewWindows> scoped_root_window_for_new_windows_;
diff --git a/ash/shell_delegate.cc b/ash/shell_delegate.cc index 6dccd69..6fe43b7 100644 --- a/ash/shell_delegate.cc +++ b/ash/shell_delegate.cc
@@ -6,6 +6,10 @@ namespace ash { +bool ShellDelegate::IsTabDrag(const ui::OSExchangeData& drop_data) { + return false; +} + aura::Window* ShellDelegate::CreateBrowserForTabDrop( aura::Window* source_window, const ui::OSExchangeData& drop_data) {
diff --git a/ash/shell_delegate.h b/ash/shell_delegate.h index 8498f86..b84c2e01 100644 --- a/ash/shell_delegate.h +++ b/ash/shell_delegate.h
@@ -58,6 +58,11 @@ // Check whether the current tab of the browser window can go back. virtual bool CanGoBack(gfx::NativeWindow window) const = 0; + // Checks whether a drag-drop operation is a tab drag. + virtual bool IsTabDrag(const ui::OSExchangeData& drop_data); + + // Drops tab in a new browser window. |drop_data| must be from a tab + // drag as determined by IsTabDrag() above. virtual aura::Window* CreateBrowserForTabDrop( aura::Window* source_window, const ui::OSExchangeData& drop_data);
diff --git a/ash/system/accessibility/floating_accessibility_view.cc b/ash/system/accessibility/floating_accessibility_view.cc index 3da7a3d2..f8f7841 100644 --- a/ash/system/accessibility/floating_accessibility_view.cc +++ b/ash/system/accessibility/floating_accessibility_view.cc
@@ -18,6 +18,7 @@ #include "ash/system/accessibility/select_to_speak_tray.h" #include "ash/system/tray/tray_constants.h" #include "ash/system/virtual_keyboard/virtual_keyboard_tray.h" +#include "ui/base/l10n/l10n_util.h" #include "ui/views/controls/separator.h" #include "ui/views/layout/box_layout.h" @@ -67,6 +68,26 @@ return button_container; } +std::string GetDescriptionForMovedToPosition(FloatingMenuPosition position) { + switch (position) { + case FloatingMenuPosition::kBottomRight: + return l10n_util::GetStringUTF8( + IDS_ASH_FLOATING_ACCESSIBILITY_MAIN_MENU_MOVED_BOTTOM_RIGHT); + case FloatingMenuPosition::kBottomLeft: + return l10n_util::GetStringUTF8( + IDS_ASH_FLOATING_ACCESSIBILITY_MAIN_MENU_MOVED_BOTTOM_LEFT); + case FloatingMenuPosition::kTopLeft: + return l10n_util::GetStringUTF8( + IDS_ASH_FLOATING_ACCESSIBILITY_MAIN_MENU_MOVED_TOP_LEFT); + case FloatingMenuPosition::kTopRight: + return l10n_util::GetStringUTF8( + IDS_ASH_FLOATING_ACCESSIBILITY_MAIN_MENU_MOVED_TOP_RIGHT); + case FloatingMenuPosition::kSystemDefault: + NOTREACHED(); + return std::string(); + } +} + } // namespace FloatingAccessibilityBubbleView::FloatingAccessibilityBubbleView( @@ -214,6 +235,10 @@ } Shell::Get()->accessibility_controller()->SetFloatingMenuPosition( new_position); + Shell::Get() + ->accessibility_controller() + ->TriggerAccessibilityAlertWithMessage( + GetDescriptionForMovedToPosition(new_position)); } return; }
diff --git a/base/callback_list.h b/base/callback_list.h index cd4f695..15cf0b29 100644 --- a/base/callback_list.h +++ b/base/callback_list.h
@@ -70,12 +70,36 @@ namespace base { +template <typename Signature> +class OnceCallbackList; + +template <typename Signature> +class RepeatingCallbackList; + namespace internal { -template <typename CallbackListImpl, typename T> +// A traits class to break circular type dependencies between CallbackListBase +// and its subclasses. +template <typename CallbackList> +struct CallbackListTraits; + +template <typename Signature> +struct CallbackListTraits<OnceCallbackList<Signature>> { + using CallbackType = OnceCallback<Signature>; + using Callbacks = std::list<CallbackType>; +}; + +template <typename Signature> +struct CallbackListTraits<RepeatingCallbackList<Signature>> { + using CallbackType = RepeatingCallback<Signature>; + using Callbacks = std::list<CallbackType>; +}; + +template <typename CallbackListImpl> class CallbackListBase { public: - using CallbackType = T; + using CallbackType = + typename CallbackListTraits<CallbackListImpl>::CallbackType; static_assert(IsBaseCallback<CallbackType>::value, ""); // A cancellation handle for callers who register callbacks. Subscription @@ -172,7 +196,7 @@ } protected: - using Callbacks = std::list<CallbackType>; + using Callbacks = typename CallbackListTraits<CallbackListImpl>::Callbacks; // Holds non-null callbacks, which will be called during Notify(). Callbacks callbacks_; @@ -210,26 +234,24 @@ template <typename Signature> class OnceCallbackList - : public internal::CallbackListBase<OnceCallbackList<Signature>, - OnceCallback<Signature>> { + : public internal::CallbackListBase<OnceCallbackList<Signature>> { private: - using Base = internal::CallbackListBase<OnceCallbackList<Signature>, - OnceCallback<Signature>>; - friend Base; + friend internal::CallbackListBase<OnceCallbackList>; + using Traits = internal::CallbackListTraits<OnceCallbackList>; // Runs the current callback, which may cancel it or any other callbacks. template <typename... RunArgs> - void RunCallback(typename Base::Callbacks::iterator it, RunArgs&&... args) { + void RunCallback(typename Traits::Callbacks::iterator it, RunArgs&&... args) { // OnceCallbacks still have Subscriptions with outstanding iterators; // splice() removes them from |callbacks_| without invalidating those. - null_callbacks_.splice(null_callbacks_.end(), Base::callbacks_, it); + null_callbacks_.splice(null_callbacks_.end(), this->callbacks_, it); std::move(*it).Run(args...); } // If |it| refers to an already-canceled callback, does any necessary cleanup // and returns true. Otherwise returns false. - bool CancelNullCallback(const typename Base::Callbacks::iterator& it) { + bool CancelNullCallback(const typename Traits::Callbacks::iterator& it) { if (it->is_null()) { null_callbacks_.erase(it); return true; @@ -241,27 +263,24 @@ // Subscriptions will still contain valid iterators. Only needed for // OnceCallbacks, since RepeatingCallbacks are not canceled except by // Subscription destruction. - typename Base::Callbacks null_callbacks_; + typename Traits::Callbacks null_callbacks_; }; template <typename Signature> class RepeatingCallbackList - : public internal::CallbackListBase<RepeatingCallbackList<Signature>, - RepeatingCallback<Signature>> { + : public internal::CallbackListBase<RepeatingCallbackList<Signature>> { private: - using Base = internal::CallbackListBase<RepeatingCallbackList<Signature>, - RepeatingCallback<Signature>>; - friend Base; - + friend internal::CallbackListBase<RepeatingCallbackList>; + using Traits = internal::CallbackListTraits<RepeatingCallbackList>; // Runs the current callback, which may cancel it or any other callbacks. template <typename... RunArgs> - void RunCallback(typename Base::Callbacks::iterator it, RunArgs&&... args) { + void RunCallback(typename Traits::Callbacks::iterator it, RunArgs&&... args) { it->Run(args...); } // If |it| refers to an already-canceled callback, does any necessary cleanup // and returns true. Otherwise returns false. - bool CancelNullCallback(const typename Base::Callbacks::iterator& it) { + bool CancelNullCallback(const typename Traits::Callbacks::iterator& it) { // Because at most one Subscription can point to a given callback, and // RepeatingCallbacks are only reset by CancelCallback(), no one should be // able to request cancellation of a canceled RepeatingCallback.
diff --git a/base/compiler_specific.h b/base/compiler_specific.h index 87356b5..c8a7649 100644 --- a/base/compiler_specific.h +++ b/base/compiler_specific.h
@@ -47,6 +47,20 @@ #define ALWAYS_INLINE inline #endif +// Annotate a function indicating it should never be tail called. Useful to make +// sure callers of the annotated function are never omitted from call-stacks. +// To provide the complementary behavior (prevent the annotated function from +// being omitted) look at NOINLINE. Also note that this doesn't prevent code +// folding of multiple identical caller functions into a single signature. To +// prevent code folding, see base::debug::Alias. +// Use like: +// void NOT_TAIL_CALLED FooBar(); +#if defined(__clang__) && __has_attribute(not_tail_called) +#define NOT_TAIL_CALLED __attribute__((not_tail_called)) +#else +#define NOT_TAIL_CALLED +#endif + // Specify memory alignment for structs, classes, etc. // Use like: // class ALIGNAS(16) MyClass { ... }
diff --git a/base/containers/circular_deque.h b/base/containers/circular_deque.h index 07476d2..6c2c3a88 100644 --- a/base/containers/circular_deque.h +++ b/base/containers/circular_deque.h
@@ -522,11 +522,11 @@ return buffer_[i - right_size]; } value_type& at(size_type i) { - return const_cast<value_type&>(as_const(*this).at(i)); + return const_cast<value_type&>(base::as_const(*this).at(i)); } value_type& operator[](size_type i) { - return const_cast<value_type&>(as_const(*this)[i]); + return const_cast<value_type&>(base::as_const(*this)[i]); } const value_type& operator[](size_type i) const { return at(i); }
diff --git a/base/debug/alias.h b/base/debug/alias.h index a7a1827..cdd2372 100644 --- a/base/debug/alias.h +++ b/base/debug/alias.h
@@ -12,22 +12,59 @@ namespace base { namespace debug { -// Make the optimizer think that var is aliased. This is to prevent it from -// optimizing out local variables that would not otherwise be live at the point -// of a potential crash. -// base::debug::Alias should only be used for local variables, not globals, -// object members, or function return values - these must be copied to locals if -// you want to ensure they are recorded in crash dumps. -// Note that if the local variable is a pointer then its value will be retained -// but the memory that it points to will probably not be saved in the crash -// dump - by default only stack memory is saved. Therefore the aliasing -// technique is usually only worthwhile with non-pointer variables. If you have -// a pointer to an object and you want to retain the object's state you need to -// copy the object or its fields to local variables. Example usage: +// Make the optimizer think that |var| is aliased. This can be used to inhibit +// three different kinds of optimizations: +// +// Case #1: Prevent a local variable from being optimized out if it would not +// otherwise be live at the point of a potential crash. This can only be done +// with local variables, not globals, object members, or function return values +// - these must be copied to locals if you want to ensure they are recorded in +// crash dumps. Note that if the local variable is a pointer then its value will +// be retained but the memory that it points to will probably not be saved in +// the crash dump - by default only stack memory is saved. Therefore the +// aliasing technique is usually only worthwhile with non-pointer variables. If +// you have a pointer to an object and you want to retain the object's state you +// need to copy the object or its fields to local variables. +// +// Example usage: // int last_error = err_; // base::debug::Alias(&last_error); // DEBUG_ALIAS_FOR_CSTR(name_copy, p->name, 16); // CHECK(false); +// +// Case #2: Prevent a tail call into a function. This is useful to make sure the +// function containing the call to base::debug::Alias() will be present in the +// call stack. In this case there is no memory that needs to be on +// the stack so we can use nullptr. The call to base::debug::Alias() needs to +// happen after the call that is suspected to be tail called. Note: This +// technique will prevent taill calls at the specific call site only. To prevent +// them for all invocations of a function look at NOT_TAIL_CALLED. +// +// Example usage: +// NOINLINE void Foo(){ +// ... code ... +// +// Bar(); +// base::debug::Alias(nullptr); +// } +// +// Case #3: Prevent code folding of a non-unique function. Code folding can +// cause the same address to be assigned to different functions if they are +// identical. If finding the precise signature of a function in the call-stack +// is important and it's suspected the function is identical to other functions +// it can be made unique using base::debug::Alias(). +// +// Example usage: +// NOINLINE void Foo(){ +// Bar(); +// const int line_number = __LINE__; +// base::debug::Alias(&line_number); +// } +// +// Finally please note that these effects compound. This means that saving a +// stack variable (case #1) using base::debug::Alias() will also inhibit +// tail calls for calls in earlier lines and prevent code folding. + void BASE_EXPORT Alias(const void* var); } // namespace debug
diff --git a/base/debug/dump_without_crashing.h b/base/debug/dump_without_crashing.h index 7c00719a..7c291be 100644 --- a/base/debug/dump_without_crashing.h +++ b/base/debug/dump_without_crashing.h
@@ -25,14 +25,10 @@ // Crashpad does this as part of crash_reporter::InitializeCrashpad. // Returns false if called before SetDumpWithoutCrashingFunction. // -// This function must not be called with a tail-call because that would cause +// This function must not be called with a tail call because that would cause // the caller to be omitted from the call stack in the crash dump, and that is // confusing and omits what is likely the most important context. -#if defined(__clang__) && __has_attribute(not_tail_called) -BASE_EXPORT bool __attribute__((not_tail_called)) DumpWithoutCrashing(); -#else -BASE_EXPORT bool DumpWithoutCrashing(); -#endif +BASE_EXPORT bool NOT_TAIL_CALLED DumpWithoutCrashing(); // Sets a function that'll be invoked to dump the current process when // DumpWithoutCrashing() is called.
diff --git a/base/memory/checked_ptr.h b/base/memory/checked_ptr.h index d88470a..261c6b4c 100644 --- a/base/memory/checked_ptr.h +++ b/base/memory/checked_ptr.h
@@ -36,13 +36,22 @@ // Unwraps the pointer's uintptr_t representation, while asserting that memory // hasn't been freed. The function is allowed to crash on nullptr. - static ALWAYS_INLINE void* SafelyUnwrapPtr(uintptr_t wrapped_ptr) { + static ALWAYS_INLINE void* SafelyUnwrapPtrForDereference( + uintptr_t wrapped_ptr) { return reinterpret_cast<void*>(wrapped_ptr); } // Unwraps the pointer's uintptr_t representation, while asserting that memory // hasn't been freed. The function must handle nullptr gracefully. - static ALWAYS_INLINE void* SafelyUnwrapPtrMayBeNull(uintptr_t wrapped_ptr) { + static ALWAYS_INLINE void* SafelyUnwrapPtrForExtraction( + uintptr_t wrapped_ptr) { + return reinterpret_cast<void*>(wrapped_ptr); + } + + // Unwraps the pointer's uintptr_t representation, without making an assertion + // on whether memory was freed or not. + static ALWAYS_INLINE void* UnsafelyUnwrapPtrForComparison( + uintptr_t wrapped_ptr) { return reinterpret_cast<void*>(wrapped_ptr); } @@ -50,18 +59,6 @@ static ALWAYS_INLINE uintptr_t Advance(uintptr_t wrapped_ptr, size_t delta) { return wrapped_ptr + delta; } - - // Checks if wrapped pointers are equal. The pointers can be nullptr. - static ALWAYS_INLINE bool AreEqual(uintptr_t wrapped_ptr1, - uintptr_t wrapped_ptr2) { - return wrapped_ptr1 == wrapped_ptr2; - } - - // Checks if a wrapped pointer is equal to a raw pointer. The pointers - // can be nullptr. - static ALWAYS_INLINE bool AreEqual(uintptr_t wrapped_ptr, const void* ptr) { - return reinterpret_cast<void*>(wrapped_ptr) == ptr; - } }; template <typename T> @@ -89,10 +86,8 @@ // 2. Keep this class as small as possible, while still satisfying goal #1 (i.e. // we aren't striving to maximize compatibility with raw pointers, merely // adding support for cases encountered so far). -template <typename T> +template <typename T, typename Impl = internal::CheckedPtrNoOpImpl> class CheckedPtr { - using Impl = internal::CheckedPtrNoOpImpl; - public: // CheckedPtr can be trivially default constructed (leaving |wrapped_ptr_| // uninitialized). This is needed for compatibility with raw pointers. @@ -129,7 +124,7 @@ // Avoid using. The goal of CheckedPtr is to be as close to raw pointer as // possible, so use it only if absolutely necessary (e.g. for const_cast). - ALWAYS_INLINE T* get() const { return GetMayBeNull(); } + ALWAYS_INLINE T* get() const { return GetForExtraction(); } explicit ALWAYS_INLINE operator bool() const { return wrapped_ptr_ != Impl::GetWrappedNullPtr(); @@ -140,15 +135,15 @@ template <typename U = T, typename V = typename internal::DereferencedPointerType<U>::Type> ALWAYS_INLINE V& operator*() const { - return *GetOkToCrashOnNull(); + return *GetForDereference(); } - ALWAYS_INLINE T* operator->() const { return GetOkToCrashOnNull(); } + ALWAYS_INLINE T* operator->() const { return GetForDereference(); } // Deliberately implicit, because CheckedPtr is supposed to resemble raw ptr. // NOLINTNEXTLINE(runtime/explicit) - ALWAYS_INLINE operator T*() const { return GetMayBeNull(); } + ALWAYS_INLINE operator T*() const { return GetForExtraction(); } template <typename U> explicit ALWAYS_INLINE operator U*() const { - return static_cast<U*>(GetMayBeNull()); + return static_cast<U*>(GetForExtraction()); } ALWAYS_INLINE CheckedPtr& operator++() { @@ -170,24 +165,43 @@ return *this += -delta_elems; } - ALWAYS_INLINE bool operator==(T* p) const { - return Impl::AreEqual(wrapped_ptr_, p); - } + ALWAYS_INLINE bool operator==(T* p) const { return GetForComparison() == p; } ALWAYS_INLINE bool operator!=(T* p) const { return !operator==(p); } + + // Useful for cases like this: + // class Base {}; + // class Derived : public Base {}; + // Derived d; + // CheckedPtr<Derived> derived_ptr = &d; + // Base* base_ptr = &d; + // if (derived_ptr == base_ptr) {...} + // Without these, such comparisons would end up calling |operator T*()|. + template <typename U> + ALWAYS_INLINE bool operator==(U* p) const { + // Add |const| when casting, because |U| may have |const| in it. Even if |T| + // doesn't, comparison between |T*| and |const T*| is fine. + return GetForComparison() == static_cast<std::add_const_t<T>*>(p); + } + template <typename U> + ALWAYS_INLINE bool operator!=(U* p) const { + return !operator==(p); + } + ALWAYS_INLINE bool operator==(const CheckedPtr& other) const { - return Impl::AreEqual(wrapped_ptr_, other.wrapped_ptr_); + return GetForComparison() == other.GetForComparison(); } ALWAYS_INLINE bool operator!=(const CheckedPtr& other) const { return !operator==(other); } - template <typename U> - ALWAYS_INLINE bool operator==(const CheckedPtr<U>& other) const { - // TODO(bartekn): Eliminate unwrapping |other| (which cast does), because it - // may check if the pointer was freed. - return Impl::AreEqual(wrapped_ptr_, static_cast<T*>(other)); + template <typename U, typename I> + ALWAYS_INLINE bool operator==(const CheckedPtr<U, I>& other) const { + // Add |const| when casting, because |U| may have |const| in it. Even if |T| + // doesn't, comparison between |T*| and |const T*| is fine. + return GetForComparison() == + static_cast<std::add_const_t<T>*>(other.GetForComparison()); } - template <typename U> - ALWAYS_INLINE bool operator!=(const CheckedPtr<U>& other) const { + template <typename U, typename I> + ALWAYS_INLINE bool operator!=(const CheckedPtr<U, I>& other) const { return !operator==(other); } @@ -196,23 +210,54 @@ } private: - // This getter is meant for situations where the pointers is merely read, not - // necessarily with intention to dereference. It doesn't crash on nullptr. - ALWAYS_INLINE T* GetMayBeNull() const { - return static_cast<T*>(Impl::SafelyUnwrapPtrMayBeNull(wrapped_ptr_)); - } - // This getter is meant for situations where the pointers is meant to be + // This getter is meant for situations where the pointer is meant to be // dereferenced. It is allowed to crash on nullptr (it may or may not), // because it knows that the caller will crash on nullptr. - ALWAYS_INLINE T* GetOkToCrashOnNull() const { - return static_cast<T*>(Impl::SafelyUnwrapPtr(wrapped_ptr_)); + ALWAYS_INLINE T* GetForDereference() const { + return static_cast<T*>(Impl::SafelyUnwrapPtrForDereference(wrapped_ptr_)); + } + // This getter is meant for situations where the raw pointer is meant to be + // extracted outside of this class, but not necessarily with an intention to + // dereference. It mustn't crash on nullptr. + ALWAYS_INLINE T* GetForExtraction() const { + return static_cast<T*>(Impl::SafelyUnwrapPtrForExtraction(wrapped_ptr_)); + } + // This getter is meant *only* for situations where the pointer is meant to be + // compared (guaranteeing no dereference or extraction outside of this class). + // Any verifications can and should be skipped for performance reasons. + ALWAYS_INLINE T* GetForComparison() const { + return static_cast<T*>(Impl::UnsafelyUnwrapPtrForComparison(wrapped_ptr_)); } // Store the pointer as |uintptr_t|, because depending on implementation, its // unused bits may be re-purposed to store extra information. uintptr_t wrapped_ptr_; + + template <typename U, typename V> + friend class CheckedPtr; }; +// These are for cases where a raw pointer is on the left hand side. Reverse +// order, so that |CheckedPtr::operator==()| kicks in, which will compare more +// efficiently. Otherwise the CheckedPtr operand would have to be cast to raw +// pointer, which may be more costly. +template <typename T, typename I> +ALWAYS_INLINE bool operator==(T* lhs, const CheckedPtr<T, I>& rhs) { + return rhs == lhs; +} +template <typename T, typename I> +ALWAYS_INLINE bool operator!=(T* lhs, const CheckedPtr<T, I>& rhs) { + return !operator==(lhs, rhs); +} +template <typename T, typename I, typename U> +ALWAYS_INLINE bool operator==(U* lhs, const CheckedPtr<T, I>& rhs) { + return rhs == lhs; +} +template <typename T, typename I, typename U> +ALWAYS_INLINE bool operator!=(U* lhs, const CheckedPtr<T, I>& rhs) { + return !operator==(lhs, rhs); +} + template <typename T> ALWAYS_INLINE void swap(CheckedPtr<T>& lhs, CheckedPtr<T>& rhs) noexcept { lhs.swap(rhs);
diff --git a/base/memory/checked_ptr_unittest.cc b/base/memory/checked_ptr_unittest.cc index b77851d..185f557 100644 --- a/base/memory/checked_ptr_unittest.cc +++ b/base/memory/checked_ptr_unittest.cc
@@ -49,6 +49,41 @@ namespace { +static int g_get_for_dereference_cnt = INT_MIN; +static int g_get_for_extraction_cnt = INT_MIN; +static int g_get_for_comparison_cnt = INT_MIN; + +static void ClearCounters() { + g_get_for_dereference_cnt = 0; + g_get_for_extraction_cnt = 0; + g_get_for_comparison_cnt = 0; +} + +struct CheckedPtrCountingNoOpImpl : base::internal::CheckedPtrNoOpImpl { + using Super = base::internal::CheckedPtrNoOpImpl; + + static ALWAYS_INLINE void* SafelyUnwrapPtrForDereference( + uintptr_t wrapped_ptr) { + ++g_get_for_dereference_cnt; + return Super::SafelyUnwrapPtrForDereference(wrapped_ptr); + } + + static ALWAYS_INLINE void* SafelyUnwrapPtrForExtraction( + uintptr_t wrapped_ptr) { + ++g_get_for_extraction_cnt; + return Super::SafelyUnwrapPtrForExtraction(wrapped_ptr); + } + + static ALWAYS_INLINE void* UnsafelyUnwrapPtrForComparison( + uintptr_t wrapped_ptr) { + ++g_get_for_comparison_cnt; + return Super::UnsafelyUnwrapPtrForComparison(wrapped_ptr); + } +}; + +template <typename T> +using CountingCheckedPtr = CheckedPtr<T, CheckedPtrCountingNoOpImpl>; + struct MyStruct { int x; }; @@ -145,50 +180,135 @@ } TEST(CheckedPtr, OperatorEQCast) { + ClearCounters(); int foo = 42; - CheckedPtr<int> int_ptr = &foo; - CheckedPtr<void> void_ptr = &foo; - EXPECT_TRUE(int_ptr == int_ptr); - EXPECT_TRUE(void_ptr == void_ptr); - EXPECT_TRUE(int_ptr == void_ptr); - EXPECT_TRUE(void_ptr == int_ptr); + const int* raw_int_ptr = &foo; + void* raw_void_ptr = &foo; + CountingCheckedPtr<int> checked_int_ptr = &foo; + CountingCheckedPtr<const void> checked_void_ptr = &foo; + EXPECT_TRUE(checked_int_ptr == checked_int_ptr); + EXPECT_TRUE(checked_int_ptr == raw_int_ptr); + EXPECT_TRUE(raw_int_ptr == checked_int_ptr); + EXPECT_TRUE(checked_void_ptr == checked_void_ptr); + EXPECT_TRUE(checked_void_ptr == raw_void_ptr); + EXPECT_TRUE(raw_void_ptr == checked_void_ptr); + EXPECT_TRUE(checked_int_ptr == checked_void_ptr); + EXPECT_TRUE(checked_int_ptr == raw_void_ptr); + EXPECT_TRUE(raw_int_ptr == checked_void_ptr); + EXPECT_TRUE(checked_void_ptr == checked_int_ptr); + EXPECT_TRUE(checked_void_ptr == raw_int_ptr); + EXPECT_TRUE(raw_void_ptr == checked_int_ptr); + // Make sure that all cases are handled by operator== (faster) and none by the + // cast operator (slower). + EXPECT_EQ(g_get_for_comparison_cnt, 16); + EXPECT_EQ(g_get_for_extraction_cnt, 0); + EXPECT_EQ(g_get_for_dereference_cnt, 0); + ClearCounters(); Derived derived_val(42, 84, 1024); - CheckedPtr<Derived> derived_ptr = &derived_val; - CheckedPtr<Base1> base1_ptr = &derived_val; - CheckedPtr<Base2> base2_ptr = &derived_val; - EXPECT_TRUE(derived_ptr == derived_ptr); - EXPECT_TRUE(derived_ptr == base1_ptr); - EXPECT_TRUE(base1_ptr == derived_ptr); + Derived* raw_derived_ptr = &derived_val; + const Base1* raw_base1_ptr = &derived_val; + Base2* raw_base2_ptr = &derived_val; + CountingCheckedPtr<const Derived> checked_derived_ptr = &derived_val; + CountingCheckedPtr<Base1> checked_base1_ptr = &derived_val; + CountingCheckedPtr<const Base2> checked_base2_ptr = &derived_val; + EXPECT_TRUE(checked_derived_ptr == checked_derived_ptr); + EXPECT_TRUE(checked_derived_ptr == raw_derived_ptr); + EXPECT_TRUE(raw_derived_ptr == checked_derived_ptr); + EXPECT_TRUE(checked_derived_ptr == checked_base1_ptr); + EXPECT_TRUE(checked_derived_ptr == raw_base1_ptr); + EXPECT_TRUE(raw_derived_ptr == checked_base1_ptr); + EXPECT_TRUE(checked_base1_ptr == checked_derived_ptr); + EXPECT_TRUE(checked_base1_ptr == raw_derived_ptr); + EXPECT_TRUE(raw_base1_ptr == checked_derived_ptr); // |base2_ptr| points to the second base class of |derived|, so will be // located at an offset. While the stored raw uinptr_t values shouldn't match, // ensure that the internal pointer manipulation correctly offsets when // casting up and down the class hierarchy. - EXPECT_NE(reinterpret_cast<uintptr_t>(base2_ptr.get()), - reinterpret_cast<uintptr_t>(derived_ptr.get())); - EXPECT_TRUE(derived_ptr == base2_ptr); - EXPECT_TRUE(base2_ptr == derived_ptr); + EXPECT_NE(reinterpret_cast<uintptr_t>(checked_base2_ptr.get()), + reinterpret_cast<uintptr_t>(checked_derived_ptr.get())); + EXPECT_NE(reinterpret_cast<uintptr_t>(raw_base2_ptr), + reinterpret_cast<uintptr_t>(checked_derived_ptr.get())); + EXPECT_NE(reinterpret_cast<uintptr_t>(checked_base2_ptr.get()), + reinterpret_cast<uintptr_t>(raw_derived_ptr)); + EXPECT_TRUE(checked_derived_ptr == checked_base2_ptr); + EXPECT_TRUE(checked_derived_ptr == raw_base2_ptr); + EXPECT_TRUE(raw_derived_ptr == checked_base2_ptr); + EXPECT_TRUE(checked_base2_ptr == checked_derived_ptr); + EXPECT_TRUE(checked_base2_ptr == raw_derived_ptr); + EXPECT_TRUE(raw_base2_ptr == checked_derived_ptr); + // Make sure that all cases are handled by operator== (faster) and none by the + // cast operator (slower). + // The 4 extractions come from .get() checks, that compare raw addresses. + EXPECT_EQ(g_get_for_comparison_cnt, 20); + EXPECT_EQ(g_get_for_extraction_cnt, 4); + EXPECT_EQ(g_get_for_dereference_cnt, 0); } TEST(CheckedPtr, OperatorNECast) { + ClearCounters(); int foo = 42; - CheckedPtr<int> int_ptr = &foo; - CheckedPtr<void> void_ptr = &foo; - EXPECT_FALSE(int_ptr != void_ptr); - EXPECT_FALSE(void_ptr != int_ptr); + int* raw_int_ptr = &foo; + const void* raw_void_ptr = &foo; + CountingCheckedPtr<const int> checked_int_ptr = &foo; + CountingCheckedPtr<void> checked_void_ptr = &foo; + EXPECT_FALSE(checked_int_ptr != checked_int_ptr); + EXPECT_FALSE(checked_int_ptr != raw_int_ptr); + EXPECT_FALSE(raw_int_ptr != checked_int_ptr); + EXPECT_FALSE(checked_void_ptr != checked_void_ptr); + EXPECT_FALSE(checked_void_ptr != raw_void_ptr); + EXPECT_FALSE(raw_void_ptr != checked_void_ptr); + EXPECT_FALSE(checked_int_ptr != checked_void_ptr); + EXPECT_FALSE(checked_int_ptr != raw_void_ptr); + EXPECT_FALSE(raw_int_ptr != checked_void_ptr); + EXPECT_FALSE(checked_void_ptr != checked_int_ptr); + EXPECT_FALSE(checked_void_ptr != raw_int_ptr); + EXPECT_FALSE(raw_void_ptr != checked_int_ptr); + // Make sure that all cases are handled by operator== (faster) and none by the + // cast operator (slower). + EXPECT_EQ(g_get_for_comparison_cnt, 16); + EXPECT_EQ(g_get_for_extraction_cnt, 0); + EXPECT_EQ(g_get_for_dereference_cnt, 0); + ClearCounters(); Derived derived_val(42, 84, 1024); - CheckedPtr<Derived> derived_ptr = &derived_val; - CheckedPtr<Base1> base1_ptr = &derived_val; - CheckedPtr<Base2> base2_ptr = &derived_val; - EXPECT_FALSE(derived_ptr != base1_ptr); - EXPECT_FALSE(base1_ptr != derived_ptr); - // base2_ptr is pointing in the middle of derived_ptr, thus having a different - // underlying address. Yet, they still should be equal. - EXPECT_EQ(reinterpret_cast<uintptr_t>(base2_ptr.get()), - reinterpret_cast<uintptr_t>(derived_ptr.get()) + 4); - EXPECT_FALSE(derived_ptr != base2_ptr); - EXPECT_FALSE(base2_ptr != derived_ptr); + const Derived* raw_derived_ptr = &derived_val; + Base1* raw_base1_ptr = &derived_val; + const Base2* raw_base2_ptr = &derived_val; + CountingCheckedPtr<Derived> checked_derived_ptr = &derived_val; + CountingCheckedPtr<const Base1> checked_base1_ptr = &derived_val; + CountingCheckedPtr<Base2> checked_base2_ptr = &derived_val; + EXPECT_FALSE(checked_derived_ptr != checked_derived_ptr); + EXPECT_FALSE(checked_derived_ptr != raw_derived_ptr); + EXPECT_FALSE(raw_derived_ptr != checked_derived_ptr); + EXPECT_FALSE(checked_derived_ptr != checked_base1_ptr); + EXPECT_FALSE(checked_derived_ptr != raw_base1_ptr); + EXPECT_FALSE(raw_derived_ptr != checked_base1_ptr); + EXPECT_FALSE(checked_base1_ptr != checked_derived_ptr); + EXPECT_FALSE(checked_base1_ptr != raw_derived_ptr); + EXPECT_FALSE(raw_base1_ptr != checked_derived_ptr); + // |base2_ptr| points to the second base class of |derived|, so will be + // located at an offset. While the stored raw uinptr_t values shouldn't match, + // ensure that the internal pointer manipulation correctly offsets when + // casting up and down the class hierarchy. + EXPECT_NE(reinterpret_cast<uintptr_t>(checked_base2_ptr.get()), + reinterpret_cast<uintptr_t>(checked_derived_ptr.get())); + EXPECT_NE(reinterpret_cast<uintptr_t>(raw_base2_ptr), + reinterpret_cast<uintptr_t>(checked_derived_ptr.get())); + EXPECT_NE(reinterpret_cast<uintptr_t>(checked_base2_ptr.get()), + reinterpret_cast<uintptr_t>(raw_derived_ptr)); + EXPECT_FALSE(checked_derived_ptr != checked_base2_ptr); + EXPECT_FALSE(checked_derived_ptr != raw_base2_ptr); + EXPECT_FALSE(raw_derived_ptr != checked_base2_ptr); + EXPECT_FALSE(checked_base2_ptr != checked_derived_ptr); + EXPECT_FALSE(checked_base2_ptr != raw_derived_ptr); + EXPECT_FALSE(raw_base2_ptr != checked_derived_ptr); + // Make sure that all cases are handled by operator== (faster) and none by the + // cast operator (slower). + // The 4 extractions come from .get() checks, that compare raw addresses. + EXPECT_EQ(g_get_for_comparison_cnt, 20); + EXPECT_EQ(g_get_for_extraction_cnt, 4); + EXPECT_EQ(g_get_for_dereference_cnt, 0); } TEST(CheckedPtr, Cast) {
diff --git a/base/message_loop/message_pump_win.cc b/base/message_loop/message_pump_win.cc index 8dad0838..83cbec1 100644 --- a/base/message_loop/message_pump_win.cc +++ b/base/message_loop/message_pump_win.cc
@@ -456,7 +456,7 @@ // dispatches the message and returns false. We return true in this // case to ensure that the message loop peeks again instead of calling // MsgWaitForMultipleObjectsEx. - bool sent_messages_in_queue = false; + bool more_work_is_plausible = false; { // Individually trace ::GetQueueStatus and ::PeekMessage because sampling // profiler is hinting that we're spending a surprising amount of time with @@ -468,7 +468,7 @@ "MessagePumpForUI::ProcessNextWindowsMessage GetQueueStatus"); DWORD queue_status = ::GetQueueStatus(QS_SENDMESSAGE); if (HIWORD(queue_status) & QS_SENDMESSAGE) - sent_messages_in_queue = true; + more_work_is_plausible = true; } MSG msg; @@ -483,19 +483,19 @@ static const auto kAdditionalFlags = FeatureList::IsEnabled(kNoYieldFromNativePeek) ? PM_NOYIELD : 0x0; - // PeekMessage can run a message if |sent_messages_in_queue|, trace that and + // PeekMessage can run a message if there are sent messages, trace that and // emit the boolean param to see if it ever janks independently (ref. // comment on GetQueueStatus). TRACE_EVENT1("base", "MessagePumpForUI::ProcessNextWindowsMessage PeekMessage", - "sent_messages_in_queue", sent_messages_in_queue); + "sent_messages_in_queue", more_work_is_plausible); has_msg = ::PeekMessage(&msg, nullptr, 0, 0, kAdditionalFlags | PM_REMOVE) != FALSE; } if (has_msg) - return ProcessMessageHelper(msg); + more_work_is_plausible |= ProcessMessageHelper(msg); - return sent_messages_in_queue; + return more_work_is_plausible; } bool MessagePumpForUI::ProcessMessageHelper(const MSG& msg) {
diff --git a/base/metrics/ukm_source_id.cc b/base/metrics/ukm_source_id.cc index 88bd082..3513b95 100644 --- a/base/metrics/ukm_source_id.cc +++ b/base/metrics/ukm_source_id.cc
@@ -4,6 +4,8 @@ #include "base/metrics/ukm_source_id.h" +#include <cmath> + #include "base/atomic_sequence_num.h" #include "base/check_op.h" #include "base/rand_util.h" @@ -13,8 +15,11 @@ namespace { const int64_t kLowBitsMask = (INT64_C(1) << 32) - 1; -const int64_t kNumTypeBits = static_cast<int64_t>(UkmSourceId::Type::kMaxValue); -const int64_t kTypeMask = (INT64_C(1) << kNumTypeBits) - 1; + +int64_t GetNumTypeBits() { + return std::ceil( + std::log2(static_cast<int64_t>(UkmSourceId::Type::kMaxValue) + 1)); +} } // namespace @@ -35,15 +40,24 @@ // static UkmSourceId UkmSourceId::FromOtherId(int64_t other_id, UkmSourceId::Type type) { + // Note on syntax: std::ceil and std::log2 are not constexpr functions thus + // these variables cannot be initialized statically in the global scope above. + // Function static initialization here is thread safe; so they are initialized + // at most once. + static const int64_t kNumTypeBits = GetNumTypeBits(); + static const int64_t kTypeMask = (INT64_C(1) << kNumTypeBits) - 1; + const int64_t type_bits = static_cast<int64_t>(type); DCHECK_EQ(type_bits, type_bits & kTypeMask); - // Stores the the type ID in the low bits of the source id, and shift the rest - // of the ID to make room. This could cause the original ID to overflow, but + // Stores the type of the source ID in its lower bits, and shift the rest of + // the ID to make room. This could cause the original ID to overflow, but // that should be rare enough that it won't matter for UKM's purposes. return UkmSourceId((other_id << kNumTypeBits) | type_bits); } UkmSourceId::Type UkmSourceId::GetType() const { + static const int64_t kNumTypeBits = GetNumTypeBits(); + static const int64_t kTypeMask = (INT64_C(1) << kNumTypeBits) - 1; return static_cast<UkmSourceId::Type>(value_ & kTypeMask); }
diff --git a/base/metrics/ukm_source_id.h b/base/metrics/ukm_source_id.h index 5368006..3ba01a0 100644 --- a/base/metrics/ukm_source_id.h +++ b/base/metrics/ukm_source_id.h
@@ -18,7 +18,7 @@ public: enum class Type : int64_t { // Source ids of this type are created via ukm::AssignNewSourceId, to denote - // 'custom' source other than the 4 types below. Source of this type has + // 'custom' source other than the types below. Source of this type has // additional restrictions with logging, as determined by // IsWhitelistedSourceId. UKM = 0,
diff --git a/base/process/launch_mac.cc b/base/process/launch_mac.cc index 62ffd51..6fc6ba1 100644 --- a/base/process/launch_mac.cc +++ b/base/process/launch_mac.cc
@@ -89,6 +89,10 @@ DPSXCHECK(posix_spawn_file_actions_addinherit_np(&file_actions_, filedes)); } + void Chdir(const char* path) API_AVAILABLE(macos(10.15)) { + DPSXCHECK(posix_spawn_file_actions_addchdir_np(&file_actions_, path)); + } + const posix_spawn_file_actions_t* get() const { return &file_actions_; } private: @@ -254,14 +258,19 @@ ? options.real_path.value().c_str() : argv_cstr[0]; - // If the new program has specified its PWD, change the thread-specific - // working directory. The new process will inherit it during posix_spawnp(). if (!options.current_directory.empty()) { - int rv = - ChangeCurrentThreadDirectory(options.current_directory.value().c_str()); - if (rv != 0) { - DPLOG(ERROR) << "pthread_chdir_np"; - return Process(); + const char* chdir_str = options.current_directory.value().c_str(); + if (__builtin_available(macOS 10.15, *)) { + file_actions.Chdir(chdir_str); + } else { + // If the chdir posix_spawn_file_actions extension is not available, + // change the thread-specific working directory. The new process will + // inherit it during posix_spawnp(). + int rv = ChangeCurrentThreadDirectory(chdir_str); + if (rv != 0) { + DPLOG(ERROR) << "pthread_chdir_np"; + return Process(); + } } } @@ -271,10 +280,10 @@ // If |options.mach_ports_for_rendezvous| is specified : the server's lock // must be held for the duration of posix_spawnp() so that new child's PID // can be recorded with the set of ports. - const bool has_mac_ports_for_rendezvous = + const bool has_mach_ports_for_rendezvous = !options.mach_ports_for_rendezvous.empty(); AutoLockMaybe rendezvous_lock( - has_mac_ports_for_rendezvous + has_mach_ports_for_rendezvous ? &MachPortRendezvousServer::GetInstance()->GetLock() : nullptr); @@ -282,7 +291,7 @@ rv = posix_spawnp(&pid, executable_path, file_actions.get(), attr.get(), &argv_cstr[0], new_environ); - if (has_mac_ports_for_rendezvous) { + if (has_mach_ports_for_rendezvous) { auto* rendezvous = MachPortRendezvousServer::GetInstance(); if (rv == 0) { rendezvous->RegisterPortsForPid(pid, options.mach_ports_for_rendezvous); @@ -301,7 +310,12 @@ // Restore the thread's working directory if it was changed. if (!options.current_directory.empty()) { - ResetCurrentThreadDirectory(); + if (__builtin_available(macOS 10.15, *)) { + // Nothing to do because no global state was changed, but + // __builtin_available is special and cannot be negated. + } else { + ResetCurrentThreadDirectory(); + } } if (rv != 0) {
diff --git a/base/task/common/task_annotator.h b/base/task/common/task_annotator.h index 7d8acf9c..30d18b1 100644 --- a/base/task/common/task_annotator.h +++ b/base/task/common/task_annotator.h
@@ -10,6 +10,7 @@ #include <memory> #include "base/base_export.h" +#include "base/compiler_specific.h" #include "base/macros.h" #include "base/pending_task.h" @@ -45,7 +46,8 @@ const char* task_queue_name); // Run a previously queued task. - void RunTask(const char* trace_event_name, PendingTask* pending_task); + void NOT_TAIL_CALLED RunTask(const char* trace_event_name, + PendingTask* pending_task); // Creates a process-wide unique ID to represent this task in trace events. // This will be mangled with a Process ID hash to reduce the likelyhood of
diff --git a/base/task/thread_pool/service_thread.cc b/base/task/thread_pool/service_thread.cc index 2b94745..6b4afa9a 100644 --- a/base/task/thread_pool/service_thread.cc +++ b/base/task/thread_pool/service_thread.cc
@@ -57,8 +57,9 @@ } NOINLINE void ServiceThread::Run(RunLoop* run_loop) { - const int line_number = __LINE__; Thread::Run(run_loop); + // Inhibit tail calls of Run and inhibit code folding. + const int line_number = __LINE__; base::debug::Alias(&line_number); }
diff --git a/base/task/thread_pool/task_tracker.cc b/base/task/thread_pool/task_tracker.cc index bccabc4..1b02bf0f 100644 --- a/base/task/thread_pool/task_tracker.cc +++ b/base/task/thread_pool/task_tracker.cc
@@ -12,7 +12,6 @@ #include "base/callback.h" #include "base/command_line.h" #include "base/compiler_specific.h" -#include "base/debug/alias.h" #include "base/json/json_writer.h" #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" @@ -760,21 +759,15 @@ } NOINLINE void TaskTracker::RunContinueOnShutdown(Task* task) { - const int line_number = __LINE__; task_annotator_.RunTask("ThreadPool_RunTask_ContinueOnShutdown", task); - base::debug::Alias(&line_number); } NOINLINE void TaskTracker::RunSkipOnShutdown(Task* task) { - const int line_number = __LINE__; task_annotator_.RunTask("ThreadPool_RunTask_SkipOnShutdown", task); - base::debug::Alias(&line_number); } NOINLINE void TaskTracker::RunBlockShutdown(Task* task) { - const int line_number = __LINE__; task_annotator_.RunTask("ThreadPool_RunTask_BlockShutdown", task); - base::debug::Alias(&line_number); } void TaskTracker::RunTaskWithShutdownBehavior(
diff --git a/base/task/thread_pool/worker_thread.cc b/base/task/thread_pool/worker_thread.cc index bfe31ef..79e5105 100644 --- a/base/task/thread_pool/worker_thread.cc +++ b/base/task/thread_pool/worker_thread.cc
@@ -220,63 +220,73 @@ } NOINLINE void WorkerThread::RunPooledWorker() { - const int line_number = __LINE__; RunWorker(); + // Inhibit tail calls of RunWorker and inhibit code folding. + const int line_number = __LINE__; base::debug::Alias(&line_number); } NOINLINE void WorkerThread::RunBackgroundPooledWorker() { - const int line_number = __LINE__; RunWorker(); + // Inhibit tail calls of RunWorker and inhibit code folding. + const int line_number = __LINE__; base::debug::Alias(&line_number); } NOINLINE void WorkerThread::RunSharedWorker() { - const int line_number = __LINE__; RunWorker(); + // Inhibit tail calls of RunWorker and inhibit code folding. + const int line_number = __LINE__; base::debug::Alias(&line_number); } NOINLINE void WorkerThread::RunBackgroundSharedWorker() { - const int line_number = __LINE__; RunWorker(); + // Inhibit tail calls of RunWorker and inhibit code folding. + const int line_number = __LINE__; base::debug::Alias(&line_number); } NOINLINE void WorkerThread::RunDedicatedWorker() { - const int line_number = __LINE__; RunWorker(); + // Inhibit tail calls of RunWorker and inhibit code folding. + const int line_number = __LINE__; base::debug::Alias(&line_number); } NOINLINE void WorkerThread::RunBackgroundDedicatedWorker() { - const int line_number = __LINE__; RunWorker(); + // Inhibit tail calls of RunWorker and inhibit code folding. + const int line_number = __LINE__; base::debug::Alias(&line_number); } #if defined(OS_WIN) NOINLINE void WorkerThread::RunSharedCOMWorker() { - const int line_number = __LINE__; RunWorker(); + // Inhibit tail calls of RunWorker and inhibit code folding. + const int line_number = __LINE__; base::debug::Alias(&line_number); } NOINLINE void WorkerThread::RunBackgroundSharedCOMWorker() { - const int line_number = __LINE__; RunWorker(); + // Inhibit tail calls of RunWorker and inhibit code folding. + const int line_number = __LINE__; base::debug::Alias(&line_number); } NOINLINE void WorkerThread::RunDedicatedCOMWorker() { - const int line_number = __LINE__; RunWorker(); + // Inhibit tail calls of RunWorker and inhibit code folding. + const int line_number = __LINE__; base::debug::Alias(&line_number); } NOINLINE void WorkerThread::RunBackgroundDedicatedCOMWorker() { - const int line_number = __LINE__; RunWorker(); + // Inhibit tail calls of RunWorker and inhibit code folding. + const int line_number = __LINE__; base::debug::Alias(&line_number); } #endif // defined(OS_WIN)
diff --git a/base/test/task_environment.h b/base/test/task_environment.h index b3950a8..846f10e3 100644 --- a/base/test/task_environment.h +++ b/base/test/task_environment.h
@@ -51,6 +51,9 @@ // RunLoop::Run(UntilIdle) or TaskEnvironment::RunUntilIdle is called on the // main thread. // +// The TaskEnvironment requires TestTimeouts::Initialize() to be called in order +// to run posted tasks, so that it can watch for problematic long-running tasks. +// // The TimeSource trait can be used to request that delayed tasks be under the // manual control of RunLoop::Run() and TaskEnvironment::FastForward*() methods. //
diff --git a/base/threading/hang_watcher.cc b/base/threading/hang_watcher.cc index f3e6ade31..9a4cdde 100644 --- a/base/threading/hang_watcher.cc +++ b/base/threading/hang_watcher.cc
@@ -227,6 +227,9 @@ // static void HangWatcher::RecordHang() { base::debug::DumpWithoutCrashing(); + // Inhibit code folding. + const int line_number = __LINE__; + base::debug::Alias(&line_number); } ScopedClosureRunner HangWatcher::RegisterThread() {
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 10ddeaeb..9f026579 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -0.20200513.1.1 \ No newline at end of file +0.20200513.3.1 \ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 10ddeaeb..c3380636 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -0.20200513.1.1 \ No newline at end of file +0.20200513.2.1 \ No newline at end of file
diff --git a/build/install-build-deps.sh b/build/install-build-deps.sh index 1b546e01..b10cbb4 100755 --- a/build/install-build-deps.sh +++ b/build/install-build-deps.sh
@@ -130,10 +130,12 @@ echo fi -if [ "$do_inst_lib32" = "1" ] || [ "$do_inst_nacl" = "1" ]; then - sudo dpkg --add-architecture i386 +if [ 0 -eq "${do_quick_check-0}" ] ; then + if [ "$do_inst_lib32" = "1" ] || [ "$do_inst_nacl" = "1" ]; then + sudo dpkg --add-architecture i386 + fi + sudo apt-get update fi -sudo apt-get update # Populate ${apt_package_list} for package_exists() parsing. apt_package_list=$(build_apt_package_list)
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc index c354081f..7b74ae2 100644 --- a/cc/layers/layer.cc +++ b/cc/layers/layer.cc
@@ -78,6 +78,7 @@ : layer_id(layer_id), hit_testable(false), contents_opaque(false), + contents_opaque_for_text(false), is_drawable(false), double_sided(true), has_will_change_transform_hint(false), @@ -804,11 +805,21 @@ if (inputs_.contents_opaque == opaque) return; inputs_.contents_opaque = opaque; + inputs_.contents_opaque_for_text = opaque; SetNeedsCommit(); SetSubtreePropertyChanged(); SetPropertyTreesNeedRebuild(); } +void Layer::SetContentsOpaqueForText(bool opaque) { + DCHECK(IsPropertyChangeAllowed()); + if (inputs_.contents_opaque_for_text == opaque) + return; + DCHECK(!contents_opaque() || opaque); + inputs_.contents_opaque_for_text = opaque; + SetNeedsCommit(); +} + void Layer::SetPosition(const gfx::PointF& position) { DCHECK(!layer_tree_host_ || !layer_tree_host_->IsUsingLayerLists()); @@ -1321,6 +1332,7 @@ layer->SetWheelEventHandlerRegion(Region()); } layer->SetContentsOpaque(inputs_.contents_opaque); + layer->SetContentsOpaqueForText(inputs_.contents_opaque_for_text); layer->SetShouldCheckBackfaceVisibility(should_check_backface_visibility_); layer->UpdateScrollable();
diff --git a/cc/layers/layer.h b/cc/layers/layer.h index 43debb1..a2da205 100644 --- a/cc/layers/layer.h +++ b/cc/layers/layer.h
@@ -333,9 +333,24 @@ // must be opaque or visual errors can occur. This applies only to this layer // and not to children, and does not imply the layer should be composited // opaquely, as effects may be applied such as opacity() or filters(). + // Note that this also calls SetContentsOpaqueForText(opaque) internally. + // To override a different contents_opaque_for_text, the client should call + // SetContentsOpaqueForText() after SetContentsOpaque(). void SetContentsOpaque(bool opaque); bool contents_opaque() const { return inputs_.contents_opaque; } + // Whether the contents area containing text is known to be opaque. + // For example, blink will SetContentsOpaque(false) but + // SetContentsOpaqueForText(true) for the following case: + // <div style="overflow: hidden; border-radius: 10px; background: white"> + // TEXT + // </div> + // See also the note for SetContentsOpaque(). + void SetContentsOpaqueForText(bool opaque); + bool contents_opaque_for_text() const { + return inputs_.contents_opaque_for_text; + } + // Set or get whether this layer should be a hit test target void SetHitTestable(bool should_hit_test); virtual bool HitTestable() const; @@ -829,6 +844,7 @@ bool hit_testable : 1; bool contents_opaque : 1; + bool contents_opaque_for_text : 1; bool is_drawable : 1; bool double_sided : 1;
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index bb1c93f25..318c2cbc 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc
@@ -55,6 +55,7 @@ layer_property_changed_from_property_trees_(false), may_contain_video_(false), contents_opaque_(false), + contents_opaque_for_text_(false), should_check_backface_visibility_(false), draws_content_(false), contributes_to_drawn_render_surface_(false), @@ -374,6 +375,7 @@ layer->has_transform_node_ = has_transform_node_; layer->offset_to_transform_parent_ = offset_to_transform_parent_; layer->contents_opaque_ = contents_opaque_; + layer->contents_opaque_for_text_ = contents_opaque_for_text_; layer->may_contain_video_ = may_contain_video_; layer->should_check_backface_visibility_ = should_check_backface_visibility_; layer->draws_content_ = draws_content_; @@ -571,6 +573,12 @@ void LayerImpl::SetContentsOpaque(bool opaque) { contents_opaque_ = opaque; + contents_opaque_for_text_ = opaque; +} + +void LayerImpl::SetContentsOpaqueForText(bool opaque) { + DCHECK(!contents_opaque_ || opaque); + contents_opaque_for_text_ = opaque; } float LayerImpl::Opacity() const {
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h index 95eb482..b9cafda 100644 --- a/cc/layers/layer_impl.h +++ b/cc/layers/layer_impl.h
@@ -165,8 +165,12 @@ // non-opaque color. Tries to return background_color(), if possible. SkColor SafeOpaqueBackgroundColor() const; + // See Layer::SetContentsOpaque() and SetContentsOpaqueForText() for the + // relationship between the two flags. void SetContentsOpaque(bool opaque); bool contents_opaque() const { return contents_opaque_; } + void SetContentsOpaqueForText(bool opaque); + bool contents_opaque_for_text() const { return contents_opaque_for_text_; } float Opacity() const; @@ -475,6 +479,7 @@ bool may_contain_video_ : 1; bool contents_opaque_ : 1; + bool contents_opaque_for_text_ : 1; bool should_check_backface_visibility_ : 1; bool draws_content_ : 1; bool contributes_to_drawn_render_surface_ : 1;
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index 00e845e..65d33f05 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc
@@ -836,7 +836,7 @@ return LCDTextDisallowedReason::kNone; if (!layer_tree_impl()->settings().can_use_lcd_text) return LCDTextDisallowedReason::kSetting; - if (!contents_opaque()) { + if (!contents_opaque_for_text()) { if (SkColorGetA(background_color()) != SK_AlphaOPAQUE) return LCDTextDisallowedReason::kBackgroundColorNotOpaque; return LCDTextDisallowedReason::kContentsNotOpaque;
diff --git a/cc/mojom/overscroll_behavior.mojom b/cc/mojom/overscroll_behavior.mojom index 36352e21..df6f782 100644 --- a/cc/mojom/overscroll_behavior.mojom +++ b/cc/mojom/overscroll_behavior.mojom
@@ -5,4 +5,4 @@ module cc.mojom; [Native] -enum OverscrollBehavior; +struct OverscrollBehavior;
diff --git a/cc/paint/display_item_list.cc b/cc/paint/display_item_list.cc index 52a3aac..071f57b6 100644 --- a/cc/paint/display_item_list.cc +++ b/cc/paint/display_item_list.cc
@@ -296,7 +296,6 @@ offsets_.shrink_to_fit(); paired_begin_stack_.clear(); paired_begin_stack_.shrink_to_fit(); - has_draw_ops_ = false; } sk_sp<PaintRecord> DisplayItemList::ReleaseAsRecord() {
diff --git a/cc/paint/display_item_list.h b/cc/paint/display_item_list.h index fa1639e7..12e91531 100644 --- a/cc/paint/display_item_list.h +++ b/cc/paint/display_item_list.h
@@ -91,8 +91,6 @@ if (usage_hint_ == kTopLevelDisplayItemList) offsets_.push_back(offset); const T* op = paint_op_buffer_.push<T>(std::forward<Args>(args)...); - if (op->IsDrawOp()) - has_draw_ops_ = true; DCHECK(op->IsValid()); return offset; } @@ -181,7 +179,7 @@ int max_ops_to_analyze = 1); std::string ToString() const; - bool has_draw_ops() const { return has_draw_ops_; } + bool has_draw_ops() const { return paint_op_buffer_.has_draw_ops(); } private: friend class DisplayItemListTest; @@ -235,7 +233,6 @@ #endif UsageHint usage_hint_; - bool has_draw_ops_ = false; friend class base::RefCountedThreadSafe<DisplayItemList>; FRIEND_TEST_ALL_PREFIXES(DisplayItemListTest, BytesUsed);
diff --git a/cc/paint/paint_flags.h b/cc/paint/paint_flags.h index c1f1cb5..bf9974f0 100644 --- a/cc/paint/paint_flags.h +++ b/cc/paint/paint_flags.h
@@ -141,9 +141,13 @@ draw_looper_ = std::move(looper); } - // Returns true if this just represents an opacity blend when - // used as saveLayer flags. + // Returns true if this just represents an opacity blend when used as + // saveLayer flags, thus the saveLayer can be converted to a saveLayerAlpha. bool IsSimpleOpacity() const; + + // Returns true if this (of a drawOp) allows the sequence + // saveLayerAlpha/drawOp/restore to be folded into a single drawOp by baking + // the alpha in the saveLayerAlpha into the flags of the drawOp. bool SupportsFoldingAlpha() const; // SkPaint does not support loopers, so callers of SkToPaint need
diff --git a/cc/paint/paint_op_buffer.cc b/cc/paint/paint_op_buffer.cc index 51955bc..aeef3ee 100644 --- a/cc/paint/paint_op_buffer.cc +++ b/cc/paint/paint_op_buffer.cc
@@ -315,10 +315,7 @@ } PlaybackParams::PlaybackParams(ImageProvider* image_provider) - : image_provider(image_provider), - original_ctm(SkMatrix::I()), - custom_callback(CustomDataRasterCallback()), - did_draw_op_callback(DidDrawOpCallback()) {} + : PlaybackParams(image_provider, SkMatrix::I()) {} PlaybackParams::PlaybackParams(ImageProvider* image_provider, const SkMatrix& original_ctm, @@ -1506,7 +1503,19 @@ const PlaybackParams& params) { // See PaintOp::kUnsetRect bool unset = op->bounds.left() == SK_ScalarInfinity; - canvas->saveLayerAlpha(unset ? nullptr : &op->bounds, op->alpha); + base::Optional<SkPaint> paint; + if (op->alpha != 0xFF) { + paint.emplace(); + paint->setAlpha(op->alpha); + } + SkCanvas::SaveLayerRec rec(unset ? nullptr : &op->bounds, + base::OptionalOrNullptr(paint)); + if (params.save_layer_alpha_should_preserve_lcd_text.has_value() && + *params.save_layer_alpha_should_preserve_lcd_text) { + rec.fSaveLayerFlags = SkCanvas::kPreserveLCDText_SaveLayerFlag | + SkCanvas::kInitWithPrevious_SaveLayerFlag; + } + canvas->saveLayer(rec); } void ScaleOp::Raster(const ScaleOp* op, @@ -2278,6 +2287,14 @@ return record->HasNonAAPaint(); } +bool DrawRecordOp::HasDrawTextOps() const { + return record->has_draw_text_ops(); +} + +bool DrawRecordOp::HasEffectsPreventingLCDTextForSaveLayerAlpha() const { + return record->has_effects_preventing_lcd_text_for_save_layer_alpha(); +} + AnnotateOp::AnnotateOp() : PaintOp(kType) {} AnnotateOp::AnnotateOp(PaintCanvas::AnnotationType annotation_type, @@ -2389,7 +2406,11 @@ default; PaintOpBuffer::PaintOpBuffer() - : has_non_aa_paint_(false), has_discardable_images_(false) {} + : has_non_aa_paint_(false), + has_discardable_images_(false), + has_draw_ops_(false), + has_draw_text_ops_(false), + has_effects_preventing_lcd_text_for_save_layer_alpha_(false) {} PaintOpBuffer::PaintOpBuffer(PaintOpBuffer&& other) { *this = std::move(other); @@ -2409,6 +2430,10 @@ subrecord_op_count_ = other.subrecord_op_count_; has_non_aa_paint_ = other.has_non_aa_paint_; has_discardable_images_ = other.has_discardable_images_; + has_draw_ops_ = other.has_draw_ops_; + has_draw_text_ops_ = other.has_draw_text_ops_; + has_effects_preventing_lcd_text_for_save_layer_alpha_ = + other.has_effects_preventing_lcd_text_for_save_layer_alpha_; // Make sure the other pob can destruct safely. other.used_ = 0; @@ -2430,6 +2455,9 @@ subrecord_bytes_used_ = 0; subrecord_op_count_ = 0; has_discardable_images_ = false; + has_draw_ops_ = false; + has_draw_text_ops_ = false; + has_effects_preventing_lcd_text_for_save_layer_alpha_ = false; } // When |op| is a nested PaintOpBuffer, this returns the PaintOp inside @@ -2556,10 +2584,22 @@ return; if (offsets && offsets->empty()) return; - // Prevent PaintOpBuffers from having side effects back into the canvas. SkAutoCanvasRestore save_restore(canvas, true); + bool save_layer_alpha_should_preserve_lcd_text = + (!params.save_layer_alpha_should_preserve_lcd_text.has_value() || + *params.save_layer_alpha_should_preserve_lcd_text) && + has_draw_text_ops_ && + !has_effects_preventing_lcd_text_for_save_layer_alpha_; + if (save_layer_alpha_should_preserve_lcd_text) { + // Check if the canvas supports LCD text. + SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType); + canvas->getProps(&props); + if (props.pixelGeometry() == kUnknown_SkPixelGeometry) + save_layer_alpha_should_preserve_lcd_text = false; + } + // TODO(enne): a PaintRecord that contains a SetMatrix assumes that the // SetMatrix is local to that PaintRecord itself. Said differently, if you // translate(x, y), then draw a paint record with a SetMatrix(identity), @@ -2568,6 +2608,8 @@ PlaybackParams new_params(params.image_provider, canvas->getTotalMatrix(), params.custom_callback, params.did_draw_op_callback); + new_params.save_layer_alpha_should_preserve_lcd_text = + save_layer_alpha_should_preserve_lcd_text; for (PlaybackFoldingIterator iter(this, offsets); iter; ++iter) { const PaintOp* op = *iter; @@ -2591,10 +2633,6 @@ if (const auto* raster_flags = scoped_flags.flags()) flags_op->RasterWithFlags(canvas, raster_flags, new_params); } else { - // TODO(enne): skip SaveLayer followed by restore with nothing in - // between, however SaveLayer with image filters on it (or maybe - // other PaintFlags options) are not a noop. Figure out what these - // are so we can skip them correctly. DCHECK_EQ(iter.alpha(), 255); op->Raster(canvas, new_params); }
diff --git a/cc/paint/paint_op_buffer.h b/cc/paint/paint_op_buffer.h index ef56440..dd591b15 100644 --- a/cc/paint/paint_op_buffer.h +++ b/cc/paint/paint_op_buffer.h
@@ -124,6 +124,7 @@ SkMatrix original_ctm; CustomDataRasterCallback custom_callback; DidDrawOpCallback did_draw_op_callback; + base::Optional<bool> save_layer_alpha_should_preserve_lcd_text; }; class CC_PAINT_EXPORT PaintOp { @@ -252,6 +253,10 @@ int CountSlowPathsFromFlags() const { return 0; } bool HasNonAAPaint() const { return false; } + bool HasDrawTextOps() const { return false; } + // Returns true if effects are present that would break LCD text or be broken + // by the flags for SaveLayerAlpha to preserving LCD text. + bool HasEffectsPreventingLCDTextForSaveLayerAlpha() const { return false; } bool HasDiscardableImages() const { return false; } bool HasDiscardableImagesFromFlags() const { return false; } @@ -672,6 +677,8 @@ bool HasDiscardableImages() const; int CountSlowPaths() const; bool HasNonAAPaint() const; + bool HasDrawTextOps() const; + bool HasEffectsPreventingLCDTextForSaveLayerAlpha() const; HAS_SERIALIZATION_FUNCTIONS(); sk_sp<const PaintRecord> record; @@ -759,6 +766,7 @@ SkCanvas* canvas, const PlaybackParams& params); bool IsValid() const { return flags.IsValid(); } + bool HasDrawTextOps() const { return true; } static bool AreEqual(const PaintOp* left, const PaintOp* right); HAS_SERIALIZATION_FUNCTIONS(); @@ -835,6 +843,10 @@ bool IsValid() const { return flags.IsValid() && IsValidOrUnsetRect(bounds); } static bool AreEqual(const PaintOp* left, const PaintOp* right); bool HasNonAAPaint() const { return false; } + // We simply assume any effects (or even no effects -- just starting an empty + // transparent layer) would break LCD text or be broken by the flags for + // SaveLayerAlpha to preserve LCD text. + bool HasEffectsPreventingLCDTextForSaveLayerAlpha() const { return true; } HAS_SERIALIZATION_FUNCTIONS(); SkRect bounds; @@ -985,6 +997,12 @@ bool HasNonAAPaint() const { return has_non_aa_paint_; } bool HasDiscardableImages() const { return has_discardable_images_; } + bool has_draw_ops() const { return has_draw_ops_; } + bool has_draw_text_ops() const { return has_draw_text_ops_; } + bool has_effects_preventing_lcd_text_for_save_layer_alpha() const { + return has_effects_preventing_lcd_text_for_save_layer_alpha_; + } + bool operator==(const PaintOpBuffer& other) const; bool operator!=(const PaintOpBuffer& other) const { return !(*this == other); @@ -1047,6 +1065,11 @@ subrecord_bytes_used_ += op->AdditionalBytesUsed(); subrecord_op_count_ += op->AdditionalOpCount(); + + has_draw_ops_ |= op->IsDrawOp(); + has_draw_text_ops_ |= op->HasDrawTextOps(); + has_effects_preventing_lcd_text_for_save_layer_alpha_ |= + op->HasEffectsPreventingLCDTextForSaveLayerAlpha(); } template <typename T> @@ -1263,15 +1286,18 @@ size_t reserved_ = 0; size_t op_count_ = 0; - // Record paths for veto-to-msaa for gpu raster. - int num_slow_paths_ = 0; // Record additional bytes used by referenced sub-records and display lists. size_t subrecord_bytes_used_ = 0; // Record total op count of referenced sub-record and display lists. size_t subrecord_op_count_ = 0; + // Record paths for veto-to-msaa for gpu raster. + int num_slow_paths_ = 0; bool has_non_aa_paint_ : 1; bool has_discardable_images_ : 1; + bool has_draw_ops_ : 1; + bool has_draw_text_ops_ : 1; + bool has_effects_preventing_lcd_text_for_save_layer_alpha_ : 1; }; } // namespace cc
diff --git a/cc/paint/paint_op_buffer_unittest.cc b/cc/paint/paint_op_buffer_unittest.cc index 7a2861e..c3cdc043 100644 --- a/cc/paint/paint_op_buffer_unittest.cc +++ b/cc/paint/paint_op_buffer_unittest.cc
@@ -3829,4 +3829,57 @@ PaintOpType::DrawImage); } +TEST(PaintOpBufferTest, HasDrawOpsAndHasDrawTextOps) { + auto buffer1 = sk_make_sp<PaintOpBuffer>(); + EXPECT_FALSE(buffer1->has_draw_ops()); + EXPECT_FALSE(buffer1->has_draw_text_ops()); + buffer1->push<DrawRectOp>(SkRect::MakeWH(3, 4), PaintFlags()); + PushDrawRectOps(buffer1.get()); + EXPECT_TRUE(buffer1->has_draw_ops()); + EXPECT_FALSE(buffer1->has_draw_text_ops()); + + auto buffer2 = sk_make_sp<PaintOpBuffer>(); + EXPECT_FALSE(buffer2->has_draw_ops()); + EXPECT_FALSE(buffer2->has_draw_text_ops()); + buffer2->push<DrawRecordOp>(std::move(buffer1)); + EXPECT_TRUE(buffer2->has_draw_ops()); + EXPECT_FALSE(buffer2->has_draw_text_ops()); + buffer2->push<DrawTextBlobOp>(SkTextBlob::MakeFromString("abc", SkFont()), 0, + 0, PaintFlags()); + PushDrawTextBlobOps(buffer2.get()); + EXPECT_TRUE(buffer2->has_draw_ops()); + EXPECT_TRUE(buffer2->has_draw_text_ops()); + buffer2->push<DrawRectOp>(SkRect::MakeWH(4, 5), PaintFlags()); + EXPECT_TRUE(buffer2->has_draw_ops()); + EXPECT_TRUE(buffer2->has_draw_text_ops()); + + auto buffer3 = sk_make_sp<PaintOpBuffer>(); + EXPECT_FALSE(buffer3->has_draw_text_ops()); + EXPECT_FALSE(buffer3->has_draw_ops()); + buffer3->push<DrawRecordOp>(std::move(buffer2)); + EXPECT_TRUE(buffer3->has_draw_ops()); + EXPECT_TRUE(buffer3->has_draw_text_ops()); +} + +TEST(PaintOpBufferTest, HasEffectsPreventingLCDTextForSaveLayerAlpha) { + auto buffer1 = sk_make_sp<PaintOpBuffer>(); + EXPECT_FALSE(buffer1->has_effects_preventing_lcd_text_for_save_layer_alpha()); + buffer1->push<DrawRectOp>(SkRect::MakeWH(3, 4), PaintFlags()); + EXPECT_FALSE(buffer1->has_effects_preventing_lcd_text_for_save_layer_alpha()); + + auto buffer2 = sk_make_sp<PaintOpBuffer>(); + EXPECT_FALSE(buffer2->has_effects_preventing_lcd_text_for_save_layer_alpha()); + buffer2->push<DrawRecordOp>(std::move(buffer1)); + EXPECT_FALSE(buffer2->has_effects_preventing_lcd_text_for_save_layer_alpha()); + buffer2->push<SaveLayerOp>(nullptr, nullptr); + EXPECT_TRUE(buffer2->has_effects_preventing_lcd_text_for_save_layer_alpha()); + buffer2->push<DrawRectOp>(SkRect::MakeWH(4, 5), PaintFlags()); + EXPECT_TRUE(buffer2->has_effects_preventing_lcd_text_for_save_layer_alpha()); + + auto buffer3 = sk_make_sp<PaintOpBuffer>(); + EXPECT_FALSE(buffer3->has_effects_preventing_lcd_text_for_save_layer_alpha()); + buffer3->push<DrawRecordOp>(std::move(buffer2)); + EXPECT_TRUE(buffer3->has_effects_preventing_lcd_text_for_save_layer_alpha()); +} + } // namespace cc
diff --git a/cc/trees/draw_properties_unittest.cc b/cc/trees/draw_properties_unittest.cc index 6abe486..4814d7e 100644 --- a/cc/trees/draw_properties_unittest.cc +++ b/cc/trees/draw_properties_unittest.cc
@@ -3699,6 +3699,16 @@ CheckCanUseLCDText(LCDTextDisallowedReason::kNone, grand_child_); } +TEST_P(LCDTextTest, CanUseLCDTextWithContentsOpaqueForText) { + child_->SetContentsOpaque(false); + child_->SetBackgroundColor(SK_ColorGREEN); + child_->SetContentsOpaqueForText(true); + CheckCanUseLCDText(LCDTextDisallowedReason::kNone, child_); + + child_->SetContentsOpaqueForText(false); + CheckCanUseLCDText(LCDTextDisallowedReason::kContentsNotOpaque, child_); +} + TEST_P(LCDTextTest, CanUseLCDTextWithAnimation) { // Sanity check: Make sure can_use_lcd_text_ is set on each node. UpdateActiveTreeDrawProperties();
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index f929592..312c44f5 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -3799,7 +3799,7 @@ return non_fast_scrollable_nodes; } -ScrollNode* LayerTreeHostImpl::FindScrollNodeForDeviceViewportPoint( +ScrollNode* LayerTreeHostImpl::FindScrollNodeForCompositedScrolling( const gfx::PointF& device_viewport_point, LayerImpl* layer_impl, bool* scroll_on_main_thread, @@ -3986,7 +3986,7 @@ } } - ScrollNode* starting_node = FindScrollNodeForDeviceViewportPoint( + ScrollNode* starting_node = FindScrollNodeForCompositedScrolling( device_viewport_point, layer_impl, &scroll_on_main_thread, &scroll_status.main_thread_scrolling_reasons); @@ -4034,6 +4034,43 @@ return scroll_status; } +ScrollNode* LayerTreeHostImpl::HitTestScrollNode( + const gfx::PointF& device_viewport_point) const { + LayerImpl* layer_impl = + active_tree_->FindLayerThatIsHitByPoint(device_viewport_point); + + if (!layer_impl) + return nullptr; + + // There are some cases where the hit layer may not be correct (e.g. layer + // squashing). If we detect this case, we can't target a scroll node here. + { + LayerImpl* first_scrolling_layer_or_scrollbar = + active_tree_->FindFirstScrollingLayerOrScrollbarThatIsHitByPoint( + device_viewport_point); + + if (!IsInitialScrollHitTestReliable(layer_impl, + first_scrolling_layer_or_scrollbar)) { + TRACE_EVENT_INSTANT0("cc", "Failed Hit Test", TRACE_EVENT_SCOPE_THREAD); + return nullptr; + } + } + + // If we hit a scrollbar layer, get the ScrollNode from its associated + // scrolling layer, rather than directly from the scrollbar layer. The latter + // would return the parent scroller's ScrollNode. + if (layer_impl->IsScrollbarLayer()) { + layer_impl = active_tree_->LayerByElementId( + ToScrollbarLayer(layer_impl)->scroll_element_id()); + DCHECK(layer_impl); + } + + ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree; + ScrollNode* scroll_node = scroll_tree.Node(layer_impl->scroll_tree_index()); + + return GetNodeToScroll(scroll_node); +} + // Requires falling back to main thread scrolling when it hit tests in scrollbar // from touch. bool LayerTreeHostImpl::IsTouchDraggingScrollbar( @@ -4076,23 +4113,9 @@ return node; } -// Initial scroll hit testing can be unreliable in the presence of squashed -// layers. In this case, we fall back to main thread scrolling. This function -// compares |layer_impl| returned from a regular hit test to the layer -// returned from a hit test performed only on scrollers and scrollbars. If the -// closest scrolling ancestor of |layer_impl| is not the other layer, then the -// layer_impl must be a squasing layer overtop of some other scroller and we -// must rely on the main thread. -// -// Note, position: fixed layers use the inner viewport as their ScrollNode -// (since they don't scroll with the outer viewport), however, scrolls from the -// fixed layer still chain to the outer viewport. It's also possible for a node -// to have the inner viewport as its ancestor without going through the outer -// viewport; however, it may still scroll using the viewport(). Hence, this -// method must use the same scroll chaining logic we use in ApplyScroll. bool LayerTreeHostImpl::IsInitialScrollHitTestReliable( LayerImpl* layer_impl, - LayerImpl* first_scrolling_layer_or_scrollbar) { + LayerImpl* first_scrolling_layer_or_scrollbar) const { if (!first_scrolling_layer_or_scrollbar) return true; @@ -5046,33 +5069,18 @@ gfx::PointF device_viewport_point = gfx::ScalePoint( gfx::PointF(viewport_point), active_tree_->device_scale_factor()); - LayerImpl* layer_impl = - active_tree_->FindLayerThatIsHitByPoint(device_viewport_point); + ScrollNode* scroll_node = HitTestScrollNode(device_viewport_point); - // Check if mouse is over a scrollbar or not. - // TODO(sahel): get rid of this extera checking when - // FindScrollNodeForDeviceViewportPoint finds the proper node for scrolling on - // the main thread when the mouse is over a scrollbar as well. - ElementId scroll_element_id; - if (layer_impl && layer_impl->IsScrollbarLayer()) - scroll_element_id = ToScrollbarLayer(layer_impl)->scroll_element_id(); - if (!scroll_element_id) { - bool scroll_on_main_thread = false; - uint32_t main_thread_scrolling_reasons; - auto* scroll_node = FindScrollNodeForDeviceViewportPoint( - device_viewport_point, layer_impl, &scroll_on_main_thread, - &main_thread_scrolling_reasons); - if (scroll_node) - scroll_element_id = scroll_node->element_id; + // The hit test can fail in some cases, e.g. we don't know if a region of a + // squashed layer has content or is empty. + if (!scroll_node) + return result; - // Scrollbars for the viewport are registered with the outer viewport layer. - if (InnerViewportScrollNode() && - scroll_element_id == InnerViewportScrollNode()->element_id) { - DCHECK(OuterViewportScrollNode()); - scroll_element_id = OuterViewportScrollNode()->element_id; - } - } + // Scrollbars for the viewport are registered with the outer viewport layer. + if (scroll_node->scrolls_inner_viewport) + scroll_node = OuterViewportScrollNode(); + ElementId scroll_element_id = scroll_node->element_id; ScrollbarAnimationController* new_animation_controller = ScrollbarAnimationControllerForElementId(scroll_element_id); if (scroll_element_id != scroll_element_id_mouse_currently_over_) { @@ -5084,7 +5092,7 @@ scroll_element_id_mouse_currently_over_ = scroll_element_id; - // Experiment: Enables will flash scorllbar when user move mouse enter a + // Experiment: Enables will flash scrollbar when user move mouse enter a // scrollable area. if (settings_.scrollbar_flash_when_mouse_enter && new_animation_controller) new_animation_controller->DidScrollUpdate();
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index d19ad11..132bb2e 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h
@@ -955,9 +955,24 @@ bool IsTouchDraggingScrollbar( LayerImpl* first_scrolling_layer_or_drawn_scrollbar, ui::ScrollInputType type); + + // Initial scroll hit testing can be unreliable in the presence of squashed + // layers. In this case, we fall back to main thread scrolling. This function + // compares |layer_impl| returned from a regular hit test to the layer + // returned from a hit test performed only on scrollers and scrollbars. If the + // closest scrolling ancestor of |layer_impl| is not the other layer, then the + // layer_impl must be a squasing layer overtop of some other scroller and we + // must rely on the main thread. + // + // Note, position: fixed layers use the inner viewport as their ScrollNode + // (since they don't scroll with the outer viewport), however, scrolls from + // the fixed layer still chain to the outer viewport. It's also possible for a + // node to have the inner viewport as its ancestor without going through the + // outer viewport; however, it may still scroll using the viewport(). Hence, + // this method must use the same scroll chaining logic we use in ApplyScroll. bool IsInitialScrollHitTestReliable( LayerImpl* layer, - LayerImpl* first_scrolling_layer_or_drawn_scrollbar); + LayerImpl* first_scrolling_layer_or_drawn_scrollbar) const; // Given a starting node (determined by hit-test), walks up the scroll tree // looking for the first node that can consume scroll from the given @@ -1001,7 +1016,18 @@ void ClearCurrentlyScrollingNode(); - ScrollNode* FindScrollNodeForDeviceViewportPoint( + // Performs a hit test to determine the ScrollNode to use when scrolling at + // |viewport_point|. Can return nullptr if the hit test fails; see the + // comment in IsInitialScrollHitTestReliable + ScrollNode* HitTestScrollNode(const gfx::PointF& device_viewport_point) const; + + // Similar to above but includes complicated logic to determine whether the + // ScrollNode is able to be scrolled on the compositor or requires main + // thread scrolling. If main thread scrolling is required + // |scroll_on_main_thread| is set to true and the reason is given in + // |main_thread_scrolling_reason| to on of the enum values in + // main_thread_scrolling_reason.h. + ScrollNode* FindScrollNodeForCompositedScrolling( const gfx::PointF& device_viewport_point, LayerImpl* layer_hit_by_point, bool* scroll_on_main_thread,
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index e90184a..b345f30 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -5073,11 +5073,13 @@ SetupViewportLayersInnerScrolls(viewport_size, content_size); auto* root_scroll = OuterViewportScrollLayer(); + const int kScrollbarThickness = 5; auto* vert_scrollbar = AddLayer<SolidColorScrollbarLayerImpl>( - host_impl_->active_tree(), VERTICAL, 5, 0, false); + host_impl_->active_tree(), VERTICAL, kScrollbarThickness, 0, false); SetupScrollbarLayer(root_scroll, vert_scrollbar); vert_scrollbar->SetBounds(gfx::Size(10, 200)); - vert_scrollbar->SetOffsetToTransformParent(gfx::Vector2dF(300, 0)); + vert_scrollbar->SetOffsetToTransformParent( + gfx::Vector2dF(300 - kScrollbarThickness, 0)); host_impl_->active_tree()->UpdateScrollbarGeometries(); @@ -5087,24 +5089,25 @@ root_scroll->element_id()); const float kDistanceToTriggerThumb = + vert_scrollbar->ComputeThumbQuadRect().height() + SingleScrollbarAnimationControllerThinning:: kMouseMoveDistanceToTriggerExpand; - // Move the mouse near the thumb in the top position. - auto near_thumb_at_top = gfx::Point(300, -kDistanceToTriggerThumb + 1); + // Move the mouse near the thumb while its at the viewport top. + auto near_thumb_at_top = gfx::Point(295, kDistanceToTriggerThumb - 1); host_impl_->MouseMoveAt(near_thumb_at_top); EXPECT_TRUE(scrollbar_controller->MouseIsNearScrollbarThumb(VERTICAL)); // Move the mouse away from the thumb. - host_impl_->MouseMoveAt(gfx::Point(300, -kDistanceToTriggerThumb - 1)); + host_impl_->MouseMoveAt(gfx::Point(295, kDistanceToTriggerThumb + 1)); EXPECT_FALSE(scrollbar_controller->MouseIsNearScrollbarThumb(VERTICAL)); - // Scroll the page down which moves the thumb down. - host_impl_->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF(0, 100), + // Scroll the page down which moves the thumb down to the viewport bottom. + host_impl_->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF(0, 800), ui::ScrollInputType::kWheel) .get(), ui::ScrollInputType::kWheel); - host_impl_->ScrollUpdate(UpdateState(gfx::Point(), gfx::Vector2d(0, 100), + host_impl_->ScrollUpdate(UpdateState(gfx::Point(), gfx::Vector2d(0, 800), ui::ScrollInputType::kWheel) .get()); host_impl_->ScrollEnd(); @@ -5114,11 +5117,11 @@ EXPECT_FALSE(scrollbar_controller->MouseIsNearScrollbarThumb(VERTICAL)); // Scroll the page up which moves the thumb back up. - host_impl_->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF(0, -100), + host_impl_->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF(0, -800), ui::ScrollInputType::kWheel) .get(), ui::ScrollInputType::kWheel); - host_impl_->ScrollUpdate(UpdateState(gfx::Point(), gfx::Vector2d(0, -100), + host_impl_->ScrollUpdate(UpdateState(gfx::Point(), gfx::Vector2d(0, -800), ui::ScrollInputType::kWheel) .get()); host_impl_->ScrollEnd();
diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_java_resources.gni index 1d57602..f6f6c2d0 100644 --- a/chrome/android/chrome_java_resources.gni +++ b/chrome/android/chrome_java_resources.gni
@@ -916,6 +916,7 @@ "java/res/layout/bottom_toolbar_menu_button.xml", "java/res/layout/bottom_toolbar_tab_switcher.xml", "java/res/layout/checkbox_layout.xml", + "java/res/layout/clear_browsing_data_button.xml", "java/res/layout/clear_browsing_data_tabs.xml", "java/res/layout/clear_browsing_important_dialog_listview.xml", "java/res/layout/compositor_view_holder.xml", @@ -1176,7 +1177,6 @@ "java/res/xml/account_management_preferences.xml", "java/res/xml/autofill_server_profile_preferences.xml", "java/res/xml/bookmark_widget_info.xml", - "java/res/xml/clear_browsing_data_button.xml", "java/res/xml/clear_browsing_data_preferences_tab.xml", "java/res/xml/contextual_search_preferences.xml", "java/res/xml/contextual_search_tap_preferences.xml",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index d47b944c..ebf86aa 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -198,6 +198,7 @@ "java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/view/DisclosureNotification.java", "java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/view/DisclosureSnackbar.java", "java/src/org/chromium/chrome/browser/browserservices/ui/SharedActivityCoordinator.java", + "java/src/org/chromium/chrome/browser/browserservices/ui/splashscreen/webapps/WebappSplashController.java", "java/src/org/chromium/chrome/browser/browserservices/ui/trustedwebactivity/TrustedWebActivityCoordinator.java", "java/src/org/chromium/chrome/browser/browsing_data/BrowsingDataBridge.java", "java/src/org/chromium/chrome/browser/browsing_data/BrowsingDataCounterBridge.java", @@ -1188,8 +1189,6 @@ "java/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandler.java", "java/src/org/chromium/chrome/browser/page_info/ChromePageInfoControllerDelegate.java", "java/src/org/chromium/chrome/browser/page_info/ChromePermissionParamsListBuilderDelegate.java", - "java/src/org/chromium/chrome/browser/page_info/PermissionParamsListBuilder.java", - "java/src/org/chromium/chrome/browser/page_info/PermissionParamsListBuilderDelegate.java", "java/src/org/chromium/chrome/browser/page_info/SiteSettingsHelper.java", "java/src/org/chromium/chrome/browser/paint_preview/PaintPreviewDemoManager.java", "java/src/org/chromium/chrome/browser/paint_preview/PaintPreviewExperiments.java", @@ -1567,7 +1566,6 @@ "java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java", "java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModel.java", "java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModelFilter.java", - "java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModelObserver.java", "java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModelSelectorObserver.java", "java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModel.java", "java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModelImplCreator.java", @@ -1773,7 +1771,6 @@ "java/src/org/chromium/chrome/browser/webapps/WebappLauncherActivity.java", "java/src/org/chromium/chrome/browser/webapps/WebappLocator.java", "java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java", - "java/src/org/chromium/chrome/browser/webapps/WebappSplashDelegate.java", "java/src/org/chromium/chrome/browser/webapps/WebappVerifier.java", "java/src/org/chromium/chrome/browser/webapps/addtohomescreen/AddToHomescreenCoordinator.java", "java/src/org/chromium/chrome/browser/webapps/addtohomescreen/AddToHomescreenDialogView.java",
diff --git a/chrome/android/chrome_test_java_sources.gni b/chrome/android/chrome_test_java_sources.gni index 2e987262..1d6d36b4 100644 --- a/chrome/android/chrome_test_java_sources.gni +++ b/chrome/android/chrome_test_java_sources.gni
@@ -15,7 +15,6 @@ "javatests/src/org/chromium/chrome/browser/CopylessPasteTest.java", "javatests/src/org/chromium/chrome/browser/ExampleUiCaptureTest.java", "javatests/src/org/chromium/chrome/browser/FeaturesAnnotationsTest.java", - "javatests/src/org/chromium/chrome/browser/FieldTrialsTest.java", "javatests/src/org/chromium/chrome/browser/FocusedEditableTextFieldZoomTest.java", "javatests/src/org/chromium/chrome/browser/HTTPSTabsOpenedFromExternalAppTest.java", "javatests/src/org/chromium/chrome/browser/InstalledAppTest.java",
diff --git a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java index fffbae53..bf0caab8 100644 --- a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java +++ b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java
@@ -40,7 +40,6 @@ import org.chromium.chrome.browser.ntp.FakeboxDelegate; import org.chromium.chrome.browser.omnibox.UrlFocusChangeListener; import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelObserver; @@ -191,7 +190,7 @@ // Hide tab carousel, which does not exist in incognito mode, when closing all // normal tabs. mNormalTabModel = mTabModelSelector.getModel(false); - mNormalTabModelObserver = new EmptyTabModelObserver() { + mNormalTabModelObserver = new TabModelObserver() { @Override public void willCloseTab(Tab tab, boolean animate) { if (mOverviewModeState == OverviewModeState.SHOWN_HOMEPAGE
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java index 4d66a07..8c05e45 100644 --- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java +++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java
@@ -54,8 +54,6 @@ import org.chromium.chrome.browser.tasks.ReturnToChromeExperimentsUtil; import org.chromium.chrome.browser.tasks.pseudotab.PseudoTab; import org.chromium.chrome.browser.tasks.pseudotab.TabAttributeCache; -import org.chromium.chrome.browser.tasks.tab_management.TabManagementDelegate; -import org.chromium.chrome.browser.tasks.tab_management.TabManagementModuleProvider; import org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarCoordinator; import org.chromium.chrome.browser.toolbar.top.TopToolbarCoordinator; import org.chromium.chrome.tab_ui.R; @@ -73,7 +71,6 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; -import java.util.concurrent.atomic.AtomicReference; /** * Integration tests of Instant Start which requires 2-stage initialization for Clank startup. @@ -285,10 +282,8 @@ Assert.assertTrue(CachedFeatureFlags.isEnabled(ChromeFeatureList.INSTANT_START)); Assert.assertTrue(ReturnToChromeExperimentsUtil.shouldShowTabSwitcher(-1)); - CriteriaHelper.pollUiThread(() - -> Assert.assertTrue(mActivityTestRule.getActivity() - .getLayoutManager() - .overviewVisible())); + CriteriaHelper.pollUiThread( + mActivityTestRule.getActivity().getLayoutManager()::overviewVisible); Assert.assertFalse(LibraryLoader.getInstance().isInitialized()); assertThat(mActivityTestRule.getActivity().getLayoutManager()) @@ -314,10 +309,8 @@ Assert.assertEquals("single", StartSurfaceConfiguration.START_SURFACE_VARIATION.getValue()); Assert.assertTrue(ReturnToChromeExperimentsUtil.shouldShowTabSwitcher(-1)); - CriteriaHelper.pollUiThread(() - -> Assert.assertTrue(mActivityTestRule.getActivity() - .getLayoutManager() - .overviewVisible())); + CriteriaHelper.pollUiThread( + mActivityTestRule.getActivity().getLayoutManager()::overviewVisible); Assert.assertFalse(LibraryLoader.getInstance().isInitialized()); assertThat(mActivityTestRule.getActivity().getLayoutManager()) @@ -434,27 +427,21 @@ (Runnable) ReturnToChromeExperimentsUtil::shouldShowStartSurfaceAsTheHomePage); } - private void showOverview() { - AtomicReference<StartSurface> startSurface = new AtomicReference<>(); - TestThreadUtils.runOnUiThreadBlocking(() -> { - TabManagementDelegate tabManagementDelegate = TabManagementModuleProvider.getDelegate(); - startSurface.set( - tabManagementDelegate.createStartSurface(mActivityTestRule.getActivity())); - startSurface.get().getController().enableRecordingFirstMeaningfulPaint(0); - startSurface.get().getController().showOverview(false); - }); - Assert.assertTrue(startSurface.get().getController().overviewVisible()); - } - @Test @SmallTest @Feature({"RenderTest"}) @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE}) - @CommandLineFlags.Add({ChromeSwitches.DISABLE_NATIVE_INITIALIZATION}) + // clang-format off + @EnableFeatures({ChromeFeatureList.TAB_SWITCHER_ON_RETURN + "<Study", + ChromeFeatureList.START_SURFACE_ANDROID + "<Study"}) + @CommandLineFlags.Add({ChromeSwitches.DISABLE_NATIVE_INITIALIZATION, + "force-fieldtrials=Study/Group", + IMMEDIATE_RETURN_PARAMS + "/start_surface_variation/omniboxonly"}) public void renderTabSwitcher_NoStateFile() throws IOException { + // clang-format on startMainActivityFromLauncher(); - showOverview(); - + CriteriaHelper.pollUiThread( + mActivityTestRule.getActivity().getLayoutManager()::overviewVisible); mRenderTestRule.render(mActivityTestRule.getActivity().findViewById(R.id.tab_list_view), "tabSwitcher_empty"); } @@ -463,12 +450,18 @@ @SmallTest @Feature({"RenderTest"}) @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE}) - @CommandLineFlags.Add({ChromeSwitches.DISABLE_NATIVE_INITIALIZATION}) + // clang-format off + @EnableFeatures({ChromeFeatureList.TAB_SWITCHER_ON_RETURN + "<Study", + ChromeFeatureList.START_SURFACE_ANDROID + "<Study"}) + @CommandLineFlags.Add({ChromeSwitches.DISABLE_NATIVE_INITIALIZATION, + "force-fieldtrials=Study/Group", + IMMEDIATE_RETURN_PARAMS + "/start_surface_variation/omniboxonly"}) public void renderTabSwitcher_CorruptedStateFile() throws IOException { + // clang-format on createCorruptedTabStateFile(); startMainActivityFromLauncher(); - showOverview(); - + CriteriaHelper.pollUiThread( + mActivityTestRule.getActivity().getLayoutManager()::overviewVisible); mRenderTestRule.render(mActivityTestRule.getActivity().findViewById(R.id.tab_list_view), "tabSwitcher_empty"); } @@ -492,8 +485,14 @@ @SmallTest @Feature({"RenderTest"}) @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE}) - @CommandLineFlags.Add({ChromeSwitches.DISABLE_NATIVE_INITIALIZATION}) + // clang-format off + @EnableFeatures({ChromeFeatureList.TAB_SWITCHER_ON_RETURN + "<Study", + ChromeFeatureList.START_SURFACE_ANDROID + "<Study"}) + @CommandLineFlags.Add({ChromeSwitches.DISABLE_NATIVE_INITIALIZATION, + "force-fieldtrials=Study/Group", + IMMEDIATE_RETURN_PARAMS + "/start_surface_variation/omniboxonly"}) public void renderTabSwitcher() throws IOException, InterruptedException { + // clang-format on createTabStateFile(new int[] {0, 1, 2}); createThumbnailBitmapAndWriteToFile(0); createThumbnailBitmapAndWriteToFile(1); @@ -504,8 +503,8 @@ // Must be after createTabStateFile() to read these files. startMainActivityFromLauncher(); - showOverview(); - + CriteriaHelper.pollUiThread( + mActivityTestRule.getActivity().getLayoutManager()::overviewVisible); RecyclerView recyclerView = mActivityTestRule.getActivity().findViewById(R.id.tab_list_view); CriteriaHelper.pollUiThread( @@ -529,9 +528,15 @@ @SmallTest @Feature({"RenderTest"}) @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE}) - @CommandLineFlags.Add({ChromeSwitches.DISABLE_NATIVE_INITIALIZATION}) - @EnableFeatures(ChromeFeatureList.TAB_GROUPS_ANDROID) + // clang-format off + @EnableFeatures({ChromeFeatureList.TAB_GROUPS_ANDROID, + ChromeFeatureList.TAB_SWITCHER_ON_RETURN + "<Study", + ChromeFeatureList.START_SURFACE_ANDROID + "<Study"}) + @CommandLineFlags.Add({ChromeSwitches.DISABLE_NATIVE_INITIALIZATION, + "force-fieldtrials=Study/Group", + IMMEDIATE_RETURN_PARAMS + "/start_surface_variation/omniboxonly"}) public void renderTabGroups() throws IOException, InterruptedException { + // clang-format on createThumbnailBitmapAndWriteToFile(0); createThumbnailBitmapAndWriteToFile(1); createThumbnailBitmapAndWriteToFile(2); @@ -547,8 +552,8 @@ // Must be after createTabStateFile() to read these files. startMainActivityFromLauncher(); - showOverview(); - + CriteriaHelper.pollUiThread( + mActivityTestRule.getActivity().getLayoutManager()::overviewVisible); RecyclerView recyclerView = mActivityTestRule.getActivity().findViewById(R.id.tab_list_view); CriteriaHelper.pollUiThread(
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java index 7f08ad3..e1b7909 100644 --- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java +++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.features.start_surface; +import static android.os.Build.VERSION_CODES.N_MR1; import static android.os.Build.VERSION_CODES.O_MR1; import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.action.ViewActions.click; @@ -1686,7 +1687,7 @@ @Test @MediumTest - @DisableIf.Build(sdk_is_greater_than = O_MR1, message = "crbug.com/1077191") + @DisableIf.Build(sdk_is_greater_than = N_MR1, message = "crbug.com/1077191, crbug.com/1081909") public void testActivityCanBeGarbageCollectedAfterFinished() throws Exception { prepareTabs(1, 0, "about:blank");
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java index fce0cd8..86e2b1a 100644 --- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java +++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java
@@ -48,7 +48,7 @@ import org.chromium.base.test.params.ParameterSet; import org.chromium.base.test.params.ParameterizedRunner; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.DisabledTest; +import org.chromium.base.test.util.DisableIf; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.Restriction; import org.chromium.chrome.browser.ChromeTabbedActivity; @@ -56,12 +56,14 @@ import org.chromium.chrome.browser.flags.CachedFeatureFlags; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; +import org.chromium.chrome.browser.ntp.NewTabPage; import org.chromium.chrome.browser.tasks.ReturnToChromeExperimentsUtil; import org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper; import org.chromium.chrome.start_surface.R; import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; +import org.chromium.chrome.test.util.ChromeTabUtils; import org.chromium.chrome.test.util.OverviewModeBehaviorWatcher; import org.chromium.chrome.test.util.browser.Features; import org.chromium.chrome.test.util.browser.Features.EnableFeatures; @@ -174,7 +176,7 @@ @Test @MediumTest @Feature({"StartSurface"}) - @DisabledTest + @DisableIf.Build(hardware_is = "bullhead", message = "crbug.com/1081657") // clang-format off @CommandLineFlags.Add({BASE_PARAMS + "/omniboxonly" + "/hide_switch_when_no_incognito_tabs/true"}) @@ -191,7 +193,7 @@ .check(matches(isDisplayed())); if (!isInstantReturn()) { - // TODO(crbug/1076274): fix toolbar to make incognito switch part of the view. + // TODO(crbug.com/1076274): fix toolbar to make incognito switch part of the view. onView(withId(org.chromium.chrome.tab_ui.R.id.incognito_switch)) .check(matches(withEffectiveVisibility(GONE))); } @@ -200,12 +202,13 @@ TabUiTestHelper.createTabs(cta, true, 1); TabUiTestHelper.verifyTabModelTabCount(cta, 1, 1); if (isInstantReturn()) { - // TODO(crbug/1076274): fix toolbar to avoid wrongly focusing on the toolbar omnibox. + // TODO(crbug.com/1076274): fix toolbar to avoid wrongly focusing on the toolbar + // omnibox. return; } TabUiTestHelper.enterTabSwitcher(cta); if (!isInstantReturn()) { - // TODO(crbug/1076274): fix toolbar to make incognito switch part of the view. + // TODO(crbug.com/1076274): fix toolbar to make incognito switch part of the view. onView(withId(org.chromium.chrome.tab_ui.R.id.incognito_switch)) .check(matches(isDisplayed())); } @@ -214,7 +217,7 @@ TabUiTestHelper.verifyTabModelTabCount(cta, 1, 0); assertTrue(mActivityTestRule.getActivity().getLayoutManager().overviewVisible()); if (!isInstantReturn()) { - // TODO(crbug/1076274): fix toolbar to make incognito switch part of the view. + // TODO(crbug.com/1076274): fix toolbar to make incognito switch part of the view. onView(withId(org.chromium.chrome.tab_ui.R.id.incognito_switch)) .check(matches(withEffectiveVisibility(GONE))); } @@ -227,7 +230,7 @@ @Test @MediumTest @Feature({"StartSurface"}) - @DisabledTest + @DisableIf.Build(hardware_is = "bullhead", message = "crbug.com/1081657") @CommandLineFlags.Add({BASE_PARAMS + "/twopanes"}) public void testShow_TwoPanes() { final ChromeTabbedActivity cta = mActivityTestRule.getActivity(); @@ -270,7 +273,7 @@ onView(withId(org.chromium.chrome.tab_ui.R.id.mv_tiles_container)) .check(matches(isDisplayed())); if (!isInstantReturn()) { - // TODO(crbug/1065314): show tab switcher section. + // TODO(crbug.com/1065314): show tab switcher section. onView(withId(org.chromium.chrome.tab_ui.R.id.tab_switcher_title)) .check(matches(isDisplayed())); onView(withId(org.chromium.chrome.tab_ui.R.id.carousel_tab_switcher_container)) @@ -294,7 +297,8 @@ } onViewWaiting(withId(R.id.secondary_tasks_surface_view)); if (isInstantReturn()) { - // TODO(crbug/1076274): fix toolbar to avoid wrongly focusing on the toolbar omnibox. + // TODO(crbug.com/1076274): fix toolbar to avoid wrongly focusing on the toolbar + // omnibox. return; } @@ -331,7 +335,7 @@ onView(withId(org.chromium.chrome.tab_ui.R.id.mv_tiles_container)) .check(matches(withEffectiveVisibility(GONE))); if (!isInstantReturn()) { - // TODO(crbug/1065314): show tab switcher section. + // TODO(crbug.com/1065314): show tab switcher section. onView(withId(org.chromium.chrome.tab_ui.R.id.tab_switcher_title)) .check(matches(isDisplayed())); onView(withId(org.chromium.chrome.tab_ui.R.id.carousel_tab_switcher_container)) @@ -341,7 +345,7 @@ .check(matches(isDisplayed())); if (!isInstantReturn()) { - // TODO(crbug/1076274): fix toolbar to make incognito switch part of the view. + // TODO(crbug.com/1076274): fix toolbar to make incognito switch part of the view. onView(withId(org.chromium.chrome.tab_ui.R.id.incognito_switch)) .check(matches(withEffectiveVisibility(GONE))); } @@ -361,7 +365,8 @@ } onViewWaiting(withId(R.id.secondary_tasks_surface_view)); if (isInstantReturn()) { - // TODO(crbug/1076274): fix toolbar to avoid wrongly focusing on the toolbar omnibox. + // TODO(crbug.com/1076274): fix toolbar to avoid wrongly focusing on the toolbar + // omnibox. return; } @@ -398,7 +403,7 @@ onView(withId(org.chromium.chrome.tab_ui.R.id.mv_tiles_container)) .check(matches(withEffectiveVisibility(GONE))); if (!isInstantReturn()) { - // TODO(crbug/1065314): show tab switcher section. + // TODO(crbug.com/1065314): show tab switcher section. onView(withId(org.chromium.chrome.tab_ui.R.id.tab_switcher_title)) .check(matches(isDisplayed())); onView(withId(org.chromium.chrome.tab_ui.R.id.carousel_tab_switcher_container)) @@ -410,7 +415,7 @@ .check(matches(isDisplayed())); if (!isInstantReturn()) { - // TODO(crbug/1076274): fix toolbar to make incognito switch part of the view. + // TODO(crbug.com/1076274): fix toolbar to make incognito switch part of the view. onView(withId(org.chromium.chrome.tab_ui.R.id.incognito_switch)) .check(matches(withEffectiveVisibility(GONE))); } @@ -431,7 +436,8 @@ onViewWaiting(withId(R.id.secondary_tasks_surface_view)); if (isInstantReturn()) { - // TODO(crbug/1076274): fix toolbar to avoid wrongly focusing on the toolbar omnibox. + // TODO(crbug.com/1076274): fix toolbar to avoid wrongly focusing on the toolbar + // omnibox. return; } pressBack(); @@ -518,7 +524,8 @@ pressBack(); } if (isInstantReturn()) { - // TODO(crbug/1076274): fix toolbar to avoid wrongly focusing on the toolbar omnibox. + // TODO(crbug.com/1076274): fix toolbar to avoid wrongly focusing on the toolbar + // omnibox. return; } TabUiTestHelper.enterTabSwitcher(mActivityTestRule.getActivity()); @@ -604,7 +611,7 @@ && mActivityTestRule.getActivity().getLayoutManager().overviewVisible()); waitForTabModel(); if (isInstantReturn()) { - // TODO(crbug/1076274): hide toolbar to make incognito switch visible. + // TODO(crbug.com/1076274): hide toolbar to make incognito switch visible. TestThreadUtils.runOnUiThreadBlocking(() -> { mActivityTestRule.getActivity().getTabModelSelector().selectModel(true); }); @@ -659,7 +666,8 @@ mActivityTestRule.getActivity().getTabModelSelector().getCurrentModel().getCount(), equalTo(2)); if (isInstantReturn()) { - // TODO(crbug/1076274): fix toolbar to avoid wrongly focusing on the toolbar omnibox. + // TODO(crbug.com/1076274): fix toolbar to avoid wrongly focusing on the toolbar + // omnibox. return; } // Press back button should close the tab opened from the Start surface. @@ -672,6 +680,67 @@ equalTo(1)); } + @Test + @MediumTest + @Feature({"StartSurface"}) + // clang-format off + @CommandLineFlags.Add({BASE_PARAMS + "/single/open_ntp_instead_of_start/true"}) + public void testCreateNewTab_OpenNTPInsteadOfStart() { + // clang-format on + ChromeTabbedActivity cta = mActivityTestRule.getActivity(); + waitForTabModel(); + TabUiTestHelper.verifyTabModelTabCount(cta, 1, 0); + + // Create a new tab from menu should create NTP instead of showing start. + ChromeTabUtils.newTabFromMenu( + InstrumentationRegistry.getInstrumentation(), cta, false, false); + TabUiTestHelper.verifyTabModelTabCount(cta, 2, 0); + if (isInstantReturn()) { + // TODO(crbug.com/1076274): fix toolbar to avoid wrongly focusing on the toolbar + // omnibox. + return; + } + CriteriaHelper.pollUiThread(() -> !cta.getOverviewModeBehavior().overviewVisible()); + TabUiTestHelper.enterTabSwitcher(cta); + TabUiTestHelper.verifyTabModelTabCount(cta, 2, 0); + + // Click plus button from top toolbar should create NTP instead of showing start surface. + onView(withId(R.id.new_tab_button)).perform(click()); + TabUiTestHelper.verifyTabModelTabCount(cta, 3, 0); + assertFalse(cta.getOverviewModeBehavior().overviewVisible()); + } + + @Test + @MediumTest + @Feature({"StartSurface"}) + // clang-format off + @CommandLineFlags.Add({BASE_PARAMS + "/single/open_ntp_instead_of_start/true"}) + public void testHomeButton_OpenNTPInsteadOfStart() { + // clang-format on + ChromeTabbedActivity cta = mActivityTestRule.getActivity(); + waitForTabModel(); + TabUiTestHelper.verifyTabModelTabCount(cta, 1, 0); + ChromeTabUtils.newTabFromMenu( + InstrumentationRegistry.getInstrumentation(), cta, false, false); + TabUiTestHelper.verifyTabModelTabCount(cta, 2, 0); + if (isInstantReturn()) { + // TODO(crbug.com/1076274): fix toolbar to avoid wrongly focusing on the toolbar + // omnibox. + return; + } + mActivityTestRule.loadUrl("about:blank"); + CriteriaHelper.pollUiThread( + () + -> cta.getTabModelSelector().getCurrentTab().getOriginalUrl().equals( + "about:blank")); + + // Click the home button should navigate to NTP instead of showing start surface. + onView(withId(R.id.home_button)).perform(click()); + CriteriaHelper.pollUiThread( + () -> NewTabPage.isNTPUrl(cta.getTabModelSelector().getCurrentTab().getUrl())); + assertFalse(cta.getOverviewModeBehavior().overviewVisible()); + } + private void waitForTabModel() { CriteriaHelper.pollUiThread(() -> mActivityTestRule.getActivity()
diff --git a/chrome/android/features/start_surface/internal/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceMediatorUnitTest.java b/chrome/android/features/start_surface/internal/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceMediatorUnitTest.java index 984ccea..1c5fab91 100644 --- a/chrome/android/features/start_surface/internal/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceMediatorUnitTest.java +++ b/chrome/android/features/start_surface/internal/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceMediatorUnitTest.java
@@ -55,9 +55,9 @@ import org.chromium.chrome.browser.omnibox.UrlFocusChangeListener; import org.chromium.chrome.browser.omnibox.voice.VoiceRecognitionHandler; import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabModel; +import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tasks.TasksSurfaceProperties; import org.chromium.chrome.browser.tasks.tab_management.TabSwitcher; @@ -104,7 +104,7 @@ @Captor private ArgumentCaptor<EmptyTabModelSelectorObserver> mTabModelSelectorObserverCaptor; @Captor - private ArgumentCaptor<EmptyTabModelObserver> mTabModelObserverCaptor; + private ArgumentCaptor<TabModelObserver> mTabModelObserverCaptor; @Captor private ArgumentCaptor<OverviewModeObserver> mOverviewModeObserverCaptor; @Captor
diff --git a/chrome/android/features/start_surface/public/java/src/org/chromium/chrome/features/start_surface/StartSurfaceConfiguration.java b/chrome/android/features/start_surface/public/java/src/org/chromium/chrome/features/start_surface/StartSurfaceConfiguration.java index 6ccd37c..92e90ab 100644 --- a/chrome/android/features/start_surface/public/java/src/org/chromium/chrome/features/start_surface/StartSurfaceConfiguration.java +++ b/chrome/android/features/start_surface/public/java/src/org/chromium/chrome/features/start_surface/StartSurfaceConfiguration.java
@@ -32,7 +32,9 @@ public static final BooleanCachedFieldTrialParameter START_SURFACE_SHOW_STACK_TAB_SWITCHER = new BooleanCachedFieldTrialParameter( ChromeFeatureList.START_SURFACE_ANDROID, "show_stack_tab_switcher", false); - + public static final BooleanCachedFieldTrialParameter START_SURFACE_OPEN_NTP_INSTEAD_OF_START = + new BooleanCachedFieldTrialParameter( + ChromeFeatureList.START_SURFACE_ANDROID, "open_ntp_instead_of_start", false); /** * @return Whether the Start Surface is enabled. */
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/SingleTabSwitcherMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/SingleTabSwitcherMediator.java index f576fd49..c904679 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/SingleTabSwitcherMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/SingleTabSwitcherMediator.java
@@ -13,7 +13,6 @@ import org.chromium.base.ObserverList; import org.chromium.chrome.browser.compositor.layouts.LayoutManager; import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabList; import org.chromium.chrome.browser.tabmodel.TabModel; @@ -51,7 +50,7 @@ } }); - mNormalTabModelObserver = new EmptyTabModelObserver() { + mNormalTabModelObserver = new TabModelObserver() { @Override public void didSelectTab(Tab tab, int type, int lastId) { assert overviewVisible();
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/pseudotab/TabAttributeCache.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/pseudotab/TabAttributeCache.java index 626a14d..a691acc 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/pseudotab/TabAttributeCache.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/pseudotab/TabAttributeCache.java
@@ -15,7 +15,6 @@ import org.chromium.chrome.browser.search_engines.TemplateUrlServiceFactory; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabImpl; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabModelFilter; import org.chromium.chrome.browser.tabmodel.TabModelObserver; @@ -93,7 +92,7 @@ } }; - mTabModelObserver = new EmptyTabModelObserver() { + mTabModelObserver = new TabModelObserver() { @Override public void tabClosureCommitted(Tab tab) { int id = tab.getId();
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java index 35422e2..8f8c249 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java
@@ -28,7 +28,6 @@ import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabSelectionType; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabCreatorManager; import org.chromium.chrome.browser.tabmodel.TabModel; @@ -129,7 +128,7 @@ mComponentName = componentName; // Register for tab model. - mTabModelObserver = new EmptyTabModelObserver() { + mTabModelObserver = new TabModelObserver() { @Override public void didAddTab( Tab tab, @TabLaunchType int type, @TabCreationState int creationState) {
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiMediator.java index 33811b91..5c02c5c 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiMediator.java
@@ -14,7 +14,6 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tasks.tab_groups.TabGroupModelFilter; @@ -81,7 +80,7 @@ }; mFullscreenManager.addListener(mFullscreenListener); - mTabModelObserver = new EmptyTabModelObserver() { + mTabModelObserver = new TabModelObserver() { @Override public void didSelectTab(Tab tab, int type, int lastId) { List<Tab> tabList = mTabModelSelector.getTabModelFilterProvider()
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupTitleEditor.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupTitleEditor.java index 9b283d34..f9c59689 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupTitleEditor.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupTitleEditor.java
@@ -6,7 +6,6 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabImpl; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tasks.tab_groups.EmptyTabGroupModelFilterObserver; @@ -26,7 +25,7 @@ public TabGroupTitleEditor(TabModelSelector tabModelSelector) { mTabModelSelector = tabModelSelector; - mTabModelObserver = new EmptyTabModelObserver() { + mTabModelObserver = new TabModelObserver() { @Override public void tabClosureCommitted(Tab tab) { int tabRootId = ((TabImpl) tab).getRootId();
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java index 786cdc8..177d4af1 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java
@@ -22,8 +22,8 @@ import org.chromium.chrome.browser.metrics.UmaSessionStats; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabImpl; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelFilterProvider; +import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tasks.tab_groups.TabGroupModelFilter; import org.chromium.chrome.browser.tasks.tab_groups.TabGroupUtils; @@ -125,7 +125,7 @@ // Record the group count after all tabs are being restored. This only happen once per life // cycle, therefore remove the observer after recording. We only focus on normal tab model // because we don't restore tabs in incognito tab model. - tabModelSelector.getModel(false).addObserver(new EmptyTabModelObserver() { + tabModelSelector.getModel(false).addObserver(new TabModelObserver() { @Override public void restoreCompleted() { recordTabGroupCount();
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java index 784401e6..733f8da5 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java
@@ -24,7 +24,6 @@ import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabSelectionType; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabCreatorManager; import org.chromium.chrome.browser.tabmodel.TabModel; @@ -140,7 +139,7 @@ .setDuration(UNDO_DISMISS_SNACKBAR_DURATION); // register for tab model - mTabModelObserver = new EmptyTabModelObserver() { + mTabModelObserver = new TabModelObserver() { private int mAddedTabId = Tab.INVALID_TAB_ID; @Override public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) {
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java index c958e1d..5c65961673 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
@@ -50,7 +50,6 @@ import org.chromium.chrome.browser.tab.TabObserver; import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.chrome.browser.tabmodel.EmptyTabModelFilter; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.TabList; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelFilter; @@ -448,7 +447,7 @@ mActionsOnAllRelatedTabs = actionOnRelatedTabs; mUiType = uiType; - mTabModelObserver = new EmptyTabModelObserver() { + mTabModelObserver = new TabModelObserver() { @Override public void didSelectTab(Tab tab, int type, int lastId) { mNextTabId = Tab.INVALID_TAB_ID; @@ -869,9 +868,7 @@ */ void prepareOverview() { if (!TabUiFeatureUtilities.isTabToGtsAnimationEnabled() - || !mTabModelSelector.getTabModelFilterProvider() - .getCurrentTabModelFilter() - .isTabModelRestored()) { + || !mTabModelSelector.isTabStateInitialized()) { return; }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java index 66cbf128..103ac8d 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java
@@ -39,7 +39,6 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabSelectionType; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabList; import org.chromium.chrome.browser.tabmodel.TabModel; @@ -219,7 +218,7 @@ }; mTabModelSelector.addObserver(mTabModelSelectorObserver); - mTabModelObserver = new EmptyTabModelObserver() { + mTabModelObserver = new TabModelObserver() { @Override public void didAddTab(Tab tab, int type, @TabCreationState int creationState) { // TODO(wychen): move didAddTab and didSelectTab to another observer and inject @@ -694,6 +693,9 @@ * @return whether tabs should show in MRU order */ static boolean isShowingTabsInMRUOrder() { + // TODO(crbug.com/1076449): Support MRU mode in Instant start. + if (CachedFeatureFlags.isEnabled(ChromeFeatureList.INSTANT_START)) return false; + String feature = StartSurfaceConfiguration.START_SURFACE_VARIATION.getValue(); return TextUtils.equals(feature, "twopanes"); }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabContextObserver.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabContextObserver.java index 5286796..712cf6e1 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabContextObserver.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabContextObserver.java
@@ -6,7 +6,6 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabCreationState; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver; @@ -32,7 +31,7 @@ } }; - mTabModelObserver = new EmptyTabModelObserver() { + mTabModelObserver = new TabModelObserver() { @Override public void didAddTab(Tab tab, int type, @TabCreationState int creationState) { onTabContextChanged(TabContextChangeReason.TAB_ADDED);
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/ConditionalTabStripTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/ConditionalTabStripTest.java index ce09a7e5..392b403 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/ConditionalTabStripTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/ConditionalTabStripTest.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.tasks.tab_management; +import static android.os.Build.VERSION_CODES.M; import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.action.ViewActions.click; import static android.support.test.espresso.action.ViewActions.longClick; @@ -42,6 +43,7 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisableIf; import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Restriction; import org.chromium.chrome.browser.ChromeTabbedActivity; @@ -125,6 +127,7 @@ @Test @MediumTest + @DisableIf.Build(sdk_is_less_than = M, message = "crbug.com/1081832") public void testStrip_updateWithAddition() throws Exception { ChromeTabbedActivity cta = mActivityTestRule.getActivity(); verifyHidingStrip(); @@ -195,6 +198,7 @@ @Test @MediumTest + @DisableIf.Build(sdk_is_less_than = M, message = "crbug.com/1081832") public void testStrip_updateWithSelection() throws Exception { ChromeTabbedActivity cta = mActivityTestRule.getActivity(); verifyHidingStrip(); @@ -275,6 +279,7 @@ @Test @MediumTest + @DisableIf.Build(sdk_is_less_than = M, message = "crbug.com/1081832") public void testStrip_switchTabWithStrip() throws Exception { ChromeTabbedActivity cta = mActivityTestRule.getActivity(); verifyHidingStrip(); @@ -292,6 +297,7 @@ @Test @MediumTest + @DisableIf.Build(sdk_is_less_than = M, message = "crbug.com/1081832") public void testStrip_closeTabWithStrip() throws Exception { ChromeTabbedActivity cta = mActivityTestRule.getActivity(); verifyHidingStrip();
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/SingleTabSwitcherMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/SingleTabSwitcherMediatorUnitTest.java index ddcf8928..1a80a3d9 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/SingleTabSwitcherMediatorUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/SingleTabSwitcherMediatorUnitTest.java
@@ -35,9 +35,9 @@ import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabSelectionType; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabModel; +import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tasks.tab_management.TabListFaviconProvider; import org.chromium.chrome.browser.tasks.tab_management.TabSwitcher; @@ -70,7 +70,7 @@ @Captor private ArgumentCaptor<EmptyTabModelSelectorObserver> mTabModelSelectorObserverCaptor; @Captor - private ArgumentCaptor<EmptyTabModelObserver> mTabModelObserverCaptor; + private ArgumentCaptor<TabModelObserver> mTabModelObserverCaptor; @Captor private ArgumentCaptor<Callback<Drawable>> mFaviconCallbackCaptor;
diff --git a/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShell.java b/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShell.java index 7da61138..e407d2e 100644 --- a/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShell.java +++ b/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShell.java
@@ -42,6 +42,7 @@ import org.chromium.chrome.browser.compositor.CompositorView; import org.chromium.chrome.browser.offlinepages.OfflinePageUtils; import org.chromium.chrome.browser.page_info.ChromePageInfoControllerDelegate; +import org.chromium.chrome.browser.page_info.ChromePermissionParamsListBuilderDelegate; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.RedirectHandlerTabHelper; import org.chromium.chrome.browser.tab.Tab; @@ -577,7 +578,8 @@ new ChromePageInfoControllerDelegate(mActivity, webContents, mActivity::getModalDialogManager, /*offlinePageLoadUrlDelegate=*/ - new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(tab))); + new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(tab)), + new ChromePermissionParamsListBuilderDelegate()); } // Called because showing audio permission dialog isn't supported in VR. This happens when
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedLoggingBridge.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedLoggingBridge.java index e3008876..37c463ca 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedLoggingBridge.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedLoggingBridge.java
@@ -362,6 +362,7 @@ return WindowOpenDisposition.SAVE_TO_DISK; case ActionType.LEARN_MORE: case ActionType.MANAGE_INTERESTS: + case ActionType.BLOCK_CONTENT: case ActionType.UNKNOWN: default: return WindowOpenDisposition.UNKNOWN; @@ -370,6 +371,9 @@ private void recordUserAction(@ActionType int actionType) { switch (actionType) { + case ActionType.BLOCK_CONTENT: + NewTabPageUma.recordAction(NewTabPageUma.ACTION_BLOCK_CONTENT); + break; case ActionType.OPEN_URL: case ActionType.OPEN_URL_INCOGNITO: case ActionType.OPEN_URL_NEW_TAB:
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java index 9090522..2d4c3cd 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java
@@ -24,6 +24,7 @@ import org.chromium.chrome.browser.native_page.ContextMenuManager; import org.chromium.chrome.browser.native_page.NativePageNavigationDelegate; import org.chromium.chrome.browser.ntp.NewTabPageLayout; +import org.chromium.chrome.browser.ntp.NewTabPageUma; import org.chromium.chrome.browser.ntp.SnapScrollHelper; import org.chromium.chrome.browser.ntp.cards.SignInPromo; import org.chromium.chrome.browser.ntp.cards.promo.HomepagePromoController.HomepagePromoStateListener; @@ -41,6 +42,8 @@ import org.chromium.components.browser_ui.widget.listmenu.ListMenuItemProperties; import org.chromium.components.feature_engagement.Tracker; import org.chromium.components.search_engines.TemplateUrlService.TemplateUrlServiceObserver; +import org.chromium.components.signin.base.CoreAccountInfo; +import org.chromium.components.signin.identitymanager.IdentityManager; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.ui.modelutil.MVCListAdapter.ModelList; import org.chromium.ui.modelutil.PropertyModel; @@ -50,9 +53,10 @@ * A mediator for the {@link FeedSurfaceCoordinator} responsible for interacting with the * native library and handling business logic. */ -class FeedSurfaceMediator - implements NewTabPageLayout.ScrollDelegate, ContextMenuManager.TouchEnabledDelegate, - TemplateUrlServiceObserver, ListMenu.Delegate, HomepagePromoStateListener { +class FeedSurfaceMediator implements NewTabPageLayout.ScrollDelegate, + ContextMenuManager.TouchEnabledDelegate, + TemplateUrlServiceObserver, ListMenu.Delegate, + HomepagePromoStateListener, IdentityManager.Observer { private static final float IPH_TRIGGER_BAR_TRANSITION_FRACTION = 1.0f; private static final float IPH_STREAM_MIN_SCROLL_FRACTION = 0.10f; private static final float IPH_FEED_HEADER_MAX_POS_FRACTION = 0.35f; @@ -226,6 +230,7 @@ } }; mCoordinator.getStream().addScrollListener(new HeaderIphScrollListener(delegate)); + mSigninManager.getIdentityManager().addObserver(this); } } // Show feed if there is no header that would allow user to hide feed. @@ -266,6 +271,7 @@ mPrefChangeRegistrar.removeObserver(Pref.NTP_ARTICLES_LIST_VISIBLE); TemplateUrlServiceFactory.get().removeObserver(this); + mSigninManager.getIdentityManager().removeObserver(this); } /** @@ -311,12 +317,19 @@ /** Returns the section header text based on the selected default search engine */ private String getSectionHeaderText(boolean isExpanded) { Resources res = mCoordinator.getSectionHeaderView().getResources(); + final boolean isDefaultSearchEngineGoogle = + TemplateUrlServiceFactory.get().isDefaultSearchEngineGoogle(); final int sectionHeaderStringId; if (mHasHeaderMenu) { - sectionHeaderStringId = - isExpanded ? R.string.ntp_discover_on : R.string.ntp_discover_off; + if (isDefaultSearchEngineGoogle) { + sectionHeaderStringId = + isExpanded ? R.string.ntp_discover_on : R.string.ntp_discover_off; + } else { + sectionHeaderStringId = isExpanded ? R.string.ntp_discover_on_branded + : R.string.ntp_discover_off_branded; + } } else { - sectionHeaderStringId = TemplateUrlServiceFactory.get().isDefaultSearchEngineGoogle() + sectionHeaderStringId = isDefaultSearchEngineGoogle ? R.string.ntp_article_suggestions_section_header : R.string.ntp_article_suggestions_section_header_branded; } @@ -326,10 +339,12 @@ private ModelList buildMenuItems() { ModelList itemList = new ModelList(); int icon_id = 0; - itemList.add(buildMenuListItem( - R.string.ntp_manage_my_activity, R.id.ntp_feed_header_menu_item_activity, icon_id)); - itemList.add(buildMenuListItem( - R.string.ntp_manage_interests, R.id.ntp_feed_header_menu_item_interest, icon_id)); + if (mSigninManager.getIdentityManager().hasPrimaryAccount()) { + itemList.add(buildMenuListItem(R.string.ntp_manage_my_activity, + R.id.ntp_feed_header_menu_item_activity, icon_id)); + itemList.add(buildMenuListItem(R.string.ntp_manage_interests, + R.id.ntp_feed_header_menu_item_interest, icon_id)); + } itemList.add(buildMenuListItem( R.string.learn_more, R.id.ntp_feed_header_menu_item_learn, icon_id)); if (mSectionHeader.isExpanded()) { @@ -454,12 +469,14 @@ if (itemId == R.id.ntp_feed_header_menu_item_activity) { mPageNavigationDelegate.openUrl(WindowOpenDisposition.CURRENT_TAB, new LoadUrlParams("https://myactivity.google.com/myactivity?product=50")); + NewTabPageUma.recordAction(NewTabPageUma.ACTION_CLICKED_MANAGE_ACTIVITY); } else if (itemId == R.id.ntp_feed_header_menu_item_interest) { mPageNavigationDelegate.openUrl(WindowOpenDisposition.CURRENT_TAB, new LoadUrlParams("https://www.google.com/preferences/interests")); + NewTabPageUma.recordAction(NewTabPageUma.ACTION_CLICKED_MANAGE_INTERESTS); } else if (itemId == R.id.ntp_feed_header_menu_item_learn) { - mPageNavigationDelegate.openUrl(WindowOpenDisposition.CURRENT_TAB, - new LoadUrlParams("https://www.google.com/chrome/privacy")); + mPageNavigationDelegate.navigateToHelpPage(); + NewTabPageUma.recordAction(NewTabPageUma.ACTION_CLICKED_LEARN_MORE); } else if (itemId == R.id.ntp_feed_header_menu_item_toggle_switch) { mSectionHeader.toggleHeader(); SuggestionsMetrics.recordExpandableHeaderTapped(mSectionHeader.isExpanded()); @@ -475,6 +492,18 @@ mCoordinator.updateHeaderViews(mSignInPromo != null && mSignInPromo.isVisible()); } + // IdentityManager.Delegate interface. + + @Override + public void onPrimaryAccountSet(CoreAccountInfo account) { + updateSectionHeader(); + } + + @Override + public void onPrimaryAccountCleared(CoreAccountInfo account) { + updateSectionHeader(); + } + /** * The {@link SignInPromo} for the Feed. * TODO(huayinz): Update content and visibility through a ModelChangeProcessor.
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/ActionType.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/ActionType.java index 83fd1f42..254b45f0 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/ActionType.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/ActionType.java
@@ -15,7 +15,8 @@ */ @IntDef({ActionType.UNKNOWN, ActionType.OPEN_URL, ActionType.OPEN_URL_INCOGNITO, ActionType.OPEN_URL_NEW_TAB, ActionType.OPEN_URL_NEW_WINDOW, ActionType.DOWNLOAD, - ActionType.LEARN_MORE, ActionType.MANAGE_INTERESTS, ActionType.NEXT_VALUE}) + ActionType.LEARN_MORE, ActionType.MANAGE_INTERESTS, ActionType.BLOCK_CONTENT, + ActionType.NEXT_VALUE}) // LINT.IfChange public @interface ActionType { int UNKNOWN = -1; @@ -26,6 +27,7 @@ int DOWNLOAD = 5; int LEARN_MORE = 6; int MANAGE_INTERESTS = 7; - int NEXT_VALUE = 8; + int BLOCK_CONTENT = 8; + int NEXT_VALUE = 9; } // LINT.ThenChange
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionparser/FeedActionParser.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionparser/FeedActionParser.java index 6c8083ab..60e4f0095 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionparser/FeedActionParser.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionparser/FeedActionParser.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.feed.library.feedactionparser; import static org.chromium.chrome.browser.feed.library.common.Validators.checkState; +import static org.chromium.components.feed.core.proto.ui.action.FeedActionProto.FeedActionMetadata.Type.BLOCK_CONTENT; import static org.chromium.components.feed.core.proto.ui.action.FeedActionProto.FeedActionMetadata.Type.DOWNLOAD; import static org.chromium.components.feed.core.proto.ui.action.FeedActionProto.FeedActionMetadata.Type.LEARN_MORE; import static org.chromium.components.feed.core.proto.ui.action.FeedActionProto.FeedActionMetadata.Type.MANAGE_INTERESTS; @@ -205,6 +206,7 @@ mProtocolAdapter.createOperations( feedActionMetadata.getBlockContentData().getDataOperationsList()), feedActionMetadata.getBlockContentData().getPayload()); + streamActionApi.onClientAction(ActionTypesConverter.convert(BLOCK_CONTENT)); break; case REPORT_VIEW: ViewReportData viewReportData = feedActionMetadata.getViewReportData();
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionparser/internal/ActionTypesConverter.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionparser/internal/ActionTypesConverter.java index 59bd71fd..275f90f 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionparser/internal/ActionTypesConverter.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionparser/internal/ActionTypesConverter.java
@@ -29,6 +29,8 @@ return ActionType.LEARN_MORE; case MANAGE_INTERESTS: return ActionType.MANAGE_INTERESTS; + case BLOCK_CONTENT: + return ActionType.BLOCK_CONTENT; default: return ActionType.UNKNOWN; }
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/FeedRequestManagerImpl.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/FeedRequestManagerImpl.java index 8756d8b..0544ec1 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/FeedRequestManagerImpl.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/FeedRequestManagerImpl.java
@@ -11,6 +11,7 @@ import com.google.protobuf.ByteString; import org.chromium.base.Consumer; +import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.browser.feed.library.api.host.config.ApplicationInfo; import org.chromium.chrome.browser.feed.library.api.host.config.Configuration; import org.chromium.chrome.browser.feed.library.api.host.config.Configuration.ConfigKey; @@ -54,6 +55,7 @@ import org.chromium.components.feed.core.proto.wire.FeedActionQueryDataProto.FeedActionQueryDataItem; import org.chromium.components.feed.core.proto.wire.FeedQueryProto.FeedQuery; import org.chromium.components.feed.core.proto.wire.FeedRequestProto.FeedRequest; +import org.chromium.components.feed.core.proto.wire.FeedResponseProto.FeedResponse; import org.chromium.components.feed.core.proto.wire.RequestProto.Request; import org.chromium.components.feed.core.proto.wire.RequestProto.Request.RequestVersion; import org.chromium.components.feed.core.proto.wire.ResponseProto.Response; @@ -265,11 +267,19 @@ "FeedRequestManagerImpl consumer", () -> consumer.accept(Result.failure())); return; } + logServerCapabilities(response); mMainThreadRunner.execute("FeedRequestManagerImpl consumer", () -> consumer.accept(mProtocolAdapter.createModel(response))); }); } + private static void logServerCapabilities(Response response) { + FeedResponse feedResponse = response.getExtension(FeedResponse.feedResponse); + List<Capability> capabilities = feedResponse.getServerCapabilitiesList(); + RecordHistogram.recordBooleanHistogram("ContentSuggestions.Feed.NoticeCardFulfilled", + capabilities.contains(Capability.REPORT_FEED_USER_ACTIONS_NOTICE_CARD)); + } + private static final class RequestBuilder { private ByteString mToken; private ConsistencyToken mConsistencyToken;
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedactionparser/FeedActionParserTest.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedactionparser/FeedActionParserTest.java index af928e48..93f22d6 100644 --- a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedactionparser/FeedActionParserTest.java +++ b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedactionparser/FeedActionParserTest.java
@@ -847,6 +847,7 @@ BLOCK_CONTENT_ACTION, mStreamActionApi, /* view= */ null, ActionSource.CLICK); verify(mStreamActionApi) .handleBlockContent(mStreamDataOperations, ActionPayload.getDefaultInstance()); + verify(mStreamActionApi).onClientAction(ActionType.BLOCK_CONTENT); } @Test
diff --git a/chrome/android/java/res/xml/clear_browsing_data_button.xml b/chrome/android/java/res/layout/clear_browsing_data_button.xml similarity index 100% rename from chrome/android/java/res/xml/clear_browsing_data_button.xml rename to chrome/android/java/res/layout/clear_browsing_data_button.xml
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index 1daac80..387f93ba 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -218,7 +218,6 @@ <dimen name="toolbar_tab_count_text_size_1_digit">12dp</dimen> <dimen name="toolbar_tab_count_text_size_2_digit">10dp</dimen> <dimen name="toolbar_height_no_shadow">56dp</dimen> - <dimen name="toolbar_shadow_height">8dp</dimen> <dimen name="toolbar_progress_bar_height">2dp</dimen> <dimen name="toolbar_button_width">48dp</dimen> <dimen name="toolbar_identity_disc_size">24dp</dimen>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java index f4d3573b9..bc7618f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -111,6 +111,7 @@ import org.chromium.chrome.browser.omaha.notification.UpdateNotificationController; import org.chromium.chrome.browser.omaha.notification.UpdateNotificationControllerFactory; import org.chromium.chrome.browser.page_info.ChromePageInfoControllerDelegate; +import org.chromium.chrome.browser.page_info.ChromePermissionParamsListBuilderDelegate; import org.chromium.chrome.browser.paint_preview.PaintPreviewInitializer; import org.chromium.chrome.browser.partnercustomizations.PartnerBrowserCustomizations; import org.chromium.chrome.browser.preferences.Pref; @@ -1991,7 +1992,8 @@ new ChromePageInfoControllerDelegate(this, webContents, this::getModalDialogManager, /*offlinePageLoadUrlDelegate=*/ - new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(currentTab))); + new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(currentTab)), + new ChromePermissionParamsListBuilderDelegate()); } else if (id == R.id.translate_id) { RecordUserAction.record("MobileMenuTranslate"); Tracker tracker = TrackerFactory.getTrackerForProfile(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index efb10f6..9951eb9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -1077,16 +1077,17 @@ } private boolean shouldShowTabSwitcherOnStart() { - if (ReturnToChromeExperimentsUtil.shouldShowStartSurfaceAsTheHomePage()) { - String intentUrl = IntentHandler.getUrlFromIntent(getIntent()); - if (NewTabPage.isNTPUrl(intentUrl) - || (isMainIntentFromLauncher(getIntent()) - && ReturnToChromeExperimentsUtil.getTotalTabCount(getTabModelSelector()) - <= 0)) { - return true; - } + String intentUrl = IntentHandler.getUrlFromIntent(getIntent()); + if (ReturnToChromeExperimentsUtil.shouldShowStartSurfaceAsTheHomePage() + && NewTabPage.isNTPUrl(intentUrl)) { + // Handle NTP intent. + return true; + } else if (ReturnToChromeExperimentsUtil.shouldShowStartSurfaceAsTheHomePageNoTabs() + && isMainIntentFromLauncher(getIntent()) + && ReturnToChromeExperimentsUtil.getTotalTabCount(getTabModelSelector()) <= 0) { + // Handle initial tab creation. + return true; } - long lastBackgroundedTimeMillis = mInactivityTracker.getLastBackgroundedTimeMs(); return isMainIntentFromLauncher(getIntent()) && ReturnToChromeExperimentsUtil.shouldShowTabSwitcher(lastBackgroundedTimeMillis); @@ -1215,9 +1216,8 @@ private void createInitialTab() { mPendingInitialTabCreation = false; - // If the grid tab switcher is enabled and the tab switcher will be shown on start, - // do not create a new tab. With the grid, creating a new tab is now a one tap action. - if (!(shouldShowTabSwitcherOnStart() && TabUiFeatureUtilities.isGridTabSwitcherEnabled())) { + // If the start surface will be shown on start, do not create a new tab. + if (!shouldShowTabSwitcherOnStart()) { String url = HomepageManager.getHomepageUri(); if (TextUtils.isEmpty(url)) { url = UrlConstants.NTP_URL;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java index f00f4935..9ec8da8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
@@ -84,6 +84,7 @@ StartSurfaceConfiguration.START_SURFACE_EXCLUDE_MV_TILES, StartSurfaceConfiguration.START_SURFACE_HIDE_INCOGNITO_SWITCH, StartSurfaceConfiguration.START_SURFACE_LAST_ACTIVE_TAB_ONLY, + StartSurfaceConfiguration.START_SURFACE_OPEN_NTP_INSTEAD_OF_START, StartSurfaceConfiguration.START_SURFACE_SHOW_STACK_TAB_SWITCHER, StartSurfaceConfiguration.START_SURFACE_VARIATION, TabContentManager.ALLOW_TO_REFETCH_TAB_THUMBNAIL_VARIATION,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/splashscreen/TwaSplashController.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/splashscreen/TwaSplashController.java index 63238be..e3a2a00b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/splashscreen/TwaSplashController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/splashscreen/TwaSplashController.java
@@ -24,8 +24,6 @@ import org.chromium.base.IntentUtils; import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider; -import org.chromium.chrome.browser.customtabs.BaseCustomTabActivity; -import org.chromium.chrome.browser.customtabs.CustomTabOrientationController; import org.chromium.chrome.browser.customtabs.TranslucentCustomTabActivity; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; import org.chromium.chrome.browser.lifecycle.InflationObserver; @@ -79,7 +77,6 @@ public TwaSplashController(SplashController splashController, Activity activity, ActivityWindowAndroid activityWindowAndroid, ActivityLifecycleDispatcher lifecycleDispatcher, - CustomTabOrientationController orientationController, SplashImageHolder splashImageCache, BrowserServicesIntentDataProvider intentDataProvider) { mSplashController = splashController; @@ -89,15 +86,10 @@ mSplashImageCache = splashImageCache; mIntentDataProvider = intentDataProvider; - long splashHideAnimationDurationMs = IntentUtils.safeGetInt( - getSplashScreenParamsFromIntent(), SplashScreenParamKey.KEY_FADE_OUT_DURATION_MS, - 0); - boolean isWindowInitiallyTranslucent = - BaseCustomTabActivity.isWindowInitiallyTranslucent(activity); - mSplashController.setConfig( - this, isWindowInitiallyTranslucent, splashHideAnimationDurationMs); - orientationController.delayOrientationRequestsIfNeeded( - mSplashController, isWindowInitiallyTranslucent); + long splashHideAnimationDurationMs = + IntentUtils.safeGetInt(getSplashScreenParamsFromIntent(), + SplashScreenParamKey.KEY_FADE_OUT_DURATION_MS, 0); + mSplashController.setConfig(this, splashHideAnimationDurationMs); lifecycleDispatcher.register(this); } @@ -137,12 +129,12 @@ private void applyCustomizationsToSplashScreenView(ImageView imageView) { Bundle params = getSplashScreenParamsFromIntent(); - int backgroundColor = IntentUtils.safeGetInt(params, - SplashScreenParamKey.KEY_BACKGROUND_COLOR, Color.WHITE); + int backgroundColor = IntentUtils.safeGetInt( + params, SplashScreenParamKey.KEY_BACKGROUND_COLOR, Color.WHITE); imageView.setBackgroundColor(ColorUtils.getOpaqueColor(backgroundColor)); - int scaleTypeOrdinal = IntentUtils.safeGetInt(params, - SplashScreenParamKey.KEY_SCALE_TYPE, -1); + int scaleTypeOrdinal = + IntentUtils.safeGetInt(params, SplashScreenParamKey.KEY_SCALE_TYPE, -1); ImageView.ScaleType[] scaleTypes = ImageView.ScaleType.values(); ImageView.ScaleType scaleType; if (scaleTypeOrdinal < 0 || scaleTypeOrdinal >= scaleTypes.length) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappSplashDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/splashscreen/webapps/WebappSplashController.java similarity index 76% rename from chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappSplashDelegate.java rename to chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/splashscreen/webapps/WebappSplashController.java index e17a3f0d..c6af558 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappSplashDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/splashscreen/webapps/WebappSplashController.java
@@ -1,10 +1,9 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// 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.chrome.browser.webapps; +package org.chromium.chrome.browser.browserservices.ui.splashscreen.webapps; -import android.app.Activity; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; @@ -17,26 +16,43 @@ import org.chromium.base.ContextUtils; import org.chromium.base.FileUtils; import org.chromium.base.StrictModeContext; +import org.chromium.chrome.browser.ChromeActivity; +import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider; import org.chromium.chrome.browser.customtabs.content.TabObserverRegistrar; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.webapps.SplashController; +import org.chromium.chrome.browser.webapps.SplashDelegate; +import org.chromium.chrome.browser.webapps.WebApkSplashNetworkErrorObserver; +import org.chromium.chrome.browser.webapps.WebappDataStorage; +import org.chromium.chrome.browser.webapps.WebappInfo; +import org.chromium.chrome.browser.webapps.WebappRegistry; import org.chromium.ui.util.ColorUtils; import org.chromium.webapk.lib.common.WebApkCommonUtils; import org.chromium.webapk.lib.common.splash.SplashLayout; -/** Delegate for splash screen for webapps and WebAPKs. */ -public class WebappSplashDelegate implements SplashDelegate { +import javax.inject.Inject; + +/** + * Displays the splash screen for homescreen shortcuts and WebAPKs. + */ +public class WebappSplashController implements SplashDelegate { public static final int HIDE_ANIMATION_DURATION_MS = 300; + private SplashController mSplashController; private TabObserverRegistrar mTabObserverRegistrar; - private WebappInfo mWebappInfo; private WebApkSplashNetworkErrorObserver mWebApkNetworkErrorObserver; - public WebappSplashDelegate( - Activity activity, TabObserverRegistrar tabObserverRegistrar, WebappInfo webappInfo) { + @Inject + public WebappSplashController(SplashController splashController, ChromeActivity<?> activity, + TabObserverRegistrar tabObserverRegistrar, + BrowserServicesIntentDataProvider intentDataProvider) { + mSplashController = splashController; mTabObserverRegistrar = tabObserverRegistrar; - mWebappInfo = webappInfo; + mWebappInfo = WebappInfo.create(intentDataProvider); + + mSplashController.setConfig(this, HIDE_ANIMATION_DURATION_MS); if (mWebappInfo.isForWebApk()) { mWebApkNetworkErrorObserver = @@ -45,6 +61,14 @@ } } + /** + * Called once the Activity's main layout is inflated and added to the content view. + */ + public void onInitialLayoutInflationComplete() { + // TODO: TWAs do this in onPostInflationStart(). Determine if there is a visual difference. + mSplashController.bringSplashBackToFront(); + } + @Override public View buildSplashView() { Context appContext = ContextUtils.getApplicationContext();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataFragment.java index 6ea3520f..fd35ca8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataFragment.java
@@ -590,7 +590,7 @@ // Add button to bottom of the preferences view. ButtonCompat clearButton = - (ButtonCompat) inflater.inflate(R.xml.clear_browsing_data_button, view, false); + (ButtonCompat) inflater.inflate(R.layout.clear_browsing_data_button, view, false); clearButton.setOnClickListener((View v) -> onClearButtonClicked()); view.addView(clearButton);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java index d824445..21eb50eb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java
@@ -43,7 +43,6 @@ import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.chrome.browser.tab.TabThemeColorHelper; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabCreatorManager; import org.chromium.chrome.browser.tabmodel.TabModel; @@ -143,7 +142,7 @@ /** * Protected class to handle {@link TabModelObserver} related tasks. Extending classes will * need to override any related calls to add new functionality */ - protected class LayoutManagerTabModelObserver extends EmptyTabModelObserver { + protected class LayoutManagerTabModelObserver implements TabModelObserver { @Override public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { if (tab.getId() != lastId) tabSelected(tab.getId(), lastId, tab.isIncognito());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java index 27dd37e..0becc2a2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
@@ -9,8 +9,10 @@ import android.app.Activity; import android.content.Intent; +import android.graphics.PixelFormat; import android.util.Pair; import android.view.KeyEvent; +import android.view.ViewGroup; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; @@ -18,9 +20,11 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.metrics.RecordHistogram; +import org.chromium.base.task.PostTask; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.KeyboardShortcuts; +import org.chromium.chrome.browser.WarmupManager; import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider; import org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityCoordinator; import org.chromium.chrome.browser.customtabs.content.CustomTabActivityNavigationController; @@ -45,6 +49,7 @@ import org.chromium.chrome.browser.webapps.WebappActivityCoordinator; import org.chromium.chrome.browser.webapps.WebappExtras; import org.chromium.components.embedder_support.delegate.WebContentsDelegateAndroid; +import org.chromium.content_public.browser.UiThreadTaskTraits; /** * Contains functionality which is shared between {@link WebappActivity} and @@ -54,6 +59,8 @@ */ public abstract class BaseCustomTabActivity<C extends BaseCustomTabActivityComponent> extends ChromeActivity<C> { + protected static Integer sOverrideCoreCountForTesting; + protected BrowserServicesIntentDataProvider mIntentDataProvider; protected CustomTabDelegateFactory mDelegateFactory; protected CustomTabToolbarCoordinator mToolbarCoordinator; @@ -72,6 +79,11 @@ // change the package name. protected boolean mShouldOverridePackage; + @VisibleForTesting + public static void setOverrideCoreCount(int coreCount) { + sOverrideCoreCountForTesting = coreCount; + } + /** * Builds {@link BrowserServicesIntentDataProvider} for this {@link CustomTabActivity}. */ @@ -199,6 +211,70 @@ return COLOR_SCHEME_LIGHT; } + private static int getCoreCount() { + if (sOverrideCoreCountForTesting != null) return sOverrideCoreCountForTesting; + return Runtime.getRuntime().availableProcessors(); + } + + @Override + protected void doLayoutInflation() { + // Conditionally do layout inflation synchronously if device has low core count. + // When layout inflation is done asynchronously, it blocks UI thread startup. While + // blocked, the UI thread will draw unnecessary frames - causing the lower priority + // layout inflation thread to be de-scheduled significantly more often, especially on + // devices with low core count. Thus for low core count devices, there is a startup + // performance improvement incurred by doing layout inflation synchronously. + // TODO: Determine whether this webapp speed optimization is still helpful given + // the current CCT speed optimizations. + if (!mIntentDataProvider.isWebappOrWebApkActivity() || getCoreCount() <= 2) { + super.doLayoutInflation(); + return; + } + + // Because we delay the layout inflation, the CompositorSurfaceManager and its + // SurfaceView(s) are created and attached late (ie after the first draw). At the time of + // the first attach of a SurfaceView to the view hierarchy (regardless of the SurfaceView's + // actual opacity), the window transparency hint changes (because the window creates a + // transparent hole and attaches the SurfaceView to that hole). This may cause older android + // versions to destroy the window and redraw it causing a flicker. This line sets the window + // transparency hint early so that when the SurfaceView gets attached later, the + // transparency hint need not change and no flickering occurs. + getWindow().setFormat(PixelFormat.TRANSLUCENT); + // No need to inflate layout synchronously since splash screen is displayed. + Runnable inflateTask = () -> { + ViewGroup mainView = WarmupManager.inflateViewHierarchy(BaseCustomTabActivity.this, + getControlContainerLayoutId(), getToolbarLayoutId()); + if (isActivityFinishingOrDestroyed()) return; + if (mainView != null) { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> { + if (isActivityFinishingOrDestroyed()) return; + onLayoutInflated(mainView); + }); + } else { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> { + if (isActivityFinishingOrDestroyed()) return; + BaseCustomTabActivity.super.doLayoutInflation(); + }); + } + }; + + new Thread(inflateTask).start(); + } + + private void onLayoutInflated(ViewGroup mainView) { + ViewGroup contentView = (ViewGroup) findViewById(android.R.id.content); + WarmupManager.transferViewHeirarchy(mainView, contentView); + onInitialLayoutInflationComplete(); + } + + @Override + protected void onInitialLayoutInflationComplete() { + if (mWebappActivityCoordinator != null) { + mWebappActivityCoordinator.onInitialLayoutInflationComplete(); + } + super.onInitialLayoutInflationComplete(); + } + @Override public void finishNativeInitialization() { if (isTaskRoot() && UsageStatsService.isEnabled()) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java index 62e9302..e84f4a0c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
@@ -49,6 +49,7 @@ import org.chromium.chrome.browser.night_mode.NightModeUtils; import org.chromium.chrome.browser.offlinepages.OfflinePageUtils; import org.chromium.chrome.browser.page_info.ChromePageInfoControllerDelegate; +import org.chromium.chrome.browser.page_info.ChromePermissionParamsListBuilderDelegate; import org.chromium.chrome.browser.previews.Previews; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.ui.appmenu.AppMenuPropertiesDelegate; @@ -216,7 +217,8 @@ new ChromePageInfoControllerDelegate(this, webContents, this::getModalDialogManager, /*offlinePageLoadUrlDelegate=*/ - new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(tab))); + new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(tab)), + new ChromePermissionParamsListBuilderDelegate()); return true; } return super.onMenuOrKeyboardAction(id, fromMenu);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/TabObserverRegistrar.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/TabObserverRegistrar.java index a1d9b22..0292c5c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/TabObserverRegistrar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/TabObserverRegistrar.java
@@ -15,7 +15,7 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabObserver; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; +import org.chromium.chrome.browser.tabmodel.TabModelObserver; import java.util.HashSet; import java.util.Iterator; @@ -28,7 +28,7 @@ * they enter/leave the TabModel. */ @ActivityScope -public class TabObserverRegistrar extends EmptyTabModelObserver implements Destroyable { +public class TabObserverRegistrar implements TabModelObserver, Destroyable { private CustomTabActivityTabProvider mTabProvider; private final Set<PageLoadMetrics.Observer> mPageLoadMetricsObservers = new HashSet<>(); private final Set<TabObserver> mTabObservers = new HashSet<>();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dependency_injection/BaseCustomTabActivityComponent.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dependency_injection/BaseCustomTabActivityComponent.java index 11a09e0..0519696 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dependency_injection/BaseCustomTabActivityComponent.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dependency_injection/BaseCustomTabActivityComponent.java
@@ -36,9 +36,11 @@ CustomTabStatusBarColorProvider resolveCustomTabStatusBarColorProvider(); CustomTabTaskDescriptionHelper resolveTaskDescriptionHelper(); CustomTabToolbarCoordinator resolveToolbarCoordinator(); - SplashController resolveSplashController(); TabObserverRegistrar resolveTabObserverRegistrar(); TwaFinishHandler resolveTwaFinishHandler(); WebappActivityCoordinator resolveWebappActivityCoordinator(); WebApkActivityCoordinator resolveWebApkActivityCoordinator(); + + // For testing + SplashController resolveSplashController(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/findinpage/FindToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/findinpage/FindToolbar.java index 349b16e4..3a6adf7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/findinpage/FindToolbar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/findinpage/FindToolbar.java
@@ -40,7 +40,6 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabObserver; import org.chromium.chrome.browser.tab.TabSelectionType; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelObserver; @@ -232,7 +231,7 @@ } }; - mTabModelObserver = new EmptyTabModelObserver() { + mTabModelObserver = new TabModelObserver() { @Override public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { deactivate();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java index 93282f6..a430186 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java
@@ -65,7 +65,7 @@ /** User navigated to the webpage for a snippet shown on the NTP. */ public static final int ACTION_OPENED_SNIPPET = 8; - /** User clicked on the "learn more" link in the footer. */ + /** User clicked on the "learn more" link in the footer or in the feed header menu. */ public static final int ACTION_CLICKED_LEARN_MORE = 9; /** User clicked on the "Refresh" button in the "all dismissed" state. */ @@ -74,11 +74,23 @@ /** User opened an explore sites tile. */ public static final int ACTION_OPENED_EXPLORE_SITES_TILE = 11; - /** User clicked on the "Manage Interests" item in the snippet card menu. */ + /** + * User clicked on the "Manage Interests" item in the snippet card menu or in the feed header + * menu. + */ public static final int ACTION_CLICKED_MANAGE_INTERESTS = 12; + /** User triggered a block content action. **/ + public static final int ACTION_BLOCK_CONTENT = 13; + + /** User clicked on the "Manage activity" item in the feed header menu. */ + public static final int ACTION_CLICKED_MANAGE_ACTIVITY = 14; + + /** User clicked on the feed header menu button item in the feed header menu. */ + public static final int ACTION_CLICKED_FEED_HEADER_MENU = 15; + /** The number of possible actions. */ - private static final int NUM_ACTIONS = 13; + private static final int NUM_ACTIONS = 16; /** Regular NTP impression (usually when a new tab is opened). */ public static final int NTP_IMPRESSION_REGULAR = 0;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SectionHeaderView.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SectionHeaderView.java index 9a97246..b1faa318 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SectionHeaderView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SectionHeaderView.java
@@ -14,6 +14,7 @@ import androidx.annotation.Nullable; import org.chromium.chrome.R; +import org.chromium.chrome.browser.ntp.NewTabPageUma; import org.chromium.chrome.browser.suggestions.SuggestionsMetrics; import org.chromium.chrome.browser.user_education.IPHCommandBuilder; import org.chromium.chrome.browser.user_education.UserEducationHelper; @@ -119,6 +120,8 @@ } private void displayMenu() { + NewTabPageUma.recordAction(NewTabPageUma.ACTION_CLICKED_FEED_HEADER_MENU); + if (mMenuView == null) { assert false : "No menu view to display the menu"; return;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusViewCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusViewCoordinator.java index 75b6d65..72cd4ee 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusViewCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusViewCoordinator.java
@@ -17,6 +17,7 @@ import org.chromium.chrome.browser.omnibox.UrlBar.UrlTextChangeListener; import org.chromium.chrome.browser.omnibox.UrlBarEditingTextStateProvider; import org.chromium.chrome.browser.page_info.ChromePageInfoControllerDelegate; +import org.chromium.chrome.browser.page_info.ChromePermissionParamsListBuilderDelegate; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabUtils; import org.chromium.chrome.browser.toolbar.IncognitoStateProvider; @@ -225,7 +226,8 @@ new ChromePageInfoControllerDelegate(activity, webContents, mModalDialogManagerSupplier, /*offlinePageLoadUrlDelegate=*/ - new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(tab))); + new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(tab)), + new ChromePermissionParamsListBuilderDelegate()); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/page_info/ChromePageInfoControllerDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/page_info/ChromePageInfoControllerDelegate.java index fb6111f..cde7c10 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/page_info/ChromePageInfoControllerDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/page_info/ChromePageInfoControllerDelegate.java
@@ -12,7 +12,6 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; -import org.chromium.base.Callback; import org.chromium.base.Consumer; import org.chromium.base.supplier.Supplier; import org.chromium.chrome.R; @@ -30,22 +29,15 @@ import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.site_settings.CookieControlsBridge; import org.chromium.chrome.browser.vr.VrModuleProvider; -import org.chromium.components.content_settings.ContentSettingValues; import org.chromium.components.content_settings.CookieControlsObserver; import org.chromium.components.feature_engagement.EventConstants; import org.chromium.components.page_info.PageInfoControllerDelegate; import org.chromium.components.page_info.PageInfoControllerDelegate.OfflinePageState; import org.chromium.components.page_info.PageInfoControllerDelegate.PreviewPageState; -import org.chromium.components.page_info.PageInfoFeatureList; -import org.chromium.components.page_info.PageInfoRowView; -import org.chromium.components.page_info.PageInfoView; import org.chromium.components.page_info.PageInfoView.PageInfoViewParams; -import org.chromium.components.page_info.PageInfoViewV2; -import org.chromium.components.page_info.SystemSettingsActivityRequiredListener; import org.chromium.components.security_state.ConnectionSecurityLevel; import org.chromium.components.security_state.SecurityStateModel; import org.chromium.content_public.browser.WebContents; -import org.chromium.ui.base.AndroidPermissionDelegate; import org.chromium.ui.modaldialog.ModalDialogManager; import org.chromium.ui.text.NoUnderlineClickableSpan; import org.chromium.ui.text.SpanApplier; @@ -63,7 +55,6 @@ private final Context mContext; private String mOfflinePageCreationDate; private OfflinePageLoadUrlDelegate mOfflinePageLoadUrlDelegate; - private PermissionParamsListBuilder mPermissionParamsListBuilder; // Bridge updating the CookieControlsView when cookie settings change. private CookieControlsBridge mBridge; @@ -274,48 +265,6 @@ mBridge.setThirdPartyCookieBlockingEnabledForSite(blockCookies); } - /** - * {@inheritDoc} - */ - @Override - public void createPermissionParamsListBuilder(AndroidPermissionDelegate permissionDelegate, - String fullUrl, boolean shouldShowTitle, - SystemSettingsActivityRequiredListener systemSettingsActivityRequiredListener, - Callback<PageInfoView.PermissionParams> displayPermissionsCallback) { - mPermissionParamsListBuilder = new PermissionParamsListBuilder(mContext, permissionDelegate, - fullUrl, shouldShowTitle, systemSettingsActivityRequiredListener, - displayPermissionsCallback, new ChromePermissionParamsListBuilderDelegate()); - } - - /** - * {@inheritDoc} - */ - @Override - public void addPermissionEntry( - String name, int type, @ContentSettingValues int currentSettingValue) { - assert (mPermissionParamsListBuilder != null); - mPermissionParamsListBuilder.addPermissionEntry(name, type, currentSettingValue); - } - - /** - * {@inheritDoc} - */ - @Override - public void updatePermissionDisplay(PageInfoView view) { - assert (mPermissionParamsListBuilder != null); - PageInfoView.PermissionParams params = mPermissionParamsListBuilder.build(); - if (PageInfoFeatureList.isEnabled(PageInfoFeatureList.PAGE_INFO_V2)) { - PageInfoRowView.ViewParams rowParams = new PageInfoRowView.ViewParams(); - rowParams.visible = true; - rowParams.title = mContext.getString(R.string.page_info_permissions_title); - // TODO(crbug.com/1077766): Create a permissions subtitle string that represents - // the state, potentially using R.plurals. - ((PageInfoViewV2) view).getPermissionsRowView().setParams(rowParams); - } else { - view.setPermissions(params); - } - } - @VisibleForTesting void setOfflinePageStateForTesting(@OfflinePageState int offlinePageState) { mOfflinePageState = offlinePageState;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/page_info/ChromePermissionParamsListBuilderDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/page_info/ChromePermissionParamsListBuilderDelegate.java index 8919fc8d..1578ca9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/page_info/ChromePermissionParamsListBuilderDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/page_info/ChromePermissionParamsListBuilderDelegate.java
@@ -9,8 +9,8 @@ import org.chromium.chrome.browser.browserservices.permissiondelegation.TrustedWebActivityPermissionManager; import org.chromium.chrome.browser.profiles.Profile; -import org.chromium.components.embedder_support.browser_context.BrowserContextHandle; import org.chromium.components.embedder_support.util.Origin; +import org.chromium.components.page_info.PermissionParamsListBuilderDelegate; /** * Chrome's customization of PermissionParamsListBuilderDelegate logic. @@ -18,7 +18,10 @@ public class ChromePermissionParamsListBuilderDelegate extends PermissionParamsListBuilderDelegate { private static Profile sProfileForTesting; - public ChromePermissionParamsListBuilderDelegate() {} + public ChromePermissionParamsListBuilderDelegate() { + super((sProfileForTesting != null) ? sProfileForTesting + : Profile.getLastUsedRegularProfile()); + } @Override @Nullable @@ -28,12 +31,6 @@ return manager.getDelegateAppName(origin); } - @Override - public BrowserContextHandle getBrowserContextHandle() { - return (sProfileForTesting != null) ? sProfileForTesting - : Profile.getLastUsedRegularProfile(); - } - @VisibleForTesting public static void setProfileForTesting(Profile profileForTesting) { sProfileForTesting = profileForTesting;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java index 993c255..2778218d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
@@ -41,7 +41,6 @@ import org.chromium.chrome.browser.settings.SettingsLauncherImpl; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabSelectionType; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelObserver; @@ -383,7 +382,7 @@ }; /** Monitors changes in the current TabModel. */ - private final TabModelObserver mTabModelObserver = new EmptyTabModelObserver() { + private final TabModelObserver mTabModelObserver = new TabModelObserver() { @Override public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { if (tab == null || tab.getId() != lastId) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/toolbar/PaymentHandlerToolbarCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/toolbar/PaymentHandlerToolbarCoordinator.java index 191d6b9..b993af84 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/toolbar/PaymentHandlerToolbarCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/toolbar/PaymentHandlerToolbarCoordinator.java
@@ -12,6 +12,7 @@ import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.offlinepages.OfflinePageUtils; import org.chromium.chrome.browser.page_info.ChromePageInfoControllerDelegate; +import org.chromium.chrome.browser.page_info.ChromePermissionParamsListBuilderDelegate; import org.chromium.chrome.browser.payments.handler.toolbar.PaymentHandlerToolbarMediator.PaymentHandlerToolbarMediatorDelegate; import org.chromium.components.omnibox.SecurityStatusIcon; import org.chromium.components.page_info.PageInfoController; @@ -134,6 +135,7 @@ new ChromePageInfoControllerDelegate(mActivity, mWebContents, mActivity::getModalDialogManager, /*offlinePageLoadUrlDelegate=*/ - new OfflinePageUtils.WebContentsOfflinePageLoadUrlDelegate(mWebContents))); + new OfflinePageUtils.WebContentsOfflinePageLoadUrlDelegate(mWebContents)), + new ChromePermissionParamsListBuilderDelegate()); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareParams.java b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareParams.java index 7a18da9..46053483 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareParams.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareParams.java
@@ -41,9 +41,6 @@ */ private final String mText; - /** The URL of the page to be shared. */ - private final String mUrl; - /** The common MIME type of the files to be shared. A wildcard if they have differing types. */ private final String mFileContentType; @@ -63,7 +60,7 @@ private TargetChosenCallback mCallback; private ShareParams(boolean shareDirectly, boolean saveLastUsed, WindowAndroid window, - String title, String text, String url, @Nullable String fileContentType, + String title, String text, @Nullable String fileContentType, @Nullable ArrayList<Uri> fileUris, @Nullable Uri offlineUri, @Nullable Uri screenshotUri, @Nullable TargetChosenCallback callback) { mShareDirectly = shareDirectly; @@ -71,7 +68,6 @@ mWindow = window; mTitle = title; mText = text; - mUrl = url; mFileContentType = fileContentType; mFileUris = fileUris; mOfflineUri = offlineUri; @@ -116,13 +112,6 @@ } /** - * @return The URL of the page to be shared. - */ - public String getUrl() { - return mUrl; - } - - /** * @return The MIME type to the arbitrary files to be shared. */ @Nullable @@ -175,7 +164,6 @@ private Uri mOfflineUri; private Uri mScreenshotUri; private TargetChosenCallback mCallback; - private boolean mIsExternalUrl; public Builder(@NonNull WindowAndroid window, @NonNull String title, @NonNull String url) { mWindow = window; @@ -209,14 +197,6 @@ } /** - * Sets the URL of the page to be shared. - */ - public Builder setUrl(@NonNull String url) { - mUrl = url; - return this; - } - - /** * Sets the MIME type of the arbitrary files to be shared. */ public Builder setFileContentType(@NonNull String fileContentType) { @@ -256,20 +236,10 @@ return this; } - /** - * Set whether the params are created by the url from external app. - */ - public Builder setIsExternalUrl(boolean isExternalUrl) { - mIsExternalUrl = isExternalUrl; - return this; - } - /** @return A fully constructed {@link ShareParams} object. */ public ShareParams build() { if (!TextUtils.isEmpty(mUrl)) { - if (!mIsExternalUrl) { - mUrl = DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl(mUrl); - } + mUrl = DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl(mUrl); if (!TextUtils.isEmpty(mText)) { // Concatenate text and URL with a space. mText = mText + " " + mUrl; @@ -277,7 +247,7 @@ mText = mUrl; } } - return new ShareParams(mShareDirectly, mSaveLastUsed, mWindow, mTitle, mText, mUrl, + return new ShareParams(mShareDirectly, mSaveLastUsed, mWindow, mTitle, mText, mFileContentType, mFileUris, mOfflineUri, mScreenshotUri, mCallback); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabViewManager.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabViewManager.java index e7f0f89..f673a1e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabViewManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabViewManager.java
@@ -6,6 +6,7 @@ import android.util.SparseIntArray; import android.view.View; +import android.widget.FrameLayout; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; @@ -54,6 +55,8 @@ private PriorityQueue<TabViewProvider> mTabViewProviders; private TabImpl mTab; + private View mCurrentView; + private BrowserControlsOffsetObserver mBrowserControlsOffsetObserver; public static TabViewManager get(Tab tab) { if (tab.getUserDataHost().getUserData(USER_DATA_KEY) == null) { @@ -66,6 +69,8 @@ TabViewManager(Tab tab) { mTab = (TabImpl) tab; mTabViewProviders = new PriorityQueue<>(PRIORITIZED_TAB_VIEW_PROVIDER_TYPES.length, this); + mBrowserControlsOffsetObserver = new BrowserControlsOffsetObserver(); + mTab.addObserver(mBrowserControlsOffsetObserver); } /** @@ -111,13 +116,30 @@ view = currentTabViewProvider.getView(); assert view != null; } - mTab.setCustomView(view); + mCurrentView = view; + updateViewMargins(); + mTab.setCustomView(mCurrentView); if (previousTabViewProvider != null) previousTabViewProvider.onHidden(); if (currentTabViewProvider != null) currentTabViewProvider.onShown(); } } /** + * Updates the top margin for the current view according to + * {@link TabBrowserControlsOffsetHelper}. + */ + private void updateViewMargins() { + if (mCurrentView == null) return; + + int topOffset = TabBrowserControlsOffsetHelper.get(mTab).contentOffset(); + int bottomOffset = TabBrowserControlsOffsetHelper.get(mTab).bottomControlsOffset(); + FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams( + FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT); + layoutParams.setMargins(0, topOffset, 0, bottomOffset); + mCurrentView.setLayoutParams(layoutParams); + } + + /** * Compares two {@link TabViewProvider}s based on their priority in * {@link #PRIORITIZED_TAB_VIEW_PROVIDER_TYPES}. Do not edit the logic here when you add a new * {@link TabViewProvider.Type}. Instead, simply add your new {@link TabViewProvider.Type} to @@ -136,6 +158,16 @@ TabViewProvider currentTabViewProvider = mTabViewProviders.peek(); if (currentTabViewProvider != null) currentTabViewProvider.onHidden(); mTabViewProviders.clear(); + mTab.removeObserver(mBrowserControlsOffsetObserver); mTab = null; } + + private class BrowserControlsOffsetObserver extends EmptyTabObserver { + @Override + public void onBrowserControlsOffsetChanged(Tab tab, int topControlsOffsetY, + int bottomControlsOffsetY, int contentOffsetY, int topControlsMinHeightOffsetY, + int bottomControlsMinHeightOffsetY) { + updateViewMargins(); + } + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java index f191006..480cde32 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
@@ -11,7 +11,6 @@ import org.chromium.base.TraceEvent; import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.ObservableSupplierImpl; -import org.chromium.base.supplier.Supplier; import org.chromium.base.task.PostTask; import org.chromium.chrome.R; import org.chromium.chrome.browser.ActivityTabProvider; @@ -89,6 +88,10 @@ profileSupplier, bookmarkBridgeSupplier); mIntentWithEffect = intentWithEffect; mEphemeralTabCoordinatorSupplier = ephemeralTabCoordinatorSupplier; + mCanAnimateBrowserControls = () -> { + final Tab tab = mActivity.getActivityTabProvider().get(); + return tab != null && tab.isUserInteractable() && !tab.isNativePage(); + }; } @Override @@ -218,15 +221,10 @@ } final ChromeFullscreenManager fullscreenManager = mActivity.getFullscreenManager(); - Supplier<Boolean> canAnimateBrowserControls = () -> { - final Tab tab = mActivity.getActivityTabProvider().get(); - return tab != null && tab.isUserInteractable() && !tab.isNativePage(); - }; - mToolbarManager.setCanAnimateNativeBrowserControlsSupplier(canAnimateBrowserControls); mStatusIndicatorCoordinator = new StatusIndicatorCoordinator(mActivity, mActivity.getCompositorViewHolder().getResourceManager(), fullscreenManager, mActivity.getStatusBarColorController()::getStatusBarColorWithoutStatusIndicator, - canAnimateBrowserControls, layoutManager::requestUpdate); + mCanAnimateBrowserControls, layoutManager::requestUpdate); layoutManager.setStatusIndicatorSceneOverlay(mStatusIndicatorCoordinator.getSceneLayer()); mStatusIndicatorObserver = new StatusIndicatorCoordinator.StatusIndicatorObserver() { @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java index c226b3f1..b69cd64 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java
@@ -45,11 +45,11 @@ public interface OverviewNTPCreator { /** * Handles showing the StartSurface instead of the NTP if needed. - * @param isNTPUrl Whether tab with NTP should be created. + * @param isNTP Whether tab with NTP should be created. * @param isIncognito Whether tab is created in incognito. * @return Whether NTP creation was handled. */ - boolean handleCreateNTPIfNeeded(boolean isNTP, boolean incognito); + boolean handleCreateNTPIfNeeded(boolean isNTP, boolean isIncognito); } private final ChromeActivity mActivity;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModelObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModelObserver.java deleted file mode 100644 index fd30b5ed..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModelObserver.java +++ /dev/null
@@ -1,56 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.tabmodel; - -import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tab.TabCreationState; -import org.chromium.chrome.browser.tab.TabLaunchType; -import org.chromium.chrome.browser.tab.TabSelectionType; - -import java.util.List; - -/** - * An empty base implementation of the TabModelObserver interface. - */ -public class EmptyTabModelObserver implements TabModelObserver { - @Override - public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) {} - - @Override - public void willCloseTab(Tab tab, boolean animate) {} - - @Override - public void didCloseTab(int tabId, boolean incognito) {} - - @Override - public void willAddTab(Tab tab, @TabLaunchType int type) {} - - @Override - public void didAddTab(Tab tab, @TabLaunchType int type, @TabCreationState int creationState) {} - - @Override - public void didMoveTab(Tab tab, int newIndex, int curIndex) {} - - @Override - public void tabPendingClosure(Tab tab) {} - - @Override - public void tabClosureUndone(Tab tab) {} - - @Override - public void tabClosureCommitted(Tab tab) {} - - @Override - public void multipleTabsPendingClosure(List<Tab> tabs, boolean isAllTabs) {} - - @Override - public void allTabsClosureCommitted() {} - - @Override - public void tabRemoved(Tab tab) {} - - @Override - public void restoreCompleted() {} -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelFilter.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelFilter.java index 43ad577b..348e890 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelFilter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelFilter.java
@@ -24,7 +24,7 @@ * If there is at least one filter active, this is a {@link TabList} that contains the most * important tabs that the filter defines. */ -public abstract class TabModelFilter extends EmptyTabModelObserver implements TabList { +public abstract class TabModelFilter implements TabModelObserver, TabList { private static final List<Tab> sEmptyRelatedTabList = Collections.unmodifiableList(new ArrayList<Tab>()); private TabModel mTabModel;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelObserver.java index c9275b47..5cc47f8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelObserver.java
@@ -21,9 +21,9 @@ * @param tab The newly selected tab. * @param type The type of selection. * @param lastId The ID of the last selected tab, or {@link Tab#INVALID_TAB_ID} if no tab was - * selected. + * selected. */ - void didSelectTab(Tab tab, @TabSelectionType int type, int lastId); + default void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) {} /** * Called when a tab starts closing. @@ -31,7 +31,7 @@ * @param tab The tab to close. * @param animate Whether or not to animate the closing. */ - void willCloseTab(Tab tab, boolean animate); + default void willCloseTab(Tab tab, boolean animate) {} /** * Called right after {@code tab} has been destroyed. @@ -39,7 +39,7 @@ * @param tabId The ID of the tab that was destroyed. * @param incognito True if the closed tab was incognito. */ - void didCloseTab(int tabId, boolean incognito); + default void didCloseTab(int tabId, boolean incognito) {} /** * Called before a tab will be added to the {@link TabModel}. @@ -47,7 +47,7 @@ * @param tab The tab about to be added. * @param type The type of tab launch. */ - void willAddTab(Tab tab, @TabLaunchType int type); + default void willAddTab(Tab tab, @TabLaunchType int type) {} /** * Called after a tab has been added to the {@link TabModel}. @@ -56,7 +56,7 @@ * @param type The type of tab launch. * @param creationState How the tab was created. */ - void didAddTab(Tab tab, @TabLaunchType int type, @TabCreationState int creationState); + default void didAddTab(Tab tab, @TabLaunchType int type, @TabCreationState int creationState) {} /** * Called after a tab has been moved from one position in the {@link TabModel} to another. @@ -65,7 +65,7 @@ * @param newIndex The new index of the tab in the model. * @param curIndex The old index of the tab in the model. */ - void didMoveTab(Tab tab, int newIndex, int curIndex); + default void didMoveTab(Tab tab, int newIndex, int curIndex) {} /** * Called when a tab is pending closure, i.e. the user has just closed it, but it can still be @@ -74,21 +74,21 @@ * * @param tab The tab that is pending closure. */ - void tabPendingClosure(Tab tab); + default void tabPendingClosure(Tab tab) {} /** * Called when a tab closure is undone. * * @param tab The tab that has been reopened. */ - void tabClosureUndone(Tab tab); + default void tabClosureUndone(Tab tab) {} /** * Called when a tab closure is committed and can't be undone anymore. * * @param tab The tab that has been closed. */ - void tabClosureCommitted(Tab tab); + default void tabClosureCommitted(Tab tab) {} /** * Called when multiple tabs are pending closure. @@ -96,23 +96,23 @@ * @param tabs The tabs that are pending closure. * @param isAllTabs Whether |tabs| are all the tabs. */ - void multipleTabsPendingClosure(List<Tab> tabs, boolean isAllTabs); + default void multipleTabsPendingClosure(List<Tab> tabs, boolean isAllTabs) {} /** * Called when an "all tabs" closure has been committed and can't be undone anymore. */ - void allTabsClosureCommitted(); + default void allTabsClosureCommitted() {} /** * Called after a tab has been removed. At this point, the tab is no longer in the tab model. * * @param tab The tab that has been removed. */ - void tabRemoved(Tab tab); + default void tabRemoved(Tab tab) {} /** * Called after all {@link org.chromium.chrome.browser.tab.TabState}s within {@link TabModel} * are loaded from storage. */ - void restoreCompleted(); + default void restoreCompleted() {} }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorBase.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorBase.java index d26cc4a6..1a6fc00 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorBase.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorBase.java
@@ -55,7 +55,7 @@ assert mActiveModelIndex != MODEL_NOT_FOUND; mTabModelFilterProvider = new TabModelFilterProvider(mTabModels); - TabModelObserver tabModelObserver = new EmptyTabModelObserver() { + TabModelObserver tabModelObserver = new TabModelObserver() { @Override public void didAddTab( Tab tab, @TabLaunchType int type, @TabCreationState int creationState) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorTabModelObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorTabModelObserver.java index 5a5eb04a..1809cd76 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorTabModelObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorTabModelObserver.java
@@ -16,7 +16,7 @@ * This can safely be constructed before native libraries have been initialized as this will * register to observe the underlying TabModels as they are created lazily. */ -public class TabModelSelectorTabModelObserver extends EmptyTabModelObserver { +public class TabModelSelectorTabModelObserver implements TabModelObserver { private final TabModelSelector mTabModelSelector; private TabModelSelectorObserver mSelectorObserver;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tasks/ReturnToChromeExperimentsUtil.java b/chrome/android/java/src/org/chromium/chrome/browser/tasks/ReturnToChromeExperimentsUtil.java index c1d3a0ca..d447e1d2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tasks/ReturnToChromeExperimentsUtil.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tasks/ReturnToChromeExperimentsUtil.java
@@ -201,12 +201,26 @@ } /** - * Check whether we should show Start Surface as the home page. - * @return Whether Start Surface should be shown as the home page, otherwise false. + * Check whether we should show Start Surface as the home page. This is used for all cases + * except initial tab creation, which uses {@link + * #shouldShowStartSurfaceAsTheHomePageNoTabs()}. + * + * @return Whether Start Surface should be shown as the home page. */ public static boolean shouldShowStartSurfaceAsTheHomePage() { - // Note that we should only show StartSurface as the HomePage if Single Pane is enabled, - // HomePage is not customized, accessibility is not enabled and not on tablet. + return shouldShowStartSurfaceAsTheHomePageNoTabs() + && !StartSurfaceConfiguration.START_SURFACE_OPEN_NTP_INSTEAD_OF_START.getValue(); + } + + /** + * Check whether we should show Start Surface as the home page for initial tab creation. + * + * @return Whether Start Surface should be shown as the home page. + */ + public static boolean shouldShowStartSurfaceAsTheHomePageNoTabs() { + // When creating initial tab, i.e. cold start without restored tabs, we should only show + // StartSurface as the HomePage if Single Pane is enabled, HomePage is not customized, + // accessibility is not enabled and not on tablet. String homePageUrl = HomepageManager.getHomepageUri(); return StartSurfaceConfiguration.isStartSurfaceSinglePaneEnabled() && (TextUtils.isEmpty(homePageUrl) || isNTPUrl(homePageUrl))
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/TabCountProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/TabCountProvider.java index 8a4dbf3d..5377c39f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/TabCountProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/TabCountProvider.java
@@ -8,7 +8,6 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelObserver; @@ -105,7 +104,7 @@ }; mTabModelSelector.addObserver(mTabModelSelectorObserver); - mTabModelFilterObserver = new EmptyTabModelObserver() { + mTabModelFilterObserver = new TabModelObserver() { @Override public void didAddTab( Tab tab, @TabLaunchType int type, @TabCreationState int creationState) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/TabSwitcherButtonCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/TabSwitcherButtonCoordinator.java index 9749f7f..de099cb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/TabSwitcherButtonCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/TabSwitcherButtonCoordinator.java
@@ -12,9 +12,6 @@ import org.chromium.chrome.browser.compositor.layouts.EmptyOverviewModeObserver; import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; import org.chromium.chrome.browser.compositor.layouts.OverviewModeState; -import org.chromium.chrome.browser.tabmodel.TabModelSelector; -import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; -import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabModelObserver; import org.chromium.chrome.browser.toolbar.TabCountProvider.TabCountObserver; import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModelChangeProcessor; @@ -32,10 +29,6 @@ private final PropertyModel mTabSwitcherButtonModel = new PropertyModel(TabSwitcherButtonProperties.ALL_KEYS); - private TabModelSelector mTabModelSelector; - private TabModelSelectorObserver mTabModelSelectorObserver; - private TabModelSelectorTabModelObserver mTabModelSelectorTabModelObserver; - private ThemeColorProvider mThemeColorProvider; private TintObserver mTintObserver;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java index 24ed6d42..01c4efc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -211,7 +211,7 @@ private int mCurrentOrientation; - private Supplier<Boolean> mCanAnimateNativeBrowserControls; + private final Supplier<Boolean> mCanAnimateNativeBrowserControls; /** * Runnable for the home and search accelerator button when Start Surface home page is enabled. @@ -251,12 +251,14 @@ List<ButtonDataProvider> buttonDataProviders, ActivityTabProvider tabProvider, ScrimCoordinator scrimCoordinator, ToolbarActionModeCallback toolbarActionModeCallback, FindToolbarManager findToolbarManager, ObservableSupplier<Profile> profileSupplier, - ObservableSupplier<BookmarkBridge> bookmarkBridgeSupplier) { + ObservableSupplier<BookmarkBridge> bookmarkBridgeSupplier, + @Nullable Supplier<Boolean> canAnimateNativeBrowserControls) { mActivity = activity; mFullscreenManager = fullscreenManager; mActionBarDelegate = new ViewShiftingActionBarDelegate(activity, controlContainer); mShareDelegateSupplier = shareDelegateSupplier; mBottomToolbarVisibilitySupplier = bottomToolbarVisibilitySupplier; + mCanAnimateNativeBrowserControls = canAnimateNativeBrowserControls; mLocationBarModel = new LocationBarModel(activity); mControlContainer = controlContainer; @@ -1360,16 +1362,6 @@ } /** - * Set a supplier that will provide a boolean indicating whether the browser controls in native - * can be animated. E.g. true if the current tab is user interactable. - * @param canAnimateNativeBrowserControlsSupplier The boolean supplier. - */ - public void setCanAnimateNativeBrowserControlsSupplier( - Supplier<Boolean> canAnimateNativeBrowserControlsSupplier) { - mCanAnimateNativeBrowserControls = canAnimateNativeBrowserControlsSupplier; - } - - /** * Record histograms covering Chrome startup. * This method will collect metrics no sooner than RECORD_UMA_PERFORMANCE_METRICS_DELAY_MS since * Activity creation to ensure availability of collected data.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java index c00ba34..1664424 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java
@@ -57,6 +57,7 @@ import org.chromium.chrome.browser.omnibox.UrlBarData; import org.chromium.chrome.browser.omnibox.voice.VoiceRecognitionHandler; import org.chromium.chrome.browser.page_info.ChromePageInfoControllerDelegate; +import org.chromium.chrome.browser.page_info.ChromePermissionParamsListBuilderDelegate; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.share.ShareDelegate; import org.chromium.chrome.browser.tab.Tab; @@ -610,7 +611,8 @@ new ChromePageInfoControllerDelegate(activity, webContents, activity::getModalDialogManager, /*offlinePageLoadUrlDelegate=*/ - new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(currentTab))); + new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(currentTab)), + new ChromePermissionParamsListBuilderDelegate()); }); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarView.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarView.java index 435fc90f..12679783 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarView.java
@@ -8,6 +8,7 @@ import android.content.res.ColorStateList; import android.graphics.Rect; import android.graphics.drawable.Drawable; +import android.os.Build; import android.util.AttributeSet; import android.view.View; import android.view.ViewPropertyAnimator; @@ -133,6 +134,12 @@ */ void setNewTabButtonVisibility(boolean isVisible) { mNewTabButton.setVisibility(isVisible ? View.VISIBLE : View.GONE); + if (isVisible && Build.VERSION.SDK_INT < Build.VERSION_CODES.P) { + // This is a workaround for the issue that the UrlBar is given the default focus on + // Android versions before Pie when showing the start surface toolbar with the new tab + // button (UrlBar is invisible to users). Check crbug.com/1081538 for more details. + mNewTabButton.getParent().requestChildFocus(mNewTabButton, mNewTabButton); + } } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTCoordinatorPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTCoordinatorPhone.java index a14d9b84..b0bb41c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTCoordinatorPhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTCoordinatorPhone.java
@@ -15,7 +15,6 @@ import org.chromium.chrome.browser.incognito.IncognitoUtils; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabCreationState; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; @@ -214,7 +213,7 @@ assert mTabModelSelector != null; mTabSwitcherModeToolbar.setTabModelSelector(mTabModelSelector); if (isNewTabVariationEnabled()) { - mTabModelObserver = new EmptyTabModelObserver() { + mTabModelObserver = new TabModelObserver() { @Override public void didAddTab(Tab tab, int type, @TabCreationState int creationState) { assert tab.isIncognito();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java index 947974e..8ff0c85 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java
@@ -1910,8 +1910,6 @@ private boolean handleOmniboxInOverviewMode(boolean inTabSwitcherMode) { if (!getToolbarDataProvider().shouldShowLocationBarInOverviewMode()) return false; - mIsHomeButtonEnabled = !inTabSwitcherMode; - if (mToggleTabStackButton != null) { boolean isGone = inTabSwitcherMode || isTabSwitcherOnBottom(); mToggleTabStackButton.setVisibility(isGone ? GONE : VISIBLE);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java index 74261607..f1e00b57 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java
@@ -104,6 +104,7 @@ @Nullable private Callback<Boolean> mOnOmniboxFocusChangedListener; protected ToolbarManager mToolbarManager; + protected Supplier<Boolean> mCanAnimateBrowserControls; private ModalDialogManagerObserver mModalDialogManagerObserver; private VrModeObserver mVrModeObserver; @@ -433,7 +434,7 @@ mShareDelegateSupplier, bottomToolbarVisibilitySupplier, mIdentityDiscController, mButtonDataProviders, mActivityTabProvider, mScrimCoordinator, mActionModeControllerCallback, mFindToolbarManager, - mProfileSupplier, mBookmarkBridgeSupplier); + mProfileSupplier, mBookmarkBridgeSupplier, mCanAnimateBrowserControls); if (!mActivity.supportsAppMenu()) { mToolbarManager.getToolbar().disableMenuButton(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ui/tablet/emptybackground/EmptyBackgroundViewWrapper.java b/chrome/android/java/src/org/chromium/chrome/browser/ui/tablet/emptybackground/EmptyBackgroundViewWrapper.java index 6f3068f0..25ada669b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ui/tablet/emptybackground/EmptyBackgroundViewWrapper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ui/tablet/emptybackground/EmptyBackgroundViewWrapper.java
@@ -18,7 +18,6 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabCreatorManager.TabCreator; import org.chromium.chrome.browser.tabmodel.TabModel; @@ -75,7 +74,7 @@ overviewModeBehavior -> mOverviewModeBehavior = overviewModeBehavior; mOverviewModeBehaviorSupplier.addObserver(mOverviewModeSupplierCallback); - mTabModelObserver = new EmptyTabModelObserver() { + mTabModelObserver = new TabModelObserver() { @Override public void didAddTab( Tab tab, @TabLaunchType int type, @TabCreationState int creationState) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ui/tablet/emptybackground/incognitotoggle/IncognitoToggleButtonTablet.java b/chrome/android/java/src/org/chromium/chrome/browser/ui/tablet/emptybackground/incognitotoggle/IncognitoToggleButtonTablet.java index 73a5156..ab296b01 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ui/tablet/emptybackground/incognitotoggle/IncognitoToggleButtonTablet.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ui/tablet/emptybackground/incognitotoggle/IncognitoToggleButtonTablet.java
@@ -12,7 +12,6 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; @@ -69,7 +68,7 @@ if (selector != null) { updateButtonVisibility(); - mTabModelObserver = new EmptyTabModelObserver() { + mTabModelObserver = new TabModelObserver() { @Override public void didAddTab( Tab tab, @TabLaunchType int type, @TabCreationState int creationState) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/undo_tab_close_snackbar/UndoBarController.java b/chrome/android/java/src/org/chromium/chrome/browser/undo_tab_close_snackbar/UndoBarController.java index 84db1415..2dac29e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/undo_tab_close_snackbar/UndoBarController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/undo_tab_close_snackbar/UndoBarController.java
@@ -10,7 +10,6 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.device.DeviceClassManager; import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; @@ -61,7 +60,7 @@ mSnackbarManagable = snackbarManagable; mTabModelSelector = selector; mContext = context; - mTabModelObserver = new EmptyTabModelObserver() { + mTabModelObserver = new TabModelObserver() { private boolean disableUndo() { return AccessibilityUtil.isAccessibilityEnabled() || DeviceClassManager.enableAccessibilityLayout();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/SplashController.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/SplashController.java index 9bbcb03..d64216068 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/SplashController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/SplashController.java
@@ -25,6 +25,8 @@ import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.browserservices.trustedwebactivityui.TwaFinishHandler; import org.chromium.chrome.browser.compositor.CompositorView; +import org.chromium.chrome.browser.customtabs.BaseCustomTabActivity; +import org.chromium.chrome.browser.customtabs.CustomTabOrientationController; import org.chromium.chrome.browser.customtabs.content.TabObserverRegistrar; import org.chromium.chrome.browser.customtabs.content.TabObserverRegistrar.CustomTabTabObserver; import org.chromium.chrome.browser.dependency_injection.ActivityScope; @@ -119,7 +121,8 @@ @Inject public SplashController(ChromeActivity<?> activity, ActivityLifecycleDispatcher lifecycleDispatcher, - TabObserverRegistrar tabObserverRegistrar, TwaFinishHandler finishHandler) { + TabObserverRegistrar tabObserverRegistrar, + CustomTabOrientationController orientationController, TwaFinishHandler finishHandler) { mActivity = activity; mLifecycleDispatcher = lifecycleDispatcher; mTabObserverRegistrar = tabObserverRegistrar; @@ -127,15 +130,19 @@ mTranslucencyRemovalStrategy = TranslucencyRemoval.NONE; mFinishHandler = finishHandler; + boolean isWindowInitiallyTranslucent = + BaseCustomTabActivity.isWindowInitiallyTranslucent(activity); + mTranslucencyRemovalStrategy = + computeTranslucencyRemovalStrategy(isWindowInitiallyTranslucent); + + orientationController.delayOrientationRequestsIfNeeded(this, isWindowInitiallyTranslucent); + mLifecycleDispatcher.register(this); mTabObserverRegistrar.registerActivityTabObserver(this); } - public void setConfig(SplashDelegate delegate, boolean isWindowInitiallyTranslucent, - long splashHideAnimationDurationMs) { + public void setConfig(SplashDelegate delegate, long splashHideAnimationDurationMs) { mDelegate = delegate; - mTranslucencyRemovalStrategy = - computeTranslucencyRemovalStrategy(isWindowInitiallyTranslucent); mSplashHideAnimationDurationMs = splashHideAnimationDurationMs; if (mDidPreInflationStartup) { showSplash();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java index 3f70bfc..d9850e9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java
@@ -5,22 +5,18 @@ package org.chromium.chrome.browser.webapps; import android.content.Intent; -import android.graphics.PixelFormat; import android.graphics.drawable.Drawable; import android.net.Uri; import android.text.TextUtils; -import android.view.ViewGroup; import androidx.annotation.VisibleForTesting; import androidx.browser.customtabs.CustomTabsIntent; import org.chromium.base.IntentUtils; import org.chromium.base.metrics.RecordUserAction; -import org.chromium.base.task.PostTask; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeApplication; import org.chromium.chrome.browser.IntentHandler; -import org.chromium.chrome.browser.WarmupManager; import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider; import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider.CustomTabsUiType; import org.chromium.chrome.browser.customtabs.BaseCustomTabActivity; @@ -34,7 +30,6 @@ import org.chromium.chrome.browser.ui.appmenu.AppMenuPropertiesDelegate; import org.chromium.chrome.browser.webapps.dependency_injection.WebappActivityComponent; import org.chromium.chrome.browser.webapps.dependency_injection.WebappActivityModule; -import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.webapk.lib.common.WebApkConstants; import java.util.ArrayList; @@ -50,11 +45,8 @@ private static BrowserServicesIntentDataProvider sIntentDataProviderOverride; private WebappActivityTabController mTabController; - private SplashController mSplashController; private TabObserverRegistrar mTabObserverRegistrar; - private static Integer sOverrideCoreCountForTesting; - @Override protected BrowserServicesIntentDataProvider buildIntentDataProvider( Intent intent, @CustomTabsIntent.ColorScheme int colorScheme) { @@ -94,70 +86,6 @@ mTabController.initializeState(); } - @VisibleForTesting - public static void setOverrideCoreCount(int coreCount) { - sOverrideCoreCountForTesting = coreCount; - } - - private static int getCoreCount() { - if (sOverrideCoreCountForTesting != null) return sOverrideCoreCountForTesting; - return Runtime.getRuntime().availableProcessors(); - } - - @Override - protected void doLayoutInflation() { - // Because we delay the layout inflation, the CompositorSurfaceManager and its - // SurfaceView(s) are created and attached late (ie after the first draw). At the time of - // the first attach of a SurfaceView to the view hierarchy (regardless of the SurfaceView's - // actual opacity), the window transparency hint changes (because the window creates a - // transparent hole and attaches the SurfaceView to that hole). This may cause older android - // versions to destroy the window and redraw it causing a flicker. This line sets the window - // transparency hint early so that when the SurfaceView gets attached later, the - // transparency hint need not change and no flickering occurs. - getWindow().setFormat(PixelFormat.TRANSLUCENT); - // No need to inflate layout synchronously since splash screen is displayed. - Runnable inflateTask = () -> { - ViewGroup mainView = WarmupManager.inflateViewHierarchy( - WebappActivity.this, getControlContainerLayoutId(), getToolbarLayoutId()); - if (isActivityFinishingOrDestroyed()) return; - if (mainView != null) { - PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> { - if (isActivityFinishingOrDestroyed()) return; - onLayoutInflated(mainView); - }); - } else { - if (isActivityFinishingOrDestroyed()) return; - PostTask.postTask( - UiThreadTaskTraits.DEFAULT, () -> WebappActivity.super.doLayoutInflation()); - } - }; - - // Conditionally do layout inflation synchronously if device has low core count. - // When layout inflation is done asynchronously, it blocks UI thread startup. While - // blocked, the UI thread will draw unnecessary frames - causing the lower priority - // layout inflation thread to be de-scheduled significantly more often, especially on - // devices with low core count. Thus for low core count devices, there is a startup - // performance improvement incurred by doing layout inflation synchronously. - if (getCoreCount() > 2) { - new Thread(inflateTask).start(); - } else { - inflateTask.run(); - } - } - - private void onLayoutInflated(ViewGroup mainView) { - ViewGroup contentView = (ViewGroup) findViewById(android.R.id.content); - WarmupManager.transferViewHeirarchy(mainView, contentView); - mSplashController.bringSplashBackToFront(); - onInitialLayoutInflationComplete(); - } - - @Override - public void performPreInflationStartup() { - super.performPreInflationStartup(); - initSplash(); - } - @Override protected WebappActivityComponent createComponent(ChromeActivityCommonsModule commonsModule) { IntentIgnoringCriterion intentIgnoringCriterion = @@ -172,7 +100,6 @@ onComponentCreated(component); mTabController = component.resolveTabController(); - mSplashController = component.resolveSplashController(); mTabObserverRegistrar = component.resolveTabObserverRegistrar(); mNavigationController.setFinishHandler((reason) -> { handleFinishAndClose(); }); @@ -236,11 +163,6 @@ return true; } - @VisibleForTesting - SplashController getSplashControllerForTests() { - return mSplashController; - } - @Override protected Drawable getBackgroundDrawable() { return null; @@ -252,14 +174,4 @@ protected boolean isContextualSearchAllowed() { return false; } - - /** Inits the splash screen */ - private void initSplash() { - // Splash screen is shown after preInflationStartup() is run and the delegate is set. - boolean isWindowInitiallyTranslucent = - BaseCustomTabActivity.isWindowInitiallyTranslucent(this); - mSplashController.setConfig(new WebappSplashDelegate(this, mTabObserverRegistrar, - WebappInfo.create(mIntentDataProvider)), - isWindowInitiallyTranslucent, WebappSplashDelegate.HIDE_ANIMATION_DURATION_MS); - } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivityCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivityCoordinator.java index 28c895f..652aaf25 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivityCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivityCoordinator.java
@@ -12,8 +12,7 @@ import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider; import org.chromium.chrome.browser.browserservices.trustedwebactivityui.controller.CurrentPageVerifier; import org.chromium.chrome.browser.browserservices.ui.SharedActivityCoordinator; -import org.chromium.chrome.browser.customtabs.BaseCustomTabActivity; -import org.chromium.chrome.browser.customtabs.CustomTabOrientationController; +import org.chromium.chrome.browser.browserservices.ui.splashscreen.webapps.WebappSplashController; import org.chromium.chrome.browser.dependency_injection.ActivityScope; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; import org.chromium.chrome.browser.lifecycle.InflationObserver; @@ -34,6 +33,7 @@ private final BrowserServicesIntentDataProvider mIntentDataProvider; private final WebappInfo mWebappInfo; private final ChromeActivity<?> mActivity; + private final WebappSplashController mSplashController; private final WebappDeferredStartupWithStorageHandler mDeferredStartupWithStorageHandler; // Whether the current page is within the webapp's scope. @@ -43,7 +43,7 @@ public WebappActivityCoordinator(SharedActivityCoordinator sharedActivityCoordinator, ChromeActivity<?> activity, BrowserServicesIntentDataProvider intentDataProvider, ActivityTabProvider activityTabProvider, CurrentPageVerifier currentPageVerifier, - CustomTabOrientationController orientationController, SplashController splashController, + WebappSplashController splashController, WebappDeferredStartupWithStorageHandler deferredStartupWithStorageHandler, WebappActionsNotificationManager actionsNotificationManager, ActivityLifecycleDispatcher lifecycleDispatcher) { @@ -53,6 +53,7 @@ mIntentDataProvider = intentDataProvider; mWebappInfo = WebappInfo.create(mIntentDataProvider); mActivity = activity; + mSplashController = splashController; mDeferredStartupWithStorageHandler = deferredStartupWithStorageHandler; // WebappActiveTabUmaTracker sets itself as an observer of |activityTabProvider|. @@ -66,9 +67,6 @@ } }); - orientationController.delayOrientationRequestsIfNeeded( - splashController, BaseCustomTabActivity.isWindowInitiallyTranslucent(activity)); - lifecycleDispatcher.register(this); // Initialize the WebappRegistry and warm up the shared preferences for this web app. No-ops @@ -87,6 +85,13 @@ mDeferredStartupWithStorageHandler.initDeferredStartupForActivity(); } + /** + * Called once the Activity's main layout is inflated and added to the content view. + */ + public void onInitialLayoutInflationComplete() { + mSplashController.onInitialLayoutInflationComplete(); + } + @Override public void onPreInflationStartup() { LaunchMetrics.recordHomeScreenLaunchIntoStandaloneActivity(mWebappInfo);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/accessibility_tab_switcher/OverviewListLayoutTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/accessibility_tab_switcher/OverviewListLayoutTest.java index 755c597..59e3c96 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/accessibility_tab_switcher/OverviewListLayoutTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/accessibility_tab_switcher/OverviewListLayoutTest.java
@@ -29,8 +29,8 @@ import org.chromium.chrome.browser.compositor.overlays.strip.StripLayoutTab; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModel; +import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.util.ChromeTabUtils; @@ -206,7 +206,7 @@ final CallbackHelper didReceiveClosureCommittedHelper = new CallbackHelper(); final TabModel model = mActivityTestRule.getActivity().getCurrentTabModel(); - model.addObserver(new EmptyTabModelObserver() { + model.addObserver(new TabModelObserver() { @Override public void tabClosureCommitted(Tab tab) { didReceiveClosureCommittedHelper.notifyCalled(); @@ -237,7 +237,7 @@ final CallbackHelper didReceiveClosureCommittedHelper = new CallbackHelper(); final TabModel model = mActivityTestRule.getActivity().getCurrentTabModel(); - model.addObserver(new EmptyTabModelObserver() { + model.addObserver(new TabModelObserver() { @Override public void tabClosureCommitted(Tab tab) { didReceiveClosureCommittedHelper.notifyCalled(); @@ -287,7 +287,7 @@ final CallbackHelper didReceivePendingClosureHelper = new CallbackHelper(); final TabModel model = mActivityTestRule.getActivity().getCurrentTabModel(); - model.addObserver(new EmptyTabModelObserver() { + model.addObserver(new TabModelObserver() { @Override public void tabPendingClosure(Tab tab) { didReceivePendingClosureHelper.notifyCalled(); @@ -453,7 +453,7 @@ getListItemAndDisableAnimations(0); final CallbackHelper didReceiveClosureCommittedHelper = new CallbackHelper(); final TabModel model = mActivityTestRule.getActivity().getCurrentTabModel(); - model.addObserver(new EmptyTabModelObserver() { + model.addObserver(new TabModelObserver() { @Override public void tabClosureCommitted(Tab tab) { didReceiveClosureCommittedHelper.notifyCalled();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java index f35ac7f2..5a1c022 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
@@ -104,7 +104,7 @@ import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabObserver; import org.chromium.chrome.browser.tab.TabTestUtils; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; +import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.test.ScreenShooter; import org.chromium.chrome.browser.toolbar.top.CustomTabToolbar; @@ -1167,7 +1167,7 @@ final CallbackHelper openTabHelper = new CallbackHelper(); TestThreadUtils.runOnUiThreadBlocking(() -> { - tabSelector.getModel(false).addObserver(new EmptyTabModelObserver() { + tabSelector.getModel(false).addObserver(new TabModelObserver() { @Override public void didAddTab( Tab tab, @TabLaunchType int type, @TabCreationState int creationState) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/content/TabObserverRegistrarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/content/TabObserverRegistrarTest.java index 9bccf34..aee8421 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/content/TabObserverRegistrarTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/content/TabObserverRegistrarTest.java
@@ -22,7 +22,7 @@ import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabSelectionType; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; +import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.content_public.browser.LoadUrlParams; @@ -86,7 +86,7 @@ // Open and wait for popup. final CallbackHelper openTabHelper = new CallbackHelper(); TestThreadUtils.runOnUiThreadBlocking(() -> { - tabSelector.getModel(false).addObserver(new EmptyTabModelObserver() { + tabSelector.getModel(false).addObserver(new TabModelObserver() { @Override public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { if (tab != initialActiveTab) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtilsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtilsTest.java index 63eafbc..a9843e4 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtilsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtilsTest.java
@@ -198,7 +198,7 @@ */ class TestShareCallback implements Callback<ShareParams> { private Semaphore mSemaphore; - private String mUri; + private String mText; public TestShareCallback(Semaphore semaphore) { mSemaphore = semaphore; @@ -206,12 +206,12 @@ @Override public void onResult(ShareParams shareParams) { - mUri = shareParams.getUrl(); + mText = shareParams.getText(); mSemaphore.release(); } - public String getSharedUri() { - return mUri; + public String getSharedText() { + return mText; } } @@ -280,11 +280,8 @@ // Wait for share callback to get called. Assert.assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS)); - // Assert that URI is what we expected. - String foundUri = shareCallback.getSharedUri(); - Uri uri = Uri.parse(foundUri); - String uriPath = uri.getPath(); - Assert.assertEquals(TEST_PAGE, uriPath); + // Assert that text is what we expected. + Assert.assertTrue(shareCallback.getSharedText().contains(TEST_PAGE)); } @Test @@ -307,8 +304,7 @@ // Wait for share callback to get called. Assert.assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS)); // Assert that URI is what we expected. - String foundUri = shareCallback.getSharedUri(); - Assert.assertTrue(foundUri.startsWith(CONTENT_URI_PREFIX)); + Assert.assertTrue(shareCallback.getSharedText().contains(CONTENT_URI_PREFIX)); } // Checks on the UI thread if an offline path corresponds to a sharable file.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoControllerTest.java index 247c800..31e0779 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoControllerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoControllerTest.java
@@ -71,7 +71,8 @@ new ChromePageInfoControllerDelegate(activity, tab.getWebContents(), activity::getModalDialogManager, /*offlinePageLoadUrlDelegate=*/ - new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(tab))); + new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(tab)), + new ChromePermissionParamsListBuilderDelegate()); }); } @@ -96,9 +97,12 @@ new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(tab)); chromePageInfoControllerDelegate.setOfflinePageStateForTesting( ChromePageInfoControllerDelegate.OfflinePageState.NOT_OFFLINE_PAGE); - PageInfoController pageInfo = new PageInfoController(tab.getWebContents(), - ConnectionSecurityLevel.NONE, - /*publisher=*/null, chromePageInfoControllerDelegate, /*isV2Enabled=*/false); + ChromePermissionParamsListBuilderDelegate chromePermissionParamsListBuilderDelegate = + new ChromePermissionParamsListBuilderDelegate(); + PageInfoController pageInfo = + new PageInfoController(tab.getWebContents(), ConnectionSecurityLevel.NONE, + /*publisher=*/null, chromePageInfoControllerDelegate, + /*isV2Enabled=*/false, chromePermissionParamsListBuilderDelegate); PageInfoView pageInfoView = pageInfo.getPageInfoViewForTesting(); // Test that the title contains the Unicode hostname rather than strict equality, as // the test server will be bound to a random port.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/partnercustomizations/PartnerHomepageIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/partnercustomizations/PartnerHomepageIntegrationTest.java index 73794e2..dd2a106 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/partnercustomizations/PartnerHomepageIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/partnercustomizations/PartnerHomepageIntegrationTest.java
@@ -30,9 +30,9 @@ import org.chromium.chrome.browser.homepage.settings.HomepageSettings; import org.chromium.chrome.browser.settings.SettingsActivity; import org.chromium.chrome.browser.settings.SettingsActivityTestRule; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.TabList; import org.chromium.chrome.browser.tabmodel.TabModel; +import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.partnercustomizations.TestPartnerBrowserCustomizationsProvider; import org.chromium.chrome.test.util.ChromeTabUtils; @@ -203,13 +203,12 @@ public void testCloseAllTabs() { final CallbackHelper tabClosed = new CallbackHelper(); final TabModel tabModel = mActivityTestRule.getActivity().getCurrentTabModel(); - mActivityTestRule.getActivity().getCurrentTabModel().addObserver( - new EmptyTabModelObserver() { - @Override - public void didCloseTab(int tabId, boolean incognito) { - if (tabModel.getCount() == 0) tabClosed.notifyCalled(); - } - }); + mActivityTestRule.getActivity().getCurrentTabModel().addObserver(new TabModelObserver() { + @Override + public void didCloseTab(int tabId, boolean incognito) { + if (tabModel.getCount() == 0) tabClosed.notifyCalled(); + } + }); InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { @Override public void run() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/share/ShareDelegateImplIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/share/ShareDelegateImplIntegrationTest.java index 265017b..ef3373a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/share/ShareDelegateImplIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/share/ShareDelegateImplIntegrationTest.java
@@ -103,7 +103,7 @@ HistogramDelta urlResultDelta = new HistogramDelta( ShareDelegateImpl.CANONICAL_URL_RESULT_HISTOGRAM, expectedUrlResult); ShareParams params = triggerShare(); - Assert.assertEquals(expectedShareUrl, params.getUrl()); + Assert.assertTrue(params.getText().contains(expectedShareUrl)); Assert.assertEquals(1, urlResultDelta.getDelta()); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/subresource_filter/SubresourceFilterTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/subresource_filter/SubresourceFilterTest.java index 0d3ccfd..8ebe1f2b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/subresource_filter/SubresourceFilterTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/subresource_filter/SubresourceFilterTest.java
@@ -25,8 +25,8 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModel; +import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.browser.ui.messages.infobar.InfoBar; import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; @@ -150,7 +150,7 @@ CallbackHelper tabCreatedCallback = new CallbackHelper(); TabModel tabModel = mActivityTestRule.getActivity().getTabModelSelector().getCurrentModel(); TestThreadUtils.runOnUiThreadBlocking( - () -> tabModel.addObserver(new EmptyTabModelObserver() { + () -> tabModel.addObserver(new TabModelObserver() { @Override public void didAddTab( Tab tab, @TabLaunchType int type, @TabCreationState int creationState) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModelTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModelTest.java index 9244cb2..1b5b2ad0 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModelTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModelTest.java
@@ -45,7 +45,7 @@ mTabModel = mActivityTestRule.getActivity().getTabModelSelector().getModel(true); } - private class CloseAllDuringAddTabTabModelObserver extends EmptyTabModelObserver { + private class CloseAllDuringAddTabTabModelObserver implements TabModelObserver { @Override public void willAddTab(Tab tab, @TabLaunchType int type) { mTabModel.closeAllTabs();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreTest.java index dc818c0..2ec8af0 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreTest.java
@@ -661,7 +661,7 @@ // Close all the tabs, using an Observer to determine what is actually being closed. TabModel regularModel = selector.getModel(false); final List<Integer> closedTabIds = new ArrayList<>(); - TabModelObserver closeObserver = new EmptyTabModelObserver() { + TabModelObserver closeObserver = new TabModelObserver() { @Override public void multipleTabsPendingClosure(List<Tab> tabs, boolean isAllTabs) { for (Tab tab : tabs) closedTabIds.add(tab.getId());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java index 4e08c341..7a27ae4 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java
@@ -118,7 +118,7 @@ Assert.assertNotNull(TabModelUtils.getTabById(model, tab.getId())); final CallbackHelper didReceivePendingClosureHelper = new CallbackHelper(); - model.addObserver(new EmptyTabModelObserver() { + model.addObserver(new TabModelObserver() { @Override public void tabPendingClosure(Tab tab) { didReceivePendingClosureHelper.notifyCalled(); @@ -159,7 +159,7 @@ Assert.assertNull(TabModelUtils.getTabById(model, tab.getId())); final CallbackHelper didReceiveClosureCancelledHelper = new CallbackHelper(); - model.addObserver(new EmptyTabModelObserver() { + model.addObserver(new TabModelObserver() { @Override public void tabClosureUndone(Tab tab) { didReceiveClosureCancelledHelper.notifyCalled(); @@ -193,7 +193,7 @@ Assert.assertNull(TabModelUtils.getTabById(model, tab.getId())); // Make sure that this TabModel throws the right events. - model.addObserver(new EmptyTabModelObserver() { + model.addObserver(new TabModelObserver() { @Override public void tabClosureUndone(Tab currentTab) { tabClosureUndoneHelper.notifyCalled(); @@ -228,7 +228,7 @@ Assert.assertNull(TabModelUtils.getTabById(model, tab.getId())); final CallbackHelper didReceiveClosureCommittedHelper = new CallbackHelper(); - model.addObserver(new EmptyTabModelObserver() { + model.addObserver(new TabModelObserver() { @Override public void tabClosureCommitted(Tab tab) { didReceiveClosureCommittedHelper.notifyCalled(); @@ -261,7 +261,7 @@ Assert.assertTrue(model.isClosurePending(tab.getId())); // Make sure that this TabModel throws the right events. - model.addObserver(new EmptyTabModelObserver() { + model.addObserver(new TabModelObserver() { @Override public void tabClosureCommitted(Tab currentTab) { tabClosureCommittedHelper.notifyCalled(); @@ -299,7 +299,7 @@ // Helper class that notifies after the tab is closed, and a tab restore service entry has been // created in tab restore service. - private static class TabClosedObserver extends EmptyTabModelObserver { + private static class TabClosedObserver implements TabModelObserver { private CallbackHelper mTabClosedCallback; public TabClosedObserver(CallbackHelper closedCallback) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tasks/ReturnToChromeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tasks/ReturnToChromeTest.java index 075c2dc2..113cf6b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tasks/ReturnToChromeTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tasks/ReturnToChromeTest.java
@@ -131,7 +131,7 @@ @EnableFeatures({ChromeFeatureList.START_SURFACE_ANDROID + "<Study"}) // clang-format off @CommandLineFlags.Add({BASE_PARAMS + "/" + TAB_SWITCHER_ON_RETURN_MS_PARAM + "/100000" - + "/start_surface_variation/single"}) + + "/start_surface_variation/single/open_ntp_instead_of_start/true"}) public void testTabSwitcherModeNotTriggeredWithinThreshold() throws Exception { // clang-format on InstantStartTest.createTabStateFile(new int[] {0, 1}); @@ -140,8 +140,8 @@ Assert.assertEquals("single", StartSurfaceConfiguration.START_SURFACE_VARIATION.getValue()); TestThreadUtils.runOnUiThreadBlocking( () - -> Assert.assertTrue(ReturnToChromeExperimentsUtil - .shouldShowStartSurfaceAsTheHomePage())); + -> Assert.assertFalse(ReturnToChromeExperimentsUtil + .shouldShowStartSurfaceAsTheHomePage())); Assert.assertFalse(mActivityTestRule.getActivity().getLayoutManager().overviewVisible()); @@ -154,6 +154,45 @@ } /** + * Test that with {@link StartSurfaceConfiguration#START_SURFACE_OPEN_NTP_INSTEAD_OF_START} + * variation, overview mode is not triggered in Single-pane variation with NTP intent, even + * though the delay is longer than the interval between stop and start. Plus, a NTP should be + * created. + */ + @Test + @SmallTest + @Feature({"ReturnToChrome"}) + @EnableFeatures({ChromeFeatureList.START_SURFACE_ANDROID + "<Study"}) + // clang-format off + @CommandLineFlags.Add({BASE_PARAMS + "/" + TAB_SWITCHER_ON_RETURN_MS_PARAM + "/100000" + + "/start_surface_variation/single/open_ntp_instead_of_start/true"}) + public void testTabSwitcherModeNotTriggeredWithinThreshold_NTP() throws Exception { + // clang-format on + InstantStartTest.createTabStateFile(new int[] {0, 1}); + startMainActivityWithURLWithoutCurrentTab(UrlConstants.NTP_URL); + + Assert.assertEquals("single", StartSurfaceConfiguration.START_SURFACE_VARIATION.getValue()); + TestThreadUtils.runOnUiThreadBlocking( + () + -> Assert.assertFalse(ReturnToChromeExperimentsUtil + .shouldShowStartSurfaceAsTheHomePage())); + + if (!mActivityTestRule.getActivity().isTablet()) { + Assert.assertFalse( + mActivityTestRule.getActivity().getLayoutManager().overviewVisible()); + } + + waitTabModelRestoration(); + + // 3 tabs since we created NTP in this case. + assertEquals(3, mActivityTestRule.getActivity().getTabModelSelector().getTotalTabCount()); + if (!mActivityTestRule.getActivity().isTablet()) { + Assert.assertFalse( + mActivityTestRule.getActivity().getLayoutManager().overviewVisible()); + } + } + + /** * Test that overview mode is triggered in Single-pane variation with no tabs, even though * the delay is longer than the interval between stop and start. */ @@ -163,7 +202,7 @@ @EnableFeatures({ChromeFeatureList.START_SURFACE_ANDROID + "<Study"}) // clang-format off @CommandLineFlags.Add({BASE_PARAMS + "/" + TAB_SWITCHER_ON_RETURN_MS_PARAM + "/100000" - + "/start_surface_variation/single"}) + + "/start_surface_variation/single/open_ntp_instead_of_start/true"}) public void testTabSwitcherModeTriggeredWithinThreshold_NoTab() { // clang-format on startMainActivityWithURLWithoutCurrentTab(null); @@ -172,7 +211,7 @@ TestThreadUtils.runOnUiThreadBlocking( () -> Assert.assertTrue(ReturnToChromeExperimentsUtil - .shouldShowStartSurfaceAsTheHomePage())); + .shouldShowStartSurfaceAsTheHomePageNoTabs())); if (!mActivityTestRule.getActivity().isTablet()) { Assert.assertTrue(mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappActivityTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappActivityTestRule.java index f614911..2fc3706 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappActivityTestRule.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappActivityTestRule.java
@@ -229,8 +229,7 @@ // We also wait till the splash screen has finished initializing. if (getActivity().getActivityTab() == null) return false; - View splashScreen = - getActivity().getSplashControllerForTests().getSplashScreenForTests(); + View splashScreen = getSplashController(getActivity()).getSplashScreenForTests(); if (splashScreen == null) return false; return (!(splashScreen instanceof ViewGroup) @@ -239,7 +238,7 @@ }, STARTUP_TIMEOUT, CriteriaHelper.DEFAULT_POLLING_INTERVAL); InstrumentationRegistry.getInstrumentation().waitForIdleSync(); - View splashScreen = getActivity().getSplashControllerForTests().getSplashScreenForTests(); + View splashScreen = getSplashController(getActivity()).getSplashScreenForTests(); Assert.assertNotNull("No splash screen available.", splashScreen); // TODO(pkotwicz): Change return type in order to accommodate new-style WebAPKs. @@ -258,12 +257,16 @@ CriteriaHelper.pollInstrumentationThread(new Criteria() { @Override public boolean isSatisfied() { - return activity.getSplashControllerForTests().wasSplashScreenHiddenForTests(); + return getSplashController(activity).wasSplashScreenHiddenForTests(); } }, STARTUP_TIMEOUT, CriteriaHelper.DEFAULT_POLLING_INTERVAL); } public boolean isSplashScreenVisible() { - return getActivity().getSplashControllerForTests().getSplashScreenForTests() != null; + return getSplashController(getActivity()).getSplashScreenForTests() != null; + } + + public static SplashController getSplashController(WebappActivity activity) { + return activity.getComponent().resolveSplashController(); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetControllerTest.java index dd7d7d1..24cb3e73 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetControllerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetControllerTest.java
@@ -33,7 +33,7 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabSelectionType; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; +import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.util.ChromeTabUtils; @@ -622,7 +622,7 @@ private void openNewTabInBackground() throws TimeoutException { CallbackHelper tabSelectedHelper = new CallbackHelper(); mActivityTestRule.getActivity().getTabModelSelector().getCurrentModel().addObserver( - new EmptyTabModelObserver() { + new TabModelObserver() { @Override public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { tabSelectedHelper.notifyCalled();
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/page_info/PermissionParamsListBuilderUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/page_info/PermissionParamsListBuilderUnitTest.java index 5783c81..6679217 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/page_info/PermissionParamsListBuilderUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/page_info/PermissionParamsListBuilderUnitTest.java
@@ -45,6 +45,7 @@ import org.chromium.components.content_settings.ContentSettingsType; import org.chromium.components.embedder_support.browser_context.BrowserContextHandle; import org.chromium.components.page_info.PageInfoView; +import org.chromium.components.page_info.PermissionParamsListBuilder; import org.chromium.components.page_info.SystemSettingsActivityRequiredListener; import org.chromium.ui.base.AndroidPermissionDelegate; import org.chromium.ui.base.PermissionCallback;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/tab/TabViewManagerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/tab/TabViewManagerTest.java index ea548d3..a9152687 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/tab/TabViewManagerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/tab/TabViewManagerTest.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.tab; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -16,6 +17,9 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.robolectric.annotation.Config; +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; import org.chromium.base.test.BaseRobolectricTestRunner; @@ -23,7 +27,23 @@ * Unit tests for the {@link TabViewManager} class. */ @RunWith(BaseRobolectricTestRunner.class) +@Config(shadows = {TabViewManagerTest.TabBrowserControlsOffsetHelperShadow.class}) public class TabViewManagerTest { + /** + * A shadow implementation of {@link TabBrowserControlsOffsetHelper}. + */ + @Implements(TabBrowserControlsOffsetHelper.class) + public static class TabBrowserControlsOffsetHelperShadow { + @Implementation + public static TabBrowserControlsOffsetHelper get(Tab tab) { + TabBrowserControlsOffsetHelper mockTabBrowserControlsOffsetHelper = + mock(TabBrowserControlsOffsetHelper.class); + when(mockTabBrowserControlsOffsetHelper.contentOffset()).thenReturn(0); + when(mockTabBrowserControlsOffsetHelper.bottomControlsOffset()).thenReturn(0); + return mockTabBrowserControlsOffsetHelper; + } + } + @Mock private TabImpl mTab; @Mock
diff --git a/chrome/app/app_management_strings.grdp b/chrome/app/app_management_strings.grdp index 23d9c53..806c086 100644 --- a/chrome/app/app_management_strings.grdp +++ b/chrome/app/app_management_strings.grdp
@@ -25,6 +25,9 @@ <message name="IDS_APP_MANAGEMENT_PIN_TO_SHELF" desc="Label for the pin to shelf button in the app settings page."> Pin to shelf </message> + <message name="IDS_APP_MANAGEMENT_PRINTING" desc="Label for the printing permission toggle."> + Printers + </message> <message name="IDS_APP_MANAGEMENT_SEARCH_PROMPT" desc="Prompt in search bar of main app management page."> Search apps </message>
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index ab40675..7f1a45fb8 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -5013,6 +5013,9 @@ <message name="IDS_PLUGIN_VM_START_VM_ERROR_MESSAGE" desc="Message in the notificataion shown when launching the 'Plugin VM' app failed due to an unknown error."> Something went wrong. Please try again. </message> + <message name="IDS_PLUGIN_VM_UNINSTALL_PROMPT_BODY" desc="Message of the confirmation dialog displayed before removal begins."> + Removing Plugin VM will delete your VM. This includes its applications, settings, and data. Are you sure you wish to continue? + </message> <message name="IDS_PLUGIN_VM_REMOVING_NOTIFICATION_IN_PROGRESS_MESSAGE" desc="Message in the notification shown when removing the 'Plugin VM' app."> Uninstalling <ph name="APP_NAME">$1<ex>Plugin VM</ex></ph>... </message>
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp index 1a1018c..72e515af 100644 --- a/chrome/app/os_settings_strings.grdp +++ b/chrome/app/os_settings_strings.grdp
@@ -850,47 +850,6 @@ Primary account </message> - <!-- Plugin VM page (OS settings) --> - <message name="IDS_SETTINGS_PLUGIN_VM_PAGE_TITLE" desc="The title of Plugin VM section."> - Plugin VM - </message> - <message name="IDS_SETTINGS_PLUGIN_VM_PAGE_LABEL" desc="The text associated with the primary section setting for Plugin VM."> - Plugin VM - </message> - <message name="IDS_SETTINGS_PLUGIN_VM_PAGE_SUBTEXT" desc="Description for the section for managing Plugin VM."> - Set up permissions - </message> - <message name="IDS_SETTINGS_PLUGIN_VM_PRINTER_ACCESS" desc="The text in the settings page for allowing printer access from Plugin VM."> - Give access to printers - </message> - <message name="IDS_SETTINGS_PLUGIN_VM_SHARED_PATHS" desc="Label for managing shared folders for Plugin VM."> - Manage shared folders - </message> - <message name="IDS_SETTINGS_PLUGIN_VM_SHARED_PATHS_LIST_HEADING" desc="Label for list of shared folders."> - Shared folders - </message> - <message name="IDS_SETTINGS_PLUGIN_VM_SHARED_PATHS_INSTRUCTIONS_ADD" desc="Instructions for how to add shared folders in Plugin VM."> - To share, right-click on a folder in Files app, then select "Share with Plugin VM". - </message> - <message name="IDS_SETTINGS_PLUGIN_VM_SHARED_PATHS_INSTRUCTIONS_REMOVE" desc="Instructions for removing shared folders in Plugin VM."> - Removing folders will stop sharing but will not delete files. - </message> - <message name="IDS_SETTINGS_PLUGIN_VM_SHARED_PATHS_REMOVE_SHARING" desc="Tooltip to show when hovering on the remove icon for a Plugin VM shared folder."> - Stop sharing - </message> - <message name="IDS_SETTINGS_PLUGIN_VM_REMOVE_LABEL" desc="Label for the row to open a dialog confirming removal of Plugin VM."> - Uninstall Plugin VM - </message> - <message name="IDS_SETTINGS_PLUGIN_VM_REMOVE_BUTTON" desc="Label for the button to open a dialog confirming removal of Plugin VM."> - Uninstall - </message> - <message name="IDS_SETTINGS_PLUGIN_VM_CONFIRM_REMOVE_DIALOG_BODY" desc="Message of the confirmation dialog displayed before removal begins."> - Removing Plugin VM will delete your VM. This includes its applications, settings, and data. Are you sure you wish to continue? - </message> - <message name="IDS_SETTINGS_PLUGIN_VM_CAMERA_ACCESS_TITLE" desc="The text in the settings page for allowing camera access from Plugin VM."> - Give access to camera - </message> - <!-- Crostini --> <message name="IDS_SETTINGS_CROSTINI_TITLE" desc="The title of Crostini section."> Linux (Beta) @@ -2660,6 +2619,23 @@ This doesn’t affect apps or content on other devices. </message> + <!-- Apps > Manage your apps > Plugin VM > Shared folders --> + <message name="IDS_SETTINGS_APPS_PLUGIN_VM_SHARED_PATHS" desc="Label for managing shared folders for Plugin VM."> + Manage shared folders + </message> + <message name="IDS_SETTINGS_APPS_PLUGIN_VM_SHARED_PATHS_LIST_HEADING" desc="Label for list of shared folders."> + Shared folders + </message> + <message name="IDS_SETTINGS_APPS_PLUGIN_VM_SHARED_PATHS_INSTRUCTIONS_ADD" desc="Instructions for how to add shared folders in Plugin VM."> + To share, right-click on a folder in Files app, then select "Share with Plugin VM". + </message> + <message name="IDS_SETTINGS_APPS_PLUGIN_VM_SHARED_PATHS_INSTRUCTIONS_REMOVE" desc="Instructions for removing shared folders in Plugin VM."> + Removing folders will stop sharing but will not delete files. + </message> + <message name="IDS_SETTINGS_APPS_PLUGIN_VM_SHARED_PATHS_REMOVE_SHARING" desc="Tooltip to show when hovering on the remove icon for a Plugin VM shared folder."> + Stop sharing + </message> + <!-- Storage --> <message name="IDS_SETTINGS_STORAGE_TITLE" desc="In Device Settings, the title for storage management."> Storage management
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_PLUGIN_VM_SHARED_PATHS_INSTRUCTIONS_REMOVE.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_APPS_PLUGIN_VM_SHARED_PATHS_INSTRUCTIONS_REMOVE.png.sha1 similarity index 100% rename from chrome/app/os_settings_strings_grdp/IDS_SETTINGS_PLUGIN_VM_SHARED_PATHS_INSTRUCTIONS_REMOVE.png.sha1 rename to chrome/app/os_settings_strings_grdp/IDS_SETTINGS_APPS_PLUGIN_VM_SHARED_PATHS_INSTRUCTIONS_REMOVE.png.sha1
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_PLUGIN_VM_SHARED_PATHS_REMOVE_SHARING.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_APPS_PLUGIN_VM_SHARED_PATHS_REMOVE_SHARING.png.sha1 similarity index 100% rename from chrome/app/os_settings_strings_grdp/IDS_SETTINGS_PLUGIN_VM_SHARED_PATHS_REMOVE_SHARING.png.sha1 rename to chrome/app/os_settings_strings_grdp/IDS_SETTINGS_APPS_PLUGIN_VM_SHARED_PATHS_REMOVE_SHARING.png.sha1
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_PLUGIN_VM_CAMERA_ACCESS_TITLE.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_PLUGIN_VM_CAMERA_ACCESS_TITLE.png.sha1 deleted file mode 100644 index aef80c1c..0000000 --- a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_PLUGIN_VM_CAMERA_ACCESS_TITLE.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -f94e7f724029c18d71fb54cddfdc0b93d9e246e0 \ No newline at end of file
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index bb3ffd7..aac0982d 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -702,6 +702,50 @@ <message name="IDS_SETTINGS_CERTIFICATE_MANAGER_WRITE_ERROR_FORMAT" desc="The text in the error dialog for PKCS #12 file write errors."> There was an error while trying to write the file: <ph name="ERROR_TEXT">$1<ex>Permission denied.</ex></ph>. </message> + <if expr="chromeos"> + <message name="IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_LIST_HEADER" desc="Header that lists the certificate provisioning processes."> + Certificates are being provisioned for these certificate profiles + </message> + <message name="IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_REFRESH" desc="Text on the button to refresh the status of a certificate provisioning process."> + Refresh + </message> + <message name="IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_DETAILS" desc="Text on the button to show debug details about a certificate provisioning process and title of the dialog that shows the details."> + Details + </message> + <message name="IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_ADVANCED" desc="Text on the button to show advanced entries on the certificate provisioning details dialog."> + Advanced + </message> + <message name="IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_PREPARING_CSR" desc="Status description of a certificate provisioning process when the client is preparing the Certificate signing request (CSR) "> + Preparing certificate signing request + </message> + <message name="IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_PREPARING_CSR_WAITING" desc="Status description of a certificate provisioning process when the client is waiting for the server to aid in preparation of the Certificate signing request (CSR)"> + Preparing certificate signing request (waiting on server) + </message> + <message name="IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_WAITING_FOR_CA" desc="Status description of a certificate provisioning process when the client is waiting for a certificate to be issued"> + Waiting for the CA to issue a certificate + </message> + <message name="IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_SUCCESS" desc="Status description of a certificate provisioning process that has succeeded"> + Success + </message> + <message name="IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_FAILURE" desc="Status description of a certificate provisioning process that has failed"> + Failure + </message> + <message name="IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_CANCELED" desc="Status description of a certificate provisioning process that has been canceled"> + Canceled + </message> + <message name="IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_CERTIFICATE_PROFILE" desc="Label of the field that displays the client certificate profile of a certificate provisioning process"> + Certificate Profile + </message> + <message name="IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS" desc="Label of the field that displays certificate provisioning status"> + Status + </message> + <message name="IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_ID" desc="Label of the field that displays certificate provisioning status id, which is a number (e.g. 6)"> + Status Id + </message> + <message name="IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_LAST_UPDATE" desc="Label of the field that displays when a certificate provisioning process had the last update"> + Last Update + </message> + </if> </if> <!-- Clear Browsing Data -->
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_CERTIFICATE_PROFILE.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_CERTIFICATE_PROFILE.png.sha1 new file mode 100644 index 0000000..fce187c --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_CERTIFICATE_PROFILE.png.sha1
@@ -0,0 +1 @@ +098b1eca163742c1b941369b9a2cf20617b2453a \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_DETAILS.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_DETAILS.png.sha1 new file mode 100644 index 0000000..b877122 --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_DETAILS.png.sha1
@@ -0,0 +1 @@ +b97394266d2fd228ed3f878b68da59ff022f3991 \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_DETAILS_ADVANCED.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_DETAILS_ADVANCED.png.sha1 new file mode 100644 index 0000000..07a2b08 --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_DETAILS_ADVANCED.png.sha1
@@ -0,0 +1 @@ +8378276f0f3f96d5a6b8c03bb63ddb0da0012dd8 \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_LAST_UPDATE.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_LAST_UPDATE.png.sha1 new file mode 100644 index 0000000..9cf8103 --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_LAST_UPDATE.png.sha1
@@ -0,0 +1 @@ +a0c8a7c625f4f861ad52f5ca9f87ca2a4266eae1 \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_LIST_HEADER.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_LIST_HEADER.png.sha1 new file mode 100644 index 0000000..70479fe4 --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_LIST_HEADER.png.sha1
@@ -0,0 +1 @@ +73732987ca6b5b5ca08d376b7492593ef3201630 \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_REFRESH.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_REFRESH.png.sha1 new file mode 100644 index 0000000..154db90 --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_REFRESH.png.sha1
@@ -0,0 +1 @@ +bb49b8b86db37e940b5d324e390ca84bc10314a1 \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS.png.sha1 new file mode 100644 index 0000000..6cc88580 --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS.png.sha1
@@ -0,0 +1 @@ +22bad87fbb1502c200140db5fed095543f3a769a \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_CANCELED.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_CANCELED.png.sha1 new file mode 100644 index 0000000..cc98b2a --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_CANCELED.png.sha1
@@ -0,0 +1 @@ +1c7ea163b68f9e9293fbebf21e671f92bd2c793e \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_FAILURE.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_FAILURE.png.sha1 new file mode 100644 index 0000000..1610cc5 --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_FAILURE.png.sha1
@@ -0,0 +1 @@ +672625a43fc4dbbb79b289aeff40e2ed74c2738f \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_ID.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_ID.png.sha1 new file mode 100644 index 0000000..32f3d82 --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_ID.png.sha1
@@ -0,0 +1 @@ +1d910f1da7e1b3d07797a61231a3d47fd5cf9fea \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_PREPARING_CSR.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_PREPARING_CSR.png.sha1 new file mode 100644 index 0000000..82f22252 --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_PREPARING_CSR.png.sha1
@@ -0,0 +1 @@ +e7ab1944099deed3f48fd846bc1eacb0c4eb70a8 \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_PREPARING_CSR_WAITING.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_PREPARING_CSR_WAITING.png.sha1 new file mode 100644 index 0000000..0df045d --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_PREPARING_CSR_WAITING.png.sha1
@@ -0,0 +1 @@ +f522d275221b7ce959abb39ec3cccb8f8f22fc06 \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_SUCCESS.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_SUCCESS.png.sha1 new file mode 100644 index 0000000..b758b40a --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_SUCCESS.png.sha1
@@ -0,0 +1 @@ +48d950359ff9ffd967d4f1642bdec3c3bff947ac \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_WAITING_FOR_CA.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_WAITING_FOR_CA.png.sha1 new file mode 100644 index 0000000..9bb6b65 --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_WAITING_FOR_CA.png.sha1
@@ -0,0 +1 @@ +3edef2a6e7feb76c9c9cfc82614c31b24231b3e0 \ No newline at end of file
diff --git a/chrome/app/theme/chromium/mac/app.icns b/chrome/app/theme/chromium/mac/app.icns index 54ee532..86160df 100644 --- a/chrome/app/theme/chromium/mac/app.icns +++ b/chrome/app/theme/chromium/mac/app.icns Binary files differ
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index ed993703..fc037e7 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -1031,6 +1031,8 @@ "page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.h", "page_load_metrics/observers/ad_metrics/frame_data.cc", "page_load_metrics/observers/ad_metrics/frame_data.h", + "page_load_metrics/observers/ad_metrics/page_ad_density_tracker.cc", + "page_load_metrics/observers/ad_metrics/page_ad_density_tracker.h", "page_load_metrics/observers/amp_page_load_metrics_observer.cc", "page_load_metrics/observers/amp_page_load_metrics_observer.h", "page_load_metrics/observers/data_saver_site_breakdown_metrics_observer.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 3632a07..02361b3 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -1408,7 +1408,8 @@ {"start_surface_variation", "single"}, {"show_last_active_tab_only", "true"}, {"exclude_mv_tiles", "true"}, - {"show_stack_tab_switcher", "true"}}; + {"show_stack_tab_switcher", "true"}, + {"open_ntp_instead_of_start", "true"}}; const FeatureEntry::FeatureParam kStartSurfaceAndroid_SingleSurfaceWithoutMvTiles[] = { @@ -1874,15 +1875,15 @@ const FeatureEntry::Choice kQueryTilesCountryChoices[] = { {flags_ui::kGenericExperimentChoiceDefault, "", ""}, {flag_descriptions::kQueryTilesCountryCodeUS, - upboarding::switches::kQueryTilesCountryCode, "US"}, + query_tiles::switches::kQueryTilesCountryCode, "US"}, {flag_descriptions::kQueryTilesCountryCodeIndia, - upboarding::switches::kQueryTilesCountryCode, "IN"}, + query_tiles::switches::kQueryTilesCountryCode, "IN"}, {flag_descriptions::kQueryTilesCountryCodeBrazil, - upboarding::switches::kQueryTilesCountryCode, "BR"}, + query_tiles::switches::kQueryTilesCountryCode, "BR"}, {flag_descriptions::kQueryTilesCountryCodeNigeria, - upboarding::switches::kQueryTilesCountryCode, "NG"}, + query_tiles::switches::kQueryTilesCountryCode, "NG"}, {flag_descriptions::kQueryTilesCountryCodeIndonesia, - upboarding::switches::kQueryTilesCountryCode, "ID"}, + query_tiles::switches::kQueryTilesCountryCode, "ID"}, }; #endif // defined(OS_ANDROID) @@ -2220,10 +2221,6 @@ flag_descriptions::kBluetoothFixA2dpPacketSizeName, flag_descriptions::kBluetoothFixA2dpPacketSizeDescription, kOsCrOS, FEATURE_VALUE_TYPE(chromeos::features::kBluetoothFixA2dpPacketSize)}, - {"bluetooth-kernel-suspend-notifier", - flag_descriptions::kBluetoothKernelSuspendNotifierName, - flag_descriptions::kBluetoothKernelSuspendNotifierDescription, kOsCrOS, - FEATURE_VALUE_TYPE(chromeos::features::kBluetoothKernelSuspendNotifier)}, {"bluetooth-next-handsfree-profile", flag_descriptions::kBluetoothNextHandsfreeProfileName, flag_descriptions::kBluetoothNextHandsfreeProfileDescription, kOsCrOS, @@ -2528,6 +2525,9 @@ {"chrome-sharing-hub", flag_descriptions::kChromeSharingHubName, flag_descriptions::kChromeSharingHubDescription, kOsAndroid, FEATURE_VALUE_TYPE(chrome::android::kChromeSharingHub)}, + {"chrome-sharing-hub-v1-5", flag_descriptions::kChromeSharingHubV15Name, + flag_descriptions::kChromeSharingHubV15Description, kOsAndroid, + FEATURE_VALUE_TYPE(chrome::android::kChromeSharingHubV15)}, {"request-unbuffered-dispatch", flag_descriptions::kRequestUnbufferedDispatchName, flag_descriptions::kRequestUnbufferedDispatchDescription, kOsAndroid, @@ -2845,20 +2845,21 @@ FEATURE_VALUE_TYPE(offline_pages::kOnTheFlyMhtmlHashComputationFeature)}, {"query-tiles", flag_descriptions::kQueryTilesName, flag_descriptions::kQueryTilesDescription, kOsAndroid, - FEATURE_VALUE_TYPE(upboarding::features::kQueryTiles)}, + FEATURE_VALUE_TYPE(query_tiles::features::kQueryTiles)}, {"query-tiles-omnibox", flag_descriptions::kQueryTilesOmniboxName, flag_descriptions::kQueryTilesOmniboxDescription, kOsAndroid, - FEATURE_VALUE_TYPE(upboarding::features::kQueryTilesInOmnibox)}, + FEATURE_VALUE_TYPE(query_tiles::features::kQueryTilesInOmnibox)}, {"query-tiles-enable-query-editing", flag_descriptions::kQueryTilesEnableQueryEditingName, flag_descriptions::kQueryTilesEnableQueryEditingDescription, kOsAndroid, - FEATURE_VALUE_TYPE(upboarding::features::kQueryTilesEnableQueryEditing)}, + FEATURE_VALUE_TYPE(query_tiles::features::kQueryTilesEnableQueryEditing)}, {"query-tiles-country-code", flag_descriptions::kQueryTilesCountryCode, flag_descriptions::kQueryTilesCountryCodeDescription, kOsAndroid, MULTI_VALUE_TYPE(kQueryTilesCountryChoices)}, {"query-tiles-instant-fetch", flag_descriptions::kQueryTilesInstantFetch, flag_descriptions::kQueryTilesInstantFetchDescription, kOsAndroid, - SINGLE_VALUE_TYPE(upboarding::switches::kQueryTilesInstantBackgroundTask)}, + SINGLE_VALUE_TYPE( + query_tiles::switches::kQueryTilesInstantBackgroundTask)}, {"android-picture-in-picture-api", flag_descriptions::kAndroidPictureInPictureAPIName, flag_descriptions::kAndroidPictureInPictureAPIDescription, kOsAndroid, @@ -2985,6 +2986,10 @@ "ForceDarkVariations")}, #endif // !OS_CHROMEOS #if defined(OS_ANDROID) + {"enable-android-dark-search", flag_descriptions::kAndroidDarkSearchName, + flag_descriptions::kAndroidDarkSearchDescription, kOsAndroid, + FEATURE_VALUE_TYPE(features::kAndroidDarkSearch)}, + {"enable-android-night-mode-tab-reparenting", flag_descriptions::kAndroidNightModeTabReparentingName, flag_descriptions::kAndroidNightModeTabReparentingDescription, kOsAndroid, @@ -5573,6 +5578,22 @@ FEATURE_VALUE_TYPE(media::kMediaFeeds)}, #endif // !defined(OS_ANDROID) + {"autofill-enable-card-nickname-management", + flag_descriptions::kAutofillEnableCardNicknameManagementName, + flag_descriptions::kAutofillEnableCardNicknameManagementDescription, + kOsAll, + FEATURE_VALUE_TYPE( + autofill::features::kAutofillEnableCardNicknameManagement)}, + + {"conversion-measurement-api", + flag_descriptions::kConversionMeasurementApiName, + flag_descriptions::kConversionMeasurementApiDescription, kOsAll, + FEATURE_VALUE_TYPE(features::kConversionMeasurement)}, + {"conversion-measurement-debug-mode", + flag_descriptions::kConversionMeasurementDebugModeName, + flag_descriptions::kConversionMeasurementDebugModeDescription, kOsAll, + SINGLE_VALUE_TYPE(switches::kConversionsDebugMode)}, + // NOTE: Adding a new flag requires adding a corresponding entry to enum // "LoginCustomFlags" in tools/metrics/histograms/enums.xml. See "Flag // Histograms" in tools/metrics/histograms/README.md (run the
diff --git a/chrome/browser/accessibility/caption_controller.h b/chrome/browser/accessibility/caption_controller.h index 400c5f6..78e3ee7 100644 --- a/chrome/browser/accessibility/caption_controller.h +++ b/chrome/browser/accessibility/caption_controller.h
@@ -41,6 +41,20 @@ // class CaptionController : public BrowserListObserver, public KeyedService { public: + // These values are persisted to logs. Entries should not be renumbered and + // numeric values should never be reused. These should be the same as + // LiveCaptionsSessionEvent in enums.xml. + enum class SessionEvent { + // We began receiving captions for an audio stream. + kStreamStarted = 0, + // The audio stream ended, meaning no more captions will be received on that + // stream. + kStreamEnded = 1, + // The close button was clicked, so we stopped listening to an audio stream. + kCloseButtonClicked = 2, + kMaxValue = kCloseButtonClicked, + }; + explicit CaptionController(Profile* profile); ~CaptionController() override; CaptionController(const CaptionController&) = delete;
diff --git a/chrome/browser/android/background_task_scheduler/chrome_background_task_factory.cc b/chrome/browser/android/background_task_scheduler/chrome_background_task_factory.cc index 7757e55..86047f3 100644 --- a/chrome/browser/android/background_task_scheduler/chrome_background_task_factory.cc +++ b/chrome/browser/android/background_task_scheduler/chrome_background_task_factory.cc
@@ -23,7 +23,7 @@ // Add your tasks here with mappings to the given task_id. switch (task_id) { case static_cast<int>(background_task::TaskIds::QUERY_TILE_JOB_ID): - return std::make_unique<upboarding::TileBackgroundTask>(); + return std::make_unique<query_tiles::TileBackgroundTask>(); case static_cast<int>(background_task::TaskIds::FEEDV2_REFRESH_JOB_ID): return std::make_unique<feed::BackgroundRefreshTask>(); default:
diff --git a/chrome/browser/android/omnibox/autocomplete_controller_android.cc b/chrome/browser/android/omnibox/autocomplete_controller_android.cc index 1530fab..9235c3bf 100644 --- a/chrome/browser/android/omnibox/autocomplete_controller_android.cc +++ b/chrome/browser/android/omnibox/autocomplete_controller_android.cc
@@ -567,7 +567,8 @@ } ScopedJavaLocalRef<jobject> j_query_tiles = - upboarding::TileConversionBridge::CreateJavaTiles(env, match.query_tiles); + query_tiles::TileConversionBridge::CreateJavaTiles(env, + match.query_tiles); BookmarkModel* bookmark_model = BookmarkModelFactory::GetForBrowserContext(profile_);
diff --git a/chrome/browser/apps/app_service/extension_apps.cc b/chrome/browser/apps/app_service/extension_apps.cc index c2ae01c1..d95281c 100644 --- a/chrome/browser/apps/app_service/extension_apps.cc +++ b/chrome/browser/apps/app_service/extension_apps.cc
@@ -55,7 +55,7 @@ apps::mojom::Readiness readiness) { apps::mojom::AppPtr app = ConvertImpl(extension, readiness); - app->icon_key = icon_key_factory_.MakeIconKey(GetIconEffects(extension)); + app->icon_key = icon_key_factory().MakeIconKey(GetIconEffects(extension)); app->has_badge = apps::mojom::OptionalBool::kFalse; app->paused = apps::mojom::OptionalBool::kFalse;
diff --git a/chrome/browser/apps/app_service/extension_apps.h b/chrome/browser/apps/app_service/extension_apps.h index 4bb406958..e136d52 100644 --- a/chrome/browser/apps/app_service/extension_apps.h +++ b/chrome/browser/apps/app_service/extension_apps.h
@@ -50,8 +50,6 @@ bool ShouldShownInLauncher(const extensions::Extension* extension) override; apps::mojom::AppPtr Convert(const extensions::Extension* extension, apps::mojom::Readiness readiness) override; - - apps_util::IncrementingIconKeyFactory icon_key_factory_; }; } // namespace apps
diff --git a/chrome/browser/apps/app_service/extension_apps_base.cc b/chrome/browser/apps/app_service/extension_apps_base.cc index b30c105b..6b8aef8 100644 --- a/chrome/browser/apps/app_service/extension_apps_base.cc +++ b/chrome/browser/apps/app_service/extension_apps_base.cc
@@ -408,11 +408,12 @@ HostContentSettingsMapFactory::GetForProfile(profile_)); app_service_ = app_service.get(); - auto* web_app_provider = web_app::WebAppProvider::Get(profile_); - if (app_type_ == apps::mojom::AppType::kWeb && web_app_provider) { - web_app_provider->system_web_app_manager().on_apps_synchronized().Post( + auto* provider = web_app::WebAppProvider::Get(profile_); + if (app_type_ == apps::mojom::AppType::kWeb && provider) { + provider->system_web_app_manager().on_apps_synchronized().Post( FROM_HERE, base::BindOnce(&ExtensionAppsBase::OnSystemWebAppsInstalled, weak_factory_.GetWeakPtr())); + app_registrar_observer_.Add(&provider->registrar()); } if (app_type_ == apps::mojom::AppType::kWeb && @@ -676,6 +677,23 @@ prefs_observer_.Remove(prefs); } +void ExtensionAppsBase::OnAppRegistrarDestroyed() { + app_registrar_observer_.RemoveAll(); +} + +void ExtensionAppsBase::OnWebAppLocallyInstalledStateChanged( + const web_app::AppId& app_id, + bool is_locally_installed) { + const extensions::Extension* extension = MaybeGetExtension(app_id); + if (!extension) + return; + auto app = apps::mojom::App::New(); + app->app_type = apps::mojom::AppType::kWeb; + app->app_id = app_id; + app->icon_key = icon_key_factory_.MakeIconKey(GetIconEffects(extension)); + Publish(std::move(app), subscribers_); +} + void ExtensionAppsBase::OnExtensionLoaded( content::BrowserContext* browser_context, const extensions::Extension* extension) {
diff --git a/chrome/browser/apps/app_service/extension_apps_base.h b/chrome/browser/apps/app_service/extension_apps_base.h index 1851c382..a7345cf 100644 --- a/chrome/browser/apps/app_service/extension_apps_base.h +++ b/chrome/browser/apps/app_service/extension_apps_base.h
@@ -13,7 +13,11 @@ #include "base/scoped_observer.h" #include "chrome/browser/apps/app_service/app_icon_factory.h" #include "chrome/browser/apps/app_service/app_launch_params.h" +#include "chrome/browser/apps/app_service/icon_key_util.h" #include "chrome/browser/ui/web_applications/web_app_launch_manager.h" +#include "chrome/browser/web_applications/components/app_registrar.h" +#include "chrome/browser/web_applications/components/app_registrar_observer.h" +#include "chrome/browser/web_applications/components/web_app_id.h" #include "chrome/services/app_service/public/cpp/publisher_base.h" #include "chrome/services/app_service/public/mojom/app_service.mojom.h" #include "chrome/services/app_service/public/mojom/types.mojom.h" @@ -50,7 +54,8 @@ class ExtensionAppsBase : public apps::PublisherBase, public extensions::ExtensionPrefsObserver, public extensions::ExtensionRegistryObserver, - public content_settings::Observer { + public content_settings::Observer, + public web_app::AppRegistrarObserver { public: ExtensionAppsBase(const mojo::Remote<apps::mojom::AppService>& app_service, Profile* profile, @@ -104,6 +109,10 @@ return weak_factory_.GetWeakPtr(); } + apps_util::IncrementingIconKeyFactory& icon_key_factory() { + return icon_key_factory_; + } + private: void Initialize(const mojo::Remote<apps::mojom::AppService>& app_service); @@ -151,6 +160,11 @@ void OnExtensionPrefsWillBeDestroyed( extensions::ExtensionPrefs* prefs) override; + // web_app::AppRegistrarObserver: + void OnAppRegistrarDestroyed() override; + void OnWebAppLocallyInstalledStateChanged(const web_app::AppId& app_id, + bool is_locally_installed) override; + // extensions::ExtensionRegistryObserver overrides. void OnExtensionLoaded(content::BrowserContext* browser_context, const extensions::Extension* extension) override; @@ -194,6 +208,8 @@ const apps::mojom::AppType app_type_; + apps_util::IncrementingIconKeyFactory icon_key_factory_; + ScopedObserver<extensions::ExtensionPrefs, extensions::ExtensionPrefsObserver> prefs_observer_{this}; ScopedObserver<extensions::ExtensionRegistry, @@ -201,6 +217,8 @@ registry_observer_{this}; ScopedObserver<HostContentSettingsMap, content_settings::Observer> content_settings_observer_{this}; + ScopedObserver<web_app::AppRegistrar, web_app::AppRegistrarObserver> + app_registrar_observer_{this}; using EnableFlowPtr = std::unique_ptr<ExtensionAppsEnableFlow>; std::map<std::string, EnableFlowPtr> enable_flow_map_;
diff --git a/chrome/browser/apps/app_service/extension_apps_chromeos.cc b/chrome/browser/apps/app_service/extension_apps_chromeos.cc index 76e0dc9..0512bcd 100644 --- a/chrome/browser/apps/app_service/extension_apps_chromeos.cc +++ b/chrome/browser/apps/app_service/extension_apps_chromeos.cc
@@ -159,10 +159,6 @@ void ExtensionAppsChromeOs::Initialize() { app_window_registry_.Add(extensions::AppWindowRegistry::Get(profile())); - auto* provider = web_app::WebAppProvider::Get(profile()); - if (provider) { - registrar_observer_.Add(&provider->registrar()); - } notification_display_service_.Add( NotificationDisplayServiceFactory::GetForProfile(profile())); @@ -709,7 +705,7 @@ : readiness); bool paused = paused_apps_.IsPaused(extension->id()); app->icon_key = - icon_key_factory_.MakeIconKey(GetIconEffects(extension, paused)); + icon_key_factory().MakeIconKey(GetIconEffects(extension, paused)); app->has_badge = app_notifications_.HasNotification(extension->id()) ? apps::mojom::OptionalBool::kTrue @@ -762,7 +758,7 @@ apps::mojom::AppPtr app = apps::mojom::App::New(); app->app_type = app_type(); app->app_id = app_id; - app->icon_key = icon_key_factory_.MakeIconKey( + app->icon_key = icon_key_factory().MakeIconKey( GetIconEffects(extension, paused_apps_.IsPaused(app_id))); Publish(std::move(app), subscribers()); } @@ -872,8 +868,4 @@ subscribers()); } -void ExtensionAppsChromeOs::OnAppRegistrarDestroyed() { - registrar_observer_.RemoveAll(); -} - } // namespace apps
diff --git a/chrome/browser/apps/app_service/extension_apps_chromeos.h b/chrome/browser/apps/app_service/extension_apps_chromeos.h index 9227bee..a453a9a 100644 --- a/chrome/browser/apps/app_service/extension_apps_chromeos.h +++ b/chrome/browser/apps/app_service/extension_apps_chromeos.h
@@ -18,7 +18,6 @@ #include "chrome/browser/notifications/notification_common.h" #include "chrome/browser/notifications/notification_display_service.h" #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" -#include "chrome/browser/web_applications/components/app_registrar_observer.h" #include "chrome/services/app_service/public/cpp/instance.h" #include "chrome/services/app_service/public/cpp/instance_registry.h" #include "chrome/services/app_service/public/mojom/app_service.mojom.h" @@ -50,8 +49,7 @@ class ExtensionAppsChromeOs : public ExtensionAppsBase, public extensions::AppWindowRegistry::Observer, public ArcAppListPrefs::Observer, - public NotificationDisplayService::Observer, - public web_app::AppRegistrarObserver { + public NotificationDisplayService::Observer { public: ExtensionAppsChromeOs( const mojo::Remote<apps::mojom::AppService>& app_service, @@ -157,16 +155,11 @@ // web_app::AppRegistrarObserver overrides. void OnWebAppDisabledStateChanged(const std::string& app_id, bool is_disabled) override; - void OnAppRegistrarDestroyed() override; - - apps_util::IncrementingIconKeyFactory icon_key_factory_; apps::InstanceRegistry* instance_registry_; ScopedObserver<extensions::AppWindowRegistry, extensions::AppWindowRegistry::Observer> app_window_registry_{this}; - ScopedObserver<web_app::AppRegistrar, web_app::AppRegistrarObserver> - registrar_observer_{this}; PausedApps paused_apps_;
diff --git a/chrome/browser/apps/app_service/plugin_vm_apps.cc b/chrome/browser/apps/app_service/plugin_vm_apps.cc index 51b776e..c90f6cc 100644 --- a/chrome/browser/apps/app_service/plugin_vm_apps.cc +++ b/chrome/browser/apps/app_service/plugin_vm_apps.cc
@@ -15,15 +15,38 @@ #include "chrome/browser/apps/app_service/menu_util.h" #include "chrome/browser/chromeos/plugin_vm/plugin_vm_manager.h" #include "chrome/browser/chromeos/plugin_vm/plugin_vm_manager_factory.h" +#include "chrome/browser/chromeos/plugin_vm/plugin_vm_pref_names.h" #include "chrome/browser/chromeos/plugin_vm/plugin_vm_util.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/webui/app_management/app_management.mojom.h" #include "chrome/grit/chrome_unscaled_resources.h" #include "chrome/grit/generated_resources.h" #include "chrome/services/app_service/public/mojom/types.mojom.h" +#include "components/prefs/pref_service.h" #include "ui/base/l10n/l10n_util.h" namespace { +struct PermissionInfo { + app_management::mojom::PluginVmPermissionType permission; + const char* pref_name; +}; + +constexpr PermissionInfo permission_infos[] = { + {app_management::mojom::PluginVmPermissionType::PRINTING, + plugin_vm::prefs::kPluginVmPrintersAllowed}, +}; + +const char* PermissionToPrefName( + app_management::mojom::PluginVmPermissionType permission) { + for (const PermissionInfo& info : permission_infos) { + if (info.permission == permission) { + return info.pref_name; + } + } + return nullptr; +} + void SetAppAllowed(apps::mojom::App* app, bool allowed) { app->readiness = allowed ? apps::mojom::Readiness::kReady : apps::mojom::Readiness::kDisabledByPolicy; @@ -38,19 +61,36 @@ app->show_in_search = opt_allowed; } -apps::mojom::AppPtr GetPluginVmApp(bool allowed) { +void SetShowInAppManagement(apps::mojom::App* app, bool installed) { + // Show when installed, even if disabled by policy, to give users the choice + // to uninstall and free up space. + app->show_in_management = installed ? apps::mojom::OptionalBool::kTrue + : apps::mojom::OptionalBool::kFalse; +} + +apps::mojom::AppPtr GetPluginVmApp(Profile* profile, bool allowed) { apps::mojom::AppPtr app = apps::PublisherBase::MakeApp( apps::mojom::AppType::kPluginVm, plugin_vm::kPluginVmAppId, allowed ? apps::mojom::Readiness::kReady : apps::mojom::Readiness::kDisabledByPolicy, l10n_util::GetStringUTF8(IDS_PLUGIN_VM_APP_NAME), - apps::mojom::InstallSource::kSystem); + apps::mojom::InstallSource::kUser); app->icon_key = apps::mojom::IconKey::New( apps::mojom::IconKey::kDoesNotChangeOverTime, IDR_LOGO_PLUGIN_VM_DEFAULT_192, apps::IconEffects::kNone); - app->show_in_management = apps::mojom::OptionalBool::kFalse; + SetShowInAppManagement(app.get(), plugin_vm::IsPluginVmConfigured(profile)); + + for (const PermissionInfo& info : permission_infos) { + auto permission = apps::mojom::Permission::New(); + permission->permission_id = static_cast<uint32_t>(info.permission); + permission->value_type = apps::mojom::PermissionValueType::kBool; + permission->value = + static_cast<uint32_t>(profile->GetPrefs()->GetBoolean(info.pref_name)); + permission->is_managed = false; + app->permissions.push_back(std::move(permission)); + } SetAppAllowed(app.get(), allowed); @@ -67,13 +107,18 @@ : profile_(profile) { PublisherBase::Initialize(app_service, apps::mojom::AppType::kPluginVm); - // Register for Plugin VM policy changes, so that we can update the - // availability of the Plugin VM app. This subscription is automatically - // cleaned-up when this object is destroyed. + // Register for Plugin VM changes to policy and installed state, so that we + // can update the availability and status of the Plugin VM app. Unretained is + // safe as these are cleaned up upon destruction. policy_subscription_ = std::make_unique<plugin_vm::PluginVmPolicySubscription>( profile_, base::BindRepeating(&PluginVmApps::OnPluginVmAllowedChanged, base::Unretained(this))); + pref_registrar_.Init(profile->GetPrefs()); + pref_registrar_.Add( + plugin_vm::prefs::kPluginVmImageExists, + base::BindRepeating(&PluginVmApps::OnPluginVmConfiguredChanged, + base::Unretained(this))); is_allowed_ = plugin_vm::IsPluginVmAllowedForProfile(profile_); } @@ -84,7 +129,7 @@ mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote, apps::mojom::ConnectOptionsPtr opts) { std::vector<apps::mojom::AppPtr> apps; - apps.push_back(GetPluginVmApp(is_allowed_)); + apps.push_back(GetPluginVmApp(profile_, is_allowed_)); mojo::Remote<apps::mojom::Subscriber> subscriber( std::move(subscriber_remote)); @@ -124,6 +169,25 @@ } } +void PluginVmApps::SetPermission(const std::string& app_id, + apps::mojom::PermissionPtr permission_ptr) { + auto permission = static_cast<app_management::mojom::PluginVmPermissionType>( + permission_ptr->permission_id); + const char* pref_name = PermissionToPrefName(permission); + if (!pref_name) { + return; + } + + profile_->GetPrefs()->SetBoolean(pref_name, permission_ptr->value); +} + +void PluginVmApps::Uninstall(const std::string& app_id, + bool clear_site_data, + bool report_abuse) { + plugin_vm::PluginVmManagerFactory::GetForProfile(profile_) + ->UninstallPluginVm(); +} + void PluginVmApps::GetMenuModel(const std::string& app_id, apps::mojom::MenuType menu_type, int64_t display_id, @@ -160,4 +224,13 @@ Publish(std::move(app), subscribers_); } +void PluginVmApps::OnPluginVmConfiguredChanged() { + // Only changed fields need to be republished. + apps::mojom::AppPtr app = apps::mojom::App::New(); + app->app_type = apps::mojom::AppType::kPluginVm; + app->app_id = plugin_vm::kPluginVmAppId; + SetShowInAppManagement(app.get(), plugin_vm::IsPluginVmConfigured(profile_)); + Publish(std::move(app), subscribers_); +} + } // namespace apps
diff --git a/chrome/browser/apps/app_service/plugin_vm_apps.h b/chrome/browser/apps/app_service/plugin_vm_apps.h index 52f4c8a..385d882 100644 --- a/chrome/browser/apps/app_service/plugin_vm_apps.h +++ b/chrome/browser/apps/app_service/plugin_vm_apps.h
@@ -11,6 +11,7 @@ #include "chrome/browser/chromeos/plugin_vm/plugin_vm_util.h" #include "chrome/services/app_service/public/cpp/publisher_base.h" #include "chrome/services/app_service/public/mojom/app_service.mojom.h" +#include "components/prefs/pref_change_registrar.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" @@ -46,12 +47,18 @@ int32_t event_flags, apps::mojom::LaunchSource launch_source, int64_t display_id) override; + void SetPermission(const std::string& app_id, + apps::mojom::PermissionPtr permission) override; + void Uninstall(const std::string& app_id, + bool clear_site_data, + bool report_abuse) override; void GetMenuModel(const std::string& app_id, apps::mojom::MenuType menu_type, int64_t display_id, GetMenuModelCallback callback) override; void OnPluginVmAllowedChanged(bool is_allowed); + void OnPluginVmConfiguredChanged(); mojo::RemoteSet<apps::mojom::Subscriber> subscribers_; @@ -61,6 +68,7 @@ bool is_allowed_; std::unique_ptr<plugin_vm::PluginVmPolicySubscription> policy_subscription_; + PrefChangeRegistrar pref_registrar_; }; } // namespace apps
diff --git a/chrome/browser/apps/app_service/uninstall_dialog.cc b/chrome/browser/apps/app_service/uninstall_dialog.cc index 0dc57b2..f6696f0 100644 --- a/chrome/browser/apps/app_service/uninstall_dialog.cc +++ b/chrome/browser/apps/app_service/uninstall_dialog.cc
@@ -39,6 +39,7 @@ switch (app_type) { case apps::mojom::AppType::kArc: + case apps::mojom::AppType::kPluginVm: break; case apps::mojom::AppType::kCrostini: // Crostini icons might be a big image, and not fit the size, so add the
diff --git a/chrome/browser/apps/app_service/web_apps.cc b/chrome/browser/apps/app_service/web_apps.cc index c5e56b2..375adf8 100644 --- a/chrome/browser/apps/app_service/web_apps.cc +++ b/chrome/browser/apps/app_service/web_apps.cc
@@ -42,7 +42,7 @@ apps::mojom::Readiness readiness) { apps::mojom::AppPtr app = ConvertImpl(web_app, readiness); - app->icon_key = icon_key_factory_.MakeIconKey(GetIconEffects(web_app)); + app->icon_key = icon_key_factory().MakeIconKey(GetIconEffects(web_app)); app->has_badge = apps::mojom::OptionalBool::kFalse; app->paused = apps::mojom::OptionalBool::kFalse;
diff --git a/chrome/browser/apps/app_service/web_apps.h b/chrome/browser/apps/app_service/web_apps.h index ad7f78b..9d905b3 100644 --- a/chrome/browser/apps/app_service/web_apps.h +++ b/chrome/browser/apps/app_service/web_apps.h
@@ -42,7 +42,6 @@ apps::mojom::Readiness readiness) override; bool Accepts(const std::string& app_id) override; - apps_util::IncrementingIconKeyFactory icon_key_factory_; }; } // namespace apps
diff --git a/chrome/browser/apps/app_service/web_apps_base.cc b/chrome/browser/apps/app_service/web_apps_base.cc index f1205e4b..2d8e7da 100644 --- a/chrome/browser/apps/app_service/web_apps_base.cc +++ b/chrome/browser/apps/app_service/web_apps_base.cc
@@ -369,6 +369,19 @@ registrar_observer_.RemoveAll(); } +void WebAppsBase::OnWebAppLocallyInstalledStateChanged( + const web_app::AppId& app_id, + bool is_locally_installed) { + const web_app::WebApp* web_app = GetWebApp(app_id); + if (!web_app) + return; + auto app = apps::mojom::App::New(); + app->app_type = apps::mojom::AppType::kWeb; + app->app_id = app_id; + app->icon_key = icon_key_factory().MakeIconKey(GetIconEffects(web_app)); + Publish(std::move(app), subscribers_); +} + void WebAppsBase::SetShowInFields(apps::mojom::AppPtr& app, const web_app::WebApp* web_app) { if (web_app->chromeos_data().has_value()) {
diff --git a/chrome/browser/apps/app_service/web_apps_base.h b/chrome/browser/apps/app_service/web_apps_base.h index 368d049..17e6879 100644 --- a/chrome/browser/apps/app_service/web_apps_base.h +++ b/chrome/browser/apps/app_service/web_apps_base.h
@@ -11,6 +11,7 @@ #include "base/memory/weak_ptr.h" #include "base/scoped_observer.h" #include "chrome/browser/apps/app_service/app_icon_factory.h" +#include "chrome/browser/apps/app_service/icon_key_util.h" #include "chrome/browser/web_applications/components/app_registrar.h" #include "chrome/browser/web_applications/components/app_registrar_observer.h" #include "chrome/browser/web_applications/components/web_app_id.h" @@ -80,6 +81,10 @@ return weak_ptr_factory_.GetWeakPtr(); } + apps_util::IncrementingIconKeyFactory& icon_key_factory() { + return icon_key_factory_; + } + private: void Initialize(const mojo::Remote<apps::mojom::AppService>& app_service); @@ -121,6 +126,8 @@ // web_app::AppRegistrarObserver: void OnWebAppInstalled(const web_app::AppId& app_id) override; void OnAppRegistrarDestroyed() override; + void OnWebAppLocallyInstalledStateChanged(const web_app::AppId& app_id, + bool is_locally_installed) override; // TODO(loyso): Implement app->last_launch_time field for the new system. void SetShowInFields(apps::mojom::AppPtr& app, @@ -142,6 +149,8 @@ Profile* const profile_; + apps_util::IncrementingIconKeyFactory icon_key_factory_; + ScopedObserver<web_app::AppRegistrar, web_app::AppRegistrarObserver> registrar_observer_{this};
diff --git a/chrome/browser/apps/app_service/web_apps_chromeos.cc b/chrome/browser/apps/app_service/web_apps_chromeos.cc index 36598fb..2511901 100644 --- a/chrome/browser/apps/app_service/web_apps_chromeos.cc +++ b/chrome/browser/apps/app_service/web_apps_chromeos.cc
@@ -249,7 +249,7 @@ apps::mojom::AppPtr app = WebAppsBase::ConvertImpl( web_app, is_disabled ? apps::mojom::Readiness::kDisabledByPolicy : apps::mojom::Readiness::kReady); - app->icon_key = icon_key_factory_.MakeIconKey( + app->icon_key = icon_key_factory().MakeIconKey( GetIconEffects(web_app, paused_apps_.IsPaused(app_id), is_disabled)); Publish(std::move(app), subscribers()); } @@ -360,7 +360,7 @@ is_disabled ? apps::mojom::Readiness::kDisabledByPolicy : readiness); bool paused = paused_apps_.IsPaused(web_app->app_id()); - app->icon_key = icon_key_factory_.MakeIconKey( + app->icon_key = icon_key_factory().MakeIconKey( GetIconEffects(web_app, paused, is_disabled)); app->paused = paused ? apps::mojom::OptionalBool::kTrue @@ -415,7 +415,7 @@ app->app_type = apps::mojom::AppType::kWeb; app->app_id = app_id; DCHECK(web_app->chromeos_data().has_value()); - app->icon_key = icon_key_factory_.MakeIconKey( + app->icon_key = icon_key_factory().MakeIconKey( GetIconEffects(web_app, paused_apps_.IsPaused(app_id), web_app->chromeos_data()->is_disabled)); Publish(std::move(app), subscribers());
diff --git a/chrome/browser/apps/app_service/web_apps_chromeos.h b/chrome/browser/apps/app_service/web_apps_chromeos.h index 802abdb..11587d6a 100644 --- a/chrome/browser/apps/app_service/web_apps_chromeos.h +++ b/chrome/browser/apps/app_service/web_apps_chromeos.h
@@ -113,8 +113,6 @@ bool Accepts(const std::string& app_id) override; - apps_util::IncrementingIconKeyFactory icon_key_factory_; - apps::InstanceRegistry* instance_registry_; PausedApps paused_apps_;
diff --git a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc index 428900a..0baab60 100644 --- a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc +++ b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc
@@ -159,10 +159,10 @@ create_if_necessary); } -upboarding::TileService* ChromeAutocompleteProviderClient::GetQueryTileService() - const { +query_tiles::TileService* +ChromeAutocompleteProviderClient::GetQueryTileService() const { ProfileKey* profile_key = profile_->GetProfileKey(); - return upboarding::TileServiceFactory::GetForKey(profile_key); + return query_tiles::TileServiceFactory::GetForKey(profile_key); } DocumentSuggestionsService*
diff --git a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.h b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.h index fa4632c4..fa07577 100644 --- a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.h +++ b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.h
@@ -52,7 +52,7 @@ std::vector<base::string16> GetBuiltinsToProvideAsUserTypes() override; component_updater::ComponentUpdateService* GetComponentUpdateService() override; - upboarding::TileService* GetQueryTileService() const override; + query_tiles::TileService* GetQueryTileService() const override; bool IsOffTheRecord() const override; bool SearchSuggestEnabled() const override;
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index 73aa083d..056df0e 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -255,7 +255,6 @@ <include name="IDR_URGENT_PASSWORD_EXPIRY_NOTIFICATION_HTML" file="resources\chromeos\password_change\urgent_password_expiry_notification.html" flattenhtml="true" allowexternalscript="true" type="chrome_html" compress="gzip" /> <include name="IDR_URGENT_PASSWORD_EXPIRY_NOTIFICATION_JS" file="resources\chromeos\password_change\urgent_password_expiry_notification.js" type="chrome_html" compress="gzip" /> - <include name="IDR_CROSH_BUILTIN_MANIFEST" file="resources\chromeos\crosh_builtin\manifest.json" type="BINDATA" /> <include name="IDR_CROSTINI_INSTALLER_INDEX_HTML" file="resources\chromeos\crostini_installer\index.html" compress="gzip" type="BINDATA" /> <include name="IDR_CROSTINI_INSTALLER_APP_JS" file="${root_gen_dir}\chrome\browser\resources\chromeos\crostini_installer\app.js" compress="gzip" type="BINDATA" use_base_dir="false" /> <include name="IDR_CROSTINI_INSTALLER_BROWSER_PROXY_JS" file="resources\chromeos\crostini_installer\browser_proxy.js" compress="gzip" type="BINDATA" />
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index c2b2147..cf61a5f7 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/chrome_content_browser_client.h" +#include <iterator> #include <map> #include <set> #include <utility> @@ -216,6 +217,7 @@ #include "components/page_load_metrics/browser/metrics_web_contents_observer.h" #include "components/page_load_metrics/browser/page_load_metrics_util.h" #include "components/payments/content/payment_request_display_manager.h" +#include "components/performance_manager/embedder/performance_manager_registry.h" #include "components/permissions/permission_context_base.h" #include "components/permissions/quota_permission_context_impl.h" #include "components/policy/content/policy_blacklist_navigation_throttle.h" @@ -1043,12 +1045,19 @@ // !defined(ADDRESS_SANITIZER) void MaybeAddThrottle( - std::vector<std::unique_ptr<content::NavigationThrottle>>* throttles, - std::unique_ptr<content::NavigationThrottle> maybe_throttle) { + std::unique_ptr<content::NavigationThrottle> maybe_throttle, + std::vector<std::unique_ptr<content::NavigationThrottle>>* throttles) { if (maybe_throttle) throttles->push_back(std::move(maybe_throttle)); } +void MaybeAddThrottles( + std::vector<std::unique_ptr<content::NavigationThrottle>> additional, + std::vector<std::unique_ptr<content::NavigationThrottle>>* combined) { + combined->insert(combined->end(), std::make_move_iterator(additional.begin()), + std::make_move_iterator(additional.end())); +} + // Returns whether |web_contents| is within a hosted app. bool IsInHostedApp(WebContents* web_contents) { #if BUILDFLAG(ENABLE_EXTENSIONS) @@ -3856,20 +3865,20 @@ } #if BUILDFLAG(ENABLE_PLUGINS) - MaybeAddThrottle(&throttles, - FlashDownloadInterception::MaybeCreateThrottleFor(handle)); + MaybeAddThrottle(FlashDownloadInterception::MaybeCreateThrottleFor(handle), + &throttles); #endif #if defined(OS_CHROMEOS) MaybeAddThrottle( - &throttles, - chromeos::WebTimeLimitNavigationThrottle::MaybeCreateThrottleFor(handle)); + chromeos::WebTimeLimitNavigationThrottle::MaybeCreateThrottleFor(handle), + &throttles); #endif // defined(OS_CHROMEOS) #if BUILDFLAG(ENABLE_SUPERVISED_USERS) MaybeAddThrottle( - &throttles, - SupervisedUserNavigationThrottle::MaybeCreateThrottleFor(handle)); + SupervisedUserNavigationThrottle::MaybeCreateThrottleFor(handle), + &throttles); #endif #if defined(OS_ANDROID) @@ -3887,18 +3896,17 @@ #if BUILDFLAG(DFMIFY_DEV_UI) // If the DevUI DFM is already installed, then this is a no-op, except for the // side effect of ensuring that the DevUI DFM is loaded. - MaybeAddThrottle(&throttles, - dev_ui::DevUiLoaderThrottle::MaybeCreateThrottleFor(handle)); + MaybeAddThrottle(dev_ui::DevUiLoaderThrottle::MaybeCreateThrottleFor(handle), + &throttles); #endif // BUILDFLAG(DFMIFY_DEV_UI) #elif BUILDFLAG(ENABLE_EXTENSIONS) if (handle->IsInMainFrame()) { // Redirect some navigations to apps that have registered matching URL // handlers ('url_handlers' in the manifest). - auto url_to_app_throttle = - PlatformAppNavigationRedirector::MaybeCreateThrottleFor(handle); - if (url_to_app_throttle) - throttles.push_back(std::move(url_to_app_throttle)); + MaybeAddThrottle( + PlatformAppNavigationRedirector::MaybeCreateThrottleFor(handle), + &throttles); } #endif @@ -3936,15 +3944,16 @@ throttles.push_back( std::make_unique<extensions::ExtensionNavigationThrottle>(handle)); - MaybeAddThrottle(&throttles, extensions::ExtensionsBrowserClient::Get() - ->GetUserScriptListener() - ->CreateNavigationThrottle(handle)); + MaybeAddThrottle(extensions::ExtensionsBrowserClient::Get() + ->GetUserScriptListener() + ->CreateNavigationThrottle(handle), + &throttles); #endif #if BUILDFLAG(ENABLE_SUPERVISED_USERS) MaybeAddThrottle( - &throttles, - SupervisedUserGoogleAuthNavigationThrottle::MaybeCreate(handle)); + SupervisedUserGoogleAuthNavigationThrottle::MaybeCreate(handle), + &throttles); #endif content::WebContents* web_contents = handle->GetWebContents(); @@ -3957,24 +3966,24 @@ #if !defined(OS_ANDROID) // BackgroundTabNavigationThrottle is used by TabManager, which is only // enabled on non-Android platforms. - MaybeAddThrottle(&throttles, - resource_coordinator::BackgroundTabNavigationThrottle:: - MaybeCreateThrottleFor(handle)); + MaybeAddThrottle(resource_coordinator::BackgroundTabNavigationThrottle:: + MaybeCreateThrottleFor(handle), + &throttles); #endif #if BUILDFLAG(FULL_SAFE_BROWSING) - MaybeAddThrottle(&throttles, - safe_browsing::MaybeCreateNavigationThrottle(handle)); + MaybeAddThrottle(safe_browsing::MaybeCreateNavigationThrottle(handle), + &throttles); #endif MaybeAddThrottle( - &throttles, - LookalikeUrlNavigationThrottle::MaybeCreateNavigationThrottle(handle)); + LookalikeUrlNavigationThrottle::MaybeCreateNavigationThrottle(handle), + &throttles); - MaybeAddThrottle(&throttles, - PDFIFrameNavigationThrottle::MaybeCreateThrottleFor(handle)); + MaybeAddThrottle(PDFIFrameNavigationThrottle::MaybeCreateThrottleFor(handle), + &throttles); - MaybeAddThrottle(&throttles, TabUnderNavigationThrottle::MaybeCreate(handle)); + MaybeAddThrottle(TabUnderNavigationThrottle::MaybeCreate(handle), &throttles); throttles.push_back(std::make_unique<PolicyBlacklistNavigationThrottle>( handle, handle->GetWebContents()->GetBrowserContext())); @@ -3991,19 +4000,19 @@ throttles.push_back(std::make_unique<LoginNavigationThrottle>(handle)); MaybeAddThrottle( - &throttles, - TypedNavigationTimingThrottle::MaybeCreateThrottleFor(handle)); + TypedNavigationTimingThrottle::MaybeCreateThrottleFor(handle), + &throttles); #if !defined(OS_ANDROID) - MaybeAddThrottle(&throttles, - DevToolsWindow::MaybeCreateNavigationThrottle(handle)); + MaybeAddThrottle(DevToolsWindow::MaybeCreateNavigationThrottle(handle), + &throttles); + + MaybeAddThrottle(NewTabPageNavigationThrottle::MaybeCreateThrottleFor(handle), + &throttles); MaybeAddThrottle( - &throttles, NewTabPageNavigationThrottle::MaybeCreateThrottleFor(handle)); - - MaybeAddThrottle( - &throttles, - GooglePasswordManagerNavigationThrottle::MaybeCreateThrottleFor(handle)); + GooglePasswordManagerNavigationThrottle::MaybeCreateThrottleFor(handle), + &throttles); #endif throttles.push_back( @@ -4017,18 +4026,25 @@ #if defined(OS_WIN) || defined(OS_MACOSX) || \ (defined(OS_LINUX) && !defined(OS_CHROMEOS)) - MaybeAddThrottle(&throttles, - browser_switcher::BrowserSwitcherNavigationThrottle:: - MaybeCreateThrottleFor(handle)); + MaybeAddThrottle(browser_switcher::BrowserSwitcherNavigationThrottle:: + MaybeCreateThrottleFor(handle), + &throttles); #endif #if defined(OS_CHROMEOS) MaybeAddThrottle( - &throttles, - chromeos::KioskSettingsNavigationThrottle::MaybeCreateThrottleFor( - handle)); + chromeos::KioskSettingsNavigationThrottle::MaybeCreateThrottleFor(handle), + &throttles); #endif + auto* performance_manager_registry = + performance_manager::PerformanceManagerRegistry::GetInstance(); + if (performance_manager_registry) { + MaybeAddThrottles( + performance_manager_registry->CreateThrottlesForNavigation(handle), + &throttles); + } + return throttles; }
diff --git a/chrome/browser/chrome_content_browser_client_receiver_bindings.cc b/chrome/browser/chrome_content_browser_client_receiver_bindings.cc index e3e7ebec..383f01c1 100644 --- a/chrome/browser/chrome_content_browser_client_receiver_bindings.cc +++ b/chrome/browser/chrome_content_browser_client_receiver_bindings.cc
@@ -211,11 +211,6 @@ chrome::internal::PopulateChromeWebUIFrameBinders(map); #if BUILDFLAG(ENABLE_EXTENSIONS) - content::WebContents* web_contents = - content::WebContents::FromRenderFrameHost(render_frame_host); - if (!web_contents) - return; - const GURL& site = render_frame_host->GetSiteInstance()->GetSiteURL(); if (!site.SchemeIs(extensions::kExtensionScheme)) return;
diff --git a/chrome/browser/chromeos/apps/apk_web_app_installer.cc b/chrome/browser/chromeos/apps/apk_web_app_installer.cc index 21666ca9..6586f93 100644 --- a/chrome/browser/chromeos/apps/apk_web_app_installer.cc +++ b/chrome/browser/chromeos/apps/apk_web_app_installer.cc
@@ -52,6 +52,7 @@ base::WeakPtr<Owner> weak_owner) : profile_(profile), is_web_only_twa_(false), + sha256_fingerprint_(base::nullopt), callback_(std::move(callback)), weak_owner_(weak_owner) {} @@ -94,6 +95,7 @@ web_app_info_->open_as_window = true; is_web_only_twa_ = web_app_info->is_web_only_twa; + sha256_fingerprint_ = web_app_info->certificate_sha256_fingerprint; // Decode the image in a sandboxed process off the main thread. // base::Unretained is safe because this object owns itself. @@ -107,7 +109,7 @@ void ApkWebAppInstaller::CompleteInstallation(const web_app::AppId& id, web_app::InstallResultCode code) { - std::move(callback_).Run(id, is_web_only_twa_, code); + std::move(callback_).Run(id, is_web_only_twa_, sha256_fingerprint_, code); delete this; }
diff --git a/chrome/browser/chromeos/apps/apk_web_app_installer.h b/chrome/browser/chromeos/apps/apk_web_app_installer.h index d75327f4..69053fa 100644 --- a/chrome/browser/chromeos/apps/apk_web_app_installer.h +++ b/chrome/browser/chromeos/apps/apk_web_app_installer.h
@@ -11,6 +11,7 @@ #include "base/callback.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "base/optional.h" #include "chrome/browser/web_applications/components/web_app_id.h" #include "chrome/common/web_application_info.h" #include "components/arc/mojom/app.mojom.h" @@ -28,10 +29,11 @@ // within it to install as a local web app. class ApkWebAppInstaller { public: - using InstallFinishCallback = - base::OnceCallback<void(const web_app::AppId&, - const bool is_web_only_twa, - web_app::InstallResultCode)>; + using InstallFinishCallback = base::OnceCallback<void( + const web_app::AppId&, + const bool is_web_only_twa, + const base::Optional<std::string> sha256_fingerprint, + web_app::InstallResultCode)>; // Do nothing class purely for the purpose of allowing us to specify // a WeakPtr<Owner> member as a proxy for a profile lifetime observer. @@ -83,6 +85,7 @@ // shorter than that of |profile_|. Profile* profile_; bool is_web_only_twa_; + base::Optional<std::string> sha256_fingerprint_; InstallFinishCallback callback_; base::WeakPtr<Owner> weak_owner_;
diff --git a/chrome/browser/chromeos/apps/apk_web_app_service.cc b/chrome/browser/chromeos/apps/apk_web_app_service.cc index 8e43fb8..357a0180 100644 --- a/chrome/browser/chromeos/apps/apk_web_app_service.cc +++ b/chrome/browser/chromeos/apps/apk_web_app_service.cc
@@ -35,12 +35,14 @@ // <web_app_id_1> : { // "package_name" : <apk_package_name_1>, // "should_remove": <bool>, -// "is_web_only_twa": <bool> +// "is_web_only_twa": <bool>, +// "sha256_fingerprint": <certificate_sha256_fingerprint_2> (optional) // }, // <web_app_id_2> : { // "package_name" : <apk_package_name_2>, // "should_remove": <bool>, -// "is_web_only_twa": <bool> +// "is_web_only_twa": <bool>, +// "sha256_fingerprint": <certificate_sha256_fingerprint_2> (optional) // }, // ... // }, @@ -50,6 +52,7 @@ const char kPackageNameKey[] = "package_name"; const char kShouldRemoveKey[] = "should_remove"; const char kIsWebOnlyTwaKey[] = "is_web_only_twa"; +const char kSha256FingerprintKey[] = "sha256_fingerprint"; constexpr char kLastAppId[] = "last_app_id"; constexpr char kPinIndex[] = "pin_index"; @@ -101,6 +104,25 @@ return v && v->GetBool(); } +base::Optional<std::string> ApkWebAppService::GetCertificateSha256Fingerprint( + const web_app::AppId& web_app_id) { + if (!IsWebAppInstalledFromArc(web_app_id)) + return base::nullopt; + + DictionaryPrefUpdate web_apps_to_apks(profile_->GetPrefs(), + kWebAppToApkDictPref); + + // Find the entry associated with the provided web app id. + const base::Value* v = web_apps_to_apks->FindPathOfType( + {web_app_id, kSha256FingerprintKey}, base::Value::Type::STRING); + + if (!v) { + return base::nullopt; + } + + return base::Optional<std::string>(v->GetString()); +} + void ApkWebAppService::SetArcAppListPrefsForTesting(ArcAppListPrefs* prefs) { DCHECK(prefs); if (arc_app_list_prefs_) @@ -219,6 +241,7 @@ } } + // TODO(crbug.com/1082547): check if fingerprint or is_twa has chagned. bool was_previously_web_app = !web_app_id.empty(); bool is_now_web_app = !package_info.web_app_info.is_null(); @@ -390,10 +413,12 @@ weak_ptr_factory_.GetWeakPtr()); } -void ApkWebAppService::OnDidFinishInstall(const std::string& package_name, - const web_app::AppId& web_app_id, - bool is_web_only_twa, - web_app::InstallResultCode code) { +void ApkWebAppService::OnDidFinishInstall( + const std::string& package_name, + const web_app::AppId& web_app_id, + bool is_web_only_twa, + const base::Optional<std::string> sha256_fingerprint, + web_app::InstallResultCode code) { // Do nothing: any error cancels installation. if (code != web_app::InstallResultCode::kSuccessNewInstall) return; @@ -409,9 +434,17 @@ // when the container starts up again. dict_update->SetPath({web_app_id, kShouldRemoveKey}, base::Value(false)); + // Set a pref to indicate if the |web_app_id| is a web-only TWA. dict_update->SetPath({web_app_id, kIsWebOnlyTwaKey}, base::Value(is_web_only_twa)); + if (sha256_fingerprint.has_value()) { + // Set a pref to hold the APK's certificate SHA256 fingerprint to use for + // digital asset link verification. + dict_update->SetPath({web_app_id, kSha256FingerprintKey}, + base::Value(sha256_fingerprint.value())); + } + // For testing. if (web_app_installed_callback_) std::move(web_app_installed_callback_).Run(package_name, web_app_id);
diff --git a/chrome/browser/chromeos/apps/apk_web_app_service.h b/chrome/browser/chromeos/apps/apk_web_app_service.h index 1007d52..485120b 100644 --- a/chrome/browser/chromeos/apps/apk_web_app_service.h +++ b/chrome/browser/chromeos/apps/apk_web_app_service.h
@@ -49,6 +49,9 @@ bool IsWebOnlyTwa(const web_app::AppId& web_app_id); + base::Optional<std::string> GetCertificateSha256Fingerprint( + const web_app::AppId& web_app_id); + using WebAppCallbackForTesting = base::OnceCallback<void(const std::string& package_name, const web_app::AppId& web_app_id)>; @@ -89,6 +92,7 @@ void OnDidFinishInstall(const std::string& package_name, const web_app::AppId& web_app_id, bool is_web_only_twa, + const base::Optional<std::string> sha256_fingerprint, web_app::InstallResultCode code); bool IsWebAppInstalledFromArc(const web_app::AppId& web_app_id);
diff --git a/chrome/browser/chromeos/arc/session/arc_session_manager.cc b/chrome/browser/chromeos/arc/session/arc_session_manager.cc index 4f85c79..c99cd28a 100644 --- a/chrome/browser/chromeos/arc/session/arc_session_manager.cc +++ b/chrome/browser/chromeos/arc/session/arc_session_manager.cc
@@ -514,12 +514,12 @@ state_ = State::STOPPED; auto* prefs = profile_->GetPrefs(); - const std::string user_id_hash( - chromeos::ProfileHelper::GetUserIdHashFromProfile(profile_)); const cryptohome::Identification cryptohome_id( multi_user_util::GetAccountIdFromProfile(profile_)); - arc_session_runner_->SetUserInfo(cryptohome_id, user_id_hash, - GetOrCreateSerialNumber(prefs)); + arc_session_runner_->SetUserInfo( + cryptohome_id, + chromeos::ProfileHelper::GetUserIdHashFromProfile(profile_), + GetOrCreateSerialNumber(prefs)); // Create the support host at initialization. Note that, practically, // ARC support Chrome app is rarely used (only opt-in and re-auth flow). @@ -537,7 +537,6 @@ support_host_->SetErrorDelegate(this); } data_remover_ = std::make_unique<ArcDataRemover>(prefs, cryptohome_id); - data_remover_->set_user_id_hash_for_profile(user_id_hash); if (g_enable_check_android_management_in_tests.value_or(g_ui_enabled)) ArcAndroidManagementChecker::StartClient();
diff --git a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler.cc b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler.cc index 4b797e83..4ce09ff 100644 --- a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler.cc +++ b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler.cc
@@ -195,8 +195,8 @@ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, - base::Bind(&CertProvisioningScheduler::ProcessProfile, - weak_factory_.GetWeakPtr(), profile), + base::Bind(&CertProvisioningScheduler::UpdateOneCertImpl, + weak_factory_.GetWeakPtr(), profile.profile_id), kInconsistentDataErrorRetryDelay); } @@ -316,8 +316,13 @@ void CertProvisioningScheduler::UpdateOneCert( const std::string& cert_profile_id) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - RecordEvent(cert_scope_, CertProvisioningEvent::kWorkerRetryManual); + UpdateOneCertImpl(cert_profile_id); +} + +void CertProvisioningScheduler::UpdateOneCertImpl( + const std::string& cert_profile_id) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); EraseByKey(failed_cert_profiles_, cert_profile_id);
diff --git a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler.h b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler.h index c455ed5..913ffd2 100644 --- a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler.h +++ b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler.h
@@ -73,8 +73,8 @@ CertProvisioningScheduler(const CertProvisioningScheduler&) = delete; CertProvisioningScheduler& operator=(const CertProvisioningScheduler&) = delete; - // Intended to be called when a user press a button in certificate manager UI. - // Retries provisioning of a specific certificate. + // Intended to be called when a user presses a button in certificate manager + // UI. Retries provisioning of a specific certificate. void UpdateOneCert(const std::string& cert_profile_id); void UpdateCerts(); void OnProfileFinished(const CertProfile& profile, @@ -98,6 +98,8 @@ void OnCleanVaKeysIfIdleDone(base::Optional<bool> delete_result); void RegisterForPrefsChanges(); + void UpdateOneCertImpl(const std::string& cert_profile_id); + void OnPrefsChange(); void DailyUpdateCerts(); void DeserializeWorkers();
diff --git a/chrome/browser/chromeos/crostini/crostini_terminal.cc b/chrome/browser/chromeos/crostini/crostini_terminal.cc index ab8e158..13104ddc 100644 --- a/chrome/browser/chromeos/crostini/crostini_terminal.cc +++ b/chrome/browser/chromeos/crostini/crostini_terminal.cc
@@ -81,8 +81,7 @@ apps::AppLaunchParams GenerateTerminalAppLaunchParams() { apps::AppLaunchParams launch_params( - extension_misc::kCroshBuiltinAppId, - apps::mojom::LaunchContainer::kLaunchContainerWindow, + /*app_id=*/"", apps::mojom::LaunchContainer::kLaunchContainerWindow, WindowOpenDisposition::NEW_WINDOW, apps::mojom::AppLaunchSource::kSourceAppLauncher); launch_params.override_app_name =
diff --git a/chrome/browser/chromeos/dbus/plugin_vm_service_provider.cc b/chrome/browser/chromeos/dbus/plugin_vm_service_provider.cc index 783adf03..8cb83e4 100644 --- a/chrome/browser/chromeos/dbus/plugin_vm_service_provider.cc +++ b/chrome/browser/chromeos/dbus/plugin_vm_service_provider.cc
@@ -14,7 +14,9 @@ #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/settings_window_manager_chromeos.h" +#include "chrome/browser/ui/webui/settings/chromeos/app_management/app_management_uma.h" #include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h" #include "chrome/common/webui_url_constants.h" #include "chromeos/dbus/plugin_vm_service/plugin_vm_service.pb.h" @@ -24,6 +26,10 @@ // A fixed UUID where the first 4 bytes spell 'test', reported when under test. constexpr char kFakeUUID[] = "74657374-4444-4444-8888-888888888888"; +// These are the accepted inputs to the ShowSettingsPage D-Bus method. +constexpr char kShowSettingsPageDetails[] = "pluginVm/details"; +constexpr char kShowSettingsPageSharedPaths[] = "pluginVm/sharedPaths"; + namespace chromeos { PluginVmServiceProvider::PluginVmServiceProvider() {} @@ -95,11 +101,15 @@ return; } - // Validate subpage path. - if ((request.subpage_path() != - chromeos::settings::mojom::kPluginVmDetailsSubpagePath) && - (request.subpage_path() != - chromeos::settings::mojom::kPluginVmSharedPathsSubpagePath)) { + Profile* profile = ProfileManager::GetPrimaryUserProfile(); + if (request.subpage_path() == kShowSettingsPageDetails) { + chrome::ShowAppManagementPage( + profile, plugin_vm::kPluginVmAppId, + AppManagementEntryPoint::kDBusServicePluginVm); + } else if (request.subpage_path() == kShowSettingsPageSharedPaths) { + chrome::SettingsWindowManager::GetInstance()->ShowOSSettings( + profile, chromeos::settings::mojom::kPluginVmSharedPathsSubpagePath); + } else { constexpr char error_message[] = "Invalid subpage_path"; LOG(ERROR) << error_message; std::move(response_sender) @@ -108,8 +118,6 @@ return; } - chrome::SettingsWindowManager::GetInstance()->ShowOSSettings( - ProfileManager::GetPrimaryUserProfile(), request.subpage_path()); std::move(response_sender).Run(dbus::Response::FromMethodCall(method_call)); }
diff --git a/chrome/browser/chromeos/events/DEPS b/chrome/browser/chromeos/events/DEPS new file mode 100644 index 0000000..24cfb57 --- /dev/null +++ b/chrome/browser/chromeos/events/DEPS
@@ -0,0 +1,5 @@ +specific_include_rules = { + "event_rewriter_unittest\.cc": [ + "+device/udev_linux/fake_udev_loader.h", + ] +} \ No newline at end of file
diff --git a/chrome/browser/chromeos/events/event_rewriter_unittest.cc b/chrome/browser/chromeos/events/event_rewriter_unittest.cc index 88f63fd..d2e3c8cd3 100644 --- a/chrome/browser/chromeos/events/event_rewriter_unittest.cc +++ b/chrome/browser/chromeos/events/event_rewriter_unittest.cc
@@ -24,6 +24,7 @@ #include "components/prefs/pref_member.h" #include "components/sync_preferences/testing_pref_service_syncable.h" #include "components/user_manager/scoped_user_manager.h" +#include "device/udev_linux/fake_udev_loader.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/aura/window.h" #include "ui/aura/window_tree_host.h" @@ -32,6 +33,7 @@ #include "ui/chromeos/events/modifier_key.h" #include "ui/chromeos/events/pref_names.h" #include "ui/events/devices/device_data_manager.h" +#include "ui/events/devices/device_data_manager_test_api.h" #include "ui/events/event.h" #include "ui/events/event_rewriter.h" #include "ui/events/event_utils.h" @@ -46,6 +48,10 @@ namespace { constexpr int kKeyboardDeviceId = 123; +constexpr uint32_t kNoScanCode = 0; +constexpr char kKbdSysPath[] = "/devices/platform/i8042/serio2/input/input1"; +constexpr char kKbdTopRowPropertyName[] = "CROS_KEYBOARD_TOP_ROW_LAYOUT"; +constexpr char kKbdTopRowLayoutAttributeName[] = "function_row_physmap"; constexpr char kKbdTopRowLayoutUnspecified[] = ""; constexpr char kKbdTopRowLayout1Tag[] = "1"; @@ -53,6 +59,12 @@ constexpr char kKbdTopRowLayoutWilcoTag[] = "3"; constexpr char kKbdTopRowLayoutDrallionTag[] = "4"; +// A default example of the layout string read from the function_row_physmap +// sysfs attribute. The values represent the scan codes for each position +// in the top row, which maps to F-Keys. +constexpr char kKbdDefaultCustomTopRowLayout[] = + "01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f"; + class TestEventRewriterContinuation : public ui::test::TestEventRewriterContinuation { public: @@ -86,17 +98,18 @@ ui::KeyboardCode ui_keycode, ui::DomCode code, int ui_flags, // ui::EventFlags - ui::DomKey key) { + ui::DomKey key, + uint32_t scan_code) { return base::StringPrintf( - "type=%d code=0x%06X flags=0x%X vk=0x%02X key=0x%08X", ui_type, - static_cast<unsigned int>(code), ui_flags & ~ui::EF_IS_REPEAT, ui_keycode, - static_cast<unsigned int>(key)); + "type=%d code=0x%06X flags=0x%X vk=0x%02X key=0x%08X scan=0x%08X", + ui_type, static_cast<unsigned int>(code), ui_flags & ~ui::EF_IS_REPEAT, + ui_keycode, static_cast<unsigned int>(key), scan_code); } std::string GetKeyEventAsString(const ui::KeyEvent& keyevent) { return GetExpectedResultAsString(keyevent.type(), keyevent.key_code(), keyevent.code(), keyevent.flags(), - keyevent.GetDomKey()); + keyevent.GetDomKey(), keyevent.scan_code()); } std::string GetRewrittenEventAsString(ui::EventRewriter* const rewriter, @@ -105,9 +118,11 @@ ui::DomCode code, int ui_flags, // ui::EventFlags ui::DomKey key, + uint32_t scan_code, int device_id = kKeyboardDeviceId) { ui::KeyEvent event(ui_type, ui_keycode, code, ui_flags, key, ui::EventTimeForNow()); + event.set_scan_code(scan_code); event.set_source_device_id(device_id); TestEventRewriterContinuation continuation; rewriter->RewriteEvent(event, continuation.weak_ptr_factory_.GetWeakPtr()); @@ -124,6 +139,7 @@ ui::DomCode code; int flags; // ui::EventFlags ui::DomKey::Base key; + uint32_t scan_code = kNoScanCode; } input, expected; int device_id = kKeyboardDeviceId; }; @@ -131,7 +147,7 @@ std::string GetTestCaseAsString(ui::EventType ui_type, const KeyTestCase::Event& test) { return GetExpectedResultAsString(ui_type, test.key_code, test.code, - test.flags, test.key); + test.flags, test.key, test.scan_code); } // Tests a single stateless key rewrite operation. @@ -141,7 +157,8 @@ EXPECT_EQ(GetTestCaseAsString(test.type, test.expected), GetRewrittenEventAsString(rewriter, test.type, test.input.key_code, test.input.code, test.input.flags, - test.input.key, test.device_id)); + test.input.key, test.input.scan_code, + test.device_id)); } } // namespace @@ -161,6 +178,7 @@ input_method_manager_mock_); // pass ownership delegate_ = std::make_unique<EventRewriterDelegateImpl>(nullptr); delegate_->set_pref_service_for_testing(prefs()); + device_data_manager_test_api_.SetKeyboardDevices({}); rewriter_ = std::make_unique<ui::EventRewriterChromeOS>(delegate_.get(), nullptr, false); ChromeAshTestBase::SetUp(); @@ -204,40 +222,84 @@ void SetupKeyboard(const std::string& name, const std::string& layout = "", - ui::InputDeviceType type = ui::INPUT_DEVICE_INTERNAL) { + ui::InputDeviceType type = ui::INPUT_DEVICE_INTERNAL, + bool has_custom_top_row = false) { + // Add a fake device to udev. + const ui::InputDevice keyboard(kKeyboardDeviceId, type, name, /*phys=*/"", + base::FilePath(kKbdSysPath), /*vendor=*/-1, + /*product=*/-1, /*version=*/-1); + + // Old CrOS keyboards supply an integer/enum as a sysfs property to identify + // their layout type. New keyboards provide the mapping of scan codes to + // F-Key position via an attribute. + std::map<std::string, std::string> sysfs_properties; + std::map<std::string, std::string> sysfs_attributes; + if (has_custom_top_row) { + if (!layout.empty()) + sysfs_attributes[kKbdTopRowLayoutAttributeName] = layout; + } else { + if (!layout.empty()) + sysfs_properties[kKbdTopRowPropertyName] = layout; + } + + fake_udev_.Reset(); + fake_udev_.AddFakeDevice(keyboard.name, keyboard.sys_path.value(), + std::move(sysfs_attributes), + std::move(sysfs_properties)); + + // Reset the state of the device manager. + device_data_manager_test_api_.SetKeyboardDevices({}); + device_data_manager_test_api_.SetKeyboardDevices({keyboard}); + + // Reset the state of the EventRewriter. rewriter_->ResetStateForTesting(); - rewriter_->KeyboardDeviceAddedForTesting(kKeyboardDeviceId, name, layout, - type); + rewriter_->KeyboardDeviceAddedForTesting(kKeyboardDeviceId); rewriter_->set_last_keyboard_device_id_for_testing(kKeyboardDeviceId); } void TestKeyboard(const std::string& name, const std::string& layout, ui::InputDeviceType type, + bool has_custom_top_row, const std::vector<KeyTestCase>& tests) { - SetupKeyboard(name, layout, type); + SetupKeyboard(name, layout, type, has_custom_top_row); for (const auto& test : tests) CheckKeyTestCase(rewriter(), test); } void TestInternalChromeKeyboard(const std::vector<KeyTestCase>& tests) { TestKeyboard("Internal Keyboard", kKbdTopRowLayoutUnspecified, - ui::INPUT_DEVICE_INTERNAL, tests); + ui::INPUT_DEVICE_INTERNAL, /*has_custom_top_row=*/false, + tests); + } + + void TestInternalChromeCustomLayoutKeyboard( + const std::vector<KeyTestCase>& tests) { + TestKeyboard("Internal Custom Layout Keyboard", + kKbdDefaultCustomTopRowLayout, ui::INPUT_DEVICE_INTERNAL, + /*has_custom_top_row=*/true, tests); } void TestExternalChromeKeyboard(const std::vector<KeyTestCase>& tests) { TestKeyboard("External Chrome Keyboard", kKbdTopRowLayout1Tag, - ui::INPUT_DEVICE_UNKNOWN, tests); + ui::INPUT_DEVICE_UNKNOWN, /*has_custom_top_row=*/false, tests); + } + + void TestExternalChromeCustomLayoutKeyboard( + const std::vector<KeyTestCase>& tests) { + TestKeyboard("External Chrome Custom Layout Keyboard", + kKbdDefaultCustomTopRowLayout, ui::INPUT_DEVICE_UNKNOWN, + /*has_custom_top_row=*/true, tests); } void TestExternalGenericKeyboard(const std::vector<KeyTestCase>& tests) { TestKeyboard("PC Keyboard", kKbdTopRowLayoutUnspecified, - ui::INPUT_DEVICE_UNKNOWN, tests); + ui::INPUT_DEVICE_UNKNOWN, /*has_custom_top_row=*/false, tests); } void TestExternalAppleKeyboard(const std::vector<KeyTestCase>& tests) { TestKeyboard("Apple Keyboard", kKbdTopRowLayoutUnspecified, - ui::INPUT_DEVICE_UNKNOWN, tests); + ui::INPUT_DEVICE_UNKNOWN, /*has_custom_top_row=*/false, tests); } void TestChromeKeyboardVariants(const std::vector<KeyTestCase>& tests) { @@ -245,8 +307,21 @@ TestExternalChromeKeyboard(tests); } + void TestChromeCustomLayoutKeyboardVariants( + const std::vector<KeyTestCase>& tests) { + TestInternalChromeCustomLayoutKeyboard(tests); + TestExternalChromeCustomLayoutKeyboard(tests); + } + void TestNonAppleKeyboardVariants(const std::vector<KeyTestCase>& tests) { TestChromeKeyboardVariants(tests); + TestChromeCustomLayoutKeyboardVariants(tests); + TestExternalGenericKeyboard(tests); + } + + void TestNonAppleNonCustomLayoutKeyboardVariants( + const std::vector<KeyTestCase>& tests) { + TestChromeKeyboardVariants(tests); TestExternalGenericKeyboard(tests); } @@ -259,6 +334,8 @@ FakeChromeUserManager* fake_user_manager_; // Not owned. user_manager::ScopedUserManager user_manager_enabler_; input_method::MockInputMethodManagerImpl* input_method_manager_mock_; + testing::FakeUdevLoader fake_udev_; + ui::DeviceDataManagerTestApi device_data_manager_test_api_; sync_preferences::TestingPrefServiceSyncable prefs_; std::unique_ptr<EventRewriterDelegateImpl> delegate_; @@ -1187,40 +1264,45 @@ EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_); // Press Search. - EXPECT_EQ(GetExpectedResultAsString( - ui::ET_KEY_PRESSED, ui::VKEY_CAPITAL, ui::DomCode::CAPS_LOCK, - ui::EF_MOD3_DOWN | ui::EF_CAPS_LOCK_ON, ui::DomKey::CAPS_LOCK), - GetRewrittenEventAsString(rewriter(), ui::ET_KEY_PRESSED, - ui::VKEY_LWIN, ui::DomCode::META_LEFT, - ui::EF_COMMAND_DOWN, ui::DomKey::META)); + EXPECT_EQ( + GetExpectedResultAsString(ui::ET_KEY_PRESSED, ui::VKEY_CAPITAL, + ui::DomCode::CAPS_LOCK, + ui::EF_MOD3_DOWN | ui::EF_CAPS_LOCK_ON, + ui::DomKey::CAPS_LOCK, kNoScanCode), + GetRewrittenEventAsString(rewriter(), ui::ET_KEY_PRESSED, ui::VKEY_LWIN, + ui::DomCode::META_LEFT, ui::EF_COMMAND_DOWN, + ui::DomKey::META, kNoScanCode)); EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_); // Release Search. - EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_RELEASED, ui::VKEY_CAPITAL, - ui::DomCode::CAPS_LOCK, ui::EF_NONE, - ui::DomKey::CAPS_LOCK), - GetRewrittenEventAsString(rewriter(), ui::ET_KEY_RELEASED, - ui::VKEY_LWIN, ui::DomCode::META_LEFT, - ui::EF_NONE, ui::DomKey::META)); + EXPECT_EQ( + GetExpectedResultAsString(ui::ET_KEY_RELEASED, ui::VKEY_CAPITAL, + ui::DomCode::CAPS_LOCK, ui::EF_NONE, + ui::DomKey::CAPS_LOCK, kNoScanCode), + GetRewrittenEventAsString(rewriter(), ui::ET_KEY_RELEASED, ui::VKEY_LWIN, + ui::DomCode::META_LEFT, ui::EF_NONE, + ui::DomKey::META, kNoScanCode)); EXPECT_TRUE(ime_keyboard.caps_lock_is_enabled_); // Press Search. - EXPECT_EQ(GetExpectedResultAsString( - ui::ET_KEY_PRESSED, ui::VKEY_CAPITAL, ui::DomCode::CAPS_LOCK, - ui::EF_CAPS_LOCK_ON | ui::EF_MOD3_DOWN, ui::DomKey::CAPS_LOCK), + EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED, ui::VKEY_CAPITAL, + ui::DomCode::CAPS_LOCK, + ui::EF_CAPS_LOCK_ON | ui::EF_MOD3_DOWN, + ui::DomKey::CAPS_LOCK, kNoScanCode), GetRewrittenEventAsString(rewriter(), ui::ET_KEY_PRESSED, ui::VKEY_LWIN, ui::DomCode::META_LEFT, ui::EF_COMMAND_DOWN | ui::EF_CAPS_LOCK_ON, - ui::DomKey::META)); + ui::DomKey::META, kNoScanCode)); EXPECT_TRUE(ime_keyboard.caps_lock_is_enabled_); // Release Search. - EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_RELEASED, ui::VKEY_CAPITAL, - ui::DomCode::CAPS_LOCK, ui::EF_NONE, - ui::DomKey::CAPS_LOCK), - GetRewrittenEventAsString(rewriter(), ui::ET_KEY_RELEASED, - ui::VKEY_LWIN, ui::DomCode::META_LEFT, - ui::EF_NONE, ui::DomKey::META)); + EXPECT_EQ( + GetExpectedResultAsString(ui::ET_KEY_RELEASED, ui::VKEY_CAPITAL, + ui::DomCode::CAPS_LOCK, ui::EF_NONE, + ui::DomKey::CAPS_LOCK, kNoScanCode), + GetRewrittenEventAsString(rewriter(), ui::ET_KEY_RELEASED, ui::VKEY_LWIN, + ui::DomCode::META_LEFT, ui::EF_NONE, + ui::DomKey::META, kNoScanCode)); EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_); // Do the same on external Chrome OS keyboard. @@ -1228,40 +1310,45 @@ ui::INPUT_DEVICE_UNKNOWN); // Press Search. - EXPECT_EQ(GetExpectedResultAsString( - ui::ET_KEY_PRESSED, ui::VKEY_CAPITAL, ui::DomCode::CAPS_LOCK, - ui::EF_MOD3_DOWN | ui::EF_CAPS_LOCK_ON, ui::DomKey::CAPS_LOCK), - GetRewrittenEventAsString(rewriter(), ui::ET_KEY_PRESSED, - ui::VKEY_LWIN, ui::DomCode::META_LEFT, - ui::EF_COMMAND_DOWN, ui::DomKey::META)); + EXPECT_EQ( + GetExpectedResultAsString(ui::ET_KEY_PRESSED, ui::VKEY_CAPITAL, + ui::DomCode::CAPS_LOCK, + ui::EF_MOD3_DOWN | ui::EF_CAPS_LOCK_ON, + ui::DomKey::CAPS_LOCK, kNoScanCode), + GetRewrittenEventAsString(rewriter(), ui::ET_KEY_PRESSED, ui::VKEY_LWIN, + ui::DomCode::META_LEFT, ui::EF_COMMAND_DOWN, + ui::DomKey::META, kNoScanCode)); EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_); // Release Search. - EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_RELEASED, ui::VKEY_CAPITAL, - ui::DomCode::CAPS_LOCK, ui::EF_NONE, - ui::DomKey::CAPS_LOCK), - GetRewrittenEventAsString(rewriter(), ui::ET_KEY_RELEASED, - ui::VKEY_LWIN, ui::DomCode::META_LEFT, - ui::EF_NONE, ui::DomKey::META)); + EXPECT_EQ( + GetExpectedResultAsString(ui::ET_KEY_RELEASED, ui::VKEY_CAPITAL, + ui::DomCode::CAPS_LOCK, ui::EF_NONE, + ui::DomKey::CAPS_LOCK, kNoScanCode), + GetRewrittenEventAsString(rewriter(), ui::ET_KEY_RELEASED, ui::VKEY_LWIN, + ui::DomCode::META_LEFT, ui::EF_NONE, + ui::DomKey::META, kNoScanCode)); EXPECT_TRUE(ime_keyboard.caps_lock_is_enabled_); // Press Search. - EXPECT_EQ(GetExpectedResultAsString( - ui::ET_KEY_PRESSED, ui::VKEY_CAPITAL, ui::DomCode::CAPS_LOCK, - ui::EF_CAPS_LOCK_ON | ui::EF_MOD3_DOWN, ui::DomKey::CAPS_LOCK), + EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED, ui::VKEY_CAPITAL, + ui::DomCode::CAPS_LOCK, + ui::EF_CAPS_LOCK_ON | ui::EF_MOD3_DOWN, + ui::DomKey::CAPS_LOCK, kNoScanCode), GetRewrittenEventAsString(rewriter(), ui::ET_KEY_PRESSED, ui::VKEY_LWIN, ui::DomCode::META_LEFT, ui::EF_COMMAND_DOWN | ui::EF_CAPS_LOCK_ON, - ui::DomKey::META)); + ui::DomKey::META, kNoScanCode)); EXPECT_TRUE(ime_keyboard.caps_lock_is_enabled_); // Release Search. - EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_RELEASED, ui::VKEY_CAPITAL, - ui::DomCode::CAPS_LOCK, ui::EF_NONE, - ui::DomKey::CAPS_LOCK), - GetRewrittenEventAsString(rewriter(), ui::ET_KEY_RELEASED, - ui::VKEY_LWIN, ui::DomCode::META_LEFT, - ui::EF_NONE, ui::DomKey::META)); + EXPECT_EQ( + GetExpectedResultAsString(ui::ET_KEY_RELEASED, ui::VKEY_CAPITAL, + ui::DomCode::CAPS_LOCK, ui::EF_NONE, + ui::DomKey::CAPS_LOCK, kNoScanCode), + GetRewrittenEventAsString(rewriter(), ui::ET_KEY_RELEASED, ui::VKEY_LWIN, + ui::DomCode::META_LEFT, ui::EF_NONE, + ui::DomKey::META, kNoScanCode)); EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_); // Try external keyboard with Caps Lock. @@ -1269,22 +1356,24 @@ ui::INPUT_DEVICE_UNKNOWN); // Press Caps Lock. - EXPECT_EQ(GetExpectedResultAsString( - ui::ET_KEY_PRESSED, ui::VKEY_CAPITAL, ui::DomCode::CAPS_LOCK, - ui::EF_CAPS_LOCK_ON | ui::EF_MOD3_DOWN, ui::DomKey::CAPS_LOCK), + EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED, ui::VKEY_CAPITAL, + ui::DomCode::CAPS_LOCK, + ui::EF_CAPS_LOCK_ON | ui::EF_MOD3_DOWN, + ui::DomKey::CAPS_LOCK, kNoScanCode), GetRewrittenEventAsString(rewriter(), ui::ET_KEY_PRESSED, ui::VKEY_CAPITAL, ui::DomCode::CAPS_LOCK, ui::EF_CAPS_LOCK_ON | ui::EF_MOD3_DOWN, - ui::DomKey::CAPS_LOCK)); + ui::DomKey::CAPS_LOCK, kNoScanCode)); EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_); // Release Caps Lock. EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_RELEASED, ui::VKEY_CAPITAL, ui::DomCode::CAPS_LOCK, ui::EF_NONE, - ui::DomKey::CAPS_LOCK), + ui::DomKey::CAPS_LOCK, kNoScanCode), GetRewrittenEventAsString(rewriter(), ui::ET_KEY_RELEASED, ui::VKEY_CAPITAL, ui::DomCode::CAPS_LOCK, - ui::EF_NONE, ui::DomKey::CAPS_LOCK)); + ui::EF_NONE, ui::DomKey::CAPS_LOCK, + kNoScanCode)); EXPECT_TRUE(ime_keyboard.caps_lock_is_enabled_); } @@ -1298,20 +1387,23 @@ EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_); // On Chrome OS, CapsLock is mapped to CapsLock with Mod3Mask. - EXPECT_EQ(GetExpectedResultAsString( - ui::ET_KEY_PRESSED, ui::VKEY_CAPITAL, ui::DomCode::CAPS_LOCK, - ui::EF_CAPS_LOCK_ON | ui::EF_MOD3_DOWN, ui::DomKey::CAPS_LOCK), + EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED, ui::VKEY_CAPITAL, + ui::DomCode::CAPS_LOCK, + ui::EF_CAPS_LOCK_ON | ui::EF_MOD3_DOWN, + ui::DomKey::CAPS_LOCK, kNoScanCode), GetRewrittenEventAsString(rewriter(), ui::ET_KEY_PRESSED, ui::VKEY_CAPITAL, ui::DomCode::CAPS_LOCK, - ui::EF_MOD3_DOWN, ui::DomKey::CAPS_LOCK)); + ui::EF_MOD3_DOWN, ui::DomKey::CAPS_LOCK, + kNoScanCode)); EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_); EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_RELEASED, ui::VKEY_CAPITAL, ui::DomCode::CAPS_LOCK, ui::EF_NONE, - ui::DomKey::CAPS_LOCK), + ui::DomKey::CAPS_LOCK, kNoScanCode), GetRewrittenEventAsString(rewriter(), ui::ET_KEY_RELEASED, ui::VKEY_CAPITAL, ui::DomCode::CAPS_LOCK, - ui::EF_MOD3_DOWN, ui::DomKey::CAPS_LOCK)); + ui::EF_MOD3_DOWN, ui::DomKey::CAPS_LOCK, + kNoScanCode)); EXPECT_TRUE(ime_keyboard.caps_lock_is_enabled_); // Remap Caps Lock to Control. @@ -1320,21 +1412,22 @@ ui::chromeos::ModifierKey::kControlKey); // Press Caps Lock. - EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED, ui::VKEY_CONTROL, - ui::DomCode::CONTROL_LEFT, - ui::EF_CONTROL_DOWN, ui::DomKey::CONTROL), + EXPECT_EQ(GetExpectedResultAsString( + ui::ET_KEY_PRESSED, ui::VKEY_CONTROL, ui::DomCode::CONTROL_LEFT, + ui::EF_CONTROL_DOWN, ui::DomKey::CONTROL, kNoScanCode), GetRewrittenEventAsString(rewriter(), ui::ET_KEY_PRESSED, ui::VKEY_CAPITAL, ui::DomCode::CAPS_LOCK, ui::EF_CAPS_LOCK_ON | ui::EF_MOD3_DOWN, - ui::DomKey::CAPS_LOCK)); + ui::DomKey::CAPS_LOCK, kNoScanCode)); // Release Caps Lock. EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_RELEASED, ui::VKEY_CONTROL, ui::DomCode::CONTROL_LEFT, ui::EF_NONE, - ui::DomKey::CONTROL), + ui::DomKey::CONTROL, kNoScanCode), GetRewrittenEventAsString(rewriter(), ui::ET_KEY_RELEASED, ui::VKEY_CAPITAL, ui::DomCode::CAPS_LOCK, - ui::EF_NONE, ui::DomKey::CAPS_LOCK)); + ui::EF_NONE, ui::DomKey::CAPS_LOCK, + kNoScanCode)); } TEST_F(EventRewriterTest, TestRewriteCapsLockToControl) { @@ -1384,12 +1477,13 @@ // Press CapsLock+a. Confirm that Mod3Mask is NOT rewritten to ControlMask // when Mod3Mask is already in use by the current XKB layout. - EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED, ui::VKEY_A, - ui::DomCode::US_A, ui::EF_NONE, - ui::DomKey::Constant<'a'>::Character), - GetRewrittenEventAsString( - rewriter(), ui::ET_KEY_PRESSED, ui::VKEY_A, ui::DomCode::US_A, - ui::EF_NONE, ui::DomKey::Constant<'a'>::Character)); + EXPECT_EQ( + GetExpectedResultAsString( + ui::ET_KEY_PRESSED, ui::VKEY_A, ui::DomCode::US_A, ui::EF_NONE, + ui::DomKey::Constant<'a'>::Character, kNoScanCode), + GetRewrittenEventAsString( + rewriter(), ui::ET_KEY_PRESSED, ui::VKEY_A, ui::DomCode::US_A, + ui::EF_NONE, ui::DomKey::Constant<'a'>::Character, kNoScanCode)); input_method_manager_mock_->set_mod3_used(false); } @@ -1519,160 +1613,10 @@ }); } -TEST_F(EventRewriterTest, TestRewriteFunctionKeys) { +TEST_F(EventRewriterTest, TestRewriteFunctionKeysCommon) { chromeos::Preferences::RegisterProfilePrefs(prefs()->registry()); - TestNonAppleKeyboardVariants({ - // F1 -> Back - {ui::ET_KEY_PRESSED, - {ui::VKEY_F1, ui::DomCode::F1, ui::EF_NONE, ui::DomKey::F1}, - {ui::VKEY_BROWSER_BACK, ui::DomCode::BROWSER_BACK, ui::EF_NONE, - ui::DomKey::BROWSER_BACK}}, - {ui::ET_KEY_PRESSED, - {ui::VKEY_F1, ui::DomCode::F1, ui::EF_CONTROL_DOWN, ui::DomKey::F1}, - {ui::VKEY_BROWSER_BACK, ui::DomCode::BROWSER_BACK, ui::EF_CONTROL_DOWN, - ui::DomKey::BROWSER_BACK}}, - {ui::ET_KEY_PRESSED, - {ui::VKEY_F1, ui::DomCode::F1, ui::EF_ALT_DOWN, ui::DomKey::F1}, - {ui::VKEY_BROWSER_BACK, ui::DomCode::BROWSER_BACK, ui::EF_ALT_DOWN, - ui::DomKey::BROWSER_BACK}}, - // F2 -> Forward - {ui::ET_KEY_PRESSED, - {ui::VKEY_F2, ui::DomCode::F2, ui::EF_NONE, ui::DomKey::F2}, - {ui::VKEY_BROWSER_FORWARD, ui::DomCode::BROWSER_FORWARD, ui::EF_NONE, - ui::DomKey::BROWSER_FORWARD}}, - {ui::ET_KEY_PRESSED, - {ui::VKEY_F2, ui::DomCode::F2, ui::EF_CONTROL_DOWN, ui::DomKey::F2}, - {ui::VKEY_BROWSER_FORWARD, ui::DomCode::BROWSER_FORWARD, - ui::EF_CONTROL_DOWN, ui::DomKey::BROWSER_FORWARD}}, - {ui::ET_KEY_PRESSED, - {ui::VKEY_F2, ui::DomCode::F2, ui::EF_ALT_DOWN, ui::DomKey::F2}, - {ui::VKEY_BROWSER_FORWARD, ui::DomCode::BROWSER_FORWARD, ui::EF_ALT_DOWN, - ui::DomKey::BROWSER_FORWARD}}, - // F3 -> Refresh - {ui::ET_KEY_PRESSED, - {ui::VKEY_F3, ui::DomCode::F3, ui::EF_NONE, ui::DomKey::F3}, - {ui::VKEY_BROWSER_REFRESH, ui::DomCode::BROWSER_REFRESH, ui::EF_NONE, - ui::DomKey::BROWSER_REFRESH}}, - {ui::ET_KEY_PRESSED, - {ui::VKEY_F3, ui::DomCode::F3, ui::EF_CONTROL_DOWN, ui::DomKey::F3}, - {ui::VKEY_BROWSER_REFRESH, ui::DomCode::BROWSER_REFRESH, - ui::EF_CONTROL_DOWN, ui::DomKey::BROWSER_REFRESH}}, - {ui::ET_KEY_PRESSED, - {ui::VKEY_F3, ui::DomCode::F3, ui::EF_ALT_DOWN, ui::DomKey::F3}, - {ui::VKEY_BROWSER_REFRESH, ui::DomCode::BROWSER_REFRESH, ui::EF_ALT_DOWN, - ui::DomKey::BROWSER_REFRESH}}, - // F4 -> Launch App 2 - {ui::ET_KEY_PRESSED, - {ui::VKEY_F4, ui::DomCode::F4, ui::EF_NONE, ui::DomKey::F4}, - {ui::VKEY_MEDIA_LAUNCH_APP2, ui::DomCode::ZOOM_TOGGLE, ui::EF_NONE, - ui::DomKey::ZOOM_TOGGLE}}, - {ui::ET_KEY_PRESSED, - {ui::VKEY_F4, ui::DomCode::F4, ui::EF_CONTROL_DOWN, ui::DomKey::F4}, - {ui::VKEY_MEDIA_LAUNCH_APP2, ui::DomCode::ZOOM_TOGGLE, - ui::EF_CONTROL_DOWN, ui::DomKey::ZOOM_TOGGLE}}, - {ui::ET_KEY_PRESSED, - {ui::VKEY_F4, ui::DomCode::F4, ui::EF_ALT_DOWN, ui::DomKey::F4}, - {ui::VKEY_MEDIA_LAUNCH_APP2, ui::DomCode::ZOOM_TOGGLE, ui::EF_ALT_DOWN, - ui::DomKey::ZOOM_TOGGLE}}, - // F5 -> Launch App 1 - {ui::ET_KEY_PRESSED, - {ui::VKEY_F5, ui::DomCode::F5, ui::EF_NONE, ui::DomKey::F5}, - {ui::VKEY_MEDIA_LAUNCH_APP1, ui::DomCode::SELECT_TASK, ui::EF_NONE, - ui::DomKey::LAUNCH_MY_COMPUTER}}, - {ui::ET_KEY_PRESSED, - {ui::VKEY_F5, ui::DomCode::F5, ui::EF_CONTROL_DOWN, ui::DomKey::F5}, - {ui::VKEY_MEDIA_LAUNCH_APP1, ui::DomCode::SELECT_TASK, - ui::EF_CONTROL_DOWN, ui::DomKey::LAUNCH_MY_COMPUTER}}, - {ui::ET_KEY_PRESSED, - {ui::VKEY_F5, ui::DomCode::F5, ui::EF_ALT_DOWN, ui::DomKey::F5}, - {ui::VKEY_MEDIA_LAUNCH_APP1, ui::DomCode::SELECT_TASK, ui::EF_ALT_DOWN, - ui::DomKey::LAUNCH_MY_COMPUTER}}, - // F6 -> Brightness down - {ui::ET_KEY_PRESSED, - {ui::VKEY_F6, ui::DomCode::F6, ui::EF_NONE, ui::DomKey::F6}, - {ui::VKEY_BRIGHTNESS_DOWN, ui::DomCode::BRIGHTNESS_DOWN, ui::EF_NONE, - ui::DomKey::BRIGHTNESS_DOWN}}, - {ui::ET_KEY_PRESSED, - {ui::VKEY_F6, ui::DomCode::F6, ui::EF_CONTROL_DOWN, ui::DomKey::F6}, - {ui::VKEY_BRIGHTNESS_DOWN, ui::DomCode::BRIGHTNESS_DOWN, - ui::EF_CONTROL_DOWN, ui::DomKey::BRIGHTNESS_DOWN}}, - {ui::ET_KEY_PRESSED, - {ui::VKEY_F6, ui::DomCode::F6, ui::EF_ALT_DOWN, ui::DomKey::F6}, - {ui::VKEY_BRIGHTNESS_DOWN, ui::DomCode::BRIGHTNESS_DOWN, ui::EF_ALT_DOWN, - ui::DomKey::BRIGHTNESS_DOWN}}, - // F7 -> Brightness up - {ui::ET_KEY_PRESSED, - {ui::VKEY_F7, ui::DomCode::F7, ui::EF_NONE, ui::DomKey::F7}, - {ui::VKEY_BRIGHTNESS_UP, ui::DomCode::BRIGHTNESS_UP, ui::EF_NONE, - ui::DomKey::BRIGHTNESS_UP}}, - {ui::ET_KEY_PRESSED, - {ui::VKEY_F7, ui::DomCode::F7, ui::EF_CONTROL_DOWN, ui::DomKey::F7}, - {ui::VKEY_BRIGHTNESS_UP, ui::DomCode::BRIGHTNESS_UP, ui::EF_CONTROL_DOWN, - ui::DomKey::BRIGHTNESS_UP}}, - {ui::ET_KEY_PRESSED, - {ui::VKEY_F7, ui::DomCode::F7, ui::EF_ALT_DOWN, ui::DomKey::F7}, - {ui::VKEY_BRIGHTNESS_UP, ui::DomCode::BRIGHTNESS_UP, ui::EF_ALT_DOWN, - ui::DomKey::BRIGHTNESS_UP}}, - // F8 -> Volume Mute - {ui::ET_KEY_PRESSED, - {ui::VKEY_F8, ui::DomCode::F8, ui::EF_NONE, ui::DomKey::F8}, - {ui::VKEY_VOLUME_MUTE, ui::DomCode::VOLUME_MUTE, ui::EF_NONE, - ui::DomKey::AUDIO_VOLUME_MUTE}}, - {ui::ET_KEY_PRESSED, - {ui::VKEY_F8, ui::DomCode::F8, ui::EF_CONTROL_DOWN, ui::DomKey::F8}, - {ui::VKEY_VOLUME_MUTE, ui::DomCode::VOLUME_MUTE, ui::EF_CONTROL_DOWN, - ui::DomKey::AUDIO_VOLUME_MUTE}}, - {ui::ET_KEY_PRESSED, - {ui::VKEY_F8, ui::DomCode::F8, ui::EF_ALT_DOWN, ui::DomKey::F8}, - {ui::VKEY_VOLUME_MUTE, ui::DomCode::VOLUME_MUTE, ui::EF_ALT_DOWN, - ui::DomKey::AUDIO_VOLUME_MUTE}}, - // F9 -> Volume Down - {ui::ET_KEY_PRESSED, - {ui::VKEY_F9, ui::DomCode::F9, ui::EF_NONE, ui::DomKey::F9}, - {ui::VKEY_VOLUME_DOWN, ui::DomCode::VOLUME_DOWN, ui::EF_NONE, - ui::DomKey::AUDIO_VOLUME_DOWN}}, - {ui::ET_KEY_PRESSED, - {ui::VKEY_F9, ui::DomCode::F9, ui::EF_CONTROL_DOWN, ui::DomKey::F9}, - {ui::VKEY_VOLUME_DOWN, ui::DomCode::VOLUME_DOWN, ui::EF_CONTROL_DOWN, - ui::DomKey::AUDIO_VOLUME_DOWN}}, - {ui::ET_KEY_PRESSED, - {ui::VKEY_F9, ui::DomCode::F9, ui::EF_ALT_DOWN, ui::DomKey::F9}, - {ui::VKEY_VOLUME_DOWN, ui::DomCode::VOLUME_DOWN, ui::EF_ALT_DOWN, - ui::DomKey::AUDIO_VOLUME_DOWN}}, - // F10 -> Volume Up - {ui::ET_KEY_PRESSED, - {ui::VKEY_F10, ui::DomCode::F10, ui::EF_NONE, ui::DomKey::F10}, - {ui::VKEY_VOLUME_UP, ui::DomCode::VOLUME_UP, ui::EF_NONE, - ui::DomKey::AUDIO_VOLUME_UP}}, - {ui::ET_KEY_PRESSED, - {ui::VKEY_F10, ui::DomCode::F10, ui::EF_CONTROL_DOWN, ui::DomKey::F10}, - {ui::VKEY_VOLUME_UP, ui::DomCode::VOLUME_UP, ui::EF_CONTROL_DOWN, - ui::DomKey::AUDIO_VOLUME_UP}}, - {ui::ET_KEY_PRESSED, - {ui::VKEY_F10, ui::DomCode::F10, ui::EF_ALT_DOWN, ui::DomKey::F10}, - {ui::VKEY_VOLUME_UP, ui::DomCode::VOLUME_UP, ui::EF_ALT_DOWN, - ui::DomKey::AUDIO_VOLUME_UP}}, - // F11 -> F11 - {ui::ET_KEY_PRESSED, - {ui::VKEY_F11, ui::DomCode::F11, ui::EF_NONE, ui::DomKey::F11}, - {ui::VKEY_F11, ui::DomCode::F11, ui::EF_NONE, ui::DomKey::F11}}, - {ui::ET_KEY_PRESSED, - {ui::VKEY_F11, ui::DomCode::F11, ui::EF_CONTROL_DOWN, ui::DomKey::F11}, - {ui::VKEY_F11, ui::DomCode::F11, ui::EF_CONTROL_DOWN, ui::DomKey::F11}}, - {ui::ET_KEY_PRESSED, - {ui::VKEY_F11, ui::DomCode::F11, ui::EF_ALT_DOWN, ui::DomKey::F11}, - {ui::VKEY_F11, ui::DomCode::F11, ui::EF_ALT_DOWN, ui::DomKey::F11}}, - // F12 -> F12 - {ui::ET_KEY_PRESSED, - {ui::VKEY_F12, ui::DomCode::F12, ui::EF_NONE, ui::DomKey::F12}, - {ui::VKEY_F12, ui::DomCode::F12, ui::EF_NONE, ui::DomKey::F12}}, - {ui::ET_KEY_PRESSED, - {ui::VKEY_F12, ui::DomCode::F12, ui::EF_CONTROL_DOWN, ui::DomKey::F12}, - {ui::VKEY_F12, ui::DomCode::F12, ui::EF_CONTROL_DOWN, ui::DomKey::F12}}, - {ui::ET_KEY_PRESSED, - {ui::VKEY_F12, ui::DomCode::F12, ui::EF_ALT_DOWN, ui::DomKey::F12}, - {ui::VKEY_F12, ui::DomCode::F12, ui::EF_ALT_DOWN, ui::DomKey::F12}}, + TestNonAppleNonCustomLayoutKeyboardVariants({ // The number row should not be rewritten without Search key. {ui::ET_KEY_PRESSED, {ui::VKEY_1, ui::DomCode::DIGIT1, ui::EF_NONE, @@ -1826,10 +1770,497 @@ }); } +TEST_F(EventRewriterTest, TestRewriteFunctionKeysNonCustomLayouts) { + chromeos::Preferences::RegisterProfilePrefs(prefs()->registry()); + + // Old CrOS keyboards that do not have custom layouts send F-Keys by default + // and are translated by default to Actions based on hardcoded mappings. + // New CrOS keyboards are not tested here because they do not remap F-Keys. + TestNonAppleNonCustomLayoutKeyboardVariants({ + // F1 -> Back + {ui::ET_KEY_PRESSED, + {ui::VKEY_F1, ui::DomCode::F1, ui::EF_NONE, ui::DomKey::F1}, + {ui::VKEY_BROWSER_BACK, ui::DomCode::BROWSER_BACK, ui::EF_NONE, + ui::DomKey::BROWSER_BACK}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F1, ui::DomCode::F1, ui::EF_CONTROL_DOWN, ui::DomKey::F1}, + {ui::VKEY_BROWSER_BACK, ui::DomCode::BROWSER_BACK, ui::EF_CONTROL_DOWN, + ui::DomKey::BROWSER_BACK}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F1, ui::DomCode::F1, ui::EF_ALT_DOWN, ui::DomKey::F1}, + {ui::VKEY_BROWSER_BACK, ui::DomCode::BROWSER_BACK, ui::EF_ALT_DOWN, + ui::DomKey::BROWSER_BACK}}, + // F2 -> Forward + {ui::ET_KEY_PRESSED, + {ui::VKEY_F2, ui::DomCode::F2, ui::EF_NONE, ui::DomKey::F2}, + {ui::VKEY_BROWSER_FORWARD, ui::DomCode::BROWSER_FORWARD, ui::EF_NONE, + ui::DomKey::BROWSER_FORWARD}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F2, ui::DomCode::F2, ui::EF_CONTROL_DOWN, ui::DomKey::F2}, + {ui::VKEY_BROWSER_FORWARD, ui::DomCode::BROWSER_FORWARD, + ui::EF_CONTROL_DOWN, ui::DomKey::BROWSER_FORWARD}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F2, ui::DomCode::F2, ui::EF_ALT_DOWN, ui::DomKey::F2}, + {ui::VKEY_BROWSER_FORWARD, ui::DomCode::BROWSER_FORWARD, ui::EF_ALT_DOWN, + ui::DomKey::BROWSER_FORWARD}}, + // F3 -> Refresh + {ui::ET_KEY_PRESSED, + {ui::VKEY_F3, ui::DomCode::F3, ui::EF_NONE, ui::DomKey::F3}, + {ui::VKEY_BROWSER_REFRESH, ui::DomCode::BROWSER_REFRESH, ui::EF_NONE, + ui::DomKey::BROWSER_REFRESH}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F3, ui::DomCode::F3, ui::EF_CONTROL_DOWN, ui::DomKey::F3}, + {ui::VKEY_BROWSER_REFRESH, ui::DomCode::BROWSER_REFRESH, + ui::EF_CONTROL_DOWN, ui::DomKey::BROWSER_REFRESH}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F3, ui::DomCode::F3, ui::EF_ALT_DOWN, ui::DomKey::F3}, + {ui::VKEY_BROWSER_REFRESH, ui::DomCode::BROWSER_REFRESH, ui::EF_ALT_DOWN, + ui::DomKey::BROWSER_REFRESH}}, + // F4 -> Launch App 2 + {ui::ET_KEY_PRESSED, + {ui::VKEY_F4, ui::DomCode::F4, ui::EF_NONE, ui::DomKey::F4}, + {ui::VKEY_MEDIA_LAUNCH_APP2, ui::DomCode::ZOOM_TOGGLE, ui::EF_NONE, + ui::DomKey::ZOOM_TOGGLE}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F4, ui::DomCode::F4, ui::EF_CONTROL_DOWN, ui::DomKey::F4}, + {ui::VKEY_MEDIA_LAUNCH_APP2, ui::DomCode::ZOOM_TOGGLE, + ui::EF_CONTROL_DOWN, ui::DomKey::ZOOM_TOGGLE}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F4, ui::DomCode::F4, ui::EF_ALT_DOWN, ui::DomKey::F4}, + {ui::VKEY_MEDIA_LAUNCH_APP2, ui::DomCode::ZOOM_TOGGLE, ui::EF_ALT_DOWN, + ui::DomKey::ZOOM_TOGGLE}}, + // F5 -> Launch App 1 + {ui::ET_KEY_PRESSED, + {ui::VKEY_F5, ui::DomCode::F5, ui::EF_NONE, ui::DomKey::F5}, + {ui::VKEY_MEDIA_LAUNCH_APP1, ui::DomCode::SELECT_TASK, ui::EF_NONE, + ui::DomKey::LAUNCH_MY_COMPUTER}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F5, ui::DomCode::F5, ui::EF_CONTROL_DOWN, ui::DomKey::F5}, + {ui::VKEY_MEDIA_LAUNCH_APP1, ui::DomCode::SELECT_TASK, + ui::EF_CONTROL_DOWN, ui::DomKey::LAUNCH_MY_COMPUTER}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F5, ui::DomCode::F5, ui::EF_ALT_DOWN, ui::DomKey::F5}, + {ui::VKEY_MEDIA_LAUNCH_APP1, ui::DomCode::SELECT_TASK, ui::EF_ALT_DOWN, + ui::DomKey::LAUNCH_MY_COMPUTER}}, + // F6 -> Brightness down + {ui::ET_KEY_PRESSED, + {ui::VKEY_F6, ui::DomCode::F6, ui::EF_NONE, ui::DomKey::F6}, + {ui::VKEY_BRIGHTNESS_DOWN, ui::DomCode::BRIGHTNESS_DOWN, ui::EF_NONE, + ui::DomKey::BRIGHTNESS_DOWN}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F6, ui::DomCode::F6, ui::EF_CONTROL_DOWN, ui::DomKey::F6}, + {ui::VKEY_BRIGHTNESS_DOWN, ui::DomCode::BRIGHTNESS_DOWN, + ui::EF_CONTROL_DOWN, ui::DomKey::BRIGHTNESS_DOWN}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F6, ui::DomCode::F6, ui::EF_ALT_DOWN, ui::DomKey::F6}, + {ui::VKEY_BRIGHTNESS_DOWN, ui::DomCode::BRIGHTNESS_DOWN, ui::EF_ALT_DOWN, + ui::DomKey::BRIGHTNESS_DOWN}}, + // F7 -> Brightness up + {ui::ET_KEY_PRESSED, + {ui::VKEY_F7, ui::DomCode::F7, ui::EF_NONE, ui::DomKey::F7}, + {ui::VKEY_BRIGHTNESS_UP, ui::DomCode::BRIGHTNESS_UP, ui::EF_NONE, + ui::DomKey::BRIGHTNESS_UP}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F7, ui::DomCode::F7, ui::EF_CONTROL_DOWN, ui::DomKey::F7}, + {ui::VKEY_BRIGHTNESS_UP, ui::DomCode::BRIGHTNESS_UP, ui::EF_CONTROL_DOWN, + ui::DomKey::BRIGHTNESS_UP}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F7, ui::DomCode::F7, ui::EF_ALT_DOWN, ui::DomKey::F7}, + {ui::VKEY_BRIGHTNESS_UP, ui::DomCode::BRIGHTNESS_UP, ui::EF_ALT_DOWN, + ui::DomKey::BRIGHTNESS_UP}}, + // F8 -> Volume Mute + {ui::ET_KEY_PRESSED, + {ui::VKEY_F8, ui::DomCode::F8, ui::EF_NONE, ui::DomKey::F8}, + {ui::VKEY_VOLUME_MUTE, ui::DomCode::VOLUME_MUTE, ui::EF_NONE, + ui::DomKey::AUDIO_VOLUME_MUTE}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F8, ui::DomCode::F8, ui::EF_CONTROL_DOWN, ui::DomKey::F8}, + {ui::VKEY_VOLUME_MUTE, ui::DomCode::VOLUME_MUTE, ui::EF_CONTROL_DOWN, + ui::DomKey::AUDIO_VOLUME_MUTE}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F8, ui::DomCode::F8, ui::EF_ALT_DOWN, ui::DomKey::F8}, + {ui::VKEY_VOLUME_MUTE, ui::DomCode::VOLUME_MUTE, ui::EF_ALT_DOWN, + ui::DomKey::AUDIO_VOLUME_MUTE}}, + // F9 -> Volume Down + {ui::ET_KEY_PRESSED, + {ui::VKEY_F9, ui::DomCode::F9, ui::EF_NONE, ui::DomKey::F9}, + {ui::VKEY_VOLUME_DOWN, ui::DomCode::VOLUME_DOWN, ui::EF_NONE, + ui::DomKey::AUDIO_VOLUME_DOWN}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F9, ui::DomCode::F9, ui::EF_CONTROL_DOWN, ui::DomKey::F9}, + {ui::VKEY_VOLUME_DOWN, ui::DomCode::VOLUME_DOWN, ui::EF_CONTROL_DOWN, + ui::DomKey::AUDIO_VOLUME_DOWN}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F9, ui::DomCode::F9, ui::EF_ALT_DOWN, ui::DomKey::F9}, + {ui::VKEY_VOLUME_DOWN, ui::DomCode::VOLUME_DOWN, ui::EF_ALT_DOWN, + ui::DomKey::AUDIO_VOLUME_DOWN}}, + // F10 -> Volume Up + {ui::ET_KEY_PRESSED, + {ui::VKEY_F10, ui::DomCode::F10, ui::EF_NONE, ui::DomKey::F10}, + {ui::VKEY_VOLUME_UP, ui::DomCode::VOLUME_UP, ui::EF_NONE, + ui::DomKey::AUDIO_VOLUME_UP}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F10, ui::DomCode::F10, ui::EF_CONTROL_DOWN, ui::DomKey::F10}, + {ui::VKEY_VOLUME_UP, ui::DomCode::VOLUME_UP, ui::EF_CONTROL_DOWN, + ui::DomKey::AUDIO_VOLUME_UP}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F10, ui::DomCode::F10, ui::EF_ALT_DOWN, ui::DomKey::F10}, + {ui::VKEY_VOLUME_UP, ui::DomCode::VOLUME_UP, ui::EF_ALT_DOWN, + ui::DomKey::AUDIO_VOLUME_UP}}, + // F11 -> F11 + {ui::ET_KEY_PRESSED, + {ui::VKEY_F11, ui::DomCode::F11, ui::EF_NONE, ui::DomKey::F11}, + {ui::VKEY_F11, ui::DomCode::F11, ui::EF_NONE, ui::DomKey::F11}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F11, ui::DomCode::F11, ui::EF_CONTROL_DOWN, ui::DomKey::F11}, + {ui::VKEY_F11, ui::DomCode::F11, ui::EF_CONTROL_DOWN, ui::DomKey::F11}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F11, ui::DomCode::F11, ui::EF_ALT_DOWN, ui::DomKey::F11}, + {ui::VKEY_F11, ui::DomCode::F11, ui::EF_ALT_DOWN, ui::DomKey::F11}}, + // F12 -> F12 + {ui::ET_KEY_PRESSED, + {ui::VKEY_F12, ui::DomCode::F12, ui::EF_NONE, ui::DomKey::F12}, + {ui::VKEY_F12, ui::DomCode::F12, ui::EF_NONE, ui::DomKey::F12}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F12, ui::DomCode::F12, ui::EF_CONTROL_DOWN, ui::DomKey::F12}, + {ui::VKEY_F12, ui::DomCode::F12, ui::EF_CONTROL_DOWN, ui::DomKey::F12}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F12, ui::DomCode::F12, ui::EF_ALT_DOWN, ui::DomKey::F12}, + {ui::VKEY_F12, ui::DomCode::F12, ui::EF_ALT_DOWN, ui::DomKey::F12}}, + }); +} + +TEST_F(EventRewriterTest, TestRewriteFunctionKeysCustomLayoutsFKeyUnchanged) { + chromeos::Preferences::RegisterProfilePrefs(prefs()->registry()); + + // On devices with custom layouts, the F-Keys are never remapped. + TestChromeCustomLayoutKeyboardVariants({ + // F1-> F1 + {ui::ET_KEY_PRESSED, + {ui::VKEY_F1, ui::DomCode::F1, ui::EF_NONE, ui::DomKey::F1}, + {ui::VKEY_F1, ui::DomCode::F1, ui::EF_NONE, ui::DomKey::F1}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F1, ui::DomCode::F1, ui::EF_CONTROL_DOWN, ui::DomKey::F1}, + {ui::VKEY_F1, ui::DomCode::F1, ui::EF_CONTROL_DOWN, ui::DomKey::F1}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F1, ui::DomCode::F1, ui::EF_ALT_DOWN, ui::DomKey::F1}, + {ui::VKEY_F1, ui::DomCode::F1, ui::EF_ALT_DOWN, ui::DomKey::F1}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F1, ui::DomCode::F1, ui::EF_COMMAND_DOWN, ui::DomKey::F1}, + {ui::VKEY_F1, ui::DomCode::F1, ui::EF_COMMAND_DOWN, ui::DomKey::F1}}, + // F2 -> F2 + {ui::ET_KEY_PRESSED, + {ui::VKEY_F2, ui::DomCode::F2, ui::EF_NONE, ui::DomKey::F2}, + {ui::VKEY_F2, ui::DomCode::F2, ui::EF_NONE, ui::DomKey::F2}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F2, ui::DomCode::F2, ui::EF_CONTROL_DOWN, ui::DomKey::F2}, + {ui::VKEY_F2, ui::DomCode::F2, ui::EF_CONTROL_DOWN, ui::DomKey::F2}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F2, ui::DomCode::F2, ui::EF_ALT_DOWN, ui::DomKey::F2}, + {ui::VKEY_F2, ui::DomCode::F2, ui::EF_ALT_DOWN, ui::DomKey::F2}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F2, ui::DomCode::F2, ui::EF_COMMAND_DOWN, ui::DomKey::F2}, + {ui::VKEY_F2, ui::DomCode::F2, ui::EF_COMMAND_DOWN, ui::DomKey::F2}}, + // F3 -> F3 + {ui::ET_KEY_PRESSED, + {ui::VKEY_F3, ui::DomCode::F3, ui::EF_NONE, ui::DomKey::F3}, + {ui::VKEY_F3, ui::DomCode::F3, ui::EF_NONE, ui::DomKey::F3}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F3, ui::DomCode::F3, ui::EF_CONTROL_DOWN, ui::DomKey::F3}, + {ui::VKEY_F3, ui::DomCode::F3, ui::EF_CONTROL_DOWN, ui::DomKey::F3}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F3, ui::DomCode::F3, ui::EF_ALT_DOWN, ui::DomKey::F3}, + {ui::VKEY_F3, ui::DomCode::F3, ui::EF_ALT_DOWN, ui::DomKey::F3}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F3, ui::DomCode::F3, ui::EF_COMMAND_DOWN, ui::DomKey::F3}, + {ui::VKEY_F3, ui::DomCode::F3, ui::EF_COMMAND_DOWN, ui::DomKey::F3}}, + // F4 -> F4 + {ui::ET_KEY_PRESSED, + {ui::VKEY_F4, ui::DomCode::F4, ui::EF_NONE, ui::DomKey::F4}, + {ui::VKEY_F4, ui::DomCode::F4, ui::EF_NONE, ui::DomKey::F4}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F4, ui::DomCode::F4, ui::EF_CONTROL_DOWN, ui::DomKey::F4}, + {ui::VKEY_F4, ui::DomCode::F4, ui::EF_CONTROL_DOWN, ui::DomKey::F4}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F4, ui::DomCode::F4, ui::EF_ALT_DOWN, ui::DomKey::F4}, + {ui::VKEY_F4, ui::DomCode::F4, ui::EF_ALT_DOWN, ui::DomKey::F4}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F4, ui::DomCode::F4, ui::EF_COMMAND_DOWN, ui::DomKey::F4}, + {ui::VKEY_F4, ui::DomCode::F4, ui::EF_COMMAND_DOWN, ui::DomKey::F4}}, + // F5 -> F5 + {ui::ET_KEY_PRESSED, + {ui::VKEY_F5, ui::DomCode::F5, ui::EF_NONE, ui::DomKey::F5}, + {ui::VKEY_F5, ui::DomCode::F5, ui::EF_NONE, ui::DomKey::F5}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F5, ui::DomCode::F5, ui::EF_CONTROL_DOWN, ui::DomKey::F5}, + {ui::VKEY_F5, ui::DomCode::F5, ui::EF_CONTROL_DOWN, ui::DomKey::F5}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F5, ui::DomCode::F5, ui::EF_ALT_DOWN, ui::DomKey::F5}, + {ui::VKEY_F5, ui::DomCode::F5, ui::EF_ALT_DOWN, ui::DomKey::F5}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F5, ui::DomCode::F5, ui::EF_COMMAND_DOWN, ui::DomKey::F5}, + {ui::VKEY_F5, ui::DomCode::F5, ui::EF_COMMAND_DOWN, ui::DomKey::F5}}, + // F6 -> F6 + {ui::ET_KEY_PRESSED, + {ui::VKEY_F6, ui::DomCode::F6, ui::EF_NONE, ui::DomKey::F6}, + {ui::VKEY_F6, ui::DomCode::F6, ui::EF_NONE, ui::DomKey::F6}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F6, ui::DomCode::F6, ui::EF_CONTROL_DOWN, ui::DomKey::F6}, + {ui::VKEY_F6, ui::DomCode::F6, ui::EF_CONTROL_DOWN, ui::DomKey::F6}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F6, ui::DomCode::F6, ui::EF_ALT_DOWN, ui::DomKey::F6}, + {ui::VKEY_F6, ui::DomCode::F6, ui::EF_ALT_DOWN, ui::DomKey::F6}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F6, ui::DomCode::F6, ui::EF_COMMAND_DOWN, ui::DomKey::F6}, + {ui::VKEY_F6, ui::DomCode::F6, ui::EF_COMMAND_DOWN, ui::DomKey::F6}}, + // F7 -> F7 + {ui::ET_KEY_PRESSED, + {ui::VKEY_F7, ui::DomCode::F7, ui::EF_NONE, ui::DomKey::F7}, + {ui::VKEY_F7, ui::DomCode::F7, ui::EF_NONE, ui::DomKey::F7}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F7, ui::DomCode::F7, ui::EF_CONTROL_DOWN, ui::DomKey::F7}, + {ui::VKEY_F7, ui::DomCode::F7, ui::EF_CONTROL_DOWN, ui::DomKey::F7}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F7, ui::DomCode::F7, ui::EF_ALT_DOWN, ui::DomKey::F7}, + {ui::VKEY_F7, ui::DomCode::F7, ui::EF_ALT_DOWN, ui::DomKey::F7}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F7, ui::DomCode::F7, ui::EF_COMMAND_DOWN, ui::DomKey::F7}, + {ui::VKEY_F7, ui::DomCode::F7, ui::EF_COMMAND_DOWN, ui::DomKey::F7}}, + // F8 -> F8 + {ui::ET_KEY_PRESSED, + {ui::VKEY_F8, ui::DomCode::F8, ui::EF_NONE, ui::DomKey::F8}, + {ui::VKEY_F8, ui::DomCode::F8, ui::EF_NONE, ui::DomKey::F8}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F8, ui::DomCode::F8, ui::EF_CONTROL_DOWN, ui::DomKey::F8}, + {ui::VKEY_F8, ui::DomCode::F8, ui::EF_CONTROL_DOWN, ui::DomKey::F8}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F8, ui::DomCode::F8, ui::EF_ALT_DOWN, ui::DomKey::F8}, + {ui::VKEY_F8, ui::DomCode::F8, ui::EF_ALT_DOWN, ui::DomKey::F8}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F8, ui::DomCode::F8, ui::EF_COMMAND_DOWN, ui::DomKey::F8}, + {ui::VKEY_F8, ui::DomCode::F8, ui::EF_COMMAND_DOWN, ui::DomKey::F8}}, + // F9 -> F9 + {ui::ET_KEY_PRESSED, + {ui::VKEY_F9, ui::DomCode::F9, ui::EF_NONE, ui::DomKey::F9}, + {ui::VKEY_F9, ui::DomCode::F9, ui::EF_NONE, ui::DomKey::F9}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F9, ui::DomCode::F9, ui::EF_CONTROL_DOWN, ui::DomKey::F9}, + {ui::VKEY_F9, ui::DomCode::F9, ui::EF_CONTROL_DOWN, ui::DomKey::F9}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F9, ui::DomCode::F9, ui::EF_ALT_DOWN, ui::DomKey::F9}, + {ui::VKEY_F9, ui::DomCode::F9, ui::EF_ALT_DOWN, ui::DomKey::F9}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F9, ui::DomCode::F9, ui::EF_COMMAND_DOWN, ui::DomKey::F9}, + {ui::VKEY_F9, ui::DomCode::F9, ui::EF_COMMAND_DOWN, ui::DomKey::F9}}, + // F10 -> F10 + {ui::ET_KEY_PRESSED, + {ui::VKEY_F10, ui::DomCode::F10, ui::EF_NONE, ui::DomKey::F10}, + {ui::VKEY_F10, ui::DomCode::F10, ui::EF_NONE, ui::DomKey::F10}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F10, ui::DomCode::F10, ui::EF_CONTROL_DOWN, ui::DomKey::F10}, + {ui::VKEY_F10, ui::DomCode::F10, ui::EF_CONTROL_DOWN, ui::DomKey::F10}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F10, ui::DomCode::F10, ui::EF_ALT_DOWN, ui::DomKey::F10}, + {ui::VKEY_F10, ui::DomCode::F10, ui::EF_ALT_DOWN, ui::DomKey::F10}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F10, ui::DomCode::F10, ui::EF_COMMAND_DOWN, ui::DomKey::F10}, + {ui::VKEY_F10, ui::DomCode::F10, ui::EF_COMMAND_DOWN, ui::DomKey::F10}}, + // F11 -> F11 + {ui::ET_KEY_PRESSED, + {ui::VKEY_F11, ui::DomCode::F11, ui::EF_NONE, ui::DomKey::F11}, + {ui::VKEY_F11, ui::DomCode::F11, ui::EF_NONE, ui::DomKey::F11}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F11, ui::DomCode::F11, ui::EF_CONTROL_DOWN, ui::DomKey::F11}, + {ui::VKEY_F11, ui::DomCode::F11, ui::EF_CONTROL_DOWN, ui::DomKey::F11}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F11, ui::DomCode::F11, ui::EF_ALT_DOWN, ui::DomKey::F11}, + {ui::VKEY_F11, ui::DomCode::F11, ui::EF_ALT_DOWN, ui::DomKey::F11}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F11, ui::DomCode::F11, ui::EF_COMMAND_DOWN, ui::DomKey::F11}, + {ui::VKEY_F11, ui::DomCode::F11, ui::EF_COMMAND_DOWN, ui::DomKey::F11}}, + // F12 -> F12 + {ui::ET_KEY_PRESSED, + {ui::VKEY_F12, ui::DomCode::F12, ui::EF_NONE, ui::DomKey::F12}, + {ui::VKEY_F12, ui::DomCode::F12, ui::EF_NONE, ui::DomKey::F12}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F12, ui::DomCode::F12, ui::EF_CONTROL_DOWN, ui::DomKey::F12}, + {ui::VKEY_F12, ui::DomCode::F12, ui::EF_CONTROL_DOWN, ui::DomKey::F12}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F12, ui::DomCode::F12, ui::EF_ALT_DOWN, ui::DomKey::F12}, + {ui::VKEY_F12, ui::DomCode::F12, ui::EF_ALT_DOWN, ui::DomKey::F12}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F12, ui::DomCode::F12, ui::EF_COMMAND_DOWN, ui::DomKey::F12}, + {ui::VKEY_F12, ui::DomCode::F12, ui::EF_COMMAND_DOWN, ui::DomKey::F12}}, + // F13 -> F13 + {ui::ET_KEY_PRESSED, + {ui::VKEY_F13, ui::DomCode::F13, ui::EF_NONE, ui::DomKey::F13}, + {ui::VKEY_F13, ui::DomCode::F13, ui::EF_NONE, ui::DomKey::F13}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F13, ui::DomCode::F13, ui::EF_CONTROL_DOWN, ui::DomKey::F13}, + {ui::VKEY_F13, ui::DomCode::F13, ui::EF_CONTROL_DOWN, ui::DomKey::F13}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F13, ui::DomCode::F13, ui::EF_ALT_DOWN, ui::DomKey::F13}, + {ui::VKEY_F13, ui::DomCode::F13, ui::EF_ALT_DOWN, ui::DomKey::F13}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F13, ui::DomCode::F13, ui::EF_COMMAND_DOWN, ui::DomKey::F13}, + {ui::VKEY_F13, ui::DomCode::F13, ui::EF_COMMAND_DOWN, ui::DomKey::F13}}, + // F14 -> F14 + {ui::ET_KEY_PRESSED, + {ui::VKEY_F14, ui::DomCode::F14, ui::EF_NONE, ui::DomKey::F14}, + {ui::VKEY_F14, ui::DomCode::F14, ui::EF_NONE, ui::DomKey::F14}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F14, ui::DomCode::F14, ui::EF_CONTROL_DOWN, ui::DomKey::F14}, + {ui::VKEY_F14, ui::DomCode::F14, ui::EF_CONTROL_DOWN, ui::DomKey::F14}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F14, ui::DomCode::F14, ui::EF_ALT_DOWN, ui::DomKey::F14}, + {ui::VKEY_F14, ui::DomCode::F14, ui::EF_ALT_DOWN, ui::DomKey::F14}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F14, ui::DomCode::F14, ui::EF_COMMAND_DOWN, ui::DomKey::F14}, + {ui::VKEY_F14, ui::DomCode::F14, ui::EF_COMMAND_DOWN, ui::DomKey::F14}}, + // F15 -> F15 + {ui::ET_KEY_PRESSED, + {ui::VKEY_F15, ui::DomCode::F15, ui::EF_NONE, ui::DomKey::F15}, + {ui::VKEY_F15, ui::DomCode::F15, ui::EF_NONE, ui::DomKey::F15}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F15, ui::DomCode::F15, ui::EF_CONTROL_DOWN, ui::DomKey::F15}, + {ui::VKEY_F15, ui::DomCode::F15, ui::EF_CONTROL_DOWN, ui::DomKey::F15}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F15, ui::DomCode::F15, ui::EF_ALT_DOWN, ui::DomKey::F15}, + {ui::VKEY_F15, ui::DomCode::F15, ui::EF_ALT_DOWN, ui::DomKey::F15}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_F15, ui::DomCode::F15, ui::EF_COMMAND_DOWN, ui::DomKey::F15}, + {ui::VKEY_F15, ui::DomCode::F15, ui::EF_COMMAND_DOWN, ui::DomKey::F15}}, + }); +} + +TEST_F(EventRewriterTest, TestRewriteFunctionKeysCustomLayoutsActionUnchanged) { + chromeos::Preferences::RegisterProfilePrefs(prefs()->registry()); + + // An action key on these devices is one where the scan code matches an entry + // in the layout map. It doesn't matter what the action is, as long the + // search key isn't pressed it will pass through unchanged. + const std::string layout = "a1 a2 a3"; + TestKeyboard("Internal Custom Layout Keyboard", layout, + ui::INPUT_DEVICE_INTERNAL, /*has_custom_top_row=*/true, + { + {ui::ET_KEY_PRESSED, + {ui::VKEY_BROWSER_REFRESH, ui::DomCode::BROWSER_REFRESH, + ui::EF_NONE, ui::DomKey::BROWSER_REFRESH, 0xa1}, + {ui::VKEY_BROWSER_REFRESH, ui::DomCode::BROWSER_REFRESH, + ui::EF_NONE, ui::DomKey::BROWSER_REFRESH, 0xa1}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_VOLUME_UP, ui::DomCode::VOLUME_UP, ui::EF_NONE, + ui::DomKey::AUDIO_VOLUME_UP, 0xa2}, + {ui::VKEY_VOLUME_UP, ui::DomCode::VOLUME_UP, ui::EF_NONE, + ui::DomKey::AUDIO_VOLUME_UP, 0xa2}}, + {ui::ET_KEY_PRESSED, + {ui::VKEY_VOLUME_DOWN, ui::DomCode::VOLUME_DOWN, + ui::EF_NONE, ui::DomKey::AUDIO_VOLUME_DOWN, 0xa3}, + {ui::VKEY_VOLUME_DOWN, ui::DomCode::VOLUME_DOWN, + ui::EF_NONE, ui::DomKey::AUDIO_VOLUME_DOWN, 0xa3}}, + }); +} + +TEST_F(EventRewriterTest, TestRewriteFunctionKeysCustomLayouts) { + chromeos::Preferences::RegisterProfilePrefs(prefs()->registry()); + + // On devices with custom layouts, scan codes that match the layout + // map get mapped to F-Keys based only on the scan code. The search + // key also gets treated as unpressed in the remapped event. + const std::string layout = "a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af"; + TestKeyboard( + "Internal Custom Layout Keyboard", layout, ui::INPUT_DEVICE_INTERNAL, + /*has_custom_top_row=*/true, + { + // Action -> F1 + {ui::ET_KEY_PRESSED, + {ui::VKEY_UNKNOWN, ui::DomCode::NONE, ui::EF_COMMAND_DOWN, + ui::DomKey::NONE, 0xa1}, + {ui::VKEY_F1, ui::DomCode::F1, ui::EF_NONE, ui::DomKey::F1, 0xa1}}, + // Action -> F2 + {ui::ET_KEY_PRESSED, + {ui::VKEY_UNKNOWN, ui::DomCode::NONE, ui::EF_COMMAND_DOWN, + ui::DomKey::NONE, 0xa2}, + {ui::VKEY_F2, ui::DomCode::F2, ui::EF_NONE, ui::DomKey::F2, 0xa2}}, + // Action -> F3 + {ui::ET_KEY_PRESSED, + {ui::VKEY_UNKNOWN, ui::DomCode::NONE, ui::EF_COMMAND_DOWN, + ui::DomKey::NONE, 0xa3}, + {ui::VKEY_F3, ui::DomCode::F3, ui::EF_NONE, ui::DomKey::F3, 0xa3}}, + // Action -> F4 + {ui::ET_KEY_PRESSED, + {ui::VKEY_UNKNOWN, ui::DomCode::NONE, ui::EF_COMMAND_DOWN, + ui::DomKey::NONE, 0xa4}, + {ui::VKEY_F4, ui::DomCode::F4, ui::EF_NONE, ui::DomKey::F4, 0xa4}}, + // Action -> F5 + {ui::ET_KEY_PRESSED, + {ui::VKEY_UNKNOWN, ui::DomCode::NONE, ui::EF_COMMAND_DOWN, + ui::DomKey::NONE, 0xa5}, + {ui::VKEY_F5, ui::DomCode::F5, ui::EF_NONE, ui::DomKey::F5, 0xa5}}, + // Action -> F6 + {ui::ET_KEY_PRESSED, + {ui::VKEY_UNKNOWN, ui::DomCode::NONE, ui::EF_COMMAND_DOWN, + ui::DomKey::NONE, 0xa6}, + {ui::VKEY_F6, ui::DomCode::F6, ui::EF_NONE, ui::DomKey::F6, 0xa6}}, + // Action -> F7 + {ui::ET_KEY_PRESSED, + {ui::VKEY_UNKNOWN, ui::DomCode::NONE, ui::EF_COMMAND_DOWN, + ui::DomKey::NONE, 0xa7}, + {ui::VKEY_F7, ui::DomCode::F7, ui::EF_NONE, ui::DomKey::F7, 0xa7}}, + // Action -> F8 + {ui::ET_KEY_PRESSED, + {ui::VKEY_UNKNOWN, ui::DomCode::NONE, ui::EF_COMMAND_DOWN, + ui::DomKey::NONE, 0xa8}, + {ui::VKEY_F8, ui::DomCode::F8, ui::EF_NONE, ui::DomKey::F8, 0xa8}}, + // Action -> F9 + {ui::ET_KEY_PRESSED, + {ui::VKEY_UNKNOWN, ui::DomCode::NONE, ui::EF_COMMAND_DOWN, + ui::DomKey::NONE, 0xa9}, + {ui::VKEY_F9, ui::DomCode::F9, ui::EF_NONE, ui::DomKey::F9, 0xa9}}, + // Action -> F10 + {ui::ET_KEY_PRESSED, + {ui::VKEY_UNKNOWN, ui::DomCode::NONE, ui::EF_COMMAND_DOWN, + ui::DomKey::NONE, 0xaa}, + {ui::VKEY_F10, ui::DomCode::F10, ui::EF_NONE, ui::DomKey::F10, + 0xaa}}, + // Action -> F11 + {ui::ET_KEY_PRESSED, + {ui::VKEY_UNKNOWN, ui::DomCode::NONE, ui::EF_COMMAND_DOWN, + ui::DomKey::NONE, 0xab}, + {ui::VKEY_F11, ui::DomCode::F11, ui::EF_NONE, ui::DomKey::F11, + 0xab}}, + // Action -> F12 + {ui::ET_KEY_PRESSED, + {ui::VKEY_UNKNOWN, ui::DomCode::NONE, ui::EF_COMMAND_DOWN, + ui::DomKey::NONE, 0xac}, + {ui::VKEY_F12, ui::DomCode::F12, ui::EF_NONE, ui::DomKey::F12, + 0xac}}, + // Action -> F13 + {ui::ET_KEY_PRESSED, + {ui::VKEY_UNKNOWN, ui::DomCode::NONE, ui::EF_COMMAND_DOWN, + ui::DomKey::NONE, 0xad}, + {ui::VKEY_F13, ui::DomCode::F13, ui::EF_NONE, ui::DomKey::F13, + 0xad}}, + // Action -> F14 + {ui::ET_KEY_PRESSED, + {ui::VKEY_UNKNOWN, ui::DomCode::NONE, ui::EF_COMMAND_DOWN, + ui::DomKey::NONE, 0xae}, + {ui::VKEY_F14, ui::DomCode::F14, ui::EF_NONE, ui::DomKey::F14, + 0xae}}, + // Action -> F15 + {ui::ET_KEY_PRESSED, + {ui::VKEY_UNKNOWN, ui::DomCode::NONE, ui::EF_COMMAND_DOWN, + ui::DomKey::NONE, 0xaf}, + {ui::VKEY_F15, ui::DomCode::F15, ui::EF_NONE, ui::DomKey::F15, + 0xaf}}, + }); +} + TEST_F(EventRewriterTest, TestRewriteFunctionKeysLayout2) { chromeos::Preferences::RegisterProfilePrefs(prefs()->registry()); TestKeyboard( "Internal Keyboard", kKbdTopRowLayout2Tag, ui::INPUT_DEVICE_INTERNAL, + /*has_custom_top_row=*/false, { // F1 -> Back {ui::ET_KEY_PRESSED, @@ -2760,7 +3191,8 @@ }); TestKeyboard("Internal Keyboard", kKbdTopRowLayout2Tag, - ui::INPUT_DEVICE_INTERNAL, layout2_tests); + ui::INPUT_DEVICE_INTERNAL, /*has_custom_top_row=*/false, + layout2_tests); } TEST_F(EventRewriterTest, TestRewriteExtendedKeysWithSearchRemapped) { @@ -2977,10 +3409,10 @@ ASSERT_FALSE(details.dispatcher_destroyed); PopEvents(&events); EXPECT_EQ(1u, events.size()); - EXPECT_EQ( - GetExpectedResultAsString(ui::ET_KEY_PRESSED, ui::VKEY_F1, - ui::DomCode::F1, ui::EF_NONE, ui::DomKey::F1), - GetKeyEventAsString(*static_cast<ui::KeyEvent*>(events[0].get()))); + EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED, ui::VKEY_F1, + ui::DomCode::F1, ui::EF_NONE, + ui::DomKey::F1, kNoScanCode), + GetKeyEventAsString(*static_cast<ui::KeyEvent*>(events[0].get()))); // If the pref isn't set when an event is sent to a regular window, F1 is // rewritten to the back key. @@ -2991,7 +3423,7 @@ EXPECT_EQ(1u, events.size()); EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED, ui::VKEY_BROWSER_BACK, ui::DomCode::BROWSER_BACK, ui::EF_NONE, - ui::DomKey::BROWSER_BACK), + ui::DomKey::BROWSER_BACK, kNoScanCode), GetKeyEventAsString(*static_cast<ui::KeyEvent*>(events[0].get()))); }
diff --git a/chrome/browser/chromeos/lacros/lacros_loader.cc b/chrome/browser/chromeos/lacros/lacros_loader.cc index c1784cbf1..4f06377 100644 --- a/chrome/browser/chromeos/lacros/lacros_loader.cc +++ b/chrome/browser/chromeos/lacros/lacros_loader.cc
@@ -7,6 +7,7 @@ #include <utility> #include "base/bind.h" +#include "base/command_line.h" #include "base/files/file_util.h" #include "base/logging.h" #include "base/process/launch.h" @@ -15,7 +16,9 @@ #include "chrome/browser/chromeos/lacros/lacros_util.h" #include "chrome/browser/component_updater/cros_component_manager.h" #include "chromeos/constants/chromeos_features.h" +#include "chromeos/constants/chromeos_switches.h" #include "chromeos/dbus/upstart/upstart_client.h" +#include "google_apis/google_api_keys.h" using component_updater::CrOSComponentManager; @@ -64,9 +67,20 @@ if (!lacros_util::IsLacrosAllowed()) return; - if (chromeos::features::IsLacrosComponentUpdaterEnabled()) { + if (chromeos::features::IsLacrosSupportEnabled()) { // TODO(crbug.com/1078607): Remove non-error logging from this class. LOG(WARNING) << "Starting lacros component load."; + + // If the user has specified a path for the lacros-chrome binary, use that + // rather than component manager. + base::FilePath lacros_chrome_path = + base::CommandLine::ForCurrentProcess()->GetSwitchValuePath( + chromeos::switches::kLacrosChromePath); + if (!lacros_chrome_path.empty()) { + OnLoadComplete(CrOSComponentManager::Error::NONE, lacros_chrome_path); + return; + } + cros_component_manager_->Load(kLacrosComponentName, CrOSComponentManager::MountPolicy::kMount, CrOSComponentManager::UpdatePolicy::kForce, @@ -92,22 +106,31 @@ if (!lacros_util::IsLacrosAllowed()) return; + // TODO(jamescook): Provide a switch to override the lacros-chrome path for + // developers. std::string chrome_path; - if (chromeos::features::IsLacrosComponentUpdaterEnabled()) { - if (lacros_path_.empty()) { - LOG(WARNING) << "lacros component image not yet available"; - return; - } - chrome_path = lacros_path_.MaybeAsASCII() + "/chrome"; - } else { - // This is the default path on eve-lacros images. - chrome_path = "/usr/local/lacros/chrome"; + if (lacros_path_.empty()) { + LOG(WARNING) << "lacros component image not yet available"; + return; } + chrome_path = lacros_path_.MaybeAsASCII() + "/chrome"; LOG(WARNING) << "Launching lacros-chrome at " << chrome_path; base::LaunchOptions options; options.environment["EGL_PLATFORM"] = "surfaceless"; options.environment["XDG_RUNTIME_DIR"] = "/run/chrome"; + + std::string api_key; + if (google_apis::HasAPIKeyConfigured()) + api_key = google_apis::GetAPIKey(); + else + api_key = google_apis::GetNonStableAPIKey(); + options.environment["GOOGLE_API_KEY"] = api_key; + options.environment["GOOGLE_DEFAULT_CLIENT_ID"] = + google_apis::GetOAuth2ClientID(google_apis::CLIENT_MAIN); + options.environment["GOOGLE_DEFAULT_CLIENT_SECRET"] = + google_apis::GetOAuth2ClientSecret(google_apis::CLIENT_MAIN); + options.kill_on_parent_death = true; std::vector<std::string> argv = {
diff --git a/chrome/browser/chromeos/login/existing_user_controller.cc b/chrome/browser/chromeos/login/existing_user_controller.cc index 5f392547..f979e8c 100644 --- a/chrome/browser/chromeos/login/existing_user_controller.cc +++ b/chrome/browser/chromeos/login/existing_user_controller.cc
@@ -65,6 +65,7 @@ #include "chrome/browser/chromeos/system/device_disabling_manager.h" #include "chrome/browser/net/system_network_context_manager.h" #include "chrome/browser/notifications/system_notification_helper.h" +#include "chrome/browser/policy/profile_policy_connector.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/signin/chrome_device_id_helper.h" @@ -1195,12 +1196,16 @@ profile_prepared_ = true; + chromeos::UserContext user_context = + UserContext(*chromeos::ProfileHelper::Get()->GetUserByProfile(profile)); + auto* profile_connector = profile->GetProfilePolicyConnector(); + user_manager::known_user::SetIsManaged(user_context.GetAccountId(), + profile_connector->IsManaged()); + // Inform |auth_status_consumer_| about successful login. // TODO(nkostylev): Pass UserContext back crbug.com/424550 if (auth_status_consumer_) { - const user_manager::User* const user = - chromeos::ProfileHelper::Get()->GetUserByProfile(profile); - auth_status_consumer_->OnAuthSuccess(UserContext(*user)); + auth_status_consumer_->OnAuthSuccess(user_context); } }
diff --git a/chrome/browser/chromeos/login/login_ui_browsertest.cc b/chrome/browser/chromeos/login/login_ui_browsertest.cc index 1393111..0f49a74 100644 --- a/chrome/browser/chromeos/login/login_ui_browsertest.cc +++ b/chrome/browser/chromeos/login/login_ui_browsertest.cc
@@ -164,6 +164,18 @@ public: DisplayPasswordButtonTest() : LoginManagerTest() {} + void LoginAndLock(const LoginManagerMixin::TestUserInfo& test_user) { + chromeos::WizardController::SkipPostLoginScreensForTesting(); + + auto context = LoginManagerMixin::CreateDefaultUserContext(test_user); + login_manager_mixin_.LoginAndWaitForActiveSession(context); + + ScreenLockerTester screen_locker_tester; + screen_locker_tester.Lock(); + + EXPECT_TRUE(ash::LoginScreenTestApi::FocusUser(test_user.account_id)); + } + void SetDisplayPasswordButtonEnabledLoginAndLock( bool display_password_button_enabled) { // Sets the feature by user policy @@ -175,15 +187,7 @@ ->set_value(display_password_button_enabled); } - chromeos::WizardController::SkipPostLoginScreensForTesting(); - - auto context = LoginManagerMixin::CreateDefaultUserContext(test_user_); - login_manager_mixin_.LoginAndWaitForActiveSession(context); - - ScreenLockerTester screen_locker_tester; - screen_locker_tester.Lock(); - - EXPECT_TRUE(ash::LoginScreenTestApi::FocusUser(test_user_.account_id)); + LoginAndLock(managed_user_); } void SetUpInProcessBrowserTestFixture() override { @@ -194,45 +198,72 @@ UserSelectionScreen::SetSkipForceOnlineSigninForTesting(true); } + void TearDownInProcessBrowserTestFixture() override { + LoginManagerTest::TearDownInProcessBrowserTestFixture(); + UserSelectionScreen::SetSkipForceOnlineSigninForTesting(false); + } + protected: - const LoginManagerMixin::TestUserInfo test_user_{ - AccountId::FromUserEmailGaiaId("user@example.com", "1111")}; - UserPolicyMixin user_policy_mixin_{&mixin_host_, test_user_.account_id}; + const LoginManagerMixin::TestUserInfo not_managed_user_{ + AccountId::FromUserEmailGaiaId("user@gmail.com", "1111")}; + const LoginManagerMixin::TestUserInfo managed_user_{ + AccountId::FromUserEmailGaiaId("user@example.com", "22222")}; + UserPolicyMixin user_policy_mixin_{&mixin_host_, managed_user_.account_id}; LoginManagerMixin login_manager_mixin_{&mixin_host_}; }; -// Check if the display password button feature is disabled on the lock screen -// after login into a session and locking the screen. +// Check if the display password button is shown on the lock screen after having +// logged into a session and having locked the screen for an unmanaged user. IN_PROC_BROWSER_TEST_F(DisplayPasswordButtonTest, - PRE_LoginUIDisplayPasswordButtonDisabled) { + PRE_DisplayPasswordButtonShownUnmanagedUser) { + LoginAndLock(not_managed_user_); + EXPECT_TRUE(ash::LoginScreenTestApi::IsDisplayPasswordButtonShown( + not_managed_user_.account_id)); +} + +// Check if the display password button is shown on the login screen for an +// unmanaged user. +IN_PROC_BROWSER_TEST_F(DisplayPasswordButtonTest, + DisplayPasswordButtonShownUnmanagedUser) { + EXPECT_TRUE(ash::LoginScreenTestApi::FocusUser(not_managed_user_.account_id)); + EXPECT_TRUE(ash::LoginScreenTestApi::IsDisplayPasswordButtonShown( + not_managed_user_.account_id)); +} + +// Check if the display password button is hidden on the lock screen after +// having logged into a session and having locked the screen for a managed user. +IN_PROC_BROWSER_TEST_F(DisplayPasswordButtonTest, + PRE_DisplayPasswordButtonHiddenManagedUser) { SetDisplayPasswordButtonEnabledLoginAndLock(false); EXPECT_FALSE(ash::LoginScreenTestApi::IsDisplayPasswordButtonShown( - test_user_.account_id)); + managed_user_.account_id)); } -// Check if the display password button feature is disabled on the login screen. +// Check if the display password button is hidden on the login screen for a +// managed user. IN_PROC_BROWSER_TEST_F(DisplayPasswordButtonTest, - LoginUIDisplayPasswordButtonDisabled) { - EXPECT_TRUE(ash::LoginScreenTestApi::FocusUser(test_user_.account_id)); + DisplayPasswordButtonHiddenManagedUser) { + EXPECT_TRUE(ash::LoginScreenTestApi::FocusUser(managed_user_.account_id)); EXPECT_FALSE(ash::LoginScreenTestApi::IsDisplayPasswordButtonShown( - test_user_.account_id)); + managed_user_.account_id)); } -// Check if the display password button feature is enabled on the lock screen -// after login into a session and locking the screen. +// Check if the display password button is shown on the lock screen after having +// logged into a session and having locked the screen for a managed user. IN_PROC_BROWSER_TEST_F(DisplayPasswordButtonTest, - PRE_LoginUIDisplayPasswordButtonEnabled) { + PRE_DisplayPasswordButtonShownManagedUser) { SetDisplayPasswordButtonEnabledLoginAndLock(true); EXPECT_TRUE(ash::LoginScreenTestApi::IsDisplayPasswordButtonShown( - test_user_.account_id)); + managed_user_.account_id)); } -// Check if the display password button feature is enabled on the login screen. +// Check if the display password button is shown on the login screen for a +// managed user. IN_PROC_BROWSER_TEST_F(DisplayPasswordButtonTest, - LoginUIDisplayPasswordButtonEnabled) { - EXPECT_TRUE(ash::LoginScreenTestApi::FocusUser(test_user_.account_id)); + DisplayPasswordButtonShownManagedUser) { + EXPECT_TRUE(ash::LoginScreenTestApi::FocusUser(managed_user_.account_id)); EXPECT_TRUE(ash::LoginScreenTestApi::IsDisplayPasswordButtonShown( - test_user_.account_id)); + managed_user_.account_id)); } // Checks that system info is visible independent of the Oobe dialog state. @@ -248,4 +279,87 @@ EXPECT_TRUE(ash::LoginScreenTestApi::IsSystemInfoShown()); } +class UserManagementDisclosureTest : public LoginManagerTest { + public: + UserManagementDisclosureTest() : LoginManagerTest() {} + + void LoginAndLock(const LoginManagerMixin::TestUserInfo& test_user, + UserPolicyMixin* user_policy_mixin) { + if (user_policy_mixin) + user_policy_mixin->RequestPolicyUpdate(); + + chromeos::WizardController::SkipPostLoginScreensForTesting(); + + auto context = LoginManagerMixin::CreateDefaultUserContext(test_user); + login_manager_mixin_.LoginAndWaitForActiveSession(context); + + ScreenLockerTester screen_locker_tester; + screen_locker_tester.Lock(); + } + + void SetUpInProcessBrowserTestFixture() override { + LoginManagerTest::SetUpInProcessBrowserTestFixture(); + // Login as a managed user would save force-online-signin to true and + // invalidate the auth token into local state, which would prevent to focus + // during the second part of the test which happens in the login screen. + UserSelectionScreen::SetSkipForceOnlineSigninForTesting(true); + } + + void TearDownInProcessBrowserTestFixture() override { + LoginManagerTest::TearDownInProcessBrowserTestFixture(); + UserSelectionScreen::SetSkipForceOnlineSigninForTesting(false); + } + + protected: + const LoginManagerMixin::TestUserInfo not_managed_user{ + AccountId::FromUserEmailGaiaId("user@gmail.com", "1111")}; + const LoginManagerMixin::TestUserInfo managed_user{ + AccountId::FromUserEmailGaiaId("user@example.com", "11111")}; + UserPolicyMixin managed_user_policy_mixin_{&mixin_host_, + managed_user.account_id}; + LoginManagerMixin login_manager_mixin_{&mixin_host_}; +}; + +// Check if the user management disclosure is hidden on the lock screen after +// having logged an unmanaged user into a session and having locked the screen. +IN_PROC_BROWSER_TEST_F(UserManagementDisclosureTest, + PRE_EnterpriseIconInvisibleNotManagedUser) { + LoginAndLock(not_managed_user, nullptr); + EXPECT_FALSE( + ash::LoginScreenTestApi::IsManagedIconShown(not_managed_user.account_id)); + EXPECT_FALSE(ash::LoginScreenTestApi::IsManagedMessageInMenuShown( + not_managed_user.account_id)); +} + +// Check if the user management disclosure is shown on the login screen for an +// unmanaged user. +IN_PROC_BROWSER_TEST_F(UserManagementDisclosureTest, + EnterpriseIconInvisibleNotManagedUser) { + EXPECT_FALSE( + ash::LoginScreenTestApi::IsManagedIconShown(not_managed_user.account_id)); + EXPECT_FALSE(ash::LoginScreenTestApi::IsManagedMessageInMenuShown( + not_managed_user.account_id)); +} + +// Check if the user management disclosure is shown on the lock screen after +// having logged a managed user into a session and having locked the screen. +IN_PROC_BROWSER_TEST_F(UserManagementDisclosureTest, + PRE_EnterpriseIconVisibleManagedUser) { + LoginAndLock(managed_user, &managed_user_policy_mixin_); + EXPECT_TRUE( + ash::LoginScreenTestApi::IsManagedIconShown(managed_user.account_id)); + EXPECT_TRUE(ash::LoginScreenTestApi::IsManagedMessageInMenuShown( + managed_user.account_id)); +} + +// Check if the user management disclosure is shown on the login screen for a +// managed user. +IN_PROC_BROWSER_TEST_F(UserManagementDisclosureTest, + EnterpriseIconVisibleManagedUser) { + EXPECT_TRUE( + ash::LoginScreenTestApi::IsManagedIconShown(managed_user.account_id)); + EXPECT_TRUE(ash::LoginScreenTestApi::IsManagedMessageInMenuShown( + managed_user.account_id)); +} + } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/screens/user_selection_screen.cc b/chrome/browser/chromeos/login/screens/user_selection_screen.cc index 6379e0f..807e13ed 100644 --- a/chrome/browser/chromeos/login/screens/user_selection_screen.cc +++ b/chrome/browser/chromeos/login/screens/user_selection_screen.cc
@@ -56,6 +56,7 @@ #include "components/user_manager/known_user.h" #include "components/user_manager/user_manager.h" #include "components/user_manager/user_type.h" +#include "google_apis/gaia/gaia_auth_util.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" #include "ui/base/user_activity/user_activity_detector.h" @@ -930,6 +931,11 @@ user_info.can_remove = CanRemoveUser(user); user_info.fingerprint_state = GetInitialFingerprintState(user); user_info.show_pin_pad_for_password = false; + if (user_manager::known_user::GetIsManaged(user->GetAccountId()) && + user->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT) { + user_info.user_enterprise_domain = + gaia::ExtractDomainName(user->display_email()); + } chromeos::CrosSettings::Get()->GetBoolean( chromeos::kDeviceShowNumericKeyboardForPassword, &user_info.show_pin_pad_for_password); @@ -951,7 +957,7 @@ std::string domain; user_info.public_account_info.emplace(); if (GetEnterpriseDomain(&domain)) - user_info.public_account_info->enterprise_domain = domain; + user_info.public_account_info->device_enterprise_domain = domain; user_info.public_account_info->using_saml = user->using_saml();
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_pref_names.cc b/chrome/browser/chromeos/plugin_vm/plugin_vm_pref_names.cc index 5eedfb03..f9d54ef01 100644 --- a/chrome/browser/chromeos/plugin_vm/plugin_vm_pref_names.cc +++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_pref_names.cc
@@ -10,6 +10,9 @@ namespace plugin_vm { namespace prefs { +// A boolean preference indicating whether Plugin VM is allowed by the +// corresponding user policy. +const char kPluginVmAllowed[] = "plugin_vm.allowed"; // A dictionary preference used to store information about PluginVm image. // Stores a url for downloading PluginVm image and a SHA-256 hash for verifying // finished download. @@ -38,6 +41,7 @@ const char kEngagementPrefsPrefix[] = "plugin_vm.metrics"; void RegisterProfilePrefs(PrefRegistrySimple* registry) { + registry->RegisterBooleanPref(kPluginVmAllowed, false); registry->RegisterDictionaryPref(kPluginVmImage); registry->RegisterBooleanPref(kPluginVmImageExists, false);
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_pref_names.h b/chrome/browser/chromeos/plugin_vm/plugin_vm_pref_names.h index 184bd68..af6789c 100644 --- a/chrome/browser/chromeos/plugin_vm/plugin_vm_pref_names.h +++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_pref_names.h
@@ -10,6 +10,7 @@ namespace plugin_vm { namespace prefs { +extern const char kPluginVmAllowed[]; extern const char kPluginVmImage[]; extern const char kPluginVmImageExists[]; extern const char kPluginVmPrintersAllowed[];
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_test_helper.cc b/chrome/browser/chromeos/plugin_vm/plugin_vm_test_helper.cc index 30bb97c..df052c06 100644 --- a/chrome/browser/chromeos/plugin_vm/plugin_vm_test_helper.cc +++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_test_helper.cc
@@ -99,6 +99,8 @@ PluginVmTestHelper::~PluginVmTestHelper() = default; void PluginVmTestHelper::SetPolicyRequirementsToAllowPluginVm() { + testing_profile_->GetPrefs()->SetBoolean(plugin_vm::prefs::kPluginVmAllowed, + true); testing_profile_->ScopedCrosSettingsTestHelper()->SetBoolean( chromeos::kPluginVmAllowed, true); testing_profile_->ScopedCrosSettingsTestHelper()->SetString(
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_util.cc b/chrome/browser/chromeos/plugin_vm/plugin_vm_util.cc index a6ee5b0..78f4d1d 100644 --- a/chrome/browser/chromeos/plugin_vm/plugin_vm_util.cc +++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_util.cc
@@ -55,7 +55,8 @@ // * PluginVm feature should be enabled. // * Device should be enterprise enrolled: // * User should be affiliated. -// * PluginVmAllowed should be set. +// * PluginVmAllowed device policy should be set to true. +// * UserPluginVmAllowed user policy should be set to true. // * At least one of the following should be set: // * PluginVmLicenseKey policy. // * PluginVmUserId policy. @@ -93,7 +94,9 @@ chromeos::kPluginVmAllowed, &plugin_vm_allowed_for_device)) { return false; } - if (!plugin_vm_allowed_for_device) + bool plugin_vm_allowed_for_user = + profile->GetPrefs()->GetBoolean(plugin_vm::prefs::kPluginVmAllowed); + if (!plugin_vm_allowed_for_device || !plugin_vm_allowed_for_user) return false; if (GetPluginVmLicenseKey().empty() && GetPluginVmUserId().empty()) @@ -224,7 +227,13 @@ DCHECK(chromeos::CrosSettings::IsInitialized()); chromeos::CrosSettings* cros_settings = chromeos::CrosSettings::Get(); // Subscriptions are automatically removed when this object is destroyed. - allowed_subscription_ = cros_settings->AddSettingsObserver( + user_allowed_pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>(); + user_allowed_pref_change_registrar_->Init(profile->GetPrefs()); + user_allowed_pref_change_registrar_->Add( + plugin_vm::prefs::kPluginVmAllowed, + base::BindRepeating(&PluginVmPolicySubscription::OnPolicyChanged, + base::Unretained(this))); + device_allowed_subscription_ = cros_settings->AddSettingsObserver( chromeos::kPluginVmAllowed, base::BindRepeating(&PluginVmPolicySubscription::OnPolicyChanged, base::Unretained(this)));
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_util.h b/chrome/browser/chromeos/plugin_vm/plugin_vm_util.h index 60184a7..a2da2d97 100644 --- a/chrome/browser/chromeos/plugin_vm/plugin_vm_util.h +++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_util.h
@@ -122,8 +122,9 @@ // The user-provided callback method. PluginVmAllowedChanged callback_; + std::unique_ptr<PrefChangeRegistrar> user_allowed_pref_change_registrar_; std::unique_ptr<chromeos::CrosSettings::ObserverSubscription> - allowed_subscription_; + device_allowed_subscription_; std::unique_ptr<chromeos::CrosSettings::ObserverSubscription> license_subscription_; std::unique_ptr<base::CallbackList<void(void)>::Subscription>
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_util_unittest.cc b/chrome/browser/chromeos/plugin_vm/plugin_vm_util_unittest.cc index ff916816..1964ab93 100644 --- a/chrome/browser/chromeos/plugin_vm/plugin_vm_util_unittest.cc +++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_util_unittest.cc
@@ -116,6 +116,11 @@ EXPECT_CALL(*this, OnPolicyChanged(true)); testing_profile_->ScopedCrosSettingsTestHelper()->SetBoolean( chromeos::kPluginVmAllowed, true); + testing::Mock::VerifyAndClearExpectations(this); + + EXPECT_CALL(*this, OnPolicyChanged(false)); + testing_profile_->GetPrefs()->SetBoolean(plugin_vm::prefs::kPluginVmAllowed, + false); } TEST_F(PluginVmUtilTest, DriveLinkDetection) {
diff --git a/chrome/browser/chromeos/web_applications/help_app_integration_browsertest.cc b/chrome/browser/chromeos/web_applications/help_app_integration_browsertest.cc index fbd4bb6..aa85eb88 100644 --- a/chrome/browser/chromeos/web_applications/help_app_integration_browsertest.cc +++ b/chrome/browser/chromeos/web_applications/help_app_integration_browsertest.cc
@@ -12,6 +12,8 @@ #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/chromeos/web_applications/system_web_app_integration_test.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_window.h" #include "chrome/browser/web_applications/system_web_app_manager.h" #include "chrome/browser/web_applications/system_web_app_manager_browsertest.h" #include "chromeos/components/help_app_ui/url_constants.h" @@ -19,7 +21,10 @@ #include "chromeos/constants/chromeos_features.h" #include "content/public/test/browser_test.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/display/screen.h" #include "ui/display/types/display_constants.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/geometry/size.h" class HelpAppIntegrationTest : public SystemWebAppIntegrationTest { public: @@ -47,6 +52,25 @@ GetManager().GetAdditionalSearchTerms(web_app::SystemAppType::HELP)); } +// Test that the Help App has a minimum window size of 600x320. +IN_PROC_BROWSER_TEST_P(HelpAppIntegrationTest, HelpAppV2MinWindowSize) { + WaitForSystemAppInstallAndLaunch(web_app::SystemAppType::HELP); + auto app_id = LaunchParamsForApp(web_app::SystemAppType::HELP).app_id; + EXPECT_EQ(GetManager().GetMinimumWindowSize(app_id), gfx::Size(600, 320)); +} + +// Test that the Help App has a default size of 960x600 and is in the center of +// the screen. +IN_PROC_BROWSER_TEST_P(HelpAppIntegrationTest, HelpAppV2DefaultWindowBounds) { + auto* browser = + WaitForSystemAppInstallAndLaunch(web_app::SystemAppType::HELP); + gfx::Rect work_area = + display::Screen::GetScreen()->GetDisplayForNewWindows().work_area(); + int x = (work_area.width() - 960) / 2; + int y = (work_area.height() - 600) / 2; + EXPECT_EQ(browser->window()->GetBounds(), gfx::Rect(x, y, 960, 600)); +} + // Test that the Help App logs metric when launching the app using the // AppServiceProxy. IN_PROC_BROWSER_TEST_P(HelpAppIntegrationTest, HelpAppV2AppServiceMetrics) {
diff --git a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc index 03819b9..7084d70b 100644 --- a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc +++ b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc
@@ -411,6 +411,33 @@ ASSERT_EQ("success", ExecuteScriptInBackgroundPage(extension_id, script)); } + void UpdateEnabledRulesets( + const ExtensionId& extension_id, + const std::vector<std::string>& ruleset_ids_to_remove, + const std::vector<std::string>& ruleset_ids_to_add) { + static constexpr char kScript[] = R"( + chrome.declarativeNetRequest.updateEnabledRulesets($1, $2, () => { + window.domAutomationController.send(chrome.runtime.lastError ? + chrome.runtime.lastError.message : 'success'); + }); + )"; + + std::unique_ptr<base::Value> ids_to_remove = + ListBuilder() + .Append(ruleset_ids_to_remove.begin(), ruleset_ids_to_remove.end()) + .Build(); + std::unique_ptr<base::Value> ids_to_add = + ListBuilder() + .Append(ruleset_ids_to_add.begin(), ruleset_ids_to_add.end()) + .Build(); + + // A cast is necessary from ListValue to Value, else this fails to compile. + const std::string script = content::JsReplace( + kScript, static_cast<const base::Value&>(*ids_to_remove), + static_cast<const base::Value&>(*ids_to_add)); + ASSERT_EQ("success", ExecuteScriptInBackgroundPage(extension_id, script)); + } + void SetActionsAsBadgeText(const ExtensionId& extension_id, bool pref) { const char* pref_string = pref ? "true" : "false"; static constexpr char kSetActionCountAsBadgeTextScript[] = R"( @@ -3989,11 +4016,15 @@ ASSERT_NO_FATAL_FAILURE( AddDynamicRules(extension_id, {CreateMainFrameBlockRule("dynamic")})); + // Also update the set of enabled static rulesets. + ASSERT_NO_FATAL_FAILURE( + UpdateEnabledRulesets(extension_id, {"id1"}, {"id2", "id3"})); + CompositeMatcher* composite_matcher = ruleset_manager()->GetMatcherForExtension(extension_id); ASSERT_TRUE(composite_matcher); EXPECT_THAT(GetPublicRulesetIDs(*extension, *composite_matcher), - UnorderedElementsAre("id1", "id3", dnr_api::DYNAMIC_RULESET_ID)); + UnorderedElementsAre("id2", "id3", dnr_api::DYNAMIC_RULESET_ID)); // Also sanity check the extension prefs entry for the rulesets. ExtensionPrefs* prefs = ExtensionPrefs::Get(profile()); @@ -4013,6 +4044,13 @@ &checksum)); EXPECT_TRUE( prefs->GetDNRDynamicRulesetChecksum(extension_id, &dynamic_checksum_1)); + base::Optional<std::set<RulesetID>> enabled_static_rulesets = + prefs->GetDNREnabledStaticRulesets(extension_id); + ASSERT_TRUE(enabled_static_rulesets); + EXPECT_THAT( + *enabled_static_rulesets, + UnorderedElementsAre(RulesetID(kMinValidStaticRulesetID.value() + 1), + RulesetID(kMinValidStaticRulesetID.value() + 2))); std::vector<TestRulesetInfo> new_rulesets = { create_single_rule_ruleset("id1", true, "yahoo"), @@ -4044,6 +4082,10 @@ EXPECT_TRUE( prefs->GetDNRDynamicRulesetChecksum(extension_id, &dynamic_checksum_2)); EXPECT_EQ(dynamic_checksum_2, dynamic_checksum_1); + + // Ensure the preference for enabled static rulesets is cleared on extension + // update. + EXPECT_FALSE(prefs->GetDNREnabledStaticRulesets(extension_id)); } // Tests extension update for an extension using declarativeNetRequest.
diff --git a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_unittest.cc b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_unittest.cc index 61b2e83..e4b0f34 100644 --- a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_unittest.cc +++ b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_unittest.cc
@@ -23,11 +23,13 @@ #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_run_loop_timeout.h" #include "base/test/test_timeouts.h" +#include "base/values.h" #include "build/build_config.h" #include "chrome/browser/extensions/api/declarative_net_request/dnr_test_base.h" #include "chrome/browser/extensions/chrome_test_extension_loader.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/load_error_reporter.h" +#include "content/public/test/test_utils.h" #include "extensions/browser/api/declarative_net_request/composite_matcher.h" #include "extensions/browser/api/declarative_net_request/constants.h" #include "extensions/browser/api/declarative_net_request/declarative_net_request_api.h" @@ -59,6 +61,12 @@ constexpr char kLargeRegexFilter[] = ".{512}x"; +constexpr char kId1[] = "1.json"; +constexpr char kId2[] = "2.json"; +constexpr char kId3[] = "3.json"; +constexpr char kId4[] = "4.json"; +constexpr char kDefaultRulesetID[] = "id"; + namespace dnr_api = extensions::api::declarative_net_request; using ::testing::Field; @@ -205,6 +213,71 @@ browser_context()); } + void RunUpdateEnabledRulesetsFunction( + const Extension& extension, + const std::vector<std::string>& ruleset_ids_to_remove, + const std::vector<std::string>& ruleset_ids_to_add, + base::Optional<std::string> expected_error) { + std::unique_ptr<base::Value> args = + ListBuilder() + .Append(ToListValue(ruleset_ids_to_remove)) + .Append(ToListValue(ruleset_ids_to_add)) + .Build(); + std::string json_args; + base::JSONWriter::WriteWithOptions( + *args, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json_args); + + auto function = base::MakeRefCounted< + DeclarativeNetRequestUpdateEnabledRulesetsFunction>(); + function->set_extension(&extension); + function->set_has_callback(true); + + if (!expected_error) { + EXPECT_TRUE(api_test_utils::RunFunction(function.get(), json_args, + browser_context())); + return; + } + + EXPECT_EQ(expected_error, + api_test_utils::RunFunctionAndReturnError( + function.get(), json_args, browser_context())); + } + + void VerifyGetEnabledRulesetsFunction( + const Extension& extension, + const std::vector<std::string>& expected_ids) { + auto function = + base::MakeRefCounted<DeclarativeNetRequestGetEnabledRulesetsFunction>(); + function->set_extension(&extension); + function->set_has_callback(true); + + std::unique_ptr<base::Value> result = + api_test_utils::RunFunctionAndReturnSingleResult( + function.get(), "[]" /* args */, browser_context()); + ASSERT_TRUE(result); + ASSERT_TRUE(result->is_list()); + const base::ListValue& ids_value = base::Value::AsListValue(*result); + + base::string16 error; + std::vector<std::string> actual_ids; + for (const auto& val : ids_value) + actual_ids.push_back(val.GetString()); + + EXPECT_THAT(expected_ids, UnorderedElementsAreArray(actual_ids)); + } + + void VerifyPublicRulesetIDs( + const Extension& extension, + const std::vector<std::string>& expected_public_ruleset_ids) { + CompositeMatcher* matcher = + manager()->GetMatcherForExtension(extension.id()); + ASSERT_TRUE(matcher); + + EXPECT_THAT( + expected_public_ruleset_ids, + UnorderedElementsAreArray(GetPublicRulesetIDs(extension, *matcher))); + } + ChromeTestExtensionLoader* extension_loader() { return loader_.get(); } const Extension* extension() const { return extension_.get(); } @@ -276,10 +349,9 @@ if (!rules_value_) rules_value_ = ToListValue(rules_list_); - constexpr char kRulesetID[] = "id"; WriteManifestAndRuleset( extension_dir(), - TestRulesetInfo(kRulesetID, kJSONRulesFilename, *rules_value_), + TestRulesetInfo(kDefaultRulesetID, kJSONRulesFilename, *rules_value_), {} /* hosts */); // Overwrite the JSON rules file with some invalid json. @@ -750,8 +822,7 @@ LoadAndExpectSuccess(); ruleset_waiter.WaitForExtensionsWithRulesetsCount(1); - const std::string extension_id = extension()->id(); - + const ExtensionId extension_id = extension()->id(); service()->DisableExtension(extension_id, disable_reason::DISABLE_USER_ACTION); ruleset_waiter.WaitForExtensionsWithRulesetsCount(0); @@ -782,9 +853,55 @@ // The API function to update the dynamic ruleset should only complete once // the initial ruleset loading (in response to OnExtensionLoaded) is complete. // Hence by now, both the static and dynamic matchers must be loaded. - CompositeMatcher* matcher = manager()->GetMatcherForExtension(extension_id); - ASSERT_TRUE(matcher); - EXPECT_EQ(2u, matcher->matchers().size()); + VerifyPublicRulesetIDs(*extension, + {kDefaultRulesetID, dnr_api::DYNAMIC_RULESET_ID}); +} + +// Ensures that an updateEnabledRulesets call in the midst of an initial ruleset +// load (in response to OnExtensionLoaded) behaves predictably and doesn't +// DCHECK. +TEST_P(SingleRulesetTest, UpdateEnabledRulesetsRace) { + RulesetManagerObserver ruleset_waiter(manager()); + + AddRule(CreateGenericRule()); + LoadAndExpectSuccess(); + ruleset_waiter.WaitForExtensionsWithRulesetsCount(1); + + const ExtensionId extension_id = extension()->id(); + service()->DisableExtension(extension_id, + disable_reason::DISABLE_USER_ACTION); + ruleset_waiter.WaitForExtensionsWithRulesetsCount(0); + + // Simulate indexed ruleset format version change. This will cause a re-index + // on subsequent extension load. Since this will further delay the initial + // ruleset load, it helps test that the ruleset loading doesn't race with the + // updateEnabledRulesets call. + ScopedIncrementRulesetVersion scoped_version_change = + CreateScopedIncrementRulesetVersionForTesting(); + + TestExtensionRegistryObserver registry_observer(registry()); + service()->EnableExtension(extension_id); + scoped_refptr<const Extension> extension = + registry_observer.WaitForExtensionLoaded(); + ASSERT_TRUE(extension); + ASSERT_EQ(extension_id, extension->id()); + + // At this point, the ruleset will still be loading. + ASSERT_FALSE(manager()->GetMatcherForExtension(extension_id)); + + // Disable the sole extension ruleset. + RunUpdateEnabledRulesetsFunction(*extension, {kDefaultRulesetID}, {}, + base::nullopt); + + // Wait for any pending tasks. This isn't actually necessary for this test + // (there shouldn't be any pending tasks at this point). However still do this + // to not rely on any task ordering assumption. + content::RunAllTasksUntilIdle(); + + // The API function to update the enabled rulesets should only complete after + // the initial ruleset loading (in response to OnExtensionLoaded) is complete. + // Hence by now, the extension shouldn't have any active rulesets. + VerifyPublicRulesetIDs(*extension, {}); } // Tests that multiple static rulesets are correctly indexed. @@ -870,6 +987,7 @@ // Tests an extension with no static rulesets. TEST_P(MultipleRulesetsTest, ZeroRulesets) { LoadAndExpectSuccess(); + VerifyGetEnabledRulesetsFunction(*extension(), {}); } // Tests an extension with multiple empty rulesets. @@ -886,12 +1004,12 @@ // specifying an invalid rules file. TEST_P(MultipleRulesetsTest, ListNotPassed) { std::vector<TestRule> rules({CreateGenericRule()}); - AddRuleset(TestRulesetInfo("id1", "path1", *ToListValue(rules))); + AddRuleset(TestRulesetInfo(kId1, "path1", *ToListValue(rules))); // Persist a ruleset with an invalid rules file. - AddRuleset(TestRulesetInfo("id2", "path2", base::DictionaryValue())); + AddRuleset(TestRulesetInfo(kId2, "path2", base::DictionaryValue())); - AddRuleset(TestRulesetInfo("id3", "path3", base::ListValue())); + AddRuleset(TestRulesetInfo(kId3, "path3", base::ListValue())); LoadAndExpectError(kErrorListNotPassed, "path2" /* filename */); } @@ -914,7 +1032,7 @@ rule.condition->regex_filter = kLargeRegexFilter; rules.push_back(rule); - TestRulesetInfo info("id1", "path1", *ToListValue(rules), true); + TestRulesetInfo info(kId1, "path1", *ToListValue(rules), true); AddRuleset(info); expected_warnings.push_back( @@ -927,7 +1045,7 @@ { // Persist a ruleset with an install warning for exceeding the rule count. TestRulesetInfo info = - CreateRuleset("id2", dnr_api::MAX_NUMBER_OF_RULES + 1, 0, false); + CreateRuleset(kId2, dnr_api::MAX_NUMBER_OF_RULES + 1, 0, false); AddRuleset(info); expected_warnings.push_back( @@ -941,7 +1059,7 @@ // count. size_t kCountNonRegexRules = 5; TestRulesetInfo info = - CreateRuleset("id3", kCountNonRegexRules, + CreateRuleset(kId3, kCountNonRegexRules, dnr_api::MAX_NUMBER_OF_REGEX_RULES + 1, false); AddRuleset(info); @@ -969,9 +1087,9 @@ } TEST_P(MultipleRulesetsTest, EnabledRulesCount) { - AddRuleset(CreateRuleset("id1", 100, 10, true)); - AddRuleset(CreateRuleset("id2", 200, 20, false)); - AddRuleset(CreateRuleset("id3", 300, 30, true)); + AddRuleset(CreateRuleset(kId1, 100, 10, true)); + AddRuleset(CreateRuleset(kId2, 200, 20, false)); + AddRuleset(CreateRuleset(kId3, 300, 30, true)); RulesetManagerObserver ruleset_waiter(manager()); LoadAndExpectSuccess(); @@ -982,8 +1100,7 @@ manager()->GetMatcherForExtension(extension()->id()); ASSERT_TRUE(composite_matcher); - EXPECT_THAT(GetPublicRulesetIDs(*extension(), *composite_matcher), - UnorderedElementsAre("id1", "id3")); + VerifyPublicRulesetIDs(*extension(), {kId1, kId3}); EXPECT_THAT(composite_matcher->matchers(), UnorderedElementsAre( @@ -995,14 +1112,13 @@ // warning. TEST_P(MultipleRulesetsTest, StaticRuleCountExceeded) { // Enabled on load. - AddRuleset(CreateRuleset("1.json", 10, 0, true)); + AddRuleset(CreateRuleset(kId1, 10, 0, true)); // Disabled by default. - AddRuleset(CreateRuleset("2.json", 20, 0, false)); + AddRuleset(CreateRuleset(kId2, 20, 0, false)); // Not enabled on load since including it exceeds the static rules count. - AddRuleset( - CreateRuleset("3.json", dnr_api::MAX_NUMBER_OF_RULES + 10, 0, true)); + AddRuleset(CreateRuleset(kId3, dnr_api::MAX_NUMBER_OF_RULES + 10, 0, true)); // Enabled on load. - AddRuleset(CreateRuleset("4.json", 30, 0, true)); + AddRuleset(CreateRuleset(kId4, 30, 0, true)); RulesetManagerObserver ruleset_waiter(manager()); extension_loader()->set_ignore_manifest_warnings(true); @@ -1027,7 +1143,7 @@ extension()->install_warnings(), UnorderedElementsAre( Field(&InstallWarning::message, - GetErrorWithFilename(kRuleCountExceeded, "3.json")), + GetErrorWithFilename(kRuleCountExceeded, kId3)), Field(&InstallWarning::message, kEnabledRuleCountExceeded))); } @@ -1037,8 +1153,7 @@ manager()->GetMatcherForExtension(extension_id); ASSERT_TRUE(composite_matcher); - EXPECT_THAT(GetPublicRulesetIDs(*extension(), *composite_matcher), - UnorderedElementsAre("1.json", "4.json")); + VerifyPublicRulesetIDs(*extension(), {kId1, kId4}); EXPECT_THAT(composite_matcher->matchers(), UnorderedElementsAre( @@ -1049,15 +1164,14 @@ // Ensure that exceeding the regex rules limit across rulesets raises a warning. TEST_P(MultipleRulesetsTest, RegexRuleCountExceeded) { // Enabled on load. - AddRuleset(CreateRuleset("1.json", 10000, 100, true)); + AddRuleset(CreateRuleset(kId1, 10000, 100, true)); // Won't be enabled on load since including it will exceed the regex rule // count. - AddRuleset( - CreateRuleset("2.json", 1, dnr_api::MAX_NUMBER_OF_REGEX_RULES, true)); + AddRuleset(CreateRuleset(kId2, 1, dnr_api::MAX_NUMBER_OF_REGEX_RULES, true)); // Won't be enabled on load since it is disabled by default. - AddRuleset(CreateRuleset("3.json", 10, 10, false)); + AddRuleset(CreateRuleset(kId3, 10, 10, false)); // Enabled on load. - AddRuleset(CreateRuleset("4.json", 20, 20, true)); + AddRuleset(CreateRuleset(kId4, 20, 20, true)); RulesetManagerObserver ruleset_waiter(manager()); extension_loader()->set_ignore_manifest_warnings(true); @@ -1078,8 +1192,7 @@ manager()->GetMatcherForExtension(extension()->id()); ASSERT_TRUE(composite_matcher); - EXPECT_THAT(GetPublicRulesetIDs(*extension(), *composite_matcher), - UnorderedElementsAre("1.json", "4.json")); + VerifyPublicRulesetIDs(*extension(), {kId1, kId4}); EXPECT_THAT( composite_matcher->matchers(), @@ -1088,6 +1201,171 @@ Pointee(Property(&RulesetMatcher::GetRulesCount, 20 + 20)))); } +TEST_P(MultipleRulesetsTest, UpdateEnabledRulesets_InvalidRulesetID) { + AddRuleset(CreateRuleset(kId1, 10, 10, true)); + AddRuleset(CreateRuleset(kId2, 10, 10, false)); + AddRuleset(CreateRuleset(kId3, 10, 10, true)); + + RulesetManagerObserver ruleset_waiter(manager()); + LoadAndExpectSuccess(); + ruleset_waiter.WaitForExtensionsWithRulesetsCount(1); + + constexpr char kInvalidRulesetId[] = "invalid_id"; + RunUpdateEnabledRulesetsFunction( + *extension(), {kId1, kInvalidRulesetId}, {}, + ErrorUtils::FormatErrorMessage(kInvalidRulesetIDError, + kInvalidRulesetId)); + VerifyPublicRulesetIDs(*extension(), {kId1, kId3}); + + RunUpdateEnabledRulesetsFunction( + *extension(), {kId1}, {kId2, kInvalidRulesetId}, + ErrorUtils::FormatErrorMessage(kInvalidRulesetIDError, + kInvalidRulesetId)); + VerifyPublicRulesetIDs(*extension(), {kId1, kId3}); +} + +TEST_P(MultipleRulesetsTest, UpdateEnabledRulesets_RuleCountExceeded) { + AddRuleset(CreateRuleset(kId1, 10, 10, true)); + AddRuleset(CreateRuleset(kId2, dnr_api::MAX_NUMBER_OF_RULES, 0, false)); + + RulesetManagerObserver ruleset_waiter(manager()); + LoadAndExpectSuccess(); + ruleset_waiter.WaitForExtensionsWithRulesetsCount(1); + + RunUpdateEnabledRulesetsFunction(*extension(), {}, {kId2}, + kEnabledRulesetsRuleCountExceeded); + VerifyPublicRulesetIDs(*extension(), {kId1}); + + // updateEnabledRulesets looks at the rule counts at the end of the update, so + // disabling |kId1| and enabling |kId2| works (because the total rule count is + // under the limit). + RunUpdateEnabledRulesetsFunction(*extension(), {kId1}, {kId2}, base::nullopt); + VerifyPublicRulesetIDs(*extension(), {kId2}); +} + +TEST_P(MultipleRulesetsTest, UpdateEnabledRulesets_RegexRuleCountExceeded) { + AddRuleset(CreateRuleset(kId1, 0, 10, false)); + AddRuleset(CreateRuleset(kId2, 0, dnr_api::MAX_NUMBER_OF_REGEX_RULES, true)); + + RulesetManagerObserver ruleset_waiter(manager()); + LoadAndExpectSuccess(); + ruleset_waiter.WaitForExtensionsWithRulesetsCount(1); + + RunUpdateEnabledRulesetsFunction(*extension(), {}, {kId1}, + kEnabledRulesetsRegexRuleCountExceeded); + VerifyPublicRulesetIDs(*extension(), {kId2}); +} + +TEST_P(MultipleRulesetsTest, UpdateEnabledRulesets_InternalError) { + AddRuleset(CreateRuleset(kId1, 10, 10, true)); + AddRuleset(CreateRuleset(kId2, 10, 10, false)); + + RulesetManagerObserver ruleset_waiter(manager()); + LoadAndExpectSuccess(); + ruleset_waiter.WaitForExtensionsWithRulesetsCount(1); + + std::vector<RulesetSource> static_sources = + RulesetSource::CreateStatic(*extension()); + ASSERT_EQ(2u, static_sources.size()); + + constexpr char kReindexHistogram[] = + "Extensions.DeclarativeNetRequest.RulesetReindexSuccessful"; + { + // First delete the indexed ruleset file for the second ruleset. Enabling it + // should cause re-indexing and succeed in enabling the ruleset. + base::HistogramTester tester; + ASSERT_TRUE(base::DeleteFile(static_sources[1].indexed_path(), + false /* recursive */)); + + RunUpdateEnabledRulesetsFunction(*extension(), {kId1}, {kId2}, + base::nullopt); + VerifyPublicRulesetIDs(*extension(), {kId2}); + + tester.ExpectBucketCount(kReindexHistogram, true /*sample*/, 1 /*count*/); + + EXPECT_TRUE(base::PathExists(static_sources[1].indexed_path())); + } + + { + // Now delete both the indexed and json ruleset file for the first ruleset. + // This will prevent enabling the first ruleset since re-indexing will fail. + base::HistogramTester tester; + ASSERT_TRUE(base::DeleteFile(static_sources[0].indexed_path(), + false /* recursive */)); + ASSERT_TRUE( + base::DeleteFile(static_sources[0].json_path(), false /* recursive */)); + + RunUpdateEnabledRulesetsFunction(*extension(), {}, {kId1}, + kInternalErrorUpdatingEnabledRulesets); + VerifyPublicRulesetIDs(*extension(), {kId2}); + + tester.ExpectBucketCount(kReindexHistogram, false /*sample*/, 1 /*count*/); + } +} + +TEST_P(MultipleRulesetsTest, UpdateAndGetEnabledRulesets_Success) { + AddRuleset(CreateRuleset(kId1, 10, 10, true)); + AddRuleset(CreateRuleset(kId2, 10, 10, false)); + AddRuleset(CreateRuleset(kId3, 10, 10, true)); + + RulesetManagerObserver ruleset_waiter(manager()); + LoadAndExpectSuccess(); + ruleset_waiter.WaitForExtensionsWithRulesetsCount(1); + + std::vector<std::string> ruleset_ids; + RunUpdateEnabledRulesetsFunction(*extension(), {kId1, kId3}, {kId2}, + base::nullopt /* expected_error */); + VerifyPublicRulesetIDs(*extension(), {kId2}); + VerifyGetEnabledRulesetsFunction(*extension(), {kId2}); + + RunUpdateEnabledRulesetsFunction(*extension(), {}, {kId3, kId3}, + base::nullopt /* expected_error */); + VerifyPublicRulesetIDs(*extension(), {kId2, kId3}); + VerifyGetEnabledRulesetsFunction(*extension(), {kId2, kId3}); + + // Ensure no-op calls succeed. + RunUpdateEnabledRulesetsFunction(*extension(), {}, {kId2, kId3}, + base::nullopt /* expected_error */); + VerifyPublicRulesetIDs(*extension(), {kId2, kId3}); + VerifyGetEnabledRulesetsFunction(*extension(), {kId2, kId3}); + + RunUpdateEnabledRulesetsFunction(*extension(), {kId1}, {}, + base::nullopt /* expected_error */); + VerifyPublicRulesetIDs(*extension(), {kId2, kId3}); + VerifyGetEnabledRulesetsFunction(*extension(), {kId2, kId3}); + + // Add dynamic rules and ensure that the setEnabledRulesets call doesn't have + // any effect on the dynamic ruleset. Also ensure that the getEnabledRulesets + // call excludes the dynamic ruleset ID. + ASSERT_TRUE( + RunDynamicRuleUpdateFunction(*extension(), {}, {CreateGenericRule()})); + VerifyPublicRulesetIDs(*extension(), + {kId2, kId3, dnr_api::DYNAMIC_RULESET_ID}); + VerifyGetEnabledRulesetsFunction(*extension(), {kId2, kId3}); + + // Ensure enabling a ruleset takes priority over disabling. + RunUpdateEnabledRulesetsFunction(*extension(), {kId1}, {kId1}, + base::nullopt /* expected_error */); + VerifyPublicRulesetIDs(*extension(), + {kId1, kId2, kId3, dnr_api::DYNAMIC_RULESET_ID}); + VerifyGetEnabledRulesetsFunction(*extension(), {kId1, kId2, kId3}); + + // Ensure the set of enabled rulesets persists across extension reloads. + const ExtensionId extension_id = extension()->id(); + service()->DisableExtension(extension_id, + disable_reason::DISABLE_USER_ACTION); + ruleset_waiter.WaitForExtensionsWithRulesetsCount(0); + + service()->EnableExtension(extension_id); + ruleset_waiter.WaitForExtensionsWithRulesetsCount(1); + const Extension* extension = + registry()->GetExtensionById(extension_id, ExtensionRegistry::ENABLED); + ASSERT_TRUE(extension); + VerifyPublicRulesetIDs(*extension, + {kId1, kId2, kId3, dnr_api::DYNAMIC_RULESET_ID}); + VerifyGetEnabledRulesetsFunction(*extension, {kId1, kId2, kId3}); +} + INSTANTIATE_TEST_SUITE_P(All, SingleRulesetTest, ::testing::Values(ExtensionLoadType::PACKED,
diff --git a/chrome/browser/extensions/api/declarative_net_request/dnr_test_base.cc b/chrome/browser/extensions/api/declarative_net_request/dnr_test_base.cc index 82676ea2..be2323e 100644 --- a/chrome/browser/extensions/api/declarative_net_request/dnr_test_base.cc +++ b/chrome/browser/extensions/api/declarative_net_request/dnr_test_base.cc
@@ -5,14 +5,11 @@ #include "chrome/browser/extensions/api/declarative_net_request/dnr_test_base.h" #include "chrome/browser/extensions/chrome_test_extension_loader.h" -#include "components/version_info/version_info.h" namespace extensions { namespace declarative_net_request { -// Use channel UNKNOWN to ensure that the declarativeNetRequest API is -// available, irrespective of its actual availability. -DNRTestBase::DNRTestBase() : channel_(::version_info::Channel::UNKNOWN) {} +DNRTestBase::DNRTestBase() = default; void DNRTestBase::SetUp() { ExtensionServiceTestBase::SetUp();
diff --git a/chrome/browser/extensions/api/declarative_net_request/dnr_test_base.h b/chrome/browser/extensions/api/declarative_net_request/dnr_test_base.h index 69b8b55..78e4a891 100644 --- a/chrome/browser/extensions/api/declarative_net_request/dnr_test_base.h +++ b/chrome/browser/extensions/api/declarative_net_request/dnr_test_base.h
@@ -10,7 +10,6 @@ #include "base/macros.h" #include "chrome/browser/extensions/extension_service_test_base.h" #include "extensions/browser/api/declarative_net_request/test_utils.h" -#include "extensions/common/features/feature_channel.h" #include "testing/gtest/include/gtest/gtest.h" namespace extensions { @@ -32,8 +31,6 @@ std::unique_ptr<ChromeTestExtensionLoader> CreateExtensionLoader(); private: - ScopedCurrentChannel channel_; - DISALLOW_COPY_AND_ASSIGN(DNRTestBase); };
diff --git a/chrome/browser/extensions/api/declarative_net_request/ruleset_manager_unittest.cc b/chrome/browser/extensions/api/declarative_net_request/ruleset_manager_unittest.cc index 4b63883..9ebdabe 100644 --- a/chrome/browser/extensions/api/declarative_net_request/ruleset_manager_unittest.cc +++ b/chrome/browser/extensions/api/declarative_net_request/ruleset_manager_unittest.cc
@@ -14,6 +14,7 @@ #include "chrome/browser/extensions/api/declarative_net_request/dnr_test_base.h" #include "chrome/browser/extensions/chrome_test_extension_loader.h" #include "chrome/browser/extensions/extension_util.h" +#include "components/version_info/channel.h" #include "extensions/browser/api/declarative_net_request/composite_matcher.h" #include "extensions/browser/api/declarative_net_request/request_action.h" #include "extensions/browser/api/declarative_net_request/ruleset_matcher.h" @@ -27,6 +28,7 @@ #include "extensions/common/api/declarative_net_request.h" #include "extensions/common/api/declarative_net_request/constants.h" #include "extensions/common/api/declarative_net_request/test_utils.h" +#include "extensions/common/features/feature_channel.h" #include "extensions/common/file_util.h" #include "extensions/common/manifest_handlers/background_info.h" #include "extensions/common/url_pattern.h" @@ -529,6 +531,10 @@ // Test that the correct modifyHeaders actions are returned for each extension. TEST_P(RulesetManagerTest, ModifyHeaders) { + // TODO(crbug.com/947591): Remove the channel override once implementation of + // modifyHeaders action is complete. + ScopedCurrentChannel channel(::version_info::Channel::UNKNOWN); + const Extension* extension_1 = nullptr; const Extension* extension_2 = nullptr; @@ -600,6 +606,10 @@ // Test that an extension's modify header rules are applied on a request only if // it has host permissions for the request. TEST_P(RulesetManagerTest, ModifyHeaders_HostPermissions) { + // TODO(crbug.com/947591): Remove the channel override once implementation of + // modifyHeaders action is complete. + ScopedCurrentChannel channel(::version_info::Channel::UNKNOWN); + // Add an extension which removes the "header1" header with host permissions // for example.com. std::unique_ptr<CompositeMatcher> matcher;
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc b/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc index 01455ccb..42ae22b 100644 --- a/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc +++ b/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc
@@ -1479,14 +1479,7 @@ EXPECT_FALSE(modifier.HasGrantedHostPermission(kMapsGoogleCom)); } -// This test is flaky on chromeos. -// https://crbug.com/937355 -#if defined(OS_CHROMEOS) -#define MAYBE_UpdateHostAccess DISABLED_UpdateHostAccess -#else -#define MAYBE_UpdateHostAccess UpdateHostAccess -#endif -TEST_F(DeveloperPrivateApiUnitTest, MAYBE_UpdateHostAccess) { +TEST_F(DeveloperPrivateApiUnitTest, UpdateHostAccess) { scoped_refptr<const Extension> extension = ExtensionBuilder("test").AddPermission("<all_urls>").Build(); service()->AddExtension(extension.get());
diff --git a/chrome/browser/extensions/api/storage/settings_sync_unittest.cc b/chrome/browser/extensions/api/storage/settings_sync_unittest.cc index 4ed57fe3..3e86de2f 100644 --- a/chrome/browser/extensions/api/storage/settings_sync_unittest.cc +++ b/chrome/browser/extensions/api/storage/settings_sync_unittest.cc
@@ -1455,15 +1455,7 @@ } // namespace -#if defined(OS_WIN) -// See: http://crbug.com/227296 -#define MAYBE_UnlimitedStorageForLocalButNotSync \ - DISABLED_UnlimitedStorageForLocalButNotSync -#else -#define MAYBE_UnlimitedStorageForLocalButNotSync \ - UnlimitedStorageForLocalButNotSync -#endif -TEST_F(ExtensionSettingsSyncTest, MAYBE_UnlimitedStorageForLocalButNotSync) { +TEST_F(ExtensionSettingsSyncTest, UnlimitedStorageForLocalButNotSync) { const std::string id = "ext"; std::set<std::string> permissions; permissions.insert("unlimitedStorage");
diff --git a/chrome/browser/extensions/api/terminal/terminal_extension_helper.cc b/chrome/browser/extensions/api/terminal/terminal_extension_helper.cc index 3010148..9d6965bb 100644 --- a/chrome/browser/extensions/api/terminal/terminal_extension_helper.cc +++ b/chrome/browser/extensions/api/terminal/terminal_extension_helper.cc
@@ -23,12 +23,10 @@ const Extension* TerminalExtensionHelper::GetTerminalExtension( Profile* profile) { - // Search order for terminal extensions. - // We prefer nassh-dev, then nassh, then the builtin crosh extension. + // Search order for terminal extensions: nassh-dev, then nassh. static const char* const kPossibleAppIds[] = { extension_misc::kHTermDevAppId, extension_misc::kHTermAppId, - extension_misc::kCroshBuiltinAppId, }; // The nassh-dev should be first in the list. @@ -50,8 +48,8 @@ // chrome-untrusted://crosh by default. GURL url(chrome::kChromeUIUntrustedCroshURL); const extensions::Extension* extension = GetTerminalExtension(profile); - // Allow nassh-dev or nassh to override, but not crosh-builtin. - if (extension && extension->id() != extension_misc::kCroshBuiltinAppId) { + // Allow nassh-dev or nassh to override. + if (extension) { url = extension->GetResourceURL(kCroshExtensionEntryPoint); } return url;
diff --git a/chrome/browser/extensions/api/terminal/terminal_extension_helper.h b/chrome/browser/extensions/api/terminal/terminal_extension_helper.h index d05709d4..0824898 100644 --- a/chrome/browser/extensions/api/terminal/terminal_extension_helper.h +++ b/chrome/browser/extensions/api/terminal/terminal_extension_helper.h
@@ -20,7 +20,6 @@ // Returns the crosh extension. It is the first found out of: // 1. nassh-dev : okddffdblfhhnmhodogpojmfkjmhinfp // 2. nassh : pnhechapfaindjhompbnflcldabbghjo - // 3. crosh builtin: nkoccljplnhpfnfiajclkommnmllphnl static const Extension* GetTerminalExtension(Profile* profile); // Returns crosh URL. chrome-untrusted://crosh is used by default, but it can
diff --git a/chrome/browser/extensions/component_extensions_whitelist/whitelist.cc b/chrome/browser/extensions/component_extensions_whitelist/whitelist.cc index 7e4d8a58..91ce47f 100644 --- a/chrome/browser/extensions/component_extensions_whitelist/whitelist.cc +++ b/chrome/browser/extensions/component_extensions_whitelist/whitelist.cc
@@ -81,7 +81,6 @@ case IDR_CHROME_APP_MANIFEST: case IDR_CONNECTIVITY_DIAGNOSTICS_LAUNCHER_MANIFEST: case IDR_CONNECTIVITY_DIAGNOSTICS_MANIFEST: - case IDR_CROSH_BUILTIN_MANIFEST: case IDR_DEMO_APP_MANIFEST: case IDR_ECHO_MANIFEST: case IDR_FILEMANAGER_MANIFEST:
diff --git a/chrome/browser/extensions/component_loader.cc b/chrome/browser/extensions/component_loader.cc index 86484b72..9a72c044 100644 --- a/chrome/browser/extensions/component_loader.cc +++ b/chrome/browser/extensions/component_loader.cc
@@ -446,12 +446,6 @@ } #endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) - // Skip all other extensions that require user session presence. - if (!skip_session_components) { - Add(IDR_CROSH_BUILTIN_MANIFEST, base::FilePath(FILE_PATH_LITERAL( - "/usr/share/chromeos-assets/crosh_builtin"))); - } - AddKeyboardApp(); #else // defined(OS_CHROMEOS) DCHECK(!skip_session_components);
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 7bd7e95..cff96bf 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -264,6 +264,11 @@ "expiry_milestone": 72 }, { + "name": "autofill-enable-card-nickname-management", + "owners": [ "siyua", "sujiezhu@google.com" ], + "expiry_milestone": 92 + }, + { "name": "autofill-enable-company-name", "owners": [ "sebsg" ], "expiry_milestone": 73 @@ -414,11 +419,6 @@ "expiry_milestone": 86 }, { - "name": "bluetooth-kernel-suspend-notifier", - "owners": [ "abhishekpandit", "chromeos-bluetooth@google.com" ], - "expiry_milestone": 84 - }, - { "name": "bluetooth-next-handsfree-profile", "owners": [ "hychao" ], "expiry_milestone": 85 @@ -469,6 +469,11 @@ "expiry_milestone": 86 }, { + "name": "chrome-sharing-hub-v1-5", + "owners": ["sophey"], + "expiry_milestone": 89 + }, + { "name": "chromeos-video-decoder", "owners": [ "chromeos-video-eng@google.com" ], // This flag should expire once all VDA-based ChromeOS video decoders have @@ -606,9 +611,19 @@ "expiry_milestone": 86 }, { + "name": "conversion-measurement-api", + "owners": [ "//content/browser/conversions/OWNERS" ], + "expiry_milestone": 87 + }, + { + "name": "conversion-measurement-debug-mode", + "owners": [ "//content/browser/conversions/OWNERS" ], + "expiry_milestone": 87 + }, + { "name": "cookie-deprecation-messages", - "owners": [ "chlily", "aarontag" ], - "expiry_milestone": 85 + "owners": [ "bingler", "chlily", "aarontag" ], + "expiry_milestone": 90 }, { "name": "cookies-without-same-site-must-be-secure", @@ -707,7 +722,7 @@ }, { "name": "cups-ipp-printing-backend", - "owners": [ "dhoss", "chrome-print@google.com" ], + "owners": [ "dhoss", "//printing/OWNERS" ], "expiry_milestone": 89 }, { @@ -1067,10 +1082,15 @@ "owners": [ "ftirelo" ], "expiry_milestone": 73 }, + { + "name": "enable-android-dark-search", + "owners": [ "wylieb", "twellington", "fgorski"], + "expiry_milestone": 90 + }, { "name": "enable-android-night-mode-tab-reparenting", "owners": [ "wylieb", "twellington", "tedchoc"], - "expiry_milestone": 85 + "expiry_milestone": 88 }, { "name": "enable-android-spellchecker", @@ -2572,7 +2592,7 @@ { "name": "gdi-text-printing", "owners": [ "//printing/OWNERS" ], - "expiry_milestone": 84 + "expiry_milestone": 89 }, { "name": "gesture-properties-dbus-service", @@ -3456,7 +3476,7 @@ { "name": "pdf-form-save", "owners": [ "thestig" ], - "expiry_milestone": 82 + "expiry_milestone": 89 }, { "name": "pdf-two-up-view",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 46b5a0c..91ead99 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -75,6 +75,17 @@ const char kConditionalTabStripAndroidDescription[] = "Allows users to access conditional tab strip."; +const char kConversionMeasurementApiName[] = "Conversion Measurement API"; +const char kConversionMeasurementApiDescription[] = + "Enables usage of the Conversion Measurement API."; + +const char kConversionMeasurementDebugModeName[] = + "Conversion Measurement Debug Mode"; +const char kConversionMeasurementDebugModeDescription[] = + "Enables debug mode for the Conversion Measurement API. This removes all " + "reporting delays and noise. Only works if the Conversion Measurement API " + "is already enabled."; + const char kEnableClipboardProviderImageSuggestionsName[] = "Omnibox clipboard image search suggestions"; const char kEnableClipboardProviderImageSuggestionsDescription[] = @@ -178,6 +189,12 @@ "When enabled, autofill will cache the responses it receives from the " "crowd-sourced field type prediction server."; +const char kAutofillEnableCardNicknameManagementName[] = + "Enable Autofill card nickname management"; +const char kAutofillEnableCardNicknameManagementDescription[] = + "When enabled, nicknames for credit cards will be able to be uploaded to " + "Payments or modified locally."; + const char kAutofillEnableCompanyNameName[] = "Enable Autofill Company Name field"; const char kAutofillEnableCompanyNameDescription[] = @@ -385,8 +402,8 @@ const char kCookieDeprecationMessagesName[] = "Cookie deprecation messages"; const char kCookieDeprecationMessagesDescription[] = - "Show messages in the DevTools console about upcoming deprecations that " - "would affect sent/received cookies."; + "Show messages in DevTools about upcoming deprecations that would affect " + "sent/received cookies."; const char kCookiesWithoutSameSiteMustBeSecureName[] = "Cookies without SameSite must be secure"; @@ -2339,6 +2356,10 @@ const char kChromeSharingHubDescription[] = "Enables the Chrome Sharing Hub/custom share sheet."; +const char kChromeSharingHubV15Name[] = "Chrome Sharing Hub V1.5"; +const char kChromeSharingHubV15Description[] = + "Enables v1.5 of the Chrome Sharing Hub."; + const char kClearOldBrowsingDataName[] = "Clear older browsing data"; const char kClearOldBrowsingDataDescription[] = "Enables clearing of browsing data which is older than a given time " @@ -2802,6 +2823,11 @@ "flow where they do not have to leave Chrome until the update is ready " "to install."; +const char kAndroidDarkSearchName[] = "Show darkened search pages on Android"; +const char kAndroidDarkSearchDescription[] = + "If enabled, users will see a darkened search page if Chrome is in " + "nightmode as well."; + const char kAndroidNightModeTabReparentingName[] = "Android Chrome UI dark mode tab reparenting"; const char kAndroidNightModeTabReparentingDescription[] = @@ -3219,12 +3245,6 @@ "Fixes Bluetooth A2DP packet size to a smaller default value to improve " "audio quality and may fix audio stutter."; -const char kBluetoothKernelSuspendNotifierName[] = - "Bluetooth kernel suspend notifier handler"; -const char kBluetoothKernelSuspendNotifierDescription[] = - "Enables the Bluetooth kernel suspend notifier which will allow wake from " - "suspend using Bluetooth HID devices."; - const char kBluetoothNextHandsfreeProfileName[] = "Enable next version of Bluetooth Handsfree profile"; const char kBluetoothNextHandsfreeProfileDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 3e7a2f7..cede3145 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -76,6 +76,12 @@ extern const char kAllowSyncXHRInPageDismissalName[]; extern const char kAllowSyncXHRInPageDismissalDescription[]; +extern const char kConversionMeasurementApiName[]; +extern const char kConversionMeasurementApiDescription[]; + +extern const char kConversionMeasurementDebugModeName[]; +extern const char kConversionMeasurementDebugModeDescription[]; + extern const char kEnableClipboardProviderImageSuggestionsName[]; extern const char kEnableClipboardProviderImageSuggestionsDescription[]; @@ -115,6 +121,9 @@ extern const char kAutofillCacheQueryResponsesName[]; extern const char kAutofillCacheQueryResponsesDescription[]; +extern const char kAutofillEnableCardNicknameManagementName[]; +extern const char kAutofillEnableCardNicknameManagementDescription[]; + extern const char kAutofillEnableCompanyNameName[]; extern const char kAutofillEnableCompanyNameDescription[]; @@ -1375,6 +1384,9 @@ extern const char kChromeSharingHubName[]; extern const char kChromeSharingHubDescription[]; +extern const char kChromeSharingHubV15Name[]; +extern const char kChromeSharingHubV15Description[]; + extern const char kClearOldBrowsingDataName[]; extern const char kClearOldBrowsingDataDescription[]; @@ -1619,6 +1631,9 @@ extern const char kInlineUpdateFlowName[]; extern const char kInlineUpdateFlowDescription[]; +extern const char kAndroidDarkSearchName[]; +extern const char kAndroidDarkSearchDescription[]; + extern const char kAndroidNightModeTabReparentingName[]; extern const char kAndroidNightModeTabReparentingDescription[]; @@ -1870,9 +1885,6 @@ extern const char kBluetoothFixA2dpPacketSizeName[]; extern const char kBluetoothFixA2dpPacketSizeDescription[]; -extern const char kBluetoothKernelSuspendNotifierName[]; -extern const char kBluetoothKernelSuspendNotifierDescription[]; - extern const char kBluetoothNextHandsfreeProfileName[]; extern const char kBluetoothNextHandsfreeProfileDescription[];
diff --git a/chrome/browser/flags/BUILD.gn b/chrome/browser/flags/BUILD.gn index 05c4d84..a8481265 100644 --- a/chrome/browser/flags/BUILD.gn +++ b/chrome/browser/flags/BUILD.gn
@@ -69,7 +69,10 @@ android_library("javatests") { testonly = true - sources = [ "android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureListInstrumentationTest.java" ] + sources = [ + "android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureListInstrumentationTest.java", + "android/java/src/org/chromium/chrome/browser/flags/FieldTrialsInstrumentationTest.java", + ] deps = [ ":java", "//base:base_java",
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index 3b90058..25967e3 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -126,6 +126,7 @@ &kChromeDuetLabeled, &kChromeShareScreenshot, &kChromeSharingHub, + &kChromeSharingHubV15, &kChromeSmartSelection, &kCommandLineOnNonRooted, &kConditionalTabStripAndroid, @@ -250,14 +251,14 @@ &password_manager::features::kPasswordEditingAndroid, &password_manager::features::kPasswordManagerOnboardingAndroid, &password_manager::features::kRecoverFromNeverSaveAndroid, + &query_tiles::features::kQueryTiles, + &query_tiles::features::kQueryTilesInOmnibox, + &query_tiles::features::kQueryTilesEnableQueryEditing, &security_state::features::kMarkHttpAsFeature, &signin::kMobileIdentityConsistency, &switches::kSyncErrorInfoBarAndroid, &switches::kSyncUseSessionsUnregisterDelay, &subresource_filter::kSafeBrowsingSubresourceFilter, - &upboarding::features::kQueryTiles, - &upboarding::features::kQueryTilesInOmnibox, - &upboarding::features::kQueryTilesEnableQueryEditing, }; const base::Feature* FindFeatureExposedToJava(const std::string& feature_name) { @@ -367,6 +368,9 @@ const base::Feature kChromeSharingHub{"ChromeSharingHub", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kChromeSharingHubV15{"ChromeSharingHubV15", + base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kChromeSmartSelection{"ChromeSmartSelection", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h index 1670fac..1910ebc0 100644 --- a/chrome/browser/flags/android/chrome_feature_list.h +++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -41,6 +41,7 @@ extern const base::Feature kChromeDuetLabeled; extern const base::Feature kChromeShareScreenshot; extern const base::Feature kChromeSharingHub; +extern const base::Feature kChromeSharingHubV15; extern const base::Feature kChromeSmartSelection; extern const base::Feature kCommandLineOnNonRooted; extern const base::Feature kConditionalTabStripAndroid;
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java index b336df6ed..b80a91d 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -239,6 +239,7 @@ public static final String CHROME_DUET_LABELED = "ChromeDuetLabeled"; public static final String CHROME_SHARE_SCREENSHOT = "ChromeShareScreenshot"; public static final String CHROME_SHARING_HUB = "ChromeSharingHub"; + public static final String CHROME_SHARING_HUB_V15 = "ChromeSharingHubV15"; public static final String CHROME_SMART_SELECTION = "ChromeSmartSelection"; public static final String CLEAR_OLD_BROWSING_DATA = "ClearOldBrowsingData"; public static final String COMMAND_LINE_ON_NON_ROOTED = "CommandLineOnNonRooted";
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/FieldTrialsTest.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/FieldTrialsInstrumentationTest.java similarity index 91% rename from chrome/android/javatests/src/org/chromium/chrome/browser/FieldTrialsTest.java rename to chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/FieldTrialsInstrumentationTest.java index c797ae0..e61bc0e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/FieldTrialsTest.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/FieldTrialsInstrumentationTest.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.chrome.browser; +package org.chromium.chrome.browser.flags; import android.support.test.filters.SmallTest; @@ -14,13 +14,8 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.chrome.browser.flags.BooleanCachedFieldTrialParameter; -import org.chromium.chrome.browser.flags.CachedFeatureFlags; -import org.chromium.chrome.browser.flags.ChromeFeatureList; -import org.chromium.chrome.browser.flags.ChromeSwitches; -import org.chromium.chrome.browser.flags.DoubleCachedFieldTrialParameter; -import org.chromium.chrome.browser.flags.IntCachedFieldTrialParameter; -import org.chromium.chrome.browser.flags.StringCachedFieldTrialParameter; +import org.chromium.chrome.browser.ChromeActivity; +import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.util.browser.Features; @@ -31,7 +26,7 @@ */ @RunWith(ChromeJUnit4ClassRunner.class) @CommandLineFlags.Add(ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE) -public final class FieldTrialsTest { +public final class FieldTrialsInstrumentationTest { private static final String sFeature1 = ChromeFeatureList.TEST_DEFAULT_DISABLED; private static final String sFeature2 = ChromeFeatureList.TEST_DEFAULT_ENABLED;
diff --git a/chrome/browser/importer/external_process_importer_client.cc b/chrome/browser/importer/external_process_importer_client.cc index 58000b2..65d4395d5 100644 --- a/chrome/browser/importer/external_process_importer_client.cc +++ b/chrome/browser/importer/external_process_importer_client.cc
@@ -11,6 +11,7 @@ #include "build/build_config.h" #include "chrome/browser/importer/external_process_importer_host.h" #include "chrome/browser/importer/in_process_importer_bridge.h" +#include "chrome/browser/service_sandbox_type.h" #include "chrome/common/importer/firefox_importer_utils.h" #include "chrome/common/importer/imported_bookmark_entry.h" #include "chrome/grit/generated_resources.h" @@ -41,7 +42,6 @@ profile_import_.BindNewPipeAndPassReceiver(), content::ServiceProcessHost::Options() .WithDisplayName(IDS_UTILITY_PROCESS_PROFILE_IMPORTER_NAME) - .WithSandboxType(service_manager::SandboxType::kNoSandbox) .Pass()); profile_import_.set_disconnect_handler( base::BindOnce(&ExternalProcessImporterClient::OnProcessCrashed, this));
diff --git a/chrome/browser/media/feeds/media_feeds_browsertest.cc b/chrome/browser/media/feeds/media_feeds_browsertest.cc index f67cbae..c724393 100644 --- a/chrome/browser/media/feeds/media_feeds_browsertest.cc +++ b/chrome/browser/media/feeds/media_feeds_browsertest.cc
@@ -34,6 +34,7 @@ #include "net/test/embedded_test_server/http_response.h" #include "services/metrics/public/cpp/ukm_builders.h" #include "testing/gmock/include/gmock/gmock.h" +#include "url/origin.h" namespace media_feeds { @@ -267,18 +268,384 @@ run_loop.Run(); WaitForDB(); + auto feeds = GetMediaFeedsSync(); + + auto logo1 = mojom::MediaImage::New(); + logo1->size = ::gfx::Size(1113, 245); + logo1->src = GURL( + "https://beccahughes.github.io/media/media-feeds/" + "chromium_logo_white.png"); + logo1->content_attributes = { + mojom::ContentAttribute::kForDarkBackground, + mojom::ContentAttribute::kHasTitle, + mojom::ContentAttribute::kHasTransparentBackground}; + auto logo2 = mojom::MediaImage::New(); + logo2->size = ::gfx::Size(600, 315); + logo2->src = + GURL("https://beccahughes.github.io/media/media-feeds/chromium_card.png"); + logo2->content_attributes = {mojom::ContentAttribute::kForLightBackground, + mojom::ContentAttribute::kHasTitle, + mojom::ContentAttribute::kCentered}; + std::set<url::Origin> origins = { + url::Origin::Create(GURL("https://www.github.com"))}; + auto user_id = mojom::UserIdentifier::New(); + user_id->name = "Becca Hughes"; + user_id->email = "beccahughes@chromium.org"; + user_id->image = mojom::MediaImage::New(); + user_id->image->size = ::gfx::Size(32, 32); + user_id->image->src = GURL( + "https://www.chromium.org/_/rsrc/1438811752264/chromium-projects/" + "logo_chrome_color_1x_web_32dp.png"); + + // First, check the feed metadata. + ASSERT_EQ(1u, feeds.size()); + EXPECT_EQ("Chromium Developers", feeds[0]->display_name); + ASSERT_EQ(2u, feeds[0]->logos.size()); + EXPECT_EQ(logo1, feeds[0]->logos[0]); + EXPECT_EQ(logo2, feeds[0]->logos[1]); + EXPECT_FALSE(feeds[0]->associated_origins.empty()); + EXPECT_THAT( + feeds[0]->associated_origins, + testing::Contains(url::Origin::Create(GURL("https://www.github.com")))); + EXPECT_EQ(user_id, feeds[0]->user_identifier); + auto items = GetItemsForMediaFeedSync(discovered_feeds[0]->id); EXPECT_EQ(7u, items.size()); - std::vector<std::string> names; - std::transform(items.begin(), items.end(), std::back_inserter(names), - [](auto& item) { return base::UTF16ToASCII(item->name); }); - EXPECT_THAT(names, testing::UnorderedElementsAre( - "Anatomy of a Web Media Experience", - "Building Modern Web Media Experiences: " - "Picture-in-Picture and AV1", - "Chrome Releases", "Chrome University", "JAM stack", - "Ask Chrome", "Big Buck Bunny")); + + // Check each feed item and all fields one-by-one. + { + mojom::MediaFeedItemPtr expected_item = mojom::MediaFeedItem::New(); + expected_item->name = + base::ASCIIToUTF16("Anatomy of a Web Media Experience"); + expected_item->type = mojom::MediaFeedItemType::kVideo; + expected_item->author = mojom::Author::New(); + expected_item->author->name = "Google Chrome Developers"; + expected_item->author->url = + GURL("https://www.youtube.com/user/ChromeDevelopers"); + ASSERT_TRUE( + base::Time::FromString("2019-05-09", &expected_item->date_published)); + expected_item->duration = + base::TimeDelta::FromMinutes(34) + base::TimeDelta::FromSeconds(41); + expected_item->genre.push_back("Factual"); + expected_item->interaction_counters = { + {mojom::InteractionCounterType::kWatch, 7252}, + {mojom::InteractionCounterType::kLike, 94}, + {mojom::InteractionCounterType::kDislike, 4}}; + expected_item->is_family_friendly = true; + expected_item->action = mojom::Action::New(); + expected_item->action->url = + GURL("https://www.youtube.com/watch?v=lXm6jOQLe1Y"); + auto image = mojom::MediaImage::New(); + image->size = ::gfx::Size(336, 188); + image->src = + GURL("https://beccahughes.github.io/media/media-feeds/video1.webp"); + image->content_attributes = {mojom::ContentAttribute::kHasTitle, + mojom::ContentAttribute::kIconic, + mojom::ContentAttribute::kPoster}; + expected_item->images.push_back(std::move(image)); + + auto actual = std::find_if(items.begin(), items.end(), [&](auto& item) { + return item->name == expected_item->name; + }); + + ASSERT_TRUE(actual != items.end()); + EXPECT_EQ(expected_item, *actual); + } + + { + mojom::MediaFeedItemPtr expected_item = mojom::MediaFeedItem::New(); + expected_item->name = base::ASCIIToUTF16( + "Building Modern Web Media Experiences: Picture-in-Picture and AV1"); + expected_item->type = mojom::MediaFeedItemType::kVideo; + expected_item->author = mojom::Author::New(); + expected_item->author->name = "Google Chrome Developers"; + expected_item->author->url = + GURL("https://www.youtube.com/user/ChromeDevelopers"); + ASSERT_TRUE( + base::Time::FromString("2018-11-12", &expected_item->date_published)); + expected_item->duration = + base::TimeDelta::FromMinutes(21) + base::TimeDelta::FromSeconds(24); + expected_item->genre.push_back("Factual"); + auto identifier = mojom::Identifier::New(); + identifier->type = mojom::Identifier::Type::kPartnerId; + identifier->value = "456789876"; + expected_item->identifiers.push_back(std::move(identifier)); + expected_item->interaction_counters = { + {mojom::InteractionCounterType::kWatch, 7252}, + {mojom::InteractionCounterType::kLike, 94}, + {mojom::InteractionCounterType::kDislike, 4}}; + expected_item->is_family_friendly = true; + expected_item->action_status = mojom::MediaFeedItemActionStatus::kActive; + expected_item->action = mojom::Action::New(); + expected_item->action->url = GURL("https://youtu.be/iTC3mfe0DwE?t=10"); + expected_item->action->start_time = base::TimeDelta::FromSeconds(10); + auto image = mojom::MediaImage::New(); + image->size = ::gfx::Size(336, 188); + image->src = + GURL("https://beccahughes.github.io/media/media-feeds/video2.webp"); + image->content_attributes = {mojom::ContentAttribute::kHasTitle, + mojom::ContentAttribute::kIconic, + mojom::ContentAttribute::kPoster}; + expected_item->images.push_back(std::move(image)); + auto image2 = mojom::MediaImage::New(); + image2->size = ::gfx::Size(1884, 982); + image2->src = GURL( + "https://beccahughes.github.io/media/media-feeds/video2_current.png"); + image2->content_attributes = {mojom::ContentAttribute::kSceneStill}; + expected_item->images.push_back(std::move(image2)); + + auto actual = std::find_if(items.begin(), items.end(), [&](auto& item) { + return item->name == expected_item->name; + }); + + ASSERT_TRUE(actual != items.end()); + EXPECT_EQ(expected_item, *actual); + } + + { + mojom::MediaFeedItemPtr expected_item = mojom::MediaFeedItem::New(); + expected_item->name = base::ASCIIToUTF16("Chrome Releases"); + expected_item->type = mojom::MediaFeedItemType::kTVSeries; + ASSERT_TRUE( + base::Time::FromString("2019-11-10", &expected_item->date_published)); + expected_item->genre.push_back("Factual"); + expected_item->is_family_friendly = true; + expected_item->action_status = mojom::MediaFeedItemActionStatus::kActive; + expected_item->action = mojom::Action::New(); + expected_item->action->url = + GURL("https://www.youtube.com/watch?v=L0OB0_bO5I0?t=254"); + expected_item->action->start_time = + base::TimeDelta::FromMinutes(4) + base::TimeDelta::FromSeconds(14); + + expected_item->tv_episode = mojom::TVEpisode::New(); + expected_item->tv_episode->name = "New in Chrome 79"; + expected_item->tv_episode->episode_number = 79; + expected_item->tv_episode->season_number = 1; + expected_item->tv_episode->duration = + base::TimeDelta::FromMinutes(4) + base::TimeDelta::FromSeconds(16); + auto episode_image = mojom::MediaImage::New(); + episode_image->size = ::gfx::Size(336, 188); + episode_image->src = + GURL("https://beccahughes.github.io/media/media-feeds/chrome79.webp"); + episode_image->content_attributes = {mojom::ContentAttribute::kHasTitle, + mojom::ContentAttribute::kIconic, + mojom::ContentAttribute::kPoster}; + expected_item->tv_episode->images.push_back(std::move(episode_image)); + auto episode_image2 = mojom::MediaImage::New(); + episode_image2->size = ::gfx::Size(1874, 970); + episode_image2->src = GURL( + "https://beccahughes.github.io/media/media-feeds/chrome79_current.png"); + episode_image2->content_attributes = {mojom::ContentAttribute::kSceneStill}; + expected_item->tv_episode->images.push_back(std::move(episode_image2)); + + expected_item->play_next_candidate = mojom::PlayNextCandidate::New(); + expected_item->play_next_candidate->name = "New in Chrome 80"; + expected_item->play_next_candidate->episode_number = 80; + expected_item->play_next_candidate->season_number = 1; + expected_item->play_next_candidate->duration = + base::TimeDelta::FromMinutes(6) + base::TimeDelta::FromSeconds(1); + expected_item->play_next_candidate->action = mojom::Action::New(); + expected_item->play_next_candidate->action->url = + GURL("https://www.youtube.com/watch?v=lM0qZpxu0Fg"); + auto play_next_image = mojom::MediaImage::New(); + play_next_image->size = ::gfx::Size(336, 188); + play_next_image->src = + GURL("https://beccahughes.github.io/media/media-feeds/chrome80.webp"); + play_next_image->content_attributes = {mojom::ContentAttribute::kHasTitle, + mojom::ContentAttribute::kIconic, + mojom::ContentAttribute::kPoster}; + expected_item->play_next_candidate->images.push_back( + std::move(play_next_image)); + + auto image = mojom::MediaImage::New(); + image->size = ::gfx::Size(336, 188); + image->src = + GURL("https://beccahughes.github.io/media/media-feeds/chromerel.webp"); + expected_item->images.push_back(std::move(image)); + + auto actual = std::find_if(items.begin(), items.end(), [&](auto& item) { + return item->name == expected_item->name; + }); + + ASSERT_TRUE(actual != items.end()); + EXPECT_EQ(expected_item, *actual); + } + + { + mojom::MediaFeedItemPtr expected_item = mojom::MediaFeedItem::New(); + expected_item->name = base::ASCIIToUTF16("Chrome University"); + expected_item->type = mojom::MediaFeedItemType::kTVSeries; + ASSERT_TRUE( + base::Time::FromString("2020-01-01", &expected_item->date_published)); + expected_item->genre.push_back("Factual"); + expected_item->is_family_friendly = true; + expected_item->action_status = mojom::MediaFeedItemActionStatus::kCompleted; + expected_item->action = mojom::Action::New(); + expected_item->action->url = + GURL("https://www.youtube.com/watch?v=kNzoswFIU9M"); + + expected_item->tv_episode = mojom::TVEpisode::New(); + expected_item->tv_episode->name = "Anatomy of the Browser"; + expected_item->tv_episode->episode_number = 10; + expected_item->tv_episode->season_number = 1; + expected_item->tv_episode->duration = + base::TimeDelta::FromMinutes(15) + base::TimeDelta::FromSeconds(33); + auto episode_image = mojom::MediaImage::New(); + episode_image->size = ::gfx::Size(336, 188); + episode_image->src = + GURL("https://beccahughes.github.io/media/media-feeds/chromeu1.webp"); + episode_image->content_attributes = {mojom::ContentAttribute::kHasTitle, + mojom::ContentAttribute::kIconic, + mojom::ContentAttribute::kPoster}; + expected_item->tv_episode->images.push_back(std::move(episode_image)); + + expected_item->play_next_candidate = mojom::PlayNextCandidate::New(); + expected_item->play_next_candidate->name = "History of the Web"; + expected_item->play_next_candidate->episode_number = 1; + expected_item->play_next_candidate->season_number = 2; + expected_item->play_next_candidate->duration = + base::TimeDelta::FromMinutes(10) + base::TimeDelta::FromSeconds(15); + expected_item->play_next_candidate->action = mojom::Action::New(); + expected_item->play_next_candidate->action->url = + GURL("https://www.youtube.com/watch?v=PzzNuCk-e0Y"); + auto play_next_image = mojom::MediaImage::New(); + play_next_image->size = ::gfx::Size(336, 188); + play_next_image->src = + GURL("https://beccahughes.github.io/media/media-feeds/chromeu2.webp"); + play_next_image->content_attributes = {mojom::ContentAttribute::kHasTitle, + mojom::ContentAttribute::kIconic, + mojom::ContentAttribute::kPoster}; + expected_item->play_next_candidate->images.push_back( + std::move(play_next_image)); + + auto image = mojom::MediaImage::New(); + image->size = ::gfx::Size(336, 188); + image->src = + GURL("https://beccahughes.github.io/media/media-feeds/chromeu.webp"); + image->content_attributes = {mojom::ContentAttribute::kHasTitle, + mojom::ContentAttribute::kIconic, + mojom::ContentAttribute::kPoster}; + expected_item->images.push_back(std::move(image)); + + auto actual = std::find_if(items.begin(), items.end(), [&](auto& item) { + return item->name == expected_item->name; + }); + + ASSERT_TRUE(actual != items.end()); + EXPECT_EQ(expected_item, *actual); + } + + { + mojom::MediaFeedItemPtr expected_item = mojom::MediaFeedItem::New(); + expected_item->name = base::ASCIIToUTF16("JAM stack"); + expected_item->type = mojom::MediaFeedItemType::kTVSeries; + ASSERT_TRUE( + base::Time::FromString("2020-01-22", &expected_item->date_published)); + expected_item->genre.push_back("Factual"); + expected_item->is_family_friendly = true; + expected_item->duration = + base::TimeDelta::FromMinutes(9) + base::TimeDelta::FromSeconds(55); + expected_item->action = mojom::Action::New(); + expected_item->action->url = + GURL("https://www.youtube.com/watch?v=QXsWaA3HTHA"); + + auto image = mojom::MediaImage::New(); + image->size = ::gfx::Size(360, 480); + image->src = + GURL("https://beccahughes.github.io/media/media-feeds/jam.webp"); + image->content_attributes = {mojom::ContentAttribute::kHasTitle, + mojom::ContentAttribute::kIconic, + mojom::ContentAttribute::kPoster}; + expected_item->images.push_back(std::move(image)); + + auto actual = std::find_if(items.begin(), items.end(), [&](auto& item) { + return item->name == expected_item->name; + }); + + ASSERT_TRUE(actual != items.end()); + EXPECT_EQ(expected_item, *actual); + } + + { + mojom::MediaFeedItemPtr expected_item = mojom::MediaFeedItem::New(); + expected_item->name = base::ASCIIToUTF16("Ask Chrome"); + expected_item->type = mojom::MediaFeedItemType::kVideo; + expected_item->author = mojom::Author::New(); + expected_item->author->name = "Google Chrome Developers"; + expected_item->author->url = + GURL("https://www.youtube.com/user/ChromeDevelopers"); + ASSERT_TRUE( + base::Time::FromString("2020-01-27", &expected_item->date_published)); + expected_item->duration = base::TimeDelta::FromMinutes(1); + expected_item->genre.push_back("Factual"); + expected_item->is_family_friendly = true; + expected_item->action = mojom::Action::New(); + expected_item->action->url = + GURL("https://www.youtube.com/watch?v=zJQNQmE6_UI"); + auto image = mojom::MediaImage::New(); + image->size = ::gfx::Size(336, 188); + image->src = + GURL("https://beccahughes.github.io/media/media-feeds/askchrome.webp"); + image->content_attributes = {mojom::ContentAttribute::kHasTitle, + mojom::ContentAttribute::kIconic, + mojom::ContentAttribute::kPoster}; + expected_item->images.push_back(std::move(image)); + expected_item->live = mojom::LiveDetails::New(); + ASSERT_TRUE(base::Time::FromString("2020-03-20T00:00:00+0000", + &expected_item->live->start_time)); + base::Time end_time; + ASSERT_TRUE(base::Time::FromString("2020-12-31T23:59:00+0000", &end_time)); + expected_item->live->end_time = end_time; + + auto actual = std::find_if(items.begin(), items.end(), [&](auto& item) { + return item->name == expected_item->name; + }); + + ASSERT_TRUE(actual != items.end()); + EXPECT_EQ(expected_item, *actual); + } + + { + mojom::MediaFeedItemPtr expected_item = mojom::MediaFeedItem::New(); + expected_item->name = base::ASCIIToUTF16("Big Buck Bunny"); + expected_item->type = mojom::MediaFeedItemType::kMovie; + ASSERT_TRUE( + base::Time::FromString("2008-01-01", &expected_item->date_published)); + auto content_rating = mojom::ContentRating::New(); + content_rating->agency = "MPAA"; + content_rating->value = "G"; + expected_item->content_ratings.push_back(std::move(content_rating)); + expected_item->duration = base::TimeDelta::FromMinutes(12); + expected_item->genre.push_back("Comedy"); + expected_item->is_family_friendly = false; + expected_item->action = mojom::Action::New(); + expected_item->action->url = GURL( + "https://mounirlamouri.github.io/sandbox/media/dynamic-controls.html"); + auto image = mojom::MediaImage::New(); + image->size = ::gfx::Size(1392, 749); + image->src = GURL( + "https://beccahughes.github.io/media/media-feeds/big_buck_bunny.jpg"); + image->content_attributes = {mojom::ContentAttribute::kHasTitle, + mojom::ContentAttribute::kIconic, + mojom::ContentAttribute::kPoster}; + expected_item->images.push_back(std::move(image)); + auto image2 = mojom::MediaImage::New(); + image2->size = ::gfx::Size(1600, 900); + image2->src = GURL( + "https://beccahughes.github.io/media/media-feeds/" + "big_buck_bunny_bg.jpg"); + image2->content_attributes = {mojom::ContentAttribute::kIconic, + mojom::ContentAttribute::kBackground}; + expected_item->images.push_back(std::move(image2)); + + auto actual = std::find_if(items.begin(), items.end(), [&](auto& item) { + return item->name == expected_item->name; + }); + + ASSERT_TRUE(actual != items.end()); + EXPECT_EQ(expected_item, *actual); + } } // Media feeds should successfully fetch and convert a minimal example feed
diff --git a/chrome/browser/media/router/providers/cast/cast_activity_manager.cc b/chrome/browser/media/router/providers/cast/cast_activity_manager.cc index e8a34d5..863b918 100644 --- a/chrome/browser/media/router/providers/cast/cast_activity_manager.cc +++ b/chrome/browser/media/router/providers/cast/cast_activity_manager.cc
@@ -89,6 +89,8 @@ MediaRoute::GetMediaRouteId(presentation_id, sink_id, source); MediaRoute route(route_id, source, sink_id, /* description */ std::string(), /* is_local */ true, /* for_display */ true); + route.set_presentation_id(presentation_id); + route.set_local_presentation(true); route.set_incognito(incognito); if (cast_source.ContainsStreamingApp()) { route.set_controller_type(RouteControllerType::kMirroring); @@ -161,6 +163,7 @@ } message_handler_->LaunchSession( sink.cast_data().cast_channel_id, app_id, launch_timeout, type_str, + cast_source.app_params(), base::BindOnce(&CastActivityManager::HandleLaunchSessionResponse, weak_ptr_factory_.GetWeakPtr(), route_id, sink, cast_source));
diff --git a/chrome/browser/media/router/providers/cast/cast_activity_manager_unittest.cc b/chrome/browser/media/router/providers/cast/cast_activity_manager_unittest.cc index f206be8..0d02a1ee 100644 --- a/chrome/browser/media/router/providers/cast/cast_activity_manager_unittest.cc +++ b/chrome/browser/media/router/providers/cast/cast_activity_manager_unittest.cc
@@ -14,6 +14,7 @@ #include "base/bind_helpers.h" #include "base/optional.h" #include "base/run_loop.h" +#include "base/strings/strcat.h" #include "base/task/post_task.h" #include "base/test/bind_test_util.h" #include "base/test/mock_callback.h" @@ -54,9 +55,11 @@ constexpr int kTabId = 1; constexpr char kAppId1[] = "ABCDEFGH"; constexpr char kAppId2[] = "BBBBBBBB"; +constexpr char kAppParams[] = "{params:\"value\"}"; std::string MakeSourceId(const std::string& app_id = kAppId1) { - return "cast:" + app_id + "?clientId=theClientId"; + return base::StrCat( + {"cast:", app_id, "?clientId=theClientId&appParams=", kAppParams}); } base::Value MakeReceiverStatus(const std::string& app_id, @@ -174,8 +177,8 @@ std::vector<std::string> supported_app_types = {"WEB"}; EXPECT_CALL(message_handler_, LaunchSession(kChannelId, app_id, kDefaultLaunchTimeout, - supported_app_types, _)) - .WillOnce(WithArg<4>([this](auto callback) { + supported_app_types, kAppParams, _)) + .WillOnce(WithArg<5>([this](auto callback) { launch_session_callback_ = std::move(callback); })); @@ -390,12 +393,12 @@ std::move(stop_session_callback_).Run(cast_channel::Result::kOk); - // LaunchSession() should not be called until we notify |maanger_| that the + // LaunchSession() should not be called until we notify |mananger_| that the // previous session was removed. std::vector<std::string> supported_app_types = {"WEB"}; EXPECT_CALL(message_handler_, LaunchSession(kChannelId, "BBBBBBBB", kDefaultLaunchTimeout, - supported_app_types, _)); + supported_app_types, _, _)); manager_->OnSessionRemoved(sink_); }
diff --git a/chrome/browser/media/router/providers/cast/cast_media_route_provider_unittest.cc b/chrome/browser/media/router/providers/cast/cast_media_route_provider_unittest.cc index 335c332..cc3985d6 100644 --- a/chrome/browser/media/router/providers/cast/cast_media_route_provider_unittest.cc +++ b/chrome/browser/media/router/providers/cast/cast_media_route_provider_unittest.cc
@@ -28,7 +28,15 @@ namespace { static constexpr char kAppId[] = "ABCDEFGH"; -static constexpr char kCastSource[] = "cast:ABCDEFGH?clientId=123"; +static constexpr char kAppParams[] = + "{requiredFeatures:[\"STREAM_TRANSFER\"],launchCheckerParams:{" + "credentialsData:{credentialsType:\"mobile\",credentials:" + "\"99843n2idsguyhga\"}}}"; +static constexpr char kCastSource[] = + "cast:ABCDEFGH?clientId=123&appParams=%7BrequiredFeatures%3A%5B%22STREAM_" + "TRANSFER%22%5D%2ClaunchCheckerParams%3A%7BcredentialsData%3A%" + "7BcredentialsType%3A%22mobile%22%2Ccredentials%3A%2299843n2idsguyhga%22%" + "7D%7D%7D"; static constexpr char kPresentationId[] = "presentationId"; static constexpr char kOrigin[] = "https://www.youtube.com"; static constexpr int kTabId = 1; @@ -180,9 +188,10 @@ media_sink_service_.AddOrUpdateSink(sink); std::vector<std::string> default_supported_app_types = {"WEB"}; - EXPECT_CALL(message_handler_, LaunchSession(sink.cast_data().cast_channel_id, - kAppId, kDefaultLaunchTimeout, - default_supported_app_types, _)); + EXPECT_CALL(message_handler_, + LaunchSession(sink.cast_data().cast_channel_id, kAppId, + kDefaultLaunchTimeout, default_supported_app_types, + kAppParams, _)); provider_->CreateRoute( kCastSource, sink.sink().id(), kPresentationId, origin_, kTabId, kRouteTimeout, /* incognito */ false, @@ -195,7 +204,7 @@ MediaSinkInternal sink = CreateCastSink(1); media_sink_service_.AddOrUpdateSink(sink); - EXPECT_CALL(message_handler_, LaunchSession(_, _, _, _, _)); + EXPECT_CALL(message_handler_, LaunchSession(_, _, _, _, _, _)); provider_->CreateRoute( kCastSource, sink.sink().id(), kPresentationId, origin_, kTabId, kRouteTimeout, /* incognito */ false,
diff --git a/chrome/browser/media/router/providers/cast/mirroring_activity_record.cc b/chrome/browser/media/router/providers/cast/mirroring_activity_record.cc index 03316181..29a1a1a 100644 --- a/chrome/browser/media/router/providers/cast/mirroring_activity_record.cc +++ b/chrome/browser/media/router/providers/cast/mirroring_activity_record.cc
@@ -71,10 +71,48 @@ } } -MirroringType GetMirroringType(const MediaRoute& route, int tab_id) { +// Get the mirroring type for a media route. Note that |target_tab_id| is +// usually ignored here, because mirroring typically only happens with a special +// URL that includes the tab ID it needs, which should be the same as the tab ID +// selected by the media router. +base::Optional<MirroringActivityRecord::MirroringType> GetMirroringType( + const MediaRoute& route, + int target_tab_id) { if (!route.is_local()) - return MirroringType::kNonLocal; - return tab_id == -1 ? MirroringType::kDesktop : MirroringType::kTab; + return base::nullopt; + + const auto source = route.media_source(); + if (source.IsTabMirroringSource()) + return MirroringActivityRecord::MirroringType::kTab; + if (source.IsDesktopMirroringSource()) + return MirroringActivityRecord::MirroringType::kDesktop; + + if (source.url().is_valid()) { + if (source.IsCastPresentationUrl()) { + const auto cast_source = CastMediaSource::FromMediaSource(source); + if (cast_source && cast_source->ContainsStreamingApp()) { + // This is a weird case. Normally if the source is a presentation URL, + // we use 2-UA mode rather than mirroring, but if the app ID it + // specifies is one of the special streaming app IDs, we activate + // mirroring instead. This only happens when a Cast SDK client requests + // a mirroring app ID, which causes its own tab to be mirrored. This is + // a strange thing to do and it's not officially supported, but some + // apps, like, Google Slides rely on it. Unlike a proper tab-based + // MediaSource, this kind of MediaSource doesn't specify a tab in the + // URL, so we choose the tab that was active when the request was made. + DCHECK_GE(target_tab_id, 0); + return MirroringActivityRecord::MirroringType::kTab; + } else { + NOTREACHED() << "Non-mirroring Cast app: " << source; + return base::nullopt; + } + } else if (source.url().SchemeIsHTTPOrHTTPS()) { + return MirroringActivityRecord::MirroringType::kOffscreenTab; + } + } + + NOTREACHED() << "Invalid source: " << source; + return base::nullopt; } } // namespace @@ -90,17 +128,22 @@ OnStopCallback callback) : ActivityRecord(route, app_id, message_handler, session_tracker), channel_id_(cast_data.cast_channel_id), - // TODO(jrw): MirroringType::kOffscreenTab should be a possible value here - // once the Presentation API 1UA mode is supported. mirroring_type_(GetMirroringType(route, target_tab_id)), on_stop_(std::move(callback)) { // TODO(jrw): Detect and report errors. mirroring_tab_id_ = target_tab_id; + if (!mirroring_type_) { + // Non-local activity doesn't need to handle messages, so return without + // setting up Mojo bindings. + return; + } + // Get a reference to the mirroring service host. - switch (mirroring_type_) { + switch (*mirroring_type_) { case MirroringType::kDesktop: { + DCHECK_EQ(target_tab_id, -1); auto stream_id = route.media_source().DesktopStreamId(); DCHECK(stream_id); media_router->GetMirroringServiceHostForDesktop( @@ -108,15 +151,15 @@ break; } case MirroringType::kTab: + DCHECK_GE(target_tab_id, 0); media_router->GetMirroringServiceHostForTab( target_tab_id, host_.BindNewPipeAndPassReceiver()); break; - case MirroringType::kNonLocal: - // Non-local activity doesn't need to handle messages, so return without - // setting up Mojo bindings. - return; - default: - NOTREACHED(); + case MirroringType::kOffscreenTab: + media_router->GetMirroringServiceHostForOffscreenTab( + route.media_source().url(), route.presentation_id(), + host_.BindNewPipeAndPassReceiver()); + break; } // Derive session type from capabilities. @@ -169,7 +212,8 @@ base::UmaHistogramTimes( kHistogramSessionLaunch, *did_start_mirroring_timestamp_ - *will_start_mirroring_timestamp_); - base::UmaHistogramEnumeration(kHistogramStartSuccess, mirroring_type_); + DCHECK(mirroring_type_); + base::UmaHistogramEnumeration(kHistogramStartSuccess, *mirroring_type_); will_start_mirroring_timestamp_.reset(); }
diff --git a/chrome/browser/media/router/providers/cast/mirroring_activity_record.h b/chrome/browser/media/router/providers/cast/mirroring_activity_record.h index fde2f06..16a7b82 100644 --- a/chrome/browser/media/router/providers/cast/mirroring_activity_record.h +++ b/chrome/browser/media/router/providers/cast/mirroring_activity_record.h
@@ -39,8 +39,7 @@ kTab, // Mirror a single tab. kDesktop, // Mirror the whole desktop. kOffscreenTab, // Used for Presentation API 1UA mode. - kNonLocal, // Activity started by other sender devices. - kMaxValue = kNonLocal, + kMaxValue = kOffscreenTab, }; MirroringActivityRecord(const MediaRoute& route, @@ -95,7 +94,7 @@ base::Optional<base::Time> did_start_mirroring_timestamp_; const int channel_id_; - const MirroringType mirroring_type_; + const base::Optional<MirroringType> mirroring_type_; OnStopCallback on_stop_; base::WeakPtrFactory<MirroringActivityRecord> weak_ptr_factory_{this}; };
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.cc index 98b25e4..a2353132 100644 --- a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.cc
@@ -46,6 +46,8 @@ #include "services/metrics/public/cpp/ukm_recorder.h" #include "third_party/blink/public/mojom/web_feature/web_feature.mojom.h" #include "ui/base/page_transition_types.h" +#include "ui/gfx/geometry/point.h" +#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" #include "url/gurl.h" @@ -310,6 +312,7 @@ if (should_ignore_detected_ad && (ad_id == previous_data->root_frame_tree_node_id())) { + page_ad_density_tracker_.RemoveRect(id_and_data->first); ad_frames_data_storage_.erase(id_and_data->second); ad_frames_data_.erase(id_and_data); @@ -530,6 +533,35 @@ ancestor_data->set_media_status(FrameData::MediaStatus::kPlayed); } +void AdsPageLoadMetricsObserver::OnFrameIntersectionUpdate( + content::RenderFrameHost* render_frame_host, + const page_load_metrics::mojom::FrameIntersectionUpdate& + intersection_update) { + if (!intersection_update.main_frame_document_intersection_rect) + return; + + int frame_tree_node_id = render_frame_host->GetFrameTreeNodeId(); + if (render_frame_host == GetDelegate().GetWebContents()->GetMainFrame()) { + page_ad_density_tracker_.UpdateMainFrameRect( + *intersection_update.main_frame_document_intersection_rect); + return; + } + + // If the frame whose size has changed is the root of the ad ancestry chain, + // then update it. + FrameData* ancestor_data = FindFrameData(frame_tree_node_id); + if (ancestor_data && + frame_tree_node_id == ancestor_data->root_frame_tree_node_id()) { + page_ad_density_tracker_.RemoveRect(frame_tree_node_id); + // Only add frames if they are visible. + if (!ancestor_data->is_display_none()) { + page_ad_density_tracker_.AddRect( + frame_tree_node_id, + *intersection_update.main_frame_document_intersection_rect); + } + } +} + void AdsPageLoadMetricsObserver::OnFrameDeleted( content::RenderFrameHost* render_frame_host) { if (!render_frame_host) @@ -555,6 +587,7 @@ ancestor_data->RecordAdFrameLoadUkmEvent(GetDelegate().GetSourceId()); DCHECK(id_and_data->second != ad_frames_data_storage_.end()); ad_frames_data_storage_.erase(id_and_data->second); + page_ad_density_tracker_.RemoveRect(id_and_data->first); } // Delete this frame's entry from the map now that the store is deleted. @@ -685,6 +718,24 @@ return; PAGE_BYTES_HISTOGRAM("PageLoad.Clients.Ads.Resources.Bytes.Ads2", aggregate_frame_data_->ad_network_bytes()); + + if (page_ad_density_tracker_.MaxPageAdDensityByArea() != -1) { + UMA_HISTOGRAM_PERCENTAGE("PageLoad.Clients.Ads.AdDensity.MaxPercentByArea", + page_ad_density_tracker_.MaxPageAdDensityByArea()); + } + + if (page_ad_density_tracker_.MaxPageAdDensityByHeight() != -1) { + UMA_HISTOGRAM_PERCENTAGE( + "PageLoad.Clients.Ads.AdDensity.MaxPercentByHeight", + page_ad_density_tracker_.MaxPageAdDensityByHeight()); + } + + // Records true if both of the density calculations succeeded on the page. + UMA_HISTOGRAM_BOOLEAN( + "PageLoad.Clients.Ads.AdDensity.Recorded", + page_ad_density_tracker_.MaxPageAdDensityByArea() != -1 && + page_ad_density_tracker_.MaxPageAdDensityByHeight() != -1); + auto* ukm_recorder = ukm::UkmRecorder::Get(); ukm::builders::AdPageLoad builder(source_id); builder.SetTotalBytes(aggregate_frame_data_->network_bytes() >> 10) @@ -696,7 +747,10 @@ FrameData::ResourceMimeType::kVideo) >> 10) .SetMainframeAdBytes(ukm::GetExponentialBucketMinForBytes( - main_frame_data_->ad_network_bytes())); + main_frame_data_->ad_network_bytes())) + .SetMaxAdDensityByArea(page_ad_density_tracker_.MaxPageAdDensityByArea()) + .SetMaxAdDensityByHeight( + page_ad_density_tracker_.MaxPageAdDensityByHeight()); // Record cpu metrics for the page. builder.SetAdCpuTime(
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.h index 66c9785..07483ca9 100644 --- a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.h +++ b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.h
@@ -14,6 +14,7 @@ #include "base/scoped_observer.h" #include "base/time/tick_clock.h" #include "chrome/browser/page_load_metrics/observers/ad_metrics/frame_data.h" +#include "chrome/browser/page_load_metrics/observers/ad_metrics/page_ad_density_tracker.h" #include "components/page_load_metrics/browser/page_load_metrics_observer.h" #include "components/page_load_metrics/common/page_load_metrics.mojom-forward.h" #include "components/subresource_filter/content/browser/subresource_filter_observer.h" @@ -120,6 +121,10 @@ void MediaStartedPlaying( const content::WebContentsObserver::MediaPlayerInfo& video_type, content::RenderFrameHost* render_frame_host) override; + void OnFrameIntersectionUpdate( + content::RenderFrameHost* render_frame_host, + const page_load_metrics::mojom::FrameIntersectionUpdate& + intersection_update) override; void OnFrameDeleted(content::RenderFrameHost* render_frame_host) override; void SetHeavyAdThresholdNoiseProviderForTesting( @@ -270,6 +275,9 @@ std::unique_ptr<HeavyAdThresholdNoiseProvider> heavy_ad_threshold_noise_provider_; + // The maximum ad density measurements for the page during it's lifecycle. + PageAdDensityTracker page_ad_density_tracker_; + DISALLOW_COPY_AND_ASSIGN(AdsPageLoadMetricsObserver); };
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 e8486ed..dacf3b2f 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
@@ -77,6 +77,15 @@ const char kHeavyAdInterventionTypeHistogramId[] = "PageLoad.Clients.Ads.HeavyAds.InterventionType2"; +const char kMaxAdDensityByAreaHistogramId[] = + "PageLoad.Clients.Ads.AdDensity.MaxPercentByArea"; + +const char kMaxAdDensityByHeightHistogramId[] = + "PageLoad.Clients.Ads.AdDensity.MaxPercentByHeight"; + +const char kMaxAdDensityRecordedHistogramId[] = + "PageLoad.Clients.Ads.AdDensity.Recorded"; + const char kHttpOkResponseHeader[] = "HTTP/1.1 200 OK\r\n" "Content-Type: text/html; charset=utf-8\r\n" @@ -231,6 +240,248 @@ static_cast<int>(FrameData::OriginStatus::kCross)); } +// Verifies that the page ad density records the maximum value during +// a page's lifecycling by creating a large ad frame, destroying it, and +// creating a smaller iframe. The ad density recorded is the density with +// the first larger frame. +IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest, + PageAdDensityRecordsPageMax) { + base::HistogramTester histogram_tester; + ukm::TestAutoSetUkmRecorder ukm_recorder; + auto waiter = CreatePageLoadMetricsTestWaiter(); + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + // Evaluate the height and width of the page as the browser_test can + // vary the dimensions. + int document_height = + EvalJs(web_contents, "document.body.scrollHeight").ExtractInt(); + int document_width = + EvalJs(web_contents, "document.body.scrollWidth").ExtractInt(); + + // Expectation is before NavigateToUrl for this test as the expectation can be + // met after NavigateToUrl and before the Wait. + waiter->AddMainFrameDocumentIntersectionExpectation( + gfx::Rect(0, 0, document_width, + document_height)); // Initial main frame rect. + ui_test_utils::NavigateToURL( + browser(), embedded_test_server()->GetURL( + "a.com", "/ads_observer/blank_with_adiframe_writer.html")); + waiter->Wait(); + web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + + // Create a frame at 100,100 of size 200,200. + waiter->AddMainFrameDocumentIntersectionExpectation( + gfx::Rect(100, 100, 200, 200)); + + // Create the frame with b.com as origin to not get caught by + // restricted ad tagging. + EXPECT_TRUE(ExecJs( + web_contents, + content::JsReplace( + "let frame = createAdIframeAtRect(100, 100, 200, 200); " + "frame.src = $1; ", + embedded_test_server()->GetURL("b.com", "/ads_observer/pixel.png")))); + waiter->Wait(); + + // Load should stop before we remove the frame. + EXPECT_TRUE(WaitForLoadStop(web_contents)); + EXPECT_TRUE(ExecJs(web_contents, + "let frames = document.getElementsByTagName('iframe'); " + "frames[0].remove(); ")); + waiter->AddMainFrameDocumentIntersectionExpectation( + gfx::Rect(400, 400, 10, 10)); + + // Delete the frame and create a new frame at 400,400 of size 10x10. The + // ad density resulting from this frame is lower than the 200x200. + EXPECT_TRUE(ExecJs( + web_contents, + content::JsReplace("let frame = createAdIframeAtRect(400, 400, 10, 10); " + "frame.src = $1; ", + embedded_test_server() + ->GetURL("b.com", "/ads_observer/pixel.png") + .spec()))); + waiter->Wait(); + + // Evaluate the height and width of the page as the browser_test can + // vary the dimensions. + document_height = + EvalJs(web_contents, "document.body.scrollHeight").ExtractInt(); + document_width = + EvalJs(web_contents, "document.body.scrollWidth").ExtractInt(); + + int page_area = document_width * document_height; + int ad_area = 200 * 200; // The area of the first larger ad iframe. + int expected_page_density_area = ad_area * 100 / page_area; + int expected_page_density_height = 200 * 100 / document_height; + + ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)); + + histogram_tester.ExpectUniqueSample(kMaxAdDensityByAreaHistogramId, + expected_page_density_area, 1); + histogram_tester.ExpectUniqueSample(kMaxAdDensityByHeightHistogramId, + expected_page_density_height, 1); + histogram_tester.ExpectUniqueSample(kMaxAdDensityRecordedHistogramId, true, + 1); + auto entries = + ukm_recorder.GetEntriesByName(ukm::builders::AdPageLoad::kEntryName); + EXPECT_EQ(1u, entries.size()); + ukm_recorder.ExpectEntryMetric( + entries.front(), ukm::builders::AdPageLoad::kMaxAdDensityByAreaName, + expected_page_density_area); + ukm_recorder.ExpectEntryMetric( + entries.front(), ukm::builders::AdPageLoad::kMaxAdDensityByHeightName, + expected_page_density_height); +} + +// Creates multiple overlapping frames and verifies the page ad density. +IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest, + PageAdDensityMultipleFrames) { + base::HistogramTester histogram_tester; + ukm::TestAutoSetUkmRecorder ukm_recorder; + auto waiter = CreatePageLoadMetricsTestWaiter(); + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + int document_height = + EvalJs(web_contents, "document.body.scrollHeight").ExtractInt(); + int document_width = + EvalJs(web_contents, "document.body.scrollWidth").ExtractInt(); + + // Expectation is before NavigateToUrl for this test as the expectation can be + // met after NavigateToUrl and before the Wait. + waiter->AddMainFrameDocumentIntersectionExpectation( + gfx::Rect(0, 0, document_width, + document_height)); // Initial main frame rect. + + ui_test_utils::NavigateToURL( + browser(), embedded_test_server()->GetURL( + "a.com", "/ads_observer/blank_with_adiframe_writer.html")); + waiter->Wait(); + web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + + // Create a frame of size 400,400 at 100,100. + waiter->AddMainFrameDocumentIntersectionExpectation( + gfx::Rect(400, 400, 100, 100)); + + // Create the frame with b.com as origin to not get caught by + // restricted ad tagging. + EXPECT_TRUE(ExecJs( + web_contents, content::JsReplace( + "let frame = createAdIframeAtRect(400, 400, 100, 100); " + "frame.src = $1", + embedded_test_server() + ->GetURL("b.com", "/ads_observer/pixel.png") + .spec()))); + + waiter->Wait(); + + // Create a frame at of size 200,200 at 450,450. + waiter->AddMainFrameDocumentIntersectionExpectation( + gfx::Rect(450, 450, 200, 200)); + EXPECT_TRUE(ExecJs( + web_contents, content::JsReplace( + "let frame = createAdIframeAtRect(450, 450, 200, 200); " + "frame.src = $1", + embedded_test_server() + ->GetURL("b.com", "/ads_observer/pixel.png") + .spec()))); + waiter->Wait(); + + // Evaluate the height and width of the page as the browser_test can + // vary the dimensions. + document_height = + EvalJs(web_contents, "document.body.scrollHeight").ExtractInt(); + document_width = + EvalJs(web_contents, "document.body.scrollWidth").ExtractInt(); + + ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)); + + int page_area = document_width * document_height; + // The area of the two iframes minus the area of the overlapping section. + int ad_area = 100 * 100 + 200 * 200 - 50 * 50; + int expected_page_density_area = ad_area * 100 / page_area; + int expected_page_density_height = 250 * 100 / document_height; + + histogram_tester.ExpectUniqueSample(kMaxAdDensityByAreaHistogramId, + expected_page_density_area, 1); + histogram_tester.ExpectUniqueSample(kMaxAdDensityByHeightHistogramId, + expected_page_density_height, 1); + histogram_tester.ExpectUniqueSample(kMaxAdDensityRecordedHistogramId, true, + 1); + auto entries = + ukm_recorder.GetEntriesByName(ukm::builders::AdPageLoad::kEntryName); + EXPECT_EQ(1u, entries.size()); + ukm_recorder.ExpectEntryMetric( + entries.front(), ukm::builders::AdPageLoad::kMaxAdDensityByAreaName, + expected_page_density_area); + ukm_recorder.ExpectEntryMetric( + entries.front(), ukm::builders::AdPageLoad::kMaxAdDensityByHeightName, + expected_page_density_height); +} + +// Creates a frame with display:none styling and verifies that it has an +// empty intersection with the main frame. +IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest, + PageAdDensityIgnoreDisplayNoneFrame) { + base::HistogramTester histogram_tester; + ukm::TestAutoSetUkmRecorder ukm_recorder; + auto waiter = CreatePageLoadMetricsTestWaiter(); + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + // Evaluate the height and width of the page as the browser_test can + // vary the dimensions. + int document_height = + EvalJs(web_contents, "document.body.scrollHeight").ExtractInt(); + int document_width = + EvalJs(web_contents, "document.body.scrollWidth").ExtractInt(); + + // Expectation is before NavigateToUrl for this test as the expectation can be + // met after NavigateToUrl and before the Wait. + waiter->AddMainFrameDocumentIntersectionExpectation( + gfx::Rect(0, 0, document_width, + document_height)); // Initial main frame rect. + + ui_test_utils::NavigateToURL( + browser(), embedded_test_server()->GetURL( + "a.com", "/ads_observer/blank_with_adiframe_writer.html")); + waiter->Wait(); + web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + + // Create a frame at 100,100 of size 200,200. The expectation is an empty rect + // as the frame is display:none and as a result has no main frame + // intersection. + waiter->AddMainFrameDocumentIntersectionExpectation(gfx::Rect(0, 0, 0, 0)); + + // Create the frame with b.com as origin to not get caught by + // restricted ad tagging. + EXPECT_TRUE(ExecJs( + web_contents, content::JsReplace( + "let frame = createAdIframeAtRect(100, 100, 200, 200); " + "frame.src = $1; " + "frame.style.display = \"none\";", + embedded_test_server() + ->GetURL("b.com", "/ads_observer/pixel.png") + .spec()))); + + waiter->Wait(); + + ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)); + + histogram_tester.ExpectUniqueSample(kMaxAdDensityByAreaHistogramId, 0, 1); + histogram_tester.ExpectUniqueSample(kMaxAdDensityByHeightHistogramId, 0, 1); + histogram_tester.ExpectUniqueSample(kMaxAdDensityRecordedHistogramId, true, + 1); + auto entries = + ukm_recorder.GetEntriesByName(ukm::builders::AdPageLoad::kEntryName); + EXPECT_EQ(1u, entries.size()); + ukm_recorder.ExpectEntryMetric( + entries.front(), ukm::builders::AdPageLoad::kMaxAdDensityByAreaName, 0); + ukm_recorder.ExpectEntryMetric( + entries.front(), ukm::builders::AdPageLoad::kMaxAdDensityByHeightName, 0); +} + // Each CreativeOriginStatus* browser test inputs a pointer to a frame object // representing the frame tree path of a website with with a (possibly null) // ad subframe, which itself may have linearly nested subframes.
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/frame_data.h b/chrome/browser/page_load_metrics/observers/ad_metrics/frame_data.h index 33fe5ad..3d3e16ee 100644 --- a/chrome/browser/page_load_metrics/observers/ad_metrics/frame_data.h +++ b/chrome/browser/page_load_metrics/observers/ad_metrics/frame_data.h
@@ -213,6 +213,8 @@ gfx::Size frame_size() const { return frame_size_; } + bool is_display_none() const { return is_display_none_; } + MediaStatus media_status() const { return media_status_; } void set_media_status(MediaStatus media_status) {
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/page_ad_density_tracker.cc b/chrome/browser/page_load_metrics/observers/ad_metrics/page_ad_density_tracker.cc new file mode 100644 index 0000000..4daffc7 --- /dev/null +++ b/chrome/browser/page_load_metrics/observers/ad_metrics/page_ad_density_tracker.cc
@@ -0,0 +1,297 @@ +// 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/page_load_metrics/observers/ad_metrics/page_ad_density_tracker.h" +#include "base/metrics/histogram_macros.h" +#include "base/numerics/checked_math.h" +#include "base/optional.h" + +namespace { + +// Calculates the combined length of a set of line segments. This counts +// each overlapping area a single time and does not include areas where there +// is no line segment. +// +// TODO(https://crbug.com/1068586): Optimize segment length calculation. +// AddSegment and RemoveSegment are both logarithmic operations, making this +// linearithmic with the number of segments. However the expected number +// of segments at any given time in the density calculation is low. +class SegmentLength { + public: + // An event to process corresponding to the left or right point of each + // line segment. + struct SegmentEvent { + SegmentEvent(int segment_id, int pos, bool is_segment_start) + : segment_id(segment_id), + pos(pos), + is_segment_start(is_segment_start) {} + SegmentEvent(const SegmentEvent& other) = default; + + // Tiebreak with position with |is_segment_start| and |segment_id|. + bool operator<(const SegmentEvent& rhs) const { + if (pos == rhs.pos) { + if (segment_id == rhs.segment_id) { + return is_segment_start != rhs.is_segment_start; + } else { + return segment_id < rhs.segment_id; + } + } else { + return pos < rhs.pos; + } + } + + int segment_id; + int pos; + bool is_segment_start; + }; + + // Iterators into the set of segment events for efficient removal of + // segment events by segment_id. Maintained by |segment_event_iterators_|. + struct SegmentEventSetIterators { + SegmentEventSetIterators(std::set<SegmentEvent>::iterator start, + std::set<SegmentEvent>::iterator end) + : start_it(start), end_it(end) {} + + SegmentEventSetIterators(const SegmentEventSetIterators& other) = default; + + std::set<SegmentEvent>::const_iterator start_it; + std::set<SegmentEvent>::const_iterator end_it; + }; + + SegmentLength() = default; + ~SegmentLength() = default; + + // Add a line segment to the set of active line segments, the segment + // corresponds to the bottom or top of a rect. + void AddSegment(int segment_id, int start, int end) { + // Safe as insert will never return an invalid iterator, it will + // point to the existing element if already in the set. + auto start_it = + active_segments_ + .insert(SegmentEvent(segment_id, start, true /*is_segment_start*/)) + .first; + auto end_it = + active_segments_ + .insert(SegmentEvent(segment_id, end, false /*is_segment_start*/)) + .first; + + segment_event_iterators_.emplace( + segment_id, SegmentEventSetIterators(start_it, end_it)); + } + + // Remove a segment from the set of active line segmnets. + void RemoveSegment(int segment_id) { + auto it = segment_event_iterators_.find(segment_id); + DCHECK(it != segment_event_iterators_.end()); + + const SegmentEventSetIterators& set_its = it->second; + active_segments_.erase(set_its.start_it); + active_segments_.erase(set_its.end_it); + segment_event_iterators_.erase(segment_id); + } + + // Calculate the combined length of segments in the active set of segments by + // iterating over the the sorted set of segment events. + base::Optional<int> Length() { + base::CheckedNumeric<int> length = 0; + int last_event_pos = -1; + int num_active = 0; + for (const auto& segment_event : active_segments_) { + if (last_event_pos == -1) { + DCHECK(segment_event.is_segment_start); + last_event_pos = segment_event.pos; + } + + if (num_active > 0) + length += segment_event.pos - last_event_pos; + + last_event_pos = segment_event.pos; + if (segment_event.is_segment_start) { + num_active += 1; + } else { + num_active -= 1; + } + } + + base::Optional<int> total_length; + if (length.IsValid()) + total_length = length.ValueOrDie(); + + return total_length; + } + + private: + std::set<SegmentEvent> active_segments_; + + // Map from the segment_id passed by user to the Segment struct. + std::unordered_map<int, SegmentEventSetIterators> segment_event_iterators_; + + DISALLOW_COPY_AND_ASSIGN(SegmentLength); +}; + +} // namespace + +PageAdDensityTracker::RectEvent::RectEvent(int id, + bool is_bottom, + const gfx::Rect& rect) + : rect_id(id), is_bottom(is_bottom), rect(rect) {} + +PageAdDensityTracker::RectEvent::RectEvent(const RectEvent& other) = default; + +PageAdDensityTracker::RectEventSetIterators::RectEventSetIterators( + std::set<RectEvent>::iterator top, + std::set<RectEvent>::iterator bottom) + : top_it(top), bottom_it(bottom) {} + +PageAdDensityTracker::RectEventSetIterators::RectEventSetIterators( + const RectEventSetIterators& other) = default; + +PageAdDensityTracker::PageAdDensityTracker() = default; + +PageAdDensityTracker::~PageAdDensityTracker() = default; + +int PageAdDensityTracker::MaxPageAdDensityByHeight() { + return max_page_ad_density_by_height_; +} + +int PageAdDensityTracker::MaxPageAdDensityByArea() { + return max_page_ad_density_by_area_; +} + +void PageAdDensityTracker::AddRect(int rect_id, const gfx::Rect& rect) { + // Check that we do not already have rect events for the rect. + DCHECK(rect_events_iterators_.find(rect_id) == rect_events_iterators_.end()); + + // We do not track empty rects. + if (rect.IsEmpty()) + return; + + // Limit the maximum number of rects tracked to 50 due to poor worst + // case performance. + const int kMaxRectsTracked = 50; + if (rect_events_iterators_.size() > kMaxRectsTracked) + return; + + auto top_it = + rect_events_.insert(RectEvent(rect_id, true /*is_bottom*/, rect)).first; + auto bottom_it = + rect_events_.insert(RectEvent(rect_id, false /*is_bottom*/, rect)).first; + rect_events_iterators_.emplace(rect_id, + RectEventSetIterators(top_it, bottom_it)); + + // TODO(https://crbug.com/1068586): Improve performance by adding additional + // throttling to only calculate when max density can decrease (frame deleted + // or moved). + CalculateDensity(); +} + +void PageAdDensityTracker::RemoveRect(int rect_id) { + auto it = rect_events_iterators_.find(rect_id); + + if (it == rect_events_iterators_.end()) + return; + + const RectEventSetIterators& set_its = it->second; + rect_events_.erase(set_its.top_it); + rect_events_.erase(set_its.bottom_it); + rect_events_iterators_.erase(rect_id); +} + +void PageAdDensityTracker::UpdateMainFrameRect(const gfx::Rect& rect) { + if (!last_main_frame_size_ || rect != *last_main_frame_size_) { + last_main_frame_size_ = rect; + CalculateDensity(); + } +} + +// Ad density measurement uses a modified Bentley's Algorithm, the high level +// approach is described on: http://jeffe.cs.illinois.edu/open/klee.html. +void PageAdDensityTracker::CalculateDensity() { + // Cannot calculate density if there is no main frame rect. + if (!last_main_frame_size_) + return; + + SegmentLength segment_length_tracker; + + int last_y = -1; + base::CheckedNumeric<int> total_area = 0; + base::CheckedNumeric<int> total_height = 0; + for (const auto& rect_event : rect_events_) { + if (last_y == -1) { + DCHECK(rect_event.is_bottom); + segment_length_tracker.AddSegment( + rect_event.rect_id, rect_event.rect.x(), + rect_event.rect.x() + rect_event.rect.width()); + last_y = + rect_event.is_bottom ? rect_event.rect.bottom() : rect_event.rect.y(); + } + + int current_y = + rect_event.is_bottom ? rect_event.rect.bottom() : rect_event.rect.y(); + DCHECK_LE(current_y, last_y); + + // If the segment length value is invalid, skip this ad density calculation. + base::Optional<int> segment_length = segment_length_tracker.Length(); + if (!segment_length) + return; + + // Check that the segment length multiplied by the height of the block + // does not overflow an int. + base::CheckedNumeric<int> current_area = *segment_length; + current_area *= (last_y - current_y); + if (!current_area.IsValid()) + return; + + total_area += *segment_length * (last_y - current_y); + + if (*segment_length > 0) + total_height += (last_y - current_y); + + // As we are iterating from the bottom of the page to the top, add segments + // when we see the start (bottom) of a new rect. + if (rect_event.is_bottom) { + segment_length_tracker.AddSegment( + rect_event.rect_id, rect_event.rect.x(), + rect_event.rect.x() + rect_event.rect.width()); + } else { + segment_length_tracker.RemoveSegment(rect_event.rect_id); + } + last_y = current_y; + } + + // If the measured height or area is invalid, skip recording this ad density + // calculation. + if (!total_height.IsValid() || !total_area.IsValid()) + return; + + base::CheckedNumeric<int> ad_density_by_height = + total_height * 100 / last_main_frame_size_->height(); + if (ad_density_by_height.IsValid() && + ad_density_by_height.ValueOrDie() > max_page_ad_density_by_height_) + max_page_ad_density_by_height_ = ad_density_by_height.ValueOrDie(); + + // Invalidate the check numeric if the checked area is invalid. + base::CheckedNumeric<int> ad_density_by_area = + total_area * 100 / + (last_main_frame_size_->size().GetCheckedArea().ValueOrDefault(0)); + if (ad_density_by_area.IsValid() && + ad_density_by_area.ValueOrDie() > max_page_ad_density_by_area_) + max_page_ad_density_by_area_ = ad_density_by_area.ValueOrDie(); +} + +bool PageAdDensityTracker::RectEvent::operator<(const RectEvent& rhs) const { + int lhs_y = is_bottom ? rect.bottom() : rect.y(); + int rhs_y = rhs.is_bottom ? rhs.rect.bottom() : rhs.rect.y(); + + // Tiebreak with |rect_id| and |is_bottom|. + if (lhs_y == rhs_y) { + if (rect_id == rhs.rect_id) { + return is_bottom == rhs.is_bottom; + } else { + return rect_id < rhs.rect_id; + } + } else { + return lhs_y > rhs_y; + } +}
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/page_ad_density_tracker.h b/chrome/browser/page_load_metrics/observers/ad_metrics/page_ad_density_tracker.h new file mode 100644 index 0000000..b2f013d --- /dev/null +++ b/chrome/browser/page_load_metrics/observers/ad_metrics/page_ad_density_tracker.h
@@ -0,0 +1,96 @@ +// 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_PAGE_LOAD_METRICS_OBSERVERS_AD_METRICS_PAGE_AD_DENSITY_TRACKER_H_ +#define CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_AD_METRICS_PAGE_AD_DENSITY_TRACKER_H_ + +#include <set> +#include <unordered_map> + +#include "base/optional.h" +#include "ui/gfx/geometry/rect.h" + +// Tracks the ad density of a page through the page's lifecycle. +// It has the following usage: +// 1. Set subframe and mainframe rects using subframe and mainframe rect +// operations (AddRect, RemoveRect, UpdateMainFrameRect). +// 2. Once a page has a main frame rect, get current density using +// DensityByHeight or DensityByArea. +class PageAdDensityTracker { + public: + PageAdDensityTracker(); + ~PageAdDensityTracker(); + + PageAdDensityTracker(const PageAdDensityTracker&) = delete; + PageAdDensityTracker& operator=(const PageAdDensityTracker&) = delete; + + // Operations to track sub frame rects in the page density calcluation. + void AddRect(int rect_id, const gfx::Rect& rect); + + // Removes a rect from the tracker if it is currently being tracked. + // Otherwise RemoveRect is a no op. + void RemoveRect(int rect_id); + + // Operations to track the main frame dimensions. The main frame rect has to + // be set to calculate density. + void UpdateMainFrameRect(const gfx::Rect& rect); + + // Returns the density by height, as a value from 0-100. If the density + // calculation fails (i.e. no main frame size), this returns -1. Percentage + // density by height is calculated as the the combined height of ads divided + // by the page's height. + int MaxPageAdDensityByHeight(); + + // Returns the density by area, as a value from 0-100. If the density + // calculation fails (i.e. no main frame size), this returns -1. + int MaxPageAdDensityByArea(); + + private: + // An event to process corresponding to the top or bottom of each rect. + struct RectEvent { + RectEvent(int id, bool is_bottom, const gfx::Rect& rect); + RectEvent(const RectEvent& other); + + // A unique identifier set when adding and removing rect events + // corresponding to a single rect. + int rect_id; + bool is_bottom; + gfx::Rect rect; + + // RectEvents are sorted by descending y value of the segment associated + // with the event. + bool operator<(const RectEvent& rhs) const; + }; + + // Iterators into the set of rect events for efficient removal of + // rect events by rect_id. Maintained by |rect_events_iterators_|. + struct RectEventSetIterators { + RectEventSetIterators(std::set<RectEvent>::iterator top, + std::set<RectEvent>::iterator bottom); + RectEventSetIterators(const RectEventSetIterators& other); + + std::set<RectEvent>::const_iterator top_it; + std::set<RectEvent>::const_iterator bottom_it; + }; + + // Calculates the combined area and height of the set of rects, this populates + // total_height_ and total_area_. + void CalculateDensity(); + + // Maintain a sorted set of rect events for use in calculating ad area. + std::set<RectEvent> rect_events_; + + // Map from rect_id to iterators of rect events in rect_events_. This allows + // efficient removal according to rect_id. + std::unordered_map<int, RectEventSetIterators> rect_events_iterators_; + + // Percentage of page ad density as a value from 0-100. These only have + // a value of -1 when ad density has not yet been calculated successfully. + int max_page_ad_density_by_area_ = -1; + int max_page_ad_density_by_height_ = -1; + + base::Optional<gfx::Rect> last_main_frame_size_; +}; + +#endif // CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_AD_METRICS_PAGE_AD_DENSITY_TRACKER_H_"
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/page_ad_density_tracker_unittest.cc b/chrome/browser/page_load_metrics/observers/ad_metrics/page_ad_density_tracker_unittest.cc new file mode 100644 index 0000000..65d92c7 --- /dev/null +++ b/chrome/browser/page_load_metrics/observers/ad_metrics/page_ad_density_tracker_unittest.cc
@@ -0,0 +1,98 @@ +// 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 <limits> + +#include "chrome/browser/page_load_metrics/observers/ad_metrics/page_ad_density_tracker.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/geometry/rect.h" + +TEST(PageAdDensityTrackerTest, MultipleRects_MaxPageDensityByAreaCalculated) { + PageAdDensityTracker tracker; + + // Page ad density is -1 before there is a main frame or subframes. + EXPECT_EQ(tracker.MaxPageAdDensityByArea(), -1); + + tracker.UpdateMainFrameRect(gfx::Rect(0, 0, 100, 100)); + tracker.AddRect(1 /* rect_id */, gfx::Rect(0, 0, 100, 10)); + EXPECT_EQ(tracker.MaxPageAdDensityByArea(), 10); + + tracker.AddRect(2 /* rect_id */, gfx::Rect(5, 5, 100, 10)); + EXPECT_EQ(tracker.MaxPageAdDensityByArea(), 15); + + tracker.AddRect(3 /* rect_id */, gfx::Rect(50, 50, 50, 50)); + EXPECT_EQ(tracker.MaxPageAdDensityByArea(), 40); + + // Removing a rect should not change the maximum ad density. + tracker.RemoveRect(3 /* rect_id */); + EXPECT_EQ(tracker.MaxPageAdDensityByArea(), 40); +} + +TEST(PageAdDensityTrackerTest, MultipleRects_MaxPageDensityByHeightCalculated) { + PageAdDensityTracker tracker; + + // Page ad density is -1 before there is a main frame or subframes. + EXPECT_EQ(tracker.MaxPageAdDensityByHeight(), -1); + + tracker.UpdateMainFrameRect(gfx::Rect(0, 0, 100, 100)); + tracker.AddRect(1 /* rect_id */, gfx::Rect(0, 0, 100, 10)); + EXPECT_EQ(tracker.MaxPageAdDensityByHeight(), 10); + + tracker.AddRect(2 /* rect_id */, gfx::Rect(5, 5, 100, 10)); + EXPECT_EQ(tracker.MaxPageAdDensityByHeight(), 15); + + tracker.AddRect(3 /* rect_id */, gfx::Rect(50, 50, 50, 50)); + EXPECT_EQ(tracker.MaxPageAdDensityByHeight(), 65); + + // Removing a rect should not change the maximum ad density. + tracker.RemoveRect(3 /* rect_id */); + EXPECT_EQ(tracker.MaxPageAdDensityByHeight(), 65); +} + +// Remove a rect that was added twice, the second RemoveRect is +// ignored as it is no longer being tracked. +TEST(PageAdDensityTrackerTest, RemoveRectTwice_SecondRemoveIgnored) { + PageAdDensityTracker tracker; + + tracker.AddRect(1 /* rect_id */, gfx::Rect(0, 0, 100, 10)); + tracker.RemoveRect(1 /* rect_id */); + tracker.RemoveRect(1 /* rect_id */); +} + +// Ensures that two rects with the same dimensions hash to different +// values in the density tracker's frame set. +TEST(PageAdDensityTrackerTest, SeperateRects_SameDimensions) { + PageAdDensityTracker tracker; + + tracker.UpdateMainFrameRect(gfx::Rect(0, 0, 100, 100)); + + tracker.AddRect(1 /* rect_id */, gfx::Rect(0, 0, 100, 10)); + tracker.AddRect(2 /* rect_id */, gfx::Rect(0, 0, 100, 10)); + EXPECT_EQ(tracker.MaxPageAdDensityByArea(), 10); + + tracker.RemoveRect(1 /* rect_id */); + tracker.RemoveRect(2 /* rect_id */); + EXPECT_EQ(tracker.MaxPageAdDensityByArea(), 10); +} + +// Create 2 rects whose total area overflow an int. +TEST(PageAdDensityTrackerTest, OverflowTotalAreaAndHeight) { + PageAdDensityTracker tracker; + + tracker.AddRect(1 /* rect_id */, gfx::Rect(std::numeric_limits<int>::min(), 0, + std::numeric_limits<int>::max(), + std::numeric_limits<int>::max())); + tracker.AddRect(2 /* rect_id */, gfx::Rect(std::numeric_limits<int>::min(), + std::numeric_limits<int>::max(), + std::numeric_limits<int>::max(), + std::numeric_limits<int>::max())); + + // Update main frame rect to force a calculation. + tracker.UpdateMainFrameRect(gfx::Rect(0, 0, 100, 100)); + + // Density should not be updated as the sum of area + // or height overflows. + EXPECT_EQ(tracker.MaxPageAdDensityByArea(), -1); + EXPECT_EQ(tracker.MaxPageAdDensityByHeight(), -1); +}
diff --git a/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc b/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc index fca439e..3eec48d 100644 --- a/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc +++ b/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc
@@ -28,7 +28,9 @@ #include "components/performance_manager/embedder/performance_manager_registry.h" #include "components/performance_manager/performance_manager_feature_observer_client.h" #include "components/performance_manager/public/decorators/page_load_tracker_decorator_helper.h" +#include "components/performance_manager/public/features.h" #include "components/performance_manager/public/graph/graph.h" +#include "components/performance_manager/public/graph/policies/tab_loading_frame_navigation_policy.h" #include "content/public/browser/storage_partition.h" #include "content/public/common/content_features.h" @@ -126,6 +128,13 @@ std::make_unique< performance_manager::policies::HighPMFMemoryPressurePolicy>()); } + + if (base::FeatureList::IsEnabled( + performance_manager::features::kTabLoadingFrameNavigationThrottles)) { + graph->PassToGraph( + std::make_unique< + performance_manager::policies::TabLoadingFrameNavigationPolicy>()); + } } content::FeatureObserverClient*
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index 67edad9..16263a7 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -966,6 +966,9 @@ { key::kPrintingSendUsernameAndFilenameEnabled, prefs::kPrintingSendUsernameAndFilenameEnabled, base::Value::Type::BOOLEAN }, + { key::kUserPluginVmAllowed, + plugin_vm::prefs::kPluginVmAllowed, + base::Value::Type::BOOLEAN }, { key::kPluginVmImage, plugin_vm::prefs::kPluginVmImage, base::Value::Type::DICTIONARY }, @@ -1112,6 +1115,9 @@ { key::kNativeWindowOcclusionEnabled, policy::policy_prefs::kNativeWindowOcclusionEnabled, base::Value::Type::BOOLEAN }, + { key::kPrintRasterizationMode, + prefs::kPrintRasterizationMode, + base::Value::Type::INTEGER }, #else // defined(OS_WIN) { key::kNtlmV2Enabled, prefs::kNtlmV2Enabled,
diff --git a/chrome/browser/printing/pdf_to_emf_converter.cc b/chrome/browser/printing/pdf_to_emf_converter.cc index 79e5971..c9a0a51 100644 --- a/chrome/browser/printing/pdf_to_emf_converter.cc +++ b/chrome/browser/printing/pdf_to_emf_converter.cc
@@ -408,6 +408,16 @@ UMA_HISTOGRAM_MEMORY_KB("Printing.ConversionSize.PostScript3", average_page_size_in_kb); return; + case PdfRenderSettings::Mode::EMF_WITH_REDUCED_RASTERIZATION: + UMA_HISTOGRAM_MEMORY_KB( + "Printing.ConversionSize.EmfWithReducedRasterization", + average_page_size_in_kb); + return; + case PdfRenderSettings::Mode::EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT: + UMA_HISTOGRAM_MEMORY_KB( + "Printing.ConversionSize.EmfWithReducedRasterizationAndGdiText", + average_page_size_in_kb); + return; default: NOTREACHED(); return;
diff --git a/chrome/browser/printing/pdf_to_emf_converter_browsertest.cc b/chrome/browser/printing/pdf_to_emf_converter_browsertest.cc index da247650..130fac6 100644 --- a/chrome/browser/printing/pdf_to_emf_converter_browsertest.cc +++ b/chrome/browser/printing/pdf_to_emf_converter_browsertest.cc
@@ -266,6 +266,26 @@ } } +IN_PROC_BROWSER_TEST_F(PdfToEmfConverterBrowserTest, + EmfWithReducedRasterizationBasic) { + const PdfRenderSettings pdf_settings( + kLetter200DpiRect, gfx::Point(0, 0), k200DpiSize, + /*autorotate=*/false, + /*use_color=*/true, + PdfRenderSettings::Mode::EMF_WITH_REDUCED_RASTERIZATION); + constexpr int kNumberOfPages = 3; + + ASSERT_TRUE(GetTestInput("pdf_converter_basic.pdf")); + ASSERT_TRUE(StartPdfConverter(pdf_settings, kNumberOfPages)); + for (int i = 0; i < kNumberOfPages; ++i) { + ASSERT_TRUE(GetPage(i)); + ASSERT_TRUE(GetPageExpectedEmfData( + GetFileNameForPageNumber("pdf_converter_basic_emf_page_", i))); + ComparePageEmfHeader(); + // TODO(thestig): Check if ComparePageEmfPayload() works on bots. + } +} + IN_PROC_BROWSER_TEST_F(PdfToEmfConverterBrowserTest, PostScriptLevel2Basic) { const PdfRenderSettings pdf_settings( kLetter200DpiRect, gfx::Point(0, 0), k200DpiSize,
diff --git a/chrome/browser/printing/print_job.cc b/chrome/browser/printing/print_job.cc index 0cfd891..d23770f 100644 --- a/chrome/browser/printing/print_job.cc +++ b/chrome/browser/printing/print_job.cc
@@ -26,20 +26,50 @@ #if defined(OS_WIN) #include "base/command_line.h" #include "chrome/browser/printing/pdf_to_emf_converter.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_features.h" +#include "chrome/common/pref_names.h" +#include "components/prefs/pref_service.h" +#include "content/public/browser/web_contents.h" #include "printing/pdf_render_settings.h" #include "printing/printed_page_win.h" +#include "printing/printing_features.h" #endif using base::TimeDelta; namespace printing { +namespace { + // Helper function to ensure |job| is valid until at least |callback| returns. void HoldRefCallback(scoped_refptr<PrintJob> job, base::OnceClosure callback) { std::move(callback).Run(); } +#if defined(OS_WIN) +// Those must be kept in sync with the values defined in policy_templates.json. +enum class PrintRasterizationMode { + // Do full page rasterization if necessary. Default value when policy not set. + kFull = 0, + // Avoid rasterization if possible. + kFast = 1, + kMaxValue = kFast, +}; + +bool PrintWithReducedRasterization(PrefService* prefs) { + // Managed preference takes precedence over user preference and field trials. + if (prefs->IsManagedPreference(prefs::kPrintRasterizationMode)) { + int value = prefs->GetInteger(prefs::kPrintRasterizationMode); + return value == static_cast<int>(PrintRasterizationMode::kFast); + } + + return base::FeatureList::IsEnabled(features::kPrintWithReducedRasterization); +} +#endif + +} // namespace + PrintJob::PrintJob() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); } @@ -319,11 +349,25 @@ bool print_text_with_gdi = settings.print_text_with_gdi() && !settings.printer_is_xps() && base::FeatureList::IsEnabled(::features::kGdiTextPrinting); + + Profile* profile = Profile::FromBrowserContext( + worker_->GetWebContents()->GetBrowserContext()); + bool print_with_reduced_rasterization = + PrintWithReducedRasterization(profile->GetPrefs()); + + using RenderMode = PdfRenderSettings::Mode; + RenderMode mode; + if (print_with_reduced_rasterization) { + mode = print_text_with_gdi + ? RenderMode::EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT + : RenderMode::EMF_WITH_REDUCED_RASTERIZATION; + } else { + mode = print_text_with_gdi ? RenderMode::GDI_TEXT : RenderMode::NORMAL; + } + PdfRenderSettings render_settings( content_area, gfx::Point(0, 0), settings.dpi_size(), - /*autorotate=*/true, settings.color() == COLOR, - print_text_with_gdi ? PdfRenderSettings::Mode::GDI_TEXT - : PdfRenderSettings::Mode::NORMAL); + /*autorotate=*/true, settings.color() == COLOR, mode); pdf_conversion_state_->Start( bytes, render_settings, base::BindOnce(&PrintJob::OnPdfConversionStarted, this)); @@ -581,4 +625,5 @@ #if defined(OS_WIN) PrintedPage* JobEventDetails::page() const { return page_.get(); } #endif + } // namespace printing
diff --git a/chrome/browser/printing/print_job_worker.cc b/chrome/browser/printing/print_job_worker.cc index 65065b7..9122bbf4 100644 --- a/chrome/browser/printing/print_job_worker.cc +++ b/chrome/browser/printing/print_job_worker.cc
@@ -258,10 +258,7 @@ SettingsCallback callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - PrintingContextDelegate* printing_context_delegate = - static_cast<PrintingContextDelegate*>(printing_context_delegate_.get()); - content::WebContents* web_contents = - printing_context_delegate->GetWebContents(); + content::WebContents* web_contents = GetWebContents(); #if defined(OS_ANDROID) if (is_scripted) { @@ -272,6 +269,8 @@ // call will return since startPendingPrint will make it return immediately // in case of error. if (tab) { + auto* printing_context_delegate = static_cast<PrintingContextDelegate*>( + printing_context_delegate_.get()); PrintingContextAndroid::SetPendingPrint( web_contents->GetTopLevelNativeWindow(), GetPrintableForTab(tab->GetJavaObject()), @@ -521,4 +520,10 @@ page_number_ = PageNumber::npos(); } +content::WebContents* PrintJobWorker::GetWebContents() { + PrintingContextDelegate* printing_context_delegate = + static_cast<PrintingContextDelegate*>(printing_context_delegate_.get()); + return printing_context_delegate->GetWebContents(); +} + } // namespace printing
diff --git a/chrome/browser/printing/print_job_worker.h b/chrome/browser/printing/print_job_worker.h index 8541347..8e14620 100644 --- a/chrome/browser/printing/print_job_worker.h +++ b/chrome/browser/printing/print_job_worker.h
@@ -18,6 +18,10 @@ #include "printing/print_job_constants.h" #include "printing/printing_context.h" +namespace content { +class WebContents; +} + namespace printing { class PrintJob; @@ -97,6 +101,9 @@ // Starts the thread. bool Start(); + // Returns the WebContents this work corresponds to. + content::WebContents* GetWebContents(); + protected: // Retrieves the context for testing only. PrintingContext* printing_context() { return printing_context_.get(); }
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc index a5fb9d2c6..b1493c54 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc
@@ -406,6 +406,10 @@ registry->RegisterBooleanPref(prefs::kPrintPreviewDisabled, false); registry->RegisterStringPref( prefs::kPrintPreviewDefaultDestinationSelectionRules, std::string()); +#if defined(OS_WIN) && BUILDFLAG(ENABLE_PRINTING) + registry->RegisterIntegerPref(prefs::kPrintRasterizationMode, 0); +#endif + registry->RegisterBooleanPref(prefs::kForceEphemeralProfiles, false); registry->RegisterBooleanPref(prefs::kEnableMediaRouter, true); #if defined(OS_CHROMEOS)
diff --git a/chrome/browser/query_tiles/android/tile_provider_factory.cc b/chrome/browser/query_tiles/android/tile_provider_factory.cc index eba1e9d8..5a227957 100644 --- a/chrome/browser/query_tiles/android/tile_provider_factory.cc +++ b/chrome/browser/query_tiles/android/tile_provider_factory.cc
@@ -23,7 +23,7 @@ if (profile_key == nullptr) return base::android::ScopedJavaLocalRef<jobject>(); - upboarding::TileService* tile_service = - upboarding::TileServiceFactory::GetInstance()->GetForKey(profile_key); - return upboarding::TileProviderBridge::GetBridgeForTileService(tile_service); + query_tiles::TileService* tile_service = + query_tiles::TileServiceFactory::GetInstance()->GetForKey(profile_key); + return query_tiles::TileProviderBridge::GetBridgeForTileService(tile_service); }
diff --git a/chrome/browser/query_tiles/tile_background_task.cc b/chrome/browser/query_tiles/tile_background_task.cc index 52dab8d..24d045d 100644 --- a/chrome/browser/query_tiles/tile_background_task.cc +++ b/chrome/browser/query_tiles/tile_background_task.cc
@@ -9,7 +9,7 @@ #include "chrome/browser/profiles/profile_key.h" #include "chrome/browser/query_tiles/tile_service_factory.h" -namespace upboarding { +namespace query_tiles { TileBackgroundTask::TileBackgroundTask() = default; @@ -49,10 +49,9 @@ TaskFinishedCallback callback) { if (is_from_reduced_mode) return; - auto* tile_service = - upboarding::TileServiceFactory::GetInstance()->GetForKey(key); + auto* tile_service = TileServiceFactory::GetInstance()->GetForKey(key); DCHECK(tile_service); tile_service->StartFetchForTiles(is_from_reduced_mode, std::move(callback)); } -} // namespace upboarding +} // namespace query_tiles
diff --git a/chrome/browser/query_tiles/tile_background_task.h b/chrome/browser/query_tiles/tile_background_task.h index ecf13ec..cc04e90 100644 --- a/chrome/browser/query_tiles/tile_background_task.h +++ b/chrome/browser/query_tiles/tile_background_task.h
@@ -13,7 +13,7 @@ struct TaskInfo; } // namespace background_task -namespace upboarding { +namespace query_tiles { using BackgroundTask = background_task::BackgroundTask; using TaskInfo = background_task::TaskInfo; @@ -50,6 +50,6 @@ TaskFinishedCallback callback_; }; -} // namespace upboarding +} // namespace query_tiles #endif // CHROME_BROWSER_QUERY_TILES_TILE_BACKGROUND_TASK_H_
diff --git a/chrome/browser/query_tiles/tile_service_factory.cc b/chrome/browser/query_tiles/tile_service_factory.cc index 025cd9e..097c121 100644 --- a/chrome/browser/query_tiles/tile_service_factory.cc +++ b/chrome/browser/query_tiles/tile_service_factory.cc
@@ -26,7 +26,7 @@ #include "google_apis/google_api_keys.h" #include "services/network/public/cpp/shared_url_loader_factory.h" -namespace upboarding { +namespace query_tiles { namespace { // Issue 1076964: Currently the variation service can be only reached in full @@ -35,9 +35,9 @@ std::string GetCountryCode() { std::string country_code; base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - if (command_line->HasSwitch(upboarding::switches::kQueryTilesCountryCode)) { + if (command_line->HasSwitch(query_tiles::switches::kQueryTilesCountryCode)) { country_code = command_line->GetSwitchValueASCII( - upboarding::switches::kQueryTilesCountryCode); + query_tiles::switches::kQueryTilesCountryCode); if (!country_code.empty()) return country_code; } @@ -109,4 +109,4 @@ url_loader_factory); } -} // namespace upboarding +} // namespace query_tiles
diff --git a/chrome/browser/query_tiles/tile_service_factory.h b/chrome/browser/query_tiles/tile_service_factory.h index 7ce4211..df01abf 100644 --- a/chrome/browser/query_tiles/tile_service_factory.h +++ b/chrome/browser/query_tiles/tile_service_factory.h
@@ -16,7 +16,7 @@ struct DefaultSingletonTraits; } // namespace base -namespace upboarding { +namespace query_tiles { class TileService; @@ -38,6 +38,6 @@ DISALLOW_COPY_AND_ASSIGN(TileServiceFactory); }; -} // namespace upboarding +} // namespace query_tiles #endif // CHROME_BROWSER_QUERY_TILES_TILE_SERVICE_FACTORY_H_
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc index e2518e930..0b9524e51 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -537,7 +537,14 @@ Profile::CreateStatus status) { if (status == Profile::CREATE_STATUS_INITIALIZED) { Browser* browser = chrome::FindLastActiveWithProfile(profile); - NavigateParams nav_params(browser, link_url, ui::PAGE_TRANSITION_LINK); + NavigateParams nav_params( + browser, link_url, + /* |ui::PAGE_TRANSITION_TYPED| is used rather than + |ui::PAGE_TRANSITION_LINK| since this ultimately opens the link in + another browser. This parameter is used within the tab strip model of + the browser it opens in implying a link from the active tab in the + destination browser which is not correct. */ + ui::PAGE_TRANSITION_TYPED); nav_params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; nav_params.referrer = referrer; nav_params.window_action = NavigateParams::SHOW_WINDOW;
diff --git a/chrome/browser/resources/chromeos/accessibility/switch_access/navigation_manager.js b/chrome/browser/resources/chromeos/accessibility/switch_access/navigation_manager.js index 8bb6721..e7c370d 100644 --- a/chrome/browser/resources/chromeos/accessibility/switch_access/navigation_manager.js +++ b/chrome/browser/resources/chromeos/accessibility/switch_access/navigation_manager.js
@@ -373,7 +373,8 @@ } /** - * Set |this.group_| to |group|. + * Set |this.group_| to |group|, and optionally sets |this.node_| to the + * group's first child. * @param {!SARootNode} group * @param {boolean} shouldSetNode * @private
diff --git a/chrome/browser/resources/chromeos/accessibility/switch_access/navigation_manager_test.js b/chrome/browser/resources/chromeos/accessibility/switch_access/navigation_manager_test.js index d9aa10a..1d7eaf4 100644 --- a/chrome/browser/resources/chromeos/accessibility/switch_access/navigation_manager_test.js +++ b/chrome/browser/resources/chromeos/accessibility/switch_access/navigation_manager_test.js
@@ -50,17 +50,23 @@ function moveToPageContents() { const navigator = NavigationManager.instance; // Start from the desktop node. - navigator.group_ = DesktopNode.build(navigator.desktop_); - navigator.node_ = navigator.group_.firstChild; + navigator.setGroup_(DesktopNode.build(navigator.desktop_)); // The first item should be the browser window. - navigator.selectCurrentNode(); + assertTrue( + navigator.node_.isGroup(), + 'Browser window should be the desktop\'s first child'); + NavigationManager.enterGroup(); + // Find the page contents in the browser window. // The third item in the browser window is the page contents. // TODO(anastasi): find the browser window dynamically. NavigationManager.moveForward(); NavigationManager.moveForward(); - navigator.selectCurrentNode(); + assertTrue( + navigator.node_.isGroup(), + 'Page contents should be the browser window\'s third child'); + NavigationManager.enterGroup(); } function currentNode() { @@ -170,6 +176,7 @@ TEST_F('SwitchAccessNavigationManagerTest', 'SelectButton', function() { const website = `<button id="test" aria-pressed=false>First Button</button> + <button>Second Button</button> <script> let state = false; let button = document.getElementById("test"); @@ -194,10 +201,7 @@ 'Checked state changed on unexpected node'); })); - chrome.automation.getDesktop(this.newCallback((d) => { - NavigationManager.initialize(d); - NavigationManager.instance.selectCurrentNode(); - })); + NavigationManager.instance.node_.performAction('select'); }); });
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.html b/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.html index 1bee3e5a..42eadd08 100644 --- a/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.html +++ b/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.html
@@ -4,7 +4,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> <link rel="import" href="chrome://resources/cr_elements/icons.html"> -<link rel="import" href="chrome://resources/cr_elements/chromeos/cr_lottie/cr_lottie.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_lottie/cr_lottie.html"> <dom-module id="assistant-voice-match"> <template> <style include="oobe-dialog-host"></style>
diff --git a/chrome/browser/resources/chromeos/crosh_builtin/OWNERS b/chrome/browser/resources/chromeos/crosh_builtin/OWNERS deleted file mode 100644 index ef513b6..0000000 --- a/chrome/browser/resources/chromeos/crosh_builtin/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -vapier@chromium.org
diff --git a/chrome/browser/resources/chromeos/crosh_builtin/manifest.json b/chrome/browser/resources/chromeos/crosh_builtin/manifest.json deleted file mode 100644 index 152a70b4..0000000 --- a/chrome/browser/resources/chromeos/crosh_builtin/manifest.json +++ /dev/null
@@ -1,26 +0,0 @@ -{ - "key": "AAAAB3NzaC1yc2EAAAADAQABAAAAgQDtKfIKWzC4HnQbyAeddk5h78K7LSyrIEnLKDsQCNxhfsavJ+otV9JprDSz3nF7EHZokXiC72SHxdMndt2IlId/aRfhbU4UGidrmFBKg6v1Fs2zey6niB+xLOhJQMe9XtwVNWDpiGXHLmwNhG/FLhj0bBBf1HZDBV18Xp47ymLiuQ==", - "name": "Terminal", - "manifest_version": 2, - "icons": { - "192": "images/dev/crostini-192.png" - }, - "content_security_policy": "script-src 'self' blob: filesystem:; object-src 'self' blob: filesystem:", - "version": "0.8.36", - "default_locale": "en", - "description": "Built-in terminal for crosh.", - "offline_enabled": true, - "options_page": "html/nassh_preferences_editor.html", - "incognito": "split", - "permissions": [ - "clipboardRead", - "clipboardWrite", - "notifications", - "storage", - "terminalPrivate", - "unlimitedStorage", - "accessibilityFeatures.read", - "crashReportPrivate", - "metricsPrivate" - ] -}
diff --git a/chrome/browser/resources/chromeos/login/BUILD.gn b/chrome/browser/resources/chromeos/login/BUILD.gn index 9142c970..c453524 100644 --- a/chrome/browser/resources/chromeos/login/BUILD.gn +++ b/chrome/browser/resources/chromeos/login/BUILD.gn
@@ -124,8 +124,8 @@ deps = [ "components:oobe_dialog_host_behavior", "components:oobe_i18n_behavior", - "//ui/webui/resources/cr_elements/chromeos/cr_lottie:cr_lottie", "//ui/webui/resources/cr_elements/cr_fingerprint:cr_fingerprint_progress_arc", + "//ui/webui/resources/cr_elements/cr_lottie:cr_lottie", ] }
diff --git a/chrome/browser/resources/chromeos/login/fingerprint_setup.html b/chrome/browser/resources/chromeos/login/fingerprint_setup.html index a880f9e..170836d7 100644 --- a/chrome/browser/resources/chromeos/login/fingerprint_setup.html +++ b/chrome/browser/resources/chromeos/login/fingerprint_setup.html
@@ -7,7 +7,7 @@ <link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> <link rel="import" href="chrome://resources/cr_elements/cr_fingerprint/cr_fingerprint_progress_arc.html"> -<link rel="import" href="chrome://resources/cr_elements/chromeos/cr_lottie/cr_lottie.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_lottie/cr_lottie.html"> <dom-module id="fingerprint-setup"> <template>
diff --git a/chrome/browser/resources/chromeos/login/gesture_navigation.html b/chrome/browser/resources/chromeos/login/gesture_navigation.html index 42d7aa3..81b4edf 100644 --- a/chrome/browser/resources/chromeos/login/gesture_navigation.html +++ b/chrome/browser/resources/chromeos/login/gesture_navigation.html
@@ -4,7 +4,7 @@ <link rel="import" href="chrome://resources/html/polymer.html"> -<link rel="import" href="chrome://resources/cr_elements/chromeos/cr_lottie/cr_lottie.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_lottie/cr_lottie.html"> <dom-module id="gesture-navigation"> <template>
diff --git a/chrome/browser/resources/chromeos/login/marketing_opt_in.html b/chrome/browser/resources/chromeos/login/marketing_opt_in.html index 2f83ec3..62d3256 100644 --- a/chrome/browser/resources/chromeos/login/marketing_opt_in.html +++ b/chrome/browser/resources/chromeos/login/marketing_opt_in.html
@@ -4,7 +4,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-iconset-svg/iron-iconset-svg.html"> -<link rel="import" href="chrome://resources/cr_elements/chromeos/cr_lottie/cr_lottie.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_lottie/cr_lottie.html"> <iron-iconset-svg name="marketing-opt-in-32" size="32"> <svg>
diff --git a/chrome/browser/resources/new_tab_page/app.html b/chrome/browser/resources/new_tab_page/app.html index 2de24d9..838c215 100644 --- a/chrome/browser/resources/new_tab_page/app.html +++ b/chrome/browser/resources/new_tab_page/app.html
@@ -45,6 +45,7 @@ ntp-fakebox, ntp-realbox { + flex-shrink: 0; margin-bottom: 32px; } @@ -56,7 +57,7 @@ #promo { bottom: 16px; - height: 35px; + height: 32px; left: 0; position: fixed; right: 0; @@ -98,7 +99,7 @@ } :host-context(.focus-outline-visible) #customizeButton:focus { - box-shadow: 0 0 0 2px var(--ntp-focus-shadow-color); + box-shadow: var(--ntp-focus-shadow); } #customizeIcon { @@ -219,7 +220,8 @@ theme="[[theme_.searchBox]]" hidden$="[[!realboxEnabled_]]"> </ntp-realbox> <ntp-most-visited id="mostVisited" dark$="[[theme_.isDark]]" - use-white-add-icon$="[[theme_.shortcutUseWhiteAddIcon]]"> + use-white-add-icon$="[[theme_.shortcutUseWhiteAddIcon]]" + use-title-pill$="[[theme_.shortcutUseTitlePill]]"> </ntp-most-visited> <dom-if if="[[lazyRender_]]"> <template>
diff --git a/chrome/browser/resources/new_tab_page/app.js b/chrome/browser/resources/new_tab_page/app.js index 8e4a70f..d2876fb1 100644 --- a/chrome/browser/resources/new_tab_page/app.js +++ b/chrome/browser/resources/new_tab_page/app.js
@@ -615,6 +615,11 @@ }; this.eventTracker_.add(window, 'resize', onResize); onResize(); + BrowserProxy.getInstance().handler.onPromoRendered( + BrowserProxy.getInstance().now()); + } else if (data.messageType === 'link-clicked') { + BrowserProxy.getInstance().handler.onPromoLinkClicked( + BrowserProxy.getInstance().now()); } }
diff --git a/chrome/browser/resources/new_tab_page/customize_backgrounds.html b/chrome/browser/resources/new_tab_page/customize_backgrounds.html index dee4b62..95d0f3f 100644 --- a/chrome/browser/resources/new_tab_page/customize_backgrounds.html +++ b/chrome/browser/resources/new_tab_page/customize_backgrounds.html
@@ -17,7 +17,7 @@ } :host-context(.focus-outline-visible) .tile:focus { - box-shadow: 0 0 0 2px var(--ntp-focus-shadow-color); + box-shadow: var(--ntp-focus-shadow); } .image {
diff --git a/chrome/browser/resources/new_tab_page/customize_shortcuts.html b/chrome/browser/resources/new_tab_page/customize_shortcuts.html index d5b5149..1c414c9 100644 --- a/chrome/browser/resources/new_tab_page/customize_shortcuts.html +++ b/chrome/browser/resources/new_tab_page/customize_shortcuts.html
@@ -22,8 +22,8 @@ width: 268px; } - :host-context(.focus-outline-visible)) .option-image:focus { - box-shadow: 0 0 0 2px var(--ntp-focus-shadow-color); + :host-context(.focus-outline-visible) .option-image:focus { + box-shadow: var(--ntp-focus-shadow); } .selected .option-image {
diff --git a/chrome/browser/resources/new_tab_page/fakebox.html b/chrome/browser/resources/new_tab_page/fakebox.html index e71d3b17..8603b202d 100644 --- a/chrome/browser/resources/new_tab_page/fakebox.html +++ b/chrome/browser/resources/new_tab_page/fakebox.html
@@ -100,16 +100,17 @@ background: url(icons/googlemic_clr_24px.svg) no-repeat center; background-size: 21px 21px; border: none; + border-radius: 2px; cursor: pointer; - height: 21px; + height: 100%; outline: none; padding: 0; pointer-events: auto; - width: 21px; + width: 26px; } :host-context(.focus-outline-visible) #voiceSearchButton:focus { - box-shadow: 0 0 0 2px var(--ntp-focus-shadow-color); + box-shadow: var(--ntp-focus-shadow); } </style> <input id="input" on-pointerdown="onPointerDown_" on-paste="onPaste_"
diff --git a/chrome/browser/resources/new_tab_page/logo.html b/chrome/browser/resources/new_tab_page/logo.html index 2e26335..17861ae 100644 --- a/chrome/browser/resources/new_tab_page/logo.html +++ b/chrome/browser/resources/new_tab_page/logo.html
@@ -90,7 +90,7 @@ <!-- The static image is always visible and the animated image is stacked on top of the static image so that there is no flicker when starting the animation. --> - <img id="image" src="[[imageUrl_]]"> + <img id="image" src="[[imageUrl_]]" on-load="onImageLoad_"> </img> <ntp-untrusted-iframe id="animation" path="[[animationUrl_]]" hidden="[[!showAnimation_]]">
diff --git a/chrome/browser/resources/new_tab_page/logo.js b/chrome/browser/resources/new_tab_page/logo.js index 3e3cccd..066511b 100644 --- a/chrome/browser/resources/new_tab_page/logo.js +++ b/chrome/browser/resources/new_tab_page/logo.js
@@ -121,7 +121,9 @@ super(); /** @private {!EventTracker} */ this.eventTracker_ = new EventTracker(); - BrowserProxy.getInstance().handler.getDoodle().then(({doodle}) => { + /** @private {newTabPage.mojom.PageHandlerRemote} */ + this.pageHandler_ = BrowserProxy.getInstance().handler; + this.pageHandler_.getDoodle().then(({doodle}) => { this.doodle_ = doodle; this.loaded_ = true; if (this.doodle_ && this.doodle_.content.interactiveDoodle) { @@ -190,15 +192,27 @@ * @private */ onImageClick_() { - if (!this.showAnimation_ && this.doodle_ && - this.doodle_.content.imageDoodle.animationUrl) { + if (this.isCtaImageShown_()) { this.showAnimation_ = true; + this.pageHandler_.onDoodleImageClicked( + newTabPage.mojom.DoodleImageType.CTA); return; } + this.pageHandler_.onDoodleImageClicked( + this.showAnimation_ ? newTabPage.mojom.DoodleImageType.ANIMATION : + newTabPage.mojom.DoodleImageType.STATIC); BrowserProxy.getInstance().open( this.doodle_.content.imageDoodle.onClickUrl.url); } + /** @private */ + onImageLoad_() { + this.pageHandler_.onDoodleImageRendered( + this.isCtaImageShown_() ? newTabPage.mojom.DoodleImageType.CTA : + newTabPage.mojom.DoodleImageType.STATIC, + BrowserProxy.getInstance().now()); + } + /** * @param {!Event} e * @private @@ -210,6 +224,15 @@ } /** + * @returns {boolean} + * @private + */ + isCtaImageShown_() { + return !this.showAnimation_ && !!this.doodle_ && + !!this.doodle_.content.imageDoodle.animationUrl; + } + + /** * @return {string} * @private */
diff --git a/chrome/browser/resources/new_tab_page/most_visited.html b/chrome/browser/resources/new_tab_page/most_visited.html index 9151ecac..63c62b0 100644 --- a/chrome/browser/resources/new_tab_page/most_visited.html +++ b/chrome/browser/resources/new_tab_page/most_visited.html
@@ -53,6 +53,7 @@ height: var(--tile-size); margin-bottom: var(--tile-margin); opacity: 1; + outline: none; padding-top: var(--tile-margin); position: relative; text-decoration: none; @@ -63,6 +64,11 @@ width: var(--tile-size); } + :host-context(.focus-outline-visible) .tile:focus, + :host-context(.focus-outline-visible) #addShortcut:focus { + box-shadow: var(--ntp-focus-shadow); + } + #addShortcut { background-color: transparent; border: none; @@ -70,14 +76,6 @@ padding: 0; } - :host-context(.focus-outline-visible) #addShortcut:focus { - outline: auto; - } - - :host-context(html:not(.focus-outline-visible)) .tile { - outline: none; - } - :host(:not([reordering_])) .tile:hover, :host(:not([reordering_])) #addShortcut:hover, .force-hover { @@ -100,15 +98,32 @@ } .tile-title { + align-items: center; + border-radius: 12px; color: var(--ntp-theme-text-color); + display: flex; + height: 24px; + margin-top: 7px; + padding: 0 8px; + width: 88px; + } + + :host([use-title-pill]) .tile-title { + background-color: white; + } + + .tile-title span { font-weight: 400; - margin-top: 16px; overflow: hidden; text-align: center; text-overflow: ellipsis; text-shadow: var(--ntp-theme-text-shadow); white-space: nowrap; - width: 88px; + width: 100%; + } + + :host([use-title-pill]) .tile-title span { + text-shadow: none; } .title-rtl { @@ -175,7 +190,7 @@ <img src$="[[getFaviconUrl_(item.url)]]" draggable="false"></img> </div> <div class$="tile-title [[getTileTitleDirectionClass_(item)]]"> - [[item.title]] + <span>[[item.title]]</span> </div> </a> </template> @@ -185,7 +200,9 @@ <div class="tile-icon"> <div id="addShortcutIcon" draggable="false"></div> </div> - <div class="tile-title">$i18n{addLinkTitle}</div> + <div class="tile-title"> + <span>$i18n{addLinkTitle}</span> + </div> </cr-button> <cr-dialog id="dialog" on-close="onDialogClose_"> <div slot="title">[[dialogTitle_]]</div>
diff --git a/chrome/browser/resources/new_tab_page/most_visited.js b/chrome/browser/resources/new_tab_page/most_visited.js index 2db992e..b4ab486 100644 --- a/chrome/browser/resources/new_tab_page/most_visited.js +++ b/chrome/browser/resources/new_tab_page/most_visited.js
@@ -86,6 +86,12 @@ reflectToAttribute: true, }, + /* If true wraps the tile titles in white pills. */ + useTitlePill: { + type: Boolean, + reflectToAttribute: true, + }, + /** @private */ columnCount_: { type: Number,
diff --git a/chrome/browser/resources/new_tab_page/realbox.html b/chrome/browser/resources/new_tab_page/realbox.html index e5612c3..65457a0f 100644 --- a/chrome/browser/resources/new_tab_page/realbox.html +++ b/chrome/browser/resources/new_tab_page/realbox.html
@@ -92,16 +92,17 @@ } #voiceSearchButton { - background-size: 21px; background: url(icons/googlemic_clr_24px.svg) no-repeat center; + background-size: 21px; border: none; + border-radius: 2px; cursor: pointer; height: 100%; outline: none; padding: 0; position: absolute; right: 16px; - width: 21px; + width: 26px; } :host-context([dir='rtl']) #voiceSearchButton { @@ -110,7 +111,7 @@ } :host-context(.focus-outline-visible) #voiceSearchButton:focus { - box-shadow: 0 0 0 2px var(--ntp-focus-shadow-color); + box-shadow: var(--ntp-focus-shadow); } </style> <div id="realboxInputWrapper">
diff --git a/chrome/browser/resources/new_tab_page/shared_vars.css b/chrome/browser/resources/new_tab_page/shared_vars.css index eaffc0a0..11cd6f1 100644 --- a/chrome/browser/resources/new_tab_page/shared_vars.css +++ b/chrome/browser/resources/new_tab_page/shared_vars.css
@@ -8,6 +8,7 @@ * 'ui/webui/resources/shared_vars_css.m.js'. */ html { + /* Colors: */ --ntp-active-background-color: rgba(var(--google-grey-900-rgb), .16); --ntp-background-override-color: white; --ntp-border-color: var(--google-grey-refresh-300); @@ -20,10 +21,14 @@ --ntp-selected-border-color: var(--google-blue-600); --ntp-selected-light-background-color: rgba(var(--google-blue-600-rgb), .24); --ntp-selected-primary-text-color: var(--google-blue-refresh-700); + + /* Other: */ + --ntp-focus-shadow: 0 0 0 2px var(--ntp-focus-shadow-color); } @media (prefers-color-scheme: dark) { html { + /* Colors: */ --ntp-active-background-color: rgba(var(--google-grey-200-rgb), .16); --ntp-background-override-color: var(--google-grey-900); --ntp-border-color: var(--google-grey-refresh-700);
diff --git a/chrome/browser/resources/new_tab_page/untrusted/promo.html b/chrome/browser/resources/new_tab_page/untrusted/promo.html index 2c9b9de..499a748 100644 --- a/chrome/browser/resources/new_tab_page/untrusted/promo.html +++ b/chrome/browser/resources/new_tab_page/untrusted/promo.html
@@ -11,6 +11,8 @@ --google-grey-200: rgb(var(--google-grey-200-rgb)); --google-grey-900-rgb: 32, 33, 36; /* #202124 */ --google-grey-900: rgb(var(--google-grey-900-rgb)); + --google-blue-refresh-300-rgb: 138, 180, 248; /* #8ab4f8 */ + --google-blue-refresh-300: rgb(var(--google-blue-refresh-300-rgb)); --google-grey-refresh-300-rgb: 218, 220, 224; /* #dadce0 */ --google-grey-refresh-300: rgb(var(--google-grey-refresh-300-rgb)); --google-grey-refresh-700-rgb: 95, 99, 104; /* #5f6368 */ @@ -60,10 +62,18 @@ text-decoration: none; } + body > div > a:focus { + outline: solid 2px rgba(var(--google-blue-600-rgb), .4); + } + @media (prefers-color-scheme: dark) { body > div > a { color: var(--google-blue-400); } + + body > div > a:focus { + outline: solid 2px rgba(var(--google-blue-refresh-300-rgb), .5); + } } body > div > img {
diff --git a/chrome/browser/resources/new_tab_page/untrusted/promo.js b/chrome/browser/resources/new_tab_page/untrusted/promo.js index de53758..454df0f2 100644 --- a/chrome/browser/resources/new_tab_page/untrusted/promo.js +++ b/chrome/browser/resources/new_tab_page/untrusted/promo.js
@@ -16,6 +16,11 @@ if (el.target !== '_blank') { el.target = '_top'; } + el.addEventListener('click', () => { + window.parent.postMessage( + {frameType: 'promo', messageType: 'link-clicked'}, + 'chrome://new-tab-page'); + }); }); // Inform the embedder that the promo has loaded and can be displayed. window.parent.postMessage(
diff --git a/chrome/browser/resources/new_tab_page/voice_search_overlay.html b/chrome/browser/resources/new_tab_page/voice_search_overlay.html index 88dd709..20e0a48c 100644 --- a/chrome/browser/resources/new_tab_page/voice_search_overlay.html +++ b/chrome/browser/resources/new_tab_page/voice_search_overlay.html
@@ -48,7 +48,7 @@ } :host-context(.focus-outline-visible) #closeButton:focus { - box-shadow: 0 0 0 2px var(--ntp-focus-shadow-color); + box-shadow: var(--ntp-focus-shadow); } :host-context([dir='ltr']) #closeButton {
diff --git a/chrome/browser/resources/settings/BUILD.gn b/chrome/browser/resources/settings/BUILD.gn index 17a5905..2b81df8 100644 --- a/chrome/browser/resources/settings/BUILD.gn +++ b/chrome/browser/resources/settings/BUILD.gn
@@ -214,6 +214,8 @@ ":open_window_proxy", "about_page:about_page_browser_proxy.m", "autofill_page:password_manager_proxy", + "people_page:sync_browser_proxy.m", + "privacy_page:privacy_page_browser_proxy.m", "search_engines_page:search_engines_browser_proxy.m", "settings_ui:settings_ui", ] @@ -248,6 +250,8 @@ "autofill_page:autofill_section", "autofill_page:payments_section", "privacy_page:cookies_page", + "privacy_page:safe_browsing_browser_proxy", + "privacy_page:security_page", "site_settings:local_data_browser_proxy", "site_settings:protocol_handlers", "site_settings:site_settings_prefs_browser_proxy",
diff --git a/chrome/browser/resources/settings/chromeos/BUILD.gn b/chrome/browser/resources/settings/chromeos/BUILD.gn index 0b9ac4e..2e34598 100644 --- a/chrome/browser/resources/settings/chromeos/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/BUILD.gn
@@ -100,7 +100,6 @@ "multidevice_page:closure_compile", "os_a11y_page:closure_compile", "os_apps_page:closure_compile", - "os_apps_page/app_management_page:closure_compile", "os_files_page:closure_compile", "os_languages_page:closure_compile", "os_people_page:closure_compile", @@ -115,7 +114,11 @@ "os_settings_ui:closure_compile", "parental_controls_page:closure_compile", "personalization_page:closure_compile", - "plugin_vm_page:closure_compile", + + # TODO: These subpages should be listed in the BUILD files of their direct + # parents instead of here. + "os_apps_page/app_management_page:closure_compile", + "os_apps_page/app_management_page/plugin_vm_page:closure_compile", ] } @@ -182,6 +185,7 @@ #"os_a11y_page:closure_compile_module", #"os_about_page:closure_compile_module", #"os_apps_page:closure_compile_module", + #"os_apps_page/app_management_page/plugin_vm_page:closure_compile_module", #"os_files_page:closure_compile_module", #"os_languages_page:closure_compile_module", #"os_people_page:closure_compile_module", @@ -197,7 +201,6 @@ #"os_toolbar:closure_compile_module", #"parental_controls_page:closure_compile_module", #"personalization_page:closure_compile_module", - #"plugin_vm_page:closure_compile_module", ] } @@ -302,6 +305,7 @@ "os_a11y_page:polymer3_elements", "os_about_page:polymer3_elements", "os_apps_page:polymer3_elements", + "os_apps_page/app_management_page/plugin_vm_page:polymer3_elements", "os_files_page:polymer3_elements", "os_languages_page:polymer3_elements", "os_people_page:polymer3_elements", @@ -317,7 +321,6 @@ "os_toolbar:polymer3_elements", "parental_controls_page:polymer3_elements", "personalization_page:polymer3_elements", - "plugin_vm_page:polymer3_elements", # Local targets ":metrics_recorder_module",
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn index 9cdd7e21..c09ff76 100644 --- a/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn
@@ -26,7 +26,9 @@ "..:metrics_recorder", "..:os_route", "../..:router", + "../../people_page:sync_browser_proxy", "../../settings_page:settings_animated_pages", + "../os_people_page:os_sync_browser_proxy", "//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_listener_behavior",
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_page.html b/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_page.html index c2890cc..b542f94 100644 --- a/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_page.html +++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_page.html
@@ -24,7 +24,9 @@ <link rel="import" href="../../controls/controlled_button.html"> <link rel="import" href="../../controls/settings_toggle_button.html"> <link rel="import" href="../../i18n_setup.html"> +<link rel="import" href="../../people_page/sync_browser_proxy.html"> <link rel="import" href="../../prefs/prefs.html"> +<link rel="import" href="../os_people_page/os_sync_browser_proxy.html"> <link rel="import" href="../os_route.html"> <link rel="import" href="../../router.html"> <link rel="import" href="../metrics_recorder.html"> @@ -143,11 +145,37 @@ <iron-icon class="policy" icon="cr20:domain"></iron-icon> <div class="settings-box-text">$i18n{networkConnectNotAllowed}</div> </div> - <div class="settings-box continuation settings-box-text" - hidden$="[[!showShared_(managedProperties_, globalPolicy, - managedNetworkAvailable)]]"> - $i18n{networkShared} - </div> + + + <!-- Notice of synced and/or shared network. --> + <template is="dom-if" + if="[[showSyncedShared_(managedProperties_, globalPolicy, + managedNetworkAvailable, isWifiSyncEnabled_)]]"> + <!-- Network is both synced and shared. --> + <div class="settings-box continuation settings-box-text"> + <settings-localized-link + localized-string="[[i18nAdvanced('networkSyncedShared')]]"> + </settings-localized-link> + </div> + </template> + <template is="dom-if" + if="[[showSyncedUser_(managedProperties_, globalPolicy, + managedNetworkAvailable, isWifiSyncEnabled_)]]"> + <!-- Network is synced but not shared. --> + <div class="settings-box continuation settings-box-text"> + <settings-localized-link + localized-string="[[i18nAdvanced('networkSyncedUser')]]"> + </settings-localized-link> + </div> + </template> + <template is="dom-if" + if="[[showShared_(managedProperties_, globalPolicy, + managedNetworkAvailable, isWifiSyncEnabled_)]]"> + <!-- Network is shared but not synced. --> + <div class="settings-box continuation settings-box-text"> + [[i18n('networkShared')]] + </div> + </template> <template is="dom-if" if="[[isSecondaryUser_]]"> <!-- Show message for non primary users. -->
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_page.js b/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_page.js index fc8d142..6707d0b 100644 --- a/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_page.js +++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_page.js
@@ -20,6 +20,7 @@ CrPolicyNetworkBehaviorMojo, settings.RouteObserverBehavior, I18nBehavior, + WebUIListenerBehavior, ], properties: { @@ -32,6 +33,9 @@ notify: true, }, + /** @private Indicates if wi-fi sync is enabled for the active user. */ + isWifiSyncEnabled_: Boolean, + /** @private {!chromeos.networkConfig.mojom.ManagedProperties|undefined} */ managedProperties_: { type: Object, @@ -199,14 +203,39 @@ /** @private {settings.InternetPageBrowserProxy} */ browserProxy_: null, + /** @private {?settings.OsSyncBrowserProxy} */ + osSyncBrowserProxy_: null, + + /** @private {?settings.SyncBrowserProxy} */ + syncBrowserProxy_: null, + /** @private {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote} */ networkConfig_: null, /** @override */ + attached() { + if (loadTimeData.getBoolean('splitSettingsSyncEnabled')) { + this.addWebUIListener( + 'os-sync-prefs-changed', this.handleOsSyncPrefsChanged_.bind(this)); + this.osSyncBrowserProxy_.sendOsSyncPrefsChanged(); + } else { + this.addWebUIListener( + 'sync-prefs-changed', this.handleSyncPrefsChanged_.bind(this)); + this.syncBrowserProxy_.sendSyncPrefsChanged(); + } + }, + + /** @override */ created() { this.browserProxy_ = settings.InternetPageBrowserProxyImpl.getInstance(); this.networkConfig_ = network_config.MojoInterfaceProviderImpl.getInstance() .getMojoServiceRemote(); + + if (loadTimeData.getBoolean('splitSettingsSyncEnabled')) { + this.osSyncBrowserProxy_ = settings.OsSyncBrowserProxyImpl.getInstance(); + } else { + this.syncBrowserProxy_ = settings.SyncBrowserProxyImpl.getInstance(); + } }, /** @@ -235,6 +264,23 @@ }, /** + * Handler for when the sync preferences are updated. + * @private + */ + handleSyncPrefsChanged_(syncPrefs) { + this.isWifiSyncEnabled_ = !!syncPrefs && syncPrefs.wifiConfigurationsSynced; + }, + + /** + * Handler for when os sync preferences are updated. + * @private + */ + handleOsSyncPrefsChanged_(osSyncFeatureEnabled, osSyncPrefs) { + this.isWifiSyncEnabled_ = osSyncFeatureEnabled && !!osSyncPrefs && + osSyncPrefs.osWifiConfigurationsSynced; + }, + + /** * @param {string} guid * @param {string} type * @param {string} name @@ -1314,18 +1360,75 @@ }, /** + * @return {boolean} If managedProperties_ is null or this.isBlockedByPolicy_. + * @private + */ + propertiesMissingOrBlockedByPolicy_() { + return !this.managedProperties_ || + this.isBlockedByPolicy_( + this.managedProperties_, this.globalPolicy, + this.managedNetworkAvailable); + }, + + /** * @param {!mojom.ManagedProperties} managedProperties * @param {!mojom.GlobalPolicy} globalPolicy * @param {boolean} managedNetworkAvailable - * @return {boolean} True if the shared message should be shown. + * @param {boolean} isWifiSyncEnabled + * @return {boolean} If the synced/shared message section should be shown. * @private */ - showShared_(managedProperties, globalPolicy, managedNetworkAvailable) { - return !!managedProperties && - (managedProperties.source == mojom.OncSource.kDevice || - managedProperties.source == mojom.OncSource.kDevicePolicy) && - !this.isBlockedByPolicy_( - managedProperties, globalPolicy, managedNetworkAvailable); + showSyncedShared_( + managedProperties, globalPolicy, managedNetworkAvailable, + isWifiSyncEnabled) { + if (this.propertiesMissingOrBlockedByPolicy_()) { + return false; + } + + return managedProperties.source == mojom.OncSource.kDevice && + (isWifiSyncEnabled && !!managedProperties.typeProperties.wifi && + managedProperties.typeProperties.wifi.isSyncable); + }, + + /** + * @param {!mojom.ManagedProperties} managedProperties + * @param {!mojom.GlobalPolicy} globalPolicy + * @param {boolean} managedNetworkAvailable + * @param {boolean} isWifiSyncEnabled + * @return {boolean} If the synced/shared message section should be shown. + * @private + */ + showSyncedUser_( + managedProperties, globalPolicy, managedNetworkAvailable, + isWifiSyncEnabled) { + if (this.propertiesMissingOrBlockedByPolicy_()) { + return false; + } + + return managedProperties.source == mojom.OncSource.kUser && + isWifiSyncEnabled && !!managedProperties.typeProperties.wifi && + managedProperties.typeProperties.wifi.isSyncable; + }, + + /** + * @param {!mojom.ManagedProperties} managedProperties + * @param {!mojom.GlobalPolicy} globalPolicy + * @param {boolean} managedNetworkAvailable + * @param {boolean} isWifiSyncEnabled + * @return {boolean} If the synced/shared message section should be shown. + * @private + */ + showShared_( + managedProperties, globalPolicy, managedNetworkAvailable, + isWifiSyncEnabled) { + if (this.propertiesMissingOrBlockedByPolicy_()) { + return false; + } + + return (managedProperties.source == mojom.OncSource.kDevice || + managedProperties.source == mojom.OncSource.kDevicePolicy) && + (!isWifiSyncEnabled || !managedProperties.typeProperties.wifi || + !managedProperties.typeProperties.wifi.isSyncable); }, /**
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/manage_a11y_page.html b/chrome/browser/resources/settings/chromeos/os_a11y_page/manage_a11y_page.html index e4af047..83f39fe 100644 --- a/chrome/browser/resources/settings/chromeos/os_a11y_page/manage_a11y_page.html +++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/manage_a11y_page.html
@@ -51,11 +51,13 @@ pref="{{prefs.settings.accessibility}}" label="$i18n{chromeVoxLabel}"> </settings-toggle-button> - <iron-collapse opened="[[prefs.settings.accessibility.value]]"> - <cr-link-row id="chromeVoxSubpageButton" - class="settings-box" on-click="onChromeVoxSettingsTap_" - label="$i18n{chromeVoxOptionsLabel}" external></cr-link-row> - </iron-collapse> + <template is="dom-if" if="[[!isKioskModeActive_]]"> + <iron-collapse opened="[[prefs.settings.accessibility.value]]"> + <cr-link-row id="chromeVoxSubpageButton" + class="settings-box" on-click="onChromeVoxSettingsTap_" + label="$i18n{chromeVoxOptionsLabel}" external></cr-link-row> + </iron-collapse> + </template> <settings-toggle-button pref="{{prefs.settings.a11y.select_to_speak}}" class="hr"
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/manage_a11y_page.js b/chrome/browser/resources/settings/chromeos/os_a11y_page/manage_a11y_page.js index ffa19ac..6fb8790 100644 --- a/chrome/browser/resources/settings/chromeos/os_a11y_page/manage_a11y_page.js +++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/manage_a11y_page.js
@@ -211,6 +211,9 @@ 'initial-data-ready', this.onManageAllyPageReady_.bind(this)); chrome.send('manageA11yPageReady'); + this.addWebUIListener( + 'tablet-mode-changed', this.onTabletModeChanged_.bind(this)); + const r = settings.routes; this.addFocusConfig_(r.MANAGE_TTS_SETTINGS, '#ttsSubpageButton'); this.addFocusConfig_(r.MANAGE_CAPTION_SETTINGS, '#captionsSubpageButton'); @@ -381,15 +384,26 @@ }, /** + * Called when tablet mode is changed. Handles updating the visibility of the + * shelf navigation buttons setting. + * @param {boolean} tabletModeEnabled Whether tablet mode is enabled. + * @private + */ + onTabletModeChanged_(tabletModeEnabled) { + this.showShelfNavigationButtonsSettings_ = tabletModeEnabled && + loadTimeData.getBoolean('showTabletModeShelfNavigationButtonsSettings'); + }, + + /** * Handles updating the visibility of the shelf navigation buttons setting * and updating whether startupSoundEnabled is checked. * @param {boolean} startup_sound_enabled Whether startup sound is enabled. - * @param {boolean} tablet_mode_supported Whether tablet mode is supported. + * @param {boolean} tabletModeEnabled Whether tablet mode is enabled. * @private */ - onManageAllyPageReady_(startup_sound_enabled, tablet_mode_supported) { + onManageAllyPageReady_(startup_sound_enabled, tabletModeEnabled) { this.$.startupSoundEnabled.checked = startup_sound_enabled; - this.showShelfNavigationButtonsSettings_ = tablet_mode_supported && + this.showShelfNavigationButtonsSettings_ = tabletModeEnabled && loadTimeData.getBoolean( 'showTabletModeShelfNavigationButtonsSettings') && !this.isKioskModeActive_;
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/BUILD.gn index 8c4309e..7de06d7 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/BUILD.gn
@@ -67,10 +67,8 @@ js_library("app_detail_view") { deps = [ - ":arc_detail_view", - ":chrome_app_detail_view", + ":actions", ":dom_switch", - ":pwa_detail_view", ":store_client", "../..:os_route", "../../..:router", @@ -104,6 +102,7 @@ } js_library("constants") { + deps = [ "//chrome/browser/ui/webui/app_management:mojo_bindings_js_library_for_compile" ] } js_library("dom_switch") { @@ -131,6 +130,7 @@ js_library("permission_item") { deps = [ + ":browser_proxy", ":fake_page_handler", ":store_client", ":toggle_row",
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_detail_view.html b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_detail_view.html index bbe1f7ee..14252f9 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_detail_view.html +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_detail_view.html
@@ -4,6 +4,7 @@ <link rel="import" href="pwa_detail_view.html"> <link rel="import" href="arc_detail_view.html"> <link rel="import" href="chrome_app_detail_view.html"> +<link rel="import" href="plugin_vm_page/plugin_vm_detail_view.html"> <link rel="import" href="../../os_route.html"> <link rel="import" href="../../../router.html"> <link rel="import" href="../../../settings_shared_css.html"> @@ -22,6 +23,8 @@ <app-management-chrome-app-detail-view route-id="chrome-app-detail-view"> </app-management-chrome-app-detail-view> + <app-management-plugin-vm-detail-view route-id="plugin-vm-detail-view"> + </app-management-plugin-vm-detail-view> </template> </app-management-dom-switch> </template>
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_detail_view.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_detail_view.js index 438e3523..fa141e0b 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_detail_view.js +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_detail_view.js
@@ -91,6 +91,8 @@ return 'chrome-app-detail-view'; case (AppType.kArc): return 'arc-detail-view'; + case (AppType.kPluginVm): + return 'plugin-vm-detail-view'; default: assertNotReached(); }
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_item.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_item.js index 196d417..3824a209 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_item.js +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_item.js
@@ -51,6 +51,8 @@ return AppManagementEntryPoint.MainViewChromeApp; case AppType.kWeb: return AppManagementEntryPoint.MainViewWebApp; + case AppType.kPluginVm: + return AppManagementEntryPoint.MainViewPluginVm; default: assertNotReached(); }
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/constants.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/constants.js index ab52438..50a06ae 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/constants.js +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/constants.js
@@ -31,6 +31,8 @@ const PwaPermissionType = appManagement.mojom.PwaPermissionType; +const PluginVmPermissionType = appManagement.mojom.PluginVmPermissionType; + const ArcPermissionType = appManagement.mojom.ArcPermissionType; const AppType = apps.mojom.AppType; @@ -63,6 +65,8 @@ MainViewChromeApp: 7, MainViewWebApp: 8, OsSettingsMainPage: 9, + MainViewPluginVm: 10, + DBusServicePluginVm: 11, }; /** @@ -88,4 +92,6 @@ ContactsTurnedOff: 14, StorageTurnedOn: 15, StorageTurnedOff: 16, + PrintingTurnedOn: 17, + PrintingTurnedOff: 18, };
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/permission_item.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/permission_item.js index d7912a0..198557b 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/permission_item.js +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/permission_item.js
@@ -257,6 +257,10 @@ return permissionValue ? AppManagementUserAction.StorageTurnedOn : AppManagementUserAction.StorageTurnedOff; + case 'PRINTING': + return permissionValue ? AppManagementUserAction.PrintingTurnedOn : + AppManagementUserAction.PrintingTurnedOff; + default: assertNotReached(); }
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/BUILD.gn new file mode 100644 index 0000000..3c63e8b --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/BUILD.gn
@@ -0,0 +1,94 @@ +# 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. + +import("//third_party/closure_compiler/compile_js.gni") + +js_type_check("closure_compile") { + deps = [ + ":plugin_vm_browser_proxy", + ":plugin_vm_detail_view", + ":plugin_vm_shared_paths", + ] +} + +js_library("plugin_vm_browser_proxy") { + deps = [ "//ui/webui/resources/js:cr" ] +} + +js_library("plugin_vm_detail_view") { + deps = [ + "../:constants", + "../:store_client", + "../:util", + ] +} + +js_library("plugin_vm_shared_paths") { + deps = [ + ":plugin_vm_browser_proxy", + "../../..:metrics_recorder", + ] +} + +# TODO: Uncomment as the Polymer3 migration makes progress. +#js_type_check("closure_compile_module") { +# is_polymer3 = true +# deps = [ +# ":plugin_vm_browser_proxy.m", +# ":plugin_vm_detail_view.m", +# ":plugin_vm_shared_paths.m", +# ] +#} + +js_library("plugin_vm_browser_proxy.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_browser_proxy.m.js" ] + deps = [ + # TODO: Fill those in. + ] + extra_deps = [ ":modulize" ] +} + +js_library("plugin_vm_detail_view.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_detail_view.m.js" ] + deps = [ + # TODO: Fill those in. + ] + extra_deps = [ ":plugin_vm_detail_view_module" ] +} + +js_library("plugin_vm_shared_paths.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_shared_paths.m.js" ] + deps = [ + # TODO: Fill those in. + ] + extra_deps = [ ":plugin_vm_shared_paths_module" ] +} + +import("//tools/polymer/polymer.gni") + +group("polymer3_elements") { + public_deps = [ + ":modulize", + ":plugin_vm_detail_view_module", + ":plugin_vm_shared_paths_module", + ] +} + +polymer_modulizer("plugin_vm_detail_view") { + js_file = "plugin_vm_detail_view.js" + html_file = "plugin_vm_detail_view.html" + html_type = "dom-module" +} + +polymer_modulizer("plugin_vm_shared_paths") { + js_file = "plugin_vm_shared_paths.js" + html_file = "plugin_vm_shared_paths.html" + html_type = "dom-module" +} + +import("//ui/webui/resources/tools/js_modulizer.gni") + +js_modulizer("modulize") { + input_files = [ "plugin_vm_browser_proxy.js" ] +}
diff --git a/chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_browser_proxy.html b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_browser_proxy.html similarity index 100% rename from chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_browser_proxy.html rename to chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_browser_proxy.html
diff --git a/chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_browser_proxy.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_browser_proxy.js similarity index 79% rename from chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_browser_proxy.js rename to chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_browser_proxy.js index d9dc1c8..bfd60c1 100644 --- a/chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_browser_proxy.js +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_browser_proxy.js
@@ -20,12 +20,6 @@ * @param {string} path Path to stop sharing. */ removePluginVmSharedPath(vmName, path) {} - - /* Removes the default vm if it is installed. */ - removePluginVm() {} - - /* Show Plugin Vm installer. */ - requestPluginVmInstallerView() {} } /** @implements {settings.PluginVmBrowserProxy} */ @@ -39,16 +33,6 @@ removePluginVmSharedPath(vmName, path) { chrome.send('removePluginVmSharedPath', [vmName, path]); } - - /** @override */ - removePluginVm() { - chrome.send('removePluginVm'); - } - - /** @override */ - requestPluginVmInstallerView() { - chrome.send('requestPluginVmInstallerView'); - } } // The singleton instance_ can be replaced with a test version of this wrapper
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_detail_view.html b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_detail_view.html new file mode 100644 index 0000000..b60fdef6 --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_detail_view.html
@@ -0,0 +1,52 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="../browser_proxy.html"> +<link rel="import" href="../icons.html"> +<link rel="import" href="../permission_item.html"> +<link rel="import" href="../pin_to_shelf_item.html"> +<link rel="import" href="../shared_style.html"> +<link rel="import" href="../store_client.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html"> +<link rel="import" href="chrome://resources/cr_elements/icons.html"> + +<dom-module id="app-management-plugin-vm-detail-view"> + <template> + <style include="app-management-shared-css"> + </style> + + <div class="permission-list"> + <!-- TODO(1082000): |app_| property on app-management-pin-to-shelf-item + should not be private. --> + <app-management-pin-to-shelf-item + id="pin-to-shelf-setting" + class="permission-card-row separated-row header-text" + app_="[[app_]]"> + </app-management-pin-to-shelf-item> + <div class="permission-card-row"> + <div class="permission-section-header"> + <div class="header-text">$i18n{appManagementPermissionsLabel}</div> + </div> + <div class="permission-list indented-permission-block"> + <app-management-permission-item + class="subpermission-row" icon="cr:print" + permission-label="$i18n{appManagementPrintingPermissionLabel}" + permission-type="PRINTING"> + </app-management-permission-item> + </div> + </div> + + <div class="permission-card-row separated-row header-text clickable" + on-click="onSharedPathsClick_"> + <div id="label" class="header-text" aria-hidden="true"> + $i18n{pluginVmSharedPaths} + </div> + <div class="permission-row-controls"> + <cr-icon-button class="subpage-arrow app-management-item-arrow" + role="link" tabindex="0" aria-labelledby="label"> + </cr-icon-button> + </div> + </div> + </div> + </template> + <script src="plugin_vm_detail_view.js"></script> +</dom-module>
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_detail_view.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_detail_view.js new file mode 100644 index 0000000..c537ae4 --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_detail_view.js
@@ -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. + +Polymer({ + is: 'app-management-plugin-vm-detail-view', + + behaviors: [ + app_management.StoreClient, + ], + + properties: { + /** + * @private {App} + */ + app_: Object, + }, + + attached() { + // When the state is changed, get the new selected app and assign it to + // |app_| + this.watch('app_', state => app_management.util.getSelectedApp(state)); + this.updateFromStore(); + }, + + /** + * @private + */ + onSharedPathsClick_() { + settings.Router.getInstance().navigateTo( + settings.routes.APP_MANAGEMENT_PLUGIN_VM_SHARED_PATHS); + }, +});
diff --git a/chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_shared_paths.html b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_shared_paths.html similarity index 90% rename from chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_shared_paths.html rename to chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_shared_paths.html index 202eb74..1c4d62e 100644 --- a/chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_shared_paths.html +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_shared_paths.html
@@ -2,8 +2,8 @@ <link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html"> <link rel="import" href="plugin_vm_browser_proxy.html"> -<link rel="import" href="../../settings_shared_css.html"> -<link rel="import" href="../metrics_recorder.html"> +<link rel="import" href="../../../../settings_shared_css.html"> +<link rel="import" href="../../../metrics_recorder.html"> <dom-module id="settings-plugin-vm-shared-paths"> <template>
diff --git a/chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_shared_paths.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_shared_paths.js similarity index 100% rename from chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_shared_paths.js rename to chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_shared_paths.js
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/util.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/util.js index e43778a..24c4718 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/util.js +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/util.js
@@ -133,6 +133,8 @@ return PwaPermissionType[permissionType]; case AppType.kArc: return ArcPermissionType[permissionType]; + case AppType.kPluginVm: + return PluginVmPermissionType[permissionType]; default: assertNotReached(); } @@ -221,6 +223,8 @@ return 'AppManagement.AppDetailViews.ChromeApp'; case AppType.kWeb: return 'AppManagement.AppDetailViews.WebApp'; + case AppType.kPluginVm: + return 'AppManagement.AppDetailViews.PluginVmApp'; default: assertNotReached(); }
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/os_apps_page.html b/chrome/browser/resources/settings/chromeos/os_apps_page/os_apps_page.html index 3d6565d..69c36a9 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/os_apps_page.html +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/os_apps_page.html
@@ -18,6 +18,7 @@ <link rel="import" href="android_apps_subpage.html"> <link rel="import" href="app_management_page/app_management_page.html"> <link rel="import" href="app_management_page/app_detail_view.html"> +<link rel="import" href="app_management_page/plugin_vm_page/plugin_vm_shared_paths.html"> <link rel="import" href="app_management_page/uninstall_button.html"> <dom-module id="os-settings-apps-page"> @@ -113,6 +114,16 @@ </settings-subpage> </template> </template> + + <!-- Plugin VM --> + <template is="dom-if" if="[[showPluginVm]]" restamp> + <template is="dom-if" route-path="/app-management/pluginVm/sharedPaths"> + <settings-subpage page-title="$i18n{pluginVmSharedPaths}"> + <settings-plugin-vm-shared-paths prefs="{{prefs}}"> + </settings-plugin-vm-shared-paths> + </settings-subpage> + </template> + </template> </settings-animated-pages> </template> <script src="os_apps_page.js"></script>
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/os_apps_page.js b/chrome/browser/resources/settings/chromeos/os_apps_page/os_apps_page.js index 44f2b56..8d4834d 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/os_apps_page.js +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/os_apps_page.js
@@ -46,6 +46,12 @@ */ showAndroidApps: Boolean, + /** + * Show Plugin VM shared folders sub-page. + * @type {boolean} + */ + showPluginVm: Boolean, + /** @private {!Map<string, string>} */ focusConfig_: { type: Object,
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_people_page/BUILD.gn index c9d774a..23cc34fa 100644 --- a/chrome/browser/resources/settings/chromeos/os_people_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/os_people_page/BUILD.gn
@@ -171,8 +171,8 @@ deps = [ ":fingerprint_browser_proxy", "..:metrics_recorder", - "//ui/webui/resources/cr_elements/chromeos/cr_lottie:cr_lottie", "//ui/webui/resources/cr_elements/cr_fingerprint:cr_fingerprint_progress_arc", + "//ui/webui/resources/cr_elements/cr_lottie:cr_lottie", "//ui/webui/resources/js:i18n_behavior", "//ui/webui/resources/js:web_ui_listener_behavior", ]
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_browser_proxy.js b/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_browser_proxy.js index 3180aea8..46e7848 100644 --- a/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_browser_proxy.js +++ b/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_browser_proxy.js
@@ -39,6 +39,11 @@ didNavigateAwayFromOsSyncPage() {} /** + * Function to invoke when the WebUI wants an update of the OsSyncPrefs. + */ + sendOsSyncPrefsChanged() {} + + /** * Sets whether the OS sync feature should be enabled. Sync will not start * until the user either navigates away from the page or closes settings. * @param {boolean} enabled @@ -67,6 +72,11 @@ } /** @override */ + sendOsSyncPrefsChanged() { + chrome.send('OsSyncPrefsDispatch'); + } + + /** @override */ setOsSyncFeatureEnabled(enabled) { return chrome.send('SetOsSyncFeatureEnabled', [enabled]); }
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/setup_fingerprint_dialog.html b/chrome/browser/resources/settings/chromeos/os_people_page/setup_fingerprint_dialog.html index 86305f6..a32b56a 100644 --- a/chrome/browser/resources/settings/chromeos/os_people_page/setup_fingerprint_dialog.html +++ b/chrome/browser/resources/settings/chromeos/os_people_page/setup_fingerprint_dialog.html
@@ -1,6 +1,6 @@ <link rel="import" href="chrome://resources/html/polymer.html"> -<link rel="import" href="chrome://resources/cr_elements/chromeos/cr_lottie/cr_lottie.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_lottie/cr_lottie.html"> <link rel="import" href="chrome://resources/cr_elements/cr_fingerprint/cr_fingerprint_progress_arc.html"> <link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html">
diff --git a/chrome/browser/resources/settings/chromeos/os_route.js b/chrome/browser/resources/settings/chromeos/os_route.js index 84fcbec..170aab2 100644 --- a/chrome/browser/resources/settings/chromeos/os_route.js +++ b/chrome/browser/resources/settings/chromeos/os_route.js
@@ -158,6 +158,12 @@ r.APPS, mojom.GOOGLE_PLAY_STORE_SUBPAGE_PATH, Subpage.kGooglePlayStore); } + if (loadTimeData.valueExists('showPluginVm') && + loadTimeData.getBoolean('showPluginVm')) { + r.APP_MANAGEMENT_PLUGIN_VM_SHARED_PATHS = createSubpage( + r.APP_MANAGEMENT, mojom.PLUGIN_VM_SHARED_PATHS_SUBPAGE_PATH, + Subpage.kPluginVmSharedPaths); + } // Crostini section. if (loadTimeData.valueExists('showCrostini') && @@ -193,19 +199,6 @@ } } - // Plugin VM section. - if (loadTimeData.valueExists('showPluginVm') && - loadTimeData.getBoolean('showPluginVm')) { - r.PLUGIN_VM = createSection( - r.BASIC, mojom.PLUGIN_VM_SECTION_PATH, Section.kPluginVm); - r.PLUGIN_VM_DETAILS = createSubpage( - r.PLUGIN_VM, mojom.PLUGIN_VM_DETAILS_SUBPAGE_PATH, - Subpage.kPluginVmDetails); - r.PLUGIN_VM_SHARED_PATHS = createSubpage( - r.PLUGIN_VM, mojom.PLUGIN_VM_SHARED_PATHS_SUBPAGE_PATH, - Subpage.kPluginVmSharedPaths); - } - // Date and Time section. r.DATETIME = createSection( r.ADVANCED, mojom.DATE_AND_TIME_SECTION_PATH, Section.kDateAndTime);
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_menu/os_settings_menu.html b/chrome/browser/resources/settings/chromeos/os_settings_menu/os_settings_menu.html index d2634564..e1d0bdb 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings_menu/os_settings_menu.html +++ b/chrome/browser/resources/settings/chromeos/os_settings_menu/os_settings_menu.html
@@ -214,12 +214,6 @@ $i18n{crostiniPageTitle} </div> </a> - <a href="/pluginVm" hidden="[[!showPluginVm]]"> - <div class="item"> - <iron-icon icon="os-settings:plugin-vm"></iron-icon> - $i18n{pluginVmPageTitle} - </div> - </a> <cr-button id="advancedButton" aria-expanded$="[[boolToString_(advancedOpened)]]" on-click="onAdvancedButtonToggle_">
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.html b/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.html index d8a945c..490decb 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.html +++ b/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.html
@@ -16,7 +16,6 @@ <link rel="import" href="../../settings_page_css.html"> <link rel="import" href="../bluetooth_page/bluetooth_page.html"> <link rel="import" href="../crostini_page/crostini_page.html"> -<link rel="import" href="../plugin_vm_page/plugin_vm_page.html"> <link rel="import" href="../../prefs/prefs_behavior.html"> <link rel="import" href="../os_route.html"> <link rel="import" href="../../router.html"> @@ -173,7 +172,8 @@ prefs="{{prefs}}" android-apps-info="[[androidAppsInfo]]" have-play-store-app="[[havePlayStoreApp]]" - show-android-apps="[[showAndroidApps]]"> + show-android-apps="[[showAndroidApps]]" + show-plugin-vm="[[showPluginVm]]"> </os-settings-apps-page> </settings-section> <template is="dom-if" if="[[showCrostini]]" restamp> @@ -184,13 +184,6 @@ </settings-crostini-page> </settings-section> </template> - <template is="dom-if" if="[[showPluginVm]]" restamp> - <settings-section page-title="$i18n{pluginVmPageTitle}" - section="pluginVm"> - <settings-plugin-vm-page prefs="{{prefs}}"> - </settings-plugin-vm-page> - </settings-section> - </template> </div> </template>
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.js b/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.js index a64517a..b233eaa 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.js +++ b/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.js
@@ -45,6 +45,8 @@ showCrostini: Boolean, + showPluginVm: Boolean, + showReset: Boolean, allowCrostini_: Boolean,
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_routes.js b/chrome/browser/resources/settings/chromeos/os_settings_routes.js index 6fa7d82..314f3808 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings_routes.js +++ b/chrome/browser/resources/settings/chromeos/os_settings_routes.js
@@ -13,6 +13,7 @@ * ADVANCED: !settings.Route, * APP_MANAGEMENT: !settings.Route, * APP_MANAGEMENT_DETAIL: !settings.Route, + * APP_MANAGEMENT_PLUGIN_VM_SHARED_PATHS: !settings.Route, * APPS: !settings.Route, * ANDROID_APPS_DETAILS: !settings.Route, * CROSTINI: !settings.Route, @@ -63,9 +64,6 @@ * OS_SYNC: !settings.Route, * OS_PEOPLE: !settings.Route, * PERSONALIZATION: !settings.Route, - * PLUGIN_VM: !settings.Route, - * PLUGIN_VM_DETAILS: !settings.Route, - * PLUGIN_VM_SHARED_PATHS: !settings.Route, * POINTERS: !settings.Route, * POWER: !settings.Route, * PRIVACY: !settings.Route,
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_ui/os_settings_ui.html b/chrome/browser/resources/settings/chromeos/os_settings_ui/os_settings_ui.html index 85c7f61..9c19015e 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings_ui/os_settings_ui.html +++ b/chrome/browser/resources/settings/chromeos/os_settings_ui/os_settings_ui.html
@@ -144,7 +144,6 @@ <template is="dom-if" if="[[showNavMenu_]]"> <os-settings-menu page-visibility="[[pageVisibility_]]" show-crostini="[[showCrostini_]]" - show-plugin-vm="[[showPluginVm_]]" show-reset="[[showReset_]]" have-play-store-app="[[havePlayStoreApp_]]" on-iron-activate="onIronActivate_"
diff --git a/chrome/browser/resources/settings/chromeos/os_toolbar/os_toolbar.js b/chrome/browser/resources/settings/chromeos/os_toolbar/os_toolbar.js index 181ccbd..bc22c34 100644 --- a/chrome/browser/resources/settings/chromeos/os_toolbar/os_toolbar.js +++ b/chrome/browser/resources/settings/chromeos/os_toolbar/os_toolbar.js
@@ -43,9 +43,11 @@ /** @return {?CrToolbarSearchFieldElement} */ getSearchField() { if (this.newOsSettingsSearch_) { - assertNotReached( - 'New OS Search should not be using OsToolbar.getSearchField()'); + return /** @type {?CrToolbarSearchFieldElement} */ ( + this.shadowRoot.querySelector('os-settings-search-box') + .$$('cr-toolbar-search-field')); } + // TODO(crbug/1080777): Remove when new settings search complete. return /** @type {?CrToolbarSearchFieldElement} */ ( this.$$('cr-toolbar-search-field')); },
diff --git a/chrome/browser/resources/settings/chromeos/plugin_vm_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/plugin_vm_page/BUILD.gn deleted file mode 100644 index 769bf101..0000000 --- a/chrome/browser/resources/settings/chromeos/plugin_vm_page/BUILD.gn +++ /dev/null
@@ -1,143 +0,0 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//third_party/closure_compiler/compile_js.gni") - -js_type_check("closure_compile") { - deps = [ - ":plugin_vm_browser_proxy", - ":plugin_vm_page", - ":plugin_vm_remove_confirmation_dialog", - ":plugin_vm_shared_paths", - ":plugin_vm_subpage", - "..:metrics_recorder", - ] -} - -js_library("plugin_vm_browser_proxy") { - deps = [ "//ui/webui/resources/js:cr" ] -} - -js_library("plugin_vm_page") { - deps = [ - "..:os_route", - "../..:router", - "../../prefs:prefs_behavior", - "//ui/webui/resources/js:i18n_behavior", - ] - externs_list = [ "$externs_path/settings_private.js" ] -} - -js_library("plugin_vm_shared_paths") { - deps = [ - ":plugin_vm_browser_proxy", - "../..:router", - ] -} - -js_library("plugin_vm_subpage") { - deps = [ - "..:os_route", - "../..:router", - "../../prefs:prefs_behavior", - ] -} - -js_library("plugin_vm_remove_confirmation_dialog") { - deps = [ ":plugin_vm_browser_proxy" ] -} - -# TODO: Uncomment as the Polymer3 migration makes progress. -#js_type_check("closure_compile_module") { -# is_polymer3 = true -# deps = [ -# ":plugin_vm_browser_proxy.m", -# ":plugin_vm_page.m", -# ":plugin_vm_remove_confirmation_dialog.m", -# ":plugin_vm_shared_paths.m", -# ":plugin_vm_subpage.m" -# ] -#} - -js_library("plugin_vm_browser_proxy.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_browser_proxy.m.js" ] - deps = [ - # TODO: Fill those in. - ] - extra_deps = [ ":modulize" ] -} - -js_library("plugin_vm_page.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_page.m.js" ] - deps = [ - # TODO: Fill those in. - ] - extra_deps = [ ":plugin_vm_page_module" ] -} - -js_library("plugin_vm_remove_confirmation_dialog.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_remove_confirmation_dialog.m.js" ] - deps = [ - # TODO: Fill those in. - ] - extra_deps = [ ":plugin_vm_remove_confirmation_dialog_module" ] -} - -js_library("plugin_vm_shared_paths.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_shared_paths.m.js" ] - deps = [ - # TODO: Fill those in. - ] - extra_deps = [ ":plugin_vm_shared_paths_module" ] -} - -js_library("plugin_vm_subpage.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_subpage.m.js" ] - deps = [ - # TODO: Fill those in. - ] - extra_deps = [ ":plugin_vm_subpage_module" ] -} - -import("//tools/polymer/polymer.gni") - -group("polymer3_elements") { - public_deps = [ - ":modulize", - ":plugin_vm_page_module", - ":plugin_vm_remove_confirmation_dialog_module", - ":plugin_vm_shared_paths_module", - ":plugin_vm_subpage_module", - ] -} - -polymer_modulizer("plugin_vm_page") { - js_file = "plugin_vm_page.js" - html_file = "plugin_vm_page.html" - html_type = "dom-module" -} - -polymer_modulizer("plugin_vm_remove_confirmation_dialog") { - js_file = "plugin_vm_remove_confirmation_dialog.js" - html_file = "plugin_vm_remove_confirmation_dialog.html" - html_type = "dom-module" -} - -polymer_modulizer("plugin_vm_shared_paths") { - js_file = "plugin_vm_shared_paths.js" - html_file = "plugin_vm_shared_paths.html" - html_type = "dom-module" -} - -polymer_modulizer("plugin_vm_subpage") { - js_file = "plugin_vm_subpage.js" - html_file = "plugin_vm_subpage.html" - html_type = "dom-module" -} - -import("//ui/webui/resources/tools/js_modulizer.gni") - -js_modulizer("modulize") { - input_files = [ "plugin_vm_browser_proxy.js" ] -}
diff --git a/chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_page.html b/chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_page.html deleted file mode 100644 index 76c37984b..0000000 --- a/chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_page.html +++ /dev/null
@@ -1,76 +0,0 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> - -<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html"> -<link rel="import" href="chrome://resources/html/i18n_behavior.html"> -<link rel="import" href="../../i18n_setup.html"> -<link rel="import" href="../../prefs/prefs_behavior.html"> -<link rel="import" href="../os_route.html"> -<link rel="import" href="../../router.html"> -<link rel="import" href="../../settings_page/settings_animated_pages.html"> -<link rel="import" href="../../settings_page/settings_subpage.html"> -<link rel="import" href="../../settings_shared_css.html"> -<link rel="import" href="plugin_vm_browser_proxy.html"> -<link rel="import" href="plugin_vm_shared_paths.html"> -<link rel="import" href="plugin_vm_subpage.html"> - -<dom-module id="settings-plugin-vm-page"> - <template> - <style include="settings-shared"></style> - - <settings-animated-pages id="pages" section="pluginVm" - focus-config="[[focusConfig_]]"> - <div route-path="default"> - <div id="pluginVm" class="settings-box two-line first" - on-click="onSubpageClick_"> - <div class="start"> - $i18n{pluginVmPageLabel} - <div class="secondary" id="secondaryText"> - $i18n{pluginVmPageSubtext} - </div> - </div> - <template is="dom-if" if="[[prefs.plugin_vm.image_exists.value]]"> - <cr-icon-button id="navigate-to-subpage" - class="subpage-arrow" - aria-label="i18n{pluginVmPageLabel}" - aria-describedby="secondaryText" - aria-roledescription="$i18n{subpageArrowRoleDescription}"> - </cr-icon-button> - </template> - <template is="dom-if" if="[[!prefs.plugin_vm.image_exists.value]]"> - <template is="dom-if" if="[[!allowPluginVm_]]" restamp> - <cr-policy-indicator indicator-type="userPolicy"> - </cr-policy-indicator> - </template> - <div class="separator"></div> - <cr-button id="enable" - disabled="[[!allowPluginVm_]]" - on-click="onEnableClick_" - aria-describedby="secondaryText"> - $i18n{pluginVmPageEnable} - </cr-button> - </template> - </div> - </div> - - <template is="dom-if" route-path="/pluginVm/details"> - <settings-subpage - associated-control="[[$$('#plugin-vm')]]" - page-title="$i18n{pluginVmPageLabel}"> - <settings-plugin-vm-subpage prefs="{{prefs}}"> - </settings-plugin-vm-subpage> - </settings-subpage> - </template> - - <template is="dom-if" route-path="/pluginVm/sharedPaths"> - <settings-subpage - associated-control="[[$$('#plugin-vm')]]" - page-title="$i18n{pluginVmSharedPaths}"> - <settings-plugin-vm-shared-paths prefs="{{prefs}}"> - </settings-plugin-vm-shared-paths> - </settings-subpage> - </template> - </settings-animated-pages> - </template> - <script src="plugin_vm_page.js"></script> -</dom-module>
diff --git a/chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_page.js b/chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_page.js deleted file mode 100644 index f6dddc9..0000000 --- a/chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_page.js +++ /dev/null
@@ -1,67 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @fileoverview - * 'plugin-vm-page' is the settings page for Plugin VM. - */ - -Polymer({ - is: 'settings-plugin-vm-page', - - behaviors: [PrefsBehavior], - - properties: { - /** Preferences state. */ - prefs: { - type: Object, - notify: true, - }, - - /** @private */ - allowPluginVm_: Boolean, - - /** @private {!Map<string, string>} */ - focusConfig_: { - type: Object, - value() { - const map = new Map(); - if (settings.routes.PLUGIN_VM_DETAILS) { - map.set(settings.routes.PLUGIN_VM_DETAILS.path, '#plugin-vm'); - } - if (settings.routes.PLUGIN_VM_SHARED_PATHS) { - map.set(settings.routes.PLUGIN_VM_SHARED_PATHS.path, '#plugin-vm'); - } - return map; - }, - }, - }, - - /** @override */ - attached: function() { - this.allowPluginVm_ = loadTimeData.valueExists('allowPluginVm') && - loadTimeData.getBoolean('allowPluginVm'); - }, - - /** - * @param {!Event} event - * @private - */ - onSubpageClick_(event) { - if (this.getPref('plugin_vm.image_exists').value) { - settings.Router.getInstance().navigateTo( - settings.routes.PLUGIN_VM_DETAILS); - } - }, - - /** - * @param {!Event} event - * @private - */ - onEnableClick_(event) { - settings.PluginVmBrowserProxyImpl.getInstance() - .requestPluginVmInstallerView(); - event.stopPropagation(); - }, -});
diff --git a/chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_remove_confirmation_dialog.html b/chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_remove_confirmation_dialog.html deleted file mode 100644 index 48cc54ee..0000000 --- a/chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_remove_confirmation_dialog.html +++ /dev/null
@@ -1,23 +0,0 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> - -<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> -<link rel="import" href="plugin_vm_browser_proxy.html"> -<link rel="import" href="../../settings_shared_css.html"> - -<dom-module id="settings-plugin-vm-remove-confirmation-dialog"> - <template> - <style include="settings-shared"></style> - <cr-dialog id="dialog" close-text="$i18n{close}"> - <div slot="title">$i18n{pluginVmRemove}</div> - <div slot="body">$i18n{pluginVmRemoveConfirmationDialogMessage}</div> - <div slot="button-container"> - <cr-button id="cancel" class="cancel-button" - on-click="onCancelClick_">$i18n{cancel}</cr-button> - <cr-button id="continue" class="action-button" - on-click="onContinueClick_">$i18n{pluginVmRemoveButton}</cr-button> - </div> - </cr-dialog> - </template> - <script src="plugin_vm_remove_confirmation_dialog.js"></script> -</dom-module>
diff --git a/chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_remove_confirmation_dialog.js b/chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_remove_confirmation_dialog.js deleted file mode 100644 index b71af55..0000000 --- a/chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_remove_confirmation_dialog.js +++ /dev/null
@@ -1,27 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @fileoverview 'settings-plugin-vm-remove-confirmation-dialog' is a component - * warning the user that remove plugin vm removes their vm's data and settings. - */ -Polymer({ - is: 'settings-plugin-vm-remove-confirmation-dialog', - - /** @override */ - attached: function() { - this.$.dialog.showModal(); - }, - - /** @private */ - onCancelClick_: function() { - this.$.dialog.cancel(); - }, - - /** @private */ - onContinueClick_: function() { - settings.PluginVmBrowserProxyImpl.getInstance().removePluginVm(); - this.$.dialog.close(); - }, -});
diff --git a/chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_subpage.html b/chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_subpage.html deleted file mode 100644 index ae7874e..0000000 --- a/chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_subpage.html +++ /dev/null
@@ -1,48 +0,0 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> - -<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html"> -<link rel="import" href="../../prefs/prefs_behavior.html"> -<link rel="import" href="../os_route.html"> -<link rel="import" href="../../router.html"> -<link rel="import" href="plugin_vm_remove_confirmation_dialog.html"> -<link rel="import" href="../../settings_shared_css.html"> -<link rel="import" href="../../controls/settings_toggle_button.html"> - -<dom-module id="settings-plugin-vm-subpage"> - <template> - <style include="settings-shared"></style> - <div id="plugin-vm-shared-paths" class="settings-box first" - on-click="onSharedPathsClick_" actionable> - <div class="start">$i18n{pluginVmSharedPaths}</div> - <cr-icon-button class="subpage-arrow" - aria-label="$i18n{pluginVmSharedPaths}" - aria-roledescription="$i18n{subpageArrowRoleDescription}"> - </cr-icon-button> - </div> - <settings-toggle-button id="plugin-vm-printer-access" - class="hr" - label="$i18n{pluginVmPrinterAccess}" - pref="{{prefs.plugin_vm.printers_allowed}}"> - </settings-toggle-button> - <template is="dom-if" if="[[showPluginVmCamera_]]"> - <settings-toggle-button - class="hr" - label="$i18n{pluginVmCameraAccessTitle}" - pref="{{prefs.plugin_vm.camera_sharing}}"> - </settings-toggle-button> - </template> - <div id="plugin-vm-remove" class="settings-box"> - <div id="pluginVmRemoveLabel" class="start">$i18n{pluginVmRemove}</div> - <cr-button on-click="onRemoveClick_" id="pluginVmRemoveButton" - aria-labelledby="pluginVmRemoveLabel"> - $i18n{pluginVmRemoveButton} - </cr-button> - <template is="dom-if" if="[[showRemoveConfirmationDialog_]]" restamp> - <settings-plugin-vm-remove-confirmation-dialog - on-close="onRemoveConfirmationDialogClose_"> - </settings-plugin-vm-remove-confirmation-dialog> - </template> - </div> - </template> - <script src="plugin_vm_subpage.js"></script> -</dom-module>
diff --git a/chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_subpage.js b/chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_subpage.js deleted file mode 100644 index 611266c..0000000 --- a/chrome/browser/resources/settings/chromeos/plugin_vm_page/plugin_vm_subpage.js +++ /dev/null
@@ -1,76 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @fileoverview - * 'plugin-vm-subpage' is the settings subpage for managing Plugin VM. - */ - -Polymer({ - is: 'settings-plugin-vm-subpage', - - behaviors: [PrefsBehavior], - - properties: { - /** Preferences state. */ - prefs: { - type: Object, - notify: true, - }, - - /** @private */ - showRemoveConfirmationDialog_: { - type: Boolean, - value: false, - }, - - /** - * Whether the toggle to share the camera with PluginVm should be shown. - * @private {boolean} - */ - showPluginVmCamera_: { - type: Boolean, - value() { - return loadTimeData.getBoolean('showPluginVmCamera'); - }, - }, - }, - - observers: [ - 'onPluginVmImageExistsChanged_(prefs.plugin_vm.image_exists.value)', - ], - - /** - * @param {boolean} exists - * @private - */ - onPluginVmImageExistsChanged_(exists) { - if (!exists) { - settings.Router.getInstance().navigateTo(settings.routes.PLUGIN_VM); - } - }, - - /** @private */ - onSharedPathsClick_() { - settings.Router.getInstance().navigateTo( - settings.routes.PLUGIN_VM_SHARED_PATHS); - }, - - /** - * Shows a confirmation dialog, which if accepted will remove PluginVm. - * @private - */ - onRemoveClick_() { - this.showRemoveConfirmationDialog_ = true; - }, - - /** - * Hides the remove confirmation dialog. - * @private - */ - onRemoveConfirmationDialogClose_: function() { - this.showRemoveConfirmationDialog_ = false; - this.$.pluginVmRemoveButton.focus(); - }, -});
diff --git a/chrome/browser/resources/settings/lazy_load.js b/chrome/browser/resources/settings/lazy_load.js index 748503e8..ff6aaad 100644 --- a/chrome/browser/resources/settings/lazy_load.js +++ b/chrome/browser/resources/settings/lazy_load.js
@@ -73,7 +73,7 @@ export {ImportDataBrowserProxyImpl, ImportDataStatus} from './people_page/import_data_browser_proxy.js'; export {ManageProfileBrowserProxyImpl, ProfileShortcutStatus} from './people_page/manage_profile_browser_proxy.js'; // </if> -export {SafeBrowsingBrowserProxyImpl} from './privacy_page/safe_browsing_browser_proxy.js'; +export {SafeBrowsingBrowserProxy, SafeBrowsingBrowserProxyImpl, SafeBrowsingRadioManagedState} from './privacy_page/safe_browsing_browser_proxy.js'; export {BioEnrollDialogPage} from './privacy_page/security_keys_bio_enroll_dialog.js'; export {Ctap2Status, SampleStatus, SecurityKeysBioEnrollProxyImpl, SecurityKeysCredentialBrowserProxyImpl, SecurityKeysPINBrowserProxyImpl, SecurityKeysResetBrowserProxyImpl} from './privacy_page/security_keys_browser_proxy.js'; export {CredentialManagementDialogPage} from './privacy_page/security_keys_credential_management_dialog.js';
diff --git a/chrome/browser/resources/settings/os_settings_resources.grd b/chrome/browser/resources/settings/os_settings_resources.grd index f86164f0..cf80563 100644 --- a/chrome/browser/resources/settings/os_settings_resources.grd +++ b/chrome/browser/resources/settings/os_settings_resources.grd
@@ -230,6 +230,24 @@ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_APP_UNINSTALL_BUTTON_HTML" file="chromeos/os_apps_page/app_management_page/uninstall_button.html" compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PLUGIN_VM_DETAIL_VIEW_JS" + file="chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_detail_view.js" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PLUGIN_VM_DETAIL_VIEW_HTML" + file="chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_detail_view.html" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PLUGIN_VM_SHARED_PATHS_HTML" + file="chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_shared_paths.html" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PLUGIN_VM_SHARED_PATHS_JS" + file="chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_shared_paths.js" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PLUGIN_VM_BROWSER_PROXY_JS" + file="chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_browser_proxy.js" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PLUGIN_VM_BROWSER_PROXY_HTML" + file="chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_browser_proxy.html" + compress="false" type="chrome_html" /> <structure name="IDR_OS_SETTINGS_CAPTIONS_SUBPAGE_JS" file="a11y_page/captions_subpage.js" compress="false" type="chrome_html" /> @@ -1314,36 +1332,6 @@ <structure name="IDR_OS_SETTINGS_PEOPLE_FINGERPRINT_BROWSER_PROXY_HTML" file="chromeos/os_people_page/fingerprint_browser_proxy.html" compress="false" type="chrome_html" /> - <structure name="IDR_OS_SETTINGS_PLUGIN_VM_PAGE_HTML" - file="chromeos/plugin_vm_page/plugin_vm_page.html" - compress="false" type="chrome_html" /> - <structure name="IDR_OS_SETTINGS_PLUGIN_VM_PAGE_JS" - file="chromeos/plugin_vm_page/plugin_vm_page.js" - compress="false" type="chrome_html" /> - <structure name="IDR_OS_SETTINGS_PLUGIN_VM_SHARED_PATHS_HTML" - file="chromeos/plugin_vm_page/plugin_vm_shared_paths.html" - compress="false" type="chrome_html" /> - <structure name="IDR_OS_SETTINGS_PLUGIN_VM_SHARED_PATHS_JS" - file="chromeos/plugin_vm_page/plugin_vm_shared_paths.js" - compress="false" type="chrome_html" /> - <structure name="IDR_OS_SETTINGS_PLUGIN_VM_SUBPAGE_HTML" - file="chromeos/plugin_vm_page/plugin_vm_subpage.html" - compress="false" type="chrome_html" /> - <structure name="IDR_OS_SETTINGS_PLUGIN_VM_SUBPAGE_JS" - file="chromeos/plugin_vm_page/plugin_vm_subpage.js" - compress="false" type="chrome_html" /> - <structure name="IDR_OS_SETTINGS_PLUGIN_VM_BROWSER_PROXY_JS" - file="chromeos/plugin_vm_page/plugin_vm_browser_proxy.js" - compress="false" type="chrome_html" /> - <structure name="IDR_OS_SETTINGS_PLUGIN_VM_BROWSER_PROXY_HTML" - file="chromeos/plugin_vm_page/plugin_vm_browser_proxy.html" - compress="false" type="chrome_html" /> - <structure name="IDR_OS_SETTINGS_PLUGIN_VM_REMOVE_CONFIRMATION_DIALOG_JS" - file="chromeos/plugin_vm_page/plugin_vm_remove_confirmation_dialog.js" - compress="false" type="chrome_html" /> - <structure name="IDR_OS_SETTINGS_PLUGIN_VM_REMOVE_CONFIRMATION_DIALOG_HTML" - file="chromeos/plugin_vm_page/plugin_vm_remove_confirmation_dialog.html" - compress="false" type="chrome_html" /> <structure name="IDR_OS_SETTINGS_USERS_PAGE_ADD_USER_DIALOG_JS" file="chromeos/os_people_page/users_add_user_dialog.js" compress="false" type="chrome_html" />
diff --git a/chrome/browser/resources/settings/settings.js b/chrome/browser/resources/settings/settings.js index 9afbf49c..bf8087a0 100644 --- a/chrome/browser/resources/settings/settings.js +++ b/chrome/browser/resources/settings/settings.js
@@ -24,11 +24,11 @@ // </if> export {ProfileInfoBrowserProxyImpl} from './people_page/profile_info_browser_proxy.m.js'; export {MAX_SIGNIN_PROMO_IMPRESSION} from './people_page/sync_account_control.m.js'; -export {PageStatus, StatusAction, SyncBrowserProxyImpl} from './people_page/sync_browser_proxy.m.js'; +export {PageStatus, StatusAction, SyncBrowserProxy, SyncBrowserProxyImpl, SyncStatus} from './people_page/sync_browser_proxy.m.js'; export {PluralStringProxyImpl} from './plural_string_proxy.js'; export {prefToString, stringToPrefValue} from './prefs/pref_util.m.js'; export {CrSettingsPrefs} from './prefs/prefs_types.m.js'; -export {PrivacyPageBrowserProxyImpl, SecureDnsMode, SecureDnsUiManagementMode} from './privacy_page/privacy_page_browser_proxy.m.js'; +export {MetricsReporting, PrivacyPageBrowserProxy, PrivacyPageBrowserProxyImpl, ResolverOption, SecureDnsMode, SecureDnsSetting, SecureDnsUiManagementMode} from './privacy_page/privacy_page_browser_proxy.m.js'; export {ResetBrowserProxyImpl} from './reset_page/reset_browser_proxy.js'; export {buildRouter, routes} from './route.js'; export {Route, Router} from './router.m.js';
diff --git a/chrome/browser/resources/settings/site_settings_page/recent_site_permissions.js b/chrome/browser/resources/settings/site_settings_page/recent_site_permissions.js index 72ecc1e0..f31537a 100644 --- a/chrome/browser/resources/settings/site_settings_page/recent_site_permissions.js +++ b/chrome/browser/resources/settings/site_settings_page/recent_site_permissions.js
@@ -16,7 +16,7 @@ import {routes} from '../route.js'; import {Route, RouteObserverBehavior, Router} from '../router.m.js'; -import {AllSitesAction, ContentSetting, SiteSettingSource} from '../site_settings/constants.js'; +import {AllSitesAction, ContentSetting, ContentSettingsTypes, SiteSettingSource} from '../site_settings/constants.js'; import {SiteSettingsBehavior} from '../site_settings/site_settings_behavior.js'; import {RawSiteException, RecentSitePermissions} from '../site_settings/site_settings_prefs_browser_proxy.js'; @@ -113,65 +113,65 @@ */ getI18nContentTypeString_(contentSettingsType) { switch (contentSettingsType) { - case 'cookies': + case ContentSettingsTypes.COOKIES: return this.i18n('siteSettingsCookies'); - case 'images': + case ContentSettingsTypes.IMAGES: return this.i18n('siteSettingsImages'); - case 'javascript': + case ContentSettingsTypes.JAVASCRIPT: return this.i18n('siteSettingsJavascript'); - case 'sound': + case ContentSettingsTypes.SOUND: return this.i18n('siteSettingsSound'); - case 'popups': + case ContentSettingsTypes.POPUPS: return this.i18n('siteSettingsPopups'); - case 'location': + case ContentSettingsTypes.GEOLOCATION: return this.i18n('siteSettingsLocation'); - case 'notifications': + case ContentSettingsTypes.NOTIFICATIONS: return this.i18n('siteSettingsNotifications'); - case 'media-stream-mic': + case ContentSettingsTypes.MIC: return this.i18n('siteSettingsMic'); - case 'media-stream-camera': + case ContentSettingsTypes.CAMERA: return this.i18n('siteSettingsCamera'); - case 'register-protocol-handler': + case ContentSettingsTypes.PROTOCOL_HANDLERS: return this.i18n('siteSettingsHandlers'); - case 'ppapi-broker': + case ContentSettingsTypes.UNSANDBOXED_PLUGINS: return this.i18n('siteSettingsUnsandboxedPlugins'); - case 'multiple-automatic-downloads': + case ContentSettingsTypes.AUTOMATIC_DOWNLOADS: return this.i18n('siteSettingsAutomaticDownloads'); - case 'background-sync': + case ContentSettingsTypes.BACKGROUND_SYNC: return this.i18n('siteSettingsBackgroundSync'); - case 'midi-sysex': + case ContentSettingsTypes.MIDI_DEVICES: return this.i18n('siteSettingsMidiDevices'); - case 'usb-devices': + case ContentSettingsTypes.USB_DEVICES: return this.i18n('siteSettingsUsbDevices'); - case 'serial-ports': + case ContentSettingsTypes.SERIAL_PORTS: return this.i18n('siteSettingsSerialPorts'); - case 'bluetooth-devices': + case ContentSettingsTypes.BLUETOOTH_DEVICES: return this.i18n('siteSettingsBluetoothDevices'); - case 'zoom-levels': + case ContentSettingsTypes.ZOOM_LEVELS: return this.i18n('siteSettingsZoomLevels'); - case 'protected-content': + case ContentSettingsTypes.PROTECTED_CONTENT: return this.i18n('siteSettingsProtectedContent'); - case 'ads': + case ContentSettingsTypes.ADS: return this.i18n('siteSettingsAds'); - case 'clipboard': + case ContentSettingsTypes.CLIPBOARD: return this.i18n('siteSettingsClipboard'); - case 'sensors': + case ContentSettingsTypes.SENSORS: return this.i18n('siteSettingsSensors'); - case 'payment-handler': + case ContentSettingsTypes.PAYMENT_HANDLER: return this.i18n('siteSettingsPaymentHandler'); - case 'mixed-script': + case ContentSettingsTypes.MIXEDSCRIPT: return this.i18n('siteSettingsInsecureContent'); - case 'bluetooth-scanning': + case ContentSettingsTypes.BLUETOOTH_SCANNING: return this.i18n('siteSettingsBluetoothScanning'); - case 'native-file-system-write': + case ContentSettingsTypes.NATIVE_FILE_SYSTEM_WRITE: return this.i18n('siteSettingsNativeFileSystemWrite'); - case 'hid-devices': + case ContentSettingsTypes.HID_DEVICES: return this.i18n('siteSettingsHidDevices'); - case 'ar': + case ContentSettingsTypes.AR: return this.i18n('siteSettingsAr'); - case 'vr': + case ContentSettingsTypes.VR: return this.i18n('siteSettingsVr'); - case 'window-placement': + case ContentSettingsTypes.WINDOW_PLACEMENT: return this.i18n('siteSettingsWindowPlacement'); default: return '';
diff --git a/chrome/browser/safe_browsing/download_protection/check_client_download_request.cc b/chrome/browser/safe_browsing/download_protection/check_client_download_request.cc index b828c817..d4418d3 100644 --- a/chrome/browser/safe_browsing/download_protection/check_client_download_request.cc +++ b/chrome/browser/safe_browsing/download_protection/check_client_download_request.cc
@@ -79,7 +79,12 @@ NOTREACHED(); return; } + } else if (reason == REASON_WHITELISTED_URL) { + callback.Run(deep_scan_result); + return; } + + NOTREACHED(); } } // namespace @@ -305,4 +310,11 @@ #endif } +bool CheckClientDownloadRequest::IsWhitelistedByPolicy() const { + Profile* profile = Profile::FromBrowserContext(GetBrowserContext()); + if (!profile) + return false; + return MatchesEnterpriseWhitelist(*profile->GetPrefs(), item_->GetUrlChain()); +} + } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/download_protection/check_client_download_request.h b/chrome/browser/safe_browsing/download_protection/check_client_download_request.h index a05c01e..720b471 100644 --- a/chrome/browser/safe_browsing/download_protection/check_client_download_request.h +++ b/chrome/browser/safe_browsing/download_protection/check_client_download_request.h
@@ -76,6 +76,8 @@ bool ShouldPromptForDeepScanning( DownloadCheckResultReason reason) const override; + bool IsWhitelistedByPolicy() const override; + // The DownloadItem we are checking. Will be NULL if the request has been // canceled. Must be accessed only on UI thread. download::DownloadItem* item_;
diff --git a/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.cc b/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.cc index 441aad3..5e689b8 100644 --- a/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.cc +++ b/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.cc
@@ -183,6 +183,12 @@ DVLOG(2) << "Starting SafeBrowsing download check for: " << source_url_; DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (IsWhitelistedByPolicy()) { + FinishRequest(DownloadCheckResult::WHITELISTED_BY_POLICY, + REASON_WHITELISTED_URL); + return; + } + // If whitelist check passes, FinishRequest() will be called to avoid // analyzing file. Otherwise, AnalyzeFile() will be called to continue with // analysis.
diff --git a/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.h b/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.h index 32a9c0fa..96226a3 100644 --- a/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.h +++ b/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.h
@@ -152,6 +152,10 @@ void OnGotAccessToken( base::Optional<signin::AccessTokenInfo> access_token_info); + // Called at the request start to determine if we should bailout due to the + // file being whitelisted by policy + virtual bool IsWhitelistedByPolicy() const = 0; + // Source URL being downloaded from. This shuold always be set, but could be // for example an artificial blob: URL if there is no source URL. const GURL source_url_;
diff --git a/chrome/browser/safe_browsing/download_protection/check_native_file_system_write_request.cc b/chrome/browser/safe_browsing/download_protection/check_native_file_system_write_request.cc index 3590e22..21bbbfe 100644 --- a/chrome/browser/safe_browsing/download_protection/check_native_file_system_write_request.cc +++ b/chrome/browser/safe_browsing/download_protection/check_native_file_system_write_request.cc
@@ -171,4 +171,11 @@ weakptr_factory_.InvalidateWeakPtrs(); } +bool CheckNativeFileSystemWriteRequest::IsWhitelistedByPolicy() const { + Profile* profile = Profile::FromBrowserContext(item_->browser_context); + if (!profile) + return false; + return IsURLWhitelistedByPolicy(item_->frame_url, *profile->GetPrefs()); +} + } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/download_protection/check_native_file_system_write_request.h b/chrome/browser/safe_browsing/download_protection/check_native_file_system_write_request.h index 967c363..bfa7df8 100644 --- a/chrome/browser/safe_browsing/download_protection/check_native_file_system_write_request.h +++ b/chrome/browser/safe_browsing/download_protection/check_native_file_system_write_request.h
@@ -55,6 +55,7 @@ DownloadCheckResultReason reason) const override; void NotifyRequestFinished(DownloadCheckResult result, DownloadCheckResultReason reason) override; + bool IsWhitelistedByPolicy() const override; const std::unique_ptr<content::NativeFileSystemWriteItem> item_; std::unique_ptr<ReferrerChainData> referrer_chain_data_;
diff --git a/chrome/browser/safe_browsing/download_protection/deep_scanning_browsertest.cc b/chrome/browser/safe_browsing/download_protection/deep_scanning_browsertest.cc index ee6248a..2b0aa13 100644 --- a/chrome/browser/safe_browsing/download_protection/deep_scanning_browsertest.cc +++ b/chrome/browser/safe_browsing/download_protection/deep_scanning_browsertest.cc
@@ -7,6 +7,7 @@ #include "base/base64.h" #include "base/path_service.h" #include "base/test/scoped_feature_list.h" +#include "base/values.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/safe_browsing/cloud_content_scanning/binary_fcm_service.h" @@ -443,4 +444,55 @@ EXPECT_EQ(item->GetState(), download::DownloadItem::INTERRUPTED); } +class WhitelistedUrlDeepScanningBrowserTest + : public DownloadDeepScanningBrowserTest { + public: + WhitelistedUrlDeepScanningBrowserTest() = default; + ~WhitelistedUrlDeepScanningBrowserTest() override = default; + + void SetUpOnMainThread() override { + DownloadDeepScanningBrowserTest::SetUpOnMainThread(); + + base::ListValue domain_list; + domain_list.AppendString(embedded_test_server()->base_url().host_piece()); + browser()->profile()->GetPrefs()->Set(prefs::kSafeBrowsingWhitelistDomains, + domain_list); + } +}; + +IN_PROC_BROWSER_TEST_F(WhitelistedUrlDeepScanningBrowserTest, + WhitelistedUrlStillDoesDlp) { + // The file is SAFE according to the metadata check + ClientDownloadResponse metadata_response; + metadata_response.set_verdict(ClientDownloadResponse::SAFE); + ExpectMetadataResponse(metadata_response); + + // The DLP scan runs synchronously, and finds a violation. + DeepScanningClientResponse sync_response; + sync_response.mutable_dlp_scan_verdict()->set_status( + DlpDeepScanningVerdict::SUCCESS); + sync_response.mutable_dlp_scan_verdict()->add_triggered_rules()->set_action( + DlpDeepScanningVerdict::TriggeredRule::BLOCK); + ExpectDeepScanSynchronousResponse(/*is_advanced_protection=*/false, + sync_response); + + GURL url = embedded_test_server()->GetURL( + "/safe_browsing/download_protection/zipfile_two_archives.zip"); + ui_test_utils::NavigateToURLWithDisposition( + browser(), url, WindowOpenDisposition::CURRENT_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP); + + WaitForDeepScanRequest(/*is_advanced_protection=*/false); + + WaitForDownloadToFinish(); + + // The file should be blocked for sensitive content. + ASSERT_EQ(download_items().size(), 1u); + download::DownloadItem* item = *download_items().begin(); + EXPECT_EQ(item->GetDangerType(), + download::DownloadDangerType:: + DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_BLOCK); + EXPECT_EQ(item->GetState(), download::DownloadItem::INTERRUPTED); +} + } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/download_protection/download_protection_service.cc b/chrome/browser/safe_browsing/download_protection/download_protection_service.cc index 1fef8b8..c2b44f1 100644 --- a/chrome/browser/safe_browsing/download_protection/download_protection_service.cc +++ b/chrome/browser/safe_browsing/download_protection/download_protection_service.cc
@@ -75,19 +75,6 @@ event_url_entry->add_server_redirect_chain()->set_url(url.spec()); } -bool MatchesEnterpriseWhitelist(const Profile* profile, - const std::vector<GURL>& url_chain) { - if (!profile) - return false; - - const PrefService* prefs = profile->GetPrefs(); - for (const GURL& url : url_chain) { - if (IsURLWhitelistedByPolicy(url, *prefs)) - return true; - } - return false; -} - int GetDownloadAttributionUserGestureLimit(const download::DownloadItem& item) { content::WebContents* web_contents = content::DownloadItemUtils::GetWebContents( @@ -179,11 +166,6 @@ void DownloadProtectionService::CheckClientDownload( download::DownloadItem* item, CheckDownloadRepeatingCallback callback) { - if (item->GetDangerType() == - download::DOWNLOAD_DANGER_TYPE_WHITELISTED_BY_POLICY) { - std::move(callback).Run(DownloadCheckResult::WHITELISTED_BY_POLICY); - return; - } auto request = std::make_unique<CheckClientDownloadRequest>( item, std::move(callback), this, database_manager_, binary_feature_extractor_); @@ -225,12 +207,16 @@ content::DownloadItemUtils::GetWebContents(item); // |web_contents| can be null in tests. // Checks if this download is whitelisted by enterprise policy. - if (web_contents && - MatchesEnterpriseWhitelist( - Profile::FromBrowserContext(web_contents->GetBrowserContext()), - item->GetUrlChain())) { - std::move(callback).Run(DownloadCheckResult::WHITELISTED_BY_POLICY); - return; + if (web_contents) { + Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); + if (profile && + MatchesEnterpriseWhitelist(*profile->GetPrefs(), item->GetUrlChain())) { + // We don't return WHITELISTED_BY_POLICY yet, because future deep scanning + // operations may indicate the file is unsafe. + std::move(callback).Run(DownloadCheckResult::SAFE); + return; + } } scoped_refptr<DownloadUrlSBClient> client(new DownloadUrlSBClient( @@ -276,7 +262,8 @@ CheckDownloadCallback callback) { DVLOG(1) << __func__ << " url:" << requestor_url << " default_file_path:" << default_file_path.value(); - if (MatchesEnterpriseWhitelist(profile, + if (profile && + MatchesEnterpriseWhitelist(*profile->GetPrefs(), {requestor_url, initiating_frame_url})) { std::move(callback).Run(DownloadCheckResult::WHITELISTED_BY_POLICY); return; @@ -295,13 +282,6 @@ void DownloadProtectionService::CheckNativeFileSystemWrite( std::unique_ptr<content::NativeFileSystemWriteItem> item, CheckDownloadCallback callback) { - if (MatchesEnterpriseWhitelist( - Profile::FromBrowserContext(item->browser_context), - {item->frame_url})) { - std::move(callback).Run(DownloadCheckResult::WHITELISTED_BY_POLICY); - return; - } - auto request = std::make_unique<CheckNativeFileSystemWriteRequest>( std::move(item), std::move(callback), this, database_manager_, binary_feature_extractor_);
diff --git a/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc b/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc index 7c96842..d8fb37e 100644 --- a/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc +++ b/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc
@@ -2339,7 +2339,7 @@ &item, base::BindOnce(&DownloadProtectionServiceTest::CheckDoneCallback, base::Unretained(this), run_loop.QuitClosure())); run_loop.Run(); - EXPECT_TRUE(IsResult(DownloadCheckResult::WHITELISTED_BY_POLICY)); + EXPECT_TRUE(IsResult(DownloadCheckResult::SAFE)); // Prepares download item that other url in the url chain matches enterprise // whitelist. @@ -2357,7 +2357,7 @@ &item2, base::BindOnce(&DownloadProtectionServiceTest::CheckDoneCallback, base::Unretained(this), run_loop2.QuitClosure())); run_loop2.Run(); - EXPECT_TRUE(IsResult(DownloadCheckResult::WHITELISTED_BY_POLICY)); + EXPECT_TRUE(IsResult(DownloadCheckResult::SAFE)); } TEST_F(DownloadProtectionServiceTest, TestDownloadRequestTimeout) { @@ -2781,15 +2781,12 @@ } TEST_F(DownloadProtectionServiceTest, CheckClientDownloadWhitelistedByPolicy) { + AddDomainToEnterpriseWhitelist("example.com"); NiceMockDownloadItem item; - PrepareBasicDownloadItem(&item, {"http://www.evil.com/a.exe"}, // url_chain - "http://www.google.com/", // referrer - FILE_PATH_LITERAL("a.tmp"), // tmp_path - FILE_PATH_LITERAL("a.exe")); // final_path - EXPECT_CALL(item, GetDangerType()) - .WillRepeatedly( - Return(download::DOWNLOAD_DANGER_TYPE_WHITELISTED_BY_POLICY)); - EXPECT_CALL(item, GetHash()).Times(0); + PrepareBasicDownloadItem(&item, {"http://example.com/a.exe"}, // url_chain + "http://www.google.com/", // referrer + FILE_PATH_LITERAL("a.tmp"), // tmp_path + FILE_PATH_LITERAL("a.exe")); // final_path EXPECT_CALL(*sb_service_->mock_database_manager(), MatchDownloadWhitelistUrl(_)) .Times(0); @@ -2800,6 +2797,7 @@ .Times(0); RunLoop run_loop; + content::DownloadItemUtils::AttachInfo(&item, profile(), nullptr); download_service_->CheckClientDownload( &item, base::BindRepeating(&DownloadProtectionServiceTest::CheckDoneCallback,
diff --git a/chrome/browser/send_tab_to_self/send_tab_to_self_util.cc b/chrome/browser/send_tab_to_self/send_tab_to_self_util.cc index feb17ec4..137073e 100644 --- a/chrome/browser/send_tab_to_self/send_tab_to_self_util.cc +++ b/chrome/browser/send_tab_to_self/send_tab_to_self_util.cc
@@ -42,9 +42,8 @@ bool AreContentRequirementsMet(const GURL& url, Profile* profile) { bool is_http_or_https = url.SchemeIsHTTPOrHTTPS(); - bool is_native_page = url.SchemeIs(content::kChromeUIScheme); bool is_incognito_mode = profile->IsIncognitoProfile(); - return is_http_or_https && !is_native_page && !is_incognito_mode; + return is_http_or_https && !is_incognito_mode; } bool ShouldOfferFeature(content::WebContents* web_contents) {
diff --git a/chrome/browser/send_tab_to_self/send_tab_to_self_util_unittest.cc b/chrome/browser/send_tab_to_self/send_tab_to_self_util_unittest.cc index 7a62bef..8a1c2fd6 100644 --- a/chrome/browser/send_tab_to_self/send_tab_to_self_util_unittest.cc +++ b/chrome/browser/send_tab_to_self/send_tab_to_self_util_unittest.cc
@@ -91,6 +91,11 @@ EXPECT_FALSE(AreContentRequirementsMet(url_, profile())); } +TEST_F(SendTabToSelfUtilTest, UntrustedPage) { + url_ = GURL("chrome-untrusted://url"); + EXPECT_FALSE(AreContentRequirementsMet(url_, profile())); +} + TEST_F(SendTabToSelfUtilTest, NativePage) { url_ = GURL("chrome://flags"); EXPECT_FALSE(AreContentRequirementsMet(url_, profile()));
diff --git a/chrome/browser/service_sandbox_type.h b/chrome/browser/service_sandbox_type.h index be75ddc..ac05340 100644 --- a/chrome/browser/service_sandbox_type.h +++ b/chrome/browser/service_sandbox_type.h
@@ -27,4 +27,16 @@ } #endif +// chrome::mojom::ProfileImport +namespace chrome { +namespace mojom { +class ProfileImport; +} +} // namespace chrome +template <> +inline content::SandboxType +content::GetServiceSandboxType<chrome::mojom::ProfileImport>() { + return content::SandboxType::kNoSandbox; +} + #endif // CHROME_BROWSER_SERVICE_SANDBOX_TYPE_H_
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/SaveImageNotificationManager.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/SaveImageNotificationManager.java index e1e3ee53..2673398d 100644 --- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/SaveImageNotificationManager.java +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/SaveImageNotificationManager.java
@@ -76,11 +76,12 @@ * * @param context The Context to use for accessing notification manager. * @param uri The Uri of the notification to show. - * @param notificationTitle The title of the notification. */ - public static void showSuccessNotification(Context context, Uri uri, String notificationTitle) { + public static void showSuccessNotification(Context context, Uri uri) { + String notificationTitle = + context.getResources().getString(R.string.qr_code_successful_download_title); String notificationText = - context.getResources().getString(R.string.download_notification_completed); + context.getResources().getString(R.string.qr_code_successful_download_text); int iconId = R.drawable.offline_pin; showNotification(context, uri, notificationTitle, notificationText, iconId, NotificationIntentInterceptor.IntentType.CONTENT_INTENT); @@ -91,11 +92,12 @@ * * @param context The Context to use for accessing notification manager. * @param uri The Uri of the notification to hide. - * @param notificationTitle The title of the notification. */ - public static void showFailureNotification(Context context, Uri uri, String notificationTitle) { + public static void showFailureNotification(Context context, Uri uri) { + String notificationTitle = + context.getResources().getString(R.string.qr_code_failed_download_title); String notificationText = - context.getResources().getString(R.string.download_notification_failed); + context.getResources().getString(R.string.qr_code_failed_download_text); int iconId = android.R.drawable.stat_sys_download_done; showNotification(context, uri, notificationTitle, notificationText, iconId, NotificationIntentInterceptor.IntentType.DELETE_INTENT);
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/qrcode/share_tab/QrCodeShareMediator.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/qrcode/share_tab/QrCodeShareMediator.java index 825ce6c..456303a 100644 --- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/qrcode/share_tab/QrCodeShareMediator.java +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/qrcode/share_tab/QrCodeShareMediator.java
@@ -76,10 +76,10 @@ // Notify success. Toast.makeText(mContext, - mContext.getResources().getString(R.string.download_notification_completed), + mContext.getResources().getString(R.string.qr_code_successful_download_title), Toast.LENGTH_LONG) .show(); - SaveImageNotificationManager.showSuccessNotification(mContext, uri, displayName); + SaveImageNotificationManager.showSuccessNotification(mContext, uri); } @Override @@ -92,9 +92,9 @@ // Notify failure. Toast.makeText(mContext, - mContext.getResources().getString(R.string.download_notification_failed), + mContext.getResources().getString(R.string.qr_code_failed_download_title), Toast.LENGTH_LONG) .show(); - SaveImageNotificationManager.showFailureNotification(mContext, null, displayName); + SaveImageNotificationManager.showFailureNotification(mContext, null); } }
diff --git a/chrome/browser/sync/test/integration/two_client_app_list_sync_test.cc b/chrome/browser/sync/test/integration/two_client_app_list_sync_test.cc index 2afaabe9..38af05d0 100644 --- a/chrome/browser/sync/test/integration/two_client_app_list_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_app_list_sync_test.cc
@@ -5,8 +5,9 @@ #include <stddef.h> #include "base/macros.h" +#include "base/one_shot_event.h" +#include "base/run_loop.h" #include "build/build_config.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sync/test/integration/apps_helper.h" @@ -23,9 +24,7 @@ #include "components/sync/base/pref_names.h" #include "components/sync/base/user_selectable_type.h" #include "components/sync/driver/sync_user_settings.h" -#include "content/public/browser/notification_service.h" #include "content/public/test/browser_test.h" -#include "content/public/test/test_utils.h" #include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_system.h" @@ -105,10 +104,10 @@ extensions::ExtensionSystem::Get(profile)->extension_service(); if (extension_service && extension_service->is_ready()) return; - content::WindowedNotificationObserver extensions_loaded_observer( - extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED, - content::NotificationService::AllSources()); - extensions_loaded_observer.Wait(); + base::RunLoop run_loop; + extensions::ExtensionSystem::Get(profile)->ready().Post( + FROM_HERE, run_loop.QuitClosure()); + run_loop.Run(); } DISALLOW_COPY_AND_ASSIGN(TwoClientAppListSyncTest);
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 0d088cf6..acd5a34 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -2086,8 +2086,6 @@ "webui/settings/chromeos/personalization_section.h", "webui/settings/chromeos/plugin_vm_handler.cc", "webui/settings/chromeos/plugin_vm_handler.h", - "webui/settings/chromeos/plugin_vm_section.cc", - "webui/settings/chromeos/plugin_vm_section.h", "webui/settings/chromeos/pref_names.cc", "webui/settings/chromeos/pref_names.h", "webui/settings/chromeos/printing_section.cc",
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd index 6d490f5..6c5af63 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -1811,30 +1811,6 @@ </message> <!-- Page info popup --> - <message name="IDS_PAGE_INFO_DSE_PERMISSION_ALLOWED" desc="The label used in the Page Info dialog to describe an allowed location permission for the current search engine. Eg: Location - Allowed for current search engine"> - Allowed for current search engine - </message> - <message name="IDS_PAGE_INFO_DSE_PERMISSION_BLOCKED" desc="The label used in the Page Info dialog to describe a blocked location permission for the current search engine. Eg: Location - Blocked for current search engine"> - Blocked for current search engine - </message> - <message name="IDS_PAGE_INFO_PERMISSION_ALLOWED" desc="The label used in the Page Info dialog to describe an allowed permission. Eg: Location - Allowed"> - Allowed - </message> - <message name="IDS_PAGE_INFO_PERMISSION_BLOCKED" desc="The label used in the Page Info dialog to describe a blocked permission. Eg: Location - Blocked"> - Blocked - </message> - <message name="IDS_PAGE_INFO_ANDROID_PERMISSION_BLOCKED" desc="The label used in the Page Info dialog to indicate a permission has been blocked within Android settings"> - Turned off in Android settings - </message> - <message name="IDS_PAGE_INFO_ANDROID_AR_CAMERA_BLOCKED" desc="The label used in the Page Info dialog for the AR permission to indicate that Camera has been disabled for the device in Android settings"> - Camera is turned off in Android settings - </message> - <message name="IDS_PAGE_INFO_ANDROID_LOCATION_BLOCKED" desc="The label used in the Page Info dialog to indicate that location has been been disabled for the device in Android settings"> - Turned off for this device - </message> - <message name="IDS_PAGE_INFO_ANDROID_NFC_UNSUPPORTED" desc="The label used in the Page Info dialog to indicate NFC is not supported by this device"> - This device can't read NFC - </message> <message name="IDS_PAGE_INFO_CONNECTION_OFFLINE" desc="Message to display in the page info bubble when viewing and offline page."> You are viewing an offline copy of this page from <ph name="CREATION_TIME">%1$s<ex>Feb 9, 2016</ex></ph> </message> @@ -2320,9 +2296,15 @@ <message name="IDS_NTP_DISCOVER_ON" desc="Title in the feed header when the feed is turned on. Please use the branded term for Discover, as listed under Product Names in the Google Glossary Manager."> Discover </message> + <message name="IDS_NTP_DISCOVER_ON_BRANDED" desc="Title in the feed header when the feed is turned on and the default search engine is not Google. Please use the branded term for Discover, as listed under Product Names in the Google Glossary Manager."> + Discover by Google + </message> <message name="IDS_NTP_DISCOVER_OFF" desc="Title in the feed header when the feed is turned off. Please use the branded term for Discover, as listed under Product Names in the Google Glossary Manager."> Discover - off </message> + <message name="IDS_NTP_DISCOVER_OFF_BRANDED" desc="Title in the feed header when the feed is turned off and the default search engine is not Google. Please use the branded term for Discover, as listed under Product Names in the Google Glossary Manager."> + Discover by Google - off + </message> <message name="IDS_NTP_FEED_MENU_IPH" desc="In-product help that points at the menu icon for the news feed on Chrome's new tab page. This string instructs the user to open the menu for settings that let them control the content that appears on the feed."> Control your stories here </message> @@ -3647,6 +3629,21 @@ chrome_qrcode_<ph name="CURRENT_TIMESTAMP_MS">%1$s<ex>1582667748515</ex></ph> </message> + <message name="IDS_QR_CODE_SUCCESSFUL_DOWNLOAD_TITLE" desc="Notification title for successful QR code download."> + QR code downloaded + </message> + + <message name="IDS_QR_CODE_SUCCESSFUL_DOWNLOAD_TEXT" desc="Notification text for successful QR code download."> + Tap to open QR code + </message> + + <message name="IDS_QR_CODE_FAILED_DOWNLOAD_TITLE" desc="Notification title for failed QR code download."> + Can't download QR code + </message> + + <message name="IDS_QR_CODE_FAILED_DOWNLOAD_TEXT" desc="Notification text for failed QR code download."> + Something went wrong + </message> <!-- Chime DFM module strings --> <message name="IDS_CHIME_MODULE_TITLE" desc="Text shown when the chime module is referenced in install start, success, failure UI (e.g. in IDS_MODULE_INSTALL_START_TEXT, which will expand to 'Installing Google Notifications Platform for Chrome…')."> Google Notifications Platform
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_NTP_DISCOVER_OFF_BRANDED.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_NTP_DISCOVER_OFF_BRANDED.png.sha1 new file mode 100644 index 0000000..e90e7a0 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_NTP_DISCOVER_OFF_BRANDED.png.sha1
@@ -0,0 +1 @@ +6d53a2dc9c3ba2634d8156b88f073787e1cc7aba \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_NTP_DISCOVER_ON_BRANDED.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_NTP_DISCOVER_ON_BRANDED.png.sha1 new file mode 100644 index 0000000..518f5d4 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_NTP_DISCOVER_ON_BRANDED.png.sha1
@@ -0,0 +1 @@ +4a7689dcd1ae24f51641a887c6c024e5571077e2 \ No newline at end of file
diff --git a/chrome/browser/ui/ash/chrome_new_window_client.cc b/chrome/browser/ui/ash/chrome_new_window_client.cc index 946ac3a..9733e3a 100644 --- a/chrome/browser/ui/ash/chrome_new_window_client.cc +++ b/chrome/browser/ui/ash/chrome_new_window_client.cc
@@ -146,8 +146,6 @@ chromeos::settings::mojom::kMultiDeviceSectionPath}, {ChromePage::NETWORKSTYPEVPN, chromeos::settings::mojom::kVpnDetailsSubpagePath}, - {ChromePage::PLUGINVMDETAILS, - chromeos::settings::mojom::kPluginVmDetailsSubpagePath}, {ChromePage::PLUGINVMSHAREDPATHS, chromeos::settings::mojom::kPluginVmSharedPathsSubpagePath}, {ChromePage::OSACCESSIBILITY, @@ -195,10 +193,14 @@ {ChromePage::ABOUTDOWNLOADS, "about:downloads"}, {ChromePage::ABOUTHISTORY, "about:history"}}; +constexpr arc::mojom::ChromePage kDeprecatedPages[] = { + ChromePage::DEPRECATED_PLUGINVMDETAILS}; + // mojom::ChromePage::LAST returns the amount of valid entries - 1. static_assert(base::size(kOSSettingsMapping) + base::size(kBrowserSettingsMapping) + - base::size(kAboutPagesMapping) == + base::size(kAboutPagesMapping) + + base::size(kDeprecatedPages) == static_cast<size_t>(arc::mojom::ChromePage::LAST) + 1, "ChromePage mapping is out of sync");
diff --git a/chrome/browser/ui/ash/chrome_new_window_client_browsertest.cc b/chrome/browser/ui/ash/chrome_new_window_client_browsertest.cc index 8e15df8..b500167d 100644 --- a/chrome/browser/ui/ash/chrome_new_window_client_browsertest.cc +++ b/chrome/browser/ui/ash/chrome_new_window_client_browsertest.cc
@@ -389,9 +389,6 @@ ChromePage::MANAGEACCESSIBILITYTTS, base_url.Resolve(chromeos::settings::mojom::kTextToSpeechSubpagePath)); TestOpenChromePage( - ChromePage::PLUGINVMDETAILS, - base_url.Resolve(chromeos::settings::mojom::kPluginVmDetailsSubpagePath)); - TestOpenChromePage( ChromePage::PLUGINVMSHAREDPATHS, base_url.Resolve( chromeos::settings::mojom::kPluginVmSharedPathsSubpagePath));
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.cc b/chrome/browser/ui/ash/chrome_shell_delegate.cc index d4a0061d..e4e5f264 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate.cc +++ b/chrome/browser/ui/ash/chrome_shell_delegate.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/ui/ash/chrome_shell_delegate.h" #include <memory> +#include <utility> #include "ash/public/cpp/ash_features.h" #include "ash/screenshot_delegate.h" @@ -73,10 +74,15 @@ return contents->GetController().CanGoBack(); } +bool ChromeShellDelegate::IsTabDrag(const ui::OSExchangeData& drop_data) { + DCHECK(ash::features::IsWebUITabStripTabDragIntegrationEnabled()); + return tab_strip_ui::IsDraggedTab(drop_data); +} + aura::Window* ChromeShellDelegate::CreateBrowserForTabDrop( aura::Window* source_window, const ui::OSExchangeData& drop_data) { - CHECK(ash::features::IsWebUITabStripTabDragIntegrationEnabled()); + DCHECK(ash::features::IsWebUITabStripTabDragIntegrationEnabled()); BrowserView* source_view = BrowserView::GetBrowserViewForNativeWindow( source_window->GetToplevelWindow());
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.h b/chrome/browser/ui/ash/chrome_shell_delegate.h index 10fdea4..ff3b095f 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate.h +++ b/chrome/browser/ui/ash/chrome_shell_delegate.h
@@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_UI_ASH_CHROME_SHELL_DELEGATE_H_ #define CHROME_BROWSER_UI_ASH_CHROME_SHELL_DELEGATE_H_ +#include <memory> + #include "ash/shell_delegate.h" #include "base/macros.h" @@ -22,6 +24,7 @@ ash::BackGestureContextualNudgeController* controller) override; void OpenKeyboardShortcutHelpPage() const override; bool CanGoBack(gfx::NativeWindow window) const override; + bool IsTabDrag(const ui::OSExchangeData& drop_data) override; aura::Window* CreateBrowserForTabDrop( aura::Window* source_window, const ui::OSExchangeData& drop_data) override;
diff --git a/chrome/browser/ui/ash/launcher/app_service/app_service_app_window_launcher_controller.cc b/chrome/browser/ui/ash/launcher/app_service/app_service_app_window_launcher_controller.cc index 1d1b3b3..706054d 100644 --- a/chrome/browser/ui/ash/launcher/app_service/app_service_app_window_launcher_controller.cc +++ b/chrome/browser/ui/ash/launcher/app_service/app_service_app_window_launcher_controller.cc
@@ -28,6 +28,9 @@ #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" #include "chrome/browser/ui/ash/multi_user/multi_user_util.h" #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_helper.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_list.h" +#include "chrome/browser/ui/browser_window.h" #include "chrome/services/app_service/public/cpp/instance.h" #include "chrome/services/app_service/public/mojom/types.mojom-shared.h" #include "chrome/services/app_service/public/mojom/types.mojom.h" @@ -70,6 +73,11 @@ std::make_unique<AppServiceAppWindowCrostiniTracker>(this); profile_list_.push_back(owner->profile()); + + for (auto* browser : *BrowserList::GetInstance()) { + if (browser && browser->window() && browser->window()->GetNativeWindow()) + observed_windows_.Add(browser->window()->GetNativeWindow()); + } } AppServiceAppWindowLauncherController:: @@ -126,11 +134,12 @@ void AppServiceAppWindowLauncherController::AdditionalUserAddedToSession( Profile* profile) { // Each users InstanceRegister needs to be observed. - apps::AppServiceProxy* proxy = - apps::AppServiceProxyFactory::GetForProfile(profile); - DCHECK(proxy); - proxy->InstanceRegistry().AddObserver(this); + proxy_ = apps::AppServiceProxyFactory::GetForProfile(profile); + DCHECK(proxy_); + proxy_->InstanceRegistry().AddObserver(this); profile_list_.push_back(profile); + + app_service_instance_helper_->AdditionalUserAddedToSession(profile); } void AppServiceAppWindowLauncherController::OnWindowInitialized( @@ -161,9 +170,7 @@ if (shelf_id.IsNull()) return; - DCHECK(proxy_); - if (proxy_->AppRegistryCache().GetAppType(shelf_id.app_id) != - apps::mojom::AppType::kBuiltIn) + if (GetAppType(shelf_id.app_id) != apps::mojom::AppType::kBuiltIn) return; app_service_instance_helper_->OnInstances(shelf_id.app_id, window, @@ -183,11 +190,11 @@ if (arc_tracker_) arc_tracker_->OnWindowVisibilityChanged(window); - ash::ShelfID shelf_id = GetShelfId(window, false /*search_profile_list*/); + ash::ShelfID shelf_id = GetShelfId(window); if (shelf_id.IsNull()) return; - if (app_service_instance_helper_->IsOpenedInBrowser(shelf_id.app_id, + if (app_service_instance_helper_->IsOpenedInBrowser(GetAppId(shelf_id.app_id), window) || shelf_id.app_id == extension_misc::kChromeAppId) { app_service_instance_helper_->OnWindowVisibilityChanged(shelf_id, window, @@ -202,8 +209,11 @@ app_service_instance_helper_->OnInstances(GetAppId(shelf_id.app_id), window, shelf_id.launch_id, state); - if (!visible || shelf_id.app_id == extension_misc::kChromeAppId) + // Only register the visible non-browser |window| for the active user. + if (!visible || shelf_id.app_id == extension_misc::kChromeAppId || + !proxy_->InstanceRegistry().Exists(window)) { return; + } RegisterWindow(window, shelf_id); @@ -222,29 +232,28 @@ // window could be teleported from the inactive user, and isn't saved in the // proxy of the active user's profile, but it should still be removed from // the controller, and the shelf, so search all the proxies. - ash::ShelfID shelf_id = GetShelfId(window, true /*search_profile_list*/); - if (shelf_id.IsNull()) { + std::string app_id = GetShelfId(window).app_id; + if (app_id.empty()) { // For Crostini apps, it could be run from the command line, and not saved // in AppService, so GetShelfId could return null when the window is // destroyed, but it should still be deleted from instance and remove the // app window from the shelf. So if we can get the window from // InstanceRegistry, we should still destroy it from InstanceRegistry and // remove the app window from the shelf - shelf_id = proxy_->InstanceRegistry().GetShelfId(window); - if (shelf_id.IsNull()) + app_id = app_service_instance_helper_->GetAppId(window); + if (app_id.empty()) return; } - if (app_service_instance_helper_->IsOpenedInBrowser(shelf_id.app_id, + if (app_service_instance_helper_->IsOpenedInBrowser(GetAppId(app_id), window) || - shelf_id.app_id == extension_misc::kChromeAppId) { + app_id == extension_misc::kChromeAppId) { return; } // Delete the instance from InstanceRegistry. - app_service_instance_helper_->OnInstances(GetAppId(shelf_id.app_id), window, - std::string(), - apps::InstanceState::kDestroyed); + app_service_instance_helper_->OnInstances( + GetAppId(app_id), window, std::string(), apps::InstanceState::kDestroyed); auto app_window_it = aura_window_to_app_window_.find(window); if (app_window_it == aura_window_to_app_window_.end()) @@ -304,8 +313,7 @@ (update.State() & apps::InstanceState::kDestroyed) == apps::InstanceState::kUnknown) { std::string app_id = update.AppId(); - if (proxy_->AppRegistryCache().GetAppType(app_id) == - apps::mojom::AppType::kCrostini || + if (GetAppType(app_id) == apps::mojom::AppType::kCrostini || crostini::IsUnmatchedCrostiniShelfAppId(app_id)) { window->SetProperty(aura::client::kAppType, static_cast<int>(ash::AppType::CROSTINI_APP)); @@ -321,8 +329,8 @@ UserHasAppOnActiveDesktop(window, shelf_id, update.BrowserContext()); } // Apps opened in browser are managed by browser, so skip them. - if (app_service_instance_helper_->IsOpenedInBrowser(shelf_id.app_id, - window) || + if (app_service_instance_helper_->IsOpenedInBrowser( + GetAppId(shelf_id.app_id), window) || shelf_id.app_id == extension_misc::kChromeAppId) { return; } @@ -418,12 +426,11 @@ if (!window || !observed_windows_.IsObserving(window)) return; - const ash::ShelfID shelf_id = - GetShelfId(window, false /*search_profile_list*/); + const ash::ShelfID shelf_id = GetShelfId(window); if (shelf_id.IsNull()) return; - if (app_service_instance_helper_->IsOpenedInBrowser(shelf_id.app_id, + if (app_service_instance_helper_->IsOpenedInBrowser(GetAppId(shelf_id.app_id), window) || shelf_id.app_id == extension_misc::kChromeAppId) { app_service_instance_helper_->SetWindowActivated(shelf_id, window, active); @@ -541,8 +548,7 @@ } ash::ShelfID AppServiceAppWindowLauncherController::GetShelfId( - aura::Window* window, - bool search_profile_list) const { + aura::Window* window) const { if (crostini_tracker_) { std::string shelf_app_id; shelf_app_id = crostini_tracker_->GetShelfAppId(window); @@ -562,47 +568,32 @@ // If the window exists in InstanceRegistry, get the shelf id from // InstanceRegistry. - if (!search_profile_list) { - // Search from the proxy of the active user's profile, and verify whether - // the app exists in the proxy. - shelf_id = proxy_->InstanceRegistry().GetShelfId(window); - if (shelf_id.IsNull()) { - shelf_id = - ash::ShelfID::Deserialize(window->GetProperty(ash::kShelfIDKey)); - } - if (!shelf_id.IsNull()) { - if (proxy_->AppRegistryCache().GetAppType(shelf_id.app_id) == - apps::mojom::AppType::kUnknown && - shelf_id.app_id != extension_misc::kChromeAppId) { - return ash::ShelfID(); - } - return shelf_id; - } - } else { - for (auto* profile : profile_list_) { - auto* proxy = apps::AppServiceProxyFactory::GetForProfile(profile); - shelf_id = proxy->InstanceRegistry().GetShelfId(window); - if (!shelf_id.IsNull()) - break; - } - if (shelf_id.IsNull()) { - shelf_id = - ash::ShelfID::Deserialize(window->GetProperty(ash::kShelfIDKey)); - } - if (!shelf_id.IsNull()) { - for (auto* profile : profile_list_) { - auto* proxy = apps::AppServiceProxyFactory::GetForProfile(profile); - if (proxy->AppRegistryCache().GetAppType(shelf_id.app_id) != - apps::mojom::AppType::kUnknown || - shelf_id.app_id == extension_misc::kChromeAppId) { - return shelf_id; - } - } - return ash::ShelfID(); + for (auto* profile : profile_list_) { + auto* proxy = apps::AppServiceProxyFactory::GetForProfile(profile); + shelf_id = proxy->InstanceRegistry().GetShelfId(window); + if (!shelf_id.IsNull()) + break; + } + if (shelf_id.IsNull()) { + shelf_id = ash::ShelfID::Deserialize(window->GetProperty(ash::kShelfIDKey)); + } + if (!shelf_id.IsNull() && + GetAppType(shelf_id.app_id) != apps::mojom::AppType::kUnknown) { + return shelf_id; + } + return ash::ShelfID(); +} + +apps::mojom::AppType AppServiceAppWindowLauncherController::GetAppType( + const std::string& app_id) const { + for (auto* profile : profile_list_) { + auto* proxy = apps::AppServiceProxyFactory::GetForProfile(profile); + auto app_type = proxy->AppRegistryCache().GetAppType(app_id); + if (app_type != apps::mojom::AppType::kUnknown) { + return app_type; } } - - return shelf_id; + return apps::mojom::AppType::kUnknown; } void AppServiceAppWindowLauncherController::UserHasAppOnActiveDesktop(
diff --git a/chrome/browser/ui/ash/launcher/app_service/app_service_app_window_launcher_controller.h b/chrome/browser/ui/ash/launcher/app_service/app_service_app_window_launcher_controller.h index 0525d624..c7213574 100644 --- a/chrome/browser/ui/ash/launcher/app_service/app_service_app_window_launcher_controller.h +++ b/chrome/browser/ui/ash/launcher/app_service/app_service_app_window_launcher_controller.h
@@ -123,15 +123,13 @@ // AppWindowLauncherController: void OnItemDelegateDiscarded(ash::ShelfItemDelegate* delegate) override; - // Returns the shelf id for |window|. The window could be teleported from the - // inactive user to the active user. When |search_profile_list| is true, we - // should check the all proxies for all profiles, otherwise, only check the - // current active user profile's proxy. - // - // When |window|'s visibility or activate status is changed, - // |search_profile_list| is false to check the active user profile only. When - // |window| is destroyed, |search_profile_list| is true to check all proxies. - ash::ShelfID GetShelfId(aura::Window* window, bool search_profile_list) const; + // Returns the shelf id for |window|. |window| could be teleported from the + // inactive user to the active user, or during the user switch phase, |window| + // could belong to one of the profile. + ash::ShelfID GetShelfId(aura::Window* window) const; + + // Returns the app type for the given |app_id|. + apps::mojom::AppType GetAppType(const std::string& app_id) const; // Register |window| if the owner of the given |window| has a window // teleported of the |window|'s application type to the current desktop.
diff --git a/chrome/browser/ui/ash/launcher/app_service/app_service_instance_registry_helper.cc b/chrome/browser/ui/ash/launcher/app_service/app_service_instance_registry_helper.cc index 278bcda7..f4d4f13 100644 --- a/chrome/browser/ui/ash/launcher/app_service/app_service_instance_registry_helper.cc +++ b/chrome/browser/ui/ash/launcher/app_service/app_service_instance_registry_helper.cc
@@ -8,9 +8,11 @@ #include <string> #include <vector> +#include "base/stl_util.h" #include "base/time/time.h" #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" +#include "chrome/browser/chromeos/crostini/crostini_shelf_utils.h" #include "chrome/browser/chromeos/crostini/crostini_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" @@ -47,6 +49,11 @@ ProfileManager::GetActiveUserProfile()); } +void AppServiceInstanceRegistryHelper::AdditionalUserAddedToSession( + Profile* profile) { + proxy_ = apps::AppServiceProxyFactory::GetForProfile(profile); +} + void AppServiceInstanceRegistryHelper::OnActiveTabChanged( content::WebContents* old_contents, content::WebContents* new_contents) { @@ -61,14 +68,14 @@ // method is changed from windows to tabs, the app_id could be changed based // on the URL, e.g. google photos, which might cause instance app_id // inconsistent DCHECK error. - std::string app_id = proxy_->InstanceRegistry().GetShelfId(window).app_id; + std::string app_id = GetAppId(window); if (app_id.empty()) app_id = launcher_controller_helper_->GetAppID(old_contents); // If app_id is empty, we should not set it as inactive because this is // Chrome's tab. if (!app_id.empty()) { - apps::InstanceState state = proxy_->InstanceRegistry().GetState(window); + apps::InstanceState state = GetState(window); // If the app has been inactive, we don't need to update the instance. if ((state & apps::InstanceState::kActive) != apps::InstanceState::kUnknown) { @@ -87,7 +94,7 @@ // method is changed from windows to tabs, the app_id could be changed based // on the URL, e.g. google photos, which might cause instance app_id // inconsistent DCHECK error. - std::string app_id = proxy_->InstanceRegistry().GetShelfId(window).app_id; + std::string app_id = GetAppId(window); if (app_id.empty()) app_id = GetAppId(new_contents); @@ -121,12 +128,8 @@ // could generate a temp instance for this window with the Chrome application // app_id. For this case, this temp instance can be deleted, otherwise, DCHECK // error for inconsistent app_id. - std::string old_app_id = app_id; - proxy_->InstanceRegistry().ForOneInstance( - window, [&old_app_id](const apps::InstanceUpdate& update) { - old_app_id = update.AppId(); - }); - if (app_id != old_app_id) { + const std::string old_app_id = GetAppId(window); + if (!old_app_id.empty() && app_id != old_app_id) { OnInstances(old_app_id, window, std::string(), apps::InstanceState::kDestroyed); } @@ -146,17 +149,16 @@ // When the tab is closed, if the window does not exists in the AppService // InstanceRegistry, we don't need to update the status. - if (!proxy_->InstanceRegistry().Exists(window)) + const std::string app_id = GetAppId(window); + if (app_id.empty()) return; - std::string app_id = proxy_->InstanceRegistry().GetShelfId(window).app_id; RemoveTabWindow(app_id, window); OnInstances(app_id, window, std::string(), apps::InstanceState::kDestroyed); } void AppServiceInstanceRegistryHelper::OnBrowserRemoved() { - std::set<aura::Window*> windows = - proxy_->InstanceRegistry().GetWindows(extension_misc::kChromeAppId); + auto windows = GetWindows(extension_misc::kChromeAppId); for (auto* window : windows) { if (!chrome::FindBrowserWithWindow(window)) { // The browser is removed if the window can't be found, so update the @@ -187,7 +189,7 @@ // current active user, so search all proxies. If the instance is found from a // proxy, still save to that proxy, otherwise, save to the current active user // profile's proxy. - auto* proxy = proxy_; + apps::AppServiceProxy* proxy = proxy_; for (auto* profile : controller_->GetProfileList()) { auto* proxy_for_profile = apps::AppServiceProxyFactory::GetForProfile(profile); @@ -208,8 +210,7 @@ // window to compare with the parameter |window|, because we save the tab // window in AppService InstanceRegistry for Web apps, and we should set the // state for the tab window to keep one instance for the Web app. - std::set<aura::Window*> windows = - proxy_->InstanceRegistry().GetWindows(shelf_id.app_id); + auto windows = GetWindows(shelf_id.app_id); for (auto* it : windows) { if (it->GetToplevelWindow() != window) continue; @@ -226,10 +227,9 @@ // For Chrome browser app windows, sets the state for each tab window instance // in this browser. for (auto* it : browser_window_to_tab_window_[window]) { - if (!proxy_->InstanceRegistry().Exists(it)) + const std::string app_id = GetAppId(it); + if (app_id.empty()) continue; - - std::string app_id = proxy_->InstanceRegistry().GetShelfId(it).app_id; apps::InstanceState state = CalculateVisibilityState(it, visible); OnInstances(app_id, it, std::string(), state); } @@ -247,8 +247,7 @@ // window to compare with |window|, because we save the tab // window in AppService InstanceRegistry for Web apps, and we should set the // state for the tab window to keep one instance for the Web app. - std::set<aura::Window*> windows = - proxy_->InstanceRegistry().GetWindows(shelf_id.app_id); + auto windows = GetWindows(shelf_id.app_id); for (auto* it : windows) { if (it->GetToplevelWindow() != window) continue; @@ -278,8 +277,7 @@ // Get the app_id from the existed instance first. The app_id for PWAs could // be changed based on the URL, e.g. google photos, which might cause // instance app_id inconsistent DCHECK error. - std::string app_id = - proxy_->InstanceRegistry().GetShelfId(contents_window).app_id; + const std::string app_id = GetAppId(contents_window); OnInstances(app_id.empty() ? GetAppId(contents) : app_id, contents_window, std::string(), state); return; @@ -288,9 +286,9 @@ // For Chrome browser app windows, sets the state for each tab window instance // in this browser. for (auto* it : browser_window_to_tab_window_[window]) { - if (!proxy_->InstanceRegistry().Exists(it)) + const std::string app_id = GetAppId(it); + if (app_id.empty()) continue; - std::string app_id = proxy_->InstanceRegistry().GetShelfId(it).app_id; apps::InstanceState state = CalculateActivatedState(it, active); OnInstances(app_id, it, std::string(), state); } @@ -302,7 +300,7 @@ apps::InstanceState AppServiceInstanceRegistryHelper::CalculateVisibilityState( aura::Window* window, bool visible) const { - apps::InstanceState state = proxy_->InstanceRegistry().GetState(window); + apps::InstanceState state = GetState(window); state = static_cast<apps::InstanceState>( state | apps::InstanceState::kStarted | apps::InstanceState::kRunning); state = (visible) ? static_cast<apps::InstanceState>( @@ -322,7 +320,7 @@ apps::InstanceState::kActive | apps::InstanceState::kVisible); } - apps::InstanceState state = proxy_->InstanceRegistry().GetState(window); + apps::InstanceState state = GetState(window); state = static_cast<apps::InstanceState>( state | apps::InstanceState::kStarted | apps::InstanceState::kRunning); state = @@ -338,10 +336,20 @@ if (app_id == crostini::kCrostiniTerminalSystemAppId) return true; - apps::mojom::AppType app_type = proxy_->AppRegistryCache().GetAppType(app_id); - if (app_type != apps::mojom::AppType::kExtension && - app_type != apps::mojom::AppType::kWeb) { + if (crostini::IsUnmatchedCrostiniShelfAppId(app_id)) return false; + + for (auto* profile : controller_->GetProfileList()) { + auto* proxy = apps::AppServiceProxyFactory::GetForProfile(profile); + apps::mojom::AppType app_type = + proxy->AppRegistryCache().GetAppType(app_id); + if (app_type == apps::mojom::AppType::kUnknown) + continue; + + if (app_type != apps::mojom::AppType::kExtension && + app_type != apps::mojom::AppType::kWeb) { + return false; + } } // For Extension apps, and Web apps, AppServiceAppWindowLauncherController @@ -371,6 +379,17 @@ } std::string AppServiceInstanceRegistryHelper::GetAppId( + aura::Window* window) const { + for (auto* profile : controller_->GetProfileList()) { + auto* proxy = apps::AppServiceProxyFactory::GetForProfile(profile); + std::string app_id = proxy->InstanceRegistry().GetShelfId(window).app_id; + if (!app_id.empty()) + return app_id; + } + return std::string(); +} + +std::string AppServiceInstanceRegistryHelper::GetAppId( content::WebContents* contents) const { std::string app_id = launcher_controller_helper_->GetAppID(contents); if (!app_id.empty()) @@ -390,6 +409,28 @@ return window; } +std::set<aura::Window*> AppServiceInstanceRegistryHelper::GetWindows( + const std::string& app_id) { + std::set<aura::Window*> windows; + for (auto* profile : controller_->GetProfileList()) { + auto* proxy = apps::AppServiceProxyFactory::GetForProfile(profile); + auto w = proxy->InstanceRegistry().GetWindows(app_id); + windows = base::STLSetUnion<std::set<aura::Window*>>(windows, w); + } + return windows; +} + +apps::InstanceState AppServiceInstanceRegistryHelper::GetState( + aura::Window* window) const { + for (auto* profile : controller_->GetProfileList()) { + auto* proxy = apps::AppServiceProxyFactory::GetForProfile(profile); + auto state = proxy->InstanceRegistry().GetState(window); + if (state != apps::InstanceState::kUnknown) + return state; + } + return apps::InstanceState::kUnknown; +} + void AppServiceInstanceRegistryHelper::AddTabWindow(const std::string& app_id, aura::Window* window) { if (app_id == extension_misc::kChromeAppId)
diff --git a/chrome/browser/ui/ash/launcher/app_service/app_service_instance_registry_helper.h b/chrome/browser/ui/ash/launcher/app_service/app_service_instance_registry_helper.h index 64e63627..020faab 100644 --- a/chrome/browser/ui/ash/launcher/app_service/app_service_instance_registry_helper.h +++ b/chrome/browser/ui/ash/launcher/app_service/app_service_instance_registry_helper.h
@@ -5,7 +5,9 @@ #ifndef CHROME_BROWSER_UI_ASH_LAUNCHER_APP_SERVICE_APP_SERVICE_INSTANCE_REGISTRY_HELPER_H_ #define CHROME_BROWSER_UI_ASH_LAUNCHER_APP_SERVICE_APP_SERVICE_INSTANCE_REGISTRY_HELPER_H_ +#include <map> #include <memory> +#include <set> #include "chrome/browser/ui/ash/launcher/launcher_controller_helper.h" #include "chrome/services/app_service/public/cpp/instance.h" @@ -32,6 +34,7 @@ ~AppServiceInstanceRegistryHelper(); void ActiveUserChanged(); + void AdditionalUserAddedToSession(Profile* profile); // Notifies the AppService InstanceRegistry that active tabs are changed. void OnActiveTabChanged(content::WebContents* old_contents, @@ -82,6 +85,10 @@ // Return true if the app is opend in a browser. bool IsOpenedInBrowser(const std::string& app_id, aura::Window* window) const; + // Returns an app id for |window| in InstanceRegistry. If there is no |window| + // in InstanceRegistry, returns an empty string. + std::string GetAppId(aura::Window* window) const; + private: // Returns an app id to represent |contents| in InstanceRegistry. If there is // no app in |contents|, returns the app id of the Chrome component @@ -93,6 +100,13 @@ // |contents|, returns the toplevel window. aura::Window* GetWindow(content::WebContents* contents); + // Returns windows in InstanceRegistry for the given |app_id|. + std::set<aura::Window*> GetWindows(const std::string& app_id); + + // Returns the state in InstanceRegistry for the given |app_id|. If there is + // no |window| in InstanceRegistry, returns apps::InstanceState::kUnknown. + apps::InstanceState GetState(aura::Window* window) const; + // Adds the tab's |window| to |browser_window_to_tab_window_|. void AddTabWindow(const std::string& app_id, aura::Window* window); // Removes the tab's |window| from |browser_window_to_tab_window_|.
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc index 961eecf..4f54c40a 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc
@@ -2425,9 +2425,9 @@ chromeos::SpeechMonitor speech_monitor; // Enable ChromeVox. - ASSERT_FALSE( - chromeos::AccessibilityManager::Get()->IsSpokenFeedbackEnabled()); - chromeos::AccessibilityManager::Get()->EnableSpokenFeedback(true); + ASSERT_FALSE( + chromeos::AccessibilityManager::Get()->IsSpokenFeedbackEnabled()); + chromeos::AccessibilityManager::Get()->EnableSpokenFeedback(true); ash::RootWindowController* controller = ash::Shell::GetRootWindowControllerWithDisplayId( @@ -2436,6 +2436,11 @@ ui::test::EventGenerator event_generator(controller->GetRootWindow()); auto* generator_ptr = &event_generator; + // There is a mouse move event being dispatched at the beginning of test + // that confuses ChromeVox. This brings back ChromeVox state so that + // GestureTapAt at home button could successfully change ChromeVox focus. + event_generator.MoveMouseTo(home_button->GetBoundsInScreen().CenterPoint()); + // AccessibilityManager sends an empty warmup utterance first. speech_monitor.ExpectSpeech(""); @@ -2465,7 +2470,7 @@ ASSERT_EQ(ash::HotseatState::kExtended, controller->shelf()->shelf_layout_manager()->hotseat_state()); }); - + speech_monitor.Call([generator_ptr]() { // Press the search + right. Expects that the browser icon receives the // accessibility focus and the hotseat remains in kExtended state.
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc index fbcc5d9..ff471ed 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
@@ -886,6 +886,7 @@ const std::string app_id = ArcAppListPrefs::GetAppId(app_info.package_name, app_info.activity); EXPECT_TRUE(prefs->GetApp(app_id)); + app_service_test().FlushMojoCalls(); return app_id; } @@ -3304,12 +3305,8 @@ TEST_F(MultiProfileMultiBrowserShelfLayoutChromeLauncherControllerTest, V2AppHandlingTwoUsers) { InitLauncherController(); - // Create a profile for our second user (will be destroyed by the framework). - TestingProfile* profile2 = CreateMultiUserProfile("user2"); const AccountId account_id( multi_user_util::GetAccountIdFromProfile(profile())); - const AccountId account_id2( - multi_user_util::GetAccountIdFromProfile(profile2)); // Check that there is a browser. EXPECT_EQ(1, model_->item_count()); @@ -3318,6 +3315,11 @@ V2App v2_app(profile(), extension1_.get()); EXPECT_EQ(2, model_->item_count()); + // Create a profile for our second user (will be destroyed by the framework). + TestingProfile* profile2 = CreateMultiUserProfile("user2"); + const AccountId account_id2( + multi_user_util::GetAccountIdFromProfile(profile2)); + // After switching users the item should go away. SwitchActiveUser(account_id2); EXPECT_EQ(1, model_->item_count()); @@ -3523,10 +3525,15 @@ InitLauncherController(); TestingProfile* profile2 = CreateMultiUserProfile("user-2"); - const AccountId account_id( - multi_user_util::GetAccountIdFromProfile(profile())); const AccountId account_id2( multi_user_util::GetAccountIdFromProfile(profile2)); + // If switch to account_id2 is not run, the following switch to account_id + // is invalid, because the user account is not changed, so switch to + // account_id2 first. + SwitchActiveUser(account_id2); + + const AccountId account_id( + multi_user_util::GetAccountIdFromProfile(profile())); SwitchActiveUser(account_id); EXPECT_EQ(1, model_->item_count());
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc index 1f0f24d..9eb1eaf2 100644 --- a/chrome/browser/ui/browser_commands.cc +++ b/chrome/browser/ui/browser_commands.cc
@@ -789,14 +789,21 @@ } int indices_size = tab_indices.size(); + int active_index = browser->tab_strip_model()->active_index(); for (int i = 0; i < indices_size; i++) { // Adjust tab index to account for tabs already moved. int adjusted_index = tab_indices[i] - i; bool pinned = browser->tab_strip_model()->IsTabPinned(adjusted_index); std::unique_ptr<WebContents> contents_move = browser->tab_strip_model()->DetachWebContentsAt(adjusted_index); - int add_types = TabStripModel::ADD_ACTIVE | - (pinned ? TabStripModel::ADD_PINNED : 0); + + int add_types = pinned ? TabStripModel::ADD_PINNED : 0; + // The last tab made active takes precedence, so activate the last active + // tab, with a fallback for the first tab (i == 0) if the active tab isn’t + // in the set of tabs being moved. + if (i == 0 || tab_indices[i] == active_index) + add_types = add_types | TabStripModel::ADD_ACTIVE; + new_browser->tab_strip_model()->AddWebContents(std::move(contents_move), -1, ui::PAGE_TRANSITION_TYPED, add_types, new_group);
diff --git a/chrome/browser/ui/browser_instant_controller_unittest.cc b/chrome/browser/ui/browser_instant_controller_unittest.cc index 9716c930..8c9b174 100644 --- a/chrome/browser/ui/browser_instant_controller_unittest.cc +++ b/chrome/browser/ui/browser_instant_controller_unittest.cc
@@ -24,6 +24,7 @@ #include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" +#include "content/public/test/browser_test_utils.h" namespace chrome { @@ -55,15 +56,18 @@ explicit FakeWebContentsObserver(content::WebContents* contents) : WebContentsObserver(contents), contents_(contents), + did_start_observer_(contents), url_(contents->GetURL()), num_reloads_(0) {} - void DidStartNavigationToPendingEntry( - const GURL& url, - content::ReloadType reload_type) override { - if (url_ == url) + void DidStartNavigation(content::NavigationHandle* navigation) override { + fprintf(stderr, "### DidStartNavigation reload_type = %d, url = %s\n", + navigation->GetReloadType(), navigation->GetURL().spec().c_str()); + if (navigation->GetReloadType() == content::ReloadType::NONE) + return; + if (url_ == navigation->GetURL()) num_reloads_++; - current_url_ = url; + current_url_ = navigation->GetURL(); } const GURL& url() const { return url_; } @@ -74,6 +78,8 @@ bool can_go_back() const { return contents_->GetController().CanGoBack(); } + void WaitForNavigationStart() { did_start_observer_.Wait(); } + protected: friend class BrowserInstantControllerTest; FRIEND_TEST_ALL_PREFIXES(BrowserInstantControllerTest, @@ -82,6 +88,7 @@ private: content::WebContents* contents_; + content::DidStartNavigationObserver did_start_observer_; const GURL& url_; GURL current_url_; int num_reloads_; @@ -123,8 +130,17 @@ } // Ensure only the expected tabs(contents) reloaded. - base::RunLoop loop; - loop.RunUntilIdle(); + // RunUntilIdle() ensures that tasks posted by TabReloader::Reload run. + base::RunLoop().RunUntilIdle(); + if (observer->web_contents()->IsLoading()) { + // Ensure that we get DidStartNavigation, which can be dispatched + // asynchronously. + observer->WaitForNavigationStart(); + } + + // WaitForLoadStop ensures that all relevant navigation callbacks caused by + // TabReloader::Run complete. + // content::WaitForLoadStop(observer->web_contents()); EXPECT_EQ(test.should_reload ? 1 : 0, observer->num_reloads()) << test.description;
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc index c5e7e2f4..d2b7790 100644 --- a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc +++ b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc
@@ -658,7 +658,7 @@ public: void SetUpCommandLine(base::CommandLine* command_line) override { base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( - switches::kEnableBlinkFeatures, "ScreenEnumeration,WindowPlacement"); + switches::kEnableBlinkFeatures, "WindowPlacement"); FullscreenControllerInteractiveTest::SetUpCommandLine(command_line); } };
diff --git a/chrome/browser/ui/settings_window_manager_browsertest_chromeos.cc b/chrome/browser/ui/settings_window_manager_browsertest_chromeos.cc index 60e3ea6..eeef558 100644 --- a/chrome/browser/ui/settings_window_manager_browsertest_chromeos.cc +++ b/chrome/browser/ui/settings_window_manager_browsertest_chromeos.cc
@@ -21,6 +21,7 @@ #include "chrome/browser/web_applications/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/common/chrome_features.h" +#include "chrome/common/chrome_switches.h" #include "chrome/common/url_constants.h" #include "chrome/common/webui_url_constants.h" #include "chrome/test/base/in_process_browser_test.h" @@ -205,3 +206,17 @@ chrome::ShowSettingsSubPage(browser(), chrome::kAutofillSubPage); EXPECT_EQ(1u, chrome::GetTotalBrowserCount()); } + +IN_PROC_BROWSER_TEST_F(SettingsWindowManagerTest, KioskMode) { + base::CommandLine::ForCurrentProcess()->AppendSwitch(switches::kForceAppMode); + + // Open settings window. + settings_manager_->ShowOSSettings(browser()->profile()); + Browser* settings_browser = + settings_manager_->FindBrowserForProfile(browser()->profile()); + ASSERT_TRUE(settings_browser); + + // In kiosk mode, browser should be created, but it should not be a system web + // app. + EXPECT_EQ(settings_browser->app_controller(), nullptr); +}
diff --git a/chrome/browser/ui/settings_window_manager_chromeos.cc b/chrome/browser/ui/settings_window_manager_chromeos.cc index ce63910..813fac5 100644 --- a/chrome/browser/ui/settings_window_manager_chromeos.cc +++ b/chrome/browser/ui/settings_window_manager_chromeos.cc
@@ -7,6 +7,7 @@ #include "ash/public/cpp/app_types.h" #include "ash/public/cpp/multi_user_window_manager.h" #include "ash/public/cpp/resources/grit/ash_public_unscaled_resources.h" +#include "chrome/browser/app_mode/app_mode_utils.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_helper.h" #include "chrome/browser/ui/ash/window_properties.h" @@ -44,7 +45,8 @@ bool AreSystemWebAppsEnabled(Profile* profile) { return web_app::SystemWebAppManager::IsEnabled() && - web_app::AreWebAppsEnabled(profile); + web_app::AreWebAppsEnabled(profile) && + !chrome::IsRunningInForcedAppMode(); } } // namespace
diff --git a/chrome/browser/ui/toolbar/toolbar_actions_model.cc b/chrome/browser/ui/toolbar/toolbar_actions_model.cc index a7cd909..a970aeb 100644 --- a/chrome/browser/ui/toolbar/toolbar_actions_model.cc +++ b/chrome/browser/ui/toolbar/toolbar_actions_model.cc
@@ -516,17 +516,14 @@ // have changed even though they haven't. pinned_action_ids_ = GetFilteredPinnedActionIds(); - if (!profile_->IsOffTheRecord()) { - base::UmaHistogramCounts100("Extensions.Toolbar.PinnedExtensionCount", + if (!profile_->IsOffTheRecord() && !action_ids_.empty()) { + base::UmaHistogramCounts100("Extensions.Toolbar.PinnedExtensionCount2", pinned_action_ids_.size()); - int percentage = 0; - if (!action_ids_.empty()) { - double percentage_double = - pinned_action_ids_.size() / action_ids_.size() * 100.0; - percentage = int{percentage_double}; - } + double percentage_double = + pinned_action_ids_.size() / action_ids_.size() * 100.0; + int percentage = int{percentage_double}; base::UmaHistogramPercentage( - "Extensions.Toolbar.PinnedExtensionPercentage", percentage); + "Extensions.Toolbar.PinnedExtensionPercentage2", percentage); } } }
diff --git a/chrome/browser/ui/views/accessibility/caption_bubble.cc b/chrome/browser/ui/views/accessibility/caption_bubble.cc index 1a86644..59a44b8c 100644 --- a/chrome/browser/ui/views/accessibility/caption_bubble.cc +++ b/chrome/browser/ui/views/accessibility/caption_bubble.cc
@@ -10,8 +10,10 @@ #include <utility> #include <vector> +#include "base/metrics/histogram_macros.h" #include "base/strings/string16.h" #include "build/build_config.h" +#include "chrome/browser/accessibility/caption_controller.h" #include "chrome/grit/generated_resources.h" #include "components/vector_icons/vector_icons.h" #include "third_party/re2/src/re2/re2.h" @@ -426,6 +428,12 @@ void CaptionBubble::ButtonPressed(views::Button* sender, const ui::Event& event) { if (sender == close_button_) { + // TODO(crbug.com/1055150): This histogram currently only reports a single + // bucket, but it will eventually be extended to report session starts and + // natural session ends (when the audio stream ends). + UMA_HISTOGRAM_ENUMERATION( + "Accessibility.LiveCaptions.Session", + CaptionController::SessionEvent::kCloseButtonClicked); DCHECK(GetWidget()); GetWidget()->CloseWithReason( views::Widget::ClosedReason::kCloseButtonClicked);
diff --git a/chrome/browser/ui/views/apps/app_dialog/app_uninstall_dialog_view.cc b/chrome/browser/ui/views/apps/app_dialog/app_uninstall_dialog_view.cc index be7dc415..d4a47fd 100644 --- a/chrome/browser/ui/views/apps/app_dialog/app_uninstall_dialog_view.cc +++ b/chrome/browser/ui/views/apps/app_dialog/app_uninstall_dialog_view.cc
@@ -104,7 +104,6 @@ case apps::mojom::AppType::kUnknown: case apps::mojom::AppType::kBuiltIn: case apps::mojom::AppType::kMacNative: - case apps::mojom::AppType::kPluginVm: case apps::mojom::AppType::kLacros: NOTREACHED(); return base::string16(); @@ -120,6 +119,7 @@ return base::string16(); #endif case apps::mojom::AppType::kCrostini: + case apps::mojom::AppType::kPluginVm: #if defined(OS_CHROMEOS) FALLTHROUGH; #else @@ -149,7 +149,6 @@ case apps::mojom::AppType::kUnknown: case apps::mojom::AppType::kBuiltIn: case apps::mojom::AppType::kMacNative: - case apps::mojom::AppType::kPluginVm: case apps::mojom::AppType::kLacros: NOTREACHED(); break; @@ -160,9 +159,18 @@ NOTREACHED(); #endif break; + case apps::mojom::AppType::kPluginVm: +#if defined(OS_CHROMEOS) + InitializeViewWithMessage(l10n_util::GetStringFUTF16( + IDS_PLUGIN_VM_UNINSTALL_PROMPT_BODY, base::UTF8ToUTF16(app_name()))); +#else + NOTREACHED(); +#endif + break; case apps::mojom::AppType::kCrostini: #if defined(OS_CHROMEOS) - InitializeViewForCrostiniApp(profile, app_id); + InitializeViewWithMessage(l10n_util::GetStringUTF16( + IDS_CROSTINI_APPLICATION_UNINSTALL_CONFIRM_BODY)); #else NOTREACHED(); #endif @@ -310,21 +318,13 @@ ui::DIALOG_BUTTON_OK, l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_UNINSTALL_BUTTON)); } else { - base::string16 subheading_text = l10n_util::GetStringUTF16( - IDS_ARC_APP_UNINSTALL_PROMPT_DATA_REMOVAL_WARNING); - auto* label = AddChildView(std::make_unique<views::Label>(subheading_text)); - label->SetMultiLine(true); - label->SetHorizontalAlignment(gfx::ALIGN_LEFT); - label->SetAllowCharacterBreak(true); + InitializeViewWithMessage(l10n_util::GetStringUTF16( + IDS_ARC_APP_UNINSTALL_PROMPT_DATA_REMOVAL_WARNING)); } } -void AppUninstallDialogView::InitializeViewForCrostiniApp( - Profile* profile, - const std::string& app_id) { - base::string16 message = l10n_util::GetStringFUTF16( - IDS_CROSTINI_APPLICATION_UNINSTALL_CONFIRM_BODY, - base::UTF8ToUTF16(app_name())); +void AppUninstallDialogView::InitializeViewWithMessage( + const base::string16& message) { auto* label = AddChildView(std::make_unique<views::Label>(message)); label->SetMultiLine(true); label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
diff --git a/chrome/browser/ui/views/apps/app_dialog/app_uninstall_dialog_view.h b/chrome/browser/ui/views/apps/app_dialog/app_uninstall_dialog_view.h index 2a10f7e..862759dc 100644 --- a/chrome/browser/ui/views/apps/app_dialog/app_uninstall_dialog_view.h +++ b/chrome/browser/ui/views/apps/app_dialog/app_uninstall_dialog_view.h
@@ -57,8 +57,7 @@ void InitializeViewForWebApp(Profile* profile, const std::string& app_id); #if defined(OS_CHROMEOS) void InitializeViewForArcApp(Profile* profile, const std::string& app_id); - void InitializeViewForCrostiniApp(Profile* profile, - const std::string& app_id); + void InitializeViewWithMessage(const base::string16& message); #endif // views::StyledLabelListener methods.
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc index 8c5ef20..0e35e2f2 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc
@@ -7,6 +7,7 @@ #include <stddef.h> #include "base/command_line.h" +#include "base/feature_list.h" #include "base/macros.h" #include "build/build_config.h" #include "chrome/app/chrome_command_ids.h" @@ -45,6 +46,7 @@ #include "ui/events/test/event_generator.h" #include "ui/views/accessibility/view_accessibility.h" #include "ui/views/controls/textfield/textfield_test_api.h" +#include "ui/views/views_features.h" #if defined(USE_AURA) #include "ui/aura/window.h" @@ -324,11 +326,19 @@ // not there was text under the tap, which appears to be flaky. // Take the focus away and tap in the omnibox again, but drag a bit before - // releasing. We should focus the omnibox but not select all of its text. + // releasing. This shouldn't select text. + // + // Whether it'll focus depends on the state of the below feature: touch and + // drag will send a tap-down event, then a scroll or swipe event, but no + // complete tap event. When enabled, textfields will take focus on a complete + // tap instead of tap-down. + const bool focused_after_drag = + !base::FeatureList::IsEnabled(views::features::kTextfieldFocusOnTapUp); ASSERT_NO_FATAL_FAILURE( ui_test_utils::ClickOnView(browser(), VIEW_ID_TAB_CONTAINER)); ASSERT_NO_FATAL_FAILURE(Tap(tap_location, tap2_location)); - EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX)); + EXPECT_EQ(focused_after_drag, + ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX)); EXPECT_FALSE(omnibox_view->IsSelectAll()); }
diff --git a/chrome/browser/ui/views/plugin_vm/plugin_vm_installer_view_browsertest.cc b/chrome/browser/ui/views/plugin_vm/plugin_vm_installer_view_browsertest.cc index 110445a..b9388ba 100644 --- a/chrome/browser/ui/views/plugin_vm/plugin_vm_installer_view_browsertest.cc +++ b/chrome/browser/ui/views/plugin_vm/plugin_vm_installer_view_browsertest.cc
@@ -80,7 +80,7 @@ void AllowPluginVm() { EnterpriseEnrollDevice(); SetUserWithAffiliation(); - SetPluginVmDevicePolicies(); + SetPluginVmPolicies(); // Set correct PluginVmImage preference value. SetPluginVmImagePref(embedded_test_server()->GetURL(kZipFile).spec(), kZipFileHash); @@ -139,7 +139,11 @@ "device_id"); } - void SetPluginVmDevicePolicies() { + void SetPluginVmPolicies() { + // User polcies. + browser()->profile()->GetPrefs()->SetBoolean( + plugin_vm::prefs::kPluginVmAllowed, true); + // Device policies. scoped_testing_cros_settings_.device_settings()->Set( chromeos::kPluginVmAllowed, base::Value(true)); scoped_testing_cros_settings_.device_settings()->Set(
diff --git a/chrome/browser/ui/views/session_crashed_bubble_view.cc b/chrome/browser/ui/views/session_crashed_bubble_view.cc index 5632644f3..525313d42 100644 --- a/chrome/browser/ui/views/session_crashed_bubble_view.cc +++ b/chrome/browser/ui/views/session_crashed_bubble_view.cc
@@ -171,10 +171,13 @@ ignored_(true) { DCHECK(anchor_view); + SetShowCloseButton(true); SetTitle(l10n_util::GetStringUTF16(IDS_SESSION_CRASHED_BUBBLE_TITLE)); + // Allow unit tests to leave out Browser. const SessionStartupPref session_startup_pref = - SessionStartupPref::GetStartupPref(browser_->profile()); + browser_ ? SessionStartupPref::GetStartupPref(browser_->profile()) + : SessionStartupPref{SessionStartupPref::DEFAULT}; // Offer the option to open the startup pages using the cancel button, but // only when the user has selected the URLS option, and set at least one url. DialogDelegate::SetButtons(
diff --git a/chrome/browser/ui/views/session_crashed_bubble_view.h b/chrome/browser/ui/views/session_crashed_bubble_view.h index af1e8dc..1a51bdb 100644 --- a/chrome/browser/ui/views/session_crashed_bubble_view.h +++ b/chrome/browser/ui/views/session_crashed_bubble_view.h
@@ -35,6 +35,11 @@ static void Show(std::unique_ptr<BrowserRemovalObserver> browser_observer, bool uma_opted_in_already); + SessionCrashedBubbleView(views::View* anchor_view, + Browser* browser, + bool offer_uma_optin); + ~SessionCrashedBubbleView() override; + protected: // views::BubbleDialogDelegateView: ax::mojom::Role GetAccessibleWindowRole() override; @@ -42,11 +47,6 @@ private: friend class SessionCrashedBubbleViewTest; - SessionCrashedBubbleView(views::View* anchor_view, - Browser* browser, - bool offer_uma_optin); - ~SessionCrashedBubbleView() override; - // WidgetDelegateView methods. void OnWidgetDestroying(views::Widget* widget) override;
diff --git a/chrome/browser/ui/views/session_crashed_bubble_view_unittest.cc b/chrome/browser/ui/views/session_crashed_bubble_view_unittest.cc new file mode 100644 index 0000000..ed749d5b --- /dev/null +++ b/chrome/browser/ui/views/session_crashed_bubble_view_unittest.cc
@@ -0,0 +1,14 @@ +// 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/views/session_crashed_bubble_view.h" +#include "chrome/test/views/chrome_views_test_base.h" + +using SessionCrashedBubbleViewUnitTest = ChromeViewsTestBase; + +TEST_F(SessionCrashedBubbleViewUnitTest, BubbleHasCloseButton) { + views::View anchor; + SessionCrashedBubbleView bubble(&anchor, nullptr, true); + EXPECT_TRUE(bubble.ShouldShowCloseButton()); +}
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc index c84c5f5..015ea23 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.cc +++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -1268,6 +1268,8 @@ void TabStrip::AddTabToGroup(base::Optional<tab_groups::TabGroupId> group, int model_index) { tab_at(model_index)->set_group(std::move(group)); + + ExitTabClosingMode(); } void TabStrip::OnGroupCreated(const tab_groups::TabGroupId& group) {
diff --git a/chrome/browser/ui/views/web_apps/pwa_confirmation_bubble_view_browsertest.cc b/chrome/browser/ui/views/web_apps/pwa_confirmation_bubble_view_browsertest.cc index b491738b..cd6912c 100644 --- a/chrome/browser/ui/views/web_apps/pwa_confirmation_bubble_view_browsertest.cc +++ b/chrome/browser/ui/views/web_apps/pwa_confirmation_bubble_view_browsertest.cc
@@ -32,4 +32,14 @@ chrome::ShowPWAInstallBubble( browser->tab_strip_model()->GetActiveWebContents(), std::move(app_info), base::DoNothing()); + + // Tests that we don't crash when attempting to show bubble when it's already + // shown. + app_info = std::make_unique<WebApplicationInfo>(); + app_info->title = base::UTF8ToUTF16("Test app 3"); + app_info->app_url = GURL("https://example3.com"); + app_info->open_as_window = true; + chrome::ShowPWAInstallBubble( + browser->tab_strip_model()->GetActiveWebContents(), std::move(app_info), + base::DoNothing()); }
diff --git a/chrome/browser/ui/views/web_apps/web_app_confirmation_view_browsertest.cc b/chrome/browser/ui/views/web_apps/web_app_confirmation_view_browsertest.cc new file mode 100644 index 0000000..874f99a --- /dev/null +++ b/chrome/browser/ui/views/web_apps/web_app_confirmation_view_browsertest.cc
@@ -0,0 +1,31 @@ +// 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/test/bind_test_util.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_dialogs.h" +#include "chrome/common/web_application_info.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "content/public/test/browser_test.h" + +using WebAppConfirmViewBrowserTest = InProcessBrowserTest; + +IN_PROC_BROWSER_TEST_F(WebAppConfirmViewBrowserTest, ShowWebAppDialog) { + auto app_info = std::make_unique<WebApplicationInfo>(); + app_info->title = base::UTF8ToUTF16("Test app"); + app_info->app_url = GURL("https://example.com"); + + chrome::SetAutoAcceptWebAppDialogForTesting(/*auto_accept=*/true, + /*auto_open_in_window=*/true); + bool is_accepted = false; + auto callback = [&is_accepted](bool result, + std::unique_ptr<WebApplicationInfo>) { + is_accepted = result; + }; + + chrome::ShowWebAppDialog(browser()->tab_strip_model()->GetActiveWebContents(), + std::move(app_info), + base::BindLambdaForTesting(callback)); + EXPECT_TRUE(is_accepted); +}
diff --git a/chrome/browser/ui/views/web_apps/web_app_frame_toolbar_interactive_uitest.cc b/chrome/browser/ui/views/web_apps/web_app_frame_toolbar_interactive_uitest.cc index 67dbe1e6..060aed6 100644 --- a/chrome/browser/ui/views/web_apps/web_app_frame_toolbar_interactive_uitest.cc +++ b/chrome/browser/ui/views/web_apps/web_app_frame_toolbar_interactive_uitest.cc
@@ -15,6 +15,7 @@ #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/web_apps/web_app_frame_toolbar_test_mixin.h" #include "chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.h" +#include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/interactive_test_utils.h" #include "content/public/test/browser_test.h" @@ -89,6 +90,12 @@ } focus_manager->AdvanceFocus(true); EXPECT_EQ(focus_manager->GetFocusedView()->GetID(), VIEW_ID_RELOAD_BUTTON); + + // Test that back button is enabled after navigating to another page + const GURL another_url("https://anothertest.org"); + web_app::NavigateToURLAndWait(app_browser(), another_url); + app_browser()->command_controller()->ExecuteCommand(IDC_FOCUS_TOOLBAR); + EXPECT_EQ(focus_manager->GetFocusedView()->GetID(), VIEW_ID_BACK_BUTTON); } INSTANTIATE_TEST_SUITE_P(ExtensionsToolbarMenu,
diff --git a/chrome/browser/ui/web_applications/app_browser_controller.cc b/chrome/browser/ui/web_applications/app_browser_controller.cc index 7796a7a..ffdee99e 100644 --- a/chrome/browser/ui/web_applications/app_browser_controller.cc +++ b/chrome/browser/ui/web_applications/app_browser_controller.cc
@@ -89,6 +89,7 @@ constexpr gfx::Rect TERMINAL_DEFAULT_BOUNDS(gfx::Point(64, 64), gfx::Size(652, 484)); constexpr gfx::Size TERMINAL_SETTINGS_DEFAULT_SIZE(768, 512); +constexpr gfx::Size HELP_DEFAULT_SIZE(960, 600); } // namespace // static @@ -317,6 +318,12 @@ return bounds; } return TERMINAL_DEFAULT_BOUNDS; + } else if (system_app_type_ == SystemAppType::HELP) { + // Help app is centered. + gfx::Rect bounds = + display::Screen::GetScreen()->GetDisplayForNewWindows().work_area(); + bounds.ClampToCenteredSize(HELP_DEFAULT_SIZE); + return bounds; } return gfx::Rect(); }
diff --git a/chrome/browser/ui/webui/app_management/app_management.mojom b/chrome/browser/ui/webui/app_management/app_management.mojom index 993f37268b..dce9350 100644 --- a/chrome/browser/ui/webui/app_management/app_management.mojom +++ b/chrome/browser/ui/webui/app_management/app_management.mojom
@@ -83,3 +83,8 @@ MEDIASTREAM_MIC = 9, MEDIASTREAM_CAMERA = 10, }; + +// The Plugin VM app publisher uses this enum directly. +enum PluginVmPermissionType { + PRINTING = 0, +};
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc index f54357d9..6fa65ee 100644 --- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc +++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -194,7 +194,6 @@ #include "chromeos/components/multidevice/debug_webui/url_constants.h" #include "chromeos/components/print_management/print_management_ui.h" #include "chromeos/components/print_management/url_constants.h" -#include "chromeos/components/sample_system_web_app_ui/url_constants.h" #include "chromeos/constants/chromeos_features.h" #include "chromeos/constants/chromeos_switches.h" #include "chromeos/services/multidevice_setup/multidevice_setup_service.h" @@ -205,6 +204,7 @@ #if defined(OS_CHROMEOS) && !defined(OFFICIAL_BUILD) #include "chrome/browser/ui/webui/chromeos/emulator/device_emulator_ui.h" #include "chromeos/components/sample_system_web_app_ui/sample_system_web_app_ui.h" +#include "chromeos/components/sample_system_web_app_ui/url_constants.h" #endif #if !defined(OS_CHROMEOS)
diff --git a/chrome/browser/ui/webui/chromeos/sync/os_sync_handler.cc b/chrome/browser/ui/webui/chromeos/sync/os_sync_handler.cc index b10a6e8..e8f9191 100644 --- a/chrome/browser/ui/webui/chromeos/sync/os_sync_handler.cc +++ b/chrome/browser/ui/webui/chromeos/sync/os_sync_handler.cc
@@ -46,6 +46,10 @@ base::BindRepeating(&OSSyncHandler::HandleDidNavigateAwayFromOsSyncPage, base::Unretained(this))); web_ui()->RegisterMessageCallback( + "OsSyncPrefsDispatch", + base::BindRepeating(&OSSyncHandler::HandleOsSyncPrefsDispatch, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( "SetOsSyncFeatureEnabled", base::BindRepeating(&OSSyncHandler::HandleSetOsSyncFeatureEnabled, base::Unretained(this))); @@ -69,13 +73,16 @@ } void OSSyncHandler::HandleDidNavigateToOsSyncPage(const base::ListValue* args) { + HandleOsSyncPrefsDispatch(args); +} + +void OSSyncHandler::HandleOsSyncPrefsDispatch(const base::ListValue* args) { AllowJavascript(); // Cache the feature enabled pref. SyncService* service = GetSyncService(); if (service) feature_enabled_ = service->GetUserSettings()->IsOsSyncFeatureEnabled(); - PushSyncPrefs(); }
diff --git a/chrome/browser/ui/webui/chromeos/sync/os_sync_handler.h b/chrome/browser/ui/webui/chromeos/sync/os_sync_handler.h index 73dd52b7..33c29e8 100644 --- a/chrome/browser/ui/webui/chromeos/sync/os_sync_handler.h +++ b/chrome/browser/ui/webui/chromeos/sync/os_sync_handler.h
@@ -40,6 +40,7 @@ // Callbacks from the page. Visible for testing. void HandleDidNavigateToOsSyncPage(const base::ListValue* args); void HandleDidNavigateAwayFromOsSyncPage(const base::ListValue* args); + void HandleOsSyncPrefsDispatch(const base::ListValue* args); void HandleSetOsSyncFeatureEnabled(const base::ListValue* args); void HandleSetOsSyncDatatypes(const base::ListValue* args);
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page.mojom b/chrome/browser/ui/webui/new_tab_page/new_tab_page.mojom index 22000bf..9aa9fc7d8 100644 --- a/chrome/browser/ui/webui/new_tab_page/new_tab_page.mojom +++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page.mojom
@@ -131,6 +131,8 @@ skia.mojom.SkColor shortcut_text_color; // True if |shortcut_background_color| is dark. bool shortcut_use_white_add_icon; + // True if the shortcuts titles should be wrapped in a pill. + bool shortcut_use_title_pill; // True if the theme is dark (e.g. NTP background color is dark). bool is_dark; // Color of Google logo. If not set show the logo multi-colored. @@ -165,6 +167,16 @@ url.mojom.Url icon_url; }; +// Type of image of an image doodle. Used for metrics logging only. +enum DoodleImageType { + // Animation of an animated doodle. + ANIMATION, + // Static preview image of an animated doodle. + CTA, + // Image of a static doodle. + STATIC, +}; + // The contents of simple and animated doodles. struct ImageDoodleContent { // Doodle image encoded as data URL. @@ -294,11 +306,19 @@ // Logs that the One Google Bar was added to the DOM / loaded in an iframe at // |time|. OnOneGoogleBarRendered(double time); + // Logs that the promo iframe was loaded at |time|. + OnPromoRendered(double time); // Logs that |tile| at position |index| was triggered to navigate to that // most visited entry. OnMostVisitedTileNavigation(MostVisitedTile tile, uint32 index); // Logs an action performed in the customize dialog. OnCustomizeDialogAction(CustomizeDialogAction action); + // Logs that the |type| image of an image doodle has been clicked. + OnDoodleImageClicked(DoodleImageType type); + // Logs that the |type| image of an image doodle has been shown at |time|. + OnDoodleImageRendered(DoodleImageType type, double time); + // Logs that a link on a promo has been clicked. + OnPromoLinkClicked(); // ======= REALBOX ======= // Queries autocomplete matches from the browser.
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc index 862e1b9a..cbc13a7 100644 --- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc +++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc
@@ -13,6 +13,7 @@ #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics_action.h" +#include "base/strings/strcat.h" #include "base/strings/string_piece.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/autocomplete/chrome_autocomplete_provider_client.h" @@ -97,7 +98,9 @@ theme->shortcut_text_color = ntp_theme.text_color; theme->shortcut_use_white_add_icon = color_utils::IsDark(ntp_theme.shortcut_color); - theme->is_dark = !color_utils::IsDark(ntp_theme.text_color); + theme->shortcut_use_title_pill = ntp_theme.has_theme_image; + theme->is_dark = + ntp_theme.has_theme_image || !color_utils::IsDark(ntp_theme.text_color); if (ntp_theme.logo_alternate) { theme->logo_color = ntp_theme.logo_color; } @@ -111,6 +114,10 @@ } else { theme->background_image_url = ntp_theme.custom_background_url; } + } else if (ntp_theme.has_theme_image) { + theme->background_image_url = + GURL(base::StrCat({"chrome-untrusted://theme/IDR_THEME_NTP_BACKGROUND?", + ntp_theme.theme_id})); } if (!ntp_theme.custom_background_attribution_line_1.empty()) { theme->background_image_attribution_1 = @@ -495,6 +502,11 @@ base::Time::FromJsTime(time) - ntp_navigation_start_time_); } +void NewTabPageHandler::OnPromoRendered(double time) { + logger_->LogEvent(NTP_MIDDLE_SLOT_PROMO_SHOWN, + base::Time::FromJsTime(time) - ntp_navigation_start_time_); +} + void NewTabPageHandler::OnMostVisitedTileNavigation( new_tab_page::mojom::MostVisitedTilePtr tile, uint32_t index) { @@ -554,6 +566,49 @@ LogEvent(event); } +void NewTabPageHandler::OnDoodleImageClicked( + new_tab_page::mojom::DoodleImageType type) { + NTPLoggingEventType event; + switch (type) { + case new_tab_page::mojom::DoodleImageType::ANIMATION: + event = NTP_ANIMATED_LOGO_CLICKED; + break; + case new_tab_page::mojom::DoodleImageType::CTA: + event = NTP_CTA_LOGO_CLICKED; + break; + case new_tab_page::mojom::DoodleImageType::STATIC: + event = NTP_STATIC_LOGO_CLICKED; + break; + default: + NOTREACHED(); + return; + } + LogEvent(event); +} + +void NewTabPageHandler::OnDoodleImageRendered( + new_tab_page::mojom::DoodleImageType type, + double time) { + NTPLoggingEventType event; + switch (type) { + case new_tab_page::mojom::DoodleImageType::CTA: + event = NTP_CTA_LOGO_SHOWN_FROM_CACHE; + break; + case new_tab_page::mojom::DoodleImageType::STATIC: + event = NTP_STATIC_LOGO_SHOWN_FROM_CACHE; + break; + default: + NOTREACHED(); + return; + } + logger_->LogEvent(event, + base::Time::FromJsTime(time) - ntp_navigation_start_time_); +} + +void NewTabPageHandler::OnPromoLinkClicked() { + LogEvent(NTP_MIDDLE_SLOT_PROMO_LINK_CLICKED); +} + void NewTabPageHandler::QueryAutocomplete(const base::string16& input, bool prevent_inline_autocomplete) { if (!autocomplete_controller_) {
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.h b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.h index 7338498..88c49a2d 100644 --- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.h +++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.h
@@ -102,10 +102,15 @@ std::vector<new_tab_page::mojom::MostVisitedTilePtr> tiles, double time) override; void OnOneGoogleBarRendered(double time) override; + void OnPromoRendered(double time) override; void OnMostVisitedTileNavigation(new_tab_page::mojom::MostVisitedTilePtr tile, uint32_t index) override; void OnCustomizeDialogAction( new_tab_page::mojom::CustomizeDialogAction action) override; + void OnDoodleImageClicked(new_tab_page::mojom::DoodleImageType type) override; + void OnDoodleImageRendered(new_tab_page::mojom::DoodleImageType type, + double time) override; + void OnPromoLinkClicked() override; void QueryAutocomplete(const base::string16& input, bool prevent_inline_autocomplete) override; void StopAutocomplete(bool clear_result) override;
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc index 3314592..4e291ac 100644 --- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc +++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/ui/webui/favicon_source.h" #include "chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.h" #include "chrome/browser/ui/webui/new_tab_page/untrusted_source.h" +#include "chrome/browser/ui/webui/theme_source.h" #include "chrome/browser/ui/webui/webui_util.h" #include "chrome/common/url_constants.h" #include "chrome/grit/browser_resources.h" @@ -229,6 +230,9 @@ profile_, chrome::FaviconUrlFormat::kFavicon2)); content::URLDataSource::Add(profile_, std::make_unique<UntrustedSource>(profile_)); + content::URLDataSource::Add( + profile_, + std::make_unique<ThemeSource>(profile_, /*serve_untrusted=*/true)); web_ui->AddRequestableScheme(content::kChromeUIUntrustedScheme);
diff --git a/chrome/browser/ui/webui/new_tab_page/untrusted_source.cc b/chrome/browser/ui/webui/new_tab_page/untrusted_source.cc index 228207c..b4f428f 100644 --- a/chrome/browser/ui/webui/new_tab_page/untrusted_source.cc +++ b/chrome/browser/ui/webui/new_tab_page/untrusted_source.cc
@@ -11,6 +11,7 @@ #include "base/files/file_util.h" #include "base/i18n/rtl.h" #include "base/memory/ref_counted_memory.h" +#include "base/metrics/histogram_macros.h" #include "base/optional.h" #include "base/strings/string_piece.h" #include "base/strings/stringprintf.h" @@ -120,6 +121,7 @@ if (promo_service_->promo_data().has_value()) { OnPromoDataUpdated(); } + promo_load_start_time_ = base::TimeTicks::Now(); promo_service_->Refresh(); return; } @@ -236,6 +238,27 @@ } void UntrustedSource::OnPromoDataUpdated() { + if (promo_load_start_time_.has_value()) { + base::TimeDelta duration = base::TimeTicks::Now() - *promo_load_start_time_; + UMA_HISTOGRAM_MEDIUM_TIMES("NewTabPage.Promos.RequestLatency2", duration); + if (promo_service_->promo_status() == PromoService::Status::OK_WITH_PROMO) { + UMA_HISTOGRAM_MEDIUM_TIMES( + "NewTabPage.Promos.RequestLatency2.SuccessWithPromo", duration); + } else if (promo_service_->promo_status() == + PromoService::Status::OK_BUT_BLOCKED) { + UMA_HISTOGRAM_MEDIUM_TIMES( + "NewTabPage.Promos.RequestLatency2.SuccessButBlocked", duration); + } else if (promo_service_->promo_status() == + PromoService::Status::OK_WITHOUT_PROMO) { + UMA_HISTOGRAM_MEDIUM_TIMES( + "NewTabPage.Promos.RequestLatency2.SuccessWithoutPromo", duration); + } else { + UMA_HISTOGRAM_MEDIUM_TIMES("NewTabPage.Promos.RequestLatency2.Failure", + duration); + } + promo_load_start_time_ = base::nullopt; + } + const auto& data = promo_service_->promo_data(); std::string html; if (data.has_value() && !data->promo_html.empty()) {
diff --git a/chrome/browser/ui/webui/new_tab_page/untrusted_source.h b/chrome/browser/ui/webui/new_tab_page/untrusted_source.h index a83eba6..ac3b88d 100644 --- a/chrome/browser/ui/webui/new_tab_page/untrusted_source.h +++ b/chrome/browser/ui/webui/new_tab_page/untrusted_source.h
@@ -77,6 +77,7 @@ PromoService* promo_service_; ScopedObserver<PromoService, PromoServiceObserver> promo_service_observer_{ this}; + base::Optional<base::TimeTicks> promo_load_start_time_; }; #endif // CHROME_BROWSER_UI_WEBUI_NEW_TAB_PAGE_UNTRUSTED_SOURCE_H_
diff --git a/chrome/browser/ui/webui/policy_ui.cc b/chrome/browser/ui/webui/policy_ui.cc index 7695bbf0..7509acf1 100644 --- a/chrome/browser/ui/webui/policy_ui.cc +++ b/chrome/browser/ui/webui/policy_ui.cc
@@ -24,52 +24,55 @@ PolicyUIHandler::AddCommonLocalizedStringsToSource(source); static constexpr webui::LocalizedString kStrings[] = { - // Localized strings (alphabetical order). - {"exportPoliciesJSON", IDS_EXPORT_POLICIES_JSON}, - {"filterPlaceholder", IDS_POLICY_FILTER_PLACEHOLDER}, - {"hideExpandedStatus", IDS_POLICY_HIDE_EXPANDED_STATUS}, - {"isAffiliatedYes", IDS_POLICY_IS_AFFILIATED_YES}, - {"isAffiliatedNo", IDS_POLICY_IS_AFFILIATED_NO}, - {"labelAssetId", IDS_POLICY_LABEL_ASSET_ID}, - {"labelClientId", IDS_POLICY_LABEL_CLIENT_ID}, - {"labelDirectoryApiId", IDS_POLICY_LABEL_DIRECTORY_API_ID}, - {"labelEnterpriseDisplayDomain", - IDS_POLICY_LABEL_ENTERPRISE_DISPLAY_DOMAIN}, - {"labelEnterpriseEnrollmentDomain", - IDS_POLICY_LABEL_ENTERPRISE_ENROLLMENT_DOMAIN}, - {"labelGaiaId", IDS_POLICY_LABEL_GAIA_ID}, - {"labelIsAffiliated", IDS_POLICY_LABEL_IS_AFFILIATED}, - {"labelLocation", IDS_POLICY_LABEL_LOCATION}, - {"labelMachineEnrollmentDomain", - IDS_POLICY_LABEL_MACHINE_ENROLLMENT_DOMAIN}, - {"labelMachineEnrollmentMachineName", - IDS_POLICY_LABEL_MACHINE_ENROLLMENT_MACHINE_NAME}, - {"labelMachineEnrollmentToken", - IDS_POLICY_LABEL_MACHINE_ENROLLMENT_TOKEN}, - {"labelMachineEntrollmentDeviceId", - IDS_POLICY_LABEL_MACHINE_ENROLLMENT_DEVICE_ID}, - {"labelIsOffHoursActive", IDS_POLICY_LABEL_IS_OFFHOURS_ACTIVE}, - {"labelPoliciesPush", IDS_POLICY_LABEL_PUSH_POLICIES}, - {"labelRefreshInterval", IDS_POLICY_LABEL_REFRESH_INTERVAL}, - {"labelStatus", IDS_POLICY_LABEL_STATUS}, - {"labelTimeSinceLastRefresh", IDS_POLICY_LABEL_TIME_SINCE_LAST_REFRESH}, - {"labelUsername", IDS_POLICY_LABEL_USERNAME}, - {"noPoliciesSet", IDS_POLICY_NO_POLICIES_SET}, - {"offHoursActive", IDS_POLICY_OFFHOURS_ACTIVE}, - {"offHoursNotActive", IDS_POLICY_OFFHOURS_NOT_ACTIVE}, - {"policiesPushOff", IDS_POLICY_PUSH_POLICIES_OFF}, - {"policiesPushOn", IDS_POLICY_PUSH_POLICIES_ON}, - {"policyLearnMore", IDS_POLICY_LEARN_MORE}, - {"reloadPolicies", IDS_POLICY_RELOAD_POLICIES}, - {"showExpandedStatus", IDS_POLICY_SHOW_EXPANDED_STATUS}, - {"showLess", IDS_POLICY_SHOW_LESS}, - {"showMore", IDS_POLICY_SHOW_MORE}, - {"showUnset", IDS_POLICY_SHOW_UNSET}, - {"signinProfile", IDS_POLICY_SIGNIN_PROFILE}, - {"status", IDS_POLICY_STATUS}, - {"statusDevice", IDS_POLICY_STATUS_DEVICE}, - {"statusMachine", IDS_POLICY_STATUS_MACHINE}, - {"statusUser", IDS_POLICY_STATUS_USER}, + // Localized strings (alphabetical order). + {"exportPoliciesJSON", IDS_EXPORT_POLICIES_JSON}, + {"filterPlaceholder", IDS_POLICY_FILTER_PLACEHOLDER}, + {"hideExpandedStatus", IDS_POLICY_HIDE_EXPANDED_STATUS}, + {"isAffiliatedYes", IDS_POLICY_IS_AFFILIATED_YES}, + {"isAffiliatedNo", IDS_POLICY_IS_AFFILIATED_NO}, + {"labelAssetId", IDS_POLICY_LABEL_ASSET_ID}, + {"labelClientId", IDS_POLICY_LABEL_CLIENT_ID}, + {"labelDirectoryApiId", IDS_POLICY_LABEL_DIRECTORY_API_ID}, + {"labelEnterpriseDisplayDomain", + IDS_POLICY_LABEL_ENTERPRISE_DISPLAY_DOMAIN}, + {"labelEnterpriseEnrollmentDomain", + IDS_POLICY_LABEL_ENTERPRISE_ENROLLMENT_DOMAIN}, + {"labelGaiaId", IDS_POLICY_LABEL_GAIA_ID}, + {"labelIsAffiliated", IDS_POLICY_LABEL_IS_AFFILIATED}, + {"labelLocation", IDS_POLICY_LABEL_LOCATION}, + {"labelMachineEnrollmentDomain", + IDS_POLICY_LABEL_MACHINE_ENROLLMENT_DOMAIN}, + {"labelMachineEnrollmentMachineName", + IDS_POLICY_LABEL_MACHINE_ENROLLMENT_MACHINE_NAME}, + {"labelMachineEnrollmentToken", IDS_POLICY_LABEL_MACHINE_ENROLLMENT_TOKEN}, + {"labelMachineEntrollmentDeviceId", + IDS_POLICY_LABEL_MACHINE_ENROLLMENT_DEVICE_ID}, + {"labelIsOffHoursActive", IDS_POLICY_LABEL_IS_OFFHOURS_ACTIVE}, + {"labelPoliciesPush", IDS_POLICY_LABEL_PUSH_POLICIES}, + {"labelRefreshInterval", IDS_POLICY_LABEL_REFRESH_INTERVAL}, + {"labelStatus", IDS_POLICY_LABEL_STATUS}, + {"labelTimeSinceLastRefresh", IDS_POLICY_LABEL_TIME_SINCE_LAST_REFRESH}, + {"labelUsername", IDS_POLICY_LABEL_USERNAME}, + {"labelVersion", IDS_POLICY_LABEL_VERSION}, + {"noPoliciesSet", IDS_POLICY_NO_POLICIES_SET}, + {"offHoursActive", IDS_POLICY_OFFHOURS_ACTIVE}, + {"offHoursNotActive", IDS_POLICY_OFFHOURS_NOT_ACTIVE}, + {"policiesPushOff", IDS_POLICY_PUSH_POLICIES_OFF}, + {"policiesPushOn", IDS_POLICY_PUSH_POLICIES_ON}, + {"policyLearnMore", IDS_POLICY_LEARN_MORE}, + {"reloadPolicies", IDS_POLICY_RELOAD_POLICIES}, + {"showExpandedStatus", IDS_POLICY_SHOW_EXPANDED_STATUS}, + {"showLess", IDS_POLICY_SHOW_LESS}, + {"showMore", IDS_POLICY_SHOW_MORE}, + {"showUnset", IDS_POLICY_SHOW_UNSET}, + {"signinProfile", IDS_POLICY_SIGNIN_PROFILE}, + {"status", IDS_POLICY_STATUS}, + {"statusDevice", IDS_POLICY_STATUS_DEVICE}, + {"statusMachine", IDS_POLICY_STATUS_MACHINE}, +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) + {"statusUpdater", IDS_POLICY_STATUS_UPDATER}, +#endif + {"statusUser", IDS_POLICY_STATUS_USER}, }; AddLocalizedStringsBulk(source, kStrings);
diff --git a/chrome/browser/ui/webui/policy_ui_handler.cc b/chrome/browser/ui/webui/policy_ui_handler.cc index 1dac03d1..d649be0 100644 --- a/chrome/browser/ui/webui/policy_ui_handler.cc +++ b/chrome/browser/ui/webui/policy_ui_handler.cc
@@ -107,7 +107,11 @@ #endif #if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) +#include <DSRole.h> + #include "chrome/browser/google/google_update_policy_fetcher_win.h" +#include "chrome/install_static/install_util.h" +#include "components/update_client/updater_state.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #endif // defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) @@ -438,6 +442,23 @@ }; #endif +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) +class UpdaterStatusProvider : public PolicyStatusProvider { + public: + UpdaterStatusProvider(); + ~UpdaterStatusProvider() override = default; + void GetStatus(base::DictionaryValue* dict) override; + + private: + static std::string FetchActiveDirectoryDomain(); + void OnDomainReceived(std::string domain); + + std::string version_; + std::string domain_; + base::WeakPtrFactory<UpdaterStatusProvider> weak_factory_{this}; +}; +#endif + PolicyStatusProvider::PolicyStatusProvider() {} PolicyStatusProvider::~PolicyStatusProvider() {} @@ -710,6 +731,51 @@ #endif // defined(OS_CHROMEOS) +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) +UpdaterStatusProvider::UpdaterStatusProvider() { + auto state = + update_client::UpdaterState::GetState(install_static::IsSystemInstall()); + const auto& version = state->find("version"); + if (version != state->end()) + version_ = version->second; + + base::ThreadPool::PostTaskAndReplyWithResult( + FROM_HERE, + {base::ThreadPool(), base::MayBlock(), + base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, + base::BindOnce(&UpdaterStatusProvider::FetchActiveDirectoryDomain), + base::BindOnce(&UpdaterStatusProvider::OnDomainReceived, + weak_factory_.GetWeakPtr())); +} + +void UpdaterStatusProvider::GetStatus(base::DictionaryValue* dict) { + if (!version_.empty()) + dict->SetString("version", version_); + if (!domain_.empty()) + dict->SetString("domain", domain_); +} + +// static +std::string UpdaterStatusProvider::FetchActiveDirectoryDomain() { + std::string domain; + ::DSROLE_PRIMARY_DOMAIN_INFO_BASIC* info = nullptr; + if (::DsRoleGetPrimaryDomainInformation(nullptr, + ::DsRolePrimaryDomainInfoBasic, + (PBYTE*)&info) != ERROR_SUCCESS) { + return domain; + } + if (info->DomainNameDns) + domain = base::WideToUTF8(info->DomainNameDns); + ::DsRoleFreeMemory(info); + return domain; +} + +void UpdaterStatusProvider::OnDomainReceived(std::string domain) { + domain_ = std::move(domain); + NotifyStatusChange(); +} +#endif + PolicyUIHandler::PolicyUIHandler() {} PolicyUIHandler::~PolicyUIHandler() { @@ -822,6 +888,7 @@ #endif // defined(OS_CHROMEOS) #if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) + updater_status_provider_ = std::make_unique<UpdaterStatusProvider>(); base::PostTaskAndReplyWithResult( base::ThreadPool::CreateCOMSTATaskRunner( {base::TaskPriority::USER_BLOCKING, @@ -838,12 +905,15 @@ device_status_provider_ = std::make_unique<PolicyStatusProvider>(); if (!machine_status_provider_.get()) machine_status_provider_ = std::make_unique<PolicyStatusProvider>(); + if (!updater_status_provider_.get()) + updater_status_provider_ = std::make_unique<PolicyStatusProvider>(); auto update_callback(base::BindRepeating(&PolicyUIHandler::SendStatus, base::Unretained(this))); user_status_provider_->SetStatusChangeCallback(update_callback); device_status_provider_->SetStatusChangeCallback(update_callback); machine_status_provider_->SetStatusChangeCallback(update_callback); + updater_status_provider_->SetStatusChangeCallback(update_callback); GetPolicyService()->AddObserver(policy::POLICY_DOMAIN_CHROME, this); GetPolicyService()->AddObserver(policy::POLICY_DOMAIN_EXTENSIONS, this); @@ -1033,6 +1103,10 @@ new base::DictionaryValue); machine_status_provider_->GetStatus(machine_status.get()); + std::unique_ptr<base::DictionaryValue> updater_status( + new base::DictionaryValue); + updater_status_provider_->GetStatus(updater_status.get()); + base::DictionaryValue status; if (!device_status->empty()) status.Set("device", std::move(device_status)); @@ -1040,6 +1114,8 @@ status.Set("machine", std::move(machine_status)); if (!user_status->empty()) status.Set("user", std::move(user_status)); + if (!updater_status->empty()) + status.Set("updater", std::move(updater_status)); FireWebUIListener("status-updated", status); }
diff --git a/chrome/browser/ui/webui/policy_ui_handler.h b/chrome/browser/ui/webui/policy_ui_handler.h index dcba4d6d..e73ced2 100644 --- a/chrome/browser/ui/webui/policy_ui_handler.h +++ b/chrome/browser/ui/webui/policy_ui_handler.h
@@ -122,6 +122,7 @@ std::unique_ptr<PolicyStatusProvider> user_status_provider_; std::unique_ptr<PolicyStatusProvider> device_status_provider_; std::unique_ptr<PolicyStatusProvider> machine_status_provider_; + std::unique_ptr<PolicyStatusProvider> updater_status_provider_; #if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) std::unique_ptr<policy::PolicyMap> updater_policies_;
diff --git a/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc b/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc index e1d6274..9f4b1674 100644 --- a/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc
@@ -29,14 +29,24 @@ enabled); } +bool IsTabletModeEnabled() { + return ash::TabletMode::Get() && ash::TabletMode::Get()->InTabletMode(); +} + } // namespace AccessibilityHandler::AccessibilityHandler(Profile* profile) - : profile_(profile) {} + : profile_(profile) { + if (ash::TabletMode::Get()) + ash::TabletMode::Get()->AddObserver(this); +} AccessibilityHandler::~AccessibilityHandler() { if (a11y_nav_buttons_toggle_metrics_reporter_timer_.IsRunning()) a11y_nav_buttons_toggle_metrics_reporter_timer_.FireNow(); + + if (ash::TabletMode::Get()) + ash::TabletMode::Get()->RemoveObserver(this); } void AccessibilityHandler::RegisterMessages() { @@ -100,31 +110,18 @@ const base::ListValue* args) { AllowJavascript(); - // When tablet mode is active we can return early since tablet mode - // is supported. - if (ash::TabletMode::Get()->InTabletMode()) { - FireWebUIListener( - "initial-data-ready", - base::Value(AccessibilityManager::Get()->GetStartupSoundEnabled()), - base::Value(true /* tablet_mode_supported */)); - return; - } - - PowerManagerClient::Get()->GetSwitchStates( - base::BindOnce(&AccessibilityHandler::OnReceivedSwitchStates, - weak_ptr_factory_.GetWeakPtr())); -} - -void AccessibilityHandler::OnReceivedSwitchStates( - base::Optional<PowerManagerClient::SwitchStates> switch_states) { - bool tablet_mode_supported = - switch_states.has_value() && - switch_states->tablet_mode != PowerManagerClient::TabletMode::UNSUPPORTED; - FireWebUIListener( "initial-data-ready", base::Value(AccessibilityManager::Get()->GetStartupSoundEnabled()), - base::Value(tablet_mode_supported)); + base::Value(IsTabletModeEnabled())); +} + +void AccessibilityHandler::OnTabletModeStarted() { + FireWebUIListener("tablet-mode-changed", base::Value(IsTabletModeEnabled())); +} + +void AccessibilityHandler::OnTabletModeEnded() { + FireWebUIListener("tablet-mode-changed", base::Value(IsTabletModeEnabled())); } void AccessibilityHandler::OpenExtensionOptionsPage(const char extension_id[]) {
diff --git a/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h b/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h index 54290f8..5f7dcb77 100644 --- a/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h +++ b/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h
@@ -5,10 +5,10 @@ #ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_ACCESSIBILITY_HANDLER_H_ #define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_ACCESSIBILITY_HANDLER_H_ +#include "ash/public/cpp/tablet_mode_observer.h" #include "base/macros.h" #include "base/timer/timer.h" #include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" -#include "chromeos/dbus/power/power_manager_client.h" namespace base { class ListValue; @@ -19,7 +19,8 @@ namespace chromeos { namespace settings { -class AccessibilityHandler : public ::settings::SettingsPageUIHandler { +class AccessibilityHandler : public ::settings::SettingsPageUIHandler, + public ash::TabletModeObserver { public: explicit AccessibilityHandler(Profile* profile); ~AccessibilityHandler() override; @@ -33,6 +34,10 @@ // mode is supported. Visible for testing. void HandleManageA11yPageReady(const base::ListValue* args); + // ash::TabletModeObserver: + void OnTabletModeStarted() override; + void OnTabletModeEnded() override; + private: // Callback for the messages to show settings for ChromeVox or // Select To Speak. @@ -42,11 +47,6 @@ void HandleRecordSelectedShowShelfNavigationButtonsValue( const base::ListValue* args); - // Callback which updates visibility for the shelf navigation buttons - // accessibility setting, depending on whether tablet mode is supported. - void OnReceivedSwitchStates( - base::Optional<chromeos::PowerManagerClient::SwitchStates> switch_states); - void OpenExtensionOptionsPage(const char extension_id[]); Profile* profile_; // Weak pointer.
diff --git a/chrome/browser/ui/webui/settings/chromeos/accessibility_handler_unittest.cc b/chrome/browser/ui/webui/settings/chromeos/accessibility_handler_unittest.cc index 8ee78ca..c2502851 100644 --- a/chrome/browser/ui/webui/settings/chromeos/accessibility_handler_unittest.cc +++ b/chrome/browser/ui/webui/settings/chromeos/accessibility_handler_unittest.cc
@@ -9,7 +9,6 @@ #include "ash/public/cpp/test/test_tablet_mode.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/in_process_browser_test.h" -#include "chromeos/dbus/power/fake_power_manager_client.h" #include "content/public/test/test_web_ui.h" #include "testing/gtest/include/gtest/gtest.h" @@ -35,7 +34,6 @@ void SetUp() override { ChromeRenderViewHostTestHarness::SetUp(); - PowerManagerClient::InitializeFake(); test_tablet_mode_ = std::make_unique<ash::TestTabletMode>(); handler_ = std::make_unique<TestingAccessibilityHandler>(&web_ui_); } @@ -43,7 +41,6 @@ void TearDown() override { handler_.reset(); test_tablet_mode_.reset(); - PowerManagerClient::Shutdown(); ChromeRenderViewHostTestHarness::TearDown(); } @@ -52,38 +49,15 @@ std::unique_ptr<TestingAccessibilityHandler> handler_; }; -// Test that when tablet mode is supported, the correct data is returned by +// Test that when tablet mode is disabled, the correct data is returned by // HandleManageA11yPageReady(). -TEST_F(AccessibilityHandlerTest, ManageA11yPageReadyTabletModeSupported) { - // Set tablet mode as supported. - chromeos::FakePowerManagerClient::Get()->SetTabletMode( - chromeos::PowerManagerClient::TabletMode::OFF, base::TimeTicks()); - +TEST_F(AccessibilityHandlerTest, ManageA11yPageReadyTabletModeDisabled) { + test_tablet_mode_->SetEnabledForTest(false); handler_->HandleManageA11yPageReady(/* args */ nullptr); - // Wait for the AccessibilityHandler to receive data from PowerManagerClient. - base::RunLoop().RunUntilIdle(); - const content::TestWebUI::CallData& call_data = *web_ui_.call_data().back(); - // Ensure tablet mode is returned as supported. - EXPECT_TRUE(call_data.arg3()->GetBool()); -} - -// Test that when tablet mode is unsupported, the correct data is returned by -// HandleManageA11yPageReady(). -TEST_F(AccessibilityHandlerTest, ManageA11yPageReadyTabletModeUnsupported) { - // Set tablet mode as unsupported. - chromeos::FakePowerManagerClient::Get()->SetTabletMode( - chromeos::PowerManagerClient::TabletMode::UNSUPPORTED, base::TimeTicks()); - handler_->HandleManageA11yPageReady(/* args */ nullptr); - - // Wait for the AccessibilityHandler to receive data from PowerManagerClient. - base::RunLoop().RunUntilIdle(); - - const content::TestWebUI::CallData& call_data = *web_ui_.call_data().back(); - - // Ensure tablet mode is returned as unsupported. + // Ensure tablet mode is returned as disabled. EXPECT_FALSE(call_data.arg3()->GetBool()); } @@ -95,7 +69,7 @@ const content::TestWebUI::CallData& call_data = *web_ui_.call_data().back(); - // Ensure tablet mode is returned as supported. + // Ensure tablet mode is returned as enabled. EXPECT_TRUE(call_data.arg3()->GetBool()); }
diff --git a/chrome/browser/ui/webui/settings/chromeos/app_management/app_management_uma.h b/chrome/browser/ui/webui/settings/chromeos/app_management/app_management_uma.h index 05322cd6..dbb61fe 100644 --- a/chrome/browser/ui/webui/settings/chromeos/app_management/app_management_uma.h +++ b/chrome/browser/ui/webui/settings/chromeos/app_management/app_management_uma.h
@@ -20,7 +20,9 @@ kAppManagementMainViewChromeApp = 7, kAppManagementMainViewWebApp = 8, kOsSettingsMainPage = 9, - kMaxValue = kOsSettingsMainPage, + kAppManagementMainViewPluginVm = 10, + kDBusServicePluginVm = 11, + kMaxValue = kDBusServicePluginVm, }; #endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_APP_MANAGEMENT_APP_MANAGEMENT_UMA_H_
diff --git a/chrome/browser/ui/webui/settings/chromeos/apps_section.cc b/chrome/browser/ui/webui/settings/chromeos/apps_section.cc index 198de983..7ae2a6a 100644 --- a/chrome/browser/ui/webui/settings/chromeos/apps_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/apps_section.cc
@@ -6,9 +6,12 @@ #include "base/no_destructor.h" #include "chrome/browser/chromeos/arc/arc_util.h" +#include "chrome/browser/chromeos/plugin_vm/plugin_vm_pref_names.h" +#include "chrome/browser/chromeos/plugin_vm/plugin_vm_util.h" #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" #include "chrome/browser/ui/webui/app_management/app_management_page_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/android_apps_handler.h" +#include "chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" #include "chrome/browser/ui/webui/webui_util.h" #include "chrome/common/url_constants.h" @@ -116,6 +119,7 @@ {"appManagementNotificationsLabel", IDS_APP_MANAGEMENT_NOTIFICATIONS}, {"appManagementPermissionsLabel", IDS_APP_MANAGEMENT_PERMISSIONS}, {"appManagementPinToShelfLabel", IDS_APP_MANAGEMENT_PIN_TO_SHELF}, + {"appManagementPrintingPermissionLabel", IDS_APP_MANAGEMENT_PRINTING}, {"appManagementSearchPrompt", IDS_APP_MANAGEMENT_SEARCH_PROMPT}, {"appManagementStoragePermissionLabel", IDS_APP_MANAGEMENT_STORAGE}, {"appManagementUninstallLabel", IDS_APP_MANAGEMENT_UNINSTALL_APP}, @@ -123,6 +127,13 @@ AddLocalizedStringsBulk(html_source, kLocalizedStrings); } +bool ShowPluginVm(const Profile* profile, const PrefService& pref_service) { + // Even if not allowed, we still want to show Plugin VM if the VM image is on + // disk, so that users are still able to delete the image at will. + return plugin_vm::IsPluginVmAllowedForProfile(profile) || + pref_service.GetBoolean(plugin_vm::prefs::kPluginVmImageExists); +} + } // namespace AppsSection::AppsSection(Profile* profile, @@ -196,11 +207,17 @@ AddAppManagementStrings(html_source); AddAndroidAppStrings(html_source); + AddPluginVmLoadTimeData(html_source); } void AppsSection::AddHandlers(content::WebUI* web_ui) { web_ui->AddMessageHandler( std::make_unique<chromeos::settings::AndroidAppsHandler>(profile())); + + if (ShowPluginVm(profile(), *pref_service_)) { + web_ui->AddMessageHandler( + std::make_unique<chromeos::settings::PluginVmHandler>(profile())); + } } void AppsSection::OnAppRegistered(const std::string& app_id, @@ -235,6 +252,25 @@ GetHelpUrlWithBoard(chrome::kAndroidAppsLearnMoreURL))); } +void AppsSection::AddPluginVmLoadTimeData( + content::WebUIDataSource* html_source) { + static constexpr webui::LocalizedString kLocalizedStrings[] = { + {"pluginVmSharedPaths", IDS_SETTINGS_APPS_PLUGIN_VM_SHARED_PATHS}, + {"pluginVmSharedPathsListHeading", + IDS_SETTINGS_APPS_PLUGIN_VM_SHARED_PATHS_LIST_HEADING}, + {"pluginVmSharedPathsInstructionsAdd", + IDS_SETTINGS_APPS_PLUGIN_VM_SHARED_PATHS_INSTRUCTIONS_ADD}, + {"pluginVmSharedPathsInstructionsRemove", + IDS_SETTINGS_APPS_PLUGIN_VM_SHARED_PATHS_INSTRUCTIONS_REMOVE}, + {"pluginVmSharedPathsRemoveSharing", + IDS_SETTINGS_APPS_PLUGIN_VM_SHARED_PATHS_REMOVE_SHARING}, + }; + AddLocalizedStringsBulk(html_source, kLocalizedStrings); + + html_source->AddBoolean("showPluginVm", + ShowPluginVm(profile(), *pref_service_)); +} + void AppsSection::UpdateAndroidSearchTags() { registry()->RemoveSearchTags(GetAndroidNoPlayStoreSearchConcepts()); registry()->RemoveSearchTags(GetAndroidPlayStoreDisabledSearchConcepts());
diff --git a/chrome/browser/ui/webui/settings/chromeos/apps_section.h b/chrome/browser/ui/webui/settings/chromeos/apps_section.h index 3cb8a66..ba926ba1 100644 --- a/chrome/browser/ui/webui/settings/chromeos/apps_section.h +++ b/chrome/browser/ui/webui/settings/chromeos/apps_section.h
@@ -39,6 +39,7 @@ const ArcAppListPrefs::AppInfo& app_info) override; void AddAndroidAppStrings(content::WebUIDataSource* html_source); + void AddPluginVmLoadTimeData(content::WebUIDataSource* html_source); void UpdateAndroidSearchTags();
diff --git a/chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom b/chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom index 17f9439..b183749 100644 --- a/chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom +++ b/chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom
@@ -17,7 +17,8 @@ kSearchAndAssistant = 6, kApps = 7, kCrostini = 8, - kPluginVm = 9, + // Note: Value 9 was for deprecated Plugin VM section - see + // https://crbug.com/1074101. Do not reuse. kDateAndTime = 10, kPrivacyAndSecurity = 11, kLanguagesAndInput = 12, @@ -81,6 +82,7 @@ kAppManagement = 700, kAppDetails = 701, kGooglePlayStore = 702, + kPluginVmSharedPaths = 703, // Crostini section. kCrostiniDetails = 800, @@ -91,9 +93,7 @@ kCrostiniPortForwarding = 805, kCrostiniDiskResize = 806, - // Plugin VM section. - kPluginVmDetails = 900, - kPluginVmSharedPaths = 901, + // Note: Deprecated Plugin VM section has no subpages. // Date and Time section. kTimeZone = 1000, @@ -180,6 +180,8 @@ const string kAppManagementSubpagePath = "app-management"; const string kAppDetailsSubpagePath = "app-management/detail"; const string kGooglePlayStoreSubpagePath = "androidAppsDetails"; +const string kPluginVmSharedPathsSubpagePath = + "app-management/pluginVm/sharedPaths"; // Crostini section. const string kCrostiniSectionPath = "crostini"; @@ -191,11 +193,6 @@ const string kCrostiniPortForwardingSubpagePath = "crostini/portForwarding"; const string kCrostiniDiskResizeSubpagePath = "crostini/diskResize"; -// Plugin VM section. -const string kPluginVmSectionPath = "pluginVm"; -const string kPluginVmDetailsSubpagePath = "pluginVm/details"; -const string kPluginVmSharedPathsSubpagePath = "pluginVm/sharedPaths"; - // Date and Time section. const string kDateAndTimeSectionPath = "dateTime"; const string kTimeZoneSubpagePath = "dateTime/timeZone"; @@ -231,4 +228,4 @@ // About Chrome OS section. const string kAboutChromeOsSectionPath = "help"; const string kAboutChromeOsDetailsSubpagePath = "help/about"; -const string kDetailedBuildInfoSubpagePath = "help/details"; \ No newline at end of file +const string kDetailedBuildInfoSubpagePath = "help/details";
diff --git a/chrome/browser/ui/webui/settings/chromeos/constants/routes_util.cc b/chrome/browser/ui/webui/settings/chromeos/constants/routes_util.cc index 47bec3d9..957b28fd 100644 --- a/chrome/browser/ui/webui/settings/chromeos/constants/routes_util.cc +++ b/chrome/browser/ui/webui/settings/chromeos/constants/routes_util.cc
@@ -72,6 +72,7 @@ chromeos::settings::mojom::kAppManagementSubpagePath, chromeos::settings::mojom::kAppDetailsSubpagePath, chromeos::settings::mojom::kGooglePlayStoreSubpagePath, + chromeos::settings::mojom::kPluginVmSharedPathsSubpagePath, // Crostini section. chromeos::settings::mojom::kCrostiniSectionPath, @@ -83,11 +84,6 @@ chromeos::settings::mojom::kCrostiniPortForwardingSubpagePath, chromeos::settings::mojom::kCrostiniDiskResizeSubpagePath, - // Plugin VM section. - chromeos::settings::mojom::kPluginVmSectionPath, - chromeos::settings::mojom::kPluginVmDetailsSubpagePath, - chromeos::settings::mojom::kPluginVmSharedPathsSubpagePath, - // Date and Time section. chromeos::settings::mojom::kDateAndTimeSectionPath, chromeos::settings::mojom::kTimeZoneSubpagePath,
diff --git a/chrome/browser/ui/webui/settings/chromeos/internet_section.cc b/chrome/browser/ui/webui/settings/chromeos/internet_section.cc index 39afbae20..c21b000 100644 --- a/chrome/browser/ui/webui/settings/chromeos/internet_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/internet_section.cc
@@ -538,6 +538,17 @@ html_source->AddString("networkGoogleNameserversLearnMoreUrl", chrome::kGoogleNameserversLearnMoreURL); + + html_source->AddString( + "networkSyncedShared", + l10n_util::GetStringFUTF16( + IDS_SETTINGS_INTERNET_NETWORK_SYNCED_SHARED, + GetHelpUrlWithBoard(chrome::kWifiSyncLearnMoreURL))); + html_source->AddString( + "networkSyncedUser", + l10n_util::GetStringFUTF16( + IDS_SETTINGS_INTERNET_NETWORK_SYNCED_USER, + GetHelpUrlWithBoard(chrome::kWifiSyncLearnMoreURL))); html_source->AddString( "internetNoNetworksMobileData", l10n_util::GetStringFUTF16(
diff --git a/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.cc b/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.cc index 3c212395..6239b24 100644 --- a/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.cc +++ b/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.cc
@@ -19,7 +19,6 @@ #include "chrome/browser/ui/webui/settings/chromeos/multidevice_section.h" #include "chrome/browser/ui/webui/settings/chromeos/people_section.h" #include "chrome/browser/ui/webui/settings/chromeos/personalization_section.h" -#include "chrome/browser/ui/webui/settings/chromeos/plugin_vm_section.h" #include "chrome/browser/ui/webui/settings/chromeos/printing_section.h" #include "chrome/browser/ui/webui/settings/chromeos/privacy_section.h" #include "chrome/browser/ui/webui/settings/chromeos/reset_section.h" @@ -91,11 +90,6 @@ sections_map_[mojom::Section::kCrostini] = crostini_section.get(); sections_.push_back(std::move(crostini_section)); - auto plugin_vm_section = std::make_unique<PluginVmSection>( - profile, search_tag_registry, profile->GetPrefs()); - sections_map_[mojom::Section::kPluginVm] = plugin_vm_section.get(); - sections_.push_back(std::move(plugin_vm_section)); - auto date_time_section = std::make_unique<DateTimeSection>(profile, search_tag_registry); sections_map_[mojom::Section::kDateAndTime] = date_time_section.get();
diff --git a/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc b/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc index 76d33751..97f2eeab 100644 --- a/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc +++ b/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc
@@ -8,13 +8,10 @@ #include "ash/public/cpp/network_config_service.h" #include "base/metrics/histogram_functions.h" -#include "chrome/browser/chromeos/plugin_vm/plugin_vm_pref_names.h" -#include "chrome/browser/chromeos/plugin_vm/plugin_vm_util.h" #include "chrome/browser/ui/webui/managed_ui_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/os_settings_manager.h" #include "chrome/browser/ui/webui/settings/chromeos/os_settings_manager_factory.h" -#include "chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/pref_names.h" #include "chrome/browser/ui/webui/settings/chromeos/search/search_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker.h" @@ -58,13 +55,6 @@ manager->AddHandlers(web_ui); manager->AddLoadTimeData(html_source); - // TODO(https://crbug.com/1074101): Move to AppsSections::AddHandler(). - if (plugin_vm::IsPluginVmAllowedForProfile(profile) || - profile->GetPrefs()->GetBoolean(plugin_vm::prefs::kPluginVmImageExists)) { - web_ui->AddMessageHandler( - std::make_unique<chromeos::settings::PluginVmHandler>(profile)); - } - // TODO(khorimoto): Move to DeviceSection::AddHandler() once |html_source| // parameter is removed. web_ui->AddMessageHandler( @@ -82,7 +72,7 @@ webui::SetupWebUIDataSource( html_source, base::make_span(kOsSettingsResources, kOsSettingsResourcesSize), - kOsGeneratedPath, IDR_OS_SETTINGS_SETTINGS_V3_HTML); + kOsGeneratedPath, IDR_OS_SETTINGS_SETTINGS_HTML); #endif ManagedUIHandler::Initialize(web_ui, html_source);
diff --git a/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.cc b/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.cc index 86f3e42..715782b 100644 --- a/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.cc
@@ -12,9 +12,6 @@ #include "base/bind_helpers.h" #include "chrome/browser/chromeos/file_manager/path_util.h" #include "chrome/browser/chromeos/guest_os/guest_os_share_path.h" -#include "chrome/browser/chromeos/plugin_vm/plugin_vm_manager.h" -#include "chrome/browser/chromeos/plugin_vm/plugin_vm_manager_factory.h" -#include "chrome/browser/chromeos/plugin_vm/plugin_vm_util.h" #include "chrome/browser/profiles/profile.h" #include "content/public/browser/browser_thread.h" @@ -35,14 +32,6 @@ "removePluginVmSharedPath", base::BindRepeating(&PluginVmHandler::HandleRemovePluginVmSharedPath, weak_ptr_factory_.GetWeakPtr())); - web_ui()->RegisterMessageCallback( - "removePluginVm", - base::BindRepeating(&PluginVmHandler::HandleRemovePluginVm, - weak_ptr_factory_.GetWeakPtr())); - web_ui()->RegisterMessageCallback( - "requestPluginVmInstallerView", - base::BindRepeating(&PluginVmHandler::HandleRequestPluginVmInstallerView, - weak_ptr_factory_.GetWeakPtr())); } void PluginVmHandler::HandleGetPluginVmSharedPathsDisplayText( @@ -79,28 +68,5 @@ path)); } -void PluginVmHandler::HandleRemovePluginVm(const base::ListValue* args) { - CHECK_EQ(0U, args->GetSize()); - - auto* manager = plugin_vm::PluginVmManagerFactory::GetForProfile(profile_); - if (!manager) { - LOG(ERROR) << "removePluginVm called from an invalid profile."; - return; - } - manager->UninstallPluginVm(); -} - -void PluginVmHandler::HandleRequestPluginVmInstallerView( - const base::ListValue* args) { - CHECK(args->empty()); - - if (plugin_vm::IsPluginVmEnabled(profile_)) { - LOG(ERROR) << "requestPluginVmInstallerView called from a profile which " - "already has Plugin VM installed."; - return; - } - plugin_vm::ShowPluginVmInstallerView(profile_); -} - } // namespace settings } // namespace chromeos
diff --git a/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.h b/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.h index b003a9e3..d57b34da 100644 --- a/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.h +++ b/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.h
@@ -32,10 +32,6 @@ void HandleGetPluginVmSharedPathsDisplayText(const base::ListValue* args); // Remove a specified path from being shared. void HandleRemovePluginVmSharedPath(const base::ListValue* args); - // Remove Plugin VM. - void HandleRemovePluginVm(const base::ListValue* args); - // Show the Plugin VM installer view if Plugin VM is not currently installed. - void HandleRequestPluginVmInstallerView(const base::ListValue* args); Profile* profile_; // weak_ptr_factory_ should always be last member.
diff --git a/chrome/browser/ui/webui/settings/chromeos/plugin_vm_section.cc b/chrome/browser/ui/webui/settings/chromeos/plugin_vm_section.cc deleted file mode 100644 index a83f6627..0000000 --- a/chrome/browser/ui/webui/settings/chromeos/plugin_vm_section.cc +++ /dev/null
@@ -1,69 +0,0 @@ -// 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/webui/settings/chromeos/plugin_vm_section.h" - -#include "base/feature_list.h" -#include "chrome/browser/chromeos/plugin_vm/plugin_vm_pref_names.h" -#include "chrome/browser/chromeos/plugin_vm/plugin_vm_util.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" -#include "chrome/browser/ui/webui/webui_util.h" -#include "chrome/grit/generated_resources.h" -#include "chromeos/constants/chromeos_features.h" -#include "components/prefs/pref_service.h" -#include "content/public/browser/web_ui_data_source.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/webui/web_ui_util.h" - -namespace chromeos { -namespace settings { - -PluginVmSection::PluginVmSection(Profile* profile, - SearchTagRegistry* search_tag_registry, - PrefService* pref_service) - : OsSettingsSection(profile, search_tag_registry), - pref_service_(pref_service) {} - -PluginVmSection::~PluginVmSection() = default; - -void PluginVmSection::AddLoadTimeData(content::WebUIDataSource* html_source) { - static constexpr webui::LocalizedString kLocalizedStrings[] = { - {"pluginVmPageTitle", IDS_SETTINGS_PLUGIN_VM_PAGE_TITLE}, - {"pluginVmPageLabel", IDS_SETTINGS_PLUGIN_VM_PAGE_LABEL}, - {"pluginVmPageSubtext", IDS_SETTINGS_PLUGIN_VM_PAGE_SUBTEXT}, - {"pluginVmPageEnable", IDS_SETTINGS_TURN_ON}, - {"pluginVmPrinterAccess", IDS_SETTINGS_PLUGIN_VM_PRINTER_ACCESS}, - {"pluginVmSharedPaths", IDS_SETTINGS_PLUGIN_VM_SHARED_PATHS}, - {"pluginVmSharedPathsListHeading", - IDS_SETTINGS_PLUGIN_VM_SHARED_PATHS_LIST_HEADING}, - {"pluginVmSharedPathsInstructionsAdd", - IDS_SETTINGS_PLUGIN_VM_SHARED_PATHS_INSTRUCTIONS_ADD}, - {"pluginVmSharedPathsInstructionsRemove", - IDS_SETTINGS_PLUGIN_VM_SHARED_PATHS_INSTRUCTIONS_REMOVE}, - {"pluginVmSharedPathsRemoveSharing", - IDS_SETTINGS_PLUGIN_VM_SHARED_PATHS_REMOVE_SHARING}, - {"pluginVmRemove", IDS_SETTINGS_PLUGIN_VM_REMOVE_LABEL}, - {"pluginVmRemoveButton", IDS_SETTINGS_PLUGIN_VM_REMOVE_BUTTON}, - {"pluginVmRemoveConfirmationDialogMessage", - IDS_SETTINGS_PLUGIN_VM_CONFIRM_REMOVE_DIALOG_BODY}, - {"pluginVmCameraAccessTitle", IDS_SETTINGS_PLUGIN_VM_CAMERA_ACCESS_TITLE}, - }; - AddLocalizedStringsBulk(html_source, kLocalizedStrings); - html_source->AddBoolean( - "showPluginVmCamera", - base::FeatureList::IsEnabled(features::kPluginVmShowCameraSetting)); - - // If |!allow_plugin_vm| we still want to |show_plugin_vm| if the VM image is - // on disk, so that users are still able to delete the image at will. - const bool allow_plugin_vm = - plugin_vm::IsPluginVmAllowedForProfile(profile()); - html_source->AddBoolean("allowPluginVm", allow_plugin_vm); - html_source->AddBoolean( - "showPluginVm", - allow_plugin_vm || - pref_service_->GetBoolean(plugin_vm::prefs::kPluginVmImageExists)); -} - -} // namespace settings -} // namespace chromeos
diff --git a/chrome/browser/ui/webui/settings/chromeos/plugin_vm_section.h b/chrome/browser/ui/webui/settings/chromeos/plugin_vm_section.h deleted file mode 100644 index c0b3e84..0000000 --- a/chrome/browser/ui/webui/settings/chromeos/plugin_vm_section.h +++ /dev/null
@@ -1,43 +0,0 @@ -// 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_WEBUI_SETTINGS_CHROMEOS_PLUGIN_VM_SECTION_H_ -#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_PLUGIN_VM_SECTION_H_ - -#include "chrome/browser/ui/webui/settings/chromeos/os_settings_section.h" - -class PrefService; - -namespace content { -class WebUIDataSource; -} // namespace content - -namespace chromeos { -namespace settings { - -class SearchTagRegistry; - -// Provides UI strings for Plugin VM settings. This class class does not provide -// search tags, since this section will be removed eventually. -// -// TODO(https://crbug.com/1074101): Remove this class when the Plugin VM section -// of settings no longer exists. -class PluginVmSection : public OsSettingsSection { - public: - PluginVmSection(Profile* profile, - SearchTagRegistry* search_tag_registry, - PrefService* pref_service); - ~PluginVmSection() override; - - private: - // OsSettingsSection: - void AddLoadTimeData(content::WebUIDataSource* html_source) override; - - PrefService* pref_service_; -}; - -} // namespace settings -} // namespace chromeos - -#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_PLUGIN_VM_SECTION_H_
diff --git a/chrome/browser/ui/webui/tab_strip/tab_strip_ui_util.cc b/chrome/browser/ui/webui/tab_strip/tab_strip_ui_util.cc index a734a70e..6ed805a0 100644 --- a/chrome/browser/ui/webui/tab_strip/tab_strip_ui_util.cc +++ b/chrome/browser/ui/webui/tab_strip/tab_strip_ui_util.cc
@@ -4,6 +4,10 @@ #include "chrome/browser/ui/webui/tab_strip/tab_strip_ui_util.h" +#include <memory> +#include <string> +#include <utility> + #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/extensions/extension_tab_util.h" @@ -72,12 +76,37 @@ to_index, std::move(detached_contents), add_types, to_group_id); } +bool IsDraggedTab(const ui::OSExchangeData& drop_data) { + base::Pickle pickle; + drop_data.GetPickledData(ui::ClipboardFormatType::GetWebCustomDataType(), + &pickle); + base::PickleIterator iter(pickle); + + uint32_t entry_count = 0; + if (!iter.ReadUInt32(&entry_count)) + return false; + + for (uint32_t i = 0; i < entry_count; ++i) { + base::StringPiece16 type; + base::StringPiece16 data; + if (!iter.ReadStringPiece16(&type) || !iter.ReadStringPiece16(&data)) + return false; + + // TODO(https://crbug.com/1069869): handle tab group drags. + if (type == base::ASCIIToUTF16(kWebUITabIdDataType)) + return true; + } + + return false; +} + bool DropTabsInNewBrowser(Browser* new_browser, const ui::OSExchangeData& drop_data) { base::Pickle pickle; drop_data.GetPickledData(ui::ClipboardFormatType::GetWebCustomDataType(), &pickle); + // TODO(https://crbug.com/1069869): handle tab group drags. base::string16 tab_id_str; ui::ReadCustomDataForType(pickle.data(), pickle.size(), base::ASCIIToUTF16(kWebUITabIdDataType),
diff --git a/chrome/browser/ui/webui/tab_strip/tab_strip_ui_util.h b/chrome/browser/ui/webui/tab_strip/tab_strip_ui_util.h index 282a75b..fcffd488b1 100644 --- a/chrome/browser/ui/webui/tab_strip/tab_strip_ui_util.h +++ b/chrome/browser/ui/webui/tab_strip/tab_strip_ui_util.h
@@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_UI_WEBUI_TAB_STRIP_TAB_STRIP_UI_UTIL_H_ #define CHROME_BROWSER_UI_WEBUI_TAB_STRIP_TAB_STRIP_UI_UTIL_H_ +#include <string> + #include "base/optional.h" #include "components/tab_groups/tab_group_id.h" @@ -31,6 +33,10 @@ int to_index, base::Optional<tab_groups::TabGroupId> to_group_id = base::nullopt); +// Returns whether |drop_data| is a tab drag originating from a WebUI +// tab strip. +bool IsDraggedTab(const ui::OSExchangeData& drop_data); + // Handles dropping tabs not destined for an existing tab strip. // |new_browser| should be the newly created Browser with no tabs, and // must have the same profile as the drag source. |drop_data| must have
diff --git a/chrome/browser/ui/webui/test_data_source.cc b/chrome/browser/ui/webui/test_data_source.cc index 43d7f40..35e02e8 100644 --- a/chrome/browser/ui/webui/test_data_source.cc +++ b/chrome/browser/ui/webui/test_data_source.cc
@@ -80,6 +80,10 @@ return "script-src chrome://* 'self';"; } +std::string TestDataSource::GetContentSecurityPolicyWorkerSrc() { + return "worker-src blob: 'self';"; +} + GURL TestDataSource::GetURLForPath(const std::string& path) { return GURL(std::string(content::kChromeUIScheme) + "://" + GetSource() + "/" + path);
diff --git a/chrome/browser/ui/webui/test_data_source.h b/chrome/browser/ui/webui/test_data_source.h index f65809d..33990d62 100644 --- a/chrome/browser/ui/webui/test_data_source.h +++ b/chrome/browser/ui/webui/test_data_source.h
@@ -34,6 +34,8 @@ std::string GetContentSecurityPolicyScriptSrc() override; + std::string GetContentSecurityPolicyWorkerSrc() override; + GURL GetURLForPath(const std::string& path); void ReadFile(const std::string& path,
diff --git a/chrome/browser/ui/webui/theme_source.cc b/chrome/browser/ui/webui/theme_source.cc index fbce24c8..060ba3f 100644 --- a/chrome/browser/ui/webui/theme_source.cc +++ b/chrome/browser/ui/webui/theme_source.cc
@@ -72,12 +72,17 @@ //////////////////////////////////////////////////////////////////////////////// // ThemeSource, public: -ThemeSource::ThemeSource(Profile* profile) : profile_(profile) {} +ThemeSource::ThemeSource(Profile* profile) + : profile_(profile), serve_untrusted_(false) {} + +ThemeSource::ThemeSource(Profile* profile, bool serve_untrusted) + : profile_(profile), serve_untrusted_(serve_untrusted) {} ThemeSource::~ThemeSource() = default; std::string ThemeSource::GetSource() { - return chrome::kChromeUIThemeHost; + return serve_untrusted_ ? chrome::kChromeUIUntrustedThemeURL + : chrome::kChromeUIThemeHost; } void ThemeSource::StartDataRequest(
diff --git a/chrome/browser/ui/webui/theme_source.h b/chrome/browser/ui/webui/theme_source.h index 281f8d7..aaf58a1 100644 --- a/chrome/browser/ui/webui/theme_source.h +++ b/chrome/browser/ui/webui/theme_source.h
@@ -18,6 +18,7 @@ class ThemeSource : public content::URLDataSource { public: explicit ThemeSource(Profile* profile); + ThemeSource(Profile* profile, bool serve_untrusted); ~ThemeSource() override; // content::URLDataSource implementation. @@ -50,6 +51,9 @@ // The profile this object was initialized with. Profile* profile_; + // Whether this source services chrome-unstrusted://theme. + bool serve_untrusted_; + DISALLOW_COPY_AND_ASSIGN(ThemeSource); };
diff --git a/chrome/browser/web_applications/components/app_registrar.cc b/chrome/browser/web_applications/components/app_registrar.cc index 4649eb2..3b85196 100644 --- a/chrome/browser/web_applications/components/app_registrar.cc +++ b/chrome/browser/web_applications/components/app_registrar.cc
@@ -53,6 +53,13 @@ RecordWebAppUninstallation(profile()->GetPrefs(), app_id); } +void AppRegistrar::NotifyWebAppLocallyInstalledStateChanged( + const AppId& app_id, + bool is_locally_installed) { + for (AppRegistrarObserver& observer : observers_) + observer.OnWebAppLocallyInstalledStateChanged(app_id, is_locally_installed); +} + void AppRegistrar::NotifyWebAppDisabledStateChanged(const AppId& app_id, bool is_disabled) { for (AppRegistrarObserver& observer : observers_)
diff --git a/chrome/browser/web_applications/components/app_registrar.h b/chrome/browser/web_applications/components/app_registrar.h index af90599..184cd6928 100644 --- a/chrome/browser/web_applications/components/app_registrar.h +++ b/chrome/browser/web_applications/components/app_registrar.h
@@ -151,6 +151,8 @@ void NotifyWebAppInstalled(const AppId& app_id); void NotifyWebAppUninstalled(const AppId& app_id); + void NotifyWebAppLocallyInstalledStateChanged(const AppId& app_id, + bool is_locally_installed); void NotifyWebAppDisabledStateChanged(const AppId& app_id, bool is_disabled); protected:
diff --git a/chrome/browser/web_applications/components/app_registrar_observer.h b/chrome/browser/web_applications/components/app_registrar_observer.h index b9cb3ae5..fa2c045 100644 --- a/chrome/browser/web_applications/components/app_registrar_observer.h +++ b/chrome/browser/web_applications/components/app_registrar_observer.h
@@ -27,6 +27,10 @@ virtual void OnAppRegistrarDestroyed() {} + virtual void OnWebAppLocallyInstalledStateChanged(const AppId& app_id, + bool is_locally_installed) { + } + // The disabled status WebApp::chromeos_data().is_disabled of the app backing // |app_id| is updated. Sometimes OnWebAppDisabledStateChanged is called but // WebApp::chromos_data().is_disabled isn't updated yet, that's why it's
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_registry_controller.cc b/chrome/browser/web_applications/extensions/bookmark_app_registry_controller.cc index 5501e87..896404b 100644 --- a/chrome/browser/web_applications/extensions/bookmark_app_registry_controller.cc +++ b/chrome/browser/web_applications/extensions/bookmark_app_registry_controller.cc
@@ -85,6 +85,8 @@ bool is_locally_installed) { SetBookmarkAppIsLocallyInstalled(profile(), GetExtension(app_id), is_locally_installed); + registrar_->NotifyWebAppLocallyInstalledStateChanged(app_id, + is_locally_installed); } web_app::WebAppSyncBridge* BookmarkAppRegistryController::AsWebAppSyncBridge() {
diff --git a/chrome/browser/web_applications/system_web_app_manager.cc b/chrome/browser/web_applications/system_web_app_manager.cc index 06388b2..99bb4b5 100644 --- a/chrome/browser/web_applications/system_web_app_manager.cc +++ b/chrome/browser/web_applications/system_web_app_manager.cc
@@ -121,6 +121,7 @@ SystemAppInfo("Help", GURL("chrome://help-app/pwa.html"))); infos.at(SystemAppType::HELP).additional_search_terms = { IDS_GENIUS_APP_NAME, IDS_HELP_APP_PERKS, IDS_HELP_APP_OFFERS}; + infos.at(SystemAppType::HELP).minimum_window_size = {600, 320}; } if (SystemWebAppManager::IsAppEnabled(SystemAppType::MEDIA)) {
diff --git a/chrome/browser/web_applications/web_app.cc b/chrome/browser/web_applications/web_app.cc index 1f63cb9..b31756f 100644 --- a/chrome/browser/web_applications/web_app.cc +++ b/chrome/browser/web_applications/web_app.cc
@@ -194,7 +194,7 @@ const WebAppShortcutMenuItemInfo& other) = default; WebApp::WebAppShortcutMenuItemInfo::WebAppShortcutMenuItemInfo( - WebAppShortcutMenuItemInfo&&) = default; + WebAppShortcutMenuItemInfo&&) noexcept = default; WebApp::WebAppShortcutMenuItemInfo::~WebAppShortcutMenuItemInfo() = default; @@ -203,8 +203,8 @@ const WebAppShortcutMenuItemInfo&) = default; WebApp::WebAppShortcutMenuItemInfo& -WebApp::WebAppShortcutMenuItemInfo::operator=(WebAppShortcutMenuItemInfo&&) = - default; +WebApp::WebAppShortcutMenuItemInfo::operator=( + WebAppShortcutMenuItemInfo&&) noexcept = default; void WebApp::SetSyncData(SyncData sync_data) { sync_data_ = std::move(sync_data);
diff --git a/chrome/browser/web_applications/web_app_sync_bridge.cc b/chrome/browser/web_applications/web_app_sync_bridge.cc index 087ba496..51fc591 100644 --- a/chrome/browser/web_applications/web_app_sync_bridge.cc +++ b/chrome/browser/web_applications/web_app_sync_bridge.cc
@@ -197,10 +197,14 @@ void WebAppSyncBridge::SetAppIsLocallyInstalled(const AppId& app_id, bool is_locally_installed) { - ScopedRegistryUpdate update(this); - WebApp* web_app = update->UpdateApp(app_id); - if (web_app) - web_app->SetIsLocallyInstalled(is_locally_installed); + { + ScopedRegistryUpdate update(this); + WebApp* web_app = update->UpdateApp(app_id); + if (web_app) + web_app->SetIsLocallyInstalled(is_locally_installed); + } + registrar_->NotifyWebAppLocallyInstalledStateChanged(app_id, + is_locally_installed); } WebAppSyncBridge* WebAppSyncBridge::AsWebAppSyncBridge() {
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index a584ed7c..84816c5e 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -19,6 +19,8 @@ #if defined(OS_ANDROID) const base::Feature kAddToHomescreenMessaging{ "AddToHomescreenMessaging", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kAndroidDarkSearch{"AndroidDarkSearch", + base::FEATURE_DISABLED_BY_DEFAULT}; #endif // defined(OS_ANDROID) #if defined(OS_CHROMEOS)
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h index 925fea19..9a381f69 100644 --- a/chrome/common/chrome_features.h +++ b/chrome/common/chrome_features.h
@@ -29,6 +29,8 @@ #if defined(OS_ANDROID) COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kAddToHomescreenMessaging; +COMPONENT_EXPORT(CHROME_FEATURES) +extern const base::Feature kAndroidDarkSearch; #endif // defined(OS_ANDROID) #if defined(OS_CHROMEOS)
diff --git a/chrome/common/extensions/extension_constants.cc b/chrome/common/extensions/extension_constants.cc index f900b80..5a9b8ed 100644 --- a/chrome/common/extensions/extension_constants.cc +++ b/chrome/common/extensions/extension_constants.cc
@@ -41,7 +41,6 @@ const char kHTermAppId[] = "pnhechapfaindjhompbnflcldabbghjo"; const char kHTermDevAppId[] = "okddffdblfhhnmhodogpojmfkjmhinfp"; const char kIdentityApiUiAppId[] = "ahjaciijnoiaklcomgnblndopackapon"; -const char kCroshBuiltinAppId[] = "nkoccljplnhpfnfiajclkommnmllphnl"; const char kTextEditorAppId[] = "mmfbcljfglbokpmkimbfghdkjmjhdgbg"; const char kInAppPaymentsSupportAppId[] = "nmmhkkegccagdldgiimedpiccmgmieda"; const char kMediaRouterStableExtensionId[] = "pkedcjkdefgpdelpbcmbmeomcjbeemfm"; @@ -68,7 +67,6 @@ kHTermAppId, kHTermDevAppId, kIdentityApiUiAppId, - kCroshBuiltinAppId, kTextEditorAppId, kInAppPaymentsSupportAppId, kMediaRouterStableExtensionId,
diff --git a/chrome/common/extensions/extension_constants.h b/chrome/common/extensions/extension_constants.h index fd6fe7ce..09804e3 100644 --- a/chrome/common/extensions/extension_constants.h +++ b/chrome/common/extensions/extension_constants.h
@@ -90,9 +90,6 @@ // The extension id of the Identity API UI application. extern const char kIdentityApiUiAppId[]; -// The extension id of the Crosh component app for ChromeOS. -extern const char kCroshBuiltinAppId[]; - // The extension id of the Text Editor application. extern const char kTextEditorAppId[];
diff --git a/chrome/common/media_router/media_source.h b/chrome/common/media_router/media_source.h index 59f7c43..edf2111 100644 --- a/chrome/common/media_router/media_source.h +++ b/chrome/common/media_router/media_source.h
@@ -48,20 +48,32 @@ // Returns true if |presentation_id| is an ID used by auto-join requests. bool IsAutoJoinPresentationId(const std::string& presentation_id); +// A media source specifier, represented as an ID string and possibly a URL. +// If there is a URL, its string value with be the same as the ID string. class MediaSource { public: using Id = std::string; + // TODO(jrw): Eliminate this constructor and use optional<MediaSource> where + // needed. MediaSource(); + + // Create from an arbitrary string, which may or may not be a presentation + // URL. explicit MediaSource(const MediaSource::Id& id); + + // Create from a URL which is assumed to be a presentation URL. If + // |presentation_url| is not a valid presentation URL, the resulting object's + // IsValid() method will return false. explicit MediaSource(const GURL& presentation_url); + ~MediaSource(); // Gets the ID of the media source. const Id& id() const { return id_; } - // If MediaSource is created from a URL, return the URL; otherwise return an - // empty GURL. + // If the source ID is a presentation URL, returns the URL; otherwise returns + // an empty GURL. const GURL& url() const { return url_; } // Returns true if two MediaSource objects use the same media ID.
diff --git a/chrome/common/media_router/providers/cast/cast_media_source.cc b/chrome/common/media_router/providers/cast/cast_media_source.cc index 9739b57..97002d0 100644 --- a/chrome/common/media_router/providers/cast/cast_media_source.cc +++ b/chrome/common/media_router/providers/cast/cast_media_source.cc
@@ -210,7 +210,8 @@ const std::string& broadcast_namespace, const std::string& encoded_broadcast_message, const std::string& launch_timeout_str, - const std::vector<ReceiverAppType>& supported_app_types) { + const std::vector<ReceiverAppType>& supported_app_types, + const std::string& app_params) { if (app_infos.empty()) return nullptr; @@ -233,9 +234,9 @@ base::TimeDelta::FromMilliseconds(launch_timeout_millis)); } - if (!supported_app_types.empty()) { + if (!supported_app_types.empty()) cast_source->set_supported_app_types(supported_app_types); - } + cast_source->set_app_params(app_params); return cast_source; } @@ -258,8 +259,8 @@ FindValueOr(params, "broadcastNamespace", ""), FindValueOr(params, "broadcastMessage", ""), FindValueOr(params, "launchTimeout", ""), - SupportedAppTypesFromString( - FindValueOr(params, "supportedAppTypes", ""))); + SupportedAppTypesFromString(FindValueOr(params, "supportedAppTypes", "")), + FindValueOr(params, "appParams", "")); } std::unique_ptr<CastMediaSource> ParseLegacyCastUrl( @@ -317,7 +318,8 @@ FindValueOr(params, "__castBroadcastNamespace__", ""), FindValueOr(params, "__castBroadcastMessage__", ""), FindValueOr(params, "__castLaunchTimeout__", ""), - /* supported_app_types */ {}); + /* supported_app_types */ {}, + /* appParams */ ""); } } // namespace
diff --git a/chrome/common/media_router/providers/cast/cast_media_source.h b/chrome/common/media_router/providers/cast/cast_media_source.h index 73b5c4ff32f..09c0449 100644 --- a/chrome/common/media_router/providers/cast/cast_media_source.h +++ b/chrome/common/media_router/providers/cast/cast_media_source.h
@@ -165,6 +165,10 @@ DefaultActionPolicy default_action_policy() const { return default_action_policy_; } + const std::string& app_params() const { return app_params_; } + void set_app_params(const std::string& app_params) { + app_params_ = app_params; + } const std::vector<ReceiverAppType>& supported_app_types() const { return supported_app_types_; } @@ -180,6 +184,7 @@ std::string client_id_; base::Optional<cast_channel::BroadcastRequest> broadcast_request_; std::vector<ReceiverAppType> supported_app_types_ = {ReceiverAppType::kWeb}; + std::string app_params_; }; } // namespace media_router
diff --git a/chrome/common/media_router/providers/cast/cast_media_source_unittest.cc b/chrome/common/media_router/providers/cast/cast_media_source_unittest.cc index c3610e4..42c5c66 100644 --- a/chrome/common/media_router/providers/cast/cast_media_source_unittest.cc +++ b/chrome/common/media_router/providers/cast/cast_media_source_unittest.cc
@@ -41,6 +41,7 @@ "&launchTimeout=30000" "&autoJoinPolicy=tab_and_origin_scoped" "&defaultActionPolicy=cast_this_tab" + "&appParams=appParams" "&supportedAppTypes=ANDROID_TV,WEB"); std::unique_ptr<CastMediaSource> source = CastMediaSource::FromMediaSourceId(source_id); @@ -62,6 +63,7 @@ EXPECT_EQ(DefaultActionPolicy::kCastThisTab, source->default_action_policy()); EXPECT_EQ(ReceiverAppType::kAndroidTv, source->supported_app_types()[0]); EXPECT_EQ(ReceiverAppType::kWeb, source->supported_app_types()[1]); + EXPECT_EQ("appParams", source->app_params()); } TEST(CastMediaSourceTest, FromLegacyCastURL) {
diff --git a/chrome/common/net/x509_certificate_model_nss.cc b/chrome/common/net/x509_certificate_model_nss.cc index 5932c3a..165d6eed 100644 --- a/chrome/common/net/x509_certificate_model_nss.cc +++ b/chrome/common/net/x509_certificate_model_nss.cc
@@ -5,6 +5,7 @@ #include "chrome/common/net/x509_certificate_model_nss.h" #include <cert.h> +#include <certt.h> #include <cms.h> #include <hasht.h> #include <keyhi.h> // SECKEY_DestroyPrivateKey @@ -29,6 +30,7 @@ #include "chrome/third_party/mozilla_security_manager/nsNSSCertificate.h" #include "chrome/third_party/mozilla_security_manager/nsUsageArrayHelper.h" #include "components/url_formatter/url_formatter.h" +#include "crypto/nss_key_util.h" #include "crypto/nss_util.h" #include "crypto/scoped_nss_types.h" #include "net/cert/x509_util_nss.h" @@ -303,6 +305,14 @@ return psm::ProcessSubjectPublicKeyInfo(&cert_handle->subjectPublicKeyInfo); } +string ProcessRawSubjectPublicKeyInfo(base::span<const uint8_t> spki_der) { + crypto::ScopedCERTSubjectPublicKeyInfo spki = + crypto::DecodeSubjectPublicKeyInfoNSS(spki_der); + if (!spki) + return std::string(); + return psm::ProcessSubjectPublicKeyInfo(spki.get()); +} + string ProcessRawBitsSignatureWrap(CERTCertificate* cert_handle) { return ProcessRawBits(cert_handle->signatureWrap.signature.data, cert_handle->signatureWrap.signature.len);
diff --git a/chrome/common/net/x509_certificate_model_nss.h b/chrome/common/net/x509_certificate_model_nss.h index c3a5c24..d9f0d85 100644 --- a/chrome/common/net/x509_certificate_model_nss.h +++ b/chrome/common/net/x509_certificate_model_nss.h
@@ -10,6 +10,7 @@ #include <string> #include <vector> +#include "base/containers/span.h" #include "net/cert/cert_type.h" #include "net/cert/scoped_nss_types.h" @@ -89,8 +90,15 @@ std::string ProcessSecAlgorithmSubjectPublicKey(CERTCertificate* cert_handle); std::string ProcessSecAlgorithmSignatureWrap(CERTCertificate* cert_handle); +// Formats the public key from the X.509 SubjectPublicKeyInfo extracted from +// |cert_handle| as a string for displaying. std::string ProcessSubjectPublicKeyInfo(CERTCertificate* cert_handle); +// Parses |public_key_spki_der| as a DER-encoded X.509 SubjectPublicKeyInfo, +// then formats the public key as a string for displaying. +std::string ProcessRawSubjectPublicKeyInfo( + base::span<const uint8_t> public_key_spki_der); + std::string ProcessRawBitsSignatureWrap(CERTCertificate* cert_handle); // For host values, if they contain IDN Punycode-encoded A-labels, this will
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index b62969e..df9e9e5 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -1357,6 +1357,11 @@ const char kPrintPreviewDefaultDestinationSelectionRules[] = "printing.default_destination_selection_rules"; +#if defined(OS_WIN) && BUILDFLAG(ENABLE_PRINTING) +// An integer pref that holds the rasterization mode to use when printing. +const char kPrintRasterizationMode[] = "printing.rasterization_mode"; +#endif + #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) // A pref that sets the default destination in Print Preview to always be the // OS default printer instead of the most recently used destination.
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index d27415e..20b1def 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -16,6 +16,7 @@ #include "extensions/buildflags/buildflags.h" #include "media/media_buildflags.h" #include "ppapi/buildflags/buildflags.h" +#include "printing/buildflags/buildflags.h" #include "rlz/buildflags/buildflags.h" namespace prefs { @@ -428,6 +429,10 @@ extern const char kPrintPreviewDisabled[]; extern const char kPrintPreviewDefaultDestinationSelectionRules[]; +#if defined(OS_WIN) && BUILDFLAG(ENABLE_PRINTING) +extern const char kPrintRasterizationMode[]; +#endif + #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) extern const char kPrintPreviewUseSystemDefaultPrinter[]; extern const char kUserDataSnapshotRetentionLimit[];
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc index 6cd8a522..1376b956 100644 --- a/chrome/common/url_constants.cc +++ b/chrome/common/url_constants.cc
@@ -407,6 +407,9 @@ const char kTabletModeGesturesLearnMoreURL[] = "https://support.google.com/chromebook?p=tablet_mode_gestures"; + +const char kWifiSyncLearnMoreURL[] = + "https://support.google.com/chromebook/?p=wifisync"; #endif // defined(OS_CHROMEOS) #if defined(OS_MACOSX)
diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h index daf222cb..808ac18 100644 --- a/chrome/common/url_constants.h +++ b/chrome/common/url_constants.h
@@ -364,6 +364,9 @@ // navigation buttons in tablet mode (the buttons are hidden by default in // favour of the gestures in question). extern const char kTabletModeGesturesLearnMoreURL[]; + +// The URL for the help center article about Wi-Fi sync. +extern const char kWifiSyncLearnMoreURL[]; #endif // defined(OS_CHROMEOS) #if defined(OS_MACOSX)
diff --git a/chrome/common/web_application_info.cc b/chrome/common/web_application_info.cc index b0f9b3c..09cef123 100644 --- a/chrome/common/web_application_info.cc +++ b/chrome/common/web_application_info.cc
@@ -26,7 +26,7 @@ const WebApplicationShortcutInfo& other) = default; WebApplicationShortcutInfo::WebApplicationShortcutInfo( - WebApplicationShortcutInfo&&) = default; + WebApplicationShortcutInfo&&) noexcept = default; WebApplicationShortcutInfo::~WebApplicationShortcutInfo() = default; @@ -34,7 +34,7 @@ const WebApplicationShortcutInfo&) = default; WebApplicationShortcutInfo& WebApplicationShortcutInfo::operator=( - WebApplicationShortcutInfo&&) = default; + WebApplicationShortcutInfo&&) noexcept = default; WebApplicationInfo::WebApplicationInfo() : mobile_capable(MOBILE_CAPABLE_UNSPECIFIED),
diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_constants.cc index 9052c604..eb4f383 100644 --- a/chrome/common/webui_url_constants.cc +++ b/chrome/common/webui_url_constants.cc
@@ -157,6 +157,7 @@ const char kChromeUITermsURL[] = "chrome://terms/"; const char kChromeUIThemeHost[] = "theme"; const char kChromeUIThemeURL[] = "chrome://theme/"; +const char kChromeUIUntrustedThemeURL[] = "chrome-untrusted://theme/"; const char kChromeUIThumbnailHost2[] = "thumb2"; const char kChromeUIThumbnailHost[] = "thumb"; const char kChromeUIThumbnailListHost[] = "thumbnails";
diff --git a/chrome/common/webui_url_constants.h b/chrome/common/webui_url_constants.h index f866a8d..6d260fb19 100644 --- a/chrome/common/webui_url_constants.h +++ b/chrome/common/webui_url_constants.h
@@ -165,6 +165,7 @@ extern const char kChromeUITermsURL[]; extern const char kChromeUIThemeHost[]; extern const char kChromeUIThemeURL[]; +extern const char kChromeUIUntrustedThemeURL[]; extern const char kChromeUIThumbnailHost2[]; extern const char kChromeUIThumbnailHost[]; extern const char kChromeUIThumbnailListHost[];
diff --git a/chrome/services/printing/pdf_to_emf_converter.cc b/chrome/services/printing/pdf_to_emf_converter.cc index 08021a0..3767a24 100644 --- a/chrome/services/printing/pdf_to_emf_converter.cc +++ b/chrome/services/printing/pdf_to_emf_converter.cc
@@ -80,8 +80,12 @@ PdfToEmfConverter::~PdfToEmfConverter() = default; void PdfToEmfConverter::SetPrintMode() { - chrome_pdf::SetPDFUseGDIPrinting(pdf_render_settings_.mode == - PdfRenderSettings::Mode::GDI_TEXT); + bool use_gdi_printing = + pdf_render_settings_.mode == PdfRenderSettings::Mode::GDI_TEXT || + pdf_render_settings_.mode == + PdfRenderSettings::Mode::EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT; + chrome_pdf::SetPDFUseGDIPrinting(use_gdi_printing); + int printing_mode; switch (pdf_render_settings_.mode) { case PdfRenderSettings::Mode::TEXTONLY: @@ -93,8 +97,11 @@ case PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3: printing_mode = chrome_pdf::PrintingMode::kPostScript3; break; + case PdfRenderSettings::Mode::EMF_WITH_REDUCED_RASTERIZATION: + case PdfRenderSettings::Mode::EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT: + printing_mode = chrome_pdf::PrintingMode::kEmfWithReducedRasterization; + break; default: - // Not using postscript or text only. printing_mode = chrome_pdf::PrintingMode::kEmf; } chrome_pdf::SetPDFUsePrintMode(printing_mode);
diff --git a/chrome/services/printing/public/mojom/pdf_render_settings.mojom b/chrome/services/printing/public/mojom/pdf_render_settings.mojom index 518a3687..4a7f379d 100644 --- a/chrome/services/printing/public/mojom/pdf_render_settings.mojom +++ b/chrome/services/printing/public/mojom/pdf_render_settings.mojom
@@ -17,7 +17,11 @@ [EnableIf=is_win] POSTSCRIPT_LEVEL2, [EnableIf=is_win] - POSTSCRIPT_LEVEL3 + POSTSCRIPT_LEVEL3, + [EnableIf=is_win] + EMF_WITH_REDUCED_RASTERIZATION, + [EnableIf=is_win] + EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT }; gfx.mojom.Rect area;
diff --git a/chrome/services/printing/public/mojom/pdf_render_settings_mojom_traits.h b/chrome/services/printing/public/mojom/pdf_render_settings_mojom_traits.h index 29fc017f..86652e1c 100644 --- a/chrome/services/printing/public/mojom/pdf_render_settings_mojom_traits.h +++ b/chrome/services/printing/public/mojom/pdf_render_settings_mojom_traits.h
@@ -16,18 +16,24 @@ printing::PdfRenderSettings::Mode> { static printing::mojom::PdfRenderSettings::Mode ToMojom( printing::PdfRenderSettings::Mode mode) { + using MojomMode = printing::mojom::PdfRenderSettings::Mode; + using PrintMode = printing::PdfRenderSettings::Mode; switch (mode) { - case printing::PdfRenderSettings::Mode::NORMAL: - return printing::mojom::PdfRenderSettings::Mode::NORMAL; + case PrintMode::NORMAL: + return MojomMode::NORMAL; #if defined(OS_WIN) - case printing::PdfRenderSettings::Mode::TEXTONLY: - return printing::mojom::PdfRenderSettings::Mode::TEXTONLY; - case printing::PdfRenderSettings::Mode::GDI_TEXT: - return printing::mojom::PdfRenderSettings::Mode::GDI_TEXT; - case printing::PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2: - return printing::mojom::PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2; - case printing::PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3: - return printing::mojom::PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3; + case PrintMode::TEXTONLY: + return MojomMode::TEXTONLY; + case PrintMode::GDI_TEXT: + return MojomMode::GDI_TEXT; + case PrintMode::POSTSCRIPT_LEVEL2: + return MojomMode::POSTSCRIPT_LEVEL2; + case PrintMode::POSTSCRIPT_LEVEL3: + return MojomMode::POSTSCRIPT_LEVEL3; + case PrintMode::EMF_WITH_REDUCED_RASTERIZATION: + return MojomMode::EMF_WITH_REDUCED_RASTERIZATION; + case PrintMode::EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT: + return MojomMode::EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT; #endif } NOTREACHED() << "Unknown mode " << static_cast<int>(mode); @@ -36,22 +42,30 @@ static bool FromMojom(printing::mojom::PdfRenderSettings::Mode input, printing::PdfRenderSettings::Mode* output) { + using MojomMode = printing::mojom::PdfRenderSettings::Mode; + using PrintMode = printing::PdfRenderSettings::Mode; switch (input) { - case printing::mojom::PdfRenderSettings::Mode::NORMAL: - *output = printing::PdfRenderSettings::Mode::NORMAL; + case MojomMode::NORMAL: + *output = PrintMode::NORMAL; return true; #if defined(OS_WIN) - case printing::mojom::PdfRenderSettings::Mode::TEXTONLY: - *output = printing::PdfRenderSettings::Mode::TEXTONLY; + case MojomMode::TEXTONLY: + *output = PrintMode::TEXTONLY; return true; - case printing::mojom::PdfRenderSettings::Mode::GDI_TEXT: - *output = printing::PdfRenderSettings::Mode::GDI_TEXT; + case MojomMode::GDI_TEXT: + *output = PrintMode::GDI_TEXT; return true; - case printing::mojom::PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2: - *output = printing::PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2; + case MojomMode::POSTSCRIPT_LEVEL2: + *output = PrintMode::POSTSCRIPT_LEVEL2; return true; - case printing::mojom::PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3: - *output = printing::PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3; + case MojomMode::POSTSCRIPT_LEVEL3: + *output = PrintMode::POSTSCRIPT_LEVEL3; + return true; + case MojomMode::EMF_WITH_REDUCED_RASTERIZATION: + *output = PrintMode::EMF_WITH_REDUCED_RASTERIZATION; + return true; + case MojomMode::EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT: + *output = PrintMode::EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT; return true; #endif }
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index eecf106..b8a661f 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1864,6 +1864,7 @@ "../browser/safe_browsing/settings_reset_prompt/settings_reset_prompt_test_utils.h", "../browser/ui/views/extensions/extension_dialog_browsertest.cc", "../browser/ui/views/web_apps/pwa_confirmation_bubble_view_browsertest.cc", + "../browser/ui/views/web_apps/web_app_confirmation_view_browsertest.cc", "../browser/ui/web_applications/test/web_app_navigation_browsertest.cc", "../browser/ui/web_applications/test/web_app_navigation_browsertest.h", ] @@ -3250,6 +3251,7 @@ "../browser/page_load_metrics/metrics_web_contents_observer_unittest.cc", "../browser/page_load_metrics/observers/aborts_page_load_metrics_observer_unittest.cc", "../browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_unittest.cc", + "../browser/page_load_metrics/observers/ad_metrics/page_ad_density_tracker_unittest.cc", "../browser/page_load_metrics/observers/amp_page_load_metrics_observer_unittest.cc", "../browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_test_utils.cc", "../browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_test_utils.h", @@ -5423,6 +5425,7 @@ "../browser/ui/views/relaunch_notification/relaunch_notification_controller_unittest.cc", "../browser/ui/views/relaunch_notification/relaunch_required_timer_internal_unittest.cc", "../browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl_unittest.cc", + "../browser/ui/views/session_crashed_bubble_view_unittest.cc", "../browser/ui/views/status_icons/status_tray_win_unittest.cc", "../browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_unittest.cc", "../browser/ui/views/tabs/color_picker_view_unittest.cc",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java index d03396a..22f8642 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java
@@ -42,7 +42,6 @@ import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabSelectionType; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.browser.ui.appmenu.AppMenuCoordinator; @@ -487,7 +486,7 @@ final CallbackHelper selectedCallback = new CallbackHelper(); TabModel incognitoTabModel = getActivity().getTabModelSelector().getModel(true); - TabModelObserver observer = new EmptyTabModelObserver() { + TabModelObserver observer = new TabModelObserver() { @Override public void didAddTab( Tab tab, @TabLaunchType int type, @TabCreationState int creationState) {
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeTabUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeTabUtils.java index d4b2b2e..afb4312a 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeTabUtils.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeTabUtils.java
@@ -28,7 +28,6 @@ import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.chrome.browser.tab.TabWebContentsObserver; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; @@ -356,7 +355,7 @@ Instrumentation instrumentation, ChromeTabbedActivity activity) { final TabModel normalTabModel = activity.getTabModelSelector().getModel(false); final CallbackHelper createdCallback = new CallbackHelper(); - normalTabModel.addObserver(new EmptyTabModelObserver() { + normalTabModel.addObserver(new TabModelObserver() { @Override public void didAddTab( Tab tab, @TabLaunchType int type, @TabCreationState int creationState) { @@ -403,7 +402,7 @@ final CallbackHelper selectedCallback = new CallbackHelper(); TabModel tabModel = activity.getTabModelSelector().getModel(incognito); - TabModelObserver observer = new EmptyTabModelObserver() { + TabModelObserver observer = new TabModelObserver() { @Override public void didAddTab( Tab tab, @TabLaunchType int type, @TabCreationState int creationState) { @@ -523,7 +522,7 @@ public static void closeTabWithAction( Instrumentation instrumentation, final ChromeActivity activity, Runnable action) { final CallbackHelper closeCallback = new CallbackHelper(); - final TabModelObserver observer = new EmptyTabModelObserver() { + final TabModelObserver observer = new TabModelObserver() { @Override public void willCloseTab(Tab tab, boolean animate) { closeCallback.notifyCalled(); @@ -565,7 +564,7 @@ public static void closeAllTabs( Instrumentation instrumentation, final ChromeTabbedActivity activity) { final CallbackHelper closeCallback = new CallbackHelper(); - final TabModelObserver observer = new EmptyTabModelObserver() { + final TabModelObserver observer = new TabModelObserver() { @Override public void multipleTabsPendingClosure(List<Tab> tabs, boolean isAllTabs) { closeCallback.notifyCalled(); @@ -607,7 +606,7 @@ public static void selectTabWithAction( Instrumentation instrumentation, final ChromeTabbedActivity activity, Runnable action) { final CallbackHelper selectCallback = new CallbackHelper(); - final TabModelObserver observer = new EmptyTabModelObserver() { + final TabModelObserver observer = new TabModelObserver() { @Override public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { selectCallback.notifyCalled(); @@ -659,7 +658,7 @@ final CallbackHelper createdCallback = new CallbackHelper(); final TabModel tabModel = testRule.getActivity().getTabModelSelector().getModel(expectIncognito); - tabModel.addObserver(new EmptyTabModelObserver() { + tabModel.addObserver(new TabModelObserver() { @Override public void didAddTab( Tab tab, @TabLaunchType int type, @TabCreationState int creationState) { @@ -709,7 +708,7 @@ final CallbackHelper createdCallback = new CallbackHelper(); final TabModel tabModel = backgroundActivity.getTabModelSelector().getModel(expectIncognito); - tabModel.addObserver(new EmptyTabModelObserver() { + tabModel.addObserver(new TabModelObserver() { @Override public void didAddTab( Tab tab, @TabLaunchType int type, @TabCreationState int creationState) {
diff --git a/chrome/test/data/ads_observer/ad_iframe_writer.js b/chrome/test/data/ads_observer/ad_iframe_writer.js index 3aa4a05..a8a991b 100644 --- a/chrome/test/data/ads_observer/ad_iframe_writer.js +++ b/chrome/test/data/ads_observer/ad_iframe_writer.js
@@ -16,3 +16,19 @@ frame.src = src; return frame; } + +function createAdIframeAtRect(x, y, width, height) { + let frame = document.createElement('iframe'); + frame.style.border = "0px none transparent"; + frame.style.overflow = "hidden"; + frame.style.position = "fixed"; + frame.style.left = x; + frame.style.top = y; + frame.scrolling = "no"; + frame.frameborder="0"; + frame.allowTransparency="true"; + frame.width = width; + frame.height = height; + document.body.appendChild(frame); + return frame; +}
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index 8cfd027c..ec2fac6 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -331,6 +331,16 @@ ] }, + "PrintRasterizationMode": { + "os": ["win"], + "policy_pref_mapping_test": [ + { + "policies": { "PrintRasterizationMode": 1 }, + "prefs": { "printing.rasterization_mode": {} } + } + ] + }, + "PrinterTypeDenyList": { "os": ["win", "linux", "mac", "chromeos"], "test_policy": { "PrinterTypeDenyList": ["privet", "extension"] }, @@ -4769,6 +4779,18 @@ ] }, + "UserPluginVmAllowed": { + "os": ["chromeos"], + "policy_pref_mapping_test": [ + { + "policies": { + "UserPluginVmAllowed": true + }, + "prefs": { "plugin_vm.allowed": {} } + } + ] + }, + "PluginVmImage": { "os": ["chromeos"], "policy_pref_mapping_test": [
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn index b704beb..8ff5531 100644 --- a/chrome/test/data/webui/BUILD.gn +++ b/chrome/test/data/webui/BUILD.gn
@@ -186,6 +186,7 @@ "$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",
diff --git a/chrome/test/data/webui/cr_elements/BUILD.gn b/chrome/test/data/webui/cr_elements/BUILD.gn index 68982e8..4fd74af 100644 --- a/chrome/test/data/webui/cr_elements/BUILD.gn +++ b/chrome/test/data/webui/cr_elements/BUILD.gn
@@ -22,6 +22,7 @@ "cr_lazy_render_tests.js", "cr_link_row_tests.js", "cr_policy_indicator_tests.js", + "cr_lottie_tests.js", "cr_policy_indicator_behavior_tests.js", "cr_policy_pref_indicator_tests.js", "cr_profile_avatar_selector_tests.js",
diff --git a/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js b/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js index 1605cd10..09e24e14 100644 --- a/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js +++ b/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js
@@ -623,7 +623,6 @@ runMochaTest(this.suiteName, cr_view_manager_test.TestNames.EventFiring); }); -GEN('#if defined(OS_CHROMEOS)'); /** * @constructor * @extends {CrElementsBrowserTest} @@ -634,8 +633,7 @@ __proto__: CrElementsBrowserTest.prototype, /** @override */ - browsePreload: 'chrome://resources/cr_elements/chromeos/cr_lottie/' + - 'cr_lottie.html', + browsePreload: 'chrome://resources/cr_elements/cr_lottie/cr_lottie.html', /** @override */ commandLineSwitches: [{ @@ -649,7 +647,6 @@ ]), }; -TEST_F('CrElementsLottieTest', 'DISABLED_All', function() { +TEST_F('CrElementsLottieTest', 'All', function() { mocha.run(); }); -GEN('#endif');
diff --git a/chrome/test/data/webui/cr_elements/cr_elements_v3_browsertest.js b/chrome/test/data/webui/cr_elements/cr_elements_v3_browsertest.js index 3e8ef39..df296c4a 100644 --- a/chrome/test/data/webui/cr_elements/cr_elements_v3_browsertest.js +++ b/chrome/test/data/webui/cr_elements/cr_elements_v3_browsertest.js
@@ -344,3 +344,20 @@ TEST_F('CrElementsPolicyIndicatorBehaviorV3Test', 'All', function() { mocha.run(); }); + +// eslint-disable-next-line no-var +var CrElementsLottieV3Test = class extends CrElementsV3BrowserTest { + /** @override */ + get browsePreload() { + return 'chrome://test?module=cr_elements/cr_lottie_tests.m.js'; + } + + /** @override */ + get commandLineSwitches() { + return [{switchName: 'enable-pixel-output-in-tests'}]; + } +}; + +TEST_F('CrElementsLottieV3Test', 'All', function() { + mocha.run(); +});
diff --git a/chrome/test/data/webui/cr_elements/cr_lottie_tests.js b/chrome/test/data/webui/cr_elements/cr_lottie_tests.js index 9fecc08..e9fc7c9 100644 --- a/chrome/test/data/webui/cr_elements/cr_lottie_tests.js +++ b/chrome/test/data/webui/cr_elements/cr_lottie_tests.js
@@ -2,8 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// clang-format off +// #import 'chrome://resources/cr_elements/cr_lottie/cr_lottie.m.js'; +// #import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +// #import {eventToPromise} from '../test_util.m.js'; +// clang-format on + /** @fileoverview Suite of tests for cr-lottie. */ -cr.define('cr_lottie_test', function() { +suite('cr_lottie_test', function() { /** * A data url that produces a sample json lottie animation. * @type {string} @@ -85,7 +91,8 @@ await waitForPlayingEvent; }); - test('TestResize', async () => { + // TODO(crbug.com/1021474): flaky. + test.skip('TestResize', async () => { const waitForInitializeEvent = test_util.eventToPromise('cr-lottie-initialized', crLottieElement); await waitForInitializeEvent; @@ -147,7 +154,8 @@ await waitForPlayingEvent; }); - test('TestRenderFrame', async () => { + // TODO(crbug.com/1021474): flaky. + test.skip('TestRenderFrame', async () => { // Offscreen canvas has a race issue when used in this test framework. To // ensure that we capture a frame from the animation and not an empty frame, // we delay the capture by 2 seconds.
diff --git a/chrome/test/data/webui/new_tab_page/app_test.js b/chrome/test/data/webui/new_tab_page/app_test.js index ef0be1a..564b97f8 100644 --- a/chrome/test/data/webui/new_tab_page/app_test.js +++ b/chrome/test/data/webui/new_tab_page/app_test.js
@@ -293,4 +293,13 @@ await testProxy.callbackRouterRemote.$.flushForTesting(); assertTrue(app.$.mostVisited.hasAttribute('use-white-add-icon')); }); + + test('theme updates use title pill', async () => { + const theme = createTheme(); + theme.shortcutUseTitlePill = true; + testProxy.callbackRouterRemote.setTheme(theme); + assertFalse(app.$.mostVisited.hasAttribute('use-title-pill')); + await testProxy.callbackRouterRemote.$.flushForTesting(); + assertTrue(app.$.mostVisited.hasAttribute('use-title-pill')); + }); });
diff --git a/chrome/test/data/webui/new_tab_page/most_visited_test.js b/chrome/test/data/webui/new_tab_page/most_visited_test.js index 5675212..ecad45f65 100644 --- a/chrome/test/data/webui/new_tab_page/most_visited_test.js +++ b/chrome/test/data/webui/new_tab_page/most_visited_test.js
@@ -4,7 +4,7 @@ import {BrowserProxy} from 'chrome://new-tab-page/new_tab_page.js'; import {isMac} from 'chrome://resources/js/cr.m.js'; -import {assertStyle, createTestProxy, keydown} from 'chrome://test/new_tab_page/test_support.js'; +import {assertNotStyle, assertStyle, createTestProxy, keydown} from 'chrome://test/new_tab_page/test_support.js'; import {eventToPromise, flushTasks} from 'chrome://test/test_util.m.js'; suite('NewTabPageMostVisitedTest', () => { @@ -724,6 +724,23 @@ 'rgb(255, 255, 255)'); }); + test('add title pill', () => { + mostVisited.style.setProperty('--ntp-theme-text-shadow', '1px 2px'); + queryAll('.tile-title').forEach(tile => { + assertStyle(tile, 'background-color', 'rgba(0, 0, 0, 0)'); + }); + queryAll('.tile-title span').forEach(tile => { + assertNotStyle(tile, 'text-shadow', 'none'); + }); + mostVisited.toggleAttribute('use-title-pill', true); + queryAll('.tile-title').forEach(tile => { + assertStyle(tile, 'background-color', 'rgb(255, 255, 255)'); + }); + queryAll('.tile-title span').forEach(tile => { + assertStyle(tile, 'text-shadow', 'none'); + }); + }); + test('rendering tiles logs event', async () => { // Arrange. testProxy.setResultFor('now', 123);
diff --git a/chrome/test/data/webui/new_tab_page/test_support.js b/chrome/test/data/webui/new_tab_page/test_support.js index 3d93704..9bb81b9c 100644 --- a/chrome/test/data/webui/new_tab_page/test_support.js +++ b/chrome/test/data/webui/new_tab_page/test_support.js
@@ -95,5 +95,6 @@ dailyRefreshCollectionId: '', searchBox: searchBox, shortcutUseWhiteAddIcon: false, + shortcutUseTitlePill: false, }; }
diff --git a/chrome/test/data/webui/settings/BUILD.gn b/chrome/test/data/webui/settings/BUILD.gn index 6ae42a6b1..ce0c649 100644 --- a/chrome/test/data/webui/settings/BUILD.gn +++ b/chrome/test/data/webui/settings/BUILD.gn
@@ -64,6 +64,7 @@ ":cookies_page_test", ":passwords_and_autofill_fake_data", ":search_page_test", + ":security_page_test", ":settings_page_test_util", ":site_list_tests", ":site_settings_page_test", @@ -74,8 +75,11 @@ ":test_metrics_browser_proxy", ":test_open_window_proxy", ":test_password_manager_proxy", + ":test_privacy_page_browser_proxy", + ":test_safe_browsing_browser_proxy", ":test_search_engines_browser_proxy.m", ":test_site_settings_prefs_browser_proxy", + ":test_sync_browser_proxy.m", ":test_util", # TODO(crbug.com/1000989): Add targets for more files here. @@ -150,6 +154,21 @@ ] } +js_library("test_privacy_page_browser_proxy") { + deps = [ + "..:chai_assert", + "..:test_browser_proxy.m", + "//chrome/browser/resources/settings:settings", + ] +} + +js_library("test_safe_browsing_browser_proxy") { + deps = [ + "..:test_browser_proxy.m", + "//chrome/browser/resources/settings:lazy_load", + ] +} + js_library("search_page_test") { deps = [ ":test_search_engines_browser_proxy.m", @@ -159,6 +178,21 @@ externs_list = [ "$externs_path/mocha-2.5.js" ] } +js_library("security_page_test") { + deps = [ + ":test_metrics_browser_proxy", + ":test_privacy_page_browser_proxy", + ":test_safe_browsing_browser_proxy", + ":test_sync_browser_proxy.m", + "..:chai_assert", + "..:test_util.m", + "//chrome/browser/resources/settings:lazy_load", + "//chrome/browser/resources/settings:settings", + "//ui/webui/resources/js:load_time_data.m", + ] + externs_list = [ "$externs_path/mocha-2.5.js" ] +} + js_library("settings_page_test_util") { deps = [ "..:chai_assert" ] } @@ -237,6 +271,15 @@ ] } +js_library("test_sync_browser_proxy.m") { + sources = [ "$root_gen_dir/chrome/test/data/webui/settings/test_sync_browser_proxy.m.js" ] + deps = [ + "..:test_browser_proxy.m", + "//chrome/browser/resources/settings:settings", + ] + extra_deps = [ ":modulize" ] +} + js_library("test_util") { deps = [ "//chrome/browser/resources/settings:lazy_load",
diff --git a/chrome/test/data/webui/settings/chromeos/app_management/plugin_vm_detail_view_test.js b/chrome/test/data/webui/settings/chromeos/app_management/plugin_vm_detail_view_test.js new file mode 100644 index 0000000..e97067f3 --- /dev/null +++ b/chrome/test/data/webui/settings/chromeos/app_management/plugin_vm_detail_view_test.js
@@ -0,0 +1,105 @@ +// 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. + +'use strict'; + +suite('<app-management-plugin-vm-detail-view>', function() { + let pluginVmDetailView; + let fakeHandler; + + function getPermissionBoolByType(permissionType) { + return app_management.util.getPermissionValueBool( + pluginVmDetailView.app_, permissionType); + } + + async function clickToggle(permissionType) { + getPermissionToggleByType(pluginVmDetailView, permissionType).click(); + await fakeHandler.flushPipesForTesting(); + } + + function getSelectedAppFromStore() { + const storeData = app_management.Store.getInstance().data; + return storeData.apps[storeData.selectedAppId]; + } + + setup(async function() { + fakeHandler = setupFakeHandler(); + replaceStore(); + + const permissions = {}; + const permissionIds = [PluginVmPermissionType.PRINTING]; + for (const permissionId of permissionIds) { + permissions[permissionId] = app_management.util.createPermission( + permissionId, PermissionValueType.kBool, Bool.kTrue, + false /*is_managed*/); + } + + // Add an app, and make it the currently selected app. + const options = { + type: apps.mojom.AppType.kPluginVm, + permissions: permissions + }; + const app = await fakeHandler.addApp(null, options); + app_management.Store.getInstance().dispatch( + app_management.actions.updateSelectedAppId(app.id)); + + pluginVmDetailView = + document.createElement('app-management-plugin-vm-detail-view'); + replaceBody(pluginVmDetailView); + }); + + test('App is rendered correctly', function() { + assertEquals( + app_management.Store.getInstance().data.selectedAppId, + pluginVmDetailView.app_.id); + }); + + test('Toggle permissions', async function() { + const checkToggle = async (permissionType) => { + assertTrue(getPermissionBoolByType(permissionType)); + assertTrue(getPermissionCrToggleByType(pluginVmDetailView, permissionType) + .checked); + + // Toggle off. + await clickToggle(permissionType); + assertFalse(getPermissionBoolByType(permissionType)); + assertFalse( + getPermissionCrToggleByType(pluginVmDetailView, permissionType) + .checked); + + // Toggle on. + await clickToggle(permissionType); + assertTrue(getPermissionBoolByType(permissionType)); + assertTrue(getPermissionCrToggleByType(pluginVmDetailView, permissionType) + .checked); + }; + + await checkToggle('PRINTING'); + }); + + test('Pin to shelf toggle', async function() { + const pinToShelfItem = pluginVmDetailView.$['pin-to-shelf-setting']; + const toggle = pinToShelfItem.$['toggle-row'].$.toggle; + + assertFalse(toggle.checked); + assertEquals( + toggle.checked, + app_management.util.convertOptionalBoolToBool( + getSelectedAppFromStore().isPinned)); + pinToShelfItem.click(); + await fakeHandler.flushPipesForTesting(); + assertTrue(toggle.checked); + assertEquals( + toggle.checked, + app_management.util.convertOptionalBoolToBool( + getSelectedAppFromStore().isPinned)); + pinToShelfItem.click(); + await fakeHandler.flushPipesForTesting(); + assertFalse(toggle.checked); + assertEquals( + toggle.checked, + app_management.util.convertOptionalBoolToBool( + getSelectedAppFromStore().isPinned)); + }); +});
diff --git a/chrome/test/data/webui/settings/chromeos/app_management/plugin_vm_shared_folders_test.js b/chrome/test/data/webui/settings/chromeos/app_management/plugin_vm_shared_folders_test.js new file mode 100644 index 0000000..8b9539c9 --- /dev/null +++ b/chrome/test/data/webui/settings/chromeos/app_management/plugin_vm_shared_folders_test.js
@@ -0,0 +1,91 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** @implements {settings.PluginVmBrowserProxy} */ +class TestPluginVmBrowserProxy extends TestBrowserProxy { + constructor() { + super([ + 'getPluginVmSharedPathsDisplayText', + 'removePluginVmSharedPath', + ]); + } + + /** override */ + getPluginVmSharedPathsDisplayText(paths) { + this.methodCalled('getPluginVmSharedPathsDisplayText'); + return Promise.resolve(paths.map(path => path + '-displayText')); + } + + /** override */ + removePluginVmSharedPath(vmName, path) { + this.methodCalled('removePluginVmSharedPath', [vmName, path]); + } +} + +suite('SharedPaths', function() { + /** @type {?SettingsPluginVmSharedPathsElement} */ + let page = null; + + /** @type {?TestPluginVmBrowserProxy} */ + let pluginVmBrowserProxy = null; + + function setPrefs(sharedPaths) { + pluginVmBrowserProxy.resetResolver('getPluginVmSharedPathsDisplayText'); + page.prefs = { + guest_os: { + paths_shared_to_vms: {value: sharedPaths}, + } + }; + return pluginVmBrowserProxy.whenCalled('getPluginVmSharedPathsDisplayText') + .then(() => { + Polymer.dom.flush(); + }); + } + + setup(function() { + pluginVmBrowserProxy = new TestPluginVmBrowserProxy(); + settings.PluginVmBrowserProxyImpl.instance_ = pluginVmBrowserProxy; + PolymerTest.clearBody(); + page = document.createElement('settings-plugin-vm-shared-paths'); + document.body.appendChild(page); + }); + + teardown(function() { + page.remove(); + }); + + test('Remove', async function() { + await setPrefs({'path1': ['PvmDefault'], 'path2': ['PvmDefault']}); + assertEquals(2, page.shadowRoot.querySelectorAll('.settings-box').length); + assertEquals(2, page.shadowRoot.querySelectorAll('.list-item').length); + assertFalse(page.$.pluginVmInstructionsRemove.hidden); + assertTrue(!!page.$$('.list-item cr-icon-button')); + + // Remove first shared path, still one left. + page.$$('.list-item cr-icon-button').click(); + { + const [vmName, path] = + await pluginVmBrowserProxy.whenCalled('removePluginVmSharedPath'); + assertEquals('PvmDefault', vmName); + assertEquals('path1', path); + } + await setPrefs({'path2': ['PvmDefault']}); + assertEquals(1, page.shadowRoot.querySelectorAll('.list-item').length); + assertFalse(page.$.pluginVmInstructionsRemove.hidden); + + // Remove remaining shared path, none left. + pluginVmBrowserProxy.resetResolver('removePluginVmSharedPath'); + page.$$('.list-item cr-icon-button').click(); + { + const [vmName, path] = + await pluginVmBrowserProxy.whenCalled('removePluginVmSharedPath'); + assertEquals('PvmDefault', vmName); + assertEquals('path2', path); + } + await setPrefs({'ignored': ['ignore']}); + assertEquals(0, page.shadowRoot.querySelectorAll('.list-item').length); + // Verify remove instructions are hidden. + assertTrue(page.$.pluginVmInstructionsRemove.hidden); + }); +});
diff --git a/chrome/test/data/webui/settings/chromeos/manage_accessibility_page_tests.js b/chrome/test/data/webui/settings/chromeos/manage_accessibility_page_tests.js index ba39b2d..cb4b44a 100644 --- a/chrome/test/data/webui/settings/chromeos/manage_accessibility_page_tests.js +++ b/chrome/test/data/webui/settings/chromeos/manage_accessibility_page_tests.js
@@ -97,9 +97,7 @@ // Accessibility learn more link should be hidden. assertFalse(isVisible(page.$$('setings-localized-link'))); - const allowed_subpages = [ - 'chromeVoxSubpageButton', 'selectToSpeakSubpageButton', 'ttsSubpageButton' - ]; + const allowed_subpages = ['selectToSpeakSubpageButton', 'ttsSubpageButton']; const subpages = page.root.querySelectorAll('cr-link-row'); subpages.forEach(function(subpage) {
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js index 4c61406..e9471227 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
@@ -391,6 +391,50 @@ mocha.run(); }); +// Test fixture for the app management Plugin VM detail view element. +// eslint-disable-next-line no-var +var OSSettingsAppManagementPluginVmDetailViewTest = + class extends OSSettingsAppManagementBrowserTest { + /** @override */ + get browsePreload() { + return super.browsePreload + 'app_management/plugin_vm_detail_view.html'; + } + + /** @override */ + get extraLibraries() { + return super.extraLibraries.concat([ + 'app_management/plugin_vm_detail_view_test.js', + ]); + } +}; + +TEST_F('OSSettingsAppManagementPluginVmDetailViewTest', 'AllJsTests', () => { + mocha.run(); +}); + +// Test fixture for the Plugin VM page. +// eslint-disable-next-line no-var +var OSSettingsAppManagementPluginVmPageTest = + class extends OSSettingsAppManagementBrowserTest { + /** @override */ + get browsePreload() { + return super.browsePreload + + 'app_management/plugin_vm_page/plugin_vm_shared_folders.html'; + } + + /** @override */ + get extraLibraries() { + return super.extraLibraries.concat([ + BROWSER_SETTINGS_PATH + '../test_browser_proxy.js', + 'app_management/plugin_vm_shared_folders_test.js', + ]); + } +}; + +TEST_F('OSSettingsAppManagementPluginVmPageTest', 'AllJsTests', () => { + mocha.run(); +}); + // Test fixture for the app management managed app view. // eslint-disable-next-line no-var var OSSettingsAppManagementManagedAppTest = @@ -491,7 +535,7 @@ mocha.grep('SubPagePortForwarding').run(); }); -TEST_F('OSSettingsCrostiniPageTest', 'DiskResize', function() { +TEST_F('OSSettingsCrostiniPageTest', 'DISABLED_DiskResize', function() { mocha.grep('DiskResize').run(); }); @@ -1139,30 +1183,6 @@ mocha.run(); }); -// Test fixture for the Plugin VM page. -// eslint-disable-next-line no-var -var OSSettingsPluginVmPageTest = class extends OSSettingsBrowserTest { - /** @override */ - get browsePreload() { - return super.browsePreload + 'chromeos/plugin_vm_page/plugin_vm_page.html'; - } - - /** @override */ - get extraLibraries() { - return super.extraLibraries.concat([ - '//ui/webui/resources/js/promise_resolver.js', - '//ui/webui/resources/js/util.js', - BROWSER_SETTINGS_PATH + '../test_util.js', - BROWSER_SETTINGS_PATH + '../test_browser_proxy.js', - 'plugin_vm_page_test.js', - ]); - } -}; - -TEST_F('OSSettingsPluginVmPageTest', 'AllJsTests', () => { - mocha.run(); -}); - // Tests for the CUPS printer entry. // eslint-disable-next-line no-var var OSSettingsPrinterEntryTest = class extends OSSettingsBrowserTest {
diff --git a/chrome/test/data/webui/settings/chromeos/plugin_vm_page_test.js b/chrome/test/data/webui/settings/chromeos/plugin_vm_page_test.js deleted file mode 100644 index 53eb0f8d..0000000 --- a/chrome/test/data/webui/settings/chromeos/plugin_vm_page_test.js +++ /dev/null
@@ -1,290 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** @implements {settings.PluginVmBrowserProxy} */ -class TestPluginVmBrowserProxy extends TestBrowserProxy { - constructor() { - super([ - 'getPluginVmSharedPathsDisplayText', - 'removePluginVmSharedPath', - 'removePluginVm', - 'requestPluginVmInstallerView', - ]); - } - - /** override */ - getPluginVmSharedPathsDisplayText(paths) { - this.methodCalled('getPluginVmSharedPathsDisplayText'); - return Promise.resolve(paths.map(path => path + '-displayText')); - } - - /** override */ - removePluginVmSharedPath(vmName, path) { - this.methodCalled('removePluginVmSharedPath', [vmName, path]); - } - - /** override */ - removePluginVm() { - this.methodCalled('removePluginVm'); - } - - /** override */ - requestPluginVmInstallerView() { - this.methodCalled('requestPluginVmInstallerView'); - } -} - -/** @type {?TestPluginVmBrowserProxy} */ -let pluginVmBrowserProxy = null; - -suite('PluginVmPage', function() { - /** @type {?SettingsPluginVmElement} */ - let page = null; - - /** @type {Array<string>} */ - let routes; - /** @type {!Object} */ - let preTestSettingsRoutes; - /** @type {!function(string)} */ - let preTestRouterNavigateTo; - - setup(function() { - pluginVmBrowserProxy = new TestPluginVmBrowserProxy(); - settings.PluginVmBrowserProxyImpl.instance_ = pluginVmBrowserProxy; - PolymerTest.clearBody(); - - routes = []; - - preTestRouterNavigateTo = settings.Router.getInstance().navigateTo; - settings.Router.getInstance().navigateTo = (route) => routes.push(route); - - preTestSettingsRoutes = settings.routes; - settings.routes = {PLUGIN_VM_DETAILS: 'TEST_PLUGIN_VM_DETAILS_ROUTE'}; - }); - - teardown(function() { - page.remove(); - - settings.Router.getInstance().navigateTo = preTestRouterNavigateTo; - - settings.routes = preTestSettingsRoutes; - }); - - function setUpPluginVmPage({allowedByPolicy, vmImageExists}) { - loadTimeData.overrideValues({allowPluginVm: allowedByPolicy}); - - page = document.createElement('settings-plugin-vm-page'); - page.prefs = {plugin_vm: {image_exists: {value: vmImageExists}}}; - document.body.appendChild(page); - - Polymer.dom.flush(); - } - - test('PolicyEnabledAndImageExists', function() { - setUpPluginVmPage({allowedByPolicy: true, vmImageExists: true}); - - assertEquals(page.$$('#enable'), null); - - assertDeepEquals(routes, []); - page.$$('#navigate-to-subpage').click(); - assertDeepEquals(routes, ['TEST_PLUGIN_VM_DETAILS_ROUTE']); - }); - - test('PolicyEnabledAndImageDoesntExist', function() { - setUpPluginVmPage({allowedByPolicy: true, vmImageExists: false}); - - assertEquals(page.$$('#navigate-to-subpage'), null); - - assertEquals( - 0, pluginVmBrowserProxy.getCallCount('requestPluginVmInstallerView')); - page.$$('#enable').click(); - assertEquals( - 1, pluginVmBrowserProxy.getCallCount('requestPluginVmInstallerView')); - }); - - test('PolicyDisabledAndImageExists', function() { - setUpPluginVmPage({allowedByPolicy: false, vmImageExists: true}); - - assertEquals(page.$$('#enable'), null); - - assertDeepEquals(routes, []); - page.$$('#navigate-to-subpage').click(); - assertDeepEquals(routes, ['TEST_PLUGIN_VM_DETAILS_ROUTE']); - }); - - test('PolicyDisabledAndImageDoesntExist', function() { - setUpPluginVmPage({allowedByPolicy: false, vmImageExists: false}); - - assertEquals(page.$$('#navigate-to-subpage'), null); - - assertTrue(page.$$('#enable').disabled); - }); -}); - -suite('Details', function() { - /** @type {?SettingsPluginVmSubpageElement} */ - let page = null; - - setup(function() { - pluginVmBrowserProxy = new TestPluginVmBrowserProxy(); - settings.PluginVmBrowserProxyImpl.instance_ = pluginVmBrowserProxy; - PolymerTest.clearBody(); - page = document.createElement('settings-plugin-vm-subpage'); - page.prefs = { - plugin_vm: { - image_exists: {value: true}, - printers_allowed: {value: false}, - } - }; - document.body.appendChild(page); - }); - - teardown(function() { - page.remove(); - }); - - test('Sanity', function() { - assertTrue(!!page.$$('#plugin-vm-shared-paths')); - }); - - test('PrintingToggle', async function() { - const toggle = page.$$('#plugin-vm-printer-access'); - assertTrue(!!toggle); - assertTrue(!!toggle); - assertFalse(toggle.checked); - assertFalse(toggle.pref.value); - toggle.click(); - assertTrue(toggle.checked); - assertTrue(toggle.pref.value); - }); -}); - -suite('SharedPaths', function() { - /** @type {?SettingsPluginVmSharedPathsElement} */ - let page = null; - - function setPrefs(sharedPaths) { - pluginVmBrowserProxy.resetResolver('getPluginVmSharedPathsDisplayText'); - page.prefs = { - guest_os: { - paths_shared_to_vms: {value: sharedPaths}, - } - }; - return pluginVmBrowserProxy.whenCalled('getPluginVmSharedPathsDisplayText') - .then(() => { - Polymer.dom.flush(); - }); - } - - setup(function() { - pluginVmBrowserProxy = new TestPluginVmBrowserProxy(); - settings.PluginVmBrowserProxyImpl.instance_ = pluginVmBrowserProxy; - PolymerTest.clearBody(); - page = document.createElement('settings-plugin-vm-shared-paths'); - document.body.appendChild(page); - }); - - teardown(function() { - page.remove(); - }); - - test('Remove', function() { - return setPrefs({'path1': ['PvmDefault'], 'path2': ['PvmDefault']}) - .then(() => { - assertEquals( - 2, page.shadowRoot.querySelectorAll('.settings-box').length); - assertEquals( - 2, page.shadowRoot.querySelectorAll('.list-item').length); - assertFalse(page.$.pluginVmInstructionsRemove.hidden); - assertTrue(!!page.$$('.list-item cr-icon-button')); - - // Remove first shared path, still one left. - page.$$('.list-item cr-icon-button').click(); - return pluginVmBrowserProxy.whenCalled('removePluginVmSharedPath'); - }) - .then(([vmName, path]) => { - assertEquals('PvmDefault', vmName); - assertEquals('path1', path); - return setPrefs({'path2': ['PvmDefault']}); - }) - .then(() => { - assertEquals( - 1, page.shadowRoot.querySelectorAll('.list-item').length); - assertFalse(page.$.pluginVmInstructionsRemove.hidden); - - // Remove remaining shared path, none left. - pluginVmBrowserProxy.resetResolver('removePluginVmSharedPath'); - page.$$('.list-item cr-icon-button').click(); - return pluginVmBrowserProxy.whenCalled('removePluginVmSharedPath'); - }) - .then(([vmName, path]) => { - assertEquals('PvmDefault', vmName); - assertEquals('path2', path); - return setPrefs({'ignored': ['ignore']}); - }) - .then(() => { - assertEquals( - 0, page.shadowRoot.querySelectorAll('.list-item').length); - // Verify remove instructions are hidden. - assertTrue(page.$.pluginVmInstructionsRemove.hidden); - }); - }); -}); - -suite('Remove', function() { - let page; - const getDialog = () => page.$$( - '#plugin-vm-remove settings-plugin-vm-remove-confirmation-dialog'); - const hasDialog = () => !!getDialog(); - - setup(function() { - pluginVmBrowserProxy = new TestPluginVmBrowserProxy(); - settings.PluginVmBrowserProxyImpl.instance_ = pluginVmBrowserProxy; - PolymerTest.clearBody(); - page = document.createElement('settings-plugin-vm-subpage'); - document.body.appendChild(page); - }); - - teardown(function() { - page.remove(); - }); - - test('Remove', async function() { - assertFalse(hasDialog()); - - page.$.pluginVmRemoveButton.click(); - assertFalse(hasDialog()); - - Polymer.dom.flush(); - assertTrue(hasDialog()); - - getDialog().$.continue.click(); - assertEquals(1, pluginVmBrowserProxy.getCallCount('removePluginVm')); - - await test_util.eventToPromise('dom-change', page.$$('#plugin-vm-remove')); - assertFalse(hasDialog()); - - assertEquals(getDeepActiveElement(), page.$.pluginVmRemoveButton); - }); - - test('RemoveDialogCancelled', async function() { - assertFalse(hasDialog()); - - page.$.pluginVmRemoveButton.click(); - assertFalse(hasDialog()); - - Polymer.dom.flush(); - assertTrue(hasDialog()); - - getDialog().$.cancel.click(); - assertTrue(hasDialog()); - assertEquals(0, pluginVmBrowserProxy.getCallCount('removePluginVm')); - - await test_util.eventToPromise('dom-change', page.$$('#plugin-vm-remove')); - assertFalse(hasDialog()); - assertEquals(0, pluginVmBrowserProxy.getCallCount('removePluginVm')); - - assertEquals(getDeepActiveElement(), page.$.pluginVmRemoveButton); - }); -});
diff --git a/chrome/test/data/webui/settings/security_page_test.js b/chrome/test/data/webui/settings/security_page_test.js index 82a3351..6519b0a 100644 --- a/chrome/test/data/webui/settings/security_page_test.js +++ b/chrome/test/data/webui/settings/security_page_test.js
@@ -5,31 +5,35 @@ // clang-format off import {CrPolicyIndicatorType} from 'chrome://resources/cr_elements/policy/cr_policy_indicator_behavior.m.js'; import {isMac, isWindows} from 'chrome://resources/js/cr.m.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {SafeBrowsingBrowserProxyImpl} from 'chrome://settings/lazy_load.js'; import {MetricsBrowserProxyImpl, PrivacyElementInteractions,PrivacyPageBrowserProxyImpl, Router, routes, SyncBrowserProxyImpl} from 'chrome://settings/settings.js'; -import {TestMetricsBrowserProxy} from 'chrome://test/settings/test_metrics_browser_proxy.js'; -import {TestPrivacyPageBrowserProxy} from 'chrome://test/settings/test_privacy_page_browser_proxy.js'; -import {TestSafeBrowsingBrowserProxy} from 'chrome://test/settings/test_safe_browsing_browser_proxy.js'; -import {TestSyncBrowserProxy} from 'chrome://test/settings/test_sync_browser_proxy.m.js'; -import {flushTasks} from 'chrome://test/test_util.m.js'; + +import {assertEquals, assertFalse, assertTrue} from '../chai_assert.js'; +import {flushTasks} from '../test_util.m.js'; + +import {TestMetricsBrowserProxy} from './test_metrics_browser_proxy.js'; +import {TestPrivacyPageBrowserProxy} from './test_privacy_page_browser_proxy.js'; +import {TestSafeBrowsingBrowserProxy} from './test_safe_browsing_browser_proxy.js'; +import {TestSyncBrowserProxy} from './test_sync_browser_proxy.m.js'; // clang-format on suite('CrSettingsSecurityPageTestWithEnhanced', function() { - /** @type {.TestMetricsBrowserProxy} */ + /** @type {!TestMetricsBrowserProxy} */ let testMetricsBrowserProxy; - /** @type {SyncBrowserProxy} */ + /** @type {!TestSyncBrowserProxy} */ let syncBrowserProxy; - /** @type {TestPrivacyPageBrowserProxy} */ + /** @type {!TestPrivacyPageBrowserProxy} */ let testPrivacyBrowserProxy; - /** @type {SafeBrowsingBrowserProxy} */ + /** @type {!TestSafeBrowsingBrowserProxy} */ let testSafeBrowsingBrowserProxy; - /** @type {SettingsSecurityPageElement} */ + /** @type {!SettingsSecurityPageElement} */ let page; suiteSetup(function() { @@ -47,8 +51,9 @@ SyncBrowserProxyImpl.instance_ = syncBrowserProxy; testSafeBrowsingBrowserProxy = new TestSafeBrowsingBrowserProxy(); SafeBrowsingBrowserProxyImpl.instance_ = testSafeBrowsingBrowserProxy; - PolymerTest.clearBody(); - page = document.createElement('settings-security-page'); + document.body.innerHTML = ''; + page = /** @type {!SettingsSecurityPageElement} */ ( + document.createElement('settings-security-page')); page.prefs = { profile: {password_manager_leak_detection: {value: true}}, signin: { @@ -92,7 +97,7 @@ page.$$('#safeBrowsingStandard').click(); flush(); - page.$.safeBrowsingReportingToggle.click(); + page.$$('#safeBrowsingReportingToggle').click(); const result = await testMetricsBrowserProxy.whenCalled('recordSettingsPageHistogram'); assertEquals(PrivacyElementInteractions.IMPROVE_SECURITY, result); @@ -100,7 +105,7 @@ test('safeBrowsingReportingToggle', function() { page.$$('#safeBrowsingStandard').click(); - const safeBrowsingReportingToggle = page.$.safeBrowsingReportingToggle; + const safeBrowsingReportingToggle = page.$$('#safeBrowsingReportingToggle'); assertTrue( page.prefs.safebrowsing.enabled.value && !page.prefs.safebrowsing.enhanced.value); @@ -205,11 +210,11 @@ page.$$('#safeBrowsingStandard').click(); flush(); - assertFalse(page.$.safeBrowsingReportingToggle.disabled); + assertFalse(page.$$('#safeBrowsingReportingToggle').disabled); page.$$('#safeBrowsingEnhanced').click(); flush(); - assertTrue(page.$.safeBrowsingReportingToggle.disabled); + assertTrue(page.$$('#safeBrowsingReportingToggle').disabled); }); test('noValueChangeSafeBrowsingReportingInEnhanced', function() { @@ -228,7 +233,7 @@ page.$$('#safeBrowsingStandard').click(); flush(); - assertFalse(page.$.safeBrowsingReportingToggle.disabled); + assertFalse(page.$$('#safeBrowsingReportingToggle').disabled); page.$$('#safeBrowsingDisabled').click(); flush(); @@ -240,7 +245,7 @@ // Wait for onDisableSafebrowsingDialogClose_ to finish. await flushTasks(); - assertTrue(page.$.safeBrowsingReportingToggle.disabled); + assertTrue(page.$$('#safeBrowsingReportingToggle').disabled); }); test('noValueChangeSafeBrowsingReportingInDisabled', async function() { @@ -345,8 +350,8 @@ 'getSafeBrowsingRadioManagedState'); testSafeBrowsingBrowserProxy.reset(); - testSafeBrowsingBrowserProxy.setResultFor( - 'getSafeBrowsingRadioManagedState', Promise.resolve(managedRadioState)); + testSafeBrowsingBrowserProxy.setSafeBrowsingRadioManagedState( + managedRadioState); // Change an arbitrary Safe Browsing pref to trigger managed state update. page.set('prefs.safebrowsing.enabled.value', false); await testSafeBrowsingBrowserProxy.whenCalled( @@ -370,9 +375,8 @@ standard: {disabled: false, indicator: CrPolicyIndicatorType.NONE}, disabled: {disabled: false, indicator: CrPolicyIndicatorType.NONE}, }; - testSafeBrowsingBrowserProxy.setResultFor( - 'getSafeBrowsingRadioManagedState', - Promise.resolve(unmanagedRadioState)); + testSafeBrowsingBrowserProxy.setSafeBrowsingRadioManagedState( + unmanagedRadioState); // Change an arbitrary Safe Browsing pref to trigger managed state update. page.set('prefs.safebrowsing.enabled.value', true); await testSafeBrowsingBrowserProxy.whenCalled( @@ -391,10 +395,10 @@ suite('CrSettingsSecurityPageTestWithoutEnhanced', function() { - /** @type {SettingsSecurityPageElement} */ + /** @type {!SettingsSecurityPageElement} */ let page; - /** @type {SafeBrowsingBrowserProxy} */ + /** @type {!TestSafeBrowsingBrowserProxy} */ let testSafeBrowsingBrowserProxy; suiteSetup(function() { @@ -406,8 +410,9 @@ setup(function() { testSafeBrowsingBrowserProxy = new TestSafeBrowsingBrowserProxy(); SafeBrowsingBrowserProxyImpl.instance_ = testSafeBrowsingBrowserProxy; - PolymerTest.clearBody(); - page = document.createElement('settings-security-page'); + document.body.innerHTML = ''; + page = /** @type {!SettingsSecurityPageElement} */ ( + document.createElement('settings-security-page')); page.prefs = { profile: {password_manager_leak_detection: {value: true}}, signin: {
diff --git a/chrome/test/data/webui/settings/test_privacy_page_browser_proxy.js b/chrome/test/data/webui/settings/test_privacy_page_browser_proxy.js index b0edb67..ebd23aea 100644 --- a/chrome/test/data/webui/settings/test_privacy_page_browser_proxy.js +++ b/chrome/test/data/webui/settings/test_privacy_page_browser_proxy.js
@@ -3,8 +3,10 @@ // found in the LICENSE file. // clang-format off -import {SecureDnsMode, SecureDnsUiManagementMode} from 'chrome://settings/settings.js'; -import {TestBrowserProxy} from 'chrome://test/test_browser_proxy.m.js'; +import { MetricsReporting,PrivacyPageBrowserProxy, ResolverOption, SecureDnsMode, SecureDnsSetting, SecureDnsUiManagementMode} from 'chrome://settings/settings.js'; + +import {assertFalse} from '../chai_assert.js'; +import {TestBrowserProxy} from '../test_browser_proxy.m.js'; // clang-format on /** @implements {PrivacyPageBrowserProxy} */ @@ -12,7 +14,6 @@ constructor() { super([ 'getMetricsReporting', - 'recordSettingsPageHistogram', 'setMetricsReportingEnabled', 'showManageSSLCertificates', 'setBlockAutoplayEnabled', @@ -64,11 +65,6 @@ return Promise.resolve(this.metricsReporting); } - /** @override*/ - recordSettingsPageHistogram(value) { - this.methodCalled('recordSettingsPageHistogram', value); - } - /** @override */ setMetricsReportingEnabled(enabled) { this.methodCalled('setMetricsReportingEnabled', enabled);
diff --git a/chrome/test/data/webui/settings/test_safe_browsing_browser_proxy.js b/chrome/test/data/webui/settings/test_safe_browsing_browser_proxy.js index 6d8c11f..632bd881 100644 --- a/chrome/test/data/webui/settings/test_safe_browsing_browser_proxy.js +++ b/chrome/test/data/webui/settings/test_safe_browsing_browser_proxy.js
@@ -2,15 +2,35 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {TestBrowserProxy} from 'chrome://test/test_browser_proxy.m.js'; +import {SafeBrowsingBrowserProxy, SafeBrowsingRadioManagedState} from 'chrome://settings/lazy_load.js'; + +import {TestBrowserProxy} from '../test_browser_proxy.m.js'; /** @implements {SafeBrowsingBrowserProxy} */ export class TestSafeBrowsingBrowserProxy extends TestBrowserProxy { constructor() { - super(); - this.mockMethods([ + super([ 'getSafeBrowsingRadioManagedState', 'validateSafeBrowsingEnhanced', ]); + + /** @type {!SafeBrowsingRadioManagedState} */ + this.managedRadioState_; + } + + /** @param {!SafeBrowsingRadioManagedState} state */ + setSafeBrowsingRadioManagedState(state) { + this.managedRadioState_ = state; + } + + /** @override */ + getSafeBrowsingRadioManagedState() { + this.methodCalled('getSafeBrowsingRadioManagedState'); + return Promise.resolve(this.managedRadioState_); + } + + /** @override */ + validateSafeBrowsingEnhanced() { + this.methodCalled('validateSafeBrowsingEnhanced'); } }
diff --git a/chrome/test/data/webui/settings/test_sync_browser_proxy.js b/chrome/test/data/webui/settings/test_sync_browser_proxy.js index fb7a4a0..5d636a05 100644 --- a/chrome/test/data/webui/settings/test_sync_browser_proxy.js +++ b/chrome/test/data/webui/settings/test_sync_browser_proxy.js
@@ -2,9 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// #import {PageStatus} from 'chrome://settings/settings.js'; -// #import {TestBrowserProxy} from 'chrome://test/test_browser_proxy.m.js'; +// clang-format off +// #import {PageStatus, SyncBrowserProxy, SyncStatus} from 'chrome://settings/settings.js'; +// #import {TestBrowserProxy} from '../test_browser_proxy.m.js'; // #import {isChromeOS} from 'chrome://resources/js/cr.m.js'; +// clang-format on /** @implements {settings.SyncBrowserProxy} */ /* #export */ class TestSyncBrowserProxy extends TestBrowserProxy { @@ -41,7 +43,8 @@ /** @override */ getSyncStatus() { this.methodCalled('getSyncStatus'); - return Promise.resolve({signedIn: true, signedInUsername: 'fakeUsername'}); + return Promise.resolve(/** @type {!settings.SyncStatus} */ ( + {signedIn: true, signedInUsername: 'fakeUsername'})); } /** @override */ @@ -111,6 +114,15 @@ sendSyncPrefsChanged() { this.methodCalled('sendSyncPrefsChanged'); } + + /** @override */ + attemptUserExit() {} + + /** @override */ + openActivityControlsUrl() {} + + /** @override */ + startKeyRetrieval() {} } if (cr.isChromeOS) {
diff --git a/chrome/test/ppapi/ppapi_browsertest.cc b/chrome/test/ppapi/ppapi_browsertest.cc index e45eee4..5b82cd2 100644 --- a/chrome/test/ppapi/ppapi_browsertest.cc +++ b/chrome/test/ppapi/ppapi_browsertest.cc
@@ -1273,17 +1273,7 @@ // is present in the DNS cache with the NetworkIsolationKey associated with the // foreground WebContents - this is needed so as not to leak what hostnames were // looked up across tabs with different first party origins. -// -// The lookup checks for an IPv4-only cache entry, as UNSPECIFIED lookups are -// sometimes replaced with IPv4-only lookups, based on the result of that probe -// of whether the local network has IPv6 connectivity. For unknown reasons, the -// results of this probe can change in the middle of a test on the bots, which -// changes the used cache key. To avoid that issue, just use A lookups. -// -// See https://crbug.com/1042354 for some discussion of the issue. -void CheckTestHostNameUsedWithCorrectNetworkIsolationKey( - Browser* browser, - bool include_canonical_name) { +void CheckTestHostNameUsedWithCorrectNetworkIsolationKey(Browser* browser) { network::mojom::NetworkContext* network_context = content::BrowserContext::GetDefaultStoragePartition(browser->profile()) ->GetNetworkContext(); @@ -1294,14 +1284,8 @@ network::mojom::ResolveHostParameters::New(); // Cache only lookup. params->source = net::HostResolverSource::LOCAL_ONLY; - // PPAPI tests are somewhat slow, and the DNS cache timeout is relatively - // short, so allow stale results to avoid flaky failures. - params->cache_usage = - network::mojom::ResolveHostParameters::CacheUsage::STALE_ALLOWED; - // A-only lookup. - params->dns_query_type = net::DnsQueryType::A; // Match the parameters used by the test. - params->include_canonical_name = include_canonical_name; + params->include_canonical_name = true; net::NetworkIsolationKey network_isolation_key = browser->tab_strip_model() ->GetActiveWebContents() @@ -1320,10 +1304,6 @@ params = network::mojom::ResolveHostParameters::New(); // Cache only lookup. params->source = net::HostResolverSource::LOCAL_ONLY; - // PPAPI tests are somewhat slow, and the DNS cache timeout is relatively - // short, so allow stale results to avoid flaky failures. - params->cache_usage = - network::mojom::ResolveHostParameters::CacheUsage::STALE_ALLOWED; // Match the parameters used by the test. params->include_canonical_name = true; network::DnsLookupResult result2 = @@ -1337,8 +1317,7 @@ #define RUN_HOST_RESOLVER_SUBTESTS \ RunTestViaHTTP(LIST_TEST(HostResolver_Empty) LIST_TEST(HostResolver_Resolve) \ LIST_TEST(HostResolver_ResolveIPv4)); \ - CheckTestHostNameUsedWithCorrectNetworkIsolationKey( \ - browser(), true /* include_canonical_name */) + CheckTestHostNameUsedWithCorrectNetworkIsolationKey(browser()) IN_PROC_BROWSER_TEST_F(OutOfProcessPPAPITest, HostResolverCrash_Basic) { if (content::IsInProcessNetworkService()) @@ -2207,33 +2186,7 @@ TEST_PPAPI_NACL(MouseCursor) -// Proxy configuration test. The PPAPI code used by these tests is in -// ppapi/tests/test_network_proxy.cc. - -IN_PROC_BROWSER_TEST_F(OutOfProcessPPAPITest, NetworkProxy) { - RunTestViaHTTP(STRIP_PREFIXES(NetworkProxy)); - CheckTestHostNameUsedWithCorrectNetworkIsolationKey( - browser(), false /* include_canonical_name */); -} - -IN_PROC_BROWSER_TEST_F(PPAPINaClNewlibTest, NetworkProxy) { - RunTestViaHTTP(STRIP_PREFIXES(NetworkProxy)); - CheckTestHostNameUsedWithCorrectNetworkIsolationKey( - browser(), false /* include_canonical_name */); -} - -IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, MAYBE_PPAPI_NACL(NetworkProxy)) { - RunTestViaHTTP(STRIP_PREFIXES(NetworkProxy)); - CheckTestHostNameUsedWithCorrectNetworkIsolationKey( - browser(), false /* include_canonical_name */); -} - -IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, - MAYBE_PNACL_NONSFI(NetworkProxy)) { - RunTestViaHTTP(STRIP_PREFIXES(NetworkProxy)); - CheckTestHostNameUsedWithCorrectNetworkIsolationKey( - browser(), false /* include_canonical_name */); -} +TEST_PPAPI_NACL(NetworkProxy) // TODO(crbug.com/619765): get working on CrOS build. #if defined(OS_CHROMEOS)
diff --git a/chrome/test/ppapi/ppapi_test.cc b/chrome/test/ppapi/ppapi_test.cc index cae6891..fdf7dcf 100644 --- a/chrome/test/ppapi/ppapi_test.cc +++ b/chrome/test/ppapi/ppapi_test.cc
@@ -160,24 +160,9 @@ // Smooth scrolling confuses the scrollbar test. command_line->AppendSwitch(switches::kDisableSmoothScrolling); - - // For a particular host name, resolve another specific host name (which - // should then be added to the DNS cache), and then return a particular proxy. - // Otherwise, return DIRECT. - command_line->AppendSwitchASCII(switches::kProxyPacUrl, - "data:," - "function FindProxyForURL(url, host) {" - " if (host == 'use.proxy.test') {" - " dnsResolve('host_resolver.test');" - " return 'PROXY proxy.test';" - " }" - " return 'DIRECT'" - "}"); } void PPAPITestBase::SetUpOnMainThread() { - host_resolver()->AddRule("host_resolver.test", - embedded_test_server()->host_port_pair().host()); host_resolver()->AddRuleWithFlags( "host_resolver.test", embedded_test_server()->host_port_pair().host(), net::HOST_RESOLVER_CANONNAME);
diff --git a/chrome/updater/mac/Info.plist b/chrome/updater/mac/Info.plist index a023e718..00a6014b 100644 --- a/chrome/updater/mac/Info.plist +++ b/chrome/updater/mac/Info.plist
@@ -16,5 +16,7 @@ <string>APPL</string> <key>CFBundleVersion</key> <string>1.0</string> + <key>LSUIElement</key> + <true/> </dict> </plist>
diff --git a/chromecast/media/audio/cast_audio_resampler_impl.cc b/chromecast/media/audio/cast_audio_resampler_impl.cc index 80d9d56..f1abed3 100644 --- a/chromecast/media/audio/cast_audio_resampler_impl.cc +++ b/chromecast/media/audio/cast_audio_resampler_impl.cc
@@ -63,7 +63,9 @@ int dest_offset = buffered_frames_; buffered_frames_ = 0; - CopyCurrentInputTo(frames_left, audio_bus, dest_offset); + if (frames_left) { + CopyCurrentInputTo(frames_left, audio_bus, dest_offset); + } } void CopyCurrentInputTo(int frames_to_copy,
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd index 15378d7e..ba78a589 100644 --- a/chromeos/chromeos_strings.grd +++ b/chromeos/chromeos_strings.grd
@@ -166,6 +166,11 @@ <ph name="ENROLLMENT_DOMAIN">$1<ex>example.com</ex></ph> manages this device and may be able to monitor your activity. </message> + <!-- Managed user session warning --> + <message name="IDS_ASH_LOGIN_MANAGED_SESSION_MONITORING_USER_WARNING" desc="Text shown in the user pod in case the user is managed."> + <ph name="ENROLLMENT_DOMAIN">$1<ex>example.com</ex></ph> manages this user. It may remotely manage settings and monitor user activity. + </message> + <!-- Status tray enterprise management. --> <message name="IDS_ASH_ENTERPRISE_DEVICE_MANAGED_BY" desc="Text for notifications showing that this device is enterpise managed. Used when the organization's domain name is available."> This device is managed by <ph name="DOMAIN">$1<ex>acmecorp.com</ex></ph>.
diff --git a/chromeos/chromeos_strings_grd/IDS_ASH_LOGIN_MANAGED_SESSION_MONITORING_USER_WARNING.png.sha1 b/chromeos/chromeos_strings_grd/IDS_ASH_LOGIN_MANAGED_SESSION_MONITORING_USER_WARNING.png.sha1 new file mode 100644 index 0000000..48d5ce4 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_ASH_LOGIN_MANAGED_SESSION_MONITORING_USER_WARNING.png.sha1
@@ -0,0 +1 @@ +abbc52d3b2dc1af788daab188bf24b924412ea27 \ No newline at end of file
diff --git a/chromeos/components/sync_wifi/BUILD.gn b/chromeos/components/sync_wifi/BUILD.gn index b72af88..f1e8b06 100644 --- a/chromeos/components/sync_wifi/BUILD.gn +++ b/chromeos/components/sync_wifi/BUILD.gn
@@ -29,6 +29,7 @@ "wifi_configuration_sync_service.h", ] deps = [ + ":network_eligibility_checker", "//ash/public/cpp", "//base", "//chromeos/dbus/shill", @@ -44,6 +45,17 @@ ] } +static_library("network_eligibility_checker") { + sources = [ + "network_eligibility_checker.cc", + "network_eligibility_checker.h", + ] + deps = [ + "//chromeos/network", + "//chromeos/services/network_config/public/mojom", + ] +} + source_set("test_support") { testonly = true sources = [
diff --git a/chromeos/components/sync_wifi/local_network_collector_impl.cc b/chromeos/components/sync_wifi/local_network_collector_impl.cc index a917f22..a44c86d 100644 --- a/chromeos/components/sync_wifi/local_network_collector_impl.cc +++ b/chromeos/components/sync_wifi/local_network_collector_impl.cc
@@ -5,6 +5,7 @@ #include "chromeos/components/sync_wifi/local_network_collector_impl.h" #include "base/guid.h" +#include "chromeos/components/sync_wifi/network_eligibility_checker.h" #include "chromeos/components/sync_wifi/network_identifier.h" #include "chromeos/components/sync_wifi/network_type_conversions.h" #include "chromeos/dbus/shill/shill_service_client.h" @@ -124,49 +125,14 @@ bool LocalNetworkCollectorImpl::IsEligible( const network_config::mojom::NetworkStatePropertiesPtr& network) { - if (!network) { - return false; - } - - if (network->type != network_config::mojom::NetworkType::kWiFi) { - return false; - } - - if (!network->connectable) { - NET_LOG(EVENT) << NetworkGuidId(network->guid) - << " is not eligible, it is not connectable."; - return false; - } - - if (network->source != network_config::mojom::OncSource::kUser && - !network_metadata_store_->GetIsCreatedByUser(network->guid)) { - NET_LOG(EVENT) << NetworkGuidId(network->guid) - << " is not eligible, was not configured by user."; + if (!network || network->type != network_config::mojom::NetworkType::kWiFi) { return false; } const network_config::mojom::WiFiStatePropertiesPtr& wifi_properties = network->type_state->get_wifi(); - if (wifi_properties->security != - network_config::mojom::SecurityType::kWepPsk && - wifi_properties->security != - network_config::mojom::SecurityType::kWpaPsk) { - NET_LOG(EVENT) << NetworkGuidId(network->guid) - << " is not eligible, security type not supported: " - << wifi_properties->security; - return false; - } - - base::TimeDelta timestamp = - network_metadata_store_->GetLastConnectedTimestamp(network->guid); - if (timestamp.is_zero()) { - NET_LOG(EVENT) << NetworkGuidId(network->guid) - << " is not eligible, never connected."; - return false; - } - - NET_LOG(EVENT) << NetworkGuidId(network->guid) << " is eligible for sync."; - return true; + return IsEligibleForSync(network->guid, network->connectable, network->source, + wifi_properties->security, /*log_result=*/true); } void LocalNetworkCollectorImpl::StartGetNetworkDetails(
diff --git a/chromeos/components/sync_wifi/network_eligibility_checker.cc b/chromeos/components/sync_wifi/network_eligibility_checker.cc new file mode 100644 index 0000000..6b21eee --- /dev/null +++ b/chromeos/components/sync_wifi/network_eligibility_checker.cc
@@ -0,0 +1,74 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/components/sync_wifi/network_eligibility_checker.h" + +#include "chromeos/network/network_event_log.h" +#include "chromeos/network/network_handler.h" +#include "chromeos/network/network_metadata_store.h" +#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h" +#include "chromeos/services/network_config/public/mojom/network_types.mojom.h" + +namespace chromeos { + +namespace sync_wifi { + +bool IsEligibleForSync(const std::string& guid, + bool is_connectable, + const network_config::mojom::OncSource& onc_source, + const network_config::mojom::SecurityType& security_type, + bool log_result) { + NetworkMetadataStore* network_metadata_store = + NetworkHandler::IsInitialized() + ? NetworkHandler::Get()->network_metadata_store() + : nullptr; + if (!network_metadata_store) + return false; + + if (!is_connectable) { + if (log_result) { + NET_LOG(EVENT) << NetworkGuidId(guid) + << " is not eligible, it is not connectable."; + } + return false; + } + + if (onc_source != network_config::mojom::OncSource::kUser && + !network_metadata_store->GetIsCreatedByUser(guid)) { + if (log_result) { + NET_LOG(EVENT) << NetworkGuidId(guid) + << " is not eligible, was not configured by user."; + } + return false; + } + + if (security_type != network_config::mojom::SecurityType::kWepPsk && + security_type != network_config::mojom::SecurityType::kWpaPsk) { + if (log_result) { + NET_LOG(EVENT) << NetworkGuidId(guid) + << " is not eligible, security type not supported: " + << security_type; + } + return false; + } + + base::TimeDelta timestamp = + network_metadata_store->GetLastConnectedTimestamp(guid); + if (timestamp.is_zero()) { + if (log_result) { + NET_LOG(EVENT) << NetworkGuidId(guid) + << " is not eligible, never connected."; + } + return false; + } + + if (log_result) { + NET_LOG(EVENT) << NetworkGuidId(guid) << " is eligible for sync."; + } + return true; +} + +} // namespace sync_wifi + +} // namespace chromeos
diff --git a/chromeos/components/sync_wifi/network_eligibility_checker.h b/chromeos/components/sync_wifi/network_eligibility_checker.h new file mode 100644 index 0000000..56bb8ec0 --- /dev/null +++ b/chromeos/components/sync_wifi/network_eligibility_checker.h
@@ -0,0 +1,27 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_COMPONENTS_SYNC_WIFI_NETWORK_ELIGIBILITY_CHECKER_H_ +#define CHROMEOS_COMPONENTS_SYNC_WIFI_NETWORK_ELIGIBILITY_CHECKER_H_ + +#include <string> + +#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom-forward.h" +#include "chromeos/services/network_config/public/mojom/network_types.mojom-forward.h" + +namespace chromeos { + +namespace sync_wifi { + +bool IsEligibleForSync(const std::string& guid, + bool is_connectable, + const network_config::mojom::OncSource& onc_source, + const network_config::mojom::SecurityType& security_type, + bool log_result); + +} // namespace sync_wifi + +} // namespace chromeos + +#endif // CHROMEOS_COMPONENTS_SYNC_WIFI_NETWORK_ELIGIBILITY_CHECKER_H_
diff --git a/chromeos/constants/chromeos_features.cc b/chromeos/constants/chromeos_features.cc index a7c8d6b..0e7f6e8 100644 --- a/chromeos/constants/chromeos_features.cc +++ b/chromeos/constants/chromeos_features.cc
@@ -66,10 +66,6 @@ const base::Feature kBluetoothPhoneFilter{"BluetoothPhoneFilter", base::FEATURE_ENABLED_BY_DEFAULT}; -// Enables or disables using the kernel suspend notifier instead of powerd. -const base::Feature kBluetoothKernelSuspendNotifier{ - "BluetoothKernelSuspendNotifier", base::FEATURE_ENABLED_BY_DEFAULT}; - // If enabled, browser will notify Chrome OS audio server to register HFP 1.7 // to BlueZ, which includes wideband speech feature. const base::Feature kBluetoothNextHandsfreeProfile{ @@ -236,10 +232,6 @@ const base::Feature kInstantTethering{"InstantTethering", base::FEATURE_DISABLED_BY_DEFAULT}; -// Uses the component updater to download the lacros-chrome binary. -const base::Feature kLacrosComponentUpdater{"LacrosComponentUpdater", - base::FEATURE_DISABLED_BY_DEFAULT}; - // Enables "Linux and Chrome OS" support. Allows a Linux version of Chrome // ("lacros-chrome") to run as a Wayland client with this instance of Chrome // ("ash-chrome") acting as the Wayland server and window manager. @@ -433,11 +425,6 @@ kInstantTetheringBackgroundAdvertisementSupport); } -bool IsLacrosComponentUpdaterEnabled() { - return base::FeatureList::IsEnabled(kLacrosSupport) && - base::FeatureList::IsEnabled(kLacrosComponentUpdater); -} - bool IsLacrosSupportEnabled() { return base::FeatureList::IsEnabled(kLacrosSupport); }
diff --git a/chromeos/constants/chromeos_features.h b/chromeos/constants/chromeos_features.h index c5e65fc8..5f3ab29 100644 --- a/chromeos/constants/chromeos_features.h +++ b/chromeos/constants/chromeos_features.h
@@ -38,8 +38,6 @@ COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kBluetoothPhoneFilter; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) -extern const base::Feature kBluetoothKernelSuspendNotifier; -COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kBluetoothNextHandsfreeProfile; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kCameraSystemWebApp; @@ -108,8 +106,6 @@ extern const base::Feature kVirtualKeyboardFloatingDefault; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kInstantTethering; -COMPONENT_EXPORT(CHROMEOS_CONSTANTS) -extern const base::Feature kLacrosComponentUpdater; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kLacrosSupport; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kMediaApp; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) @@ -191,7 +187,6 @@ COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsImeDecoderWithSandboxEnabled(); COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsInstantTetheringBackgroundAdvertisingSupported(); -COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsLacrosComponentUpdaterEnabled(); COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsLacrosSupportEnabled(); COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsOobeScreensPriorityEnabled(); COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsParentalControlsSettingsEnabled();
diff --git a/chromeos/constants/chromeos_switches.cc b/chromeos/constants/chromeos_switches.cc index e1646125..00ab2593 100644 --- a/chromeos/constants/chromeos_switches.cc +++ b/chromeos/constants/chromeos_switches.cc
@@ -396,6 +396,11 @@ // chrome://flags const char kKernelnextRestrictVMs[] = "kernelnext-restrict-vms"; +// If this switch is set, then ash-chrome will exec the lacros-chrome binary +// from the indicated path rather than from component updater. Note that the +// path should be to a directory that contains a binary named 'chrome'. +const char kLacrosChromePath[] = "lacros-chrome-path"; + // Enables Chrome-as-a-login-manager behavior. const char kLoginManager[] = "login-manager";
diff --git a/chromeos/constants/chromeos_switches.h b/chromeos/constants/chromeos_switches.h index fd27c84..0b72b95 100644 --- a/chromeos/constants/chromeos_switches.h +++ b/chromeos/constants/chromeos_switches.h
@@ -161,6 +161,7 @@ COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const char kIgnoreUserProfileMappingForTests[]; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const char kKernelnextRestrictVMs[]; +COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const char kLacrosChromePath[]; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const char kLoginManager[]; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const char kLoginProfile[]; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const char kLoginUser[];
diff --git a/chromeos/dbus/dlcservice/dlcservice_client.cc b/chromeos/dbus/dlcservice/dlcservice_client.cc index 07880e71..e8cadb17 100644 --- a/chromeos/dbus/dlcservice/dlcservice_client.cc +++ b/chromeos/dbus/dlcservice/dlcservice_client.cc
@@ -37,9 +37,6 @@ namespace { -// TODO(kimjae): Delete and remove usages once system_api is uprev'ed. -const char kGetExistingDlcsMethod[] = "GetExistingDlcs"; - DlcserviceClient* g_instance = nullptr; class DlcserviceErrorResponseHandler { @@ -192,9 +189,8 @@ } TaskStarted(); - // TODO(kimjae): Use |kGetExistingDlcsMethod| once system_api is uprev'ed. dbus::MethodCall method_call(dlcservice::kDlcServiceInterface, - kGetExistingDlcsMethod); + dlcservice::kGetExistingDlcsMethod); VLOG(1) << "Requesting to get existing DLC(s)."; dlcservice_proxy_->CallMethodWithErrorResponse(
diff --git a/chromeos/dbus/dlcservice/dlcservice_client_unittest.cc b/chromeos/dbus/dlcservice/dlcservice_client_unittest.cc index 7ec93a4..eee5e38 100644 --- a/chromeos/dbus/dlcservice/dlcservice_client_unittest.cc +++ b/chromeos/dbus/dlcservice/dlcservice_client_unittest.cc
@@ -125,9 +125,8 @@ } TEST_F(DlcserviceClientTest, GetExistingDlcsFailureTest) { - // TODO(kimjae): Use |kGetExistingDlcsMethod| once system_api is uprev'ed. dbus::MethodCall method_call(dlcservice::kDlcServiceInterface, - "GetExsitingDlcs"); + dlcservice::kGetExistingDlcsMethod); method_call.SetSerial(123); err_responses_.push_back(dbus::ErrorResponse::FromMethodCall( &method_call, DBUS_ERROR_FAILED, "some-unknown-error"));
diff --git a/chromeos/resources/BUILD.gn b/chromeos/resources/BUILD.gn index d2e3d8d..b3ba0827 100644 --- a/chromeos/resources/BUILD.gn +++ b/chromeos/resources/BUILD.gn
@@ -64,9 +64,9 @@ # Resources automatically served by the chrome://help-app bundle, obtained via DEPS. grit("help_app_bundle_resources") { if (enable_cros_help_app) { - # Obtained via src-internal/DEPS. + # Obtained via an internal CIPD package in src/DEPS. source = - "../components/help_app_ui/resources/app/help_app_bundle_resources.grd" + "../components/help_app_ui/resources/prod/help_app_bundle_resources.grd" } else { source = "../components/help_app_ui/resources/mock/help_app_bundle_mock_resources.grd" }
diff --git a/chromeos/services/assistant/assistant_manager_service_impl.cc b/chromeos/services/assistant/assistant_manager_service_impl.cc index f711e767..4566d68 100644 --- a/chromeos/services/assistant/assistant_manager_service_impl.cc +++ b/chromeos/services/assistant/assistant_manager_service_impl.cc
@@ -174,8 +174,8 @@ : media_session_(std::make_unique<AssistantMediaSession>(this)), action_module_(std::make_unique<action::CrosActionModule>( this, - assistant::features::IsAppSupportEnabled(), - assistant::features::IsRoutinesEnabled())), + features::IsAppSupportEnabled(), + features::IsWaitSchedulingEnabled())), chromium_api_delegate_(std::move(pending_url_loader_factory)), assistant_settings_( std::make_unique<AssistantSettingsImpl>(context, this)), @@ -696,6 +696,7 @@ void AssistantManagerServiceImpl::OnScheduleWait(int id, int time_ms) { ENSURE_MAIN_THREAD(&AssistantManagerServiceImpl::OnScheduleWait, id, time_ms); + DCHECK(features::IsWaitSchedulingEnabled()); // Schedule a wait for |time_ms|, notifying the CrosActionModule when the wait // has finished so that it can inform LibAssistant to resume execution. @@ -1309,11 +1310,21 @@ id, duration.InSeconds()); } -void AssistantManagerServiceImpl::RemoveAlarmTimer(const std::string& id) { +void AssistantManagerServiceImpl::PauseTimer(const std::string& id) { + if (assistant_manager_internal_) + assistant_manager_internal_->GetAlarmTimerManager()->PauseTimer(id); +} + +void AssistantManagerServiceImpl::RemoveAlarmOrTimer(const std::string& id) { if (assistant_manager_internal_) assistant_manager_internal_->GetAlarmTimerManager()->RemoveEvent(id); } +void AssistantManagerServiceImpl::ResumeTimer(const std::string& id) { + if (assistant_manager_internal_) + assistant_manager_internal_->GetAlarmTimerManager()->ResumeTimer(id); +} + void AssistantManagerServiceImpl::NotifyEntryIntoAssistantUi( mojom::AssistantEntryPoint entry_point) { base::AutoLock lock(last_trigger_source_lock_);
diff --git a/chromeos/services/assistant/assistant_manager_service_impl.h b/chromeos/services/assistant/assistant_manager_service_impl.h index ab1652df..c15ac00 100644 --- a/chromeos/services/assistant/assistant_manager_service_impl.h +++ b/chromeos/services/assistant/assistant_manager_service_impl.h
@@ -160,7 +160,9 @@ void NotifyEntryIntoAssistantUi( mojom::AssistantEntryPoint entry_point) override; void AddTimeToTimer(const std::string& id, base::TimeDelta duration) override; - void RemoveAlarmTimer(const std::string& id) override; + void PauseTimer(const std::string& id) override; + void RemoveAlarmOrTimer(const std::string& id) override; + void ResumeTimer(const std::string& id) override; // AssistantActionObserver overrides: void OnScheduleWait(int id, int time_ms) override;
diff --git a/chromeos/services/assistant/fake_assistant_manager_service_impl.cc b/chromeos/services/assistant/fake_assistant_manager_service_impl.cc index 5fbe3c5..49437289 100644 --- a/chromeos/services/assistant/fake_assistant_manager_service_impl.cc +++ b/chromeos/services/assistant/fake_assistant_manager_service_impl.cc
@@ -119,7 +119,12 @@ base::TimeDelta duration) { } -void FakeAssistantManagerServiceImpl::RemoveAlarmTimer(const std::string& id) {} +void FakeAssistantManagerServiceImpl::PauseTimer(const std::string& id) {} + +void FakeAssistantManagerServiceImpl::RemoveAlarmOrTimer( + const std::string& id) {} + +void FakeAssistantManagerServiceImpl::ResumeTimer(const std::string& id) {} void FakeAssistantManagerServiceImpl::SetStateAndInformObservers( State new_state) {
diff --git a/chromeos/services/assistant/fake_assistant_manager_service_impl.h b/chromeos/services/assistant/fake_assistant_manager_service_impl.h index 8e73d4a..67b2f39 100644 --- a/chromeos/services/assistant/fake_assistant_manager_service_impl.h +++ b/chromeos/services/assistant/fake_assistant_manager_service_impl.h
@@ -76,7 +76,9 @@ void NotifyEntryIntoAssistantUi( mojom::AssistantEntryPoint entry_point) override; void AddTimeToTimer(const std::string& id, base::TimeDelta duration) override; - void RemoveAlarmTimer(const std::string& id) override; + void PauseTimer(const std::string& id) override; + void RemoveAlarmOrTimer(const std::string& id) override; + void ResumeTimer(const std::string& id) override; // Update the state to the corresponding value, and inform the // |AssistantStateObserver| of the change.
diff --git a/chromeos/services/assistant/public/cpp/features.cc b/chromeos/services/assistant/public/cpp/features.cc index fa7bcc8..82e5fc1 100644 --- a/chromeos/services/assistant/public/cpp/features.cc +++ b/chromeos/services/assistant/public/cpp/features.cc
@@ -81,6 +81,9 @@ const base::Feature kAssistantTimersV2{"AssistantTimersV2", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kAssistantWaitScheduling{"AssistantWaitScheduling", + base::FEATURE_ENABLED_BY_DEFAULT}; + const base::Feature kEnableClearCutLog{"EnableClearCutLog", base::FEATURE_DISABLED_BY_DEFAULT}; @@ -200,14 +203,20 @@ return base::FeatureList::IsEnabled(kAssistantTimersV2); } -bool IsWarmerWelcomeEnabled() { - return base::FeatureList::IsEnabled(kAssistantWarmerWelcomeFeature); -} - bool IsVoiceMatchDisabled() { return base::FeatureList::IsEnabled(kDisableVoiceMatch); } +bool IsWaitSchedulingEnabled() { + // Wait scheduling is only supported for response processing v2 and routines. + return base::FeatureList::IsEnabled(kAssistantWaitScheduling) && + (IsResponseProcessingV2Enabled() || IsRoutinesEnabled()); +} + +bool IsWarmerWelcomeEnabled() { + return base::FeatureList::IsEnabled(kAssistantWarmerWelcomeFeature); +} + } // namespace features } // namespace assistant } // namespace chromeos
diff --git a/chromeos/services/assistant/public/cpp/features.h b/chromeos/services/assistant/public/cpp/features.h index 039b977..342c71f 100644 --- a/chromeos/services/assistant/public/cpp/features.h +++ b/chromeos/services/assistant/public/cpp/features.h
@@ -72,6 +72,13 @@ COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) extern const base::Feature kAssistantTimersV2; +// Enables server-driven wait scheduling. This allows the server to inject +// pauses into the interaction response to give the user time to digest one leg +// of a routine before proceeding to the next, for example, or to provide +// comedic timing for jokes. +COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) +extern const base::Feature kAssistantWaitScheduling; + // Enables clear cut logging. COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) extern const base::Feature kEnableClearCutLog; @@ -155,10 +162,12 @@ COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) bool IsTimersV2Enabled(); -COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) bool IsWarmerWelcomeEnabled(); - COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) bool IsVoiceMatchDisabled(); +COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) bool IsWaitSchedulingEnabled(); + +COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) bool IsWarmerWelcomeEnabled(); + } // namespace features } // namespace assistant } // namespace chromeos
diff --git a/chromeos/services/assistant/public/mojom/assistant.mojom b/chromeos/services/assistant/public/mojom/assistant.mojom index 07b7866..3bedfaad 100644 --- a/chromeos/services/assistant/public/mojom/assistant.mojom +++ b/chromeos/services/assistant/public/mojom/assistant.mojom
@@ -95,9 +95,19 @@ // this method is a no-op if there is no existing timer identified by |id|. AddTimeToTimer(string id, mojo_base.mojom.TimeDelta duration); + // Pauses the timer specified by |id|. Note that this method is a no-op if + // there is no existing timer identified by |id| or if a timer does exist but + // is already paused. + PauseTimer(string id); + // Remove the alarm/timer specified by |id|. // NOTE: this is a no-op if no such alarm/timer exists. - RemoveAlarmTimer(string id); + RemoveAlarmOrTimer(string id); + + // Resumes the timer specified by |id|. Note that this method is a no-op if + // there is no existing timer identified by |id| or if a timer does exist but + // isn't currently paused. + ResumeTimer(string id); }; // Enumeration of Assistant entry points. These values are persisted to logs.
diff --git a/chromeos/services/network_config/BUILD.gn b/chromeos/services/network_config/BUILD.gn index cb8be1428..31fc049 100644 --- a/chromeos/services/network_config/BUILD.gn +++ b/chromeos/services/network_config/BUILD.gn
@@ -12,6 +12,7 @@ deps = [ "//base", + "//chromeos/components/sync_wifi:network_eligibility_checker", "//chromeos/login/login_state", "//chromeos/network", "//chromeos/services/network_config/public/cpp",
diff --git a/chromeos/services/network_config/cros_network_config.cc b/chromeos/services/network_config/cros_network_config.cc index 298a527..fb13ee9 100644 --- a/chromeos/services/network_config/cros_network_config.cc +++ b/chromeos/services/network_config/cros_network_config.cc
@@ -5,12 +5,14 @@ #include "chromeos/services/network_config/cros_network_config.h" #include "base/strings/string_util.h" +#include "chromeos/components/sync_wifi/network_eligibility_checker.h" #include "chromeos/login/login_state/login_state.h" #include "chromeos/network/device_state.h" #include "chromeos/network/managed_network_configuration_handler.h" #include "chromeos/network/network_connection_handler.h" #include "chromeos/network/network_device_handler.h" #include "chromeos/network/network_handler.h" +#include "chromeos/network/network_metadata_store.h" #include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" #include "chromeos/network/network_type_pattern.h" @@ -1405,6 +1407,10 @@ wifi->signal_strength = GetInt32(wifi_dict, ::onc::wifi::kSignalStrength); wifi->tethering_state = GetString(wifi_dict, ::onc::wifi::kTetheringState); + wifi->is_syncable = sync_wifi::IsEligibleForSync( + result->guid, result->connectable, result->source, wifi->security, + /*log_result=*/false); + result->type_properties = mojom::NetworkTypeManagedProperties::NewWifi(std::move(wifi)); break;
diff --git a/chromeos/services/network_config/cros_network_config_unittest.cc b/chromeos/services/network_config/cros_network_config_unittest.cc index 3c6170da..646feee8b 100644 --- a/chromeos/services/network_config/cros_network_config_unittest.cc +++ b/chromeos/services/network_config/cros_network_config_unittest.cc
@@ -19,6 +19,7 @@ #include "chromeos/network/network_configuration_handler.h" #include "chromeos/network/network_connection_handler.h" #include "chromeos/network/network_device_handler.h" +#include "chromeos/network/network_metadata_store.h" #include "chromeos/network/network_profile_handler.h" #include "chromeos/network/network_state_handler.h" #include "chromeos/network/network_state_test_helper.h" @@ -51,6 +52,7 @@ CrosNetworkConfigTest() { LoginState::Initialize(); NetworkCertLoader::Initialize(); + NetworkHandler::Initialize(); network_profile_handler_ = NetworkProfileHandler::InitializeForTesting(); network_device_handler_ = NetworkDeviceHandler::InitializeForTesting( helper_.network_state_handler()); @@ -64,6 +66,9 @@ PrefProxyConfigTrackerImpl::RegisterPrefs(local_state_.registry()); ::onc::RegisterProfilePrefs(user_prefs_.registry()); ::onc::RegisterPrefs(local_state_.registry()); + NetworkMetadataStore::RegisterPrefs(user_prefs_.registry()); + NetworkMetadataStore::RegisterPrefs(local_state_.registry()); + NetworkHandler::Get()->InitializePrefServices(&user_prefs_, &local_state_); ui_proxy_config_service_ = std::make_unique<chromeos::UIProxyConfigService>( &user_prefs_, &local_state_, helper_.network_state_handler(), @@ -98,6 +103,7 @@ network_device_handler_.reset(); network_profile_handler_.reset(); ui_proxy_config_service_.reset(); + NetworkHandler::Shutdown(); NetworkCertLoader::Shutdown(); LoginState::Shutdown(); } @@ -172,6 +178,15 @@ "Visible": false})"); helper().profile_test()->AddService( NetworkProfileHandler::GetSharedProfilePath(), wifi3_path); + + // Syncable wifi network: + std::string service_path = helper().ConfigureService( + R"({"GUID": "wifi4_guid", "Type": "wifi", "SSID": "wifi4", + "State": "idle", "SecurityClass": "psk", "Strength": 100, + "Profile": "user_profile_path", "Connectable": true})"); + NetworkHandler::Get()->network_metadata_store()->ConnectSucceeded( + service_path); + base::RunLoop().RunUntilIdle(); } @@ -561,24 +576,27 @@ filter->network_type = mojom::NetworkType::kWiFi; filter->limit = mojom::kNoLimit; networks = GetNetworkStateList(filter.Clone()); - ASSERT_EQ(3u, networks.size()); + ASSERT_EQ(4u, networks.size()); EXPECT_EQ("wifi1_guid", networks[0]->guid); EXPECT_EQ("wifi2_guid", networks[1]->guid); - EXPECT_EQ("wifi3_guid", networks[2]->guid); + EXPECT_EQ("wifi4_guid", networks[2]->guid); + EXPECT_EQ("wifi3_guid", networks[3]->guid); // Visible wifi networks filter->filter = mojom::FilterType::kVisible; networks = GetNetworkStateList(filter.Clone()); - ASSERT_EQ(2u, networks.size()); + ASSERT_EQ(3u, networks.size()); EXPECT_EQ("wifi1_guid", networks[0]->guid); EXPECT_EQ("wifi2_guid", networks[1]->guid); + EXPECT_EQ("wifi4_guid", networks[2]->guid); // Configured wifi networks filter->filter = mojom::FilterType::kConfigured; networks = GetNetworkStateList(filter.Clone()); - ASSERT_EQ(2u, networks.size()); + ASSERT_EQ(3u, networks.size()); EXPECT_EQ("wifi2_guid", networks[0]->guid); - EXPECT_EQ("wifi3_guid", networks[1]->guid); + EXPECT_EQ("wifi4_guid", networks[1]->guid); + EXPECT_EQ("wifi3_guid", networks[2]->guid); } TEST_F(CrosNetworkConfigTest, GetDeviceStateList) { @@ -639,6 +657,7 @@ ASSERT_TRUE(properties->type_properties->is_wifi()); EXPECT_EQ(50, properties->type_properties->get_wifi()->signal_strength); EXPECT_EQ(mojom::OncSource::kNone, properties->source); + EXPECT_EQ(false, properties->type_properties->get_wifi()->is_syncable); properties = GetManagedProperties("wifi2_guid"); ASSERT_TRUE(properties); @@ -653,6 +672,7 @@ EXPECT_EQ(mojom::SecurityType::kWpaPsk, wifi->security); EXPECT_EQ(100, wifi->signal_strength); EXPECT_EQ(mojom::OncSource::kUserPolicy, properties->source); + EXPECT_EQ(false, properties->type_properties->get_wifi()->is_syncable); properties = GetManagedProperties("wifi3_guid"); ASSERT_TRUE(properties); @@ -661,6 +681,16 @@ EXPECT_EQ(mojom::ConnectionStateType::kNotConnected, properties->connection_state); EXPECT_EQ(mojom::OncSource::kDevice, properties->source); + EXPECT_EQ(false, properties->type_properties->get_wifi()->is_syncable); + + properties = GetManagedProperties("wifi4_guid"); + ASSERT_TRUE(properties); + EXPECT_EQ("wifi4_guid", properties->guid); + EXPECT_EQ(mojom::NetworkType::kWiFi, properties->type); + EXPECT_EQ(mojom::ConnectionStateType::kNotConnected, + properties->connection_state); + EXPECT_EQ(mojom::OncSource::kUser, properties->source); + EXPECT_EQ(true, properties->type_properties->get_wifi()->is_syncable); properties = GetManagedProperties("cellular_guid"); ASSERT_TRUE(properties);
diff --git a/chromeos/services/network_config/public/mojom/cros_network_config.mojom b/chromeos/services/network_config/public/mojom/cros_network_config.mojom index 11336ecb6..02d6cab 100644 --- a/chromeos/services/network_config/public/mojom/cros_network_config.mojom +++ b/chromeos/services/network_config/public/mojom/cros_network_config.mojom
@@ -545,6 +545,8 @@ SecurityType security; int32 signal_strength = 0; string? tethering_state; + // Indicates whether the network is eligible to be included in Chrome Sync. + bool is_syncable; }; union NetworkTypeManagedProperties {
diff --git a/components/arc/mojom/app.mojom b/components/arc/mojom/app.mojom index aa5d040..25ff611 100644 --- a/components/arc/mojom/app.mojom +++ b/components/arc/mojom/app.mojom
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Next MinVersion: 45 +// Next MinVersion: 46 module arc.mojom; @@ -43,6 +43,9 @@ // If the web app is tied to a web-only TWA. [MinVersion=44] bool is_web_only_twa; + + // SHA256 fingerprint of the APK the web app belongs to. + [MinVersion=45] string? certificate_sha256_fingerprint; }; // Describes ARC package.
diff --git a/components/arc/mojom/intent_helper.mojom b/components/arc/mojom/intent_helper.mojom index a7791f6..3be1655 100644 --- a/components/arc/mojom/intent_helper.mojom +++ b/components/arc/mojom/intent_helper.mojom
@@ -171,7 +171,7 @@ ETHERNET, CELLULAR, AMBIENTMODE, - PLUGINVMDETAILS, + DEPRECATED_PLUGINVMDETAILS, PLUGINVMSHAREDPATHS, OSACCESSIBILITY, OSLANGUAGES,
diff --git a/components/arc/session/arc_data_remover.cc b/components/arc/session/arc_data_remover.cc index 40ae810b..d39ef987 100644 --- a/components/arc/session/arc_data_remover.cc +++ b/components/arc/session/arc_data_remover.cc
@@ -4,25 +4,16 @@ #include "components/arc/session/arc_data_remover.h" +#include <string> #include <utility> #include "base/bind.h" #include "base/callback_helpers.h" #include "base/logging.h" -#include "chromeos/dbus/dbus_thread_manager.h" -#include "chromeos/dbus/debug_daemon/debug_daemon_client.h" #include "chromeos/dbus/upstart/upstart_client.h" #include "components/arc/arc_prefs.h" -#include "components/arc/arc_util.h" namespace arc { -namespace { - -chromeos::ConciergeClient* GetConciergeClient() { - return chromeos::DBusThreadManager::Get()->GetConciergeClient(); -} - -} // namespace // The conversion of upstart job names to dbus object paths is undocumented. See // function nih_dbus_path in libnih for the implementation. @@ -54,16 +45,6 @@ return; } - // TODO(yusukes): Stop special-casing ARCVM once we use virtio-fs for - // exporting /data. - if (IsArcVmEnabled()) { - VLOG(1) << "Starting ARCVM data removal"; - chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()->StartConcierge( - base::BindOnce(&ArcDataRemover::OnConciergeStarted, - weak_factory_.GetWeakPtr(), std::move(callback))); - return; - } - VLOG(1) << "Starting ARC data removal"; auto* upstart_client = chromeos::UpstartClient::Get(); if (!upstart_client) { @@ -95,35 +76,4 @@ std::move(callback).Run(success); } -void ArcDataRemover::OnConciergeStarted(RunCallback callback, bool success) { - if (!success) { - LOG(ERROR) << "Failed to start Concierge service for arcvm"; - OnDataRemoved(std::move(callback), false); - return; - } - vm_tools::concierge::DestroyDiskImageRequest request; - request.set_cryptohome_id(user_id_hash_); - request.set_disk_path(kArcVmName); - GetConciergeClient()->DestroyDiskImage( - std::move(request), - base::BindOnce(&ArcDataRemover::OnDiskImageDestroyed, - weak_factory_.GetWeakPtr(), std::move(callback))); -} - -void ArcDataRemover::OnDiskImageDestroyed( - RunCallback callback, - base::Optional<vm_tools::concierge::DestroyDiskImageResponse> reply) { - if (!reply) { - LOG(ERROR) << "Failed to destroy disk image. Empty response."; - OnDataRemoved(std::move(callback), false); - return; - } - if (reply->status() != vm_tools::concierge::DISK_STATUS_DESTROYED) { - LOG(ERROR) << "Failed to destroy disk image: " << reply->failure_reason(); - OnDataRemoved(std::move(callback), false); - return; - } - OnDataRemoved(std::move(callback), true); -} - } // namespace arc
diff --git a/components/arc/session/arc_data_remover.h b/components/arc/session/arc_data_remover.h index 187e613..c18a823 100644 --- a/components/arc/session/arc_data_remover.h +++ b/components/arc/session/arc_data_remover.h
@@ -5,15 +5,12 @@ #ifndef COMPONENTS_ARC_SESSION_ARC_DATA_REMOVER_H_ #define COMPONENTS_ARC_SESSION_ARC_DATA_REMOVER_H_ -#include <string> - #include "base/callback.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/optional.h" #include "base/threading/thread_checker.h" #include "chromeos/cryptohome/cryptohome_parameters.h" -#include "chromeos/dbus/concierge_client.h" #include "components/prefs/pref_member.h" class PrefService; @@ -40,20 +37,9 @@ using RunCallback = base::OnceCallback<void(base::Optional<bool> result)>; void Run(RunCallback callback); - // TODO(yusukes): Remove the setter. - void set_user_id_hash_for_profile(const std::string& user_id_hash) { - user_id_hash_ = user_id_hash; - } - private: void OnDataRemoved(RunCallback callback, bool success); - // TODO(yusukes): Remove these ARCVM functions. - void OnConciergeStarted(RunCallback callback, bool success); - void OnDiskImageDestroyed( - RunCallback callback, - base::Optional<vm_tools::concierge::DestroyDiskImageResponse> reply); - THREAD_CHECKER(thread_checker_); // Pref accessor to the "arc.data.remove_requested". @@ -62,9 +48,6 @@ // Cryptohome ID for the user whose /data is being deleted. const cryptohome::Identification cryptohome_id_; - // TODO(yusukes): Remove the member variable. - std::string user_id_hash_; - base::WeakPtrFactory<ArcDataRemover> weak_factory_{this}; DISALLOW_COPY_AND_ASSIGN(ArcDataRemover); };
diff --git a/components/arc/session/arc_property_util.cc b/components/arc/session/arc_property_util.cc index e18cc33..9b6498c5 100644 --- a/components/arc/session/arc_property_util.cc +++ b/components/arc/session/arc_property_util.cc
@@ -214,6 +214,25 @@ return true; } +bool ExpandPropertyFile(const base::FilePath& input, + const base::FilePath& output, + CrosConfig* config) { + std::string content; + std::string expanded; + if (!base::ReadFileToString(input, &content)) { + PLOG(ERROR) << "Failed to read " << input; + return false; + } + if (!ExpandPropertyContents(content, config, &expanded)) + return false; + if (base::WriteFile(output, expanded.data(), expanded.size()) != + static_cast<int>(expanded.size())) { + PLOG(ERROR) << "Failed to write to " << output; + return false; + } + return true; +} + } // namespace CrosConfig::CrosConfig() { @@ -265,23 +284,10 @@ return TruncateAndroidProperty(line, truncated); } -bool ExpandPropertyFile(const base::FilePath& input, - const base::FilePath& output, - CrosConfig* config) { - std::string content; - std::string expanded; - if (!base::ReadFileToString(input, &content)) { - PLOG(ERROR) << "Failed to read " << input; - return false; - } - if (!ExpandPropertyContents(content, config, &expanded)) - return false; - if (base::WriteFile(output, expanded.data(), expanded.size()) != - static_cast<int>(expanded.size())) { - PLOG(ERROR) << "Failed to write to " << output; - return false; - } - return true; +bool ExpandPropertyFileForTesting(const base::FilePath& input, + const base::FilePath& output, + CrosConfig* config) { + return ExpandPropertyFile(input, output, config); } bool ExpandPropertyFiles(const base::FilePath& source_path,
diff --git a/components/arc/session/arc_property_util.h b/components/arc/session/arc_property_util.h index ab43bb6..ce780cf 100644 --- a/components/arc/session/arc_property_util.h +++ b/components/arc/session/arc_property_util.h
@@ -53,9 +53,9 @@ // Expands properties (i.e. {property-name}) in |input| with the dictionary // |config| provides, and writes the results to |output|. Returns true if the // output file is successfully written. -bool ExpandPropertyFile(const base::FilePath& input, - const base::FilePath& output, - CrosConfig* config); +bool ExpandPropertyFileForTesting(const base::FilePath& input, + const base::FilePath& output, + CrosConfig* config); // Calls ExpandPropertyFile for {build,default}.prop files in |source_path|. // Expanded files are written in |dest_path|. Returns true on success.
diff --git a/components/arc/session/arc_property_util_unittest.cc b/components/arc/session/arc_property_util_unittest.cc index 1af9f71..29e8a5e 100644 --- a/components/arc/session/arc_property_util_unittest.cc +++ b/components/arc/session/arc_property_util_unittest.cc
@@ -211,10 +211,10 @@ base::WriteFile(path, kValidProp, strlen(kValidProp)); const base::FilePath dest = GetTempDir().Append("new.prop"); - EXPECT_TRUE(ExpandPropertyFile(path, dest, config())); + EXPECT_TRUE(ExpandPropertyFileForTesting(path, dest, config())); std::string content; EXPECT_TRUE(base::ReadFileToString(dest, &content)); - // Note: ExpandPropertyFile() adds a trailing LF. + // Note: ExpandPropertyFileForTesting() adds a trailing LF. EXPECT_EQ(std::string(kValidProp) + "\n", content); } @@ -230,10 +230,10 @@ base::WriteFile(path, kValidProp, strlen(kValidProp)); const base::FilePath dest = GetTempDir().Append("new.prop"); - EXPECT_TRUE(ExpandPropertyFile(path, dest, config())); + EXPECT_TRUE(ExpandPropertyFileForTesting(path, dest, config())); std::string content; EXPECT_TRUE(base::ReadFileToString(dest, &content)); - // Note: ExpandPropertyFile() adds a trailing LF. + // Note: ExpandPropertyFileForTesting() adds a trailing LF. EXPECT_EQ("ro.foo=v1\nro.baz=v2\n", content); } @@ -249,10 +249,10 @@ base::WriteFile(path, kValidProp, strlen(kValidProp)); const base::FilePath dest = GetTempDir().Append("new.prop"); - EXPECT_TRUE(ExpandPropertyFile(path, dest, config())); + EXPECT_TRUE(ExpandPropertyFileForTesting(path, dest, config())); std::string content; EXPECT_TRUE(base::ReadFileToString(dest, &content)); - // Note: ExpandPropertyFile() adds a trailing LF. + // Note: ExpandPropertyFileForTesting() adds a trailing LF. EXPECT_EQ("ro.foo=v2\nro.baz=v2\n", content); } @@ -264,14 +264,15 @@ ASSERT_TRUE(CreateTemporaryFileInDir(GetTempDir(), &path)); base::WriteFile(path, kValidProp, strlen(kValidProp)); const base::FilePath dest = GetTempDir().Append("new.prop"); - EXPECT_FALSE(ExpandPropertyFile(path, dest, config())); + EXPECT_FALSE(ExpandPropertyFileForTesting(path, dest, config())); } // Test that ExpandPropertyFile handles the case where the input file is not // found. TEST_F(ArcPropertyUtilTest, ExpandPropertyFile_NoSourceFile) { - EXPECT_FALSE(ExpandPropertyFile(base::FilePath("/nonexistent"), - base::FilePath("/nonexistent2"), config())); + EXPECT_FALSE(ExpandPropertyFileForTesting(base::FilePath("/nonexistent"), + base::FilePath("/nonexistent2"), + config())); } // Test that ExpandPropertyFile handles the case where the output file cannot @@ -281,8 +282,8 @@ base::FilePath path; ASSERT_TRUE(CreateTemporaryFileInDir(GetTempDir(), &path)); base::WriteFile(path, kValidProp, strlen(kValidProp)); - EXPECT_FALSE( - ExpandPropertyFile(path, base::FilePath("/nonexistent2"), config())); + EXPECT_FALSE(ExpandPropertyFileForTesting( + path, base::FilePath("/nonexistent2"), config())); } TEST_F(ArcPropertyUtilTest, ExpandPropertyFiles_NoSource) { @@ -322,7 +323,7 @@ EXPECT_TRUE(base::PathExists(dest_dir.Append("vendor_build.prop"))); // Verify their content. - // Note: ExpandPropertyFile() adds a trailing LF. + // Note: ExpandPropertyFileForTesting() adds a trailing LF. std::string content; EXPECT_TRUE( base::ReadFileToString(dest_dir.Append("default.prop"), &content));
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn index e7cd75c9b..d614370e 100644 --- a/components/autofill/core/browser/BUILD.gn +++ b/components/autofill/core/browser/BUILD.gn
@@ -104,6 +104,7 @@ "data_model/test_data_creator.h", "field_filler.cc", "field_filler.h", + "field_types.cc", "field_types.h", "form_data_importer.cc", "form_data_importer.h",
diff --git a/components/autofill/core/browser/autofill_field.cc b/components/autofill/core/browser/autofill_field.cc index bd06fa6..ca7737f 100644 --- a/components/autofill/core/browser/autofill_field.cc +++ b/components/autofill/core/browser/autofill_field.cc
@@ -178,7 +178,11 @@ } bool AutofillField::IsFieldFillable() const { - return !Type().IsUnknown(); + if (!base::FeatureList::IsEnabled(features::kAutofillFixFillableFieldTypes)) + return !Type().IsUnknown(); + + ServerFieldType field_type = Type().GetStorableType(); + return IsFillableFieldType(field_type); } void AutofillField::SetPasswordRequirements(PasswordRequirementsSpec spec) {
diff --git a/components/autofill/core/browser/field_types.cc b/components/autofill/core/browser/field_types.cc new file mode 100644 index 0000000..d734b327 --- /dev/null +++ b/components/autofill/core/browser/field_types.cc
@@ -0,0 +1,131 @@ +// 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/autofill/core/browser/field_types.h" + +#include "base/notreached.h" +#include "components/autofill/core/common/autofill_features.h" + +namespace autofill { + +bool IsFillableFieldType(ServerFieldType field_type) { + switch (field_type) { + case NAME_FIRST: + case NAME_MIDDLE: + case NAME_LAST: + case NAME_MIDDLE_INITIAL: + case NAME_FULL: + case NAME_SUFFIX: + case EMAIL_ADDRESS: + case USERNAME_AND_EMAIL_ADDRESS: + case PHONE_HOME_NUMBER: + case PHONE_HOME_CITY_CODE: + case PHONE_HOME_COUNTRY_CODE: + case PHONE_HOME_CITY_AND_NUMBER: + case PHONE_HOME_WHOLE_NUMBER: + case PHONE_HOME_EXTENSION: + case ADDRESS_HOME_LINE1: + case ADDRESS_HOME_LINE2: + case ADDRESS_HOME_LINE3: + case ADDRESS_HOME_APT_NUM: + case ADDRESS_HOME_CITY: + case ADDRESS_HOME_STATE: + case ADDRESS_HOME_ZIP: + case ADDRESS_HOME_COUNTRY: + case ADDRESS_HOME_STREET_ADDRESS: + case ADDRESS_HOME_SORTING_CODE: + case ADDRESS_HOME_DEPENDENT_LOCALITY: + case ADDRESS_HOME_STREET: + case ADDRESS_HOME_HOUSE_NUMBER: + case ADDRESS_HOME_FLOOR: + case ADDRESS_HOME_OTHER_SUBUNIT: + return true; + + // Billing address types that should not be returned by GetStorableType(). + case NAME_BILLING_FIRST: + case NAME_BILLING_MIDDLE: + case NAME_BILLING_LAST: + case NAME_BILLING_MIDDLE_INITIAL: + case NAME_BILLING_FULL: + case NAME_BILLING_SUFFIX: + case PHONE_BILLING_NUMBER: + case PHONE_BILLING_CITY_CODE: + case PHONE_BILLING_COUNTRY_CODE: + case PHONE_BILLING_CITY_AND_NUMBER: + case PHONE_BILLING_WHOLE_NUMBER: + case ADDRESS_BILLING_LINE1: + case ADDRESS_BILLING_LINE2: + case ADDRESS_BILLING_LINE3: + case ADDRESS_BILLING_APT_NUM: + case ADDRESS_BILLING_CITY: + case ADDRESS_BILLING_STATE: + case ADDRESS_BILLING_ZIP: + case ADDRESS_BILLING_COUNTRY: + case ADDRESS_BILLING_STREET_ADDRESS: + case ADDRESS_BILLING_SORTING_CODE: + case ADDRESS_BILLING_DEPENDENT_LOCALITY: + NOTREACHED(); + return false; + + case CREDIT_CARD_NAME_FULL: + case CREDIT_CARD_NAME_FIRST: + case CREDIT_CARD_NAME_LAST: + case CREDIT_CARD_NUMBER: + case CREDIT_CARD_EXP_MONTH: + case CREDIT_CARD_EXP_2_DIGIT_YEAR: + case CREDIT_CARD_EXP_4_DIGIT_YEAR: + case CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR: + case CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR: + case CREDIT_CARD_TYPE: + case CREDIT_CARD_VERIFICATION_CODE: + return true; + + case UPI_VPA: + return base::FeatureList::IsEnabled(features::kAutofillSaveAndFillVPA); + + case COMPANY_NAME: + return base::FeatureList::IsEnabled(features::kAutofillEnableCompanyName); + + // Fillable credential fields. + case USERNAME: + case PASSWORD: + case ACCOUNT_CREATION_PASSWORD: + case CONFIRMATION_PASSWORD: + case SINGLE_USERNAME: + return true; + + // Not fillable credential fields. + case NOT_PASSWORD: + case NOT_USERNAME: + return false; + + // Credential field types that the server should never return as + // classifications. + case NOT_ACCOUNT_CREATION_PASSWORD: + case NEW_PASSWORD: + case PROBABLY_NEW_PASSWORD: + case NOT_NEW_PASSWORD: + return false; + + case NO_SERVER_DATA: + case EMPTY_TYPE: + case AMBIGUOUS_TYPE: + case PHONE_FAX_NUMBER: + case PHONE_FAX_CITY_CODE: + case PHONE_FAX_COUNTRY_CODE: + case PHONE_FAX_CITY_AND_NUMBER: + case PHONE_FAX_WHOLE_NUMBER: + case FIELD_WITH_DEFAULT_VALUE: + case MERCHANT_EMAIL_SIGNUP: + case MERCHANT_PROMO_CODE: + case PRICE: + case SEARCH_TERM: + case UNKNOWN_TYPE: + case MAX_VALID_FIELD_TYPE: + return false; + } + return false; +} + +} // namespace autofill
diff --git a/components/autofill/core/browser/field_types.h b/components/autofill/core/browser/field_types.h index e874de0c..b8964f24 100644 --- a/components/autofill/core/browser/field_types.h +++ b/components/autofill/core/browser/field_types.h
@@ -311,6 +311,9 @@ typedef std::set<ServerFieldType> ServerFieldTypeSet; +// Returns whether the field can be filled with data. +bool IsFillableFieldType(ServerFieldType field_type); + } // namespace autofill #endif // COMPONENTS_AUTOFILL_CORE_BROWSER_FIELD_TYPES_H_
diff --git a/components/autofill/core/browser/form_parsing/form_field.cc b/components/autofill/core/browser/form_parsing/form_field.cc index cdf5a7ff..3ecfdf4 100644 --- a/components/autofill/core/browser/form_parsing/form_field.cc +++ b/components/autofill/core/browser/form_parsing/form_field.cc
@@ -16,6 +16,7 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "components/autofill/core/browser/autofill_field.h" +#include "components/autofill/core/browser/autofill_type.h" #include "components/autofill/core/browser/form_parsing/address_field.h" #include "components/autofill/core/browser/form_parsing/autofill_scanner.h" #include "components/autofill/core/browser/form_parsing/credit_card_field.h" @@ -28,6 +29,7 @@ #include "components/autofill/core/browser/form_structure.h" #include "components/autofill/core/browser/logging/log_manager.h" #include "components/autofill/core/common/autofill_constants.h" +#include "components/autofill/core/common/autofill_features.h" #include "components/autofill/core/common/autofill_internals/log_message.h" #include "components/autofill/core/common/autofill_internals/logging_scope.h" #include "components/autofill/core/common/autofill_regexes.h" @@ -103,16 +105,48 @@ ParseFormFieldsPass(SearchField::Parse, processed_fields, &field_candidates, log_manager); + size_t fillable_fields = 0; + if (base::FeatureList::IsEnabled(features::kAutofillFixFillableFieldTypes)) { + for (const auto& candidate : field_candidates) { + if (IsFillableFieldType(candidate.second.BestHeuristicType())) + ++fillable_fields; + } + } else { + fillable_fields = field_candidates.size(); + } + // Do not autofill a form if there aren't enough fields. Otherwise, it is // very easy to have false positives. See http://crbug.com/447332 // For <form> tags, make an exception for email fields, which are commonly // the only recognized field on account registration sites. const bool accept_parsing = - field_candidates.size() >= MinRequiredFieldsForHeuristics() || + fillable_fields >= MinRequiredFieldsForHeuristics() || (is_form_tag && email_count > 0); - if (!accept_parsing) + if (!accept_parsing) { + if (log_manager) { + LogBuffer table_rows; + for (const auto& field : fields) { + table_rows << Tr{} << "Field:" << *field; + } + for (const auto& candidate : field_candidates) { + LogBuffer name; + name << "Type candidate for: " << candidate.first; + LogBuffer description; + ServerFieldType field_type = candidate.second.BestHeuristicType(); + description << "BestHeuristicType: " + << AutofillType::ServerFieldTypeToString(field_type) + << ", is fillable: " << IsFillableFieldType(field_type); + table_rows << Tr{} << std::move(name) << std::move(description); + } + log_manager->Log() + << LoggingScope::kParsing + << LogMessage::kLocalHeuristicDidNotFindEnoughFillableFields + << Tag{"table"} << Attrib{"class", "form"} << std::move(table_rows) + << CTag{"table"}; + } field_candidates.clear(); + } return field_candidates; }
diff --git a/components/autofill/core/browser/form_parsing/form_field_unittest.cc b/components/autofill/core/browser/form_parsing/form_field_unittest.cc index b00699ef..09a0a05 100644 --- a/components/autofill/core/browser/form_parsing/form_field_unittest.cc +++ b/components/autofill/core/browser/form_parsing/form_field_unittest.cc
@@ -14,6 +14,7 @@ #include "testing/gtest/include/gtest/gtest.h" using autofill::features::kAutofillEnforceMinRequiredFieldsForHeuristics; +using autofill::features::kAutofillFixFillableFieldTypes; using base::ASCIIToUTF16; namespace autofill { @@ -194,4 +195,57 @@ } } +// Test that the minimum number of required fields for the heuristics considers +// whether a field is actually fillable. +TEST(FormFieldTest, ParseFormFieldEnforceMinFillableFields) { + std::vector<std::unique_ptr<AutofillField>> fields; + FormFieldData field_data; + field_data.form_control_type = "text"; + + field_data.label = ASCIIToUTF16("Address line 1"); + fields.push_back( + std::make_unique<AutofillField>(field_data, field_data.label)); + + field_data.label = ASCIIToUTF16("Address line 2"); + fields.push_back( + std::make_unique<AutofillField>(field_data, field_data.label)); + + // Don't parse forms with 2 fields. + { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature( + kAutofillEnforceMinRequiredFieldsForHeuristics); + EXPECT_EQ(0u, FormField::ParseFormFields(fields, true).size()); + } + + field_data.label = ASCIIToUTF16("Search"); + fields.push_back( + std::make_unique<AutofillField>(field_data, field_data.label)); + + // Before the fix in kAutofillFixFillableFieldTypes, we would parse the form + // now, although a search field is not fillable. + { + base::test::ScopedFeatureList feature_list; + feature_list.InitWithFeatures( + /*enabled_features=*/ + {kAutofillEnforceMinRequiredFieldsForHeuristics}, + /*disabled_features=*/{kAutofillFixFillableFieldTypes}); + EXPECT_EQ(3u, FormField::ParseFormFields(fields, true).size()); + } + + // With the fix, we don't parse the form because search fields are not + // fillable (therefore, the form has only 2 fillable fields). + { + base::test::ScopedFeatureList feature_list; + feature_list.InitWithFeatures( + /*enabled_features=*/ + {kAutofillEnforceMinRequiredFieldsForHeuristics, + kAutofillFixFillableFieldTypes}, + /*disabled_features=*/{}); + const FieldCandidatesMap field_candidates_map = + FormField::ParseFormFields(fields, true); + EXPECT_EQ(0u, FormField::ParseFormFields(fields, true).size()); + } +} + } // namespace autofill
diff --git a/components/autofill/core/browser/payments/credit_card_fido_authenticator.cc b/components/autofill/core/browser/payments/credit_card_fido_authenticator.cc index d1eb0697..1260d1ca 100644 --- a/components/autofill/core/browser/payments/credit_card_fido_authenticator.cc +++ b/components/autofill/core/browser/payments/credit_card_fido_authenticator.cc
@@ -123,13 +123,15 @@ void CreditCardFIDOAuthenticator::IsUserVerifiable( base::OnceCallback<void(bool)> callback) { - if (base::FeatureList::IsEnabled( - features::kAutofillCreditCardAuthentication)) { - authenticator()->IsUserVerifyingPlatformAuthenticatorAvailable( - std::move(callback)); - } else { + if (!base::FeatureList::IsEnabled( + features::kAutofillCreditCardAuthentication) || + !authenticator()) { std::move(callback).Run(false); + return; } + + authenticator()->IsUserVerifyingPlatformAuthenticatorAvailable( + std::move(callback)); } bool CreditCardFIDOAuthenticator::IsUserOptedIn() { @@ -752,12 +754,18 @@ } InternalAuthenticator* CreditCardFIDOAuthenticator::authenticator() { - if (!authenticator_) { - authenticator_ = - autofill_driver_->GetOrCreateCreditCardInternalAuthenticator(); + if (authenticator_) + return authenticator_; + + authenticator_ = + autofill_driver_->GetOrCreateCreditCardInternalAuthenticator(); + + // |authenticator_| may be null for unsupported platforms. + if (authenticator_) { authenticator()->SetEffectiveOrigin( url::Origin::Create(payments::GetBaseSecureUrl())); } + return authenticator_; } } // namespace autofill
diff --git a/components/autofill/core/browser/test_autofill_client.cc b/components/autofill/core/browser/test_autofill_client.cc index 9ba0335a..550946e 100644 --- a/components/autofill/core/browser/test_autofill_client.cc +++ b/components/autofill/core/browser/test_autofill_client.cc
@@ -10,6 +10,10 @@ #include "components/autofill/core/browser/payments/local_card_migration_manager.h" #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" +#if !defined(OS_IOS) +#include "components/autofill/core/browser/payments/test_internal_authenticator.h" +#endif + namespace autofill { TestAutofillClient::TestAutofillClient() @@ -75,6 +79,14 @@ return page_language_; } +#if !defined(OS_IOS) +std::unique_ptr<InternalAuthenticator> +TestAutofillClient::CreateCreditCardInternalAuthenticator( + content::RenderFrameHost* rfh) { + return std::make_unique<TestInternalAuthenticator>(); +} +#endif + void TestAutofillClient::ShowAutofillSettings(bool show_credit_card_settings) {} void TestAutofillClient::ShowUnmaskPrompt(
diff --git a/components/autofill/core/browser/test_autofill_client.h b/components/autofill/core/browser/test_autofill_client.h index 6234c9f..608f1f4 100644 --- a/components/autofill/core/browser/test_autofill_client.h +++ b/components/autofill/core/browser/test_autofill_client.h
@@ -27,6 +27,10 @@ #include "components/ukm/test_ukm_recorder.h" #include "services/metrics/public/cpp/delegating_ukm_recorder.h" +#if !defined(OS_IOS) +#include "components/autofill/core/browser/payments/internal_authenticator.h" +#endif + namespace autofill { // This class is for easier writing of tests. @@ -49,6 +53,10 @@ AddressNormalizer* GetAddressNormalizer() override; security_state::SecurityLevel GetSecurityLevelForUmaHistograms() override; std::string GetPageLanguage() const override; +#if !defined(OS_IOS) + std::unique_ptr<InternalAuthenticator> CreateCreditCardInternalAuthenticator( + content::RenderFrameHost* rfh) override; +#endif void ShowAutofillSettings(bool show_credit_card_settings) override; void ShowUnmaskPrompt(const CreditCard& card,
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc index 2558915..3856188 100644 --- a/components/autofill/core/common/autofill_features.cc +++ b/components/autofill/core/common/autofill_features.cc
@@ -91,6 +91,14 @@ "AutofillEnforceMinRequiredFieldsForUpload", base::FEATURE_DISABLED_BY_DEFAULT}; +// Autofill uses the local heuristic such that address forms are only filled if +// at least 3 fields are fillable according to local heuristics. Unfortunately, +// the criterion for fillability is only that the field type is unknown. So many +// field types that we don't fill (search term, price, ...) count towards that +// counter, effectively reducing the threshold for some forms. +const base::Feature kAutofillFixFillableFieldTypes{ + "AutofillFixFillableFieldTypes", base::FEATURE_DISABLED_BY_DEFAULT}; + // When enabled, autofill suggestions are displayed in the keyboard accessory // instead of the regular popup. const base::Feature kAutofillKeyboardAccessory{
diff --git a/components/autofill/core/common/autofill_features.h b/components/autofill/core/common/autofill_features.h index 737347c..30cf3076 100644 --- a/components/autofill/core/common/autofill_features.h +++ b/components/autofill/core/common/autofill_features.h
@@ -34,6 +34,7 @@ extern const base::Feature kAutofillEnforceMinRequiredFieldsForHeuristics; extern const base::Feature kAutofillEnforceMinRequiredFieldsForQuery; extern const base::Feature kAutofillEnforceMinRequiredFieldsForUpload; +extern const base::Feature kAutofillFixFillableFieldTypes; extern const base::Feature kAutofillKeyboardAccessory; extern const base::Feature kAutofillPruneSuggestions; extern const base::Feature kAutofillMetadataUploads;
diff --git a/components/autofill/core/common/autofill_internals/log_message.h b/components/autofill/core/common/autofill_internals/log_message.h index 8e5ec4333..8604f63 100644 --- a/components/autofill/core/common/autofill_internals/log_message.h +++ b/components/autofill/core/common/autofill_internals/log_message.h
@@ -18,6 +18,9 @@ T(ParsedForms, "Parsed forms:") \ T(SendAutofillUpload, "Sending Autofill Upload Request:") \ T(LocalHeuristicRegExMatched, "RegEx of local heuristic matched:") \ + T(LocalHeuristicDidNotFindEnoughFillableFields, \ + "Local heuristics did not find enough fillable fields to classify the " \ + "form as fillable; therefore it did not produce any classifications.") \ T(AbortParsingTooManyForms, "Abort parsing form: Too many forms in cache: ") \ T(AbortParsingNotAllowedScheme, \ "Abort parsing form: Ignoring form because the source url has no allowed " \
diff --git a/components/autofill/core/common/autofill_payments_features.cc b/components/autofill/core/common/autofill_payments_features.cc index 63d4482..24c62fb 100644 --- a/components/autofill/core/common/autofill_payments_features.cc +++ b/components/autofill/core/common/autofill_payments_features.cc
@@ -47,6 +47,11 @@ const base::Feature kAutofillCreditCardUploadFeedback{ "AutofillCreditCardUploadFeedback", base::FEATURE_DISABLED_BY_DEFAULT}; +// When enabled, the credit card nicknames will be manageable. They can be +// uploaded to Payments or be modified locally. +const base::Feature kAutofillEnableCardNicknameManagement{ + "AutofillEnableCardNicknameManagement", base::FEATURE_DISABLED_BY_DEFAULT}; + // When enabled, autofill payments bubbles' result will be recorded as either // 'accepted', 'cancelled', 'closed', 'not interacted' or 'lost focus'. const base::Feature kAutofillEnableFixedPaymentsBubbleLogging{
diff --git a/components/autofill/core/common/autofill_payments_features.h b/components/autofill/core/common/autofill_payments_features.h index 74196ccb..4e5c628c 100644 --- a/components/autofill/core/common/autofill_payments_features.h +++ b/components/autofill/core/common/autofill_payments_features.h
@@ -24,6 +24,7 @@ extern const base::Feature kAutofillCreditCardAblationExperiment; extern const base::Feature kAutofillCreditCardAuthentication; extern const base::Feature kAutofillCreditCardUploadFeedback; +extern const base::Feature kAutofillEnableCardNicknameManagement; extern const base::Feature kAutofillEnableFixedPaymentsBubbleLogging; extern const base::Feature kAutofillEnableGoogleIssuedCard; extern const base::Feature kAutofillEnableStickyPaymentsBubble;
diff --git a/components/browser_ui/settings/android/BUILD.gn b/components/browser_ui/settings/android/BUILD.gn index 29a3fa9..741932b 100644 --- a/components/browser_ui/settings/android/BUILD.gn +++ b/components/browser_ui/settings/android/BUILD.gn
@@ -36,7 +36,6 @@ "//components/browser_ui/strings/android:browser_ui_strings_grd", "//components/browser_ui/styles/android:java_resources", "//third_party/android_deps:androidx_preference_preference_java", - "//third_party/android_deps:com_google_android_material_material_java", "//ui/android:ui_java_resources", ] sources = [
diff --git a/components/browser_ui/site_settings/android/BUILD.gn b/components/browser_ui/site_settings/android/BUILD.gn index 5b70e583..894e9a34 100644 --- a/components/browser_ui/site_settings/android/BUILD.gn +++ b/components/browser_ui/site_settings/android/BUILD.gn
@@ -28,8 +28,10 @@ "//components/content_settings/core/browser", "//components/embedder_support/android:browser_context", "//components/permissions", + "//components/subresource_filter/android", "//components/user_prefs", "//content/public/browser", + "//services/device/public/cpp:device_feature_list", "//services/network/public/mojom", "//storage/browser", "//url",
diff --git a/components/browser_ui/site_settings/android/website_preference_bridge.cc b/components/browser_ui/site_settings/android/website_preference_bridge.cc index 50d19a65..7de8090a 100644 --- a/components/browser_ui/site_settings/android/website_preference_bridge.cc +++ b/components/browser_ui/site_settings/android/website_preference_bridge.cc
@@ -622,6 +622,10 @@ static_cast<ContentSettingsType>(content_settings_type); permissions::ChooserContextBase* context = GetChooserContext(jbrowser_context_handle, type); + // The ChooserContextBase can be null if the embedder doesn't support the + // given ContentSettingsType. + if (!context) + return; for (const auto& object : context->GetAllGrantedObjects()) { // Remove the trailing slash so that origins are matched correctly in // SingleWebsitePreferences.mergePermissionInfoForTopLevelOrigin.
diff --git a/components/browser_ui/strings/android/browser_ui_strings.grd b/components/browser_ui/strings/android/browser_ui_strings.grd index 6363c57f2..59a6fbf 100644 --- a/components/browser_ui/strings/android/browser_ui_strings.grd +++ b/components/browser_ui/strings/android/browser_ui_strings.grd
@@ -444,6 +444,30 @@ <message name="IDS_PAGE_INFO_FAST_SITE_MESSAGE" desc="A short paragraph that explains what is meant by labeling the current website as fast."> This site opens and responds quickly for most people </message> + <message name="IDS_PAGE_INFO_ANDROID_LOCATION_BLOCKED" desc="The label used in the Page Info dialog to indicate that location has been been disabled for the device in Android settings"> + Turned off for this device + </message> + <message name="IDS_PAGE_INFO_ANDROID_NFC_UNSUPPORTED" desc="The label used in the Page Info dialog to indicate NFC is not supported by this device"> + This device can't read NFC + </message> + <message name="IDS_PAGE_INFO_ANDROID_PERMISSION_BLOCKED" desc="The label used in the Page Info dialog to indicate a permission has been blocked within Android settings"> + Turned off in Android settings + </message> + <message name="IDS_PAGE_INFO_ANDROID_AR_CAMERA_BLOCKED" desc="The label used in the Page Info dialog for the AR permission to indicate that Camera has been disabled for the device in Android settings"> + Camera is turned off in Android settings + </message> + <message name="IDS_PAGE_INFO_PERMISSION_ALLOWED" desc="The label used in the Page Info dialog to describe an allowed permission. Eg: Location - Allowed"> + Allowed + </message> + <message name="IDS_PAGE_INFO_PERMISSION_BLOCKED" desc="The label used in the Page Info dialog to describe a blocked permission. Eg: Location - Blocked"> + Blocked + </message> + <message name="IDS_PAGE_INFO_DSE_PERMISSION_ALLOWED" desc="The label used in the Page Info dialog to describe an allowed location permission for the current search engine. Eg: Location - Allowed for current search engine"> + Allowed for current search engine + </message> + <message name="IDS_PAGE_INFO_DSE_PERMISSION_BLOCKED" desc="The label used in the Page Info dialog to describe a blocked location permission for the current search engine. Eg: Location - Blocked for current search engine"> + Blocked for current search engine + </message> <message name="IDS_COOKIES_TITLE" desc="Title for the Cookies settings screen [CHAR-LIMIT=32]"> Cookies
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PAGE_INFO_ANDROID_AR_CAMERA_BLOCKED.png.sha1 b/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_PAGE_INFO_ANDROID_AR_CAMERA_BLOCKED.png.sha1 similarity index 100% rename from chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PAGE_INFO_ANDROID_AR_CAMERA_BLOCKED.png.sha1 rename to components/browser_ui/strings/android/browser_ui_strings_grd/IDS_PAGE_INFO_ANDROID_AR_CAMERA_BLOCKED.png.sha1
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PAGE_INFO_ANDROID_NFC_UNSUPPORTED.png.sha1 b/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_PAGE_INFO_ANDROID_NFC_UNSUPPORTED.png.sha1 similarity index 100% rename from chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PAGE_INFO_ANDROID_NFC_UNSUPPORTED.png.sha1 rename to components/browser_ui/strings/android/browser_ui_strings_grd/IDS_PAGE_INFO_ANDROID_NFC_UNSUPPORTED.png.sha1
diff --git a/components/browser_ui/styles/android/java/res/values/dimens.xml b/components/browser_ui/styles/android/java/res/values/dimens.xml index a1e033e..856bf31 100644 --- a/components/browser_ui/styles/android/java/res/values/dimens.xml +++ b/components/browser_ui/styles/android/java/res/values/dimens.xml
@@ -14,4 +14,8 @@ <!-- Alert dialog --> <dimen name="dialog_padding_top">@dimen/abc_dialog_padding_top_material</dimen> <dimen name="dialog_padding_sides">@dimen/abc_dialog_padding_material</dimen> + + <!-- Toolbar dimensions --> + <dimen name="toolbar_shadow_height">8dp</dimen> + </resources>
diff --git a/components/cast_channel/cast_message_handler.cc b/components/cast_channel/cast_message_handler.cc index 74876294..43c79ac 100644 --- a/components/cast_channel/cast_message_handler.cc +++ b/components/cast_channel/cast_message_handler.cc
@@ -197,6 +197,7 @@ const std::string& app_id, base::TimeDelta launch_timeout, const std::vector<std::string>& supported_app_types, + const std::string& app_params, LaunchSessionCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); CastSocket* socket = socket_service_->GetSocket(channel_id);
diff --git a/components/cast_channel/cast_message_handler.h b/components/cast_channel/cast_message_handler.h index 1a5a197..f7791e7 100644 --- a/components/cast_channel/cast_message_handler.h +++ b/components/cast_channel/cast_message_handler.h
@@ -185,6 +185,7 @@ const std::string& app_id, base::TimeDelta launch_timeout, const std::vector<std::string>& supported_app_types, + const std::string& app_params, LaunchSessionCallback callback); // Stops the session given by |session_id| on the device given by
diff --git a/components/cast_channel/cast_message_handler_unittest.cc b/components/cast_channel/cast_message_handler_unittest.cc index fa7a112..81086b6 100644 --- a/components/cast_channel/cast_message_handler_unittest.cc +++ b/components/cast_channel/cast_message_handler_unittest.cc
@@ -136,7 +136,8 @@ void CreatePendingRequests() { EXPECT_CALL(*transport_, SendMessage(_, _)).Times(AnyNumber()); handler_.LaunchSession(channel_id_, "theAppId", base::TimeDelta::Max(), - {"WEB"}, launch_session_callback_.Get()); + {"WEB"}, /* appParams */ "", + launch_session_callback_.Get()); for (int i = 0; i < 2; i++) { handler_.RequestAppAvailability(&cast_socket_, "theAppId", get_app_availability_callback_.Get()); @@ -318,6 +319,7 @@ handler_.LaunchSession( channel_id_, "AAAAAAAA", base::TimeDelta::FromSeconds(30), {"WEB"}, + /* appParams */ "", base::BindOnce(&CastMessageHandlerTest::ExpectSessionLaunchResult, base::Unretained(this), LaunchSessionResponse::Result::kOk)); @@ -356,6 +358,7 @@ handler_.LaunchSession( channel_id_, "AAAAAAAA", base::TimeDelta::FromSeconds(30), {"WEB"}, + /* appParams */ "", base::BindOnce(&CastMessageHandlerTest::ExpectSessionLaunchResult, base::Unretained(this), LaunchSessionResponse::Result::kTimedOut));
diff --git a/components/cast_channel/cast_test_util.h b/components/cast_channel/cast_test_util.h index 8a5d095b..d907a9a 100644 --- a/components/cast_channel/cast_test_util.h +++ b/components/cast_channel/cast_test_util.h
@@ -178,11 +178,12 @@ void(int, const std::vector<std::string>&, const BroadcastRequest&)); - MOCK_METHOD5(LaunchSession, + MOCK_METHOD6(LaunchSession, void(int, const std::string&, base::TimeDelta, const std::vector<std::string>&, + const std::string&, LaunchSessionCallback callback)); MOCK_METHOD4(StopSession, void(int channel_id,
diff --git a/components/crash/core/app/BUILD.gn b/components/crash/core/app/BUILD.gn index bb11c40..af031a0 100644 --- a/components/crash/core/app/BUILD.gn +++ b/components/crash/core/app/BUILD.gn
@@ -22,7 +22,10 @@ "crash_reporter_client.h", ] - deps = [ "//base" ] + deps = [ + "//base", + "//build:branding_buildflags", + ] } source_set("crashpad_handler_main") {
diff --git a/components/crash/core/app/breakpad_linux.cc b/components/crash/core/app/breakpad_linux.cc index 192b0a7..8ca43e2 100644 --- a/components/crash/core/app/breakpad_linux.cc +++ b/components/crash/core/app/breakpad_linux.cc
@@ -103,7 +103,11 @@ // while we do have functions to deal with uint64_t's. uint64_t g_crash_loop_before_time = 0; #else -const char kUploadURL[] = "https://clients2.google.com/cr/report"; +char* g_upload_url = nullptr; +void SetUploadURL(const std::string& url) { + DCHECK(!g_upload_url); + g_upload_url = strdup(url.c_str()); +} #endif bool g_is_crash_reporter_enabled = false; @@ -1400,16 +1404,16 @@ static const char kWgetBinary[] = "/usr/bin/wget"; const char* args[] = { - kWgetBinary, - header_content_encoding, - header_content_type, - post_file, - kUploadURL, - "--timeout=10", // Set a timeout so we don't hang forever. - "--tries=1", // Don't retry if the upload fails. - "-O", // Output reply to the file descriptor path. - status_fd_path, - nullptr, + kWgetBinary, + header_content_encoding, + header_content_type, + post_file, + g_upload_url, + "--timeout=10", // Set a timeout so we don't hang forever. + "--tries=1", // Don't retry if the upload fails. + "-O", // Output reply to the file descriptor path. + status_fd_path, + nullptr, }; static const char msg[] = "Cannot upload crash dump: cannot exec " "/usr/bin/wget\n"; @@ -2037,6 +2041,10 @@ #endif process_type.empty(); +#if !defined(OS_CHROMEOS) + SetUploadURL(GetCrashReporterClient()->GetUploadUrl()); +#endif + if (is_browser_process) { bool enable_breakpad = GetCrashReporterClient()->GetCollectStatsConsent() || GetCrashReporterClient()->IsRunningUnattended();
diff --git a/components/crash/core/app/crash_reporter_client.cc b/components/crash/core/app/crash_reporter_client.cc index 96ce56bb..44e81b2 100644 --- a/components/crash/core/app/crash_reporter_client.cc +++ b/components/crash/core/app/crash_reporter_client.cc
@@ -4,6 +4,7 @@ #include "components/crash/core/app/crash_reporter_client.h" +#include "build/branding_buildflags.h" #include "build/build_config.h" // On Windows don't use FilePath and logging.h. @@ -22,6 +23,10 @@ CrashReporterClient* g_client = nullptr; +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) && defined(OFFICIAL_BUILD) +const char kDefaultUploadURL[] = "https://clients2.google.com/cr/report"; +#endif + } // namespace void SetCrashReporterClient(CrashReporterClient* client) { @@ -191,6 +196,16 @@ } #endif +std::string CrashReporterClient::GetUploadUrl() { +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) && defined(OFFICIAL_BUILD) + // Only allow the possibility of report upload in official builds. This + // crash server won't have symbols for any other build types. + return kDefaultUploadURL; +#else + return std::string(); +#endif +} + bool CrashReporterClient::ShouldMonitorCrashHandlerExpensively() { return false; }
diff --git a/components/crash/core/app/crash_reporter_client.h b/components/crash/core/app/crash_reporter_client.h index 245ddda6..0553842 100644 --- a/components/crash/core/app/crash_reporter_client.h +++ b/components/crash/core/app/crash_reporter_client.h
@@ -191,6 +191,9 @@ bool* sanitize_stacks); #endif + // Returns the URL target for crash report uploads. + virtual std::string GetUploadUrl(); + // This method should return true to configure a crash reporter capable of // monitoring itself for its own crashes to do so, even if self-monitoring // would be expensive. "Expensive" self-monitoring dedicates an additional
diff --git a/components/crash/core/app/crashpad_linux.cc b/components/crash/core/app/crashpad_linux.cc index 5d31d09..56a79e2 100644 --- a/components/crash/core/app/crashpad_linux.cc +++ b/components/crash/core/app/crashpad_linux.cc
@@ -120,9 +120,8 @@ // to ChromeOS's /sbin/crash_reporter which in turn passes the dump to // crash_sender which handles the upload. std::string url; -#if BUILDFLAG(GOOGLE_CHROME_BRANDING) && defined(OFFICIAL_BUILD) && \ - !defined(OS_CHROMEOS) - url = "https://clients2.google.com/cr/report"; +#if !defined(OS_CHROMEOS) + url = crash_reporter_client->GetUploadUrl(); #else url = std::string(); #endif
diff --git a/components/crash/core/app/crashpad_mac.mm b/components/crash/core/app/crashpad_mac.mm index b579521..c49d380 100644 --- a/components/crash/core/app/crashpad_mac.mm +++ b/components/crash/core/app/crashpad_mac.mm
@@ -133,13 +133,7 @@ crash_reporter_client->GetCrashDumpLocation(&database_path); crash_reporter_client->GetCrashMetricsLocation(&metrics_path); -#if BUILDFLAG(GOOGLE_CHROME_BRANDING) && defined(OFFICIAL_BUILD) - // Only allow the possibility of report upload in official builds. This - // crash server won't have symbols for any other build types. - std::string url = "https://clients2.google.com/cr/report"; -#else - std::string url; -#endif + std::string url = crash_reporter_client->GetUploadUrl(); std::vector<std::string> arguments;
diff --git a/components/crash/core/app/crashpad_win.cc b/components/crash/core/app/crashpad_win.cc index 669f5bea..c199b467 100644 --- a/components/crash/core/app/crashpad_win.cc +++ b/components/crash/core/app/crashpad_win.cc
@@ -85,11 +85,7 @@ std::map<std::string, std::string> process_annotations; GetPlatformCrashpadAnnotations(&process_annotations); -#if BUILDFLAG(GOOGLE_CHROME_BRANDING) - std::string url = "https://clients2.google.com/cr/report"; -#else - std::string url; -#endif + std::string url = crash_reporter_client->GetUploadUrl(); // Allow the crash server to be overridden for testing. If the variable // isn't present in the environment then the default URL will remain.
diff --git a/components/gcm_driver/gcm_client_impl.cc b/components/gcm_driver/gcm_client_impl.cc index 4bb4f95a..1d0c9ced 100644 --- a/components/gcm_driver/gcm_client_impl.cc +++ b/components/gcm_driver/gcm_client_impl.cc
@@ -796,7 +796,7 @@ void GCMClientImpl::IgnoreWriteResultCallback( const std::string& operation_suffix_for_uma, bool success) { - // TODO(tschumann): Implement proper error handling. + // TODO(crbug.com/1081149): Implement proper error handling. // TODO(fgorski): Ignoring the write result for now to make sure // sync_intergration_tests are not broken. base::UmaHistogramBoolean(
diff --git a/components/omnibox/browser/autocomplete_classifier.cc b/components/omnibox/browser/autocomplete_classifier.cc index 2aadbc0..fe419c4 100644 --- a/components/omnibox/browser/autocomplete_classifier.cc +++ b/components/omnibox/browser/autocomplete_classifier.cc
@@ -57,7 +57,7 @@ AutocompleteProvider::TYPE_HISTORY_QUICK | AutocompleteProvider::TYPE_HISTORY_URL | AutocompleteProvider::TYPE_SEARCH | AutocompleteProvider::TYPE_SHORTCUTS | - (base::FeatureList::IsEnabled(upboarding::features::kQueryTilesInOmnibox) + (base::FeatureList::IsEnabled(query_tiles::features::kQueryTilesInOmnibox) ? AutocompleteProvider::TYPE_QUERY_TILE : 0); }
diff --git a/components/omnibox/browser/autocomplete_match.h b/components/omnibox/browser/autocomplete_match.h index 14b4bf1..3213b5c 100644 --- a/components/omnibox/browser/autocomplete_match.h +++ b/components/omnibox/browser/autocomplete_match.h
@@ -648,7 +648,7 @@ std::vector<AutocompleteMatch> duplicate_matches; // A list of query tiles to be shown as part of this match. - std::vector<upboarding::Tile> query_tiles; + std::vector<query_tiles::Tile> query_tiles; // So users of AutocompleteMatch can use the same ellipsis that it uses. static const char kEllipsis[];
diff --git a/components/omnibox/browser/autocomplete_provider_client.h b/components/omnibox/browser/autocomplete_provider_client.h index 96d913d..ecd0c46c 100644 --- a/components/omnibox/browser/autocomplete_provider_client.h +++ b/components/omnibox/browser/autocomplete_provider_client.h
@@ -47,7 +47,7 @@ class ComponentUpdateService; } -namespace upboarding { +namespace query_tiles { class TileService; } @@ -78,7 +78,7 @@ virtual scoped_refptr<ShortcutsBackend> GetShortcutsBackendIfExists() = 0; virtual std::unique_ptr<KeywordExtensionsDelegate> GetKeywordExtensionsDelegate(KeywordProvider* keyword_provider) = 0; - virtual upboarding::TileService* GetQueryTileService() const = 0; + virtual query_tiles::TileService* GetQueryTileService() const = 0; // The value to use for Accept-Languages HTTP header when making an HTTP // request.
diff --git a/components/omnibox/browser/fake_autocomplete_provider_client.cc b/components/omnibox/browser/fake_autocomplete_provider_client.cc index bdefe018..dca40ce 100644 --- a/components/omnibox/browser/fake_autocomplete_provider_client.cc +++ b/components/omnibox/browser/fake_autocomplete_provider_client.cc
@@ -40,7 +40,7 @@ GetHistoryService(), base::FilePath(), true); shortcuts_backend_->Init(); - tile_service_ = std::make_unique<upboarding::FakeTileService>(); + tile_service_ = std::make_unique<query_tiles::FakeTileService>(); } FakeAutocompleteProviderClient::~FakeAutocompleteProviderClient() { @@ -87,7 +87,7 @@ return shortcuts_backend_; } -upboarding::TileService* FakeAutocompleteProviderClient::GetQueryTileService() +query_tiles::TileService* FakeAutocompleteProviderClient::GetQueryTileService() const { return tile_service_.get(); }
diff --git a/components/omnibox/browser/fake_autocomplete_provider_client.h b/components/omnibox/browser/fake_autocomplete_provider_client.h index b9b019e4..6e57666f 100644 --- a/components/omnibox/browser/fake_autocomplete_provider_client.h +++ b/components/omnibox/browser/fake_autocomplete_provider_client.h
@@ -42,7 +42,7 @@ InMemoryURLIndex* GetInMemoryURLIndex() override; scoped_refptr<ShortcutsBackend> GetShortcutsBackend() override; scoped_refptr<ShortcutsBackend> GetShortcutsBackendIfExists() override; - upboarding::TileService* GetQueryTileService() const override; + query_tiles::TileService* GetQueryTileService() const override; void set_in_memory_url_index(std::unique_ptr<InMemoryURLIndex> index) { in_memory_url_index_ = std::move(index); @@ -65,7 +65,7 @@ std::unique_ptr<InMemoryURLIndex> in_memory_url_index_; std::unique_ptr<history::HistoryService> history_service_; scoped_refptr<ShortcutsBackend> shortcuts_backend_; - std::unique_ptr<upboarding::TileService> tile_service_; + std::unique_ptr<query_tiles::TileService> tile_service_; // Substring used to match URLs for IsTabOpenWithURL(). std::string substring_to_match_;
diff --git a/components/omnibox/browser/in_memory_url_index.cc b/components/omnibox/browser/in_memory_url_index.cc index 2ebe5a5..d5ab4ef 100644 --- a/components/omnibox/browser/in_memory_url_index.cc +++ b/components/omnibox/browser/in_memory_url_index.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/files/file_util.h" +#include "base/no_destructor.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/task/post_task.h" @@ -299,13 +300,13 @@ &URLIndexPrivateData::WritePrivateDataToCacheFileTask), private_data_, path)); #ifndef LEAK_SANITIZER - // Intentionally allocate and then leak a scoped_refptr to private_data_. This + // Intentionally create and then leak a scoped_refptr to private_data_. This // permanently raises the reference count so that the URLIndexPrivateData // destructor won't run during browser shutdown. This saves having to walk the // maps to free their memory, which saves time and avoids shutdown hangs, // especially if some of the memory has been paged out. - auto* leak_pointer = new scoped_refptr<URLIndexPrivateData>(private_data_); - ANALYZER_ALLOW_UNUSED(leak_pointer); + base::NoDestructor<scoped_refptr<URLIndexPrivateData>> leak_reference( + private_data_); #endif needs_to_be_cached_ = false; }
diff --git a/components/omnibox/browser/mock_autocomplete_provider_client.h b/components/omnibox/browser/mock_autocomplete_provider_client.h index 139da119..9d0db4e 100644 --- a/components/omnibox/browser/mock_autocomplete_provider_client.h +++ b/components/omnibox/browser/mock_autocomplete_provider_client.h
@@ -76,7 +76,7 @@ KeywordProvider* keyword_provider) override { return nullptr; } - upboarding::TileService* GetQueryTileService() const override { + query_tiles::TileService* GetQueryTileService() const override { return nullptr; }
diff --git a/components/omnibox/browser/query_tile_provider.cc b/components/omnibox/browser/query_tile_provider.cc index 0ea4eb2..815514e9 100644 --- a/components/omnibox/browser/query_tile_provider.cc +++ b/components/omnibox/browser/query_tile_provider.cc
@@ -20,7 +20,7 @@ // selected query tile, if any. If there is no query tile selected, empty input // text is considered a match. bool TextMatchesQueryTile(base::string16 input_text, - base::Optional<upboarding::Tile> tile) { + base::Optional<query_tiles::Tile> tile) { auto trimmed_input = base::TrimWhitespace(input_text, base::TrimPositions::TRIM_TRAILING); auto tile_text = tile.has_value() ? tile->query_text : ""; @@ -121,24 +121,25 @@ void QueryTileProvider::OnTopLevelTilesFetched( const AutocompleteInput& input, - std::vector<upboarding::Tile> tiles) { + std::vector<query_tiles::Tile> tiles) { BuildSuggestion(input, base::nullopt, std::move(tiles)); } void QueryTileProvider::OnSubTilesFetched( const AutocompleteInput& input, - base::Optional<upboarding::Tile> tile) { + base::Optional<query_tiles::Tile> tile) { DCHECK(tile.has_value()); - std::vector<upboarding::Tile> sub_tiles; + std::vector<query_tiles::Tile> sub_tiles; for (const auto& sub_tile : std::move(tile->sub_tiles)) sub_tiles.emplace_back(std::move(*sub_tile.get())); BuildSuggestion(input, tile, std::move(sub_tiles)); } -void QueryTileProvider::BuildSuggestion(const AutocompleteInput& input, - base::Optional<upboarding::Tile> parent, - std::vector<upboarding::Tile> tiles) { +void QueryTileProvider::BuildSuggestion( + const AutocompleteInput& input, + base::Optional<query_tiles::Tile> parent, + std::vector<query_tiles::Tile> tiles) { if (done_) return;
diff --git a/components/omnibox/browser/query_tile_provider.h b/components/omnibox/browser/query_tile_provider.h index be886271e..0ba83e8 100644 --- a/components/omnibox/browser/query_tile_provider.h +++ b/components/omnibox/browser/query_tile_provider.h
@@ -13,11 +13,10 @@ #include "components/omnibox/browser/autocomplete_input.h" #include "components/omnibox/browser/autocomplete_provider.h" -namespace upboarding { +namespace query_tiles { class TileService; struct Tile; - -} // namespace upboarding +} // namespace query_tiles class AutocompleteProviderClient; class AutocompleteProviderListener; @@ -52,25 +51,25 @@ // Callback invoked in response to fetching the top level tiles from // TileService. void OnTopLevelTilesFetched(const AutocompleteInput& input, - std::vector<upboarding::Tile> tiles); + std::vector<query_tiles::Tile> tiles); // Callback invoked in response to fetching subtiles of a selected query tile // from TileService. void OnSubTilesFetched(const AutocompleteInput& input, - base::Optional<upboarding::Tile> tile); + base::Optional<query_tiles::Tile> tile); // For the given |input| and optionally a selected tile denoted by |parent|, // checks if a suggestion should be shown. If yes, builds a query tile // suggestion with the matching |tiles|. void BuildSuggestion(const AutocompleteInput& input, - base::Optional<upboarding::Tile> parent, - std::vector<upboarding::Tile> tiles); + base::Optional<query_tiles::Tile> parent, + std::vector<query_tiles::Tile> tiles); AutocompleteProviderClient* const client_; AutocompleteProviderListener* const listener_; // The backend providing query tiles. - upboarding::TileService* const tile_service_; + query_tiles::TileService* const tile_service_; base::WeakPtrFactory<QueryTileProvider> weak_ptr_factory_{this}; };
diff --git a/components/page_info/android/BUILD.gn b/components/page_info/android/BUILD.gn index 060e48f..e456e5e 100644 --- a/components/page_info/android/BUILD.gn +++ b/components/page_info/android/BUILD.gn
@@ -63,6 +63,8 @@ custom_package = "org.chromium.components.page_info" deps = [ "//components/browser_ui/strings/android:browser_ui_strings_grd", + "//components/permissions/android:java_resources", + "//components/strings:components_strings_grd", "//ui/android:ui_java_resources", ] } @@ -80,6 +82,8 @@ "java/src/org/chromium/components/page_info/PageInfoRowView.java", "java/src/org/chromium/components/page_info/PageInfoView.java", "java/src/org/chromium/components/page_info/PageInfoViewV2.java", + "java/src/org/chromium/components/page_info/PermissionParamsListBuilder.java", + "java/src/org/chromium/components/page_info/PermissionParamsListBuilderDelegate.java", "java/src/org/chromium/components/page_info/SystemSettingsActivityRequiredListener.java", "java/src/org/chromium/components/page_info/VrHandler.java", ] @@ -89,17 +93,21 @@ ":page_info_action_enum_java", "//base:base_java", "//base:jni_java", + "//components/browser_ui/site_settings/android:java", "//components/content_settings/android:content_settings_enums_java", "//components/content_settings/android:java", "//components/dom_distiller/core/android:dom_distiller_core_java", + "//components/embedder_support/android:browser_context_java", "//components/embedder_support/android:util_java", "//components/feature_engagement/public:public_java", "//components/omnibox/browser:browser_java", + "//components/permissions/android:java", "//components/security_state/content/android:java", "//components/security_state/core:security_state_enums_java", "//components/strings:components_strings_grd", "//components/url_formatter/android:url_formatter_java", "//content/public/android:content_java", + "//services/device/public/java:device_feature_list_java", "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:androidx_annotation_annotation_java", "//ui/android:ui_java",
diff --git a/components/page_info/android/DEPS b/components/page_info/android/DEPS index 97aa255d..cd94558 100644 --- a/components/page_info/android/DEPS +++ b/components/page_info/android/DEPS
@@ -1,8 +1,10 @@ include_rules = [ + "+components/browser_ui/site_settings/android/java", "+components/content_settings/android/java", "+components/dom_distiller/core/android/java", "+components/embedder_support/android/java", "+components/feature_engagement/public/android/java", + "+components/location/android/java", "+components/omnibox/browser/android/java", "+components/security_state/content/android/java", "+components/strings/grit/components_strings.h",
diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoController.java b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoController.java index 172586fb..937d025 100644 --- a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoController.java +++ b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoController.java
@@ -114,6 +114,11 @@ // Whether Version 2 of the PageInfoView is enabled. private boolean mIsV2Enabled; + // Used to show Site settings from Page Info UI. + private final PermissionParamsListBuilder mPermissionParamsListBuilder; + + // Delegate used by PermissionParamsListBuilder. + private final PermissionParamsListBuilderDelegate mPermissionParamsListBuilderDelegate; /** * Creates the PageInfoController, but does not display it. Also initializes the corresponding @@ -126,11 +131,13 @@ */ @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED) public PageInfoController(WebContents webContents, int securityLevel, String publisher, - PageInfoControllerDelegate delegate, boolean isV2Enabled) { + PageInfoControllerDelegate delegate, boolean isV2Enabled, + PermissionParamsListBuilderDelegate permissionParamsListBuilderDelegate) { mWebContents = webContents; mSecurityLevel = securityLevel; mDelegate = delegate; mIsV2Enabled = isV2Enabled; + mPermissionParamsListBuilderDelegate = permissionParamsListBuilderDelegate; mRunAfterDismissConsumer = new Consumer<Runnable>() { @Override public void accept(Runnable r) { @@ -234,8 +241,9 @@ if (isSheet(mContext)) mView.setBackgroundColor(Color.WHITE); // TODO(crbug.com/1040091): Remove when cookie controls are launched. boolean showTitle = viewParams.cookieControlsShown; - mDelegate.createPermissionParamsListBuilder( - mWindowAndroid, mFullUrl, showTitle, this, mView::setPermissions); + mPermissionParamsListBuilder = + new PermissionParamsListBuilder(mContext, mWindowAndroid, mFullUrl, showTitle, this, + mView::setPermissions, mPermissionParamsListBuilderDelegate); mNativePageInfoController = PageInfoControllerJni.get().init(this, mWebContents); if (mIsV2Enabled) { @@ -316,7 +324,7 @@ @CalledByNative private void addPermissionSection( String name, int type, @ContentSettingValues int currentSettingValue) { - mDelegate.addPermissionEntry(name, type, currentSettingValue); + mPermissionParamsListBuilder.addPermissionEntry(name, type, currentSettingValue); } /** @@ -324,7 +332,8 @@ */ @CalledByNative private void updatePermissionDisplay() { - mDelegate.updatePermissionDisplay(mView); + assert (mPermissionParamsListBuilder != null); + mView.setPermissions(mPermissionParamsListBuilder.build()); } /** @@ -466,7 +475,8 @@ */ public static void show(final Activity activity, WebContents webContents, final String contentPublisher, @OpenedFromSource int source, - PageInfoControllerDelegate delegate) { + PageInfoControllerDelegate delegate, + PermissionParamsListBuilderDelegate permissionParamsListBuilderDelegate) { // If the activity's decor view is not attached to window, we don't show the dialog because // the window manager might have revoked the window token for this activity. See // https://crbug.com/921450. @@ -485,7 +495,8 @@ sLastPageInfoControllerForTesting = new WeakReference<>(new PageInfoController(webContents, SecurityStateModel.getSecurityLevelForWebContents(webContents), contentPublisher, - delegate, PageInfoFeatureList.isEnabled(PageInfoFeatureList.PAGE_INFO_V2))); + delegate, PageInfoFeatureList.isEnabled(PageInfoFeatureList.PAGE_INFO_V2), + permissionParamsListBuilderDelegate)); } @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoControllerDelegate.java b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoControllerDelegate.java index 10a54a42..ddf0cad4 100644 --- a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoControllerDelegate.java +++ b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoControllerDelegate.java
@@ -9,14 +9,11 @@ import androidx.annotation.IntDef; import androidx.annotation.Nullable; -import org.chromium.base.Callback; import org.chromium.base.Consumer; import org.chromium.base.supplier.Supplier; -import org.chromium.components.content_settings.ContentSettingValues; import org.chromium.components.content_settings.CookieControlsObserver; import org.chromium.components.omnibox.AutocompleteSchemeClassifier; import org.chromium.components.page_info.PageInfoView.PageInfoViewParams; -import org.chromium.ui.base.AndroidPermissionDelegate; import org.chromium.ui.modaldialog.ModalDialogManager; import java.lang.annotation.Retention; @@ -208,45 +205,4 @@ * Notes whether third party cookies should be blocked for the site. */ public void setThirdPartyCookieBlockingEnabledForSite(boolean blockCookies) {} - - // TODO(crbug.com/1058595): Componentize PermissionParamsBuilder once site settings code has - // been componentized. These methods can be removed at that point. - /** - * Creates a Permission Params List builder and holds on to it. - * @param permissionDelegate Delegate for checking system permissions. - * @param fullUrl Full URL of the site whose permissions are being displayed. - * @param shouldShowTitle Should show section title for permissions in Page Info UI. - * @param systemSettingsActivityRequiredListener Listener for when we need the user to enable - * a system setting to proceed. - * @param displayPermissionsCallback Callback to run to display fresh permissions in response to - * user interaction with a permission entry. - */ - public void createPermissionParamsListBuilder(AndroidPermissionDelegate permissionDelegate, - String fullUrl, boolean shouldShowTitle, - SystemSettingsActivityRequiredListener systemSettingsActivityRequiredListener, - Callback<PageInfoView.PermissionParams> displayPermissionsCallback) { - // TODO(crbug.com/1058597): Override for Webayer once PermissionParamsListBuilder has been - // componentized. - } - - /** - * Adds a permission entry corresponding to the input params. - * @param name Name of the permission to add. - * @param type Type of the permission to add. - * @param currentSettingValue The value of the permission to add. - */ - public void addPermissionEntry( - String name, int type, @ContentSettingValues int currentSettingValue) { - // TODO(crbug.com/1058597): Override for Webayer once PermissionParamsListBuilder has been - // componentized. - } - - /** - * Updates the Page Info View passed in with up to date permissions info. - * @param view The Page Info view to update. - */ - public void updatePermissionDisplay(PageInfoView view) { - // TODO(crbug.com/1058597): Override for Webayer once PermissionParamsListBuilder has been - // componentized. - } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/page_info/PermissionParamsListBuilder.java b/components/page_info/android/java/src/org/chromium/components/page_info/PermissionParamsListBuilder.java similarity index 95% rename from chrome/android/java/src/org/chromium/chrome/browser/page_info/PermissionParamsListBuilder.java rename to components/page_info/android/java/src/org/chromium/components/page_info/PermissionParamsListBuilder.java index be2577c..c086970 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/page_info/PermissionParamsListBuilder.java +++ b/components/page_info/android/java/src/org/chromium/components/page_info/PermissionParamsListBuilder.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.chrome.browser.page_info; +package org.chromium.components.page_info; import android.content.Context; import android.content.Intent; @@ -16,7 +16,6 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.Callback; -import org.chromium.chrome.R; import org.chromium.components.browser_ui.site_settings.ContentSettingsResources; import org.chromium.components.browser_ui.site_settings.SiteSettingsFeatureList; import org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridge; @@ -24,8 +23,6 @@ import org.chromium.components.content_settings.ContentSettingsType; import org.chromium.components.embedder_support.util.Origin; import org.chromium.components.location.LocationUtils; -import org.chromium.components.page_info.PageInfoView; -import org.chromium.components.page_info.SystemSettingsActivityRequiredListener; import org.chromium.components.permissions.PermissionUtil; import org.chromium.components.permissions.nfc.NfcSystemLevelSetting; import org.chromium.ui.base.AndroidPermissionDelegate; @@ -39,8 +36,7 @@ * permission values into PermissionParams suitable for PageInfoView to display. * */ -class PermissionParamsListBuilder { - +public class PermissionParamsListBuilder { private final List<PageInfoPermissionEntry> mEntries; private final String mFullUrl; private final boolean mShouldShowTitle; @@ -62,8 +58,8 @@ * @param displayPermissionsCallback Callback to run to display fresh permissions in response to * user interaction with a permission entry. */ - PermissionParamsListBuilder(Context context, AndroidPermissionDelegate permissionDelegate, - String fullUrl, boolean shouldShowTitle, + public PermissionParamsListBuilder(Context context, + AndroidPermissionDelegate permissionDelegate, String fullUrl, boolean shouldShowTitle, SystemSettingsActivityRequiredListener systemSettingsActivityRequiredListener, Callback<PageInfoView.PermissionParams> displayPermissionsCallback, PermissionParamsListBuilderDelegate delegate) { @@ -77,11 +73,11 @@ mDelegate = delegate; } - void addPermissionEntry(String name, int type, @ContentSettingValues int value) { + public void addPermissionEntry(String name, int type, @ContentSettingValues int value) { mEntries.add(new PageInfoPermissionEntry(name, type, value)); } - PageInfoView.PermissionParams build() { + public PageInfoView.PermissionParams build() { List<PageInfoView.PermissionRowParams> rowParams = new ArrayList<>(); for (PermissionParamsListBuilder.PageInfoPermissionEntry permission : mEntries) { rowParams.add(createPermissionParams(permission));
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/page_info/PermissionParamsListBuilderDelegate.java b/components/page_info/android/java/src/org/chromium/components/page_info/PermissionParamsListBuilderDelegate.java similarity index 74% rename from chrome/android/java/src/org/chromium/chrome/browser/page_info/PermissionParamsListBuilderDelegate.java rename to components/page_info/android/java/src/org/chromium/components/page_info/PermissionParamsListBuilderDelegate.java index e9ddcf2..871f6df 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/page_info/PermissionParamsListBuilderDelegate.java +++ b/components/page_info/android/java/src/org/chromium/components/page_info/PermissionParamsListBuilderDelegate.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.chrome.browser.page_info; +package org.chromium.components.page_info; import androidx.annotation.Nullable; @@ -14,7 +14,10 @@ * logic. */ public class PermissionParamsListBuilderDelegate { - public PermissionParamsListBuilderDelegate() {} + private final BrowserContextHandle mBrowserContextHandle; + public PermissionParamsListBuilderDelegate(BrowserContextHandle browserContextHandle) { + mBrowserContextHandle = browserContextHandle; + } /** * Returns the user visible name of the app that will handle permission delegation for the @@ -29,6 +32,6 @@ * Returns the BrowserContextHandle to be used by PermissionParamsListBuilder. */ public BrowserContextHandle getBrowserContextHandle() { - return null; + return mBrowserContextHandle; } }
diff --git a/components/paint_preview/browser/paint_preview_client.cc b/components/paint_preview/browser/paint_preview_client.cc index e720afed2..35dec779 100644 --- a/components/paint_preview/browser/paint_preview_client.cc +++ b/components/paint_preview/browser/paint_preview_client.cc
@@ -104,8 +104,8 @@ PaintPreviewClient::PaintPreviewData::~PaintPreviewData() = default; PaintPreviewClient::PaintPreviewData& -PaintPreviewClient::PaintPreviewData::operator=(PaintPreviewData&& rhs) = - default; +PaintPreviewClient::PaintPreviewData::operator=( + PaintPreviewData&& rhs) noexcept = default; PaintPreviewClient::PaintPreviewData::PaintPreviewData( PaintPreviewData&& other) noexcept = default;
diff --git a/components/paint_preview/player/android/java/src/org/chromium/components/paintpreview/player/frame/PlayerFrameMediator.java b/components/paint_preview/player/android/java/src/org/chromium/components/paintpreview/player/frame/PlayerFrameMediator.java index 4b90049..500369a6 100644 --- a/components/paint_preview/player/android/java/src/org/chromium/components/paintpreview/player/frame/PlayerFrameMediator.java +++ b/components/paint_preview/player/android/java/src/org/chromium/components/paintpreview/player/frame/PlayerFrameMediator.java
@@ -333,7 +333,11 @@ @Override public void onClick(int x, int y) { - mCompositorDelegate.onClick(mGuid, mViewportRect.left + x, mViewportRect.top + y); + // x and y are in the View's coordinate system (scaled). This needs to be adjusted to the + // absolute coordinate system for hit testing. + mCompositorDelegate.onClick(mGuid, + Math.round((float) (mViewportRect.left + x) / mScaleFactor), + Math.round((float) (mViewportRect.top + y) / mScaleFactor)); } @Override
diff --git a/components/paint_preview/player/android/javatests/src/org/chromium/components/paintpreview/player/PaintPreviewPlayerTest.java b/components/paint_preview/player/android/javatests/src/org/chromium/components/paintpreview/player/PaintPreviewPlayerTest.java index bd3dc44..8e52536 100644 --- a/components/paint_preview/player/android/javatests/src/org/chromium/components/paintpreview/player/PaintPreviewPlayerTest.java +++ b/components/paint_preview/player/android/javatests/src/org/chromium/components/paintpreview/player/PaintPreviewPlayerTest.java
@@ -5,11 +5,9 @@ package org.chromium.components.paintpreview.player; import android.graphics.Rect; -import android.os.SystemClock; import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; import android.support.test.uiautomator.UiDevice; -import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; @@ -21,7 +19,6 @@ import org.chromium.base.task.PostTask; import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.CallbackHelper; -import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.ScalableTimeout; import org.chromium.base.test.util.UrlUtils; import org.chromium.content_public.browser.UiThreadTaskTraits; @@ -46,6 +43,7 @@ private static final String TEST_OUT_OF_VIEWPORT_LINK_URL = "https://foundation.wikimedia.org/wiki/Privacy_policy"; + private static final int TEST_PAGE_WIDTH = 1082; private static final int TEST_PAGE_HEIGHT = 5019; @Rule @@ -106,7 +104,6 @@ */ @Test @MediumTest - @DisabledTest(message = "crbug.com/1065441") public void linkClickTest() { initPlayerManager(); final View playerHostView = mPlayerManager.getView(); @@ -124,13 +121,9 @@ // Scroll to the bottom, and click on a link. scrollToBottom(); - int playerHeight = playerHostView.getHeight(); - assertLinkUrl(playerHostView, 322, playerHeight - (TEST_PAGE_HEIGHT - 4946), - TEST_OUT_OF_VIEWPORT_LINK_URL); - assertLinkUrl(playerHostView, 376, playerHeight - (TEST_PAGE_HEIGHT - 4954), - TEST_OUT_OF_VIEWPORT_LINK_URL); - assertLinkUrl(playerHostView, 422, playerHeight - (TEST_PAGE_HEIGHT - 4965), - TEST_OUT_OF_VIEWPORT_LINK_URL); + assertLinkUrl(playerHostView, 322, 4946, TEST_OUT_OF_VIEWPORT_LINK_URL); + assertLinkUrl(playerHostView, 376, 4954, TEST_OUT_OF_VIEWPORT_LINK_URL); + assertLinkUrl(playerHostView, 422, 4965, TEST_OUT_OF_VIEWPORT_LINK_URL); } /** @@ -154,12 +147,15 @@ int padding = 20; int swipeSteps = 5; int viewPortBottom = deviceHeight - statusBarHeight - navigationBarHeight; - while (viewPortBottom < TEST_PAGE_HEIGHT) { - int fromY = deviceHeight - navigationBarHeight - padding; - int toY = statusBarHeight + padding; + int fromY = deviceHeight - navigationBarHeight - padding; + int toY = statusBarHeight + padding; + int delta = fromY - toY; + while (viewPortBottom < scaleAbsoluteCoordinateToViewCoordinate(TEST_PAGE_HEIGHT)) { uiDevice.swipe(50, fromY, 50, toY, swipeSteps); - viewPortBottom += fromY - toY; + viewPortBottom += delta; } + // Repeat an addition time to avoid flakiness. + uiDevice.swipe(50, fromY, 50, toY, swipeSteps); } private void initPlayerManager() { @@ -184,35 +180,47 @@ CriteriaHelper.DEFAULT_POLLING_INTERVAL); } - private void destroyPlayerManager() {} + /* + * Scales the provided coordinate to be view relative + */ + private int scaleAbsoluteCoordinateToViewCoordinate(int coordinate) { + float scaleFactor = (float) mPlayerManager.getView().getWidth() / (float) TEST_PAGE_WIDTH; + return Math.round((float) coordinate * scaleFactor); + } + /* + * Asserts that the expectedUrl is found in the view at absolute coordinates x and y. + */ private void assertLinkUrl(View view, int x, int y, String expectedUrl) { + int scaledX = scaleAbsoluteCoordinateToViewCoordinate(x); + int scaledY = scaleAbsoluteCoordinateToViewCoordinate(y); + + // In this test scaledY will only exceed the view height if scrolled to the bottom of a + // page. + if (scaledY > view.getHeight()) { + scaledY = view.getHeight() + - (scaleAbsoluteCoordinateToViewCoordinate(TEST_PAGE_HEIGHT) - scaledY); + } + mLinkClickHandler.mUrl = null; - dispatchTapEvent(view, x, y); + + int[] locationXY = new int[2]; + view.getLocationOnScreen(locationXY); + UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); + device.click(scaledX + locationXY[0], scaledY + locationXY[1]); + CriteriaHelper.pollUiThread( - ()-> { + () + -> { GURL url = mLinkClickHandler.mUrl; if (url == null) return false; return url.getSpec().equals(expectedUrl); }, - "Link press on (" + x + ", " + y + ") failed. Expected: " + expectedUrl + "Link press on abs (" + x + ", " + y + ") failed. Expected: " + expectedUrl + ", found: " + (mLinkClickHandler.mUrl == null ? null : mLinkClickHandler.mUrl.getSpec()), TIMEOUT_MS, CriteriaHelper.DEFAULT_POLLING_INTERVAL); } - - private void dispatchTapEvent(View view, int x, int y) { - long downTime = SystemClock.uptimeMillis(); - MotionEvent downEvent = MotionEvent.obtain( - downTime, downTime + 100, MotionEvent.ACTION_DOWN, (float) x, (float) y, 0); - MotionEvent upEvent = MotionEvent.obtain( - downTime + 150, downTime + 200, MotionEvent.ACTION_UP, (float) x, (float) y, 0); - - PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> { - view.dispatchTouchEvent(downEvent); - view.dispatchTouchEvent(upEvent); - }); - } }
diff --git a/components/password_manager/core/browser/multi_store_form_fetcher.cc b/components/password_manager/core/browser/multi_store_form_fetcher.cc index a7549b1..7e86b0e 100644 --- a/components/password_manager/core/browser/multi_store_form_fetcher.cc +++ b/components/password_manager/core/browser/multi_store_form_fetcher.cc
@@ -56,8 +56,9 @@ } bool MultiStoreFormFetcher::IsBlacklisted() const { - if (client_->GetPasswordFeatureManager()->GetDefaultPasswordStore() == - PasswordForm::Store::kAccountStore) { + if (client_->GetPasswordFeatureManager()->IsOptedInForAccountStorage() && + client_->GetPasswordFeatureManager()->GetDefaultPasswordStore() == + PasswordForm::Store::kAccountStore) { return is_blacklisted_in_account_store_; } return is_blacklisted_in_profile_store_;
diff --git a/components/password_manager/core/browser/multi_store_form_fetcher_unittest.cc b/components/password_manager/core/browser/multi_store_form_fetcher_unittest.cc index 4de9147..aa0121a 100644 --- a/components/password_manager/core/browser/multi_store_form_fetcher_unittest.cc +++ b/components/password_manager/core/browser/multi_store_form_fetcher_unittest.cc
@@ -190,7 +190,9 @@ TEST_F(MultiStoreFormFetcherTest, CloningMultiStoreFetcherClonesState) { Fetch(); - // Simluate a user in the account mode. + // Simulate a user in the account mode. + ON_CALL(*client()->GetPasswordFeatureManager(), IsOptedInForAccountStorage()) + .WillByDefault(Return(true)); ON_CALL(*client()->GetPasswordFeatureManager(), GetDefaultPasswordStore()) .WillByDefault(Return(PasswordForm::Store::kAccountStore)); @@ -214,7 +216,9 @@ TEST_F(MultiStoreFormFetcherTest, CloningMultiStoreFetcherResumesFetch) { Fetch(); - // Simluate a user in the account mode. + // Simulate a user in the account mode. + ON_CALL(*client()->GetPasswordFeatureManager(), IsOptedInForAccountStorage()) + .WillByDefault(Return(true)); ON_CALL(*client()->GetPasswordFeatureManager(), GetDefaultPasswordStore()) .WillByDefault(Return(PasswordForm::Store::kAccountStore)); @@ -318,12 +322,28 @@ // Pass empty response from the second store. form_fetcher_->OnGetPasswordStoreResults({}); - // Simluate a user in the account mode. + // Simulate a user in the account mode. + ON_CALL(*client()->GetPasswordFeatureManager(), IsOptedInForAccountStorage()) + .WillByDefault(Return(true)); ON_CALL(*client()->GetPasswordFeatureManager(), GetDefaultPasswordStore()) .WillByDefault(Return(PasswordForm::Store::kAccountStore)); EXPECT_TRUE(form_fetcher_->IsBlacklisted()); - // Simluate a user in the profile mode. + // Simulate a user in the profile mode. + ON_CALL(*client()->GetPasswordFeatureManager(), GetDefaultPasswordStore()) + .WillByDefault(Return(PasswordForm::Store::kProfileStore)); + EXPECT_FALSE(form_fetcher_->IsBlacklisted()); + + // Now simulate a user who isn't opted in for the account storage. In this + // case, the blacklist entry in the account store shouldn't matter, + // independent of the mode. + ON_CALL(*client()->GetPasswordFeatureManager(), IsOptedInForAccountStorage()) + .WillByDefault(Return(false)); + + ON_CALL(*client()->GetPasswordFeatureManager(), GetDefaultPasswordStore()) + .WillByDefault(Return(PasswordForm::Store::kAccountStore)); + EXPECT_FALSE(form_fetcher_->IsBlacklisted()); + ON_CALL(*client()->GetPasswordFeatureManager(), GetDefaultPasswordStore()) .WillByDefault(Return(PasswordForm::Store::kProfileStore)); EXPECT_FALSE(form_fetcher_->IsBlacklisted()); @@ -341,12 +361,28 @@ // Pass empty response from the second store. form_fetcher_->OnGetPasswordStoreResults({}); - // Simluate a user in the account mode. + // Simulate a user in the account mode. + ON_CALL(*client()->GetPasswordFeatureManager(), IsOptedInForAccountStorage()) + .WillByDefault(Return(true)); ON_CALL(*client()->GetPasswordFeatureManager(), GetDefaultPasswordStore()) .WillByDefault(Return(PasswordForm::Store::kAccountStore)); EXPECT_FALSE(form_fetcher_->IsBlacklisted()); - // Simluate a user in the profile mode. + // Simulate a user in the profile mode. + ON_CALL(*client()->GetPasswordFeatureManager(), GetDefaultPasswordStore()) + .WillByDefault(Return(PasswordForm::Store::kProfileStore)); + EXPECT_TRUE(form_fetcher_->IsBlacklisted()); + + // Now simulate a user who isn't opted in for the account storage. In this + // case, the blacklist entry in the profile store should take effect, whatever + // the mode is. + ON_CALL(*client()->GetPasswordFeatureManager(), IsOptedInForAccountStorage()) + .WillByDefault(Return(false)); + + ON_CALL(*client()->GetPasswordFeatureManager(), GetDefaultPasswordStore()) + .WillByDefault(Return(PasswordForm::Store::kAccountStore)); + EXPECT_TRUE(form_fetcher_->IsBlacklisted()); + ON_CALL(*client()->GetPasswordFeatureManager(), GetDefaultPasswordStore()) .WillByDefault(Return(PasswordForm::Store::kProfileStore)); EXPECT_TRUE(form_fetcher_->IsBlacklisted());
diff --git a/components/password_manager/core/browser/password_form_metrics_recorder.cc b/components/password_manager/core/browser/password_form_metrics_recorder.cc index f496f56..dfd469f 100644 --- a/components/password_manager/core/browser/password_form_metrics_recorder.cc +++ b/components/password_manager/core/browser/password_form_metrics_recorder.cc
@@ -283,6 +283,10 @@ if (is_main_frame_secure_) { UMA_HISTOGRAM_ENUMERATION( "PasswordManager.FillingAssistance.SecureOrigin", filling_assistance); + if (is_mixed_content_form_) { + UMA_HISTOGRAM_ENUMERATION("PasswordManager.FillingAssistance.MixedForm", + filling_assistance); + } } else { UMA_HISTOGRAM_ENUMERATION( "PasswordManager.FillingAssistance.InsecureOrigin", @@ -454,6 +458,11 @@ metrics_util::PasswordAccountStorageUsageLevel account_storage_usage_level) { CalculateJsOnlyInput(submitted_form); + if (is_main_frame_secure_ && submitted_form.action.is_valid() && + !submitted_form.is_action_empty && + !submitted_form.action.SchemeIsCryptographic()) { + is_mixed_content_form_ = true; + } filling_source_ = FillingSource::kNotFilled; account_storage_usage_level_ = account_storage_usage_level;
diff --git a/components/password_manager/core/browser/password_form_metrics_recorder.h b/components/password_manager/core/browser/password_form_metrics_recorder.h index f59a140..4431fd90 100644 --- a/components/password_manager/core/browser/password_form_metrics_recorder.h +++ b/components/password_manager/core/browser/password_form_metrics_recorder.h
@@ -483,6 +483,8 @@ base::Optional<JsOnlyInput> js_only_input_; + bool is_mixed_content_form_ = false; + DISALLOW_COPY_AND_ASSIGN(PasswordFormMetricsRecorder); };
diff --git a/components/password_manager/core/browser/password_form_metrics_recorder_unittest.cc b/components/password_manager/core/browser/password_form_metrics_recorder_unittest.cc index 68e433c..d2eeb171 100644 --- a/components/password_manager/core/browser/password_form_metrics_recorder_unittest.cc +++ b/components/password_manager/core/browser/password_form_metrics_recorder_unittest.cc
@@ -638,22 +638,39 @@ struct SubCase { bool is_main_frame_secure; PasswordAccountStorageUsageLevel account_storage_usage_level; + // Is mixed form only makes sense when is_main_frame_secure is true. + bool is_mixed_form = false; } sub_cases[] = { {.is_main_frame_secure = true, .account_storage_usage_level = - PasswordAccountStorageUsageLevel::kNotUsingAccountStorage}, + PasswordAccountStorageUsageLevel::kNotUsingAccountStorage, + .is_mixed_form = false}, + {.is_main_frame_secure = true, + .account_storage_usage_level = + PasswordAccountStorageUsageLevel::kNotUsingAccountStorage, + .is_mixed_form = true}, {.is_main_frame_secure = false, .account_storage_usage_level = PasswordAccountStorageUsageLevel::kNotUsingAccountStorage}, {.is_main_frame_secure = true, .account_storage_usage_level = - PasswordAccountStorageUsageLevel::kUsingAccountStorage}, + PasswordAccountStorageUsageLevel::kUsingAccountStorage, + .is_mixed_form = false}, + {.is_main_frame_secure = true, + .account_storage_usage_level = + PasswordAccountStorageUsageLevel::kUsingAccountStorage, + .is_mixed_form = true}, {.is_main_frame_secure = false, .account_storage_usage_level = PasswordAccountStorageUsageLevel::kUsingAccountStorage}, {.is_main_frame_secure = true, .account_storage_usage_level = - PasswordAccountStorageUsageLevel::kSyncing}, + PasswordAccountStorageUsageLevel::kSyncing, + .is_mixed_form = false}, + {.is_main_frame_secure = true, + .account_storage_usage_level = + PasswordAccountStorageUsageLevel::kUsingAccountStorage, + .is_mixed_form = true}, {.is_main_frame_secure = false, .account_storage_usage_level = PasswordAccountStorageUsageLevel::kSyncing}}; @@ -664,12 +681,20 @@ << ", is_main_frame_secure: " << std::boolalpha << sub_case.is_main_frame_secure << ", account_storage_usage_level: " << metrics_util::GetPasswordAccountStorageUsageLevelHistogramSuffix( - sub_case.account_storage_usage_level)); + sub_case.account_storage_usage_level) + << ", is_mixed_form: " << std::boolalpha << sub_case.is_mixed_form); base::test::TaskEnvironment task_environment; base::HistogramTester histogram_tester; FormData form_data = ConvertToFormData(test_case.fields); + if (sub_case.is_main_frame_secure) { + if (sub_case.is_mixed_form) { + form_data.action = GURL("http://notsecure.test"); + } else { + form_data.action = GURL("https://secure.test"); + } + } // Note: Don't bother with the profile store vs. account store distinction // here; there are separate tests that cover the filling source. @@ -699,6 +724,9 @@ !sub_case.is_main_frame_secure ? expected_count : 0; int expected_secure_count = sub_case.is_main_frame_secure ? expected_count : 0; + int expected_mixed_count = + sub_case.is_main_frame_secure && sub_case.is_mixed_form ? expected_count + : 0; // Split by account storage usage level. int expected_not_using_account_storage_count = 0; @@ -725,6 +753,8 @@ histogram_tester.ExpectTotalCount( "PasswordManager.FillingAssistance.SecureOrigin", expected_secure_count); + histogram_tester.ExpectTotalCount( + "PasswordManager.FillingAssistance.MixedForm", expected_mixed_count); histogram_tester.ExpectTotalCount( "PasswordManager.FillingAssistance.NotUsingAccountStorage", @@ -745,6 +775,12 @@ : "PasswordManager.FillingAssistance.InsecureOrigin", *test_case.expectation, 1); + if (sub_case.is_main_frame_secure && sub_case.is_mixed_form) { + histogram_tester.ExpectUniqueSample( + "PasswordManager.FillingAssistance.MixedForm", + *test_case.expectation, 1); + } + std::string account_storage_histogram; switch (sub_case.account_storage_usage_level) { case PasswordAccountStorageUsageLevel::kNotUsingAccountStorage:
diff --git a/components/performance_manager/BUILD.gn b/components/performance_manager/BUILD.gn index 94b2cac..a22123b 100644 --- a/components/performance_manager/BUILD.gn +++ b/components/performance_manager/BUILD.gn
@@ -106,6 +106,7 @@ "public/graph/worker_node.h", "public/mechanisms/tab_loading_frame_navigation_scheduler.h", "public/performance_manager.h", + "public/performance_manager_main_thread_mechanism.h", "public/performance_manager_main_thread_observer.h", "public/render_frame_host_proxy.h", "public/render_process_host_proxy.h",
diff --git a/components/performance_manager/embedder/performance_manager_registry.h b/components/performance_manager/embedder/performance_manager_registry.h index d7d3adf..61b02aec 100644 --- a/components/performance_manager/embedder/performance_manager_registry.h +++ b/components/performance_manager/embedder/performance_manager_registry.h
@@ -6,6 +6,7 @@ #define COMPONENTS_PERFORMANCE_MANAGER_EMBEDDER_PERFORMANCE_MANAGER_REGISTRY_H_ #include <memory> +#include <vector> #include "mojo/public/cpp/bindings/binder_map.h" #include "services/service_manager/public/cpp/binder_registry.h" @@ -14,6 +15,8 @@ class BrowserContext; class RenderFrameHost; class RenderProcessHost; +class NavigationHandle; +class NavigationThrottle; class WebContents; } // namespace content @@ -34,6 +37,8 @@ // This class can only be accessed on the main thread. class PerformanceManagerRegistry { public: + using Throttles = std::vector<std::unique_ptr<content::NavigationThrottle>>; + virtual ~PerformanceManagerRegistry() = default; PerformanceManagerRegistry(const PerformanceManagerRegistry&) = delete; @@ -57,6 +62,12 @@ virtual void CreatePageNodeForWebContents( content::WebContents* web_contents) = 0; + // Must be invoked for a NavigationHandle when it is committed, allowing the + // PM the opportunity to apply NavigationThrottles. Typically wired up to + // ContentBrowserClient::CreateThrottlesForNavigation. + virtual Throttles CreateThrottlesForNavigation( + content::NavigationHandle* handle) = 0; + // Must be invoked when a BrowserContext is added/removed. // Registers/unregisters an observer that creates WorkerNodes when // SharedWorkerInstances are added in the BrowserContext.
diff --git a/components/performance_manager/mechanisms/tab_loading_frame_navigation_scheduler.cc b/components/performance_manager/mechanisms/tab_loading_frame_navigation_scheduler.cc index 208c9382..d7df827b 100644 --- a/components/performance_manager/mechanisms/tab_loading_frame_navigation_scheduler.cc +++ b/components/performance_manager/mechanisms/tab_loading_frame_navigation_scheduler.cc
@@ -6,6 +6,8 @@ #include "base/no_destructor.h" #include "components/performance_manager/public/graph/policies/tab_loading_frame_navigation_policy.h" +#include "components/performance_manager/public/performance_manager.h" +#include "components/performance_manager/public/performance_manager_main_thread_mechanism.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/navigation_throttle.h" @@ -53,6 +55,36 @@ return g_policy_delegate; } +class MainThreadMechanism : public PerformanceManagerMainThreadMechanism { + public: + MainThreadMechanism() = default; + ~MainThreadMechanism() override = default; + + MainThreadMechanism(const MainThreadMechanism&) = delete; + MainThreadMechanism& operator=(const MainThreadMechanism&) = delete; + + // PerformanceManagerMainThreadMechanism implementation: + Throttles CreateThrottlesForNavigation( + content::NavigationHandle* handle) override { + auto throttle = + TabLoadingFrameNavigationScheduler::MaybeCreateThrottleForNavigation( + handle); + Throttles throttles; + if (throttle) + throttles.push_back(std::move(throttle)); + return throttles; + } + + static MainThreadMechanism* Instance() { + // NOTE: We should really have the policy object create an instance of the + // mechanism, and explicitly manage its lifetime, instead of having this + // singleton proxy that lives forever. To do that properly we'll need + // something like GraphRegistered for the main thread. + static base::NoDestructor<MainThreadMechanism> instance; + return instance.get(); + } +}; + } // namespace // A very simple throttle that always defers until Resume is called. @@ -166,11 +198,15 @@ if (enabled == g_throttling_enabled) return; g_throttling_enabled = enabled; - if (enabled) + + if (enabled) { + PerformanceManager::AddMechanism(MainThreadMechanism::Instance()); return; + } // At this point the throttling is being disabled. Stop throttling all // currently-throttled contents. + PerformanceManager::RemoveMechanism(MainThreadMechanism::Instance()); while (g_root) g_root->StopThrottlingImpl(); // Causes |g_root| to delete itself. } @@ -202,6 +238,11 @@ return g_throttling_enabled; } +// static +bool TabLoadingFrameNavigationScheduler::IsMechanismRegisteredForTesting() { + return PerformanceManager::HasMechanism(MainThreadMechanism::Instance()); +} + TabLoadingFrameNavigationScheduler::TabLoadingFrameNavigationScheduler( content::WebContents* contents) : content::WebContentsObserver(contents) {
diff --git a/components/performance_manager/mechanisms/tab_loading_frame_navigation_scheduler_browsertest.cc b/components/performance_manager/mechanisms/tab_loading_frame_navigation_scheduler_browsertest.cc index fd995521..75f5fd11 100644 --- a/components/performance_manager/mechanisms/tab_loading_frame_navigation_scheduler_browsertest.cc +++ b/components/performance_manager/mechanisms/tab_loading_frame_navigation_scheduler_browsertest.cc
@@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/run_loop.h" #include "base/test/bind_test_util.h" +#include "components/performance_manager/performance_manager_registry_impl.h" #include "components/performance_manager/test_support/performance_manager_browsertest_harness.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/navigation_controller.h" @@ -74,9 +75,13 @@ // Enable the mechanism at the beginning of all tests. EXPECT_FALSE( TabLoadingFrameNavigationScheduler::IsThrottlingEnabledForTesting()); + EXPECT_FALSE( + TabLoadingFrameNavigationScheduler::IsMechanismRegisteredForTesting()); TabLoadingFrameNavigationScheduler::SetThrottlingEnabled(true); EXPECT_TRUE( TabLoadingFrameNavigationScheduler::IsThrottlingEnabledForTesting()); + EXPECT_TRUE( + TabLoadingFrameNavigationScheduler::IsMechanismRegisteredForTesting()); // Register a callback so we can set navigation throttles. Passing // |this| is fine because we clear the callback before we are torn down. @@ -95,10 +100,13 @@ content::ShellContentBrowserClient::Get() ->set_create_throttles_for_navigation_callback(callback); - // Disable at the end of all tests. + // Disable at the end of all tests. Some tests may already have disabled + // throttling, so don't first check it is enabled. TabLoadingFrameNavigationScheduler::SetThrottlingEnabled(false); EXPECT_FALSE( TabLoadingFrameNavigationScheduler::IsThrottlingEnabledForTesting()); + EXPECT_FALSE( + TabLoadingFrameNavigationScheduler::IsMechanismRegisteredForTesting()); TabLoadingFrameNavigationScheduler::SetPolicyDelegateForTesting(nullptr);
diff --git a/components/performance_manager/performance_manager.cc b/components/performance_manager/performance_manager.cc index f614442d..ea828fd 100644 --- a/components/performance_manager/performance_manager.cc +++ b/components/performance_manager/performance_manager.cc
@@ -91,4 +91,22 @@ PerformanceManagerRegistryImpl::GetInstance()->RemoveObserver(observer); } +// static +void PerformanceManager::AddMechanism( + PerformanceManagerMainThreadMechanism* mechanism) { + PerformanceManagerRegistryImpl::GetInstance()->AddMechanism(mechanism); +} + +// static +void PerformanceManager::RemoveMechanism( + PerformanceManagerMainThreadMechanism* mechanism) { + PerformanceManagerRegistryImpl::GetInstance()->RemoveMechanism(mechanism); +} + +// static +bool PerformanceManager::HasMechanism( + PerformanceManagerMainThreadMechanism* mechanism) { + return PerformanceManagerRegistryImpl::GetInstance()->HasMechanism(mechanism); +} + } // namespace performance_manager
diff --git a/components/performance_manager/performance_manager_registry_impl.cc b/components/performance_manager/performance_manager_registry_impl.cc index 24ae683..4cb56c4 100644 --- a/components/performance_manager/performance_manager_registry_impl.cc +++ b/components/performance_manager/performance_manager_registry_impl.cc
@@ -4,6 +4,7 @@ #include "components/performance_manager/performance_manager_registry_impl.h" +#include <iterator> #include <utility> #include "base/stl_util.h" @@ -11,10 +12,12 @@ #include "components/performance_manager/performance_manager_tab_helper.h" #include "components/performance_manager/public/mojom/coordination_unit.mojom.h" #include "components/performance_manager/public/performance_manager.h" +#include "components/performance_manager/public/performance_manager_main_thread_mechanism.h" #include "components/performance_manager/public/performance_manager_main_thread_observer.h" #include "components/performance_manager/service_worker_context_adapter.h" #include "components/performance_manager/worker_watcher.h" #include "content/public/browser/browser_context.h" +#include "content/public/browser/navigation_throttle.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/storage_partition.h" @@ -59,6 +62,21 @@ observers_.RemoveObserver(observer); } +void PerformanceManagerRegistryImpl::AddMechanism( + PerformanceManagerMainThreadMechanism* mechanism) { + mechanisms_.AddObserver(mechanism); +} + +void PerformanceManagerRegistryImpl::RemoveMechanism( + PerformanceManagerMainThreadMechanism* mechanism) { + mechanisms_.RemoveObserver(mechanism); +} + +bool PerformanceManagerRegistryImpl::HasMechanism( + PerformanceManagerMainThreadMechanism* mechanism) { + return mechanisms_.HasObserver(mechanism); +} + void PerformanceManagerRegistryImpl::CreatePageNodeForWebContents( content::WebContents* web_contents) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -80,6 +98,19 @@ } } +PerformanceManagerRegistryImpl::Throttles +PerformanceManagerRegistryImpl::CreateThrottlesForNavigation( + content::NavigationHandle* handle) { + Throttles combined_throttles; + for (auto& mechanism : mechanisms_) { + Throttles throttles = mechanism.CreateThrottlesForNavigation(handle); + combined_throttles.insert(combined_throttles.end(), + std::make_move_iterator(throttles.begin()), + std::make_move_iterator(throttles.end())); + } + return combined_throttles; +} + void PerformanceManagerRegistryImpl::NotifyBrowserContextAdded( content::BrowserContext* browser_context) { content::StoragePartition* storage_partition =
diff --git a/components/performance_manager/performance_manager_registry_impl.h b/components/performance_manager/performance_manager_registry_impl.h index 5ac2b77..c9281f37 100644 --- a/components/performance_manager/performance_manager_registry_impl.h +++ b/components/performance_manager/performance_manager_registry_impl.h
@@ -25,6 +25,7 @@ namespace performance_manager { +class PerformanceManagerMainThreadMechanism; class PerformanceManagerMainThreadObserver; class ServiceWorkerContextAdapter; class WorkerWatcher; @@ -46,13 +47,21 @@ static PerformanceManagerRegistryImpl* GetInstance(); // Adds / removes an observer that is notified when a PageNode is created on - // the main thread. + // the main thread. Forwarded to from the public PerformanceManager interface. void AddObserver(PerformanceManagerMainThreadObserver* observer); void RemoveObserver(PerformanceManagerMainThreadObserver* observer); + // Adds / removes main thread mechanisms. Forwarded to from the public + // PerformanceManager interface. + void AddMechanism(PerformanceManagerMainThreadMechanism* mechanism); + void RemoveMechanism(PerformanceManagerMainThreadMechanism* mechanism); + bool HasMechanism(PerformanceManagerMainThreadMechanism* mechanism); + // PerformanceManagerRegistry: void CreatePageNodeForWebContents( content::WebContents* web_contents) override; + Throttles CreateThrottlesForNavigation( + content::NavigationHandle* handle) override; void NotifyBrowserContextAdded( content::BrowserContext* browser_context) override; void NotifyBrowserContextRemoved( @@ -101,6 +110,7 @@ performance_manager::TabHelperFrameNodeSource frame_node_source_; base::ObserverList<PerformanceManagerMainThreadObserver> observers_; + base::ObserverList<PerformanceManagerMainThreadMechanism> mechanisms_; }; } // namespace performance_manager
diff --git a/components/performance_manager/performance_manager_registry_impl_unittest.cc b/components/performance_manager/performance_manager_registry_impl_unittest.cc index a27526a..7381157f 100644 --- a/components/performance_manager/performance_manager_registry_impl_unittest.cc +++ b/components/performance_manager/performance_manager_registry_impl_unittest.cc
@@ -4,8 +4,13 @@ #include "components/performance_manager/performance_manager_registry_impl.h" +#include "base/memory/ptr_util.h" +#include "components/performance_manager/public/performance_manager_main_thread_mechanism.h" #include "components/performance_manager/public/performance_manager_main_thread_observer.h" #include "components/performance_manager/test_support/performance_manager_test_harness.h" +#include "content/public/browser/navigation_handle.h" +#include "content/public/test/mock_navigation_handle.h" +#include "content/public/test/test_navigation_throttle.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -29,6 +34,36 @@ using MockObserver = ::testing::StrictMock<LenientMockObserver>; +class LenientMockMechanism : public PerformanceManagerMainThreadMechanism { + public: + LenientMockMechanism() = default; + ~LenientMockMechanism() override = default; + + void ExpectCallToCreateThrottlesForNavigation( + content::NavigationHandle* handle, + Throttles throttles_to_return) { + throttles_to_return_ = std::move(throttles_to_return); + EXPECT_CALL(*this, OnCreateThrottlesForNavigation(handle)); + } + + private: + MOCK_METHOD1(OnCreateThrottlesForNavigation, + void(content::NavigationHandle*)); + + // PerformanceManagerMainThreadMechanism implementation: + // GMock doesn't support move-only types, so we use a custom wrapper to work + // around this. + Throttles CreateThrottlesForNavigation( + content::NavigationHandle* handle) override { + OnCreateThrottlesForNavigation(handle); + return std::move(throttles_to_return_); + } + + Throttles throttles_to_return_; +}; + +using MockMechanism = ::testing::StrictMock<LenientMockMechanism>; + } // namespace TEST_F(PerformanceManagerRegistryImplTest, @@ -47,4 +82,49 @@ registry->RemoveObserver(&observer); } +TEST_F(PerformanceManagerRegistryImplTest, + MechanismCreateThrottlesForNavigation) { + MockMechanism mechanism1, mechanism2; + PerformanceManagerRegistryImpl* registry = + PerformanceManagerRegistryImpl::GetInstance(); + registry->AddMechanism(&mechanism1); + registry->AddMechanism(&mechanism2); + + std::unique_ptr<content::WebContents> contents = + content::RenderViewHostTestHarness::CreateTestWebContents(); + std::unique_ptr<content::NavigationHandle> handle = + base::WrapUnique(new content::MockNavigationHandle(contents.get())); + std::unique_ptr<content::NavigationThrottle> throttle1 = + base::WrapUnique(new content::TestNavigationThrottle(handle.get())); + std::unique_ptr<content::NavigationThrottle> throttle2 = + base::WrapUnique(new content::TestNavigationThrottle(handle.get())); + std::unique_ptr<content::NavigationThrottle> throttle3 = + base::WrapUnique(new content::TestNavigationThrottle(handle.get())); + auto* raw_throttle1 = throttle1.get(); + auto* raw_throttle2 = throttle2.get(); + auto* raw_throttle3 = throttle3.get(); + MockMechanism::Throttles throttles1, throttles2; + throttles1.push_back(std::move(throttle1)); + throttles2.push_back(std::move(throttle2)); + throttles2.push_back(std::move(throttle3)); + + mechanism1.ExpectCallToCreateThrottlesForNavigation(handle.get(), + std::move(throttles1)); + mechanism2.ExpectCallToCreateThrottlesForNavigation(handle.get(), + std::move(throttles2)); + auto throttles = registry->CreateThrottlesForNavigation(handle.get()); + testing::Mock::VerifyAndClear(&mechanism1); + testing::Mock::VerifyAndClear(&mechanism2); + + // Expect that the throttles from both mechanisms were combined into one + // list. + ASSERT_EQ(3u, throttles.size()); + EXPECT_EQ(raw_throttle1, throttles[0].get()); + EXPECT_EQ(raw_throttle2, throttles[1].get()); + EXPECT_EQ(raw_throttle3, throttles[2].get()); + + registry->RemoveMechanism(&mechanism1); + registry->RemoveMechanism(&mechanism2); +} + } // namespace performance_manager
diff --git a/components/performance_manager/public/mechanisms/tab_loading_frame_navigation_scheduler.h b/components/performance_manager/public/mechanisms/tab_loading_frame_navigation_scheduler.h index 27f08339..520031b0 100644 --- a/components/performance_manager/public/mechanisms/tab_loading_frame_navigation_scheduler.h +++ b/components/performance_manager/public/mechanisms/tab_loading_frame_navigation_scheduler.h
@@ -49,6 +49,8 @@ // in a disabled state, and only starts throttling when explicitly enabled. // When subsequently disabled all outstanding throttles are released. Can be // toggled multiple times, but this should only really happen in tests. + // The mechanism adds itself to the list of PM UI-thread mechanisms when it is + // enabled, and removes itself when disabled. static void SetThrottlingEnabled(bool enabled); // Stops throttling the given |contents|, only if it is currently treating the @@ -59,6 +61,7 @@ // Testing seams. static void SetPolicyDelegateForTesting(PolicyDelegate* policy_delegate); static bool IsThrottlingEnabledForTesting(); + static bool IsMechanismRegisteredForTesting(); void StopThrottlingForTesting() { StopThrottlingImpl(); } size_t GetThrottleCountForTesting() const { return throttles_.size(); }
diff --git a/components/performance_manager/public/performance_manager.h b/components/performance_manager/public/performance_manager.h index bf85e8d..4616099 100644 --- a/components/performance_manager/public/performance_manager.h +++ b/components/performance_manager/public/performance_manager.h
@@ -22,6 +22,7 @@ class Graph; class GraphOwned; class PageNode; +class PerformanceManagerMainThreadMechanism; class PerformanceManagerMainThreadObserver; // The performance manager is a rendezvous point for communicating with the @@ -77,6 +78,12 @@ static void AddObserver(PerformanceManagerMainThreadObserver* observer); static void RemoveObserver(PerformanceManagerMainThreadObserver* observer); + // Adds / removes a mechanism that need to be called synchronously on the main + // thread (ie, to apply NavigationThrottles). + static void AddMechanism(PerformanceManagerMainThreadMechanism* mechanism); + static void RemoveMechanism(PerformanceManagerMainThreadMechanism* mechanism); + static bool HasMechanism(PerformanceManagerMainThreadMechanism* mechanism); + protected: PerformanceManager();
diff --git a/components/performance_manager/public/performance_manager_main_thread_mechanism.h b/components/performance_manager/public/performance_manager_main_thread_mechanism.h new file mode 100644 index 0000000..a139a1bb --- /dev/null +++ b/components/performance_manager/public/performance_manager_main_thread_mechanism.h
@@ -0,0 +1,44 @@ +// 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_PERFORMANCE_MANAGER_PUBLIC_PERFORMANCE_MANAGER_MAIN_THREAD_MECHANISM_H_ +#define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_PERFORMANCE_MANAGER_MAIN_THREAD_MECHANISM_H_ + +#include "base/observer_list_types.h" + +#include <memory> +#include <vector> + +namespace content { +class NavigationHandle; +class NavigationThrottle; +} // namespace content + +namespace performance_manager { + +// Interface for implementing PerformanceManager mechanism hooks that occur on +// the main thread. All methods are invoked on the main thread. +class PerformanceManagerMainThreadMechanism : public base::CheckedObserver { + public: + using Throttles = std::vector<std::unique_ptr<content::NavigationThrottle>>; + + ~PerformanceManagerMainThreadMechanism() override = default; + + PerformanceManagerMainThreadMechanism( + const PerformanceManagerMainThreadMechanism&) = delete; + PerformanceManagerMainThreadMechanism& operator=( + const PerformanceManagerMainThreadMechanism&) = delete; + + // Invoked when a NavigationHandle is committed, providing an opportunity for + // the mechanism to apply throttles. + virtual Throttles CreateThrottlesForNavigation( + content::NavigationHandle* handle) = 0; + + protected: + PerformanceManagerMainThreadMechanism() = default; +}; + +} // namespace performance_manager + +#endif // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_PERFORMANCE_MANAGER_MAIN_THREAD_OBSERVER_H_
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index a1c7554..f323251b6 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -1019,6 +1019,7 @@ 'ExternalPrintServers', 'ExternalPrintServersWhitelist', 'PrinterTypeDenyList', + 'PrintRasterizationMode', ] }, { @@ -3624,7 +3625,6 @@ }, 'id': 700, 'supported_on' : ['chrome.*:84-', 'chrome_os:84-'], - 'future': True, 'caption': '''List of file types that should be automatically opened on download''', 'tags': [], 'desc': '''List of file types that should be automatically opened on download. The leading separator should not be included when listing the file type, so list "txt" instead of ".txt". @@ -17966,9 +17966,29 @@ 'id': 503, 'caption': '''Allow devices to use a <ph name="PLUGIN_VM_NAME">PluginVm</ph> on <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph>''', 'tags': [], - 'desc': '''Enable this device to run PluginVm. + 'desc': '''Allow this device to run PluginVm. - If the policy is set to false or left unset, <ph name="PLUGIN_VM_NAME">PluginVm</ph> is not enabled for the device. If set to true, <ph name="PLUGIN_VM_NAME">PluginVm</ph> is enabled for the device as long as other settings also allow it. <ph name="PLUGIN_VM_ALLOWED_POLICY_NAME">PluginVmAllowed</ph> needs to be true, and either <ph name="PLUGIN_VM_LICENSE_KEY_POLICY_NAME">PluginVmLicenseKey</ph> or <ph name="PLUGIN_VM_USER_ID_POLICY_NAME">PluginVmUserId</ph> or <ph name="PLUGIN_VM_IMAGE_POLICY_NAME">PluginVmImage</ph> need to be set for <ph name="PLUGIN_VM_NAME">PluginVm</ph> to be allowed to run.''', + If the policy is set to false or left unset, <ph name="PLUGIN_VM_NAME">PluginVm</ph> is not enabled for the device. + If set to true, <ph name="PLUGIN_VM_NAME">PluginVm</ph> is enabled for the device as long as other settings also allow it. <ph name="PLUGIN_VM_ALLOWED_POLICY_NAME">PluginVmAllowed</ph> and <ph name="USER_PLUGIN_VM_ALLOWED_POLICY_NAME">UserPluginVmAllowed</ph> need to be true, and either <ph name="PLUGIN_VM_LICENSE_KEY_POLICY_NAME">PluginVmLicenseKey</ph> or <ph name="PLUGIN_VM_USER_ID_POLICY_NAME">PluginVmUserId</ph> need to be set for <ph name="PLUGIN_VM_NAME">PluginVm</ph> to be allowed to run.''', + }, + { + 'name': 'UserPluginVmAllowed', + 'owners': ['okalitova@chromium.org', 'janagrill@chromium.org'], + 'type': 'main', + 'schema': { 'type': 'boolean' }, + 'supported_on': ['chrome_os:84-'], + 'features': { + 'dynamic_refresh': True, + 'per_profile': False, + }, + 'example_value': True, + 'id': 705, + 'caption': '''Allow users to use a <ph name="PLUGIN_VM_NAME">PluginVm</ph> on <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph>''', + 'tags': [], + 'desc': '''Allow this user to run PluginVm. + + If the policy is set to false or left unset, <ph name="PLUGIN_VM_NAME">PluginVm</ph> is not enabled for the user. + If set to true, <ph name="PLUGIN_VM_NAME">PluginVm</ph> is enabled for the user as long as other settings also allow it. <ph name="PLUGIN_VM_ALLOWED_POLICY_NAME">PluginVmAllowed</ph> and <ph name="USER_PLUGIN_VM_ALLOWED_POLICY_NAME">UserPluginVmAllowed</ph> need to be true, and either <ph name="PLUGIN_VM_LICENSE_KEY_POLICY_NAME">PluginVmLicenseKey</ph> or <ph name="PLUGIN_VM_USER_ID_POLICY_NAME">PluginVmUserId</ph> need to be set for <ph name="PLUGIN_VM_NAME">PluginVm</ph> to be allowed to run.''', }, { 'name': 'PluginVmLicenseKey', @@ -20638,6 +20658,45 @@ Local printers are also known as native printing destinations, and include destinations available to the local machine and shared network printers.''' }, { + 'name': 'PrintRasterizationMode', + 'owners': ['thestig@chromium.org', 'file://printing/OWNERS'], + 'type': 'int-enum', + 'schema': { + 'type': 'integer', + 'enum': [ 0, 1 ], + }, + 'items': [ + { + 'name': 'Full', + 'value': 0, + 'caption': '''available''', + }, + { + 'name': 'Fast', + 'value': 1, + 'caption': '''disabled''', + }, + ], + 'supported_on': ['chrome.win:84-'], + 'features': { + 'dynamic_refresh': True, + 'per_profile': True, + }, + 'example_value': 1, + 'id': 706, + 'caption': '''Print Rasterization Mode''', + 'tags': [], + 'desc': '''Controls how <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> prints on Windows. + + When printing to a non-PostScript printer on Windows, sometimes print jobs need to be rasterized to print correctly. + + When this policy is set to Full, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will do full page rasterization if necessary. + + When this policy is set to Fast, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will avoid rasterization if possible, reducing the amount of rasterization can help reduce print job sizes and increase printing speed. + + When this policy is not set, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will be in Full mode.''' + }, + { 'name': 'AmbientAuthenticationInPrivateModesEnabled', 'owners': ['rhalavati@chromium.org', 'roagarwal@chromium.org', 'chrome-privacy-core@google.com'], 'type': 'int-enum', @@ -21896,6 +21955,7 @@ 'caption': '''PluginVm''', 'policies': [ 'PluginVmAllowed', + 'UserPluginVmAllowed', 'PluginVmLicenseKey', 'PluginVmImage', 'PluginVmUserId', @@ -22014,6 +22074,6 @@ ], 'placeholders': [], 'deleted_policy_ids': [412, 476, 546, 562, 569, 578], - 'highest_id_currently_used': 704, + 'highest_id_currently_used': 706, 'highest_atomic_group_id_currently_used': 38 }
diff --git a/components/policy/resources/webui/policy.html b/components/policy/resources/webui/policy.html index 4ef1ca6d8..f41a83d 100644 --- a/components/policy/resources/webui/policy.html +++ b/components/policy/resources/webui/policy.html
@@ -53,6 +53,10 @@ <fieldset id="status-box-template"> <legend class="legend"></legend> <div class="status-entry" hidden> + <div class="label">$i18n{labelVersion}</div> + <div class="version"></div> + </div> + <div class="status-entry" hidden> <div class="label">$i18n{labelEnterpriseEnrollmentDomain}</div> <div class="enterprise-enrollment-domain"></div> </div> @@ -100,19 +104,19 @@ <div class="label">$i18n{labelDirectoryApiId}</div> <div class="directory-api-id"></div> </div> - <div class="status-entry"> + <div class="status-entry" hidden> <div class="label">$i18n{labelTimeSinceLastRefresh}</div> <div class="time-since-last-refresh"></div> </div> - <div class="status-entry"> + <div class="status-entry" hidden> <div class="label">$i18n{labelRefreshInterval}</div> <div class="refresh-interval"></div> </div> - <div class="status-entry"> + <div class="status-entry" hidden> <div class="label">$i18n{labelPoliciesPush}</div> <div class="policy-push"></div> </div> - <div class="status-entry"> + <div class="status-entry" hidden> <div class="label">$i18n{labelStatus}</div> <div class="status"></div> </div> @@ -124,6 +128,10 @@ <div class="label">$i18n{labelIsOffHoursActive}</div> <div class="is-offhours-active"></div> </div> + <div class="status-entry" hidden> + <div class="label">$i18n{labelVersion}</div> + <div class="version"></div> + </div> </fieldset> <div class="policy-table" id="policy-table-template" role="table"
diff --git a/components/policy/resources/webui/policy_base.js b/components/policy/resources/webui/policy_base.js index 3f810a3a..c0cbb30 100644 --- a/components/policy/resources/webui/policy_base.js +++ b/components/policy/resources/webui/policy_base.js
@@ -96,8 +96,8 @@ }, /** * Populate the box with the given cloud policy status. - * @param {string} scope The policy scope, either "device", "machine", or - * "user". + * @param {string} scope The policy scope, either "device", "machine", + * "user", or "updater". * @param {Object} status Dictionary with information about the status. */ initialize(scope, status) { @@ -144,6 +144,15 @@ '.machine-enrollment-token', status.enrollmentToken); this.setLabelAndShow_('.machine-enrollment-name', status.machine); this.setLabelAndShow_('.machine-enrollment-domain', status.domain); + } else if (scope === 'updater') { + this.querySelector('.legend').textContent = + loadTimeData.getString('statusUpdater'); + if (status.version) { + this.setLabelAndShow_('.version', status.version); + } + if (status.domain) { + this.setLabelAndShow_('.enterprise-enrollment-domain', status.domain); + } } else { // For user policy, set the appropriate title and populate the topmost // status item with the username that policies apply to. @@ -161,15 +170,19 @@ status.isAffiliated ? 'isAffiliatedYes' : 'isAffiliatedNo')); } } - this.setLabelAndShow_( - '.time-since-last-refresh', status.timeSinceLastRefresh, false); - this.setLabelAndShow_('.refresh-interval', status.refreshInterval, false); - this.setLabelAndShow_('.status', status.status, false); - this.setLabelAndShow_( - '.policy-push', - loadTimeData.getString( - status.policiesPushAvailable ? 'policiesPushOn' : - 'policiesPushOff')); + + if (scope !== 'updater') { + this.setLabelAndShow_( + '.time-since-last-refresh', status.timeSinceLastRefresh, false); + this.setLabelAndShow_( + '.refresh-interval', status.refreshInterval, false); + this.setLabelAndShow_('.status', status.status, false); + this.setLabelAndShow_( + '.policy-push', + loadTimeData.getString( + status.policiesPushAvailable ? 'policiesPushOn' : + 'policiesPushOff')); + } }, };
diff --git a/components/policy_strings.grdp b/components/policy_strings.grdp index b17025b05..2abfdb4 100644 --- a/components/policy_strings.grdp +++ b/components/policy_strings.grdp
@@ -297,6 +297,11 @@ <message name="IDS_POLICY_STATUS_MACHINE" desc="Title for the machine policy status box."> Machine policies </message> + <if expr="is_win"> + <message name="IDS_POLICY_STATUS_UPDATER" desc="Title for the updater policy status box on windows."> + Google Update + </message> + </if> <message name="IDS_POLICY_LABEL_ENTERPRISE_ENROLLMENT_DOMAIN" desc="Label for the enrollment domain in the device policy status box."> Enrollment domain: </message> @@ -369,6 +374,9 @@ <message name="IDS_POLICY_LABEL_VALUE" desc="Label for the value row in the policy table."> Value </message> + <message name="IDS_POLICY_LABEL_VERSION" desc="Label for the version in the policy status box."> + Version: + </message> <message name="IDS_POLICY_LABEL_STATUS" desc="Label for the actual status in the policy status boxes."> Status: </message>
diff --git a/components/query_tiles/DEPS b/components/query_tiles/DEPS index 19bffde..ba8feee5 100644 --- a/components/query_tiles/DEPS +++ b/components/query_tiles/DEPS
@@ -4,6 +4,7 @@ "+components/image_fetcher", "+components/keyed_service", "+components/leveldb_proto", + "+components/prefs", "+net", "+services/network/public", "+services/network/test",
diff --git a/components/query_tiles/android/java/src/org/chromium/components/query_tiles/bridges/TileConversionBridge.java b/components/query_tiles/android/java/src/org/chromium/components/query_tiles/bridges/TileConversionBridge.java index 7d56eccf..5ab5e77f 100644 --- a/components/query_tiles/android/java/src/org/chromium/components/query_tiles/bridges/TileConversionBridge.java +++ b/components/query_tiles/android/java/src/org/chromium/components/query_tiles/bridges/TileConversionBridge.java
@@ -16,7 +16,7 @@ /** * Bridge to the native query tile service for the given {@link Profile}. */ -@JNINamespace("upboarding") +@JNINamespace("query_tiles") public class TileConversionBridge { @CalledByNative private static List<QueryTile> createList() {
diff --git a/components/query_tiles/android/java/src/org/chromium/components/query_tiles/bridges/TileProviderBridge.java b/components/query_tiles/android/java/src/org/chromium/components/query_tiles/bridges/TileProviderBridge.java index 4af9da3..7028add 100644 --- a/components/query_tiles/android/java/src/org/chromium/components/query_tiles/bridges/TileProviderBridge.java +++ b/components/query_tiles/android/java/src/org/chromium/components/query_tiles/bridges/TileProviderBridge.java
@@ -16,7 +16,7 @@ /** * Bridge to the native query tile service for the given {@link Profile}. */ -@JNINamespace("upboarding") +@JNINamespace("query_tiles") public class TileProviderBridge implements TileProvider { private long mNativeTileProviderBridge;
diff --git a/components/query_tiles/android/tile_conversion_bridge.cc b/components/query_tiles/android/tile_conversion_bridge.cc index 023044a..18042c0 100644 --- a/components/query_tiles/android/tile_conversion_bridge.cc +++ b/components/query_tiles/android/tile_conversion_bridge.cc
@@ -11,7 +11,7 @@ #include "base/android/jni_string.h" #include "components/query_tiles/jni_headers/TileConversionBridge_jni.h" -namespace upboarding { +namespace query_tiles { using base::android::ConvertUTF8ToJavaString; using base::android::ToJavaArrayOfStrings; @@ -49,4 +49,4 @@ return jlist; } -} // namespace upboarding +} // namespace query_tiles
diff --git a/components/query_tiles/android/tile_conversion_bridge.h b/components/query_tiles/android/tile_conversion_bridge.h index d55692d..3aa0744d 100644 --- a/components/query_tiles/android/tile_conversion_bridge.h +++ b/components/query_tiles/android/tile_conversion_bridge.h
@@ -12,7 +12,7 @@ using base::android::ScopedJavaLocalRef; -namespace upboarding { +namespace query_tiles { // Helper class providing tile conversion utility methods between C++ and Java. class TileConversionBridge { @@ -22,6 +22,6 @@ const std::vector<Tile>& tiles); }; -} // namespace upboarding +} // namespace query_tiles #endif // COMPONENTS_QUERY_TILES_ANDROID_TILE_CONVERSION_BRIDGE_H_
diff --git a/components/query_tiles/android/tile_provider_bridge.cc b/components/query_tiles/android/tile_provider_bridge.cc index 8cc42d7..e94cbc97 100644 --- a/components/query_tiles/android/tile_provider_bridge.cc +++ b/components/query_tiles/android/tile_provider_bridge.cc
@@ -17,7 +17,7 @@ using base::android::AttachCurrentThread; -namespace upboarding { +namespace query_tiles { namespace { const char kTileProviderBridgeKey[] = "tile_provider_bridge"; @@ -67,4 +67,4 @@ &RunGetTilesCallback, ScopedJavaGlobalRef<jobject>(jcallback))); } -} // namespace upboarding +} // namespace query_tiles
diff --git a/components/query_tiles/android/tile_provider_bridge.h b/components/query_tiles/android/tile_provider_bridge.h index 32f296d..bd2b4fce 100644 --- a/components/query_tiles/android/tile_provider_bridge.h +++ b/components/query_tiles/android/tile_provider_bridge.h
@@ -14,7 +14,7 @@ using base::android::ScopedJavaGlobalRef; using base::android::ScopedJavaLocalRef; -namespace upboarding { +namespace query_tiles { // Helper class responsible for bridging the TileProvider between C++ and Java. class TileProviderBridge : public base::SupportsUserData::Data { @@ -43,6 +43,6 @@ DISALLOW_COPY_AND_ASSIGN(TileProviderBridge); }; -} // namespace upboarding +} // namespace query_tiles #endif // COMPONENTS_QUERY_TILES_ANDROID_TILE_PROVIDER_BRIDGE_H_
diff --git a/components/query_tiles/internal/BUILD.gn b/components/query_tiles/internal/BUILD.gn index 858e875..f2e9916 100644 --- a/components/query_tiles/internal/BUILD.gn +++ b/components/query_tiles/internal/BUILD.gn
@@ -31,6 +31,8 @@ "tile_manager.h", "tile_service_impl.cc", "tile_service_impl.h", + "tile_service_scheduler.cc", + "tile_service_scheduler.h", "tile_store.cc", "tile_store.h", "tile_types.h", @@ -42,6 +44,7 @@ "//base", "//components/background_task_scheduler:public", "//components/leveldb_proto", + "//components/prefs", "//components/query_tiles:public", "//components/query_tiles/proto", "//net",
diff --git a/components/query_tiles/internal/cached_image_loader.cc b/components/query_tiles/internal/cached_image_loader.cc index 54321867..3d8b3a2 100644 --- a/components/query_tiles/internal/cached_image_loader.cc +++ b/components/query_tiles/internal/cached_image_loader.cc
@@ -21,7 +21,7 @@ using image_fetcher::ImageFetcherParams; using image_fetcher::RequestMetadata; -namespace upboarding { +namespace query_tiles { namespace { // A string used to log UMA for query tiles in image fetcher service. @@ -105,4 +105,4 @@ CreateImageFetcherParams()); } -} // namespace upboarding +} // namespace query_tiles
diff --git a/components/query_tiles/internal/cached_image_loader.h b/components/query_tiles/internal/cached_image_loader.h index 12dc56e..e2df62a 100644 --- a/components/query_tiles/internal/cached_image_loader.h +++ b/components/query_tiles/internal/cached_image_loader.h
@@ -14,7 +14,7 @@ class ImageFetcher; } // namespace image_fetcher -namespace upboarding { +namespace query_tiles { // Loads image with image fetcher service, which provides a disk cache to reduce // network data consumption. @@ -38,6 +38,6 @@ image_fetcher::ImageFetcher* reduced_mode_image_fetcher_; }; -} // namespace upboarding +} // namespace query_tiles #endif // COMPONENTS_QUERY_TILES_INTERNAL_CACHED_IMAGE_LOADER_H_
diff --git a/components/query_tiles/internal/cached_image_loader_unittest.cc b/components/query_tiles/internal/cached_image_loader_unittest.cc index 20303c8f..3019b8b 100644 --- a/components/query_tiles/internal/cached_image_loader_unittest.cc +++ b/components/query_tiles/internal/cached_image_loader_unittest.cc
@@ -24,7 +24,7 @@ using ::testing::_; using ::testing::Invoke; -namespace upboarding { +namespace query_tiles { namespace { class CachedImageLoaderTest : public testing::Test { @@ -107,4 +107,4 @@ } } // namespace -} // namespace upboarding +} // namespace query_tiles
diff --git a/components/query_tiles/internal/image_loader.h b/components/query_tiles/internal/image_loader.h index 9489827..6cae486 100644 --- a/components/query_tiles/internal/image_loader.h +++ b/components/query_tiles/internal/image_loader.h
@@ -14,7 +14,7 @@ class SkBitmap; -namespace upboarding { +namespace query_tiles { // Loads image for query tiles. class ImageLoader { @@ -37,6 +37,6 @@ virtual void PrefetchImage(const GURL& url, SuccessCallback callback) = 0; }; -} // namespace upboarding +} // namespace query_tiles #endif // COMPONENTS_QUERY_TILES_INTERNAL_IMAGE_LOADER_H_
diff --git a/components/query_tiles/internal/init_aware_tile_service.cc b/components/query_tiles/internal/init_aware_tile_service.cc index 3bb1a0b..1e42a7a8 100644 --- a/components/query_tiles/internal/init_aware_tile_service.cc +++ b/components/query_tiles/internal/init_aware_tile_service.cc
@@ -8,7 +8,7 @@ #include "base/bind_helpers.h" #include "base/threading/thread_task_runner_handle.h" -namespace upboarding { +namespace query_tiles { InitAwareTileService::InitAwareTileService( std::unique_ptr<InitializableTileService> tile_service) @@ -102,4 +102,4 @@ InitAwareTileService::~InitAwareTileService() = default; -} // namespace upboarding +} // namespace query_tiles
diff --git a/components/query_tiles/internal/init_aware_tile_service.h b/components/query_tiles/internal/init_aware_tile_service.h index beffa71..e1ade43 100644 --- a/components/query_tiles/internal/init_aware_tile_service.h +++ b/components/query_tiles/internal/init_aware_tile_service.h
@@ -13,7 +13,7 @@ #include "components/query_tiles/internal/tile_service_impl.h" #include "components/query_tiles/tile_service.h" -namespace upboarding { +namespace query_tiles { // TileService that can cache API calls before the underlying |tile_service_| is // initialized. After a successful initialization of |tile_service_|, all cached @@ -50,6 +50,6 @@ base::WeakPtrFactory<InitAwareTileService> weak_ptr_factory_{this}; }; -} // namespace upboarding +} // namespace query_tiles #endif // COMPONENTS_QUERY_TILES_INTERNAL_INIT_AWARE_TILE_SERVICE_H_
diff --git a/components/query_tiles/internal/init_aware_tile_service_unittest.cc b/components/query_tiles/internal/init_aware_tile_service_unittest.cc index 2821b777..401a5ce9 100644 --- a/components/query_tiles/internal/init_aware_tile_service_unittest.cc +++ b/components/query_tiles/internal/init_aware_tile_service_unittest.cc
@@ -18,7 +18,7 @@ using testing::Invoke; using testing::StrictMock; -namespace upboarding { +namespace query_tiles { namespace { class MockInitializableTileService : public InitializableTileService { @@ -206,4 +206,4 @@ } } // namespace -} // namespace upboarding +} // namespace query_tiles
diff --git a/components/query_tiles/internal/proto_conversion.cc b/components/query_tiles/internal/proto_conversion.cc index a12f72f8..363666ca 100644 --- a/components/query_tiles/internal/proto_conversion.cc +++ b/components/query_tiles/internal/proto_conversion.cc
@@ -9,7 +9,7 @@ #include "base/strings/utf_string_conversions.h" -namespace upboarding { +namespace query_tiles { namespace { // Helper method to convert base::Time to integer for serialization. Loses @@ -133,4 +133,4 @@ tile_group->tiles.emplace_back(std::move(new_tile)); } } -} // namespace upboarding +} // namespace query_tiles
diff --git a/components/query_tiles/internal/proto_conversion.h b/components/query_tiles/internal/proto_conversion.h index 86ea3506..b3b3c7f 100644 --- a/components/query_tiles/internal/proto_conversion.h +++ b/components/query_tiles/internal/proto_conversion.h
@@ -10,7 +10,7 @@ #include "components/query_tiles/proto/tile_response.pb.h" #include "components/query_tiles/tile.h" -namespace upboarding { +namespace query_tiles { using ResponseGroupProto = query_tiles::proto::ServerResponse; using ResponseTileProto = query_tiles::proto::TileInfo; @@ -33,6 +33,6 @@ void TileGroupFromResponse(const ResponseGroupProto& response, TileGroup* tile_group); -} // namespace upboarding +} // namespace query_tiles #endif // COMPONENTS_QUERY_TILES_INTERNAL_PROTO_CONVERSION_H_
diff --git a/components/query_tiles/internal/proto_conversion_unittest.cc b/components/query_tiles/internal/proto_conversion_unittest.cc index 4383d03..9549c29 100644 --- a/components/query_tiles/internal/proto_conversion_unittest.cc +++ b/components/query_tiles/internal/proto_conversion_unittest.cc
@@ -9,7 +9,7 @@ #include "components/query_tiles/test/test_utils.h" #include "testing/gtest/include/gtest/gtest.h" -namespace upboarding { +namespace query_tiles { namespace { using TileInfoGroup = query_tiles::proto::TileInfoGroup; @@ -47,7 +47,7 @@ } void TestTileConversion(Tile& expected) { - upboarding::query_tiles::proto::Tile proto; + query_tiles::proto::Tile proto; Tile actual; TileToProto(&expected, &proto); TileFromProto(&proto, &actual); @@ -58,7 +58,7 @@ } void TestTileGroupConversion(TileGroup& expected) { - upboarding::query_tiles::proto::TileGroup proto; + query_tiles::proto::TileGroup proto; TileGroup actual; TileGroupToProto(&expected, &proto); TileGroupFromProto(&proto, &actual); @@ -105,4 +105,4 @@ } // namespace -} // namespace upboarding +} // namespace query_tiles
diff --git a/components/query_tiles/internal/stats.cc b/components/query_tiles/internal/stats.cc index 99342b9..8d4816b 100644 --- a/components/query_tiles/internal/stats.cc +++ b/components/query_tiles/internal/stats.cc
@@ -6,7 +6,7 @@ #include "base/notreached.h" -namespace upboarding { +namespace query_tiles { namespace stats { void RecordImageLoading(ImageLoadingEvent event) { @@ -14,4 +14,4 @@ } } // namespace stats -} // namespace upboarding \ No newline at end of file +} // namespace query_tiles \ No newline at end of file
diff --git a/components/query_tiles/internal/stats.h b/components/query_tiles/internal/stats.h index 09693bf5..76f4863 100644 --- a/components/query_tiles/internal/stats.h +++ b/components/query_tiles/internal/stats.h
@@ -5,7 +5,7 @@ #ifndef COMPONENTS_QUERY_TILES_INTERNAL_STATS_H_ #define COMPONENTS_QUERY_TILES_INTERNAL_STATS_H_ -namespace upboarding { +namespace query_tiles { namespace stats { // Event to track image loading metrics. @@ -21,6 +21,6 @@ void RecordImageLoading(ImageLoadingEvent event); } // namespace stats -} // namespace upboarding +} // namespace query_tiles #endif // COMPONENTS_QUERY_TILES_INTERNAL_STATS_H_
diff --git a/components/query_tiles/internal/store.h b/components/query_tiles/internal/store.h index 4fdf16d..896ce352 100644 --- a/components/query_tiles/internal/store.h +++ b/components/query_tiles/internal/store.h
@@ -13,7 +13,7 @@ #include "base/callback.h" #include "base/macros.h" -namespace upboarding { +namespace query_tiles { // Interface of query tile collection store. template <typename T> @@ -42,6 +42,6 @@ Store& operator=(const Store& other) = delete; }; -} // namespace upboarding +} // namespace query_tiles #endif // COMPONENTS_QUERY_TILES_INTERNAL_STORE_H_
diff --git a/components/query_tiles/internal/tile_config.cc b/components/query_tiles/internal/tile_config.cc index ab04523..0605975b 100644 --- a/components/query_tiles/internal/tile_config.cc +++ b/components/query_tiles/internal/tile_config.cc
@@ -7,31 +7,52 @@ #include "base/metrics/field_trial_params.h" #include "components/query_tiles/switches.h" -namespace upboarding { +namespace query_tiles { // Default base URL string for the Query Tiles server. constexpr char kDefaultBaseURL[] = "https://autopush-gsaprototype-pa.sandbox.googleapis.com"; // Default URL string for GetQueryTiles RPC. -const char kDefaultGetQueryTilePath[] = "/v1/querytiles"; +constexpr char kDefaultGetQueryTilePath[] = "/v1/querytiles"; // Finch parameter key for experiment tag to be passed to the server. -const char kExperimentTagKey[] = "experiment_tag"; +constexpr char kExperimentTagKey[] = "experiment_tag"; // Finch parameter key for base server URL to retrieve the tiles. -const char kBaseURLKey[] = "base_url"; +constexpr char kBaseURLKey[] = "base_url"; // Finch parameter key for expire duration in seconds. -const char kExpireDurationKey[] = "expire_duration"; +constexpr char kExpireDurationKey[] = "expire_duration"; // Finch parameter key for expire duration in seconds. -const char kIsUnmeteredNetworkRequiredKey[] = "is_unmetered_network_required"; +constexpr char kIsUnmeteredNetworkRequiredKey[] = + "is_unmetered_network_required"; + +// Finch parameter key for schedule interval. +constexpr char kScheduleIntervalKey[] = + "tile_background_task_schedule_interval"; + +// Finch parameter key for random window. +constexpr char kMaxRandomWindowKey[] = "tile_background_task_random_window"; + +// Finch parameter key for oneoff task window. +constexpr char kOneoffTaskWindowKey[] = + "tile_background_task_oneoff_task_window"; const char kImagePrefetchModeKey[] = "image_prefetch_mode"; // Default expire duration. -const int kDefaultExpireDurationInSeconds = 48 * 60 * 60; +constexpr int kDefaultExpireDurationInSeconds = 48 * 60 * 60; // 2 days. + +// Default periodic interval of background task. +constexpr int kDefaultScheduleInterval = 12 * 3600 * 1000; // 12 hours. + +// Default length of random window added to the interval. +constexpr int kDefaultRandomWindow = 4 * 3600 * 1000; // 4 hours. + +// Default length of random window added to the interval. +constexpr int kDefaultOneoffTaskWindow = 2 * 3600 * 1000; // 2 hours. namespace { const GURL BuildGetQueryTileURL(const GURL& base_url, const char* path) { @@ -83,4 +104,22 @@ return ImagePrefetchMode::kTopLevel; } -} // namespace upboarding +// static +int TileConfig::GetScheduleIntervalInMs() { + return base::GetFieldTrialParamByFeatureAsInt( + features::kQueryTiles, kScheduleIntervalKey, kDefaultScheduleInterval); +} + +// static +int TileConfig::GetMaxRandomWindowInMs() { + return base::GetFieldTrialParamByFeatureAsInt( + features::kQueryTiles, kMaxRandomWindowKey, kDefaultRandomWindow); +} + +// static +int TileConfig::GetOneoffTaskWindowInMs() { + return base::GetFieldTrialParamByFeatureAsInt( + features::kQueryTiles, kOneoffTaskWindowKey, kDefaultOneoffTaskWindow); +} + +} // namespace query_tiles
diff --git a/components/query_tiles/internal/tile_config.h b/components/query_tiles/internal/tile_config.h index cb017d70..2c9e3c0 100644 --- a/components/query_tiles/internal/tile_config.h +++ b/components/query_tiles/internal/tile_config.h
@@ -12,7 +12,7 @@ #include "components/query_tiles/internal/tile_types.h" #include "url/gurl.h" -namespace upboarding { +namespace query_tiles { // Default URL string for GetQueryTiles RPC. extern const char kDefaultGetQueryTilePath[]; @@ -32,6 +32,15 @@ // Finch parameter key for image prefetch mode. extern const char kImagePrefetchModeKey[]; +// Finch parameter key for the minimum interval to next schedule. +extern const char kNextScheduleMinIntervalKey[]; + +// Finch parameter key for random window. +extern const char kMaxRandomWindowKey[]; + +// Finch parameter key for one off task window. +extern const char kOneoffTaskWindowKey[]; + class TileConfig { public: // Gets the URL for the Query Tiles server. @@ -50,8 +59,18 @@ // Gets the image prefetch mode to determine how many images will be // prefetched in background task. static ImagePrefetchMode GetImagePrefetchMode(); + + // Get the interval of schedule window in ms. + static int GetScheduleIntervalInMs(); + + // Get the maxmium window for randomization in ms. + static int GetMaxRandomWindowInMs(); + + // Get the schedule window duration from start to end in one-off task params + // in ms. + static int GetOneoffTaskWindowInMs(); }; -} // namespace upboarding +} // namespace query_tiles #endif // COMPONENTS_QUERY_TILES_INTERNAL_TILE_CONFIG_H_
diff --git a/components/query_tiles/internal/tile_config_unittest.cc b/components/query_tiles/internal/tile_config_unittest.cc index ad4ca42..21053d8 100644 --- a/components/query_tiles/internal/tile_config_unittest.cc +++ b/components/query_tiles/internal/tile_config_unittest.cc
@@ -8,7 +8,7 @@ #include "components/query_tiles/switches.h" #include "testing/gtest/include/gtest/gtest.h" -namespace upboarding { +namespace query_tiles { namespace { @@ -68,4 +68,4 @@ ImagePrefetchMode::kAll); } -} // namespace upboarding +} // namespace query_tiles
diff --git a/components/query_tiles/internal/tile_fetcher.cc b/components/query_tiles/internal/tile_fetcher.cc index f4e833c6..53062ed 100644 --- a/components/query_tiles/internal/tile_fetcher.cc +++ b/components/query_tiles/internal/tile_fetcher.cc
@@ -14,7 +14,7 @@ #include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/simple_url_loader.h" -namespace upboarding { +namespace query_tiles { namespace { const char kRequestContentType[] = "application/x-protobuf"; @@ -167,4 +167,4 @@ TileFetcher::TileFetcher() = default; TileFetcher::~TileFetcher() = default; -} // namespace upboarding +} // namespace query_tiles
diff --git a/components/query_tiles/internal/tile_fetcher.h b/components/query_tiles/internal/tile_fetcher.h index 77545bea..3ff12aa4 100644 --- a/components/query_tiles/internal/tile_fetcher.h +++ b/components/query_tiles/internal/tile_fetcher.h
@@ -19,7 +19,7 @@ class SharedURLLoaderFactory; } // namespace network -namespace upboarding { +namespace query_tiles { class TileFetcher { public: @@ -50,6 +50,6 @@ TileFetcher(); }; -} // namespace upboarding +} // namespace query_tiles #endif // COMPONENTS_QUERY_TILES_INTERNAL_TILE_FETCHER_H_
diff --git a/components/query_tiles/internal/tile_fetcher_unittest.cc b/components/query_tiles/internal/tile_fetcher_unittest.cc index 8f0e50d..db20206 100644 --- a/components/query_tiles/internal/tile_fetcher_unittest.cc +++ b/components/query_tiles/internal/tile_fetcher_unittest.cc
@@ -38,7 +38,7 @@ })pb"; } // namespace -namespace upboarding { +namespace query_tiles { class TileFetcherTest : public testing::Test { public: TileFetcherTest(); @@ -234,4 +234,4 @@ "https://www.test.com/?country_code=US"); } -} // namespace upboarding +} // namespace query_tiles
diff --git a/components/query_tiles/internal/tile_group.cc b/components/query_tiles/internal/tile_group.cc index a2698990..c2f4ca0 100644 --- a/components/query_tiles/internal/tile_group.cc +++ b/components/query_tiles/internal/tile_group.cc
@@ -6,7 +6,7 @@ #include <utility> -namespace upboarding { +namespace query_tiles { namespace { @@ -50,4 +50,4 @@ TileGroup& TileGroup::operator=(TileGroup&& other) = default; -} // namespace upboarding +} // namespace query_tiles
diff --git a/components/query_tiles/internal/tile_group.h b/components/query_tiles/internal/tile_group.h index 79cac50..96cc243 100644 --- a/components/query_tiles/internal/tile_group.h +++ b/components/query_tiles/internal/tile_group.h
@@ -12,7 +12,7 @@ #include "base/time/time.h" #include "components/query_tiles/tile.h" -namespace upboarding { +namespace query_tiles { // A group of query tiles and metadata. struct TileGroup { @@ -41,6 +41,6 @@ std::vector<std::unique_ptr<Tile>> tiles; }; -} // namespace upboarding +} // namespace query_tiles #endif // COMPONENTS_QUERY_TILES_INTERNAL_TILE_GROUP_H_
diff --git a/components/query_tiles/internal/tile_group_unittest.cc b/components/query_tiles/internal/tile_group_unittest.cc index 8d7daed..ba0e8c8f 100644 --- a/components/query_tiles/internal/tile_group_unittest.cc +++ b/components/query_tiles/internal/tile_group_unittest.cc
@@ -12,7 +12,7 @@ #include "components/query_tiles/test/test_utils.h" #include "testing/gtest/include/gtest/gtest.h" -namespace upboarding { +namespace query_tiles { namespace { TEST(TileGroupTest, CompareOperators) { @@ -71,4 +71,4 @@ } // namespace -} // namespace upboarding +} // namespace query_tiles
diff --git a/components/query_tiles/internal/tile_iterator.cc b/components/query_tiles/internal/tile_iterator.cc index 5431dfc..d7275ae2 100644 --- a/components/query_tiles/internal/tile_iterator.cc +++ b/components/query_tiles/internal/tile_iterator.cc
@@ -7,7 +7,7 @@ #include "components/query_tiles/internal/tile_group.h" #include "components/query_tiles/tile.h" -namespace upboarding { +namespace query_tiles { TileIterator::TileIterator(std::vector<const Tile*> tiles, int levels) : levels_(levels) { @@ -52,4 +52,4 @@ tiles_queue_.push(TileLevelPair(level, tile)); } -} // namespace upboarding \ No newline at end of file +} // namespace query_tiles \ No newline at end of file
diff --git a/components/query_tiles/internal/tile_iterator.h b/components/query_tiles/internal/tile_iterator.h index 8b6d788..1b17a64f 100644 --- a/components/query_tiles/internal/tile_iterator.h +++ b/components/query_tiles/internal/tile_iterator.h
@@ -9,7 +9,7 @@ #include <utility> #include <vector> -namespace upboarding { +namespace query_tiles { struct Tile; struct TileGroup; @@ -63,6 +63,6 @@ const int levels_; }; -} // namespace upboarding +} // namespace query_tiles #endif // COMPONENTS_QUERY_TILES_INTERNAL_TILE_ITERATOR_H_
diff --git a/components/query_tiles/internal/tile_iterator_unittest.cc b/components/query_tiles/internal/tile_iterator_unittest.cc index 468766f..114b0e055 100644 --- a/components/query_tiles/internal/tile_iterator_unittest.cc +++ b/components/query_tiles/internal/tile_iterator_unittest.cc
@@ -12,7 +12,7 @@ #include "components/query_tiles/tile.h" #include "testing/gtest/include/gtest/gtest.h" -namespace upboarding { +namespace query_tiles { TEST(TileIteratorTest, EmtpyTileIterator) { TileIterator it(std::vector<const Tile*>(), TileIterator::kAllTiles); @@ -105,4 +105,4 @@ EXPECT_FALSE(it.Next()); } -} // namespace upboarding \ No newline at end of file +} // namespace query_tiles \ No newline at end of file
diff --git a/components/query_tiles/internal/tile_manager.cc b/components/query_tiles/internal/tile_manager.cc index 029d3b5..96b87a5 100644 --- a/components/query_tiles/internal/tile_manager.cc +++ b/components/query_tiles/internal/tile_manager.cc
@@ -15,7 +15,7 @@ #include "components/query_tiles/internal/tile_iterator.h" #include "components/query_tiles/internal/tile_manager.h" -namespace upboarding { +namespace query_tiles { namespace { class TileManagerImpl : public TileManager { @@ -96,7 +96,9 @@ bool success, std::map<std::string, std::unique_ptr<TileGroup>> loaded_groups) { if (!success) { - std::move(callback).Run(TileGroupStatus::kFailureDbOperation); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), + TileGroupStatus::kFailureDbOperation)); return; } @@ -117,7 +119,6 @@ auto group_id = pair.first; auto* group = pair.second.get(); if (!ValidateGroup(group)) { - status = TileGroupStatus::kInvalidGroup; to_deprecated_in_db.emplace_back(group_id); } } @@ -130,11 +131,13 @@ // Moves the valid group into in memory holder. if (!loaded_groups.empty()) std::swap(tile_group_, loaded_groups.begin()->second); - std::move(callback).Run(status); + else + status = TileGroupStatus::kNoTiles; + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), status)); } - // Returns true if the group is not expired and the locale matches OS - // setting. + // Returns true if the group is not expired. bool ValidateGroup(const TileGroup* group) const { return clock_->Now() - group->last_updated_ts < TileConfig::GetExpireDuration(); @@ -209,4 +212,4 @@ locale); } -} // namespace upboarding +} // namespace query_tiles
diff --git a/components/query_tiles/internal/tile_manager.h b/components/query_tiles/internal/tile_manager.h index 11a3696..06dd020 100644 --- a/components/query_tiles/internal/tile_manager.h +++ b/components/query_tiles/internal/tile_manager.h
@@ -17,7 +17,7 @@ #include "components/query_tiles/internal/tile_types.h" #include "components/query_tiles/tile.h" -namespace upboarding { +namespace query_tiles { // Manages the in-memory tile group and coordinates with storage layer. class TileManager { @@ -56,6 +56,6 @@ TileManager& operator=(const TileManager& other) = delete; }; -} // namespace upboarding +} // namespace query_tiles #endif // COMPONENTS_QUERY_TILES_INTERNAL_TILE_MANAGER_H_
diff --git a/components/query_tiles/internal/tile_manager_unittest.cc b/components/query_tiles/internal/tile_manager_unittest.cc index 477903a..641a1a37 100644 --- a/components/query_tiles/internal/tile_manager_unittest.cc +++ b/components/query_tiles/internal/tile_manager_unittest.cc
@@ -19,7 +19,7 @@ using testing::_; using ::testing::Invoke; -namespace upboarding { +namespace query_tiles { namespace { class MockTileStore : public Store<TileGroup> { @@ -178,7 +178,7 @@ std::move(callback).Run(true, MockTileStore::KeysAndEntries()); })); - Init(TileGroupStatus::kSuccess); + Init(TileGroupStatus::kNoTiles); GetTiles(std::vector<Tile>() /*expect an empty result*/); } @@ -198,7 +198,7 @@ EXPECT_CALL(*tile_store(), Delete(_, _)); - Init(TileGroupStatus::kInvalidGroup); + Init(TileGroupStatus::kNoTiles); GetTiles(std::vector<Tile>() /*expect an empty result*/); } @@ -263,7 +263,7 @@ })); EXPECT_CALL(*tile_store(), Delete(_, _)).Times(0); - Init(TileGroupStatus::kSuccess); + Init(TileGroupStatus::kNoTiles); auto tile_to_save = std::make_unique<Tile>(); test::ResetTestEntry(tile_to_save.get()); @@ -289,7 +289,7 @@ })); EXPECT_CALL(*tile_store(), Delete(_, _)).Times(0); - Init(TileGroupStatus::kSuccess); + Init(TileGroupStatus::kNoTiles); auto tile_to_save = std::make_unique<Tile>(); auto expected_tile = std::make_unique<Tile>(); @@ -368,4 +368,4 @@ } // namespace -} // namespace upboarding +} // namespace query_tiles
diff --git a/components/query_tiles/internal/tile_service_impl.cc b/components/query_tiles/internal/tile_service_impl.cc index 8999801..875b2d0 100644 --- a/components/query_tiles/internal/tile_service_impl.cc +++ b/components/query_tiles/internal/tile_service_impl.cc
@@ -17,7 +17,7 @@ #include "components/query_tiles/internal/tile_config.h" #include "components/query_tiles/switches.h" -namespace upboarding { +namespace query_tiles { namespace { // Default periodic interval of background task. @@ -146,4 +146,4 @@ std::move(task_finished_callback).Run(false /*reschedule*/); } -} // namespace upboarding +} // namespace query_tiles
diff --git a/components/query_tiles/internal/tile_service_impl.h b/components/query_tiles/internal/tile_service_impl.h index 87586d2..c43e842 100644 --- a/components/query_tiles/internal/tile_service_impl.h +++ b/components/query_tiles/internal/tile_service_impl.h
@@ -16,7 +16,7 @@ #include "components/query_tiles/internal/tile_types.h" #include "components/query_tiles/tile_service.h" -namespace upboarding { +namespace query_tiles { // A TileService that needs to be explicitly initialized. class InitializableTileService : public TileService { @@ -86,6 +86,6 @@ base::WeakPtrFactory<TileServiceImpl> weak_ptr_factory_{this}; }; -} // namespace upboarding +} // namespace query_tiles #endif // COMPONENTS_QUERY_TILES_INTERNAL_TILE_SERVICE_IMPL_H_
diff --git a/components/query_tiles/internal/tile_service_impl_unittest.cc b/components/query_tiles/internal/tile_service_impl_unittest.cc index 0fa3d30..187f55bb 100644 --- a/components/query_tiles/internal/tile_service_impl_unittest.cc +++ b/components/query_tiles/internal/tile_service_impl_unittest.cc
@@ -23,7 +23,7 @@ using testing::_; using ::testing::Invoke; -namespace upboarding { +namespace query_tiles { namespace { class MockTileManager : public TileManager { @@ -162,4 +162,4 @@ FetchForTilesWithError(); } -} // namespace upboarding +} // namespace query_tiles
diff --git a/components/query_tiles/internal/tile_service_scheduler.cc b/components/query_tiles/internal/tile_service_scheduler.cc new file mode 100644 index 0000000..2e57d9e --- /dev/null +++ b/components/query_tiles/internal/tile_service_scheduler.cc
@@ -0,0 +1,180 @@ +// 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/query_tiles/internal/tile_service_scheduler.h" + +#include <memory> + +#include "base/rand_util.h" +#include "base/time/default_tick_clock.h" +#include "components/prefs/pref_service.h" +#include "components/query_tiles/internal/tile_config.h" +#include "net/base/backoff_entry_serializer.h" + +namespace query_tiles { +namespace { + +// Key for query tiles backoff entry stored in pref service. +constexpr char kBackoffEntryKey[] = "query_tiles.backoff_entry_key"; + +class TileServiceSchedulerImpl : public TileServiceScheduler { + public: + TileServiceSchedulerImpl( + background_task::BackgroundTaskScheduler* scheduler, + PrefService* prefs, + base::Clock* clock, + const base::TickClock* tick_clock, + std::unique_ptr<net::BackoffEntry::Policy> backoff_policy) + : scheduler_(scheduler), + prefs_(prefs), + clock_(clock), + tick_clock_(tick_clock), + backoff_policy_(std::move(backoff_policy)), + is_suspend_(false) {} + + private: + // TileServiceScheduler implementation. + void CancelTask() override { + scheduler_->Cancel( + static_cast<int>(background_task::TaskIds::QUERY_TILE_JOB_ID)); + ResetBackoff(); + } + + void OnFetchCompleted(TileInfoRequestStatus status) override { + if (status == TileInfoRequestStatus::kShouldSuspend) { + MaximizeBackoff(); + ScheduleTask(false); + is_suspend_ = true; + } else if (status == TileInfoRequestStatus::kFailure) { + AddBackoff(); + ScheduleTask(false); + } else if (status == TileInfoRequestStatus::kSuccess && !is_suspend_) { + ResetBackoff(); + ScheduleTask(true); + } + } + + void OnTileManagerInitialized(TileGroupStatus status) override { + if (status == TileGroupStatus::kNoTiles && !is_suspend_) { + ResetBackoff(); + ScheduleTask(true); + } else if (status == TileGroupStatus::kFailureDbOperation) { + MaximizeBackoff(); + ScheduleTask(false); + is_suspend_ = true; + } + } + + void ScheduleTask(bool is_init_schedule) { + background_task::OneOffInfo one_off_task_info; + GetTaskWindow(&one_off_task_info.window_start_time_ms, + &one_off_task_info.window_end_time_ms, is_init_schedule); + background_task::TaskInfo task_info( + static_cast<int>(background_task::TaskIds::QUERY_TILE_JOB_ID), + one_off_task_info); + task_info.is_persisted = true; + task_info.update_current = true; + task_info.network_type = + TileConfig::GetIsUnMeteredNetworkRequired() + ? background_task::TaskInfo::NetworkType::UNMETERED + : background_task::TaskInfo::NetworkType::ANY; + scheduler_->Schedule(task_info); + } + + void AddBackoff() { + std::unique_ptr<net::BackoffEntry> current = GetCurrentBackoff(); + current->InformOfRequest(false); + UpdateBackoff(current.get()); + } + + void ResetBackoff() { + std::unique_ptr<net::BackoffEntry> current = GetCurrentBackoff(); + current->Reset(); + UpdateBackoff(current.get()); + } + + void MaximizeBackoff() { + std::unique_ptr<net::BackoffEntry> current = GetCurrentBackoff(); + current->Reset(); + current->SetCustomReleaseTime( + tick_clock_->NowTicks() + + base::TimeDelta::FromMilliseconds(backoff_policy_->maximum_backoff_ms)); + UpdateBackoff(current.get()); + } + + int64_t GetDelaysFromBackoff() { + return GetCurrentBackoff()->GetTimeUntilRelease().InMilliseconds(); + } + + void GetTaskWindow(int64_t* start_time_ms, + int64_t* end_time_ms, + bool is_init_schedule) { + if (is_init_schedule) { + *start_time_ms = + clock_->Now().ToDeltaSinceWindowsEpoch().InMilliseconds() + + TileConfig::GetScheduleIntervalInMs() + + base::RandGenerator(TileConfig::GetMaxRandomWindowInMs()); + } else { + *start_time_ms = GetDelaysFromBackoff(); + } + *end_time_ms = *start_time_ms + TileConfig::GetOneoffTaskWindowInMs(); + } + + std::unique_ptr<net::BackoffEntry> GetCurrentBackoff() { + std::unique_ptr<net::BackoffEntry> result; + const base::ListValue* value = prefs_->GetList(kBackoffEntryKey); + if (value) { + result = net::BackoffEntrySerializer::DeserializeFromValue( + *value, backoff_policy_.get(), tick_clock_, clock_->Now()); + } + if (!result) { + return std::make_unique<net::BackoffEntry>(backoff_policy_.get(), + tick_clock_); + } + return result; + } + + void UpdateBackoff(net::BackoffEntry* backoff) { + std::unique_ptr<base::Value> value = + net::BackoffEntrySerializer::SerializeToValue(*backoff, clock_->Now()); + prefs_->Set(kBackoffEntryKey, *value); + } + + // Native Background Scheduler instance. + background_task::BackgroundTaskScheduler* scheduler_; + + // PrefService. + PrefService* prefs_; + + // Clock object to get current time. + base::Clock* clock_; + + // TickClock used for building backoff entry. + const base::TickClock* tick_clock_; + + // Backoff policy used for reschdule. + std::unique_ptr<net::BackoffEntry::Policy> backoff_policy_; + + // Flag to indicate if currently have a suspend status to avoid overwriting if + // already scheduled a suspend task during this lifecycle. + bool is_suspend_; +}; + +} // namespace + +std::unique_ptr<TileServiceScheduler> TileServiceScheduler::Create( + background_task::BackgroundTaskScheduler* scheduler, + PrefService* prefs, + base::Clock* clock, + const base::TickClock* tick_clock, + std::unique_ptr<net::BackoffEntry::Policy> backoff_policy) { + return std::make_unique<TileServiceSchedulerImpl>( + scheduler, prefs, clock, tick_clock, std::move(backoff_policy)); +} + +TileServiceScheduler::TileServiceScheduler() = default; + +TileServiceScheduler::~TileServiceScheduler() = default; + +} // namespace query_tiles
diff --git a/components/query_tiles/internal/tile_service_scheduler.h b/components/query_tiles/internal/tile_service_scheduler.h new file mode 100644 index 0000000..5579306 --- /dev/null +++ b/components/query_tiles/internal/tile_service_scheduler.h
@@ -0,0 +1,60 @@ +// 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_QUERY_TILES_INTERNAL_TILE_SERVICE_SCHEDULER_H_ +#define COMPONENTS_QUERY_TILES_INTERNAL_TILE_SERVICE_SCHEDULER_H_ + +#include <memory> + +#include "base/time/clock.h" +#include "base/time/tick_clock.h" +#include "components/background_task_scheduler/background_task_scheduler.h" +#include "components/query_tiles/internal/tile_config.h" +#include "components/query_tiles/internal/tile_types.h" +#include "net/base/backoff_entry_serializer.h" + +class PrefService; + +namespace query_tiles { + +// Coordinates with native background task scheduler to schedule or cancel a +// TileBackgroundTask. +class TileServiceScheduler { + public: + // Method to create a TileServiceScheduler instance. + static std::unique_ptr<TileServiceScheduler> Create( + background_task::BackgroundTaskScheduler* scheduler, + PrefService* prefs, + base::Clock* clock, + const base::TickClock* tick_clock, + std::unique_ptr<net::BackoffEntry::Policy> backoff_policy); + + // Called on fetch task completed, schedule another task with or without + // backoff based on the status. Success status will lead a regular schedule + // after around 14 - 18 hours. Failure status will lead a backoff, the release + // duration is related to count of failures. Suspend status will directly set + // the release time until 24 hours later. + virtual void OnFetchCompleted(TileInfoRequestStatus status) = 0; + + // Called on tile manager initialization completed, schedule another task with + // or without backoff based on the status. NoTiles status will lead a regular + // schedule after around 14 - 18 hours. DbOperationFailure status will + // directly set the release time until 24 hours later. + virtual void OnTileManagerInitialized(TileGroupStatus status) = 0; + + // Cancel current existing task, and reset backoff. + virtual void CancelTask() = 0; + + virtual ~TileServiceScheduler(); + + TileServiceScheduler(const TileServiceScheduler& other) = delete; + TileServiceScheduler& operator=(const TileServiceScheduler& other) = delete; + + protected: + TileServiceScheduler(); +}; + +} // namespace query_tiles + +#endif // COMPONENTS_QUERY_TILES_INTERNAL_TILE_SERVICE_SCHEDULER_H_
diff --git a/components/query_tiles/internal/tile_store.cc b/components/query_tiles/internal/tile_store.cc index af83a08..a150a9a 100644 --- a/components/query_tiles/internal/tile_store.cc +++ b/components/query_tiles/internal/tile_store.cc
@@ -10,19 +10,19 @@ namespace leveldb_proto { -void DataToProto(upboarding::TileGroup* data, - upboarding::query_tiles::proto::TileGroup* proto) { +void DataToProto(query_tiles::TileGroup* data, + query_tiles::proto::TileGroup* proto) { TileGroupToProto(data, proto); } -void ProtoToData(upboarding::query_tiles::proto::TileGroup* proto, - upboarding::TileGroup* data) { +void ProtoToData(query_tiles::proto::TileGroup* proto, + query_tiles::TileGroup* data) { TileGroupFromProto(proto, data); } } // namespace leveldb_proto -namespace upboarding { +namespace query_tiles { TileStore::TileStore(TileProtoDb db) : db_(std::move(db)) {} @@ -83,4 +83,4 @@ std::move(callback).Run(true, std::move(keys_and_entries)); } -} // namespace upboarding +} // namespace query_tiles
diff --git a/components/query_tiles/internal/tile_store.h b/components/query_tiles/internal/tile_store.h index d4caeb4..cd59cc61 100644 --- a/components/query_tiles/internal/tile_store.h +++ b/components/query_tiles/internal/tile_store.h
@@ -22,14 +22,14 @@ namespace leveldb_proto { -void DataToProto(upboarding::TileGroup* data, - upboarding::query_tiles::proto::TileGroup* proto); -void ProtoToData(upboarding::query_tiles::proto::TileGroup* proto, - upboarding::TileGroup* data); +void DataToProto(query_tiles::TileGroup* data, + query_tiles::proto::TileGroup* proto); +void ProtoToData(query_tiles::proto::TileGroup* proto, + query_tiles::TileGroup* data); } // namespace leveldb_proto -namespace upboarding { +namespace query_tiles { // TileStore is the storage layer of all TileGroup which contains // the top-level tile entries and group metadata. Sub-level tiles are // recursively owned by their parents. @@ -70,6 +70,6 @@ base::WeakPtrFactory<TileStore> weak_ptr_factory_{this}; }; -} // namespace upboarding +} // namespace query_tiles #endif // COMPONENTS_QUERY_TILES_INTERNAL_TILE_STORE_H_
diff --git a/components/query_tiles/internal/tile_store_unittest.cc b/components/query_tiles/internal/tile_store_unittest.cc index 1d3daeb..a0438659 100644 --- a/components/query_tiles/internal/tile_store_unittest.cc +++ b/components/query_tiles/internal/tile_store_unittest.cc
@@ -19,7 +19,7 @@ using leveldb_proto::test::FakeDB; using InitStatus = leveldb_proto::Enums::InitStatus; -namespace upboarding { +namespace query_tiles { namespace { class TileStoreTest : public testing::Test { @@ -55,7 +55,7 @@ void CreateTestDbEntries(TestEntries input) { for (auto& entry : input) { TileGroupProto proto; - upboarding::TileGroupToProto(&entry, &proto); + query_tiles::TileGroupToProto(&entry, &proto); db_entries_.emplace(entry.id, proto); } } @@ -199,4 +199,4 @@ } } // namespace -} // namespace upboarding +} // namespace query_tiles
diff --git a/components/query_tiles/internal/tile_types.h b/components/query_tiles/internal/tile_types.h index 7b92bb4..2c3fe9c 100644 --- a/components/query_tiles/internal/tile_types.h +++ b/components/query_tiles/internal/tile_types.h
@@ -5,6 +5,8 @@ #ifndef COMPONENTS_QUERY_TILES_INTERNAL_TILE_TYPES_H_ #define COMPONENTS_QUERY_TILES_INTERNAL_TILE_TYPES_H_ +#include "base/callback.h" + enum class TileInfoRequestStatus { // Initial status, request is not sent. kInit = 0, @@ -25,10 +27,10 @@ kUninitialized = 1, // Db operations failed. kFailureDbOperation = 2, - // The group status is invalid, reason could be expired or locale not match. - kInvalidGroup = 3, + // Group data has been expired or hasn't been downloaded yet. + kNoTiles = 3, // Max value. - kMaxValue = kInvalidGroup, + kMaxValue = kNoTiles, }; // Config to control how tile images are prefetched in background task.
diff --git a/components/query_tiles/proto/tile.proto b/components/query_tiles/proto/tile.proto index 6dbd7e7a8..165ce2d1 100644 --- a/components/query_tiles/proto/tile.proto +++ b/components/query_tiles/proto/tile.proto
@@ -6,7 +6,7 @@ option optimize_for = LITE_RUNTIME; -package upboarding.query_tiles.proto; +package query_tiles.proto; // The Tile is the schema to represent data in entries. // Next tag: 7
diff --git a/components/query_tiles/proto/tile_response.proto b/components/query_tiles/proto/tile_response.proto index baccb9b2..d10c2f3c 100644 --- a/components/query_tiles/proto/tile_response.proto +++ b/components/query_tiles/proto/tile_response.proto
@@ -6,7 +6,7 @@ option optimize_for = LITE_RUNTIME; -package upboarding.query_tiles.proto; +package query_tiles.proto; // URL and id of the image to be displayed on tiles. message TileImage {
diff --git a/components/query_tiles/switches.cc b/components/query_tiles/switches.cc index 0d8e0ec..3f991d6 100644 --- a/components/query_tiles/switches.cc +++ b/components/query_tiles/switches.cc
@@ -4,7 +4,7 @@ #include "components/query_tiles/switches.h" -namespace upboarding { +namespace query_tiles { namespace features { const base::Feature kQueryTiles{"QueryTiles", base::FEATURE_DISABLED_BY_DEFAULT}; @@ -21,4 +21,4 @@ const char kQueryTilesInstantBackgroundTask[] = "query-tiles-instant-background-task"; } // namespace switches -} // namespace upboarding +} // namespace query_tiles
diff --git a/components/query_tiles/switches.h b/components/query_tiles/switches.h index 7d7098d..664032cc 100644 --- a/components/query_tiles/switches.h +++ b/components/query_tiles/switches.h
@@ -7,7 +7,7 @@ #include "base/feature_list.h" -namespace upboarding { +namespace query_tiles { namespace features { // Main feature flag for the query tiles feature. @@ -33,6 +33,6 @@ extern const char kQueryTilesInstantBackgroundTask[]; } // namespace switches -} // namespace upboarding +} // namespace query_tiles #endif // COMPONENTS_QUERY_TILES_SWITCHES_H_
diff --git a/components/query_tiles/test/fake_tile_service.cc b/components/query_tiles/test/fake_tile_service.cc index 72d3adc8..149a4f07 100644 --- a/components/query_tiles/test/fake_tile_service.cc +++ b/components/query_tiles/test/fake_tile_service.cc
@@ -6,7 +6,7 @@ #include <utility> -namespace upboarding { +namespace query_tiles { namespace { std::unique_ptr<Tile> CreateTile(const std::string& id, @@ -88,4 +88,4 @@ bool is_from_reduced_mode, BackgroundTaskFinishedCallback callback) {} -} // namespace upboarding \ No newline at end of file +} // namespace query_tiles \ No newline at end of file
diff --git a/components/query_tiles/test/fake_tile_service.h b/components/query_tiles/test/fake_tile_service.h index f56e258..ffebcac 100644 --- a/components/query_tiles/test/fake_tile_service.h +++ b/components/query_tiles/test/fake_tile_service.h
@@ -11,7 +11,7 @@ #include "base/memory/weak_ptr.h" #include "components/query_tiles/tile_service.h" -namespace upboarding { +namespace query_tiles { // A fake TileService that can be used for tests. class FakeTileService : public TileService { @@ -34,6 +34,6 @@ base::WeakPtrFactory<FakeTileService> weak_ptr_factory_{this}; }; -} // namespace upboarding +} // namespace query_tiles #endif // COMPONENTS_QUERY_TILES_TEST_FAKE_TILE_SERVICE_H_
diff --git a/components/query_tiles/test/test_utils.cc b/components/query_tiles/test/test_utils.cc index 7cabab8e..c58ba57 100644 --- a/components/query_tiles/test/test_utils.cc +++ b/components/query_tiles/test/test_utils.cc
@@ -12,7 +12,7 @@ #include <utility> #include <vector> -namespace upboarding { +namespace query_tiles { namespace test { namespace { @@ -191,4 +191,4 @@ } // namespace test -} // namespace upboarding +} // namespace query_tiles
diff --git a/components/query_tiles/test/test_utils.h b/components/query_tiles/test/test_utils.h index 5c563f2..1b48217 100644 --- a/components/query_tiles/test/test_utils.h +++ b/components/query_tiles/test/test_utils.h
@@ -11,7 +11,7 @@ #include "components/query_tiles/internal/tile_group.h" #include "components/query_tiles/tile.h" -namespace upboarding { +namespace query_tiles { namespace test { // Print data in Tile, also with tree represent by adjacent nodes @@ -42,6 +42,6 @@ bool AreTilesIdentical(std::vector<Tile> lhs, std::vector<Tile> rhs); } // namespace test -} // namespace upboarding +} // namespace query_tiles #endif // COMPONENTS_QUERY_TILES_TEST_TEST_UTILS_H_
diff --git a/components/query_tiles/tile.cc b/components/query_tiles/tile.cc index 9ae04aa..7662d5cd 100644 --- a/components/query_tiles/tile.cc +++ b/components/query_tiles/tile.cc
@@ -6,7 +6,7 @@ #include <utility> -namespace upboarding { +namespace query_tiles { namespace { void DeepCopyTiles(const Tile& input, Tile* out) { @@ -57,7 +57,7 @@ Tile::Tile() = default; -Tile::Tile(Tile&& other) = default; +Tile::Tile(Tile&& other) noexcept = default; Tile::~Tile() = default; @@ -66,6 +66,6 @@ return *this; } -Tile& Tile::operator=(Tile&& other) = default; +Tile& Tile::operator=(Tile&& other) noexcept = default; -} // namespace upboarding +} // namespace query_tiles
diff --git a/components/query_tiles/tile.h b/components/query_tiles/tile.h index f064b07..ebdce52d 100644 --- a/components/query_tiles/tile.h +++ b/components/query_tiles/tile.h
@@ -12,7 +12,7 @@ #include "base/time/time.h" #include "url/gurl.h" -namespace upboarding { +namespace query_tiles { // Metadata of a tile image. struct ImageMetadata { @@ -58,6 +58,6 @@ std::vector<std::unique_ptr<Tile>> sub_tiles; }; -} // namespace upboarding +} // namespace query_tiles #endif // COMPONENTS_QUERY_TILES_TILE_H_
diff --git a/components/query_tiles/tile_service.h b/components/query_tiles/tile_service.h index 42fe58d1..0ead349 100644 --- a/components/query_tiles/tile_service.h +++ b/components/query_tiles/tile_service.h
@@ -18,7 +18,7 @@ class Image; } // namespace gfx -namespace upboarding { +namespace query_tiles { using TileList = std::vector<Tile>; using GetTilesCallback = base::OnceCallback<void(TileList)>; @@ -47,6 +47,6 @@ TileService& operator=(const TileService&) = delete; }; -} // namespace upboarding +} // namespace query_tiles #endif // COMPONENTS_QUERY_TILES_TILE_SERVICE_H_
diff --git a/components/query_tiles/tile_service_factory_helper.cc b/components/query_tiles/tile_service_factory_helper.cc index 30e7ec6c4..acfdf8e 100644 --- a/components/query_tiles/tile_service_factory_helper.cc +++ b/components/query_tiles/tile_service_factory_helper.cc
@@ -23,7 +23,7 @@ #include "components/query_tiles/internal/tile_service_impl.h" #include "services/network/public/cpp/shared_url_loader_factory.h" -namespace upboarding { +namespace query_tiles { namespace { const base::FilePath::CharType kTileDbName[] = FILE_PATH_LITERAL("UpboardingQueryTileDatabase"); @@ -70,4 +70,4 @@ return std::make_unique<InitAwareTileService>(std::move(tile_service_impl)); } -} // namespace upboarding +} // namespace query_tiles
diff --git a/components/query_tiles/tile_service_factory_helper.h b/components/query_tiles/tile_service_factory_helper.h index cff0127..d3e8ab6 100644 --- a/components/query_tiles/tile_service_factory_helper.h +++ b/components/query_tiles/tile_service_factory_helper.h
@@ -26,7 +26,7 @@ class SharedURLLoaderFactory; } // namespace network -namespace upboarding { +namespace query_tiles { class TileService; @@ -40,6 +40,6 @@ const std::string& api_key, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); -} // namespace upboarding +} // namespace query_tiles #endif // COMPONENTS_QUERY_TILES_TILE_SERVICE_FACTORY_HELPER_H_
diff --git a/components/query_tiles/tile_unittest.cc b/components/query_tiles/tile_unittest.cc index befae77..f89b9bc 100644 --- a/components/query_tiles/tile_unittest.cc +++ b/components/query_tiles/tile_unittest.cc
@@ -10,7 +10,7 @@ #include "components/query_tiles/test/test_utils.h" #include "testing/gtest/include/gtest/gtest.h" -namespace upboarding { +namespace query_tiles { namespace { TEST(TileTest, CompareOperators) { @@ -102,4 +102,4 @@ } // namespace -} // namespace upboarding +} // namespace query_tiles
diff --git a/components/safe_browsing/core/common/safe_browsing_prefs.cc b/components/safe_browsing/core/common/safe_browsing_prefs.cc index b6a360d..2b86cf12 100644 --- a/components/safe_browsing/core/common/safe_browsing_prefs.cc +++ b/components/safe_browsing/core/common/safe_browsing_prefs.cc
@@ -393,6 +393,15 @@ return false; } +bool MatchesEnterpriseWhitelist(const PrefService& pref, + const std::vector<GURL>& url_chain) { + for (const GURL& url : url_chain) { + if (IsURLWhitelistedByPolicy(url, pref)) + return true; + } + return false; +} + void GetPasswordProtectionLoginURLsPref(const PrefService& prefs, std::vector<GURL>* out_login_url_list) { const base::ListValue* pref_value =
diff --git a/components/safe_browsing/core/common/safe_browsing_prefs.h b/components/safe_browsing/core/common/safe_browsing_prefs.h index 421a913..656ee9b 100644 --- a/components/safe_browsing/core/common/safe_browsing_prefs.h +++ b/components/safe_browsing/core/common/safe_browsing_prefs.h
@@ -339,6 +339,12 @@ // Called on UI thread. bool IsURLWhitelistedByPolicy(const GURL& url, const PrefService& pref); +// Helper function to determine if any entry on the |url_chain| matches Safe +// Browsing whitelist domains. +// Called on UI thread. +bool MatchesEnterpriseWhitelist(const PrefService& pref, + const std::vector<GURL>& url_chain); + // Helper function to get the pref value of password protection login URLs. void GetPasswordProtectionLoginURLsPref(const PrefService& prefs, std::vector<GURL>* out_login_url_list);
diff --git a/components/sync/driver/sync_driver_switches.cc b/components/sync/driver/sync_driver_switches.cc index 1c1105e..81f7641 100644 --- a/components/sync/driver/sync_driver_switches.cc +++ b/components/sync/driver/sync_driver_switches.cc
@@ -66,6 +66,6 @@ // Enables the running of backend ProfileSyncService tasks on the ThreadPool. const base::Feature kProfileSyncServiceUsesThreadPool{ - "ProfileSyncServiceUsesThreadPool", base::FEATURE_DISABLED_BY_DEFAULT}; + "ProfileSyncServiceUsesThreadPool", base::FEATURE_ENABLED_BY_DEFAULT}; } // namespace switches
diff --git a/components/translate/core/browser/translate_manager.cc b/components/translate/core/browser/translate_manager.cc index 4594069..e1a4b91 100644 --- a/components/translate/core/browser/translate_manager.cc +++ b/components/translate/core/browser/translate_manager.cc
@@ -877,6 +877,8 @@ void TranslateManager::MaybeShowOmniboxIcon( const TranslateTriggerDecision& decision) { if (decision.IsTriggeringPossible()) { + // Show the omnibox icon if any translate trigger is possible. + language_state_.SetTranslateEnabled(true); TranslateBrowserMetrics::ReportInitiationStatus( TranslateBrowserMetrics::INITIATION_STATUS_SHOW_ICON); }
diff --git a/components/translate/core/browser/translate_manager_unittest.cc b/components/translate/core/browser/translate_manager_unittest.cc index 8b3fa75..927f2be 100644 --- a/components/translate/core/browser/translate_manager_unittest.cc +++ b/components/translate/core/browser/translate_manager_unittest.cc
@@ -544,6 +544,7 @@ EXPECT_EQ("hi", TranslateManager::GetTargetLanguage( &translate_prefs_, &mock_language_model_, {"en"})); translate_manager_->InitiateTranslation("en"); + EXPECT_TRUE(translate_manager_->GetLanguageState().translate_enabled()); EXPECT_THAT( histogram_tester.GetAllSamples(kInitiationStatusName), ElementsAre(Bucket(metrics::INITIATION_STATUS_ABORTED_BY_RANKER, 1), @@ -582,6 +583,7 @@ EXPECT_EQ("hi", TranslateManager::GetTargetLanguage( &translate_prefs_, &mock_language_model_, {})); translate_manager_->InitiateTranslation("fr"); + EXPECT_TRUE(translate_manager_->GetLanguageState().translate_enabled()); EXPECT_THAT(histogram_tester.GetAllSamples(kInitiationStatusName), ElementsAre(Bucket(metrics::INITIATION_STATUS_SHOW_INFOBAR, 1), Bucket(metrics::INITIATION_STATUS_SHOW_ICON, 1)));
diff --git a/components/user_manager/OWNERS b/components/user_manager/OWNERS index fb10e77..9c31b9e 100644 --- a/components/user_manager/OWNERS +++ b/components/user_manager/OWNERS
@@ -1,4 +1,6 @@ achuith@chromium.org alemate@chromium.org +antrim@chromium.org +rsorokin@chromium.org xiyuan@chromium.org # COMPONENT: Enterprise
diff --git a/components/user_manager/known_user.cc b/components/user_manager/known_user.cc index 9fd926f..32beb1d 100644 --- a/components/user_manager/known_user.cc +++ b/components/user_manager/known_user.cc
@@ -77,6 +77,9 @@ const char kLastOnlineSignin[] = "last_online_singin"; const char kOfflineSigninLimit[] = "offline_signin_limit"; +// Key of the boolean flag telling if user is managed. +const char kIsManaged[] = "is_managed"; + // List containing all the known user preferences keys. const char* kReservedKeys[] = {kCanonicalEmail, kGAIAIdKey, @@ -645,6 +648,17 @@ return time_delta; } +void SetIsManaged(const AccountId& account_id, bool is_managed) { + SetBooleanPref(account_id, kIsManaged, is_managed); +} + +bool GetIsManaged(const AccountId& account_id) { + bool is_managed; + if (GetBooleanPref(account_id, kIsManaged, &is_managed)) + return is_managed; + return false; +} + void RemovePrefs(const AccountId& account_id) { PrefService* local_state = GetLocalState();
diff --git a/components/user_manager/known_user.h b/components/user_manager/known_user.h index 2c0843e..df34996 100644 --- a/components/user_manager/known_user.h +++ b/components/user_manager/known_user.h
@@ -227,6 +227,11 @@ base::TimeDelta USER_MANAGER_EXPORT GetOfflineSigninLimit(const AccountId& account_id); +void USER_MANAGER_EXPORT SetIsManaged(const AccountId& account_id, + bool is_managed); + +bool USER_MANAGER_EXPORT GetIsManaged(const AccountId& account_id); + // Removes all user preferences associated with |account_id|. // Not exported as code should not be calling this outside this component void RemovePrefs(const AccountId& account_id);
diff --git a/components/viz/common/gpu/vulkan_in_process_context_provider.cc b/components/viz/common/gpu/vulkan_in_process_context_provider.cc index 933ba9d..17dbe35 100644 --- a/components/viz/common/gpu/vulkan_in_process_context_provider.cc +++ b/components/viz/common/gpu/vulkan_in_process_context_provider.cc
@@ -11,11 +11,13 @@ #include "gpu/vulkan/vulkan_function_pointers.h" #include "gpu/vulkan/vulkan_implementation.h" #include "gpu/vulkan/vulkan_instance.h" +#include "gpu/vulkan/vulkan_util.h" #include "third_party/skia/include/gpu/GrContext.h" #include "third_party/skia/include/gpu/vk/GrVkExtensions.h" namespace viz { +// static scoped_refptr<VulkanInProcessContextProvider> VulkanInProcessContextProvider::Create( gpu::VulkanImplementation* vulkan_implementation, @@ -71,8 +73,12 @@ GrVkGetProc get_proc = [](const char* proc_name, VkInstance instance, VkDevice device) { - return device ? vkGetDeviceProcAddr(device, proc_name) - : vkGetInstanceProcAddr(instance, proc_name); + if (device) { + if (std::strcmp("vkQueueSubmit", proc_name) == 0) + return reinterpret_cast<PFN_vkVoidFunction>(&gpu::QueueSubmitHook); + return vkGetDeviceProcAddr(device, proc_name); + } + return vkGetInstanceProcAddr(instance, proc_name); }; std::vector<const char*> device_extensions;
diff --git a/components/viz/service/display/damage_frame_annotator.cc b/components/viz/service/display/damage_frame_annotator.cc index d39992e6..78c99bd 100644 --- a/components/viz/service/display/damage_frame_annotator.cc +++ b/components/viz/service/display/damage_frame_annotator.cc
@@ -37,13 +37,6 @@ void DamageFrameAnnotator::AnnotateRootRenderPass(RenderPass* render_pass) { const size_t num_quads_to_add = annotations_.size(); - // Insert |num_quads_to_add| new SharedQuadState at the start of the list. - // This will invalidate all the existing SharedQuadState* in DrawQuads. - auto sqs_iter = - render_pass->shared_quad_state_list - .InsertBeforeAndInvalidateAllPointers<SharedQuadState>( - render_pass->shared_quad_state_list.begin(), num_quads_to_add); - // Insert |num_quads_to_add| new DebugBorderDrawQuad at start of list. The // quads will be drawn on top of the original quads. auto quad_iter = @@ -56,7 +49,8 @@ gfx::Rect output_rect = cc::MathUtil::MapEnclosingClippedRect( annotation.transform, annotation.rect); - SharedQuadState* new_sqs = *sqs_iter; + SharedQuadState* new_sqs = render_pass->shared_quad_state_list + .AllocateAndConstruct<SharedQuadState>(); new_sqs->SetAll(annotation.transform, output_rect, output_rect, gfx::RRectF(), output_rect, true, false, 1.f, SkBlendMode::kSrcOver, 0); @@ -66,32 +60,9 @@ new_quad->SetNew(new_sqs, annotation.rect, annotation.rect, annotation.highlight.color, annotation.highlight.width); - ++sqs_iter; ++quad_iter; } - // At this point |quad_iter| points to the first DrawQuad that needs - // |shared_quad_state| fixed. |sqs_iter| points to the new address for the - // first original SharedQuadState. Iterate through all DrawQuads updating - // |shared_quad_state|. - const SharedQuadState* last_quad_from_sqs = (*quad_iter)->shared_quad_state; - while (quad_iter != render_pass->quad_list.end()) { - DrawQuad* quad = *quad_iter; - const SharedQuadState* from_sqs = quad->shared_quad_state; - - // If |shared_quad_state| of the current quad is different than the last - // quad we know to advance |sqs_iter| as well. - if (from_sqs != last_quad_from_sqs) { - DCHECK(sqs_iter != render_pass->shared_quad_state_list.end()); - ++sqs_iter; - last_quad_from_sqs = from_sqs; - } - - quad->shared_quad_state = *sqs_iter; - ++quad_iter; - } - DCHECK(++sqs_iter == render_pass->shared_quad_state_list.end()); - // Set the entire frame as damaged. render_pass->damage_rect = render_pass->output_rect; }
diff --git a/components/viz/service/display/direct_renderer.cc b/components/viz/service/display/direct_renderer.cc index 15ac491..2547c67 100644 --- a/components/viz/service/display/direct_renderer.cc +++ b/components/viz/service/display/direct_renderer.cc
@@ -465,6 +465,15 @@ current_frame_valid_ = false; } +gfx::Rect DirectRenderer::GetTargetDamageBoundingRect() const { + gfx::Rect bounding_rect = output_surface_->GetCurrentFramebufferDamage(); + if (overlay_processor_) { + bounding_rect.Union( + overlay_processor_->GetPreviousFrameOverlaysBoundingRect()); + } + return bounding_rect; +} + gfx::Rect DirectRenderer::DeviceViewportRectInDrawSpace() const { gfx::Rect device_viewport_rect(current_frame()->device_viewport_size); device_viewport_rect -= current_viewport_rect_.OffsetFromOrigin();
diff --git a/components/viz/service/display/direct_renderer.h b/components/viz/service/display/direct_renderer.h index 259ec01..ef57383 100644 --- a/components/viz/service/display/direct_renderer.h +++ b/components/viz/service/display/direct_renderer.h
@@ -69,6 +69,11 @@ const gfx::Size& device_viewport_size, const gfx::DisplayColorSpaces& display_color_spaces); + // The renderer might expand the damage (e.g: HW overlays were used, + // invalidation rects on previous buffers). This function returns a + // bounding rect of the area that might need to be recomposited. + gfx::Rect GetTargetDamageBoundingRect() const; + // Public interface implemented by subclasses. struct SwapFrameData { SwapFrameData();
diff --git a/components/viz/service/display/display.cc b/components/viz/service/display/display.cc index a11119a4e..852aaba 100644 --- a/components/viz/service/display/display.cc +++ b/components/viz/service/display/display.cc
@@ -520,9 +520,9 @@ // Outputting a partial list of quads might not work in cases where contents // outside the damage rect might be needed by the renderer. bool output_partial_list = - output_surface_->capabilities().only_invalidates_damage_rect && renderer_->use_partial_swap() && - !overlay_processor_->IsOverlaySupported(); + (!overlay_processor_->IsOverlaySupported() || + output_surface_->capabilities().supports_target_damage); aggregator_ = std::make_unique<SurfaceAggregator>( surface_manager_, resource_provider_.get(), output_partial_list, @@ -609,9 +609,13 @@ { FrameRateDecider::ScopedAggregate scoped_aggregate( frame_rate_decider_.get()); - frame = - aggregator_->Aggregate(current_surface_id_, expected_display_time, - current_display_transform, ++swapped_trace_id_); + gfx::Rect target_damage_bounding_rect; + if (output_surface_->capabilities().supports_target_damage) + target_damage_bounding_rect = renderer_->GetTargetDamageBoundingRect(); + + frame = aggregator_->Aggregate( + current_surface_id_, expected_display_time, current_display_transform, + target_damage_bounding_rect, ++swapped_trace_id_); } #if defined(OS_ANDROID)
diff --git a/components/viz/service/display/output_surface.h b/components/viz/service/display/output_surface.h index 6476ec1..584bda7 100644 --- a/components/viz/service/display/output_surface.h +++ b/components/viz/service/display/output_surface.h
@@ -84,10 +84,9 @@ // the unified display on Chrome OS. All drawing is handled by the physical // displays so the unified display should skip that work. bool skips_draw = false; - // Indicates whether this surface will invalidate only the damage rect. - // When this is false contents outside the damaged area might need to be - // recomposited to the surface. - bool only_invalidates_damage_rect = true; + // Whether OutputSurface::GetTargetDamageBoundingRect is implemented and + // will return a bounding rectangle of the target buffer invalidated area. + bool supports_target_damage = false; // Whether the gpu supports surfaceless surface (equivalent of using buffer // queue). bool supports_surfaceless = false;
diff --git a/components/viz/service/display/overlay_processor_interface.h b/components/viz/service/display/overlay_processor_interface.h index c5db304..e1779e03 100644 --- a/components/viz/service/display/overlay_processor_interface.h +++ b/components/viz/service/display/overlay_processor_interface.h
@@ -107,6 +107,10 @@ virtual ~OverlayProcessorInterface() {} virtual bool IsOverlaySupported() const = 0; + // Returns a bounding rectangle of the last set of overlay planes scheduled. + // It's expected to be called after ProcessForOverlays at frame N-1 has been + // called and before GetAndResetOverlayDamage at frame N. + virtual gfx::Rect GetPreviousFrameOverlaysBoundingRect() const = 0; virtual gfx::Rect GetAndResetOverlayDamage() = 0; // Returns true if the platform supports hw overlays and surface occluding
diff --git a/components/viz/service/display/overlay_processor_mac.cc b/components/viz/service/display/overlay_processor_mac.cc index d972c98..2a3b10b 100644 --- a/components/viz/service/display/overlay_processor_mac.cc +++ b/components/viz/service/display/overlay_processor_mac.cc
@@ -37,6 +37,12 @@ return could_overlay_; } +gfx::Rect OverlayProcessorMac::GetPreviousFrameOverlaysBoundingRect() const { + // TODO(dcastagna): Implement me. + NOTIMPLEMENTED(); + return gfx::Rect(); +} + gfx::Rect OverlayProcessorMac::GetAndResetOverlayDamage() { gfx::Rect result = ca_overlay_damage_rect_; ca_overlay_damage_rect_ = gfx::Rect();
diff --git a/components/viz/service/display/overlay_processor_mac.h b/components/viz/service/display/overlay_processor_mac.h index 03a8112..26e583a 100644 --- a/components/viz/service/display/overlay_processor_mac.h +++ b/components/viz/service/display/overlay_processor_mac.h
@@ -35,6 +35,7 @@ bool DisableSplittingQuads() const override; bool IsOverlaySupported() const override; + gfx::Rect GetPreviousFrameOverlaysBoundingRect() const override; gfx::Rect GetAndResetOverlayDamage() override; // Returns true if the platform supports hw overlays and surface occluding
diff --git a/components/viz/service/display/overlay_processor_ozone.cc b/components/viz/service/display/overlay_processor_ozone.cc index a7cec95f..9dc16e1 100644 --- a/components/viz/service/display/overlay_processor_ozone.cc +++ b/components/viz/service/display/overlay_processor_ozone.cc
@@ -158,6 +158,8 @@ // Skip the candidate if the corresponding NativePixmap is not found. if (!result) { *ozone_surface_iterator = ui::OverlaySurfaceCandidate(); + ozone_surface_iterator->plane_z_order = + surface_iterator->plane_z_order; } } }
diff --git a/components/viz/service/display/overlay_processor_stub.cc b/components/viz/service/display/overlay_processor_stub.cc index 7990838..0be55ee 100644 --- a/components/viz/service/display/overlay_processor_stub.cc +++ b/components/viz/service/display/overlay_processor_stub.cc
@@ -11,6 +11,10 @@ gfx::Rect OverlayProcessorStub::GetAndResetOverlayDamage() { return gfx::Rect(); } +gfx::Rect OverlayProcessorStub::GetPreviousFrameOverlaysBoundingRect() const { + return gfx::Rect(); +} + bool OverlayProcessorStub::NeedsSurfaceOccludingDamageRect() const { return false; }
diff --git a/components/viz/service/display/overlay_processor_stub.h b/components/viz/service/display/overlay_processor_stub.h index 92069a7..1dee051 100644 --- a/components/viz/service/display/overlay_processor_stub.h +++ b/components/viz/service/display/overlay_processor_stub.h
@@ -18,6 +18,7 @@ // Overrides OverlayProcessorInterface's pure virtual functions. bool IsOverlaySupported() const final; + gfx::Rect GetPreviousFrameOverlaysBoundingRect() const final; gfx::Rect GetAndResetOverlayDamage() final; bool NeedsSurfaceOccludingDamageRect() const final; void ProcessForOverlays(
diff --git a/components/viz/service/display/overlay_processor_using_strategy.cc b/components/viz/service/display/overlay_processor_using_strategy.cc index a218f08..86b00f8 100644 --- a/components/viz/service/display/overlay_processor_using_strategy.cc +++ b/components/viz/service/display/overlay_processor_using_strategy.cc
@@ -35,6 +35,13 @@ OverlayProcessorUsingStrategy::~OverlayProcessorUsingStrategy() = default; +gfx::Rect OverlayProcessorUsingStrategy::GetPreviousFrameOverlaysBoundingRect() + const { + gfx::Rect result = overlay_damage_rect_; + result.Union(previous_frame_underlay_rect_); + return result; +} + gfx::Rect OverlayProcessorUsingStrategy::GetAndResetOverlayDamage() { gfx::Rect result = overlay_damage_rect_; overlay_damage_rect_ = gfx::Rect();
diff --git a/components/viz/service/display/overlay_processor_using_strategy.h b/components/viz/service/display/overlay_processor_using_strategy.h index f946919c3..faa34d1 100644 --- a/components/viz/service/display/overlay_processor_using_strategy.h +++ b/components/viz/service/display/overlay_processor_using_strategy.h
@@ -66,6 +66,7 @@ ~OverlayProcessorUsingStrategy() override; + gfx::Rect GetPreviousFrameOverlaysBoundingRect() const final; gfx::Rect GetAndResetOverlayDamage() final; // Override OverlayProcessor.
diff --git a/components/viz/service/display/overlay_processor_win.cc b/components/viz/service/display/overlay_processor_win.cc index ffa85923..9c5b852 100644 --- a/components/viz/service/display/overlay_processor_win.cc +++ b/components/viz/service/display/overlay_processor_win.cc
@@ -27,6 +27,12 @@ return enable_dc_overlay_; } +gfx::Rect OverlayProcessorWin::GetPreviousFrameOverlaysBoundingRect() const { + // TODO(dcastagna): Implement me. + NOTIMPLEMENTED(); + return gfx::Rect(); +} + gfx::Rect OverlayProcessorWin::GetAndResetOverlayDamage() { return gfx::Rect(); }
diff --git a/components/viz/service/display/overlay_processor_win.h b/components/viz/service/display/overlay_processor_win.h index f7863ad2..95147c7d 100644 --- a/components/viz/service/display/overlay_processor_win.h +++ b/components/viz/service/display/overlay_processor_win.h
@@ -34,6 +34,7 @@ ~OverlayProcessorWin() override; bool IsOverlaySupported() const override; + gfx::Rect GetPreviousFrameOverlaysBoundingRect() const override; gfx::Rect GetAndResetOverlayDamage() override; // Returns true if the platform supports hw overlays and surface occluding
diff --git a/components/viz/service/display/surface_aggregator.cc b/components/viz/service/display/surface_aggregator.cc index ea0032f..6d26c63 100644 --- a/components/viz/service/display/surface_aggregator.cc +++ b/components/viz/service/display/surface_aggregator.cc
@@ -1763,6 +1763,7 @@ const SurfaceId& surface_id, base::TimeTicks expected_display_time, gfx::OverlayTransform display_transform, + const gfx::Rect& target_damage, int64_t display_trace_id) { DCHECK(!expected_display_time.is_null()); @@ -1810,8 +1811,13 @@ new_surfaces_.clear(); DCHECK(referenced_surfaces_.empty()); PrewalkResult prewalk_result; - root_damage_rect_ = + gfx::Rect surfaces_damage_rect = PrewalkTree(surface, false, 0, true /* will_draw */, &prewalk_result); + + root_damage_rect_ = surfaces_damage_rect; + // |root_damage_rect_| is used to restrict aggregating quads only if they + // intersect this area. + root_damage_rect_.Union(target_damage); root_content_color_usage_ = prewalk_result.content_color_usage; if (prewalk_result.frame_sinks_changed) @@ -1827,6 +1833,15 @@ CopyPasses(root_surface_frame, surface); referenced_surfaces_.erase(surface_id); + // The root render pass damage might have been expanded by target_damage (the + // area that might need to be recomposited on the target surface). We restrict + // the damage_rect of the root render pass to the one caused by the source + // surfaces. + // The damage on the root render pass should not include the expanded area + // since Renderer and OverlayProcessor expect the non expanded damage. + if (!RenderPassNeedsFullDamage(dest_pass_list_->back().get())) + dest_pass_list_->back()->damage_rect.Intersect(surfaces_damage_rect); + // Now that we've handled our main surface aggregation, apply de-jelly effect // if enabled. if (de_jelly_enabled_)
diff --git a/components/viz/service/display/surface_aggregator.h b/components/viz/service/display/surface_aggregator.h index 6da752f..bdc4db4 100644 --- a/components/viz/service/display/surface_aggregator.h +++ b/components/viz/service/display/surface_aggregator.h
@@ -50,9 +50,14 @@ bool needs_surface_occluding_damage_rect); ~SurfaceAggregator(); + // |target_damage| represents an area on the output surface that might have + // been invalidated. It can be used in cases where we still want to support + // partial damage but the target surface might need contents outside the + // damage rect of the root surface. CompositorFrame Aggregate(const SurfaceId& surface_id, base::TimeTicks expected_display_time, gfx::OverlayTransform display_transform, + const gfx::Rect& target_damage = gfx::Rect(), int64_t display_trace_id = -1); void ReleaseResources(const SurfaceId& surface_id); const SurfaceIndexMap& previous_contained_surfaces() const {
diff --git a/components/viz/service/display/surface_aggregator_unittest.cc b/components/viz/service/display/surface_aggregator_unittest.cc index 0a3f1ae..0f7dace 100644 --- a/components/viz/service/display/surface_aggregator_unittest.cc +++ b/components/viz/service/display/surface_aggregator_unittest.cc
@@ -132,10 +132,11 @@ testing::Test::TearDown(); } - CompositorFrame AggregateFrame(const SurfaceId& surface_id) { + CompositorFrame AggregateFrame(const SurfaceId& surface_id, + gfx::Rect target_damage = gfx::Rect()) { return aggregator_.Aggregate( surface_id, GetNextDisplayTimeAndIncrement(), - gfx::OVERLAY_TRANSFORM_NONE /* display_transform */); + /*display_transform=*/gfx::OVERLAY_TRANSFORM_NONE, target_damage); } struct Quad { @@ -4399,6 +4400,133 @@ } } +TEST_F(SurfaceAggregatorPartialSwapTest, ExpandByTargetDamage) { + ParentLocalSurfaceIdAllocator allocator; + allocator.GenerateId(); + LocalSurfaceId child_local_surface_id = + allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id(); + SurfaceId child_surface_id(child_sink_->frame_sink_id(), + child_local_surface_id); + constexpr float device_scale_factor = 1.0f; + + // The child surface has one quad. + { + int child_pass_id = 1; + std::vector<Quad> child_quads1 = { + Quad::SolidColorQuad(SK_ColorGREEN, gfx::Rect(5, 5))}; + std::vector<Pass> child_passes = { + Pass(child_quads1, child_pass_id, gfx::Rect(5, 5))}; + + RenderPassList child_pass_list; + std::vector<SurfaceRange> referenced_surfaces; + AddPasses(&child_pass_list, child_passes, &referenced_surfaces); + + SubmitPassListAsFrame(child_sink_.get(), child_local_surface_id, + &child_pass_list, std::move(referenced_surfaces), + device_scale_factor); + } + + { + std::vector<Quad> root_quads = {Quad::SurfaceQuad( + SurfaceRange(base::nullopt, child_surface_id), SK_ColorWHITE, + gfx::Rect(SurfaceSize()), /*stretch_content_to_fill_bounds=*/false)}; + + std::vector<Pass> root_passes = {Pass(root_quads, SurfaceSize())}; + + RenderPassList root_pass_list; + std::vector<SurfaceRange> referenced_surfaces; + AddPasses(&root_pass_list, root_passes, &referenced_surfaces); + // No damage, this is the first frame submitted, so all quads should be + // produced. + SubmitPassListAsFrame(root_sink_.get(), root_local_surface_id_, + &root_pass_list, std::move(referenced_surfaces), + device_scale_factor); + } + + SurfaceId root_surface_id(root_sink_->frame_sink_id(), + root_local_surface_id_); + CompositorFrame aggregated_frame = AggregateFrame(root_surface_id); + + const auto& aggregated_pass_list = aggregated_frame.render_pass_list; + + ASSERT_EQ(1u, aggregated_pass_list.size()); + + // Damage rect for first aggregation should contain entire root surface. + EXPECT_EQ(gfx::Rect(SurfaceSize()), aggregated_pass_list.back()->damage_rect); + EXPECT_EQ(1u, aggregated_pass_list[0]->quad_list.size()); + + // Create a root surface with a smaller damage rect. + // This time the damage should be smaller. + { + std::vector<Quad> root_quads = {Quad::SurfaceQuad( + SurfaceRange(base::nullopt, child_surface_id), SK_ColorWHITE, + gfx::Rect(SurfaceSize()), /*stretch_content_to_fill_bounds=*/false)}; + + std::vector<Pass> root_passes = {Pass(root_quads, SurfaceSize())}; + + RenderPassList root_pass_list; + std::vector<SurfaceRange> referenced_surfaces; + AddPasses(&root_pass_list, root_passes, &referenced_surfaces); + + auto* root_pass = root_pass_list[0].get(); + root_pass->damage_rect = gfx::Rect(10, 10, 2, 2); + SubmitPassListAsFrame(root_sink_.get(), root_local_surface_id_, + &root_pass_list, std::move(referenced_surfaces), + device_scale_factor); + } + + { + CompositorFrame aggregated_frame = AggregateFrame(root_surface_id); + + const auto& aggregated_pass_list = aggregated_frame.render_pass_list; + + ASSERT_EQ(1u, aggregated_pass_list.size()); + + // No quads inside the damage + EXPECT_EQ(gfx::Rect(10, 10, 2, 2), + aggregated_pass_list.back()->damage_rect); + EXPECT_EQ(0u, aggregated_pass_list.back()->quad_list.size()); + } + + // This pass has damage that does not intersect the quad in the child + // surface. + { + std::vector<Quad> root_quads = { + Quad::SurfaceQuad(SurfaceRange(base::nullopt, child_surface_id), + SK_ColorWHITE, gfx::Rect(SurfaceSize()), false)}; + + std::vector<Pass> root_passes = {Pass(root_quads, SurfaceSize())}; + + RenderPassList root_pass_list; + std::vector<SurfaceRange> referenced_surfaces; + AddPasses(&root_pass_list, root_passes, &referenced_surfaces); + + auto* root_pass = root_pass_list[0].get(); + root_pass->damage_rect = gfx::Rect(10, 10, 2, 2); + SubmitPassListAsFrame(root_sink_.get(), root_local_surface_id_, + &root_pass_list, std::move(referenced_surfaces), + device_scale_factor); + } + + // The target surface invalidates one pixel in the top left, the quad in the + // child surface should be added even if it's not causing damage nor in the + // root render pass damage. + { + gfx::Rect target_damage(0, 0, 1, 1); + CompositorFrame aggregated_frame = + AggregateFrame(root_surface_id, target_damage); + + const auto& aggregated_pass_list = aggregated_frame.render_pass_list; + ASSERT_EQ(1u, aggregated_pass_list.size()); + + // The damage rect of the root render pass should not be changed. + EXPECT_EQ(gfx::Rect(10, 10, 2, 2), + aggregated_pass_list.back()->damage_rect); + // We expect one quad + ASSERT_EQ(1u, aggregated_pass_list[0]->quad_list.size()); + } +} + class SurfaceAggregatorWithResourcesTest : public testing::Test, public DisplayTimeSource { public:
diff --git a/components/viz/service/display_embedder/buffer_queue.cc b/components/viz/service/display_embedder/buffer_queue.cc index 8524108..c77f77f 100644 --- a/components/viz/service/display_embedder/buffer_queue.cc +++ b/components/viz/service/display_embedder/buffer_queue.cc
@@ -52,8 +52,18 @@ } gfx::Rect BufferQueue::CurrentBufferDamage() const { - DCHECK(current_surface_); - return current_surface_->damage; + if (current_surface_) + return current_surface_->damage; + + // In case there is no current_surface_, we get the damage from the surface + // that will be set as current_surface_ by the next call to GetNextSurface. + if (!available_surfaces_.empty()) { + return available_surfaces_.back()->damage; + } + + // If we can't determine which surface will be the next current_surface_, we + // conservatively invalidate the whole buffer. + return gfx::Rect(size_); } void BufferQueue::SwapBuffers(const gfx::Rect& damage) {
diff --git a/components/viz/service/display_embedder/gl_output_surface_buffer_queue.cc b/components/viz/service/display_embedder/gl_output_surface_buffer_queue.cc index cde84ea..fa97c20 100644 --- a/components/viz/service/display_embedder/gl_output_surface_buffer_queue.cc +++ b/components/viz/service/display_embedder/gl_output_surface_buffer_queue.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/command_line.h" +#include "build/build_config.h" #include "components/viz/common/frame_sinks/begin_frame_source.h" #include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/switches.h" @@ -29,7 +30,6 @@ std::unique_ptr<BufferQueue> buffer_queue) : GLOutputSurface(context_provider, surface_handle), buffer_queue_(std::move(buffer_queue)) { - capabilities_.only_invalidates_damage_rect = false; capabilities_.uses_default_gl_framebuffer = false; capabilities_.output_surface_origin = gfx::SurfaceOrigin::kTopLeft; // Set |max_frames_pending| to 2 for buffer_queue, which aligns scheduling @@ -40,7 +40,13 @@ // shifts the start of the new frame forward relative to the old // implementation. capabilities_.max_frames_pending = 2; - + // GetCurrentFramebufferDamage will return an upper bound of the part of the + // buffer that needs to be recomposited. +#if defined(OS_MACOSX) + capabilities_.supports_target_damage = false; +#else + capabilities_.supports_target_damage = true; +#endif // Force the number of max pending frames to one when the switch // "double-buffer-compositing" is passed. // This will keep compositing in double buffered mode assuming |buffer_queue_|
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 1ba33bf..2025cce 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
@@ -291,7 +291,6 @@ if (command_line->HasSwitch(switches::kDoubleBufferCompositing)) capabilities_.max_frames_pending = 1; - capabilities_.only_invalidates_damage_rect = false; // Set supports_surfaceless to enable overlays. capabilities_.supports_surfaceless = true; capabilities_.preserve_buffer_content = true;
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 36404ea6..b30c3c5 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl.cc
@@ -691,7 +691,6 @@ if (capabilities_.preserve_buffer_content && capabilities_.supports_post_sub_buffer) { - capabilities_.only_invalidates_damage_rect = false; damage_of_buffers_.resize(capabilities_.max_frames_pending + 1); }
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc index e41811a..1c27142 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
@@ -68,6 +68,7 @@ #if BUILDFLAG(ENABLE_VULKAN) #include "components/viz/service/display_embedder/skia_output_device_vulkan.h" +#include "gpu/vulkan/vulkan_util.h" #endif #if (BUILDFLAG(ENABLE_VULKAN) || BUILDFLAG(SKIA_USE_DAWN)) && defined(USE_X11) @@ -1040,6 +1041,10 @@ } context_state_->UpdateSkiaOwnedMemorySize(); destroy_after_swap_.clear(); +#if BUILDFLAG(ENABLE_VULKAN) + if (is_using_vulkan()) + gpu::ReportQueueSubmitPerSwapBuffers(); +#endif } void SkiaOutputSurfaceImplOnGpu::SwapBuffersSkipped( @@ -1050,6 +1055,10 @@ scoped_output_device_paint_.reset(); context_state_->UpdateSkiaOwnedMemorySize(); destroy_after_swap_.clear(); +#if BUILDFLAG(ENABLE_VULKAN) + if (is_using_vulkan()) + gpu::ReportQueueSubmitPerSwapBuffers(); +#endif } void SkiaOutputSurfaceImplOnGpu::FinishPaintRenderPass(
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index e11853c..edd0921 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -2760,7 +2760,12 @@ group("for_content_tests") { visibility = [ "//content/test/*", - "//content/public/test/*", + "//content/public/test/android/*", + + # TODO(danakj): Split out the web test parts of //content/shell/browser + # and only point to them here (similar to //content/renderer and + # //content/shell:web_test_renderer). + "//content/shell:content_shell_lib", ] if (!is_component_build) { public_deps = [ ":browser" ]
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc index 4f521568..f22af5d 100644 --- a/content/browser/accessibility/browser_accessibility_manager.cc +++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -610,7 +610,7 @@ return focus; } -bool BrowserAccessibilityManager::NativeViewHasFocus() const { +bool BrowserAccessibilityManager::NativeViewHasFocus() { BrowserAccessibilityDelegate* delegate = GetDelegateFromRootManager(); return delegate && delegate->AccessibilityViewHasFocus(); }
diff --git a/content/browser/accessibility/browser_accessibility_manager.h b/content/browser/accessibility/browser_accessibility_manager.h index 6d223ff..8892004 100644 --- a/content/browser/accessibility/browser_accessibility_manager.h +++ b/content/browser/accessibility/browser_accessibility_manager.h
@@ -86,10 +86,10 @@ virtual ~BrowserAccessibilityDelegate() {} virtual void AccessibilityPerformAction(const ui::AXActionData& data) = 0; - virtual bool AccessibilityViewHasFocus() const = 0; + virtual bool AccessibilityViewHasFocus() = 0; virtual void AccessibilityViewSetFocus() = 0; - virtual gfx::Rect AccessibilityGetViewBounds() const = 0; - virtual float AccessibilityGetDeviceScaleFactor() const = 0; + virtual gfx::Rect AccessibilityGetViewBounds() = 0; + virtual float AccessibilityGetDeviceScaleFactor() = 0; virtual void AccessibilityFatalError() = 0; virtual gfx::AcceleratedWidget AccessibilityGetAcceleratedWidget() = 0; virtual gfx::NativeViewAccessible AccessibilityGetNativeViewAccessible() = 0; @@ -99,7 +99,7 @@ // Returns true if this delegate represents the main (topmost) frame in a // tree of frames. - virtual bool AccessibilityIsMainFrame() const = 0; + virtual bool AccessibilityIsMainFrame() = 0; }; // This is all of the information about the current find in page result, @@ -345,7 +345,7 @@ BrowserAccessibility* GetActiveDescendant(BrowserAccessibility* focus) const; // Returns true if native focus is anywhere in this WebContents or not. - bool NativeViewHasFocus() const; + bool NativeViewHasFocus(); // True by default, but some platforms want to treat the root // scroll offsets separately.
diff --git a/content/browser/accessibility/browser_accessibility_manager_mac.mm b/content/browser/accessibility/browser_accessibility_manager_mac.mm index 9a9f6dea..2540186 100644 --- a/content/browser/accessibility/browser_accessibility_manager_mac.mm +++ b/content/browser/accessibility/browser_accessibility_manager_mac.mm
@@ -246,8 +246,8 @@ mac_notification = NSAccessibilitySelectedRowsChangedNotification; } else { // VoiceOver does not read anything if selection changes on the - // currently focused object, and the focus did not move. Detect a - // selection change in a where the focus did not change. + // currently focused object, and the focus did not move. Fire a + // selection change if the focus did not change. BrowserAccessibility* focus = GetFocus(); BrowserAccessibility* container = focus->PlatformGetSelectionContainer();
diff --git a/content/browser/accessibility/test_browser_accessibility_delegate.cc b/content/browser/accessibility/test_browser_accessibility_delegate.cc index 65ec2ada..9e3fe4f 100644 --- a/content/browser/accessibility/test_browser_accessibility_delegate.cc +++ b/content/browser/accessibility/test_browser_accessibility_delegate.cc
@@ -14,18 +14,17 @@ void TestBrowserAccessibilityDelegate::AccessibilityPerformAction( const ui::AXActionData& data) {} -bool TestBrowserAccessibilityDelegate::AccessibilityViewHasFocus() const { +bool TestBrowserAccessibilityDelegate::AccessibilityViewHasFocus() { return false; } void TestBrowserAccessibilityDelegate::AccessibilityViewSetFocus() {} -gfx::Rect TestBrowserAccessibilityDelegate::AccessibilityGetViewBounds() const { +gfx::Rect TestBrowserAccessibilityDelegate::AccessibilityGetViewBounds() { return gfx::Rect(); } -float TestBrowserAccessibilityDelegate::AccessibilityGetDeviceScaleFactor() - const { +float TestBrowserAccessibilityDelegate::AccessibilityGetDeviceScaleFactor() { return 1.0f; } @@ -52,7 +51,7 @@ return nullptr; } -bool TestBrowserAccessibilityDelegate::AccessibilityIsMainFrame() const { +bool TestBrowserAccessibilityDelegate::AccessibilityIsMainFrame() { return is_root_frame_; }
diff --git a/content/browser/accessibility/test_browser_accessibility_delegate.h b/content/browser/accessibility/test_browser_accessibility_delegate.h index 1d5d743..818e827b 100644 --- a/content/browser/accessibility/test_browser_accessibility_delegate.h +++ b/content/browser/accessibility/test_browser_accessibility_delegate.h
@@ -14,17 +14,17 @@ TestBrowserAccessibilityDelegate(); void AccessibilityPerformAction(const ui::AXActionData& data) override; - bool AccessibilityViewHasFocus() const override; + bool AccessibilityViewHasFocus() override; void AccessibilityViewSetFocus() override; - gfx::Rect AccessibilityGetViewBounds() const override; - float AccessibilityGetDeviceScaleFactor() const override; + gfx::Rect AccessibilityGetViewBounds() override; + float AccessibilityGetDeviceScaleFactor() override; void AccessibilityFatalError() override; gfx::AcceleratedWidget AccessibilityGetAcceleratedWidget() override; gfx::NativeViewAccessible AccessibilityGetNativeViewAccessible() override; gfx::NativeViewAccessible AccessibilityGetNativeViewAccessibleForWindow() override; WebContents* AccessibilityWebContents() override; - bool AccessibilityIsMainFrame() const override; + bool AccessibilityIsMainFrame() override; bool got_fatal_error() const; void reset_got_fatal_error();
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index e7009984..79f1dcc4 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -15,7 +15,6 @@ #include "base/base_switches.h" #include "base/bind.h" #include "base/command_line.h" -#include "base/debug/alias.h" #include "base/deferred_sequenced_task_runner.h" #include "base/feature_list.h" #include "base/location.h" @@ -295,13 +294,11 @@ } #endif // defined(USE_GLIB) -// Tell compiler not to inline this function so it's possible to tell what -// thread was unresponsive by inspecting the callstack. +// NOINLINE so it's possible to tell what thread was unresponsive by inspecting +// the callstack. NOINLINE void ResetThread_IO( std::unique_ptr<BrowserProcessSubThread> io_thread) { - const int line_number = __LINE__; io_thread.reset(); - base::debug::Alias(&line_number); } enum WorkerPoolType : size_t {
diff --git a/content/browser/browser_process_sub_thread.cc b/content/browser/browser_process_sub_thread.cc index f7c731e..748e7cf 100644 --- a/content/browser/browser_process_sub_thread.cc +++ b/content/browser/browser_process_sub_thread.cc
@@ -125,14 +125,14 @@ // them together. NOINLINE void BrowserProcessSubThread::UIThreadRun(base::RunLoop* run_loop) { - const int line_number = __LINE__; Thread::Run(run_loop); + + // Inhibit tail calls of Run and inhibit code folding. + const int line_number = __LINE__; base::debug::Alias(&line_number); } NOINLINE void BrowserProcessSubThread::IOThreadRun(base::RunLoop* run_loop) { - const int line_number = __LINE__; - // Register the IO thread for hang watching before it starts running and set // up a closure to automatically unregister it when Run() returns. base::ScopedClosureRunner unregister_thread_closure; @@ -142,6 +142,9 @@ } Thread::Run(run_loop); + + // Inhibit tail calls of Run and inhibit code folding. + const int line_number = __LINE__; base::debug::Alias(&line_number); }
diff --git a/content/browser/browsing_data/browsing_data_remover_impl.cc b/content/browser/browsing_data/browsing_data_remover_impl.cc index e680346d..d83d7974 100644 --- a/content/browser/browsing_data/browsing_data_remover_impl.cc +++ b/content/browser/browsing_data/browsing_data_remover_impl.cc
@@ -637,12 +637,6 @@ base::UmaHistogramMediumTimes( "History.ClearBrowsingData.Duration.TimeRangeDeletion", delta); } - // TODO(dullweber): Remove this metric after M83. - if (!task.delete_begin.is_null() || !task.delete_end.is_max() || - !task.filter_builder->IsEmptyBlacklist()) { - base::UmaHistogramMediumTimes( - "History.ClearBrowsingData.Duration.PartialDeletion", delta); - } } else { base::UmaHistogramMediumTimes( "History.ClearBrowsingData.Duration.OriginDeletion", delta);
diff --git a/content/browser/conversions/conversion_internals.mojom b/content/browser/conversions/conversion_internals.mojom index c9dab9b..8bfdeca 100644 --- a/content/browser/conversions/conversion_internals.mojom +++ b/content/browser/conversions/conversion_internals.mojom
@@ -43,6 +43,11 @@ // being sent. GetPendingReports() => (array<WebUIConversionReport> reports); + // Sends all stored reports, ignoring delay, returning when the + // operation has been completed and all reports have been cleared from + // storage. + SendPendingReports() => (); + // Deletes all persisted data for the Conversion API, returning when the // operation has been completed. ClearStorage() => ();
diff --git a/content/browser/conversions/conversion_internals_browsertest.cc b/content/browser/conversions/conversion_internals_browsertest.cc index e365f5f..9f88538 100644 --- a/content/browser/conversions/conversion_internals_browsertest.cc +++ b/content/browser/conversions/conversion_internals_browsertest.cc
@@ -183,7 +183,7 @@ ConversionReport report( ImpressionBuilder(base::Time::Now()).SetData("100").Build(), "7" /* conversion_data */, base::Time::Now() /* report_time */, - base::nullopt /* conversion_id */); + 1 /* conversion_id */); manager.SetReportsForWebUI({report}); OverrideWebUIConversionManager(&manager); @@ -211,7 +211,7 @@ ConversionReport report( ImpressionBuilder(base::Time::Now()).SetData("100").Build(), "7" /* conversion_data */, base::Time::Now() /* report_time */, - base::nullopt /* conversion_id */); + 1 /* conversion_id */); manager.SetReportsForWebUI({report}); OverrideWebUIConversionManager(&manager); @@ -241,4 +241,44 @@ EXPECT_EQ(kDeleteTitle, delete_title_watcher.WaitAndGetTitle()); } +// TODO(johnidel): Use a real ConversionManager here and verify that the reports +// are actually sent. +IN_PROC_BROWSER_TEST_F(ConversionInternalsWebUiBrowserTest, + WebUISendReports_ReportsRemoved) { + EXPECT_TRUE(NavigateToURL(shell(), GURL(kConversionInternalsUrl))); + + TestConversionManager manager; + ConversionReport report( + ImpressionBuilder(base::Time::Now()).SetData("100").Build(), + "7" /* conversion_data */, base::Time::Now() /* report_time */, + 1 /* conversion_id */); + manager.SetReportsForWebUI({report}); + OverrideWebUIConversionManager(&manager); + + std::string wait_script = R"( + let table = document.getElementById("report-table-body"); + let obs = new MutationObserver(() => { + if (table.children.length === 1 && + table.children[0].children[1].innerText === "0x7") { + document.title = $1; + } + }); + obs.observe(table, {'childList': true});)"; + EXPECT_TRUE(ExecJsInWebUI(JsReplace(wait_script, kCompleteTitle))); + + // Wait for the table to rendered. + TitleWatcher title_watcher(shell()->web_contents(), kCompleteTitle); + ClickRefreshButton(); + EXPECT_EQ(kCompleteTitle, title_watcher.WaitAndGetTitle()); + + // Click the send reports button and expect that the report table is emptied. + const base::string16 kSentTitle = base::ASCIIToUTF16("Sent"); + TitleWatcher sent_title_watcher(shell()->web_contents(), kSentTitle); + SetTitleOnReportsTableEmpty(kSentTitle); + + EXPECT_TRUE( + ExecJsInWebUI("document.getElementById('send-reports').click();")); + EXPECT_EQ(kSentTitle, sent_title_watcher.WaitAndGetTitle()); +} + } // namespace content
diff --git a/content/browser/conversions/conversion_internals_handler_impl.cc b/content/browser/conversions/conversion_internals_handler_impl.cc index 53be78ce..b1ec072 100644 --- a/content/browser/conversions/conversion_internals_handler_impl.cc +++ b/content/browser/conversions/conversion_internals_handler_impl.cc
@@ -100,6 +100,16 @@ } } +void ConversionInternalsHandlerImpl::SendPendingReports( + ::mojom::ConversionInternalsHandler::SendPendingReportsCallback callback) { + if (ConversionManager* manager = + manager_provider_->GetManager(web_ui_->GetWebContents())) { + manager->SendReportsForWebUI(std::move(callback)); + } else { + std::move(callback).Run(); + } +} + void ConversionInternalsHandlerImpl::ClearStorage( ::mojom::ConversionInternalsHandler::ClearStorageCallback callback) { if (ConversionManager* manager =
diff --git a/content/browser/conversions/conversion_internals_handler_impl.h b/content/browser/conversions/conversion_internals_handler_impl.h index 03d784b..76f6213 100644 --- a/content/browser/conversions/conversion_internals_handler_impl.h +++ b/content/browser/conversions/conversion_internals_handler_impl.h
@@ -35,6 +35,9 @@ void GetPendingReports( ::mojom::ConversionInternalsHandler::GetPendingReportsCallback callback) override; + void SendPendingReports( + ::mojom::ConversionInternalsHandler::SendPendingReportsCallback callback) + override; void ClearStorage(::mojom::ConversionInternalsHandler::ClearStorageCallback callback) override;
diff --git a/content/browser/conversions/conversion_manager.h b/content/browser/conversions/conversion_manager.h index 1697238..ca1e1a0 100644 --- a/content/browser/conversions/conversion_manager.h +++ b/content/browser/conversions/conversion_manager.h
@@ -47,10 +47,6 @@ // conversion reports to storage. virtual void HandleConversion(const StorableConversion& conversion) = 0; - // Notify storage to delete the given |conversion_id| when it's associated - // report has been sent. - virtual void HandleSentReport(int64_t conversion_id) = 0; - // Get all impressions that are currently stored in this partition. Used for // populating WebUI. virtual void GetActiveImpressionsForWebUI( @@ -62,6 +58,10 @@ base::OnceCallback<void(std::vector<ConversionReport>)> callback, base::Time max_report_time) = 0; + // Sends all pending reports immediately, and runs |done| once they have all + // been sent. + virtual void SendReportsForWebUI(base::OnceClosure done) = 0; + // Returns the ConversionPolicy that is used to control API policies such // as noise. virtual const ConversionPolicy& GetConversionPolicy() const = 0;
diff --git a/content/browser/conversions/conversion_manager_impl.cc b/content/browser/conversions/conversion_manager_impl.cc index 92d8c1a5..4f3f9ca 100644 --- a/content/browser/conversions/conversion_manager_impl.cc +++ b/content/browser/conversions/conversion_manager_impl.cc
@@ -6,6 +6,7 @@ #include <utility> +#include "base/barrier_closure.h" #include "base/bind.h" #include "base/command_line.h" #include "base/memory/ptr_util.h" @@ -52,7 +53,6 @@ : ConversionManagerImpl( std::make_unique<ConversionReporterImpl>( storage_partition, - this, base::DefaultClock::GetInstance()), std::make_unique<ConversionPolicy>( base::CommandLine::ForCurrentProcess()->HasSwitch( @@ -124,13 +124,6 @@ GetAndQueueReportsForNextInterval(); } -void ConversionManagerImpl::HandleSentReport(int64_t conversion_id) { - storage_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(base::IgnoreResult(&ConversionStorage::DeleteConversion), - base::Unretained(storage_.get()), conversion_id)); -} - void ConversionManagerImpl::GetActiveImpressionsForWebUI( base::OnceCallback<void(std::vector<StorableImpression>)> callback) { // Unretained is safe because any task to delete |storage_| will be posted @@ -145,13 +138,14 @@ void ConversionManagerImpl::GetReportsForWebUI( base::OnceCallback<void(std::vector<ConversionReport>)> callback, base::Time max_report_time) { - // Unretained is safe because any task to delete |storage_| will be posted - // after this one because |storage_| uses base::OnTaskRunnerDeleter. - base::PostTaskAndReplyWithResult( - storage_task_runner_.get(), FROM_HERE, - base::BindOnce(&ConversionStorage::GetConversionsToReport, - base::Unretained(storage_.get()), max_report_time), - std::move(callback)); + GetAndHandleReports(std::move(callback), max_report_time); +} + +void ConversionManagerImpl::SendReportsForWebUI(base::OnceClosure done) { + GetAndHandleReports( + base::BindOnce(&ConversionManagerImpl::HandleReportsSentFromWebUI, + weak_factory_.GetWeakPtr(), std::move(done)), + base::Time::Max()); } const ConversionPolicy& ConversionManagerImpl::GetConversionPolicy() const { @@ -181,7 +175,8 @@ // Chrome was not running and handle these specially. GetAndHandleReports( base::BindOnce(&ConversionManagerImpl::HandleReportsExpiredAtStartup, - weak_factory_.GetWeakPtr())); + weak_factory_.GetWeakPtr()), + clock_->Now() + kConversionManagerQueueReportsInterval); // Start a repeating timer that will fetch reports once every // |kConversionManagerQueueReportsInterval| and add them to |reporter_|. @@ -191,12 +186,12 @@ } void ConversionManagerImpl::GetAndHandleReports( - ReportsHandlerFunc handler_function) { + ReportsHandlerFunc handler_function, + base::Time max_report_time) { base::PostTaskAndReplyWithResult( storage_task_runner_.get(), FROM_HERE, base::BindOnce(&ConversionStorage::GetConversionsToReport, - base::Unretained(storage_.get()), - clock_->Now() + kConversionManagerQueueReportsInterval), + base::Unretained(storage_.get()), max_report_time), std::move(handler_function)); } @@ -204,13 +199,20 @@ // Get all the reports that will be reported in the next interval and them to // the |reporter_|. GetAndHandleReports(base::BindOnce(&ConversionManagerImpl::QueueReports, - weak_factory_.GetWeakPtr())); + weak_factory_.GetWeakPtr()), + clock_->Now() + kConversionManagerQueueReportsInterval); } void ConversionManagerImpl::QueueReports( std::vector<ConversionReport> reports) { - if (!reports.empty()) - reporter_->AddReportsToQueue(std::move(reports)); + if (!reports.empty()) { + // |reporter_| is owned by |this|, so base::Unretained() is safe as the + // reporter and callbacks will be deleted first. + reporter_->AddReportsToQueue( + std::move(reports), + base::BindRepeating(&ConversionManagerImpl::OnReportSent, + base::Unretained(this))); + } } void ConversionManagerImpl::HandleReportsExpiredAtStartup( @@ -232,4 +234,49 @@ QueueReports(std::move(reports)); } +void ConversionManagerImpl::HandleReportsSentFromWebUI( + base::OnceClosure done, + std::vector<ConversionReport> reports) { + if (reports.empty()) { + std::move(done).Run(); + return; + } + + // All reports should be sent immediately. + for (ConversionReport& report : reports) { + report.report_time = base::Time::Min(); + } + + // Wraps |done| so that is will run once all of the reports have finished + // sending. + base::RepeatingClosure all_reports_sent = + base::BarrierClosure(reports.size(), std::move(done)); + + // |reporter_| is owned by |this|, so base::Unretained() is safe as the + // reporter and callbacks will be deleted first. + reporter_->AddReportsToQueue( + std::move(reports), + base::BindRepeating(&ConversionManagerImpl::OnReportSentFromWebUI, + base::Unretained(this), std::move(all_reports_sent))); +} + +void ConversionManagerImpl::OnReportSent(int64_t conversion_id) { + storage_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(base::IgnoreResult(&ConversionStorage::DeleteConversion), + base::Unretained(storage_.get()), conversion_id)); +} + +void ConversionManagerImpl::OnReportSentFromWebUI( + base::OnceClosure reports_sent_barrier, + int64_t conversion_id) { + // |reports_sent_barrier| is a OnceClosure view of a RepeatingClosure obtained + // by base::BarrierClosure(). + storage_task_runner_->PostTaskAndReply( + FROM_HERE, + base::BindOnce(base::IgnoreResult(&ConversionStorage::DeleteConversion), + base::Unretained(storage_.get()), conversion_id), + std::move(reports_sent_barrier)); +} + } // namespace content
diff --git a/content/browser/conversions/conversion_manager_impl.h b/content/browser/conversions/conversion_manager_impl.h index bf99ed11..03bcd94 100644 --- a/content/browser/conversions/conversion_manager_impl.h +++ b/content/browser/conversions/conversion_manager_impl.h
@@ -56,10 +56,12 @@ public: virtual ~ConversionReporter() = default; - // Adds |reports| to a shared queue of reports that need to be sent. The - // reporter needs to notify it's owning manager when a report has been sent - // via ConversionManager::HandleSentReport(). - virtual void AddReportsToQueue(std::vector<ConversionReport> reports) = 0; + // Adds |reports| to a shared queue of reports that need to be sent. Runs + // |report_sent_callback| for every report that is sent, with the associated + // |conversion_id| of the report. + virtual void AddReportsToQueue( + std::vector<ConversionReport> reports, + base::RepeatingCallback<void(int64_t)> report_sent_callback) = 0; }; static std::unique_ptr<ConversionManagerImpl> CreateForTesting( @@ -81,13 +83,13 @@ // ConversionManager: void HandleImpression(const StorableImpression& impression) override; void HandleConversion(const StorableConversion& conversion) override; - void HandleSentReport(int64_t conversion_id) override; void GetActiveImpressionsForWebUI( base::OnceCallback<void(std::vector<StorableImpression>)> callback) override; void GetReportsForWebUI( base::OnceCallback<void(std::vector<ConversionReport>)> callback, base::Time max_report_time) override; + void SendReportsForWebUI(base::OnceClosure done) override; const ConversionPolicy& GetConversionPolicy() const override; void ClearData(base::Time delete_begin, base::Time delete_end, @@ -104,9 +106,12 @@ void OnInitCompleted(bool success); + // Retrieves reports from storage whose |report_time| <= |max_report_time|, + // and calls |handler_function| on them. using ReportsHandlerFunc = base::OnceCallback<void(std::vector<ConversionReport>)>; - void GetAndHandleReports(ReportsHandlerFunc handler_function); + void GetAndHandleReports(ReportsHandlerFunc handler_function, + base::Time max_report_time); // Get the next set of reports from storage that need to be sent before the // next call from |get_and_queue_reports_timer_|. Adds the reports to @@ -118,6 +123,18 @@ void HandleReportsExpiredAtStartup(std::vector<ConversionReport> reports); + void HandleReportsSentFromWebUI(base::OnceClosure done, + std::vector<ConversionReport> reports); + + // Notify storage to delete the given |conversion_id| when it's associated + // report has been sent. + void OnReportSent(int64_t conversion_id); + + // Similar to OnReportSent, but invokes |reports_sent_barrier| when the + // report has been removed from storage. + void OnReportSentFromWebUI(base::OnceClosure reports_sent_barrier, + int64_t conversion_id); + // Friend to expose the ConversionStorage and task runner, consider changing // to just expose the storage if it moves to SequenceBound. friend std::vector<ConversionReport> GetConversionsToReportForTesting(
diff --git a/content/browser/conversions/conversion_manager_impl_unittest.cc b/content/browser/conversions/conversion_manager_impl_unittest.cc index 1766dc31..3ca019f 100644 --- a/content/browser/conversions/conversion_manager_impl_unittest.cc +++ b/content/browser/conversions/conversion_manager_impl_unittest.cc
@@ -51,15 +51,27 @@ ~TestConversionReporter() override = default; // ConversionManagerImpl::ConversionReporter - void AddReportsToQueue(std::vector<ConversionReport> reports) override { + void AddReportsToQueue( + std::vector<ConversionReport> reports, + base::RepeatingCallback<void(int64_t)> report_sent_callback) override { num_reports_ += reports.size(); last_conversion_id_ = *reports.back().conversion_id; last_report_time_ = reports.back().report_time; + if (should_run_report_sent_callbacks_) { + for (const auto& report : reports) { + report_sent_callback.Run(*report.conversion_id); + } + } + if (quit_closure_ && num_reports_ >= expected_num_reports_) std::move(quit_closure_).Run(); } + void ShouldRunReportSentCallbacks(bool should_run_report_sent_callbacks) { + should_run_report_sent_callbacks_ = should_run_report_sent_callbacks; + } + size_t num_reports() { return num_reports_; } int64_t last_conversion_id() { return last_conversion_id_; } @@ -77,6 +89,7 @@ } private: + bool should_run_report_sent_callbacks_ = false; size_t expected_num_reports_ = 0u; size_t num_reports_ = 0u; int64_t last_conversion_id_ = 0UL; @@ -213,6 +226,7 @@ } TEST_F(ConversionManagerImplTest, QueuedReportSent_NotQueuedAgain) { + test_reporter_->ShouldRunReportSentCallbacks(true); conversion_manager_->HandleImpression( ImpressionBuilder(clock().Now()).SetExpiry(kImpressionExpiry).Build()); conversion_manager_->HandleConversion(DefaultConversion()); @@ -220,9 +234,6 @@ kConversionManagerQueueReportsInterval); EXPECT_EQ(1u, test_reporter_->num_reports()); - // Notify the manager that the report has been sent. - conversion_manager_->HandleSentReport(test_reporter_->last_conversion_id()); - // The report should not be added to the queue again. task_environment_.FastForwardBy(kConversionManagerQueueReportsInterval); EXPECT_EQ(1u, test_reporter_->num_reports()); @@ -256,9 +267,9 @@ // Create the manager and check that the first report is queued immediately. CreateManager(); + test_reporter_->ShouldRunReportSentCallbacks(true); test_reporter_->WaitForNumReports(1); EXPECT_EQ(1u, test_reporter_->num_reports()); - conversion_manager_->HandleSentReport(test_reporter_->last_conversion_id()); // The second report is still queued at the correct time. task_environment_.FastForwardBy(kConversionManagerQueueReportsInterval); @@ -289,6 +300,19 @@ } } +TEST_F(ConversionManagerImplTest, ConversionsSentFromUI_ReportedImmediately) { + conversion_manager_->HandleImpression( + ImpressionBuilder(clock().Now()).SetExpiry(kImpressionExpiry).Build()); + conversion_manager_->HandleImpression( + ImpressionBuilder(clock().Now()).SetExpiry(kImpressionExpiry).Build()); + conversion_manager_->HandleConversion(DefaultConversion()); + EXPECT_EQ(0u, test_reporter_->num_reports()); + + conversion_manager_->SendReportsForWebUI(base::DoNothing()); + task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(0)); + EXPECT_EQ(2u, test_reporter_->num_reports()); +} + TEST_F(ConversionManagerImplTest, ExpiredReportsAtStartup_Delayed) { // Create a report that will be reported at t= 2 days. base::Time start_time = clock().Now();
diff --git a/content/browser/conversions/conversion_network_sender_impl.cc b/content/browser/conversions/conversion_network_sender_impl.cc index 41c06ea..d2259fb 100644 --- a/content/browser/conversions/conversion_network_sender_impl.cc +++ b/content/browser/conversions/conversion_network_sender_impl.cc
@@ -44,6 +44,11 @@ // Called when a network request is started for |report|, for logging metrics. void LogMetricsOnReportSend(ConversionReport* report) { DCHECK(report); + + // Reports sent from the WebUI should not log metrics. + if (report->report_time == base::Time::Min()) + return; + // Use a large time range to capture users that might not open the browser for // a long time while a conversion report is pending. Revisit this range if it // is non-ideal for real world data.
diff --git a/content/browser/conversions/conversion_policy.cc b/content/browser/conversions/conversion_policy.cc index 305b845..4df9ed7 100644 --- a/content/browser/conversions/conversion_policy.cc +++ b/content/browser/conversions/conversion_policy.cc
@@ -42,8 +42,8 @@ ConversionPolicy::ConversionPolicy(bool debug_mode) : debug_mode_(debug_mode), - noise_provider_(debug_mode ? std::make_unique<NoiseProvider>() - : nullptr) {} + noise_provider_(debug_mode ? nullptr + : std::make_unique<NoiseProvider>()) {} ConversionPolicy::ConversionPolicy( std::unique_ptr<ConversionPolicy::NoiseProvider> noise_provider)
diff --git a/content/browser/conversions/conversion_policy_unittest.cc b/content/browser/conversions/conversion_policy_unittest.cc index 7eaf4abe..15ff3505 100644 --- a/content/browser/conversions/conversion_policy_unittest.cc +++ b/content/browser/conversions/conversion_policy_unittest.cc
@@ -73,6 +73,16 @@ ->GetSanitizedConversionData(4UL)); } +// This test will fail flakily if noise is used. +TEST_F(ConversionPolicyTest, DebugMode_ConversionDataNotNoised) { + uint64_t conversion_data = 0UL; + for (int i = 0; i < 100; i++) { + EXPECT_EQ(base::NumberToString(conversion_data), + ConversionPolicy(true /* debug_mode */) + .GetSanitizedConversionData(conversion_data)); + } +} + TEST_F(ConversionPolicyTest, NoExpiryForImpression_DefaultUsed) { base::Time impression_time = base::Time::Now(); EXPECT_EQ(impression_time + base::TimeDelta::FromDays(30),
diff --git a/content/browser/conversions/conversion_reporter_impl.cc b/content/browser/conversions/conversion_reporter_impl.cc index 3a5b3c6..3011e2ef 100644 --- a/content/browser/conversions/conversion_reporter_impl.cc +++ b/content/browser/conversions/conversion_reporter_impl.cc
@@ -15,19 +15,16 @@ ConversionReporterImpl::ConversionReporterImpl( StoragePartition* storage_partition, - ConversionManager* conversion_manager, const base::Clock* clock) - : conversion_manager_(conversion_manager), - clock_(clock), + : clock_(clock), network_sender_( - std::make_unique<ConversionNetworkSenderImpl>(storage_partition)) { - DCHECK(conversion_manager_); -} + std::make_unique<ConversionNetworkSenderImpl>(storage_partition)) {} ConversionReporterImpl::~ConversionReporterImpl() = default; void ConversionReporterImpl::AddReportsToQueue( - std::vector<ConversionReport> reports) { + std::vector<ConversionReport> reports, + base::RepeatingCallback<void(int64_t)> report_sent_callback) { DCHECK(!reports.empty()); std::vector<std::unique_ptr<ConversionReport>> swappable_reports; @@ -45,8 +42,9 @@ for (std::unique_ptr<ConversionReport>& report : swappable_reports) { // If the given report is already being processed, ignore it. - bool inserted = - conversion_ids_being_processed_.insert(*(report->conversion_id)).second; + bool inserted = conversion_report_callbacks_ + .emplace(*(report->conversion_id), report_sent_callback) + .second; if (inserted) report_queue_.push(std::move(report)); } @@ -84,14 +82,18 @@ // Unretained is safe because the task should never actually be posted if the // timer itself is destroyed send_report_timer_.Start( - FROM_HERE, report_time - current_time, + FROM_HERE, + (report_time < current_time) ? base::TimeDelta() + : report_time - current_time, base::BindOnce(&ConversionReporterImpl::SendNextReport, base::Unretained(this))); } void ConversionReporterImpl::OnReportSent(int64_t conversion_id) { - conversion_ids_being_processed_.erase(conversion_id); - conversion_manager_->HandleSentReport(conversion_id); + auto it = conversion_report_callbacks_.find(conversion_id); + DCHECK(it != conversion_report_callbacks_.end()); + std::move(it->second).Run(conversion_id); + conversion_report_callbacks_.erase(it); } bool ConversionReporterImpl::ReportComparator::operator()(
diff --git a/content/browser/conversions/conversion_reporter_impl.h b/content/browser/conversions/conversion_reporter_impl.h index 0517645b..855a2b3a 100644 --- a/content/browser/conversions/conversion_reporter_impl.h +++ b/content/browser/conversions/conversion_reporter_impl.h
@@ -10,7 +10,8 @@ #include <queue> #include <vector> -#include "base/containers/flat_set.h" +#include "base/callback.h" +#include "base/containers/flat_map.h" #include "base/time/time.h" #include "base/timer/timer.h" #include "content/browser/conversions/conversion_manager_impl.h" @@ -24,7 +25,6 @@ namespace content { -class ConversionManager; class StoragePartition; // This class is responsible for managing the dispatch of conversion reports to @@ -52,14 +52,15 @@ }; ConversionReporterImpl(StoragePartition* storage_partition, - ConversionManager* manager, const base::Clock* clock); ConversionReporterImpl(const ConversionReporterImpl&) = delete; ConversionReporterImpl& operator=(const ConversionReporterImpl&) = delete; ~ConversionReporterImpl() override; // ConversionManagerImpl::ConversionReporter: - void AddReportsToQueue(std::vector<ConversionReport> reports) override; + void AddReportsToQueue( + std::vector<ConversionReport> reports, + base::RepeatingCallback<void(int64_t)> report_sent_callback) override; void SetNetworkSenderForTesting( std::unique_ptr<NetworkSender> network_sender); @@ -86,13 +87,12 @@ ReportComparator> report_queue_; - // Set of all conversion ids that are currently in |report_queue| or are being - // sent by |network_sender_|. The number of concurrent conversion reports - // being sent at any time is expected to be small, so a flat_set is used. - base::flat_set<int64_t> conversion_ids_being_processed_; - - // Must outlive |this|. - ConversionManager* conversion_manager_; + // Map of all conversion ids that are currently in |report_queue| or are being + // sent by |network_sender_|, and their associated report sent callbacks. The + // number of concurrent conversion reports being sent at any time is expected + // to be small, so a flat_map is used. + base::flat_map<int64_t, base::OnceCallback<void(int64_t)>> + conversion_report_callbacks_; const base::Clock* clock_;
diff --git a/content/browser/conversions/conversion_reporter_impl_unittest.cc b/content/browser/conversions/conversion_reporter_impl_unittest.cc index 615a406..a2b030ed 100644 --- a/content/browser/conversions/conversion_reporter_impl_unittest.cc +++ b/content/browser/conversions/conversion_reporter_impl_unittest.cc
@@ -4,9 +4,13 @@ #include "content/browser/conversions/conversion_reporter_impl.h" +#include <stdint.h> + +#include "base/bind.h" #include "base/sequenced_task_runner.h" #include "base/strings/strcat.h" #include "base/task/post_task.h" +#include "base/test/bind_test_util.h" #include "base/test/simple_test_clock.h" #include "content/browser/conversions/conversion_manager.h" #include "content/browser/conversions/conversion_test_utils.h" @@ -60,7 +64,6 @@ browser_context_(std::make_unique<TestBrowserContext>()), reporter_(std::make_unique<ConversionReporterImpl>( BrowserContext::GetDefaultStoragePartition(browser_context_.get()), - &test_manager_, task_environment_.GetMockClock())) { auto network_sender = std::make_unique<MockNetworkSender>(); sender_ = network_sender.get(); @@ -74,32 +77,35 @@ content::BrowserTaskEnvironment task_environment_; std::unique_ptr<TestBrowserContext> browser_context_; - TestConversionManager test_manager_; std::unique_ptr<ConversionReporterImpl> reporter_; MockNetworkSender* sender_; }; TEST_F(ConversionReporterImplTest, ReportAddedWithImmediateReportTime_ReportSent) { - reporter_->AddReportsToQueue({GetReport(clock().Now(), /*conversion_id=*/1)}); + reporter_->AddReportsToQueue({GetReport(clock().Now(), /*conversion_id=*/1)}, + base::BindRepeating([](int64_t conversion_id) { + EXPECT_EQ(1L, conversion_id); + })); // Fast forward by 0, as we yield the thread when a report is scheduled to be // sent. task_environment_.FastForwardBy(base::TimeDelta()); EXPECT_EQ(1, sender_->last_sent_report_id()); - EXPECT_EQ(1, test_manager_.last_sent_report_id()); } TEST_F(ConversionReporterImplTest, ReportWithReportTimeBeforeCurrentTime_ReportSent) { - reporter_->AddReportsToQueue({GetReport( - clock().Now() - base::TimeDelta::FromHours(10), /*conversion_id=*/1)}); + reporter_->AddReportsToQueue( + {GetReport(clock().Now() - base::TimeDelta::FromHours(10), + /*conversion_id=*/1)}, + base::BindRepeating( + [](int64_t conversion_id) { EXPECT_EQ(1L, conversion_id); })); // Fast forward by 0, as we yield the thread when a report is scheduled to be // sent. task_environment_.FastForwardBy(base::TimeDelta()); EXPECT_EQ(1, sender_->last_sent_report_id()); - EXPECT_EQ(1, test_manager_.last_sent_report_id()); } TEST_F(ConversionReporterImplTest, @@ -107,7 +113,8 @@ const base::TimeDelta delay = base::TimeDelta::FromMinutes(30); reporter_->AddReportsToQueue( - {GetReport(clock().Now() + delay, /*conversion_id=*/1)}); + {GetReport(clock().Now() + delay, /*conversion_id=*/1)}, + base::DoNothing()); task_environment_.FastForwardBy(base::TimeDelta()); EXPECT_EQ(0u, sender_->num_reports_sent()); @@ -119,36 +126,46 @@ } TEST_F(ConversionReporterImplTest, DuplicateReportScheduled_Ignored) { - reporter_->AddReportsToQueue({GetReport( - clock().Now() + base::TimeDelta::FromMinutes(1), /*conversion_id=*/1)}); + reporter_->AddReportsToQueue( + {GetReport(clock().Now() + base::TimeDelta::FromMinutes(1), + /*conversion_id=*/1)}, + base::DoNothing()); // A duplicate report should not be scheduled. - reporter_->AddReportsToQueue({GetReport( - clock().Now() + base::TimeDelta::FromMinutes(1), /*conversion_id=*/1)}); + reporter_->AddReportsToQueue( + {GetReport(clock().Now() + base::TimeDelta::FromMinutes(1), + /*conversion_id=*/1)}, + base::DoNothing()); task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1)); EXPECT_EQ(1u, sender_->num_reports_sent()); } TEST_F(ConversionReporterImplTest, NewReportWithPreviouslySeenConversionId_Scheduled) { - reporter_->AddReportsToQueue({GetReport(clock().Now(), /*conversion_id=*/1)}); + reporter_->AddReportsToQueue({GetReport(clock().Now(), /*conversion_id=*/1)}, + base::DoNothing()); task_environment_.FastForwardBy(base::TimeDelta()); EXPECT_EQ(1u, sender_->num_reports_sent()); // We should schedule the new report because the previous report has been // sent. - reporter_->AddReportsToQueue({GetReport(clock().Now(), /*conversion_id=*/1)}); + reporter_->AddReportsToQueue({GetReport(clock().Now(), /*conversion_id=*/1)}, + base::DoNothing()); task_environment_.FastForwardBy(base::TimeDelta()); EXPECT_EQ(2u, sender_->num_reports_sent()); } TEST_F(ConversionReporterImplTest, ManyReportsAddedAtOnce_SentInOrder) { std::vector<ConversionReport> reports; + int64_t last_report_id = 0UL; for (int i = 1; i < 10; i++) { reports.push_back(GetReport(clock().Now() + base::TimeDelta::FromMinutes(i), /*conversion_id=*/i)); } - reporter_->AddReportsToQueue(reports); + reporter_->AddReportsToQueue( + reports, base::BindLambdaForTesting([&](int64_t conversion_id) { + last_report_id = conversion_id; + })); task_environment_.FastForwardBy(base::TimeDelta()); EXPECT_EQ(0u, sender_->num_reports_sent()); @@ -157,15 +174,19 @@ EXPECT_EQ(static_cast<size_t>(i), sender_->num_reports_sent()); EXPECT_EQ(static_cast<int64_t>(i), sender_->last_sent_report_id()); - EXPECT_EQ(static_cast<int64_t>(i), test_manager_.last_sent_report_id()); + EXPECT_EQ(static_cast<int64_t>(i), last_report_id); } } TEST_F(ConversionReporterImplTest, ManyReportsAddedSeparately_SentInOrder) { + int64_t last_report_id = 0; + auto report_sent_callback = base::BindLambdaForTesting( + [&](int64_t conversion_id) { last_report_id = conversion_id; }); for (int i = 1; i < 10; i++) { reporter_->AddReportsToQueue( {GetReport(clock().Now() + base::TimeDelta::FromMinutes(i), - /*conversion_id=*/i)}); + /*conversion_id=*/i)}, + report_sent_callback); } task_environment_.FastForwardBy(base::TimeDelta()); EXPECT_EQ(0u, sender_->num_reports_sent()); @@ -175,7 +196,7 @@ EXPECT_EQ(static_cast<size_t>(i), sender_->num_reports_sent()); EXPECT_EQ(static_cast<int64_t>(i), sender_->last_sent_report_id()); - EXPECT_EQ(static_cast<int64_t>(i), test_manager_.last_sent_report_id()); + EXPECT_EQ(static_cast<int64_t>(i), last_report_id); } }
diff --git a/content/browser/conversions/conversion_test_utils.cc b/content/browser/conversions/conversion_test_utils.cc index 8a47956..0af4239 100644 --- a/content/browser/conversions/conversion_test_utils.cc +++ b/content/browser/conversions/conversion_test_utils.cc
@@ -52,10 +52,6 @@ num_conversions_++; } -void TestConversionManager::HandleSentReport(int64_t conversion_id) { - last_sent_report_id_ = conversion_id; -} - void TestConversionManager::GetActiveImpressionsForWebUI( base::OnceCallback<void(std::vector<StorableImpression>)> callback) { std::move(callback).Run(impressions_); @@ -67,6 +63,11 @@ std::move(callback).Run(reports_); } +void TestConversionManager::SendReportsForWebUI(base::OnceClosure done) { + reports_.clear(); + std::move(done).Run(); +} + const ConversionPolicy& TestConversionManager::GetConversionPolicy() const { return policy_; } @@ -94,7 +95,6 @@ void TestConversionManager::Reset() { num_impressions_ = 0u; num_conversions_ = 0u; - last_sent_report_id_ = 0UL; } // Builds an impression with default values. This is done as a builder because
diff --git a/content/browser/conversions/conversion_test_utils.h b/content/browser/conversions/conversion_test_utils.h index dcdc5e8d..ae9ec9b04 100644 --- a/content/browser/conversions/conversion_test_utils.h +++ b/content/browser/conversions/conversion_test_utils.h
@@ -57,13 +57,13 @@ // ConversionManager: void HandleImpression(const StorableImpression& impression) override; void HandleConversion(const StorableConversion& conversion) override; - void HandleSentReport(int64_t conversion_id) override; void GetActiveImpressionsForWebUI( base::OnceCallback<void(std::vector<StorableImpression>)> callback) override; void GetReportsForWebUI( base::OnceCallback<void(std::vector<ConversionReport>)> callback, base::Time max_report_time) override; + void SendReportsForWebUI(base::OnceClosure done) override; const ConversionPolicy& GetConversionPolicy() const override; void ClearData(base::Time delete_begin, base::Time delete_end, @@ -80,13 +80,10 @@ size_t num_impressions() const { return num_impressions_; } size_t num_conversions() const { return num_conversions_; } - int64_t last_sent_report_id() { return last_sent_report_id_; } - private: ConversionPolicy policy_; size_t num_impressions_ = 0; size_t num_conversions_ = 0; - int64_t last_sent_report_id_ = 0L; std::vector<StorableImpression> impressions_; std::vector<ConversionReport> reports_;
diff --git a/content/browser/devtools/devtools_instrumentation.cc b/content/browser/devtools/devtools_instrumentation.cc index 81f3c5a0..74e34ba 100644 --- a/content/browser/devtools/devtools_instrumentation.cc +++ b/content/browser/devtools/devtools_instrumentation.cc
@@ -665,6 +665,10 @@ WarnSameSiteUnspecifiedLaxAllowUnsafe); } + // If schemeful messages are disabled, don't add a warning for them. + if (!base::FeatureList::IsEnabled(features::kCookieDeprecationMessages)) + return warning_reasons; + // There can only be one of the following warnings. if (status.HasWarningReason(net::CanonicalCookie::CookieInclusionStatus:: WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE)) {
diff --git a/content/browser/frame_host/cookie_utils.cc b/content/browser/frame_host/cookie_utils.cc index c854504..e951953 100644 --- a/content/browser/frame_host/cookie_utils.cc +++ b/content/browser/frame_host/cookie_utils.cc
@@ -83,11 +83,6 @@ base::FeatureList::GetInstance()->IsFeatureOverriddenFromCommandLine( features::kCookieDeprecationMessages.name, base::FeatureList::OVERRIDE_DISABLE_FEATURE); - bool emit_messages = - !messages_disabled_by_cmdline && - (net::cookie_util::IsSameSiteByDefaultCookiesEnabled() || - net::cookie_util::IsCookiesWithoutSameSiteMustBeSecureEnabled() || - base::FeatureList::IsEnabled(features::kCookieDeprecationMessages)); bool breaking_context_downgrade = false; @@ -124,7 +119,7 @@ : blink::mojom::SameSiteCookieOperation::SetCookie, cookie_details->devtools_request_id); } - if (emit_messages) { + if (!messages_disabled_by_cmdline) { root_frame_host->AddSameSiteCookieDeprecationMessage( cookie_url, excluded_cookie.status, net::cookie_util::IsSameSiteByDefaultCookiesEnabled(),
diff --git a/content/browser/frame_host/navigation_controller_impl_unittest.cc b/content/browser/frame_host/navigation_controller_impl_unittest.cc index 807e835..ea263eeb 100644 --- a/content/browser/frame_host/navigation_controller_impl_unittest.cc +++ b/content/browser/frame_host/navigation_controller_impl_unittest.cc
@@ -165,12 +165,6 @@ } // WebContentsObserver: - void DidStartNavigationToPendingEntry(const GURL& url, - ReloadType reload_type) override { - navigated_url_ = url; - last_reload_type_ = reload_type; - } - void NavigationEntryCommitted( const LoadCommittedDetails& load_details) override { navigation_entry_committed_counter_++; @@ -190,8 +184,6 @@ navigation_entries_deleted_counter_++; } - const GURL& navigated_url() const { return navigated_url_; } - NavigationControllerImpl& controller_impl() { return static_cast<NavigationControllerImpl&>(controller()); } @@ -222,13 +214,11 @@ FrameTreeNode* root_ftn() { return contents()->GetFrameTree()->root(); } protected: - GURL navigated_url_; size_t navigation_entry_committed_counter_ = 0; size_t navigation_entry_changed_counter_ = 0; size_t navigation_list_pruned_counter_ = 0; size_t navigation_entries_deleted_counter_ = 0; PrunedDetails last_navigation_entry_pruned_details_; - ReloadType last_reload_type_; }; class TestWebContentsDelegate : public WebContentsDelegate { @@ -1297,7 +1287,6 @@ EXPECT_EQ(0U, navigation_list_pruned_counter_); // The reload is pending. The request should point to the original URL. - EXPECT_EQ(original_url, navigated_url()); EXPECT_EQ(controller.GetEntryCount(), 1); EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0); EXPECT_EQ(controller.GetPendingEntryIndex(), 0); @@ -4532,79 +4521,6 @@ EXPECT_EQ(url_b, controller.GetEntryAtIndex(2)->GetURL()); } -// Tests that successive navigations with intermittent duplicate navigations -// are correctly marked as reload in the navigation controller. -// We test the cases where in a navigation is pending/comitted before the new -// navigation is initiated. -// http://crbug.com/664319 -TEST_F(NavigationControllerTest, MultipleNavigationsAndReload) { - NavigationControllerImpl& controller = controller_impl(); - - GURL initial_url("http://www.google.com"); - GURL url_1("http://foo.com"); - GURL url_2("http://foo2.com"); - - // Test 1. - // A normal navigation to initial_url should not be marked as a reload. - auto navigation1 = - NavigationSimulator::CreateBrowserInitiated(initial_url, contents()); - navigation1->Start(); - EXPECT_EQ(initial_url, controller.GetVisibleEntry()->GetURL()); - navigation1->Commit(); - EXPECT_EQ(ReloadType::NONE, last_reload_type_); - - // Test 2. - // A navigation to initial_url with the navigation commit delayed should be - // marked as a reload. - auto navigation2 = - NavigationSimulator::CreateBrowserInitiated(initial_url, contents()); - navigation2->Start(); - EXPECT_EQ(initial_url, controller.GetVisibleEntry()->GetURL()); - navigation2->ReadyToCommit(); - EXPECT_EQ(initial_url, controller.GetVisibleEntry()->GetURL()); - EXPECT_EQ(ReloadType::NORMAL, last_reload_type_); - - // Test 3. - // A navigation to url_1 while the navigation to intial_url is still pending - // should not be marked as a reload. - auto navigation3 = - NavigationSimulator::CreateBrowserInitiated(url_1, contents()); - navigation3->Start(); - EXPECT_EQ(url_1, controller.GetVisibleEntry()->GetURL()); - EXPECT_EQ(ReloadType::NONE, last_reload_type_); - - // Test 4. - // A navigation to url_1 while the previous navigation to url_1 is pending - // should not be marked as reload. Even though the URL is the same as the - // previous navigation, the previous navigation did not commit. We can only - // reload navigations that committed. See https://crbug.com/809040. - auto navigation4 = - NavigationSimulator::CreateBrowserInitiated(url_1, contents()); - navigation4->Start(); - EXPECT_EQ(url_1, controller.GetVisibleEntry()->GetURL()); - EXPECT_EQ(ReloadType::NONE, last_reload_type_); - - navigation2->Commit(); - - // Test 5 - // A navigation to url_2 followed by a navigation to the previously pending - // url_1 should not be marked as a reload. - auto navigation5 = - NavigationSimulator::CreateBrowserInitiated(url_2, contents()); - navigation5->Start(); - EXPECT_EQ(url_2, controller.GetVisibleEntry()->GetURL()); - EXPECT_EQ(ReloadType::NONE, last_reload_type_); - - controller.LoadURL(url_1, Referrer(), ui::PAGE_TRANSITION_TYPED, - std::string()); - auto navigation6 = - NavigationSimulator::CreateBrowserInitiated(url_1, contents()); - navigation6->ReadyToCommit(); - EXPECT_EQ(url_1, controller.GetVisibleEntry()->GetURL()); - EXPECT_EQ(ReloadType::NONE, last_reload_type_); - navigation6->Commit(); -} - // Test to ensure that the pending entry index is updated when a transient entry // is inserted or removed. TEST_F(NavigationControllerTest, PendingEntryIndexUpdatedWithTransient) {
diff --git a/content/browser/frame_host/navigator.cc b/content/browser/frame_host/navigator.cc index 5d1d6af..89ae014 100644 --- a/content/browser/frame_host/navigator.cc +++ b/content/browser/frame_host/navigator.cc
@@ -361,8 +361,9 @@ GURL dest_url = request->common_params().url; FrameTreeNode* frame_tree_node = request->frame_tree_node(); - navigation_data_.reset(new NavigationMetricsData( - request->common_params().navigation_start, dest_url, restore_type)); + navigation_data_.reset( + new NavigationMetricsData(request->common_params().navigation_start, + request->common_params().url, restore_type)); // Check if the BeforeUnload event needs to execute before assigning the // NavigationRequest to the FrameTreeNode. Assigning it to the FrameTreeNode @@ -405,10 +406,6 @@ // Make sure no code called via RFH::Navigate clears the pending entry. if (is_pending_entry) CHECK_EQ(nav_entry_id, controller_->GetPendingEntry()->GetUniqueID()); - - // Notify observers about navigation. - if (delegate_ && is_pending_entry) - delegate_->DidStartNavigationToPendingEntry(dest_url, reload_type); } void Navigator::RequestOpenURL(
diff --git a/content/browser/frame_host/navigator_delegate.h b/content/browser/frame_host/navigator_delegate.h index aab1d201d..6ee4197 100644 --- a/content/browser/frame_host/navigator_delegate.h +++ b/content/browser/frame_host/navigator_delegate.h
@@ -82,11 +82,6 @@ // WebContents::NotifyNavigationStateChanged. virtual void NotifyChangedNavigationState(InvalidateTypes changed_flags) = 0; - // Notifies the Navigator embedder that a navigation to the pending - // NavigationEntry has started in the browser process. - virtual void DidStartNavigationToPendingEntry(const GURL& url, - ReloadType reload_type) = 0; - // Opens a URL with the given parameters. See PageNavigator::OpenURL, which // this is an alias of. virtual WebContents* OpenURL(const OpenURLParams& params) = 0;
diff --git a/content/browser/frame_host/raw_clipboard_host_impl.cc b/content/browser/frame_host/raw_clipboard_host_impl.cc index 890d664..85d2fdf 100644 --- a/content/browser/frame_host/raw_clipboard_host_impl.cc +++ b/content/browser/frame_host/raw_clipboard_host_impl.cc
@@ -26,10 +26,6 @@ mojo::PendingReceiver<blink::mojom::RawClipboardHost> receiver) { DCHECK(render_frame_host); - PermissionControllerImpl* permission_controller = - PermissionControllerImpl::FromBrowserContext( - render_frame_host->GetProcess()->GetBrowserContext()); - // Feature flags and permission should already be checked in the renderer // process, but recheck in the browser process in case of a hijacked renderer. if (!base::FeatureList::IsEnabled(blink::features::kRawClipboard)) { @@ -37,15 +33,28 @@ return; } + // Renderer process should already check for user activation before sending + // this request. Double check in case of compromised renderer. + if (!render_frame_host->HasTransientUserActivation()) { + // mojo::ReportBadMessage() is not appropriate here, because user + // activation may expire after the renderer check but before the browser + // check. + return; + } + + PermissionControllerImpl* permission_controller = + PermissionControllerImpl::FromBrowserContext( + render_frame_host->GetProcess()->GetBrowserContext()); + blink::mojom::PermissionStatus status = permission_controller->GetPermissionStatusForFrame( PermissionType::CLIPBOARD_READ_WRITE, render_frame_host, render_frame_host->GetLastCommittedOrigin().GetURL()); if (status != blink::mojom::PermissionStatus::GRANTED) { - // This may be hit by a race condition, where permission is denied after - // the renderer check, but before the browser check. It may also be hit by - // a compromised renderer. + // mojo::ReportBadMessage() is not appropriate here because the permission + // may be granted after the renderer check, but revoked before the browser + // check. return; } @@ -53,7 +62,7 @@ // loops. Use manual memory management instead of SelfOwnedReceiver<T> which // synchronously destroys on failure and can result in some unfortunate // use-after-frees after the nested message loops exit. - auto* host = new RawClipboardHostImpl(std::move(receiver)); + auto* host = new RawClipboardHostImpl(std::move(receiver), render_frame_host); host->receiver_.set_disconnect_handler(base::BindOnce( [](RawClipboardHostImpl* host) { base::SequencedTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, host); @@ -66,14 +75,20 @@ } RawClipboardHostImpl::RawClipboardHostImpl( - mojo::PendingReceiver<blink::mojom::RawClipboardHost> receiver) + mojo::PendingReceiver<blink::mojom::RawClipboardHost> receiver, + RenderFrameHost* render_frame_host) : receiver_(this, std::move(receiver)), clipboard_(ui::Clipboard::GetForCurrentThread()), clipboard_writer_( - new ui::ScopedClipboardWriter(ui::ClipboardBuffer::kCopyPaste)) {} + new ui::ScopedClipboardWriter(ui::ClipboardBuffer::kCopyPaste)), + render_frame_host_(render_frame_host) { + DCHECK(render_frame_host); +} void RawClipboardHostImpl::ReadAvailableFormatNames( ReadAvailableFormatNamesCallback callback) { + if (!HasTransientUserActivation()) + return; std::vector<base::string16> raw_types = clipboard_->ReadAvailablePlatformSpecificFormatNames( ui::ClipboardBuffer::kCopyPaste); @@ -82,6 +97,8 @@ void RawClipboardHostImpl::Read(const base::string16& format, ReadCallback callback) { + if (!HasTransientUserActivation()) + return; if (format.size() >= kMaxFormatSize) { receiver_.ReportBadMessage("Requested format string length too long."); return; @@ -98,6 +115,8 @@ void RawClipboardHostImpl::Write(const base::string16& format, mojo_base::BigBuffer data) { + if (!HasTransientUserActivation()) + return; if (format.size() >= kMaxFormatSize) { receiver_.ReportBadMessage("Target format string length too long."); return; @@ -136,4 +155,12 @@ new ui::ScopedClipboardWriter(ui::ClipboardBuffer::kCopyPaste)); } +bool RawClipboardHostImpl::HasTransientUserActivation() const { + // Renderer process should already check for user activation before sending + // this request. Double check in case of compromised renderer. + // mojo::ReportBadMessage() is not appropriate here, because user activation + // may expire after the renderer check but before the browser check. + return render_frame_host_->HasTransientUserActivation(); +} + } // namespace content
diff --git a/content/browser/frame_host/raw_clipboard_host_impl.h b/content/browser/frame_host/raw_clipboard_host_impl.h index f97b409..e305a59 100644 --- a/content/browser/frame_host/raw_clipboard_host_impl.h +++ b/content/browser/frame_host/raw_clipboard_host_impl.h
@@ -19,6 +19,9 @@ class RenderFrameHost; +// Instances destroy themselves when the blink::mojom::RawClipboardHost is +// disconnected, and this can only be used on the frame and sequence it's +// created on. class CONTENT_EXPORT RawClipboardHostImpl : public blink::mojom::RawClipboardHost { public: @@ -30,8 +33,9 @@ ~RawClipboardHostImpl() override; private: - explicit RawClipboardHostImpl( - mojo::PendingReceiver<blink::mojom::RawClipboardHost> receiver); + RawClipboardHostImpl( + mojo::PendingReceiver<blink::mojom::RawClipboardHost> receiver, + RenderFrameHost* render_frame_host); // mojom::RawClipboardHost. void ReadAvailableFormatNames( @@ -40,9 +44,15 @@ void Write(const base::string16& format, mojo_base::BigBuffer data) override; void CommitWrite() override; + bool HasTransientUserActivation() const; + mojo::Receiver<blink::mojom::RawClipboardHost> receiver_; ui::Clipboard* const clipboard_; // Not owned. std::unique_ptr<ui::ScopedClipboardWriter> clipboard_writer_; + // Not owned. Raw pointer usage is safe here because RawClipboardHostImpl is + // per-frame, so |render_frame_host_| is guaranteed to outlive the + // RawClipboardHostImpl. + RenderFrameHost* const render_frame_host_; }; } // namespace content
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index b021aa6..d10d99df7 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -1683,7 +1683,7 @@ render_accessibility_->PerformAction(action_data); } -bool RenderFrameHostImpl::AccessibilityViewHasFocus() const { +bool RenderFrameHostImpl::AccessibilityViewHasFocus() { if (!is_active()) return false; @@ -1702,7 +1702,7 @@ view->Focus(); } -gfx::Rect RenderFrameHostImpl::AccessibilityGetViewBounds() const { +gfx::Rect RenderFrameHostImpl::AccessibilityGetViewBounds() { if (!is_active()) return gfx::Rect(); @@ -1712,7 +1712,7 @@ return gfx::Rect(); } -float RenderFrameHostImpl::AccessibilityGetDeviceScaleFactor() const { +float RenderFrameHostImpl::AccessibilityGetDeviceScaleFactor() { if (!is_active()) return 1.0f; @@ -1788,7 +1788,7 @@ return delegate()->GetAsWebContents(); } -bool RenderFrameHostImpl::AccessibilityIsMainFrame() const { +bool RenderFrameHostImpl::AccessibilityIsMainFrame() { if (!is_active()) return false; return frame_tree_node()->IsMainFrame(); @@ -8253,14 +8253,15 @@ return true; } -void RenderFrameHostImpl::PostMessageEvent(int32_t source_routing_id, - const base::string16& source_origin, - const base::string16& target_origin, - blink::TransferableMessage message) { +void RenderFrameHostImpl::PostMessageEvent( + const base::Optional<base::UnguessableToken>& source_token, + const base::string16& source_origin, + const base::string16& target_origin, + blink::TransferableMessage message) { DCHECK(render_frame_created_); - GetNavigationControl()->PostMessageEvent(source_routing_id, source_origin, - target_origin, std::move(message)); + GetAssociatedLocalFrame()->PostMessageEvent( + source_token, source_origin, target_origin, std::move(message)); } bool RenderFrameHostImpl::IsTestRenderFrameHost() const {
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index 7462933..2bba134 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -403,17 +403,17 @@ // BrowserAccessibilityDelegate void AccessibilityPerformAction(const ui::AXActionData& data) override; - bool AccessibilityViewHasFocus() const override; + bool AccessibilityViewHasFocus() override; void AccessibilityViewSetFocus() override; - gfx::Rect AccessibilityGetViewBounds() const override; - float AccessibilityGetDeviceScaleFactor() const override; + gfx::Rect AccessibilityGetViewBounds() override; + float AccessibilityGetDeviceScaleFactor() override; void AccessibilityFatalError() override; gfx::AcceleratedWidget AccessibilityGetAcceleratedWidget() override; gfx::NativeViewAccessible AccessibilityGetNativeViewAccessible() override; gfx::NativeViewAccessible AccessibilityGetNativeViewAccessibleForWindow() override; WebContents* AccessibilityWebContents() override; - bool AccessibilityIsMainFrame() const override; + bool AccessibilityIsMainFrame() override; // RenderProcessHostObserver implementation. void RenderProcessExited(RenderProcessHost* host, @@ -1174,10 +1174,11 @@ CommitCallbackInterceptor* interceptor); // Posts a message from a frame in another process to the current renderer. - void PostMessageEvent(int32_t source_routing_id, - const base::string16& source_origin, - const base::string16& target_origin, - blink::TransferableMessage message); + void PostMessageEvent( + const base::Optional<base::UnguessableToken>& source_token, + const base::string16& source_origin, + const base::string16& target_origin, + blink::TransferableMessage message); // Requests to swap the current frame into the frame tree, replacing the // RenderFrameProxy it is associated with.
diff --git a/content/browser/frame_host/render_frame_proxy_host.cc b/content/browser/frame_host/render_frame_proxy_host.cc index c2e9988..425b0b4f 100644 --- a/content/browser/frame_host/render_frame_proxy_host.cc +++ b/content/browser/frame_host/render_frame_proxy_host.cc
@@ -557,19 +557,17 @@ GetSiteInstance())) return; - int32_t source_routing_id = params.source_routing_id; + base::Optional<base::UnguessableToken> translated_source_token; base::string16 source_origin = params.source_origin; base::string16 target_origin = params.target_origin; blink::TransferableMessage message = std::move(params.message->data); - // If there is a source_routing_id, translate it to the routing ID of the + // If there is a source_routing_id, translate it to the frame token of the // equivalent RenderFrameProxyHost in the target process. - if (source_routing_id != MSG_ROUTING_NONE) { - RenderFrameHostImpl* source_rfh = - RenderFrameHostImpl::FromID(GetProcess()->GetID(), source_routing_id); - if (!source_rfh) { - source_routing_id = MSG_ROUTING_NONE; - } else { + if (params.source_routing_id != MSG_ROUTING_NONE) { + RenderFrameHostImpl* source_rfh = RenderFrameHostImpl::FromID( + GetProcess()->GetID(), params.source_routing_id); + if (source_rfh) { // https://crbug.com/822958: If the postMessage is going to a descendant // frame, ensure that any pending visual properties such as size are sent // to the target frame before the postMessage, as sites might implicitly @@ -619,16 +617,14 @@ ->render_manager() ->GetRenderFrameProxyHost(target_site_instance); if (source_proxy_in_target_site_instance) { - source_routing_id = - source_proxy_in_target_site_instance->GetRoutingID(); - } else { - source_routing_id = MSG_ROUTING_NONE; + translated_source_token = + source_proxy_in_target_site_instance->GetFrameToken(); } } } - target_rfh->PostMessageEvent(source_routing_id, source_origin, target_origin, - std::move(message)); + target_rfh->PostMessageEvent(translated_source_token, source_origin, + target_origin, std::move(message)); } void RenderFrameProxyHost::OnDidChangeOpener(int32_t opener_routing_id) {
diff --git a/content/browser/message_port_provider.cc b/content/browser/message_port_provider.cc index 3b7ca96..2f6c6b1f 100644 --- a/content/browser/message_port_provider.cc +++ b/content/browser/message_port_provider.cc
@@ -6,6 +6,8 @@ #include <utility> +#include "base/optional.h" +#include "base/unguessable_token.h" #include "build/build_config.h" #include "build/chromecast_buildflags.h" #include "content/browser/renderer_host/render_process_host_impl.h" @@ -43,11 +45,10 @@ message.owned_encoded_message = blink::EncodeStringMessage(data); message.encoded_message = message.owned_encoded_message; message.ports = std::move(channels); - int32_t source_routing_id = MSG_ROUTING_NONE; RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(web_contents->GetMainFrame()); - rfh->PostMessageEvent(source_routing_id, source_origin, target_origin, + rfh->PostMessageEvent(base::nullopt, source_origin, target_origin, std::move(message)); }
diff --git a/content/browser/renderer_host/input/input_router_impl.cc b/content/browser/renderer_host/input/input_router_impl.cc index 9ac3432..a7a2b26 100644 --- a/content/browser/renderer_host/input/input_router_impl.cc +++ b/content/browser/renderer_host/input/input_router_impl.cc
@@ -297,9 +297,13 @@ UpdateTouchAckTimeoutEnabled(); } -void InputRouterImpl::DidOverscroll(const ui::DidOverscrollParams& params) { +void InputRouterImpl::DidOverscroll( + blink::mojom::DidOverscrollParamsPtr params) { // Touchpad and Touchscreen flings are handled on the browser side. - ui::DidOverscrollParams fling_updated_params = params; + ui::DidOverscrollParams fling_updated_params = { + params->accumulated_overscroll, params->latest_overscroll_delta, + params->current_fling_velocity, params->causal_event_viewport_point, + params->overscroll_behavior}; fling_updated_params.current_fling_velocity = gesture_event_queue_.CurrentFlingVelocity(); client_->DidOverscroll(fling_updated_params); @@ -528,8 +532,7 @@ TRACE_EVENT_SCOPE_THREAD); if (filtered_state != blink::mojom::InputEventResultState::kUnknown) { std::move(callback).Run(blink::mojom::InputEventResultSource::kBrowser, - latency_info, filtered_state, base::nullopt, - base::nullopt); + latency_info, filtered_state, nullptr, nullptr); } return; } @@ -547,8 +550,8 @@ blink::mojom::InputEventResultSource source, const ui::LatencyInfo& latency, blink::mojom::InputEventResultState state, - const base::Optional<ui::DidOverscrollParams>& overscroll, - const base::Optional<cc::TouchAction>& touch_action) { + blink::mojom::DidOverscrollParamsPtr overscroll, + blink::mojom::TouchActionOptionalPtr touch_action) { // Filter source to ensure only valid values are sent from the // renderer. if (source == blink::mojom::InputEventResultSource::kBrowser) { @@ -557,8 +560,9 @@ return; } - std::move(callback).Run(source, latency, state, overscroll, - touch_action); + std::move(callback).Run(source, latency, state, + std::move(overscroll), + std::move(touch_action)); }, std::move(callback), weak_this_); client_->GetWidgetInputHandler()->DispatchEvent( @@ -568,10 +572,9 @@ TRACE_EVENT_SCOPE_THREAD); client_->GetWidgetInputHandler()->DispatchNonBlockingEvent( std::move(event)); - std::move(callback).Run(blink::mojom::InputEventResultSource::kBrowser, - latency_info, - blink::mojom::InputEventResultState::kIgnored, - base::nullopt, base::nullopt); + std::move(callback).Run( + blink::mojom::InputEventResultSource::kBrowser, latency_info, + blink::mojom::InputEventResultState::kIgnored, nullptr, nullptr); } } @@ -581,8 +584,8 @@ blink::mojom::InputEventResultSource source, const ui::LatencyInfo& latency, blink::mojom::InputEventResultState state, - const base::Optional<ui::DidOverscrollParams>& overscroll, - const base::Optional<cc::TouchAction>& touch_action) { + blink::mojom::DidOverscrollParamsPtr overscroll, + blink::mojom::TouchActionOptionalPtr touch_action) { TRACE_EVENT2("input", "InputRouterImpl::KeboardEventHandled", "type", WebInputEvent::GetName(event.event.GetType()), "ack", InputEventResultStateToString(state)); @@ -604,8 +607,8 @@ blink::mojom::InputEventResultSource source, const ui::LatencyInfo& latency, blink::mojom::InputEventResultState state, - const base::Optional<ui::DidOverscrollParams>& overscroll, - const base::Optional<cc::TouchAction>& touch_action) { + blink::mojom::DidOverscrollParamsPtr overscroll, + blink::mojom::TouchActionOptionalPtr touch_action) { TRACE_EVENT2("input", "InputRouterImpl::MouseEventHandled", "type", WebInputEvent::GetName(event.event.GetType()), "ack", InputEventResultStateToString(state)); @@ -621,8 +624,8 @@ blink::mojom::InputEventResultSource source, const ui::LatencyInfo& latency, blink::mojom::InputEventResultState state, - const base::Optional<ui::DidOverscrollParams>& overscroll, - const base::Optional<cc::TouchAction>& touch_action) { + blink::mojom::DidOverscrollParamsPtr overscroll, + blink::mojom::TouchActionOptionalPtr touch_action) { TRACE_EVENT2("input", "InputRouterImpl::TouchEventHandled", "type", WebInputEvent::GetName(touch_event.event.GetType()), "ack", InputEventResultStateToString(state)); @@ -633,11 +636,11 @@ // The SetTouchAction IPC occurs on a different channel so always // send it in the input event ack to ensure it is available at the // time the ACK is handled. - if (touch_action.has_value()) { + if (touch_action) { if (source == blink::mojom::InputEventResultSource::kCompositorThread) - OnSetWhiteListedTouchAction(touch_action.value()); + OnSetWhiteListedTouchAction(touch_action->touch_action); else if (source == blink::mojom::InputEventResultSource::kMainThread) - OnSetTouchAction(touch_action.value()); + OnSetTouchAction(touch_action->touch_action); else NOTREACHED(); } @@ -655,8 +658,8 @@ blink::mojom::InputEventResultSource source, const ui::LatencyInfo& latency, blink::mojom::InputEventResultState state, - const base::Optional<ui::DidOverscrollParams>& overscroll, - const base::Optional<cc::TouchAction>& touch_action) { + blink::mojom::DidOverscrollParamsPtr overscroll, + blink::mojom::TouchActionOptionalPtr touch_action) { TRACE_EVENT2("input", "InputRouterImpl::GestureEventHandled", "type", WebInputEvent::GetName(gesture_event.event.GetType()), "ack", InputEventResultStateToString(state)); @@ -666,7 +669,7 @@ if (overscroll) { DCHECK_EQ(WebInputEvent::Type::kGestureScrollUpdate, gesture_event.event.GetType()); - DidOverscroll(overscroll.value()); + DidOverscroll(std::move(overscroll)); } // |gesture_event_queue_| will forward to OnGestureEventAck when appropriate. @@ -680,8 +683,8 @@ blink::mojom::InputEventResultSource source, const ui::LatencyInfo& latency, blink::mojom::InputEventResultState state, - const base::Optional<ui::DidOverscrollParams>& overscroll, - const base::Optional<cc::TouchAction>& touch_action) { + blink::mojom::DidOverscrollParamsPtr overscroll, + blink::mojom::TouchActionOptionalPtr touch_action) { TRACE_EVENT2("input", "InputRouterImpl::MouseWheelEventHandled", "type", WebInputEvent::GetName(event.event.GetType()), "ack", InputEventResultStateToString(state)); @@ -690,7 +693,7 @@ event.latency.AddNewLatencyFrom(latency); if (overscroll) - DidOverscroll(overscroll.value()); + DidOverscroll(std::move(overscroll)); std::move(callback).Run(event, source, state); }
diff --git a/content/browser/renderer_host/input/input_router_impl.h b/content/browser/renderer_host/input/input_router_impl.h index 787ac21..47961159 100644 --- a/content/browser/renderer_host/input/input_router_impl.h +++ b/content/browser/renderer_host/input/input_router_impl.h
@@ -33,7 +33,6 @@ namespace ui { class LatencyInfo; -struct DidOverscrollParams; } // namespace ui namespace content { @@ -92,7 +91,7 @@ // InputHandlerHost impl void SetTouchActionFromMain(cc::TouchAction touch_action) override; - void DidOverscroll(const ui::DidOverscrollParams& params) override; + void DidOverscroll(blink::mojom::DidOverscrollParamsPtr params) override; void ImeCancelComposition() override; void DidStartScrollingViewport() override; void ImeCompositionRangeChanged( @@ -184,44 +183,40 @@ const ui::LatencyInfo& latency_info, mojom::WidgetInputHandler::DispatchEventCallback callback); - void KeyboardEventHandled( - const NativeWebKeyboardEventWithLatencyInfo& event, - KeyboardEventCallback event_result_callback, - blink::mojom::InputEventResultSource source, - const ui::LatencyInfo& latency, - blink::mojom::InputEventResultState state, - const base::Optional<ui::DidOverscrollParams>& overscroll, - const base::Optional<cc::TouchAction>& touch_action); - void MouseEventHandled( - const MouseEventWithLatencyInfo& event, - MouseEventCallback event_result_callback, - blink::mojom::InputEventResultSource source, - const ui::LatencyInfo& latency, - blink::mojom::InputEventResultState state, - const base::Optional<ui::DidOverscrollParams>& overscroll, - const base::Optional<cc::TouchAction>& touch_action); - void TouchEventHandled( - const TouchEventWithLatencyInfo& touch_event, - blink::mojom::InputEventResultSource source, - const ui::LatencyInfo& latency, - blink::mojom::InputEventResultState state, - const base::Optional<ui::DidOverscrollParams>& overscroll, - const base::Optional<cc::TouchAction>& touch_action); - void GestureEventHandled( - const GestureEventWithLatencyInfo& gesture_event, - blink::mojom::InputEventResultSource source, - const ui::LatencyInfo& latency, - blink::mojom::InputEventResultState state, - const base::Optional<ui::DidOverscrollParams>& overscroll, - const base::Optional<cc::TouchAction>& touch_action); + void KeyboardEventHandled(const NativeWebKeyboardEventWithLatencyInfo& event, + KeyboardEventCallback event_result_callback, + blink::mojom::InputEventResultSource source, + const ui::LatencyInfo& latency, + blink::mojom::InputEventResultState state, + blink::mojom::DidOverscrollParamsPtr overscroll, + blink::mojom::TouchActionOptionalPtr touch_action); + void MouseEventHandled(const MouseEventWithLatencyInfo& event, + MouseEventCallback event_result_callback, + blink::mojom::InputEventResultSource source, + const ui::LatencyInfo& latency, + blink::mojom::InputEventResultState state, + blink::mojom::DidOverscrollParamsPtr overscroll, + blink::mojom::TouchActionOptionalPtr touch_action); + void TouchEventHandled(const TouchEventWithLatencyInfo& touch_event, + blink::mojom::InputEventResultSource source, + const ui::LatencyInfo& latency, + blink::mojom::InputEventResultState state, + blink::mojom::DidOverscrollParamsPtr overscroll, + blink::mojom::TouchActionOptionalPtr touch_action); + void GestureEventHandled(const GestureEventWithLatencyInfo& gesture_event, + blink::mojom::InputEventResultSource source, + const ui::LatencyInfo& latency, + blink::mojom::InputEventResultState state, + blink::mojom::DidOverscrollParamsPtr overscroll, + blink::mojom::TouchActionOptionalPtr touch_action); void MouseWheelEventHandled( const MouseWheelEventWithLatencyInfo& event, MouseWheelEventQueueClient::MouseWheelEventHandledCallback callback, blink::mojom::InputEventResultSource source, const ui::LatencyInfo& latency, blink::mojom::InputEventResultState state, - const base::Optional<ui::DidOverscrollParams>& overscroll, - const base::Optional<cc::TouchAction>& touch_action); + blink::mojom::DidOverscrollParamsPtr overscroll, + blink::mojom::TouchActionOptionalPtr touch_action); // Called when a touch timeout-affecting bit has changed, in turn toggling the // touch ack timeout feature of the |touch_event_queue_| as appropriate. Input
diff --git a/content/browser/renderer_host/input/input_router_impl_unittest.cc b/content/browser/renderer_host/input/input_router_impl_unittest.cc index 0e6718a..d70d6c3 100644 --- a/content/browser/renderer_host/input/input_router_impl_unittest.cc +++ b/content/browser/renderer_host/input/input_router_impl_unittest.cc
@@ -438,15 +438,14 @@ } void ActiveTouchSequenceCountTest( - const base::Optional<cc::TouchAction>& touch_action, + blink::mojom::TouchActionOptionalPtr touch_action, blink::mojom::InputEventResultState state) { PressTouchPoint(1, 1); - base::Optional<ui::DidOverscrollParams> overscroll; input_router_->SendTouchEvent(TouchEventWithLatencyInfo(touch_event_)); input_router_->TouchEventHandled( TouchEventWithLatencyInfo(touch_event_), blink::mojom::InputEventResultSource::kMainThread, ui::LatencyInfo(), - state, overscroll, touch_action); + state, nullptr, std::move(touch_action)); EXPECT_EQ(input_router_->touch_action_filter_.num_of_active_touches_, 1); ReleaseTouchPoint(0); input_router_->OnTouchEventAck( @@ -458,15 +457,13 @@ void StopTimeoutMonitorTest() { ResetTouchAction(); PressTouchPoint(1, 1); - base::Optional<ui::DidOverscrollParams> overscroll; - base::Optional<cc::TouchAction> touch_action = cc::TouchAction::kPan; input_router_->SendTouchEvent(TouchEventWithLatencyInfo(touch_event_)); EXPECT_TRUE(input_router_->touch_event_queue_.IsTimeoutRunningForTesting()); input_router_->TouchEventHandled( TouchEventWithLatencyInfo(touch_event_), blink::mojom::InputEventResultSource::kCompositorThread, ui::LatencyInfo(), blink::mojom::InputEventResultState::kNotConsumed, - overscroll, touch_action); + nullptr, blink::mojom::TouchActionOptional::New(cc::TouchAction::kPan)); EXPECT_TRUE(input_router_->touch_event_queue_.IsTimeoutRunningForTesting()); input_router_->SetTouchActionFromMain(cc::TouchAction::kPan); EXPECT_FALSE( @@ -674,30 +671,28 @@ // Test that the active touch sequence count increment when the touch start is // not ACKed from the main thread. TEST_F(InputRouterImplTest, ActiveTouchSequenceCountWithoutTouchAction) { - base::Optional<cc::TouchAction> touch_action; ActiveTouchSequenceCountTest( - touch_action, blink::mojom::InputEventResultState::kSetNonBlocking); + nullptr, blink::mojom::InputEventResultState::kSetNonBlocking); } TEST_F(InputRouterImplTest, ActiveTouchSequenceCountWithoutTouchActionNoConsumer) { - base::Optional<cc::TouchAction> touch_action; ActiveTouchSequenceCountTest( - touch_action, blink::mojom::InputEventResultState::kNoConsumerExists); + nullptr, blink::mojom::InputEventResultState::kNoConsumerExists); } // Test that the active touch sequence count increment when the touch start is // ACKed from the main thread. TEST_F(InputRouterImplTest, ActiveTouchSequenceCountWithTouchAction) { - base::Optional<cc::TouchAction> touch_action(cc::TouchAction::kPanY); ActiveTouchSequenceCountTest( - touch_action, blink::mojom::InputEventResultState::kSetNonBlocking); + blink::mojom::TouchActionOptional::New(cc::TouchAction::kPanY), + blink::mojom::InputEventResultState::kSetNonBlocking); } TEST_F(InputRouterImplTest, ActiveTouchSequenceCountWithTouchActionNoConsumer) { - base::Optional<cc::TouchAction> touch_action(cc::TouchAction::kPanY); ActiveTouchSequenceCountTest( - touch_action, blink::mojom::InputEventResultState::kNoConsumerExists); + blink::mojom::TouchActionOptional::New(cc::TouchAction::kPanY), + blink::mojom::InputEventResultState::kNoConsumerExists); } TEST_F(InputRouterImplTest, TouchActionAutoWithAckStateConsumed) { @@ -1346,8 +1341,8 @@ CancelTouchTimeout(); dispatched_messages[0]->ToEvent()->CallCallback( blink::mojom::InputEventResultSource::kMainThread, ui::LatencyInfo(), - blink::mojom::InputEventResultState::kConsumed, base::nullopt, - cc::TouchAction::kNone); + blink::mojom::InputEventResultState::kConsumed, nullptr, + blink::mojom::TouchActionOptional::New(cc::TouchAction::kNone)); EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount()); EXPECT_FALSE(TouchEventTimeoutEnabled()); @@ -1431,8 +1426,8 @@ touch_press_event1[0]->ToEvent()->CallCallback( blink::mojom::InputEventResultSource::kMainThread, ui::LatencyInfo(), - blink::mojom::InputEventResultState::kConsumed, base::nullopt, - cc::TouchAction::kNone); + blink::mojom::InputEventResultState::kConsumed, nullptr, + blink::mojom::TouchActionOptional::New(cc::TouchAction::kNone)); touch_move_event1[0]->ToEvent()->CallCallback( blink::mojom::InputEventResultState::kConsumed); @@ -1457,7 +1452,7 @@ touch_press_event2[0]->ToEvent()->CallCallback( blink::mojom::InputEventResultSource::kCompositorThread, ui::LatencyInfo(), blink::mojom::InputEventResultState::kConsumed, - base::nullopt, cc::TouchAction::kAuto); + nullptr, blink::mojom::TouchActionOptional::New(cc::TouchAction::kAuto)); touch_press_event2[0]->ToEvent()->CallCallback( blink::mojom::InputEventResultState::kConsumed); touch_move_event2[0]->ToEvent()->CallCallback( @@ -1495,8 +1490,8 @@ CancelTouchTimeout(); touch_press_event1[0]->ToEvent()->CallCallback( blink::mojom::InputEventResultSource::kMainThread, ui::LatencyInfo(), - blink::mojom::InputEventResultState::kConsumed, base::nullopt, - cc::TouchAction::kNone); + blink::mojom::InputEventResultState::kConsumed, nullptr, + blink::mojom::TouchActionOptional::New(cc::TouchAction::kNone)); touch_move_event1[0]->ToEvent()->CallCallback( blink::mojom::InputEventResultState::kConsumed); @@ -1571,8 +1566,8 @@ // Ensure we have touch-action:none, suppressing scroll events. dispatched_messages[0]->ToEvent()->CallCallback( blink::mojom::InputEventResultSource::kMainThread, ui::LatencyInfo(), - blink::mojom::InputEventResultState::kConsumed, base::nullopt, - cc::TouchAction::kNone); + blink::mojom::InputEventResultState::kConsumed, nullptr, + blink::mojom::TouchActionOptional::New(cc::TouchAction::kNone)); EXPECT_EQ(0U, GetAndResetDispatchedMessages().size()); dispatched_messages[1]->ToEvent()->CallCallback( blink::mojom::InputEventResultState::kNotConsumed); @@ -1659,8 +1654,8 @@ ASSERT_TRUE(dispatched_messages[0]->ToEvent()); dispatched_messages[0]->ToEvent()->CallCallback( blink::mojom::InputEventResultSource::kMainThread, ui::LatencyInfo(), - blink::mojom::InputEventResultState::kConsumed, base::nullopt, - cc::TouchAction::kNone); + blink::mojom::InputEventResultState::kConsumed, nullptr, + blink::mojom::TouchActionOptional::New(cc::TouchAction::kNone)); ReleaseTouchPoint(0); SendTouchEvent(); @@ -2001,12 +1996,12 @@ // Test proper routing of overscroll notifications received either from // event acks or from |DidOverscroll| IPC messages. TEST_F(InputRouterImplTest, OverscrollDispatch) { - DidOverscrollParams overscroll; + blink::mojom::DidOverscrollParams overscroll; overscroll.accumulated_overscroll = gfx::Vector2dF(-14, 14); overscroll.latest_overscroll_delta = gfx::Vector2dF(-7, 0); overscroll.current_fling_velocity = gfx::Vector2dF(-1, 0); - input_router_->DidOverscroll(overscroll); + input_router_->DidOverscroll(overscroll.Clone()); DidOverscrollParams client_overscroll = client_->GetAndResetOverscroll(); EXPECT_EQ(overscroll.accumulated_overscroll, client_overscroll.accumulated_overscroll); @@ -2018,7 +2013,7 @@ // controller. EXPECT_EQ(gfx::Vector2dF(), client_overscroll.current_fling_velocity); - DidOverscrollParams wheel_overscroll; + blink::mojom::DidOverscrollParams wheel_overscroll; wheel_overscroll.accumulated_overscroll = gfx::Vector2dF(7, -7); wheel_overscroll.latest_overscroll_delta = gfx::Vector2dF(3, 0); wheel_overscroll.current_fling_velocity = gfx::Vector2dF(1, 0); @@ -2031,7 +2026,7 @@ dispatched_messages[0]->ToEvent()->CallCallback( blink::mojom::InputEventResultSource::kCompositorThread, ui::LatencyInfo(), blink::mojom::InputEventResultState::kNotConsumed, - DidOverscrollParams(wheel_overscroll), base::nullopt); + wheel_overscroll.Clone(), nullptr); client_overscroll = client_->GetAndResetOverscroll(); EXPECT_EQ(wheel_overscroll.accumulated_overscroll, @@ -2096,7 +2091,7 @@ dispatched_messages[0]->ToEvent()->CallCallback( blink::mojom::InputEventResultSource::kCompositorThread, ui::LatencyInfo(), blink::mojom::InputEventResultState::kConsumed, - base::nullopt, expected_touch_action); + nullptr, blink::mojom::TouchActionOptional::New(cc::TouchAction::kPan)); ASSERT_EQ(1U, disposition_handler_->GetAndResetAckCount()); base::Optional<cc::TouchAction> allowed_touch_action = AllowedTouchAction(); cc::TouchAction white_listed_touch_action = WhiteListedTouchAction();
diff --git a/content/browser/renderer_host/input/mouse_wheel_event_queue.h b/content/browser/renderer_host/input/mouse_wheel_event_queue.h index 062949b..3e4414b3 100644 --- a/content/browser/renderer_host/input/mouse_wheel_event_queue.h +++ b/content/browser/renderer_host/input/mouse_wheel_event_queue.h
@@ -58,7 +58,19 @@ virtual bool IsAutoscrollInProgress() = 0; }; -// A queue for throttling and coalescing mouse wheel events. +// A queue for throttling and coalescing mouse wheel events. This class tracks +// wheel events sent to the renderer and receives their ACKs. If the ACK +// reports the event went unconsumed by the renderer, this class will generate +// a sequence of gesture scroll events. +// +// Within a sequence, wheel events are initially forwarded using a blocking +// dispatch. This means that further wheel events are queued and scroll event +// generation will wait (i.e. block) until the in-flight wheel event is ACKed. +// Once a wheel event goes unconsumed, and scrolling begins, dispatch of +// subsequent wheel events becomes non-blocking. This means the wheel event +// will be ACKed by the browser immediately after being dispatched. This will +// cause scroll events to follow the wheel immediately and new wheel events +// will be dispatched immediately rather than queueing. class CONTENT_EXPORT MouseWheelEventQueue { public: // The |client| must outlive the MouseWheelEventQueue.
diff --git a/content/browser/renderer_host/pepper/pepper_network_proxy_host.cc b/content/browser/renderer_host/pepper/pepper_network_proxy_host.cc index e3ec39c..37ec5a3 100644 --- a/content/browser/renderer_host/pepper/pepper_network_proxy_host.cc +++ b/content/browser/renderer_host/pepper/pepper_network_proxy_host.cc
@@ -46,9 +46,9 @@ StoragePartition* storage_partition = BrowserContext::GetStoragePartition( site_instance->GetBrowserContext(), site_instance); + // TODO(https://crbug.com/1021661): Pass in a non-empty NetworkIsolationKey. storage_partition->GetNetworkContext()->LookUpProxyForURL( - url, render_frame_host->GetNetworkIsolationKey(), - std::move(proxy_lookup_client)); + url, net::NetworkIsolationKey::Todo(), std::move(proxy_lookup_client)); return true; }
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index b831bd2..e753093 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -3271,7 +3271,6 @@ switches::kDisablePermissionsAPI, switches::kDisablePresentationAPI, switches::kDisableRGBA4444Textures, - switches::kDisableAxSerializerForTesting, switches::kDisableRTCSmoothnessAlgorithm, switches::kDisableScrollToTextFragment, switches::kDisableSharedWorkers,
diff --git a/content/browser/renderer_host/web_database_host_impl_unittest.cc b/content/browser/renderer_host/web_database_host_impl_unittest.cc index 0ef35aa..85e2788 100644 --- a/content/browser/renderer_host/web_database_host_impl_unittest.cc +++ b/content/browser/renderer_host/web_database_host_impl_unittest.cc
@@ -6,6 +6,7 @@ #include "base/bind.h" #include "base/run_loop.h" +#include "base/sequenced_task_runner.h" #include "base/strings/utf_string_conversions.h" #include "base/test/bind_test_util.h" #include "content/browser/child_process_security_policy_impl.h" @@ -47,26 +48,44 @@ base::FilePath(), /*is_incognito=*/false, /*special_storage_policy=*/nullptr, /*quota_manager_proxy=*/nullptr); - db_tracker->set_task_runner_for_testing( - base::ThreadTaskRunnerHandle::Get()); + task_runner_ = db_tracker->task_runner(); host_ = std::make_unique<WebDatabaseHostImpl>(process_id(), std::move(db_tracker)); } + void TearDown() override { + task_runner_->DeleteSoon(FROM_HERE, std::move(host_)); + RunUntilIdle(); + } + template <typename Callable> void CheckUnauthorizedOrigin(const Callable& func) { - FakeMojoMessageDispatchContext fake_dispatch_context; mojo::test::BadMessageObserver bad_message_observer; - func(); + base::RunLoop run_loop; + task_runner()->PostTask( + FROM_HERE, base::BindLambdaForTesting([&]() { + FakeMojoMessageDispatchContext fake_dispatch_context; + func(); + run_loop.Quit(); + })); + run_loop.Run(); + RunUntilIdle(); EXPECT_EQ("Unauthorized origin.", bad_message_observer.WaitForBadMessage()); } template <typename Callable> void CheckInvalidOrigin(const Callable& func) { - FakeMojoMessageDispatchContext fake_dispatch_context; mojo::test::BadMessageObserver bad_message_observer; - func(); + base::RunLoop run_loop; + task_runner()->PostTask( + FROM_HERE, base::BindLambdaForTesting([&]() { + FakeMojoMessageDispatchContext fake_dispatch_context; + func(); + run_loop.Quit(); + })); + run_loop.Run(); + RunUntilIdle(); EXPECT_EQ("Invalid origin.", bad_message_observer.WaitForBadMessage()); } @@ -78,15 +97,19 @@ render_process_host_.release(); } + void RunUntilIdle() { task_environment_.RunUntilIdle(); } + WebDatabaseHostImpl* host() { return host_.get(); } int process_id() const { return render_process_host_->GetID(); } BrowserContext* browser_context() { return &browser_context_; } + base::SequencedTaskRunner* task_runner() { return task_runner_.get(); } private: BrowserTaskEnvironment task_environment_; TestBrowserContext browser_context_; std::unique_ptr<MockRenderProcessHost> render_process_host_; std::unique_ptr<WebDatabaseHostImpl> host_; + scoped_refptr<base::SequencedTaskRunner> task_runner_; DISALLOW_COPY_AND_ASSIGN(WebDatabaseHostImplTest); }; @@ -205,11 +228,16 @@ // Verify that an error occurs with OpenFile() call before process shutdown. { - FakeMojoMessageDispatchContext fake_dispatch_context; - host()->OpenFile(bad_vfs_file_name, - /*desired_flags=*/0, success_callback); - - base::RunLoop().RunUntilIdle(); + base::RunLoop run_loop; + task_runner()->PostTask( + FROM_HERE, base::BindLambdaForTesting([&]() { + FakeMojoMessageDispatchContext fake_dispatch_context; + host()->OpenFile(bad_vfs_file_name, + /*desired_flags=*/0, success_callback); + run_loop.Quit(); + })); + run_loop.Run(); + RunUntilIdle(); EXPECT_FALSE(success_callback_was_called); EXPECT_TRUE(error_callback_message.has_value()); @@ -225,11 +253,16 @@ // Attempt the call again and verify that no callbacks were called. { - FakeMojoMessageDispatchContext fake_dispatch_context; - host()->OpenFile(bad_vfs_file_name, - /*desired_flags=*/0, success_callback); - - base::RunLoop().RunUntilIdle(); + base::RunLoop run_loop; + task_runner()->PostTask( + FROM_HERE, base::BindLambdaForTesting([&]() { + FakeMojoMessageDispatchContext fake_dispatch_context; + host()->OpenFile(bad_vfs_file_name, + /*desired_flags=*/0, success_callback); + run_loop.Quit(); + })); + run_loop.Run(); + RunUntilIdle(); // Verify none of the callbacks were called. EXPECT_FALSE(success_callback_was_called);
diff --git a/content/browser/resources/conversions/conversion_internals.html b/content/browser/resources/conversions/conversion_internals.html index 8d7e32f..4513c8b 100644 --- a/content/browser/resources/conversions/conversion_internals.html +++ b/content/browser/resources/conversions/conversion_internals.html
@@ -104,6 +104,9 @@ </tbody> </table> </div> + <div> + <button id="send-reports">Send All Reports</button> + </div> </div> </div>
diff --git a/content/browser/resources/conversions/conversion_internals.js b/content/browser/resources/conversions/conversion_internals.js index 3bd64e3..9b87dfd 100644 --- a/content/browser/resources/conversions/conversion_internals.js +++ b/content/browser/resources/conversions/conversion_internals.js
@@ -155,12 +155,30 @@ }); } +/** + * Sends all conversion reports, and updates the page once they are sent. + * Disables the button while the reports are still being sent. + */ +function sendReports() { + const button = $('send-reports'); + const previousText = $('send-reports').innerText; + + button.disabled = true; + button.innerText = 'Sending...'; + pageHandler.sendPendingReports().then(() => { + updatePageData(); + button.disabled = false; + button.innerText = previousText; + }); +} + document.addEventListener('DOMContentLoaded', function() { // Setup the mojo interface. pageHandler = mojom.ConversionInternalsHandler.getRemote(); $('refresh').addEventListener('click', updatePageData); $('clear-data').addEventListener('click', clearStorage); + $('send-reports').addEventListener('click', sendReports); // Automatically refresh every 2 minutes. setInterval(updatePageData, 2 * 60 * 1000);
diff --git a/content/browser/screen_enumeration/screen_enumeration_browsertest.cc b/content/browser/screen_enumeration/screen_enumeration_browsertest.cc index 69c68ca3..5d0eb01 100644 --- a/content/browser/screen_enumeration/screen_enumeration_browsertest.cc +++ b/content/browser/screen_enumeration/screen_enumeration_browsertest.cc
@@ -83,7 +83,7 @@ } // namespace -// Tests the ScreenEnumeration feature. +// Tests screen enumeration aspects of the WindowPlacement feature. class ScreenEnumerationTest : public ContentBrowserTest { public: ScreenEnumerationTest() = default; @@ -95,7 +95,7 @@ // ContentBrowserTest: void SetUpCommandLine(base::CommandLine* command_line) override { base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( - switches::kEnableBlinkFeatures, "ScreenEnumeration"); + switches::kEnableBlinkFeatures, "WindowPlacement"); ContentBrowserTest::SetUpCommandLine(command_line); } }; @@ -107,7 +107,7 @@ EXPECT_EQ(GetExpectedScreens(), base::Value::AsListValue(result.value)); } -// Tests the ScreenEnumeration feature with a fake Screen object. +// Tests screen enumeration functionality with a fake Screen object. class FakeScreenEnumerationTest : public ScreenEnumerationTest { public: FakeScreenEnumerationTest() = default;
diff --git a/content/browser/service_sandbox_type.h b/content/browser/service_sandbox_type.h index d9417287..218e04e 100644 --- a/content/browser/service_sandbox_type.h +++ b/content/browser/service_sandbox_type.h
@@ -25,4 +25,18 @@ return content::SandboxType::kAudio; } +// device::mojom::XRDeviceService +#if defined(OS_WIN) +namespace device { +namespace mojom { +class XRDeviceService; +} +} // namespace device +template <> +inline content::SandboxType +content::GetServiceSandboxType<device::mojom::XRDeviceService>() { + return content::SandboxType::kXrCompositing; +} +#endif // OS_WIN + #endif // CONTENT_BROWSER_SERVICE_SANDBOX_TYPE_H_
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 5eef929..708362b 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -4475,13 +4475,6 @@ NotifyNavigationStateChanged(changed_flags); } -void WebContentsImpl::DidStartNavigationToPendingEntry(const GURL& url, - ReloadType reload_type) { - // Notify observers about navigation. - for (auto& observer : observers_) - observer.DidStartNavigationToPendingEntry(url, reload_type); -} - bool WebContentsImpl::ShouldTransferNavigation(bool is_main_frame_navigation) { if (!delegate_) return true;
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index 83c46191..e86be96 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -834,8 +834,6 @@ void SetMainFrameMimeType(const std::string& mime_type) override; bool CanOverscrollContent() const override; void NotifyChangedNavigationState(InvalidateTypes changed_flags) override; - void DidStartNavigationToPendingEntry(const GURL& url, - ReloadType reload_type) override; bool ShouldTransferNavigation(bool is_main_frame_navigation) override; void DidStartLoading(FrameTreeNode* frame_tree_node, bool to_different_document) override;
diff --git a/content/browser/web_contents/web_contents_view_aura_unittest.cc b/content/browser/web_contents/web_contents_view_aura_unittest.cc index 10d5353..ca77acc 100644 --- a/content/browser/web_contents/web_contents_view_aura_unittest.cc +++ b/content/browser/web_contents/web_contents_view_aura_unittest.cc
@@ -251,7 +251,7 @@ ASSERT_NE(nullptr, view->current_drop_data_); #if defined(USE_X11) - // By design, OSExchangeDataProviderAuraX11::GetString returns an empty string + // By design, OSExchangeDataProviderX11::GetString returns an empty string // if file data is also present. EXPECT_TRUE(view->current_drop_data_->text.string().empty()); #else @@ -281,7 +281,7 @@ CheckDropData(view); #if defined(USE_X11) - // By design, OSExchangeDataProviderAuraX11::GetString returns an empty string + // By design, OSExchangeDataProviderX11::GetString returns an empty string // if file data is also present. EXPECT_TRUE(drop_complete_data_->drop_data.text.string().empty()); #else @@ -340,7 +340,7 @@ ASSERT_NE(nullptr, view->current_drop_data_); #if defined(USE_X11) - // By design, OSExchangeDataProviderAuraX11::GetString returns an empty string + // By design, OSExchangeDataProviderX11::GetString returns an empty string // if file data is also present. EXPECT_TRUE(view->current_drop_data_->text.string().empty()); #else @@ -363,7 +363,7 @@ CheckDropData(view); #if defined(USE_X11) - // By design, OSExchangeDataProviderAuraX11::GetString returns an empty string + // By design, OSExchangeDataProviderX11::GetString returns an empty string // if file data is also present. EXPECT_TRUE(drop_complete_data_->drop_data.text.string().empty()); #else
diff --git a/content/browser/webauth/authenticator_impl_unittest.cc b/content/browser/webauth/authenticator_impl_unittest.cc index aac4d56..97d8340 100644 --- a/content/browser/webauth/authenticator_impl_unittest.cc +++ b/content/browser/webauth/authenticator_impl_unittest.cc
@@ -52,6 +52,7 @@ #include "device/fido/fido_test_data.h" #include "device/fido/hid/fake_hid_impl_for_testing.h" #include "device/fido/mock_fido_device.h" +#include "device/fido/public_key.h" #include "device/fido/test_callback_receiver.h" #include "device/fido/virtual_fido_device_factory.h" #include "mojo/public/cpp/bindings/pending_receiver.h" @@ -915,6 +916,39 @@ EXPECT_EQ(AuthenticatorStatus::NOT_ALLOWED_ERROR, callback_receiver.status()); } +TEST_F(AuthenticatorImplTest, TestMakeCredentialRSA) { + virtual_device_factory_->SetSupportedProtocol( + device::ProtocolVersion::kCtap2); + SimulateNavigation(GURL(kTestOrigin1)); + + mojo::Remote<blink::mojom::Authenticator> authenticator = + ConnectToAuthenticator(); + PublicKeyCredentialCreationOptionsPtr options = + GetTestPublicKeyCredentialCreationOptions(); + options->public_key_parameters = GetTestPublicKeyCredentialParameters( + static_cast<int32_t>(device::CoseAlgorithmIdentifier::kCoseRs256)); + TestMakeCredentialCallback callback; + authenticator->MakeCredential(std::move(options), callback.callback()); + base::RunLoop().RunUntilIdle(); + callback.WaitForCallback(); + + ASSERT_EQ(callback.status(), AuthenticatorStatus::SUCCESS); + + base::Optional<Value> attestation_value = + Reader::Read(callback.value()->attestation_object); + ASSERT_TRUE(attestation_value); + ASSERT_TRUE(attestation_value->is_map()); + const auto& attestation = attestation_value->GetMap(); + + const auto auth_data_it = attestation.find(Value("authData")); + ASSERT_TRUE(auth_data_it != attestation.end()); + ASSERT_TRUE(auth_data_it->second.is_bytestring()); + auto auth_data = device::AuthenticatorData::DecodeAuthenticatorData( + auth_data_it->second.GetBytestring()); + EXPECT_EQ(static_cast<int32_t>(device::CoseAlgorithmIdentifier::kCoseRs256), + auth_data->attested_data()->public_key()->algorithm()); +} + // Verify behavior for various combinations of origins and RP IDs. TEST_F(AuthenticatorImplTest, GetAssertionOriginAndRpIds) { // These instances should return security errors (for circumstances
diff --git a/content/browser/webui/shared_resources_data_source.cc b/content/browser/webui/shared_resources_data_source.cc index 52edf24..91ce33a 100644 --- a/content/browser/webui/shared_resources_data_source.cc +++ b/content/browser/webui/shared_resources_data_source.cc
@@ -81,14 +81,12 @@ }; #if defined(OS_CHROMEOS) - // Add lottie library for Chrome OS. - aliases["../../../third_party/lottie/"] = "lottie/"; - if (UsingMultiplePolymerVersions()) return aliases; #endif // defined(OS_CHROMEOS) #if !defined(OS_ANDROID) + aliases["../../../third_party/lottie/"] = "lottie/"; aliases["../../../third_party/polymer/v1_0/components-chromium/polymer2/"] = "polymer/v1_0/polymer/"; #endif // !defined(OS_ANDROID) @@ -401,6 +399,10 @@ return origin; } +std::string SharedResourcesDataSource::GetContentSecurityPolicyWorkerSrc() { + return "worker-src blob: 'self';"; +} + #if defined(OS_CHROMEOS) void SharedResourcesDataSource::DisablePolymer2ForHost( const std::string& host) { @@ -408,10 +410,6 @@ disabled_polymer2_host_ = host; } -std::string SharedResourcesDataSource::GetContentSecurityPolicyWorkerSrc() { - return "worker-src blob: 'self';"; -} - // Returns true if the WebContents making the request has disabled Polymer 2. bool SharedResourcesDataSource::IsPolymer2DisabledForPage( const WebContents::Getter& wc_getter) {
diff --git a/content/browser/webui/shared_resources_data_source.h b/content/browser/webui/shared_resources_data_source.h index 910918e..4500bb4 100644 --- a/content/browser/webui/shared_resources_data_source.h +++ b/content/browser/webui/shared_resources_data_source.h
@@ -29,9 +29,9 @@ bool ShouldServeMimeTypeAsContentTypeHeader() override; std::string GetAccessControlAllowOriginForOrigin( const std::string& origin) override; + std::string GetContentSecurityPolicyWorkerSrc() override; #if defined(OS_CHROMEOS) void DisablePolymer2ForHost(const std::string& host) override; - std::string GetContentSecurityPolicyWorkerSrc() override; #endif // defined (OS_CHROMEOS) private:
diff --git a/content/browser/xr/service/xr_device_service.cc b/content/browser/xr/service/xr_device_service.cc index 5c70413..0b8b1c5 100644 --- a/content/browser/xr/service/xr_device_service.cc +++ b/content/browser/xr/service/xr_device_service.cc
@@ -6,6 +6,7 @@ #include "base/no_destructor.h" #include "build/build_config.h" +#include "content/browser/service_sandbox_type.h" #include "content/public/browser/service_process_host.h" namespace content { @@ -26,9 +27,6 @@ content::ServiceProcessHost::Launch( remote->BindNewPipeAndPassReceiver(), content::ServiceProcessHost::Options() -#if defined(OS_WIN) - .WithSandboxType(service_manager::SandboxType::kXrCompositing) -#endif .WithDisplayName("Isolated XR Device Service") .Pass());
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index a3c69a3c..8e5a783fe 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -373,7 +373,8 @@ kEnableOnly}, {"StorageAccessAPI", blink::features::kStorageAccessAPI, kEnableOnly}, {"TrustedDOMTypes", features::kTrustedDOMTypes, kEnableOnly}, - {"UserAgentClientHint", features::kUserAgentClientHint, kEnableOnly}, + {"UserAgentClientHint", features::kUserAgentClientHint, + kUseFeatureState}, }; for (const auto& mapping : runtimeFeatureNameToChromiumFeatureMapping) {
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index 3c7a15da..ddddfa0 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -148,8 +148,6 @@ "input/synthetic_tap_gesture_params.h", "input/synthetic_web_input_event_builders.cc", "input/synthetic_web_input_event_builders.h", - "input/touch_action_optional_mojom_traits.cc", - "input/touch_action_optional_mojom_traits.h", "input/touch_event_stream_validator.cc", "input/touch_event_stream_validator.h", "input/web_mouse_wheel_event_traits.cc", @@ -576,10 +574,6 @@ cpp = "::content::ContentSecurityPolicy" }, { - mojom = "content.mojom.DidOverscrollParams" - cpp = "::ui::DidOverscrollParams" - }, - { mojom = "content.mojom.Event" cpp = "::std::unique_ptr<::content::InputEvent>" move_only = true @@ -621,10 +615,6 @@ cpp = "::ui::NativeTheme::SystemThemeColor" }, { - mojom = "content.mojom.TouchActionOptional" - cpp = "::cc::TouchAction" - }, - { mojom = "content.mojom.VisualProperties" cpp = "::content::VisualProperties" }, @@ -664,7 +654,6 @@ traits_private_headers = [ "//content/common/frame_messages.h", "//content/common/input/input_event_mojom_traits.h", - "//content/common/input/touch_action_optional_mojom_traits.h", "//content/common/input_messages.h", "//content/common/view_messages.h", "//content/common/widget_messages.h",
diff --git a/content/common/frame.mojom b/content/common/frame.mojom index 7b03ce27..5dfb747 100644 --- a/content/common/frame.mojom +++ b/content/common/frame.mojom
@@ -213,21 +213,6 @@ bool wants_result, int32 world_id) => (mojo_base.mojom.Value result); - // Posts a message from a frame in another process to the current renderer. - // |source_routing_id| is the routing ID of the source frame in the source - // process when sent to the browser. The browser replaces it with the routing - // ID of the equivalent frame proxy in the destination process. - // |source_origin| is the origin of the source frame when the message was - // sent, and |target_origin| specifies what the origin of the target frame - // must be for the message to be dispatched. An empty string allows the - // message to be dispatched to any origin. - // |message| is the encoded data, and any extra properties such as - // transferred ports or blobs. - PostMessageEvent(int32 source_routing_id, - mojo_base.mojom.String16 source_origin, - mojo_base.mojom.String16 target_origin, - blink.mojom.TransferableMessage message); - // Forwards a message from a portal's host to the main frame in the portal's // guest contents. ForwardMessageFromHost(blink.mojom.TransferableMessage message,
diff --git a/content/common/input/input_handler.mojom b/content/common/input/input_handler.mojom index 3924cef..6ae8d0bf 100644 --- a/content/common/input/input_handler.mojom +++ b/content/common/input/input_handler.mojom
@@ -167,10 +167,6 @@ TouchData? touch_data; }; -struct TouchActionOptional { - cc.mojom.TouchAction touch_action; -}; - // Interface exposed by the browser to the renderer. interface WidgetInputHandlerHost { // When the renderer's main thread computes the touch action, send this to the @@ -179,7 +175,7 @@ // Sent by the compositor when input scroll events are dropped due to bounds // restrictions on the root scroll offset. - DidOverscroll(DidOverscrollParams params); + DidOverscroll(blink.mojom.DidOverscrollParams params); // Sent by the compositor when a GSB has started scrolling the viewport. DidStartScrollingViewport(); @@ -285,8 +281,8 @@ => (blink.mojom.InputEventResultSource source, ui.mojom.LatencyInfo updated_latency, blink.mojom.InputEventResultState state, - DidOverscrollParams? overscroll, - TouchActionOptional? touch_action); + blink.mojom.DidOverscrollParams? overscroll, + blink.mojom.TouchActionOptional? touch_action); // Sends a non-blocking input event to the render widget. The behaviour // of this API is the same as DispatchEvent just that there is no callback
diff --git a/content/common/input/touch_action_optional_mojom_traits.cc b/content/common/input/touch_action_optional_mojom_traits.cc deleted file mode 100644 index a6f8a6b..0000000 --- a/content/common/input/touch_action_optional_mojom_traits.cc +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/common/input/touch_action_optional_mojom_traits.h" - -#include "content/public/common/common_param_traits_macros.h" - -namespace mojo { -bool StructTraits< - content::mojom::TouchActionOptionalDataView, - cc::TouchAction>::Read(content::mojom::TouchActionOptionalDataView r, - cc::TouchAction* out) { - return r.ReadTouchAction(out); -} -} // namespace mojo
diff --git a/content/common/input/touch_action_optional_mojom_traits.h b/content/common/input/touch_action_optional_mojom_traits.h deleted file mode 100644 index c715a23..0000000 --- a/content/common/input/touch_action_optional_mojom_traits.h +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_COMMON_INPUT_TOUCH_ACTION_OPTIONAL_MOJOM_TRAITS_H_ -#define CONTENT_COMMON_INPUT_TOUCH_ACTION_OPTIONAL_MOJOM_TRAITS_H_ - -#include "base/optional.h" -#include "content/common/input/input_handler.mojom.h" - -namespace mojo { - -template <> -struct StructTraits<content::mojom::TouchActionOptionalDataView, - cc::TouchAction> { - static cc::TouchAction touch_action(cc::TouchAction action) { return action; } - static bool Read(content::mojom::TouchActionOptionalDataView r, - cc::TouchAction* out); -}; - -} // namespace mojo - -#endif // CONTENT_COMMON_INPUT_TOUCH_ACTION_OPTIONAL_MOJOM_TRAITS_H_
diff --git a/content/common/input_messages.h b/content/common/input_messages.h index a17d699..7f88de6 100644 --- a/content/common/input_messages.h +++ b/content/common/input_messages.h
@@ -54,13 +54,6 @@ content::SyntheticPointerActionParams::Button::BUTTON_MAX) IPC_ENUM_TRAITS_MAX_VALUE(content::InputEventDispatchType, content::InputEventDispatchType::DISPATCH_TYPE_MAX) -IPC_STRUCT_TRAITS_BEGIN(ui::DidOverscrollParams) - IPC_STRUCT_TRAITS_MEMBER(accumulated_overscroll) - IPC_STRUCT_TRAITS_MEMBER(latest_overscroll_delta) - IPC_STRUCT_TRAITS_MEMBER(current_fling_velocity) - IPC_STRUCT_TRAITS_MEMBER(causal_event_viewport_point) - IPC_STRUCT_TRAITS_MEMBER(overscroll_behavior) -IPC_STRUCT_TRAITS_END() IPC_STRUCT_TRAITS_BEGIN(content::SyntheticGestureParams) IPC_STRUCT_TRAITS_MEMBER(gesture_source_type)
diff --git a/content/common/native_types.mojom b/content/common/native_types.mojom index e40337e..9882968 100644 --- a/content/common/native_types.mojom +++ b/content/common/native_types.mojom
@@ -41,9 +41,6 @@ struct WebCursor; [Native] -struct DidOverscrollParams; - -[Native] struct SyntheticSmoothDrag; [Native]
diff --git a/content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionClient.java b/content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionClient.java index 9af944b..6f95c03 100644 --- a/content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionClient.java +++ b/content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionClient.java
@@ -66,16 +66,15 @@ return null; } - return new SmartSelectionClient(callback, webContents, windowAndroid); + return new SmartSelectionClient(callback, webContents); } - private SmartSelectionClient( - ResultCallback callback, WebContents webContents, WindowAndroid windowAndroid) { + private SmartSelectionClient(ResultCallback callback, WebContents webContents) { assert Build.VERSION.SDK_INT >= Build.VERSION_CODES.O; - mProvider = new SmartSelectionProvider(callback, windowAndroid); + mProvider = new SmartSelectionProvider(callback, webContents); mCallback = callback; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - mSmartSelectionMetricsLogger = SmartSelectionMetricsLogger.create(windowAndroid); + mSmartSelectionMetricsLogger = SmartSelectionMetricsLogger.create(webContents); } mNativeSmartSelectionClient = SmartSelectionClientJni.get().init(SmartSelectionClient.this, webContents);
diff --git a/content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionMetricsLogger.java b/content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionMetricsLogger.java index f8ce430..0dadb3c 100644 --- a/content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionMetricsLogger.java +++ b/content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionMetricsLogger.java
@@ -14,8 +14,11 @@ import org.chromium.base.Log; import org.chromium.base.annotations.VerifiesOnP; +import org.chromium.content.browser.WindowEventObserver; +import org.chromium.content.browser.WindowEventObserverManager; import org.chromium.content_public.browser.SelectionClient; import org.chromium.content_public.browser.SelectionMetricsLogger; +import org.chromium.content_public.browser.WebContents; import org.chromium.ui.base.WindowAndroid; /** @@ -40,15 +43,24 @@ private SelectionIndicesConverter mConverter; - public static SmartSelectionMetricsLogger create(WindowAndroid windowAndroid) { - if (windowAndroid.getContext().get() == null) { + public static SmartSelectionMetricsLogger create(WebContents webContents) { + if (webContents.getTopLevelNativeWindow().getContext().get() == null) { return null; } - return new SmartSelectionMetricsLogger(windowAndroid); + return new SmartSelectionMetricsLogger(webContents); } - private SmartSelectionMetricsLogger(WindowAndroid windowAndroid) { - mWindowAndroid = windowAndroid; + private SmartSelectionMetricsLogger(WebContents webContents) { + mWindowAndroid = webContents.getTopLevelNativeWindow(); + WindowEventObserverManager manager = WindowEventObserverManager.from(webContents); + if (manager != null) { + manager.addObserver(new WindowEventObserver() { + @Override + public void onWindowAndroidChanged(WindowAndroid newWindowAndroid) { + mWindowAndroid = newWindowAndroid; + } + }); + } } public void logSelectionStarted(String selectionText, int startOffset, boolean editable) {
diff --git a/content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionProvider.java b/content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionProvider.java index 2431f37..5a421f8 100644 --- a/content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionProvider.java +++ b/content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionProvider.java
@@ -18,7 +18,10 @@ import androidx.annotation.IntDef; import org.chromium.base.task.AsyncTask; +import org.chromium.content.browser.WindowEventObserver; +import org.chromium.content.browser.WindowEventObserverManager; import org.chromium.content_public.browser.SelectionClient; +import org.chromium.content_public.browser.WebContents; import org.chromium.ui.base.WindowAndroid; import java.lang.annotation.Retention; @@ -46,9 +49,19 @@ private Runnable mFailureResponseRunnable; public SmartSelectionProvider( - SelectionClient.ResultCallback callback, WindowAndroid windowAndroid) { + SelectionClient.ResultCallback callback, WebContents webContents) { mResultCallback = callback; - mWindowAndroid = windowAndroid; + mWindowAndroid = webContents.getTopLevelNativeWindow(); + WindowEventObserverManager manager = WindowEventObserverManager.from(webContents); + if (manager != null) { + manager.addObserver(new WindowEventObserver() { + @Override + public void onWindowAndroidChanged(WindowAndroid newWindowAndroid) { + mWindowAndroid = newWindowAndroid; + } + }); + } + mHandler = new Handler(); mFailureResponseRunnable = new Runnable() { @Override
diff --git a/content/public/android/junit/src/org/chromium/content/browser/selection/SmartSelectionMetricsLoggerTest.java b/content/public/android/junit/src/org/chromium/content/browser/selection/SmartSelectionMetricsLoggerTest.java index a13ee80b..6466f227 100644 --- a/content/public/android/junit/src/org/chromium/content/browser/selection/SmartSelectionMetricsLoggerTest.java +++ b/content/public/android/junit/src/org/chromium/content/browser/selection/SmartSelectionMetricsLoggerTest.java
@@ -10,7 +10,9 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.when; +import android.content.Context; import android.view.textclassifier.SelectionEvent; import android.view.textclassifier.TextClassificationManager; import android.view.textclassifier.TextClassifier; @@ -30,8 +32,10 @@ import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.Feature; +import org.chromium.content.browser.webcontents.WebContentsImpl; import org.chromium.ui.base.WindowAndroid; +import java.lang.ref.WeakReference; import java.text.BreakIterator; /** @@ -40,6 +44,9 @@ @RunWith(BaseRobolectricTestRunner.class) @Config(manifest = Config.NONE) public class SmartSelectionMetricsLoggerTest { + private WebContentsImpl mWebContents; + private WindowAndroid mWindowAndroid; + @Mock private TextClassifier mTextClassifier; @@ -61,6 +68,13 @@ MockitoAnnotations.initMocks(this); ShadowLog.stream = System.out; + mWebContents = Mockito.mock(WebContentsImpl.class); + mWindowAndroid = Mockito.mock(WindowAndroid.class); + when(mWebContents.getTopLevelNativeWindow()).thenReturn(mWindowAndroid); + when(mWindowAndroid.getContext()) + .thenReturn( + new WeakReference<Context>(ApplicationProvider.getApplicationContext())); + TextClassificationManager tcm = ApplicationProvider.getApplicationContext().getSystemService( TextClassificationManager.class); @@ -304,8 +318,7 @@ @Test @Feature({"TextInput", "SmartSelection"}) public void testNormalLoggingFlow() { - SmartSelectionMetricsLogger logger = SmartSelectionMetricsLogger.create( - new WindowAndroid(ApplicationProvider.getApplicationContext())); + SmartSelectionMetricsLogger logger = SmartSelectionMetricsLogger.create(mWebContents); ArgumentCaptor<SelectionEvent> captor = ArgumentCaptor.forClass(SelectionEvent.class); InOrder inOrder = inOrder(mTextClassifier); @@ -374,8 +387,7 @@ @Test @Feature({"TextInput", "SmartSelection"}) public void testMultipleDrag() { - SmartSelectionMetricsLogger logger = SmartSelectionMetricsLogger.create( - new WindowAndroid(ApplicationProvider.getApplicationContext())); + SmartSelectionMetricsLogger logger = SmartSelectionMetricsLogger.create(mWebContents); ArgumentCaptor<SelectionEvent> captor = ArgumentCaptor.forClass(SelectionEvent.class); InOrder inOrder = inOrder(mTextClassifier); @@ -424,8 +436,7 @@ @Test @Feature({"TextInput", "SmartSelection"}) public void testTextShift() { - SmartSelectionMetricsLogger logger = SmartSelectionMetricsLogger.create( - new WindowAndroid(ApplicationProvider.getApplicationContext())); + SmartSelectionMetricsLogger logger = SmartSelectionMetricsLogger.create(mWebContents); ArgumentCaptor<SelectionEvent> captor = ArgumentCaptor.forClass(SelectionEvent.class); InOrder inOrder = inOrder(mTextClassifier); @@ -468,8 +479,7 @@ @Test @Feature({"TextInput", "SmartSelection"}) public void testSelectionChanged() { - SmartSelectionMetricsLogger logger = SmartSelectionMetricsLogger.create( - new WindowAndroid(ApplicationProvider.getApplicationContext())); + SmartSelectionMetricsLogger logger = SmartSelectionMetricsLogger.create(mWebContents); ArgumentCaptor<SelectionEvent> captor = ArgumentCaptor.forClass(SelectionEvent.class); InOrder inOrder = inOrder(mTextClassifier);
diff --git a/content/public/browser/web_contents_observer.h b/content/public/browser/web_contents_observer.h index c4cc607..f80da27 100644 --- a/content/public/browser/web_contents_observer.h +++ b/content/public/browser/web_contents_observer.h
@@ -211,19 +211,6 @@ // so do not keep a reference to it afterward. virtual void DidFinishNavigation(NavigationHandle* navigation_handle) {} - // Navigation (obsolete and deprecated) -------------------------------------- - - // This method is invoked after the browser process starts a navigation to a - // pending NavigationEntry. It is not called for renderer-initiated - // navigations unless they are sent to the browser process via OpenURL. It may - // be called multiple times for a given navigation, such as a typed URL - // followed by a cross-process client or server redirect. - // - // SOON TO BE DEPRECATED. Use DidStartNavigation instead. - // TODO(clamy): Remove this function. - virtual void DidStartNavigationToPendingEntry(const GURL& url, - ReloadType reload_type) {} - // Document load events ------------------------------------------------------ // These three methods correspond to the points in time when a document starts
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index cc45980..4b259988 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -142,10 +142,10 @@ const base::Feature kConversionMeasurement{"ConversionMeasurement", base::FEATURE_DISABLED_BY_DEFAULT}; -// Show messages in the DevTools console about upcoming deprecations -// that would affect sent/received cookies. +// Show messages in DevTools about upcoming deprecations that would affect +// sent/received cookies. const base::Feature kCookieDeprecationMessages{ - "CookieDeprecationMessages", base::FEATURE_ENABLED_BY_DEFAULT}; + "CookieDeprecationMessages", base::FEATURE_DISABLED_BY_DEFAULT}; // Enables Blink cooperative scheduling. const base::Feature kCooperativeScheduling{"CooperativeScheduling",
diff --git a/content/public/common/content_switch_dependent_feature_overrides.cc b/content/public/common/content_switch_dependent_feature_overrides.cc index 27df27b..c3f1d16 100644 --- a/content/public/common/content_switch_dependent_feature_overrides.cc +++ b/content/public/common/content_switch_dependent_feature_overrides.cc
@@ -64,6 +64,9 @@ // Overrides for --enable-experimental-cookie-features. {switches::kEnableExperimentalCookieFeatures, + std::cref(features::kCookieDeprecationMessages), + base::FeatureList::OVERRIDE_ENABLE_FEATURE}, + {switches::kEnableExperimentalCookieFeatures, std::cref(net::features::kCookiesWithoutSameSiteMustBeSecure), base::FeatureList::OVERRIDE_ENABLE_FEATURE}, {switches::kEnableExperimentalCookieFeatures,
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index a2692533..8e9eb36 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc
@@ -103,10 +103,6 @@ const char kDisableAcceleratedVideoEncode[] = "disable-accelerated-video-encode"; -// Turns off the accessibility in the renderer. -const char kDisableAxSerializerForTesting[] = - "disable-ax-serializer-for-testing"; - // Disable limits on the number of backing stores. Can prevent blinking for // users with many windows/tabs and lots of memory. const char kDisableBackingStoreLimit[] = "disable-backing-store-limit";
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index 62f71e50..81c110d 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h
@@ -40,7 +40,6 @@ CONTENT_EXPORT extern const char kDisableYUVImageDecoding[]; CONTENT_EXPORT extern const char kDisableAcceleratedVideoDecode[]; CONTENT_EXPORT extern const char kDisableAcceleratedVideoEncode[]; -CONTENT_EXPORT extern const char kDisableAxSerializerForTesting[]; extern const char kDisableBackingStoreLimit[]; CONTENT_EXPORT extern const char kDisableBackgroundingOccludedWindowsForTesting[];
diff --git a/content/public/test/fake_local_frame.cc b/content/public/test/fake_local_frame.cc index 4c63ee0..2b34c6e 100644 --- a/content/public/test/fake_local_frame.cc +++ b/content/public/test/fake_local_frame.cc
@@ -91,6 +91,12 @@ void FakeLocalFrame::OnScreensChange() {} +void FakeLocalFrame::PostMessageEvent( + const base::Optional<base::UnguessableToken>& source_frame_token, + const base::string16& source_origin, + const base::string16& target_origin, + blink::TransferableMessage message) {} + #if defined(OS_MACOSX) void FakeLocalFrame::GetCharacterIndexAtPoint(const gfx::Point& point) {} void FakeLocalFrame::GetFirstRectForRange(const gfx::Range& range) {}
diff --git a/content/public/test/fake_local_frame.h b/content/public/test/fake_local_frame.h index f0d08ed0..bca54ab 100644 --- a/content/public/test/fake_local_frame.h +++ b/content/public/test/fake_local_frame.h
@@ -5,11 +5,13 @@ #ifndef CONTENT_PUBLIC_TEST_FAKE_LOCAL_FRAME_H_ #define CONTENT_PUBLIC_TEST_FAKE_LOCAL_FRAME_H_ +#include "base/optional.h" #include "base/unguessable_token.h" #include "build/build_config.h" #include "mojo/public/cpp/bindings/associated_receiver_set.h" #include "mojo/public/cpp/bindings/pending_associated_receiver.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" +#include "third_party/blink/public/common/messaging/transferable_message.h" #include "third_party/blink/public/mojom/frame/frame.mojom.h" #include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom.h" #include "third_party/blink/public/mojom/input/focus_type.mojom-forward.h" @@ -69,6 +71,12 @@ network::mojom::CSPViolationPtr violation) override; void DidUpdateFramePolicy(const blink::FramePolicy& frame_policy) override; void OnScreensChange() override; + void PostMessageEvent( + const base::Optional<base::UnguessableToken>& source_frame_token, + const base::string16& source_origin, + const base::string16& target_origin, + blink::TransferableMessage message) override; + #if defined(OS_MACOSX) void GetCharacterIndexAtPoint(const gfx::Point& point) override; void GetFirstRectForRange(const gfx::Range& range) override;
diff --git a/content/renderer/input/main_thread_event_queue.cc b/content/renderer/input/main_thread_event_queue.cc index 57c3026..73abc49 100644 --- a/content/renderer/input/main_thread_event_queue.cc +++ b/content/renderer/input/main_thread_event_queue.cc
@@ -138,7 +138,7 @@ void HandledEvent(MainThreadEventQueue* queue, blink::mojom::InputEventResultState ack_result, const ui::LatencyInfo& latency_info, - std::unique_ptr<ui::DidOverscrollParams> overscroll, + blink::mojom::DidOverscrollParamsPtr overscroll, base::Optional<cc::TouchAction> touch_action) { if (callback_) { std::move(callback_).Run(ack_result, latency_info, std::move(overscroll), @@ -258,9 +258,9 @@ blink::mojom::InputEventResultState::kSetNonBlockingDueToFling || ack_result == blink::mojom::InputEventResultState::kNotConsumed); - bool non_blocking = - original_dispatch_type == DISPATCH_TYPE_NON_BLOCKING || - ack_result == blink::mojom::InputEventResultState::kSetNonBlocking; + bool is_blocking = + original_dispatch_type == DISPATCH_TYPE_BLOCKING && + ack_result != blink::mojom::InputEventResultState::kSetNonBlocking; bool is_wheel = event->GetType() == blink::WebInputEvent::Type::kMouseWheel; bool is_touch = blink::WebInputEvent::IsTouchEventType(event->GetType()); bool originally_cancelable = false; @@ -274,7 +274,7 @@ // Adjust the |dispatchType| on the event since the compositor // determined all event listeners are passive. - if (non_blocking) { + if (!is_blocking) { touch_event->dispatch_type = blink::WebInputEvent::DispatchType::kListenersNonBlockingPassive; } @@ -291,15 +291,15 @@ last_touch_start_forced_nonblocking_due_to_fling_) { touch_event->dispatch_type = blink::WebInputEvent::DispatchType:: kListenersForcedNonBlockingDueToFling; - non_blocking = true; + is_blocking = false; last_touch_start_forced_nonblocking_due_to_fling_ = true; } } // If the event is non-cancelable ACK it right away. - if (!non_blocking && touch_event->dispatch_type != - blink::WebInputEvent::DispatchType::kBlocking) - non_blocking = true; + if (is_blocking && touch_event->dispatch_type != + blink::WebInputEvent::DispatchType::kBlocking) + is_blocking = false; } if (is_wheel) { @@ -307,7 +307,7 @@ static_cast<blink::WebMouseWheelEvent*>(event.get()); originally_cancelable = wheel_event->dispatch_type == blink::WebInputEvent::DispatchType::kBlocking; - if (non_blocking) { + if (!is_blocking) { // Adjust the |dispatchType| on the event since the compositor // determined all event listeners are passive. wheel_event->dispatch_type = @@ -316,7 +316,7 @@ } HandledEventCallback event_callback; - if (!non_blocking) { + if (is_blocking) { TRACE_EVENT_INSTANT0("input", "Blocking", TRACE_EVENT_SCOPE_THREAD); event_callback = std::move(callback); }
diff --git a/content/renderer/input/main_thread_event_queue.h b/content/renderer/input/main_thread_event_queue.h index c29ff90e..8f338767 100644 --- a/content/renderer/input/main_thread_event_queue.h +++ b/content/renderer/input/main_thread_event_queue.h
@@ -17,8 +17,8 @@ #include "content/renderer/input/main_thread_event_queue_task_list.h" #include "third_party/blink/public/common/input/web_input_event.h" #include "third_party/blink/public/mojom/input/input_event_result.mojom-shared.h" +#include "third_party/blink/public/mojom/input/input_handler.mojom.h" #include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h" -#include "ui/events/blink/did_overscroll_params.h" #include "ui/events/blink/web_input_event_traits.h" #include "ui/latency/latency_info.h" @@ -27,7 +27,7 @@ using HandledEventCallback = base::OnceCallback<void(blink::mojom::InputEventResultState ack_state, const ui::LatencyInfo& latency_info, - std::unique_ptr<ui::DidOverscrollParams>, + blink::mojom::DidOverscrollParamsPtr, base::Optional<cc::TouchAction>)>; // All interaction with the MainThreadEventQueueClient will occur
diff --git a/content/renderer/input/main_thread_event_queue_unittest.cc b/content/renderer/input/main_thread_event_queue_unittest.cc index c0178e8..69894a6 100644 --- a/content/renderer/input/main_thread_event_queue_unittest.cc +++ b/content/renderer/input/main_thread_event_queue_unittest.cc
@@ -160,7 +160,7 @@ void DidHandleEvent(size_t index, blink::mojom::InputEventResultState ack_result, const ui::LatencyInfo& latency, - std::unique_ptr<ui::DidOverscrollParams> params, + blink::mojom::DidOverscrollParamsPtr params, base::Optional<cc::TouchAction> touch_action) { callbacks_received_[index] = ReceivedCallback( handling_event_ ? CallbackReceivedState::kCalledWhileHandlingEvent
diff --git a/content/renderer/input/render_widget_input_handler.cc b/content/renderer/input/render_widget_input_handler.cc index 24eaf380..a9ed79c 100644 --- a/content/renderer/input/render_widget_input_handler.cc +++ b/content/renderer/input/render_widget_input_handler.cc
@@ -226,7 +226,7 @@ // handled. If the event causes overscroll, the overscroll metadata can be // bundled in the event ack, saving an IPC. Note that we must continue // supporting overscroll IPC notifications due to fling animation updates. - std::unique_ptr<ui::DidOverscrollParams> event_overscroll; + blink::mojom::DidOverscrollParamsPtr event_overscroll; base::Optional<cc::TouchAction> touch_action; @@ -558,12 +558,9 @@ const gfx::PointF& position, const gfx::Vector2dF& velocity, const cc::OverscrollBehavior& behavior) { - std::unique_ptr<DidOverscrollParams> params(new DidOverscrollParams()); - params->accumulated_overscroll = accumulatedOverscroll; - params->latest_overscroll_delta = overscrollDelta; - params->current_fling_velocity = velocity; - params->causal_event_viewport_point = position; - params->overscroll_behavior = behavior; + blink::mojom::DidOverscrollParamsPtr params = + blink::mojom::DidOverscrollParams::New( + accumulatedOverscroll, overscrollDelta, velocity, position, behavior); // If we're currently handling an event, stash the overscroll data such that // it can be bundled in the event ack. @@ -572,7 +569,7 @@ return; } - delegate_->OnDidOverscroll(*params); + delegate_->OnDidOverscroll(std::move(params)); } void RenderWidgetInputHandler::InjectGestureScrollEvent(
diff --git a/content/renderer/input/render_widget_input_handler_delegate.h b/content/renderer/input/render_widget_input_handler_delegate.h index 02b251127..69686ad 100644 --- a/content/renderer/input/render_widget_input_handler_delegate.h +++ b/content/renderer/input/render_widget_input_handler_delegate.h
@@ -8,6 +8,7 @@ #include <memory> #include "content/common/content_export.h" +#include "third_party/blink/public/mojom/input/input_handler.mojom.h" #include "third_party/blink/public/platform/web_input_event_result.h" namespace blink { @@ -42,7 +43,7 @@ virtual void OnDidHandleKeyEvent() = 0; // Notifies that an overscroll was completed from Blink. - virtual void OnDidOverscroll(const ui::DidOverscrollParams& params) = 0; + virtual void OnDidOverscroll(blink::mojom::DidOverscrollParamsPtr params) = 0; // Notifies the delegate of the |input_handler| managing it. virtual void SetInputHandler(RenderWidgetInputHandler* input_handler) = 0;
diff --git a/content/renderer/input/widget_input_handler_manager.cc b/content/renderer/input/widget_input_handler_manager.cc index c29566b..4c606ed 100644 --- a/content/renderer/input/widget_input_handler_manager.cc +++ b/content/renderer/input/widget_input_handler_manager.cc
@@ -39,32 +39,31 @@ namespace { -base::Optional<ui::DidOverscrollParams> ToDidOverscrollParams( - const std::unique_ptr<blink::InputHandlerProxy::DidOverscrollParams>& - overscroll_params) { +blink::mojom::DidOverscrollParamsPtr ToDidOverscrollParams( + const blink::InputHandlerProxy::DidOverscrollParams* overscroll_params) { if (!overscroll_params) - return base::nullopt; - return ui::DidOverscrollParams{overscroll_params->accumulated_overscroll, - overscroll_params->latest_overscroll_delta, - overscroll_params->current_fling_velocity, - overscroll_params->causal_event_viewport_point, - overscroll_params->overscroll_behavior}; + return nullptr; + return blink::mojom::DidOverscrollParams::New( + overscroll_params->accumulated_overscroll, + overscroll_params->latest_overscroll_delta, + overscroll_params->current_fling_velocity, + overscroll_params->causal_event_viewport_point, + overscroll_params->overscroll_behavior); } void CallCallback(mojom::WidgetInputHandler::DispatchEventCallback callback, blink::mojom::InputEventResultState result_state, const ui::LatencyInfo& latency_info, - std::unique_ptr<ui::DidOverscrollParams> overscroll_params, + blink::mojom::DidOverscrollParamsPtr overscroll_params, base::Optional<cc::TouchAction> touch_action) { ui::LatencyInfo::TraceIntermediateFlowEvents( {latency_info}, ChromeLatencyInfo::STEP_HANDLED_INPUT_EVENT_IMPL); std::move(callback).Run( blink::mojom::InputEventResultSource::kMainThread, latency_info, - result_state, - overscroll_params - ? base::Optional<ui::DidOverscrollParams>(*overscroll_params) - : base::nullopt, - touch_action); + result_state, std::move(overscroll_params), + touch_action + ? blink::mojom::TouchActionOptional::New(touch_action.value()) + : nullptr); } blink::mojom::InputEventResultState InputEventDispositionToAck( @@ -157,6 +156,12 @@ if (uses_input_handler) manager->InitInputHandler(); + // A compositor thread implies we're using an input handler. + DCHECK(!manager->compositor_task_runner_ || uses_input_handler); + // Conversely, if we don't use an input handler we must not have a compositor + // thread. + DCHECK(uses_input_handler || !manager->compositor_task_runner_); + return manager; } @@ -354,10 +359,9 @@ // Call |callback| if it was available indicating this event wasn't // handled. if (callback) { - std::move(callback).Run(blink::mojom::InputEventResultSource::kMainThread, - ui::LatencyInfo(), - blink::mojom::InputEventResultState::kNotConsumed, - base::nullopt, base::nullopt); + std::move(callback).Run( + blink::mojom::InputEventResultSource::kMainThread, ui::LatencyInfo(), + blink::mojom::InputEventResultState::kNotConsumed, nullptr, nullptr); } return; } @@ -379,10 +383,9 @@ // without a begin. Scrolling, pinch-zoom etc. don't seem dangerous. if (renderer_deferral_state_ && !allow_pre_commit_input_ && !event_is_move) { if (callback) { - std::move(callback).Run(blink::mojom::InputEventResultSource::kMainThread, - ui::LatencyInfo(), - blink::mojom::InputEventResultState::kNotConsumed, - base::nullopt, base::nullopt); + std::move(callback).Run( + blink::mojom::InputEventResultSource::kMainThread, ui::LatencyInfo(), + blink::mojom::InputEventResultState::kNotConsumed, nullptr, nullptr); } return; } @@ -401,19 +404,27 @@ std::move(callback).Run( blink::mojom::InputEventResultSource::kMainThread, ui::LatencyInfo(), - blink::mojom::InputEventResultState::kNotConsumed, base::nullopt, - base::nullopt); + blink::mojom::InputEventResultState::kNotConsumed, nullptr, + nullptr); } return; } + + // The InputHandlerProxy will be the first to try handing the event on the + // compositor thread. It will respond to this class by calling + // DidHandleInputEventSentToCompositor with the result of its attempt. Based + // on the resulting disposition, DidHandleInputEventSentToCompositor will + // either ACK the event as handled to the browser or forward it to the main + // thread. input_handler_proxy_->HandleInputEventWithLatencyInfo( std::move(event->web_event), event->latency_info, base::BindOnce( - &WidgetInputHandlerManager::DidHandleInputEventAndOverscroll, this, - std::move(callback))); + &WidgetInputHandlerManager::DidHandleInputEventSentToCompositor, + this, std::move(callback))); } else { - HandleInputEvent(std::move(event->web_event), event->latency_info, - std::move(callback)); + DCHECK(!input_handler_proxy_); + DispatchDirectlyToWidget(std::move(event->web_event), event->latency_info, + std::move(callback)); } } @@ -516,6 +527,7 @@ const base::WeakPtr<cc::InputHandler>& input_handler, bool sync_compositing) { DCHECK(InputThreadTaskRunner()->BelongsToCurrentThread()); + DCHECK(uses_input_handler_); // It is possible that the input_handle has already been destroyed before this // Init() call was invoked. If so, early out. @@ -561,29 +573,35 @@ handler->SetReceiver(std::move(receiver)); } -void WidgetInputHandlerManager::HandleInputEvent( +void WidgetInputHandlerManager::DispatchDirectlyToWidget( const ui::WebScopedInputEvent& event, const ui::LatencyInfo& latency, mojom::WidgetInputHandler::DispatchEventCallback callback) { + // This path should only be taken by non-frame RenderWidgets that don't use a + // compositor (e.g. popups, plugins). Events bounds for a frame RenderWidget + // must be passed through the InputHandlerProxy first. + DCHECK(!uses_input_handler_); + // Input messages must not be processed if the RenderWidget was destroyed or // was just recreated for a provisional frame. if (!render_widget_ || render_widget_->IsForProvisionalFrame()) { if (callback) { - std::move(callback).Run(blink::mojom::InputEventResultSource::kMainThread, - latency, - blink::mojom::InputEventResultState::kNotConsumed, - base::nullopt, base::nullopt); + std::move(callback).Run( + blink::mojom::InputEventResultSource::kMainThread, latency, + blink::mojom::InputEventResultState::kNotConsumed, nullptr, nullptr); } return; } - auto send_callback = base::BindOnce( - &WidgetInputHandlerManager::HandledInputEvent, this, std::move(callback)); + + auto send_callback = + base::BindOnce(&WidgetInputHandlerManager::DidHandleInputEventSentToMain, + this, std::move(callback)); blink::WebCoalescedInputEvent coalesced_event(*event, latency); render_widget_->HandleInputEvent(coalesced_event, std::move(send_callback)); } -void WidgetInputHandlerManager::DidHandleInputEventAndOverscroll( +void WidgetInputHandlerManager::DidHandleInputEventSentToCompositor( mojom::WidgetInputHandler::DispatchEventCallback callback, blink::InputHandlerProxy::EventDisposition event_disposition, ui::WebScopedInputEvent input_event, @@ -592,8 +610,10 @@ overscroll_params, const blink::WebInputEventAttribution& attribution) { TRACE_EVENT1("input", - "WidgetInputHandlerManager::DidHandleInputEventAndOverscroll", + "WidgetInputHandlerManager::DidHandleInputEventSentToCompositor", "Disposition", event_disposition); + DCHECK(InputThreadTaskRunner()->BelongsToCurrentThread()); + ui::LatencyInfo::TraceIntermediateFlowEvents( {latency_info}, ChromeLatencyInfo::STEP_DID_HANDLE_INPUT_AND_OVERSCROLL); @@ -618,9 +638,9 @@ InputEventDispatchType dispatch_type = callback.is_null() ? DISPATCH_TYPE_NON_BLOCKING : DISPATCH_TYPE_BLOCKING; - HandledEventCallback handled_event = - base::BindOnce(&WidgetInputHandlerManager::HandledInputEvent, this, - std::move(callback)); + HandledEventCallback handled_event = base::BindOnce( + &WidgetInputHandlerManager::DidHandleInputEventSentToMain, this, + std::move(callback)); input_event_queue_->HandleEvent(std::move(input_event), latency_info, dispatch_type, ack_state, attribution, std::move(handled_event)); @@ -629,20 +649,21 @@ if (callback) { std::move(callback).Run( blink::mojom::InputEventResultSource::kCompositorThread, latency_info, - ack_state, ToDidOverscrollParams(overscroll_params), base::nullopt); + ack_state, ToDidOverscrollParams(overscroll_params.get()), nullptr); } } -void WidgetInputHandlerManager::HandledInputEvent( +void WidgetInputHandlerManager::DidHandleInputEventSentToMain( mojom::WidgetInputHandler::DispatchEventCallback callback, blink::mojom::InputEventResultState ack_state, const ui::LatencyInfo& latency_info, - std::unique_ptr<ui::DidOverscrollParams> overscroll_params, + blink::mojom::DidOverscrollParamsPtr overscroll_params, base::Optional<cc::TouchAction> touch_action) { if (!callback) return; - TRACE_EVENT1("input", "WidgetInputHandlerManager::HandledInputEvent", + TRACE_EVENT1("input", + "WidgetInputHandlerManager::DidHandleInputEventSentToMain", "ack_state", ack_state); ui::LatencyInfo::TraceIntermediateFlowEvents( {latency_info}, ChromeLatencyInfo::STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL); @@ -672,11 +693,10 @@ is_compositor_thread ? blink::mojom::InputEventResultSource::kCompositorThread : blink::mojom::InputEventResultSource::kMainThread, - latency_info, ack_state, - overscroll_params - ? base::Optional<ui::DidOverscrollParams>(*overscroll_params) - : base::nullopt, - touch_action); + latency_info, ack_state, std::move(overscroll_params), + touch_action + ? blink::mojom::TouchActionOptional::New(touch_action.value()) + : nullptr); } }
diff --git a/content/renderer/input/widget_input_handler_manager.h b/content/renderer/input/widget_input_handler_manager.h index 6a160c7..d5d9597 100644 --- a/content/renderer/input/widget_input_handler_manager.h +++ b/content/renderer/input/widget_input_handler_manager.h
@@ -156,11 +156,26 @@ void BindAssociatedChannel( mojo::PendingAssociatedReceiver<mojom::WidgetInputHandler> receiver); void BindChannel(mojo::PendingReceiver<mojom::WidgetInputHandler> receiver); - void HandleInputEvent( + + // This method skips the input handler proxy and sends the event directly to + // the RenderWidget (main thread). Should only be used by non-frame + // RenderWidgets that don't use a compositor (e.g. popups, plugins). Events + // for a frame RenderWidget should always be passed through the + // InputHandlerProxy by calling DispatchEvent which will re-route to the main + // thread if needed. + void DispatchDirectlyToWidget( const ui::WebScopedInputEvent& event, const ui::LatencyInfo& latency, mojom::WidgetInputHandler::DispatchEventCallback callback); - void DidHandleInputEventAndOverscroll( + + // This method is the callback used by the compositor input handler to + // communicate back whether the event was successfully handled on the + // compositor thread or whether it needs to forwarded to the main thread. + // This method is responsible for passing the event on to the main thread or + // replying to the browser that the event was handled. This is always called + // on the input handling thread (i.e. if a compositor thread exists, it'll be + // called from it). + void DidHandleInputEventSentToCompositor( mojom::WidgetInputHandler::DispatchEventCallback callback, blink::InputHandlerProxy::EventDisposition event_disposition, ui::WebScopedInputEvent input_event, @@ -168,12 +183,18 @@ std::unique_ptr<blink::InputHandlerProxy::DidOverscrollParams> overscroll_params, const blink::WebInputEventAttribution& attribution); - void HandledInputEvent( + + // Similar to the above; this is used by the main thread input handler to + // communicate back the result of handling the event. Note: this may be + // called on either thread as non-blocking events sent to the main thread + // will be ACKed immediately when added to the main thread event queue. + void DidHandleInputEventSentToMain( mojom::WidgetInputHandler::DispatchEventCallback callback, blink::mojom::InputEventResultState ack_state, const ui::LatencyInfo& latency_info, - std::unique_ptr<ui::DidOverscrollParams> overscroll_params, + blink::mojom::DidOverscrollParamsPtr overscroll_params, base::Optional<cc::TouchAction> touch_action); + void ObserveGestureEventOnInputHandlingThread( const blink::WebGestureEvent& gesture_event, const cc::InputHandlerScrollResult& scroll_result); @@ -214,7 +235,10 @@ base::OnceClosure input_processed_callback_; // Whether this widget uses an InputHandler or forwards all input to the - // WebWidget (Popups, Plugins). + // WebWidget (Popups, Plugins). This is always true if we have a compositor + // thread; however, we can use an input handler if we don't have a compositor + // thread (e.g. in tests). Conversely, if we're not using an input handler, + // we definitely don't have a compositor thread. bool uses_input_handler_ = false; // State tracking which parts of the rendering pipeline are currently
diff --git a/content/renderer/media/batching_media_log.cc b/content/renderer/media/batching_media_log.cc index 468e0c6..a1a1016 100644 --- a/content/renderer/media/batching_media_log.cc +++ b/content/renderer/media/batching_media_log.cc
@@ -53,10 +53,10 @@ BatchingMediaLog::BatchingMediaLog( const GURL& security_origin, scoped_refptr<base::SingleThreadTaskRunner> task_runner, - std::unique_ptr<EventHandler> event_handler) + std::vector<std::unique_ptr<EventHandler>> event_handlers) : security_origin_(security_origin), task_runner_(std::move(task_runner)), - event_handler_(std::move(event_handler)), + event_handlers_(std::move(event_handlers)), tick_clock_(base::DefaultTickClock::GetInstance()), last_ipc_send_time_(tick_clock_->NowTicks()), ipc_send_pending_(false) { @@ -81,7 +81,8 @@ } void BatchingMediaLog::OnWebMediaPlayerDestroyedLocked() { - event_handler_->OnWebMediaPlayerDestroyed(); + for (const auto& handler : event_handlers_) + handler->OnWebMediaPlayerDestroyed(); } void BatchingMediaLog::AddLogRecordLocked( @@ -217,7 +218,8 @@ if (events_to_send.empty()) return; - event_handler_->SendQueuedMediaEvents(std::move(events_to_send)); + for (const auto& handler : event_handlers_) + handler->SendQueuedMediaEvents(events_to_send); } void BatchingMediaLog::SetTickClockForTesting(
diff --git a/content/renderer/media/batching_media_log.h b/content/renderer/media/batching_media_log.h index 57a226c..32e2bbb8 100644 --- a/content/renderer/media/batching_media_log.h +++ b/content/renderer/media/batching_media_log.h
@@ -40,7 +40,7 @@ BatchingMediaLog(const GURL& security_origin, scoped_refptr<base::SingleThreadTaskRunner> task_runner, - std::unique_ptr<EventHandler> impl); + std::vector<std::unique_ptr<EventHandler>> impl); ~BatchingMediaLog() override; // Will reset |last_ipc_send_time_| with the value of NowTicks(). @@ -66,7 +66,7 @@ scoped_refptr<base::SingleThreadTaskRunner> task_runner_; // impl for sending queued events. - std::unique_ptr<EventHandler> event_handler_; + std::vector<std::unique_ptr<EventHandler>> event_handlers_; // |lock_| protects access to all of the following member variables. It // allows any render process thread to AddEvent(), while preserving their
diff --git a/content/renderer/media/batching_media_log_unittest.cc b/content/renderer/media/batching_media_log_unittest.cc index 52bf499f..ccd285a 100644 --- a/content/renderer/media/batching_media_log_unittest.cc +++ b/content/renderer/media/batching_media_log_unittest.cc
@@ -25,6 +25,13 @@ std::vector<media::MediaLogRecord> events) override; void OnWebMediaPlayerDestroyed() override; + static std::vector<std::unique_ptr<BatchingMediaLog::EventHandler>> Create( + BatchingMediaLogTest* ptr) { + std::vector<std::unique_ptr<BatchingMediaLog::EventHandler>> move_me; + move_me.push_back(std::make_unique<TestEventHandler>(ptr)); + return move_me; + } + private: BatchingMediaLogTest* test_cls_; }; @@ -35,7 +42,7 @@ : task_runner_(new base::TestMockTimeTaskRunner()), log_(GURL("http://foo.com"), task_runner_, - std::make_unique<TestEventHandler>(this)) { + TestEventHandler::Create(this)) { log_.SetTickClockForTesting(&tick_clock_); }
diff --git a/content/renderer/media/media_factory.cc b/content/renderer/media/media_factory.cc index bcc2c75..a1c33d7 100644 --- a/content/renderer/media/media_factory.cc +++ b/content/renderer/media/media_factory.cc
@@ -343,12 +343,12 @@ media::kMemoryPressureBasedSourceBufferGC, "enable_instant_source_buffer_gc", false); - std::unique_ptr<BatchingMediaLog::EventHandler> event_handler; + std::vector<std::unique_ptr<BatchingMediaLog::EventHandler>> handlers; + handlers.push_back(std::make_unique<RenderMediaEventHandler>()); + if (base::FeatureList::IsEnabled(media::kMediaInspectorLogging)) { - event_handler = - std::make_unique<InspectorMediaEventHandler>(inspector_context); - } else { - event_handler = std::make_unique<RenderMediaEventHandler>(); + handlers.push_back( + std::make_unique<InspectorMediaEventHandler>(inspector_context)); } // This must be created for every new WebMediaPlayer, each instance generates @@ -356,7 +356,7 @@ auto media_log = std::make_unique<BatchingMediaLog>( url::Origin(security_origin).GetURL(), render_frame_->GetTaskRunner(blink::TaskType::kInternalMedia), - std::move(event_handler)); + std::move(handlers)); base::WeakPtr<media::MediaObserver> media_observer; auto factory_selector = CreateRendererFactorySelector( @@ -622,12 +622,12 @@ scoped_refptr<base::SingleThreadTaskRunner> video_frame_compositor_task_runner; - std::unique_ptr<BatchingMediaLog::EventHandler> event_handler; + std::vector<std::unique_ptr<BatchingMediaLog::EventHandler>> handlers; + handlers.push_back(std::make_unique<RenderMediaEventHandler>()); + if (base::FeatureList::IsEnabled(media::kMediaInspectorLogging)) { - event_handler = - std::make_unique<InspectorMediaEventHandler>(inspector_context); - } else { - event_handler = std::make_unique<RenderMediaEventHandler>(); + handlers.push_back( + std::make_unique<InspectorMediaEventHandler>(inspector_context)); } // This must be created for every new WebMediaPlayer, each instance generates @@ -635,7 +635,7 @@ auto media_log = std::make_unique<BatchingMediaLog>( url::Origin(security_origin).GetURL(), render_frame_->GetTaskRunner(blink::TaskType::kInternalMedia), - std::move(event_handler)); + std::move(handlers)); std::unique_ptr<blink::WebVideoFrameSubmitter> submitter = CreateSubmitter( &video_frame_compositor_task_runner, settings, media_log.get());
diff --git a/content/renderer/pepper/video_decoder_shim.cc b/content/renderer/pepper/video_decoder_shim.cc index e73cad2..d3a7a4b 100644 --- a/content/renderer/pepper/video_decoder_shim.cc +++ b/content/renderer/pepper/video_decoder_shim.cc
@@ -315,11 +315,7 @@ VideoDecoderShim::~VideoDecoderShim() { DCHECK(RenderThreadImpl::current()); - // Delete any remaining textures. - auto it = texture_id_map_.begin(); - for (; it != texture_id_map_.end(); ++it) - DeleteTexture(it->second); - texture_id_map_.clear(); + texture_mailbox_map_.clear(); FlushCommandBuffer(); @@ -404,14 +400,11 @@ std::vector<gpu::Mailbox> mailboxes = host_->TakeMailboxes(); DCHECK_EQ(buffers.size(), mailboxes.size()); GLuint num_textures = base::checked_cast<GLuint>(buffers.size()); - std::vector<uint32_t> local_texture_ids(num_textures); - gpu::raster::RasterInterface* ri = context_provider_->RasterInterface(); for (uint32_t i = 0; i < num_textures; i++) { DCHECK_EQ(1u, buffers[i].client_texture_ids().size()); - local_texture_ids[i] = ri->CreateAndConsumeForGpuRaster(mailboxes[i]); - // Map the plugin texture id to the local texture id. + // Map the plugin texture id to the mailbox uint32_t plugin_texture_id = buffers[i].client_texture_ids()[0]; - texture_id_map_[plugin_texture_id] = local_texture_ids[i]; + texture_mailbox_map_[plugin_texture_id] = mailboxes[i]; available_textures_.insert(plugin_texture_id); } SendPictures(); @@ -422,7 +415,8 @@ uint32_t texture_id = static_cast<uint32_t>(picture_buffer_id); if (textures_to_dismiss_.find(texture_id) != textures_to_dismiss_.end()) { DismissTexture(texture_id); - } else if (texture_id_map_.find(texture_id) != texture_id_map_.end()) { + } else if (texture_mailbox_map_.find(texture_id) != + texture_mailbox_map_.end()) { available_textures_.insert(texture_id); SendPictures(); } else { @@ -484,9 +478,8 @@ // If the size has changed, all current textures must be dismissed. Add // all textures to |textures_to_dismiss_| and dismiss any that aren't in // use by the plugin. We will dismiss the rest as they are recycled. - for (TextureIdMap::const_iterator it = texture_id_map_.begin(); - it != texture_id_map_.end(); - ++it) { + for (IdToMailboxMap::const_iterator it = texture_mailbox_map_.begin(); + it != texture_mailbox_map_.end(); ++it) { textures_to_dismiss_.insert(it->first); } for (auto it = available_textures_.begin(); @@ -517,10 +510,11 @@ uint32_t texture_id = *it; available_textures_.erase(it); - uint32_t local_texture_id = texture_id_map_[texture_id]; - ConvertFromVideoFrameYUVTextures(frame->video_frame.get(), - context_provider_.get(), GL_TEXTURE_2D, - local_texture_id); + gpu::MailboxHolder destination_holder; + destination_holder.mailbox = texture_mailbox_map_[texture_id]; + destination_holder.texture_target = GL_TEXTURE_2D; + ConvertFromVideoFrameYUV(frame->video_frame.get(), context_provider_.get(), + destination_holder); host_->PictureReady(media::Picture(texture_id, frame->decode_id, frame->video_frame->visible_rect(), gfx::ColorSpace(), false)); @@ -567,17 +561,11 @@ void VideoDecoderShim::DismissTexture(uint32_t texture_id) { DCHECK(host_); textures_to_dismiss_.erase(texture_id); - DCHECK(texture_id_map_.find(texture_id) != texture_id_map_.end()); - DeleteTexture(texture_id_map_[texture_id]); - texture_id_map_.erase(texture_id); + DCHECK(texture_mailbox_map_.find(texture_id) != texture_mailbox_map_.end()); + texture_mailbox_map_.erase(texture_id); host_->DismissPictureBuffer(texture_id); } -void VideoDecoderShim::DeleteTexture(uint32_t texture_id) { - gpu::raster::RasterInterface* ri = context_provider_->RasterInterface(); - ri->DeleteGpuRasterTexture(texture_id); -} - void VideoDecoderShim::FlushCommandBuffer() { context_provider_->RasterInterface()->Flush(); }
diff --git a/content/renderer/pepper/video_decoder_shim.h b/content/renderer/pepper/video_decoder_shim.h index 6332cc38..1edd117 100644 --- a/content/renderer/pepper/video_decoder_shim.h +++ b/content/renderer/pepper/video_decoder_shim.h
@@ -83,9 +83,9 @@ // The current decoded frame size. gfx::Size texture_size_; - // Map that takes the plugin's GL texture id to the renderer's GL texture id. - using TextureIdMap = std::unordered_map<uint32_t, uint32_t>; - TextureIdMap texture_id_map_; + // Map that takes the plugin's GL texture id to the renderer's mailbox. + using IdToMailboxMap = std::unordered_map<uint32_t, gpu::Mailbox>; + IdToMailboxMap texture_mailbox_map_; // Available textures (these are plugin ids.) using TextureIdSet = std::unordered_set<uint32_t>; TextureIdSet available_textures_;
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index aa8f6b4..34cdad7f 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -2679,39 +2679,6 @@ frame_->SetOpener(opener); } -void RenderFrameImpl::PostMessageEvent(int32_t source_routing_id, - const base::string16& source_origin, - const base::string16& target_origin, - blink::TransferableMessage message) { - // Make sure that |message| owns its data so that the data is alive even after - // moved. - message.EnsureDataIsOwned(); - - // Find the source frame if it exists. - WebFrame* source_frame = nullptr; - if (source_routing_id != MSG_ROUTING_NONE) { - RenderFrameProxy* source_proxy = - RenderFrameProxy::FromRoutingID(source_routing_id); - if (source_proxy) - source_frame = source_proxy->web_frame(); - } - - // We must pass in the target_origin to do the security check on this side, - // since it may have changed since the original postMessage call was made. - WebSecurityOrigin target_security_origin; - if (!target_origin.empty()) { - target_security_origin = WebSecurityOrigin::CreateFromString( - WebString::FromUTF16(target_origin)); - } - - WebDOMMessageEvent msg_event(std::move(message), - WebString::FromUTF16(source_origin), - source_frame, frame_->GetDocument()); - - frame_->DispatchMessageEventWithOriginCheck(target_security_origin, - msg_event); -} - void RenderFrameImpl::OnReload() { frame_->StartReload(WebFrameLoadType::kReload); }
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 29c39ee..8d6bfbc 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -526,10 +526,6 @@ void EnableMojoJsBindings() override; // mojom::FrameNavigationControl implementation: - void PostMessageEvent(int32_t source_routing_id, - const base::string16& source_origin, - const base::string16& target_origin, - blink::TransferableMessage message) override; void ForwardMessageFromHost( blink::TransferableMessage message, const url::Origin& source_origin,
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 1490b7e..97b42c2 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -1245,10 +1245,11 @@ edit_commands_.clear(); } -void RenderWidget::OnDidOverscroll(const ui::DidOverscrollParams& params) { +void RenderWidget::OnDidOverscroll( + blink::mojom::DidOverscrollParamsPtr params) { if (mojom::WidgetInputHandlerHost* host = widget_input_handler_manager_->GetWidgetInputHandlerHost()) { - host->DidOverscroll(params); + host->DidOverscroll(std::move(params)); } }
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index d80e357..b54b0ba 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h
@@ -102,7 +102,6 @@ namespace ui { class Cursor; -struct DidOverscrollParams; } namespace content { @@ -306,7 +305,7 @@ bool event_processed) override; void OnDidHandleKeyEvent() override; - void OnDidOverscroll(const ui::DidOverscrollParams& params) override; + void OnDidOverscroll(blink::mojom::DidOverscrollParamsPtr params) override; void SetInputHandler(RenderWidgetInputHandler* input_handler) override; void ShowVirtualKeyboard() override; void UpdateTextInputState() override;
diff --git a/content/renderer/render_widget_unittest.cc b/content/renderer/render_widget_unittest.cc index 8d77f2d..5433bc5 100644 --- a/content/renderer/render_widget_unittest.cc +++ b/content/renderer/render_widget_unittest.cc
@@ -22,7 +22,6 @@ #include "cc/trees/layer_tree_host.h" #include "components/viz/common/surfaces/parent_local_surface_id_allocator.h" #include "content/common/frame_replication_state.h" -#include "content/common/input/input_handler.mojom.h" #include "content/common/input/synthetic_web_input_event_builders.h" #include "content/common/input_messages.h" #include "content/common/view_messages.h" @@ -60,10 +59,11 @@ using testing::_; -namespace ui { +namespace blink { +namespace mojom { -bool operator==(const ui::DidOverscrollParams& lhs, - const ui::DidOverscrollParams& rhs) { +bool operator==(const DidOverscrollParams& lhs, + const DidOverscrollParams& rhs) { return lhs.accumulated_overscroll == rhs.accumulated_overscroll && lhs.latest_overscroll_delta == rhs.latest_overscroll_delta && lhs.current_fling_velocity == rhs.current_fling_velocity && @@ -71,7 +71,8 @@ lhs.overscroll_behavior == rhs.overscroll_behavior; } -} // namespace ui +} // namespace mojom +} // namespace blink namespace cc { class AnimationHost; @@ -106,7 +107,7 @@ uint32_t, blink::mojom::InputEventResultState)); - MOCK_METHOD1(DidOverscroll, void(const ui::DidOverscrollParams&)); + MOCK_METHOD1(DidOverscroll, void(blink::mojom::DidOverscrollParamsPtr)); MOCK_METHOD0(DidStopFlinging, void()); @@ -150,7 +151,7 @@ MOCK_METHOD4_T(Run, void(blink::mojom::InputEventResultState, const ui::LatencyInfo&, - std::unique_ptr<ui::DidOverscrollParams>&, + blink::mojom::DidOverscrollParams* overscroll, base::Optional<cc::TouchAction>)); HandledEventCallback GetCallback() { @@ -161,9 +162,9 @@ private: void HandleCallback(blink::mojom::InputEventResultState ack_state, const ui::LatencyInfo& latency_info, - std::unique_ptr<ui::DidOverscrollParams> overscroll, + blink::mojom::DidOverscrollParamsPtr overscroll, base::Optional<cc::TouchAction> touch_action) { - Run(ack_state, latency_info, overscroll, touch_action); + Run(ack_state, latency_info, overscroll.get(), touch_action); } DISALLOW_COPY_AND_ASSIGN(MockHandledEventCallback); @@ -448,7 +449,7 @@ scroll.data.scroll_update.delta_y = 10; MockHandledEventCallback handled_event; - ui::DidOverscrollParams expected_overscroll; + blink::mojom::DidOverscrollParams expected_overscroll; expected_overscroll.latest_overscroll_delta = gfx::Vector2dF(0, 10); expected_overscroll.accumulated_overscroll = gfx::Vector2dF(0, 10); expected_overscroll.causal_event_viewport_point = gfx::PointF(-10, 0);
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn index acf456f..5a50a2d 100644 --- a/content/shell/BUILD.gn +++ b/content/shell/BUILD.gn
@@ -345,6 +345,9 @@ "browser/web_test/web_test_permission_manager.h", "browser/web_test/web_test_push_messaging_service.cc", "browser/web_test/web_test_push_messaging_service.h", + "browser/web_test/web_test_shell_platform_delegate.cc", + "browser/web_test/web_test_shell_platform_delegate.h", + "browser/web_test/web_test_shell_platform_delegate_mac.mm", "browser/web_test/web_test_tts_controller_delegate.cc", "browser/web_test/web_test_tts_controller_delegate.h", "browser/web_test/web_test_tts_platform.cc", @@ -380,6 +383,13 @@ "CONTENT_SHELL_MAJOR_VERSION=\"$content_shell_major_version\"", ] + # This is to support our dependency on //content/browser. + # See comment at the top of //content/BUILD.gn for why this is disabled in + # component builds. + if (is_component_build) { + check_includes = false + } + public_deps = [ ":android_shell_descriptors", @@ -419,7 +429,9 @@ "//content:content_resources", "//content:dev_ui_content_resources", "//content/app/resources", + "//content/browser:for_content_tests", # For non-component builds. "//content/gpu", + "//content/public/browser", # For component builds. "//content/public/common", "//content/public/common:service_names", "//content/test:blink_test_browser_support",
diff --git a/content/shell/browser/DEPS b/content/shell/browser/DEPS index a2b574a..4c17205 100644 --- a/content/shell/browser/DEPS +++ b/content/shell/browser/DEPS
@@ -16,12 +16,6 @@ ] specific_include_rules = { - "shell\.cc": [ - "+content/shell/browser/layout_test", - ], - "shell_devtools_manager_delegate\.cc": [ - "+content/shell/browser/layout_test", - ], "shell_browser_main_parts\.cc": [ "+ui/gtk", ],
diff --git a/content/shell/browser/shell.cc b/content/shell/browser/shell.cc index c848ae3..6d732ba 100644 --- a/content/shell/browser/shell.cc +++ b/content/shell/browser/shell.cc
@@ -270,6 +270,10 @@ return shell; } +void Shell::RenderViewReady() { + g_platform->RenderViewReady(this); +} + void Shell::LoadURL(const GURL& url) { LoadURLForFrame( url, std::string(),
diff --git a/content/shell/browser/shell.h b/content/shell/browser/shell.h index 82787b962..c1359cc 100644 --- a/content/shell/browser/shell.h +++ b/content/shell/browser/shell.h
@@ -187,14 +187,6 @@ delay_popup_contents_delegate_for_testing_ = delay; } - // This pointer is owned and used only by ShellPlatformDelegate. - void set_platform_data(ShellPlatformDelegate::ShellData* data) { - platform_data_ = data; - } - ShellPlatformDelegate::ShellData* platform_data() const { - return platform_data_; - } - // TODO(danakj): Move this to WebTestShellPlatformDelegate (a test-only // subclass of ShellPlatformDelegate that does not exist yet). bool headless() const { return headless_; } @@ -228,11 +220,10 @@ void LoadProgressChanged(double progress) override; #endif void TitleWasSet(NavigationEntry* entry) override; + void RenderViewReady() override; void OnDevToolsWebContentsDestroyed(); - ShellPlatformDelegate::ShellData* platform_data_ = nullptr; - std::unique_ptr<ShellJavaScriptDialogManager> dialog_manager_; std::unique_ptr<WebContents> web_contents_;
diff --git a/content/shell/browser/shell_devtools_manager_delegate.cc b/content/shell/browser/shell_devtools_manager_delegate.cc index cc09d20..809d9a96 100644 --- a/content/shell/browser/shell_devtools_manager_delegate.cc +++ b/content/shell/browser/shell_devtools_manager_delegate.cc
@@ -200,10 +200,8 @@ scoped_refptr<DevToolsAgentHost> ShellDevToolsManagerDelegate::CreateNewTarget(const GURL& url) { - Shell* shell = Shell::CreateNewWindow(browser_context_, - url, - nullptr, - gfx::Size()); + Shell* shell = Shell::CreateNewWindow(browser_context_, url, nullptr, + Shell::GetShellDefaultSize()); if (switches::IsRunWebTestsSwitchPresent()) SecondaryTestWindowObserver::CreateForWebContents(shell->web_contents()); return DevToolsAgentHost::GetOrCreateFor(shell->web_contents());
diff --git a/content/shell/browser/shell_platform_delegate.h b/content/shell/browser/shell_platform_delegate.h index a51e9e4..ae21eba 100644 --- a/content/shell/browser/shell_platform_delegate.h +++ b/content/shell/browser/shell_platform_delegate.h
@@ -5,6 +5,7 @@ #ifndef CONTENT_SHELL_BROWSER_SHELL_PLATFORM_DELEGATE_H_ #define CONTENT_SHELL_BROWSER_SHELL_PLATFORM_DELEGATE_H_ +#include "base/containers/flat_map.h" #include "base/strings/string16.h" #include "build/build_config.h" #include "ui/gfx/geometry/size.h" @@ -24,11 +25,6 @@ public: enum UIControl { BACK_BUTTON, FORWARD_BUTTON, STOP_BUTTON }; - // Data held for each Shell instance, since there is one ShellPlatformDelegate - // for the whole browser process (shared across Shells). This is defined for - // each platform implementation. - struct ShellData; - ShellPlatformDelegate(); virtual ~ShellPlatformDelegate(); @@ -47,7 +43,7 @@ virtual void SetContents(Shell* shell); // Resize the web contents in the shell window to the given size. - void ResizeWebContent(Shell* shell, const gfx::Size& content_size); + virtual void ResizeWebContent(Shell* shell, const gfx::Size& content_size); // Enable/disable a button. virtual void EnableUIControl(Shell* shell, @@ -63,6 +59,10 @@ // Set the title of shell window virtual void SetTitle(Shell* shell, const base::string16& title); + // Called when a RenderView is created for a renderer process; forwarded from + // WebContentsObserver. + virtual void RenderViewReady(Shell* shell); + // Destroy the Shell. Returns true if the ShellPlatformDelegate did the // destruction. Returns false if the Shell should destroy itself. virtual bool DestroyShell(Shell* shell); @@ -98,6 +98,14 @@ #endif private: + // Data held for each Shell instance, since there is one ShellPlatformDelegate + // for the whole browser process (shared across Shells). This is defined for + // each platform implementation. + struct ShellData; + + // Holds an instance of ShellData for each Shell. + base::flat_map<Shell*, ShellData> shell_data_map_; + // Data held in ShellPlatformDelegate that is shared between all Shells. This // is created in Initialize(), and is defined for each platform // implementation.
diff --git a/content/shell/browser/shell_platform_delegate_android.cc b/content/shell/browser/shell_platform_delegate_android.cc index 7ecea162..263d1ee 100644 --- a/content/shell/browser/shell_platform_delegate_android.cc +++ b/content/shell/browser/shell_platform_delegate_android.cc
@@ -44,33 +44,32 @@ void ShellPlatformDelegate::CreatePlatformWindow( Shell* shell, const gfx::Size& initial_size) { - ShellData* shell_data = new ShellData; - shell->set_platform_data(shell_data); + DCHECK(!base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; - shell_data->java_object.Reset(CreateShellView(shell)); + shell_data.java_object.Reset(CreateShellView(shell)); } void ShellPlatformDelegate::CleanUp(Shell* shell) { JNIEnv* env = AttachCurrentThread(); - ShellData* shell_data = shell->platform_data(); + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; - RemoveShellView(shell_data->java_object); + RemoveShellView(shell_data.java_object); - if (!shell_data->java_object.is_null()) - Java_Shell_onNativeDestroyed(env, shell_data->java_object); + if (!shell_data.java_object.is_null()) + Java_Shell_onNativeDestroyed(env, shell_data.java_object); - delete shell_data; - // This shouldn't be used anymore, but just in case. - shell->set_platform_data(nullptr); + shell_data_map_.erase(shell); } void ShellPlatformDelegate::SetContents(Shell* shell) { JNIEnv* env = AttachCurrentThread(); - ShellData* shell_data = shell->platform_data(); + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; Java_Shell_initFromNativeTabContents( - env, shell_data->java_object, - shell->web_contents()->GetJavaWebContents()); + env, shell_data.java_object, shell->web_contents()->GetJavaWebContents()); } void ShellPlatformDelegate::ResizeWebContent(Shell* shell, @@ -82,31 +81,36 @@ UIControl control, bool is_enabled) { JNIEnv* env = AttachCurrentThread(); - ShellData* shell_data = shell->platform_data(); + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; - if (shell_data->java_object.is_null()) + if (shell_data.java_object.is_null()) return; - Java_Shell_enableUiControl(env, shell_data->java_object, control, is_enabled); + Java_Shell_enableUiControl(env, shell_data.java_object, control, is_enabled); } void ShellPlatformDelegate::SetAddressBarURL(Shell* shell, const GURL& url) { JNIEnv* env = AttachCurrentThread(); - ShellData* shell_data = shell->platform_data(); + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; ScopedJavaLocalRef<jstring> j_url = ConvertUTF8ToJavaString(env, url.spec()); - Java_Shell_onUpdateUrl(env, shell_data->java_object, j_url); + Java_Shell_onUpdateUrl(env, shell_data.java_object, j_url); } void ShellPlatformDelegate::SetIsLoading(Shell* shell, bool loading) { JNIEnv* env = AttachCurrentThread(); - ShellData* shell_data = shell->platform_data(); + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; - Java_Shell_setIsLoading(env, shell_data->java_object, loading); + Java_Shell_setIsLoading(env, shell_data.java_object, loading); } void ShellPlatformDelegate::SetTitle(Shell* shell, const base::string16& title) {} +void ShellPlatformDelegate::RenderViewReady(Shell* shell) {} + bool ShellPlatformDelegate::DestroyShell(Shell* shell) { return false; // Shell destroys itself. } @@ -116,9 +120,10 @@ WebContents* web_contents, bool enter_fullscreen) { JNIEnv* env = AttachCurrentThread(); - ShellData* shell_data = shell->platform_data(); + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; - Java_Shell_toggleFullscreenModeForTab(env, shell_data->java_object, + Java_Shell_toggleFullscreenModeForTab(env, shell_data.java_object, enter_fullscreen); } @@ -126,25 +131,28 @@ Shell* shell, const WebContents* web_contents) const { JNIEnv* env = AttachCurrentThread(); - ShellData* shell_data = shell->platform_data(); + DCHECK(base::Contains(shell_data_map_, shell)); + const ShellData& shell_data = shell_data_map_.find(shell)->second; - return Java_Shell_isFullscreenForTabOrPending(env, shell_data->java_object); + return Java_Shell_isFullscreenForTabOrPending(env, shell_data.java_object); } void ShellPlatformDelegate::SetOverlayMode(Shell* shell, bool use_overlay_mode) { JNIEnv* env = base::android::AttachCurrentThread(); - ShellData* shell_data = shell->platform_data(); + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; - return Java_Shell_setOverlayMode(env, shell_data->java_object, + return Java_Shell_setOverlayMode(env, shell_data.java_object, use_overlay_mode); } void ShellPlatformDelegate::LoadProgressChanged(Shell* shell, double progress) { JNIEnv* env = AttachCurrentThread(); - ShellData* shell_data = shell->platform_data(); + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; - Java_Shell_onLoadProgressChanged(env, shell_data->java_object, progress); + Java_Shell_onLoadProgressChanged(env, shell_data.java_object, progress); } // static
diff --git a/content/shell/browser/shell_platform_delegate_aura.cc b/content/shell/browser/shell_platform_delegate_aura.cc index e440d5cdd..782d92c3 100644 --- a/content/shell/browser/shell_platform_delegate_aura.cc +++ b/content/shell/browser/shell_platform_delegate_aura.cc
@@ -34,29 +34,25 @@ void ShellPlatformDelegate::CreatePlatformWindow( Shell* shell, const gfx::Size& initial_size) { - ShellData* shell_data = new ShellData; - shell->set_platform_data(shell_data); + DCHECK(!base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; if (!shell->headless()) platform_->aura->ShowWindow(); platform_->aura->ResizeWindow(initial_size); - shell_data->window = platform_->aura->host()->window(); + shell_data.window = platform_->aura->host()->window(); } gfx::NativeWindow ShellPlatformDelegate::GetNativeWindow(Shell* shell) { - ShellData* shell_data = shell->platform_data(); - return shell_data->window; + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; + return shell_data.window; } void ShellPlatformDelegate::CleanUp(Shell* shell) { - ShellData* shell_data = shell->platform_data(); - - // Any ShellData cleanup happens here. - - delete shell_data; - // This shouldn't be used anymore, but just in case. - shell->set_platform_data(nullptr); + DCHECK(base::Contains(shell_data_map_, shell)); + shell_data_map_.erase(shell); } void ShellPlatformDelegate::SetContents(Shell* shell) { @@ -84,6 +80,8 @@ void ShellPlatformDelegate::SetTitle(Shell* shell, const base::string16& title) {} +void ShellPlatformDelegate::RenderViewReady(Shell* shell) {} + bool ShellPlatformDelegate::DestroyShell(Shell* shell) { return false; // Shell destroys itself. }
diff --git a/content/shell/browser/shell_platform_delegate_mac.mm b/content/shell/browser/shell_platform_delegate_mac.mm index 750e302..3e543d4 100644 --- a/content/shell/browser/shell_platform_delegate_mac.mm +++ b/content/shell/browser/shell_platform_delegate_mac.mm
@@ -124,8 +124,7 @@ struct ShellPlatformDelegate::ShellData { gfx::NativeWindow window; - NSTextField* url_edit_view; - gfx::Size content_size; + NSTextField* url_edit_view = nullptr; }; struct ShellPlatformDelegate::PlatformData {}; @@ -140,13 +139,10 @@ void ShellPlatformDelegate::CreatePlatformWindow( Shell* shell, const gfx::Size& initial_size) { - ShellData* shell_data = new ShellData; - shell->set_platform_data(shell_data); + DCHECK(!shell->headless()); - if (shell->headless()) { - shell_data->content_size = initial_size; - return; - } + DCHECK(!base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; int width = initial_size.width(); int height = initial_size.height(); @@ -214,42 +210,35 @@ [url_edit_view setAction:@selector(takeURLStringValueFrom:)]; [[url_edit_view cell] setWraps:NO]; [[url_edit_view cell] setScrollable:YES]; - shell_data->url_edit_view = url_edit_view.get(); + shell_data.url_edit_view = url_edit_view.get(); } // Show the new window. [window makeKeyAndOrderFront:nil]; - shell_data->window = window; + shell_data.window = window; } gfx::NativeWindow ShellPlatformDelegate::GetNativeWindow(Shell* shell) { - ShellData* shell_data = shell->platform_data(); - return shell_data->window; + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; + + return shell_data.window; } void ShellPlatformDelegate::CleanUp(Shell* shell) { - ShellData* shell_data = shell->platform_data(); - - // Any ShellData cleanup happens here. - - delete shell_data; - // This shouldn't be used anymore, but just in case. - shell->set_platform_data(nullptr); + DCHECK(base::Contains(shell_data_map_, shell)); + shell_data_map_.erase(shell); } void ShellPlatformDelegate::SetContents(Shell* shell) { - ShellData* shell_data = shell->platform_data(); + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; NSView* web_view = shell->web_contents()->GetNativeView().GetNativeNSView(); [web_view setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; - if (shell->headless()) { - ResizeWebContent(shell, shell_data->content_size); - return; - } - - NSView* content = [shell_data->window.GetNativeNSWindow() contentView]; + NSView* content = [shell_data.window.GetNativeNSWindow() contentView]; [content addSubview:web_view]; NSRect frame = [content bounds]; @@ -261,28 +250,24 @@ void ShellPlatformDelegate::ResizeWebContent(Shell* shell, const gfx::Size& content_size) { - ShellData* shell_data = shell->platform_data(); + DCHECK(!shell->headless()); - if (!shell->headless()) { - int toolbar_height = Shell::ShouldHideToolbar() ? 0 : kURLBarHeight; - NSRect frame = NSMakeRect(0, 0, content_size.width(), - content_size.height() + toolbar_height); - [shell_data->window.GetNativeNSWindow().contentView setFrame:frame]; - return; - } + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; - NSView* web_view = shell->web_contents()->GetNativeView().GetNativeNSView(); - NSRect frame = NSMakeRect(0, 0, content_size.width(), content_size.height()); - [web_view setFrame:frame]; + int toolbar_height = Shell::ShouldHideToolbar() ? 0 : kURLBarHeight; + NSRect frame = NSMakeRect(0, 0, content_size.width(), + content_size.height() + toolbar_height); + [shell_data.window.GetNativeNSWindow().contentView setFrame:frame]; } void ShellPlatformDelegate::EnableUIControl(Shell* shell, UIControl control, bool is_enabled) { - if (shell->headless()) - return; + DCHECK(!shell->headless()); - ShellData* shell_data = shell->platform_data(); + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; int id; switch (control) { @@ -299,99 +284,89 @@ NOTREACHED() << "Unknown UI control"; return; } - [[[shell_data->window.GetNativeNSWindow() contentView] viewWithTag:id] + [[[shell_data.window.GetNativeNSWindow() contentView] viewWithTag:id] setEnabled:is_enabled]; } void ShellPlatformDelegate::SetAddressBarURL(Shell* shell, const GURL& url) { - if (shell->headless() || Shell::ShouldHideToolbar()) + DCHECK(!shell->headless()); + + if (Shell::ShouldHideToolbar()) return; - ShellData* shell_data = shell->platform_data(); + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; NSString* url_string = base::SysUTF8ToNSString(url.spec()); - [shell_data->url_edit_view setStringValue:url_string]; + [shell_data.url_edit_view setStringValue:url_string]; } void ShellPlatformDelegate::SetIsLoading(Shell* shell, bool loading) {} void ShellPlatformDelegate::SetTitle(Shell* shell, const base::string16& title) { - if (shell->headless()) - return; + DCHECK(!shell->headless()); - ShellData* shell_data = shell->platform_data(); + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; NSString* title_string = base::SysUTF16ToNSString(title); - [shell_data->window.GetNativeNSWindow() setTitle:title_string]; + [shell_data.window.GetNativeNSWindow() setTitle:title_string]; +} + +void ShellPlatformDelegate::RenderViewReady(Shell* shell) { + DCHECK(!shell->headless()); } bool ShellPlatformDelegate::DestroyShell(Shell* shell) { - if (shell->headless()) - return false; // Shell destroys itself. + DCHECK(!shell->headless()); - ShellData* shell_data = shell->platform_data(); + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; - [shell_data->window.GetNativeNSWindow() performClose:nil]; + [shell_data.window.GetNativeNSWindow() performClose:nil]; return true; // The performClose() will do the destruction of Shell. } void ShellPlatformDelegate::ActivateContents(Shell* shell, WebContents* top_contents) { - ShellData* shell_data = shell->platform_data(); + DCHECK(!shell->headless()); - if (!shell->headless()) { - // This focuses the main frame RenderWidgetHost in the window, but does not - // make the window itself active. The WebContentsDelegate (this class) is - // responsible for doing both. - top_contents->Focus(); - // This makes the window the active window for the application, and when the - // app is active, the window will be also. That makes all RenderWidgetHosts - // for the window active (which is separate from focused on mac). - [shell_data->window.GetNativeNSWindow() makeKeyAndOrderFront:nil]; - // This makes the application active so that we can actually move focus - // between windows and the renderer can receive focus/blur events. - [NSApp activateIgnoringOtherApps:YES]; - return; - } + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; - // In headless mode, there are no system windows, so we can't go down the - // normal path which relies on calling the OS to move focus/active states. - // Instead we fake it out by just informing the RenderWidgetHost directly. - - // For all windows other than this one, blur them. - for (Shell* window : Shell::windows()) { - if (window != shell) { - WebContents* other_top_contents = window->web_contents(); - RenderWidgetHost* other_main_widget = - other_top_contents->GetMainFrame()->GetView()->GetRenderWidgetHost(); - other_main_widget->Blur(); - other_main_widget->SetActive(false); - } - } - - RenderWidgetHost* main_widget = - top_contents->GetMainFrame()->GetView()->GetRenderWidgetHost(); - main_widget->Focus(); - main_widget->SetActive(true); + // This focuses the main frame RenderWidgetHost in the window, but does not + // make the window itself active. The WebContentsDelegate (this class) is + // responsible for doing both. + top_contents->Focus(); + // This makes the window the active window for the application, and when the + // app is active, the window will be also. That makes all RenderWidgetHosts + // for the window active (which is separate from focused on mac). + [shell_data.window.GetNativeNSWindow() makeKeyAndOrderFront:nil]; + // This makes the application active so that we can actually move focus + // between windows and the renderer can receive focus/blur events. + [NSApp activateIgnoringOtherApps:YES]; } bool ShellPlatformDelegate::HandleKeyboardEvent( Shell* shell, WebContents* source, const NativeWebKeyboardEvent& event) { - if (event.skip_in_browser || shell->headless() || Shell::ShouldHideToolbar()) + DCHECK(!shell->headless()); + + if (event.skip_in_browser || Shell::ShouldHideToolbar()) return false; - ShellData* shell_data = shell->platform_data(); + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; // The event handling to get this strictly right is a tangle; cheat here a bit // by just letting the menus have a chance at it. if ([event.os_event type] == NSKeyDown) { if (([event.os_event modifierFlags] & NSCommandKeyMask) && [[event.os_event characters] isEqual:@"l"]) { - [shell_data->window.GetNativeNSWindow() - makeFirstResponder:shell_data->url_edit_view]; + [shell_data.window.GetNativeNSWindow() + makeFirstResponder:shell_data.url_edit_view]; return true; }
diff --git a/content/shell/browser/shell_platform_delegate_views.cc b/content/shell/browser/shell_platform_delegate_views.cc index c8ef8a8..a6ca40c3 100644 --- a/content/shell/browser/shell_platform_delegate_views.cc +++ b/content/shell/browser/shell_platform_delegate_views.cc
@@ -356,10 +356,10 @@ void ShellPlatformDelegate::CreatePlatformWindow( Shell* shell, const gfx::Size& initial_size) { - ShellData* shell_data = new ShellData; - shell->set_platform_data(shell_data); + DCHECK(!base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; - shell_data->content_size = initial_size; + shell_data.content_size = initial_size; if (shell->headless()) { if (!platform_->aura) @@ -370,18 +370,18 @@ } #if defined(OS_CHROMEOS) - shell_data->window_widget = views::Widget::CreateWindowWithContext( + shell_data.window_widget = views::Widget::CreateWindowWithContext( new ShellWindowDelegateView(shell), platform_->wm_test_helper->GetDefaultParent(nullptr, gfx::Rect()), gfx::Rect(initial_size)); #else - shell_data->window_widget = new views::Widget(); + shell_data.window_widget = new views::Widget(); views::Widget::InitParams params; params.bounds = gfx::Rect(initial_size); params.delegate = new ShellWindowDelegateView(shell); params.wm_class_class = "chromium-content_shell"; params.wm_class_name = params.wm_class_class; - shell_data->window_widget->Init(std::move(params)); + shell_data.window_widget->Init(std::move(params)); #endif // |window_widget| is made visible in PlatformSetContents(), so that the @@ -389,20 +389,20 @@ } gfx::NativeWindow ShellPlatformDelegate::GetNativeWindow(Shell* shell) { - ShellData* shell_data = shell->platform_data(); - return shell_data->window_widget->GetNativeWindow(); + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; + + return shell_data.window_widget->GetNativeWindow(); } void ShellPlatformDelegate::CleanUp(Shell* shell) { - ShellData* shell_data = shell->platform_data(); - - delete shell_data; - // This shouldn't be used anymore, but just in case. - shell->set_platform_data(nullptr); + DCHECK(base::Contains(shell_data_map_, shell)); + shell_data_map_.erase(shell); } void ShellPlatformDelegate::SetContents(Shell* shell) { - ShellData* shell_data = shell->platform_data(); + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; if (shell->headless()) { aura::Window* content = shell->web_contents()->GetNativeView(); @@ -414,20 +414,20 @@ content->MoveCursorTo(gfx::Point()); content->Show(); } - content->SetBounds(gfx::Rect(shell_data->content_size)); + content->SetBounds(gfx::Rect(shell_data.content_size)); RenderWidgetHostView* host_view = shell->web_contents()->GetRenderWidgetHostView(); if (host_view) - host_view->SetSize(shell_data->content_size); + host_view->SetSize(shell_data.content_size); } else { views::WidgetDelegate* widget_delegate = - shell_data->window_widget->widget_delegate(); + shell_data.window_widget->widget_delegate(); auto* delegate_view = static_cast<ShellWindowDelegateView*>(widget_delegate); delegate_view->SetWebContents(shell->web_contents(), - shell_data->content_size); - shell_data->window_widget->GetNativeWindow()->GetHost()->Show(); - shell_data->window_widget->Show(); + shell_data.content_size); + shell_data.window_widget->GetNativeWindow()->GetHost()->Show(); + shell_data.window_widget->Show(); } } @@ -442,10 +442,11 @@ if (shell->headless() || Shell::ShouldHideToolbar()) return; - ShellData* shell_data = shell->platform_data(); + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; auto* delegate_view = static_cast<ShellWindowDelegateView*>( - shell_data->window_widget->widget_delegate()); + shell_data.window_widget->widget_delegate()); if (control == BACK_BUTTON) { delegate_view->EnableUIControl(ShellWindowDelegateView::BACK_BUTTON, is_enabled); @@ -462,10 +463,11 @@ if (shell->headless() || Shell::ShouldHideToolbar()) return; - ShellData* shell_data = shell->platform_data(); + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; auto* delegate_view = static_cast<ShellWindowDelegateView*>( - shell_data->window_widget->widget_delegate()); + shell_data.window_widget->widget_delegate()); delegate_view->SetAddressBarURL(url); } @@ -476,21 +478,25 @@ if (shell->headless()) return; - ShellData* shell_data = shell->platform_data(); + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; auto* delegate_view = static_cast<ShellWindowDelegateView*>( - shell_data->window_widget->widget_delegate()); + shell_data.window_widget->widget_delegate()); delegate_view->SetWindowTitle(title); - shell_data->window_widget->UpdateWindowTitle(); + shell_data.window_widget->UpdateWindowTitle(); } +void ShellPlatformDelegate::RenderViewReady(Shell* shell) {} + bool ShellPlatformDelegate::DestroyShell(Shell* shell) { if (shell->headless()) return false; // Shell destroys itself. - ShellData* shell_data = shell->platform_data(); + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; - shell_data->window_widget->CloseNow(); + shell_data.window_widget->CloseNow(); return true; // The CloseNow() will do the destruction of Shell. }
diff --git a/content/shell/browser/web_test/DEPS b/content/shell/browser/web_test/DEPS index cb25ec5..b662c4d 100644 --- a/content/shell/browser/web_test/DEPS +++ b/content/shell/browser/web_test/DEPS
@@ -1,3 +1,11 @@ include_rules = [ "+content/shell/common/web_test", ] + +specific_include_rules = { + # cc (and mm) files do not leak includes so they are allowed to reference + # //content/browser. + ".*\.(cc|mm)": [ + "+content/browser", + ], +}
diff --git a/content/shell/browser/web_test/web_test_browser_main_parts.cc b/content/shell/browser/web_test/web_test_browser_main_parts.cc index 8309fcfe..f3e858f 100644 --- a/content/shell/browser/web_test/web_test_browser_main_parts.cc +++ b/content/shell/browser/web_test/web_test_browser_main_parts.cc
@@ -20,6 +20,7 @@ #include "content/shell/browser/shell_browser_context.h" #include "content/shell/browser/shell_devtools_manager_delegate.h" #include "content/shell/browser/web_test/web_test_browser_context.h" +#include "content/shell/browser/web_test/web_test_shell_platform_delegate.h" #include "content/shell/common/shell_switches.h" #include "net/base/filename_util.h" #include "net/base/net_module.h" @@ -61,4 +62,9 @@ #endif } +std::unique_ptr<ShellPlatformDelegate> +WebTestBrowserMainParts::CreateShellPlatformDelegate() { + return std::make_unique<WebTestShellPlatformDelegate>(); +} + } // namespace content
diff --git a/content/shell/browser/web_test/web_test_browser_main_parts.h b/content/shell/browser/web_test/web_test_browser_main_parts.h index ee6c7789..e9a80af7 100644 --- a/content/shell/browser/web_test/web_test_browser_main_parts.h +++ b/content/shell/browser/web_test/web_test_browser_main_parts.h
@@ -22,8 +22,10 @@ ~WebTestBrowserMainParts() override; private: + // ShellBrowserMainParts overrides. void InitializeBrowserContexts() override; void InitializeMessageLoopContext() override; + std::unique_ptr<ShellPlatformDelegate> CreateShellPlatformDelegate() override; #if BUILDFLAG(ENABLE_PLUGINS) std::unique_ptr<ShellPluginServiceFilter> plugin_service_filter_;
diff --git a/content/shell/browser/web_test/web_test_control_host.cc b/content/shell/browser/web_test/web_test_control_host.cc index 6e6882b..6662027f 100644 --- a/content/shell/browser/web_test/web_test_control_host.cc +++ b/content/shell/browser/web_test/web_test_control_host.cc
@@ -512,37 +512,39 @@ browser_context->GetClientHintsControllerDelegate()->ResetForTesting(); - initial_size_ = Shell::GetShellDefaultSize(); + const gfx::Size window_size = Shell::GetShellDefaultSize(); + if (!main_window_) { main_window_ = content::Shell::CreateNewWindow( - browser_context, GURL(url::kAboutBlankURL), nullptr, initial_size_); + browser_context, GURL(url::kAboutBlankURL), nullptr, window_size); WebContentsObserver::Observe(main_window_->web_contents()); current_pid_ = base::kNullProcessId; - default_prefs_ = main_window_->web_contents() - ->GetRenderViewHost() - ->GetWebkitPreferences(); - } else { + RenderViewHost* render_view_host = main_window_->web_contents()->GetRenderViewHost(); - RenderWidgetHost* render_widget_host = render_view_host->GetWidget(); - + default_prefs_ = render_view_host->GetWebkitPreferences(); + } else { // Set a different size first to reset the possibly inconsistent state // caused by the previous test using unfortunate synchronous resize mode. // This forces SetSize() not to early return which would otherwise happen - // when we set the size to initial_size_ which is the same as its current + // when we set the size to |window_size| which is the same as its current // size. See http://crbug.com/1011191 for more details. - render_widget_host->GetView()->SetSize( - gfx::ScaleToCeiledSize(initial_size_, 0.5, 1)); - render_widget_host->GetView()->SetSize(initial_size_); + // TODO(crbug.com/309760): This resize to half-size could go away if + // testRunner.useUnfortunateSynchronousResizeMode() goes away. + main_window_->ResizeWebContentForTests( + gfx::ScaleToCeiledSize(window_size, 0.5f, 1)); + main_window_->ResizeWebContentForTests(window_size); + RenderViewHost* render_view_host = + main_window_->web_contents()->GetRenderViewHost(); render_view_host->UpdateWebkitPreferences(default_prefs_); } if (is_devtools_js_test && !secondary_window_) { secondary_window_ = content::Shell::CreateNewWindow( ShellContentBrowserClient::Get()->browser_context(), - GURL(url::kAboutBlankURL), nullptr, initial_size_); + GURL(url::kAboutBlankURL), nullptr, window_size); } // The main frame is constructed along with the Shell, which is before we can @@ -1089,7 +1091,6 @@ base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kAllowExternalPages); params->expected_pixel_hash = expected_pixel_hash_; - params->initial_size = initial_size_; params->protocol_mode = protocol_mode_; if (did_send_initial_test_configuration_) {
diff --git a/content/shell/browser/web_test/web_test_control_host.h b/content/shell/browser/web_test/web_test_control_host.h index 0d212b52..960a782 100644 --- a/content/shell/browser/web_test/web_test_control_host.h +++ b/content/shell/browser/web_test/web_test_control_host.h
@@ -41,7 +41,6 @@ class SkBitmap; namespace content { - class DevToolsProtocolTestBindings; class RenderFrameHost; class Shell; @@ -265,6 +264,12 @@ void CompositeNodeQueueThen(base::OnceCallback<void()> callback); void BuildDepthFirstQueue(Node* node); +#if defined(OS_MACOSX) + // Bypasses system APIs to force a resize on the RenderWidgetHostView when in + // headless web tests. + static void PlatformResizeWindowMac(Shell* shell, const gfx::Size& size); +#endif + public: std::unique_ptr<WebTestResultPrinter> printer_; @@ -292,7 +297,6 @@ // Per test config. std::string expected_pixel_hash_; - gfx::Size initial_size_; GURL test_url_; bool protocol_mode_;
diff --git a/content/shell/browser/web_test/web_test_shell_platform_delegate.cc b/content/shell/browser/web_test/web_test_shell_platform_delegate.cc new file mode 100644 index 0000000..b3a8727 --- /dev/null +++ b/content/shell/browser/web_test/web_test_shell_platform_delegate.cc
@@ -0,0 +1,18 @@ +// 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 "content/shell/browser/web_test/web_test_shell_platform_delegate.h" + +namespace content { + +// When other platforms define their own implementation of +// WebTestShellPlatformDelegate, move their implementation of these to their +// platform-specific file so they can see the definition of their own +// WebTestShellData. +#if !defined(OS_MACOSX) +WebTestShellPlatformDelegate::WebTestShellPlatformDelegate() = default; +WebTestShellPlatformDelegate::~WebTestShellPlatformDelegate() = default; +#endif + +} // namespace content
diff --git a/content/shell/browser/web_test/web_test_shell_platform_delegate.h b/content/shell/browser/web_test/web_test_shell_platform_delegate.h new file mode 100644 index 0000000..ceb5711 --- /dev/null +++ b/content/shell/browser/web_test/web_test_shell_platform_delegate.h
@@ -0,0 +1,53 @@ +// 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 CONTENT_SHELL_BROWSER_WEB_TEST_WEB_TEST_SHELL_PLATFORM_DELEGATE_H_ +#define CONTENT_SHELL_BROWSER_WEB_TEST_WEB_TEST_SHELL_PLATFORM_DELEGATE_H_ + +#include "build/build_config.h" +#include "content/shell/browser/shell_platform_delegate.h" + +namespace content { + +class WebTestShellPlatformDelegate : public ShellPlatformDelegate { + public: + WebTestShellPlatformDelegate(); + ~WebTestShellPlatformDelegate() override; + +#if defined(OS_MACOSX) + // ShellPlatformDelegate overrides. + void CreatePlatformWindow(Shell* shell, + const gfx::Size& initial_size) override; + gfx::NativeWindow GetNativeWindow(Shell* shell) override; + void CleanUp(Shell* shell) override; + void SetContents(Shell* shell) override; + void EnableUIControl(Shell* shell, + UIControl control, + bool is_enabled) override; + void SetAddressBarURL(Shell* shell, const GURL& url) override; + void SetTitle(Shell* shell, const base::string16& title) override; + void RenderViewReady(Shell* shell) override; + bool DestroyShell(Shell* shell) override; + void ResizeWebContent(Shell* shell, const gfx::Size& content_size) override; + void ActivateContents(Shell* shell, WebContents* top_contents) override; + bool HandleKeyboardEvent(Shell* shell, + WebContents* source, + const NativeWebKeyboardEvent& event) override; +#endif + + private: +#if defined(OS_MACOSX) + // Data held for each Shell instance, since there is one ShellPlatformDelegate + // for the whole browser process (shared across Shells). This is defined for + // each platform implementation. + struct WebTestShellData; + + // Holds an instance of WebTestShellData for each Shell. + base::flat_map<Shell*, WebTestShellData> web_test_shell_data_map_; +#endif +}; + +} // namespace content + +#endif // CONTENT_SHELL_BROWSER_WEB_TEST_WEB_TEST_SHELL_PLATFORM_DELEGATE_H_
diff --git a/content/shell/browser/web_test/web_test_shell_platform_delegate_mac.mm b/content/shell/browser/web_test/web_test_shell_platform_delegate_mac.mm new file mode 100644 index 0000000..60bcb96 --- /dev/null +++ b/content/shell/browser/web_test/web_test_shell_platform_delegate_mac.mm
@@ -0,0 +1,183 @@ +// 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 "content/shell/browser/web_test/web_test_shell_platform_delegate.h" + +#import "base/mac/foundation_util.h" +#include "content/browser/renderer_host/render_widget_host_view_mac.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/render_widget_host.h" +#include "content/shell/browser/shell.h" + +namespace content { + +// On mac, the WebTestShellPlatformDelegate replaces behaviour in the base class +// ShellPlatformDelegate when in headless mode. Otherwise it defers to +// the base class. +// TODO(danakj): Maybe we should only instatiate a WebTestShellPlatformDelegate +// when in headless mode? Depends on the needs of other platforms. + +struct WebTestShellPlatformDelegate::WebTestShellData { + gfx::Size initial_size; +}; + +WebTestShellPlatformDelegate::WebTestShellPlatformDelegate() = default; +WebTestShellPlatformDelegate::~WebTestShellPlatformDelegate() = default; + +void WebTestShellPlatformDelegate::CreatePlatformWindow( + Shell* shell, + const gfx::Size& initial_size) { + if (!shell->headless()) { + ShellPlatformDelegate::CreatePlatformWindow(shell, initial_size); + return; + } + + DCHECK(!base::Contains(web_test_shell_data_map_, shell)); + WebTestShellData& shell_data = web_test_shell_data_map_[shell]; + + shell_data.initial_size = initial_size; +} + +gfx::NativeWindow WebTestShellPlatformDelegate::GetNativeWindow(Shell* shell) { + if (!shell->headless()) + return ShellPlatformDelegate::GetNativeWindow(shell); + + NOTREACHED(); + return {}; +} + +void WebTestShellPlatformDelegate::CleanUp(Shell* shell) { + if (!shell->headless()) { + ShellPlatformDelegate::GetNativeWindow(shell); + return; + } + + DCHECK(base::Contains(web_test_shell_data_map_, shell)); + web_test_shell_data_map_.erase(shell); +} + +void WebTestShellPlatformDelegate::SetContents(Shell* shell) { + if (!shell->headless()) { + ShellPlatformDelegate::SetContents(shell); + return; + } +} + +void WebTestShellPlatformDelegate::EnableUIControl(Shell* shell, + UIControl control, + bool is_enabled) { + if (!shell->headless()) { + ShellPlatformDelegate::EnableUIControl(shell, control, is_enabled); + return; + } +} + +void WebTestShellPlatformDelegate::SetAddressBarURL(Shell* shell, + const GURL& url) { + if (!shell->headless()) { + ShellPlatformDelegate::SetAddressBarURL(shell, url); + return; + } +} + +void WebTestShellPlatformDelegate::SetTitle(Shell* shell, + const base::string16& title) { + if (!shell->headless()) { + ShellPlatformDelegate::SetTitle(shell, title); + return; + } +} + +void WebTestShellPlatformDelegate::RenderViewReady(Shell* shell) { + if (!shell->headless()) { + ShellPlatformDelegate::RenderViewReady(shell); + return; + } + + DCHECK(base::Contains(web_test_shell_data_map_, shell)); + WebTestShellData& shell_data = web_test_shell_data_map_[shell]; + + // In mac headless mode, the OS view for the WebContents is not attached to a + // window so the usual notifications from the OS about the bounds of the web + // contents do not occur. We need to make sure the renderer knows its bounds, + // and to do this we force a resize to happen on the WebContents. However, the + // WebContents can not be fully resized until after the RenderWidgetHostView + // is created, which may not be not done until the first navigation starts. + // Failing to do this resize *after* the navigation causes the + // RenderWidgetHostView to be created would leave the WebContents with invalid + // sizes (such as the window screen rect). + // + // We use the signal that the RenderView has been created in the renderer as + // a proxy for knowing when the top level RenderWidgetHostView is created, + // since they are created at the same time. + DCHECK(shell->web_contents()->GetMainFrame()->GetView()); + ResizeWebContent(shell, shell_data.initial_size); +} + +bool WebTestShellPlatformDelegate::DestroyShell(Shell* shell) { + if (shell->headless()) + return false; // Shell destroys itself. + return ShellPlatformDelegate::DestroyShell(shell); +} + +void WebTestShellPlatformDelegate::ResizeWebContent( + Shell* shell, + const gfx::Size& content_size) { + if (!shell->headless()) { + ShellPlatformDelegate::ResizeWebContent(shell, content_size); + return; + } + + NSView* web_view = shell->web_contents()->GetNativeView().GetNativeNSView(); + NSRect frame = NSMakeRect(0, 0, content_size.width(), content_size.height()); + [web_view setFrame:frame]; + + // The above code changes the RenderWidgetHostView's size, but does not change + // the widget's screen rects, since the RenerWidgetHostView is not attached to + // a window in headless mode. So this call causes them to be updated so they + // are not left as 0x0. + auto* rwhv_mac = static_cast<RenderWidgetHostViewMac*>( + shell->web_contents()->GetMainFrame()->GetView()); + if (rwhv_mac) + rwhv_mac->OnWindowFrameInScreenChanged(gfx::Rect(content_size)); +} + +void WebTestShellPlatformDelegate::ActivateContents(Shell* shell, + WebContents* top_contents) { + if (!shell->headless()) { + ShellPlatformDelegate::ActivateContents(shell, top_contents); + return; + } + + // In headless mode, there are no system windows, so we can't go down the + // normal path which relies on calling the OS to move focus/active states. + // Instead we fake it out by just informing the RenderWidgetHost directly. + + // For all windows other than this one, blur them. + for (Shell* window : Shell::windows()) { + if (window != shell) { + WebContents* other_top_contents = window->web_contents(); + RenderWidgetHost* other_main_widget = + other_top_contents->GetMainFrame()->GetView()->GetRenderWidgetHost(); + other_main_widget->Blur(); + other_main_widget->SetActive(false); + } + } + + RenderWidgetHost* main_widget = + top_contents->GetMainFrame()->GetView()->GetRenderWidgetHost(); + main_widget->Focus(); + main_widget->SetActive(true); +} + +bool WebTestShellPlatformDelegate::HandleKeyboardEvent( + Shell* shell, + WebContents* source, + const NativeWebKeyboardEvent& event) { + if (shell->headless()) + return false; + return ShellPlatformDelegate::HandleKeyboardEvent(shell, source, event); +} + +} // namespace content
diff --git a/content/shell/common/web_test/web_test.mojom b/content/shell/common/web_test/web_test.mojom index 90420a5..6193f47 100644 --- a/content/shell/common/web_test/web_test.mojom +++ b/content/shell/common/web_test/web_test.mojom
@@ -29,9 +29,6 @@ // The expected MD5 hash of the pixel results. string expected_pixel_hash; - // The initial size of the test window. - gfx.mojom.Size initial_size; - // Whether the test is running in protocol mode. // See TestInfo::protocol_mode in browser/web_test/test_info_extractor.h. bool protocol_mode;
diff --git a/content/shell/renderer/web_test/accessibility_controller.cc b/content/shell/renderer/web_test/accessibility_controller.cc index 3f077bb..ef2a119 100644 --- a/content/shell/renderer/web_test/accessibility_controller.cc +++ b/content/shell/renderer/web_test/accessibility_controller.cc
@@ -4,8 +4,6 @@ #include "content/shell/renderer/web_test/accessibility_controller.h" -#include <string> - #include "base/stl_util.h" #include "content/shell/renderer/web_test/blink_test_runner.h" #include "content/shell/renderer/web_test/web_view_test_proxy.h" @@ -176,17 +174,19 @@ void AccessibilityController::NotificationReceived( blink::WebLocalFrame* frame, const blink::WebAXObject& target, - const std::string& notification_name) { + const std::string& notification_name, + const std::vector<ui::AXEventIntent>& event_intents) { frame->GetTaskRunner(blink::TaskType::kInternalTest) ->PostTask(FROM_HERE, base::BindOnce(&AccessibilityController::PostNotification, weak_factory_.GetWeakPtr(), target, - notification_name)); + notification_name, event_intents)); } void AccessibilityController::PostNotification( const blink::WebAXObject& target, - const std::string& notification_name) { + const std::string& notification_name, + const std::vector<ui::AXEventIntent>& event_intents) { v8::Isolate* isolate = blink::MainThreadIsolate(); v8::HandleScope handle_scope(isolate); @@ -209,7 +209,7 @@ WebAXObjectProxy* element; bool result = gin::ConvertFromV8(isolate, element_handle, &element); DCHECK(result); - element->NotificationReceived(local_frame, notification_name); + element->NotificationReceived(local_frame, notification_name, event_intents); if (notification_callback_.IsEmpty()) return;
diff --git a/content/shell/renderer/web_test/accessibility_controller.h b/content/shell/renderer/web_test/accessibility_controller.h index 5c51800..5932e6b 100644 --- a/content/shell/renderer/web_test/accessibility_controller.h +++ b/content/shell/renderer/web_test/accessibility_controller.h
@@ -7,17 +7,23 @@ #include <vector> +#include <memory> +#include <string> + #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "content/shell/renderer/web_test/web_ax_object_proxy.h" #include "third_party/blink/public/web/web_ax_object.h" +#include "ui/accessibility/ax_event_intent.h" #include "v8/include/v8.h" namespace blink { + class WebAXContext; class WebLocalFrame; class WebString; class WebView; + } // namespace blink namespace content { @@ -32,11 +38,14 @@ void Reset(); void Install(blink::WebLocalFrame* frame); bool ShouldLogAccessibilityEvents(); - void NotificationReceived(blink::WebLocalFrame* frame, - const blink::WebAXObject& target, - const std::string& notification_name); + void NotificationReceived( + blink::WebLocalFrame* frame, + const blink::WebAXObject& target, + const std::string& notification_name, + const std::vector<ui::AXEventIntent>& event_intents); void PostNotification(const blink::WebAXObject& target, - const std::string& notification_name); + const std::string& notification_name, + const std::vector<ui::AXEventIntent>& event_intents); private: friend class AccessibilityControllerBindings;
diff --git a/content/shell/renderer/web_test/blink_test_runner.cc b/content/shell/renderer/web_test/blink_test_runner.cc index 5dbbf71e..53999a9 100644 --- a/content/shell/renderer/web_test/blink_test_runner.cc +++ b/content/shell/renderer/web_test/blink_test_runner.cc
@@ -516,17 +516,6 @@ // Allows the window to receive replicated WebTestRuntimeFlags and to // control or end the test. interfaces->SetTestIsRunning(true); - - // All non-main windows get sized to 800x600 (so does the main window). - // This is done for the main frame only, not child local roots in other - // processes. - if (web_view_test_proxy_->GetMainRenderFrame()) { - RenderWidget* widget = - web_view_test_proxy_->GetMainRenderFrame()->GetLocalRootRenderWidget(); - gfx::Rect window_rect(widget->WindowRect().x, widget->WindowRect().y, 800, - 600); - widget->SetWindowRectSynchronouslyForTesting(window_rect); - } } void BlinkTestRunner::ApplyTestConfiguration( @@ -551,15 +540,7 @@ mojom::WebTestRunTestConfigurationPtr params) { DCHECK(web_view_test_proxy_->GetMainRenderFrame()); - gfx::Size window_size = params->initial_size; - ApplyTestConfiguration(std::move(params)); - - RenderWidget* widget = - web_view_test_proxy_->GetMainRenderFrame()->GetLocalRootRenderWidget(); - gfx::Rect window_rect(widget->WindowRect().x, widget->WindowRect().y, - window_size.width(), window_size.height()); - widget->SetWindowRectSynchronouslyForTesting(window_rect); } void BlinkTestRunner::OnResetRendererAfterWebTest() {
diff --git a/content/shell/renderer/web_test/pixel_dump.cc b/content/shell/renderer/web_test/pixel_dump.cc index ded031a3..33137ba 100644 --- a/content/shell/renderer/web_test/pixel_dump.cc +++ b/content/shell/renderer/web_test/pixel_dump.cc
@@ -86,20 +86,18 @@ } void CopyImageAtAndCapturePixels( - blink::WebLocalFrame* web_frame, + RenderFrame* frame, int x, int y, base::OnceCallback<void(const SkBitmap&)> callback) { mojo::Remote<blink::mojom::ClipboardHost> clipboard; - content::RenderFrame* render_frame = - content::RenderFrame::FromWebFrame(web_frame); - render_frame->GetBrowserInterfaceBroker()->GetInterface( + frame->GetBrowserInterfaceBroker()->GetInterface( clipboard.BindNewPipeAndPassReceiver()); uint64_t sequence_number_before = 0; clipboard->GetSequenceNumber(ui::ClipboardBuffer::kCopyPaste, &sequence_number_before); - web_frame->CopyImageAtForTesting(gfx::Point(x, y)); + frame->GetWebFrame()->CopyImageAtForTesting(gfx::Point(x, y)); uint64_t sequence_number_after = 0; while (sequence_number_before == sequence_number_after) { clipboard->GetSequenceNumber(ui::ClipboardBuffer::kCopyPaste,
diff --git a/content/shell/renderer/web_test/pixel_dump.h b/content/shell/renderer/web_test/pixel_dump.h index 66a99ed1..1c550a3 100644 --- a/content/shell/renderer/web_test/pixel_dump.h +++ b/content/shell/renderer/web_test/pixel_dump.h
@@ -14,15 +14,16 @@ } // namespace blink namespace content { +class RenderFrame; // Asks |web_frame| to print itself and calls |callback| with the result. void PrintFrameAsync(blink::WebLocalFrame* web_frame, base::OnceCallback<void(const SkBitmap&)> callback); -// Copy to clipboard the image present at |x|, |y| coordinates in |web_frame| +// Copy to clipboard the image present at |x|, |y| coordinates in |frame| // and pass the captured image to |callback|. void CopyImageAtAndCapturePixels( - blink::WebLocalFrame* web_frame, + RenderFrame* frame, int x, int y, base::OnceCallback<void(const SkBitmap&)> callback);
diff --git a/content/shell/renderer/web_test/test_runner.cc b/content/shell/renderer/web_test/test_runner.cc index 596fd905..860ae2d 100644 --- a/content/shell/renderer/web_test/test_runner.cc +++ b/content/shell/renderer/web_test/test_runner.cc
@@ -21,6 +21,7 @@ #include "build/build_config.h" #include "cc/paint/paint_canvas.h" #include "content/public/common/use_zoom_for_dsf_policy.h" +#include "content/renderer/render_thread_impl.h" #include "content/shell/common/web_test/web_test_constants.h" #include "content/shell/common/web_test/web_test_string_util.h" #include "content/shell/renderer/web_test/app_banner_service.h" @@ -46,6 +47,7 @@ #include "third_party/blink/public/mojom/app_banner/app_banner.mojom.h" #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" #include "third_party/blink/public/platform/web_data.h" +#include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/platform/web_url_response.h" #include "third_party/blink/public/web/blink.h" #include "third_party/blink/public/web/web_array_buffer.h" @@ -55,6 +57,8 @@ #include "third_party/blink/public/web/web_frame.h" #include "third_party/blink/public/web/web_input_element.h" #include "third_party/blink/public/web/web_local_frame.h" +#include "third_party/blink/public/web/web_manifest_manager.h" +#include "third_party/blink/public/web/web_render_theme.h" #include "third_party/blink/public/web/web_script_source.h" #include "third_party/blink/public/web/web_security_policy.h" #include "third_party/blink/public/web/web_serialized_script_value.h" @@ -182,7 +186,6 @@ void FocusDevtoolsSecondaryWindow(); void ForceNextDrawingBufferCreationToFail(); void ForceNextWebGLContextCreationToFail(); - void ForceRedSelectionColors(); void GetBluetoothManualChooserEvents(v8::Local<v8::Function> callback); void GetManifestThen(v8::Local<v8::Function> callback); base::FilePath::StringType GetWritableDirectory(); @@ -262,7 +265,6 @@ void SetTextSubpixelPositioning(bool value); void SetTrustTokenKeyCommitments(const std::string& raw_commitments, v8::Local<v8::Function> callback); - void SetViewSourceForFrame(const std::string& name, bool enabled); void SetWillSendRequestClearHeader(const std::string& header); void SetWillSendRequestClearReferrer(); void SimulateBrowserWindowFocus(bool value); @@ -406,12 +408,16 @@ .SetMethod("addDisallowedURL", &TestRunnerBindings::NotImplemented) .SetMethod("addOriginAccessAllowListEntry", &TestRunnerBindings::AddOriginAccessAllowListEntry) + // Permits the adding of only one opaque overlay. May only be called from + // inside the main frame. .SetMethod("addWebPageOverlay", &TestRunnerBindings::AddWebPageOverlay) .SetMethod("capturePixelsAsyncThen", &TestRunnerBindings::CapturePixelsAsyncThen) .SetMethod("clearAllDatabases", &TestRunnerBindings::ClearAllDatabases) .SetMethod("clearBackForwardList", &TestRunnerBindings::NotImplemented) .SetMethod("clearPrinting", &TestRunnerBindings::ClearPrinting) + // Clears persistent Trust Tokens state in the browser. See + // https://github.com/wicg/trust-token-api. .SetMethod("clearTrustTokenState", &TestRunnerBindings::ClearTrustTokenState) .SetMethod("copyImageAtAndCapturePixelsAsyncThen", @@ -474,12 +480,13 @@ .SetMethod("findString", &TestRunnerBindings::FindString) .SetMethod("focusDevtoolsSecondaryWindow", &TestRunnerBindings::FocusDevtoolsSecondaryWindow) + // Sets a flag causing the next call to WebGLRenderingContext::Create() to + // fail. .SetMethod("forceNextDrawingBufferCreationToFail", &TestRunnerBindings::ForceNextDrawingBufferCreationToFail) + // Sets a flag causing the next call to DrawingBuffer::Create() to fail. .SetMethod("forceNextWebGLContextCreationToFail", &TestRunnerBindings::ForceNextWebGLContextCreationToFail) - .SetMethod("forceRedSelectionColors", - &TestRunnerBindings::ForceRedSelectionColors) // The Bluetooth functions are specified at // https://webbluetoothcg.github.io/web-bluetooth/tests/. @@ -490,10 +497,14 @@ &TestRunnerBindings::GetWritableDirectory) .SetMethod("insertStyleSheet", &TestRunnerBindings::InsertStyleSheet) .SetMethod("isChooserShown", &TestRunnerBindings::IsChooserShown) + // Checks if an internal editing command is currently available for the + // frame's document. .SetMethod("isCommandEnabled", &TestRunnerBindings::IsCommandEnabled) .SetMethod("keepWebHistory", &TestRunnerBindings::NotImplemented) .SetMethod("updateAllLifecyclePhasesAndComposite", &TestRunnerBindings::UpdateAllLifecyclePhasesAndComposite) + // Note, the reply callback is executed synchronously. Wrap in + // setTimeout() to run asynchronously. .SetMethod("updateAllLifecyclePhasesAndCompositeThen", &TestRunnerBindings::UpdateAllLifecyclePhasesAndCompositeThen) .SetMethod("setAnimationRequiresRaster", @@ -515,15 +526,26 @@ .SetMethod("queueReload", &TestRunnerBindings::QueueReload) .SetMethod("removeSpellCheckResolvedCallback", &TestRunnerBindings::RemoveSpellCheckResolvedCallback) + // Removes an overlay added by addWebPageOverlay(). May only be called + // from inside the main frame. .SetMethod("removeWebPageOverlay", &TestRunnerBindings::RemoveWebPageOverlay) .SetMethod("resolveBeforeInstallPromptPromise", &TestRunnerBindings::ResolveBeforeInstallPromptPromise) + // Immediately run all pending idle tasks, including all pending + // requestIdleCallback calls. Invoke the callback when all + // idle tasks are complete. .SetMethod("runIdleTasks", &TestRunnerBindings::RunIdleTasks) .SetMethod("selectionAsMarkup", &TestRunnerBindings::SelectionAsMarkup) // The Bluetooth functions are specified at // https://webbluetoothcg.github.io/web-bluetooth/tests/. + + // Calls the BluetoothChooser::EventHandler with the arguments here. Valid + // event strings are: + // * "cancel" - simulates the user canceling the chooser. + // * "select" - simulates the user selecting a device whose device ID is + // in the 2nd parameter. .SetMethod("sendBluetoothManualChooserEvent", &TestRunnerBindings::SendBluetoothManualChooserEvent) .SetMethod("setAcceptLanguages", &TestRunnerBindings::SetAcceptLanguages) @@ -536,10 +558,12 @@ .SetMethod("setAudioData", &TestRunnerBindings::SetAudioData) .SetMethod("setBackingScaleFactor", &TestRunnerBindings::SetBackingScaleFactor) - // The Bluetooth functions are specified at - // https://webbluetoothcg.github.io/web-bluetooth/tests/. + // Change the bluetooth test data while running a web test. .SetMethod("setBluetoothFakeAdapter", &TestRunnerBindings::SetBluetoothFakeAdapter) + // If |enable| is true, makes the Bluetooth chooser record its input and + // wait for instructions from the test program on how to proceed. + // Otherwise falls back to the browser's default chooser. .SetMethod("setBluetoothManualChooser", &TestRunnerBindings::SetBluetoothManualChooser) .SetMethod("setCallCloseOnWebViews", &TestRunnerBindings::NotImplemented) @@ -603,15 +627,17 @@ // elements or inserts a '\t' char in text area .SetMethod("setTabKeyCyclesThroughElements", &TestRunnerBindings::SetTabKeyCyclesThroughElements) + // Changes the direction of text for the frame's focused element. .SetMethod("setTextDirection", &TestRunnerBindings::SetTextDirection) .SetMethod("setTextSubpixelPositioning", &TestRunnerBindings::SetTextSubpixelPositioning) + // Sets the network service-global Trust Tokens key commitments. + // Takes a |raw_commitments| string that should be JSON-encoded according + // to the format expected by NetworkService::SetTrustTokenKeyCommitments. .SetMethod("setTrustTokenKeyCommitments", &TestRunnerBindings::SetTrustTokenKeyCommitments) .SetMethod("setUseDashboardCompatibilityMode", &TestRunnerBindings::NotImplemented) - .SetMethod("setViewSourceForFrame", - &TestRunnerBindings::SetViewSourceForFrame) .SetMethod("setWillSendRequestClearHeader", &TestRunnerBindings::SetWillSendRequestClearHeader) .SetMethod("setWillSendRequestClearReferrer", @@ -746,13 +772,15 @@ } bool TestRunnerBindings::IsCommandEnabled(const std::string& command) { - return view_runner_->IsCommandEnabled(command); + return frame_->GetWebFrame()->IsCommandEnabled( + blink::WebString::FromUTF8(command)); } void TestRunnerBindings::SetDomainRelaxationForbiddenForURLScheme( bool forbidden, const std::string& scheme) { - view_runner_->SetDomainRelaxationForbiddenForURLScheme(forbidden, scheme); + blink::SetDomainRelaxationForbidden(forbidden, + blink::WebString::FromUTF8(scheme)); } void TestRunnerBindings::SetDumpConsoleMessages(bool enabled) { @@ -857,10 +885,6 @@ } } -void TestRunnerBindings::ForceRedSelectionColors() { - view_runner_->ForceRedSelectionColors(); -} - void TestRunnerBindings::InsertStyleSheet(const std::string& source_code) { if (runner_) runner_->InsertStyleSheet(source_code); @@ -869,11 +893,29 @@ bool TestRunnerBindings::FindString( const std::string& search_text, const std::vector<std::string>& options_array) { - return view_runner_->FindString(search_text, options_array); + bool match_case = true; + bool forward = true; + bool find_next = true; + bool wrap_around = false; + for (const auto& option : options_array) { + if (option == "CaseInsensitive") + match_case = false; + else if (option == "Backwards") + forward = false; + else if (option == "StartInSelection") + find_next = false; + else if (option == "WrapAround") + wrap_around = true; + } + + const bool find_result = frame_->GetWebFrame()->FindForTesting( + 0, blink::WebString::FromUTF8(search_text), match_case, forward, + find_next, false /* force */, wrap_around); + return find_result; } std::string TestRunnerBindings::SelectionAsMarkup() { - return view_runner_->SelectionAsMarkup(); + return frame_->GetWebFrame()->SelectionAsMarkup().Utf8(); } void TestRunnerBindings::SetTextSubpixelPositioning(bool value) { @@ -884,8 +926,9 @@ void TestRunnerBindings::SetTrustTokenKeyCommitments( const std::string& raw_commitments, v8::Local<v8::Function> callback) { - if (view_runner_) - view_runner_->SetTrustTokenKeyCommitments(raw_commitments, callback); + runner_->blink_test_runner_->SetTrustTokenKeyCommitments( + raw_commitments, + view_runner_->CreateClosureThatPostsV8Callback(std::move(callback))); } void TestRunnerBindings::SetPageVisibility(const std::string& new_visibility) { @@ -893,7 +936,18 @@ } void TestRunnerBindings::SetTextDirection(const std::string& direction_name) { - view_runner_->SetTextDirection(direction_name); + // Map a direction name to a base::i18n::TextDirection value. + base::i18n::TextDirection direction; + if (direction_name == "auto") + direction = base::i18n::UNKNOWN_DIRECTION; + else if (direction_name == "rtl") + direction = base::i18n::RIGHT_TO_LEFT; + else if (direction_name == "ltr") + direction = base::i18n::LEFT_TO_RIGHT; + else + return; + + frame_->GetWebFrame()->SetTextDirection(direction); } void TestRunnerBindings::UseUnfortunateSynchronousResizeMode() { @@ -1200,8 +1254,8 @@ void TestRunnerBindings::ClearTrustTokenState( v8::Local<v8::Function> callback) { - if (view_runner_) - view_runner_->ClearTrustTokenState(callback); + runner_->blink_test_runner_->ClearTrustTokenState( + view_runner_->CreateClosureThatPostsV8Callback(std::move(callback))); } void TestRunnerBindings::SetShouldGeneratePixelResults(bool value) { @@ -1329,11 +1383,13 @@ void TestRunnerBindings::SetBluetoothFakeAdapter( const std::string& adapter_name, v8::Local<v8::Function> callback) { - view_runner_->SetBluetoothFakeAdapter(adapter_name, callback); + runner_->blink_test_runner_->SetBluetoothFakeAdapter( + adapter_name, + view_runner_->CreateClosureThatPostsV8Callback(std::move(callback))); } void TestRunnerBindings::SetBluetoothManualChooser(bool enable) { - view_runner_->SetBluetoothManualChooser(enable); + runner_->blink_test_runner_->SetBluetoothManualChooser(enable); } void TestRunnerBindings::GetBluetoothManualChooserEvents( @@ -1344,7 +1400,7 @@ void TestRunnerBindings::SendBluetoothManualChooserEvent( const std::string& event, const std::string& argument) { - view_runner_->SendBluetoothManualChooserEvent(event, argument); + runner_->blink_test_runner_->SendBluetoothManualChooserEvent(event, argument); } void TestRunnerBindings::SetPOSIXLocale(const std::string& locale) { @@ -1405,24 +1461,32 @@ } void TestRunnerBindings::SetHighlightAds() { - view_runner_->SetHighlightAds(true); + blink::WebView* web_view = frame_->GetWebFrame()->View(); + web_view->GetSettings()->SetHighlightAds(true); } void TestRunnerBindings::AddWebPageOverlay() { - view_runner_->AddWebPageOverlay(); + DCHECK(frame_->IsMainFrame()); + frame_->GetWebFrame()->SetMainFrameOverlayColor(SK_ColorCYAN); } void TestRunnerBindings::RemoveWebPageOverlay() { - view_runner_->RemoveWebPageOverlay(); + DCHECK(frame_->IsMainFrame()); + frame_->GetWebFrame()->SetMainFrameOverlayColor(SK_ColorTRANSPARENT); } void TestRunnerBindings::UpdateAllLifecyclePhasesAndComposite() { - view_runner_->UpdateAllLifecyclePhasesAndComposite(); + auto* frame_proxy = static_cast<WebFrameTestProxy*>(frame_); + frame_proxy->GetLocalRootWebWidgetTestProxy()->SynchronouslyComposite( + /*raster=*/true); } void TestRunnerBindings::UpdateAllLifecyclePhasesAndCompositeThen( v8::Local<v8::Function> callback) { - view_runner_->UpdateAllLifecyclePhasesAndCompositeThen(callback); + UpdateAllLifecyclePhasesAndComposite(); + + view_runner_->InvokeV8Callback(v8::UniquePersistent<v8::Function>( + blink::MainThreadIsolate(), std::move(callback))); } void TestRunnerBindings::SetAnimationRequiresRaster(bool do_raster) { @@ -1431,8 +1495,24 @@ runner_->SetAnimationRequiresRaster(do_raster); } +static void GetManifestReply(base::WeakPtr<TestRunner> test_runner, + TestRunnerForSpecificView* view_runner, + v8::UniquePersistent<v8::Function> callback, + const blink::WebURL& manifest_url, + const blink::Manifest& manifest) { + if (!test_runner) + return; + view_runner->PostV8CallbackWithArgs(std::move(callback), 0, nullptr); +} + void TestRunnerBindings::GetManifestThen(v8::Local<v8::Function> callback) { - view_runner_->GetManifestThen(callback); + auto blink_callback = v8::UniquePersistent<v8::Function>( + blink::MainThreadIsolate(), std::move(callback)); + + blink::WebManifestManager::RequestManifestForTesting( + frame_->GetWebFrame(), + base::BindOnce(&GetManifestReply, runner_, view_runner_, + std::move(blink_callback))); } void TestRunnerBindings::CapturePixelsAsyncThen( @@ -1440,11 +1520,28 @@ view_runner_->CapturePixelsAsyncThen(callback); } +static void ProxyToRunJSCallbackWithBitmap( + base::WeakPtr<TestRunner> test_runner, + TestRunnerForSpecificView* view_runner, + v8::UniquePersistent<v8::Function> callback, + const SkBitmap& snapshot) { + if (!test_runner) + return; + // TODO(danakj): Move this method over to TestRunner or TestRunnerBindings + // and drop this ProxyTo function. + view_runner->RunJSCallbackWithBitmap(std::move(callback), snapshot); +} + void TestRunnerBindings::CopyImageAtAndCapturePixelsAsyncThen( int x, int y, v8::Local<v8::Function> callback) { - view_runner_->CopyImageAtAndCapturePixelsAsyncThen(x, y, callback); + auto blink_callback = v8::UniquePersistent<v8::Function>( + blink::MainThreadIsolate(), std::move(callback)); + CopyImageAtAndCapturePixels( + frame_, x, y, + base::BindOnce(&ProxyToRunJSCallbackWithBitmap, runner_, view_runner_, + std::move(blink_callback))); } void TestRunnerBindings::SetCustomTextOutput(const std::string& output) { @@ -1452,11 +1549,6 @@ runner_->SetCustomTextOutput(output); } -void TestRunnerBindings::SetViewSourceForFrame(const std::string& name, - bool enabled) { - view_runner_->SetViewSourceForFrame(name, enabled); -} - void TestRunnerBindings::SetPermission(const std::string& name, const std::string& value, const std::string& origin, @@ -1520,7 +1612,11 @@ } void TestRunnerBindings::RunIdleTasks(v8::Local<v8::Function> callback) { - view_runner_->RunIdleTasks(callback); + blink::scheduler::WebThreadScheduler* scheduler = + content::RenderThreadImpl::current()->GetWebMainThreadScheduler(); + blink::scheduler::RunIdleTasksForTesting( + scheduler, + view_runner_->CreateClosureThatPostsV8Callback(std::move(callback))); } std::string TestRunnerBindings::PlatformName() { @@ -1542,7 +1638,7 @@ } void TestRunnerBindings::ForceNextWebGLContextCreationToFail() { - view_runner_->ForceNextWebGLContextCreationToFail(); + blink::ForceNextWebGLContextCreationToFailForTest(); } void TestRunnerBindings::FocusDevtoolsSecondaryWindow() { @@ -1550,7 +1646,7 @@ } void TestRunnerBindings::ForceNextDrawingBufferCreationToFail() { - view_runner_->ForceNextDrawingBufferCreationToFail(); + blink::ForceNextDrawingBufferCreationToFailForTest(); } void TestRunnerBindings::NotImplemented(const gin::Arguments& args) {} @@ -1664,6 +1760,7 @@ #if defined(OS_LINUX) || defined(OS_FUCHSIA) blink::WebFontRenderStyle::SetSubpixelPositioning(false); #endif + blink::ResetDomainRelaxation(); if (blink_test_runner_) { // Reset the default quota for each origin. @@ -1701,6 +1798,21 @@ close_remaining_windows_ = true; } +void TestRunner::ResetWebView(WebViewTestProxy* web_view_test_proxy) { + blink::WebView* web_view = web_view_test_proxy->GetWebView(); + + web_view->SetTabKeyCyclesThroughElements(true); + web_view->GetSettings()->SetHighlightAds(false); +} + +void TestRunner::ResetWebFrame(WebFrameTestProxy* web_frame_test_proxy) { + blink::WebLocalFrame* web_frame = web_frame_test_proxy->GetWebFrame(); + + if (web_frame_test_proxy->IsMainFrame()) { + web_frame->SetMainFrameOverlayColor(SK_ColorTRANSPARENT); + } +} + void TestRunner::SetTestIsRunning(bool running) { test_is_running_ = running; }
diff --git a/content/shell/renderer/web_test/test_runner.h b/content/shell/renderer/web_test/test_runner.h index 6fbad6d..c2b1e4b 100644 --- a/content/shell/renderer/web_test/test_runner.h +++ b/content/shell/renderer/web_test/test_runner.h
@@ -59,6 +59,8 @@ class SpellCheckClient; class TestInterfaces; class TestRunnerForSpecificView; +class WebFrameTestProxy; +class WebViewTestProxy; // TestRunner class currently has dual purpose: // 1. It implements TestRunner javascript bindings for "global" / "ambient". @@ -85,7 +87,12 @@ void SetDelegate(BlinkTestRunner*); void SetMainView(blink::WebView*); + // Resets state on the TestRunner for the next test. void Reset(); + // Resets state on the |web_view_test_proxy| for the next test. + void ResetWebView(WebViewTestProxy* web_view_test_proxy); + // Resets state on the |web_frame_test_proxy| for the next test. + void ResetWebFrame(WebFrameTestProxy* web_frame_test_proxy); void SetTestIsRunning(bool); bool TestIsRunning() const { return test_is_running_; }
diff --git a/content/shell/renderer/web_test/test_runner_for_specific_view.cc b/content/shell/renderer/web_test/test_runner_for_specific_view.cc index f1a29dc..e27c6e2 100644 --- a/content/shell/renderer/web_test/test_runner_for_specific_view.cc +++ b/content/shell/renderer/web_test/test_runner_for_specific_view.cc
@@ -21,7 +21,6 @@ #include "content/public/common/isolated_world_ids.h" #include "content/public/common/use_zoom_for_dsf_policy.h" #include "content/public/renderer/render_frame.h" -#include "content/renderer/render_thread_impl.h" #include "content/shell/common/web_test/web_test_string_util.h" #include "content/shell/renderer/web_test/blink_test_runner.h" #include "content/shell/renderer/web_test/layout_dump.h" @@ -54,7 +53,6 @@ #include "third_party/blink/public/web/web_frame_widget.h" #include "third_party/blink/public/web/web_input_element.h" #include "third_party/blink/public/web/web_local_frame.h" -#include "third_party/blink/public/web/web_manifest_manager.h" #include "third_party/blink/public/web/web_render_theme.h" #include "third_party/blink/public/web/web_script_source.h" #include "third_party/blink/public/web/web_security_policy.h" @@ -86,13 +84,6 @@ if (!web_view() || !web_view()->MainFrame()) return; - RemoveWebPageOverlay(); - -#if !defined(OS_MACOSX) && !defined(OS_WIN) - // (Constants copied because we can't depend on the header that defined - // them from this file.) - blink::SetSelectionColors(0xff1e90ff, 0xff000000, 0xffc8c8c8, 0xff323232); -#endif if (web_view()->MainFrame()->IsWebLocalFrame()) { web_view()->MainFrame()->ToWebLocalFrame()->EnableViewSourceMode(false); web_view()->SetTextZoomFactor(1); @@ -208,21 +199,6 @@ blink::MainThreadIsolate(), callback))); } -void TestRunnerForSpecificView::UpdateAllLifecyclePhasesAndComposite() { - // Note, this is executed synchronously. Wrap in setTimeout() to run - // asynchronously. - main_frame_render_widget()->SynchronouslyComposite(/*raster=*/true); -} - -void TestRunnerForSpecificView::UpdateAllLifecyclePhasesAndCompositeThen( - v8::Local<v8::Function> callback) { - // Note, this is executed synchronously. Wrap in setTimeout() to run - // asynchronously. - UpdateAllLifecyclePhasesAndComposite(); - InvokeV8Callback( - v8::UniquePersistent<v8::Function>(blink::MainThreadIsolate(), callback)); -} - void TestRunnerForSpecificView::CapturePixelsAsyncThen( v8::Local<v8::Function> callback) { v8::UniquePersistent<v8::Function> persistent_callback( @@ -305,45 +281,6 @@ PostV8CallbackWithArgs(std::move(callback), base::size(argv), argv); } -void TestRunnerForSpecificView::CopyImageAtAndCapturePixelsAsyncThen( - int x, - int y, - v8::Local<v8::Function> callback) { - v8::UniquePersistent<v8::Function> persistent_callback( - blink::MainThreadIsolate(), callback); - CopyImageAtAndCapturePixels( - web_view()->MainFrame()->ToWebLocalFrame(), x, y, - base::BindOnce(&TestRunnerForSpecificView::RunJSCallbackWithBitmap, - weak_factory_.GetWeakPtr(), - std::move(persistent_callback))); -} - -void TestRunnerForSpecificView::GetManifestThen( - v8::Local<v8::Function> callback) { - // TODO(danakj): Move GetManifestThen method to per-frame TestRunnerBindings, - // instead of per-view bindings. Then we don't need to find a (main) frame. - if (!web_view()->MainFrame()->IsWebLocalFrame()) { - CHECK(false) << "This function cannot be called if the main frame is not a " - "local frame."; - } - - v8::UniquePersistent<v8::Function> persistent_callback( - blink::MainThreadIsolate(), callback); - - blink::WebManifestManager::RequestManifestForTesting( - web_view()->MainFrame()->ToWebLocalFrame(), - base::BindOnce(&TestRunnerForSpecificView::GetManifestCallback, - weak_factory_.GetWeakPtr(), - std::move(persistent_callback))); -} - -void TestRunnerForSpecificView::GetManifestCallback( - v8::UniquePersistent<v8::Function> callback, - const blink::WebURL& manifest_url, - const blink::Manifest& manifest) { - PostV8CallbackWithArgs(std::move(callback), 0, nullptr); -} - void TestRunnerForSpecificView::GetBluetoothManualChooserEvents( v8::Local<v8::Function> callback) { return blink_test_runner()->GetBluetoothManualChooserEvents(base::BindOnce( @@ -374,39 +311,6 @@ PostV8CallbackWithArgs(std::move(callback), 1, &arg); } -void TestRunnerForSpecificView::SetBluetoothFakeAdapter( - const std::string& adapter_name, - v8::Local<v8::Function> callback) { - blink_test_runner()->SetBluetoothFakeAdapter( - adapter_name, CreateClosureThatPostsV8Callback(callback)); -} - -void TestRunnerForSpecificView::SetBluetoothManualChooser(bool enable) { - blink_test_runner()->SetBluetoothManualChooser(enable); -} - -void TestRunnerForSpecificView::SendBluetoothManualChooserEvent( - const std::string& event, - const std::string& argument) { - blink_test_runner()->SendBluetoothManualChooserEvent(event, argument); -} - -void TestRunnerForSpecificView::RunIdleTasks(v8::Local<v8::Function> callback) { - blink::scheduler::WebThreadScheduler* scheduler = - content::RenderThreadImpl::current()->GetWebMainThreadScheduler(); - blink::scheduler::RunIdleTasksForTesting( - scheduler, CreateClosureThatPostsV8Callback(std::move(callback))); -} - -bool TestRunnerForSpecificView::IsCommandEnabled(const std::string& command) { - return web_view()->FocusedFrame()->IsCommandEnabled( - blink::WebString::FromUTF8(command)); -} - -void TestRunnerForSpecificView::ForceRedSelectionColors() { - blink::SetSelectionColors(0xffee0000, 0xff00ee00, 0xff000000, 0xffc0c0c0); -} - void TestRunnerForSpecificView::SetPageVisibility( const std::string& new_visibility) { content::PageVisibilityState visibility; @@ -436,42 +340,6 @@ /*initial_setting=*/false); } -void TestRunnerForSpecificView::SetTextDirection( - const std::string& direction_name) { - // Map a direction name to a base::i18n::TextDirection value. - base::i18n::TextDirection direction; - if (direction_name == "auto") - direction = base::i18n::UNKNOWN_DIRECTION; - else if (direction_name == "rtl") - direction = base::i18n::RIGHT_TO_LEFT; - else if (direction_name == "ltr") - direction = base::i18n::LEFT_TO_RIGHT; - else - return; - - web_view()->FocusedFrame()->SetTextDirection(direction); -} - -void TestRunnerForSpecificView::AddWebPageOverlay() { - web_view()->SetMainFrameOverlayColor(SK_ColorCYAN); -} - -void TestRunnerForSpecificView::RemoveWebPageOverlay() { - web_view()->SetMainFrameOverlayColor(SK_ColorTRANSPARENT); -} - -void TestRunnerForSpecificView::SetHighlightAds(bool enabled) { - web_view()->GetSettings()->SetHighlightAds(enabled); -} - -void TestRunnerForSpecificView::ForceNextWebGLContextCreationToFail() { - web_view()->ForceNextWebGLContextCreationToFail(); -} - -void TestRunnerForSpecificView::ForceNextDrawingBufferCreationToFail() { - web_view()->ForceNextDrawingBufferCreationToFail(); -} - void TestRunnerForSpecificView::DidAcquirePointerLock() { DidAcquirePointerLockInternal(); } @@ -516,13 +384,6 @@ web_view()->MainFrameWidget()->DidLosePointerLock(); } -void TestRunnerForSpecificView::SetDomainRelaxationForbiddenForURLScheme( - bool forbidden, - const std::string& scheme) { - web_view()->SetDomainRelaxationForbidden(forbidden, - blink::WebString::FromUTF8(scheme)); -} - v8::Local<v8::Value> TestRunnerForSpecificView::EvaluateScriptInIsolatedWorldAndReturnValue( int32_t world_id, @@ -591,64 +452,6 @@ .InsertStyleSheet(blink::WebString::FromUTF8(source_code)); } -// Sets the network service-global Trust Tokens key commitments. -// |raw_commitments| should be JSON-encoded according to the format expected -// by NetworkService::SetTrustTokenKeyCommitments. -void TestRunnerForSpecificView::SetTrustTokenKeyCommitments( - const std::string& raw_commitments, - v8::Local<v8::Function> callback) { - blink_test_runner()->SetTrustTokenKeyCommitments( - raw_commitments, CreateClosureThatPostsV8Callback(callback)); -} - -// Clears persistent Trust Tokens state -// (https://github.com/wicg/trust-token-api) via a test-only Mojo interface. -void TestRunnerForSpecificView::ClearTrustTokenState( - v8::Local<v8::Function> callback) { - blink_test_runner()->ClearTrustTokenState( - CreateClosureThatPostsV8Callback(callback)); -} - -bool TestRunnerForSpecificView::FindString( - const std::string& search_text, - const std::vector<std::string>& options_array) { - bool match_case = true; - bool forward = true; - bool find_next = true; - bool wrap_around = false; - for (const std::string& option : options_array) { - if (option == "CaseInsensitive") - match_case = false; - else if (option == "Backwards") - forward = false; - else if (option == "StartInSelection") - find_next = false; - else if (option == "WrapAround") - wrap_around = true; - } - - blink::WebLocalFrame* frame = GetLocalMainFrame(); - const bool find_result = frame->FindForTesting( - 0, blink::WebString::FromUTF8(search_text), match_case, forward, - find_next, false /* force */, wrap_around); - return find_result; -} - -std::string TestRunnerForSpecificView::SelectionAsMarkup() { - return GetLocalMainFrame()->SelectionAsMarkup().Utf8(); -} - -void TestRunnerForSpecificView::SetViewSourceForFrame(const std::string& name, - bool enabled) { - blink::WebFrame* target_frame = - GetLocalMainFrame()->FindFrameByName(blink::WebString::FromUTF8(name)); - if (target_frame) { - CHECK(target_frame->IsWebLocalFrame()) - << "This function requires that the target frame is a local frame."; - target_frame->ToWebLocalFrame()->EnableViewSourceMode(enabled); - } -} - blink::WebLocalFrame* TestRunnerForSpecificView::GetLocalMainFrame() { if (!web_view()->MainFrame()->IsWebLocalFrame()) { // Hitting the check below uncovers a new scenario that requires OOPIF
diff --git a/content/shell/renderer/web_test/test_runner_for_specific_view.h b/content/shell/renderer/web_test/test_runner_for_specific_view.h index e59139f..cc8ec1f 100644 --- a/content/shell/renderer/web_test/test_runner_for_specific_view.h +++ b/content/shell/renderer/web_test/test_runner_for_specific_view.h
@@ -18,10 +18,8 @@ class SkBitmap; namespace blink { -struct Manifest; class WebLocalFrame; class WebView; -class WebURL; } // namespace blink namespace gfx { @@ -62,26 +60,22 @@ base::OnceClosure CreateClosureThatPostsV8Callback( const v8::Local<v8::Function>& callback); - private: - friend class TestRunnerBindings; - - void PostTask(base::OnceClosure callback); - - void UpdateAllLifecyclePhasesAndComposite(); - void UpdateAllLifecyclePhasesAndCompositeThen( - v8::Local<v8::Function> callback); - - // The callback will be called after the next full frame update and raster, - // with the captured snapshot as the parameters (width, height, snapshot). - // The snapshot is in uint8_t RGBA format. - void CapturePixelsAsyncThen(v8::Local<v8::Function> callback); - void RunJSCallbackAfterCompositorLifecycle( v8::UniquePersistent<v8::Function> callback, const gfx::PresentationFeedback&); void RunJSCallbackWithBitmap(v8::UniquePersistent<v8::Function> callback, const SkBitmap& snapshot); + private: + friend class TestRunnerBindings; + + void PostTask(base::OnceClosure callback); + + // The callback will be called after the next full frame update and raster, + // with the captured snapshot as the parameters (width, height, snapshot). + // The snapshot is in uint8_t RGBA format. + void CapturePixelsAsyncThen(v8::Local<v8::Function> callback); + // Similar to CapturePixelsAsyncThen(). Copies to the clipboard the image // located at a particular point in the WebView (if there is such an image), // reads back its pixels, and provides the snapshot to the callback. If there @@ -91,11 +85,6 @@ int y, const v8::Local<v8::Function> callback); - void GetManifestThen(v8::Local<v8::Function> callback); - void GetManifestCallback(v8::UniquePersistent<v8::Function> callback, - const blink::WebURL& manifest_url, - const blink::Manifest& manifest); - // Calls |callback| with a DOMString[] representing the events recorded since // the last call to this function. void GetBluetoothManualChooserEvents(v8::Local<v8::Function> callback); @@ -103,52 +92,12 @@ v8::UniquePersistent<v8::Function> callback, const std::vector<std::string>& events); - // Change the bluetooth test data while running a web test. - void SetBluetoothFakeAdapter(const std::string& adapter_name, - v8::Local<v8::Function> callback); - - // If |enable| is true, makes the Bluetooth chooser record its input and wait - // for instructions from the test program on how to proceed. Otherwise falls - // back to the browser's default chooser. - void SetBluetoothManualChooser(bool enable); - - // Calls the BluetoothChooser::EventHandler with the arguments here. Valid - // event strings are: - // * "cancel" - simulates the user canceling the chooser. - // * "select" - simulates the user selecting a device whose device ID is in - // |argument|. - void SendBluetoothManualChooserEvent(const std::string& event, - const std::string& argument); - - // Immediately run all pending idle tasks, including all pending - // requestIdleCallback calls. Invoke the callback when all - // idle tasks are complete. - void RunIdleTasks(v8::Local<v8::Function> callback); - - // Checks if an internal command is currently available. - bool IsCommandEnabled(const std::string& command); - - // Forces the selection colors for testing under Linux. - void ForceRedSelectionColors(); - // Switch the visibility of the page. void SetPageVisibility(const std::string& new_visibility); // Changes the direction of the focused element. void SetTextDirection(const std::string& direction_name); - // Permits the adding and removing of only one opaque overlay. - void AddWebPageOverlay(); - void RemoveWebPageOverlay(); - - void SetHighlightAds(bool); - - // Sets a flag causing the next call to WebGLRenderingContext::create to fail. - void ForceNextWebGLContextCreationToFail(); - - // Sets a flag causing the next call to DrawingBuffer::create to fail. - void ForceNextDrawingBufferCreationToFail(); - // Pointer lock handling. void DidAcquirePointerLock(); void DidNotAcquirePointerLock(); @@ -165,8 +114,6 @@ PointerLockWillFailSync, } pointer_lock_planned_result_; - void SetDomainRelaxationForbiddenForURLScheme(bool forbidden, - const std::string& scheme); v8::Local<v8::Value> EvaluateScriptInIsolatedWorldAndReturnValue( int32_t world_id, const std::string& script); @@ -175,20 +122,6 @@ void SetIsolatedWorldInfo(int32_t world_id, v8::Local<v8::Value> security_origin, v8::Local<v8::Value> content_security_policy); - bool FindString(const std::string& search_text, - const std::vector<std::string>& options_array); - std::string SelectionAsMarkup(); - void SetViewSourceForFrame(const std::string& name, bool enabled); - - // Sets the network service-global Trust Tokens key commitments. - // |raw_commitments| should be JSON-encoded according to the format expected - // by NetworkService::SetTrustTokenKeyCommitments. - void SetTrustTokenKeyCommitments(const std::string& raw_commitments, - v8::Local<v8::Function> callback); - - // Clears persistent Trust Tokens state - // (https://github.com/wicg/trust-token-api) via a test-only Mojo interface. - void ClearTrustTokenState(v8::Local<v8::Function> callback); // Many parts of the web test harness assume that the main frame is local. // Having all of them go through the helper below makes it easier to catch
diff --git a/content/shell/renderer/web_test/web_ax_object_proxy.cc b/content/shell/renderer/web_test/web_ax_object_proxy.cc index e8af42b..d2ffa16 100644 --- a/content/shell/renderer/web_test/web_ax_object_proxy.cc +++ b/content/shell/renderer/web_test/web_ax_object_proxy.cc
@@ -6,6 +6,10 @@ #include <stddef.h> +#include <algorithm> +#include <map> +#include <utility> + #include "base/stl_util.h" #include "base/strings/stringprintf.h" #include "gin/handle.h" @@ -529,7 +533,7 @@ return blink::WebRect(); } -std::vector<std::string> GetMisspellings(blink::WebAXObject& object) { +std::vector<std::string> GetMisspellings(const blink::WebAXObject& object) { std::vector<std::string> misspellings; std::string text(object.GetName().Utf8()); @@ -875,7 +879,8 @@ void WebAXObjectProxy::NotificationReceived( blink::WebLocalFrame* frame, - const std::string& notification_name) { + const std::string& notification_name, + const std::vector<ui::AXEventIntent>& event_intents) { if (notification_callback_.IsEmpty()) return; @@ -885,12 +890,21 @@ v8::Isolate* isolate = blink::MainThreadIsolate(); + v8::Local<v8::Array> intents_array( + v8::Array::New(isolate, event_intents.size())); + for (size_t i = 0; i < event_intents.size(); ++i) { + intents_array + ->CreateDataProperty(context, uint32_t{i}, + v8::String::NewFromUtf8( + isolate, event_intents[i].ToString().c_str()) + .ToLocalChecked()) + .Check(); + } + v8::Local<v8::Value> argv[] = { - v8::String::NewFromUtf8(isolate, notification_name.data(), - v8::NewStringType::kNormal, - notification_name.size()) + v8::String::NewFromUtf8(isolate, notification_name.c_str()) .ToLocalChecked(), - }; + intents_array}; // TODO(aboxhall): Can we force this to run in a new task, to avoid // dirtying layout during post-layout hooks? frame->CallFunctionEvenIfScriptDisabled(
diff --git a/content/shell/renderer/web_test/web_ax_object_proxy.h b/content/shell/renderer/web_test/web_ax_object_proxy.h index 6e59aec1..909bcdc3 100644 --- a/content/shell/renderer/web_test/web_ax_object_proxy.h +++ b/content/shell/renderer/web_test/web_ax_object_proxy.h
@@ -8,11 +8,13 @@ #include <stdint.h> #include <string> +#include <vector> #include "base/macros.h" #include "gin/object_template_builder.h" #include "gin/wrappable.h" #include "third_party/blink/public/web/web_ax_object.h" +#include "ui/accessibility/ax_event_intent.h" #include "v8/include/v8.h" namespace blink { @@ -43,8 +45,10 @@ virtual bool IsRoot() const; bool IsEqualToObject(const blink::WebAXObject& object); - void NotificationReceived(blink::WebLocalFrame* frame, - const std::string& notification_name); + void NotificationReceived( + blink::WebLocalFrame* frame, + const std::string& notification_name, + const std::vector<ui::AXEventIntent>& event_intents); void Reset(); protected:
diff --git a/content/shell/renderer/web_test/web_frame_test_proxy.cc b/content/shell/renderer/web_test/web_frame_test_proxy.cc index 0743578..96e4c42 100644 --- a/content/shell/renderer/web_test/web_frame_test_proxy.cc +++ b/content/shell/renderer/web_test/web_frame_test_proxy.cc
@@ -253,6 +253,10 @@ // the main frame on each navigation, including to about:blank and then to the // next test. So resetting the frame or RenderWidget won't be meaningful then. + TestInterfaces* interfaces = web_view_test_proxy_->test_interfaces(); + TestRunner* test_runner = interfaces->GetTestRunner(); + test_runner->ResetWebFrame(this); + if (IsMainFrame()) { GetWebFrame()->SetName(blink::WebString()); GetWebFrame()->ClearOpener(); @@ -621,14 +625,16 @@ blink::WebDocument document = GetWebFrame()->GetDocument(); auto object = blink::WebAXObject::FromWebDocumentByID(document, event.id); - HandleWebAccessibilityEvent(std::move(object), event_name); + HandleWebAccessibilityEvent(std::move(object), event_name, + event.event_intents); RenderFrameImpl::PostAccessibilityEvent(event); } void WebFrameTestProxy::MarkWebAXObjectDirty(const blink::WebAXObject& object, bool subtree) { - HandleWebAccessibilityEvent(object, "MarkDirty"); + HandleWebAccessibilityEvent(object, "MarkDirty", + std::vector<ui::AXEventIntent>()); // Guard against the case where |this| was deleted as a result of an // accessibility listener detaching a frame. If that occurs, the @@ -641,7 +647,8 @@ void WebFrameTestProxy::HandleWebAccessibilityEvent( const blink::WebAXObject& object, - const char* event_name) { + const char* event_name, + const std::vector<ui::AXEventIntent>& event_intents) { // Only hook the accessibility events that occurred during the test run. // This check prevents false positives in BlinkLeakDetector. // The pending tasks in browser/renderer message queue may trigger @@ -655,7 +662,7 @@ web_view_test_proxy_->accessibility_controller(); accessibility_controller->NotificationReceived(GetWebFrame(), object, - event_name); + event_name, event_intents); if (accessibility_controller->ShouldLogAccessibilityEvents()) { std::string message("AccessibilityNotification - ");
diff --git a/content/shell/renderer/web_test/web_frame_test_proxy.h b/content/shell/renderer/web_test/web_frame_test_proxy.h index 780bc53..1176497 100644 --- a/content/shell/renderer/web_test/web_frame_test_proxy.h +++ b/content/shell/renderer/web_test/web_frame_test_proxy.h
@@ -8,6 +8,7 @@ #include <memory> #include <string> #include <utility> +#include <vector> #include "base/macros.h" #include "content/renderer/render_frame_impl.h" @@ -19,6 +20,7 @@ #include "third_party/blink/public/web/web_local_frame.h" #include "third_party/blink/public/web/web_local_frame_client.h" #include "ui/accessibility/ax_event.h" +#include "ui/accessibility/ax_event_intent.h" namespace content { class BlinkTestRunner; @@ -97,8 +99,10 @@ void BindReceiver( mojo::PendingAssociatedReceiver<mojom::WebTestRenderFrame> receiver); - void HandleWebAccessibilityEvent(const blink::WebAXObject& object, - const char* event_name); + void HandleWebAccessibilityEvent( + const blink::WebAXObject& object, + const char* event_name, + const std::vector<ui::AXEventIntent>& event_intents); TestRunner* test_runner(); BlinkTestRunner* blink_test_runner();
diff --git a/content/shell/renderer/web_test/web_view_test_proxy.cc b/content/shell/renderer/web_test/web_view_test_proxy.cc index 04fef39..45c2c3c 100644 --- a/content/shell/renderer/web_test/web_view_test_proxy.cc +++ b/content/shell/renderer/web_test/web_view_test_proxy.cc
@@ -7,8 +7,6 @@ #include <stddef.h> #include <stdint.h> -#include "base/command_line.h" -#include "content/public/common/content_switches.h" #include "content/shell/common/web_test/web_test_string_util.h" #include "content/shell/renderer/web_test/blink_test_runner.h" #include "content/shell/renderer/web_test/mock_screen_orientation_client.h" @@ -82,7 +80,7 @@ view_test_runner_.Reset(); // Resets things on the WebView that TestRunnerBindings can modify. - GetWebView()->SetTabKeyCyclesThroughElements(true); + GetTestRunner()->ResetWebView(this); for (blink::WebFrame* frame = GetWebView()->MainFrame(); frame; frame = frame->TraverseNext()) { @@ -96,15 +94,7 @@ } void WebViewTestProxy::Install(blink::WebLocalFrame* frame) { - if (!base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableAxSerializerForTesting)) { - RenderFrame* render_frame = RenderFrame::FromWebFrame(frame); - if (render_frame) - render_frame->SetAccessibilityModeForTest(ui::AXMode::kWebContents); - } - accessibility_controller_.Install(frame); - text_input_controller_.Install(frame); }
diff --git a/content/test/gpu/gpu_tests/skia_gold_integration_test_base.py b/content/test/gpu/gpu_tests/skia_gold_integration_test_base.py index 38fbfcf..cca2adfd 100644 --- a/content/test/gpu/gpu_tests/skia_gold_integration_test_base.py +++ b/content/test/gpu/gpu_tests/skia_gold_integration_test_base.py
@@ -368,6 +368,12 @@ 'msaa': str(img_params.msaa), 'model_name': _ToNonEmptyStrOrNone(img_params.model_name), } + # If we have a grace period active, then the test is potentially flaky. + # Include a pair that will cause Gold to ignore any untriaged images, which + # will prevent it from automatically commenting on unrelated CLs that happen + # to produce a new image. + if _GracePeriodActive(page): + gpu_keys['ignore'] = '1' return gpu_keys # TODO(crbug.com/1076144): This is due for a refactor, likely similar to how @@ -445,7 +451,11 @@ '--failure-file', failure_file ] + build_id_args + extra_imgtest_args + algorithm_args) # yapf: enable - subprocess.check_output(cmd, stderr=subprocess.STDOUT) + output = subprocess.check_output(cmd, stderr=subprocess.STDOUT) + # TODO(skbug.com/10245): Remove this once the issue with auto-triaging + # inexactly matched images is fixed. + if 'VP9_YUY2' in image_name: + logging.error(output) except CalledProcessError as e: # We don't want to bother printing out triage links for local runs. # Instead, we print out local filepaths for debugging. However, we want @@ -526,7 +536,7 @@ return False # Don't surface if the test was recently added and we're still within its # grace period. - if page.grace_period_end and date.today() <= page.grace_period_end: + if _GracePeriodActive(page): return False return True @@ -632,6 +642,19 @@ return 'None' if val == '' else str(val) +def _GracePeriodActive(page): + """Returns whether a grace period is currently active for a test. + + Args: + page: The GPU PixelTestPage object for the test in question. + + Returns: + True if a grace period is defined for |page| and has not yet expired. + Otherwise, False. + """ + return page.grace_period_end and date.today() <= page.grace_period_end + + def load_tests(loader, tests, pattern): del loader, tests, pattern # Unused. return gpu_integration_test.LoadAllTestsInModule(sys.modules[__name__])
diff --git a/content/test/mock_widget_input_handler.cc b/content/test/mock_widget_input_handler.cc index 5c6f4a04..2bf1f94 100644 --- a/content/test/mock_widget_input_handler.cc +++ b/content/test/mock_widget_input_handler.cc
@@ -208,10 +208,9 @@ MockWidgetInputHandler::DispatchedEventMessage::~DispatchedEventMessage() { if (callback_) { - std::move(callback_).Run(blink::mojom::InputEventResultSource::kUnknown, - ui::LatencyInfo(), - blink::mojom::InputEventResultState::kNotConsumed, - base::nullopt, base::nullopt); + std::move(callback_).Run( + blink::mojom::InputEventResultSource::kUnknown, ui::LatencyInfo(), + blink::mojom::InputEventResultState::kNotConsumed, nullptr, nullptr); base::RunLoop().RunUntilIdle(); } } @@ -225,8 +224,7 @@ blink::mojom::InputEventResultState state) { if (callback_) { std::move(callback_).Run(blink::mojom::InputEventResultSource::kMainThread, - ui::LatencyInfo(), state, base::nullopt, - base::nullopt); + ui::LatencyInfo(), state, nullptr, nullptr); base::RunLoop().RunUntilIdle(); } } @@ -235,11 +233,11 @@ blink::mojom::InputEventResultSource source, const ui::LatencyInfo& latency_info, blink::mojom::InputEventResultState state, - const base::Optional<ui::DidOverscrollParams>& overscroll, - const base::Optional<cc::TouchAction>& touch_action) { + blink::mojom::DidOverscrollParamsPtr overscroll, + blink::mojom::TouchActionOptionalPtr touch_action) { if (callback_) { - std::move(callback_).Run(source, latency_info, state, overscroll, - touch_action); + std::move(callback_).Run(source, latency_info, state, std::move(overscroll), + std::move(touch_action)); base::RunLoop().RunUntilIdle(); } }
diff --git a/content/test/mock_widget_input_handler.h b/content/test/mock_widget_input_handler.h index 183da1a..26ecd88 100644 --- a/content/test/mock_widget_input_handler.h +++ b/content/test/mock_widget_input_handler.h
@@ -155,8 +155,8 @@ void CallCallback(blink::mojom::InputEventResultSource source, const ui::LatencyInfo& latency_info, blink::mojom::InputEventResultState state, - const base::Optional<ui::DidOverscrollParams>& overscroll, - const base::Optional<cc::TouchAction>& touch_action); + blink::mojom::DidOverscrollParamsPtr overscroll, + blink::mojom::TouchActionOptionalPtr touch_action); // Return if the callback is set. bool HasCallback() const;
diff --git a/content/test/ppapi/ppapi_browsertest.cc b/content/test/ppapi/ppapi_browsertest.cc index 69b45c0..46e036d 100644 --- a/content/test/ppapi/ppapi_browsertest.cc +++ b/content/test/ppapi/ppapi_browsertest.cc
@@ -123,6 +123,8 @@ TEST_PPAPI_OUT_OF_PROCESS(MessageLoop_Basics) TEST_PPAPI_OUT_OF_PROCESS(MessageLoop_Post) +TEST_PPAPI_OUT_OF_PROCESS(NetworkProxy) + // TODO(danakj): http://crbug.com/115286 TEST_PPAPI_IN_PROCESS(DISABLED_Scrollbar) // http://crbug.com/89961
diff --git a/crypto/nss_key_util.cc b/crypto/nss_key_util.cc index ab948b6..083a437 100644 --- a/crypto/nss_key_util.cc +++ b/crypto/nss_key_util.cc
@@ -20,25 +20,10 @@ namespace { -struct PublicKeyInfoDeleter { - inline void operator()(CERTSubjectPublicKeyInfo* spki) { - SECKEY_DestroySubjectPublicKeyInfo(spki); - } -}; - -typedef std::unique_ptr<CERTSubjectPublicKeyInfo, PublicKeyInfoDeleter> - ScopedPublicKeyInfo; - // Decodes |input| as a SubjectPublicKeyInfo and returns a SECItem containing // the CKA_ID of that public key or nullptr on error. ScopedSECItem MakeIDFromSPKI(base::span<const uint8_t> input) { - // First, decode and save the public key. - SECItem key_der; - key_der.type = siBuffer; - key_der.data = const_cast<unsigned char*>(input.data()); - key_der.len = input.size(); - - ScopedPublicKeyInfo spki(SECKEY_DecodeDERSubjectPublicKeyInfo(&key_der)); + ScopedCERTSubjectPublicKeyInfo spki = DecodeSubjectPublicKeyInfoNSS(input); if (!spki) return nullptr; @@ -190,4 +175,17 @@ PK11_FindKeyByKeyID(slot, cka_id.get(), nullptr)); } +ScopedCERTSubjectPublicKeyInfo DecodeSubjectPublicKeyInfoNSS( + base::span<const uint8_t> input) { + // First, decode and save the public key. + SECItem key_der; + key_der.type = siBuffer; + key_der.data = const_cast<unsigned char*>(input.data()); + key_der.len = input.size(); + + ScopedCERTSubjectPublicKeyInfo spki( + SECKEY_DecodeDERSubjectPublicKeyInfo(&key_der)); + return spki; +} + } // namespace crypto
diff --git a/crypto/nss_key_util.h b/crypto/nss_key_util.h index d1dab9a..112a1b9b 100644 --- a/crypto/nss_key_util.h +++ b/crypto/nss_key_util.h
@@ -61,6 +61,11 @@ FindNSSKeyFromPublicKeyInfoInSlot(base::span<const uint8_t> input, PK11SlotInfo* slot); +// Decodes |input| as a DER-encoded X.509 SubjectPublicKeyInfo and returns the +// NSS representation of it. +CRYPTO_EXPORT ScopedCERTSubjectPublicKeyInfo +DecodeSubjectPublicKeyInfoNSS(base::span<const uint8_t> input); + } // namespace crypto #endif // CRYPTO_NSS_KEY_UTIL_H_
diff --git a/crypto/scoped_nss_types.h b/crypto/scoped_nss_types.h index a739565..2a3a6e1 100644 --- a/crypto/scoped_nss_types.h +++ b/crypto/scoped_nss_types.h
@@ -7,6 +7,7 @@ #include <keyhi.h> #include <nss.h> +#include <nss/certt.h> #include <pk11pub.h> #include <plarena.h> @@ -57,6 +58,10 @@ typedef std::unique_ptr<PLArenaPool, NSSDestroyer1<PLArenaPool, PORT_FreeArena, PR_FALSE>> ScopedPLArenaPool; +typedef std::unique_ptr< + CERTSubjectPublicKeyInfo, + NSSDestroyer<CERTSubjectPublicKeyInfo, SECKEY_DestroySubjectPublicKeyInfo>> + ScopedCERTSubjectPublicKeyInfo; } // namespace crypto
diff --git a/device/bluetooth/bluez/bluetooth_adapter_bluez.cc b/device/bluetooth/bluez/bluetooth_adapter_bluez.cc index 1c55f56..6e6928e 100644 --- a/device/bluetooth/bluez/bluetooth_adapter_bluez.cc +++ b/device/bluetooth/bluez/bluetooth_adapter_bluez.cc
@@ -15,7 +15,6 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/callback_helpers.h" -#include "base/feature_list.h" #include "base/location.h" #include "base/logging.h" #include "base/memory/ptr_util.h" @@ -26,7 +25,6 @@ #include "base/time/time.h" #include "build/build_config.h" #include "components/device_event_log/device_event_log.h" -#include "device/base/features.h" #include "device/bluetooth/bluetooth_common.h" #include "device/bluetooth/bluetooth_device.h" #include "device/bluetooth/bluetooth_discovery_session_outcome.h" @@ -52,7 +50,6 @@ #include "third_party/cros_system_api/dbus/service_constants.h" #if defined(OS_CHROMEOS) -#include "chromeos/constants/chromeos_features.h" #include "chromeos/constants/devicetype.h" #include "device/bluetooth/bluetooth_adapter_factory.h" #include "device/bluetooth/chromeos/bluetooth_utils.h" @@ -1078,10 +1075,6 @@ if (properties->discovering.value()) DiscoveringChanged(true); -#if defined(OS_CHROMEOS) - SetChromeOSKernelSuspendNotifier(properties); -#endif - std::vector<dbus::ObjectPath> device_paths = bluez::BluezDBusManager::Get() ->GetBluetoothDeviceClient() @@ -1121,25 +1114,6 @@ base::PersistentHash(address) & 0xFFFF); SetName(alias, base::DoNothing(), base::DoNothing()); } - -// If the property is available, set the value according to the feature flag. -void BluetoothAdapterBlueZ::SetChromeOSKernelSuspendNotifier( - bluez::BluetoothAdapterClient::Properties* properties) { - if (!properties->use_kernel_suspend_notifier.is_valid()) - return; - - bool use_notifier = base::FeatureList::IsEnabled( - chromeos::features::kBluetoothKernelSuspendNotifier); - - base::OnceCallback<void(bool)> cb = base::BindOnce( - [](bool value, bool success) { - if (!success) { - BLUETOOTH_LOG(ERROR) << "Failed to set suspend notifier to " << value; - } - }, - use_notifier); - properties->use_kernel_suspend_notifier.Set(use_notifier, std::move(cb)); -} #endif void BluetoothAdapterBlueZ::RemoveAdapter() {
diff --git a/device/bluetooth/bluez/bluetooth_adapter_bluez.h b/device/bluetooth/bluez/bluetooth_adapter_bluez.h index 2ec8fae1..e5aa24f 100644 --- a/device/bluetooth/bluez/bluetooth_adapter_bluez.h +++ b/device/bluetooth/bluez/bluetooth_adapter_bluez.h
@@ -351,10 +351,6 @@ #if defined(OS_CHROMEOS) // Set the adapter name to one chosen from the system information. void SetStandardChromeOSAdapterName(); - - // Set the kernel suspend notifier property based off value of chrome://flags. - void SetChromeOSKernelSuspendNotifier( - bluez::BluetoothAdapterClient::Properties* properties); #endif // Remove the currently tracked adapter. IsPresent() will return false after
diff --git a/device/bluetooth/dbus/OWNERS b/device/bluetooth/dbus/OWNERS index c8d05370..46af1342 100644 --- a/device/bluetooth/dbus/OWNERS +++ b/device/bluetooth/dbus/OWNERS
@@ -1,3 +1,4 @@ mcchou@chromium.org +sonnysasaka@chromium.org # COMPONENT: OS>Systems>Bluetooth
diff --git a/device/bluetooth/dbus/bluetooth_adapter_client.cc b/device/bluetooth/dbus/bluetooth_adapter_client.cc index fbf0ca1..c0dbd0a 100644 --- a/device/bluetooth/dbus/bluetooth_adapter_client.cc +++ b/device/bluetooth/dbus/bluetooth_adapter_client.cc
@@ -182,8 +182,6 @@ RegisterProperty(bluetooth_adapter::kDiscoveringProperty, &discovering); RegisterProperty(bluetooth_adapter::kUUIDsProperty, &uuids); RegisterProperty(bluetooth_adapter::kModaliasProperty, &modalias); - RegisterProperty(bluetooth_adapter::kUseSuspendNotifierProperty, - &use_kernel_suspend_notifier); } BluetoothAdapterClient::Properties::~Properties() = default;
diff --git a/device/bluetooth/dbus/bluetooth_adapter_client.h b/device/bluetooth/dbus/bluetooth_adapter_client.h index 2d77d46..b7dff6d 100644 --- a/device/bluetooth/dbus/bluetooth_adapter_client.h +++ b/device/bluetooth/dbus/bluetooth_adapter_client.h
@@ -106,10 +106,6 @@ // Local Device ID information in Linux kernel modalias format. Read-only. dbus::Property<std::string> modalias; - // Flag to enable usage of kernel suspend notifier. - // TODO(b/149795111): Remove once feature is default behavior in stable. - dbus::Property<bool> use_kernel_suspend_notifier; - Properties(dbus::ObjectProxy* object_proxy, const std::string& interface_name, const PropertyChangedCallback& callback);
diff --git a/device/fido/BUILD.gn b/device/fido/BUILD.gn index fe8813d..b1867a8b 100644 --- a/device/fido/BUILD.gn +++ b/device/fido/BUILD.gn
@@ -130,6 +130,8 @@ "reset_request_handler.h", "response_data.cc", "response_data.h", + "rsa_public_key.cc", + "rsa_public_key.h", "set_pin_request_handler.cc", "set_pin_request_handler.h", "u2f_command_constructor.cc",
diff --git a/device/fido/attested_credential_data.cc b/device/fido/attested_credential_data.cc index 6e6c4e5..e1c4f9e 100644 --- a/device/fido/attested_credential_data.cc +++ b/device/fido/attested_credential_data.cc
@@ -14,6 +14,7 @@ #include "device/fido/fido_parsing_utils.h" #include "device/fido/p256_public_key.h" #include "device/fido/public_key.h" +#include "device/fido/rsa_public_key.h" namespace device { @@ -92,23 +93,33 @@ return base::nullopt; } - if (public_key_type->second.is_unsigned() && - public_key_type->second.GetUnsigned() == - static_cast<int64_t>(CoseKeyTypes::kEC2)) { - auto curve = public_key_map.find( - cbor::Value(static_cast<int64_t>(CoseKeyKey::kEllipticCurve))); - if (curve == public_key_map.end() || !curve->second.is_integer()) { - return base::nullopt; - } - - if (curve->second.GetInteger() == static_cast<int64_t>(CoseCurves::kP256)) { - auto p256_key = P256PublicKey::ExtractFromCOSEKey( - algorithm, public_key_cbor_bytes, public_key_map); - if (!p256_key) { - FIDO_LOG(ERROR) << "Invalid P-256 public key"; + if (public_key_type->second.is_unsigned()) { + const int64_t key_type = public_key_type->second.GetUnsigned(); + if (key_type == static_cast<int64_t>(CoseKeyTypes::kEC2)) { + auto curve = public_key_map.find( + cbor::Value(static_cast<int64_t>(CoseKeyKey::kEllipticCurve))); + if (curve == public_key_map.end() || !curve->second.is_integer()) { return base::nullopt; } - public_key = std::move(p256_key); + + if (curve->second.GetInteger() == + static_cast<int64_t>(CoseCurves::kP256)) { + auto p256_key = P256PublicKey::ExtractFromCOSEKey( + algorithm, public_key_cbor_bytes, public_key_map); + if (!p256_key) { + FIDO_LOG(ERROR) << "Invalid P-256 public key"; + return base::nullopt; + } + public_key = std::move(p256_key); + } + } else if (key_type == static_cast<int64_t>(CoseKeyTypes::kRSA)) { + auto rsa_key = RSAPublicKey::ExtractFromCOSEKey( + algorithm, public_key_cbor_bytes, public_key_map); + if (!rsa_key) { + FIDO_LOG(ERROR) << "Invalid RSA public key"; + return base::nullopt; + } + public_key = std::move(rsa_key); } }
diff --git a/device/fido/authenticator_get_info_response.cc b/device/fido/authenticator_get_info_response.cc index a5fdbd9..616fa068 100644 --- a/device/fido/authenticator_get_info_response.cc +++ b/device/fido/authenticator_get_info_response.cc
@@ -75,6 +75,15 @@ 8, base::strict_cast<int64_t>(*response.max_credential_id_length)); } + if (!response.algorithms.empty()) { + std::vector<cbor::Value> algorithms_cbor; + algorithms_cbor.reserve(response.algorithms.size()); + for (const auto& algorithm : response.algorithms) { + algorithms_cbor.emplace_back(cbor::Value(algorithm)); + } + device_info_map.emplace(10, std::move(algorithms_cbor)); + } + auto encoded_bytes = cbor::Writer::Write(cbor::Value(std::move(device_info_map))); DCHECK(encoded_bytes);
diff --git a/device/fido/authenticator_get_info_response.h b/device/fido/authenticator_get_info_response.h index 0433d20a..95f4fde 100644 --- a/device/fido/authenticator_get_info_response.h +++ b/device/fido/authenticator_get_info_response.h
@@ -41,6 +41,9 @@ base::Optional<uint32_t> max_credential_id_length; base::Optional<std::vector<uint8_t>> pin_protocols; base::Optional<std::vector<std::string>> extensions; + std::vector<int32_t> algorithms = { + static_cast<int32_t>(CoseAlgorithmIdentifier::kCoseEs256), + }; AuthenticatorSupportedOptions options; private:
diff --git a/device/fido/ctap_response_unittest.cc b/device/fido/ctap_response_unittest.cc index b91ad360..1a20bec1 100644 --- a/device/fido/ctap_response_unittest.cc +++ b/device/fido/ctap_response_unittest.cc
@@ -641,6 +641,7 @@ response.options = std::move(options); response.max_msg_size = 1200; response.pin_protocols.emplace({static_cast<uint8_t>(1)}); + response.algorithms.clear(); EXPECT_THAT(AuthenticatorGetInfoResponse::EncodeToCBOR(response), ::testing::ElementsAreArray(
diff --git a/device/fido/fido_constants.h b/device/fido/fido_constants.h index 7ca0020..144d1fb 100644 --- a/device/fido/fido_constants.h +++ b/device/fido/fido_constants.h
@@ -235,6 +235,8 @@ enum class CoseKeyKey : int { kAlg = 3, kKty = 1, + kRSAModulus = -1, + kRSAPublicExponent = -2, kEllipticCurve = -1, kEllipticX = -2, kEllipticY = -3, @@ -242,13 +244,19 @@ // Enumerates COSE key types. See // https://tools.ietf.org/html/rfc8152#section-13 -enum class CoseKeyTypes : int { kEC2 = 2 }; +enum class CoseKeyTypes : int { + kEC2 = 2, + kRSA = 3, +}; // Enumerates COSE elliptic curves. See // https://tools.ietf.org/html/rfc8152#section-13.1 enum class CoseCurves : int { kP256 = 1 }; -enum class CoseAlgorithmIdentifier : int { kCoseEs256 = -7 }; +enum class CoseAlgorithmIdentifier : int { + kCoseEs256 = -7, + kCoseRs256 = -257, +}; // APDU instruction code for U2F request encoding. // https://fidoalliance.org/specs/fido-u2f-v1.0-ps-20141009/fido-u2f-u2f.h-v1.0-ps-20141009.pdf
diff --git a/device/fido/rsa_public_key.cc b/device/fido/rsa_public_key.cc new file mode 100644 index 0000000..e4abd88f --- /dev/null +++ b/device/fido/rsa_public_key.cc
@@ -0,0 +1,75 @@ +// 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 "device/fido/rsa_public_key.h" + +#include <utility> + +#include "components/cbor/writer.h" +#include "device/fido/fido_constants.h" +#include "third_party/boringssl/src/include/openssl/bn.h" +#include "third_party/boringssl/src/include/openssl/bytestring.h" +#include "third_party/boringssl/src/include/openssl/evp.h" +#include "third_party/boringssl/src/include/openssl/mem.h" +#include "third_party/boringssl/src/include/openssl/obj.h" +#include "third_party/boringssl/src/include/openssl/rsa.h" + +namespace device { + +// static +std::unique_ptr<PublicKey> RSAPublicKey::ExtractFromCOSEKey( + int32_t algorithm, + base::span<const uint8_t> cbor_bytes, + const cbor::Value::MapValue& map) { + // See https://tools.ietf.org/html/rfc8230#section-4 + cbor::Value::MapValue::const_iterator it = + map.find(cbor::Value(static_cast<int64_t>(CoseKeyKey::kKty))); + if (it == map.end() || !it->second.is_integer() || + it->second.GetInteger() != static_cast<int64_t>(CoseKeyTypes::kRSA)) { + return nullptr; + } + + cbor::Value::MapValue::const_iterator it_n = + map.find(cbor::Value(static_cast<int64_t>(CoseKeyKey::kRSAModulus))); + cbor::Value::MapValue::const_iterator it_e = map.find( + cbor::Value(static_cast<int64_t>(CoseKeyKey::kRSAPublicExponent))); + + if (it_n == map.end() || !it_n->second.is_bytestring() || it_e == map.end() || + !it_e->second.is_bytestring()) { + return nullptr; + } + + const std::vector<uint8_t>& n(it_n->second.GetBytestring()); + const std::vector<uint8_t>& e(it_e->second.GetBytestring()); + + bssl::UniquePtr<BIGNUM> n_bn(BN_new()); + bssl::UniquePtr<BIGNUM> e_bn(BN_new()); + if (!BN_bin2bn(n.data(), n.size(), n_bn.get()) || + !BN_bin2bn(e.data(), e.size(), e_bn.get())) { + return nullptr; + } + + bssl::UniquePtr<RSA> rsa(RSA_new()); + if (!RSA_set0_key(rsa.get(), n_bn.release(), e_bn.release(), /*d=*/nullptr)) { + return nullptr; + } + + bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new()); + CHECK(EVP_PKEY_assign_RSA(pkey.get(), rsa.release())); + + bssl::ScopedCBB cbb; + uint8_t* der_bytes = nullptr; + size_t der_bytes_len = 0; + CHECK(CBB_init(cbb.get(), /* initial size */ 128) && + EVP_marshal_public_key(cbb.get(), pkey.get()) && + CBB_finish(cbb.get(), &der_bytes, &der_bytes_len)); + + std::vector<uint8_t> der_bytes_vec(der_bytes, der_bytes + der_bytes_len); + OPENSSL_free(der_bytes); + + return std::make_unique<PublicKey>(algorithm, cbor_bytes, + std::move(der_bytes_vec)); +} + +} // namespace device
diff --git a/device/fido/rsa_public_key.h b/device/fido/rsa_public_key.h new file mode 100644 index 0000000..90073765 --- /dev/null +++ b/device/fido/rsa_public_key.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 DEVICE_FIDO_RSA_PUBLIC_KEY_H_ +#define DEVICE_FIDO_RSA_PUBLIC_KEY_H_ + +#include <stdint.h> +#include <memory> +#include <string> +#include <vector> + +#include "base/component_export.h" +#include "base/containers/span.h" +#include "components/cbor/values.h" +#include "device/fido/public_key.h" + +namespace device { + +class COMPONENT_EXPORT(DEVICE_FIDO) RSAPublicKey { + public: + static std::unique_ptr<PublicKey> ExtractFromCOSEKey( + int32_t algorithm, + base::span<const uint8_t> cbor_bytes, + const cbor::Value::MapValue& map); +}; + +} // namespace device + +#endif // DEVICE_FIDO_RSA_PUBLIC_KEY_H_
diff --git a/device/fido/virtual_ctap2_device.cc b/device/fido/virtual_ctap2_device.cc index e4df130..6cea9e49 100644 --- a/device/fido/virtual_ctap2_device.cc +++ b/device/fido/virtual_ctap2_device.cc
@@ -87,18 +87,6 @@ CRYPTO_memcmp(pin_auth.data(), calculated_pin_auth, 16) == 0; } -// Checks that whether the received MakeCredential request includes EA256 -// algorithm in publicKeyCredParam. -bool AreMakeCredentialParamsValid(const CtapMakeCredentialRequest& request) { - const auto& params = - request.public_key_credential_params.public_key_credential_params(); - return std::any_of( - params.begin(), params.end(), [](const auto& credential_info) { - return credential_info.algorithm == - base::strict_cast<int>(CoseAlgorithmIdentifier::kCoseEs256); - }); -} - std::vector<uint8_t> ConstructSignatureBuffer( const AuthenticatorData& authenticator_data, base::span<const uint8_t, kClientDataHashLength> client_data_hash) { @@ -399,6 +387,10 @@ VirtualCtap2Device::VirtualCtap2Device() : VirtualFidoDevice() { device_info_ = AuthenticatorGetInfoResponse({ProtocolVersion::kCtap2}, kDeviceAaguid); + device_info_->algorithms = { + static_cast<int32_t>(CoseAlgorithmIdentifier::kCoseEs256), + static_cast<int32_t>(CoseAlgorithmIdentifier::kCoseRs256), + }; } VirtualCtap2Device::VirtualCtap2Device(scoped_refptr<State> state, @@ -758,11 +750,28 @@ } // Step 7. - if (!AreMakeCredentialParamsValid(request)) { - DLOG(ERROR) << "Virtual CTAP2 device does not support options required by " - "the request."; + std::unique_ptr<PrivateKey> private_key; + for (const auto& param : + request.public_key_credential_params.public_key_credential_params()) { + switch (param.algorithm) { + default: + continue; + case static_cast<int32_t>(CoseAlgorithmIdentifier::kCoseEs256): + private_key = FreshP256Key(); + break; + case static_cast<int32_t>(CoseAlgorithmIdentifier::kCoseRs256): + private_key = FreshRSAKey(); + break; + } + break; + } + + if (!private_key) { + DLOG(ERROR) << "Virtual CTAP2 device does not support any public-key " + "algorithm listed in the request"; return CtapDeviceResponseCode::kCtap2ErrUnsupportedAlgorithm; } + std::unique_ptr<PublicKey> public_key(private_key->GetPublicKey()); // Step 8. if ((request.resident_key_required && !options.supports_resident_key) || @@ -775,12 +784,6 @@ return base::nullopt; } - // Create key to register. - // Note: Non-deterministic, you need to mock this out if you rely on - // deterministic behavior. - std::unique_ptr<PrivateKey> private_key(FreshP256Key()); - std::unique_ptr<PublicKey> public_key(private_key->GetPublicKey()); - // Our key handles are simple hashes of the public key. const auto key_handle = crypto::SHA256Hash(public_key->cose_key_bytes());
diff --git a/device/fido/virtual_fido_device.cc b/device/fido/virtual_fido_device.cc index 16ae9951..be4c6c2cc 100644 --- a/device/fido/virtual_fido_device.cc +++ b/device/fido/virtual_fido_device.cc
@@ -9,17 +9,21 @@ #include <utility> #include "base/bind.h" +#include "components/cbor/values.h" +#include "components/cbor/writer.h" #include "crypto/ec_private_key.h" #include "crypto/ec_signature_creator.h" #include "crypto/openssl_util.h" #include "device/fido/fido_parsing_utils.h" #include "device/fido/p256_public_key.h" #include "device/fido/public_key.h" +#include "third_party/boringssl/src/include/openssl/bn.h" #include "third_party/boringssl/src/include/openssl/bytestring.h" #include "third_party/boringssl/src/include/openssl/ec.h" #include "third_party/boringssl/src/include/openssl/ec_key.h" #include "third_party/boringssl/src/include/openssl/evp.h" #include "third_party/boringssl/src/include/openssl/mem.h" +#include "third_party/boringssl/src/include/openssl/rsa.h" namespace device { @@ -134,6 +138,52 @@ } }; +class RSAPrivateKey : public EVPBackedPrivateKey { + public: + RSAPrivateKey() : EVPBackedPrivateKey(EVP_PKEY_RSA, ConfigureKeyGen) {} + + explicit RSAPrivateKey(bssl::UniquePtr<EVP_PKEY> pkey) + : EVPBackedPrivateKey(std::move(pkey)) {} + + std::unique_ptr<PublicKey> GetPublicKey() const override { + const RSA* rsa = EVP_PKEY_get0_RSA(pkey_.get()); + const BIGNUM* n = RSA_get0_n(rsa); + const BIGNUM* e = RSA_get0_e(rsa); + + std::vector<uint8_t> modulus(BN_num_bytes(n)); + BN_bn2bin(n, modulus.data()); + + std::vector<uint8_t> public_exponent(BN_num_bytes(e)); + BN_bn2bin(e, public_exponent.data()); + + cbor::Value::MapValue map; + map.emplace(static_cast<int64_t>(CoseKeyKey::kAlg), + static_cast<int64_t>(CoseAlgorithmIdentifier::kCoseRs256)); + map.emplace(static_cast<int64_t>(CoseKeyKey::kKty), + static_cast<int64_t>(CoseKeyTypes::kRSA)); + map.emplace(static_cast<int64_t>(CoseKeyKey::kRSAModulus), + std::move(modulus)); + map.emplace(static_cast<int64_t>(CoseKeyKey::kRSAPublicExponent), + std::move(public_exponent)); + + base::Optional<std::vector<uint8_t>> cbor_bytes( + cbor::Writer::Write(cbor::Value(std::move(map)))); + + std::vector<uint8_t> der_bytes( + CBBFunctionToVector<decltype(EVP_marshal_public_key), + EVP_marshal_public_key>(pkey_.get())); + + return std::make_unique<PublicKey>( + static_cast<int32_t>(CoseAlgorithmIdentifier::kCoseRs256), *cbor_bytes, + std::move(der_bytes)); + } + + private: + static int ConfigureKeyGen(EVP_PKEY_CTX* ctx) { + return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048); + } +}; + } // namespace // VirtualFidoDevice::PrivateKey ---------------------------------------------- @@ -167,6 +217,10 @@ return base::nullopt; } return std::unique_ptr<PrivateKey>(new P256PrivateKey(std::move(pkey))); + + case EVP_PKEY_RSA: + return std::unique_ptr<PrivateKey>(new RSAPrivateKey(std::move(pkey))); + default: return base::nullopt; } @@ -286,6 +340,12 @@ return std::make_unique<P256PrivateKey>(); } +// static +std::unique_ptr<VirtualFidoDevice::PrivateKey> +VirtualFidoDevice::FreshRSAKey() { + return std::unique_ptr<PrivateKey>(new RSAPrivateKey); +} + bool VirtualFidoDevice::Sign(crypto::ECPrivateKey* private_key, base::span<const uint8_t> sign_buffer, std::vector<uint8_t>* signature) {
diff --git a/device/fido/virtual_fido_device.h b/device/fido/virtual_fido_device.h index 4f14dcc4..267b5b7b 100644 --- a/device/fido/virtual_fido_device.h +++ b/device/fido/virtual_fido_device.h
@@ -259,6 +259,7 @@ scoped_refptr<State> NewReferenceToState() const { return state_; } static std::unique_ptr<PrivateKey> FreshP256Key(); + static std::unique_ptr<PrivateKey> FreshRSAKey(); static bool Sign(crypto::ECPrivateKey* private_key, base::span<const uint8_t> sign_buffer, std::vector<uint8_t>* signature);
diff --git a/device/udev_linux/fake_udev_loader.cc b/device/udev_linux/fake_udev_loader.cc index 2ce37827..c825ec1 100644 --- a/device/udev_linux/fake_udev_loader.cc +++ b/device/udev_linux/fake_udev_loader.cc
@@ -58,6 +58,10 @@ return devices_.back().get(); } +void FakeUdevLoader::Reset() { + devices_.clear(); +} + bool FakeUdevLoader::Init() { return true; }
diff --git a/device/udev_linux/fake_udev_loader.h b/device/udev_linux/fake_udev_loader.h index 850674f..da6d8d6 100644 --- a/device/udev_linux/fake_udev_loader.h +++ b/device/udev_linux/fake_udev_loader.h
@@ -25,6 +25,8 @@ std::map<std::string, std::string> sysattrs, std::map<std::string, std::string> properties); + void Reset(); + private: bool Init() override; const char* udev_device_get_action(udev_device* udev_device) override;
diff --git a/docs/gpu/gpu_testing.md b/docs/gpu/gpu_testing.md index 807b42f6..a2d9b204 100644 --- a/docs/gpu/gpu_testing.md +++ b/docs/gpu/gpu_testing.md
@@ -562,6 +562,13 @@ `https://chrome-gpu-gold.skia.org/search?query=name%3D<test name>` +**NOTE** If you have a grace period active for your test, then Gold will be told +to ignore results for the test. This is so that it does not comment on unrelated +CLs about untriaged images if your test is noisy. Images will still be uploaded +to Gold and can be triaged, but will not show up on the main page's untriaged +image list, and you will need to enable the "Ignored" toggle at the top of the +page when looking at the triage page specific to your test. + ## Stamping out Flakiness It's critically important to aggressively investigate and eliminate the root
diff --git a/docs/linux/debugging.md b/docs/linux/debugging.md index 69ef581a..fd96694 100644 --- a/docs/linux/debugging.md +++ b/docs/linux/debugging.md
@@ -258,6 +258,10 @@ and then debugging based on that. I recommend installing it by compiling [from source](https://github.com/mozilla/rr/wiki/Building-And-Installing). +Currently you must apply a patch adding +[support for recording the MADV_WIPEONFORK](https://bugs.chromium.org/p/chromium/issues/detail?id=1082304#c6) +syscall as upstream rr triggers an internal assert on this call. + Once installed, you can use it like this: ``` rr record out/Debug/content_shell --single-process --no-sandbox --disable-hang-monitor --single-process --disable-seccomp-sandbox --disable-setuid-sandbox
diff --git a/extensions/browser/api/declarative_net_request/composite_matcher.cc b/extensions/browser/api/declarative_net_request/composite_matcher.cc index 9027b4b5..d2da82a8 100644 --- a/extensions/browser/api/declarative_net_request/composite_matcher.cc +++ b/extensions/browser/api/declarative_net_request/composite_matcher.cc
@@ -10,12 +10,14 @@ #include <utility> #include "base/metrics/histogram_macros.h" +#include "base/stl_util.h" #include "base/time/time.h" #include "base/timer/elapsed_timer.h" #include "extensions/browser/api/declarative_net_request/flat/extension_ruleset_generated.h" #include "extensions/browser/api/declarative_net_request/request_action.h" #include "extensions/browser/api/declarative_net_request/request_params.h" #include "extensions/browser/api/declarative_net_request/utils.h" +#include "extensions/common/api/declarative_net_request/constants.h" namespace extensions { namespace declarative_net_request { @@ -71,27 +73,41 @@ CompositeMatcher::~CompositeMatcher() = default; +CompositeMatcher::MatcherList CompositeMatcher::GetAndResetMatchers() { + MatcherList result; + std::swap(result, matchers_); + OnMatchersModified(); + return result; +} + +void CompositeMatcher::SetMatchers(MatcherList matchers) { + matchers_ = std::move(matchers); + OnMatchersModified(); +} + void CompositeMatcher::AddOrUpdateRuleset( std::unique_ptr<RulesetMatcher> new_matcher) { // A linear search is ok since the number of rulesets per extension is // expected to be quite small. - auto it = std::find_if( - matchers_.begin(), matchers_.end(), - [&new_matcher](const std::unique_ptr<RulesetMatcher>& matcher) { - return new_matcher->id() == matcher->id(); - }); + base::EraseIf(matchers_, + [&new_matcher](const std::unique_ptr<RulesetMatcher>& matcher) { + return matcher->id() == new_matcher->id(); + }); + matchers_.push_back(std::move(new_matcher)); - if (it == matchers_.end()) { - matchers_.push_back(std::move(new_matcher)); - } else { - // Update the matcher. - *it = std::move(new_matcher); + OnMatchersModified(); +} + +std::set<RulesetID> CompositeMatcher::ComputeStaticRulesetIDs() const { + std::set<RulesetID> result; + for (const std::unique_ptr<RulesetMatcher>& matcher : matchers_) { + if (matcher->id() == kDynamicRulesetID) + continue; + + result.insert(matcher->id()); } - // Clear the renderers' cache so that they take the updated rules into - // account. - ClearRendererCacheOnNavigation(); - has_any_extra_headers_matcher_.reset(); + return result; } ActionInfo CompositeMatcher::GetBeforeRequestAction( @@ -205,6 +221,16 @@ matcher->OnDidFinishNavigation(host); } +void CompositeMatcher::OnMatchersModified() { + DCHECK(AreIDsUnique(matchers_)); + + // Clear the renderers' cache so that they take the updated rules into + // account. + ClearRendererCacheOnNavigation(); + + has_any_extra_headers_matcher_.reset(); +} + bool CompositeMatcher::ComputeHasAnyExtraHeadersMatcher() const { for (const auto& matcher : matchers_) { if (matcher->IsExtraHeadersMatcher())
diff --git a/extensions/browser/api/declarative_net_request/composite_matcher.h b/extensions/browser/api/declarative_net_request/composite_matcher.h index 855de8a9..4e77b3e 100644 --- a/extensions/browser/api/declarative_net_request/composite_matcher.h +++ b/extensions/browser/api/declarative_net_request/composite_matcher.h
@@ -7,6 +7,7 @@ #include <cstdint> #include <memory> +#include <set> #include <vector> #include "base/macros.h" @@ -53,10 +54,20 @@ const MatcherList& matchers() const { return matchers_; } + // Returns the set of matchers and resets |matchers_| to an empty vector. + MatcherList GetAndResetMatchers(); + + // Updates the set of matchers. IDs for all the |matchers| must be unique. + void SetMatchers(MatcherList matchers); + // Adds the |new_matcher| to the list of matchers. If a matcher with the // corresponding ID is already present, updates the matcher. void AddOrUpdateRuleset(std::unique_ptr<RulesetMatcher> new_matcher); + // Computes and returns the set of static RulesetIDs corresponding to + // |matchers_|. + std::set<RulesetID> ComputeStaticRulesetIDs() const; + // Returns a RequestAction for the network request specified by |params|, or // base::nullopt if there is no matching rule. ActionInfo GetBeforeRequestAction( @@ -87,8 +98,12 @@ void OnDidFinishNavigation(content::RenderFrameHost* host); private: + // This must be called whenever |matchers_| are modified. + void OnMatchersModified(); + bool ComputeHasAnyExtraHeadersMatcher() const; + // The RulesetMatchers, in an arbitrary order. MatcherList matchers_; // Denotes the cached return value for |HasAnyExtraHeadersMatcher|. Care must
diff --git a/extensions/browser/api/declarative_net_request/composite_matcher_unittest.cc b/extensions/browser/api/declarative_net_request/composite_matcher_unittest.cc index f83ac82..356e427 100644 --- a/extensions/browser/api/declarative_net_request/composite_matcher_unittest.cc +++ b/extensions/browser/api/declarative_net_request/composite_matcher_unittest.cc
@@ -9,7 +9,7 @@ #include <vector> #include "base/strings/stringprintf.h" -#include "components/version_info/version_info.h" +#include "components/version_info/channel.h" #include "extensions/browser/api/declarative_net_request/constants.h" #include "extensions/browser/api/declarative_net_request/request_action.h" #include "extensions/browser/api/declarative_net_request/request_params.h" @@ -34,16 +34,7 @@ namespace dnr_api = api::declarative_net_request; -class CompositeMatcherTest : public ::testing::Test { - public: - CompositeMatcherTest() : channel_(::version_info::Channel::UNKNOWN) {} - - private: - // Run this on the trunk channel to ensure the API is available. - ScopedCurrentChannel channel_; - - DISALLOW_COPY_AND_ASSIGN(CompositeMatcherTest); -}; +using CompositeMatcherTest = ::testing::Test; // Ensure that the rules in a CompositeMatcher are in the same priority space. TEST_F(CompositeMatcherTest, SamePrioritySpace) { @@ -193,6 +184,10 @@ // Tests the GetModifyHeadersActions method. TEST_F(CompositeMatcherTest, GetModifyHeadersActions) { + // TODO(crbug.com/947591): Remove the channel override once implementation of + // modifyHeaders action is complete. + ScopedCurrentChannel channel(::version_info::Channel::UNKNOWN); + auto create_modify_headers_rule = [](int id, int priority, const std::string& url_filter, std::vector<TestHeaderInfo> request_headers_list) {
diff --git a/extensions/browser/api/declarative_net_request/constants.cc b/extensions/browser/api/declarative_net_request/constants.cc index 219e538..078962ae 100644 --- a/extensions/browser/api/declarative_net_request/constants.cc +++ b/extensions/browser/api/declarative_net_request/constants.cc
@@ -91,6 +91,15 @@ const char kDynamicRuleCountExceeded[] = "Dynamic rule count exceeded."; const char kDynamicRegexRuleCountExceeded[] = "Dynamic rule count for regex rules exceeded."; + +const char kInvalidRulesetIDError[] = "Invalid ruleset id: *."; +const char kEnabledRulesetsRuleCountExceeded[] = + "The set of enabled rulesets exceeds the rule count limit."; +const char kEnabledRulesetsRegexRuleCountExceeded[] = + "The set of enabled rulesets exceeds the regular expression rule count " + "limit."; +const char kInternalErrorUpdatingEnabledRulesets[] = "Internal error."; + const char kIndexAndPersistRulesTimeHistogram[] = "Extensions.DeclarativeNetRequest.IndexAndPersistRulesTime"; const char kManifestRulesCountHistogram[] =
diff --git a/extensions/browser/api/declarative_net_request/constants.h b/extensions/browser/api/declarative_net_request/constants.h index 394a0628..39f378d 100644 --- a/extensions/browser/api/declarative_net_request/constants.h +++ b/extensions/browser/api/declarative_net_request/constants.h
@@ -129,6 +129,12 @@ extern const char kDynamicRuleCountExceeded[]; extern const char kDynamicRegexRuleCountExceeded[]; +// Static ruleset toggling API errors. +extern const char kInvalidRulesetIDError[]; +extern const char kEnabledRulesetsRuleCountExceeded[]; +extern const char kEnabledRulesetsRegexRuleCountExceeded[]; +extern const char kInternalErrorUpdatingEnabledRulesets[]; + // Histogram names. extern const char kIndexAndPersistRulesTimeHistogram[]; extern const char kManifestRulesCountHistogram[];
diff --git a/extensions/browser/api/declarative_net_request/declarative_net_request_api.cc b/extensions/browser/api/declarative_net_request/declarative_net_request_api.cc index f52ac69..755b2461 100644 --- a/extensions/browser/api/declarative_net_request/declarative_net_request_api.cc +++ b/extensions/browser/api/declarative_net_request/declarative_net_request_api.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/optional.h" +#include "base/stl_util.h" #include "base/strings/stringprintf.h" #include "base/task/post_task.h" #include "base/task_runner_util.h" @@ -27,6 +28,8 @@ #include "extensions/browser/quota_service.h" #include "extensions/common/api/declarative_net_request.h" #include "extensions/common/api/declarative_net_request/constants.h" +#include "extensions/common/api/declarative_net_request/dnr_manifest_data.h" +#include "extensions/common/error_utils.h" #include "extensions/common/extension_id.h" namespace extensions { @@ -144,6 +147,105 @@ dnr_api::GetDynamicRules::Results::Create(read_json_result.rules))); } +DeclarativeNetRequestUpdateEnabledRulesetsFunction:: + DeclarativeNetRequestUpdateEnabledRulesetsFunction() = default; +DeclarativeNetRequestUpdateEnabledRulesetsFunction:: + ~DeclarativeNetRequestUpdateEnabledRulesetsFunction() = default; + +ExtensionFunction::ResponseAction +DeclarativeNetRequestUpdateEnabledRulesetsFunction::Run() { + using Params = dnr_api::UpdateEnabledRulesets::Params; + using RulesetID = declarative_net_request::RulesetID; + using DNRManifestData = declarative_net_request::DNRManifestData; + + base::string16 error; + std::unique_ptr<Params> params(Params::Create(*args_, &error)); + EXTENSION_FUNCTION_VALIDATE(params); + EXTENSION_FUNCTION_VALIDATE(error.empty()); + + auto* rules_monitor_service = + declarative_net_request::RulesMonitorService::Get(browser_context()); + DCHECK(rules_monitor_service); + DCHECK(extension()); + + std::set<RulesetID> ids_to_disable; + std::set<RulesetID> ids_to_enable; + const DNRManifestData::ManifestIDToRulesetMap& public_id_map = + DNRManifestData::GetManifestIDToRulesetMap(*extension()); + + for (const std::string& public_id_to_enable : params->ruleset_ids_to_enable) { + auto it = public_id_map.find(public_id_to_enable); + if (it == public_id_map.end()) { + return RespondNow(Error(ErrorUtils::FormatErrorMessage( + declarative_net_request::kInvalidRulesetIDError, + public_id_to_enable))); + } + + ids_to_enable.insert(it->second->id); + } + + for (const std::string& public_id_to_disable : + params->ruleset_ids_to_disable) { + auto it = public_id_map.find(public_id_to_disable); + if (it == public_id_map.end()) { + return RespondNow(Error(ErrorUtils::FormatErrorMessage( + declarative_net_request::kInvalidRulesetIDError, + public_id_to_disable))); + } + + // |ruleset_ids_to_enable| takes priority over |ruleset_ids_to_disable|. + RulesetID id = it->second->id; + if (base::Contains(ids_to_enable, id)) + continue; + + ids_to_disable.insert(id); + } + + rules_monitor_service->UpdateEnabledStaticRulesets( + *extension(), std::move(ids_to_disable), std::move(ids_to_enable), + base::BindOnce(&DeclarativeNetRequestUpdateEnabledRulesetsFunction:: + OnEnabledStaticRulesetsUpdated, + this)); + + return did_respond() ? AlreadyResponded() : RespondLater(); +} + +void DeclarativeNetRequestUpdateEnabledRulesetsFunction:: + OnEnabledStaticRulesetsUpdated(base::Optional<std::string> error) { + if (error) + Respond(Error(std::move(*error))); + else + Respond(NoArguments()); +} + +DeclarativeNetRequestGetEnabledRulesetsFunction:: + DeclarativeNetRequestGetEnabledRulesetsFunction() = default; +DeclarativeNetRequestGetEnabledRulesetsFunction:: + ~DeclarativeNetRequestGetEnabledRulesetsFunction() = default; + +ExtensionFunction::ResponseAction +DeclarativeNetRequestGetEnabledRulesetsFunction::Run() { + auto* rules_monitor_service = + declarative_net_request::RulesMonitorService::Get(browser_context()); + DCHECK(rules_monitor_service); + + std::vector<std::string> public_ids; + declarative_net_request::CompositeMatcher* matcher = + rules_monitor_service->ruleset_manager()->GetMatcherForExtension( + extension_id()); + if (matcher) { + DCHECK(extension()); + public_ids = GetPublicRulesetIDs(*extension(), *matcher); + + // Exclude the dynamic ruleset ID if present, as expected by the API + // function. + base::Erase(public_ids, dnr_api::DYNAMIC_RULESET_ID); + } + + return RespondNow( + ArgumentList(dnr_api::GetEnabledRulesets::Results::Create(public_ids))); +} + // static bool DeclarativeNetRequestGetMatchedRulesFunction::disable_throttling_for_test_ =
diff --git a/extensions/browser/api/declarative_net_request/declarative_net_request_api.h b/extensions/browser/api/declarative_net_request/declarative_net_request_api.h index 2d9ca2c..a42fe8a 100644 --- a/extensions/browser/api/declarative_net_request/declarative_net_request_api.h +++ b/extensions/browser/api/declarative_net_request/declarative_net_request_api.h
@@ -31,8 +31,6 @@ private: void OnDynamicRulesUpdated(base::Optional<std::string> error); - - DISALLOW_COPY_AND_ASSIGN(DeclarativeNetRequestUpdateDynamicRulesFunction); }; class DeclarativeNetRequestGetDynamicRulesFunction : public ExtensionFunction { @@ -50,8 +48,38 @@ private: void OnDynamicRulesFetched( declarative_net_request::ReadJSONRulesResult read_json_result); +}; - DISALLOW_COPY_AND_ASSIGN(DeclarativeNetRequestGetDynamicRulesFunction); +class DeclarativeNetRequestUpdateEnabledRulesetsFunction + : public ExtensionFunction { + public: + DeclarativeNetRequestUpdateEnabledRulesetsFunction(); + DECLARE_EXTENSION_FUNCTION("declarativeNetRequest.updateEnabledRulesets", + DECLARATIVENETREQUEST_UPDATEENABLEDRULESETS) + + protected: + ~DeclarativeNetRequestUpdateEnabledRulesetsFunction() override; + + private: + void OnEnabledStaticRulesetsUpdated(base::Optional<std::string> error); + + // ExtensionFunction override: + ExtensionFunction::ResponseAction Run() override; +}; + +class DeclarativeNetRequestGetEnabledRulesetsFunction + : public ExtensionFunction { + public: + DeclarativeNetRequestGetEnabledRulesetsFunction(); + DECLARE_EXTENSION_FUNCTION("declarativeNetRequest.getEnabledRulesets", + DECLARATIVENETREQUEST_GETENABLEDRULESETS) + + protected: + ~DeclarativeNetRequestGetEnabledRulesetsFunction() override; + + private: + // ExtensionFunction override: + ExtensionFunction::ResponseAction Run() override; }; class DeclarativeNetRequestGetMatchedRulesFunction : public ExtensionFunction { @@ -75,8 +103,6 @@ private: static bool disable_throttling_for_test_; - - DISALLOW_COPY_AND_ASSIGN(DeclarativeNetRequestGetMatchedRulesFunction); }; class DeclarativeNetRequestSetActionCountAsBadgeTextFunction @@ -90,10 +116,6 @@ ~DeclarativeNetRequestSetActionCountAsBadgeTextFunction() override; ExtensionFunction::ResponseAction Run() override; - - private: - DISALLOW_COPY_AND_ASSIGN( - DeclarativeNetRequestSetActionCountAsBadgeTextFunction); }; } // namespace extensions
diff --git a/extensions/browser/api/declarative_net_request/file_sequence_helper.h b/extensions/browser/api/declarative_net_request/file_sequence_helper.h index 63bf250..4a9e77cb 100644 --- a/extensions/browser/api/declarative_net_request/file_sequence_helper.h +++ b/extensions/browser/api/declarative_net_request/file_sequence_helper.h
@@ -114,6 +114,7 @@ // Loads rulesets for |load_data|. Invokes |ui_callback| on the UI thread once // loading is done. Also tries to reindex the rulesets on failure. + // |load_data.rulesets| must not be empty. using LoadRulesetsUICallback = base::OnceCallback<void(LoadRequestData)>; void LoadRulesets(LoadRequestData load_data, LoadRulesetsUICallback ui_callback) const;
diff --git a/extensions/browser/api/declarative_net_request/file_sequence_helper_unittest.cc b/extensions/browser/api/declarative_net_request/file_sequence_helper_unittest.cc index 56698d0..4f112cf8 100644 --- a/extensions/browser/api/declarative_net_request/file_sequence_helper_unittest.cc +++ b/extensions/browser/api/declarative_net_request/file_sequence_helper_unittest.cc
@@ -15,7 +15,6 @@ #include "base/test/metrics/histogram_tester.h" #include "base/threading/thread_restrictions.h" #include "components/crx_file/id_util.h" -#include "components/version_info/version_info.h" #include "extensions/browser/api/declarative_net_request/constants.h" #include "extensions/browser/api/declarative_net_request/parse_info.h" #include "extensions/browser/api/declarative_net_request/ruleset_source.h" @@ -26,7 +25,6 @@ #include "extensions/common/api/declarative_net_request.h" #include "extensions/common/api/declarative_net_request/constants.h" #include "extensions/common/api/declarative_net_request/test_utils.h" -#include "extensions/common/features/feature_channel.h" #include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h" #include "testing/gtest/include/gtest/gtest.h" @@ -62,7 +60,7 @@ class FileSequenceHelperTest : public ExtensionsTest { public: - FileSequenceHelperTest() : channel_(::version_info::Channel::UNKNOWN) {} + FileSequenceHelperTest() = default; // ExtensionsTest overrides: void SetUp() override { @@ -182,9 +180,6 @@ } private: - // Run this on the trunk channel to ensure the API is available. - ScopedCurrentChannel channel_; - std::unique_ptr<FileSequenceHelper> helper_; // Required to use DataDecoder's JSON parsing for re-indexing.
diff --git a/extensions/browser/api/declarative_net_request/index_helper.cc b/extensions/browser/api/declarative_net_request/index_helper.cc index 9d887120..e573e2a0 100644 --- a/extensions/browser/api/declarative_net_request/index_helper.cc +++ b/extensions/browser/api/declarative_net_request/index_helper.cc
@@ -64,7 +64,7 @@ total_index_and_persist_time += index_result.index_and_persist_time; total_rules_count += index_result.rules_count; - if (source->enabled()) { + if (source->enabled_by_default()) { enabled_rules_count += index_result.rules_count; enabled_regex_rules_count += index_result.regex_rules_count; }
diff --git a/extensions/browser/api/declarative_net_request/indexed_rule_unittest.cc b/extensions/browser/api/declarative_net_request/indexed_rule_unittest.cc index ab7959e4..cb8e429 100644 --- a/extensions/browser/api/declarative_net_request/indexed_rule_unittest.cc +++ b/extensions/browser/api/declarative_net_request/indexed_rule_unittest.cc
@@ -14,13 +14,11 @@ #include "base/stl_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" -#include "components/version_info/version_info.h" #include "extensions/browser/api/declarative_net_request/constants.h" #include "extensions/browser/api/declarative_net_request/test_utils.h" #include "extensions/common/api/declarative_net_request.h" #include "extensions/common/api/declarative_net_request/constants.h" #include "extensions/common/extension.h" -#include "extensions/common/features/feature_channel.h" #include "testing/gtest/include/gtest/gtest.h" namespace extensions { @@ -51,15 +49,7 @@ return rule; } -class IndexedRuleTest : public testing::Test { - public: - IndexedRuleTest() : channel_(::version_info::Channel::UNKNOWN) {} - - private: - ScopedCurrentChannel channel_; - - DISALLOW_COPY_AND_ASSIGN(IndexedRuleTest); -}; +using IndexedRuleTest = ::testing::Test; TEST_F(IndexedRuleTest, IDParsing) { struct {
diff --git a/extensions/browser/api/declarative_net_request/rules_monitor_service.cc b/extensions/browser/api/declarative_net_request/rules_monitor_service.cc index 8d8d090..1b00322 100644 --- a/extensions/browser/api/declarative_net_request/rules_monitor_service.cc +++ b/extensions/browser/api/declarative_net_request/rules_monitor_service.cc
@@ -14,11 +14,13 @@ #include "base/lazy_instance.h" #include "base/location.h" #include "base/memory/ptr_util.h" +#include "base/stl_util.h" #include "base/task/post_task.h" #include "base/threading/thread_restrictions.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "extensions/browser/api/declarative_net_request/composite_matcher.h" +#include "extensions/browser/api/declarative_net_request/constants.h" #include "extensions/browser/api/declarative_net_request/file_sequence_helper.h" #include "extensions/browser/api/declarative_net_request/ruleset_manager.h" #include "extensions/browser/api/declarative_net_request/ruleset_matcher.h" @@ -134,37 +136,29 @@ // Sanity check that this is only called for an enabled extension. DCHECK(extension_registry_->enabled_extensions().Contains(extension.id())); - DynamicRuleUpdate update(std::move(rule_ids_to_remove), - std::move(rules_to_add), std::move(callback)); - - // There are two possible cases, either the extension has completed its - // initial ruleset load in response to OnExtensionLoaded or it is still - // undergoing that load. For the latter case, we must wait till the ruleset - // loading is complete. - auto it = pending_dynamic_rule_updates_.find(extension.id()); - if (it != pending_dynamic_rule_updates_.end()) { - it->second.push_back(std::move(update)); - return; - } - - // Else we can update dynamic rules immediately. - UpdateDynamicRulesInternal(extension.id(), std::move(update)); + ExecuteOrQueueAPICall( + extension, + base::BindOnce(&RulesMonitorService::UpdateDynamicRulesInternal, + weak_factory_.GetWeakPtr(), extension.id(), + std::move(rule_ids_to_remove), std::move(rules_to_add), + std::move(callback))); } -RulesMonitorService::DynamicRuleUpdate::DynamicRuleUpdate( - std::vector<int> rule_ids_to_remove, - std::vector<api::declarative_net_request::Rule> rules_to_add, - RulesMonitorService::DynamicRuleUpdateUICallback ui_callback) - : rule_ids_to_remove(std::move(rule_ids_to_remove)), - rules_to_add(std::move(rules_to_add)), - ui_callback(std::move(ui_callback)) {} +void RulesMonitorService::UpdateEnabledStaticRulesets( + const Extension& extension, + std::set<RulesetID> ids_to_disable, + std::set<RulesetID> ids_to_enable, + UpdateEnabledRulesetsUICallback callback) { + // Sanity check that this is only called for an enabled extension. + DCHECK(extension_registry_->enabled_extensions().Contains(extension.id())); -RulesMonitorService::DynamicRuleUpdate::DynamicRuleUpdate(DynamicRuleUpdate&&) = - default; -RulesMonitorService::DynamicRuleUpdate& -RulesMonitorService::DynamicRuleUpdate::operator=(DynamicRuleUpdate&&) = - default; -RulesMonitorService::DynamicRuleUpdate::~DynamicRuleUpdate() = default; + ExecuteOrQueueAPICall( + extension, + base::BindOnce(&RulesMonitorService::UpdateEnabledStaticRulesetsInternal, + weak_factory_.GetWeakPtr(), extension.id(), + std::move(ids_to_disable), std::move(ids_to_enable), + std::move(callback))); +} RulesMonitorService::RulesMonitorService( content::BrowserContext* browser_context) @@ -214,9 +208,16 @@ { std::vector<RulesetSource> sources = RulesetSource::CreateStatic(*extension); + + base::Optional<std::set<RulesetID>> prefs_enabled_rulesets = + prefs_->GetDNREnabledStaticRulesets(extension->id()); + bool ruleset_failed_to_load = false; for (auto& source : sources) { - if (!source.enabled()) + bool enabled = prefs_enabled_rulesets + ? base::Contains(*prefs_enabled_rulesets, source.id()) + : source.enabled_by_default(); + if (!enabled) continue; if (!prefs_->GetDNRStaticRulesetChecksum(extension->id(), source.id(), @@ -246,12 +247,6 @@ load_data.rulesets.push_back(std::move(dynamic_ruleset)); } - // Sort by ruleset IDs. This would ensure the dynamic ruleset comes first - // followed by static rulesets, which would be in the order in which they were - // defined in the manifest. - std::sort(load_data.rulesets.begin(), load_data.rulesets.end(), - &RulesetInfoCompareByID); - if (load_data.rulesets.empty()) { if (test_observer_) test_observer_->OnRulesetLoadComplete(extension->id()); @@ -259,16 +254,17 @@ return; } - // Add an entry for the extension in |pending_dynamic_rule_updates_| to - // indicate that it's loading its rulesets. + // Add an entry for the extension in |tasks_pending_on_load_| to indicate that + // it's loading its rulesets. bool inserted = - pending_dynamic_rule_updates_ - .emplace(extension->id(), std::vector<DynamicRuleUpdate>()) + tasks_pending_on_load_ + .emplace(extension->id(), std::make_unique<base::OneShotEvent>()) .second; DCHECK(inserted); - auto load_ruleset_callback = base::BindOnce( - &RulesMonitorService::OnRulesetsLoaded, weak_factory_.GetWeakPtr()); + auto load_ruleset_callback = + base::BindOnce(&RulesMonitorService::OnInitialRulesetsLoaded, + weak_factory_.GetWeakPtr()); file_sequence_bridge_->LoadRulesets(std::move(load_data), std::move(load_ruleset_callback)); } @@ -283,7 +279,7 @@ if (!ruleset_manager_.GetMatcherForExtension(extension->id())) return; - UnloadRulesets(extension->id()); + RemoveCompositeMatcher(extension->id()); } void RulesMonitorService::OnExtensionUninstalled( @@ -317,12 +313,14 @@ void RulesMonitorService::UpdateDynamicRulesInternal( const ExtensionId& extension_id, - DynamicRuleUpdate update) { + std::vector<int> rule_ids_to_remove, + std::vector<api::declarative_net_request::Rule> rules_to_add, + DynamicRuleUpdateUICallback callback) { if (!extension_registry_->enabled_extensions().Contains(extension_id)) { // There is no enabled extension to respond to. While this is probably a // no-op, still dispatch the callback to ensure any related book-keeping is // done. - std::move(update.ui_callback).Run(base::nullopt /* error */); + std::move(callback).Run(base::nullopt /* error */); return; } @@ -335,59 +333,79 @@ auto update_rules_callback = base::BindOnce(&RulesMonitorService::OnDynamicRulesUpdated, - weak_factory_.GetWeakPtr(), std::move(update.ui_callback)); + weak_factory_.GetWeakPtr(), std::move(callback)); file_sequence_bridge_->UpdateDynamicRules( - std::move(data), std::move(update.rule_ids_to_remove), - std::move(update.rules_to_add), std::move(update_rules_callback)); + std::move(data), std::move(rule_ids_to_remove), std::move(rules_to_add), + std::move(update_rules_callback)); } -void RulesMonitorService::OnRulesetsLoaded(LoadRequestData load_data) { +void RulesMonitorService::UpdateEnabledStaticRulesetsInternal( + const ExtensionId& extension_id, + std::set<RulesetID> ids_to_disable, + std::set<RulesetID> ids_to_enable, + UpdateEnabledRulesetsUICallback callback) { + const Extension* extension = extension_registry_->GetExtensionById( + extension_id, ExtensionRegistry::ENABLED); + if (!extension) { + // There is no enabled extension to respond to. While this is probably a + // no-op, still dispatch the callback to ensure any related book-keeping is + // done. + std::move(callback).Run(base::nullopt /* error */); + return; + } + + LoadRequestData load_data(extension_id); + + // Don't hop to the file sequence if there are no rulesets to load. + // TODO(karandeepb): Hop to the file sequence in this case as well to ensure + // that subsequent updateEnabledRulesets calls complete in FIFO order. + if (ids_to_enable.empty()) { + OnNewStaticRulesetsLoaded(std::move(callback), std::move(ids_to_disable), + std::move(ids_to_enable), std::move(load_data)); + return; + } + + int expected_ruleset_checksum = -1; + for (const RulesetID& id_to_enable : ids_to_enable) { + if (!prefs_->GetDNRStaticRulesetChecksum(extension_id, id_to_enable, + &expected_ruleset_checksum)) { + // This might happen on prefs corruption. + // TODO(crbug.com/754526): Log metrics on how often this happens. + std::move(callback).Run(kInternalErrorUpdatingEnabledRulesets); + return; + } + + const DNRManifestData::RulesetInfo& info = + DNRManifestData::GetRuleset(*extension, id_to_enable); + RulesetInfo static_ruleset(RulesetSource::CreateStatic(*extension, info)); + static_ruleset.set_expected_checksum(expected_ruleset_checksum); + load_data.rulesets.push_back(std::move(static_ruleset)); + } + + auto load_ruleset_callback = + base::BindOnce(&RulesMonitorService::OnNewStaticRulesetsLoaded, + weak_factory_.GetWeakPtr(), std::move(callback), + std::move(ids_to_disable), std::move(ids_to_enable)); + file_sequence_bridge_->LoadRulesets(std::move(load_data), + std::move(load_ruleset_callback)); +} + +void RulesMonitorService::OnInitialRulesetsLoaded(LoadRequestData load_data) { DCHECK(!load_data.rulesets.empty()); - DCHECK(std::all_of( - load_data.rulesets.begin(), load_data.rulesets.end(), - [](const RulesetInfo& ruleset) { return ruleset.source().enabled(); })); - DCHECK(std::is_sorted(load_data.rulesets.begin(), load_data.rulesets.end(), - &RulesetInfoCompareByID)); - // Perform pending dynamic rule updates. + // Signal ruleset load completion. { - auto it = pending_dynamic_rule_updates_.find(load_data.extension_id); - - // Even if there are no updates to perform (i.e., the list is empty), we - // expect an entry in the map. - DCHECK(it != pending_dynamic_rule_updates_.end()); - - for (DynamicRuleUpdate& update : it->second) - UpdateDynamicRulesInternal(load_data.extension_id, std::move(update)); - - pending_dynamic_rule_updates_.erase(it); + auto it = tasks_pending_on_load_.find(load_data.extension_id); + DCHECK(it != tasks_pending_on_load_.end()); + DCHECK(!it->second->is_signaled()); + it->second->Signal(); + tasks_pending_on_load_.erase(it); } if (test_observer_) test_observer_->OnRulesetLoadComplete(load_data.extension_id); - // The extension may have been uninstalled by this point. Return early if - // that's the case. - if (!extension_registry_->GetInstalledExtension(load_data.extension_id)) - return; - - // Update checksums for all rulesets. - // Note: We also do this for a non-enabled extension. The ruleset on the disk - // has already been modified at this point. So we do want to update the - // checksum for it to be in sync with what's on disk. - for (const RulesetInfo& ruleset : load_data.rulesets) { - if (!ruleset.new_checksum()) - continue; - - if (ruleset.source().is_dynamic_ruleset()) { - prefs_->SetDNRDynamicRulesetChecksum(load_data.extension_id, - *(ruleset.new_checksum())); - } else { - prefs_->SetDNRStaticRulesetChecksum(load_data.extension_id, - ruleset.source().id(), - *(ruleset.new_checksum())); - } - } + UpdateRulesetChecksumsIfNeeded(load_data); // It's possible that the extension has been disabled since the initial load // ruleset request. If it's disabled, do nothing. @@ -396,12 +414,19 @@ return; } + // Sort by ruleset IDs. This would ensure the dynamic ruleset comes first + // followed by static rulesets, which would be in the order in which they were + // defined in the manifest. + std::sort(load_data.rulesets.begin(), load_data.rulesets.end(), + &RulesetInfoCompareByID); + // Build the CompositeMatcher for the extension. Also enforce rules limit // across the enabled static rulesets. Note: we don't enforce the rules limit // at install time (by raising a hard error) to maintain forwards - // compatibility. Since we iterate based on the ruleset ID, we'll give more - // preference to rulesets occurring first in the manifest. + // compatibility. Since we iterate based on the order of ruleset ID, we'll + // give more preference to rulesets occurring first in the manifest. CompositeMatcher::MatcherList matchers; + matchers.reserve(load_data.rulesets.size()); size_t static_rules_count = 0; size_t static_regex_rules_count = 0; bool notify_ruleset_failed_to_load = false; @@ -448,8 +473,140 @@ if (matchers.empty()) return; - LoadRulesets(load_data.extension_id, - std::make_unique<CompositeMatcher>(std::move(matchers))); + AddCompositeMatcher(load_data.extension_id, + std::make_unique<CompositeMatcher>(std::move(matchers))); +} + +void RulesMonitorService::OnNewStaticRulesetsLoaded( + UpdateEnabledRulesetsUICallback callback, + std::set<RulesetID> ids_to_disable, + std::set<RulesetID> ids_to_enable, + LoadRequestData load_data) { + UpdateRulesetChecksumsIfNeeded(load_data); + + // It's possible that the extension has been disabled since the initial + // request. If it's disabled, return early. + if (!extension_registry_->enabled_extensions().Contains( + load_data.extension_id)) { + // Still dispatch the |callback|, even though it's probably a no-op. + std::move(callback).Run(base::nullopt /* error */); + return; + } + + size_t static_rules_count = 0; + size_t static_regex_rules_count = 0; + CompositeMatcher* matcher = + ruleset_manager_.GetMatcherForExtension(load_data.extension_id); + if (matcher) { + // Iterate over the existing matchers to compute |static_rules_count| and + // |static_regex_rules_count|. + for (const std::unique_ptr<RulesetMatcher>& matcher : matcher->matchers()) { + // Exclude since we are only including static rulesets. + if (matcher->id() == kDynamicRulesetID) + continue; + + // Exclude since we'll be removing this |matcher|. + if (base::Contains(ids_to_disable, matcher->id())) + continue; + + // Exclude to prevent double counting. This will be a part of + // |new_matchers| below. + if (base::Contains(ids_to_enable, matcher->id())) + continue; + + static_rules_count += matcher->GetRulesCount(); + static_regex_rules_count += matcher->GetRegexRulesCount(); + } + } + + CompositeMatcher::MatcherList new_matchers; + new_matchers.reserve(load_data.rulesets.size()); + for (RulesetInfo& ruleset : load_data.rulesets) { + if (!ruleset.did_load_successfully()) { + // TODO(crbug.com/754526): Log metrics on how often this happens. + std::move(callback).Run(kInternalErrorUpdatingEnabledRulesets); + return; + } + + std::unique_ptr<RulesetMatcher> matcher = ruleset.TakeMatcher(); + + // Per-ruleset limits should have been enforced during + // indexing/installation. + DCHECK_LE(matcher->GetRegexRulesCount(), + static_cast<size_t>(dnr_api::MAX_NUMBER_OF_REGEX_RULES)); + DCHECK_LE(matcher->GetRulesCount(), ruleset.source().rule_count_limit()); + + static_rules_count += matcher->GetRulesCount(); + static_regex_rules_count += matcher->GetRegexRulesCount(); + new_matchers.push_back(std::move(matcher)); + } + + if (static_rules_count > static_cast<size_t>(dnr_api::MAX_NUMBER_OF_RULES)) { + std::move(callback).Run(kEnabledRulesetsRuleCountExceeded); + return; + } + + if (static_regex_rules_count > + static_cast<size_t>(dnr_api::MAX_NUMBER_OF_REGEX_RULES)) { + std::move(callback).Run(kEnabledRulesetsRegexRuleCountExceeded); + return; + } + + if (!matcher) { + // The extension didn't have any existing rulesets. Hence just add a new + // CompositeMatcher with |new_matchers|. + AddCompositeMatcher( + load_data.extension_id, + std::make_unique<CompositeMatcher>(std::move(new_matchers))); + std::move(callback).Run(base::nullopt); + return; + } + + bool had_extra_headers_matcher = ruleset_manager_.HasAnyExtraHeadersMatcher(); + + // Do another pass over the existing matchers for the extension to compute the + // final set of matchers. + { + CompositeMatcher::MatcherList old_matchers = matcher->GetAndResetMatchers(); + base::EraseIf(old_matchers, + [&ids_to_disable, &ids_to_enable]( + const std::unique_ptr<RulesetMatcher>& matcher) { + // We also check |ids_to_enable| to omit duplicate matchers. + // |new_matchers| already contains RulesetMatchers + // corresponding to |ids_to_enable|. + return base::Contains(ids_to_disable, matcher->id()) || + base::Contains(ids_to_enable, matcher->id()); + }); + + new_matchers.insert(new_matchers.end(), + std::make_move_iterator(old_matchers.begin()), + std::make_move_iterator(old_matchers.end())); + } + + matcher->SetMatchers(std::move(new_matchers)); + + prefs_->SetDNREnabledStaticRulesets(load_data.extension_id, + matcher->ComputeStaticRulesetIDs()); + + AdjustExtraHeaderListenerCountIfNeeded(had_extra_headers_matcher); + + std::move(callback).Run(base::nullopt); +} + +void RulesMonitorService::ExecuteOrQueueAPICall(const Extension& extension, + base::OnceClosure task) { + auto it = tasks_pending_on_load_.find(extension.id()); + if (it != tasks_pending_on_load_.end()) { + // The ruleset is still loading in response to OnExtensionLoaded(). Wait + // till the ruleset loading is complete to prevent a race. + DCHECK(!it->second->is_signaled()); + it->second->Post(FROM_HERE, std::move(task)); + return; + } + + // The extension's initial rulesets are fully loaded; dispatch |task| + // immediately. + std::move(task).Run(); } void RulesMonitorService::OnDynamicRulesUpdated( @@ -464,7 +621,7 @@ // The extension may have been uninstalled by this point. Return early if // that's the case. if (!extension_registry_->GetInstalledExtension(load_data.extension_id)) { - // Still dispatch the |callback|, although it's probably a no-op. + // Still dispatch the |callback|, even though it's probably a no-op. std::move(callback).Run(std::move(error)); return; } @@ -499,54 +656,47 @@ } // Update the dynamic ruleset. - UpdateRuleset(load_data.extension_id, dynamic_ruleset.TakeMatcher()); + UpdateRulesetMatcher(load_data.extension_id, dynamic_ruleset.TakeMatcher()); } -void RulesMonitorService::UnloadRulesets(const ExtensionId& extension_id) { +void RulesMonitorService::RemoveCompositeMatcher( + const ExtensionId& extension_id) { bool had_extra_headers_matcher = ruleset_manager_.HasAnyExtraHeadersMatcher(); ruleset_manager_.RemoveRuleset(extension_id); action_tracker_.ClearExtensionData(extension_id); - - if (had_extra_headers_matcher && - !ruleset_manager_.HasAnyExtraHeadersMatcher()) { - ExtensionWebRequestEventRouter::GetInstance() - ->DecrementExtraHeadersListenerCount(context_); - } + AdjustExtraHeaderListenerCountIfNeeded(had_extra_headers_matcher); } -void RulesMonitorService::LoadRulesets( +void RulesMonitorService::AddCompositeMatcher( const ExtensionId& extension_id, std::unique_ptr<CompositeMatcher> matcher) { - bool increment_extra_headers = - !ruleset_manager_.HasAnyExtraHeadersMatcher() && - matcher->HasAnyExtraHeadersMatcher(); + bool had_extra_headers_matcher = ruleset_manager_.HasAnyExtraHeadersMatcher(); ruleset_manager_.AddRuleset(extension_id, std::move(matcher)); - - if (increment_extra_headers) { - ExtensionWebRequestEventRouter::GetInstance() - ->IncrementExtraHeadersListenerCount(context_); - } + AdjustExtraHeaderListenerCountIfNeeded(had_extra_headers_matcher); } -void RulesMonitorService::UpdateRuleset( +void RulesMonitorService::UpdateRulesetMatcher( const ExtensionId& extension_id, std::unique_ptr<RulesetMatcher> ruleset_matcher) { - bool had_extra_headers_matcher = ruleset_manager_.HasAnyExtraHeadersMatcher(); - CompositeMatcher* matcher = ruleset_manager_.GetMatcherForExtension(extension_id); - // The extension didn't have any active rulesets. + // The extension didn't have a corresponding CompositeMatcher. if (!matcher) { CompositeMatcher::MatcherList matchers; matchers.push_back(std::move(ruleset_matcher)); - LoadRulesets(extension_id, - std::make_unique<CompositeMatcher>(std::move(matchers))); + AddCompositeMatcher( + extension_id, std::make_unique<CompositeMatcher>(std::move(matchers))); return; } + bool had_extra_headers_matcher = ruleset_manager_.HasAnyExtraHeadersMatcher(); matcher->AddOrUpdateRuleset(std::move(ruleset_matcher)); + AdjustExtraHeaderListenerCountIfNeeded(had_extra_headers_matcher); +} +void RulesMonitorService::AdjustExtraHeaderListenerCountIfNeeded( + bool had_extra_headers_matcher) { bool has_extra_headers_matcher = ruleset_manager_.HasAnyExtraHeadersMatcher(); if (had_extra_headers_matcher == has_extra_headers_matcher) return; @@ -559,6 +709,32 @@ } } +void RulesMonitorService::UpdateRulesetChecksumsIfNeeded( + const LoadRequestData& load_data) { + // The extension may have been uninstalled by this point. Return early if + // that's the case. + if (!extension_registry_->GetInstalledExtension(load_data.extension_id)) + return; + + // Update checksums for all rulesets. + // Note: We also do this for a non-enabled extension. The ruleset on the disk + // has already been modified at this point. So we do want to update the + // checksum for it to be in sync with what's on disk. + for (const RulesetInfo& ruleset : load_data.rulesets) { + if (!ruleset.new_checksum()) + continue; + + if (ruleset.source().is_dynamic_ruleset()) { + prefs_->SetDNRDynamicRulesetChecksum(load_data.extension_id, + *(ruleset.new_checksum())); + } else { + prefs_->SetDNRStaticRulesetChecksum(load_data.extension_id, + ruleset.source().id(), + *(ruleset.new_checksum())); + } + } +} + } // namespace declarative_net_request template <>
diff --git a/extensions/browser/api/declarative_net_request/rules_monitor_service.h b/extensions/browser/api/declarative_net_request/rules_monitor_service.h index 1c6cbf5..72b4c52a 100644 --- a/extensions/browser/api/declarative_net_request/rules_monitor_service.h +++ b/extensions/browser/api/declarative_net_request/rules_monitor_service.h
@@ -14,6 +14,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "base/one_shot_event.h" #include "base/optional.h" #include "base/scoped_observer.h" #include "extensions/browser/api/declarative_net_request/action_tracker.h" @@ -21,6 +22,7 @@ #include "extensions/browser/browser_context_keyed_api_factory.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_registry_observer.h" +#include "extensions/common/api/declarative_net_request/constants.h" #include "extensions/common/extension_id.h" namespace content { @@ -84,6 +86,15 @@ std::vector<api::declarative_net_request::Rule> rules_to_add, DynamicRuleUpdateUICallback callback); + // Updates the set of enabled static rulesets for the |extension| and then + // invokes |callback| with an optional error. + using UpdateEnabledRulesetsUICallback = + base::OnceCallback<void(base::Optional<std::string> error)>; + void UpdateEnabledStaticRulesets(const Extension& extension, + std::set<RulesetID> ids_to_disable, + std::set<RulesetID> ids_to_enable, + UpdateEnabledRulesetsUICallback callback); + RulesetManager* ruleset_manager() { return &ruleset_manager_; } const ActionTracker& action_tracker() const { return action_tracker_; } @@ -96,22 +107,6 @@ friend class BrowserContextKeyedAPIFactory<RulesMonitorService>; - struct DynamicRuleUpdate { - DynamicRuleUpdate( - std::vector<int> rule_ids_to_remove, - std::vector<api::declarative_net_request::Rule> rules_to_add, - DynamicRuleUpdateUICallback ui_callback); - - DynamicRuleUpdate(DynamicRuleUpdate&&); - DynamicRuleUpdate& operator=(DynamicRuleUpdate&&); - - ~DynamicRuleUpdate(); - - std::vector<int> rule_ids_to_remove; - std::vector<api::declarative_net_request::Rule> rules_to_add; - DynamicRuleUpdateUICallback ui_callback; - }; - // The constructor is kept private since this should only be created by the // BrowserContextKeyedAPIFactory. explicit RulesMonitorService(content::BrowserContext* browser_context); @@ -132,28 +127,64 @@ UninstallReason reason) override; // Internal helper for UpdateDynamicRules. - void UpdateDynamicRulesInternal(const ExtensionId& extension_id, - DynamicRuleUpdate update); + void UpdateDynamicRulesInternal( + const ExtensionId& extension_id, + std::vector<int> rule_ids_to_remove, + std::vector<api::declarative_net_request::Rule> rules_to_add, + DynamicRuleUpdateUICallback callback); + + // Internal helper for UpdateEnabledStaticRulesets. + void UpdateEnabledStaticRulesetsInternal( + const ExtensionId& extension_id, + std::set<RulesetID> ids_to_disable, + std::set<RulesetID> ids_to_enable, + UpdateEnabledRulesetsUICallback callback); // Invoked when we have loaded the rulesets in |load_data| on - // |file_task_runner_|. - void OnRulesetsLoaded(LoadRequestData load_data); + // |file_task_runner_| in response to OnExtensionLoaded. + void OnInitialRulesetsLoaded(LoadRequestData load_data); - // Invoked when the dynamic rules for the extension have been updated. + // Invoked when rulesets are loaded in response to + // UpdateEnabledStaticRulesets. + void OnNewStaticRulesetsLoaded(UpdateEnabledRulesetsUICallback callback, + std::set<RulesetID> ids_to_disable, + std::set<RulesetID> ids_to_enable, + LoadRequestData load_data); + + // Helper to execute a |task| only once the initial ruleset load for the + // |extension| is complete. Should be called in response to API function calls + // which modify rulesets on disk in order to prevent a race with the initial + // ruleset load. + void ExecuteOrQueueAPICall(const Extension& extension, + base::OnceClosure task); + + // Invoked when the dynamic rules for the extension have been updated in + // response to UpdateDynamicRules. void OnDynamicRulesUpdated(DynamicRuleUpdateUICallback callback, LoadRequestData load_data, base::Optional<std::string> error); // Unloads all rulesets for the given |extension_id|. - void UnloadRulesets(const ExtensionId& extension_id); + void RemoveCompositeMatcher(const ExtensionId& extension_id); // Loads the given |matcher| for the given |extension_id|. - void LoadRulesets(const ExtensionId& extension_id, - std::unique_ptr<CompositeMatcher> matcher); + void AddCompositeMatcher(const ExtensionId& extension_id, + std::unique_ptr<CompositeMatcher> matcher); - // Adds the given ruleset for the given |extension_id|. - void UpdateRuleset(const ExtensionId& extension_id, - std::unique_ptr<RulesetMatcher> ruleset_matcher); + // Adds the given |ruleset_matcher| to the set of matchers for the given + // |extension_id|. If a RulesetMatcher with the same ID is already present for + // the extension, it is replaced. + void UpdateRulesetMatcher(const ExtensionId& extension_id, + std::unique_ptr<RulesetMatcher> ruleset_matcher); + + // Adjusts the extra headers listener count on the + // ExtensionWebRequestEventRouter. Usually called after an update to the + // RulesetManager. |had_extra_headers_matcher| denotes whether the + // RulesetManager had an extra headers matcher before the update. + void AdjustExtraHeaderListenerCountIfNeeded(bool had_extra_headers_matcher); + + // Updates ruleset checksum in preferences from |load_data|. + void UpdateRulesetChecksumsIfNeeded(const LoadRequestData& load_data); ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> registry_observer_{this}; @@ -175,11 +206,11 @@ // Non-owned pointer. TestObserver* test_observer_ = nullptr; - // Stores the pending dynamic rule updates to be performed once ruleset - // loading is done for an extension. This is only maintained for extensions - // which are undergoing a ruleset load in response to OnExtensionLoaded. - std::map<ExtensionId, std::vector<DynamicRuleUpdate>> - pending_dynamic_rule_updates_; + // Stores the tasks to be performed once ruleset loading is done for an + // extension. This is only maintained for extensions which are undergoing a + // ruleset load in response to OnExtensionLoaded. + std::map<ExtensionId, std::unique_ptr<base::OneShotEvent>> + tasks_pending_on_load_; // Must be the last member variable. See WeakPtrFactory documentation for // details.
diff --git a/extensions/browser/api/declarative_net_request/ruleset_manager.cc b/extensions/browser/api/declarative_net_request/ruleset_manager.cc index d0b04d7c..46f0fe06 100644 --- a/extensions/browser/api/declarative_net_request/ruleset_manager.cc +++ b/extensions/browser/api/declarative_net_request/ruleset_manager.cc
@@ -16,6 +16,7 @@ #include "base/stl_util.h" #include "base/time/time.h" #include "base/timer/elapsed_timer.h" +#include "components/version_info/channel.h" #include "components/web_cache/browser/web_cache_manager.h" #include "extensions/browser/api/declarative_net_request/composite_matcher.h" #include "extensions/browser/api/declarative_net_request/constants.h" @@ -31,6 +32,7 @@ #include "extensions/common/api/declarative_net_request.h" #include "extensions/common/api/declarative_net_request/utils.h" #include "extensions/common/constants.h" +#include "extensions/common/features/feature_channel.h" #include "url/origin.h" namespace extensions { @@ -453,11 +455,15 @@ if (!remove_headers_actions.empty()) return remove_headers_actions; - std::vector<RequestAction> modify_headers_actions = - GetModifyHeadersActions(rulesets_to_evaluate, request, params); + // TODO(crbug.com/947591): Remove the channel check once implementation of + // modifyHeaders action is complete. + if (GetCurrentChannel() != version_info::Channel::STABLE) { + std::vector<RequestAction> modify_headers_actions = + GetModifyHeadersActions(rulesets_to_evaluate, request, params); - if (!modify_headers_actions.empty()) - return modify_headers_actions; + if (!modify_headers_actions.empty()) + return modify_headers_actions; + } return actions; }
diff --git a/extensions/browser/api/declarative_net_request/ruleset_matcher_unittest.cc b/extensions/browser/api/declarative_net_request/ruleset_matcher_unittest.cc index a1473791..ac7b5d5 100644 --- a/extensions/browser/api/declarative_net_request/ruleset_matcher_unittest.cc +++ b/extensions/browser/api/declarative_net_request/ruleset_matcher_unittest.cc
@@ -13,7 +13,7 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "components/url_pattern_index/flat/url_pattern_index_generated.h" -#include "components/version_info/version_info.h" +#include "components/version_info/channel.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" #include "content/public/test/navigation_simulator.h" @@ -42,14 +42,7 @@ namespace dnr_api = api::declarative_net_request; -class RulesetMatcherTest : public ExtensionsTest { - public: - RulesetMatcherTest() : channel_(::version_info::Channel::UNKNOWN) {} - - private: - // Run this on the trunk channel to ensure the API is available. - ScopedCurrentChannel channel_; -}; +using RulesetMatcherTest = ExtensionsTest; // Tests a simple blocking rule. TEST_F(RulesetMatcherTest, BlockingRule) { @@ -313,6 +306,10 @@ } TEST_F(RulesetMatcherTest, ModifyHeaders_IsExtraHeaderMatcher) { + // TODO(crbug.com/947591): Remove the channel override once implementation of + // modifyHeaders action is complete. + ScopedCurrentChannel channel(::version_info::Channel::UNKNOWN); + TestRule rule = CreateGenericRule(); rule.condition->url_filter = std::string("example.com"); std::unique_ptr<RulesetMatcher> matcher; @@ -327,6 +324,10 @@ } TEST_F(RulesetMatcherTest, ModifyHeaders) { + // TODO(crbug.com/947591): Remove the channel override once implementation of + // modifyHeaders action is complete. + ScopedCurrentChannel channel(::version_info::Channel::UNKNOWN); + TestRule rule_1 = CreateGenericRule(); rule_1.id = kMinValidID; rule_1.priority = kMinValidPriority + 1; @@ -578,6 +579,10 @@ // Tests regex rules are evaluated correctly for different action types. TEST_F(RulesetMatcherTest, RegexRules) { + // TODO(crbug.com/947591): Remove the channel override once implementation of + // modifyHeaders action is complete. + ScopedCurrentChannel channel(::version_info::Channel::UNKNOWN); + auto create_regex_rule = [](size_t id, const std::string& regex_filter) { TestRule rule = CreateGenericRule(); rule.id = id; @@ -1104,6 +1109,10 @@ } TEST_F(RulesetMatcherTest, RegexAndFilterListRules_ModifyHeaders) { + // TODO(crbug.com/947591): Remove the channel override once implementation of + // modifyHeaders action is complete. + ScopedCurrentChannel channel(::version_info::Channel::UNKNOWN); + std::vector<TestRule> rules; TestRule rule = CreateGenericRule(); @@ -1361,14 +1370,7 @@ // Test fixture to test allowAllRequests rules. We inherit from ExtensionsTest // to ensure we can work with WebContentsTester and associated classes. -class AllowAllRequestsTest : public ExtensionsTest { - public: - AllowAllRequestsTest() : channel_(::version_info::Channel::UNKNOWN) {} - - private: - // Run this on the trunk channel to ensure the API is available. - ScopedCurrentChannel channel_; -}; +using AllowAllRequestsTest = ExtensionsTest; // Tests that we track allowlisted frames (frames matching allowAllRequests // rules) correctly.
diff --git a/extensions/browser/api/declarative_net_request/ruleset_source.cc b/extensions/browser/api/declarative_net_request/ruleset_source.cc index 450cdb8..4189b4b3 100644 --- a/extensions/browser/api/declarative_net_request/ruleset_source.cc +++ b/extensions/browser/api/declarative_net_request/ruleset_source.cc
@@ -23,6 +23,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/timer/elapsed_timer.h" #include "base/values.h" +#include "components/version_info/channel.h" #include "content/public/browser/browser_context.h" #include "extensions/browser/api/declarative_net_request/constants.h" #include "extensions/browser/api/declarative_net_request/flat_ruleset_indexer.h" @@ -35,6 +36,7 @@ #include "extensions/common/error_utils.h" #include "extensions/common/extension.h" #include "extensions/common/extension_resource.h" +#include "extensions/common/features/feature_channel.h" #include "extensions/common/file_util.h" #include "extensions/common/install_warning.h" #include "extensions/common/manifest_constants.h" @@ -302,16 +304,22 @@ declarative_net_request::DNRManifestData::GetRulesets(extension); std::vector<RulesetSource> sources; - for (const auto& info : rulesets) { - sources.push_back(RulesetSource( - extension.path().Append(info.relative_path), - extension.path().Append( - file_util::GetIndexedRulesetRelativePath(info.id.value())), - info.id, dnr_api::MAX_NUMBER_OF_RULES, extension.id(), info.enabled)); - } + for (const auto& info : rulesets) + sources.push_back(CreateStatic(extension, info)); + return sources; } +RulesetSource RulesetSource::CreateStatic( + const Extension& extension, + const DNRManifestData::RulesetInfo& info) { + return RulesetSource( + extension.path().Append(info.relative_path), + extension.path().Append( + file_util::GetIndexedRulesetRelativePath(info.id.value())), + info.id, dnr_api::MAX_NUMBER_OF_RULES, extension.id(), info.enabled); +} + // static RulesetSource RulesetSource::CreateDynamic(content::BrowserContext* context, const ExtensionId& extension_id) { @@ -323,7 +331,7 @@ dynamic_ruleset_directory.AppendASCII(kDynamicRulesJSONFilename), dynamic_ruleset_directory.AppendASCII(kDynamicIndexedRulesFilename), kDynamicRulesetID, dnr_api::MAX_NUMBER_OF_DYNAMIC_RULES, extension_id, - true /* enabled */); + true /* enabled_by_default */); } // static @@ -341,7 +349,8 @@ // Use WrapUnique since RulesetSource constructor is private. return base::WrapUnique(new RulesetSource( std::move(temporary_file_json), std::move(temporary_file_indexed), id, - rule_count_limit, std::move(extension_id), true /* enabled */)); + rule_count_limit, std::move(extension_id), + true /* enabled_by_default */)); } RulesetSource::~RulesetSource() = default; @@ -350,7 +359,7 @@ RulesetSource RulesetSource::Clone() const { return RulesetSource(json_path_, indexed_path_, id_, rule_count_limit_, - extension_id_, enabled_); + extension_id_, enabled_by_default_); } IndexAndPersistJSONRulesetResult @@ -405,6 +414,15 @@ if (!inserted) return ParseInfo(ParseResult::ERROR_DUPLICATE_IDS, &rule_id); + // Ensure modifyHeaders actions don't have any side-effects on Stable + // since it's under development. + // TODO(crbug.com/947591): Remove the channel check once implementation + // of modifyHeaders action is complete. + if (rule.action.type == dnr_api::RULE_ACTION_TYPE_MODIFYHEADERS && + GetCurrentChannel() == version_info::Channel::STABLE) { + continue; + } + IndexedRule indexed_rule; ParseResult parse_result = IndexedRule::CreateIndexedRule( std::move(rule), base_url, &indexed_rule); @@ -492,13 +510,13 @@ RulesetID id, size_t rule_count_limit, ExtensionId extension_id, - bool enabled) + bool enabled_by_default) : json_path_(std::move(json_path)), indexed_path_(std::move(indexed_path)), id_(id), rule_count_limit_(rule_count_limit), extension_id_(std::move(extension_id)), - enabled_(enabled) {} + enabled_by_default_(enabled_by_default) {} } // namespace declarative_net_request } // namespace extensions
diff --git a/extensions/browser/api/declarative_net_request/ruleset_source.h b/extensions/browser/api/declarative_net_request/ruleset_source.h index ee28b3ae..4666d77 100644 --- a/extensions/browser/api/declarative_net_request/ruleset_source.h +++ b/extensions/browser/api/declarative_net_request/ruleset_source.h
@@ -14,6 +14,7 @@ #include "base/time/time.h" #include "extensions/common/api/declarative_net_request.h" #include "extensions/common/api/declarative_net_request/constants.h" +#include "extensions/common/api/declarative_net_request/dnr_manifest_data.h" #include "extensions/common/extension_id.h" namespace content { @@ -122,10 +123,14 @@ class RulesetSource { public: // Creates RulesetSources corresponding to the static rulesets in the - // extension package. This must only be called for extensions which specified - // a declarative ruleset. + // extension package. static std::vector<RulesetSource> CreateStatic(const Extension& extension); + // Creates a static RulesetSource corresponding to |info| for the given + // |extension|. + static RulesetSource CreateStatic(const Extension& extension, + const DNRManifestData::RulesetInfo& info); + // Creates RulesetSource corresponding to the dynamic rules added by the // extension. This must only be called for extensions which specified a // declarative ruleset. @@ -163,8 +168,8 @@ const ExtensionId& extension_id() const { return extension_id_; } // Whether the ruleset is enabled by default (as specified in the extension - // manifest). - bool enabled() const { return enabled_; } + // manifest for a static ruleset). Always true for a dynamic ruleset. + bool enabled_by_default() const { return enabled_by_default_; } // Indexes and persists the JSON ruleset. This is potentially unsafe since the // JSON rules file is parsed in-process. Note: This must be called on a @@ -208,7 +213,7 @@ RulesetID id_; size_t rule_count_limit_; ExtensionId extension_id_; - bool enabled_; + bool enabled_by_default_; DISALLOW_COPY_AND_ASSIGN(RulesetSource); };
diff --git a/extensions/browser/api/declarative_net_request/test_utils.cc b/extensions/browser/api/declarative_net_request/test_utils.cc index a807968..bee70ba 100644 --- a/extensions/browser/api/declarative_net_request/test_utils.cc +++ b/extensions/browser/api/declarative_net_request/test_utils.cc
@@ -12,7 +12,6 @@ #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/json/json_file_value_serializer.h" -#include "extensions/browser/api/declarative_net_request/composite_matcher.h" #include "extensions/browser/api/declarative_net_request/indexed_rule.h" #include "extensions/browser/api/declarative_net_request/ruleset_matcher.h" #include "extensions/browser/api/declarative_net_request/ruleset_source.h" @@ -372,15 +371,6 @@ return lhs.operation == rhs.operation && lhs.header == rhs.header; } -std::vector<std::string> GetPublicRulesetIDs(const Extension& extension, - const CompositeMatcher& matcher) { - std::vector<std::string> ids; - for (const std::unique_ptr<RulesetMatcher>& matcher : matcher.matchers()) - ids.push_back(GetPublicRulesetID(extension, matcher->id())); - - return ids; -} - RulesetManagerObserver::RulesetManagerObserver(RulesetManager* manager) : manager_(manager), current_count_(manager_->GetMatcherCountForTest()) { manager_->SetObserverForTest(this);
diff --git a/extensions/browser/api/declarative_net_request/test_utils.h b/extensions/browser/api/declarative_net_request/test_utils.h index e6319f86..c67fbc3 100644 --- a/extensions/browser/api/declarative_net_request/test_utils.h +++ b/extensions/browser/api/declarative_net_request/test_utils.h
@@ -31,7 +31,6 @@ namespace declarative_net_request { -class CompositeMatcher; class RulesetSource; class RulesetMatcher; struct TestRule; @@ -84,11 +83,6 @@ const api::declarative_net_request::ModifyHeaderInfo& lhs, const api::declarative_net_request::ModifyHeaderInfo& rhs); -// Returns the public ruleset IDs corresponding to the given |extension| and -// |matcher|. -std::vector<std::string> GetPublicRulesetIDs(const Extension& extension, - const CompositeMatcher& matcher); - // Test observer for RulesetManager. This is a multi-use observer i.e. // WaitForExtensionsWithRulesetsCount can be called multiple times per lifetime // of an observer.
diff --git a/extensions/browser/api/declarative_net_request/utils.cc b/extensions/browser/api/declarative_net_request/utils.cc index cf69956..c325a88 100644 --- a/extensions/browser/api/declarative_net_request/utils.cc +++ b/extensions/browser/api/declarative_net_request/utils.cc
@@ -19,8 +19,10 @@ #include "components/url_pattern_index/url_pattern_index.h" #include "components/web_cache/browser/web_cache_manager.h" #include "content/public/browser/browser_thread.h" +#include "extensions/browser/api/declarative_net_request/composite_matcher.h" #include "extensions/browser/api/declarative_net_request/constants.h" #include "extensions/browser/api/declarative_net_request/flat/extension_ruleset_generated.h" +#include "extensions/browser/api/declarative_net_request/ruleset_matcher.h" #include "extensions/browser/api/web_request/web_request_info.h" #include "extensions/common/api/declarative_net_request/constants.h" #include "extensions/common/api/declarative_net_request/dnr_manifest_data.h" @@ -274,7 +276,17 @@ return dnr_api::DYNAMIC_RULESET_ID; DCHECK_GE(ruleset_id, kMinValidStaticRulesetID); - return DNRManifestData::GetManifestID(extension, ruleset_id); + return DNRManifestData::GetRuleset(extension, ruleset_id).manifest_id; +} + +std::vector<std::string> GetPublicRulesetIDs(const Extension& extension, + const CompositeMatcher& matcher) { + std::vector<std::string> ids; + ids.reserve(matcher.matchers().size()); + for (const std::unique_ptr<RulesetMatcher>& matcher : matcher.matchers()) + ids.push_back(GetPublicRulesetID(extension, matcher->id())); + + return ids; } } // namespace declarative_net_request
diff --git a/extensions/browser/api/declarative_net_request/utils.h b/extensions/browser/api/declarative_net_request/utils.h index 22819d5e..f8f36f3 100644 --- a/extensions/browser/api/declarative_net_request/utils.h +++ b/extensions/browser/api/declarative_net_request/utils.h
@@ -29,6 +29,7 @@ struct WebRequestInfo; namespace declarative_net_request { +class CompositeMatcher; // Returns true if |data| represents a valid data buffer containing indexed // ruleset data with |expected_checksum|. @@ -93,6 +94,11 @@ std::string GetPublicRulesetID(const Extension& extension, RulesetID ruleset_id); +// Returns the public ruleset IDs corresponding to the given |extension| and +// |matcher|. +std::vector<std::string> GetPublicRulesetIDs(const Extension& extension, + const CompositeMatcher& matcher); + // Helper to convert a flatbufffers::String to a string-like object with type T. template <typename T> T CreateString(const flatbuffers::String& str) {
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h index 4d7ea5b..718bb7e 100644 --- a/extensions/browser/extension_function_histogram_value.h +++ b/extensions/browser/extension_function_histogram_value.h
@@ -1531,6 +1531,8 @@ AUTOTESTPRIVATE_STOPSMOOTHNESSTRACKING = 1468, ACCESSIBILITY_PRIVATE_UPDATESWITCHACCESSBUBBLE = 1469, TERMINALPRIVATE_OPENOPTIONSPAGE = 1470, + DECLARATIVENETREQUEST_UPDATEENABLEDRULESETS = 1471, + DECLARATIVENETREQUEST_GETENABLEDRULESETS = 1472, // Last entry: Add new entries above, then run: // python tools/metrics/histograms/update_extension_histograms.py ENUM_BOUNDARY
diff --git a/extensions/browser/extension_prefs.cc b/extensions/browser/extension_prefs.cc index 49ce80f..eac7d0a 100644 --- a/extensions/browser/extension_prefs.cc +++ b/extensions/browser/extension_prefs.cc
@@ -227,6 +227,10 @@ // Net Request API. constexpr const char kDNRChecksumKey[] = "checksum"; +// Key corresponding to the list of enabled static ruleset IDs for an extension. +// Used for the Declarative Net Request API. +constexpr const char kDNREnabledStaticRulesetIDs[] = "dnr_enabled_ruleset_ids"; + // A boolean preference that indicates whether the extension's icon should be // automatically badged to the matched action count for a tab. False by default. constexpr const char kPrefDNRUseActionCountAsBadgeText[] = @@ -1869,6 +1873,36 @@ std::make_unique<base::Value>(checksum)); } +base::Optional<std::set<declarative_net_request::RulesetID>> +ExtensionPrefs::GetDNREnabledStaticRulesets( + const ExtensionId& extension_id) const { + std::set<declarative_net_request::RulesetID> ids; + const base::ListValue* ids_value = nullptr; + if (!ReadPrefAsList(extension_id, kDNREnabledStaticRulesetIDs, &ids_value)) + return base::nullopt; + + DCHECK(ids_value); + for (const base::Value& id_value : ids_value->GetList()) { + if (!id_value.is_int()) + return base::nullopt; + + ids.insert(declarative_net_request::RulesetID(id_value.GetInt())); + } + + return ids; +} + +void ExtensionPrefs::SetDNREnabledStaticRulesets( + const ExtensionId& extension_id, + const std::set<declarative_net_request::RulesetID>& ids) { + std::vector<base::Value> ids_list; + for (const auto& id : ids) + ids_list.push_back(base::Value(id.value())); + + UpdateExtensionPref(extension_id, kDNREnabledStaticRulesetIDs, + std::make_unique<base::Value>(ids_list)); +} + bool ExtensionPrefs::GetDNRUseActionCountAsBadgeText( const ExtensionId& extension_id) const { return ReadPrefAsBooleanAndReturn(extension_id, @@ -2065,6 +2099,10 @@ std::move(ruleset_prefs)); } + // Clear the list of enabled static rulesets for the extension since it + // shouldn't persist across extension updates. + extension_dict->Remove(kDNREnabledStaticRulesetIDs, nullptr /* out_value */); + if (util::CanWithholdPermissionsFromExtension(*extension)) { // If the withhold permission creation flag is present it takes precedence // over any previous stored value.
diff --git a/extensions/browser/extension_prefs.h b/extensions/browser/extension_prefs.h index 5a4d66202..139a76a 100644 --- a/extensions/browser/extension_prefs.h +++ b/extensions/browser/extension_prefs.h
@@ -608,6 +608,16 @@ void SetDNRDynamicRulesetChecksum(const ExtensionId& extension_id, int checksum); + // Returns the set of enabled static ruleset IDs or base::nullopt if the + // extension hasn't updated the set of enabled static rulesets. + base::Optional<std::set<declarative_net_request::RulesetID>> + GetDNREnabledStaticRulesets(const ExtensionId& extension_id) const; + // Updates the set of enabled static rulesets for the |extension_id|. This + // preference gets cleared on extension update. + void SetDNREnabledStaticRulesets( + const ExtensionId& extension_id, + const std::set<declarative_net_request::RulesetID>& ids); + // Whether the extension with the given |extension_id| is using its ruleset's // matched action count for the badge text. This is set via the // setActionCountAsBadgeText API call.
diff --git a/extensions/browser/updater/update_service.cc b/extensions/browser/updater/update_service.cc index 15c25d23..e0dca18 100644 --- a/extensions/browser/updater/update_service.cc +++ b/extensions/browser/updater/update_service.cc
@@ -37,9 +37,6 @@ UpdateService* update_service_override = nullptr; -// 98% of update checks have 22 or less extensions. -constexpr size_t kMaxExtensionsPerUpdate = 22; - // This set contains all Omaha attributes that is associated with extensions. constexpr const char* kOmahaAttributes[] = {"_malware"}; @@ -121,23 +118,12 @@ VLOG(2) << "UpdateService::OnEvent " << static_cast<int>(event) << " " << extension_id; - bool complete_event = false; - bool finish_delayed_installation = false; bool should_perform_action_on_omaha_attributes = false; switch (event) { - case Events::COMPONENT_UPDATED: - complete_event = true; - break; - case Events::COMPONENT_UPDATE_ERROR: - complete_event = true; - finish_delayed_installation = true; - break; case Events::COMPONENT_NOT_UPDATED: - complete_event = true; // Attributes is currently only added when no_update is true in the update // client config. should_perform_action_on_omaha_attributes = true; - finish_delayed_installation = true; break; case Events::COMPONENT_UPDATE_FOUND: // This flag is set since it makes sense to update attributes when an @@ -151,6 +137,8 @@ case Events::COMPONENT_UPDATE_READY: case Events::COMPONENT_UPDATE_DOWNLOADING: case Events::COMPONENT_UPDATE_UPDATING: + case Events::COMPONENT_UPDATED: + case Events::COMPONENT_UPDATE_ERROR: break; } @@ -162,33 +150,6 @@ } ExtensionSystem::Get(browser_context_) ->PerformActionBasedOnOmahaAttributes(extension_id, attributes); - - if (complete_event) { - // The update check for |extension_id| has completed, thus it can be - // removed from all in-progress update checks. - DCHECK_GT(updating_extension_ids_.count(extension_id), 0u); - updating_extension_ids_.erase(extension_id); - - bool install_immediately = false; - for (auto& update : in_progress_updates_) { - install_immediately |= update.install_immediately; - update.pending_extension_ids.erase(extension_id); - } - - // When no update is found or there's an update error, a previous update - // check might have queued an update for this extension because it was in - // use at the time. We should ask for the install of the queued update now - // if it's ready. - if (finish_delayed_installation && install_immediately) { - ExtensionSystem::Get(browser_context_) - ->FinishDelayedInstallationIfReady(extension_id, - true /*install_immediately*/); - } - } -} - -bool UpdateService::IsBusy() const { - return !updating_extension_ids_.empty(); } UpdateService::UpdateService( @@ -222,23 +183,18 @@ return; } - in_progress_updates_.push_back( - InProgressUpdate(std::move(callback), update_params.install_immediately)); - InProgressUpdate& update = in_progress_updates_.back(); + InProgressUpdate update = + InProgressUpdate(std::move(callback), update_params.install_immediately); - // |update_data| only store update info of extensions that are not being - // updated at the moment. ExtensionUpdateDataMap update_data; + std::vector<ExtensionId> update_ids; + update_ids.reserve(update_params.update_info.size()); for (const auto& update_info : update_params.update_info) { const std::string& extension_id = update_info.first; DCHECK(!extension_id.empty()); update.pending_extension_ids.insert(extension_id); - if (updating_extension_ids_.count(extension_id) > 0) - continue; - - updating_extension_ids_.insert(extension_id); ExtensionUpdateData data = update_info.second; if (data.is_corrupt_reinstall) { @@ -248,60 +204,38 @@ ExtensionUpdateCheckParams::FOREGROUND) { data.install_source = "ondemand"; } + update_ids.push_back(extension_id); update_data.insert(std::make_pair(extension_id, data)); } - // Divide extensions into batches to reduce the size of update check - // requests generated by the update client. - for (auto it = update_data.begin(); it != update_data.end();) { - ExtensionUpdateDataMap batch_data; - size_t batch_size = - std::min(kMaxExtensionsPerUpdate, - static_cast<size_t>(std::distance(it, update_data.end()))); - - std::vector<std::string> batch_ids; - batch_ids.reserve(batch_size); - for (size_t i = 0; i < batch_size; ++i, ++it) { - batch_ids.push_back(it->first); - batch_data.emplace(it->first, std::move(it->second)); - } - - update_client_->Update( - batch_ids, - base::BindOnce(&UpdateDataProvider::GetData, update_data_provider_, - update_params.install_immediately, - std::move(batch_data)), - {}, update_params.priority == ExtensionUpdateCheckParams::FOREGROUND, - base::BindOnce(&UpdateService::UpdateCheckComplete, - weak_ptr_factory_.GetWeakPtr())); - } + update_client_->Update( + update_ids, + base::BindOnce(&UpdateDataProvider::GetData, update_data_provider_, + update_params.install_immediately, std::move(update_data)), + {}, update_params.priority == ExtensionUpdateCheckParams::FOREGROUND, + base::BindOnce(&UpdateService::UpdateCheckComplete, + weak_ptr_factory_.GetWeakPtr(), std::move(update))); } -void UpdateService::UpdateCheckComplete(update_client::Error error) { +void UpdateService::UpdateCheckComplete(InProgressUpdate update, + update_client::Error error) { VLOG(2) << "UpdateService::UpdateCheckComplete"; DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - // There must be at least one in-progress update (the one that just - // finished). - DCHECK(!in_progress_updates_.empty()); - - if (!in_progress_updates_[0].pending_extension_ids.empty()) { - // This can happen when the update check request is batched. - return; + // When no update is found or there's an update error, a previous update + // check might have queued an update for this extension because it was in + // use at the time. We should ask for the install of the queued update now + // if it's ready. + if (update.install_immediately) { + for (const ExtensionId& extension_id : update.pending_extension_ids) { + ExtensionSystem::Get(browser_context_) + ->FinishDelayedInstallationIfReady(extension_id, + true /*install_immediately*/); + } } - // Find all updates that have finished and remove them from the list. - in_progress_updates_.erase( - std::remove_if(in_progress_updates_.begin(), in_progress_updates_.end(), - [](InProgressUpdate& update) { - if (!update.pending_extension_ids.empty()) - return false; - VLOG(2) << "UpdateComplete"; - if (!update.callback.is_null()) - std::move(update.callback).Run(); - return true; - }), - in_progress_updates_.end()); + if (!update.callback.is_null()) + std::move(update.callback).Run(); } void UpdateService::AddUpdateClientObserver(
diff --git a/extensions/browser/updater/update_service.h b/extensions/browser/updater/update_service.h index 6cb55bdc..c96e173c 100644 --- a/extensions/browser/updater/update_service.h +++ b/extensions/browser/updater/update_service.h
@@ -68,9 +68,6 @@ // Overriden from |update_client::UpdateClient::Observer|. void OnEvent(Events event, const std::string& id) override; - // Returns true if the update service is updating one or more extensions. - virtual bool IsBusy() const; - protected: UpdateService(content::BrowserContext* context, scoped_refptr<update_client::UpdateClient> update_client); @@ -81,10 +78,6 @@ friend class UpdateServiceFactory; friend std::unique_ptr<UpdateService>::deleter_type; - // This function is executed by the update client after an update check - // request has completed. - void UpdateCheckComplete(update_client::Error error); - struct InProgressUpdate { InProgressUpdate(base::OnceClosure callback, bool install_immediately); ~InProgressUpdate(); @@ -100,6 +93,10 @@ std::set<std::string> pending_extension_ids; }; + // This function is executed by the update client after an update check + // request has completed. + void UpdateCheckComplete(InProgressUpdate update, update_client::Error error); + // Adds/Removes observer to/from |update_client::UpdateClient|. // Mainly used for browser tests. void AddUpdateClientObserver(update_client::UpdateClient::Observer* observer); @@ -117,10 +114,6 @@ scoped_refptr<update_client::UpdateClient> update_client_; scoped_refptr<UpdateDataProvider> update_data_provider_; - // The set of extension IDs that are being checked for update. - std::set<std::string> updating_extension_ids_; - std::vector<InProgressUpdate> in_progress_updates_; - THREAD_CHECKER(thread_checker_); // used to create WeakPtrs to |this|.
diff --git a/extensions/browser/updater/update_service_unittest.cc b/extensions/browser/updater/update_service_unittest.cc index fbe8bdc5..f6719ed5 100644 --- a/extensions/browser/updater/update_service_unittest.cc +++ b/extensions/browser/updater/update_service_unittest.cc
@@ -279,6 +279,11 @@ registry->AddEnabled(extension1); } + bool FinishDelayedInstallationIfReady(const std::string& extension_id, + bool install_immediately) override { + return false; + } + private: std::vector<InstallUpdateRequest> install_requests_; base::OnceClosure next_install_callback_; @@ -589,24 +594,19 @@ update_client()->RunDelayedUpdate(0); EXPECT_TRUE(executed); - EXPECT_FALSE(update_service()->IsBusy()); } -TEST_F(UpdateServiceTest, InProgressUpdate_Duplicate) { +// Incorrect deduplicating of the same extension ID but with different flags may +// lead to incorrect behaviour: corrupted extension won't be reinstalled. +TEST_F(UpdateServiceTest, InProgressUpdate_DuplicateWithDifferentData) { base::HistogramTester histogram_tester; update_client()->set_delay_update(); ExtensionUpdateCheckParams uc1, uc2; uc1.update_info["A"] = ExtensionUpdateData(); - uc1.update_info["B"] = ExtensionUpdateData(); - uc1.update_info["C"] = ExtensionUpdateData(); - uc1.update_info["D"] = ExtensionUpdateData(); - uc1.update_info["E"] = ExtensionUpdateData(); uc2.update_info["A"] = ExtensionUpdateData(); - uc2.update_info["B"] = ExtensionUpdateData(); - uc2.update_info["C"] = ExtensionUpdateData(); - uc2.update_info["D"] = ExtensionUpdateData(); - uc2.update_info["E"] = ExtensionUpdateData(); + uc2.update_info["A"].install_source = "reinstall"; + uc2.update_info["A"].is_corrupt_reinstall = true; bool executed1 = false; update_service()->StartUpdateCheck( @@ -620,16 +620,24 @@ base::BindOnce([](bool* executed) { *executed = true; }, &executed2)); EXPECT_FALSE(executed2); - ASSERT_EQ(1, update_client()->num_update_requests()); + ASSERT_EQ(2, update_client()->num_update_requests()); - const auto& request = update_client()->update_request(0); - EXPECT_THAT(request.extension_ids, - testing::ElementsAre("A", "B", "C", "D", "E")); + { + const auto& request = update_client()->update_request(0); + EXPECT_THAT(request.extension_ids, testing::ElementsAre("A")); + } + + { + const auto& request = update_client()->update_request(1); + EXPECT_THAT(request.extension_ids, testing::ElementsAre("A")); + } update_client()->RunDelayedUpdate(0); EXPECT_TRUE(executed1); + EXPECT_FALSE(executed2); + + update_client()->RunDelayedUpdate(1); EXPECT_TRUE(executed2); - EXPECT_FALSE(update_service()->IsBusy()); } TEST_F(UpdateServiceTest, InProgressUpdate_NonOverlapped) { @@ -667,302 +675,9 @@ update_client()->RunDelayedUpdate(0); EXPECT_TRUE(executed1); EXPECT_FALSE(executed2); - EXPECT_TRUE(update_service()->IsBusy()); update_client()->RunDelayedUpdate(1); EXPECT_TRUE(executed2); - EXPECT_FALSE(update_service()->IsBusy()); -} - -TEST_F(UpdateServiceTest, InProgressUpdate_Overlapped) { - base::HistogramTester histogram_tester; - update_client()->set_delay_update(); - ExtensionUpdateCheckParams uc1, uc2; - - uc1.update_info["A"] = ExtensionUpdateData(); - uc1.update_info["B"] = ExtensionUpdateData(); - uc1.update_info["C"] = ExtensionUpdateData(); - - uc2.update_info["C"] = ExtensionUpdateData(); - uc2.update_info["D"] = ExtensionUpdateData(); - - bool executed1 = false; - update_service()->StartUpdateCheck( - uc1, - base::BindOnce([](bool* executed) { *executed = true; }, &executed1)); - EXPECT_FALSE(executed1); - - bool executed2 = false; - update_service()->StartUpdateCheck( - uc2, - base::BindOnce([](bool* executed) { *executed = true; }, &executed2)); - EXPECT_FALSE(executed2); - - const auto& request1 = update_client()->update_request(0); - const auto& request2 = update_client()->update_request(1); - - EXPECT_THAT(request1.extension_ids, testing::ElementsAre("A", "B", "C")); - EXPECT_THAT(request2.extension_ids, testing::ElementsAre("D")); - - update_client()->RunDelayedUpdate(0); - ASSERT_TRUE(executed1); - ASSERT_FALSE(executed2); - EXPECT_TRUE(update_service()->IsBusy()); - - update_client()->RunDelayedUpdate(1); - ASSERT_TRUE(executed2); - EXPECT_FALSE(update_service()->IsBusy()); -} - -TEST_F(UpdateServiceTest, InProgressUpdate_3Overlapped) { - // 3 overlapped requests. The 3rd request have all of its IDs in request1 and - // request2. - base::HistogramTester histogram_tester; - update_client()->set_delay_update(); - ExtensionUpdateCheckParams uc1, uc2, uc3; - - uc1.update_info["A"] = ExtensionUpdateData(); - uc1.update_info["B"] = ExtensionUpdateData(); - uc1.update_info["C"] = ExtensionUpdateData(); - - uc2.update_info["C"] = ExtensionUpdateData(); - uc2.update_info["D"] = ExtensionUpdateData(); - uc2.update_info["E"] = ExtensionUpdateData(); - - uc3.update_info["A"] = ExtensionUpdateData(); - uc3.update_info["B"] = ExtensionUpdateData(); - uc3.update_info["C"] = ExtensionUpdateData(); - uc3.update_info["D"] = ExtensionUpdateData(); - uc3.update_info["E"] = ExtensionUpdateData(); - - bool executed1 = false; - update_service()->StartUpdateCheck( - uc1, - base::BindOnce([](bool* executed) { *executed = true; }, &executed1)); - EXPECT_FALSE(executed1); - - bool executed2 = false; - update_service()->StartUpdateCheck( - uc2, - base::BindOnce([](bool* executed) { *executed = true; }, &executed2)); - EXPECT_FALSE(executed2); - - bool executed3 = false; - update_service()->StartUpdateCheck( - uc3, - base::BindOnce([](bool* executed) { *executed = true; }, &executed3)); - EXPECT_FALSE(executed3); - - ASSERT_EQ(2, update_client()->num_update_requests()); - const auto& request1 = update_client()->update_request(0); - const auto& request2 = update_client()->update_request(1); - - EXPECT_THAT(request1.extension_ids, testing::ElementsAre("A", "B", "C")); - EXPECT_THAT(request2.extension_ids, testing::ElementsAre("D", "E")); - - update_client()->RunDelayedUpdate(0); - ASSERT_TRUE(executed1); - ASSERT_FALSE(executed2); - ASSERT_FALSE(executed3); - EXPECT_TRUE(update_service()->IsBusy()); - - update_client()->RunDelayedUpdate(1); - ASSERT_TRUE(executed2); - ASSERT_TRUE(executed3); - EXPECT_FALSE(update_service()->IsBusy()); -} - -TEST_F(UpdateServiceTest, InProgressUpdate_4Overlapped) { - // Similar to 3Overlapped, but the 4th request doesn't overlap with the first - // 3 requests. - base::HistogramTester histogram_tester; - update_client()->set_delay_update(); - ExtensionUpdateCheckParams uc1, uc2, uc3, uc4; - - uc1.update_info["A"] = ExtensionUpdateData(); - uc1.update_info["B"] = ExtensionUpdateData(); - uc1.update_info["C"] = ExtensionUpdateData(); - - uc2.update_info["C"] = ExtensionUpdateData(); - uc2.update_info["D"] = ExtensionUpdateData(); - uc2.update_info["E"] = ExtensionUpdateData(); - - uc3.update_info["A"] = ExtensionUpdateData(); - uc3.update_info["B"] = ExtensionUpdateData(); - uc3.update_info["C"] = ExtensionUpdateData(); - uc3.update_info["D"] = ExtensionUpdateData(); - uc3.update_info["E"] = ExtensionUpdateData(); - - uc4.update_info["G"] = ExtensionUpdateData(); - uc4.update_info["H"] = ExtensionUpdateData(); - uc4.update_info["I"] = ExtensionUpdateData(); - uc4.update_info["J"] = ExtensionUpdateData(); - - bool executed1 = false; - update_service()->StartUpdateCheck( - uc1, - base::BindOnce([](bool* executed) { *executed = true; }, &executed1)); - EXPECT_FALSE(executed1); - - bool executed2 = false; - update_service()->StartUpdateCheck( - uc2, - base::BindOnce([](bool* executed) { *executed = true; }, &executed2)); - EXPECT_FALSE(executed2); - - bool executed3 = false; - update_service()->StartUpdateCheck( - uc3, - base::BindOnce([](bool* executed) { *executed = true; }, &executed3)); - EXPECT_FALSE(executed3); - - bool executed4 = false; - update_service()->StartUpdateCheck( - uc4, - base::BindOnce([](bool* executed) { *executed = true; }, &executed4)); - EXPECT_FALSE(executed4); - - ASSERT_EQ(3, update_client()->num_update_requests()); - const auto& request1 = update_client()->update_request(0); - const auto& request2 = update_client()->update_request(1); - const auto& request3 = update_client()->update_request(2); - - EXPECT_THAT(request1.extension_ids, testing::ElementsAre("A", "B", "C")); - EXPECT_THAT(request2.extension_ids, testing::ElementsAre("D", "E")); - EXPECT_THAT(request3.extension_ids, testing::ElementsAre("G", "H", "I", "J")); - - update_client()->RunDelayedUpdate(0); - ASSERT_TRUE(executed1); - ASSERT_FALSE(executed2); - ASSERT_FALSE(executed3); - ASSERT_FALSE(executed4); - EXPECT_TRUE(update_service()->IsBusy()); - - update_client()->RunDelayedUpdate(1); - ASSERT_TRUE(executed2); - ASSERT_TRUE(executed3); - ASSERT_FALSE(executed4); - EXPECT_TRUE(update_service()->IsBusy()); - - update_client()->RunDelayedUpdate(2); - ASSERT_TRUE(executed4); - EXPECT_FALSE(update_service()->IsBusy()); -} - -TEST_F(UpdateServiceTest, InProgressUpdate_Batch) { - // Verify that extensions are batched when the number of extensions exceeds - // 23. - base::HistogramTester histogram_tester; - update_client()->set_delay_update(); - ExtensionUpdateCheckParams uc; - - for (int i = 0; i < 60; ++i) - uc.update_info[base::StringPrintf("A%02d", i)] = ExtensionUpdateData(); - - bool executed = false; - update_service()->StartUpdateCheck( - uc, base::BindOnce([](bool* executed) { *executed = true; }, &executed)); - EXPECT_FALSE(executed); - - ASSERT_EQ(3, update_client()->num_update_requests()); - - const auto& request1 = update_client()->update_request(0); - const auto& request2 = update_client()->update_request(1); - const auto& request3 = update_client()->update_request(2); - - EXPECT_THAT(request1.extension_ids, - testing::ElementsAre("A00", "A01", "A02", "A03", "A04", "A05", - "A06", "A07", "A08", "A09", "A10", "A11", - "A12", "A13", "A14", "A15", "A16", "A17", - "A18", "A19", "A20", "A21")); - EXPECT_THAT(request2.extension_ids, - testing::ElementsAre("A22", "A23", "A24", "A25", "A26", "A27", - "A28", "A29", "A30", "A31", "A32", "A33", - "A34", "A35", "A36", "A37", "A38", "A39", - "A40", "A41", "A42", "A43")); - EXPECT_THAT(request3.extension_ids, - testing::ElementsAre("A44", "A45", "A46", "A47", "A48", "A49", - "A50", "A51", "A52", "A53", "A54", "A55", - "A56", "A57", "A58", "A59")); - - update_client()->RunDelayedUpdate(0); - EXPECT_FALSE(executed); - EXPECT_TRUE(update_service()->IsBusy()); - - update_client()->RunDelayedUpdate(1); - EXPECT_FALSE(executed); - EXPECT_TRUE(update_service()->IsBusy()); - - update_client()->RunDelayedUpdate(2); - EXPECT_TRUE(executed); - EXPECT_FALSE(update_service()->IsBusy()); -} - -TEST_F(UpdateServiceTest, InProgressUpdate_NoBatchAndBatch) { - base::HistogramTester histogram_tester; - update_client()->set_delay_update(); - ExtensionUpdateCheckParams uc1; - ExtensionUpdateCheckParams uc2; - - uc1.update_info["AA"] = ExtensionUpdateData(); - uc1.update_info["BB"] = ExtensionUpdateData(); - uc1.update_info["CC"] = ExtensionUpdateData(); - uc1.update_info["DD"] = ExtensionUpdateData(); - - for (int i = 0; i < 55; ++i) - uc2.update_info[base::StringPrintf("A%02d", i)] = ExtensionUpdateData(); - - bool executed1 = false; - update_service()->StartUpdateCheck( - uc1, - base::BindOnce([](bool* executed) { *executed = true; }, &executed1)); - EXPECT_FALSE(executed1); - - bool executed2 = false; - update_service()->StartUpdateCheck( - uc2, - base::BindOnce([](bool* executed) { *executed = true; }, &executed2)); - EXPECT_FALSE(executed2); - - ASSERT_EQ(4, update_client()->num_update_requests()); - - const auto& request1 = update_client()->update_request(0); - const auto& request2 = update_client()->update_request(1); - const auto& request3 = update_client()->update_request(2); - const auto& request4 = update_client()->update_request(3); - - EXPECT_THAT(request1.extension_ids, - testing::ElementsAre("AA", "BB", "CC", "DD")); - EXPECT_THAT(request2.extension_ids, - testing::ElementsAre("A00", "A01", "A02", "A03", "A04", "A05", - "A06", "A07", "A08", "A09", "A10", "A11", - "A12", "A13", "A14", "A15", "A16", "A17", - "A18", "A19", "A20", "A21")); - EXPECT_THAT(request3.extension_ids, - testing::ElementsAre("A22", "A23", "A24", "A25", "A26", "A27", - "A28", "A29", "A30", "A31", "A32", "A33", - "A34", "A35", "A36", "A37", "A38", "A39", - "A40", "A41", "A42", "A43")); - EXPECT_THAT(request4.extension_ids, - testing::ElementsAre("A44", "A45", "A46", "A47", "A48", "A49", - "A50", "A51", "A52", "A53", "A54")); - - update_client()->RunDelayedUpdate(0); - EXPECT_TRUE(executed1); - EXPECT_FALSE(executed2); - EXPECT_TRUE(update_service()->IsBusy()); - - update_client()->RunDelayedUpdate(1); - EXPECT_FALSE(executed2); - EXPECT_TRUE(update_service()->IsBusy()); - - update_client()->RunDelayedUpdate(2); - EXPECT_FALSE(executed2); - EXPECT_TRUE(update_service()->IsBusy()); - - update_client()->RunDelayedUpdate(3); - EXPECT_TRUE(executed2); - EXPECT_FALSE(update_service()->IsBusy()); } class UpdateServiceCanUpdateTest : public UpdateServiceTest {
diff --git a/extensions/common/api/_manifest_features.json b/extensions/common/api/_manifest_features.json index a057d75..425ec6a 100644 --- a/extensions/common/api/_manifest_features.json +++ b/extensions/common/api/_manifest_features.json
@@ -120,7 +120,7 @@ "extension_types": "all" }, "declarative_net_request": { - "channel": "beta", + "channel": "stable", "extension_types": ["extension"], "min_manifest_version": 2, "feature_flag": "DeclarativeNetRequest"
diff --git a/extensions/common/api/_permission_features.json b/extensions/common/api/_permission_features.json index bba4413..1e2f7ae 100644 --- a/extensions/common/api/_permission_features.json +++ b/extensions/common/api/_permission_features.json
@@ -211,13 +211,13 @@ ] }, "declarativeNetRequest": { - "channel": "beta", + "channel": "stable", "extension_types": ["extension"], "min_manifest_version": 2, "feature_flag": "DeclarativeNetRequest" }, "declarativeNetRequestFeedback": { - "channel": "beta", + "channel": "stable", "extension_types": ["extension"], "min_manifest_version": 2, "feature_flag": "DeclarativeNetRequest"
diff --git a/extensions/common/api/declarative_net_request.idl b/extensions/common/api/declarative_net_request.idl index c27b00bd..013d6f65 100644 --- a/extensions/common/api/declarative_net_request.idl +++ b/extensions/common/api/declarative_net_request.idl
@@ -368,6 +368,7 @@ callback GetAllowedPagesCallback = void(DOMString[] result); callback GetRulesCallback = void(Rule[] rules); callback GetMatchedRulesCallback = void(RulesMatchedDetails details); + callback GetEnabledRulesetsCallback = void(DOMString[] rulesetIds); interface Functions { @@ -376,7 +377,8 @@ // and then the rules given in <code>rulesToAdd</code> are added. This // update happens as a single atomic operation: either all specified rules // are added and removed, or an error is returned. - // These rules are persisted across browser sessions. + // These rules are persisted across browser sessions and across extension + // updates. // Any ids in <code>ruleIdsToRemove</code> that are not present will be // ignored. // Note that static rules specified as part of the extension package can @@ -386,10 +388,10 @@ // |ruleIdsToRemove|: The IDs of rules to remove. // |rulesToAdd|: The rules to add. // |callback|: Called once the update is complete or has failed. In case of - // an error, $(ref:runtime.lastError) will be set to denote the error - // message and no change will be made to the rule set. This can happen for - // multiple reasons, such as invalid rule format, duplicate rule ID, rule - // count limit exceeded, internal errors, and others. + // an error, $(ref:runtime.lastError) will be set and no change will be made + // to the rule set. This can happen for multiple reasons, such as invalid + // rule format, duplicate rule ID, rule count limit exceeded, internal + // errors, and others. static void updateDynamicRules(long[] ruleIdsToRemove, Rule[] rulesToAdd, optional EmptyCallback callback); @@ -398,6 +400,35 @@ // raised in case of transient internal errors. static void getDynamicRules(GetRulesCallback callback); + // Updates the set of enabled static rulesets for the extension. The + // rulesets with IDs listed in <code>rulesetIDsToDisable</code> are first + // removed, and then the rulesets listed in <code>rulesetIDsToEnable</code> + // are added. + // Note that the set of enabled static rulesets is persisted across sessions + // but not across extension updates, i.e. the <code>rule_resources</code> + // manifest key will determine the set of enabled static rulesets on each + // extension update. + // |rulesetIdsToDisable|: The set of ids corresponding to a static + // $(ref:Ruleset) that should be disabled. + // |rulesetIdsToEnable|: The set of ids corresponding to a static + // $(ref:Ruleset) that should be enabled. + // |callback|: Called once the update is complete. In case of an error, + // $(ref:runtime.lastError) will be set and no change will be made to set of + // enabled rulesets. This can happen for multiple reasons, such as invalid + // ruleset IDs, rule count limit exceeded, or internal errors. + // TODO(crbug.com/754526): Enable the documentation. + [nodoc] + static void updateEnabledRulesets( + DOMString[] rulesetIdsToDisable, DOMString[] rulesetIdsToEnable, + EmptyCallback callback); + + // Returns the ids for the current set of enabled static rulesets. + // |callback|: Called with a list of ids, where each id corresponds to an + // enabled static $(ref:Ruleset). + // TODO(crbug.com/754526): Enable the documentation. + [nodoc] + static void getEnabledRulesets(GetEnabledRulesetsCallback callback); + // Returns all rules matched for the extension. Callers can optionally // filter the list of matched rules by specifying a |filter|. This method is // only available to extensions with the
diff --git a/extensions/common/api/declarative_net_request/dnr_manifest_data.cc b/extensions/common/api/declarative_net_request/dnr_manifest_data.cc index fb520c45..bc0b22d 100644 --- a/extensions/common/api/declarative_net_request/dnr_manifest_data.cc +++ b/extensions/common/api/declarative_net_request/dnr_manifest_data.cc
@@ -20,7 +20,11 @@ RulesetInfo&&) = default; DNRManifestData::DNRManifestData(std::vector<RulesetInfo> rulesets) - : rulesets(std::move(rulesets)) {} + : rulesets(std::move(rulesets)) { + for (const RulesetInfo& info : this->rulesets) + manifest_id_to_ruleset_map.emplace(info.manifest_id, &info); +} + DNRManifestData::~DNRManifestData() = default; // static @@ -39,9 +43,24 @@ return static_cast<DNRManifestData*>(data)->rulesets; } +const DNRManifestData::ManifestIDToRulesetMap& +DNRManifestData::GetManifestIDToRulesetMap(const Extension& extension) { + // Since we return a reference, use a function local static for the case where + // the extension didn't specify any rulesets. + static const base::NoDestructor<ManifestIDToRulesetMap> empty_map; + + Extension::ManifestData* data = + extension.GetManifestData(manifest_keys::kDeclarativeNetRequestKey); + if (!data) + return *empty_map; + + return static_cast<DNRManifestData*>(data)->manifest_id_to_ruleset_map; +} + // static -const std::string& DNRManifestData::GetManifestID(const Extension& extension, - RulesetID ruleset_id) { +const DNRManifestData::RulesetInfo& DNRManifestData::GetRuleset( + const Extension& extension, + RulesetID ruleset_id) { Extension::ManifestData* data = extension.GetManifestData(manifest_keys::kDeclarativeNetRequestKey); DCHECK(data); @@ -53,7 +72,7 @@ CHECK_GE(index, 0); CHECK_LT(static_cast<size_t>(index), rulesets.size()); - return rulesets[index].manifest_id; + return rulesets[index]; } } // namespace declarative_net_request
diff --git a/extensions/common/api/declarative_net_request/dnr_manifest_data.h b/extensions/common/api/declarative_net_request/dnr_manifest_data.h index 7032b4f..9d1746d 100644 --- a/extensions/common/api/declarative_net_request/dnr_manifest_data.h +++ b/extensions/common/api/declarative_net_request/dnr_manifest_data.h
@@ -5,6 +5,8 @@ #ifndef EXTENSIONS_COMMON_API_DECLARATIVE_NET_REQUEST_DNR_MANIFEST_DATA_H_ #define EXTENSIONS_COMMON_API_DECLARATIVE_NET_REQUEST_DNR_MANIFEST_DATA_H_ +#include <map> +#include <string> #include <vector> #include "base/files/file_path.h" @@ -29,6 +31,7 @@ // ID provided for the ruleset in the extension manifest. Uniquely // identifies the ruleset. + // TODO(karandeepb): Rename to |public_id|. std::string manifest_id; // Uniquely identifies an extension ruleset. The order of rulesets within @@ -46,6 +49,8 @@ bool enabled = false; }; + using ManifestIDToRulesetMap = std::map<std::string, const RulesetInfo*>; + explicit DNRManifestData(std::vector<RulesetInfo> ruleset); ~DNRManifestData() override; @@ -54,14 +59,21 @@ static const std::vector<RulesetInfo>& GetRulesets( const Extension& extension); - // Returns the |manifest_id| corresponding to the given |ruleset_id|. - static const std::string& GetManifestID(const Extension& extension, - RulesetID ruleset_id); + // Returns the RulesetInfo corresponding to the given |ruleset_id|. Must only + // be called for a valid |ruleset_id|. + static const RulesetInfo& GetRuleset(const Extension& extension, + RulesetID ruleset_id); + + static const ManifestIDToRulesetMap& GetManifestIDToRulesetMap( + const Extension& extension); // Static rulesets specified by the extension in its manifest, in the order in // which they were specified. std::vector<RulesetInfo> rulesets; + // Map from the manifest ID to the corresponding RulesetInfo. + ManifestIDToRulesetMap manifest_id_to_ruleset_map; + DISALLOW_COPY_AND_ASSIGN(DNRManifestData); };
diff --git a/extensions/common/api/declarative_net_request/dnr_manifest_unittest.cc b/extensions/common/api/declarative_net_request/dnr_manifest_unittest.cc index 682b681..c4a9cbae 100644 --- a/extensions/common/api/declarative_net_request/dnr_manifest_unittest.cc +++ b/extensions/common/api/declarative_net_request/dnr_manifest_unittest.cc
@@ -9,7 +9,6 @@ #include "base/strings/pattern.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" -#include "components/version_info/version_info.h" #include "extensions/common/api/declarative_net_request.h" #include "extensions/common/api/declarative_net_request/constants.h" #include "extensions/common/api/declarative_net_request/dnr_manifest_data.h" @@ -17,7 +16,6 @@ #include "extensions/common/constants.h" #include "extensions/common/error_utils.h" #include "extensions/common/extension.h" -#include "extensions/common/features/feature_channel.h" #include "extensions/common/file_util.h" #include "extensions/common/manifest_constants.h" #include "extensions/common/value_builder.h" @@ -41,7 +39,7 @@ // Fixture testing the kDeclarativeNetRequestKey manifest key. class DNRManifestTest : public testing::Test { public: - DNRManifestTest() : channel_(::version_info::Channel::UNKNOWN) {} + DNRManifestTest() = default; protected: // Loads the extension and verifies the |expected_error|. @@ -80,8 +78,8 @@ EXPECT_EQ(info[i].enabled, rulesets[i].enabled); - EXPECT_EQ(rulesets[i].manifest_id, - DNRManifestData::GetManifestID(*extension, rulesets[i].id)); + EXPECT_EQ(&rulesets[i], + &DNRManifestData::GetRuleset(*extension, rulesets[i].id)); } } @@ -111,7 +109,6 @@ private: base::ScopedTempDir temp_dir_; - ScopedCurrentChannel channel_; DISALLOW_COPY_AND_ASSIGN(DNRManifestTest); };
diff --git a/extensions/renderer/extensions_render_frame_observer.cc b/extensions/renderer/extensions_render_frame_observer.cc index 150dfd38..5802bde0 100644 --- a/extensions/renderer/extensions_render_frame_observer.cc +++ b/extensions/renderer/extensions_render_frame_observer.cc
@@ -97,6 +97,10 @@ } void ExtensionsRenderFrameObserver::SetVisuallyDeemphasized(bool deemphasized) { + // TODO(danakj): This mojo API should be a MainFrame-only interface and object + // rather than an every-frame interface and object. + DCHECK(render_frame()->IsMainFrame()); + if (webview_visually_deemphasized_ == deemphasized) return; @@ -104,8 +108,7 @@ SkColor color = deemphasized ? SkColorSetARGB(178, 0, 0, 0) : SK_ColorTRANSPARENT; - render_frame()->GetRenderView()->GetWebView()->SetMainFrameOverlayColor( - color); + render_frame()->GetWebFrame()->SetMainFrameOverlayColor(color); } void ExtensionsRenderFrameObserver::DetailedConsoleMessageAdded(
diff --git a/fuchsia/engine/BUILD.gn b/fuchsia/engine/BUILD.gn index 24aea9f..8c277b1c 100644 --- a/fuchsia/engine/BUILD.gn +++ b/fuchsia/engine/BUILD.gn
@@ -15,6 +15,17 @@ defines = [ "WEB_ENGINE_IMPLEMENTATION" ] } +declare_args() { + # If set, includes assets served under chrome://resources in web_engine.pak. + # They are required by some test-oriented diagnostic views like + # chrome://gpu. + # Including the resources will increase the application size, so this value + # should be left unset for release builds. + # TODO(crbug.com/1082420): change default to 'false' once all bots that run + # GPU integration tests set this flag to 'true'. + include_webui_resources = !is_official_build +} + mojom("mojom") { sources = [ "on_load_script_injector.mojom", @@ -41,11 +52,14 @@ "$root_gen_dir/third_party/blink/public/resources/blink_scaled_resources_100_percent.pak", "$root_gen_dir/third_party/blink/public/strings/blink_strings_en-US.pak", "$root_gen_dir/ui/resources/ui_resources_100_percent.pak", - "$root_gen_dir/ui/resources/webui_resources.pak", "$root_gen_dir/ui/strings/app_locale_settings_en-US.pak", "$root_gen_dir/ui/strings/ui_strings_en-US.pak", ] + if (include_webui_resources) { + sources += [ "$root_gen_dir/ui/resources/webui_resources.pak" ] + } + deps = [ "//components/resources:components_resources", "//components/strings",
diff --git a/gpu/config/gpu_info_collector_win.cc b/gpu/config/gpu_info_collector_win.cc index 7804990..3d5eb92b 100644 --- a/gpu/config/gpu_info_collector_win.cc +++ b/gpu/config/gpu_info_collector_win.cc
@@ -337,9 +337,14 @@ VkApplicationInfo app_info = {}; app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; + const std::vector<const char*> enabled_instance_extensions = { + "VK_KHR_surface", "VK_KHR_win32_surface"}; + VkInstanceCreateInfo create_info = {}; create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; create_info.pApplicationInfo = &app_info; + create_info.enabledExtensionCount = enabled_instance_extensions.size(); + create_info.ppEnabledExtensionNames = enabled_instance_extensions.data(); // Get the Vulkan API version supported in the GPU driver int highest_minor_version = VK_VERSION_MINOR(info->vulkan_version);
diff --git a/gpu/vulkan/vulkan_util.cc b/gpu/vulkan/vulkan_util.cc index 35f6c2f..8a9661a3 100644 --- a/gpu/vulkan/vulkan_util.cc +++ b/gpu/vulkan/vulkan_util.cc
@@ -5,10 +5,14 @@ #include "gpu/vulkan/vulkan_util.h" #include "base/logging.h" +#include "base/metrics/histogram_macros.h" #include "base/strings/stringprintf.h" #include "gpu/vulkan/vulkan_function_pointers.h" namespace gpu { +namespace { +uint64_t g_submit_count = 0; +} bool SubmitSignalVkSemaphores(VkQueue vk_queue, const base::span<VkSemaphore>& vk_semaphores, @@ -81,4 +85,19 @@ VK_VERSION_PATCH(version)); } +VkResult QueueSubmitHook(VkQueue queue, + uint32_t submitCount, + const VkSubmitInfo* pSubmits, + VkFence fence) { + g_submit_count++; + return vkQueueSubmit(queue, submitCount, pSubmits, fence); +} + +void ReportQueueSubmitPerSwapBuffers() { + static uint64_t last_count = 0; + UMA_HISTOGRAM_CUSTOM_COUNTS("GPU.Vulkan.QueueSubmitPerSwapBuffers", + g_submit_count - last_count, 1, 50, 50); + last_count = g_submit_count; +} + } // namespace gpu \ No newline at end of file
diff --git a/gpu/vulkan/vulkan_util.h b/gpu/vulkan/vulkan_util.h index fd21e5d5..e6f44251 100644 --- a/gpu/vulkan/vulkan_util.h +++ b/gpu/vulkan/vulkan_util.h
@@ -71,6 +71,14 @@ COMPONENT_EXPORT(VULKAN) std::string VkVersionToString(uint32_t version); +COMPONENT_EXPORT(VULKAN) +VKAPI_ATTR VkResult VKAPI_CALL QueueSubmitHook(VkQueue queue, + uint32_t submitCount, + const VkSubmitInfo* pSubmits, + VkFence fence); + +COMPONENT_EXPORT(VULKAN) void ReportQueueSubmitPerSwapBuffers(); + } // namespace gpu #endif // GPU_VULKAN_VULKAN_UTIL_H_
diff --git a/infra/config/README.md b/infra/config/README.md index c5499318..968e2483 100644 --- a/infra/config/README.md +++ b/infra/config/README.md
@@ -1,13 +1,12 @@ -**IMPORTANT:** If you see this in a branch which is not `master`, -**this directory has no effect and should be ignored.** +**IMPORTANT:** This branch only has an effect for branches that have projects +set up in +https://chrome-internal.googlesource.com/infradata/config/+/refs/heads/master/configs/luci-config/projects.cfg This directory contains chromium project-wide configurations for Chrome Operations services. For example, [cr-buildbucket.cfg](generated/cr-buildbucket.cfg) defines builders. -**Remember** Change these configs on `master` branch only! - Currently active version can be checked at https://luci-config.appspot.com/#/projects/chromium .
diff --git a/infra/config/generated/commit-queue.cfg b/infra/config/generated/commit-queue.cfg index 3b87b7e..292857fb 100644 --- a/infra/config/generated/commit-queue.cfg +++ b/infra/config/generated/commit-queue.cfg
@@ -1281,6 +1281,9 @@ name: "chromium/try-m81/android-kitkat-arm-rel" > builders: < + name: "chromium/try-m81/android-lollipop-arm-rel" + > + builders: < name: "chromium/try-m81/android-marshmallow-arm64-rel" > builders: < @@ -1395,6 +1398,9 @@ location_regexp_exclude: ".+/[+]/components/cronet/ios/.+" > builders: < + name: "chromium/try-m83/android-lollipop-arm-rel" + > + builders: < name: "chromium/try-m83/android-marshmallow-arm64-rel" > builders: <
diff --git a/infra/config/generated/cr-buildbucket.cfg b/infra/config/generated/cr-buildbucket.cfg index b3e6aab..472d6ee 100644 --- a/infra/config/generated/cr-buildbucket.cfg +++ b/infra/config/generated/cr-buildbucket.cfg
@@ -13696,6 +13696,38 @@ > > builders: < + name: "android-lollipop-arm-rel" + swarming_host: "chromium-swarm.appspot.com" + swarming_tags: "vpython:native-python-wrapper" + dimensions: "builderless:1" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-16.04" + dimensions: "pool:luci.chromium.ci" + dimensions: "ssd:0" + recipe: < + name: "chromium" + cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" + cipd_version: "refs/heads/master" + properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" + properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" + properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" + properties_j: "mastername:\"chromium.android\"" + > + execution_timeout_secs: 10800 + build_numbers: YES + service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" + resultdb: < + enable: true + bq_exports: < + project: "luci-resultdb" + dataset: "chromium" + table: "ci_test_results" + test_results: <> + > + > + > + builders: < name: "android-marshmallow-arm64-rel" swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper" @@ -16091,6 +16123,38 @@ > > builders: < + name: "android-lollipop-arm-rel" + swarming_host: "chromium-swarm.appspot.com" + swarming_tags: "vpython:native-python-wrapper" + dimensions: "builderless:1" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-16.04" + dimensions: "pool:luci.chromium.ci" + dimensions: "ssd:0" + recipe: < + name: "chromium" + cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" + cipd_version: "refs/heads/master" + properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" + properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" + properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" + properties_j: "mastername:\"chromium.android\"" + > + execution_timeout_secs: 10800 + build_numbers: YES + service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" + resultdb: < + enable: true + bq_exports: < + project: "luci-resultdb" + dataset: "chromium" + table: "ci_test_results" + test_results: <> + > + > + > + builders: < name: "android-marshmallow-arm64-rel" swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper" @@ -28745,7 +28809,45 @@ cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" - properties_j: "$build/test_utils:{\"should_exonerate_flaky_failures\":true}" + properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" + properties_j: "mastername:\"tryserver.chromium.android\"" + > + execution_timeout_secs: 14400 + expiration_secs: 7200 + caches: < + name: "win_toolchain" + path: "win_toolchain" + > + build_numbers: YES + service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" + task_template_canary_percentage: < + value: 5 + > + resultdb: < + enable: true + bq_exports: < + project: "luci-resultdb" + dataset: "chromium" + table: "try_test_results" + test_results: <> + > + > + > + builders: < + name: "android-lollipop-arm-rel" + swarming_host: "chromium-swarm.appspot.com" + swarming_tags: "vpython:native-python-wrapper" + dimensions: "builderless:1" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-16.04" + dimensions: "pool:luci.chromium.try" + dimensions: "ssd:0" + recipe: < + name: "chromium_trybot" + cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" + cipd_version: "refs/heads/master" + properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.android\"" > @@ -29376,7 +29478,6 @@ cipd_version: "refs/heads/master" properties_j: "$build/code_coverage:{\"use_clang_coverage\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" - properties_j: "$build/test_utils:{\"should_exonerate_flaky_failures\":true}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.linux\"" > @@ -29536,7 +29637,6 @@ cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" properties_j: "$build/goma:{\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" - properties_j: "$build/test_utils:{\"should_exonerate_flaky_failures\":true}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.mac\"" > @@ -29652,7 +29752,6 @@ cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" - properties_j: "$build/test_utils:{\"should_exonerate_flaky_failures\":true}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.win\"" > @@ -29827,6 +29926,45 @@ > > builders: < + name: "android-lollipop-arm-rel" + swarming_host: "chromium-swarm.appspot.com" + swarming_tags: "vpython:native-python-wrapper" + dimensions: "builderless:1" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-16.04" + dimensions: "pool:luci.chromium.try" + dimensions: "ssd:0" + recipe: < + name: "chromium_trybot" + cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" + cipd_version: "refs/heads/master" + properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" + properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" + properties_j: "mastername:\"tryserver.chromium.android\"" + > + execution_timeout_secs: 14400 + expiration_secs: 7200 + caches: < + name: "win_toolchain" + path: "win_toolchain" + > + build_numbers: YES + service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" + task_template_canary_percentage: < + value: 5 + > + resultdb: < + enable: true + bq_exports: < + project: "luci-resultdb" + dataset: "chromium" + table: "try_test_results" + test_results: <> + > + > + > + builders: < name: "android-marshmallow-arm64-rel" swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper"
diff --git a/infra/config/generated/luci-milo.cfg b/infra/config/generated/luci-milo.cfg index 0d03e84..fd64b1e 100644 --- a/infra/config/generated/luci-milo.cfg +++ b/infra/config/generated/luci-milo.cfg
@@ -11346,6 +11346,11 @@ short_name: "K" > builders: < + name: "buildbucket/luci.chromium.ci-m81/android-lollipop-arm-rel" + category: "chromium.android|on_cq" + short_name: "L" + > + builders: < name: "buildbucket/luci.chromium.ci-m81/android-marshmallow-arm64-rel" category: "chromium.android|on_cq" short_name: "M" @@ -11934,6 +11939,11 @@ short_name: "P" > builders: < + name: "buildbucket/luci.chromium.ci-m83/android-lollipop-arm-rel" + category: "chromium.android|on_cq" + short_name: "L" + > + builders: < name: "buildbucket/luci.chromium.ci-m83/android-marshmallow-arm64-rel" category: "chromium.android|on_cq" short_name: "M" @@ -12837,6 +12847,9 @@ name: "buildbucket/luci.chromium.try-m81/android-kitkat-arm-rel" > builders: < + name: "buildbucket/luci.chromium.try-m81/android-lollipop-arm-rel" + > + builders: < name: "buildbucket/luci.chromium.try-m81/android-marshmallow-arm64-rel" > builders: < @@ -12920,6 +12933,9 @@ name: "buildbucket/luci.chromium.try-m83/android-cronet-arm-dbg" > builders: < + name: "buildbucket/luci.chromium.try-m83/android-lollipop-arm-rel" + > + builders: < name: "buildbucket/luci.chromium.try-m83/android-marshmallow-arm64-rel" > builders: <
diff --git a/infra/config/generated/luci-scheduler.cfg b/infra/config/generated/luci-scheduler.cfg index bf81bed8..c467a278 100644 --- a/infra/config/generated/luci-scheduler.cfg +++ b/infra/config/generated/luci-scheduler.cfg
@@ -8601,6 +8601,15 @@ > > job: < + id: "ci-m81-android-lollipop-arm-rel" + acl_sets: "ci-m81" + buildbucket: < + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci-m81" + builder: "android-lollipop-arm-rel" + > +> +job: < id: "ci-m81-android-marshmallow-arm64-rel" acl_sets: "ci-m81" buildbucket: < @@ -9440,6 +9449,15 @@ > > job: < + id: "ci-m83-android-lollipop-arm-rel" + acl_sets: "ci-m83" + buildbucket: < + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci-m83" + builder: "android-lollipop-arm-rel" + > +> +job: < id: "ci-m83-android-marshmallow-arm64-rel" acl_sets: "ci-m83" buildbucket: < @@ -10824,6 +10842,7 @@ triggers: "ci-m81-Win x64 Builder" triggers: "ci-m81-android-cronet-arm-rel" triggers: "android-kitkat-arm-rel" + triggers: "ci-m81-android-lollipop-arm-rel" triggers: "ci-m81-android-marshmallow-arm64-rel" triggers: "ci-m81-chromeos-amd64-generic-rel" triggers: "ci-m81-chromeos-arm-generic-rel" @@ -10866,6 +10885,7 @@ triggers: "ci-m83-Win x64 Builder" triggers: "ci-m83-android-cronet-arm-dbg" triggers: "ci-m83-android-cronet-arm-rel" + triggers: "ci-m83-android-lollipop-arm-rel" triggers: "ci-m83-android-marshmallow-arm64-rel" triggers: "ci-m83-android-pie-arm64-rel" triggers: "ci-m83-chromeos-amd64-generic-dbg" @@ -11077,7 +11097,7 @@ triggers: "android-cronet-x86-dbg" triggers: "android-cronet-x86-rel" triggers: "android-incremental-dbg" - triggers: "android-lollipop-arm-rel" + triggers: "ci-android-lollipop-arm-rel" triggers: "ci-android-marshmallow-arm64-rel" triggers: "android-marshmallow-x86-fyi-rel" triggers: "android-mojo-webview-rel"
diff --git a/infra/config/lib/builders.star b/infra/config/lib/builders.star index c816483..6cb8892 100644 --- a/infra/config/lib/builders.star +++ b/infra/config/lib/builders.star
@@ -223,7 +223,6 @@ use_clang_coverage = False, use_java_coverage = False, resultdb_bigquery_exports = [], - should_exonerate_flaky_failures = False, # Provide vars for bucket and executable so users don't have to # unnecessarily make wrapper functions @@ -258,7 +257,6 @@ use_clang_coverage=args.DEFAULT, use_java_coverage=args.DEFAULT, resultdb_bigquery_exports=args.DEFAULT, - should_exonerate_flaky_failures=args.DEFAULT, **kwargs): """Define a builder. @@ -332,8 +330,6 @@ * use_java_coverage - a boolean indicating whether java coverage should be used. If True, the 'use_java_coverage" field will be set in the '$build/code_coverage' property. By default, considered False. - * should_exonerate_flaky_failures - a boolean indicathing whether the - builder should exonerate a test failure if it's known to be flaky on ToT. * resultdb_bigquery_exports - a list of resultdb.export_test_results(...) specifying parameters for exporting test results to BigQuery. By default, do not export. @@ -428,13 +424,6 @@ if code_coverage != None: properties['$build/code_coverage'] = code_coverage - should_exonerate_flaky_failures = defaults.get_value( - 'should_exonerate_flaky_failures', should_exonerate_flaky_failures) - if should_exonerate_flaky_failures: - properties['$build/test_utils'] = { - 'should_exonerate_flaky_failures': True, - } - kwargs = dict(kwargs) bucket = defaults.get_value('bucket', bucket) if bucket != args.COMPUTE:
diff --git a/infra/config/subprojects/chromium/versioned/trunk/vars.star b/infra/config/project.star similarity index 95% rename from infra/config/subprojects/chromium/versioned/trunk/vars.star rename to infra/config/project.star index ca8441e..29bee44 100644 --- a/infra/config/subprojects/chromium/versioned/trunk/vars.star +++ b/infra/config/project.star
@@ -1,4 +1,4 @@ -vars = struct( +settings = struct( # Switch this to False for branches is_master = True, ref = 'refs/heads/master',
diff --git a/infra/config/subprojects/chromium/README.md b/infra/config/subprojects/chromium/README.md index 0844acf6..489dec85 100644 --- a/infra/config/subprojects/chromium/README.md +++ b/infra/config/subprojects/chromium/README.md
@@ -1,7 +1,19 @@ Definitions of LUCI entities that test the chromium/src codebase. -* versioned - Builders for the main waterfall. -* ci.star - Non-main waterfall builders that do post-submit testing. -* try.star, gpu.try.star, swangle.try.star - Non-main waterfall builders that do - pre-submit testing. -* consoles - Manually curated consoles for chromium subproject builders. +* **master-only** + * builders not on the main waterfall that are only run against the master + branch + * milestone-specific versions of these builders do not exist +* **versioned** + * builders on the main waterfall for milestones + * milestones are being switched to use separate projects, so this is only used + for milestones <= M83. +* **ci.star** + * main waterfall builders that do post-submit testing against the master + branch + * when new milestones are created, milestone-specific versions of the builders + will be created +* **try.star**, **gpu.try.star**, **swangle.try.star** + * main waterfall builders that do pre-submit testing against the master branch + * when new milestones are created, milestone-specific versions of the builders + will be created
diff --git a/infra/config/subprojects/chromium/ci.star b/infra/config/subprojects/chromium/ci.star index b1891578..087a3ba 100644 --- a/infra/config/subprojects/chromium/ci.star +++ b/infra/config/subprojects/chromium/ci.star
@@ -1,1700 +1,505 @@ -load('//lib/builders.star', 'cpu', 'goma', 'os', 'xcode_cache') +load('//lib/builders.star', 'builder_name', 'cpu', 'goma', 'os') load('//lib/ci.star', 'ci') -load('./versioned/trunk/vars.star', 'vars') - -# Execute the versioned files to define all of the per-branch entities -# (bucket, builders, console, poller, etc.) -exec('./versioned/trunk/buckets/ci.star') -exec('./versioned/m81/buckets/ci.star') -exec('./versioned/m83/buckets/ci.star') +load('//project.star', 'settings') ci.set_defaults( - vars, - add_to_console_view = True, + settings, + bucketed_triggers = True, + main_console_view = settings.main_console_name, ) - -# *** After this point everything is trunk only *** -ci.console_view( - name = 'chromium', - include_experimental_builds = True, - ordering = {}, -) - -ci.console_view( - name = 'chromium.android', - ordering = { - None: ['cronet', 'builder', 'tester'], - '*cpu*': ['arm', 'arm64', 'x86'], - 'cronet': '*cpu*', - 'builder': '*cpu*', - 'builder|det': ci.ordering(short_names=['rel', 'dbg']), - 'tester': ['phone', 'tablet'], - 'builder_tester|arm64': ci.ordering(short_names=['M proguard']), - }, -) - -ci.console_view( - name = 'chromium.android.fyi', - ordering = { - None: ['android', 'memory', 'weblayer', 'webview'], - }, -) - -ci.console_view( - name = 'chromium.chromiumos', - ordering = { - None: ['default'], - 'default': ci.ordering(short_names=['ful', 'rel']), - 'simple': ['release', 'debug'], - }, -) - -ci.console_view( - name = 'chromium.clang', - ordering = { - None: [ - 'ToT Linux', - 'ToT Android', - 'ToT Mac', - 'ToT Windows', - 'ToT Code Coverage', - ], - 'ToT Linux': ci.ordering( - short_names=['rel', 'ofi', 'dbg', 'asn', 'fuz', 'msn', 'tsn'], - ), - 'ToT Android': ci.ordering(short_names=['rel', 'dbg', 'x64']), - 'ToT Mac': ci.ordering(short_names=['rel', 'ofi', 'dbg']), - 'ToT Windows': ci.ordering( - short_names=['rel', 'ofi'], - categories=['x64'], - ), - 'ToT Windows|x64': ci.ordering(short_names=['rel']), - 'CFI|Win': ci.ordering(short_names=['x86', 'x64']), - 'iOS': ['public'], - 'iOS|public': ci.ordering(short_names=['sim', 'dev']), - }, - entries = [ - luci.console_view_entry( - builder = 'chrome:ci/ToTLinuxOfficial', - category = 'ToT Linux', - short_name = 'ofi', - ), - luci.console_view_entry( - builder = 'chrome:ci/ToTMacOfficial', - category = 'ToT Mac', - short_name = 'ofi', - ), - luci.console_view_entry( - builder = 'chrome:ci/ToTWin', - category = 'ToT Windows', - short_name = 'rel', - ), - luci.console_view_entry( - builder = 'chrome:ci/ToTWin64', - category = 'ToT Windows|x64', - short_name = 'rel', - ), - luci.console_view_entry( - builder = 'chrome:ci/ToTWinOfficial', - category = 'ToT Windows', - short_name = 'ofi', - ), - luci.console_view_entry( - builder = 'chrome:ci/ToTWinThinLTO64', - category = 'ToT Windows|x64', - short_name = 'lto', - ), - luci.console_view_entry( - builder = 'chrome:ci/clang-tot-device', - category = 'iOS|internal', - short_name = 'dev', - ), - ], -) - -ci.console_view( - name = 'chromium.dawn', - ordering = { - None: ['ToT'], - '*builder*': ['Builder'], - '*cpu*': ci.ordering(short_names=['x86']), - 'ToT|Mac': '*builder*', - 'ToT|Windows|Builder': '*cpu*', - 'ToT|Windows|Intel': '*cpu*', - 'ToT|Windows|Nvidia': '*cpu*', - 'DEPS|Mac': '*builder*', - 'DEPS|Windows|Builder': '*cpu*', - 'DEPS|Windows|Intel': '*cpu*', - 'DEPS|Windows|Nvidia': '*cpu*', - }, -) - -ci.console_view( - name = 'chromium.fyi', - ordering = { - None: [ - 'closure_compilation', - 'code_coverage', - 'cronet', - 'mac', - 'deterministic', - 'fuchsia', - 'chromeos', - 'iOS', - 'linux', - 'mojo', - 'recipe', - 'remote_run', - 'site_isolation', - 'network', - 'viz', - 'win10', - 'win32', - ], - 'code_coverage': ci.ordering( - short_names=['and', 'ann', 'lnx', 'lcr', 'mac'] - ), - 'mac': ci.ordering(short_names=['bld', '15', 'herm']), - 'deterministic|mac': ci.ordering(short_names=['rel', 'dbg']), - 'iOS|iOS13': ci.ordering(short_names=['dev', 'sim']), - 'linux|blink': ci.ordering(short_names=['TD']), - }, -) - -ci.console_view( - name ='chromium.fuzz', - ordering = { - None: [ - 'afl', - 'win asan', - 'mac asan', - 'cros asan', - 'linux asan', - 'libfuzz', - 'linux msan', - 'linux tsan', - ], - '*config*': ci.ordering(short_names=['dbg', 'rel']), - 'win asan': '*config*', - 'mac asan': '*config*', - 'linux asan': '*config*', - 'linux asan|x64 v8-ARM': '*config*', - 'libfuzz': ci.ordering(short_names=[ - 'chromeos-asan', - 'linux32', - 'linux32-dbg', - 'linux', - 'linux-dbg', - 'linux-msan', - 'linux-ubsan', - 'mac-asan', - 'win-asan', - ]), - }, -) - -ci.console_view( - name = 'chromium.gpu', - ordering = { - None: ['Windows', 'Mac', 'Linux'], - }, -) - -ci.console_view( - name = 'chromium.gpu.fyi', - ordering = { - None: ['Windows', 'Mac', 'Linux'], - '*builder*': ['Builder'], - '*type*': ci.ordering(short_names=['rel', 'dbg', 'exp']), - '*cpu*': ci.ordering(short_names=['x86']), - 'Windows': '*builder*', - 'Windows|Builder': ['Release', 'dEQP', 'dx12vk', 'Debug'], - 'Windows|Builder|Release': '*cpu*', - 'Windows|Builder|dEQP': '*cpu*', - 'Windows|Builder|dx12vk': '*type*', - 'Windows|Builder|Debug': '*cpu*', - 'Windows|10|x64|Intel': '*type*', - 'Windows|10|x64|Nvidia': '*type*', - 'Windows|10|x86|Nvidia': '*type*', - 'Windows|7|x64|Nvidia': '*type*', - 'Mac': '*builder*', - 'Mac|Builder': '*type*', - 'Mac|AMD|Retina': '*type*', - 'Mac|Intel': '*type*', - 'Mac|Nvidia': '*type*', - 'Linux': '*builder*', - 'Linux|Builder': '*type*', - 'Linux|Intel': '*type*', - 'Linux|Nvidia': '*type*', - 'Android': ['L32', 'M64', 'N64', 'P32', 'vk', 'dqp', 'skgl', 'skv'], - 'Android|M64': ['QCOM'], - }, -) - -ci.console_view( - name = 'chromium.linux', - ordering = { - None: ['release', 'debug'], - 'release': ci.ordering(short_names=['bld', 'tst', 'nsl', 'gcc']), - 'cast': ci.ordering(short_names=['vid', 'aud']), - }, -) - -ci.console_view( - name = 'chromium.mac', - ordering = { - None: ['release'], - 'release': ci.ordering(short_names=['bld']), - 'debug': ci.ordering(short_names=['bld']), - 'ios|default': ci.ordering(short_names=['dev', 'sim']), - }, -) - -ci.console_view( - name = 'chromium.memory', - ordering = { - None: ['win', 'mac', 'linux', 'cros'], - '*build-or-test*': ci.ordering(short_names=['bld', 'tst']), - 'linux|TSan v2': '*build-or-test*', - 'linux|asan lsan': '*build-or-test*', - 'linux|webkit': ci.ordering(short_names=['asn', 'msn']), - }, -) - -ci.console_view( - name = 'chromium.swangle', - ordering = { - None: ['DEPS', 'ToT ANGLE', 'ToT SwiftShader'], - '*os*': ['Windows', 'Mac'], - '*cpu*': ci.ordering(short_names=['x86', 'x64']), - 'DEPS': '*os*', - 'DEPS|Windows': '*cpu*', - 'DEPS|Linux': '*cpu*', - 'ToT ANGLE': '*os*', - 'ToT ANGLE|Windows': '*cpu*', - 'ToT ANGLE|Linux': '*cpu*', - 'ToT SwiftShader': '*os*', - 'ToT SwiftShader|Windows': '*cpu*', - 'ToT SwiftShader|Linux': '*cpu*', - 'Chromium': '*os*', - }, -) - -ci.console_view( - name = 'chromium.win', - ordering = { - None: ['release', 'debug'], - 'debug|builder': ci.ordering(short_names=['64', '32']), - 'debug|tester': ci.ordering(short_names=['7', '10']), - }, -) - -# The main console includes some entries for builders from the chrome project -[luci.console_view_entry( - builder = 'chrome:ci/{}'.format(name), - console_view = 'main', - category = 'chrome', - short_name = short_name, -) for name, short_name in ( - ('linux-chromeos-chrome', 'cro'), - ('linux-chrome', 'lnx'), - ('mac-chrome', 'mac'), - ('win-chrome', 'win'), - ('win64-chrome', 'win'), -)] +ci.declare_bucket(settings) # Builders are sorted first lexicographically by the function used to define # them, then lexicographically by their name -ci.builder( - name = 'android-avd-packager', - executable = 'recipe:android/avd_packager', - properties = { - 'avd_configs': [ - 'tools/android/avd/proto/creation/generic_android23.textpb', - 'tools/android/avd/proto/creation/generic_android28.textpb', - 'tools/android/avd/proto/creation/generic_playstore_android28.textpb', - ], - }, - schedule = '0 7 * * 0 *', - service_account = 'chromium-cipd-builder@chops-service-accounts.iam.gserviceaccount.com', - triggered_by = [], +ci.android_builder( + name = 'Android WebView M (dbg)', + console_view_entry = ci.console_view_entry( + category = 'tester|webview', + short_name = 'M', + ), + triggered_by = [builder_name('Android arm64 Builder (dbg)')], ) -ci.builder( - name = 'android-sdk-packager', - executable = 'recipe:android/sdk_packager', - schedule = '0 7 * * 0 *', - service_account = 'chromium-cipd-builder@chops-service-accounts.iam.gserviceaccount.com', - triggered_by = [], - properties = { - # We still package part of build-tools;25.0.2 to support - # http://bit.ly/2KNUygZ - 'packages': [ - { - 'sdk_package_name': 'build-tools;25.0.2', - 'cipd_yaml': 'third_party/android_sdk/cipd/build-tools/25.0.2.yaml' - }, - { - 'sdk_package_name': 'build-tools;27.0.3', - 'cipd_yaml': 'third_party/android_sdk/cipd/build-tools/27.0.3.yaml' - }, - { - 'sdk_package_name': 'build-tools;29.0.2', - 'cipd_yaml': 'third_party/android_sdk/cipd/build-tools/29.0.2.yaml' - }, - { - 'sdk_package_name': 'emulator', - 'cipd_yaml': 'third_party/android_sdk/cipd/emulator.yaml' - }, - { - 'sdk_package_name': 'extras;google;gcm', - 'cipd_yaml': 'third_party/android_sdk/cipd/extras/google/gcm.yaml' - }, - { - 'sdk_package_name': 'patcher;v4', - 'cipd_yaml': 'third_party/android_sdk/cipd/patcher/v4.yaml' - }, - { - 'sdk_package_name': 'platforms;android-23', - 'cipd_yaml': 'third_party/android_sdk/cipd/platforms/android-23.yaml' - }, - { - 'sdk_package_name': 'platforms;android-28', - 'cipd_yaml': 'third_party/android_sdk/cipd/platforms/android-28.yaml' - }, - { - 'sdk_package_name': 'platforms;android-29', - 'cipd_yaml': 'third_party/android_sdk/cipd/platforms/android-29.yaml' - }, - { - 'sdk_package_name': 'platform-tools', - 'cipd_yaml': 'third_party/android_sdk/cipd/platform-tools.yaml' - }, - { - 'sdk_package_name': 'sources;android-28', - 'cipd_yaml': 'third_party/android_sdk/cipd/sources/android-28.yaml' - }, - { - 'sdk_package_name': 'sources;android-29', - 'cipd_yaml': 'third_party/android_sdk/cipd/sources/android-29.yaml' - }, - { - 'sdk_package_name': 'system-images;android-23;google_apis;x86', - 'cipd_yaml': 'third_party/android_sdk/cipd/system_images/android-23/google_apis/x86.yaml' - }, - { - 'sdk_package_name': 'system-images;android-28;google_apis;x86', - 'cipd_yaml': 'third_party/android_sdk/cipd/system_images/android-28/google_apis/x86.yaml' - }, - { - 'sdk_package_name': 'system-images;android-28;google_apis_playstore;x86', - 'cipd_yaml': 'third_party/android_sdk/cipd/system_images/android-28/google_apis_playstore/x86.yaml' - }, - { - 'sdk_package_name': 'system-images;android-29;google_apis;x86', - 'cipd_yaml': 'third_party/android_sdk/cipd/system_images/android-29/google_apis/x86.yaml' - }, - { - 'sdk_package_name': 'system-images;android-29;google_apis_playstore;x86', - 'cipd_yaml': 'third_party/android_sdk/cipd/system_images/android-29/google_apis_playstore/x86.yaml' - }, - ], - }, -) - - ci.android_builder( - name = 'Android ASAN (dbg)', + name = 'Android WebView N (dbg)', + console_view_entry = ci.console_view_entry( + category = 'tester|webview', + short_name = 'N', + ), + triggered_by = [builder_name('Android arm64 Builder (dbg)')], +) + +ci.android_builder( + name = 'Android WebView O (dbg)', + console_view_entry = ci.console_view_entry( + category = 'tester|webview', + short_name = 'O', + ), + triggered_by = [builder_name('Android arm64 Builder (dbg)')], +) + +ci.android_builder( + name = 'Android WebView P (dbg)', + console_view_entry = ci.console_view_entry( + category = 'tester|webview', + short_name = 'P', + ), + triggered_by = [builder_name('Android arm64 Builder (dbg)')], +) + +ci.android_builder( + name = 'Android arm Builder (dbg)', console_view_entry = ci.console_view_entry( category = 'builder|arm', - short_name = 'san', + short_name = '32', ), - # Higher build timeout since dbg ASAN builds can take a while on a clobber - # build. execution_timeout = 4 * time.hour, ) ci.android_builder( - name = 'Android WebView L (dbg)', + name = 'Android arm64 Builder (dbg)', console_view_entry = ci.console_view_entry( - category = 'tester|webview', - short_name = 'L', - ), - main_console_view = 'main', - triggered_by = ['ci/Android arm Builder (dbg)'], -) - -ci.android_builder( - name = 'Deterministic Android', - console_view_entry = ci.console_view_entry( - category = 'builder|det', - short_name = 'rel', - ), - executable = 'recipe:swarming/deterministic_build', - execution_timeout = 6 * time.hour, -) - -ci.android_builder( - name = 'Deterministic Android (dbg)', - console_view_entry = ci.console_view_entry( - category = 'builder|det', - short_name = 'dbg', - ), - executable = 'recipe:swarming/deterministic_build', - execution_timeout = 6 * time.hour, -) - -ci.android_builder( - name = 'Lollipop Phone Tester', - console_view_entry = ci.console_view_entry( - category = 'tester|phone', - short_name = 'L', - ), - # We have limited phone capacity and thus limited ability to run - # tests in parallel, hence the high timeout. - execution_timeout = 6 * time.hour, - main_console_view = 'main', - triggered_by = ['ci/Android arm Builder (dbg)'], -) - -ci.android_builder( - name = 'Lollipop Tablet Tester', - console_view_entry = ci.console_view_entry( - category = 'tester|tablet', - short_name = 'L', - ), - # We have limited tablet capacity and thus limited ability to run - # tests in parallel, hence the high timeout. - execution_timeout = 20 * time.hour, - main_console_view = 'main', - triggered_by = ['ci/Android arm Builder (dbg)'], -) - -ci.android_builder( - name = 'Marshmallow Tablet Tester', - console_view_entry = ci.console_view_entry( - category = 'tester|tablet', - short_name = 'M', - ), - # We have limited tablet capacity and thus limited ability to run - # tests in parallel, hence the high timeout. - execution_timeout = 12 * time.hour, - main_console_view = 'main', - triggered_by = ['ci/Android arm Builder (dbg)'], -) - -ci.android_builder( - name = 'android-arm64-proguard-rel', - console_view_entry = ci.console_view_entry( - category = 'builder_tester|arm64', - short_name = 'M proguard', + category = 'builder|arm', + short_name = '64', ), goma_jobs = goma.jobs.MANY_JOBS_FOR_CI, - execution_timeout = 6 * time.hour, + execution_timeout = 4 * time.hour, ) ci.android_builder( - name = 'android-cronet-arm64-dbg', + name = 'Android x64 Builder (dbg)', console_view_entry = ci.console_view_entry( - category = 'cronet|arm64', + category = 'builder|x86', + short_name = '64', + ), + execution_timeout = 4 * time.hour, +) + +ci.android_builder( + name = 'Android x86 Builder (dbg)', + console_view_entry = ci.console_view_entry( + category = 'builder|x86', + short_name = '32', + ), +) + +ci.android_builder( + name = 'Cast Android (dbg)', + console_view_entry = ci.console_view_entry( + category = 'on_cq', + short_name = 'cst', + ), +) + +ci.android_builder( + name = 'Marshmallow 64 bit Tester', + console_view_entry = ci.console_view_entry( + category = 'tester|phone', + short_name = 'M', + ), + triggered_by = [builder_name('Android arm64 Builder (dbg)')], +) + +ci.android_builder( + name = 'Nougat Phone Tester', + console_view_entry = ci.console_view_entry( + category = 'tester|phone', + short_name = 'N', + ), + triggered_by = [builder_name('Android arm64 Builder (dbg)')], +) + +ci.android_builder( + name = 'Oreo Phone Tester', + console_view_entry = ci.console_view_entry( + category = 'tester|phone', + short_name = 'O', + ), + triggered_by = [builder_name('Android arm64 Builder (dbg)')], +) + +ci.android_builder( + name = 'android-cronet-arm-dbg', + console_view_entry = ci.console_view_entry( + category = 'cronet|arm', short_name = 'dbg', ), notifies = ['cronet'], ) ci.android_builder( - name = 'android-cronet-arm64-rel', + name = 'android-cronet-arm-rel', console_view_entry = ci.console_view_entry( - category = 'cronet|arm64', + category = 'cronet|arm', short_name = 'rel', ), notifies = ['cronet'], ) ci.android_builder( - name = 'android-cronet-asan-arm-rel', - console_view_entry = ci.console_view_entry( - category = 'cronet|asan', - ), - notifies = ['cronet'], -) - -# Runs on a specific machine with an attached phone -ci.android_builder( - name = 'android-cronet-marshmallow-arm64-perf-rel', - console_view_entry = ci.console_view_entry( - category = 'cronet|test|perf', - short_name = 'm', - ), - cores = None, - cpu = None, - executable = 'recipe:cronet', - notifies = ['cronet'], - os = os.ANDROID, -) - -ci.android_builder( - name = 'android-cronet-marshmallow-arm64-rel', + name = 'android-cronet-kitkat-arm-rel', console_view_entry = ci.console_view_entry( category = 'cronet|test', - short_name = 'm', + short_name = 'k', ), notifies = ['cronet'], - triggered_by = ['android-cronet-arm64-rel'], + triggered_by = [builder_name('android-cronet-arm-rel')], ) ci.android_builder( - name = 'android-cronet-x86-dbg', + name = 'android-cronet-lollipop-arm-rel', console_view_entry = ci.console_view_entry( - category = 'cronet|x86', - short_name = 'dbg', + category = 'cronet|test', + short_name = 'l', ), notifies = ['cronet'], + triggered_by = [builder_name('android-cronet-arm-rel')], ) ci.android_builder( - name = 'android-cronet-x86-rel', + name = 'android-lollipop-arm-rel', console_view_entry = ci.console_view_entry( - category = 'cronet|x86', - short_name = 'rel', - ), - notifies = ['cronet'], -) - -ci.android_builder( - name = 'android-incremental-dbg', - console_view_entry = ci.console_view_entry( - category = 'tester|incremental', + category = 'on_cq', + short_name = 'L', ), ) ci.android_builder( - name = 'android-pie-x86-rel', + name = 'android-marshmallow-arm64-rel', console_view_entry = ci.console_view_entry( - category = 'builder_tester|x86', + category = 'on_cq', + short_name = 'M', + ), +) + +ci.android_builder( + name = 'android-pie-arm64-dbg', + console_view_entry = ci.console_view_entry( + category = 'tester|phone', + short_name = 'P', + ), + triggered_by = [builder_name('Android arm64 Builder (dbg)')], +) + +ci.android_builder( + name = 'android-pie-arm64-rel', + console_view_entry = ci.console_view_entry( + category = 'on_cq', short_name = 'P', ), ) -ci.android_builder( - name = 'android-10-arm64-rel', - console_view_entry = ci.console_view_entry( - category = 'builder_tester|arm64', - short_name = '10', - ), -) - - -ci.android_fyi_builder( - name = 'android-bfcache-rel', - console_view_entry = ci.console_view_entry( - category = 'android', - ), -) - -ci.android_fyi_builder( - name = 'Android WebLayer P FYI (rel)', - console_view_entry = ci.console_view_entry( - category = 'weblayer', - short_name = 'p-rel', - ), -) - -ci.android_fyi_builder( - name = 'android-weblayer-pie-x86-fyi-rel', - console_view_entry = ci.console_view_entry( - category = 'weblayer', - short_name = 'p-x86-rel', - ), -) - -ci.android_fyi_builder( - name = 'Android WebView P Blink-CORS FYI (rel)', - console_view_entry = ci.console_view_entry( - category = 'webview', - short_name = 'cors', - ), -) - -ci.android_fyi_builder( - name = 'Android WebView P FYI (rel)', - console_view_entry = ci.console_view_entry( - category = 'webview', - short_name = 'p-rel', - ), -) - -ci.android_fyi_builder( - name = 'android-marshmallow-x86-fyi-rel', - console_view_entry = ci.console_view_entry( - category = 'emulator|M|x86', - short_name = 'rel', - ), - goma_jobs=goma.jobs.J150, -) - -# TODO(hypan): remove this once there is no associated disabled tests -ci.android_fyi_builder( - name = 'android-pie-x86-fyi-rel', - console_view_entry = ci.console_view_entry( - category = 'emulator|P|x86', - short_name = 'rel', - ), - goma_jobs=goma.jobs.J150, - schedule = 'triggered', # triggered manually via Scheduler UI -) - - - -ci.chromium_builder( - name = 'android-archive-dbg', - # Bump to 32 if needed. - console_view_entry = ci.console_view_entry( - category = 'android', - short_name = 'dbg', - ), - cores = 8, - main_console_view = 'main', -) - -ci.chromium_builder( - name = 'android-archive-rel', - console_view_entry = ci.console_view_entry( - category = 'android', - short_name = 'rel', - ), - cores = 32, - main_console_view = 'main', -) - -ci.chromium_builder( - name = 'linux-archive-dbg', - console_view_entry = ci.console_view_entry( - category = 'linux', - short_name = 'dbg', - ), - # Bump to 32 if needed. - cores = 8, - main_console_view = 'main', -) - -ci.chromium_builder( - name = 'linux-archive-rel', - console_view_entry = ci.console_view_entry( - category = 'linux', - short_name = 'rel', - ), - cores = 32, - main_console_view = 'main', -) - -ci.chromium_builder( - name = 'mac-archive-dbg', - console_view_entry = ci.console_view_entry( - category = 'mac', - short_name = 'dbg', - ), - # Bump to 8 cores if needed. - cores = 4, - main_console_view = 'main', - os = os.MAC_DEFAULT, -) - -ci.chromium_builder( - name = 'mac-archive-rel', - console_view_entry = ci.console_view_entry( - category = 'mac', - short_name = 'rel', - ), - main_console_view = 'main', - os = os.MAC_DEFAULT, -) - -ci.chromium_builder( - name = 'win-archive-dbg', - console_view_entry = ci.console_view_entry( - category = 'win|dbg', - short_name = '64', - ), - cores = 32, - main_console_view = 'main', - os = os.WINDOWS_DEFAULT, -) - -ci.chromium_builder( - name = 'win-archive-rel', - console_view_entry = ci.console_view_entry( - category = 'win|rel', - short_name = '64', - ), - cores = 32, - main_console_view = 'main', - os = os.WINDOWS_DEFAULT, -) - -ci.chromium_builder( - name = 'win32-archive-dbg', - console_view_entry = ci.console_view_entry( - category = 'win|dbg', - short_name = '32', - ), - cores = 32, - main_console_view = 'main', - os = os.WINDOWS_DEFAULT, -) - -ci.chromium_builder( - name = 'win32-archive-rel', - console_view_entry = ci.console_view_entry( - category = 'win|rel', - short_name = '32', - ), - cores = 32, - main_console_view = 'main', - os = os.WINDOWS_DEFAULT, -) - ci.chromiumos_builder( - name = 'Linux ChromiumOS Full', + name = 'chromeos-amd64-generic-dbg', console_view_entry = ci.console_view_entry( - category = 'default', - short_name = 'ful', + category = 'simple|debug|x64', + short_name = 'dbg', ), ) ci.chromiumos_builder( - name = 'chromeos-amd64-generic-asan-rel', + name = 'chromeos-amd64-generic-rel', console_view_entry = ci.console_view_entry( category = 'simple|release|x64', - short_name = 'asn', + short_name = 'rel', ), ) ci.chromiumos_builder( - name = 'chromeos-amd64-generic-cfi-thin-lto-rel', + name = 'chromeos-arm-generic-rel', console_view_entry = ci.console_view_entry( - category = 'simple|release|x64', - short_name = 'cfi', - ), -) - -ci.chromiumos_builder( - name = 'chromeos-arm-generic-dbg', - console_view_entry = ci.console_view_entry( - category = 'simple|debug', + category = 'simple|release', short_name = 'arm', ), ) - -ci.clang_builder( - name = 'CFI Linux CF', - goma_backend = goma.backend.RBE_PROD, +ci.chromiumos_builder( + name = 'chromeos-kevin-rel', console_view_entry = ci.console_view_entry( - category = 'CFI|Linux', - short_name = 'CF', + category = 'simple|release', + short_name = 'kvn', ), ) -ci.clang_builder( - name = 'CFI Linux ToT', +ci.fyi_builder( + name = 'chromeos-kevin-rel-hw-tests', console_view_entry = ci.console_view_entry( - category = 'CFI|Linux', - short_name = 'ToT', + category = 'chromeos', ), ) -ci.clang_builder( - name = 'CrWinAsan', +ci.chromiumos_builder( + name = 'linux-chromeos-dbg', console_view_entry = ci.console_view_entry( - category = 'ToT Windows|Asan', - short_name = 'asn', + category = 'default', + short_name = 'dbg', ), - os = os.WINDOWS_ANY, ) -ci.clang_builder( - name = 'CrWinAsan(dll)', +ci.chromiumos_builder( + name = 'linux-chromeos-rel', console_view_entry = ci.console_view_entry( - category = 'ToT Windows|Asan', - short_name = 'dll', - ), - os = os.WINDOWS_ANY, -) - -ci.clang_builder( - name = 'ToTAndroid', - console_view_entry = ci.console_view_entry( - category = 'ToT Android', + category = 'default', short_name = 'rel', ), ) -ci.clang_builder( - name = 'ToTAndroid (dbg)', - console_view_entry = ci.console_view_entry( - category = 'ToT Android', - short_name = 'dbg', - ), -) - -ci.clang_builder( - name = 'ToTAndroid x64', - console_view_entry = ci.console_view_entry( - category = 'ToT Android', - short_name = 'x64', - ), -) - -ci.clang_builder( - name = 'ToTAndroid64', - console_view_entry = ci.console_view_entry( - category = 'ToT Android', - short_name = 'a64', - ), -) - -ci.clang_builder( - name = 'ToTAndroidASan', - console_view_entry = ci.console_view_entry( - category = 'ToT Android', - short_name = 'asn', - ), -) - -ci.clang_builder( - name = 'ToTAndroidCFI', - console_view_entry = ci.console_view_entry( - category = 'ToT Android', - short_name = 'cfi', - ), -) - -ci.clang_builder( - name = 'ToTAndroidOfficial', - console_view_entry = ci.console_view_entry( - category = 'ToT Android', - short_name = 'off', - ), -) - -ci.clang_builder( - name = 'ToTLinux', - console_view_entry = ci.console_view_entry( - category = 'ToT Linux', - short_name = 'rel', - ), -) - -ci.clang_builder( - name = 'ToTLinux (dbg)', - console_view_entry = ci.console_view_entry( - category = 'ToT Linux', - short_name = 'dbg', - ), -) - -ci.clang_builder( - name = 'ToTLinuxASan', - console_view_entry = ci.console_view_entry( - category = 'ToT Linux', - short_name = 'asn', - ), -) - -ci.clang_builder( - name = 'ToTLinuxASanLibfuzzer', - console_view_entry = ci.console_view_entry( - category = 'ToT Linux', - short_name = 'fuz', - ), -) - -ci.clang_builder( - name = 'ToTLinuxCoverage', - console_view_entry = ci.console_view_entry( - category = 'ToT Code Coverage', - short_name = 'linux', - ), - executable = 'recipe:chromium_clang_coverage_tot', -) - -ci.clang_builder( - name = 'ToTLinuxMSan', - console_view_entry = ci.console_view_entry( - category = 'ToT Linux', - short_name = 'msn', - ), -) - -ci.clang_builder( - name = 'ToTLinuxTSan', - console_view_entry = ci.console_view_entry( - category = 'ToT Linux', - short_name = 'tsn', - ), -) - -ci.clang_builder( - name = 'ToTLinuxThinLTO', - console_view_entry = ci.console_view_entry( - category = 'ToT Linux', - short_name = 'lto', - ), -) - -ci.clang_builder( - name = 'ToTLinuxUBSanVptr', - console_view_entry = ci.console_view_entry( - category = 'ToT Linux', - short_name = 'usn', - ), -) - -ci.clang_builder( - name = 'ToTWin(dbg)', - console_view_entry = ci.console_view_entry( - category = 'ToT Windows', - short_name = 'dbg', - ), - os = os.WINDOWS_ANY, -) - -ci.clang_builder( - name = 'ToTWin(dll)', - console_view_entry = ci.console_view_entry( - category = 'ToT Windows', - short_name = 'dll', - ), - os = os.WINDOWS_ANY, -) - -ci.clang_builder( - name = 'ToTWin64(dbg)', - console_view_entry = ci.console_view_entry( - category = 'ToT Windows|x64', - short_name = 'dbg', - ), - os = os.WINDOWS_ANY, -) - -ci.clang_builder( - name = 'ToTWin64(dll)', - console_view_entry = ci.console_view_entry( - category = 'ToT Windows|x64', - short_name = 'dll', - ), - os = os.WINDOWS_ANY, -) - -ci.clang_builder( - name = 'ToTWinASanLibfuzzer', - console_view_entry = ci.console_view_entry( - category = 'ToT Windows|Asan', - short_name = 'fuz', - ), - os = os.WINDOWS_ANY, -) - -ci.clang_builder( - name = 'ToTWinCFI', - console_view_entry = ci.console_view_entry( - category = 'CFI|Win', - short_name = 'x86', - ), - os = os.WINDOWS_ANY, -) - -ci.clang_builder( - name = 'ToTWinCFI64', - console_view_entry = ci.console_view_entry( - category = 'CFI|Win', - short_name = 'x64', - ), - os = os.WINDOWS_ANY, -) - -ci.clang_builder( - name = 'UBSanVptr Linux', - console_view_entry = ci.console_view_entry( - short_name = 'usn', - ), - goma_backend = goma.backend.RBE_PROD, -) - -ci.clang_builder( - name = 'linux-win_cross-rel', - console_view_entry = ci.console_view_entry( - category = 'ToT Windows', - short_name = 'lxw', - ), -) - -ci.clang_builder( - name = 'ToTiOS', - caches = [xcode_cache.x11c29], - console_view_entry = ci.console_view_entry( - category = 'iOS|public', - short_name = 'sim', - ), - cores = None, - os = os.MAC_10_14, - properties = { - 'xcode_build_version': '11c29' - }, - ssd=True -) - -ci.clang_builder( - name = 'ToTiOSDevice', - caches = [xcode_cache.x11c29], - console_view_entry = ci.console_view_entry( - category = 'iOS|public', - short_name = 'dev', - ), - cores = None, - os = os.MAC_10_14, - properties = { - 'xcode_build_version': '11c29' - }, - ssd=True -) - - -ci.clang_mac_builder( - name = 'ToTMac', - console_view_entry = ci.console_view_entry( - category = 'ToT Mac', - short_name = 'rel', - ), -) - -ci.clang_mac_builder( - name = 'ToTMac (dbg)', - console_view_entry = ci.console_view_entry( - category = 'ToT Mac', - short_name = 'dbg', - ), -) - -ci.clang_mac_builder( - name = 'ToTMacASan', - console_view_entry = ci.console_view_entry( - category = 'ToT Mac', - short_name = 'asn', - ), -) - -ci.clang_mac_builder( - name = 'ToTMacCoverage', - console_view_entry = ci.console_view_entry( - category = 'ToT Code Coverage', - short_name = 'mac', - ), - executable = 'recipe:chromium_clang_coverage_tot', -) - ci.dawn_builder( - name = 'Dawn Linux x64 Builder', + name = 'Dawn Linux x64 DEPS Builder', console_view_entry = ci.console_view_entry( - category = 'ToT|Linux|Builder', + category = 'DEPS|Linux|Builder', short_name = 'x64', ), ) ci.dawn_builder( - name = 'Dawn Linux x64 Release (Intel HD 630)', + name = 'Dawn Linux x64 DEPS Release (Intel HD 630)', console_view_entry = ci.console_view_entry( - category = 'ToT|Linux|Intel', + category = 'DEPS|Linux|Intel', short_name = 'x64', ), cores = 2, os = os.LINUX_DEFAULT, - triggered_by = ['Dawn Linux x64 Builder'], + triggered_by = [builder_name('Dawn Linux x64 DEPS Builder')], ) ci.dawn_builder( - name = 'Dawn Linux x64 Release (NVIDIA)', + name = 'Dawn Linux x64 DEPS Release (NVIDIA)', console_view_entry = ci.console_view_entry( - category = 'ToT|Linux|Nvidia', + category = 'DEPS|Linux|Nvidia', short_name = 'x64', ), cores = 2, os = os.LINUX_DEFAULT, - triggered_by = ['Dawn Linux x64 Builder'], + triggered_by = [builder_name('Dawn Linux x64 DEPS Builder')], ) ci.dawn_builder( - name = 'Dawn Mac x64 Builder', - console_view_entry = ci.console_view_entry( - category = 'ToT|Mac|Builder', - short_name = 'x64', - ), + name = 'Dawn Mac x64 DEPS Builder', builderless = False, + console_view_entry = ci.console_view_entry( + category = 'DEPS|Mac|Builder', + short_name = 'x64', + ), cores = None, os = os.MAC_ANY, ) +# Note that the Mac testers are all thin Linux VMs, triggering jobs on the +# physical Mac hardware in the Swarming pool which is why they run on linux ci.dawn_builder( - name = 'Dawn Mac x64 Release (AMD)', + name = 'Dawn Mac x64 DEPS Release (AMD)', console_view_entry = ci.console_view_entry( - category = 'ToT|Mac|AMD', + category = 'DEPS|Mac|AMD', short_name = 'x64', ), cores = 2, os = os.LINUX_DEFAULT, - triggered_by = ['Dawn Mac x64 Builder'], + triggered_by = [builder_name('Dawn Mac x64 DEPS Builder')], ) ci.dawn_builder( - name = 'Dawn Mac x64 Release (Intel)', + name = 'Dawn Mac x64 DEPS Release (Intel)', console_view_entry = ci.console_view_entry( - category = 'ToT|Mac|Intel', + category = 'DEPS|Mac|Intel', short_name = 'x64', ), cores = 2, os = os.LINUX_DEFAULT, - triggered_by = ['Dawn Mac x64 Builder'], + triggered_by = [builder_name('Dawn Mac x64 DEPS Builder')], ) ci.dawn_builder( - name = 'Dawn Win10 x86 Builder', + name = 'Dawn Win10 x64 DEPS Builder', console_view_entry = ci.console_view_entry( - category = 'ToT|Windows|Builder', + category = 'DEPS|Windows|Builder', + short_name = 'x64', + ), + os = os.WINDOWS_ANY, +) + +ci.dawn_builder( + name = 'Dawn Win10 x64 DEPS Release (Intel HD 630)', + console_view_entry = ci.console_view_entry( + category = 'DEPS|Windows|Intel', + short_name = 'x64', + ), + cores = 2, + os = os.LINUX_DEFAULT, + triggered_by = [builder_name('Dawn Win10 x64 DEPS Builder')], +) + +ci.dawn_builder( + name = 'Dawn Win10 x64 DEPS Release (NVIDIA)', + console_view_entry = ci.console_view_entry( + category = 'DEPS|Windows|Nvidia', + short_name = 'x64', + ), + cores = 2, + os = os.LINUX_DEFAULT, + triggered_by = [builder_name('Dawn Win10 x64 DEPS Builder')], +) + +ci.dawn_builder( + name = 'Dawn Win10 x86 DEPS Builder', + console_view_entry = ci.console_view_entry( + category = 'DEPS|Windows|Builder', short_name = 'x86', ), os = os.WINDOWS_ANY, ) ci.dawn_builder( - name = 'Dawn Win10 x64 Builder', + name = 'Dawn Win10 x86 DEPS Release (Intel HD 630)', console_view_entry = ci.console_view_entry( - category = 'ToT|Windows|Builder', - short_name = 'x64', - ), - os = os.WINDOWS_ANY, -) - -# Note that the Win testers are all thin Linux VMs, triggering jobs on the -# physical Win hardware in the Swarming pool, which is why they run on linux -ci.dawn_builder( - name = 'Dawn Win10 x86 Release (Intel HD 630)', - console_view_entry = ci.console_view_entry( - category = 'ToT|Windows|Intel', + category = 'DEPS|Windows|Intel', short_name = 'x86', ), cores = 2, os = os.LINUX_DEFAULT, - triggered_by = ['Dawn Win10 x86 Builder'], + triggered_by = [builder_name('Dawn Win10 x86 DEPS Builder')], ) ci.dawn_builder( - name = 'Dawn Win10 x64 Release (Intel HD 630)', + name = 'Dawn Win10 x86 DEPS Release (NVIDIA)', console_view_entry = ci.console_view_entry( - category = 'ToT|Windows|Intel', - short_name = 'x64', - ), - cores = 2, - os = os.LINUX_DEFAULT, - triggered_by = ['Dawn Win10 x64 Builder'], -) - -ci.dawn_builder( - name = 'Dawn Win10 x86 Release (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'ToT|Windows|Nvidia', + category = 'DEPS|Windows|Nvidia', short_name = 'x86', ), cores = 2, os = os.LINUX_DEFAULT, - triggered_by = ['Dawn Win10 x86 Builder'], -) - -ci.dawn_builder( - name = 'Dawn Win10 x64 Release (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'ToT|Windows|Nvidia', - short_name = 'x64', - ), - cores = 2, - os = os.LINUX_DEFAULT, - triggered_by = ['Dawn Win10 x64 Builder'], -) - - -ci.fuzz_builder( - name = 'ASAN Debug', - console_view_entry = ci.console_view_entry( - category = 'linux asan', - short_name = 'dbg', - ), - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 4, - ), -) - -ci.fuzz_builder( - name = 'ASan Debug (32-bit x86 with V8-ARM)', - console_view_entry = ci.console_view_entry( - category = 'linux asan|x64 v8-ARM', - short_name = 'dbg', - ), - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 4, - ), -) - -ci.fuzz_builder( - name = 'ASAN Release', - console_view_entry = ci.console_view_entry( - category = 'linux asan', - short_name = 'rel', - ), - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 5, - ), -) - -ci.fuzz_builder( - name = 'ASan Release (32-bit x86 with V8-ARM)', - console_view_entry = ci.console_view_entry( - category = 'linux asan|x64 v8-ARM', - short_name = 'rel', - ), - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 4, - ), -) - -ci.fuzz_builder( - name = 'ASAN Release Media', - console_view_entry = ci.console_view_entry( - category = 'linux asan', - short_name = 'med', - ), - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 4, - ), -) - -ci.fuzz_builder( - name = 'Afl Upload Linux ASan', - console_view_entry = ci.console_view_entry( - category = 'afl', - short_name = 'afl', - ), - executable = 'recipe:chromium_afl', - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 4, - ), -) - -ci.fuzz_builder( - name = 'ASan Release Media (32-bit x86 with V8-ARM)', - console_view_entry = ci.console_view_entry( - category = 'linux asan|x64 v8-ARM', - short_name = 'med', - ), - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 4, - ), -) - -ci.fuzz_builder( - name = 'ChromiumOS ASAN Release', - console_view_entry = ci.console_view_entry( - category = 'cros asan', - ), - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 6, - ), -) - -ci.fuzz_builder( - name = 'MSAN Release (chained origins)', - console_view_entry = ci.console_view_entry( - category = 'linux msan', - short_name = 'org', - ), - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 4, - ), -) - -ci.fuzz_builder( - name = 'MSAN Release (no origins)', - console_view_entry = ci.console_view_entry( - category = 'linux msan', - short_name = 'rel', - ), - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 4, - ), -) - -ci.fuzz_builder( - name = 'Mac ASAN Release', - builderless = False, - console_view_entry = ci.console_view_entry( - category = 'mac asan', - short_name = 'rel', - ), - cores = 4, - os = os.MAC_DEFAULT, - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 2, - ), -) - -ci.fuzz_builder( - name = 'Mac ASAN Release Media', - builderless = False, - console_view_entry = ci.console_view_entry( - category = 'mac asan', - short_name = 'med', - ), - cores = 4, - os = os.MAC_DEFAULT, - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 2, - ), -) - -ci.fuzz_builder( - name = 'TSAN Debug', - console_view_entry = ci.console_view_entry( - category = 'linux tsan', - short_name = 'dbg', - ), - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 4, - ), -) - -ci.fuzz_builder( - name = 'TSAN Release', - console_view_entry = ci.console_view_entry( - category = 'linux tsan', - short_name = 'rel', - ), - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 3, - ), -) - -ci.fuzz_builder( - name = 'UBSan Release', - console_view_entry = ci.console_view_entry( - category = 'linux UBSan', - short_name = 'rel', - ), - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 4, - ), -) - -ci.fuzz_builder( - name = 'UBSan vptr Release', - console_view_entry = ci.console_view_entry( - category = 'linux UBSan', - short_name = 'vpt', - ), - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 4, - ), -) - -ci.fuzz_builder( - name = 'Win ASan Release', - builderless = False, - console_view_entry = ci.console_view_entry( - category = 'win asan', - short_name = 'rel', - ), - os = os.WINDOWS_DEFAULT, - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 7, - ), -) - -ci.fuzz_builder( - name = 'Win ASan Release Media', - builderless = False, - console_view_entry = ci.console_view_entry( - category = 'win asan', - short_name = 'med', - ), - os = os.WINDOWS_DEFAULT, - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 6, - ), -) - - -ci.fuzz_libfuzzer_builder( - name = 'Libfuzzer Upload Chrome OS ASan', - console_view_entry = ci.console_view_entry( - category = 'libfuzz', - short_name = 'chromeos-asan', - ), - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 3, - ), -) - -ci.fuzz_libfuzzer_builder( - name = 'Libfuzzer Upload Linux ASan', - console_view_entry = ci.console_view_entry( - category = 'libfuzz', - short_name = 'linux', - ), - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 5, - ), -) - -ci.fuzz_libfuzzer_builder( - name = 'Libfuzzer Upload Linux ASan Debug', - console_view_entry = ci.console_view_entry( - category = 'libfuzz', - short_name = 'linux-dbg', - ), - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 5, - ), -) - -ci.fuzz_libfuzzer_builder( - name = 'Libfuzzer Upload Linux MSan', - console_view_entry = ci.console_view_entry( - category = 'libfuzz', - short_name = 'linux-msan', - ), - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 5, - ), -) - -ci.fuzz_libfuzzer_builder( - name = 'Libfuzzer Upload Linux UBSan', - # Do not use builderless for this (crbug.com/980080). - builderless = False, - console_view_entry = ci.console_view_entry( - category = 'libfuzz', - short_name = 'linux-ubsan', - ), - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 5, - ), -) - -ci.fuzz_libfuzzer_builder( - name = 'Libfuzzer Upload Linux V8-ARM64 ASan', - console_view_entry = ci.console_view_entry( - category = 'libfuzz', - short_name = 'arm64', - ), - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 1, - ), -) - -ci.fuzz_libfuzzer_builder( - name = 'Libfuzzer Upload Linux V8-ARM64 ASan Debug', - console_view_entry = ci.console_view_entry( - category = 'libfuzz', - short_name = 'arm64-dbg', - ), - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 1, - ), -) - -ci.fuzz_libfuzzer_builder( - name = 'Libfuzzer Upload Linux32 ASan', - console_view_entry = ci.console_view_entry( - category = 'libfuzz', - short_name = 'linux32', - ), - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 3, - ), -) - -ci.fuzz_libfuzzer_builder( - name = 'Libfuzzer Upload Linux32 ASan Debug', - console_view_entry = ci.console_view_entry( - category = 'libfuzz', - short_name = 'linux32-dbg', - ), - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 3, - ), -) - -ci.fuzz_libfuzzer_builder( - name = 'Libfuzzer Upload Linux32 V8-ARM ASan', - console_view_entry = ci.console_view_entry( - category = 'libfuzz', - short_name = 'arm', - ), - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 1, - ), -) - -ci.fuzz_libfuzzer_builder( - name = 'Libfuzzer Upload Linux32 V8-ARM ASan Debug', - console_view_entry = ci.console_view_entry( - category = 'libfuzz', - short_name = 'arm-dbg', - ), - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 1, - ), -) - -ci.fuzz_libfuzzer_builder( - name = 'Libfuzzer Upload Mac ASan', - console_view_entry = ci.console_view_entry( - category = 'libfuzz', - short_name = 'mac-asan', - ), - cores = 24, - execution_timeout = 4 * time.hour, - os = os.MAC_DEFAULT, -) - -ci.fuzz_libfuzzer_builder( - name = 'Libfuzzer Upload Windows ASan', - console_view_entry = ci.console_view_entry( - category = 'libfuzz', - short_name = 'win-asan', - ), - os = os.WINDOWS_DEFAULT, - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 3, - ), + triggered_by = [builder_name('Dawn Win10 x86 DEPS Builder')], ) ci.fyi_builder( - name = 'Closure Compilation Linux', + name = 'VR Linux', console_view_entry = ci.console_view_entry( - category = 'closure_compilation', - ), - executable = 'recipe:closure_compilation', -) - -ci.fyi_builder( - name = 'Linux Viz', - console_view_entry = ci.console_view_entry( - category = 'viz', + category = 'linux', ), ) +# This is launching & collecting entirely isolated tests. +# OS shouldn't matter. ci.fyi_builder( - name = 'Linux remote_run Builder', + name = 'mac-osxbeta-rel', console_view_entry = ci.console_view_entry( - category = 'remote_run', + category = 'mac', + short_name = 'beta', ), + goma_backend = None, + triggered_by = [builder_name('Mac Builder')], ) -ci.fyi_builder( - name = 'Linux remote_run Tester', - console_view_entry = ci.console_view_entry( - category = 'remote_run', - ), - triggered_by = ['Linux remote_run Builder'], -) -ci.fyi_builder( - name = 'Mojo Android', +ci.fyi_ios_builder( + name = 'ios-simulator-cronet', console_view_entry = ci.console_view_entry( - category = 'mojo', - short_name = 'and', + category = 'cronet', ), -) - -ci.fyi_builder( - name = 'Mojo ChromiumOS', - console_view_entry = ci.console_view_entry( - category = 'mojo', - short_name = 'cr', - ), -) - -ci.fyi_builder( - name = 'Mojo Linux', - console_view_entry = ci.console_view_entry( - category = 'mojo', - short_name = 'lnx', - ), -) - -ci.fyi_builder( - name = 'Site Isolation Android', - console_view_entry = ci.console_view_entry( - category = 'site_isolation', - ), -) - -ci.fyi_builder( - name = 'android-mojo-webview-rel', - console_view_entry = ci.console_view_entry( - category = 'mojo', - short_name = 'aw', - ), -) - -ci.fyi_builder( - name = 'chromeos-amd64-generic-lacros-rel', - console_view_entry = ci.console_view_entry( - category = 'chromeos', - ), + executable = 'recipe:chromium', + notifies = ['cronet'], properties = { - # The format of these properties is defined at archive/properties.proto - '$build/archive' : { - 'archive_datas': [ - { - 'files': [ - 'chrome', - 'chrome_100_percent.pak', - 'chrome_200_percent.pak', - 'crashpad_handler', - 'headless_lib.pak', - 'icudtl.dat', - 'nacl_helper', - 'nacl_irt_x86_64.nexe', - 'resources.pak', - 'snapshot_blob.bin', - ], - 'dirs': ['locales', 'swiftshader'], - 'gcs_bucket': 'chromium-lacros-fishfood', - 'gcs_path': 'x86_64/{%position%}/lacros.zip', - 'archive_type': 'ARCHIVE_TYPE_ZIP', - }, - ], - }, + 'xcode_build_version': '11c29', }, ) -ci.fyi_builder( - name = 'chromeos-amd64-generic-rel-vm-tests', + +ci.fyi_windows_builder( + name = 'Win10 Tests x64 1803', console_view_entry = ci.console_view_entry( - category = 'chromeos', + category = 'win10|1803', + ), + goma_backend = None, + os = os.WINDOWS_10, + triggered_by = [builder_name('Win x64 Builder')], +) + + +ci.gpu_builder( + name = 'Android Release (Nexus 5X)', + console_view_entry = ci.console_view_entry( + category = 'Android', ), ) -ci.fyi_builder( - name = 'fuchsia-fyi-arm64-rel', +ci.gpu_builder( + name = 'GPU Linux Builder', + console_view_entry = ci.console_view_entry( + category = 'Linux', + ), +) + +ci.gpu_builder( + name = 'GPU Mac Builder', + console_view_entry = ci.console_view_entry( + category = 'Mac', + ), + cores = None, + os = os.MAC_ANY, +) + +ci.gpu_builder( + name = 'GPU Win x64 Builder', + builderless = True, + console_view_entry = ci.console_view_entry( + category = 'Windows', + ), + os = os.WINDOWS_ANY, +) + + +ci.gpu_thin_tester( + name = 'Linux Release (NVIDIA)', + console_view_entry = ci.console_view_entry( + category = 'Linux', + ), + triggered_by = [builder_name('GPU Linux Builder')], +) + +ci.gpu_thin_tester( + name = 'Mac Release (Intel)', + console_view_entry = ci.console_view_entry( + category = 'Mac', + ), + triggered_by = [builder_name('GPU Mac Builder')], +) + +ci.gpu_thin_tester( + name = 'Mac Retina Release (AMD)', + console_view_entry = ci.console_view_entry( + category = 'Mac', + ), + triggered_by = [builder_name('GPU Mac Builder')], +) + +ci.gpu_thin_tester( + name = 'Win10 x64 Release (NVIDIA)', + console_view_entry = ci.console_view_entry( + category = 'Windows', + ), + triggered_by = [builder_name('GPU Win x64 Builder')], +) + + +ci.linux_builder( + name = 'Cast Linux', + console_view_entry = ci.console_view_entry( + category = 'cast', + short_name = 'vid', + ), + goma_jobs = goma.jobs.J50, +) + +ci.linux_builder( + name = 'Fuchsia ARM64', console_view_entry = ci.console_view_entry( category = 'fuchsia|a64', short_name = 'rel', @@ -1702,17 +507,8 @@ notifies = ['cr-fuchsia'], ) -ci.fyi_builder( - name = 'fuchsia-fyi-x64-dbg', - console_view_entry = ci.console_view_entry( - category = 'fuchsia|x64', - short_name = 'dbg', - ), - notifies = ['cr-fuchsia'], -) - -ci.fyi_builder( - name = 'fuchsia-fyi-x64-rel', +ci.linux_builder( + name = 'Fuchsia x64', console_view_entry = ci.console_view_entry( category = 'fuchsia|x64', short_name = 'rel', @@ -1720,1619 +516,278 @@ notifies = ['cr-fuchsia'], ) -ci.fyi_builder( - name = 'linux-annotator-rel', +ci.linux_builder( + name = 'Linux Builder', console_view_entry = ci.console_view_entry( - category = 'network|traffic|annotations', - short_name = 'lnx', - ), -) - -ci.fyi_builder( - name = 'linux-bfcache-rel', - console_view_entry = ci.console_view_entry( - category = 'linux', - ), -) - -ci.fyi_builder( - name = 'linux-blink-animation-use-time-delta', - console_view_entry = ci.console_view_entry( - category = 'linux|blink', - short_name = 'TD', - ), -) - -ci.fyi_builder( - name = 'linux-blink-cors-rel', - console_view_entry = ci.console_view_entry( - category = 'linux', - ), -) - -ci.fyi_builder( - name = 'linux-blink-heap-concurrent-marking-tsan-rel', - console_view_entry = ci.console_view_entry( - category = 'linux|blink', - short_name = 'CM', - ), -) - -ci.fyi_builder( - name = 'linux-blink-heap-verification', - console_view_entry = ci.console_view_entry( - category = 'linux|blink', - short_name = 'VF', - ), -) - -ci.fyi_builder( - name = 'linux-chromium-tests-staging-builder', - console_view_entry = ci.console_view_entry( - category = 'recipe|staging|linux', + category = 'release', short_name = 'bld', ), ) -ci.fyi_builder( - name = 'linux-chromium-tests-staging-tests', +ci.linux_builder( + name = 'Linux Builder (dbg)', console_view_entry = ci.console_view_entry( - category = 'recipe|staging|linux', - short_name = 'tst', - ), - triggered_by = ['linux-chromium-tests-staging-builder'], -) - -ci.fyi_builder( - name = 'linux-fieldtrial-rel', - console_view_entry = ci.console_view_entry( - category = 'linux', - ), -) - -ci.fyi_builder( - name = 'linux-perfetto-rel', - console_view_entry = ci.console_view_entry( - category = 'linux', - ), -) - -ci.fyi_builder( - name = 'linux-wpt-fyi-rel', - console_view_entry = ci.console_view_entry( - category = 'linux', - ), - experimental = True, - goma_backend = None, -) - -ci.fyi_builder( - name = 'win-pixel-builder-rel', - console_view_entry = ci.console_view_entry( - category = 'win10', - ), - os = os.WINDOWS_10, -) - -ci.fyi_builder( - name = 'win-pixel-tester-rel', - console_view_entry = ci.console_view_entry( - category = 'win10', - ), - os = None, - triggered_by = ['win-pixel-builder-rel'], -) - -ci.fyi_builder( - name = 'linux-upload-perfetto', - console_view_entry = ci.console_view_entry( - category = 'perfetto', - short_name = 'lnx', - ), - os = os.LINUX_DEFAULT, -) - -ci.fyi_builder( - name = 'mac-upload-perfetto', - builderless = True, - console_view_entry = ci.console_view_entry( - category = 'perfetto', - short_name = 'mac', - ), - os = os.MAC_DEFAULT, - schedule = 'with 3h interval', - triggered_by = [], -) - -ci.fyi_builder( - name = 'win-upload-perfetto', - builderless = True, - console_view_entry = ci.console_view_entry( - category = 'perfetto', - short_name = 'win', - ), - os = os.WINDOWS_DEFAULT, - schedule = 'with 3h interval', - triggered_by = [], -) - -ci.fyi_celab_builder( - name = 'win-celab-builder-rel', - console_view_entry = ci.console_view_entry( - category = 'celab', - ), - schedule = '0 0,6,12,18 * * *', - triggered_by = [], -) - -ci.fyi_celab_builder( - name = 'win-celab-tester-rel', - console_view_entry = ci.console_view_entry( - category = 'celab', - ), - triggered_by = ['win-celab-builder-rel'], -) - - -ci.fyi_coverage_builder( - name = 'android-code-coverage', - console_view_entry = ci.console_view_entry( - category = 'code_coverage', - short_name = 'and', - ), - use_java_coverage = True, - schedule = 'triggered', - triggered_by = [], -) - -ci.fyi_coverage_builder( - name = 'android-code-coverage-native', - console_view_entry = ci.console_view_entry( - category = 'code_coverage', - short_name = 'ann', - ), - use_clang_coverage = True, -) - -ci.fyi_coverage_builder( - name = 'ios-simulator-code-coverage', - caches = [xcode_cache.x11c29], - console_view_entry = ci.console_view_entry( - category = 'code_coverage', - short_name = 'ios', - ), - cores = None, - os = os.MAC_ANY, - use_clang_coverage = True, - properties = { - 'coverage_exclude_sources': 'ios_test_files_and_test_utils', - 'coverage_test_types': ['overall', 'unit'], - 'xcode_build_version': '11c29', - }, -) - -ci.fyi_coverage_builder( - name = 'linux-chromeos-code-coverage', - console_view_entry = ci.console_view_entry( - category = 'code_coverage', - short_name = 'lcr', - ), - use_clang_coverage = True, - schedule = 'triggered', - triggered_by = [], -) - -ci.fyi_coverage_builder( - name = 'linux-code-coverage', - console_view_entry = ci.console_view_entry( - category = 'code_coverage', - short_name = 'lnx', - ), - use_clang_coverage = True, - triggered_by = [], -) - -ci.fyi_coverage_builder( - name = 'mac-code-coverage', - builderless = True, - console_view_entry = ci.console_view_entry( - category = 'code_coverage', - short_name = 'mac', - ), - cores = 24, - os = os.MAC_ANY, - use_clang_coverage = True, -) - -ci.fyi_coverage_builder( - name = 'win10-code-coverage', - builderless = True, - console_view_entry = ci.console_view_entry( - category = 'code_coverage', - short_name = 'win', - ), - os = os.WINDOWS_DEFAULT, - use_clang_coverage = True, -) - - -ci.fyi_ios_builder( - name = 'ios-simulator-cr-recipe', - console_view_entry = ci.console_view_entry( - category = 'iOS', - short_name = 'chr', - ), - executable = 'recipe:chromium', - properties = { - 'xcode_build_version': '11a1027', - }, -) - -ci.fyi_ios_builder( - name = 'ios-simulator-multi-window', - console_view_entry = ci.console_view_entry( - category = 'iOS', - short_name = 'mwd', - ), - executable = 'recipe:chromium', - properties = { - 'xcode_build_version': '11c29', - }, -) - -ci.fyi_ios_builder( - name = 'ios-webkit-tot', - caches = [xcode_cache.x11n605cwk], - console_view_entry = ci.console_view_entry( - category = 'iOS', - short_name = 'wk', - ), - executable = 'recipe:chromium', - properties = { - 'xcode_build_version': '11n605cwk' - }, - schedule = '0 1-23/6 * * *', - triggered_by = [], -) - -ci.fyi_ios_builder( - name = 'ios13-beta-simulator', - console_view_entry = ci.console_view_entry( - category = 'iOS|iOS13', - short_name = 'ios13', - ), - executable = 'recipe:chromium', - properties = { - 'xcode_build_version': '11c29', - }, -) - -ci.fyi_ios_builder( - name = 'ios13-sdk-device', - console_view_entry = ci.console_view_entry( - category = 'iOS|iOS13', - short_name = 'dev', - ), - executable = 'recipe:chromium', - properties = { - 'xcode_build_version': '11c29', - }, -) - -ci.fyi_ios_builder( - name = 'ios13-sdk-simulator', - console_view_entry = ci.console_view_entry( - category = 'iOS|iOS13', - short_name = 'sim', - ), - caches = [xcode_cache.x11e146], - executable = 'recipe:chromium', - os = os.MAC_10_15, - properties = { - 'xcode_build_version': '11e146' - } -) - - -ci.fyi_mac_builder( - name = 'Mac Builder Next', - console_view_entry = ci.console_view_entry( - category = 'mac', - short_name = 'bld', - ), - cores = None, - os = None, -) - -ci.thin_tester( - name = 'Mac10.15 Tests', - mastername = 'chromium.fyi', - console_view_entry = ci.console_view_entry( - category = 'mac', - short_name = '15', - ), - triggered_by = ['Mac Builder Next'], -) - -ci.fyi_mac_builder( - name = 'Mac deterministic', - console_view_entry = ci.console_view_entry( - category = 'deterministic|mac', - short_name = 'rel', - ), - cores = None, - executable = 'recipe:swarming/deterministic_build', - execution_timeout = 6 * time.hour, -) - -ci.fyi_mac_builder( - name = 'Mac deterministic (dbg)', - console_view_entry = ci.console_view_entry( - category = 'deterministic|mac', - short_name = 'dbg', - ), - cores = None, - executable = 'recipe:swarming/deterministic_build', - execution_timeout = 6 * time.hour, -) - -ci.fyi_mac_builder( - name = 'mac-hermetic-upgrade-rel', - console_view_entry = ci.console_view_entry( - category = 'mac', - short_name = 'herm', - ), - cores = 8, -) - -ci.fyi_mac_builder( - name = 'mac-mojo-rel', - console_view_entry = ci.console_view_entry( - category = 'mojo', - short_name = 'mac', - ), - os = os.MAC_ANY, -) - - -ci.fyi_windows_builder( - name = 'Win 10 Fast Ring', - console_view_entry = ci.console_view_entry( - category = 'win10', - ), - os = os.WINDOWS_10, -) - -ci.fyi_windows_builder( - name = 'win32-arm64-rel', - console_view_entry = ci.console_view_entry( - category = 'win32|arm64', - ), - cpu = cpu.X86, - goma_jobs = goma.jobs.J150, -) - -ci.fyi_windows_builder( - name = 'win-annotator-rel', - builderless = True, - console_view_entry = ci.console_view_entry( - category = 'network|traffic|annotations', - short_name = 'win', - ), - execution_timeout = 16 * time.hour, -) - -ci.fyi_windows_builder( - name = 'Mojo Windows', - console_view_entry = ci.console_view_entry( - category = 'mojo', - short_name = 'win', - ), -) - - -ci.gpu_builder( - name = 'GPU Linux Builder (dbg)', - console_view_entry = ci.console_view_entry( - category = 'Linux', - ), -) - -ci.gpu_builder( - name = 'GPU Mac Builder (dbg)', - console_view_entry = ci.console_view_entry( - category = 'Mac', - ), - cores = None, - os = os.MAC_ANY, -) - -ci.gpu_builder( - name = 'GPU Win x64 Builder (dbg)', - builderless = True, - console_view_entry = ci.console_view_entry( - category = 'Windows', - ), - os = os.WINDOWS_ANY, -) - - -ci.gpu_thin_tester( - name = 'Linux Debug (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'Linux', - ), - triggered_by = ['GPU Linux Builder (dbg)'], -) - -ci.gpu_thin_tester( - name = 'Mac Debug (Intel)', - console_view_entry = ci.console_view_entry( - category = 'Mac', - ), - triggered_by = ['GPU Mac Builder (dbg)'], -) - -ci.gpu_thin_tester( - name = 'Mac Retina Debug (AMD)', - console_view_entry = ci.console_view_entry( - category = 'Mac', - ), - triggered_by = ['GPU Mac Builder (dbg)'], -) - -ci.gpu_thin_tester( - name = 'Win10 x64 Debug (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'Windows', - ), - triggered_by = ['GPU Win x64 Builder (dbg)'], -) - - -ci.gpu_fyi_linux_builder( - name = 'Android FYI 32 Vk Release (Pixel 2)', - console_view_entry = ci.console_view_entry( - category = 'Android|vk|Q32', - short_name = 'P2', - ), -) - -ci.gpu_fyi_linux_builder( - name = 'Android FYI 32 dEQP Vk Release (Pixel 2)', - console_view_entry = ci.console_view_entry( - category = 'Android|dqp|vk|Q32', - short_name = 'P2', - ), -) - -ci.gpu_fyi_linux_builder( - name = 'Android FYI 64 Perf (Pixel 2)', - console_view_entry = ci.console_view_entry( - category = 'Android|Perf|Q64', - short_name = 'P2', - ), - cores = 2, - triggered_by = ['GPU FYI Perf Android 64 Builder'], -) - -ci.gpu_fyi_linux_builder( - name = 'Android FYI 64 Vk Release (Pixel 2)', - console_view_entry = ci.console_view_entry( - category = 'Android|vk|Q64', - short_name = 'P2', - ), -) - -ci.gpu_fyi_linux_builder( - name = 'Android FYI 64 dEQP Vk Release (Pixel 2)', - console_view_entry = ci.console_view_entry( - category = 'Android|dqp|vk|Q64', - short_name = 'P2', - ), -) - -ci.gpu_fyi_linux_builder( - name = 'Android FYI Release (NVIDIA Shield TV)', - console_view_entry = ci.console_view_entry( - category = 'Android|N64|NVDA', - short_name = 'STV', - ), -) - -ci.gpu_fyi_linux_builder( - name = 'Android FYI Release (Nexus 5)', - console_view_entry = ci.console_view_entry( - category = 'Android|L32', - short_name = 'N5', - ), -) - -ci.gpu_fyi_linux_builder( - name = 'Android FYI Release (Nexus 5X)', - console_view_entry = ci.console_view_entry( - category = 'Android|M64|QCOM', - short_name = 'N5X', - ), -) - -ci.gpu_fyi_linux_builder( - name = 'Android FYI Release (Nexus 6)', - console_view_entry = ci.console_view_entry( - category = 'Android|L32', - short_name = 'N6', - ), -) - -ci.gpu_fyi_linux_builder( - name = 'Android FYI Release (Nexus 6P)', - console_view_entry = ci.console_view_entry( - category = 'Android|M64|QCOM', - short_name = 'N6P', - ), -) - -ci.gpu_fyi_linux_builder( - name = 'Android FYI Release (Nexus 9)', - console_view_entry = ci.console_view_entry( - category = 'Android|M64|NVDA', - short_name = 'N9', - ), -) - -ci.gpu_fyi_linux_builder( - name = 'Android FYI Release (Pixel 2)', - console_view_entry = ci.console_view_entry( - category = 'Android|P32|QCOM', - short_name = 'P2', - ), -) - -ci.gpu_fyi_linux_builder( - name = 'Android FYI SkiaRenderer GL (Nexus 5X)', - console_view_entry = ci.console_view_entry( - category = 'Android|skgl|M64', - short_name = 'N5X', - ), -) - -ci.gpu_fyi_linux_builder( - name = 'Android FYI SkiaRenderer Vulkan (Pixel 2)', - console_view_entry = ci.console_view_entry( - category = 'Android|skv|P32', - short_name = 'P2', - ), -) - -ci.gpu_fyi_linux_builder( - name = 'Android FYI dEQP Release (Nexus 5X)', - console_view_entry = ci.console_view_entry( - category = 'Android|dqp|M64', - short_name = 'N5X', - ), -) - -ci.gpu_fyi_linux_builder( - name = 'ChromeOS FYI Release (amd64-generic)', - console_view_entry = ci.console_view_entry( - category = 'ChromeOS|amd64|generic', - short_name = 'x64' - ), -) - -ci.gpu_fyi_linux_builder( - name = 'ChromeOS FYI Release (kevin)', - console_view_entry = ci.console_view_entry( - category = 'ChromeOS|arm|kevin', - short_name = 'kvn' - ), -) - -ci.gpu_fyi_linux_builder( - name = 'GPU FYI Linux Builder', - console_view_entry = ci.console_view_entry( - category = 'Linux|Builder', - short_name = 'rel', - ), -) - -ci.gpu_fyi_linux_builder( - name = 'GPU FYI Linux Builder (dbg)', - console_view_entry = ci.console_view_entry( - category = 'Linux|Builder', - short_name = 'dbg', - ), -) - -ci.gpu_fyi_linux_builder( - name = 'GPU FYI Linux Ozone Builder', - console_view_entry = ci.console_view_entry( - category = 'Linux|Builder', - short_name = 'ozn', - ), -) - -ci.gpu_fyi_linux_builder( - name = 'GPU FYI Linux dEQP Builder', - console_view_entry = ci.console_view_entry( - category = 'Linux|Builder', - short_name = 'dqp', - ), -) - -ci.gpu_fyi_linux_builder( - name = 'GPU FYI Perf Android 64 Builder', - console_view_entry = ci.console_view_entry( - category = 'Android|Perf|Builder', + category = 'debug|builder', short_name = '64', ), ) -ci.gpu_fyi_linux_builder( - name = 'Linux FYI GPU TSAN Release', +ci.linux_builder( + name = 'Linux Tests', console_view_entry = ci.console_view_entry( - category = 'Linux', - short_name = 'tsn', + category = 'release', + short_name = 'tst', ), + goma_backend = None, + triggered_by = [builder_name('Linux Builder')], ) -# Builder + tester. -ci.gpu_fyi_linux_builder( - name = 'Linux FYI SkiaRenderer Dawn Release (Intel HD 630)', - console_view_entry = ci.console_view_entry( - category = 'Linux|Intel', - short_name = 'skd', - ), -) - - -ci.gpu_fyi_mac_builder( - name = 'Mac FYI GPU ASAN Release', - console_view_entry = ci.console_view_entry( - category = 'Mac', - short_name = 'asn', - ), -) - -ci.gpu_fyi_mac_builder( - name = 'GPU FYI Mac Builder', - console_view_entry = ci.console_view_entry( - category = 'Mac|Builder', - short_name = 'rel', - ), -) - -ci.gpu_fyi_mac_builder( - name = 'GPU FYI Mac Builder (dbg)', - console_view_entry = ci.console_view_entry( - category = 'Mac|Builder', - short_name = 'dbg', - ), -) - -ci.gpu_fyi_mac_builder( - name = 'GPU FYI Mac dEQP Builder', - console_view_entry = ci.console_view_entry( - category = 'Mac|Builder', - short_name = 'dqp', - ), -) - - -ci.gpu_fyi_thin_tester( - name = 'Linux FYI Debug (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'Linux|Nvidia', - short_name = 'dbg', - ), - triggered_by = ['GPU FYI Linux Builder (dbg)'], -) - -ci.gpu_fyi_thin_tester( - name = 'Linux FYI Experimental Release (Intel HD 630)', - console_view_entry = ci.console_view_entry( - category = 'Linux|Intel', - short_name = 'exp', - ), - triggered_by = ['GPU FYI Linux Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Linux FYI Experimental Release (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'Linux|Nvidia', - short_name = 'exp', - ), - triggered_by = ['GPU FYI Linux Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Linux FYI Ozone (Intel)', - console_view_entry = ci.console_view_entry( - category = 'Linux|Intel', - short_name = 'ozn', - ), - triggered_by = ['GPU FYI Linux Ozone Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Linux FYI Release (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'Linux|Nvidia', - short_name = 'rel', - ), - triggered_by = ['GPU FYI Linux Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Linux FYI Release (AMD R7 240)', - console_view_entry = ci.console_view_entry( - category = 'Linux|AMD', - short_name = 'rel', - ), - triggered_by = ['GPU FYI Linux Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Linux FYI Release (Intel HD 630)', - console_view_entry = ci.console_view_entry( - category = 'Linux|Intel', - short_name = 'rel', - ), - triggered_by = ['GPU FYI Linux Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Linux FYI Release (Intel UHD 630)', - console_view_entry = ci.console_view_entry( - category = 'Linux|Intel', - short_name = 'uhd', - ), - # TODO(https://crbug.com/986939): Remove this increased timeout once more - # devices are added. - execution_timeout = 18 * time.hour, - triggered_by = ['GPU FYI Linux Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Linux FYI SkiaRenderer Vulkan (Intel HD 630)', - console_view_entry = ci.console_view_entry( - category = 'Linux|Intel', - short_name = 'skv', - ), - triggered_by = ['GPU FYI Linux Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Linux FYI SkiaRenderer Vulkan (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'Linux|Nvidia', - short_name = 'skv', - ), - triggered_by = ['GPU FYI Linux Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Linux FYI dEQP Release (Intel HD 630)', - console_view_entry = ci.console_view_entry( - category = 'Linux|Intel', - short_name = 'dqp', - ), - triggered_by = ['GPU FYI Linux dEQP Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Linux FYI dEQP Release (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'Linux|Nvidia', - short_name = 'dqp', - ), - triggered_by = ['GPU FYI Linux dEQP Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Mac FYI Debug (Intel)', - console_view_entry = ci.console_view_entry( - category = 'Mac|Intel', - short_name = 'dbg', - ), - triggered_by = ['GPU FYI Mac Builder (dbg)'], -) - -ci.gpu_fyi_thin_tester( - name = 'Mac FYI Experimental Release (Intel)', - console_view_entry = ci.console_view_entry( - category = 'Mac|Intel', - short_name = 'exp', - ), - triggered_by = ['GPU FYI Mac Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Mac FYI Experimental Retina Release (AMD)', - console_view_entry = ci.console_view_entry( - category = 'Mac|AMD|Retina', - short_name = 'exp', - ), - triggered_by = ['GPU FYI Mac Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Mac FYI Experimental Retina Release (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'Mac|Nvidia', - short_name = 'exp', - ), - # This bot has one machine backing its tests at the moment. - # If it gets more, this can be removed. - # See crbug.com/853307 for more context. - execution_timeout = 12 * time.hour, - triggered_by = ['GPU FYI Mac Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Mac FYI Release (Intel)', - console_view_entry = ci.console_view_entry( - category = 'Mac|Intel', - short_name = 'rel', - ), - triggered_by = ['GPU FYI Mac Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Mac FYI Retina Debug (AMD)', - console_view_entry = ci.console_view_entry( - category = 'Mac|AMD|Retina', - short_name = 'dbg', - ), - triggered_by = ['GPU FYI Mac Builder (dbg)'], -) - -ci.gpu_fyi_thin_tester( - name = 'Mac FYI Retina Debug (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'Mac|Nvidia', - short_name = 'dbg', - ), - triggered_by = ['GPU FYI Mac Builder (dbg)'], -) - -ci.gpu_fyi_thin_tester( - name = 'Mac FYI Retina Release (AMD)', - console_view_entry = ci.console_view_entry( - category = 'Mac|AMD|Retina', - short_name = 'rel', - ), - triggered_by = ['GPU FYI Mac Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Mac FYI Retina Release (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'Mac|Nvidia', - short_name = 'rel', - ), - triggered_by = ['GPU FYI Mac Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Mac FYI dEQP Release AMD', - console_view_entry = ci.console_view_entry( - category = 'Mac|AMD', - short_name = 'dqp', - ), - triggered_by = ['GPU FYI Mac dEQP Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Mac FYI dEQP Release Intel', - console_view_entry = ci.console_view_entry( - category = 'Mac|Intel', - short_name = 'dqp', - ), - triggered_by = ['GPU FYI Mac dEQP Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Mac Pro FYI Release (AMD)', - console_view_entry = ci.console_view_entry( - category = 'Mac|AMD|Pro', - short_name = 'rel', - ), - triggered_by = ['GPU FYI Mac Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Win10 FYI x64 Debug (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'Windows|10|x64|Nvidia', - short_name = 'dbg', - ), - triggered_by = ['GPU FYI Win x64 Builder (dbg)'], -) - -ci.gpu_fyi_thin_tester( - name = 'Win10 FYI x64 DX12 Vulkan Debug (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'Windows|10|x64|Nvidia|dx12vk', - short_name = 'dbg', - ), - triggered_by = ['GPU FYI Win x64 DX12 Vulkan Builder (dbg)'], -) - -ci.gpu_fyi_thin_tester( - name = 'Win10 FYI x64 DX12 Vulkan Release (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'Windows|10|x64|Nvidia|dx12vk', - short_name = 'rel', - ), - triggered_by = ['GPU FYI Win x64 DX12 Vulkan Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Win10 FYI x64 Exp Release (Intel HD 630)', - console_view_entry = ci.console_view_entry( - category = 'Windows|10|x64|Intel', - short_name = 'exp', - ), - triggered_by = ['GPU FYI Win x64 Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Win10 FYI x64 Exp Release (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'Windows|10|x64|Nvidia', - short_name = 'exp', - ), - triggered_by = ['GPU FYI Win x64 Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Win10 FYI x64 Release (AMD RX 550)', - console_view_entry = ci.console_view_entry( - category = 'Windows|10|x64|AMD', - short_name = 'rel', - ), - triggered_by = ['GPU FYI Win x64 Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Win10 FYI x64 Release (Intel HD 630)', - console_view_entry = ci.console_view_entry( - category = 'Windows|10|x64|Intel', - short_name = 'rel', - ), - triggered_by = ['GPU FYI Win x64 Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Win10 FYI x64 Release (Intel UHD 630)', - console_view_entry = ci.console_view_entry( - category = 'Windows|10|x64|Intel', - short_name = 'uhd', - ), - # TODO(https://crbug.com/986939): Remove this increased timeout once - # more devices are added. - execution_timeout = 18 * time.hour, - triggered_by = ['GPU FYI Win x64 Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Win10 FYI x64 Release (NVIDIA GeForce GTX 1660)', - console_view_entry = ci.console_view_entry( - category = 'Windows|10|x64|Nvidia', - short_name = 'gtx', - ), - execution_timeout = 18 * time.hour, - triggered_by = ['GPU FYI Win x64 Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Win10 FYI x64 Release (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'Windows|10|x64|Nvidia', - short_name = 'rel', - ), - triggered_by = ['GPU FYI Win x64 Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Win10 FYI x64 Release XR Perf (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'Windows|10|x64|Nvidia', - short_name = 'xr', - ), - triggered_by = ['GPU FYI XR Win x64 Builder'], -) - -# Builder + tester. -ci.gpu_fyi_windows_builder( - name = 'Win10 FYI x64 SkiaRenderer Dawn Release (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'Windows|10|x64|Nvidia', - short_name = 'skd', - ), -) - -ci.gpu_fyi_thin_tester( - name = 'Win10 FYI x64 SkiaRenderer GL (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'Windows|10|x64|Nvidia', - short_name = 'skgl', - ), - triggered_by = ['GPU FYI Win x64 Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Win10 FYI x64 dEQP Release (Intel HD 630)', - console_view_entry = ci.console_view_entry( - category = 'Windows|10|x64|Intel', - short_name = 'dqp', - ), - triggered_by = ['GPU FYI Win x64 dEQP Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Win10 FYI x64 dEQP Release (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'Windows|10|x64|Nvidia', - short_name = 'dqp', - ), - triggered_by = ['GPU FYI Win x64 dEQP Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Win10 FYI x86 Release (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'Windows|10|x86|Nvidia', - short_name = 'rel', - ), - triggered_by = ['GPU FYI Win Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Win7 FYI Debug (AMD)', - console_view_entry = ci.console_view_entry( - category = 'Windows|7|x86|AMD', - short_name = 'dbg', - ), - triggered_by = ['GPU FYI Win Builder (dbg)'], -) - -ci.gpu_fyi_thin_tester( - name = 'Win7 FYI Release (AMD)', - console_view_entry = ci.console_view_entry( - category = 'Windows|7|x86|AMD', - short_name = 'rel', - ), - triggered_by = ['GPU FYI Win Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Win7 FYI Release (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'Windows|7|x86|Nvidia', - short_name = 'rel', - ), - triggered_by = ['GPU FYI Win Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Win7 FYI dEQP Release (AMD)', - console_view_entry = ci.console_view_entry( - category = 'Windows|7|x86|AMD', - short_name = 'dqp', - ), - triggered_by = ['GPU FYI Win dEQP Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Win7 FYI x64 Release (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'Windows|7|x64|Nvidia', - short_name = 'rel', - ), - triggered_by = ['GPU FYI Win x64 Builder'], -) - -ci.gpu_fyi_thin_tester( - name = 'Win7 FYI x64 dEQP Release (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'Windows|7|x64|Nvidia', - short_name = 'dqp', - ), - triggered_by = ['GPU FYI Win x64 dEQP Builder'], -) - - -ci.gpu_fyi_windows_builder( - name = 'GPU FYI Win Builder', - console_view_entry = ci.console_view_entry( - category = 'Windows|Builder|Release', - short_name = 'x86', - ), -) - -ci.gpu_fyi_windows_builder( - name = 'GPU FYI Win Builder (dbg)', - console_view_entry = ci.console_view_entry( - category = 'Windows|Builder|Debug', - short_name = 'x86', - ), -) - -ci.gpu_fyi_windows_builder( - name = 'GPU FYI Win dEQP Builder', - console_view_entry = ci.console_view_entry( - category = 'Windows|Builder|dEQP', - short_name = 'x86', - ), -) - -ci.gpu_fyi_windows_builder( - name = 'GPU FYI Win x64 Builder', - console_view_entry = ci.console_view_entry( - category = 'Windows|Builder|Release', - short_name = 'x64', - ), -) - -ci.gpu_fyi_windows_builder( - name = 'GPU FYI Win x64 Builder (dbg)', - console_view_entry = ci.console_view_entry( - category = 'Windows|Builder|Debug', - short_name = 'x64', - ), -) - -ci.gpu_fyi_windows_builder( - name = 'GPU FYI Win x64 dEQP Builder', - console_view_entry = ci.console_view_entry( - category = 'Windows|Builder|dEQP', - short_name = 'x64', - ), -) - -ci.gpu_fyi_windows_builder( - name = 'GPU FYI Win x64 DX12 Vulkan Builder', - console_view_entry = ci.console_view_entry( - category = 'Windows|Builder|dx12vk', - short_name = 'rel', - ), -) - -ci.gpu_fyi_windows_builder( - name = 'GPU FYI Win x64 DX12 Vulkan Builder (dbg)', - console_view_entry = ci.console_view_entry( - category = 'Windows|Builder|dx12vk', - short_name = 'dbg', - ), -) - -ci.gpu_fyi_windows_builder( - name = 'GPU FYI XR Win x64 Builder', - console_view_entry = ci.console_view_entry( - category = 'Windows|Builder|XR', - short_name = 'x64', - ), -) - - ci.linux_builder( - name = 'Cast Audio Linux', + name = 'Linux Tests (dbg)(1)', console_view_entry = ci.console_view_entry( - category = 'cast', - short_name = 'aud', + category = 'debug|tester', + short_name = '64', + ), + triggered_by = [builder_name('Linux Builder (dbg)')], +) + +ci.linux_builder( + name = 'fuchsia-arm64-cast', + console_view_entry = ci.console_view_entry( + category = 'fuchsia|cast', + short_name = 'a64', + ), + notifies = ['cr-fuchsia'], +) + +ci.linux_builder( + name = 'fuchsia-x64-cast', + console_view_entry = ci.console_view_entry( + category = 'fuchsia|cast', + short_name = 'x64', + ), + notifies = ['cr-fuchsia'], +) + +ci.linux_builder( + name = 'linux-ozone-rel', + console_view_entry = ci.console_view_entry( + category = 'release', + short_name = 'ozo', + ), +) + +ci.linux_builder( + name = 'Linux Ozone Tester (Headless)', + console_view = 'chromium.fyi', + console_view_entry = ci.console_view_entry( + category = 'linux', + short_name = 'loh', + ), + triggered_by = [builder_name('linux-ozone-rel')], +) + +ci.linux_builder( + name = 'Linux Ozone Tester (Wayland)', + console_view = 'chromium.fyi', + console_view_entry = ci.console_view_entry( + category = 'linux', + short_name = 'low', + ), + triggered_by = [builder_name('linux-ozone-rel')], +) + +ci.linux_builder( + name = 'Linux Ozone Tester (X11)', + console_view = 'chromium.fyi', + console_view_entry = ci.console_view_entry( + category = 'linux', + short_name = 'lox', + ), + triggered_by = [builder_name('linux-ozone-rel')], +) + + +ci.mac_builder( + name = 'Mac Builder', + console_view_entry = ci.console_view_entry( + category = 'release', + short_name = 'bld', + ), + os = os.MAC_10_14, +) + +ci.mac_builder( + name = 'Mac Builder (dbg)', + console_view_entry = ci.console_view_entry( + category = 'debug', + short_name = 'bld', + ), + os = os.MAC_ANY, +) + +ci.thin_tester( + name = 'Mac10.10 Tests', + mastername = 'chromium.mac', + console_view_entry = ci.console_view_entry( + category = 'release', + short_name = '10', + ), + triggered_by = [builder_name('Mac Builder')], +) + +ci.thin_tester( + name = 'Mac10.11 Tests', + mastername = 'chromium.mac', + console_view_entry = ci.console_view_entry( + category = 'release', + short_name = '11', + ), + triggered_by = [builder_name('Mac Builder')], +) + +ci.thin_tester( + name = 'Mac10.12 Tests', + mastername = 'chromium.mac', + console_view_entry = ci.console_view_entry( + category = 'release', + short_name = '12', + ), + triggered_by = [builder_name('Mac Builder')], +) + +ci.thin_tester( + name = 'Mac10.13 Tests', + mastername = 'chromium.mac', + console_view_entry = ci.console_view_entry( + category = 'release', + short_name = '13', + ), + triggered_by = [builder_name('Mac Builder')], +) + +ci.thin_tester( + name = 'Mac10.14 Tests', + mastername = 'chromium.mac', + console_view_entry = ci.console_view_entry( + category = 'release', + short_name = '14', + ), + triggered_by = [builder_name('Mac Builder')], +) + +ci.thin_tester( + name = 'Mac10.13 Tests (dbg)', + mastername = 'chromium.mac', + console_view_entry = ci.console_view_entry( + category = 'debug', + short_name = '13', + ), + triggered_by = [builder_name('Mac Builder (dbg)')], +) + +ci.thin_tester( + name = 'WebKit Mac10.13 (retina)', + mastername = 'chromium.mac', + console_view_entry = ci.console_view_entry( + category = 'release', + short_name = 'ret', + ), + triggered_by = [builder_name('Mac Builder')], +) + + +ci.mac_ios_builder( + name = 'ios-simulator', + console_view_entry = ci.console_view_entry( + category = 'ios|default', + short_name = 'sim', + ), + executable = 'recipe:chromium', + properties = { + 'xcode_build_version': '11c29', + }, +) + +ci.mac_ios_builder( + name = 'ios-simulator-full-configs', + console_view_entry = ci.console_view_entry( + category = 'ios|default', + short_name = 'ful', + ), + executable = 'recipe:chromium', +) + + +ci.memory_builder( + name = 'Linux ASan LSan Builder', + console_view_entry = ci.console_view_entry( + category = 'linux|asan lsan', + short_name = 'bld', ), ssd = True, ) -ci.linux_builder( - name = 'Deterministic Fuchsia (dbg)', - console_view_entry = ci.console_view_entry( - category = 'fuchsia|x64', - short_name = 'det', - ), - executable = 'recipe:swarming/deterministic_build', - execution_timeout = 6 * time.hour, - goma_jobs = None, -) - -ci.linux_builder( - name = 'Deterministic Linux', - console_view_entry = ci.console_view_entry( - category = 'release', - short_name = 'det', - ), - executable = 'recipe:swarming/deterministic_build', - execution_timeout = 6 * time.hour, -) - -ci.linux_builder( - name = 'Deterministic Linux (dbg)', - console_view_entry = ci.console_view_entry( - category = 'debug|builder', - short_name = 'det', - ), - cores = 32, - executable = 'recipe:swarming/deterministic_build', - execution_timeout = 6 * time.hour, -) - -ci.linux_builder( - name = 'Leak Detection Linux', - console_view = 'chromium.fyi', - console_view_entry = ci.console_view_entry( - category = 'linux', - short_name = 'lk', - ), -) - -ci.linux_builder( - name = 'Linux Builder (dbg)(32)', - console_view_entry = ci.console_view_entry( - category = 'debug|builder', - short_name = '32', - ), -) - -ci.linux_builder( - name = 'Network Service Linux', - console_view_entry = ci.console_view_entry( - category = 'release', - short_name = 'nsl', - ), -) - -ci.linux_builder( - name = 'fuchsia-x64-dbg', - console_view_entry = ci.console_view_entry( - category = 'fuchsia|x64', - short_name = 'dbg', - ), - notifies = ['cr-fuchsia'], -) - -ci.linux_builder( - name = 'linux-gcc-rel', - console_view_entry = ci.console_view_entry( - category = 'release', - short_name = 'gcc', - ), - goma_backend = None, -) - -ci.linux_builder( - name = 'linux-trusty-rel', - console_view_entry = ci.console_view_entry( - category = 'release', - short_name = 'tru', - ), - os = os.LINUX_TRUSTY, -) - -ci.linux_builder( - name = 'linux_chromium_component_updater', - executable = 'recipe:findit/chromium/update_components', - schedule = '0 0,6,12,18 * * *', - service_account = 'component-mapping-updater@chops-service-accounts.iam.gserviceaccount.com', - triggered_by = [], -) - - -ci.mac_ios_builder( - name = 'ios-device', - console_view_entry = ci.console_view_entry( - category = 'ios|default', - short_name = 'dev', - ), - executable = 'recipe:chromium', - # We don't have necessary capacity to run this configuration in CQ, but it - # is part of the main waterfall - main_console_view = 'main', -) - -ci.mac_ios_builder( - name = 'ios-simulator-noncq', - console_view_entry = ci.console_view_entry( - category = 'ios|default', - short_name = 'non', - ), - # We don't have necessary capacity to run this configuration in CQ, but it - # is part of the main waterfall - main_console_view = 'main', -) - - ci.memory_builder( - name = 'Android CFI', - # TODO(https://crbug.com/1008094) When this builder is not consistently - # failing, remove the console_view value - console_view = 'chromium.android.fyi', + name = 'Linux ASan LSan Tests (1)', console_view_entry = ci.console_view_entry( - category = 'memory', - short_name = 'cfi', - ), - cores = 32, - # TODO(https://crbug.com/919430) Remove the larger timeout once compile - # times have been brought down to reasonable level - execution_timeout = time.hour * 9 / 2, # 4.5 (can't multiply float * duration) -) - -ci.memory_builder( - name = 'Linux CFI', - console_view_entry = ci.console_view_entry( - category = 'cfi', - short_name = 'lnx', - ), - cores = 32, - # TODO(thakis): Remove once https://crbug.com/927738 is resolved. - execution_timeout = 4 * time.hour, - goma_jobs = goma.jobs.MANY_JOBS_FOR_CI, -) - -ci.memory_builder( - name = 'Linux Chromium OS ASan LSan Builder', - console_view_entry = ci.console_view_entry( - category = 'cros|asan', - short_name = 'bld', - ), - # TODO(crbug.com/1030593): Builds take more than 3 hours sometimes. Remove - # once the builds are faster. - execution_timeout = 6 * time.hour, -) - -ci.memory_builder( - name = 'Linux Chromium OS ASan LSan Tests (1)', - console_view_entry = ci.console_view_entry( - category = 'cros|asan', + category = 'linux|asan lsan', short_name = 'tst', ), - triggered_by = ['Linux Chromium OS ASan LSan Builder'], + triggered_by = [builder_name('Linux ASan LSan Builder')], ) ci.memory_builder( - name = 'Linux ChromiumOS MSan Builder', + name = 'Linux ASan Tests (sandboxed)', console_view_entry = ci.console_view_entry( - category = 'cros|msan', + category = 'linux|asan lsan', + short_name = 'sbx', + ), + triggered_by = [builder_name('Linux ASan LSan Builder')], +) + +ci.memory_builder( + name = 'Linux TSan Builder', + console_view_entry = ci.console_view_entry( + category = 'linux|TSan v2', short_name = 'bld', ), ) ci.memory_builder( - name = 'Linux ChromiumOS MSan Tests', + name = 'Linux TSan Tests', console_view_entry = ci.console_view_entry( - category = 'cros|msan', + category = 'linux|TSan v2', short_name = 'tst', ), - triggered_by = ['Linux ChromiumOS MSan Builder'], -) - -ci.memory_builder( - name = 'Linux MSan Builder', - console_view_entry = ci.console_view_entry( - category = 'linux|msan', - short_name = 'bld', - ), - goma_jobs = goma.jobs.MANY_JOBS_FOR_CI, -) - -ci.memory_builder( - name = 'Linux MSan Tests', - console_view_entry = ci.console_view_entry( - category = 'linux|msan', - short_name = 'tst', - ), - triggered_by = ['Linux MSan Builder'], -) - -ci.memory_builder( - name = 'Mac ASan 64 Builder', - builderless = False, - console_view_entry = ci.console_view_entry( - category = 'mac', - short_name = 'bld', - ), - goma_debug = True, # TODO(hinoka): Remove this after debugging. - goma_jobs = None, - cores = None, # Swapping between 8 and 24 - os = os.MAC_DEFAULT, - triggering_policy = scheduler.greedy_batching( - max_concurrent_invocations = 2, - ), -) - -ci.memory_builder( - name = 'Mac ASan 64 Tests (1)', - builderless = False, - console_view_entry = ci.console_view_entry( - category = 'mac', - short_name = 'tst', - ), - os = os.MAC_DEFAULT, - triggered_by = ['Mac ASan 64 Builder'], -) - -ci.memory_builder( - name = 'WebKit Linux ASAN', - console_view_entry = ci.console_view_entry( - category = 'linux|webkit', - short_name = 'asn', - ), -) - -ci.memory_builder( - name = 'WebKit Linux Leak', - console_view_entry = ci.console_view_entry( - category = 'linux|webkit', - short_name = 'lk', - ), -) - -ci.memory_builder( - name = 'WebKit Linux MSAN', - console_view_entry = ci.console_view_entry( - category = 'linux|webkit', - short_name = 'msn', - ), -) - -ci.memory_builder( - name = 'android-asan', - console_view_entry = ci.console_view_entry( - category = 'android', - short_name = 'asn', - ), -) - -ci.memory_builder( - name = 'win-asan', - console_view_entry = ci.console_view_entry( - category = 'win', - short_name = 'asn', - ), - cores = 32, - builderless = True, - os = os.WINDOWS_DEFAULT, -) - - -ci.swangle_linux_builder( - name = 'linux-swangle-chromium-x64', - console_view_entry = ci.console_view_entry( - category = 'Chromium|Linux', - short_name = 'x64', - ), -) - -ci.swangle_linux_builder( - name = 'linux-swangle-tot-angle-x64', - console_view_entry = ci.console_view_entry( - category = 'ToT ANGLE|Linux', - short_name = 'x64', - ), -) - -ci.swangle_linux_builder( - name = 'linux-swangle-tot-angle-x86', - console_view_entry = ci.console_view_entry( - category = 'ToT ANGLE|Linux', - short_name = 'x86', - ), -) - -ci.swangle_linux_builder( - name = 'linux-swangle-tot-swiftshader-x64', - console_view_entry = ci.console_view_entry( - category = 'ToT SwiftShader|Linux', - short_name = 'x64', - ), -) - -ci.swangle_linux_builder( - name = 'linux-swangle-tot-swiftshader-x86', - console_view_entry = ci.console_view_entry( - category = 'ToT SwiftShader|Linux', - short_name = 'x86', - ), -) - -ci.swangle_linux_builder( - name = 'linux-swangle-x64', - console_view_entry = ci.console_view_entry( - category = 'DEPS|Linux', - short_name = 'x64', - ), -) - -ci.swangle_linux_builder( - name = 'linux-swangle-x86', - console_view_entry = ci.console_view_entry( - category = 'DEPS|Linux', - short_name = 'x86', - ), -) - - -ci.swangle_mac_builder( - name = 'mac-swangle-chromium-x64', - console_view_entry = ci.console_view_entry( - category = 'Chromium|Mac', - short_name = 'x64', - ), -) - - -ci.swangle_windows_builder( - name = 'win-swangle-chromium-x86', - console_view_entry = ci.console_view_entry( - category = 'Chromium|Windows', - short_name = 'x86', - ), -) - -ci.swangle_windows_builder( - name = 'win-swangle-tot-angle-x64', - console_view_entry = ci.console_view_entry( - category = 'ToT ANGLE|Windows', - short_name = 'x64', - ), -) - -ci.swangle_windows_builder( - name = 'win-swangle-tot-angle-x86', - console_view_entry = ci.console_view_entry( - category = 'ToT ANGLE|Windows', - short_name = 'x86', - ), -) - -ci.swangle_windows_builder( - name = 'win-swangle-tot-swiftshader-x64', - console_view_entry = ci.console_view_entry( - category = 'ToT SwiftShader|Windows', - short_name = 'x64', - ), -) - -ci.swangle_windows_builder( - name = 'win-swangle-tot-swiftshader-x86', - console_view_entry = ci.console_view_entry( - category = 'ToT SwiftShader|Windows', - short_name = 'x86', - ), -) - -ci.swangle_windows_builder( - name = 'win-swangle-x64', - console_view_entry = ci.console_view_entry( - category = 'DEPS|Windows', - short_name = 'x64', - ), -) - -ci.swangle_windows_builder( - name = 'win-swangle-x86', - console_view_entry = ci.console_view_entry( - category = 'DEPS|Windows', - short_name = 'x86', - ), + triggered_by = [builder_name('Linux TSan Builder')], ) ci.win_builder( - name = 'WebKit Win10', + name = 'Win7 Tests (dbg)(1)', console_view_entry = ci.console_view_entry( - category = 'misc', - short_name = 'wbk', + category = 'debug|tester', + short_name = '7', ), - triggered_by = ['Win Builder'], + os = os.WINDOWS_7, + triggered_by = [builder_name('Win Builder (dbg)')], ) ci.win_builder( - name = 'Win Builder', + name = 'Win 7 Tests x64 (1)', console_view_entry = ci.console_view_entry( - category = 'release|builder', + category = 'release|tester', + short_name = '64', + ), + os = os.WINDOWS_7, + triggered_by = [builder_name('Win x64 Builder')], +) + +ci.win_builder( + name = 'Win Builder (dbg)', + console_view_entry = ci.console_view_entry( + category = 'debug|builder', short_name = '32', ), cores = 32, @@ -3340,51 +795,20 @@ ) ci.win_builder( - name = 'Win x64 Builder (dbg)', + name = 'Win x64 Builder', console_view_entry = ci.console_view_entry( - category = 'debug|builder', + category = 'release|builder', short_name = '64', ), cores = 32, - builderless = True, os = os.WINDOWS_ANY, ) ci.win_builder( - name = 'Win10 Tests x64 (dbg)', - console_view_entry = ci.console_view_entry( - category = 'debug|tester', - short_name = '10', - ), - triggered_by = ['Win x64 Builder (dbg)'], -) - -ci.win_builder( - name = 'Win7 (32) Tests', + name = 'Win10 Tests x64', console_view_entry = ci.console_view_entry( category = 'release|tester', - short_name = '32', + short_name = 'w10', ), - os = os.WINDOWS_7, - triggered_by = ['Win Builder'], -) - -ci.win_builder( - name = 'Win7 Tests (1)', - console_view_entry = ci.console_view_entry( - category = 'release|tester', - short_name = '32', - ), - os = os.WINDOWS_7, - triggered_by = ['Win Builder'], -) - -ci.win_builder( - name = 'Windows deterministic', - console_view_entry = ci.console_view_entry( - category = 'misc', - short_name = 'det', - ), - executable = 'recipe:swarming/deterministic_build', - execution_timeout = 6 * time.hour, + triggered_by = [builder_name('Win x64 Builder')], )
diff --git a/infra/config/subprojects/chromium/main.star b/infra/config/subprojects/chromium/main.star index c0cff46..d330c7b 100644 --- a/infra/config/subprojects/chromium/main.star +++ b/infra/config/subprojects/chromium/main.star
@@ -1,7 +1,4 @@ exec('./ci.star') -exec('./gpu.try.star') -exec('./swangle.try.star') exec('./try.star') -exec('./consoles/android.packager.star') -exec('./consoles/luci.chromium.try.star') -exec('./consoles/sheriff.ios.star') + +exec('./master-only/main.star')
diff --git a/infra/config/subprojects/chromium/master-only/README.md b/infra/config/subprojects/chromium/master-only/README.md new file mode 100644 index 0000000..d44be8e7 --- /dev/null +++ b/infra/config/subprojects/chromium/master-only/README.md
@@ -0,0 +1,12 @@ +Definitions of LUCI entities that only exist for the master branch. + +* **consoles** + * manually curated consoles for chromium subproject builders +* **ci.star** + * builders that do post-submit testing against the master branch + * when new milestones are created, milestone-specific versions of the builders + will not be created +* **try.star**, **gpu.try.star**, **swangle.try.star** + * builders that do pre-submit testing against the master branch + * when new milestones are created, milestone-specific versions of the builders + will not be created
diff --git a/infra/config/subprojects/chromium/master-only/ci.star b/infra/config/subprojects/chromium/master-only/ci.star new file mode 100644 index 0000000..7ed76cf --- /dev/null +++ b/infra/config/subprojects/chromium/master-only/ci.star
@@ -0,0 +1,3389 @@ +load('//lib/builders.star', 'cpu', 'goma', 'os', 'xcode_cache') +load('//lib/ci.star', 'ci') +load('//project.star', 'settings') + +# Execute the versioned files to define all of the per-branch entities +# (bucket, builders, console, poller, etc.) +exec('../versioned/m81/buckets/ci.star') +exec('../versioned/m83/buckets/ci.star') + + +ci.set_defaults( + settings, + add_to_console_view = True, +) + + +# *** After this point everything is trunk only *** +ci.console_view( + name = 'chromium', + include_experimental_builds = True, + ordering = {}, +) + +ci.console_view( + name = 'chromium.android', + ordering = { + None: ['cronet', 'builder', 'tester'], + '*cpu*': ['arm', 'arm64', 'x86'], + 'cronet': '*cpu*', + 'builder': '*cpu*', + 'builder|det': ci.ordering(short_names=['rel', 'dbg']), + 'tester': ['phone', 'tablet'], + 'builder_tester|arm64': ci.ordering(short_names=['M proguard']), + }, +) + +ci.console_view( + name = 'chromium.android.fyi', + ordering = { + None: ['android', 'memory', 'weblayer', 'webview'], + }, +) + +ci.console_view( + name = 'chromium.chromiumos', + ordering = { + None: ['default'], + 'default': ci.ordering(short_names=['ful', 'rel']), + 'simple': ['release', 'debug'], + }, +) + +ci.console_view( + name = 'chromium.clang', + ordering = { + None: [ + 'ToT Linux', + 'ToT Android', + 'ToT Mac', + 'ToT Windows', + 'ToT Code Coverage', + ], + 'ToT Linux': ci.ordering( + short_names=['rel', 'ofi', 'dbg', 'asn', 'fuz', 'msn', 'tsn'], + ), + 'ToT Android': ci.ordering(short_names=['rel', 'dbg', 'x64']), + 'ToT Mac': ci.ordering(short_names=['rel', 'ofi', 'dbg']), + 'ToT Windows': ci.ordering( + short_names=['rel', 'ofi'], + categories=['x64'], + ), + 'ToT Windows|x64': ci.ordering(short_names=['rel']), + 'CFI|Win': ci.ordering(short_names=['x86', 'x64']), + 'iOS': ['public'], + 'iOS|public': ci.ordering(short_names=['sim', 'dev']), + }, + entries = [ + luci.console_view_entry( + builder = 'chrome:ci/ToTLinuxOfficial', + category = 'ToT Linux', + short_name = 'ofi', + ), + luci.console_view_entry( + builder = 'chrome:ci/ToTMacOfficial', + category = 'ToT Mac', + short_name = 'ofi', + ), + luci.console_view_entry( + builder = 'chrome:ci/ToTWin', + category = 'ToT Windows', + short_name = 'rel', + ), + luci.console_view_entry( + builder = 'chrome:ci/ToTWin64', + category = 'ToT Windows|x64', + short_name = 'rel', + ), + luci.console_view_entry( + builder = 'chrome:ci/ToTWinOfficial', + category = 'ToT Windows', + short_name = 'ofi', + ), + luci.console_view_entry( + builder = 'chrome:ci/ToTWinThinLTO64', + category = 'ToT Windows|x64', + short_name = 'lto', + ), + luci.console_view_entry( + builder = 'chrome:ci/clang-tot-device', + category = 'iOS|internal', + short_name = 'dev', + ), + ], +) + +ci.console_view( + name = 'chromium.dawn', + ordering = { + None: ['ToT'], + '*builder*': ['Builder'], + '*cpu*': ci.ordering(short_names=['x86']), + 'ToT|Mac': '*builder*', + 'ToT|Windows|Builder': '*cpu*', + 'ToT|Windows|Intel': '*cpu*', + 'ToT|Windows|Nvidia': '*cpu*', + 'DEPS|Mac': '*builder*', + 'DEPS|Windows|Builder': '*cpu*', + 'DEPS|Windows|Intel': '*cpu*', + 'DEPS|Windows|Nvidia': '*cpu*', + }, +) + +ci.console_view( + name = 'chromium.fyi', + ordering = { + None: [ + 'closure_compilation', + 'code_coverage', + 'cronet', + 'mac', + 'deterministic', + 'fuchsia', + 'chromeos', + 'iOS', + 'linux', + 'mojo', + 'recipe', + 'remote_run', + 'site_isolation', + 'network', + 'viz', + 'win10', + 'win32', + ], + 'code_coverage': ci.ordering( + short_names=['and', 'ann', 'lnx', 'lcr', 'mac'] + ), + 'mac': ci.ordering(short_names=['bld', '15', 'herm']), + 'deterministic|mac': ci.ordering(short_names=['rel', 'dbg']), + 'iOS|iOS13': ci.ordering(short_names=['dev', 'sim']), + 'linux|blink': ci.ordering(short_names=['TD']), + }, +) + +ci.console_view( + name ='chromium.fuzz', + ordering = { + None: [ + 'afl', + 'win asan', + 'mac asan', + 'cros asan', + 'linux asan', + 'libfuzz', + 'linux msan', + 'linux tsan', + ], + '*config*': ci.ordering(short_names=['dbg', 'rel']), + 'win asan': '*config*', + 'mac asan': '*config*', + 'linux asan': '*config*', + 'linux asan|x64 v8-ARM': '*config*', + 'libfuzz': ci.ordering(short_names=[ + 'chromeos-asan', + 'linux32', + 'linux32-dbg', + 'linux', + 'linux-dbg', + 'linux-msan', + 'linux-ubsan', + 'mac-asan', + 'win-asan', + ]), + }, +) + +ci.console_view( + name = 'chromium.gpu', + ordering = { + None: ['Windows', 'Mac', 'Linux'], + }, +) + +ci.console_view( + name = 'chromium.gpu.fyi', + ordering = { + None: ['Windows', 'Mac', 'Linux'], + '*builder*': ['Builder'], + '*type*': ci.ordering(short_names=['rel', 'dbg', 'exp']), + '*cpu*': ci.ordering(short_names=['x86']), + 'Windows': '*builder*', + 'Windows|Builder': ['Release', 'dEQP', 'dx12vk', 'Debug'], + 'Windows|Builder|Release': '*cpu*', + 'Windows|Builder|dEQP': '*cpu*', + 'Windows|Builder|dx12vk': '*type*', + 'Windows|Builder|Debug': '*cpu*', + 'Windows|10|x64|Intel': '*type*', + 'Windows|10|x64|Nvidia': '*type*', + 'Windows|10|x86|Nvidia': '*type*', + 'Windows|7|x64|Nvidia': '*type*', + 'Mac': '*builder*', + 'Mac|Builder': '*type*', + 'Mac|AMD|Retina': '*type*', + 'Mac|Intel': '*type*', + 'Mac|Nvidia': '*type*', + 'Linux': '*builder*', + 'Linux|Builder': '*type*', + 'Linux|Intel': '*type*', + 'Linux|Nvidia': '*type*', + 'Android': ['L32', 'M64', 'N64', 'P32', 'vk', 'dqp', 'skgl', 'skv'], + 'Android|M64': ['QCOM'], + }, +) + +ci.console_view( + name = 'chromium.linux', + ordering = { + None: ['release', 'debug'], + 'release': ci.ordering(short_names=['bld', 'tst', 'nsl', 'gcc']), + 'cast': ci.ordering(short_names=['vid', 'aud']), + }, +) + +ci.console_view( + name = 'chromium.mac', + ordering = { + None: ['release'], + 'release': ci.ordering(short_names=['bld']), + 'debug': ci.ordering(short_names=['bld']), + 'ios|default': ci.ordering(short_names=['dev', 'sim']), + }, +) + +ci.console_view( + name = 'chromium.memory', + ordering = { + None: ['win', 'mac', 'linux', 'cros'], + '*build-or-test*': ci.ordering(short_names=['bld', 'tst']), + 'linux|TSan v2': '*build-or-test*', + 'linux|asan lsan': '*build-or-test*', + 'linux|webkit': ci.ordering(short_names=['asn', 'msn']), + }, +) + +ci.console_view( + name = 'chromium.swangle', + ordering = { + None: ['DEPS', 'ToT ANGLE', 'ToT SwiftShader'], + '*os*': ['Windows', 'Mac'], + '*cpu*': ci.ordering(short_names=['x86', 'x64']), + 'DEPS': '*os*', + 'DEPS|Windows': '*cpu*', + 'DEPS|Linux': '*cpu*', + 'ToT ANGLE': '*os*', + 'ToT ANGLE|Windows': '*cpu*', + 'ToT ANGLE|Linux': '*cpu*', + 'ToT SwiftShader': '*os*', + 'ToT SwiftShader|Windows': '*cpu*', + 'ToT SwiftShader|Linux': '*cpu*', + 'Chromium': '*os*', + }, +) + +ci.console_view( + name = 'chromium.win', + ordering = { + None: ['release', 'debug'], + 'debug|builder': ci.ordering(short_names=['64', '32']), + 'debug|tester': ci.ordering(short_names=['7', '10']), + }, +) + +# The main console includes some entries for builders from the chrome project +[luci.console_view_entry( + builder = 'chrome:ci/{}'.format(name), + console_view = 'main', + category = 'chrome', + short_name = short_name, +) for name, short_name in ( + ('linux-chromeos-chrome', 'cro'), + ('linux-chrome', 'lnx'), + ('mac-chrome', 'mac'), + ('win-chrome', 'win'), + ('win64-chrome', 'win'), +)] + + +# Builders are sorted first lexicographically by the function used to define +# them, then lexicographically by their name + + +ci.builder( + name = 'android-avd-packager', + executable = 'recipe:android/avd_packager', + properties = { + 'avd_configs': [ + 'tools/android/avd/proto/creation/generic_android23.textpb', + 'tools/android/avd/proto/creation/generic_android28.textpb', + 'tools/android/avd/proto/creation/generic_playstore_android28.textpb', + ], + }, + schedule = '0 7 * * 0 *', + service_account = 'chromium-cipd-builder@chops-service-accounts.iam.gserviceaccount.com', + triggered_by = [], +) + +ci.builder( + name = 'android-sdk-packager', + executable = 'recipe:android/sdk_packager', + schedule = '0 7 * * 0 *', + service_account = 'chromium-cipd-builder@chops-service-accounts.iam.gserviceaccount.com', + triggered_by = [], + properties = { + # We still package part of build-tools;25.0.2 to support + # http://bit.ly/2KNUygZ + 'packages': [ + { + 'sdk_package_name': 'build-tools;25.0.2', + 'cipd_yaml': 'third_party/android_sdk/cipd/build-tools/25.0.2.yaml' + }, + { + 'sdk_package_name': 'build-tools;27.0.3', + 'cipd_yaml': 'third_party/android_sdk/cipd/build-tools/27.0.3.yaml' + }, + { + 'sdk_package_name': 'build-tools;29.0.2', + 'cipd_yaml': 'third_party/android_sdk/cipd/build-tools/29.0.2.yaml' + }, + { + 'sdk_package_name': 'emulator', + 'cipd_yaml': 'third_party/android_sdk/cipd/emulator.yaml' + }, + { + 'sdk_package_name': 'extras;google;gcm', + 'cipd_yaml': 'third_party/android_sdk/cipd/extras/google/gcm.yaml' + }, + { + 'sdk_package_name': 'patcher;v4', + 'cipd_yaml': 'third_party/android_sdk/cipd/patcher/v4.yaml' + }, + { + 'sdk_package_name': 'platforms;android-23', + 'cipd_yaml': 'third_party/android_sdk/cipd/platforms/android-23.yaml' + }, + { + 'sdk_package_name': 'platforms;android-28', + 'cipd_yaml': 'third_party/android_sdk/cipd/platforms/android-28.yaml' + }, + { + 'sdk_package_name': 'platforms;android-29', + 'cipd_yaml': 'third_party/android_sdk/cipd/platforms/android-29.yaml' + }, + { + 'sdk_package_name': 'platform-tools', + 'cipd_yaml': 'third_party/android_sdk/cipd/platform-tools.yaml' + }, + { + 'sdk_package_name': 'sources;android-28', + 'cipd_yaml': 'third_party/android_sdk/cipd/sources/android-28.yaml' + }, + { + 'sdk_package_name': 'sources;android-29', + 'cipd_yaml': 'third_party/android_sdk/cipd/sources/android-29.yaml' + }, + { + 'sdk_package_name': 'system-images;android-23;google_apis;x86', + 'cipd_yaml': 'third_party/android_sdk/cipd/system_images/android-23/google_apis/x86.yaml' + }, + { + 'sdk_package_name': 'system-images;android-28;google_apis;x86', + 'cipd_yaml': 'third_party/android_sdk/cipd/system_images/android-28/google_apis/x86.yaml' + }, + { + 'sdk_package_name': 'system-images;android-28;google_apis_playstore;x86', + 'cipd_yaml': 'third_party/android_sdk/cipd/system_images/android-28/google_apis_playstore/x86.yaml' + }, + { + 'sdk_package_name': 'system-images;android-29;google_apis;x86', + 'cipd_yaml': 'third_party/android_sdk/cipd/system_images/android-29/google_apis/x86.yaml' + }, + { + 'sdk_package_name': 'system-images;android-29;google_apis_playstore;x86', + 'cipd_yaml': 'third_party/android_sdk/cipd/system_images/android-29/google_apis_playstore/x86.yaml' + }, + ], + }, +) + + +ci.android_builder( + name = 'Android ASAN (dbg)', + console_view_entry = ci.console_view_entry( + category = 'builder|arm', + short_name = 'san', + ), + # Higher build timeout since dbg ASAN builds can take a while on a clobber + # build. + execution_timeout = 4 * time.hour, +) + +ci.android_builder( + name = 'Android WebView L (dbg)', + console_view_entry = ci.console_view_entry( + category = 'tester|webview', + short_name = 'L', + ), + main_console_view = 'main', + triggered_by = ['ci/Android arm Builder (dbg)'], +) + +ci.android_builder( + name = 'Deterministic Android', + console_view_entry = ci.console_view_entry( + category = 'builder|det', + short_name = 'rel', + ), + executable = 'recipe:swarming/deterministic_build', + execution_timeout = 6 * time.hour, +) + +ci.android_builder( + name = 'Deterministic Android (dbg)', + console_view_entry = ci.console_view_entry( + category = 'builder|det', + short_name = 'dbg', + ), + executable = 'recipe:swarming/deterministic_build', + execution_timeout = 6 * time.hour, +) + +ci.android_builder( + name = 'Lollipop Phone Tester', + console_view_entry = ci.console_view_entry( + category = 'tester|phone', + short_name = 'L', + ), + # We have limited phone capacity and thus limited ability to run + # tests in parallel, hence the high timeout. + execution_timeout = 6 * time.hour, + main_console_view = 'main', + triggered_by = ['ci/Android arm Builder (dbg)'], +) + +ci.android_builder( + name = 'Lollipop Tablet Tester', + console_view_entry = ci.console_view_entry( + category = 'tester|tablet', + short_name = 'L', + ), + # We have limited tablet capacity and thus limited ability to run + # tests in parallel, hence the high timeout. + execution_timeout = 20 * time.hour, + main_console_view = 'main', + triggered_by = ['ci/Android arm Builder (dbg)'], +) + +ci.android_builder( + name = 'Marshmallow Tablet Tester', + console_view_entry = ci.console_view_entry( + category = 'tester|tablet', + short_name = 'M', + ), + # We have limited tablet capacity and thus limited ability to run + # tests in parallel, hence the high timeout. + execution_timeout = 12 * time.hour, + main_console_view = 'main', + triggered_by = ['ci/Android arm Builder (dbg)'], +) + +ci.android_builder( + name = 'android-arm64-proguard-rel', + console_view_entry = ci.console_view_entry( + category = 'builder_tester|arm64', + short_name = 'M proguard', + ), + goma_jobs = goma.jobs.MANY_JOBS_FOR_CI, + execution_timeout = 6 * time.hour, +) + +ci.android_builder( + name = 'android-cronet-arm64-dbg', + console_view_entry = ci.console_view_entry( + category = 'cronet|arm64', + short_name = 'dbg', + ), + notifies = ['cronet'], +) + +ci.android_builder( + name = 'android-cronet-arm64-rel', + console_view_entry = ci.console_view_entry( + category = 'cronet|arm64', + short_name = 'rel', + ), + notifies = ['cronet'], +) + +ci.android_builder( + name = 'android-cronet-asan-arm-rel', + console_view_entry = ci.console_view_entry( + category = 'cronet|asan', + ), + notifies = ['cronet'], +) + +# Runs on a specific machine with an attached phone +ci.android_builder( + name = 'android-cronet-marshmallow-arm64-perf-rel', + console_view_entry = ci.console_view_entry( + category = 'cronet|test|perf', + short_name = 'm', + ), + cores = None, + cpu = None, + executable = 'recipe:cronet', + notifies = ['cronet'], + os = os.ANDROID, +) + +ci.android_builder( + name = 'android-cronet-marshmallow-arm64-rel', + console_view_entry = ci.console_view_entry( + category = 'cronet|test', + short_name = 'm', + ), + notifies = ['cronet'], + triggered_by = ['android-cronet-arm64-rel'], +) + +ci.android_builder( + name = 'android-cronet-x86-dbg', + console_view_entry = ci.console_view_entry( + category = 'cronet|x86', + short_name = 'dbg', + ), + notifies = ['cronet'], +) + +ci.android_builder( + name = 'android-cronet-x86-rel', + console_view_entry = ci.console_view_entry( + category = 'cronet|x86', + short_name = 'rel', + ), + notifies = ['cronet'], +) + +ci.android_builder( + name = 'android-incremental-dbg', + console_view_entry = ci.console_view_entry( + category = 'tester|incremental', + ), +) + +ci.android_builder( + name = 'android-pie-x86-rel', + console_view_entry = ci.console_view_entry( + category = 'builder_tester|x86', + short_name = 'P', + ), +) + +ci.android_builder( + name = 'android-10-arm64-rel', + console_view_entry = ci.console_view_entry( + category = 'builder_tester|arm64', + short_name = '10', + ), +) + + +ci.android_fyi_builder( + name = 'android-bfcache-rel', + console_view_entry = ci.console_view_entry( + category = 'android', + ), +) + +ci.android_fyi_builder( + name = 'Android WebLayer P FYI (rel)', + console_view_entry = ci.console_view_entry( + category = 'weblayer', + short_name = 'p-rel', + ), +) + +ci.android_fyi_builder( + name = 'android-weblayer-pie-x86-fyi-rel', + console_view_entry = ci.console_view_entry( + category = 'weblayer', + short_name = 'p-x86-rel', + ), +) + +ci.android_fyi_builder( + name = 'Android WebView P Blink-CORS FYI (rel)', + console_view_entry = ci.console_view_entry( + category = 'webview', + short_name = 'cors', + ), +) + +ci.android_fyi_builder( + name = 'Android WebView P FYI (rel)', + console_view_entry = ci.console_view_entry( + category = 'webview', + short_name = 'p-rel', + ), +) + +ci.android_fyi_builder( + name = 'android-marshmallow-x86-fyi-rel', + console_view_entry = ci.console_view_entry( + category = 'emulator|M|x86', + short_name = 'rel', + ), + goma_jobs=goma.jobs.J150, +) + +# TODO(hypan): remove this once there is no associated disabled tests +ci.android_fyi_builder( + name = 'android-pie-x86-fyi-rel', + console_view_entry = ci.console_view_entry( + category = 'emulator|P|x86', + short_name = 'rel', + ), + goma_jobs=goma.jobs.J150, + schedule = 'triggered', # triggered manually via Scheduler UI +) + + + +ci.chromium_builder( + name = 'android-archive-dbg', + # Bump to 32 if needed. + console_view_entry = ci.console_view_entry( + category = 'android', + short_name = 'dbg', + ), + cores = 8, + main_console_view = 'main', +) + +ci.chromium_builder( + name = 'android-archive-rel', + console_view_entry = ci.console_view_entry( + category = 'android', + short_name = 'rel', + ), + cores = 32, + main_console_view = 'main', +) + +ci.chromium_builder( + name = 'linux-archive-dbg', + console_view_entry = ci.console_view_entry( + category = 'linux', + short_name = 'dbg', + ), + # Bump to 32 if needed. + cores = 8, + main_console_view = 'main', +) + +ci.chromium_builder( + name = 'linux-archive-rel', + console_view_entry = ci.console_view_entry( + category = 'linux', + short_name = 'rel', + ), + cores = 32, + main_console_view = 'main', +) + +ci.chromium_builder( + name = 'mac-archive-dbg', + console_view_entry = ci.console_view_entry( + category = 'mac', + short_name = 'dbg', + ), + # Bump to 8 cores if needed. + cores = 4, + main_console_view = 'main', + os = os.MAC_DEFAULT, +) + +ci.chromium_builder( + name = 'mac-archive-rel', + console_view_entry = ci.console_view_entry( + category = 'mac', + short_name = 'rel', + ), + main_console_view = 'main', + os = os.MAC_DEFAULT, +) + +ci.chromium_builder( + name = 'win-archive-dbg', + console_view_entry = ci.console_view_entry( + category = 'win|dbg', + short_name = '64', + ), + cores = 32, + main_console_view = 'main', + os = os.WINDOWS_DEFAULT, +) + +ci.chromium_builder( + name = 'win-archive-rel', + console_view_entry = ci.console_view_entry( + category = 'win|rel', + short_name = '64', + ), + cores = 32, + main_console_view = 'main', + os = os.WINDOWS_DEFAULT, +) + +ci.chromium_builder( + name = 'win32-archive-dbg', + console_view_entry = ci.console_view_entry( + category = 'win|dbg', + short_name = '32', + ), + cores = 32, + main_console_view = 'main', + os = os.WINDOWS_DEFAULT, +) + +ci.chromium_builder( + name = 'win32-archive-rel', + console_view_entry = ci.console_view_entry( + category = 'win|rel', + short_name = '32', + ), + cores = 32, + main_console_view = 'main', + os = os.WINDOWS_DEFAULT, +) + + +ci.chromiumos_builder( + name = 'Linux ChromiumOS Full', + console_view_entry = ci.console_view_entry( + category = 'default', + short_name = 'ful', + ), +) + +ci.chromiumos_builder( + name = 'chromeos-amd64-generic-asan-rel', + console_view_entry = ci.console_view_entry( + category = 'simple|release|x64', + short_name = 'asn', + ), +) + +ci.chromiumos_builder( + name = 'chromeos-amd64-generic-cfi-thin-lto-rel', + console_view_entry = ci.console_view_entry( + category = 'simple|release|x64', + short_name = 'cfi', + ), +) + +ci.chromiumos_builder( + name = 'chromeos-arm-generic-dbg', + console_view_entry = ci.console_view_entry( + category = 'simple|debug', + short_name = 'arm', + ), +) + + +ci.clang_builder( + name = 'CFI Linux CF', + goma_backend = goma.backend.RBE_PROD, + console_view_entry = ci.console_view_entry( + category = 'CFI|Linux', + short_name = 'CF', + ), +) + +ci.clang_builder( + name = 'CFI Linux ToT', + console_view_entry = ci.console_view_entry( + category = 'CFI|Linux', + short_name = 'ToT', + ), +) + +ci.clang_builder( + name = 'CrWinAsan', + console_view_entry = ci.console_view_entry( + category = 'ToT Windows|Asan', + short_name = 'asn', + ), + os = os.WINDOWS_ANY, +) + +ci.clang_builder( + name = 'CrWinAsan(dll)', + console_view_entry = ci.console_view_entry( + category = 'ToT Windows|Asan', + short_name = 'dll', + ), + os = os.WINDOWS_ANY, +) + +ci.clang_builder( + name = 'ToTAndroid', + console_view_entry = ci.console_view_entry( + category = 'ToT Android', + short_name = 'rel', + ), +) + +ci.clang_builder( + name = 'ToTAndroid (dbg)', + console_view_entry = ci.console_view_entry( + category = 'ToT Android', + short_name = 'dbg', + ), +) + +ci.clang_builder( + name = 'ToTAndroid x64', + console_view_entry = ci.console_view_entry( + category = 'ToT Android', + short_name = 'x64', + ), +) + +ci.clang_builder( + name = 'ToTAndroid64', + console_view_entry = ci.console_view_entry( + category = 'ToT Android', + short_name = 'a64', + ), +) + +ci.clang_builder( + name = 'ToTAndroidASan', + console_view_entry = ci.console_view_entry( + category = 'ToT Android', + short_name = 'asn', + ), +) + +ci.clang_builder( + name = 'ToTAndroidCFI', + console_view_entry = ci.console_view_entry( + category = 'ToT Android', + short_name = 'cfi', + ), +) + +ci.clang_builder( + name = 'ToTAndroidOfficial', + console_view_entry = ci.console_view_entry( + category = 'ToT Android', + short_name = 'off', + ), +) + +ci.clang_builder( + name = 'ToTLinux', + console_view_entry = ci.console_view_entry( + category = 'ToT Linux', + short_name = 'rel', + ), +) + +ci.clang_builder( + name = 'ToTLinux (dbg)', + console_view_entry = ci.console_view_entry( + category = 'ToT Linux', + short_name = 'dbg', + ), +) + +ci.clang_builder( + name = 'ToTLinuxASan', + console_view_entry = ci.console_view_entry( + category = 'ToT Linux', + short_name = 'asn', + ), +) + +ci.clang_builder( + name = 'ToTLinuxASanLibfuzzer', + console_view_entry = ci.console_view_entry( + category = 'ToT Linux', + short_name = 'fuz', + ), +) + +ci.clang_builder( + name = 'ToTLinuxCoverage', + console_view_entry = ci.console_view_entry( + category = 'ToT Code Coverage', + short_name = 'linux', + ), + executable = 'recipe:chromium_clang_coverage_tot', +) + +ci.clang_builder( + name = 'ToTLinuxMSan', + console_view_entry = ci.console_view_entry( + category = 'ToT Linux', + short_name = 'msn', + ), +) + +ci.clang_builder( + name = 'ToTLinuxTSan', + console_view_entry = ci.console_view_entry( + category = 'ToT Linux', + short_name = 'tsn', + ), +) + +ci.clang_builder( + name = 'ToTLinuxThinLTO', + console_view_entry = ci.console_view_entry( + category = 'ToT Linux', + short_name = 'lto', + ), +) + +ci.clang_builder( + name = 'ToTLinuxUBSanVptr', + console_view_entry = ci.console_view_entry( + category = 'ToT Linux', + short_name = 'usn', + ), +) + +ci.clang_builder( + name = 'ToTWin(dbg)', + console_view_entry = ci.console_view_entry( + category = 'ToT Windows', + short_name = 'dbg', + ), + os = os.WINDOWS_ANY, +) + +ci.clang_builder( + name = 'ToTWin(dll)', + console_view_entry = ci.console_view_entry( + category = 'ToT Windows', + short_name = 'dll', + ), + os = os.WINDOWS_ANY, +) + +ci.clang_builder( + name = 'ToTWin64(dbg)', + console_view_entry = ci.console_view_entry( + category = 'ToT Windows|x64', + short_name = 'dbg', + ), + os = os.WINDOWS_ANY, +) + +ci.clang_builder( + name = 'ToTWin64(dll)', + console_view_entry = ci.console_view_entry( + category = 'ToT Windows|x64', + short_name = 'dll', + ), + os = os.WINDOWS_ANY, +) + +ci.clang_builder( + name = 'ToTWinASanLibfuzzer', + console_view_entry = ci.console_view_entry( + category = 'ToT Windows|Asan', + short_name = 'fuz', + ), + os = os.WINDOWS_ANY, +) + +ci.clang_builder( + name = 'ToTWinCFI', + console_view_entry = ci.console_view_entry( + category = 'CFI|Win', + short_name = 'x86', + ), + os = os.WINDOWS_ANY, +) + +ci.clang_builder( + name = 'ToTWinCFI64', + console_view_entry = ci.console_view_entry( + category = 'CFI|Win', + short_name = 'x64', + ), + os = os.WINDOWS_ANY, +) + +ci.clang_builder( + name = 'UBSanVptr Linux', + console_view_entry = ci.console_view_entry( + short_name = 'usn', + ), + goma_backend = goma.backend.RBE_PROD, +) + +ci.clang_builder( + name = 'linux-win_cross-rel', + console_view_entry = ci.console_view_entry( + category = 'ToT Windows', + short_name = 'lxw', + ), +) + +ci.clang_builder( + name = 'ToTiOS', + caches = [xcode_cache.x11c29], + console_view_entry = ci.console_view_entry( + category = 'iOS|public', + short_name = 'sim', + ), + cores = None, + os = os.MAC_10_14, + properties = { + 'xcode_build_version': '11c29' + }, + ssd=True +) + +ci.clang_builder( + name = 'ToTiOSDevice', + caches = [xcode_cache.x11c29], + console_view_entry = ci.console_view_entry( + category = 'iOS|public', + short_name = 'dev', + ), + cores = None, + os = os.MAC_10_14, + properties = { + 'xcode_build_version': '11c29' + }, + ssd=True +) + + +ci.clang_mac_builder( + name = 'ToTMac', + console_view_entry = ci.console_view_entry( + category = 'ToT Mac', + short_name = 'rel', + ), +) + +ci.clang_mac_builder( + name = 'ToTMac (dbg)', + console_view_entry = ci.console_view_entry( + category = 'ToT Mac', + short_name = 'dbg', + ), +) + +ci.clang_mac_builder( + name = 'ToTMacASan', + console_view_entry = ci.console_view_entry( + category = 'ToT Mac', + short_name = 'asn', + ), +) + +ci.clang_mac_builder( + name = 'ToTMacCoverage', + console_view_entry = ci.console_view_entry( + category = 'ToT Code Coverage', + short_name = 'mac', + ), + executable = 'recipe:chromium_clang_coverage_tot', +) + + +ci.dawn_builder( + name = 'Dawn Linux x64 Builder', + console_view_entry = ci.console_view_entry( + category = 'ToT|Linux|Builder', + short_name = 'x64', + ), +) + +ci.dawn_builder( + name = 'Dawn Linux x64 Release (Intel HD 630)', + console_view_entry = ci.console_view_entry( + category = 'ToT|Linux|Intel', + short_name = 'x64', + ), + cores = 2, + os = os.LINUX_DEFAULT, + triggered_by = ['Dawn Linux x64 Builder'], +) + +ci.dawn_builder( + name = 'Dawn Linux x64 Release (NVIDIA)', + console_view_entry = ci.console_view_entry( + category = 'ToT|Linux|Nvidia', + short_name = 'x64', + ), + cores = 2, + os = os.LINUX_DEFAULT, + triggered_by = ['Dawn Linux x64 Builder'], +) + +ci.dawn_builder( + name = 'Dawn Mac x64 Builder', + console_view_entry = ci.console_view_entry( + category = 'ToT|Mac|Builder', + short_name = 'x64', + ), + builderless = False, + cores = None, + os = os.MAC_ANY, +) + +ci.dawn_builder( + name = 'Dawn Mac x64 Release (AMD)', + console_view_entry = ci.console_view_entry( + category = 'ToT|Mac|AMD', + short_name = 'x64', + ), + cores = 2, + os = os.LINUX_DEFAULT, + triggered_by = ['Dawn Mac x64 Builder'], +) + +ci.dawn_builder( + name = 'Dawn Mac x64 Release (Intel)', + console_view_entry = ci.console_view_entry( + category = 'ToT|Mac|Intel', + short_name = 'x64', + ), + cores = 2, + os = os.LINUX_DEFAULT, + triggered_by = ['Dawn Mac x64 Builder'], +) + +ci.dawn_builder( + name = 'Dawn Win10 x86 Builder', + console_view_entry = ci.console_view_entry( + category = 'ToT|Windows|Builder', + short_name = 'x86', + ), + os = os.WINDOWS_ANY, +) + +ci.dawn_builder( + name = 'Dawn Win10 x64 Builder', + console_view_entry = ci.console_view_entry( + category = 'ToT|Windows|Builder', + short_name = 'x64', + ), + os = os.WINDOWS_ANY, +) + +# Note that the Win testers are all thin Linux VMs, triggering jobs on the +# physical Win hardware in the Swarming pool, which is why they run on linux +ci.dawn_builder( + name = 'Dawn Win10 x86 Release (Intel HD 630)', + console_view_entry = ci.console_view_entry( + category = 'ToT|Windows|Intel', + short_name = 'x86', + ), + cores = 2, + os = os.LINUX_DEFAULT, + triggered_by = ['Dawn Win10 x86 Builder'], +) + +ci.dawn_builder( + name = 'Dawn Win10 x64 Release (Intel HD 630)', + console_view_entry = ci.console_view_entry( + category = 'ToT|Windows|Intel', + short_name = 'x64', + ), + cores = 2, + os = os.LINUX_DEFAULT, + triggered_by = ['Dawn Win10 x64 Builder'], +) + +ci.dawn_builder( + name = 'Dawn Win10 x86 Release (NVIDIA)', + console_view_entry = ci.console_view_entry( + category = 'ToT|Windows|Nvidia', + short_name = 'x86', + ), + cores = 2, + os = os.LINUX_DEFAULT, + triggered_by = ['Dawn Win10 x86 Builder'], +) + +ci.dawn_builder( + name = 'Dawn Win10 x64 Release (NVIDIA)', + console_view_entry = ci.console_view_entry( + category = 'ToT|Windows|Nvidia', + short_name = 'x64', + ), + cores = 2, + os = os.LINUX_DEFAULT, + triggered_by = ['Dawn Win10 x64 Builder'], +) + + +ci.fuzz_builder( + name = 'ASAN Debug', + console_view_entry = ci.console_view_entry( + category = 'linux asan', + short_name = 'dbg', + ), + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 4, + ), +) + +ci.fuzz_builder( + name = 'ASan Debug (32-bit x86 with V8-ARM)', + console_view_entry = ci.console_view_entry( + category = 'linux asan|x64 v8-ARM', + short_name = 'dbg', + ), + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 4, + ), +) + +ci.fuzz_builder( + name = 'ASAN Release', + console_view_entry = ci.console_view_entry( + category = 'linux asan', + short_name = 'rel', + ), + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 5, + ), +) + +ci.fuzz_builder( + name = 'ASan Release (32-bit x86 with V8-ARM)', + console_view_entry = ci.console_view_entry( + category = 'linux asan|x64 v8-ARM', + short_name = 'rel', + ), + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 4, + ), +) + +ci.fuzz_builder( + name = 'ASAN Release Media', + console_view_entry = ci.console_view_entry( + category = 'linux asan', + short_name = 'med', + ), + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 4, + ), +) + +ci.fuzz_builder( + name = 'Afl Upload Linux ASan', + console_view_entry = ci.console_view_entry( + category = 'afl', + short_name = 'afl', + ), + executable = 'recipe:chromium_afl', + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 4, + ), +) + +ci.fuzz_builder( + name = 'ASan Release Media (32-bit x86 with V8-ARM)', + console_view_entry = ci.console_view_entry( + category = 'linux asan|x64 v8-ARM', + short_name = 'med', + ), + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 4, + ), +) + +ci.fuzz_builder( + name = 'ChromiumOS ASAN Release', + console_view_entry = ci.console_view_entry( + category = 'cros asan', + ), + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 6, + ), +) + +ci.fuzz_builder( + name = 'MSAN Release (chained origins)', + console_view_entry = ci.console_view_entry( + category = 'linux msan', + short_name = 'org', + ), + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 4, + ), +) + +ci.fuzz_builder( + name = 'MSAN Release (no origins)', + console_view_entry = ci.console_view_entry( + category = 'linux msan', + short_name = 'rel', + ), + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 4, + ), +) + +ci.fuzz_builder( + name = 'Mac ASAN Release', + builderless = False, + console_view_entry = ci.console_view_entry( + category = 'mac asan', + short_name = 'rel', + ), + cores = 4, + os = os.MAC_DEFAULT, + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 2, + ), +) + +ci.fuzz_builder( + name = 'Mac ASAN Release Media', + builderless = False, + console_view_entry = ci.console_view_entry( + category = 'mac asan', + short_name = 'med', + ), + cores = 4, + os = os.MAC_DEFAULT, + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 2, + ), +) + +ci.fuzz_builder( + name = 'TSAN Debug', + console_view_entry = ci.console_view_entry( + category = 'linux tsan', + short_name = 'dbg', + ), + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 4, + ), +) + +ci.fuzz_builder( + name = 'TSAN Release', + console_view_entry = ci.console_view_entry( + category = 'linux tsan', + short_name = 'rel', + ), + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 3, + ), +) + +ci.fuzz_builder( + name = 'UBSan Release', + console_view_entry = ci.console_view_entry( + category = 'linux UBSan', + short_name = 'rel', + ), + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 4, + ), +) + +ci.fuzz_builder( + name = 'UBSan vptr Release', + console_view_entry = ci.console_view_entry( + category = 'linux UBSan', + short_name = 'vpt', + ), + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 4, + ), +) + +ci.fuzz_builder( + name = 'Win ASan Release', + builderless = False, + console_view_entry = ci.console_view_entry( + category = 'win asan', + short_name = 'rel', + ), + os = os.WINDOWS_DEFAULT, + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 7, + ), +) + +ci.fuzz_builder( + name = 'Win ASan Release Media', + builderless = False, + console_view_entry = ci.console_view_entry( + category = 'win asan', + short_name = 'med', + ), + os = os.WINDOWS_DEFAULT, + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 6, + ), +) + + +ci.fuzz_libfuzzer_builder( + name = 'Libfuzzer Upload Chrome OS ASan', + console_view_entry = ci.console_view_entry( + category = 'libfuzz', + short_name = 'chromeos-asan', + ), + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 3, + ), +) + +ci.fuzz_libfuzzer_builder( + name = 'Libfuzzer Upload Linux ASan', + console_view_entry = ci.console_view_entry( + category = 'libfuzz', + short_name = 'linux', + ), + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 5, + ), +) + +ci.fuzz_libfuzzer_builder( + name = 'Libfuzzer Upload Linux ASan Debug', + console_view_entry = ci.console_view_entry( + category = 'libfuzz', + short_name = 'linux-dbg', + ), + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 5, + ), +) + +ci.fuzz_libfuzzer_builder( + name = 'Libfuzzer Upload Linux MSan', + console_view_entry = ci.console_view_entry( + category = 'libfuzz', + short_name = 'linux-msan', + ), + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 5, + ), +) + +ci.fuzz_libfuzzer_builder( + name = 'Libfuzzer Upload Linux UBSan', + # Do not use builderless for this (crbug.com/980080). + builderless = False, + console_view_entry = ci.console_view_entry( + category = 'libfuzz', + short_name = 'linux-ubsan', + ), + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 5, + ), +) + +ci.fuzz_libfuzzer_builder( + name = 'Libfuzzer Upload Linux V8-ARM64 ASan', + console_view_entry = ci.console_view_entry( + category = 'libfuzz', + short_name = 'arm64', + ), + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 1, + ), +) + +ci.fuzz_libfuzzer_builder( + name = 'Libfuzzer Upload Linux V8-ARM64 ASan Debug', + console_view_entry = ci.console_view_entry( + category = 'libfuzz', + short_name = 'arm64-dbg', + ), + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 1, + ), +) + +ci.fuzz_libfuzzer_builder( + name = 'Libfuzzer Upload Linux32 ASan', + console_view_entry = ci.console_view_entry( + category = 'libfuzz', + short_name = 'linux32', + ), + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 3, + ), +) + +ci.fuzz_libfuzzer_builder( + name = 'Libfuzzer Upload Linux32 ASan Debug', + console_view_entry = ci.console_view_entry( + category = 'libfuzz', + short_name = 'linux32-dbg', + ), + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 3, + ), +) + +ci.fuzz_libfuzzer_builder( + name = 'Libfuzzer Upload Linux32 V8-ARM ASan', + console_view_entry = ci.console_view_entry( + category = 'libfuzz', + short_name = 'arm', + ), + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 1, + ), +) + +ci.fuzz_libfuzzer_builder( + name = 'Libfuzzer Upload Linux32 V8-ARM ASan Debug', + console_view_entry = ci.console_view_entry( + category = 'libfuzz', + short_name = 'arm-dbg', + ), + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 1, + ), +) + +ci.fuzz_libfuzzer_builder( + name = 'Libfuzzer Upload Mac ASan', + console_view_entry = ci.console_view_entry( + category = 'libfuzz', + short_name = 'mac-asan', + ), + cores = 24, + execution_timeout = 4 * time.hour, + os = os.MAC_DEFAULT, +) + +ci.fuzz_libfuzzer_builder( + name = 'Libfuzzer Upload Windows ASan', + console_view_entry = ci.console_view_entry( + category = 'libfuzz', + short_name = 'win-asan', + ), + os = os.WINDOWS_DEFAULT, + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 3, + ), +) + + +ci.fyi_builder( + name = 'Closure Compilation Linux', + console_view_entry = ci.console_view_entry( + category = 'closure_compilation', + ), + executable = 'recipe:closure_compilation', +) + +ci.fyi_builder( + name = 'Linux Viz', + console_view_entry = ci.console_view_entry( + category = 'viz', + ), +) + +ci.fyi_builder( + name = 'Linux remote_run Builder', + console_view_entry = ci.console_view_entry( + category = 'remote_run', + ), +) + +ci.fyi_builder( + name = 'Linux remote_run Tester', + console_view_entry = ci.console_view_entry( + category = 'remote_run', + ), + triggered_by = ['Linux remote_run Builder'], +) + +ci.fyi_builder( + name = 'Mojo Android', + console_view_entry = ci.console_view_entry( + category = 'mojo', + short_name = 'and', + ), +) + +ci.fyi_builder( + name = 'Mojo ChromiumOS', + console_view_entry = ci.console_view_entry( + category = 'mojo', + short_name = 'cr', + ), +) + +ci.fyi_builder( + name = 'Mojo Linux', + console_view_entry = ci.console_view_entry( + category = 'mojo', + short_name = 'lnx', + ), +) + +ci.fyi_builder( + name = 'Site Isolation Android', + console_view_entry = ci.console_view_entry( + category = 'site_isolation', + ), +) + +ci.fyi_builder( + name = 'android-mojo-webview-rel', + console_view_entry = ci.console_view_entry( + category = 'mojo', + short_name = 'aw', + ), +) + +ci.fyi_builder( + name = 'chromeos-amd64-generic-lacros-rel', + console_view_entry = ci.console_view_entry( + category = 'chromeos', + ), + properties = { + # The format of these properties is defined at archive/properties.proto + '$build/archive' : { + 'archive_datas': [ + { + 'files': [ + 'chrome', + 'chrome_100_percent.pak', + 'chrome_200_percent.pak', + 'crashpad_handler', + 'headless_lib.pak', + 'icudtl.dat', + 'nacl_helper', + 'nacl_irt_x86_64.nexe', + 'resources.pak', + 'snapshot_blob.bin', + ], + 'dirs': ['locales', 'swiftshader'], + 'gcs_bucket': 'chromium-lacros-fishfood', + 'gcs_path': 'x86_64/{%position%}/lacros.zip', + 'archive_type': 'ARCHIVE_TYPE_ZIP', + }, + ], + }, + }, +) + +ci.fyi_builder( + name = 'chromeos-amd64-generic-rel-vm-tests', + console_view_entry = ci.console_view_entry( + category = 'chromeos', + ), +) + +ci.fyi_builder( + name = 'fuchsia-fyi-arm64-rel', + console_view_entry = ci.console_view_entry( + category = 'fuchsia|a64', + short_name = 'rel', + ), + notifies = ['cr-fuchsia'], +) + +ci.fyi_builder( + name = 'fuchsia-fyi-x64-dbg', + console_view_entry = ci.console_view_entry( + category = 'fuchsia|x64', + short_name = 'dbg', + ), + notifies = ['cr-fuchsia'], +) + +ci.fyi_builder( + name = 'fuchsia-fyi-x64-rel', + console_view_entry = ci.console_view_entry( + category = 'fuchsia|x64', + short_name = 'rel', + ), + notifies = ['cr-fuchsia'], +) + +ci.fyi_builder( + name = 'linux-annotator-rel', + console_view_entry = ci.console_view_entry( + category = 'network|traffic|annotations', + short_name = 'lnx', + ), +) + +ci.fyi_builder( + name = 'linux-bfcache-rel', + console_view_entry = ci.console_view_entry( + category = 'linux', + ), +) + +ci.fyi_builder( + name = 'linux-blink-animation-use-time-delta', + console_view_entry = ci.console_view_entry( + category = 'linux|blink', + short_name = 'TD', + ), +) + +ci.fyi_builder( + name = 'linux-blink-cors-rel', + console_view_entry = ci.console_view_entry( + category = 'linux', + ), +) + +ci.fyi_builder( + name = 'linux-blink-heap-concurrent-marking-tsan-rel', + console_view_entry = ci.console_view_entry( + category = 'linux|blink', + short_name = 'CM', + ), +) + +ci.fyi_builder( + name = 'linux-blink-heap-verification', + console_view_entry = ci.console_view_entry( + category = 'linux|blink', + short_name = 'VF', + ), +) + +ci.fyi_builder( + name = 'linux-chromium-tests-staging-builder', + console_view_entry = ci.console_view_entry( + category = 'recipe|staging|linux', + short_name = 'bld', + ), +) + +ci.fyi_builder( + name = 'linux-chromium-tests-staging-tests', + console_view_entry = ci.console_view_entry( + category = 'recipe|staging|linux', + short_name = 'tst', + ), + triggered_by = ['linux-chromium-tests-staging-builder'], +) + +ci.fyi_builder( + name = 'linux-fieldtrial-rel', + console_view_entry = ci.console_view_entry( + category = 'linux', + ), +) + +ci.fyi_builder( + name = 'linux-perfetto-rel', + console_view_entry = ci.console_view_entry( + category = 'linux', + ), +) + +ci.fyi_builder( + name = 'linux-wpt-fyi-rel', + console_view_entry = ci.console_view_entry( + category = 'linux', + ), + experimental = True, + goma_backend = None, +) + +ci.fyi_builder( + name = 'win-pixel-builder-rel', + console_view_entry = ci.console_view_entry( + category = 'win10', + ), + os = os.WINDOWS_10, +) + +ci.fyi_builder( + name = 'win-pixel-tester-rel', + console_view_entry = ci.console_view_entry( + category = 'win10', + ), + os = None, + triggered_by = ['win-pixel-builder-rel'], +) + +ci.fyi_builder( + name = 'linux-upload-perfetto', + console_view_entry = ci.console_view_entry( + category = 'perfetto', + short_name = 'lnx', + ), + os = os.LINUX_DEFAULT, +) + +ci.fyi_builder( + name = 'mac-upload-perfetto', + builderless = True, + console_view_entry = ci.console_view_entry( + category = 'perfetto', + short_name = 'mac', + ), + os = os.MAC_DEFAULT, + schedule = 'with 3h interval', + triggered_by = [], +) + +ci.fyi_builder( + name = 'win-upload-perfetto', + builderless = True, + console_view_entry = ci.console_view_entry( + category = 'perfetto', + short_name = 'win', + ), + os = os.WINDOWS_DEFAULT, + schedule = 'with 3h interval', + triggered_by = [], +) + +ci.fyi_celab_builder( + name = 'win-celab-builder-rel', + console_view_entry = ci.console_view_entry( + category = 'celab', + ), + schedule = '0 0,6,12,18 * * *', + triggered_by = [], +) + +ci.fyi_celab_builder( + name = 'win-celab-tester-rel', + console_view_entry = ci.console_view_entry( + category = 'celab', + ), + triggered_by = ['win-celab-builder-rel'], +) + + +ci.fyi_coverage_builder( + name = 'android-code-coverage', + console_view_entry = ci.console_view_entry( + category = 'code_coverage', + short_name = 'and', + ), + use_java_coverage = True, + schedule = 'triggered', + triggered_by = [], +) + +ci.fyi_coverage_builder( + name = 'android-code-coverage-native', + console_view_entry = ci.console_view_entry( + category = 'code_coverage', + short_name = 'ann', + ), + use_clang_coverage = True, +) + +ci.fyi_coverage_builder( + name = 'ios-simulator-code-coverage', + caches = [xcode_cache.x11c29], + console_view_entry = ci.console_view_entry( + category = 'code_coverage', + short_name = 'ios', + ), + cores = None, + os = os.MAC_ANY, + use_clang_coverage = True, + properties = { + 'coverage_exclude_sources': 'ios_test_files_and_test_utils', + 'coverage_test_types': ['overall', 'unit'], + 'xcode_build_version': '11c29', + }, +) + +ci.fyi_coverage_builder( + name = 'linux-chromeos-code-coverage', + console_view_entry = ci.console_view_entry( + category = 'code_coverage', + short_name = 'lcr', + ), + use_clang_coverage = True, + schedule = 'triggered', + triggered_by = [], +) + +ci.fyi_coverage_builder( + name = 'linux-code-coverage', + console_view_entry = ci.console_view_entry( + category = 'code_coverage', + short_name = 'lnx', + ), + use_clang_coverage = True, + triggered_by = [], +) + +ci.fyi_coverage_builder( + name = 'mac-code-coverage', + builderless = True, + console_view_entry = ci.console_view_entry( + category = 'code_coverage', + short_name = 'mac', + ), + cores = 24, + os = os.MAC_ANY, + use_clang_coverage = True, +) + +ci.fyi_coverage_builder( + name = 'win10-code-coverage', + builderless = True, + console_view_entry = ci.console_view_entry( + category = 'code_coverage', + short_name = 'win', + ), + os = os.WINDOWS_DEFAULT, + use_clang_coverage = True, +) + + +ci.fyi_ios_builder( + name = 'ios-simulator-cr-recipe', + console_view_entry = ci.console_view_entry( + category = 'iOS', + short_name = 'chr', + ), + executable = 'recipe:chromium', + properties = { + 'xcode_build_version': '11a1027', + }, +) + +ci.fyi_ios_builder( + name = 'ios-simulator-multi-window', + console_view_entry = ci.console_view_entry( + category = 'iOS', + short_name = 'mwd', + ), + executable = 'recipe:chromium', + properties = { + 'xcode_build_version': '11c29', + }, +) + +ci.fyi_ios_builder( + name = 'ios-webkit-tot', + caches = [xcode_cache.x11n605cwk], + console_view_entry = ci.console_view_entry( + category = 'iOS', + short_name = 'wk', + ), + executable = 'recipe:chromium', + properties = { + 'xcode_build_version': '11n605cwk' + }, + schedule = '0 1-23/6 * * *', + triggered_by = [], +) + +ci.fyi_ios_builder( + name = 'ios13-beta-simulator', + console_view_entry = ci.console_view_entry( + category = 'iOS|iOS13', + short_name = 'ios13', + ), + executable = 'recipe:chromium', + properties = { + 'xcode_build_version': '11c29', + }, +) + +ci.fyi_ios_builder( + name = 'ios13-sdk-device', + console_view_entry = ci.console_view_entry( + category = 'iOS|iOS13', + short_name = 'dev', + ), + executable = 'recipe:chromium', + properties = { + 'xcode_build_version': '11c29', + }, +) + +ci.fyi_ios_builder( + name = 'ios13-sdk-simulator', + console_view_entry = ci.console_view_entry( + category = 'iOS|iOS13', + short_name = 'sim', + ), + caches = [xcode_cache.x11e146], + executable = 'recipe:chromium', + os = os.MAC_10_15, + properties = { + 'xcode_build_version': '11e146' + } +) + + +ci.fyi_mac_builder( + name = 'Mac Builder Next', + console_view_entry = ci.console_view_entry( + category = 'mac', + short_name = 'bld', + ), + cores = None, + os = None, +) + +ci.thin_tester( + name = 'Mac10.15 Tests', + mastername = 'chromium.fyi', + console_view_entry = ci.console_view_entry( + category = 'mac', + short_name = '15', + ), + triggered_by = ['Mac Builder Next'], +) + +ci.fyi_mac_builder( + name = 'Mac deterministic', + console_view_entry = ci.console_view_entry( + category = 'deterministic|mac', + short_name = 'rel', + ), + cores = None, + executable = 'recipe:swarming/deterministic_build', + execution_timeout = 6 * time.hour, +) + +ci.fyi_mac_builder( + name = 'Mac deterministic (dbg)', + console_view_entry = ci.console_view_entry( + category = 'deterministic|mac', + short_name = 'dbg', + ), + cores = None, + executable = 'recipe:swarming/deterministic_build', + execution_timeout = 6 * time.hour, +) + +ci.fyi_mac_builder( + name = 'mac-hermetic-upgrade-rel', + console_view_entry = ci.console_view_entry( + category = 'mac', + short_name = 'herm', + ), + cores = 8, +) + +ci.fyi_mac_builder( + name = 'mac-mojo-rel', + console_view_entry = ci.console_view_entry( + category = 'mojo', + short_name = 'mac', + ), + os = os.MAC_ANY, +) + + +ci.fyi_windows_builder( + name = 'Win 10 Fast Ring', + console_view_entry = ci.console_view_entry( + category = 'win10', + ), + os = os.WINDOWS_10, +) + +ci.fyi_windows_builder( + name = 'win32-arm64-rel', + console_view_entry = ci.console_view_entry( + category = 'win32|arm64', + ), + cpu = cpu.X86, + goma_jobs = goma.jobs.J150, +) + +ci.fyi_windows_builder( + name = 'win-annotator-rel', + builderless = True, + console_view_entry = ci.console_view_entry( + category = 'network|traffic|annotations', + short_name = 'win', + ), + execution_timeout = 16 * time.hour, +) + +ci.fyi_windows_builder( + name = 'Mojo Windows', + console_view_entry = ci.console_view_entry( + category = 'mojo', + short_name = 'win', + ), +) + + +ci.gpu_builder( + name = 'GPU Linux Builder (dbg)', + console_view_entry = ci.console_view_entry( + category = 'Linux', + ), +) + +ci.gpu_builder( + name = 'GPU Mac Builder (dbg)', + console_view_entry = ci.console_view_entry( + category = 'Mac', + ), + cores = None, + os = os.MAC_ANY, +) + +ci.gpu_builder( + name = 'GPU Win x64 Builder (dbg)', + builderless = True, + console_view_entry = ci.console_view_entry( + category = 'Windows', + ), + os = os.WINDOWS_ANY, +) + + +ci.gpu_thin_tester( + name = 'Linux Debug (NVIDIA)', + console_view_entry = ci.console_view_entry( + category = 'Linux', + ), + triggered_by = ['GPU Linux Builder (dbg)'], +) + +ci.gpu_thin_tester( + name = 'Mac Debug (Intel)', + console_view_entry = ci.console_view_entry( + category = 'Mac', + ), + triggered_by = ['GPU Mac Builder (dbg)'], +) + +ci.gpu_thin_tester( + name = 'Mac Retina Debug (AMD)', + console_view_entry = ci.console_view_entry( + category = 'Mac', + ), + triggered_by = ['GPU Mac Builder (dbg)'], +) + +ci.gpu_thin_tester( + name = 'Win10 x64 Debug (NVIDIA)', + console_view_entry = ci.console_view_entry( + category = 'Windows', + ), + triggered_by = ['GPU Win x64 Builder (dbg)'], +) + + +ci.gpu_fyi_linux_builder( + name = 'Android FYI 32 Vk Release (Pixel 2)', + console_view_entry = ci.console_view_entry( + category = 'Android|vk|Q32', + short_name = 'P2', + ), +) + +ci.gpu_fyi_linux_builder( + name = 'Android FYI 32 dEQP Vk Release (Pixel 2)', + console_view_entry = ci.console_view_entry( + category = 'Android|dqp|vk|Q32', + short_name = 'P2', + ), +) + +ci.gpu_fyi_linux_builder( + name = 'Android FYI 64 Perf (Pixel 2)', + console_view_entry = ci.console_view_entry( + category = 'Android|Perf|Q64', + short_name = 'P2', + ), + cores = 2, + triggered_by = ['GPU FYI Perf Android 64 Builder'], +) + +ci.gpu_fyi_linux_builder( + name = 'Android FYI 64 Vk Release (Pixel 2)', + console_view_entry = ci.console_view_entry( + category = 'Android|vk|Q64', + short_name = 'P2', + ), +) + +ci.gpu_fyi_linux_builder( + name = 'Android FYI 64 dEQP Vk Release (Pixel 2)', + console_view_entry = ci.console_view_entry( + category = 'Android|dqp|vk|Q64', + short_name = 'P2', + ), +) + +ci.gpu_fyi_linux_builder( + name = 'Android FYI Release (NVIDIA Shield TV)', + console_view_entry = ci.console_view_entry( + category = 'Android|N64|NVDA', + short_name = 'STV', + ), +) + +ci.gpu_fyi_linux_builder( + name = 'Android FYI Release (Nexus 5)', + console_view_entry = ci.console_view_entry( + category = 'Android|L32', + short_name = 'N5', + ), +) + +ci.gpu_fyi_linux_builder( + name = 'Android FYI Release (Nexus 5X)', + console_view_entry = ci.console_view_entry( + category = 'Android|M64|QCOM', + short_name = 'N5X', + ), +) + +ci.gpu_fyi_linux_builder( + name = 'Android FYI Release (Nexus 6)', + console_view_entry = ci.console_view_entry( + category = 'Android|L32', + short_name = 'N6', + ), +) + +ci.gpu_fyi_linux_builder( + name = 'Android FYI Release (Nexus 6P)', + console_view_entry = ci.console_view_entry( + category = 'Android|M64|QCOM', + short_name = 'N6P', + ), +) + +ci.gpu_fyi_linux_builder( + name = 'Android FYI Release (Nexus 9)', + console_view_entry = ci.console_view_entry( + category = 'Android|M64|NVDA', + short_name = 'N9', + ), +) + +ci.gpu_fyi_linux_builder( + name = 'Android FYI Release (Pixel 2)', + console_view_entry = ci.console_view_entry( + category = 'Android|P32|QCOM', + short_name = 'P2', + ), +) + +ci.gpu_fyi_linux_builder( + name = 'Android FYI SkiaRenderer GL (Nexus 5X)', + console_view_entry = ci.console_view_entry( + category = 'Android|skgl|M64', + short_name = 'N5X', + ), +) + +ci.gpu_fyi_linux_builder( + name = 'Android FYI SkiaRenderer Vulkan (Pixel 2)', + console_view_entry = ci.console_view_entry( + category = 'Android|skv|P32', + short_name = 'P2', + ), +) + +ci.gpu_fyi_linux_builder( + name = 'Android FYI dEQP Release (Nexus 5X)', + console_view_entry = ci.console_view_entry( + category = 'Android|dqp|M64', + short_name = 'N5X', + ), +) + +ci.gpu_fyi_linux_builder( + name = 'ChromeOS FYI Release (amd64-generic)', + console_view_entry = ci.console_view_entry( + category = 'ChromeOS|amd64|generic', + short_name = 'x64' + ), +) + +ci.gpu_fyi_linux_builder( + name = 'ChromeOS FYI Release (kevin)', + console_view_entry = ci.console_view_entry( + category = 'ChromeOS|arm|kevin', + short_name = 'kvn' + ), +) + +ci.gpu_fyi_linux_builder( + name = 'GPU FYI Linux Builder', + console_view_entry = ci.console_view_entry( + category = 'Linux|Builder', + short_name = 'rel', + ), +) + +ci.gpu_fyi_linux_builder( + name = 'GPU FYI Linux Builder (dbg)', + console_view_entry = ci.console_view_entry( + category = 'Linux|Builder', + short_name = 'dbg', + ), +) + +ci.gpu_fyi_linux_builder( + name = 'GPU FYI Linux Ozone Builder', + console_view_entry = ci.console_view_entry( + category = 'Linux|Builder', + short_name = 'ozn', + ), +) + +ci.gpu_fyi_linux_builder( + name = 'GPU FYI Linux dEQP Builder', + console_view_entry = ci.console_view_entry( + category = 'Linux|Builder', + short_name = 'dqp', + ), +) + +ci.gpu_fyi_linux_builder( + name = 'GPU FYI Perf Android 64 Builder', + console_view_entry = ci.console_view_entry( + category = 'Android|Perf|Builder', + short_name = '64', + ), +) + +ci.gpu_fyi_linux_builder( + name = 'Linux FYI GPU TSAN Release', + console_view_entry = ci.console_view_entry( + category = 'Linux', + short_name = 'tsn', + ), +) + +# Builder + tester. +ci.gpu_fyi_linux_builder( + name = 'Linux FYI SkiaRenderer Dawn Release (Intel HD 630)', + console_view_entry = ci.console_view_entry( + category = 'Linux|Intel', + short_name = 'skd', + ), +) + + +ci.gpu_fyi_mac_builder( + name = 'Mac FYI GPU ASAN Release', + console_view_entry = ci.console_view_entry( + category = 'Mac', + short_name = 'asn', + ), +) + +ci.gpu_fyi_mac_builder( + name = 'GPU FYI Mac Builder', + console_view_entry = ci.console_view_entry( + category = 'Mac|Builder', + short_name = 'rel', + ), +) + +ci.gpu_fyi_mac_builder( + name = 'GPU FYI Mac Builder (dbg)', + console_view_entry = ci.console_view_entry( + category = 'Mac|Builder', + short_name = 'dbg', + ), +) + +ci.gpu_fyi_mac_builder( + name = 'GPU FYI Mac dEQP Builder', + console_view_entry = ci.console_view_entry( + category = 'Mac|Builder', + short_name = 'dqp', + ), +) + + +ci.gpu_fyi_thin_tester( + name = 'Linux FYI Debug (NVIDIA)', + console_view_entry = ci.console_view_entry( + category = 'Linux|Nvidia', + short_name = 'dbg', + ), + triggered_by = ['GPU FYI Linux Builder (dbg)'], +) + +ci.gpu_fyi_thin_tester( + name = 'Linux FYI Experimental Release (Intel HD 630)', + console_view_entry = ci.console_view_entry( + category = 'Linux|Intel', + short_name = 'exp', + ), + triggered_by = ['GPU FYI Linux Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Linux FYI Experimental Release (NVIDIA)', + console_view_entry = ci.console_view_entry( + category = 'Linux|Nvidia', + short_name = 'exp', + ), + triggered_by = ['GPU FYI Linux Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Linux FYI Ozone (Intel)', + console_view_entry = ci.console_view_entry( + category = 'Linux|Intel', + short_name = 'ozn', + ), + triggered_by = ['GPU FYI Linux Ozone Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Linux FYI Release (NVIDIA)', + console_view_entry = ci.console_view_entry( + category = 'Linux|Nvidia', + short_name = 'rel', + ), + triggered_by = ['GPU FYI Linux Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Linux FYI Release (AMD R7 240)', + console_view_entry = ci.console_view_entry( + category = 'Linux|AMD', + short_name = 'rel', + ), + triggered_by = ['GPU FYI Linux Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Linux FYI Release (Intel HD 630)', + console_view_entry = ci.console_view_entry( + category = 'Linux|Intel', + short_name = 'rel', + ), + triggered_by = ['GPU FYI Linux Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Linux FYI Release (Intel UHD 630)', + console_view_entry = ci.console_view_entry( + category = 'Linux|Intel', + short_name = 'uhd', + ), + # TODO(https://crbug.com/986939): Remove this increased timeout once more + # devices are added. + execution_timeout = 18 * time.hour, + triggered_by = ['GPU FYI Linux Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Linux FYI SkiaRenderer Vulkan (Intel HD 630)', + console_view_entry = ci.console_view_entry( + category = 'Linux|Intel', + short_name = 'skv', + ), + triggered_by = ['GPU FYI Linux Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Linux FYI SkiaRenderer Vulkan (NVIDIA)', + console_view_entry = ci.console_view_entry( + category = 'Linux|Nvidia', + short_name = 'skv', + ), + triggered_by = ['GPU FYI Linux Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Linux FYI dEQP Release (Intel HD 630)', + console_view_entry = ci.console_view_entry( + category = 'Linux|Intel', + short_name = 'dqp', + ), + triggered_by = ['GPU FYI Linux dEQP Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Linux FYI dEQP Release (NVIDIA)', + console_view_entry = ci.console_view_entry( + category = 'Linux|Nvidia', + short_name = 'dqp', + ), + triggered_by = ['GPU FYI Linux dEQP Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Mac FYI Debug (Intel)', + console_view_entry = ci.console_view_entry( + category = 'Mac|Intel', + short_name = 'dbg', + ), + triggered_by = ['GPU FYI Mac Builder (dbg)'], +) + +ci.gpu_fyi_thin_tester( + name = 'Mac FYI Experimental Release (Intel)', + console_view_entry = ci.console_view_entry( + category = 'Mac|Intel', + short_name = 'exp', + ), + triggered_by = ['GPU FYI Mac Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Mac FYI Experimental Retina Release (AMD)', + console_view_entry = ci.console_view_entry( + category = 'Mac|AMD|Retina', + short_name = 'exp', + ), + triggered_by = ['GPU FYI Mac Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Mac FYI Experimental Retina Release (NVIDIA)', + console_view_entry = ci.console_view_entry( + category = 'Mac|Nvidia', + short_name = 'exp', + ), + # This bot has one machine backing its tests at the moment. + # If it gets more, this can be removed. + # See crbug.com/853307 for more context. + execution_timeout = 12 * time.hour, + triggered_by = ['GPU FYI Mac Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Mac FYI Release (Intel)', + console_view_entry = ci.console_view_entry( + category = 'Mac|Intel', + short_name = 'rel', + ), + triggered_by = ['GPU FYI Mac Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Mac FYI Retina Debug (AMD)', + console_view_entry = ci.console_view_entry( + category = 'Mac|AMD|Retina', + short_name = 'dbg', + ), + triggered_by = ['GPU FYI Mac Builder (dbg)'], +) + +ci.gpu_fyi_thin_tester( + name = 'Mac FYI Retina Debug (NVIDIA)', + console_view_entry = ci.console_view_entry( + category = 'Mac|Nvidia', + short_name = 'dbg', + ), + triggered_by = ['GPU FYI Mac Builder (dbg)'], +) + +ci.gpu_fyi_thin_tester( + name = 'Mac FYI Retina Release (AMD)', + console_view_entry = ci.console_view_entry( + category = 'Mac|AMD|Retina', + short_name = 'rel', + ), + triggered_by = ['GPU FYI Mac Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Mac FYI Retina Release (NVIDIA)', + console_view_entry = ci.console_view_entry( + category = 'Mac|Nvidia', + short_name = 'rel', + ), + triggered_by = ['GPU FYI Mac Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Mac FYI dEQP Release AMD', + console_view_entry = ci.console_view_entry( + category = 'Mac|AMD', + short_name = 'dqp', + ), + triggered_by = ['GPU FYI Mac dEQP Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Mac FYI dEQP Release Intel', + console_view_entry = ci.console_view_entry( + category = 'Mac|Intel', + short_name = 'dqp', + ), + triggered_by = ['GPU FYI Mac dEQP Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Mac Pro FYI Release (AMD)', + console_view_entry = ci.console_view_entry( + category = 'Mac|AMD|Pro', + short_name = 'rel', + ), + triggered_by = ['GPU FYI Mac Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Win10 FYI x64 Debug (NVIDIA)', + console_view_entry = ci.console_view_entry( + category = 'Windows|10|x64|Nvidia', + short_name = 'dbg', + ), + triggered_by = ['GPU FYI Win x64 Builder (dbg)'], +) + +ci.gpu_fyi_thin_tester( + name = 'Win10 FYI x64 DX12 Vulkan Debug (NVIDIA)', + console_view_entry = ci.console_view_entry( + category = 'Windows|10|x64|Nvidia|dx12vk', + short_name = 'dbg', + ), + triggered_by = ['GPU FYI Win x64 DX12 Vulkan Builder (dbg)'], +) + +ci.gpu_fyi_thin_tester( + name = 'Win10 FYI x64 DX12 Vulkan Release (NVIDIA)', + console_view_entry = ci.console_view_entry( + category = 'Windows|10|x64|Nvidia|dx12vk', + short_name = 'rel', + ), + triggered_by = ['GPU FYI Win x64 DX12 Vulkan Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Win10 FYI x64 Exp Release (Intel HD 630)', + console_view_entry = ci.console_view_entry( + category = 'Windows|10|x64|Intel', + short_name = 'exp', + ), + triggered_by = ['GPU FYI Win x64 Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Win10 FYI x64 Exp Release (NVIDIA)', + console_view_entry = ci.console_view_entry( + category = 'Windows|10|x64|Nvidia', + short_name = 'exp', + ), + triggered_by = ['GPU FYI Win x64 Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Win10 FYI x64 Release (AMD RX 550)', + console_view_entry = ci.console_view_entry( + category = 'Windows|10|x64|AMD', + short_name = 'rel', + ), + triggered_by = ['GPU FYI Win x64 Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Win10 FYI x64 Release (Intel HD 630)', + console_view_entry = ci.console_view_entry( + category = 'Windows|10|x64|Intel', + short_name = 'rel', + ), + triggered_by = ['GPU FYI Win x64 Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Win10 FYI x64 Release (Intel UHD 630)', + console_view_entry = ci.console_view_entry( + category = 'Windows|10|x64|Intel', + short_name = 'uhd', + ), + # TODO(https://crbug.com/986939): Remove this increased timeout once + # more devices are added. + execution_timeout = 18 * time.hour, + triggered_by = ['GPU FYI Win x64 Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Win10 FYI x64 Release (NVIDIA GeForce GTX 1660)', + console_view_entry = ci.console_view_entry( + category = 'Windows|10|x64|Nvidia', + short_name = 'gtx', + ), + execution_timeout = 18 * time.hour, + triggered_by = ['GPU FYI Win x64 Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Win10 FYI x64 Release (NVIDIA)', + console_view_entry = ci.console_view_entry( + category = 'Windows|10|x64|Nvidia', + short_name = 'rel', + ), + triggered_by = ['GPU FYI Win x64 Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Win10 FYI x64 Release XR Perf (NVIDIA)', + console_view_entry = ci.console_view_entry( + category = 'Windows|10|x64|Nvidia', + short_name = 'xr', + ), + triggered_by = ['GPU FYI XR Win x64 Builder'], +) + +# Builder + tester. +ci.gpu_fyi_windows_builder( + name = 'Win10 FYI x64 SkiaRenderer Dawn Release (NVIDIA)', + console_view_entry = ci.console_view_entry( + category = 'Windows|10|x64|Nvidia', + short_name = 'skd', + ), +) + +ci.gpu_fyi_thin_tester( + name = 'Win10 FYI x64 SkiaRenderer GL (NVIDIA)', + console_view_entry = ci.console_view_entry( + category = 'Windows|10|x64|Nvidia', + short_name = 'skgl', + ), + triggered_by = ['GPU FYI Win x64 Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Win10 FYI x64 dEQP Release (Intel HD 630)', + console_view_entry = ci.console_view_entry( + category = 'Windows|10|x64|Intel', + short_name = 'dqp', + ), + triggered_by = ['GPU FYI Win x64 dEQP Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Win10 FYI x64 dEQP Release (NVIDIA)', + console_view_entry = ci.console_view_entry( + category = 'Windows|10|x64|Nvidia', + short_name = 'dqp', + ), + triggered_by = ['GPU FYI Win x64 dEQP Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Win10 FYI x86 Release (NVIDIA)', + console_view_entry = ci.console_view_entry( + category = 'Windows|10|x86|Nvidia', + short_name = 'rel', + ), + triggered_by = ['GPU FYI Win Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Win7 FYI Debug (AMD)', + console_view_entry = ci.console_view_entry( + category = 'Windows|7|x86|AMD', + short_name = 'dbg', + ), + triggered_by = ['GPU FYI Win Builder (dbg)'], +) + +ci.gpu_fyi_thin_tester( + name = 'Win7 FYI Release (AMD)', + console_view_entry = ci.console_view_entry( + category = 'Windows|7|x86|AMD', + short_name = 'rel', + ), + triggered_by = ['GPU FYI Win Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Win7 FYI Release (NVIDIA)', + console_view_entry = ci.console_view_entry( + category = 'Windows|7|x86|Nvidia', + short_name = 'rel', + ), + triggered_by = ['GPU FYI Win Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Win7 FYI dEQP Release (AMD)', + console_view_entry = ci.console_view_entry( + category = 'Windows|7|x86|AMD', + short_name = 'dqp', + ), + triggered_by = ['GPU FYI Win dEQP Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Win7 FYI x64 Release (NVIDIA)', + console_view_entry = ci.console_view_entry( + category = 'Windows|7|x64|Nvidia', + short_name = 'rel', + ), + triggered_by = ['GPU FYI Win x64 Builder'], +) + +ci.gpu_fyi_thin_tester( + name = 'Win7 FYI x64 dEQP Release (NVIDIA)', + console_view_entry = ci.console_view_entry( + category = 'Windows|7|x64|Nvidia', + short_name = 'dqp', + ), + triggered_by = ['GPU FYI Win x64 dEQP Builder'], +) + + +ci.gpu_fyi_windows_builder( + name = 'GPU FYI Win Builder', + console_view_entry = ci.console_view_entry( + category = 'Windows|Builder|Release', + short_name = 'x86', + ), +) + +ci.gpu_fyi_windows_builder( + name = 'GPU FYI Win Builder (dbg)', + console_view_entry = ci.console_view_entry( + category = 'Windows|Builder|Debug', + short_name = 'x86', + ), +) + +ci.gpu_fyi_windows_builder( + name = 'GPU FYI Win dEQP Builder', + console_view_entry = ci.console_view_entry( + category = 'Windows|Builder|dEQP', + short_name = 'x86', + ), +) + +ci.gpu_fyi_windows_builder( + name = 'GPU FYI Win x64 Builder', + console_view_entry = ci.console_view_entry( + category = 'Windows|Builder|Release', + short_name = 'x64', + ), +) + +ci.gpu_fyi_windows_builder( + name = 'GPU FYI Win x64 Builder (dbg)', + console_view_entry = ci.console_view_entry( + category = 'Windows|Builder|Debug', + short_name = 'x64', + ), +) + +ci.gpu_fyi_windows_builder( + name = 'GPU FYI Win x64 dEQP Builder', + console_view_entry = ci.console_view_entry( + category = 'Windows|Builder|dEQP', + short_name = 'x64', + ), +) + +ci.gpu_fyi_windows_builder( + name = 'GPU FYI Win x64 DX12 Vulkan Builder', + console_view_entry = ci.console_view_entry( + category = 'Windows|Builder|dx12vk', + short_name = 'rel', + ), +) + +ci.gpu_fyi_windows_builder( + name = 'GPU FYI Win x64 DX12 Vulkan Builder (dbg)', + console_view_entry = ci.console_view_entry( + category = 'Windows|Builder|dx12vk', + short_name = 'dbg', + ), +) + +ci.gpu_fyi_windows_builder( + name = 'GPU FYI XR Win x64 Builder', + console_view_entry = ci.console_view_entry( + category = 'Windows|Builder|XR', + short_name = 'x64', + ), +) + + +ci.linux_builder( + name = 'Cast Audio Linux', + console_view_entry = ci.console_view_entry( + category = 'cast', + short_name = 'aud', + ), + ssd = True, +) + +ci.linux_builder( + name = 'Deterministic Fuchsia (dbg)', + console_view_entry = ci.console_view_entry( + category = 'fuchsia|x64', + short_name = 'det', + ), + executable = 'recipe:swarming/deterministic_build', + execution_timeout = 6 * time.hour, + goma_jobs = None, +) + +ci.linux_builder( + name = 'Deterministic Linux', + console_view_entry = ci.console_view_entry( + category = 'release', + short_name = 'det', + ), + executable = 'recipe:swarming/deterministic_build', + execution_timeout = 6 * time.hour, +) + +ci.linux_builder( + name = 'Deterministic Linux (dbg)', + console_view_entry = ci.console_view_entry( + category = 'debug|builder', + short_name = 'det', + ), + cores = 32, + executable = 'recipe:swarming/deterministic_build', + execution_timeout = 6 * time.hour, +) + +ci.linux_builder( + name = 'Leak Detection Linux', + console_view = 'chromium.fyi', + console_view_entry = ci.console_view_entry( + category = 'linux', + short_name = 'lk', + ), +) + +ci.linux_builder( + name = 'Linux Builder (dbg)(32)', + console_view_entry = ci.console_view_entry( + category = 'debug|builder', + short_name = '32', + ), +) + +ci.linux_builder( + name = 'Network Service Linux', + console_view_entry = ci.console_view_entry( + category = 'release', + short_name = 'nsl', + ), +) + +ci.linux_builder( + name = 'fuchsia-x64-dbg', + console_view_entry = ci.console_view_entry( + category = 'fuchsia|x64', + short_name = 'dbg', + ), + notifies = ['cr-fuchsia'], +) + +ci.linux_builder( + name = 'linux-gcc-rel', + console_view_entry = ci.console_view_entry( + category = 'release', + short_name = 'gcc', + ), + goma_backend = None, +) + +ci.linux_builder( + name = 'linux-trusty-rel', + console_view_entry = ci.console_view_entry( + category = 'release', + short_name = 'tru', + ), + os = os.LINUX_TRUSTY, +) + +ci.linux_builder( + name = 'linux_chromium_component_updater', + executable = 'recipe:findit/chromium/update_components', + schedule = '0 0,6,12,18 * * *', + service_account = 'component-mapping-updater@chops-service-accounts.iam.gserviceaccount.com', + triggered_by = [], +) + + +ci.mac_ios_builder( + name = 'ios-device', + console_view_entry = ci.console_view_entry( + category = 'ios|default', + short_name = 'dev', + ), + executable = 'recipe:chromium', + # We don't have necessary capacity to run this configuration in CQ, but it + # is part of the main waterfall + main_console_view = 'main', +) + +ci.mac_ios_builder( + name = 'ios-simulator-noncq', + console_view_entry = ci.console_view_entry( + category = 'ios|default', + short_name = 'non', + ), + # We don't have necessary capacity to run this configuration in CQ, but it + # is part of the main waterfall + main_console_view = 'main', +) + + +ci.memory_builder( + name = 'Android CFI', + # TODO(https://crbug.com/1008094) When this builder is not consistently + # failing, remove the console_view value + console_view = 'chromium.android.fyi', + console_view_entry = ci.console_view_entry( + category = 'memory', + short_name = 'cfi', + ), + cores = 32, + # TODO(https://crbug.com/919430) Remove the larger timeout once compile + # times have been brought down to reasonable level + execution_timeout = time.hour * 9 / 2, # 4.5 (can't multiply float * duration) +) + +ci.memory_builder( + name = 'Linux CFI', + console_view_entry = ci.console_view_entry( + category = 'cfi', + short_name = 'lnx', + ), + cores = 32, + # TODO(thakis): Remove once https://crbug.com/927738 is resolved. + execution_timeout = 4 * time.hour, + goma_jobs = goma.jobs.MANY_JOBS_FOR_CI, +) + +ci.memory_builder( + name = 'Linux Chromium OS ASan LSan Builder', + console_view_entry = ci.console_view_entry( + category = 'cros|asan', + short_name = 'bld', + ), + # TODO(crbug.com/1030593): Builds take more than 3 hours sometimes. Remove + # once the builds are faster. + execution_timeout = 6 * time.hour, +) + +ci.memory_builder( + name = 'Linux Chromium OS ASan LSan Tests (1)', + console_view_entry = ci.console_view_entry( + category = 'cros|asan', + short_name = 'tst', + ), + triggered_by = ['Linux Chromium OS ASan LSan Builder'], +) + +ci.memory_builder( + name = 'Linux ChromiumOS MSan Builder', + console_view_entry = ci.console_view_entry( + category = 'cros|msan', + short_name = 'bld', + ), +) + +ci.memory_builder( + name = 'Linux ChromiumOS MSan Tests', + console_view_entry = ci.console_view_entry( + category = 'cros|msan', + short_name = 'tst', + ), + triggered_by = ['Linux ChromiumOS MSan Builder'], +) + +ci.memory_builder( + name = 'Linux MSan Builder', + console_view_entry = ci.console_view_entry( + category = 'linux|msan', + short_name = 'bld', + ), + goma_jobs = goma.jobs.MANY_JOBS_FOR_CI, +) + +ci.memory_builder( + name = 'Linux MSan Tests', + console_view_entry = ci.console_view_entry( + category = 'linux|msan', + short_name = 'tst', + ), + triggered_by = ['Linux MSan Builder'], +) + +ci.memory_builder( + name = 'Mac ASan 64 Builder', + builderless = False, + console_view_entry = ci.console_view_entry( + category = 'mac', + short_name = 'bld', + ), + goma_debug = True, # TODO(hinoka): Remove this after debugging. + goma_jobs = None, + cores = None, # Swapping between 8 and 24 + os = os.MAC_DEFAULT, + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 2, + ), +) + +ci.memory_builder( + name = 'Mac ASan 64 Tests (1)', + builderless = False, + console_view_entry = ci.console_view_entry( + category = 'mac', + short_name = 'tst', + ), + os = os.MAC_DEFAULT, + triggered_by = ['Mac ASan 64 Builder'], +) + +ci.memory_builder( + name = 'WebKit Linux ASAN', + console_view_entry = ci.console_view_entry( + category = 'linux|webkit', + short_name = 'asn', + ), +) + +ci.memory_builder( + name = 'WebKit Linux Leak', + console_view_entry = ci.console_view_entry( + category = 'linux|webkit', + short_name = 'lk', + ), +) + +ci.memory_builder( + name = 'WebKit Linux MSAN', + console_view_entry = ci.console_view_entry( + category = 'linux|webkit', + short_name = 'msn', + ), +) + +ci.memory_builder( + name = 'android-asan', + console_view_entry = ci.console_view_entry( + category = 'android', + short_name = 'asn', + ), +) + +ci.memory_builder( + name = 'win-asan', + console_view_entry = ci.console_view_entry( + category = 'win', + short_name = 'asn', + ), + cores = 32, + builderless = True, + os = os.WINDOWS_DEFAULT, +) + + +ci.swangle_linux_builder( + name = 'linux-swangle-chromium-x64', + console_view_entry = ci.console_view_entry( + category = 'Chromium|Linux', + short_name = 'x64', + ), +) + +ci.swangle_linux_builder( + name = 'linux-swangle-tot-angle-x64', + console_view_entry = ci.console_view_entry( + category = 'ToT ANGLE|Linux', + short_name = 'x64', + ), +) + +ci.swangle_linux_builder( + name = 'linux-swangle-tot-angle-x86', + console_view_entry = ci.console_view_entry( + category = 'ToT ANGLE|Linux', + short_name = 'x86', + ), +) + +ci.swangle_linux_builder( + name = 'linux-swangle-tot-swiftshader-x64', + console_view_entry = ci.console_view_entry( + category = 'ToT SwiftShader|Linux', + short_name = 'x64', + ), +) + +ci.swangle_linux_builder( + name = 'linux-swangle-tot-swiftshader-x86', + console_view_entry = ci.console_view_entry( + category = 'ToT SwiftShader|Linux', + short_name = 'x86', + ), +) + +ci.swangle_linux_builder( + name = 'linux-swangle-x64', + console_view_entry = ci.console_view_entry( + category = 'DEPS|Linux', + short_name = 'x64', + ), +) + +ci.swangle_linux_builder( + name = 'linux-swangle-x86', + console_view_entry = ci.console_view_entry( + category = 'DEPS|Linux', + short_name = 'x86', + ), +) + + +ci.swangle_mac_builder( + name = 'mac-swangle-chromium-x64', + console_view_entry = ci.console_view_entry( + category = 'Chromium|Mac', + short_name = 'x64', + ), +) + + +ci.swangle_windows_builder( + name = 'win-swangle-chromium-x86', + console_view_entry = ci.console_view_entry( + category = 'Chromium|Windows', + short_name = 'x86', + ), +) + +ci.swangle_windows_builder( + name = 'win-swangle-tot-angle-x64', + console_view_entry = ci.console_view_entry( + category = 'ToT ANGLE|Windows', + short_name = 'x64', + ), +) + +ci.swangle_windows_builder( + name = 'win-swangle-tot-angle-x86', + console_view_entry = ci.console_view_entry( + category = 'ToT ANGLE|Windows', + short_name = 'x86', + ), +) + +ci.swangle_windows_builder( + name = 'win-swangle-tot-swiftshader-x64', + console_view_entry = ci.console_view_entry( + category = 'ToT SwiftShader|Windows', + short_name = 'x64', + ), +) + +ci.swangle_windows_builder( + name = 'win-swangle-tot-swiftshader-x86', + console_view_entry = ci.console_view_entry( + category = 'ToT SwiftShader|Windows', + short_name = 'x86', + ), +) + +ci.swangle_windows_builder( + name = 'win-swangle-x64', + console_view_entry = ci.console_view_entry( + category = 'DEPS|Windows', + short_name = 'x64', + ), +) + +ci.swangle_windows_builder( + name = 'win-swangle-x86', + console_view_entry = ci.console_view_entry( + category = 'DEPS|Windows', + short_name = 'x86', + ), +) + + +ci.win_builder( + name = 'WebKit Win10', + console_view_entry = ci.console_view_entry( + category = 'misc', + short_name = 'wbk', + ), + triggered_by = ['Win Builder'], +) + +ci.win_builder( + name = 'Win Builder', + console_view_entry = ci.console_view_entry( + category = 'release|builder', + short_name = '32', + ), + cores = 32, + os = os.WINDOWS_ANY, +) + +ci.win_builder( + name = 'Win x64 Builder (dbg)', + console_view_entry = ci.console_view_entry( + category = 'debug|builder', + short_name = '64', + ), + cores = 32, + builderless = True, + os = os.WINDOWS_ANY, +) + +ci.win_builder( + name = 'Win10 Tests x64 (dbg)', + console_view_entry = ci.console_view_entry( + category = 'debug|tester', + short_name = '10', + ), + triggered_by = ['Win x64 Builder (dbg)'], +) + +ci.win_builder( + name = 'Win7 (32) Tests', + console_view_entry = ci.console_view_entry( + category = 'release|tester', + short_name = '32', + ), + os = os.WINDOWS_7, + triggered_by = ['Win Builder'], +) + +ci.win_builder( + name = 'Win7 Tests (1)', + console_view_entry = ci.console_view_entry( + category = 'release|tester', + short_name = '32', + ), + os = os.WINDOWS_7, + triggered_by = ['Win Builder'], +) + +ci.win_builder( + name = 'Windows deterministic', + console_view_entry = ci.console_view_entry( + category = 'misc', + short_name = 'det', + ), + executable = 'recipe:swarming/deterministic_build', + execution_timeout = 6 * time.hour, +)
diff --git a/infra/config/subprojects/chromium/consoles/android.packager.star b/infra/config/subprojects/chromium/master-only/consoles/android.packager.star similarity index 100% rename from infra/config/subprojects/chromium/consoles/android.packager.star rename to infra/config/subprojects/chromium/master-only/consoles/android.packager.star
diff --git a/infra/config/subprojects/chromium/consoles/luci.chromium.try.star b/infra/config/subprojects/chromium/master-only/consoles/luci.chromium.try.star similarity index 100% rename from infra/config/subprojects/chromium/consoles/luci.chromium.try.star rename to infra/config/subprojects/chromium/master-only/consoles/luci.chromium.try.star
diff --git a/infra/config/subprojects/chromium/consoles/sheriff.ios.star b/infra/config/subprojects/chromium/master-only/consoles/sheriff.ios.star similarity index 100% rename from infra/config/subprojects/chromium/consoles/sheriff.ios.star rename to infra/config/subprojects/chromium/master-only/consoles/sheriff.ios.star
diff --git a/infra/config/subprojects/chromium/gpu.try.star b/infra/config/subprojects/chromium/master-only/gpu.try.star similarity index 99% rename from infra/config/subprojects/chromium/gpu.try.star rename to infra/config/subprojects/chromium/master-only/gpu.try.star index a7cd88f..fb3e8cf 100644 --- a/infra/config/subprojects/chromium/gpu.try.star +++ b/infra/config/subprojects/chromium/master-only/gpu.try.star
@@ -1,10 +1,10 @@ load('//lib/builders.star', 'builder', 'cpu', 'defaults', 'goma', 'os') load('//lib/try.star', 'try_') -load('./versioned/trunk/vars.star', 'vars') +load('//project.star', 'settings') try_.set_defaults( - vars, + settings, execution_timeout = 6 * time.hour, service_account = 'chromium-try-gpu-builder@chops-service-accounts.iam.gserviceaccount.com', )
diff --git a/infra/config/subprojects/chromium/master-only/main.star b/infra/config/subprojects/chromium/master-only/main.star new file mode 100644 index 0000000..c0cff46 --- /dev/null +++ b/infra/config/subprojects/chromium/master-only/main.star
@@ -0,0 +1,7 @@ +exec('./ci.star') +exec('./gpu.try.star') +exec('./swangle.try.star') +exec('./try.star') +exec('./consoles/android.packager.star') +exec('./consoles/luci.chromium.try.star') +exec('./consoles/sheriff.ios.star')
diff --git a/infra/config/subprojects/chromium/swangle.try.star b/infra/config/subprojects/chromium/master-only/swangle.try.star similarity index 97% rename from infra/config/subprojects/chromium/swangle.try.star rename to infra/config/subprojects/chromium/master-only/swangle.try.star index 20cc627..655939b 100644 --- a/infra/config/subprojects/chromium/swangle.try.star +++ b/infra/config/subprojects/chromium/master-only/swangle.try.star
@@ -1,10 +1,10 @@ load('//lib/builders.star', 'builder', 'cpu', 'defaults', 'goma', 'os') load('//lib/try.star', 'try_') -load('./versioned/trunk/vars.star', 'vars') +load('//project.star', 'settings') try_.set_defaults( - vars, + settings, execution_timeout = 2 * time.hour, service_account = 'chromium-try-gpu-builder@chops-service-accounts.iam.gserviceaccount.com', )
diff --git a/infra/config/subprojects/chromium/master-only/try.star b/infra/config/subprojects/chromium/master-only/try.star new file mode 100644 index 0000000..17987c4 --- /dev/null +++ b/infra/config/subprojects/chromium/master-only/try.star
@@ -0,0 +1,750 @@ +load('//lib/builders.star', 'cpu', 'goma', 'os', 'xcode_cache') +load('//lib/try.star', 'try_') +load('//project.star', 'settings') + +# Execute the versioned files to define all of the per-branch entities +# (bucket, builders, console, cq_group, etc.) +exec('../versioned/m81/buckets/try.star') +exec('../versioned/m83/buckets/try.star') + + +try_.set_defaults( + settings, + add_to_list_view = True, +) + + +# *** After this point everything is trunk only *** + +[try_.list_view( + name = name, +) for name in ( + 'tryserver.blink', + 'tryserver.chromium.android', + 'tryserver.chromium.angle', + 'tryserver.chromium.chromiumos', + 'tryserver.chromium.dawn', + 'tryserver.chromium.linux', + 'tryserver.chromium.mac', + 'tryserver.chromium.swangle', + 'tryserver.chromium.win', +)] + + +# Builders are sorted first lexicographically by the function used to define +# them, then lexicographically by their name + + +try_.blink_builder( + name = 'win10-blink-rel', + goma_backend = goma.backend.RBE_PROD, + os = os.WINDOWS_ANY, + builderless = True, +) + +try_.blink_builder( + name = 'win7-blink-rel', + goma_backend = goma.backend.RBE_PROD, + os = os.WINDOWS_ANY, + builderless = True, +) + + +try_.blink_mac_builder( + name = 'mac10.10-blink-rel', +) + +try_.blink_mac_builder( + name = 'mac10.11-blink-rel', +) + +try_.blink_mac_builder( + name = 'mac10.12-blink-rel', +) + +try_.blink_mac_builder( + name = 'mac10.13-blink-rel', +) + +try_.blink_mac_builder( + name = 'mac10.13_retina-blink-rel', +) + +try_.blink_mac_builder( + name = 'mac10.14-blink-rel', +) + +try_.blink_mac_builder( + name = 'mac10.15-blink-rel', +) + + +try_.chromium_android_builder( + name = 'android-asan', +) + +try_.chromium_android_builder( + name = 'android-bfcache-rel', +) + +try_.chromium_android_builder( + name = 'android-deterministic-dbg', + executable = 'recipe:swarming/deterministic_build', + execution_timeout = 6 * time.hour, +) + +try_.chromium_android_builder( + name = 'android-deterministic-rel', + executable = 'recipe:swarming/deterministic_build', + execution_timeout = 6 * time.hour, +) + +try_.chromium_android_builder( + name = 'android-marshmallow-x86-fyi-rel', +) + +try_.chromium_android_builder( + name = 'android-opus-arm-rel', +) + +try_.chromium_android_builder( + name = 'android-oreo-arm64-cts-networkservice-dbg', +) + +try_.chromium_android_builder( + name = 'android-oreo-arm64-dbg', +) + +try_.chromium_android_builder( + name = 'android-pie-x86-rel', + goma_jobs=goma.jobs.J150, +) + +try_.chromium_android_builder( + name = 'android-pie-arm64-coverage-rel', + cores = 16, + goma_jobs = goma.jobs.J300, + ssd = True, + use_clang_coverage = True, +) + +try_.chromium_android_builder( + name = 'android-10-arm64-rel', +) + +try_.chromium_android_builder( + name = 'android-weblayer-pie-arm64-fyi-rel', +) + +try_.chromium_android_builder( + name = 'android-weblayer-pie-x86-fyi-rel', +) + +try_.chromium_android_builder( + name = 'android-webview-marshmallow-arm64-dbg', +) + +try_.chromium_android_builder( + name = 'android-webview-nougat-arm64-dbg', +) + +try_.chromium_android_builder( + name = 'android-webview-oreo-arm64-dbg', +) + +try_.chromium_android_builder( + name = 'android-webview-pie-arm64-dbg', +) + +try_.chromium_android_builder( + name = 'android-webview-pie-arm64-fyi-rel', +) + +try_.chromium_android_builder( + name = 'android_archive_rel_ng', +) + +try_.chromium_android_builder( + name = 'android_arm64_dbg_recipe', + goma_jobs = goma.jobs.J300, +) + +try_.chromium_android_builder( + name = 'android_blink_rel', +) + +try_.chromium_android_builder( + name = 'android_cfi_rel_ng', + cores = 32, +) + +try_.chromium_android_builder( + name = 'android_clang_dbg_recipe', + goma_jobs = goma.jobs.J300, +) + +try_.chromium_android_builder( + name = 'android_cronet_tester', + properties = { + 'buildername': 'android-cronet-arm-dbg', + }, +) + +try_.chromium_android_builder( + name = 'android_mojo', +) + +try_.chromium_android_builder( + name = 'android_n5x_swarming_dbg', +) + +try_.chromium_android_builder( + name = 'android_unswarmed_pixel_aosp', +) + +try_.chromium_android_builder( + name = 'linux_android_dbg_ng', +) + +try_.chromium_android_builder( + name = 'try-nougat-phone-tester', +) + + +try_.chromium_angle_builder( + name = 'android_angle_deqp_rel_ng', +) + +try_.chromium_angle_builder( + name = 'android_angle_rel_ng', +) + +try_.chromium_angle_builder( + name = 'android_angle_vk32_deqp_rel_ng', +) + +try_.chromium_angle_builder( + name = 'android_angle_vk32_rel_ng', +) + +try_.chromium_angle_builder( + name = 'android_angle_vk64_deqp_rel_ng', +) + +try_.chromium_angle_builder( + name = 'android_angle_vk64_rel_ng', +) + +try_.chromium_angle_builder( + name = 'fuchsia-angle-rel', +) + +try_.chromium_angle_builder( + name = 'linux-angle-rel', +) + +try_.chromium_angle_builder( + name = 'linux_angle_deqp_rel_ng', +) + +try_.chromium_angle_builder( + name = 'linux_angle_ozone_rel_ng', +) + +try_.chromium_angle_builder( + name = 'mac-angle-rel', + cores = None, + os = os.MAC_ANY, +) + +try_.chromium_angle_builder( + name = 'win-angle-deqp-rel-32', + os = os.WINDOWS_ANY, +) + +try_.chromium_angle_builder( + name = 'win-angle-deqp-rel-64', + os = os.WINDOWS_ANY, +) + +try_.chromium_angle_builder( + name = 'win-angle-rel-32', + os = os.WINDOWS_ANY, +) + +try_.chromium_angle_builder( + name = 'win-angle-rel-64', + os = os.WINDOWS_ANY, +) + + +try_.chromium_chromiumos_builder( + name = 'chromeos-amd64-generic-cfi-thin-lto-rel', +) + +try_.chromium_chromiumos_builder( + name = 'chromeos-arm-generic-dbg', +) + +try_.chromium_chromiumos_builder( + name = 'linux-chromeos-dbg', +) + + +try_.chromium_dawn_builder( + name = 'linux-dawn-rel', +) + +try_.chromium_dawn_builder( + name = 'mac-dawn-rel', + os = os.MAC_ANY, +) + +try_.chromium_dawn_builder( + name = 'win-dawn-rel', + os = os.WINDOWS_ANY, +) + + +try_.chromium_linux_builder( + name = 'cast_shell_audio_linux', +) + +try_.chromium_linux_builder( + name = 'fuchsia-compile-x64-dbg', + tryjob = try_.job( + experiment_percentage = 50, + ), +) + +try_.chromium_linux_builder( + name = 'fuchsia-fyi-arm64-rel', +) + +try_.chromium_linux_builder( + name = 'fuchsia-fyi-x64-dbg', +) + +try_.chromium_linux_builder( + name = 'fuchsia-fyi-x64-rel', +) + +try_.chromium_linux_builder( + name = 'layout_test_leak_detection', +) + +try_.chromium_linux_builder( + name = 'leak_detection_linux', +) + +try_.chromium_linux_builder( + name = 'linux-annotator-rel', +) + +try_.chromium_linux_builder( + name = 'linux-bfcache-rel', +) + +try_.chromium_linux_builder( + name = 'linux-blink-heap-concurrent-marking-tsan-rel', +) + +try_.chromium_linux_builder( + name = 'linux-blink-heap-verification-try', +) + +try_.chromium_linux_builder( + name = 'linux-clang-tidy-dbg', + executable = 'recipe:tricium_clang_tidy_wrapper', + goma_jobs = goma.jobs.J150, +) + +try_.chromium_linux_builder( + name = 'linux-clang-tidy-rel', + executable = 'recipe:tricium_clang_tidy_wrapper', + goma_jobs = goma.jobs.J150, +) + +try_.chromium_linux_builder( + name = 'linux-dcheck-off-rel', +) + +try_.chromium_linux_builder( + name = 'linux-gcc-rel', + goma_backend = None, +) + +try_.chromium_linux_builder( + name = 'linux-perfetto-rel', + tryjob = try_.job( + experiment_percentage = 100, + location_regexp = [ + '.+/[+]/base/trace_event/.+', + '.+/[+]/base/tracing/.+', + '.+/[+]/components/tracing/.+', + '.+/[+]/content/browser/tracing/.+', + '.+/[+]/services/tracing/.+', + ], + ), +) + +try_.chromium_linux_builder( + name = 'linux-trusty-rel', + goma_jobs = goma.jobs.J150, + os = os.LINUX_TRUSTY, +) + +try_.chromium_linux_builder( + name = 'linux-viz-rel', +) + +try_.chromium_linux_builder( + name = 'linux-webkit-msan-rel', +) + +try_.chromium_linux_builder( + name = 'linux_chromium_analysis', +) + +try_.chromium_linux_builder( + name = 'linux_chromium_archive_rel_ng', +) + +try_.chromium_linux_builder( + name = 'linux_chromium_cfi_rel_ng', + cores = 32, +) + +try_.chromium_linux_builder( + name = 'linux_chromium_chromeos_asan_rel_ng', + goma_jobs = goma.jobs.J150, +) + +try_.chromium_linux_builder( + name = 'linux_chromium_chromeos_msan_rel_ng', + goma_jobs = goma.jobs.J150, +) + +try_.chromium_linux_builder( + name = 'linux_chromium_clobber_deterministic', + executable = 'recipe:swarming/deterministic_build', + execution_timeout = 6 * time.hour, +) + +try_.chromium_linux_builder( + name = 'linux_chromium_clobber_rel_ng', +) + +try_.chromium_linux_builder( + name = 'linux_chromium_compile_dbg_32_ng', +) + +try_.chromium_linux_builder( + name = 'linux_chromium_compile_rel_ng', +) + +try_.chromium_linux_builder( + name = 'linux_chromium_msan_rel_ng', + goma_jobs = goma.jobs.J150, +) + +try_.chromium_linux_builder( + name = 'linux_chromium_ubsan_rel_ng', +) + +try_.chromium_linux_builder( + name = 'linux-layout-tests-edit-ng', +) + +try_.chromium_linux_builder( + name = 'linux-autofill-assistant', +) + +try_.chromium_linux_builder( + name = 'linux-layout-tests-fragment-item', +) + +try_.chromium_linux_builder( + name = 'linux_mojo', +) + +try_.chromium_linux_builder( + name = 'linux_mojo_chromeos', +) + +try_.chromium_linux_builder( + name = 'linux_upload_clang', + builderless = True, + cores = 32, + executable = 'recipe:chromium_upload_clang', + goma_backend = None, + os = os.LINUX_TRUSTY, +) + +try_.chromium_linux_builder( + name = 'linux-wpt-fyi-rel', +) + +try_.chromium_linux_builder( + name = 'tricium-metrics-analysis', + executable = 'recipe:tricium_metrics', +) + + +try_.chromium_mac_builder( + name = 'mac-coverage-rel', + use_clang_coverage = True, + goma_jobs = goma.jobs.J150, + tryjob = try_.job(experiment_percentage = 3) +) + +try_.chromium_mac_builder( + name = 'mac-osxbeta-rel', + os = os.MAC_DEFAULT, +) + +# NOTE: the following trybots aren't sensitive to Mac version on which +# they are built, hence no additional dimension is specified. +# The 10.xx version translates to which bots will run isolated tests. +try_.chromium_mac_builder( + name = 'mac_chromium_10.10', +) + +try_.chromium_mac_builder( + name = 'mac_chromium_10.12_rel_ng', +) + +try_.chromium_mac_builder( + name = 'mac_chromium_10.13_rel_ng', +) + +try_.chromium_mac_builder( + name = 'mac_chromium_10.14_rel_ng', +) + +try_.chromium_mac_builder( + name = 'mac_chromium_10.15_rel_ng', +) + +try_.chromium_mac_builder( + name = 'mac_chromium_archive_rel_ng', +) + +try_.chromium_mac_builder( + name = 'mac_chromium_asan_rel_ng', + goma_jobs = goma.jobs.J150, +) + +try_.chromium_mac_builder( + name = 'mac_chromium_compile_rel_ng', +) + +try_.chromium_mac_builder( + name = 'mac_chromium_dbg_ng', +) + +try_.chromium_mac_builder( + name = 'mac_upload_clang', + builderless = False, + caches = [ + swarming.cache( + name = 'xcode_mac_9a235', + path = 'xcode_mac_9a235.app', + ), + ], + executable = 'recipe:chromium_upload_clang', + execution_timeout = 6 * time.hour, + goma_backend = None, # Does not use Goma. + properties = { + '$depot_tools/osx_sdk': { + 'sdk_version': '9a235', + }, + }, +) + + +try_.chromium_mac_ios_builder( + name = 'ios-device', + executable = 'recipe:chromium_trybot', +) + +try_.chromium_mac_ios_builder( + name = 'ios-simulator-code-coverage', + executable = 'recipe:chromium_trybot', + use_clang_coverage = True, + properties = { + 'coverage_exclude_sources': 'ios_test_files_and_test_utils', + 'coverage_test_types': ['unit'], + 'xcode_build_version': '11c29', + }, +) + +try_.chromium_mac_ios_builder( + name = 'ios-simulator-cr-recipe', + executable = 'recipe:chromium_trybot', +) + +try_.chromium_mac_ios_builder( + name = 'ios-simulator-eg', +) + +try_.chromium_mac_ios_builder( + name = 'ios-simulator-multi-window', + executable = 'recipe:chromium_trybot', +) + +try_.chromium_mac_ios_builder( + name = 'ios-simulator-noncq', +) + +try_.chromium_mac_ios_builder( + name = 'ios13-beta-simulator', + executable = 'recipe:chromium_trybot', +) + +try_.chromium_mac_ios_builder( + name = 'ios13-sdk-simulator', + executable = 'recipe:chromium_trybot', + caches = [xcode_cache.x11e146], + os = os.MAC_10_15, + properties = { + 'xcode_build_version': '11e146' + } +) + +try_.chromium_win_builder( + name = 'win-annotator-rel', +) + +try_.chromium_win_builder( + name = 'win-asan', + goma_jobs = goma.jobs.J150, +) + +try_.chromium_win_builder( + name = 'win-celab-try-rel', + executable = 'recipe:celab', + properties = { + 'exclude': 'chrome_only', + 'pool_name': 'celab-chromium-try', + 'pool_size': 20, + 'tests': '*', + }, +) + +try_.chromium_win_builder( + name = 'win10_chromium_x64_coverage_rel_ng', + os = os.WINDOWS_10, + use_clang_coverage = True, + goma_jobs = goma.jobs.J150, + ssd = True, + tryjob = try_.job(experiment_percentage = 3), +) + +try_.chromium_win_builder( + name = 'win10_chromium_x64_dbg_ng', + os = os.WINDOWS_10, +) + +try_.chromium_win_builder( + name = 'win10_chromium_x64_rel_ng_exp', + builderless = False, + os = os.WINDOWS_ANY, +) + +try_.chromium_win_builder( + name = 'win7-rel', + execution_timeout = time.hour * 9 / 2, # 4.5 (can't multiply float * duration) + goma_jobs = goma.jobs.J300, + ssd = True, +) + +try_.chromium_win_builder( + name = 'win_archive', +) + +try_.chromium_win_builder( + name = 'win_chromium_compile_rel_ng', +) + +try_.chromium_win_builder( + name = 'win_chromium_dbg_ng', +) + +try_.chromium_win_builder( + name = 'win_chromium_x64_rel_ng', +) + +try_.chromium_win_builder( + name = 'win_mojo', +) + +try_.chromium_win_builder( + name = 'win_upload_clang', + builderless = False, + cores = 32, + executable = 'recipe:chromium_upload_clang', + goma_backend = None, + os = os.WINDOWS_ANY, +) + +try_.chromium_win_builder( + name = 'win_x64_archive', +) + + +# Used for listing chrome trybots in chromium's commit-queue.cfg without also +# adding them to chromium's cr-buildbucket.cfg. Note that the recipe these +# builders run allow only known roller accounts when triggered via the CQ. +def chrome_internal_verifier( + *, + builder): + luci.cq_tryjob_verifier( + builder = 'chrome:try/' + builder, + cq_group = 'cq', + includable_only = True, + owner_whitelist = [ + "googlers", + "project-chromium-robot-committers", + ], + ) + +chrome_internal_verifier( + builder = 'chromeos-betty-chrome', +) + +chrome_internal_verifier( + builder = 'chromeos-betty-pi-arc-chrome', +) + +chrome_internal_verifier( + builder = 'chromeos-eve-compile-chrome', +) + +chrome_internal_verifier( + builder = 'chromeos-kevin-compile-chrome', +) + +chrome_internal_verifier( + builder = 'ipad-device', +) + +chrome_internal_verifier( + builder = 'iphone-device', +) + +chrome_internal_verifier( + builder = 'linux-chromeos-chrome', +) + +chrome_internal_verifier( + builder = 'mac-chrome', +) + +chrome_internal_verifier( + builder = 'win-chrome', +) + +chrome_internal_verifier( + builder = 'win64-chrome', +)
diff --git a/infra/config/subprojects/chromium/try.star b/infra/config/subprojects/chromium/try.star index c6a24659..759a38d 100644 --- a/infra/config/subprojects/chromium/try.star +++ b/infra/config/subprojects/chromium/try.star
@@ -1,751 +1,617 @@ -load('//lib/builders.star', 'cpu', 'goma', 'os', 'xcode_cache') +load('//lib/builders.star', 'cpu', 'goma', 'os') load('//lib/try.star', 'try_') -load('./versioned/trunk/vars.star', 'vars') +load('//project.star', 'settings') -# Execute the versioned files to define all of the per-branch entities -# (bucket, builders, console, cq_group, etc.) -exec('./versioned/trunk/buckets/try.star') -exec('./versioned/m81/buckets/try.star') -exec('./versioned/m83/buckets/try.star') +try_.declare_bucket(settings) try_.set_defaults( - vars, - add_to_list_view = True, + settings, + main_list_view = settings.main_list_view_name, ) -# *** After this point everything is trunk only *** - -[try_.list_view( - name = name, -) for name in ( - 'tryserver.blink', - 'tryserver.chromium.android', - 'tryserver.chromium.angle', - 'tryserver.chromium.chromiumos', - 'tryserver.chromium.dawn', - 'tryserver.chromium.linux', - 'tryserver.chromium.mac', - 'tryserver.chromium.swangle', - 'tryserver.chromium.win', -)] - - # Builders are sorted first lexicographically by the function used to define # them, then lexicographically by their name try_.blink_builder( - name = 'win10-blink-rel', + name = 'linux-blink-rel', goma_backend = goma.backend.RBE_PROD, - os = os.WINDOWS_ANY, - builderless = True, -) - -try_.blink_builder( - name = 'win7-blink-rel', - goma_backend = goma.backend.RBE_PROD, - os = os.WINDOWS_ANY, - builderless = True, -) - - -try_.blink_mac_builder( - name = 'mac10.10-blink-rel', -) - -try_.blink_mac_builder( - name = 'mac10.11-blink-rel', -) - -try_.blink_mac_builder( - name = 'mac10.12-blink-rel', -) - -try_.blink_mac_builder( - name = 'mac10.13-blink-rel', -) - -try_.blink_mac_builder( - name = 'mac10.13_retina-blink-rel', -) - -try_.blink_mac_builder( - name = 'mac10.14-blink-rel', -) - -try_.blink_mac_builder( - name = 'mac10.15-blink-rel', -) - - -try_.chromium_android_builder( - name = 'android-asan', -) - -try_.chromium_android_builder( - name = 'android-bfcache-rel', -) - -try_.chromium_android_builder( - name = 'android-deterministic-dbg', - executable = 'recipe:swarming/deterministic_build', - execution_timeout = 6 * time.hour, -) - -try_.chromium_android_builder( - name = 'android-deterministic-rel', - executable = 'recipe:swarming/deterministic_build', - execution_timeout = 6 * time.hour, -) - -try_.chromium_android_builder( - name = 'android-marshmallow-x86-fyi-rel', -) - -try_.chromium_android_builder( - name = 'android-opus-arm-rel', -) - -try_.chromium_android_builder( - name = 'android-oreo-arm64-cts-networkservice-dbg', -) - -try_.chromium_android_builder( - name = 'android-oreo-arm64-dbg', -) - -try_.chromium_android_builder( - name = 'android-pie-x86-rel', - goma_jobs=goma.jobs.J150, -) - -try_.chromium_android_builder( - name = 'android-pie-arm64-coverage-rel', - cores = 16, - goma_jobs = goma.jobs.J300, - ssd = True, - use_clang_coverage = True, -) - -try_.chromium_android_builder( - name = 'android-10-arm64-rel', -) - -try_.chromium_android_builder( - name = 'android-weblayer-pie-arm64-fyi-rel', -) - -try_.chromium_android_builder( - name = 'android-weblayer-pie-x86-fyi-rel', -) - -try_.chromium_android_builder( - name = 'android-webview-marshmallow-arm64-dbg', -) - -try_.chromium_android_builder( - name = 'android-webview-nougat-arm64-dbg', -) - -try_.chromium_android_builder( - name = 'android-webview-oreo-arm64-dbg', -) - -try_.chromium_android_builder( - name = 'android-webview-pie-arm64-dbg', -) - -try_.chromium_android_builder( - name = 'android-webview-pie-arm64-fyi-rel', -) - -try_.chromium_android_builder( - name = 'android_archive_rel_ng', -) - -try_.chromium_android_builder( - name = 'android_arm64_dbg_recipe', - goma_jobs = goma.jobs.J300, -) - -try_.chromium_android_builder( - name = 'android_blink_rel', -) - -try_.chromium_android_builder( - name = 'android_cfi_rel_ng', - cores = 32, -) - -try_.chromium_android_builder( - name = 'android_clang_dbg_recipe', - goma_jobs = goma.jobs.J300, -) - -try_.chromium_android_builder( - name = 'android_cronet_tester', - properties = { - 'buildername': 'android-cronet-arm-dbg', - }, -) - -try_.chromium_android_builder( - name = 'android_mojo', -) - -try_.chromium_android_builder( - name = 'android_n5x_swarming_dbg', -) - -try_.chromium_android_builder( - name = 'android_unswarmed_pixel_aosp', -) - -try_.chromium_android_builder( - name = 'linux_android_dbg_ng', -) - -try_.chromium_android_builder( - name = 'try-nougat-phone-tester', -) - - -try_.chromium_angle_builder( - name = 'android_angle_deqp_rel_ng', -) - -try_.chromium_angle_builder( - name = 'android_angle_rel_ng', -) - -try_.chromium_angle_builder( - name = 'android_angle_vk32_deqp_rel_ng', -) - -try_.chromium_angle_builder( - name = 'android_angle_vk32_rel_ng', -) - -try_.chromium_angle_builder( - name = 'android_angle_vk64_deqp_rel_ng', -) - -try_.chromium_angle_builder( - name = 'android_angle_vk64_rel_ng', -) - -try_.chromium_angle_builder( - name = 'fuchsia-angle-rel', -) - -try_.chromium_angle_builder( - name = 'linux-angle-rel', -) - -try_.chromium_angle_builder( - name = 'linux_angle_deqp_rel_ng', -) - -try_.chromium_angle_builder( - name = 'linux_angle_ozone_rel_ng', -) - -try_.chromium_angle_builder( - name = 'mac-angle-rel', - cores = None, - os = os.MAC_ANY, -) - -try_.chromium_angle_builder( - name = 'win-angle-deqp-rel-32', - os = os.WINDOWS_ANY, -) - -try_.chromium_angle_builder( - name = 'win-angle-deqp-rel-64', - os = os.WINDOWS_ANY, -) - -try_.chromium_angle_builder( - name = 'win-angle-rel-32', - os = os.WINDOWS_ANY, -) - -try_.chromium_angle_builder( - name = 'win-angle-rel-64', - os = os.WINDOWS_ANY, -) - - -try_.chromium_chromiumos_builder( - name = 'chromeos-amd64-generic-cfi-thin-lto-rel', -) - -try_.chromium_chromiumos_builder( - name = 'chromeos-arm-generic-dbg', -) - -try_.chromium_chromiumos_builder( - name = 'linux-chromeos-dbg', -) - - -try_.chromium_dawn_builder( - name = 'linux-dawn-rel', -) - -try_.chromium_dawn_builder( - name = 'mac-dawn-rel', - os = os.MAC_ANY, -) - -try_.chromium_dawn_builder( - name = 'win-dawn-rel', - os = os.WINDOWS_ANY, -) - - -try_.chromium_linux_builder( - name = 'cast_shell_audio_linux', -) - -try_.chromium_linux_builder( - name = 'fuchsia-compile-x64-dbg', tryjob = try_.job( - experiment_percentage = 50, + location_regexp = [ + '.+/[+]/cc/.+', + '.+/[+]/third_party/blink/renderer/core/paint/.+', + '.+/[+]/third_party/blink/renderer/core/svg/.+', + '.+/[+]/third_party/blink/renderer/platform/graphics/.+', + ], ), ) -try_.chromium_linux_builder( - name = 'fuchsia-fyi-arm64-rel', -) -try_.chromium_linux_builder( - name = 'fuchsia-fyi-x64-dbg', -) - -try_.chromium_linux_builder( - name = 'fuchsia-fyi-x64-rel', -) - -try_.chromium_linux_builder( - name = 'layout_test_leak_detection', -) - -try_.chromium_linux_builder( - name = 'leak_detection_linux', -) - -try_.chromium_linux_builder( - name = 'linux-annotator-rel', -) - -try_.chromium_linux_builder( - name = 'linux-bfcache-rel', -) - -try_.chromium_linux_builder( - name = 'linux-blink-heap-concurrent-marking-tsan-rel', -) - -try_.chromium_linux_builder( - name = 'linux-blink-heap-verification-try', -) - -try_.chromium_linux_builder( - name = 'linux-clang-tidy-dbg', - executable = 'recipe:tricium_clang_tidy_wrapper', +try_.chromium_android_builder( + name = 'android-binary-size', + executable = 'recipe:binary_size_trybot', goma_jobs = goma.jobs.J150, + properties = { + '$build/binary_size': { + 'analyze_targets': [ + '//android_webview:system_webview_apk_manifest_expectations', + '//android_webview:trichrome_webview_apk_manifest_expectations', + '//chrome/android:chrome_modern_public_bundle__base_libs_and_assets_expectations', + '//chrome/android:monochrome_public_bundle__base_bundle_module_manifest_expectations', + '//chrome/android:monochrome_public_bundle__base_libs_and_assets_expectations', + '//chrome/android:monochrome_public_bundle_proguard_expectations', + '//chrome/android:monochrome_public_minimal_apks', + '//chrome/android:trichrome_chrome_bundle__base_bundle_module_manifest_expectations', + '//chrome/android:trichrome_chrome_bundle__base_libs_and_assets_expectations', + '//chrome/android:trichrome_library_apk_libs_and_assets_expectations', + '//chrome/android:trichrome_library_apk_manifest_expectations', + '//tools/binary_size:binary_size_trybot_py', + ], + 'compile_targets': [ + 'chrome_modern_public_bundle__base_libs_and_assets_expectations', + 'monochrome_public_bundle__base_bundle_module_manifest_expectations', + 'monochrome_public_bundle__base_libs_and_assets_expectations', + 'monochrome_public_bundle_proguard_expectations', + 'monochrome_public_minimal_apks', + 'monochrome_static_initializers', + 'system_webview_apk_manifest_expectations', + 'trichrome_chrome_bundle__base_bundle_module_manifest_expectations', + 'trichrome_chrome_bundle__base_libs_and_assets_expectations', + 'trichrome_library_apk_libs_and_assets_expectations', + 'trichrome_library_apk_manifest_expectations', + 'trichrome_webview_apk_manifest_expectations' + ], + }, + }, + tryjob = try_.job(), ) -try_.chromium_linux_builder( - name = 'linux-clang-tidy-rel', - executable = 'recipe:tricium_clang_tidy_wrapper', - goma_jobs = goma.jobs.J150, -) - -try_.chromium_linux_builder( - name = 'linux-dcheck-off-rel', -) - -try_.chromium_linux_builder( - name = 'linux-gcc-rel', - goma_backend = None, -) - -try_.chromium_linux_builder( - name = 'linux-perfetto-rel', +try_.chromium_android_builder( + name = 'android-cronet-arm-dbg', tryjob = try_.job( - experiment_percentage = 100, location_regexp = [ - '.+/[+]/base/trace_event/.+', - '.+/[+]/base/tracing/.+', - '.+/[+]/components/tracing/.+', - '.+/[+]/content/browser/tracing/.+', - '.+/[+]/services/tracing/.+', + '.+/[+]/components/cronet/.+', + '.+/[+]/components/grpc_support/.+', + '.+/[+]/build/android/.+', + '.+/[+]/build/config/android/.+', + ], + location_regexp_exclude = [ + '.+/[+]/components/cronet/ios/.+', + ], + ), +) + +try_.chromium_android_builder( + name = 'android-lollipop-arm-rel', + goma_jobs = goma.jobs.J150, + tryjob = try_.job(), +) + +try_.chromium_android_builder( + name = 'android-marshmallow-arm64-rel', + cores = 16, + goma_jobs = goma.jobs.J300, + ssd = True, + use_java_coverage = True, + tryjob = try_.job(), +) + +try_.chromium_android_builder( + name = 'android-pie-arm64-dbg', + tryjob = try_.job( + location_regexp = [ + '.+/[+]/chrome/android/features/vr/.+', + '.+/[+]/chrome/android/java/src/org/chromium/chrome/browser/vr/.+', + '.+/[+]/chrome/android/javatests/src/org/chromium/chrome/browser/vr/.+', + '.+/[+]/chrome/browser/vr/.+', + '.+/[+]/content/browser/xr/.+', + '.+/[+]/third_party/gvr-android-sdk/.+', + '.+/[+]/third_party/arcore-android-sdk/.+', + '.+/[+]/third_party/arcore-android-sdk-client/.+', + ], + ), +) + +try_.chromium_android_builder( + name = 'android-pie-arm64-rel', + cores = 16, + goma_jobs = goma.jobs.J300, + ssd = True, + tryjob = try_.job(), +) + +try_.chromium_android_builder( + name = 'android_compile_dbg', + goma_jobs = goma.jobs.J150, + tryjob = try_.job(), +) + +try_.chromium_android_builder( + name = 'android_compile_x64_dbg', + tryjob = try_.job( + location_regexp = [ + '.+/[+]/chrome/android/java/src/org/chromium/chrome/browser/vr/.+', + '.+/[+]/chrome/browser/vr/.+', + '.+/[+]/content/browser/xr/.+', + '.+/[+]/sandbox/linux/seccomp-bpf/.+', + '.+/[+]/sandbox/linux/seccomp-bpf-helpers/.+', + '.+/[+]/sandbox/linux/system_headers/.+', + '.+/[+]/sandbox/linux/tests/.+', + '.+/[+]/third_party/gvr-android-sdk/.+', + ], + ), +) + +try_.chromium_android_builder( + name = 'android_compile_x86_dbg', + tryjob = try_.job( + location_regexp = [ + '.+/[+]/chrome/android/java/src/org/chromium/chrome/browser/vr/.+', + '.+/[+]/chrome/browser/vr/.+', + '.+/[+]/content/browser/xr/.+', + '.+/[+]/sandbox/linux/seccomp-bpf/.+', + '.+/[+]/sandbox/linux/seccomp-bpf-helpers/.+', + '.+/[+]/sandbox/linux/system_headers/.+', + '.+/[+]/sandbox/linux/tests/.+', + '.+/[+]/third_party/gvr-android-sdk/.+', + ], + ), +) + +try_.chromium_android_builder( + name = 'android_cronet', + tryjob = try_.job(), +) + +try_.chromium_android_builder( + name = 'cast_shell_android', + tryjob = try_.job(), +) + + +try_.chromium_chromiumos_builder( + name = 'chromeos-amd64-generic-dbg', + tryjob = try_.job( + location_regexp = [ + '.+/[+]/content/gpu/.+', + '.+/[+]/media/.+', + ], + ), +) + +try_.chromium_chromiumos_builder( + name = 'chromeos-amd64-generic-rel', + tryjob = try_.job(), +) + +try_.chromium_chromiumos_builder( + name = 'chromeos-arm-generic-rel', + tryjob = try_.job(), +) + +try_.chromium_chromiumos_builder( + name = 'chromeos-kevin-compile-rel', + tryjob = try_.job( + location_regexp = [ + '.+/[+]/chromeos/CHROMEOS_LKGM', + ], + ), +) + +try_.chromium_chromiumos_builder( + name = 'chromeos-kevin-rel', + tryjob = try_.job( + location_regexp = [ + '.+/[+]/build/chromeos/.+', + '.+/[+]/build/config/chromeos/.*', + ], + ), +) + +try_.chromium_chromiumos_builder( + name = 'linux-chromeos-compile-dbg', + tryjob = try_.job(), +) + +try_.chromium_chromiumos_builder( + name = 'linux-chromeos-rel', + goma_jobs = goma.jobs.J150, + tryjob = try_.job(cancel_stale = False), + use_clang_coverage = True, +) + + +try_.chromium_dawn_builder( + name = 'dawn-linux-x64-deps-rel', + tryjob = try_.job( + location_regexp = [ + '.+/[+]/gpu/.+', + '.+/[+]/testing/buildbot/chromium.dawn.json', + '.+/[+]/third_party/blink/renderer/modules/webgpu/.+', + '.+/[+]/third_party/blink/web_tests/external/wpt/webgpu/.+', + '.+/[+]/third_party/blink/web_tests/wpt_internal/webgpu/.+', + '.+/[+]/third_party/blink/web_tests/WebGPUExpectations', + '.+/[+]/third_party/dawn/.+', + '.+/[+]/tools/clang/scripts/update.py', + '.+/[+]/ui/gl/features.gni', + ], + ), +) + +try_.chromium_dawn_builder( + name = 'dawn-mac-x64-deps-rel', + os = os.MAC_ANY, + tryjob = try_.job( + location_regexp = [ + '.+/[+]/gpu/.+', + '.+/[+]/testing/buildbot/chromium.dawn.json', + '.+/[+]/third_party/blink/renderer/modules/webgpu/.+', + '.+/[+]/third_party/blink/web_tests/external/wpt/webgpu/.+', + '.+/[+]/third_party/blink/web_tests/wpt_internal/webgpu/.+', + '.+/[+]/third_party/blink/web_tests/WebGPUExpectations', + '.+/[+]/third_party/dawn/.+', + '.+/[+]/tools/clang/scripts/update.py', + '.+/[+]/ui/gl/features.gni', + ], + ), +) + +try_.chromium_dawn_builder( + name = 'dawn-win10-x64-deps-rel', + os = os.WINDOWS_ANY, + tryjob = try_.job( + location_regexp = [ + '.+/[+]/gpu/.+', + '.+/[+]/testing/buildbot/chromium.dawn.json', + '.+/[+]/third_party/blink/renderer/modules/webgpu/.+', + '.+/[+]/third_party/blink/web_tests/external/wpt/webgpu/.+', + '.+/[+]/third_party/blink/web_tests/wpt_internal/webgpu/.+', + '.+/[+]/third_party/blink/web_tests/WebGPUExpectations', + '.+/[+]/third_party/dawn/.+', + '.+/[+]/tools/clang/scripts/update.py', + '.+/[+]/ui/gl/features.gni', + ], + ), +) + +try_.chromium_dawn_builder( + name = 'dawn-win10-x86-deps-rel', + os = os.WINDOWS_ANY, + tryjob = try_.job( + location_regexp = [ + '.+/[+]/gpu/.+', + '.+/[+]/testing/buildbot/chromium.dawn.json', + '.+/[+]/third_party/blink/renderer/modules/webgpu/.+', + '.+/[+]/third_party/blink/web_tests/external/wpt/webgpu/.+', + '.+/[+]/third_party/blink/web_tests/wpt_internal/webgpu/.+', + '.+/[+]/third_party/blink/web_tests/WebGPUExpectations', + '.+/[+]/third_party/dawn/.+', + '.+/[+]/tools/clang/scripts/update.py', + '.+/[+]/ui/gl/features.gni', + ], + ), +) + + +try_.chromium_linux_builder( + name = 'cast_shell_linux', + tryjob = try_.job(), +) + +try_.chromium_linux_builder( + name = 'closure_compilation', + executable = 'recipe:closure_compilation', + tryjob = try_.job( + location_regexp = [ + '.+/[+]/third_party/closure_compiler/.+', ], ), ) try_.chromium_linux_builder( - name = 'linux-trusty-rel', - goma_jobs = goma.jobs.J150, - os = os.LINUX_TRUSTY, -) - -try_.chromium_linux_builder( - name = 'linux-viz-rel', -) - -try_.chromium_linux_builder( - name = 'linux-webkit-msan-rel', -) - -try_.chromium_linux_builder( - name = 'linux_chromium_analysis', -) - -try_.chromium_linux_builder( - name = 'linux_chromium_archive_rel_ng', -) - -try_.chromium_linux_builder( - name = 'linux_chromium_cfi_rel_ng', - cores = 32, -) - -try_.chromium_linux_builder( - name = 'linux_chromium_chromeos_asan_rel_ng', - goma_jobs = goma.jobs.J150, -) - -try_.chromium_linux_builder( - name = 'linux_chromium_chromeos_msan_rel_ng', - goma_jobs = goma.jobs.J150, -) - -try_.chromium_linux_builder( - name = 'linux_chromium_clobber_deterministic', - executable = 'recipe:swarming/deterministic_build', - execution_timeout = 6 * time.hour, -) - -try_.chromium_linux_builder( - name = 'linux_chromium_clobber_rel_ng', -) - -try_.chromium_linux_builder( - name = 'linux_chromium_compile_dbg_32_ng', -) - -try_.chromium_linux_builder( - name = 'linux_chromium_compile_rel_ng', -) - -try_.chromium_linux_builder( - name = 'linux_chromium_msan_rel_ng', - goma_jobs = goma.jobs.J150, -) - -try_.chromium_linux_builder( - name = 'linux_chromium_ubsan_rel_ng', -) - -try_.chromium_linux_builder( - name = 'linux-layout-tests-edit-ng', -) - -try_.chromium_linux_builder( - name = 'linux-autofill-assistant', -) - -try_.chromium_linux_builder( - name = 'linux-layout-tests-fragment-item', -) - -try_.chromium_linux_builder( - name = 'linux_mojo', -) - -try_.chromium_linux_builder( - name = 'linux_mojo_chromeos', -) - -try_.chromium_linux_builder( - name = 'linux_upload_clang', - builderless = True, - cores = 32, - executable = 'recipe:chromium_upload_clang', + name = 'chromium_presubmit', + executable = 'recipe:presubmit', goma_backend = None, - os = os.LINUX_TRUSTY, + properties = { + '$depot_tools/presubmit': { + 'runhooks': True, + 'timeout_s': 480, + }, + 'repo_name': 'chromium', + }, + tryjob = try_.job( + disable_reuse = True, + ), ) try_.chromium_linux_builder( - name = 'linux-wpt-fyi-rel', + name = 'fuchsia-arm64-cast', + tryjob = try_.job( + location_regexp = [ + '.+/[+]/chromecast/.+', + ], + ), ) try_.chromium_linux_builder( - name = 'tricium-metrics-analysis', - executable = 'recipe:tricium_metrics', + name = 'fuchsia-x64-cast', + tryjob = try_.job(), ) +try_.chromium_linux_builder( + name = 'fuchsia_arm64', + tryjob = try_.job(), +) -try_.chromium_mac_builder( - name = 'mac-coverage-rel', +try_.chromium_linux_builder( + name = 'fuchsia_x64', + tryjob = try_.job(), +) + +try_.chromium_linux_builder( + name = 'linux-libfuzzer-asan-rel', + executable = 'recipe:chromium_libfuzzer_trybot', + tryjob = try_.job(), +) + +try_.chromium_linux_builder( + name = 'linux-ozone-rel', + tryjob = try_.job(), +) + +try_.chromium_linux_builder( + name = 'linux-rel', + goma_jobs = goma.jobs.J150, + tryjob = try_.job(), use_clang_coverage = True, +) + +try_.chromium_linux_builder( + name = 'linux_chromium_asan_rel_ng', goma_jobs = goma.jobs.J150, - tryjob = try_.job(experiment_percentage = 3) + ssd = True, + tryjob = try_.job(), ) -try_.chromium_mac_builder( - name = 'mac-osxbeta-rel', - os = os.MAC_DEFAULT, -) - -# NOTE: the following trybots aren't sensitive to Mac version on which -# they are built, hence no additional dimension is specified. -# The 10.xx version translates to which bots will run isolated tests. -try_.chromium_mac_builder( - name = 'mac_chromium_10.10', -) - -try_.chromium_mac_builder( - name = 'mac_chromium_10.12_rel_ng', -) - -try_.chromium_mac_builder( - name = 'mac_chromium_10.13_rel_ng', -) - -try_.chromium_mac_builder( - name = 'mac_chromium_10.14_rel_ng', -) - -try_.chromium_mac_builder( - name = 'mac_chromium_10.15_rel_ng', -) - -try_.chromium_mac_builder( - name = 'mac_chromium_archive_rel_ng', -) - -try_.chromium_mac_builder( - name = 'mac_chromium_asan_rel_ng', - goma_jobs = goma.jobs.J150, -) - -try_.chromium_mac_builder( - name = 'mac_chromium_compile_rel_ng', -) - -try_.chromium_mac_builder( - name = 'mac_chromium_dbg_ng', -) - -try_.chromium_mac_builder( - name = 'mac_upload_clang', - builderless = False, +try_.chromium_linux_builder( + name = 'linux_chromium_compile_dbg_ng', caches = [ swarming.cache( - name = 'xcode_mac_9a235', - path = 'xcode_mac_9a235.app', + name = 'builder', + path = 'linux_debug', ), ], - executable = 'recipe:chromium_upload_clang', - execution_timeout = 6 * time.hour, - goma_backend = None, # Does not use Goma. - properties = { - '$depot_tools/osx_sdk': { - 'sdk_version': '9a235', - }, - }, + goma_jobs = goma.jobs.J150, + tryjob = try_.job(), +) + +try_.chromium_linux_builder( + name = 'linux_chromium_dbg_ng', + caches = [ + swarming.cache( + name = 'builder', + path = 'linux_debug', + ), + ], + tryjob = try_.job( + location_regexp = [ + '.+/[+]/build/.*check_gn_headers.*', + ], + ), +) + +try_.chromium_linux_builder( + name = 'linux_chromium_tsan_rel_ng', + goma_jobs = goma.jobs.J150, + tryjob = try_.job(), +) + +try_.chromium_linux_builder( + name = 'linux_layout_tests_composite_after_paint', + tryjob = try_.job( + location_regexp = [ + '.+/[+]/third_party/blink/renderer/core/paint/.+', + '.+/[+]/third_party/blink/renderer/core/svg/.+', + '.+/[+]/third_party/blink/renderer/platform/graphics/.+', + '.+/[+]/third_party/blink/web_tests/.+', + ], + ), +) + +try_.chromium_linux_builder( + name = 'linux_layout_tests_layout_ng_disabled', + tryjob = try_.job( + location_regexp = [ + '.+/[+]/third_party/blink/renderer/core/editing/.+', + '.+/[+]/third_party/blink/renderer/core/layout/.+', + '.+/[+]/third_party/blink/renderer/core/paint/.+', + '.+/[+]/third_party/blink/renderer/core/svg/.+', + '.+/[+]/third_party/blink/renderer/platform/fonts/shaping/.+', + '.+/[+]/third_party/blink/renderer/platform/graphics/.+', + '.+/[+]/third_party/blink/web_tests/FlagExpectations/disable-layout-ng', + '.+/[+]/third_party/blink/web_tests/flag-specific/disable-layout-ng/.+', + ], + ), +) + +try_.chromium_linux_builder( + name = 'linux_vr', + tryjob = try_.job( + location_regexp = [ + '.+/[+]/chrome/browser/vr/.+', + '.+/[+]/content/browser/xr/.+', + ], + ), +) + + +try_.chromium_mac_builder( + name = 'mac-rel', + goma_jobs = goma.jobs.J150, + os = os.MAC_10_13, + tryjob = try_.job(), +) + +try_.chromium_mac_builder( + name = 'mac_chromium_compile_dbg_ng', + goma_jobs = goma.jobs.J150, + os = os.MAC_10_13, + tryjob = try_.job(), ) try_.chromium_mac_ios_builder( - name = 'ios-device', + name = 'ios-simulator', executable = 'recipe:chromium_trybot', -) - -try_.chromium_mac_ios_builder( - name = 'ios-simulator-code-coverage', - executable = 'recipe:chromium_trybot', - use_clang_coverage = True, properties = { - 'coverage_exclude_sources': 'ios_test_files_and_test_utils', - 'coverage_test_types': ['unit'], 'xcode_build_version': '11c29', }, + tryjob = try_.job(), ) try_.chromium_mac_ios_builder( - name = 'ios-simulator-cr-recipe', + name = 'ios-simulator-cronet', executable = 'recipe:chromium_trybot', + tryjob = try_.job( + location_regexp = [ + '.+/[+]/components/cronet/.+', + '.+/[+]/components/grpc_support/.+', + '.+/[+]/ios/.+', + ], + location_regexp_exclude = [ + '.+/[+]/components/cronet/android/.+', + ], + ), ) try_.chromium_mac_ios_builder( - name = 'ios-simulator-eg', -) - -try_.chromium_mac_ios_builder( - name = 'ios-simulator-multi-window', + name = 'ios-simulator-full-configs', executable = 'recipe:chromium_trybot', + tryjob = try_.job( + location_regexp = [ + '.+/[+]/ios/.+', + ], + ), ) -try_.chromium_mac_ios_builder( - name = 'ios-simulator-noncq', -) -try_.chromium_mac_ios_builder( - name = 'ios13-beta-simulator', - executable = 'recipe:chromium_trybot', -) - -try_.chromium_mac_ios_builder( - name = 'ios13-sdk-simulator', - executable = 'recipe:chromium_trybot', - caches = [xcode_cache.x11e146], - os = os.MAC_10_15, - properties = { - 'xcode_build_version': '11e146' - } +try_.chromium_win_builder( + name = 'win-libfuzzer-asan-rel', + builderless = False, + executable = 'recipe:chromium_libfuzzer_trybot', + os = os.WINDOWS_ANY, + tryjob = try_.job(cancel_stale = False), ) try_.chromium_win_builder( - name = 'win-annotator-rel', -) - -try_.chromium_win_builder( - name = 'win-asan', + name = 'win_chromium_compile_dbg_ng', goma_jobs = goma.jobs.J150, + tryjob = try_.job(cancel_stale = False), ) try_.chromium_win_builder( - name = 'win-celab-try-rel', - executable = 'recipe:celab', - properties = { - 'exclude': 'chrome_only', - 'pool_name': 'celab-chromium-try', - 'pool_size': 20, - 'tests': '*', - }, -) - -try_.chromium_win_builder( - name = 'win10_chromium_x64_coverage_rel_ng', + name = 'win10_chromium_x64_rel_ng', + goma_jobs = goma.jobs.J150, os = os.WINDOWS_10, + ssd = True, use_clang_coverage = True, - goma_jobs = goma.jobs.J150, - ssd = True, - tryjob = try_.job(experiment_percentage = 3), -) - -try_.chromium_win_builder( - name = 'win10_chromium_x64_dbg_ng', - os = os.WINDOWS_10, -) - -try_.chromium_win_builder( - name = 'win10_chromium_x64_rel_ng_exp', - builderless = False, - os = os.WINDOWS_ANY, -) - -try_.chromium_win_builder( - name = 'win7-rel', - execution_timeout = time.hour * 9 / 2, # 4.5 (can't multiply float * duration) - goma_jobs = goma.jobs.J300, - ssd = True, -) - -try_.chromium_win_builder( - name = 'win_archive', -) - -try_.chromium_win_builder( - name = 'win_chromium_compile_rel_ng', -) - -try_.chromium_win_builder( - name = 'win_chromium_dbg_ng', -) - -try_.chromium_win_builder( - name = 'win_chromium_x64_rel_ng', -) - -try_.chromium_win_builder( - name = 'win_mojo', -) - -try_.chromium_win_builder( - name = 'win_upload_clang', - builderless = False, - cores = 32, - executable = 'recipe:chromium_upload_clang', - goma_backend = None, - os = os.WINDOWS_ANY, -) - -try_.chromium_win_builder( - name = 'win_x64_archive', + tryjob = try_.job(cancel_stale = False), ) -# Used for listing chrome trybots in chromium's commit-queue.cfg without also -# adding them to chromium's cr-buildbucket.cfg. Note that the recipe these -# builders run allow only known roller accounts when triggered via the CQ. -def chrome_internal_verifier( - *, - builder): - luci.cq_tryjob_verifier( - builder = 'chrome:try/' + builder, - cq_group = 'cq', - includable_only = True, - owner_whitelist = [ - "googlers", - "project-chromium-robot-committers", - ], - ) - -chrome_internal_verifier( - builder = 'chromeos-betty-chrome', +try_.gpu_chromium_android_builder( + name = 'android_optional_gpu_tests_rel', + tryjob = try_.job( + location_regexp = [ + '.+/[+]/cc/.+', + '.+/[+]/chrome/browser/vr/.+', + '.+/[+]/content/browser/xr/.+', + '.+/[+]/components/viz/.+', + '.+/[+]/content/test/gpu/.+', + '.+/[+]/gpu/.+', + '.+/[+]/media/audio/.+', + '.+/[+]/media/filters/.+', + '.+/[+]/media/gpu/.+', + '.+/[+]/services/viz/.+', + '.+/[+]/testing/trigger_scripts/.+', + '.+/[+]/third_party/blink/renderer/modules/webgl/.+', + '.+/[+]/third_party/blink/renderer/platform/graphics/gpu/.+', + '.+/[+]/tools/clang/scripts/update.py', + '.+/[+]/ui/gl/.+', + ], + ), ) -chrome_internal_verifier( - builder = 'chromeos-betty-pi-arc-chrome', + +try_.gpu_chromium_linux_builder( + name = 'linux_optional_gpu_tests_rel', + tryjob = try_.job( + location_regexp = [ + '.+/[+]/chrome/browser/vr/.+', + '.+/[+]/content/browser/xr/.+', + '.+/[+]/content/test/gpu/.+', + '.+/[+]/gpu/.+', + '.+/[+]/media/audio/.+', + '.+/[+]/media/filters/.+', + '.+/[+]/media/gpu/.+', + '.+/[+]/testing/buildbot/chromium.gpu.fyi.json', + '.+/[+]/testing/trigger_scripts/.+', + '.+/[+]/third_party/blink/renderer/modules/webgl/.+', + '.+/[+]/third_party/blink/renderer/platform/graphics/gpu/.+', + '.+/[+]/tools/clang/scripts/update.py', + '.+/[+]/ui/gl/.+', + ], + ), ) -chrome_internal_verifier( - builder = 'chromeos-eve-compile-chrome', + +try_.gpu_chromium_mac_builder( + name = 'mac_optional_gpu_tests_rel', + tryjob = try_.job( + location_regexp = [ + '.+/[+]/chrome/browser/vr/.+', + '.+/[+]/content/browser/xr/.+', + '.+/[+]/content/test/gpu/.+', + '.+/[+]/gpu/.+', + '.+/[+]/media/audio/.+', + '.+/[+]/media/filters/.+', + '.+/[+]/media/gpu/.+', + '.+/[+]/services/shape_detection/.+', + '.+/[+]/testing/buildbot/chromium.gpu.fyi.json', + '.+/[+]/testing/trigger_scripts/.+', + '.+/[+]/third_party/blink/renderer/modules/webgl/.+', + '.+/[+]/third_party/blink/renderer/platform/graphics/gpu/.+', + '.+/[+]/tools/clang/scripts/update.py', + '.+/[+]/ui/gl/.+', + ], + ), ) -chrome_internal_verifier( - builder = 'chromeos-kevin-compile-chrome', -) -chrome_internal_verifier( - builder = 'ipad-device', -) - -chrome_internal_verifier( - builder = 'iphone-device', -) - -chrome_internal_verifier( - builder = 'linux-chromeos-chrome', -) - -chrome_internal_verifier( - builder = 'mac-chrome', -) - -chrome_internal_verifier( - builder = 'win-chrome', -) - -chrome_internal_verifier( - builder = 'win64-chrome', +try_.gpu_chromium_win_builder( + name = 'win_optional_gpu_tests_rel', + builderless = True, + os = os.WINDOWS_DEFAULT, + tryjob = try_.job( + location_regexp = [ + '.+/[+]/chrome/browser/vr/.+', + '.+/[+]/content/browser/xr/.+', + '.+/[+]/content/test/gpu/.+', + '.+/[+]/device/vr/.+', + '.+/[+]/gpu/.+', + '.+/[+]/media/audio/.+', + '.+/[+]/media/filters/.+', + '.+/[+]/media/gpu/.+', + '.+/[+]/testing/buildbot/chromium.gpu.fyi.json', + '.+/[+]/testing/trigger_scripts/.+', + '.+/[+]/third_party/blink/renderer/modules/vr/.+', + '.+/[+]/third_party/blink/renderer/modules/webgl/.+', + '.+/[+]/third_party/blink/renderer/modules/xr/.+', + '.+/[+]/third_party/blink/renderer/platform/graphics/gpu/.+', + '.+/[+]/tools/clang/scripts/update.py', + '.+/[+]/ui/gl/.+', + ], + ), )
diff --git a/infra/config/subprojects/chromium/versioned/README.md b/infra/config/subprojects/chromium/versioned/README.md index b582c006..09bc955c 100644 --- a/infra/config/subprojects/chromium/versioned/README.md +++ b/infra/config/subprojects/chromium/versioned/README.md
@@ -2,11 +2,8 @@ Contents: -* **milestones** +* **m81**, **m83** * contains subdirectories that contain the versioned configuration for the active milestones * non-dimension changes should be infrequent -* **trunk** - * contains the versioned configuration for the current canary/dev builds - * open to changes - + * more recent milestones will use separate project instead
diff --git a/infra/config/subprojects/chromium/versioned/m81/buckets/ci.star b/infra/config/subprojects/chromium/versioned/m81/buckets/ci.star index 6046a0e..cecf812e 100644 --- a/infra/config/subprojects/chromium/versioned/m81/buckets/ci.star +++ b/infra/config/subprojects/chromium/versioned/m81/buckets/ci.star
@@ -73,6 +73,14 @@ ) ci.android_builder( + name = 'android-lollipop-arm-rel', + console_view_entry = ci.console_view_entry( + category = 'on_cq', + short_name = 'L', + ), +) + +ci.android_builder( name = 'android-marshmallow-arm64-rel', console_view_entry = ci.console_view_entry( category = 'on_cq',
diff --git a/infra/config/subprojects/chromium/versioned/m81/buckets/try.star b/infra/config/subprojects/chromium/versioned/m81/buckets/try.star index 0baf52cb..166be723 100644 --- a/infra/config/subprojects/chromium/versioned/m81/buckets/try.star +++ b/infra/config/subprojects/chromium/versioned/m81/buckets/try.star
@@ -28,7 +28,12 @@ name = 'android-kitkat-arm-rel', goma_jobs = goma.jobs.J150, tryjob = try_.job(), - should_exonerate_flaky_failures = True, +) + +try_.chromium_android_builder( + name = 'android-lollipop-arm-rel', + goma_jobs = goma.jobs.J150, + tryjob = try_.job(), ) try_.chromium_android_builder( @@ -126,7 +131,6 @@ goma_jobs = goma.jobs.J150, tryjob = try_.job(), use_clang_coverage = True, - should_exonerate_flaky_failures = True, ) try_.chromium_linux_builder( @@ -160,7 +164,6 @@ goma_jobs = goma.jobs.J150, os = os.MAC_10_13, tryjob = try_.job(), - should_exonerate_flaky_failures = True, ) try_.chromium_mac_builder( @@ -198,5 +201,4 @@ os = os.WINDOWS_10, ssd = True, tryjob = try_.job(cancel_stale = False), - should_exonerate_flaky_failures = True, )
diff --git a/infra/config/subprojects/chromium/versioned/m83/buckets/ci.star b/infra/config/subprojects/chromium/versioned/m83/buckets/ci.star index fd29f9e..0646408 100644 --- a/infra/config/subprojects/chromium/versioned/m83/buckets/ci.star +++ b/infra/config/subprojects/chromium/versioned/m83/buckets/ci.star
@@ -164,6 +164,14 @@ ) ci.android_builder( + name = 'android-lollipop-arm-rel', + console_view_entry = ci.console_view_entry( + category = 'on_cq', + short_name = 'L', + ), +) + +ci.android_builder( name = 'android-marshmallow-arm64-rel', console_view_entry = ci.console_view_entry( category = 'on_cq',
diff --git a/infra/config/subprojects/chromium/versioned/m83/buckets/try.star b/infra/config/subprojects/chromium/versioned/m83/buckets/try.star index da99d26..bebe103 100644 --- a/infra/config/subprojects/chromium/versioned/m83/buckets/try.star +++ b/infra/config/subprojects/chromium/versioned/m83/buckets/try.star
@@ -54,6 +54,12 @@ ) try_.chromium_android_builder( + name = 'android-lollipop-arm-rel', + goma_jobs = goma.jobs.J150, + tryjob = try_.job(), +) + +try_.chromium_android_builder( name = 'android-marshmallow-arm64-rel', cores = 16, goma_jobs = goma.jobs.J300,
diff --git a/infra/config/subprojects/chromium/versioned/trunk/buckets/ci.star b/infra/config/subprojects/chromium/versioned/trunk/buckets/ci.star deleted file mode 100644 index 239a8d6..0000000 --- a/infra/config/subprojects/chromium/versioned/trunk/buckets/ci.star +++ /dev/null
@@ -1,816 +0,0 @@ -load('//lib/builders.star', 'builder_name', 'cpu', 'goma', 'os') -load('//lib/ci.star', 'ci') -# Load this using relative path so that the load statement doesn't -# need to be changed when making a new milestone -load('../vars.star', 'vars') - - -ci.set_defaults( - vars, - bucketed_triggers = True, - main_console_view = vars.main_console_name, -) - -ci.declare_bucket(vars) - - -# Builders are sorted first lexicographically by the function used to define -# them, then lexicographically by their name - - -ci.android_builder( - name = 'Android WebView M (dbg)', - console_view_entry = ci.console_view_entry( - category = 'tester|webview', - short_name = 'M', - ), - triggered_by = [builder_name('Android arm64 Builder (dbg)')], -) - -ci.android_builder( - name = 'Android WebView N (dbg)', - console_view_entry = ci.console_view_entry( - category = 'tester|webview', - short_name = 'N', - ), - triggered_by = [builder_name('Android arm64 Builder (dbg)')], -) - -ci.android_builder( - name = 'Android WebView O (dbg)', - console_view_entry = ci.console_view_entry( - category = 'tester|webview', - short_name = 'O', - ), - triggered_by = [builder_name('Android arm64 Builder (dbg)')], -) - -ci.android_builder( - name = 'Android WebView P (dbg)', - console_view_entry = ci.console_view_entry( - category = 'tester|webview', - short_name = 'P', - ), - triggered_by = [builder_name('Android arm64 Builder (dbg)')], -) - -ci.android_builder( - name = 'Android arm Builder (dbg)', - console_view_entry = ci.console_view_entry( - category = 'builder|arm', - short_name = '32', - ), - execution_timeout = 4 * time.hour, -) - -ci.android_builder( - name = 'Android arm64 Builder (dbg)', - console_view_entry = ci.console_view_entry( - category = 'builder|arm', - short_name = '64', - ), - goma_jobs = goma.jobs.MANY_JOBS_FOR_CI, - execution_timeout = 4 * time.hour, -) - -ci.android_builder( - name = 'Android x64 Builder (dbg)', - console_view_entry = ci.console_view_entry( - category = 'builder|x86', - short_name = '64', - ), - execution_timeout = 4 * time.hour, -) - -ci.android_builder( - name = 'Android x86 Builder (dbg)', - console_view_entry = ci.console_view_entry( - category = 'builder|x86', - short_name = '32', - ), -) - -ci.android_builder( - name = 'Cast Android (dbg)', - console_view_entry = ci.console_view_entry( - category = 'on_cq', - short_name = 'cst', - ), -) - -ci.android_builder( - name = 'Marshmallow 64 bit Tester', - console_view_entry = ci.console_view_entry( - category = 'tester|phone', - short_name = 'M', - ), - triggered_by = [builder_name('Android arm64 Builder (dbg)')], -) - -ci.android_builder( - name = 'Nougat Phone Tester', - console_view_entry = ci.console_view_entry( - category = 'tester|phone', - short_name = 'N', - ), - triggered_by = [builder_name('Android arm64 Builder (dbg)')], -) - -ci.android_builder( - name = 'Oreo Phone Tester', - console_view_entry = ci.console_view_entry( - category = 'tester|phone', - short_name = 'O', - ), - triggered_by = [builder_name('Android arm64 Builder (dbg)')], -) - -ci.android_builder( - name = 'android-cronet-arm-dbg', - console_view_entry = ci.console_view_entry( - category = 'cronet|arm', - short_name = 'dbg', - ), - notifies = ['cronet'], -) - -ci.android_builder( - name = 'android-cronet-arm-rel', - console_view_entry = ci.console_view_entry( - category = 'cronet|arm', - short_name = 'rel', - ), - notifies = ['cronet'], -) - -ci.android_builder( - name = 'android-cronet-kitkat-arm-rel', - console_view_entry = ci.console_view_entry( - category = 'cronet|test', - short_name = 'k', - ), - notifies = ['cronet'], - triggered_by = [builder_name('android-cronet-arm-rel')], -) - -ci.android_builder( - name = 'android-cronet-lollipop-arm-rel', - console_view_entry = ci.console_view_entry( - category = 'cronet|test', - short_name = 'l', - ), - notifies = ['cronet'], - triggered_by = [builder_name('android-cronet-arm-rel')], -) - -ci.android_builder( - name = 'android-lollipop-arm-rel', - console_view_entry = ci.console_view_entry( - category = 'on_cq', - short_name = 'L', - ), -) - -ci.android_builder( - name = 'android-marshmallow-arm64-rel', - console_view_entry = ci.console_view_entry( - category = 'on_cq', - short_name = 'M', - ), -) - -ci.android_builder( - name = 'android-pie-arm64-dbg', - console_view_entry = ci.console_view_entry( - category = 'tester|phone', - short_name = 'P', - ), - triggered_by = [builder_name('Android arm64 Builder (dbg)')], -) - -ci.android_builder( - name = 'android-pie-arm64-rel', - console_view_entry = ci.console_view_entry( - category = 'on_cq', - short_name = 'P', - ), -) - - -ci.chromiumos_builder( - name = 'chromeos-amd64-generic-dbg', - console_view_entry = ci.console_view_entry( - category = 'simple|debug|x64', - short_name = 'dbg', - ), -) - -ci.chromiumos_builder( - name = 'chromeos-amd64-generic-rel', - console_view_entry = ci.console_view_entry( - category = 'simple|release|x64', - short_name = 'rel', - ), -) - -ci.chromiumos_builder( - name = 'chromeos-arm-generic-rel', - console_view_entry = ci.console_view_entry( - category = 'simple|release', - short_name = 'arm', - ), -) - -ci.chromiumos_builder( - name = 'chromeos-kevin-rel', - console_view_entry = ci.console_view_entry( - category = 'simple|release', - short_name = 'kvn', - ), -) - -ci.fyi_builder( - name = 'chromeos-kevin-rel-hw-tests', - console_view_entry = ci.console_view_entry( - category = 'chromeos', - ), -) - -ci.chromiumos_builder( - name = 'linux-chromeos-dbg', - console_view_entry = ci.console_view_entry( - category = 'default', - short_name = 'dbg', - ), -) - -ci.chromiumos_builder( - name = 'linux-chromeos-rel', - console_view_entry = ci.console_view_entry( - category = 'default', - short_name = 'rel', - ), -) - - -ci.dawn_builder( - name = 'Dawn Linux x64 DEPS Builder', - console_view_entry = ci.console_view_entry( - category = 'DEPS|Linux|Builder', - short_name = 'x64', - ), -) - -ci.dawn_builder( - name = 'Dawn Linux x64 DEPS Release (Intel HD 630)', - console_view_entry = ci.console_view_entry( - category = 'DEPS|Linux|Intel', - short_name = 'x64', - ), - cores = 2, - os = os.LINUX_DEFAULT, - triggered_by = [builder_name('Dawn Linux x64 DEPS Builder')], -) - -ci.dawn_builder( - name = 'Dawn Linux x64 DEPS Release (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'DEPS|Linux|Nvidia', - short_name = 'x64', - ), - cores = 2, - os = os.LINUX_DEFAULT, - triggered_by = [builder_name('Dawn Linux x64 DEPS Builder')], -) - -ci.dawn_builder( - name = 'Dawn Mac x64 DEPS Builder', - builderless = False, - console_view_entry = ci.console_view_entry( - category = 'DEPS|Mac|Builder', - short_name = 'x64', - ), - cores = None, - os = os.MAC_ANY, -) - -# Note that the Mac testers are all thin Linux VMs, triggering jobs on the -# physical Mac hardware in the Swarming pool which is why they run on linux -ci.dawn_builder( - name = 'Dawn Mac x64 DEPS Release (AMD)', - console_view_entry = ci.console_view_entry( - category = 'DEPS|Mac|AMD', - short_name = 'x64', - ), - cores = 2, - os = os.LINUX_DEFAULT, - triggered_by = [builder_name('Dawn Mac x64 DEPS Builder')], -) - -ci.dawn_builder( - name = 'Dawn Mac x64 DEPS Release (Intel)', - console_view_entry = ci.console_view_entry( - category = 'DEPS|Mac|Intel', - short_name = 'x64', - ), - cores = 2, - os = os.LINUX_DEFAULT, - triggered_by = [builder_name('Dawn Mac x64 DEPS Builder')], -) - -ci.dawn_builder( - name = 'Dawn Win10 x64 DEPS Builder', - console_view_entry = ci.console_view_entry( - category = 'DEPS|Windows|Builder', - short_name = 'x64', - ), - os = os.WINDOWS_ANY, -) - -ci.dawn_builder( - name = 'Dawn Win10 x64 DEPS Release (Intel HD 630)', - console_view_entry = ci.console_view_entry( - category = 'DEPS|Windows|Intel', - short_name = 'x64', - ), - cores = 2, - os = os.LINUX_DEFAULT, - triggered_by = [builder_name('Dawn Win10 x64 DEPS Builder')], -) - -ci.dawn_builder( - name = 'Dawn Win10 x64 DEPS Release (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'DEPS|Windows|Nvidia', - short_name = 'x64', - ), - cores = 2, - os = os.LINUX_DEFAULT, - triggered_by = [builder_name('Dawn Win10 x64 DEPS Builder')], -) - -ci.dawn_builder( - name = 'Dawn Win10 x86 DEPS Builder', - console_view_entry = ci.console_view_entry( - category = 'DEPS|Windows|Builder', - short_name = 'x86', - ), - os = os.WINDOWS_ANY, -) - -ci.dawn_builder( - name = 'Dawn Win10 x86 DEPS Release (Intel HD 630)', - console_view_entry = ci.console_view_entry( - category = 'DEPS|Windows|Intel', - short_name = 'x86', - ), - cores = 2, - os = os.LINUX_DEFAULT, - triggered_by = [builder_name('Dawn Win10 x86 DEPS Builder')], -) - -ci.dawn_builder( - name = 'Dawn Win10 x86 DEPS Release (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'DEPS|Windows|Nvidia', - short_name = 'x86', - ), - cores = 2, - os = os.LINUX_DEFAULT, - triggered_by = [builder_name('Dawn Win10 x86 DEPS Builder')], -) - - -ci.fyi_builder( - name = 'VR Linux', - console_view_entry = ci.console_view_entry( - category = 'linux', - ), -) - -# This is launching & collecting entirely isolated tests. -# OS shouldn't matter. -ci.fyi_builder( - name = 'mac-osxbeta-rel', - console_view_entry = ci.console_view_entry( - category = 'mac', - short_name = 'beta', - ), - goma_backend = None, - triggered_by = [builder_name('Mac Builder')], -) - - -ci.fyi_ios_builder( - name = 'ios-simulator-cronet', - console_view_entry = ci.console_view_entry( - category = 'cronet', - ), - executable = 'recipe:chromium', - notifies = ['cronet'], - properties = { - 'xcode_build_version': '11c29', - }, -) - - -ci.fyi_windows_builder( - name = 'Win10 Tests x64 1803', - console_view_entry = ci.console_view_entry( - category = 'win10|1803', - ), - goma_backend = None, - os = os.WINDOWS_10, - triggered_by = [builder_name('Win x64 Builder')], -) - - -ci.gpu_builder( - name = 'Android Release (Nexus 5X)', - console_view_entry = ci.console_view_entry( - category = 'Android', - ), -) - -ci.gpu_builder( - name = 'GPU Linux Builder', - console_view_entry = ci.console_view_entry( - category = 'Linux', - ), -) - -ci.gpu_builder( - name = 'GPU Mac Builder', - console_view_entry = ci.console_view_entry( - category = 'Mac', - ), - cores = None, - os = os.MAC_ANY, -) - -ci.gpu_builder( - name = 'GPU Win x64 Builder', - builderless = True, - console_view_entry = ci.console_view_entry( - category = 'Windows', - ), - os = os.WINDOWS_ANY, -) - - -ci.gpu_thin_tester( - name = 'Linux Release (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'Linux', - ), - triggered_by = [builder_name('GPU Linux Builder')], -) - -ci.gpu_thin_tester( - name = 'Mac Release (Intel)', - console_view_entry = ci.console_view_entry( - category = 'Mac', - ), - triggered_by = [builder_name('GPU Mac Builder')], -) - -ci.gpu_thin_tester( - name = 'Mac Retina Release (AMD)', - console_view_entry = ci.console_view_entry( - category = 'Mac', - ), - triggered_by = [builder_name('GPU Mac Builder')], -) - -ci.gpu_thin_tester( - name = 'Win10 x64 Release (NVIDIA)', - console_view_entry = ci.console_view_entry( - category = 'Windows', - ), - triggered_by = [builder_name('GPU Win x64 Builder')], -) - - -ci.linux_builder( - name = 'Cast Linux', - console_view_entry = ci.console_view_entry( - category = 'cast', - short_name = 'vid', - ), - goma_jobs = goma.jobs.J50, -) - -ci.linux_builder( - name = 'Fuchsia ARM64', - console_view_entry = ci.console_view_entry( - category = 'fuchsia|a64', - short_name = 'rel', - ), - notifies = ['cr-fuchsia'], -) - -ci.linux_builder( - name = 'Fuchsia x64', - console_view_entry = ci.console_view_entry( - category = 'fuchsia|x64', - short_name = 'rel', - ), - notifies = ['cr-fuchsia'], -) - -ci.linux_builder( - name = 'Linux Builder', - console_view_entry = ci.console_view_entry( - category = 'release', - short_name = 'bld', - ), -) - -ci.linux_builder( - name = 'Linux Builder (dbg)', - console_view_entry = ci.console_view_entry( - category = 'debug|builder', - short_name = '64', - ), -) - -ci.linux_builder( - name = 'Linux Tests', - console_view_entry = ci.console_view_entry( - category = 'release', - short_name = 'tst', - ), - goma_backend = None, - triggered_by = [builder_name('Linux Builder')], -) - -ci.linux_builder( - name = 'Linux Tests (dbg)(1)', - console_view_entry = ci.console_view_entry( - category = 'debug|tester', - short_name = '64', - ), - triggered_by = [builder_name('Linux Builder (dbg)')], -) - -ci.linux_builder( - name = 'fuchsia-arm64-cast', - console_view_entry = ci.console_view_entry( - category = 'fuchsia|cast', - short_name = 'a64', - ), - notifies = ['cr-fuchsia'], -) - -ci.linux_builder( - name = 'fuchsia-x64-cast', - console_view_entry = ci.console_view_entry( - category = 'fuchsia|cast', - short_name = 'x64', - ), - notifies = ['cr-fuchsia'], -) - -ci.linux_builder( - name = 'linux-ozone-rel', - console_view_entry = ci.console_view_entry( - category = 'release', - short_name = 'ozo', - ), -) - -ci.linux_builder( - name = 'Linux Ozone Tester (Headless)', - console_view = 'chromium.fyi', - console_view_entry = ci.console_view_entry( - category = 'linux', - short_name = 'loh', - ), - triggered_by = [builder_name('linux-ozone-rel')], -) - -ci.linux_builder( - name = 'Linux Ozone Tester (Wayland)', - console_view = 'chromium.fyi', - console_view_entry = ci.console_view_entry( - category = 'linux', - short_name = 'low', - ), - triggered_by = [builder_name('linux-ozone-rel')], -) - -ci.linux_builder( - name = 'Linux Ozone Tester (X11)', - console_view = 'chromium.fyi', - console_view_entry = ci.console_view_entry( - category = 'linux', - short_name = 'lox', - ), - triggered_by = [builder_name('linux-ozone-rel')], -) - - -ci.mac_builder( - name = 'Mac Builder', - console_view_entry = ci.console_view_entry( - category = 'release', - short_name = 'bld', - ), - os = os.MAC_10_14, -) - -ci.mac_builder( - name = 'Mac Builder (dbg)', - console_view_entry = ci.console_view_entry( - category = 'debug', - short_name = 'bld', - ), - os = os.MAC_ANY, -) - -ci.thin_tester( - name = 'Mac10.10 Tests', - mastername = 'chromium.mac', - console_view_entry = ci.console_view_entry( - category = 'release', - short_name = '10', - ), - triggered_by = [builder_name('Mac Builder')], -) - -ci.thin_tester( - name = 'Mac10.11 Tests', - mastername = 'chromium.mac', - console_view_entry = ci.console_view_entry( - category = 'release', - short_name = '11', - ), - triggered_by = [builder_name('Mac Builder')], -) - -ci.thin_tester( - name = 'Mac10.12 Tests', - mastername = 'chromium.mac', - console_view_entry = ci.console_view_entry( - category = 'release', - short_name = '12', - ), - triggered_by = [builder_name('Mac Builder')], -) - -ci.thin_tester( - name = 'Mac10.13 Tests', - mastername = 'chromium.mac', - console_view_entry = ci.console_view_entry( - category = 'release', - short_name = '13', - ), - triggered_by = [builder_name('Mac Builder')], -) - -ci.thin_tester( - name = 'Mac10.14 Tests', - mastername = 'chromium.mac', - console_view_entry = ci.console_view_entry( - category = 'release', - short_name = '14', - ), - triggered_by = [builder_name('Mac Builder')], -) - -ci.thin_tester( - name = 'Mac10.13 Tests (dbg)', - mastername = 'chromium.mac', - console_view_entry = ci.console_view_entry( - category = 'debug', - short_name = '13', - ), - triggered_by = [builder_name('Mac Builder (dbg)')], -) - -ci.thin_tester( - name = 'WebKit Mac10.13 (retina)', - mastername = 'chromium.mac', - console_view_entry = ci.console_view_entry( - category = 'release', - short_name = 'ret', - ), - triggered_by = [builder_name('Mac Builder')], -) - - -ci.mac_ios_builder( - name = 'ios-simulator', - console_view_entry = ci.console_view_entry( - category = 'ios|default', - short_name = 'sim', - ), - executable = 'recipe:chromium', - properties = { - 'xcode_build_version': '11c29', - }, -) - -ci.mac_ios_builder( - name = 'ios-simulator-full-configs', - console_view_entry = ci.console_view_entry( - category = 'ios|default', - short_name = 'ful', - ), - executable = 'recipe:chromium', -) - - -ci.memory_builder( - name = 'Linux ASan LSan Builder', - console_view_entry = ci.console_view_entry( - category = 'linux|asan lsan', - short_name = 'bld', - ), - ssd = True, -) - -ci.memory_builder( - name = 'Linux ASan LSan Tests (1)', - console_view_entry = ci.console_view_entry( - category = 'linux|asan lsan', - short_name = 'tst', - ), - triggered_by = [builder_name('Linux ASan LSan Builder')], -) - -ci.memory_builder( - name = 'Linux ASan Tests (sandboxed)', - console_view_entry = ci.console_view_entry( - category = 'linux|asan lsan', - short_name = 'sbx', - ), - triggered_by = [builder_name('Linux ASan LSan Builder')], -) - -ci.memory_builder( - name = 'Linux TSan Builder', - console_view_entry = ci.console_view_entry( - category = 'linux|TSan v2', - short_name = 'bld', - ), -) - -ci.memory_builder( - name = 'Linux TSan Tests', - console_view_entry = ci.console_view_entry( - category = 'linux|TSan v2', - short_name = 'tst', - ), - triggered_by = [builder_name('Linux TSan Builder')], -) - - -ci.win_builder( - name = 'Win7 Tests (dbg)(1)', - console_view_entry = ci.console_view_entry( - category = 'debug|tester', - short_name = '7', - ), - os = os.WINDOWS_7, - triggered_by = [builder_name('Win Builder (dbg)')], -) - -ci.win_builder( - name = 'Win 7 Tests x64 (1)', - console_view_entry = ci.console_view_entry( - category = 'release|tester', - short_name = '64', - ), - os = os.WINDOWS_7, - triggered_by = [builder_name('Win x64 Builder')], -) - -ci.win_builder( - name = 'Win Builder (dbg)', - console_view_entry = ci.console_view_entry( - category = 'debug|builder', - short_name = '32', - ), - cores = 32, - os = os.WINDOWS_ANY, -) - -ci.win_builder( - name = 'Win x64 Builder', - console_view_entry = ci.console_view_entry( - category = 'release|builder', - short_name = '64', - ), - cores = 32, - os = os.WINDOWS_ANY, -) - -ci.win_builder( - name = 'Win10 Tests x64', - console_view_entry = ci.console_view_entry( - category = 'release|tester', - short_name = 'w10', - ), - triggered_by = [builder_name('Win x64 Builder')], -)
diff --git a/infra/config/subprojects/chromium/versioned/trunk/buckets/try.star b/infra/config/subprojects/chromium/versioned/trunk/buckets/try.star deleted file mode 100644 index 5cdf7fb..0000000 --- a/infra/config/subprojects/chromium/versioned/trunk/buckets/try.star +++ /dev/null
@@ -1,619 +0,0 @@ -load('//lib/builders.star', 'cpu', 'goma', 'os') -load('//lib/try.star', 'try_') -# Load this using relative path so that the load statement doesn't -# need to be changed when making a new milestone -load('../vars.star', 'vars') - - -try_.declare_bucket(vars) - -try_.set_defaults( - vars, - main_list_view = vars.main_list_view_name, -) - - -# Builders are sorted first lexicographically by the function used to define -# them, then lexicographically by their name - - -try_.blink_builder( - name = 'linux-blink-rel', - goma_backend = goma.backend.RBE_PROD, - tryjob = try_.job( - location_regexp = [ - '.+/[+]/cc/.+', - '.+/[+]/third_party/blink/renderer/core/paint/.+', - '.+/[+]/third_party/blink/renderer/core/svg/.+', - '.+/[+]/third_party/blink/renderer/platform/graphics/.+', - ], - ), -) - - -try_.chromium_android_builder( - name = 'android-binary-size', - executable = 'recipe:binary_size_trybot', - goma_jobs = goma.jobs.J150, - properties = { - '$build/binary_size': { - 'analyze_targets': [ - '//android_webview:system_webview_apk_manifest_expectations', - '//android_webview:trichrome_webview_apk_manifest_expectations', - '//chrome/android:chrome_modern_public_bundle__base_libs_and_assets_expectations', - '//chrome/android:monochrome_public_bundle__base_bundle_module_manifest_expectations', - '//chrome/android:monochrome_public_bundle__base_libs_and_assets_expectations', - '//chrome/android:monochrome_public_bundle_proguard_expectations', - '//chrome/android:monochrome_public_minimal_apks', - '//chrome/android:trichrome_chrome_bundle__base_bundle_module_manifest_expectations', - '//chrome/android:trichrome_chrome_bundle__base_libs_and_assets_expectations', - '//chrome/android:trichrome_library_apk_libs_and_assets_expectations', - '//chrome/android:trichrome_library_apk_manifest_expectations', - '//tools/binary_size:binary_size_trybot_py', - ], - 'compile_targets': [ - 'chrome_modern_public_bundle__base_libs_and_assets_expectations', - 'monochrome_public_bundle__base_bundle_module_manifest_expectations', - 'monochrome_public_bundle__base_libs_and_assets_expectations', - 'monochrome_public_bundle_proguard_expectations', - 'monochrome_public_minimal_apks', - 'monochrome_static_initializers', - 'system_webview_apk_manifest_expectations', - 'trichrome_chrome_bundle__base_bundle_module_manifest_expectations', - 'trichrome_chrome_bundle__base_libs_and_assets_expectations', - 'trichrome_library_apk_libs_and_assets_expectations', - 'trichrome_library_apk_manifest_expectations', - 'trichrome_webview_apk_manifest_expectations' - ], - }, - }, - tryjob = try_.job(), -) - -try_.chromium_android_builder( - name = 'android-cronet-arm-dbg', - tryjob = try_.job( - location_regexp = [ - '.+/[+]/components/cronet/.+', - '.+/[+]/components/grpc_support/.+', - '.+/[+]/build/android/.+', - '.+/[+]/build/config/android/.+', - ], - location_regexp_exclude = [ - '.+/[+]/components/cronet/ios/.+', - ], - ), -) - -try_.chromium_android_builder( - name = 'android-lollipop-arm-rel', - goma_jobs = goma.jobs.J150, - tryjob = try_.job(), -) - -try_.chromium_android_builder( - name = 'android-marshmallow-arm64-rel', - cores = 16, - goma_jobs = goma.jobs.J300, - ssd = True, - use_java_coverage = True, - tryjob = try_.job(), -) - -try_.chromium_android_builder( - name = 'android-pie-arm64-dbg', - tryjob = try_.job( - location_regexp = [ - '.+/[+]/chrome/android/features/vr/.+', - '.+/[+]/chrome/android/java/src/org/chromium/chrome/browser/vr/.+', - '.+/[+]/chrome/android/javatests/src/org/chromium/chrome/browser/vr/.+', - '.+/[+]/chrome/browser/vr/.+', - '.+/[+]/content/browser/xr/.+', - '.+/[+]/third_party/gvr-android-sdk/.+', - '.+/[+]/third_party/arcore-android-sdk/.+', - '.+/[+]/third_party/arcore-android-sdk-client/.+', - ], - ), -) - -try_.chromium_android_builder( - name = 'android-pie-arm64-rel', - cores = 16, - goma_jobs = goma.jobs.J300, - ssd = True, - tryjob = try_.job(), -) - -try_.chromium_android_builder( - name = 'android_compile_dbg', - goma_jobs = goma.jobs.J150, - tryjob = try_.job(), -) - -try_.chromium_android_builder( - name = 'android_compile_x64_dbg', - tryjob = try_.job( - location_regexp = [ - '.+/[+]/chrome/android/java/src/org/chromium/chrome/browser/vr/.+', - '.+/[+]/chrome/browser/vr/.+', - '.+/[+]/content/browser/xr/.+', - '.+/[+]/sandbox/linux/seccomp-bpf/.+', - '.+/[+]/sandbox/linux/seccomp-bpf-helpers/.+', - '.+/[+]/sandbox/linux/system_headers/.+', - '.+/[+]/sandbox/linux/tests/.+', - '.+/[+]/third_party/gvr-android-sdk/.+', - ], - ), -) - -try_.chromium_android_builder( - name = 'android_compile_x86_dbg', - tryjob = try_.job( - location_regexp = [ - '.+/[+]/chrome/android/java/src/org/chromium/chrome/browser/vr/.+', - '.+/[+]/chrome/browser/vr/.+', - '.+/[+]/content/browser/xr/.+', - '.+/[+]/sandbox/linux/seccomp-bpf/.+', - '.+/[+]/sandbox/linux/seccomp-bpf-helpers/.+', - '.+/[+]/sandbox/linux/system_headers/.+', - '.+/[+]/sandbox/linux/tests/.+', - '.+/[+]/third_party/gvr-android-sdk/.+', - ], - ), -) - -try_.chromium_android_builder( - name = 'android_cronet', - tryjob = try_.job(), -) - -try_.chromium_android_builder( - name = 'cast_shell_android', - tryjob = try_.job(), -) - - -try_.chromium_chromiumos_builder( - name = 'chromeos-amd64-generic-dbg', - tryjob = try_.job( - location_regexp = [ - '.+/[+]/content/gpu/.+', - '.+/[+]/media/.+', - ], - ), -) - -try_.chromium_chromiumos_builder( - name = 'chromeos-amd64-generic-rel', - tryjob = try_.job(), -) - -try_.chromium_chromiumos_builder( - name = 'chromeos-arm-generic-rel', - tryjob = try_.job(), -) - -try_.chromium_chromiumos_builder( - name = 'chromeos-kevin-compile-rel', - tryjob = try_.job( - location_regexp = [ - '.+/[+]/chromeos/CHROMEOS_LKGM', - ], - ), -) - -try_.chromium_chromiumos_builder( - name = 'chromeos-kevin-rel', - tryjob = try_.job( - location_regexp = [ - '.+/[+]/build/chromeos/.+', - '.+/[+]/build/config/chromeos/.*', - ], - ), -) - -try_.chromium_chromiumos_builder( - name = 'linux-chromeos-compile-dbg', - tryjob = try_.job(), -) - -try_.chromium_chromiumos_builder( - name = 'linux-chromeos-rel', - goma_jobs = goma.jobs.J150, - tryjob = try_.job(cancel_stale = False), - use_clang_coverage = True, -) - - -try_.chromium_dawn_builder( - name = 'dawn-linux-x64-deps-rel', - tryjob = try_.job( - location_regexp = [ - '.+/[+]/gpu/.+', - '.+/[+]/testing/buildbot/chromium.dawn.json', - '.+/[+]/third_party/blink/renderer/modules/webgpu/.+', - '.+/[+]/third_party/blink/web_tests/external/wpt/webgpu/.+', - '.+/[+]/third_party/blink/web_tests/wpt_internal/webgpu/.+', - '.+/[+]/third_party/blink/web_tests/WebGPUExpectations', - '.+/[+]/third_party/dawn/.+', - '.+/[+]/tools/clang/scripts/update.py', - '.+/[+]/ui/gl/features.gni', - ], - ), -) - -try_.chromium_dawn_builder( - name = 'dawn-mac-x64-deps-rel', - os = os.MAC_ANY, - tryjob = try_.job( - location_regexp = [ - '.+/[+]/gpu/.+', - '.+/[+]/testing/buildbot/chromium.dawn.json', - '.+/[+]/third_party/blink/renderer/modules/webgpu/.+', - '.+/[+]/third_party/blink/web_tests/external/wpt/webgpu/.+', - '.+/[+]/third_party/blink/web_tests/wpt_internal/webgpu/.+', - '.+/[+]/third_party/blink/web_tests/WebGPUExpectations', - '.+/[+]/third_party/dawn/.+', - '.+/[+]/tools/clang/scripts/update.py', - '.+/[+]/ui/gl/features.gni', - ], - ), -) - -try_.chromium_dawn_builder( - name = 'dawn-win10-x64-deps-rel', - os = os.WINDOWS_ANY, - tryjob = try_.job( - location_regexp = [ - '.+/[+]/gpu/.+', - '.+/[+]/testing/buildbot/chromium.dawn.json', - '.+/[+]/third_party/blink/renderer/modules/webgpu/.+', - '.+/[+]/third_party/blink/web_tests/external/wpt/webgpu/.+', - '.+/[+]/third_party/blink/web_tests/wpt_internal/webgpu/.+', - '.+/[+]/third_party/blink/web_tests/WebGPUExpectations', - '.+/[+]/third_party/dawn/.+', - '.+/[+]/tools/clang/scripts/update.py', - '.+/[+]/ui/gl/features.gni', - ], - ), -) - -try_.chromium_dawn_builder( - name = 'dawn-win10-x86-deps-rel', - os = os.WINDOWS_ANY, - tryjob = try_.job( - location_regexp = [ - '.+/[+]/gpu/.+', - '.+/[+]/testing/buildbot/chromium.dawn.json', - '.+/[+]/third_party/blink/renderer/modules/webgpu/.+', - '.+/[+]/third_party/blink/web_tests/external/wpt/webgpu/.+', - '.+/[+]/third_party/blink/web_tests/wpt_internal/webgpu/.+', - '.+/[+]/third_party/blink/web_tests/WebGPUExpectations', - '.+/[+]/third_party/dawn/.+', - '.+/[+]/tools/clang/scripts/update.py', - '.+/[+]/ui/gl/features.gni', - ], - ), -) - - -try_.chromium_linux_builder( - name = 'cast_shell_linux', - tryjob = try_.job(), -) - -try_.chromium_linux_builder( - name = 'closure_compilation', - executable = 'recipe:closure_compilation', - tryjob = try_.job( - location_regexp = [ - '.+/[+]/third_party/closure_compiler/.+', - ], - ), -) - -try_.chromium_linux_builder( - name = 'chromium_presubmit', - executable = 'recipe:presubmit', - goma_backend = None, - properties = { - '$depot_tools/presubmit': { - 'runhooks': True, - 'timeout_s': 480, - }, - 'repo_name': 'chromium', - }, - tryjob = try_.job( - disable_reuse = True, - ), -) - -try_.chromium_linux_builder( - name = 'fuchsia-arm64-cast', - tryjob = try_.job( - location_regexp = [ - '.+/[+]/chromecast/.+', - ], - ), -) - -try_.chromium_linux_builder( - name = 'fuchsia-x64-cast', - tryjob = try_.job(), -) - -try_.chromium_linux_builder( - name = 'fuchsia_arm64', - tryjob = try_.job(), -) - -try_.chromium_linux_builder( - name = 'fuchsia_x64', - tryjob = try_.job(), -) - -try_.chromium_linux_builder( - name = 'linux-libfuzzer-asan-rel', - executable = 'recipe:chromium_libfuzzer_trybot', - tryjob = try_.job(), -) - -try_.chromium_linux_builder( - name = 'linux-ozone-rel', - tryjob = try_.job(), -) - -try_.chromium_linux_builder( - name = 'linux-rel', - goma_jobs = goma.jobs.J150, - tryjob = try_.job(), - use_clang_coverage = True, -) - -try_.chromium_linux_builder( - name = 'linux_chromium_asan_rel_ng', - goma_jobs = goma.jobs.J150, - ssd = True, - tryjob = try_.job(), -) - -try_.chromium_linux_builder( - name = 'linux_chromium_compile_dbg_ng', - caches = [ - swarming.cache( - name = 'builder', - path = 'linux_debug', - ), - ], - goma_jobs = goma.jobs.J150, - tryjob = try_.job(), -) - -try_.chromium_linux_builder( - name = 'linux_chromium_dbg_ng', - caches = [ - swarming.cache( - name = 'builder', - path = 'linux_debug', - ), - ], - tryjob = try_.job( - location_regexp = [ - '.+/[+]/build/.*check_gn_headers.*', - ], - ), -) - -try_.chromium_linux_builder( - name = 'linux_chromium_tsan_rel_ng', - goma_jobs = goma.jobs.J150, - tryjob = try_.job(), -) - -try_.chromium_linux_builder( - name = 'linux_layout_tests_composite_after_paint', - tryjob = try_.job( - location_regexp = [ - '.+/[+]/third_party/blink/renderer/core/paint/.+', - '.+/[+]/third_party/blink/renderer/core/svg/.+', - '.+/[+]/third_party/blink/renderer/platform/graphics/.+', - '.+/[+]/third_party/blink/web_tests/.+', - ], - ), -) - -try_.chromium_linux_builder( - name = 'linux_layout_tests_layout_ng_disabled', - tryjob = try_.job( - location_regexp = [ - '.+/[+]/third_party/blink/renderer/core/editing/.+', - '.+/[+]/third_party/blink/renderer/core/layout/.+', - '.+/[+]/third_party/blink/renderer/core/paint/.+', - '.+/[+]/third_party/blink/renderer/core/svg/.+', - '.+/[+]/third_party/blink/renderer/platform/fonts/shaping/.+', - '.+/[+]/third_party/blink/renderer/platform/graphics/.+', - '.+/[+]/third_party/blink/web_tests/FlagExpectations/disable-layout-ng', - '.+/[+]/third_party/blink/web_tests/flag-specific/disable-layout-ng/.+', - ], - ), -) - -try_.chromium_linux_builder( - name = 'linux_vr', - tryjob = try_.job( - location_regexp = [ - '.+/[+]/chrome/browser/vr/.+', - '.+/[+]/content/browser/xr/.+', - ], - ), -) - - -try_.chromium_mac_builder( - name = 'mac-rel', - goma_jobs = goma.jobs.J150, - os = os.MAC_10_13, - tryjob = try_.job(), -) - -try_.chromium_mac_builder( - name = 'mac_chromium_compile_dbg_ng', - goma_jobs = goma.jobs.J150, - os = os.MAC_10_13, - tryjob = try_.job(), -) - - -try_.chromium_mac_ios_builder( - name = 'ios-simulator', - executable = 'recipe:chromium_trybot', - properties = { - 'xcode_build_version': '11c29', - }, - tryjob = try_.job(), -) - -try_.chromium_mac_ios_builder( - name = 'ios-simulator-cronet', - executable = 'recipe:chromium_trybot', - tryjob = try_.job( - location_regexp = [ - '.+/[+]/components/cronet/.+', - '.+/[+]/components/grpc_support/.+', - '.+/[+]/ios/.+', - ], - location_regexp_exclude = [ - '.+/[+]/components/cronet/android/.+', - ], - ), -) - -try_.chromium_mac_ios_builder( - name = 'ios-simulator-full-configs', - executable = 'recipe:chromium_trybot', - tryjob = try_.job( - location_regexp = [ - '.+/[+]/ios/.+', - ], - ), -) - - -try_.chromium_win_builder( - name = 'win-libfuzzer-asan-rel', - builderless = False, - executable = 'recipe:chromium_libfuzzer_trybot', - os = os.WINDOWS_ANY, - tryjob = try_.job(cancel_stale = False), -) - -try_.chromium_win_builder( - name = 'win_chromium_compile_dbg_ng', - goma_jobs = goma.jobs.J150, - tryjob = try_.job(cancel_stale = False), -) - -try_.chromium_win_builder( - name = 'win10_chromium_x64_rel_ng', - goma_jobs = goma.jobs.J150, - os = os.WINDOWS_10, - ssd = True, - use_clang_coverage = True, - tryjob = try_.job(cancel_stale = False), -) - - -try_.gpu_chromium_android_builder( - name = 'android_optional_gpu_tests_rel', - tryjob = try_.job( - location_regexp = [ - '.+/[+]/cc/.+', - '.+/[+]/chrome/browser/vr/.+', - '.+/[+]/content/browser/xr/.+', - '.+/[+]/components/viz/.+', - '.+/[+]/content/test/gpu/.+', - '.+/[+]/gpu/.+', - '.+/[+]/media/audio/.+', - '.+/[+]/media/filters/.+', - '.+/[+]/media/gpu/.+', - '.+/[+]/services/viz/.+', - '.+/[+]/testing/trigger_scripts/.+', - '.+/[+]/third_party/blink/renderer/modules/webgl/.+', - '.+/[+]/third_party/blink/renderer/platform/graphics/gpu/.+', - '.+/[+]/tools/clang/scripts/update.py', - '.+/[+]/ui/gl/.+', - ], - ), -) - - -try_.gpu_chromium_linux_builder( - name = 'linux_optional_gpu_tests_rel', - tryjob = try_.job( - location_regexp = [ - '.+/[+]/chrome/browser/vr/.+', - '.+/[+]/content/browser/xr/.+', - '.+/[+]/content/test/gpu/.+', - '.+/[+]/gpu/.+', - '.+/[+]/media/audio/.+', - '.+/[+]/media/filters/.+', - '.+/[+]/media/gpu/.+', - '.+/[+]/testing/buildbot/chromium.gpu.fyi.json', - '.+/[+]/testing/trigger_scripts/.+', - '.+/[+]/third_party/blink/renderer/modules/webgl/.+', - '.+/[+]/third_party/blink/renderer/platform/graphics/gpu/.+', - '.+/[+]/tools/clang/scripts/update.py', - '.+/[+]/ui/gl/.+', - ], - ), -) - - -try_.gpu_chromium_mac_builder( - name = 'mac_optional_gpu_tests_rel', - tryjob = try_.job( - location_regexp = [ - '.+/[+]/chrome/browser/vr/.+', - '.+/[+]/content/browser/xr/.+', - '.+/[+]/content/test/gpu/.+', - '.+/[+]/gpu/.+', - '.+/[+]/media/audio/.+', - '.+/[+]/media/filters/.+', - '.+/[+]/media/gpu/.+', - '.+/[+]/services/shape_detection/.+', - '.+/[+]/testing/buildbot/chromium.gpu.fyi.json', - '.+/[+]/testing/trigger_scripts/.+', - '.+/[+]/third_party/blink/renderer/modules/webgl/.+', - '.+/[+]/third_party/blink/renderer/platform/graphics/gpu/.+', - '.+/[+]/tools/clang/scripts/update.py', - '.+/[+]/ui/gl/.+', - ], - ), -) - - -try_.gpu_chromium_win_builder( - name = 'win_optional_gpu_tests_rel', - builderless = True, - os = os.WINDOWS_DEFAULT, - tryjob = try_.job( - location_regexp = [ - '.+/[+]/chrome/browser/vr/.+', - '.+/[+]/content/browser/xr/.+', - '.+/[+]/content/test/gpu/.+', - '.+/[+]/device/vr/.+', - '.+/[+]/gpu/.+', - '.+/[+]/media/audio/.+', - '.+/[+]/media/filters/.+', - '.+/[+]/media/gpu/.+', - '.+/[+]/testing/buildbot/chromium.gpu.fyi.json', - '.+/[+]/testing/trigger_scripts/.+', - '.+/[+]/third_party/blink/renderer/modules/vr/.+', - '.+/[+]/third_party/blink/renderer/modules/webgl/.+', - '.+/[+]/third_party/blink/renderer/modules/xr/.+', - '.+/[+]/third_party/blink/renderer/platform/graphics/gpu/.+', - '.+/[+]/tools/clang/scripts/update.py', - '.+/[+]/ui/gl/.+', - ], - ), -)
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index 1b96a0b..cb43bc7 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -932,6 +932,9 @@ <message name="IDS_IOS_MANAGE_YOUR_GOOGLE_ACCOUNT_TITLE" desc="Title for the view in the Settings to open 'Google Account' web page."> Manage Your Google Account </message> + <message name="IDS_IOS_REMOVE_GOOGLE_ACCOUNT_TITLE" desc="Title for the button that removes a Google account from the device"> + Remove Account from this Device + </message> <message name="IDS_IOS_MANAGE_SYNC_SETTINGS_TITLE" desc="Title for the view in the Settings for enabling/disabling Sync. [iOS only]"> Manage Sync </message>
diff --git a/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.h b/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.h index dbeb9aa..901d8e14 100644 --- a/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.h +++ b/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.h
@@ -47,7 +47,7 @@ scoped_refptr<ShortcutsBackend> GetShortcutsBackendIfExists() override; std::unique_ptr<KeywordExtensionsDelegate> GetKeywordExtensionsDelegate( KeywordProvider* keyword_provider) override; - upboarding::TileService* GetQueryTileService() const override; + query_tiles::TileService* GetQueryTileService() const override; std::string GetAcceptLanguages() const override; std::string GetEmbedderRepresentationOfAboutScheme() const override; std::vector<base::string16> GetBuiltinURLs() override;
diff --git a/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.mm b/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.mm index 35c26ce..d8e6db0 100644 --- a/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.mm +++ b/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.mm
@@ -136,7 +136,7 @@ return nullptr; } -upboarding::TileService* AutocompleteProviderClientImpl::GetQueryTileService() +query_tiles::TileService* AutocompleteProviderClientImpl::GetQueryTileService() const { return nullptr; }
diff --git a/ios/chrome/browser/browsing_data/browsing_data_remover_impl.mm b/ios/chrome/browser/browsing_data/browsing_data_remover_impl.mm index f1ed8b6..2123ad2 100644 --- a/ios/chrome/browser/browsing_data/browsing_data_remover_impl.mm +++ b/ios/chrome/browser/browsing_data/browsing_data_remover_impl.mm
@@ -619,7 +619,7 @@ "History.ClearBrowsingData.Duration.FullDeletion", delta); } else { UMA_HISTOGRAM_MEDIUM_TIMES( - "History.ClearBrowsingData.Duration.PartialDeletion", delta); + "History.ClearBrowsingData.Duration.TimeRangeDeletion", delta); } } removal_queue_.pop();
diff --git a/ios/chrome/browser/browsing_data/browsing_data_remover_impl_unittest.mm b/ios/chrome/browser/browsing_data/browsing_data_remover_impl_unittest.mm index 56478f21..c39cfe0 100644 --- a/ios/chrome/browser/browsing_data/browsing_data_remover_impl_unittest.mm +++ b/ios/chrome/browser/browsing_data/browsing_data_remover_impl_unittest.mm
@@ -50,8 +50,8 @@ const char kFullDeletionHistogram[] = "History.ClearBrowsingData.Duration.FullDeletion"; -const char kPartialDeletionHistogram[] = - "History.ClearBrowsingData.Duration.PartialDeletion"; +const char kTimeRangeDeletionHistogram[] = + "History.ClearBrowsingData.Duration.TimeRangeDeletion"; // Observer used to validate that BrowsingDataRemoverImpl notifies its // observers. @@ -154,7 +154,7 @@ base::HistogramTester histogram_tester; __block int remaining_calls = 1; histogram_tester.ExpectTotalCount(kFullDeletionHistogram, 0); - histogram_tester.ExpectTotalCount(kPartialDeletionHistogram, 0); + histogram_tester.ExpectTotalCount(kTimeRangeDeletionHistogram, 0); browsing_data_remover_.Remove(browsing_data::TimePeriod::ALL_TIME, kRemoveMask, base::BindOnce(^{ @@ -167,7 +167,7 @@ })); histogram_tester.ExpectTotalCount(kFullDeletionHistogram, 1); - histogram_tester.ExpectTotalCount(kPartialDeletionHistogram, 0); + histogram_tester.ExpectTotalCount(kTimeRangeDeletionHistogram, 0); } // Tests that BrowsingDataRemoverImpl::Remove() Logs the duration to the correct @@ -176,7 +176,7 @@ base::HistogramTester histogram_tester; __block int remaining_calls = 1; histogram_tester.ExpectTotalCount(kFullDeletionHistogram, 0); - histogram_tester.ExpectTotalCount(kPartialDeletionHistogram, 0); + histogram_tester.ExpectTotalCount(kTimeRangeDeletionHistogram, 0); browsing_data_remover_.Remove(browsing_data::TimePeriod::LAST_HOUR, kRemoveMask, base::BindOnce(^{ @@ -189,7 +189,7 @@ })); histogram_tester.ExpectTotalCount(kFullDeletionHistogram, 0); - histogram_tester.ExpectTotalCount(kPartialDeletionHistogram, 1); + histogram_tester.ExpectTotalCount(kTimeRangeDeletionHistogram, 1); } // Tests that BrowsingDataRemoverImpl::Remove() can finish performing its
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index 341db2ee..c4d6031e 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -621,6 +621,12 @@ {"enable-mygoogle", flag_descriptions::kEnableMyGoogleName, flag_descriptions::kEnableMyGoogleDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(kEnableMyGoogle)}, + {"autofill-enable-card-nickname-management", + flag_descriptions::kAutofillEnableCardNicknameManagementName, + flag_descriptions::kAutofillEnableCardNicknameManagementDescription, + flags_ui::kOsIos, + FEATURE_VALUE_TYPE( + autofill::features::kAutofillEnableCardNicknameManagement)}, }; bool SkipConditionalFeatureEntry(const flags_ui::FeatureEntry& entry) {
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc index d2729aa..16f09f3 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -23,6 +23,12 @@ "Offers uploading Autofilled credit cards to Google Payments after form " "submission."; +const char kAutofillEnableCardNicknameManagementName[] = + "Enable Autofill card nickname management"; +const char kAutofillEnableCardNicknameManagementDescription[] = + "When enabled, nicknames for credit cards will be able to be uploaded to " + "Payments or modified locally."; + const char kAutofillEnableCompanyNameName[] = "Enable Autofill Company Name field"; const char kAutofillEnableCompanyNameDescription[] =
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h index 429821c..cdbf26b 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -19,6 +19,10 @@ extern const char kAutofillCreditCardUploadName[]; extern const char kAutofillCreditCardUploadDescription[]; +// Title and description for the flag to control card nickname management. +extern const char kAutofillEnableCardNicknameManagementName[]; +extern const char kAutofillEnableCardNicknameManagementDescription[]; + // Title and description for the flag to control deprecating company name. extern const char kAutofillEnableCompanyNameName[]; extern const char kAutofillEnableCompanyNameDescription[];
diff --git a/ios/chrome/browser/infobars/overlays/infobar_overlay_request_factory_impl.mm b/ios/chrome/browser/infobars/overlays/infobar_overlay_request_factory_impl.mm index 578e563..161e813be 100644 --- a/ios/chrome/browser/infobars/overlays/infobar_overlay_request_factory_impl.mm +++ b/ios/chrome/browser/infobars/overlays/infobar_overlay_request_factory_impl.mm
@@ -5,6 +5,7 @@ #import "ios/chrome/browser/infobars/overlays/infobar_overlay_request_factory_impl.h" #import "ios/chrome/browser/infobars/infobar_ios.h" +#import "ios/chrome/browser/overlays/public/infobar_banner/confirm_infobar_banner_overlay_request_config.h" #import "ios/chrome/browser/overlays/public/infobar_banner/save_password_infobar_banner_overlay.h" #import "ios/chrome/browser/overlays/public/infobar_banner/translate_infobar_banner_overlay_request_config.h" #import "ios/chrome/browser/overlays/public/infobar_modal/password_infobar_modal_overlay_request_config.h" @@ -17,6 +18,7 @@ using infobars::InfoBar; using translate_infobar_overlays::TranslateBannerRequestConfig; using translate_infobar_overlays::TranslateModalRequestConfig; +using confirm_infobar_overlays::ConfirmBannerRequestConfig; InfobarOverlayRequestFactoryImpl::InfobarOverlayRequestFactoryImpl() { // Create the factory helpers for the supported infobar types. @@ -30,6 +32,10 @@ CreateFactory<TranslateBannerRequestConfig>(), /*detail_sheet_factory=*/nullptr, CreateFactory<TranslateModalRequestConfig>()); + SetUpFactories(InfobarType::kInfobarTypeConfirm, + CreateFactory<ConfirmBannerRequestConfig>(), + /*detail_sheet_factory=*/nullptr, + /*modal_factory=*/nullptr); } InfobarOverlayRequestFactoryImpl::~InfobarOverlayRequestFactoryImpl() = default;
diff --git a/ios/chrome/browser/overlays/public/infobar_banner/BUILD.gn b/ios/chrome/browser/overlays/public/infobar_banner/BUILD.gn index 1905e08..3ad4c1b 100644 --- a/ios/chrome/browser/overlays/public/infobar_banner/BUILD.gn +++ b/ios/chrome/browser/overlays/public/infobar_banner/BUILD.gn
@@ -4,6 +4,8 @@ source_set("infobar_banner") { sources = [ + "confirm_infobar_banner_overlay_request_config.h", + "confirm_infobar_banner_overlay_request_config.mm", "infobar_banner_overlay_responses.cc", "infobar_banner_overlay_responses.h", "save_password_infobar_banner_overlay.h",
diff --git a/ios/chrome/browser/overlays/public/infobar_banner/confirm_infobar_banner_overlay_request_config.h b/ios/chrome/browser/overlays/public/infobar_banner/confirm_infobar_banner_overlay_request_config.h new file mode 100644 index 0000000..bec1a77a --- /dev/null +++ b/ios/chrome/browser/overlays/public/infobar_banner/confirm_infobar_banner_overlay_request_config.h
@@ -0,0 +1,52 @@ +// 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 IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_BANNER_CONFIRM_INFOBAR_BANNER_OVERLAY_REQUEST_CONFIG_H_ +#define IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_BANNER_CONFIRM_INFOBAR_BANNER_OVERLAY_REQUEST_CONFIG_H_ + +#include "base/strings/string16.h" +#include "ios/chrome/browser/overlays/public/overlay_request_config.h" +#include "ios/chrome/browser/overlays/public/overlay_user_data.h" +#include "ui/gfx/image/image.h" + +namespace infobars { +class InfoBar; +} + +namespace confirm_infobar_overlays { + +// Configuration object for OverlayRequests for the banner UI for an InfoBar +// with a ConfirmInfoBarDelegate. +class ConfirmBannerRequestConfig + : public OverlayRequestConfig<ConfirmBannerRequestConfig> { + public: + ~ConfirmBannerRequestConfig() override; + + // The message text. + base::string16 message_text() const { return message_text_; } + + // The button label text. + base::string16 button_label_text() const { return button_label_text_; } + + // The infobar's icon image. + gfx::Image icon_image() const { return icon_image_; } + + private: + OVERLAY_USER_DATA_SETUP(ConfirmBannerRequestConfig); + explicit ConfirmBannerRequestConfig(infobars::InfoBar* infobar); + + // OverlayUserData: + void CreateAuxiliaryData(base::SupportsUserData* user_data) override; + + // The InfoBar causing this banner. + infobars::InfoBar* infobar_ = nullptr; + // Configuration data extracted from |infobar_|'s confirm delegate. + base::string16 message_text_; + base::string16 button_label_text_; + gfx::Image icon_image_; +}; + +} // namespace confirm_infobar_overlays + +#endif // IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_BANNER_CONFIRM_INFOBAR_BANNER_OVERLAY_REQUEST_CONFIG_H_
diff --git a/ios/chrome/browser/overlays/public/infobar_banner/confirm_infobar_banner_overlay_request_config.mm b/ios/chrome/browser/overlays/public/infobar_banner/confirm_infobar_banner_overlay_request_config.mm new file mode 100644 index 0000000..26c24228 --- /dev/null +++ b/ios/chrome/browser/overlays/public/infobar_banner/confirm_infobar_banner_overlay_request_config.mm
@@ -0,0 +1,42 @@ +// 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. + +#import "ios/chrome/browser/overlays/public/infobar_banner/confirm_infobar_banner_overlay_request_config.h" + +#include "components/infobars/core/confirm_infobar_delegate.h" +#include "components/infobars/core/infobar.h" +#include "ios/chrome/browser/infobars/infobar_ios.h" +#import "ios/chrome/browser/infobars/overlays/infobar_overlay_type.h" +#import "ios/chrome/browser/overlays/public/common/infobars/infobar_overlay_request_config.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace confirm_infobar_overlays { + +OVERLAY_USER_DATA_SETUP_IMPL(ConfirmBannerRequestConfig); + +ConfirmBannerRequestConfig::ConfirmBannerRequestConfig( + infobars::InfoBar* infobar) + : infobar_(infobar) { + DCHECK(infobar_); + ConfirmInfoBarDelegate* delegate = + static_cast<ConfirmInfoBarDelegate*>(infobar_->delegate()); + message_text_ = delegate->GetMessageText(); + button_label_text_ = + delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_OK); + icon_image_ = delegate->GetIcon(); +} + +ConfirmBannerRequestConfig::~ConfirmBannerRequestConfig() = default; + +void ConfirmBannerRequestConfig::CreateAuxiliaryData( + base::SupportsUserData* user_data) { + InfobarOverlayRequestConfig::CreateForUserData( + user_data, static_cast<InfoBarIOS*>(infobar_), + InfobarOverlayType::kBanner); +} + +} // namespace confirm_infobar_overlays
diff --git a/ios/chrome/browser/tabs/tab_helper_util.mm b/ios/chrome/browser/tabs/tab_helper_util.mm index f1fa69e0..d9e9437c 100644 --- a/ios/chrome/browser/tabs/tab_helper_util.mm +++ b/ios/chrome/browser/tabs/tab_helper_util.mm
@@ -65,6 +65,7 @@ #import "ios/chrome/browser/web/features.h" #import "ios/chrome/browser/web/font_size_tab_helper.h" #import "ios/chrome/browser/web/image_fetch_tab_helper.h" +#import "ios/chrome/browser/web/invalid_url_tab_helper.h" #import "ios/chrome/browser/web/java_script_console/java_script_console_tab_helper.h" #import "ios/chrome/browser/web/load_timing_tab_helper.h" #import "ios/chrome/browser/web/page_placeholder_tab_helper.h" @@ -112,6 +113,10 @@ security_interstitials::IOSBlockingPageTabHelper::CreateForWebState( web_state); + if (base::FeatureList::IsEnabled(web::features::kUseJSForErrorPage)) { + InvalidUrlTabHelper::CreateForWebState(web_state); + } + if (base::FeatureList::IsEnabled(kInfobarOverlayUI)) { InfobarOverlayRequestInserter::CreateForWebState(web_state); InfobarOverlayTabHelper::CreateForWebState(web_state);
diff --git a/ios/chrome/browser/translate/BUILD.gn b/ios/chrome/browser/translate/BUILD.gn index 1f8b4d3..b97600a 100644 --- a/ios/chrome/browser/translate/BUILD.gn +++ b/ios/chrome/browser/translate/BUILD.gn
@@ -114,7 +114,7 @@ testonly = true sources = [ "translate_egtest.mm" ] deps = [ - ":test_support", + ":eg_test_support", ":translate", "//base", "//base/test:test_support", @@ -177,20 +177,19 @@ } source_set("test_support") { - defines = [ "CHROME_EARL_GREY_1" ] testonly = true sources = [ - "translate_app_interface.h", - "translate_app_interface.mm", + "fake_translate_infobar_delegate.h", + "fake_translate_infobar_delegate.mm", ] deps = [ + "//components/infobars/core", + "//components/sync_preferences:test_support", "//components/translate/core/browser:browser", - "//components/translate/core/common:common", - "//components/translate/ios/browser:browser", - "//ios/chrome/browser/browser_state:browser_state", - "//ios/chrome/browser/translate", - "//ios/chrome/test/app:test_support", + "//components/translate/core/browser:test_support", "//ios/chrome/test/fakes:fakes", + "//testing/gmock", + "//third_party/metrics_proto", ] configs += [ "//build/config/compiler:enable_arc" ] } @@ -219,6 +218,30 @@ ] } +source_set("eg_test_support") { + defines = [ "CHROME_EARL_GREY_1" ] + configs += [ + "//build/config/compiler:enable_arc", + "//build/config/ios:xctest_config", + ] + testonly = true + sources = [ + "translate_app_interface.h", + "translate_app_interface.mm", + ] + deps = [ + "//base:base", + "//components/translate/core/browser:browser", + "//components/translate/core/common:common", + "//components/translate/ios/browser:browser", + "//ios/chrome/browser/browser_state:browser_state", + "//ios/chrome/browser/translate:translate", + "//ios/chrome/test/app:test_support", + "//ios/chrome/test/fakes:fakes", + "//net:net", + ] +} + source_set("eg_test_support+eg2") { defines = [ "CHROME_EARL_GREY_2" ] configs += [
diff --git a/ios/chrome/browser/translate/fake_translate_infobar_delegate.h b/ios/chrome/browser/translate/fake_translate_infobar_delegate.h new file mode 100644 index 0000000..e79952b --- /dev/null +++ b/ios/chrome/browser/translate/fake_translate_infobar_delegate.h
@@ -0,0 +1,64 @@ +// 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 IOS_CHROME_BROWSER_TRANSLATE_FAKE_TRANSLATE_INFOBAR_DELEGATE_H_ +#define IOS_CHROME_BROWSER_TRANSLATE_FAKE_TRANSLATE_INFOBAR_DELEGATE_H_ + +#include "components/sync_preferences/testing_pref_service_syncable.h" +#include "components/translate/core/browser/mock_translate_client.h" +#include "components/translate/core/browser/mock_translate_driver.h" +#include "components/translate/core/browser/mock_translate_infobar_delegate.h" +#include "components/translate/core/browser/mock_translate_ranker.h" +#include "components/translate/core/browser/translate_infobar_delegate.h" + +// Fake of TranslateInfoBarDelegate that allows for triggering Observer +// callbacks. +class FakeTranslateInfoBarDelegate + : public translate::TranslateInfoBarDelegate { + public: + FakeTranslateInfoBarDelegate( + const base::WeakPtr<translate::TranslateManager>& translate_manager, + bool is_off_the_record, + translate::TranslateStep step, + const std::string& original_language, + const std::string& target_language, + translate::TranslateErrors::Type error_type, + bool triggered_from_menu); + ~FakeTranslateInfoBarDelegate() override; + + void AddObserver(Observer* observer) override; + void RemoveObserver(Observer* observer) override; + + // Call the OnTranslateStepChanged() observer method on all + // |OnTranslateStepChanged|. + void TriggerOnTranslateStepChanged( + translate::TranslateStep step, + translate::TranslateErrors::Type error_type); + + private: + base::ObserverList<Observer> observers_; +}; + +// Factory class to create instances of FakeTranslateInfoBarDelegate. +class FakeTranslateInfoBarDelegateFactory { + public: + FakeTranslateInfoBarDelegateFactory(); + ~FakeTranslateInfoBarDelegateFactory(); + + // Create a FakeTranslateInfoBarDelegate unique_ptr with + // |original_language|and |target_language|. + std::unique_ptr<FakeTranslateInfoBarDelegate> + CreateFakeTranslateInfoBarDelegate(const std::string& original_language, + const std::string& target_language); + + private: + translate::testing::MockTranslateDriver driver_; + std::unique_ptr<sync_preferences::TestingPrefServiceSyncable> pref_service_; + std::unique_ptr<translate::testing::MockTranslateClient> client_; + std::unique_ptr<translate::testing::MockTranslateRanker> ranker_; + std::unique_ptr<translate::testing::MockLanguageModel> language_model_; + std::unique_ptr<translate::TranslateManager> manager_; +}; + +#endif // IOS_CHROME_BROWSER_TRANSLATE_FAKE_TRANSLATE_INFOBAR_DELEGATE_H_
diff --git a/ios/chrome/browser/translate/fake_translate_infobar_delegate.mm b/ios/chrome/browser/translate/fake_translate_infobar_delegate.mm new file mode 100644 index 0000000..3e74f97 --- /dev/null +++ b/ios/chrome/browser/translate/fake_translate_infobar_delegate.mm
@@ -0,0 +1,79 @@ +// 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. + +#import "ios/chrome/browser/translate/fake_translate_infobar_delegate.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +using translate::testing::MockTranslateClient; +using translate::testing::MockTranslateRanker; +using translate::testing::MockLanguageModel; + +FakeTranslateInfoBarDelegate::FakeTranslateInfoBarDelegate( + const base::WeakPtr<translate::TranslateManager>& translate_manager, + bool is_off_the_record, + translate::TranslateStep step, + const std::string& original_language, + const std::string& target_language, + translate::TranslateErrors::Type error_type, + bool triggered_from_menu) + : translate::TranslateInfoBarDelegate(translate_manager, + is_off_the_record, + step, + original_language, + target_language, + error_type, + triggered_from_menu) {} + +FakeTranslateInfoBarDelegate::~FakeTranslateInfoBarDelegate() { + for (auto& observer : observers_) { + observer.OnTranslateInfoBarDelegateDestroyed(this); + } +} + +void FakeTranslateInfoBarDelegate::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void FakeTranslateInfoBarDelegate::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +void FakeTranslateInfoBarDelegate::TriggerOnTranslateStepChanged( + translate::TranslateStep step, + translate::TranslateErrors::Type error_type) { + for (auto& observer : observers_) { + observer.OnTranslateStepChanged(step, error_type); + } +} + +FakeTranslateInfoBarDelegateFactory::FakeTranslateInfoBarDelegateFactory() { + pref_service_ = + std::make_unique<sync_preferences::TestingPrefServiceSyncable>(); + language::LanguagePrefs::RegisterProfilePrefs(pref_service_->registry()); + translate::TranslatePrefs::RegisterProfilePrefs(pref_service_->registry()); + pref_service_->registry()->RegisterBooleanPref(prefs::kOfferTranslateEnabled, + true); + client_ = + std::make_unique<MockTranslateClient>(&driver_, pref_service_.get()); + ranker_ = std::make_unique<MockTranslateRanker>(); + language_model_ = std::make_unique<MockLanguageModel>(); + manager_ = std::make_unique<translate::TranslateManager>( + client_.get(), ranker_.get(), language_model_.get()); +} + +FakeTranslateInfoBarDelegateFactory::~FakeTranslateInfoBarDelegateFactory() {} + +std::unique_ptr<FakeTranslateInfoBarDelegate> +FakeTranslateInfoBarDelegateFactory::CreateFakeTranslateInfoBarDelegate( + const std::string& original_language, + const std::string& target_language) { + return std::make_unique<FakeTranslateInfoBarDelegate>( + manager_->GetWeakPtr(), false, + translate::TranslateStep::TRANSLATE_STEP_BEFORE_TRANSLATE, + original_language, target_language, + translate::TranslateErrors::Type::NONE, false); +}
diff --git a/ios/chrome/browser/ui/authentication/cells/signin_promo_view.mm b/ios/chrome/browser/ui/authentication/cells/signin_promo_view.mm index f811461..ab635991 100644 --- a/ios/chrome/browser/ui/authentication/cells/signin_promo_view.mm +++ b/ios/chrome/browser/ui/authentication/cells/signin_promo_view.mm
@@ -18,6 +18,7 @@ #import "ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" #import "ios/chrome/common/ui/util/constraints_ui_util.h" +#import "ios/chrome/common/ui/util/pointer_interaction_util.h" #include "ios/chrome/grit/ios_strings.h" #include "ui/base/l10n/l10n_util.h" @@ -117,6 +118,8 @@ if (@available(iOS 13.4, *)) { if (base::FeatureList::IsEnabled(kPointerSupport)) { _primaryButton.pointerInteractionEnabled = YES; + _primaryButton.pointerStyleProvider = + CreateOpaqueButtonPointerStyleProvider(); } } #endif // defined(__IPHONE_13_4)
diff --git a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm index 5f06735..c6e4cec6 100644 --- a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm +++ b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm
@@ -47,6 +47,7 @@ #include "ios/chrome/common/string_util.h" #import "ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" +#import "ios/chrome/common/ui/util/pointer_interaction_util.h" #include "ios/chrome/grit/ios_chromium_strings.h" #include "ios/chrome/grit/ios_strings.h" #import "ios/public/provider/chrome/browser/chrome_browser_provider.h" @@ -842,6 +843,8 @@ if (@available(iOS 13.4, *)) { if (base::FeatureList::IsEnabled(kPointerSupport)) { _primaryButton.pointerInteractionEnabled = YES; + _primaryButton.pointerStyleProvider = + CreateOpaqueButtonPointerStyleProvider(); } } #endif // defined(__IPHONE_13_4) @@ -858,6 +861,8 @@ if (@available(iOS 13.4, *)) { if (base::FeatureList::IsEnabled(kPointerSupport)) { _secondaryButton.pointerInteractionEnabled = YES; + _secondaryButton.pointerStyleProvider = + CreateTransparentButtonPointerStyleProvider(); } } #endif // defined(__IPHONE_13_4)
diff --git a/ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_view_controller.mm b/ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_view_controller.mm index cb57ac3..010aba4c 100644 --- a/ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_view_controller.mm +++ b/ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_view_controller.mm
@@ -14,6 +14,7 @@ #import "ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" #import "ios/chrome/common/ui/util/constraints_ui_util.h" +#import "ios/chrome/common/ui/util/pointer_interaction_util.h" #import "ios/chrome/grit/ios_strings.h" #import "ios/third_party/material_components_ios/src/components/ActivityIndicator/src/MaterialActivityIndicator.h" #import "ui/base/l10n/l10n_util.h" @@ -427,6 +428,8 @@ if (@available(iOS 13.4, *)) { if (base::FeatureList::IsEnabled(kPointerSupport)) { self.confirmationButton.pointerInteractionEnabled = YES; + self.confirmationButton.pointerStyleProvider = + CreateOpaqueButtonPointerStyleProvider(); } } #endif // defined(__IPHONE_13_4) @@ -454,6 +457,8 @@ if (@available(iOS 13.4, *)) { if (base::FeatureList::IsEnabled(kPointerSupport)) { self.skipSigninButton.pointerInteractionEnabled = YES; + self.skipSigninButton.pointerStyleProvider = + CreateTransparentButtonPointerStyleProvider(); } } #endif // defined(__IPHONE_13_4) @@ -483,7 +488,6 @@ - (void)setSkipSigninStylingWithButton:(UIButton*)button { DCHECK(button); - button.backgroundColor = self.systemBackgroundColor; [button setTitleColor:[UIColor colorNamed:kBlueColor] forState:UIControlStateNormal]; }
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_accessory_view_controller.mm b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_accessory_view_controller.mm index 4d33c69..417d88c1 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_accessory_view_controller.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_accessory_view_controller.mm
@@ -4,7 +4,9 @@ #import "ios/chrome/browser/ui/autofill/manual_fill/manual_fill_accessory_view_controller.h" +#include "base/feature_list.h" #include "base/metrics/user_metrics.h" +#include "ios/chrome/browser/ui/ui_feature_flags.h" #include "ios/chrome/browser/ui/util/ui_util.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" #import "ios/chrome/common/ui/util/constraints_ui_util.h" @@ -182,27 +184,36 @@ self.passwordButton.contentEdgeInsets = UIEdgeInsetsMake(0, 2, 0, 2); [icons addObject:self.passwordButton]; - self.cardsButton = - [self manualFillButtonWithAction:@selector(cardButtonPressed:) - ImageNamed:@"ic_credit_card" - accessibilityIdentifier: - manual_fill::AccessoryCreditCardAccessibilityIdentifier - accessibilityLabel: - l10n_util::GetNSString( - IDS_IOS_MANUAL_FALLBACK_SHOW_CREDIT_CARDS)]; - self.cardsButton.hidden = self.isCreditCardButtonHidden; - [icons addObject:self.cardsButton]; + self.cardsButton = + [self manualFillButtonWithAction:@selector(cardButtonPressed:) + ImageNamed:@"ic_credit_card" + accessibilityIdentifier: + manual_fill::AccessoryCreditCardAccessibilityIdentifier + accessibilityLabel: + l10n_util::GetNSString( + IDS_IOS_MANUAL_FALLBACK_SHOW_CREDIT_CARDS)]; + self.cardsButton.hidden = self.isCreditCardButtonHidden; + [icons addObject:self.cardsButton]; - self.accountButton = [self - manualFillButtonWithAction:@selector(accountButtonPressed:) - ImageNamed:@"ic_place" - accessibilityIdentifier:manual_fill:: - AccessoryAddressAccessibilityIdentifier - accessibilityLabel:l10n_util::GetNSString( - IDS_IOS_MANUAL_FALLBACK_SHOW_ADDRESSES)]; + self.accountButton = [self + manualFillButtonWithAction:@selector(accountButtonPressed:) + ImageNamed:@"ic_place" + accessibilityIdentifier:manual_fill:: + AccessoryAddressAccessibilityIdentifier + accessibilityLabel:l10n_util::GetNSString( + IDS_IOS_MANUAL_FALLBACK_SHOW_ADDRESSES)]; - self.accountButton.hidden = self.isAddressButtonHidden; - [icons addObject:self.accountButton]; + self.accountButton.hidden = self.isAddressButtonHidden; + [icons addObject:self.accountButton]; + +#if defined(__IPHONE_13_4) + if (@available(iOS 13.4, *)) { + if (base::FeatureList::IsEnabled(kPointerSupport)) { + for (UIButton* button in icons) + button.pointerInteractionEnabled = YES; + } + } +#endif // defined(__IPHONE_13_4) UIStackView* stackView = [[UIStackView alloc] initWithArrangedSubviews:icons]; stackView.spacing =
diff --git a/ios/chrome/browser/ui/fancy_ui/BUILD.gn b/ios/chrome/browser/ui/fancy_ui/BUILD.gn index cf0070c1..bb700bc 100644 --- a/ios/chrome/browser/ui/fancy_ui/BUILD.gn +++ b/ios/chrome/browser/ui/fancy_ui/BUILD.gn
@@ -13,8 +13,10 @@ deps = [ "//base", "//base:i18n", + "//ios/chrome/browser/ui:feature_flags", "//ios/chrome/browser/ui/colors", "//ios/chrome/common/ui/colors", + "//ios/chrome/common/ui/util", ] public_deps = [ "//ios/third_party/material_components_ios" ] libs = [ "UIKit.framework" ]
diff --git a/ios/chrome/browser/ui/fancy_ui/primary_action_button.mm b/ios/chrome/browser/ui/fancy_ui/primary_action_button.mm index f197263..1b7943d 100644 --- a/ios/chrome/browser/ui/fancy_ui/primary_action_button.mm +++ b/ios/chrome/browser/ui/fancy_ui/primary_action_button.mm
@@ -4,9 +4,12 @@ #import "ios/chrome/browser/ui/fancy_ui/primary_action_button.h" +#include "base/feature_list.h" #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h" +#include "ios/chrome/browser/ui/ui_feature_flags.h" #import "ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" +#import "ios/chrome/common/ui/util/pointer_interaction_util.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -35,6 +38,14 @@ - (void)updateStyling { self.hasOpaqueBackground = YES; +#if defined(__IPHONE_13_4) + if (@available(iOS 13.4, *)) { + if (base::FeatureList::IsEnabled(kPointerSupport)) { + self.pointerInteractionEnabled = YES; + self.pointerStyleProvider = CreateOpaqueButtonPointerStyleProvider(); + } + } +#endif // defined(__IPHONE_13_4) UIColor* hintColor = UIColor.cr_systemBackgroundColor; UIColor* inkColor = [UIColor colorWithWhite:1 alpha:0.2f];
diff --git a/ios/chrome/browser/ui/first_run/welcome_to_chrome_view.mm b/ios/chrome/browser/ui/first_run/welcome_to_chrome_view.mm index 42c9812..fba3f75 100644 --- a/ios/chrome/browser/ui/first_run/welcome_to_chrome_view.mm +++ b/ios/chrome/browser/ui/first_run/welcome_to_chrome_view.mm
@@ -5,13 +5,11 @@ #import "ios/chrome/browser/ui/first_run/welcome_to_chrome_view.h" #include "base/check_op.h" -#include "base/feature_list.h" #include "base/i18n/rtl.h" #include "base/notreached.h" #include "base/strings/sys_string_conversions.h" #include "ios/chrome/browser/ui/fancy_ui/primary_action_button.h" #include "ios/chrome/browser/ui/first_run/first_run_util.h" -#include "ios/chrome/browser/ui/ui_feature_flags.h" #import "ios/chrome/browser/ui/util/CRUILabel+AttributeUtils.h" #import "ios/chrome/browser/ui/util/label_link_controller.h" #import "ios/chrome/browser/ui/util/label_observer.h" @@ -293,13 +291,6 @@ UIImage* selectedImage = [[UIImage imageNamed:kCheckBoxCheckedImageName] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; [_checkBoxButton setImage:selectedImage forState:UIControlStateSelected]; -#if defined(__IPHONE_13_4) - if (@available(iOS 13.4, *)) { - if (base::FeatureList::IsEnabled(kPointerSupport)) { - _checkBoxButton.pointerInteractionEnabled = YES; - } - } -#endif // defined(__IPHONE_13_4) } return _checkBoxButton; } @@ -318,13 +309,6 @@ // First Run UI when it shows up. SetA11yLabelAndUiAutomationName( _OKButton, IDS_IOS_FIRSTRUN_OPT_IN_ACCEPT_BUTTON, @"Accept & Continue"); -#if defined(__IPHONE_13_4) - if (@available(iOS 13.4, *)) { - if (base::FeatureList::IsEnabled(kPointerSupport)) { - _OKButton.pointerInteractionEnabled = YES; - } - } -#endif // defined(__IPHONE_13_4) } return _OKButton; }
diff --git a/ios/chrome/browser/ui/infobars/BUILD.gn b/ios/chrome/browser/ui/infobars/BUILD.gn index 6132098..97defa7b 100644 --- a/ios/chrome/browser/ui/infobars/BUILD.gn +++ b/ios/chrome/browser/ui/infobars/BUILD.gn
@@ -93,6 +93,7 @@ "//ios/chrome/browser/ui/toolbar/public", "//ios/chrome/browser/ui/util", "//ios/chrome/common/ui/colors", + "//ios/chrome/common/ui/util", "//ios/public/provider/chrome/browser/ui", "//ios/third_party/material_components_ios", "//ui/base", @@ -196,7 +197,7 @@ "//components/translate/core/common", "//ios/chrome/app/strings:ios_strings_grit", "//ios/chrome/browser:chrome_url_constants", - "//ios/chrome/browser/translate:test_support", + "//ios/chrome/browser/translate:eg_test_support", "//ios/chrome/browser/ui/badges:public", "//ios/chrome/browser/ui/infobars:constants", "//ios/chrome/browser/ui/infobars:feature_flags",
diff --git a/ios/chrome/browser/ui/infobars/confirm_infobar_view.mm b/ios/chrome/browser/ui/infobars/confirm_infobar_view.mm index 3c99cc5..0d5d71f 100644 --- a/ios/chrome/browser/ui/infobars/confirm_infobar_view.mm +++ b/ios/chrome/browser/ui/infobars/confirm_infobar_view.mm
@@ -23,6 +23,7 @@ #import "ios/chrome/browser/ui/util/named_guide.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" +#import "ios/chrome/common/ui/util/pointer_interaction_util.h" #include "ios/chrome/grit/ios_theme_resources.h" #import "ios/third_party/material_components_ios/src/components/Buttons/src/MaterialButtons.h" #include "ui/base/l10n/l10n_util.h" @@ -1045,6 +1046,7 @@ if (@available(iOS 13.4, *)) { if (base::FeatureList::IsEnabled(kPointerSupport)) { button.pointerInteractionEnabled = YES; + button.pointerStyleProvider = CreateOpaqueButtonPointerStyleProvider(); } } #endif // defined(__IPHONE_13_4)
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/BUILD.gn b/ios/chrome/browser/ui/overlays/infobar_banner/BUILD.gn index e7f1b10..e7b023e 100644 --- a/ios/chrome/browser/ui/overlays/infobar_banner/BUILD.gn +++ b/ios/chrome/browser/ui/overlays/infobar_banner/BUILD.gn
@@ -29,6 +29,7 @@ "//ios/chrome/browser/ui/infobars/presentation", "//ios/chrome/browser/ui/overlays:coordinators", "//ios/chrome/browser/ui/overlays:util", + "//ios/chrome/browser/ui/overlays/infobar_banner/confirm", "//ios/chrome/browser/ui/overlays/infobar_banner/passwords", "//ios/chrome/browser/ui/util", ]
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/confirm/BUILD.gn b/ios/chrome/browser/ui/overlays/infobar_banner/confirm/BUILD.gn new file mode 100644 index 0000000..df22790 --- /dev/null +++ b/ios/chrome/browser/ui/overlays/infobar_banner/confirm/BUILD.gn
@@ -0,0 +1,48 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("confirm") { + sources = [ + "confirm_infobar_banner_overlay_mediator.h", + "confirm_infobar_banner_overlay_mediator.mm", + ] + + configs += [ "//build/config/compiler:enable_arc" ] + + deps = [ + "//base", + "//ios/chrome/app/strings:ios_strings_grit", + "//ios/chrome/browser/overlays", + "//ios/chrome/browser/overlays/public/infobar_banner", + "//ios/chrome/browser/ui/infobars/banners", + "//ios/chrome/browser/ui/overlays/infobar_banner:mediators", + "//ui/base", + ] +} + +source_set("unit_tests") { + testonly = true + sources = [ "confirm_infobar_banner_overlay_mediator_unittest.mm" ] + + configs += [ "//build/config/compiler:enable_arc" ] + + deps = [ + ":confirm", + "//base/test:test_support", + "//components/infobars/core", + "//ios/chrome/app/strings:ios_strings_grit", + "//ios/chrome/browser/infobars", + "//ios/chrome/browser/infobars/test", + "//ios/chrome/browser/overlays", + "//ios/chrome/browser/overlays/public/infobar_banner", + "//ios/chrome/browser/overlays/test", + "//ios/chrome/browser/ui/infobars:feature_flags", + "//ios/chrome/browser/ui/infobars/banners/test", + "//ios/chrome/browser/ui/infobars/test", + "//ios/chrome/browser/ui/overlays/test", + "//testing/gmock", + "//testing/gtest", + "//ui/base", + ] +}
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/confirm/confirm_infobar_banner_overlay_mediator.h b/ios/chrome/browser/ui/overlays/infobar_banner/confirm/confirm_infobar_banner_overlay_mediator.h new file mode 100644 index 0000000..d4cbed87 --- /dev/null +++ b/ios/chrome/browser/ui/overlays/infobar_banner/confirm/confirm_infobar_banner_overlay_mediator.h
@@ -0,0 +1,14 @@ +// 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 IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_BANNER_CONFIRM_CONFIRM_INFOBAR_BANNER_OVERLAY_MEDIATOR_H_ +#define IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_BANNER_CONFIRM_CONFIRM_INFOBAR_BANNER_OVERLAY_MEDIATOR_H_ + +#import "ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator.h" + +// Mediator that configures an infobar banner for a confirm infobar. +@interface ConfirmInfobarBannerOverlayMediator : InfobarBannerOverlayMediator +@end + +#endif // IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_BANNER_CONFIRM_CONFIRM_INFOBAR_BANNER_OVERLAY_MEDIATOR_H_
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/confirm/confirm_infobar_banner_overlay_mediator.mm b/ios/chrome/browser/ui/overlays/infobar_banner/confirm/confirm_infobar_banner_overlay_mediator.mm new file mode 100644 index 0000000..231cbd6 --- /dev/null +++ b/ios/chrome/browser/ui/overlays/infobar_banner/confirm/confirm_infobar_banner_overlay_mediator.mm
@@ -0,0 +1,58 @@ +// 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. + +#import "ios/chrome/browser/ui/overlays/infobar_banner/confirm/confirm_infobar_banner_overlay_mediator.h" + +#include "base/strings/sys_string_conversions.h" +#import "ios/chrome/browser/overlays/public/infobar_banner/confirm_infobar_banner_overlay_request_config.h" +#import "ios/chrome/browser/ui/infobars/banners/infobar_banner_consumer.h" +#import "ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator+consumer_support.h" +#include "ui/base/l10n/l10n_util.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +using confirm_infobar_overlays::ConfirmBannerRequestConfig; + +@interface ConfirmInfobarBannerOverlayMediator () +// The confirm banner config from the request. +@property(nonatomic, readonly) ConfirmBannerRequestConfig* config; +@end + +@implementation ConfirmInfobarBannerOverlayMediator + +#pragma mark - Accessors + +- (ConfirmBannerRequestConfig*)config { + return self.request ? self.request->GetConfig<ConfirmBannerRequestConfig>() + : nullptr; +} + +#pragma mark - OverlayRequestMediator + ++ (const OverlayRequestSupport*)requestSupport { + return ConfirmBannerRequestConfig::RequestSupport(); +} + +@end + +@implementation ConfirmInfobarBannerOverlayMediator (ConsumerSupport) + +- (void)configureConsumer { + ConfirmBannerRequestConfig* config = self.config; + if (!self.consumer || !config) + return; + + [self.consumer setBannerAccessibilityLabel:base::SysUTF16ToNSString( + config->button_label_text())]; + [self.consumer + setButtonText:base::SysUTF16ToNSString(config->button_label_text())]; + if (!config->icon_image().IsEmpty()) + [self.consumer setIconImage:config->icon_image().ToUIImage()]; + [self.consumer setPresentsModal:NO]; + [self.consumer setTitleText:base::SysUTF16ToNSString(config->message_text())]; +} + +@end
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/confirm/confirm_infobar_banner_overlay_mediator_unittest.mm b/ios/chrome/browser/ui/overlays/infobar_banner/confirm/confirm_infobar_banner_overlay_mediator_unittest.mm new file mode 100644 index 0000000..0ca597a3 --- /dev/null +++ b/ios/chrome/browser/ui/overlays/infobar_banner/confirm/confirm_infobar_banner_overlay_mediator_unittest.mm
@@ -0,0 +1,67 @@ +// 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. + +#import "ios/chrome/browser/ui/overlays/infobar_banner/confirm/confirm_infobar_banner_overlay_mediator.h" + +#include "base/feature_list.h" +#include "base/strings/string16.h" +#include "base/strings/sys_string_conversions.h" +#include "base/test/scoped_feature_list.h" +#include "components/infobars/core/infobar.h" +#include "components/infobars/core/infobar_feature.h" +#include "ios/chrome/browser/infobars/infobar_ios.h" +#include "ios/chrome/browser/infobars/test/fake_infobar_delegate.h" +#import "ios/chrome/browser/overlays/public/infobar_banner/confirm_infobar_banner_overlay_request_config.h" +#include "ios/chrome/browser/overlays/public/overlay_request.h" +#import "ios/chrome/browser/ui/infobars/banners/test/fake_infobar_banner_consumer.h" +#import "ios/chrome/browser/ui/infobars/infobar_feature.h" +#import "testing/gtest_mac.h" +#include "testing/platform_test.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +using confirm_infobar_overlays::ConfirmBannerRequestConfig; + +// Test fixture for ConfirmInfobarBannerOverlayMediator. +class ConfirmInfobarBannerOverlayMediatorTest : public PlatformTest { + public: + ConfirmInfobarBannerOverlayMediatorTest() { + feature_list_.InitWithFeatures({kIOSInfobarUIReboot}, + {kInfobarUIRebootOnlyiOS13}); + } + + private: + base::test::ScopedFeatureList feature_list_; +}; + +// Tests that a ConfirmInfobarBannerOverlayMediator correctly sets up its +// consumer. +TEST_F(ConfirmInfobarBannerOverlayMediatorTest, SetUpConsumer) { + // Create an InfoBarIOS with a ConfirmInfoBarDelegate. + std::unique_ptr<FakeInfobarDelegate> passed_delegate = + std::make_unique<FakeInfobarDelegate>(); + FakeInfobarDelegate* delegate = passed_delegate.get(); + InfoBarIOS infobar(InfobarType::kInfobarTypeConfirm, + std::move(passed_delegate)); + // Package the infobar into an OverlayRequest, then create a mediator that + // uses this request in order to set up a fake consumer. + std::unique_ptr<OverlayRequest> request = + OverlayRequest::CreateWithConfig<ConfirmBannerRequestConfig>(&infobar); + ConfirmInfobarBannerOverlayMediator* mediator = + [[ConfirmInfobarBannerOverlayMediator alloc] + initWithRequest:request.get()]; + FakeInfobarBannerConsumer* consumer = + [[FakeInfobarBannerConsumer alloc] init]; + mediator.consumer = consumer; + // Verify that the infobar was set up properly. + NSString* title = base::SysUTF16ToNSString(delegate->GetMessageText()); + + EXPECT_NSEQ(title, consumer.titleText); + EXPECT_NSEQ(base::SysUTF16ToNSString( + delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_OK)), + consumer.buttonText); + EXPECT_FALSE(consumer.presentsModal); +}
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_coordinator.mm b/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_coordinator.mm index 863efb6..edacb5f 100644 --- a/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_coordinator.mm +++ b/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_coordinator.mm
@@ -16,6 +16,7 @@ #import "ios/chrome/browser/ui/infobars/infobar_constants.h" #import "ios/chrome/browser/ui/infobars/presentation/infobar_banner_positioner.h" #import "ios/chrome/browser/ui/infobars/presentation/infobar_banner_transition_driver.h" +#import "ios/chrome/browser/ui/overlays/infobar_banner/confirm/confirm_infobar_banner_overlay_mediator.h" #import "ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator.h" #import "ios/chrome/browser/ui/overlays/infobar_banner/passwords/save_password_infobar_banner_overlay_mediator.h" #import "ios/chrome/browser/ui/overlays/overlay_request_coordinator+subclassing.h" @@ -42,7 +43,10 @@ #pragma mark - Accessors + (NSArray<Class>*)supportedMediatorClasses { - return @ [[SavePasswordInfobarBannerOverlayMediator class]]; + return @[ + [SavePasswordInfobarBannerOverlayMediator class], + [ConfirmInfobarBannerOverlayMediator class] + ]; } + (const OverlayRequestSupport*)requestSupport {
diff --git a/ios/chrome/browser/ui/qr_generator/qr_generator_coordinator.mm b/ios/chrome/browser/ui/qr_generator/qr_generator_coordinator.mm index 57e3144..e0991fdc 100644 --- a/ios/chrome/browser/ui/qr_generator/qr_generator_coordinator.mm +++ b/ios/chrome/browser/ui/qr_generator/qr_generator_coordinator.mm
@@ -5,6 +5,8 @@ #import "ios/chrome/browser/ui/qr_generator/qr_generator_coordinator.h" +#include "base/metrics/user_metrics.h" +#include "base/metrics/user_metrics_action.h" #include "base/strings/sys_string_conversions.h" #include "ios/chrome/browser/main/browser.h" #import "ios/chrome/browser/ui/activity_services/activity_service_coordinator.h" @@ -95,6 +97,8 @@ } - (void)confirmationAlertPrimaryAction { + base::RecordAction(base::UserMetricsAction("MobileShareQRCode")); + self.activityServiceCoordinator = [[ActivityServiceCoordinator alloc] initWithBaseViewController:self.viewController browser:self.browser];
diff --git a/ios/chrome/browser/ui/sad_tab/sad_tab_view.mm b/ios/chrome/browser/ui/sad_tab/sad_tab_view.mm index ca4533b8..28ba0e1 100644 --- a/ios/chrome/browser/ui/sad_tab/sad_tab_view.mm +++ b/ios/chrome/browser/ui/sad_tab/sad_tab_view.mm
@@ -18,6 +18,7 @@ #include "ios/chrome/browser/ui/util/rtl_geometry.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" +#import "ios/chrome/common/ui/util/pointer_interaction_util.h" #import "ios/third_party/material_components_ios/src/components/Buttons/src/MaterialButtons.h" #import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h" #include "ios/web/public/browser_state.h" @@ -566,6 +567,8 @@ if (@available(iOS 13.4, *)) { if (base::FeatureList::IsEnabled(kPointerSupport)) { _actionButton.pointerInteractionEnabled = YES; + _actionButton.pointerStyleProvider = + CreateOpaqueButtonPointerStyleProvider(); } } #endif // defined(__IPHONE_13_4)
diff --git a/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm b/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm index d5086d1..3a7c4420 100644 --- a/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm
@@ -356,7 +356,9 @@ base::mac::ObjCCastStrict<TableViewAccountItem>( [self.tableViewModel itemAtIndexPath:indexPath]); DCHECK(item.chromeIdentity); - [self showAccountDetails:item.chromeIdentity]; + UIView* itemView = + [[tableView cellForRowAtIndexPath:indexPath] contentView]; + [self showAccountDetails:item.chromeIdentity itemView:itemView]; break; } case ItemTypeAddAccount: { @@ -425,13 +427,48 @@ } } -- (void)showAccountDetails:(ChromeIdentity*)identity { +- (void)showAccountDetails:(ChromeIdentity*)identity + itemView:(UIView*)itemView { if ([_alertCoordinator isVisible]) return; - _dimissAccountDetailsViewControllerBlock = - ios::GetChromeBrowserProvider() - ->GetChromeIdentityService() - ->PresentAccountDetailsController(identity, self, /*animated=*/YES); + if (base::FeatureList::IsEnabled(kEnableMyGoogle)) { + _alertCoordinator = [[ActionSheetCoordinator alloc] + initWithBaseViewController:self + browser:_browser + title:nil + message:identity.userEmail + rect:itemView.frame + view:itemView]; + + [_alertCoordinator + addItemWithTitle:l10n_util::GetNSString( + IDS_IOS_MANAGE_YOUR_GOOGLE_ACCOUNT_TITLE) + action:^{ + _dimissAccountDetailsViewControllerBlock = + ios::GetChromeBrowserProvider() + ->GetChromeIdentityService() + ->PresentAccountDetailsController(identity, self, + /*animated=*/YES); + } + style:UIAlertActionStyleDefault]; + [_alertCoordinator addItemWithTitle:l10n_util::GetNSString( + IDS_IOS_REMOVE_GOOGLE_ACCOUNT_TITLE) + action:^{ + // TODO(crbug.com/1043080): Use Identity API + // to remove account. + } + style:UIAlertActionStyleDestructive]; + + [_alertCoordinator addItemWithTitle:l10n_util::GetNSString(IDS_CANCEL) + action:nil + style:UIAlertActionStyleCancel]; + [_alertCoordinator start]; + } else { + _dimissAccountDetailsViewControllerBlock = + ios::GetChromeBrowserProvider() + ->GetChromeIdentityService() + ->PresentAccountDetailsController(identity, self, /*animated=*/YES); + } } - (void)showSignOutWithClearData:(BOOL)forceClearData
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_text_button_item.mm b/ios/chrome/browser/ui/table_view/cells/table_view_text_button_item.mm index 745d4b65..a11a83a 100644 --- a/ios/chrome/browser/ui/table_view/cells/table_view_text_button_item.mm +++ b/ios/chrome/browser/ui/table_view/cells/table_view_text_button_item.mm
@@ -12,6 +12,7 @@ #import "ios/chrome/browser/ui/util/uikit_ui_util.h" #import "ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" +#import "ios/chrome/common/ui/util/pointer_interaction_util.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -155,16 +156,11 @@ if (@available(iOS 13.4, *)) { if (base::FeatureList::IsEnabled(kPointerSupport)) { self.button.pointerInteractionEnabled = YES; - // UIKit seems to dynamically adjust the default pointer interaction - // behavior based on the size of the button relative to the size of its - // container. This produces inconsistent and undesired behavior in some - // uses of this table view cell. Removing the pointer shape seems to - // produce more consistent and acceptable behavior. + // This button's background color is configured whenever the cell is + // reused. The pointer style provider used here dynamically provides the + // appropriate style based on the background color at runtime. self.button.pointerStyleProvider = - ^UIPointerStyle*(UIButton* button, UIPointerEffect* proposedEffect, - UIPointerShape* proposedShape) { - return [UIPointerStyle styleWithEffect:proposedEffect shape:nil]; - }; + CreateOpaqueOrTransparentButtonPointerStyleProvider(); } } #endif // defined(__IPHONE_13_4)
diff --git a/ios/chrome/browser/ui/translate/BUILD.gn b/ios/chrome/browser/ui/translate/BUILD.gn index 398284e..30ab8c04 100644 --- a/ios/chrome/browser/ui/translate/BUILD.gn +++ b/ios/chrome/browser/ui/translate/BUILD.gn
@@ -65,6 +65,7 @@ "//components/strings:components_strings", "//ios/chrome/app/strings:ios_strings_grit", "//ios/chrome/browser", + "//ios/chrome/browser/ui:feature_flags", "//ios/chrome/browser/ui/colors", "//ios/chrome/browser/ui/commands", "//ios/chrome/browser/ui/fullscreen:ui",
diff --git a/ios/chrome/browser/ui/translate/OWNERS b/ios/chrome/browser/ui/translate/OWNERS index adccd5d..b413b49 100644 --- a/ios/chrome/browser/ui/translate/OWNERS +++ b/ios/chrome/browser/ui/translate/OWNERS
@@ -1,4 +1,5 @@ mahmadi@chromium.org +thegreenfrog@chromium.org # TEAM: ios-directory-owners@chromium.org # OS: iOS
diff --git a/ios/chrome/browser/ui/translate/translate_infobar_language_tab_view.mm b/ios/chrome/browser/ui/translate/translate_infobar_language_tab_view.mm index e5c632c..a918d27 100644 --- a/ios/chrome/browser/ui/translate/translate_infobar_language_tab_view.mm +++ b/ios/chrome/browser/ui/translate/translate_infobar_language_tab_view.mm
@@ -4,9 +4,11 @@ #import "ios/chrome/browser/ui/translate/translate_infobar_language_tab_view.h" +#include "base/feature_list.h" #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h" #import "ios/chrome/browser/ui/translate/translate_infobar_language_tab_strip_view.h" #import "ios/chrome/browser/ui/translate/translate_infobar_language_tab_view_delegate.h" +#include "ios/chrome/browser/ui/ui_feature_flags.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" #import "ios/chrome/common/ui/elements/highlight_button.h" @@ -106,6 +108,14 @@ forControlEvents:UIControlEventTouchUpInside]; [self addSubview:self.button]; +#if defined(__IPHONE_13_4) + if (@available(iOS 13.4, *)) { + if (base::FeatureList::IsEnabled(kPointerSupport)) { + self.button.pointerInteractionEnabled = YES; + } + } +#endif // defined(__IPHONE_13_4) + AddSameConstraints(self, self.button); }
diff --git a/ios/chrome/browser/ui/translate/translate_infobar_view.mm b/ios/chrome/browser/ui/translate/translate_infobar_view.mm index 118fb59..3dbca69 100644 --- a/ios/chrome/browser/ui/translate/translate_infobar_view.mm +++ b/ios/chrome/browser/ui/translate/translate_infobar_view.mm
@@ -5,6 +5,7 @@ #import "ios/chrome/browser/ui/translate/translate_infobar_view.h" #include "base/check.h" +#include "base/feature_list.h" #include "base/strings/sys_string_conversions.h" #include "components/strings/grit/components_strings.h" #import "ios/chrome/browser/procedural_block_types.h" @@ -17,6 +18,7 @@ #import "ios/chrome/browser/ui/translate/translate_infobar_language_tab_strip_view_delegate.h" #import "ios/chrome/browser/ui/translate/translate_infobar_view_constants.h" #import "ios/chrome/browser/ui/translate/translate_infobar_view_delegate.h" +#include "ios/chrome/browser/ui/ui_feature_flags.h" #import "ios/chrome/browser/ui/util/label_link_controller.h" #import "ios/chrome/browser/ui/util/layout_guide_names.h" #import "ios/chrome/browser/ui/util/named_guide.h" @@ -286,6 +288,15 @@ self.dismissButton = dismissButton; [contentView addSubview:self.dismissButton]; +#if defined(__IPHONE_13_4) + if (@available(iOS 13.4, *)) { + if (base::FeatureList::IsEnabled(kPointerSupport)) { + self.optionsButton.pointerInteractionEnabled = YES; + self.dismissButton.pointerInteractionEnabled = YES; + } + } +#endif // defined(__IPHONE_13_4) + ApplyVisualConstraintsWithMetrics( @[ @"H:|-(iconLeadingMargin)-[icon(iconSize)]-(iconTrailingMargin)-[languages][options(buttonSize)][dismiss(buttonSize)]|",
diff --git a/ios/chrome/browser/url_loading/url_loading_browser_agent.mm b/ios/chrome/browser/url_loading/url_loading_browser_agent.mm index 1c7b0d49..bb60d244 100644 --- a/ios/chrome/browser/url_loading/url_loading_browser_agent.mm +++ b/ios/chrome/browser/url_loading/url_loading_browser_agent.mm
@@ -65,7 +65,7 @@ (crash_string == "" || crash_string == "true")) { // Induce an intentional crash in the browser process. CHECK(false); - // Call another function, so that the above CHECK can't be tail-call + // Call another function, so that the above CHECK can't be tail call // optimized. This ensures that this method's name will show up in the stack // for easier identification. CHECK(true);
diff --git a/ios/chrome/browser/web/BUILD.gn b/ios/chrome/browser/web/BUILD.gn index 230c854f..0694098 100644 --- a/ios/chrome/browser/web/BUILD.gn +++ b/ios/chrome/browser/web/BUILD.gn
@@ -15,6 +15,8 @@ "font_size_tab_helper.mm", "image_fetch_tab_helper.h", "image_fetch_tab_helper.mm", + "invalid_url_tab_helper.h", + "invalid_url_tab_helper.mm", "load_timing_tab_helper.h", "load_timing_tab_helper.mm", "repost_form_tab_helper.h", @@ -112,6 +114,7 @@ "font_size_tab_helper_unittest.mm", "image_fetch_js_unittest.mm", "image_fetch_tab_helper_unittest.mm", + "invalid_url_tab_helper_unittest.mm", "load_timing_tab_helper_unittest.mm", "page_placeholder_tab_helper_unittest.mm", "repost_form_tab_helper_unittest.mm", @@ -144,6 +147,7 @@ "//ios/chrome/browser/ui/util", "//ios/chrome/browser/web:feature_flags", "//ios/chrome/test:test_support", + "//ios/net", "//ios/net:test_support", "//ios/web", "//ios/web/public/test",
diff --git a/ios/chrome/browser/web/chrome_web_client.mm b/ios/chrome/browser/web/chrome_web_client.mm index c5b27de..bea10ce 100644 --- a/ios/chrome/browser/web/chrome_web_client.mm +++ b/ios/chrome/browser/web/chrome_web_client.mm
@@ -7,6 +7,7 @@ #include "base/command_line.h" #include "base/feature_list.h" #include "base/files/file_util.h" +#import "base/ios/ios_util.h" #import "base/ios/ns_error_util.h" #include "base/mac/bundle_locations.h" #include "base/strings/sys_string_conversions.h" @@ -102,15 +103,20 @@ } void ChromeWebClient::PreWebViewCreation() const { - // Initialize the audio session to allow a web page's audio to continue - // playing after the app is backgrounded. - VoiceSearchProvider* voice_provider = - ios::GetChromeBrowserProvider()->GetVoiceSearchProvider(); - if (voice_provider) { - AudioSessionController* audio_controller = - voice_provider->GetAudioSessionController(); - if (audio_controller) { - audio_controller->InitializeSessionIfNecessary(); + // TODO(crbug.com/1082371): Confirm that this code is no longer needed and + // remove it entirely. Until then, prevent this from running on iOS 13.4+, as + // it occasionally triggers a permissions prompt. + if (!base::ios::IsRunningOnOrLater(13, 4, 0)) { + // Initialize the audio session to allow a web page's audio to continue + // playing after the app is backgrounded. + VoiceSearchProvider* voice_provider = + ios::GetChromeBrowserProvider()->GetVoiceSearchProvider(); + if (voice_provider) { + AudioSessionController* audio_controller = + voice_provider->GetAudioSessionController(); + if (audio_controller) { + audio_controller->InitializeSessionIfNecessary(); + } } } }
diff --git a/ios/chrome/browser/web/invalid_url_tab_helper.h b/ios/chrome/browser/web/invalid_url_tab_helper.h new file mode 100644 index 0000000..2b0c4f2 --- /dev/null +++ b/ios/chrome/browser/web/invalid_url_tab_helper.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 IOS_CHROME_BROWSER_WEB_INVALID_URL_TAB_HELPER_H_ +#define IOS_CHROME_BROWSER_WEB_INVALID_URL_TAB_HELPER_H_ + +#import "ios/web/public/navigation/web_state_policy_decider.h" +#import "ios/web/public/web_state_user_data.h" + +// A tab helper that cancels the navigation to invalid URLs: +// - Invalid data URLs (these request download if the load is allowed, +// which is suboptimal user experience). +// - Extremely long URLs (these use a lot of memory during the navigation +// causing stability problems). +class InvalidUrlTabHelper : public web::WebStateUserData<InvalidUrlTabHelper>, + public web::WebStatePolicyDecider { + public: + ~InvalidUrlTabHelper() override; + + InvalidUrlTabHelper(const InvalidUrlTabHelper&) = delete; + InvalidUrlTabHelper& operator=(const InvalidUrlTabHelper&) = delete; + + private: + explicit InvalidUrlTabHelper(web::WebState* web_state); + PolicyDecision ShouldAllowRequest(NSURLRequest* request, + const RequestInfo& request_info) override; + + friend class web::WebStateUserData<InvalidUrlTabHelper>; + WEB_STATE_USER_DATA_KEY_DECL(); +}; + +#endif // IOS_CHROME_BROWSER_WEB_INVALID_URL_TAB_HELPER_H_
diff --git a/ios/chrome/browser/web/invalid_url_tab_helper.mm b/ios/chrome/browser/web/invalid_url_tab_helper.mm new file mode 100644 index 0000000..17daad5 --- /dev/null +++ b/ios/chrome/browser/web/invalid_url_tab_helper.mm
@@ -0,0 +1,75 @@ +// 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. + +#import "ios/chrome/browser/web/invalid_url_tab_helper.h" + +#include "base/strings/sys_string_conversions.h" +#import "ios/net/protocol_handler_util.h" +#include "net/base/data_url.h" +#import "net/base/mac/url_conversions.h" +#include "net/base/net_errors.h" +#include "net/http/http_response_headers.h" +#include "ui/base/page_transition_types.h" +#include "url/url_constants.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace { + +// Returns true if URL request is valid and navigation should be allowed. +bool IsUrlRequestValid(NSURLRequest* request) { + if (request.URL.absoluteString.length > url::kMaxURLChars) { + return false; + } + + if ([request.URL.scheme isEqual:@"data"]) { + std::string mime_type; + std::string charset; + std::string data; + scoped_refptr<net::HttpResponseHeaders> headers; + if (net::DataURL::BuildResponse(net::GURLWithNSURL(request.URL), + base::SysNSStringToUTF8(request.HTTPMethod), + &mime_type, &charset, &data, + &headers) == net::ERR_INVALID_URL) { + return false; + } + } + + return true; +} + +} // namespace + +InvalidUrlTabHelper::InvalidUrlTabHelper(web::WebState* web_state) + : web::WebStatePolicyDecider(web_state) {} +InvalidUrlTabHelper::~InvalidUrlTabHelper() = default; + +web::WebStatePolicyDecider::PolicyDecision +InvalidUrlTabHelper::ShouldAllowRequest(NSURLRequest* request, + const RequestInfo& request_info) { + if (IsUrlRequestValid(request)) { + return PolicyDecision::Allow(); + } + + // URL is invalid. Show error for certain browser-initiated navigations (f.e. + // the user typed the URL, tapped the bookmark or onmibox suggestion) and + // silently cancel the navigation for other navigations (f.e. the user clicked + // the link or page made a client side redirect). + + using ui::PageTransitionCoreTypeIs; + ui::PageTransition transition = request_info.transition_type; + if (PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_TYPED) || + PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_GENERATED) || + PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_AUTO_BOOKMARK)) { + return PolicyDecision::CancelAndDisplayError([NSError + errorWithDomain:net::kNSErrorDomain + code:net::ERR_INVALID_URL + userInfo:nil]); + } + return PolicyDecision::Cancel(); +} + +WEB_STATE_USER_DATA_KEY_IMPL(InvalidUrlTabHelper)
diff --git a/ios/chrome/browser/web/invalid_url_tab_helper_unittest.mm b/ios/chrome/browser/web/invalid_url_tab_helper_unittest.mm new file mode 100644 index 0000000..ae7695ff --- /dev/null +++ b/ios/chrome/browser/web/invalid_url_tab_helper_unittest.mm
@@ -0,0 +1,106 @@ +// 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. + +#import "ios/chrome/browser/web/invalid_url_tab_helper.h" + +#import <Foundation/Foundation.h> + +#import "ios/net/protocol_handler_util.h" +#import "ios/web/public/navigation/web_state_policy_decider.h" +#import "ios/web/public/test/fakes/test_web_state.h" +#include "net/base/net_errors.h" +#include "testing/gtest_mac.h" +#include "testing/platform_test.h" +#include "url/url_constants.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +class InvalidUrlTabHelperTest : public PlatformTest { + protected: + InvalidUrlTabHelperTest() { + InvalidUrlTabHelper::CreateForWebState(&web_state_); + } + + // Returns PolicyDecision for URL request with given |spec| and |transition|. + web::WebStatePolicyDecider::PolicyDecision GetPolicy( + NSString* spec, + ui::PageTransition transition) { + NSURL* url = [NSURL URLWithString:spec]; + NSURLRequest* request = [[NSURLRequest alloc] initWithURL:url]; + web::WebStatePolicyDecider::RequestInfo info(transition, + /*target_frame_is_main=*/true, + /*has_user_gesture=*/false); + return web_state_.ShouldAllowRequest(request, info); + } + + web::TestWebState web_state_; +}; + +// Tests that navigation is allowed for https url link. +TEST_F(InvalidUrlTabHelperTest, HttpsUrl) { + auto policy = GetPolicy(@"https://foo.test", ui::PAGE_TRANSITION_LINK); + EXPECT_TRUE(policy.ShouldAllowNavigation()); +} + +// Tests that navigation is allowed for https url links if url length is under +// allowed limit. +TEST_F(InvalidUrlTabHelperTest, HttpsUrlUnderLengthLimit) { + NSString* spec = [@"https://" stringByPaddingToLength:url::kMaxURLChars + withString:@"0" + startingAtIndex:0]; + auto policy = GetPolicy(spec, ui::PAGE_TRANSITION_LINK); + EXPECT_TRUE(policy.ShouldAllowNavigation()); +} + +// Tests that navigation is cancelled for https url links if url length is above +// allowed limit. +TEST_F(InvalidUrlTabHelperTest, HttpsUrlAboveLengthLimit) { + NSString* spec = [@"https://" stringByPaddingToLength:url::kMaxURLChars + 1 + withString:@"0" + startingAtIndex:0]; + auto policy = GetPolicy(spec, ui::PAGE_TRANSITION_LINK); + EXPECT_FALSE(policy.ShouldAllowNavigation()); + EXPECT_FALSE(policy.ShouldDisplayError()); +} + +// Tests that navigation is allowed for valid data url link. +TEST_F(InvalidUrlTabHelperTest, ValidDataUrlLink) { + auto policy = GetPolicy(@"data:text/plain;charset=utf-8,test", + ui::PAGE_TRANSITION_LINK); + EXPECT_TRUE(policy.ShouldAllowNavigation()); +} + +// Tests that navigation is sillently cancelled for invalid data url link. +TEST_F(InvalidUrlTabHelperTest, InvalidDataUrlLink) { + auto policy = GetPolicy(@"data://", ui::PAGE_TRANSITION_LINK); + EXPECT_FALSE(policy.ShouldAllowNavigation()); + EXPECT_FALSE(policy.ShouldDisplayError()); +} + +// Tests that navigation is cancelled with error for invalid data: url bookmark. +TEST_F(InvalidUrlTabHelperTest, InvalidDataUrlBookmark) { + auto policy = GetPolicy(@"data://", ui::PAGE_TRANSITION_AUTO_BOOKMARK); + EXPECT_FALSE(policy.ShouldAllowNavigation()); + EXPECT_NSEQ(net::kNSErrorDomain, policy.GetDisplayError().domain); + EXPECT_EQ(net::ERR_INVALID_URL, policy.GetDisplayError().code); +} + +// Tests that navigation is cancelled with error for invalid data: url typed. +TEST_F(InvalidUrlTabHelperTest, InvalidDataUrlTyped) { + auto policy = GetPolicy(@"data://", ui::PAGE_TRANSITION_TYPED); + EXPECT_FALSE(policy.ShouldAllowNavigation()); + EXPECT_NSEQ(net::kNSErrorDomain, policy.GetDisplayError().domain); + EXPECT_EQ(net::ERR_INVALID_URL, policy.GetDisplayError().code); +} + +// Tests that navigation is cancelled with error for invalid data: url +// generated. +TEST_F(InvalidUrlTabHelperTest, InvalidDataUrlGenerated) { + auto policy = GetPolicy(@"data://", ui::PAGE_TRANSITION_GENERATED); + EXPECT_FALSE(policy.ShouldAllowNavigation()); + EXPECT_NSEQ(net::kNSErrorDomain, policy.GetDisplayError().domain); + EXPECT_EQ(net::ERR_INVALID_URL, policy.GetDisplayError().code); +}
diff --git a/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.mm b/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.mm index 76d98ee..6a78d97 100644 --- a/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.mm +++ b/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.mm
@@ -9,6 +9,7 @@ #import "ios/chrome/common/ui/util/constraints_ui_util.h" #include "ios/chrome/common/ui/util/dynamic_type_util.h" #import "ios/chrome/common/ui/util/image_util.h" +#import "ios/chrome/common/ui/util/pointer_interaction_util.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -495,26 +496,8 @@ if (@available(iOS 13.4, *)) { if (self.pointerInteractionEnabled) { primaryActionButton.pointerInteractionEnabled = YES; - primaryActionButton.pointerStyleProvider = - ^UIPointerStyle*(UIButton* button, UIPointerEffect* proposedEffect, - __unused UIPointerShape* proposedShape) { - // - // The default pointer interaction on this button is awful (It does a - // lift on the button with an weird mousing highlight effect on just - // the label). All attempts to correct this for a button wide lift have - // failed ; no matter what is done in this block the only reasonable - // effect achievable is a hover with the cursor still visible. - // - // It seems that anything larger than roughly the third of the width - // of an iPad screen causes the framework to cancel the the lift effect - // and to replace it with a simple hover. - // - // This code below should do a lift. Does a lift on a smaller version - // of the exact same button. But it only achieves a hover. - // - return [UIPointerStyle styleWithEffect:proposedEffect shape:nil]; - }; + CreateOpaqueButtonPointerStyleProvider(); } } #endif // defined(__IPHONE_13_4)
diff --git a/ios/chrome/common/ui/util/pointer_interaction_util.h b/ios/chrome/common/ui/util/pointer_interaction_util.h index f6e3a8f2..78d056fa 100644 --- a/ios/chrome/common/ui/util/pointer_interaction_util.h +++ b/ios/chrome/common/ui/util/pointer_interaction_util.h
@@ -17,6 +17,36 @@ // pointer shape. UIButtonPointerStyleProvider CreateLiftEffectCirclePointerStyleProvider() API_AVAILABLE(ios(13.4)); + +// Returns a pointer style provider that is best for opaque buttons, such as the +// primary action buttons which have a blue background and white text. +// By default, UIKit creates inconsistent hover effects for buttons with opaque +// backgrounds depending on the size of the button. Wide buttons get a weird +// mousing highlight effect on just the label. This function should be used for +// all opaque buttons to ensure that various sizes have consistent effects. This +// effect has a slight background color tint, with no shadow nor scale nor +// pointer shape change. +UIButtonPointerStyleProvider CreateOpaqueButtonPointerStyleProvider() + API_AVAILABLE(ios(13.4)); + +// Returns a pointer style provider that is best for transparent buttons, such +// as secondary action buttons which have a transparent background and blue +// text. By default, UIKit chooses the best size of the highlight pointer shape. +// Small buttons get a highlight pointer shape of the whole button. Wide buttons +// get a highlight pointer of just the label. To fix this, a custom pointer +// shape is set with the size of the button. This function should be used for +// wide transparent buttons, especially if the size of the button is set larger +// than the intrinsic size of the text label. It is not needed for very small +// buttons. +UIButtonPointerStyleProvider CreateTransparentButtonPointerStyleProvider() + API_AVAILABLE(ios(13.4)); + +// Returns either an opaque or transparent button pointer style based on the +// button's background color at runtime. This function is useful for generic +// components with a button that may be styled differently in different use +// cases. +UIButtonPointerStyleProvider +CreateOpaqueOrTransparentButtonPointerStyleProvider() API_AVAILABLE(ios(13.4)); #endif // defined(__IPHONE_13_4) #endif // IOS_CHROME_COMMON_UI_UTIL_POINTER_INTERACTION_UTIL_H_
diff --git a/ios/chrome/common/ui/util/pointer_interaction_util.mm b/ios/chrome/common/ui/util/pointer_interaction_util.mm index 6966b983..73e035d8 100644 --- a/ios/chrome/common/ui/util/pointer_interaction_util.mm +++ b/ios/chrome/common/ui/util/pointer_interaction_util.mm
@@ -14,6 +14,32 @@ #if defined(__IPHONE_13_4) +namespace { +// Returns a pointer style with a hover effect with a slight tint and no pointer +// shape (i.e., the pointer stays the same). +UIPointerStyle* CreateHoverEffectNoShapePointerStyle(UIButton* button) + API_AVAILABLE(ios(13.4)) { + UITargetedPreview* preview = [[UITargetedPreview alloc] initWithView:button]; + UIPointerHoverEffect* effect = + [UIPointerHoverEffect effectWithPreview:preview]; + effect.preferredTintMode = UIPointerEffectTintModeOverlay; + effect.prefersScaledContent = NO; + effect.prefersShadow = NO; + return [UIPointerStyle styleWithEffect:effect shape:nil]; +} + +// Returns a pointer style with a highlight effect and a rounded rectangle +// pointer shape sized to the button frame. +UIPointerStyle* CreateHighlightEffectRectShapePointerStyle(UIButton* button) + API_AVAILABLE(ios(13.4)) { + UITargetedPreview* preview = [[UITargetedPreview alloc] initWithView:button]; + UIPointerHighlightEffect* effect = + [UIPointerHighlightEffect effectWithPreview:preview]; + UIPointerShape* shape = [UIPointerShape shapeWithRoundedRect:button.frame]; + return [UIPointerStyle styleWithEffect:effect shape:shape]; +} +} // namespace + UIButtonPointerStyleProvider CreateDefaultEffectCirclePointerStyleProvider() API_AVAILABLE(ios(13.4)) { return ^UIPointerStyle*(UIButton* button, UIPointerEffect* proposedEffect, @@ -44,4 +70,38 @@ }; } +UIButtonPointerStyleProvider CreateOpaqueButtonPointerStyleProvider() + API_AVAILABLE(ios(13.4)) { + return ^UIPointerStyle*(UIButton* button, UIPointerEffect* proposedEffect, + UIPointerShape* proposedShape) { + DCHECK(button.backgroundColor && + button.backgroundColor != [UIColor clearColor]) + << "Expected an opaque background for button."; + return CreateHoverEffectNoShapePointerStyle(button); + }; +} + +UIButtonPointerStyleProvider CreateTransparentButtonPointerStyleProvider() + API_AVAILABLE(ios(13.4)) { + return ^UIPointerStyle*(UIButton* button, UIPointerEffect* proposedEffect, + UIPointerShape* proposedShape) { + DCHECK(!button.backgroundColor || + button.backgroundColor == [UIColor clearColor]) + << "Expected a transparent background for button."; + return CreateHighlightEffectRectShapePointerStyle(button); + }; +} + +UIButtonPointerStyleProvider +CreateOpaqueOrTransparentButtonPointerStyleProvider() API_AVAILABLE(ios(13.4)) { + return ^UIPointerStyle*(UIButton* button, UIPointerEffect* proposedEffect, + UIPointerShape* proposedShape) { + if (button.backgroundColor && + button.backgroundColor != [UIColor clearColor]) { + return CreateHoverEffectNoShapePointerStyle(button); + } + return CreateHighlightEffectRectShapePointerStyle(button); + }; +} + #endif // defined(__IPHONE_13_4)
diff --git a/ios/chrome/test/BUILD.gn b/ios/chrome/test/BUILD.gn index 0f6a0cdc..596b0aec 100644 --- a/ios/chrome/test/BUILD.gn +++ b/ios/chrome/test/BUILD.gn
@@ -279,6 +279,7 @@ "//ios/chrome/browser/ui/open_in:unit_tests", "//ios/chrome/browser/ui/overlays:unit_tests", "//ios/chrome/browser/ui/overlays/infobar_banner:unit_tests", + "//ios/chrome/browser/ui/overlays/infobar_banner/confirm:unit_tests", "//ios/chrome/browser/ui/overlays/infobar_banner/passwords:unit_tests", "//ios/chrome/browser/ui/overlays/infobar_modal:unit_tests", "//ios/chrome/browser/ui/overlays/infobar_modal/passwords:unit_tests",
diff --git a/ios/public/provider/chrome/browser/signin/fake_chrome_identity_service.mm b/ios/public/provider/chrome/browser/signin/fake_chrome_identity_service.mm index 9103f77..bbea926 100644 --- a/ios/public/provider/chrome/browser/signin/fake_chrome_identity_service.mm +++ b/ios/public/provider/chrome/browser/signin/fake_chrome_identity_service.mm
@@ -37,6 +37,7 @@ @interface FakeAccountDetailsViewController : UIViewController { __weak ChromeIdentity* _identity; UIButton* _removeAccountButton; + UIButton* _closeAccountDetailsButton; } @end @@ -54,6 +55,9 @@ [_removeAccountButton removeTarget:self action:@selector(didTapRemoveAccount:) forControlEvents:UIControlEventTouchUpInside]; + [_closeAccountDetailsButton removeTarget:self + action:@selector(didTapCloseAccount:) + forControlEvents:UIControlEventTouchUpInside]; } - (void)viewDidLoad { @@ -63,21 +67,43 @@ self.view.backgroundColor = [UIColor orangeColor]; _removeAccountButton = [UIButton buttonWithType:UIButtonTypeCustom]; - [_removeAccountButton setTitle:@"Remove account" - forState:UIControlStateNormal]; - [_removeAccountButton addTarget:self - action:@selector(didTapRemoveAccount:) - forControlEvents:UIControlEventTouchUpInside]; - [self.view addSubview:_removeAccountButton]; + [self addButtonToSubviewWithTitle:@"Remove account" + button:_removeAccountButton + action:@selector(didTapRemoveAccount:)]; + + _closeAccountDetailsButton = [UIButton buttonWithType:UIButtonTypeCustom]; + [self addButtonToSubviewWithTitle:@"Close account" + button:_closeAccountDetailsButton + action:@selector(didTapCloseAccount:)]; } - (void)viewWillLayoutSubviews { [super viewWillLayoutSubviews]; CGRect bounds = self.view.bounds; - [_removeAccountButton - setCenter:CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds))]; - [_removeAccountButton sizeToFit]; + [self sizeButtonToFitWithCenter:CGPointMake(CGRectGetMidX(bounds), + CGRectGetMinY(bounds)) + button:_removeAccountButton]; + [self sizeButtonToFitWithCenter:CGPointMake(CGRectGetMidX(bounds), + CGRectGetMidY(bounds)) + button:_closeAccountDetailsButton]; +} + +#pragma mark - Private + +- (void)addButtonToSubviewWithTitle:(NSString*)title + button:(UIButton*)button + action:(SEL)action { + [button setTitle:title forState:UIControlStateNormal]; + [button addTarget:self + action:action + forControlEvents:UIControlEventTouchUpInside]; + [self.view addSubview:button]; +} + +- (void)sizeButtonToFitWithCenter:(CGPoint)center button:(UIButton*)button { + [button setCenter:center]; + [button sizeToFit]; } - (void)didTapRemoveAccount:(id)sender { @@ -87,6 +113,10 @@ }); } +- (void)didTapCloseAccount:(id)sender { + [self dismissViewControllerAnimated:YES completion:nil]; +} + @end namespace ios {
diff --git a/ios/web/web_sub_thread.cc b/ios/web/web_sub_thread.cc index 5780560..11f4d50 100644 --- a/ios/web/web_sub_thread.cc +++ b/ios/web/web_sub_thread.cc
@@ -107,14 +107,16 @@ } void WebSubThread::UIThreadRun(base::RunLoop* run_loop) { - const int line_number = __LINE__; Thread::Run(run_loop); + // Inhibit tail calls of Run and inhibit code folding. + const int line_number = __LINE__; base::debug::Alias(&line_number); } void WebSubThread::IOThreadRun(base::RunLoop* run_loop) { - const int line_number = __LINE__; Thread::Run(run_loop); + // Inhibit tail calls of Run and inhibit code folding. + const int line_number = __LINE__; base::debug::Alias(&line_number); }
diff --git a/ios/web_view/BUILD.gn b/ios/web_view/BUILD.gn index d13a46e..1111de73 100644 --- a/ios/web_view/BUILD.gn +++ b/ios/web_view/BUILD.gn
@@ -352,7 +352,8 @@ public_headers += cronet_native_public_headers } - sources = [ "internal/web_view_global_state_util.mm" ] + sources = ios_web_view_public_headers + sources += [ "internal/web_view_global_state_util.mm" ] if (ios_web_view_include_cronet) { sources += [ "//components/cronet/ios/Cronet.h" ] }
diff --git a/media/base/media_log.h b/media/base/media_log.h index 72bac1f..4812b87 100644 --- a/media/base/media_log.h +++ b/media/base/media_log.h
@@ -23,7 +23,6 @@ #include "media/base/media_log_message_levels.h" #include "media/base/media_log_properties.h" #include "media/base/media_log_record.h" -#include "media/base/pipeline_impl.h" #include "media/base/pipeline_status.h" #include "url/gurl.h"
diff --git a/media/base/test_helpers.h b/media/base/test_helpers.h index 8e97cdc..bffe5960 100644 --- a/media/base/test_helpers.h +++ b/media/base/test_helpers.h
@@ -16,6 +16,7 @@ #include "base/strings/stringprintf.h" #include "media/base/audio_parameters.h" #include "media/base/channel_layout.h" +#include "media/base/demuxer_stream.h" #include "media/base/media_log.h" #include "media/base/pipeline_status.h" #include "media/base/sample_format.h"
diff --git a/media/capture/BUILD.gn b/media/capture/BUILD.gn index 9808afdb..06e45ca 100644 --- a/media/capture/BUILD.gn +++ b/media/capture/BUILD.gn
@@ -393,6 +393,16 @@ ] } + if (is_fuchsia) { + deps += [ + "//media/fuchsia/camera:test_support", + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.camera3", + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.sysmem", + "//third_party/fuchsia-sdk/sdk/pkg/sys_cpp", + ] + sources += [ "video/fuchsia/video_capture_device_fuchsia_test.cc" ] + } + if (is_win) { sources += [ "video/win/video_capture_device_factory_win_unittest.cc",
diff --git a/media/capture/video/fuchsia/video_capture_device_fuchsia.cc b/media/capture/video/fuchsia/video_capture_device_fuchsia.cc index 46bf443..946ad15 100644 --- a/media/capture/video/fuchsia/video_capture_device_fuchsia.cc +++ b/media/capture/video/fuchsia/video_capture_device_fuchsia.cc
@@ -11,6 +11,7 @@ #include "base/time/time.h" #include "media/base/video_types.h" #include "third_party/libyuv/include/libyuv/convert.h" +#include "third_party/libyuv/include/libyuv/video_common.h" #include "ui/gfx/buffer_format_util.h" namespace media { @@ -21,71 +22,68 @@ return ((value + alignment - 1) / alignment) * alignment; } -void CopyAndConvertFrame( - base::span<const uint8_t> src_span, - fuchsia::sysmem::PixelFormatType src_pixel_format, - size_t src_stride_y, - size_t src_coded_height, - std::unique_ptr<VideoCaptureBufferHandle> output_handle, - gfx::Size output_size) { - const uint8_t* src_y = src_span.data(); - size_t src_y_plane_size = src_stride_y * src_coded_height; - - // Calculate offsets and strides for the output buffer. - uint8_t* dst_y = output_handle->data(); - int dst_stride_y = output_size.width(); - size_t dst_y_plane_size = output_size.width() * output_size.height(); - uint8_t* dst_u = dst_y + dst_y_plane_size; - int dst_stride_u = output_size.width() / 2; - uint8_t* dst_v = dst_u + dst_y_plane_size / 4; - int dst_stride_v = output_size.width() / 2; - - // Check that the output fits in the buffer. - const uint8_t* dst_end = dst_v + dst_y_plane_size / 4; - CHECK_LE(dst_end, output_handle->data() + output_handle->mapped_size()); - +libyuv::FourCC GetFourccForPixelFormat( + fuchsia::sysmem::PixelFormatType src_pixel_format) { switch (src_pixel_format) { + case fuchsia::sysmem::PixelFormatType::I420: + return libyuv::FourCC::FOURCC_I420; case fuchsia::sysmem::PixelFormatType::YV12: - case fuchsia::sysmem::PixelFormatType::I420: { - const uint8_t* src_u = src_y + src_y_plane_size; - int src_stride_u = src_stride_y / 2; - size_t src_u_plane_size = src_stride_u * src_coded_height / 2; - const uint8_t* src_v = src_u + src_u_plane_size; - int src_stride_v = src_stride_y / 2; - - if (src_pixel_format == fuchsia::sysmem::PixelFormatType::YV12) { - // Swap U and V planes to account for different plane order in YV12. - std::swap(src_u, src_v); - } - - size_t src_v_plane_size = src_stride_v * src_coded_height / 2; - const uint8_t* src_end = src_v + src_v_plane_size; - CHECK_LE(src_end, src_span.data() + src_span.size()); - - libyuv::I420Copy(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_y, dst_stride_y, dst_u, dst_stride_u, - dst_v, dst_stride_v, output_size.width(), - output_size.height()); - break; - } - - case fuchsia::sysmem::PixelFormatType::NV12: { - const uint8_t* src_uv = src_y + src_stride_y * src_coded_height; - int src_stride_uv = src_stride_y; - - int src_uv_plane_size = src_stride_uv * src_coded_height / 2; - const uint8_t* src_end = src_uv + src_uv_plane_size; - CHECK_LE(src_end, src_span.data() + src_span.size()); - - libyuv::NV12ToI420(src_y, src_stride_y, src_uv, src_stride_uv, dst_y, - dst_stride_y, dst_u, dst_stride_u, dst_v, dst_stride_v, - output_size.width(), output_size.height()); - - break; - } - + return libyuv::FourCC::FOURCC_YV12; + case fuchsia::sysmem::PixelFormatType::NV12: + return libyuv::FourCC::FOURCC_NV12; default: NOTREACHED(); + return libyuv::FourCC::FOURCC_I420; + } +} + +libyuv::RotationMode CameraOrientationToLibyuvRotation( + fuchsia::camera3::Orientation orientation, + bool* flip_y) { + switch (orientation) { + case fuchsia::camera3::Orientation::UP: + *flip_y = false; + return libyuv::RotationMode::kRotate0; + + case fuchsia::camera3::Orientation::DOWN: + *flip_y = false; + return libyuv::RotationMode::kRotate180; + + case fuchsia::camera3::Orientation::LEFT: + *flip_y = false; + return libyuv::RotationMode::kRotate270; + + case fuchsia::camera3::Orientation::RIGHT: + *flip_y = false; + return libyuv::RotationMode::kRotate90; + + case fuchsia::camera3::Orientation::UP_FLIPPED: + *flip_y = true; + return libyuv::RotationMode::kRotate180; + + case fuchsia::camera3::Orientation::DOWN_FLIPPED: + *flip_y = true; + return libyuv::RotationMode::kRotate0; + + case fuchsia::camera3::Orientation::LEFT_FLIPPED: + *flip_y = true; + return libyuv::RotationMode::kRotate90; + + case fuchsia::camera3::Orientation::RIGHT_FLIPPED: + *flip_y = true; + return libyuv::RotationMode::kRotate270; + } +} + +gfx::Size RotateSize(gfx::Size size, libyuv::RotationMode rotation) { + switch (rotation) { + case libyuv::RotationMode::kRotate0: + case libyuv::RotationMode::kRotate180: + return size; + + case libyuv::RotationMode::kRotate90: + case libyuv::RotationMode::kRotate270: + return gfx::Size(size.height(), size.width()); } } @@ -150,6 +148,7 @@ fit::bind_member(this, &VideoCaptureDeviceFuchsia::OnStreamError)); WatchResolution(); + WatchOrientation(); // Call SetBufferCollection() with a new buffer collection token to indicate // that we are interested in buffer collection negotiation. The collection @@ -213,6 +212,21 @@ WatchResolution(); } +void VideoCaptureDeviceFuchsia::WatchOrientation() { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + + stream_->WatchOrientation(fit::bind_member( + this, &VideoCaptureDeviceFuchsia::OnWatchOrientationResult)); +} + +void VideoCaptureDeviceFuchsia::OnWatchOrientationResult( + fuchsia::camera3::Orientation orientation) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + + orientation_ = orientation; + WatchOrientation(); +} + void VideoCaptureDeviceFuchsia::WatchBufferCollection() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -333,8 +347,15 @@ sysmem_buffer_format.bytes_per_row_divisor); gfx::Size visible_size = frame_size_.value_or(gfx::Size(src_coded_width, src_coded_height)); - gfx::Size output_size((visible_size.width() + 1) & ~1, - (visible_size.height() + 1) & ~1); + gfx::Size nonrotated_output_size((visible_size.width() + 1) & ~1, + (visible_size.height() + 1) & ~1); + + bool flip_y; + libyuv::RotationMode rotation = + CameraOrientationToLibyuvRotation(orientation_, &flip_y); + + gfx::Size output_size = RotateSize(nonrotated_output_size, rotation); + visible_size = RotateSize(visible_size, rotation); base::TimeTicks reference_time = base::TimeTicks::FromZxTime(frame_info.timestamp); @@ -375,11 +396,36 @@ return; } - auto src_pixel_format = buffer_reader_->buffer_settings() - .image_format_constraints.pixel_format.type; - CopyAndConvertFrame(src_span, src_pixel_format, src_stride, src_coded_height, - buffer.handle_provider->GetHandleForInProcessAccess(), - output_size); + std::unique_ptr<VideoCaptureBufferHandle> output_handle = + buffer.handle_provider->GetHandleForInProcessAccess(); + + // Calculate offsets and strides for the output buffer. + uint8_t* dst_y = output_handle->data(); + int dst_stride_y = output_size.width(); + size_t dst_y_plane_size = output_size.width() * output_size.height(); + uint8_t* dst_u = dst_y + dst_y_plane_size; + int dst_stride_u = output_size.width() / 2; + uint8_t* dst_v = dst_u + dst_y_plane_size / 4; + int dst_stride_v = output_size.width() / 2; + + // Check that the output fits in the buffer. + const uint8_t* dst_end = dst_v + dst_y_plane_size / 4; + CHECK_LE(dst_end, output_handle->data() + output_handle->mapped_size()); + + // Vertical flip is indicated to ConvertToI420() by negating src_height. + int flipped_src_height = static_cast<int>(src_coded_height); + if (flip_y) + flipped_src_height = -flipped_src_height; + + auto four_cc = + GetFourccForPixelFormat(buffer_reader_->buffer_settings() + .image_format_constraints.pixel_format.type); + + libyuv::ConvertToI420(src_span.data(), src_span.size(), dst_y, dst_stride_y, + dst_u, dst_stride_u, dst_v, dst_stride_v, + /*crop_x=*/0, /*crop_y=*/0, src_stride, + flipped_src_height, nonrotated_output_size.width(), + nonrotated_output_size.height(), rotation, four_cc); client_->OnIncomingCapturedBufferExt( std::move(buffer), capture_format, gfx::ColorSpace(), reference_time,
diff --git a/media/capture/video/fuchsia/video_capture_device_fuchsia.h b/media/capture/video/fuchsia/video_capture_device_fuchsia.h index c948997..1d2e40c 100644 --- a/media/capture/video/fuchsia/video_capture_device_fuchsia.h +++ b/media/capture/video/fuchsia/video_capture_device_fuchsia.h
@@ -60,6 +60,12 @@ // Callback for WatchResolution(). void OnWatchResolutionResult(fuchsia::math::Size frame_size); + // Watches for orientation updates and updates |orientation_| accordingly. + void WatchOrientation(); + + // Callback for WatchOrientation(). + void OnWatchOrientationResult(fuchsia::camera3::Orientation orientation); + // Watches for sysmem buffer collection updates from the camera. void WatchBufferCollection(); @@ -95,6 +101,8 @@ std::unique_ptr<SysmemBufferReader> buffer_reader_; base::Optional<gfx::Size> frame_size_; + fuchsia::camera3::Orientation orientation_ = + fuchsia::camera3::Orientation::UP; base::TimeTicks start_time_;
diff --git a/media/capture/video/fuchsia/video_capture_device_fuchsia_test.cc b/media/capture/video/fuchsia/video_capture_device_fuchsia_test.cc new file mode 100644 index 0000000..63627c46 --- /dev/null +++ b/media/capture/video/fuchsia/video_capture_device_fuchsia_test.cc
@@ -0,0 +1,324 @@ +// 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 "media/capture/video/fuchsia/video_capture_device_fuchsia.h" + +#include "base/test/task_environment.h" +#include "media/fuchsia/camera/fake_fuchsia_camera.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/geometry/size.h" + +namespace media { + +namespace { + +struct ReceivedFrame { + VideoCaptureDevice::Client::Buffer buffer; + VideoCaptureFormat format; + gfx::ColorSpace color_space; + base::TimeTicks reference_time; + base::TimeDelta timestamp; + gfx::Rect visible_rect; +}; + +void ValidateReceivedFrame(const ReceivedFrame& frame, + gfx::Size expected_size, + uint8_t salt) { + gfx::Size coded_size((expected_size.width() + 1) & ~1, + (expected_size.height() + 1) & ~1); + ASSERT_EQ(frame.format.frame_size, coded_size); + EXPECT_EQ(frame.format.pixel_format, PIXEL_FORMAT_I420); + EXPECT_EQ(frame.visible_rect, gfx::Rect(expected_size)); + EXPECT_EQ(frame.color_space, gfx::ColorSpace()); + + auto handle = frame.buffer.handle_provider->GetHandleForInProcessAccess(); + + FakeCameraStream::ValidateFrameData(handle->data(), coded_size, salt); +} + +// VideoCaptureBufferHandle implementation that references memory allocated on +// the heap. +class HeapBufferHandle : public VideoCaptureBufferHandle { + public: + HeapBufferHandle(size_t size, uint8_t* data) : size_(size), data_(data) {} + + size_t mapped_size() const final { return size_; } + uint8_t* data() const final { return data_; } + const uint8_t* const_data() const final { return data_; } + + private: + const size_t size_; + uint8_t* const data_; +}; + +// VideoCaptureDevice::Client::Buffer::HandleProvider implementation that +// allocates memory on the heap. +class HeapBufferHandleProvider + : public VideoCaptureDevice::Client::Buffer::HandleProvider { + public: + HeapBufferHandleProvider(size_t size) : data_(size) {} + ~HeapBufferHandleProvider() final = default; + + base::UnsafeSharedMemoryRegion DuplicateAsUnsafeRegion() final { + NOTREACHED(); + return {}; + } + + mojo::ScopedSharedBufferHandle DuplicateAsMojoBuffer() final { + NOTREACHED(); + return {}; + } + + std::unique_ptr<VideoCaptureBufferHandle> GetHandleForInProcessAccess() + override { + return std::make_unique<HeapBufferHandle>(data_.size(), data_.data()); + } + + gfx::GpuMemoryBufferHandle GetGpuMemoryBufferHandle() override { + return gfx::GpuMemoryBufferHandle(); + } + + private: + std::vector<uint8_t> data_; +}; + +class TestVideoCaptureClient : public VideoCaptureDevice::Client { + public: + ~TestVideoCaptureClient() final = default; + + void WaitFrame() { + EXPECT_FALSE(wait_frame_run_loop_); + + wait_frame_run_loop_.emplace(); + wait_frame_run_loop_->Run(); + wait_frame_run_loop_.reset(); + } + + const std::vector<ReceivedFrame>& received_frames() { + return received_frames_; + } + + private: + // VideoCaptureDevice::Client implementation. + void OnStarted() final { + EXPECT_FALSE(started_); + started_ = true; + } + + ReserveResult ReserveOutputBuffer(const gfx::Size& dimensions, + VideoPixelFormat format, + int frame_feedback_id, + Buffer* buffer) final { + EXPECT_TRUE(started_); + EXPECT_EQ(format, PIXEL_FORMAT_I420); + EXPECT_EQ(dimensions.width() % 2, 0); + EXPECT_EQ(dimensions.height() % 2, 0); + + size_t size = dimensions.width() * dimensions.height() * 3 / 2; + buffer->handle_provider = std::make_unique<HeapBufferHandleProvider>(size); + return VideoCaptureDevice::Client::ReserveResult::kSucceeded; + } + + void OnIncomingCapturedBufferExt( + Buffer buffer, + const VideoCaptureFormat& format, + const gfx::ColorSpace& color_space, + base::TimeTicks reference_time, + base::TimeDelta timestamp, + gfx::Rect visible_rect, + const VideoFrameMetadata& additional_metadata) final { + EXPECT_TRUE(started_); + + received_frames_.push_back(ReceivedFrame{std::move(buffer), format, + color_space, reference_time, + timestamp, visible_rect}); + + if (wait_frame_run_loop_) + wait_frame_run_loop_->Quit(); + } + + void OnIncomingCapturedData(const uint8_t* data, + int length, + const VideoCaptureFormat& frame_format, + const gfx::ColorSpace& color_space, + int clockwise_rotation, + bool flip_y, + base::TimeTicks reference_time, + base::TimeDelta timestamp, + int frame_feedback_id) final { + NOTREACHED(); + } + void OnIncomingCapturedGfxBuffer(gfx::GpuMemoryBuffer* buffer, + const VideoCaptureFormat& frame_format, + int clockwise_rotation, + base::TimeTicks reference_time, + base::TimeDelta timestamp, + int frame_feedback_id) final { + NOTREACHED(); + } + void OnIncomingCapturedBuffer(Buffer buffer, + const VideoCaptureFormat& format, + base::TimeTicks reference_time, + base::TimeDelta timestamp) final { + NOTREACHED(); + } + void OnError(VideoCaptureError error, + const base::Location& from_here, + const std::string& reason) final { + NOTREACHED(); + } + void OnFrameDropped(VideoCaptureFrameDropReason reason) final { + NOTREACHED(); + } + void OnLog(const std::string& message) final { NOTREACHED(); } + double GetBufferPoolUtilization() const final { + NOTREACHED(); + return 0; + } + + bool started_ = false; + std::vector<ReceivedFrame> received_frames_; + base::Optional<base::RunLoop> wait_frame_run_loop_; +}; + +} // namespace + +class VideoCaptureDeviceFuchsiaTest : public testing::Test { + public: + VideoCaptureDeviceFuchsiaTest() { + fidl::InterfaceHandle<fuchsia::camera3::Device> device_handle; + fake_device_.Bind(device_handle.NewRequest()); + device_ = + std::make_unique<VideoCaptureDeviceFuchsia>(std::move(device_handle)); + } + + ~VideoCaptureDeviceFuchsiaTest() override { device_->StopAndDeAllocate(); } + + void StartCapturer() { + VideoCaptureParams params; + params.requested_format.frame_size = FakeCameraStream::kDefaultFrameSize; + params.requested_format.frame_rate = 30.0; + params.requested_format.pixel_format = PIXEL_FORMAT_I420; + + auto client = std::make_unique<TestVideoCaptureClient>(); + client_ = client.get(); + device_->AllocateAndStart(params, std::move(client)); + + EXPECT_TRUE(fake_stream_.WaitBuffersAllocated()); + } + + protected: + base::test::SingleThreadTaskEnvironment task_environment_{ + base::test::SingleThreadTaskEnvironment::MainThreadType::IO}; + + FakeCameraStream fake_stream_; + FakeCameraDevice fake_device_{&fake_stream_}; + std::unique_ptr<VideoCaptureDeviceFuchsia> device_; + TestVideoCaptureClient* client_ = nullptr; +}; + +TEST_F(VideoCaptureDeviceFuchsiaTest, Initialize) { + StartCapturer(); +} + +TEST_F(VideoCaptureDeviceFuchsiaTest, SendFrame) { + StartCapturer(); + + auto frame_timestamp = base::TimeTicks::Now(); + fake_stream_.ProduceFrame(frame_timestamp, 1); + client_->WaitFrame(); + + ASSERT_EQ(client_->received_frames().size(), 1U); + EXPECT_EQ(client_->received_frames()[0].reference_time, frame_timestamp); + ValidateReceivedFrame(client_->received_frames()[0], + FakeCameraStream::kDefaultFrameSize, 1); +} + +TEST_F(VideoCaptureDeviceFuchsiaTest, MultipleFrames) { + StartCapturer(); + + EXPECT_TRUE(fake_stream_.WaitBuffersAllocated()); + + for (size_t i = 0; i < 10; ++i) { + ASSERT_TRUE(fake_stream_.WaitFreeBuffer()); + + auto frame_timestamp = + base::TimeTicks() + base::TimeDelta::FromMilliseconds(i * 16); + fake_stream_.ProduceFrame(frame_timestamp, i); + client_->WaitFrame(); + + ASSERT_EQ(client_->received_frames().size(), i + 1); + EXPECT_EQ(client_->received_frames()[i].reference_time, frame_timestamp); + ValidateReceivedFrame(client_->received_frames()[i], + FakeCameraStream::kDefaultFrameSize, i); + } +} + +TEST_F(VideoCaptureDeviceFuchsiaTest, FrameRotation) { + const gfx::Size kResolution(4, 2); + fake_stream_.SetFakeResolution(kResolution); + + StartCapturer(); + + EXPECT_TRUE(fake_stream_.WaitBuffersAllocated()); + + for (int i = static_cast<int>(fuchsia::camera3::Orientation::UP); + i <= static_cast<int>(fuchsia::camera3::Orientation::RIGHT_FLIPPED); + ++i) { + SCOPED_TRACE(testing::Message() << "Orientation " << i); + + auto orientation = static_cast<fuchsia::camera3::Orientation>(i); + + ASSERT_TRUE(fake_stream_.WaitFreeBuffer()); + fake_stream_.SetFakeOrientation(orientation); + fake_stream_.ProduceFrame(base::TimeTicks::Now(), i); + client_->WaitFrame(); + + gfx::Size expected_size = kResolution; + if (orientation == fuchsia::camera3::Orientation::LEFT || + orientation == fuchsia::camera3::Orientation::LEFT_FLIPPED || + orientation == fuchsia::camera3::Orientation::RIGHT || + orientation == fuchsia::camera3::Orientation::RIGHT_FLIPPED) { + expected_size = gfx::Size(expected_size.height(), expected_size.width()); + } + ValidateReceivedFrame(client_->received_frames().back(), expected_size, i); + } +} + +TEST_F(VideoCaptureDeviceFuchsiaTest, FrameDimensionsNotDivisibleBy2) { + const gfx::Size kOddResolution(21, 7); + fake_stream_.SetFakeResolution(kOddResolution); + + StartCapturer(); + + fake_stream_.ProduceFrame(base::TimeTicks::Now(), 1); + client_->WaitFrame(); + + ASSERT_EQ(client_->received_frames().size(), 1U); + ValidateReceivedFrame(client_->received_frames()[0], kOddResolution, 1); +} + +TEST_F(VideoCaptureDeviceFuchsiaTest, MidStreamResolutionChange) { + StartCapturer(); + + // Capture the first frame at the default resolution. + fake_stream_.ProduceFrame(base::TimeTicks::Now(), 1); + client_->WaitFrame(); + ASSERT_TRUE(fake_stream_.WaitFreeBuffer()); + + // Update resolution and produce another frames. + const gfx::Size kUpdatedResolution(3, 14); + fake_stream_.SetFakeResolution(kUpdatedResolution); + fake_stream_.ProduceFrame(base::TimeTicks::Now(), 1); + client_->WaitFrame(); + + // Verify that we get captured frames with correct resolution. + ASSERT_EQ(client_->received_frames().size(), 2U); + ValidateReceivedFrame(client_->received_frames()[0], + FakeCameraStream::kDefaultFrameSize, 1); + ValidateReceivedFrame(client_->received_frames()[1], kUpdatedResolution, 1); +} + +} // namespace media
diff --git a/media/fuchsia/camera/BUILD.gn b/media/fuchsia/camera/BUILD.gn new file mode 100644 index 0000000..c8ec86f --- /dev/null +++ b/media/fuchsia/camera/BUILD.gn
@@ -0,0 +1,19 @@ +# 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. + +source_set("test_support") { + testonly = true + public_deps = [ + "//base", + "//testing/gtest", + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.camera3", + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.sysmem", + "//third_party/fuchsia-sdk/sdk/pkg/fidl_cpp", + "//ui/gfx/geometry", + ] + sources = [ + "fake_fuchsia_camera.cc", + "fake_fuchsia_camera.h", + ] +}
diff --git a/media/fuchsia/camera/fake_fuchsia_camera.cc b/media/fuchsia/camera/fake_fuchsia_camera.cc new file mode 100644 index 0000000..0f592c7 --- /dev/null +++ b/media/fuchsia/camera/fake_fuchsia_camera.cc
@@ -0,0 +1,477 @@ +// 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 "media/fuchsia/camera/fake_fuchsia_camera.h" + +#include <fuchsia/sysmem/cpp/fidl.h> +#include <lib/sys/cpp/component_context.h> + +#include "base/fuchsia/default_context.h" +#include "base/memory/platform_shared_memory_region.h" +#include "base/memory/writable_shared_memory_region.h" +#include "base/message_loop/message_loop_current.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace media { + +namespace { + +constexpr uint8_t kYPlaneSalt = 1; +constexpr uint8_t kUPlaneSalt = 2; +constexpr uint8_t kVPlaneSalt = 3; + +uint8_t GetTestFrameValue(gfx::Size size, int x, int y, uint8_t salt) { + return static_cast<uint8_t>(y + x * size.height() + salt); +} + +// Fills one plane of a test frame. |data| points at the location of the pixel +// (0, 0). |orientation| specifies frame orientation transformation that will be +// applied on the receiving end, so this function applies _reverse_ of the +// |orientation| transformation. +void FillPlane(uint8_t* data, + gfx::Size size, + int x_step, + int y_step, + fuchsia::camera3::Orientation orientation, + uint8_t salt) { + // First flip X axis for flipped orientation. + if (orientation == fuchsia::camera3::Orientation::UP_FLIPPED || + orientation == fuchsia::camera3::Orientation::DOWN_FLIPPED || + orientation == fuchsia::camera3::Orientation::RIGHT_FLIPPED || + orientation == fuchsia::camera3::Orientation::LEFT_FLIPPED) { + // Move the origin to the top right corner and flip the X axis. + data += (size.width() - 1) * x_step; + x_step = -x_step; + } + + switch (orientation) { + case fuchsia::camera3::Orientation::UP: + case fuchsia::camera3::Orientation::UP_FLIPPED: + break; + + case fuchsia::camera3::Orientation::DOWN: + case fuchsia::camera3::Orientation::DOWN_FLIPPED: + // Move |data| to point to the bottom right corner and reverse direction + // of both axes. + data += (size.width() - 1) * x_step + (size.height() - 1) * y_step; + x_step = -x_step; + y_step = -y_step; + break; + + case fuchsia::camera3::Orientation::LEFT: + case fuchsia::camera3::Orientation::LEFT_FLIPPED: + // Rotate 90 degrees clockwise by moving |data| to point to the right top + // corner, swapping the axes and reversing direction of the Y axis. + data += (size.width() - 1) * x_step; + size = gfx::Size(size.height(), size.width()); + std::swap(x_step, y_step); + y_step = -y_step; + break; + + case fuchsia::camera3::Orientation::RIGHT: + case fuchsia::camera3::Orientation::RIGHT_FLIPPED: + // Rotate 90 degrees counter-clockwise by moving |data| to point to the + // bottom left corner, swapping the axes and reversing direction of the X + // axis. + data += (size.height() - 1) * y_step; + size = gfx::Size(size.height(), size.width()); + std::swap(x_step, y_step); + x_step = -x_step; + break; + } + + for (int y = 0; y < size.height(); ++y) { + for (int x = 0; x < size.width(); ++x) { + data[x * x_step + y * y_step] = GetTestFrameValue(size, x, y, salt); + } + } +} + +void ValidatePlane(const uint8_t* data, + gfx::Size size, + size_t x_step, + size_t y_step, + uint8_t salt) { + for (int y = 0; y < size.height(); ++y) { + for (int x = 0; x < size.width(); ++x) { + SCOPED_TRACE(testing::Message() << "x=" << x << " y=" << y); + EXPECT_EQ(data[x * x_step + y * y_step], + GetTestFrameValue(size, x, y, salt)); + } + } +} + +} // namespace + +// static +const gfx::Size FakeCameraStream::kMaxFrameSize = gfx::Size(100, 60); +// static +const gfx::Size FakeCameraStream::kDefaultFrameSize = gfx::Size(60, 40); + +// static +void FakeCameraStream::ValidateFrameData(const uint8_t* data, + gfx::Size size, + uint8_t salt) { + const uint8_t* y_plane = data; + { + SCOPED_TRACE("Y plane"); + ValidatePlane(y_plane, size, 1, size.width(), salt + kYPlaneSalt); + } + + gfx::Size uv_size(size.width() / 2, size.height() / 2); + const uint8_t* u_plane = y_plane + size.width() * size.height(); + { + SCOPED_TRACE("U plane"); + ValidatePlane(u_plane, uv_size, 1, uv_size.width(), salt + kUPlaneSalt); + } + + const uint8_t* v_plane = u_plane + uv_size.width() * uv_size.height(); + { + SCOPED_TRACE("V plane"); + ValidatePlane(v_plane, uv_size, 1, uv_size.width(), salt + kVPlaneSalt); + } +} + +struct FakeCameraStream::Buffer { + explicit Buffer(base::WritableSharedMemoryMapping mapping) + : mapping(std::move(mapping)), + release_fence_watch_controller(FROM_HERE) {} + + base::WritableSharedMemoryMapping mapping; + + // Frame is used by the client when the |release_fence| is not null. + zx::eventpair release_fence; + + base::MessagePumpForIO::ZxHandleWatchController + release_fence_watch_controller; +}; + +FakeCameraStream::FakeCameraStream() : binding_(this) {} +FakeCameraStream::~FakeCameraStream() = default; + +void FakeCameraStream::Bind( + fidl::InterfaceRequest<fuchsia::camera3::Stream> request) { + binding_.Bind(std::move(request)); +} + +void FakeCameraStream::SetFakeResolution(gfx::Size resolution) { + resolution_ = resolution; + resolution_update_ = + fuchsia::math::Size{resolution_.width(), resolution_.height()}; + SendResolution(); +} + +void FakeCameraStream::SetFakeOrientation( + fuchsia::camera3::Orientation orientation) { + orientation_ = orientation; + orientation_update_ = orientation; + SendOrientation(); +} + +bool FakeCameraStream::WaitBuffersAllocated() { + EXPECT_FALSE(wait_buffers_allocated_run_loop_); + + if (!buffers_.empty()) + return true; + + wait_buffers_allocated_run_loop_.emplace(); + wait_buffers_allocated_run_loop_->Run(); + wait_buffers_allocated_run_loop_.reset(); + + return !buffers_.empty(); +} + +bool FakeCameraStream::WaitFreeBuffer() { + EXPECT_FALSE(wait_free_buffer_run_loop_); + + if (num_used_buffers_ < buffers_.size()) + return true; + + wait_free_buffer_run_loop_.emplace(); + wait_free_buffer_run_loop_->Run(); + wait_free_buffer_run_loop_.reset(); + + return num_used_buffers_ < buffers_.size(); +} + +void FakeCameraStream::ProduceFrame(base::TimeTicks timestamp, uint8_t salt) { + ASSERT_LT(num_used_buffers_, buffers_.size()); + ASSERT_FALSE(next_frame_); + + size_t index = buffers_.size(); + for (size_t i = 0; i < buffers_.size(); ++i) { + if (!buffers_[i]->release_fence) { + index = i; + break; + } + } + EXPECT_LT(index, buffers_.size()); + + auto* buffer = buffers_[index].get(); + + gfx::Size coded_size((resolution_.width() + 1) & ~1, + (resolution_.height() + 1) & ~1); + + // Fill Y plane. + uint8_t* y_plane = reinterpret_cast<uint8_t*>(buffer->mapping.memory()); + size_t stride = kMaxFrameSize.width(); + FillPlane(y_plane, coded_size, /*x_step=*/1, /*y_step=*/stride, orientation_, + salt + kYPlaneSalt); + + // Fill UV plane. + gfx::Size uv_size(coded_size.width() / 2, coded_size.height() / 2); + uint8_t* uv_plane = y_plane + kMaxFrameSize.width() * kMaxFrameSize.height(); + FillPlane(uv_plane, uv_size, /*x_step=*/2, /*y_step=*/stride, orientation_, + salt + kUPlaneSalt); + FillPlane(uv_plane + 1, uv_size, /*x_step=*/2, /*y_step=*/stride, + orientation_, salt + kVPlaneSalt); + + // Create FrameInfo. + fuchsia::camera3::FrameInfo frame; + frame.frame_counter = frame_counter_++; + frame.buffer_index = 0; + frame.timestamp = timestamp.ToZxTime(); + EXPECT_EQ( + zx::eventpair::create(0u, &frame.release_fence, &buffer->release_fence), + ZX_OK); + + // Watch release fence to get notified when the frame is released. + base::MessageLoopCurrentForIO::Get()->WatchZxHandle( + buffer->release_fence.get(), /*persistent=*/false, + ZX_EVENTPAIR_PEER_CLOSED, &buffer->release_fence_watch_controller, this); + + num_used_buffers_++; + next_frame_ = std::move(frame); + SendNextFrame(); +} + +void FakeCameraStream::WatchResolution(WatchResolutionCallback callback) { + EXPECT_FALSE(watch_resolution_callback_); + watch_resolution_callback_ = std::move(callback); + SendResolution(); +} + +void FakeCameraStream::WatchOrientation(WatchOrientationCallback callback) { + EXPECT_FALSE(watch_orientation_callback_); + watch_orientation_callback_ = std::move(callback); + SendOrientation(); +} + +void FakeCameraStream::SetBufferCollection( + fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken> + token_handle) { + EXPECT_TRUE(token_handle); + + // Drop old buffers. + buffers_.clear(); + if (buffer_collection_) { + buffer_collection_->Close(); + buffer_collection_.Unbind(); + } + + // Use a SyncPtr to be able to wait for Sync() synchronously. + fuchsia::sysmem::BufferCollectionTokenSyncPtr token; + token.Bind(std::move(token_handle)); + + // Duplicate the token to access from the stream. + fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken> local_token; + zx_status_t status = + token->Duplicate(/*rights_attenuation_mask=*/0, local_token.NewRequest()); + EXPECT_EQ(status, ZX_OK); + + status = token->Sync(); + EXPECT_EQ(status, ZX_OK); + + // Return the token back to the client. + new_buffer_collection_token_ = token.Unbind(); + SendBufferCollection(); + + // Initialize the new collection using |local_token|. + auto allocator = base::fuchsia::ComponentContextForCurrentProcess() + ->svc() + ->Connect<fuchsia::sysmem::Allocator>(); + + allocator->BindSharedCollection(std::move(local_token), + buffer_collection_.NewRequest()); + EXPECT_EQ(status, ZX_OK); + + buffer_collection_.set_error_handler( + fit::bind_member(this, &FakeCameraStream::OnBufferCollectionError)); + + fuchsia::sysmem::BufferCollectionConstraints constraints; + constraints.usage.cpu = + fuchsia::sysmem::cpuUsageRead | fuchsia::sysmem::cpuUsageWrite; + + // The client is expected to request buffers it may need. We don't need to + // reserve any for the server side. + constraints.min_buffer_count_for_camping = 0; + + // Initialize image format. + constraints.image_format_constraints_count = 1; + constraints.image_format_constraints[0].pixel_format.type = + fuchsia::sysmem::PixelFormatType::NV12; + constraints.image_format_constraints[0].color_spaces_count = 1; + constraints.image_format_constraints[0].color_space[0].type = + fuchsia::sysmem::ColorSpaceType::REC601_NTSC; + constraints.image_format_constraints[0].required_max_coded_width = + kMaxFrameSize.width(); + constraints.image_format_constraints[0].required_max_coded_height = + kMaxFrameSize.height(); + + buffer_collection_->SetConstraints(/*has_constraints=*/true, + std::move(constraints)); + buffer_collection_->WaitForBuffersAllocated( + fit::bind_member(this, &FakeCameraStream::OnBufferCollectionAllocated)); +} + +void FakeCameraStream::WatchBufferCollection( + WatchBufferCollectionCallback callback) { + EXPECT_FALSE(watch_buffer_collection_callback_); + watch_buffer_collection_callback_ = std::move(callback); + SendBufferCollection(); +} + +void FakeCameraStream::GetNextFrame(GetNextFrameCallback callback) { + EXPECT_FALSE(get_next_frame_callback_); + get_next_frame_callback_ = std::move(callback); + SendNextFrame(); +} + +void FakeCameraStream::NotImplemented_(const std::string& name) { + ADD_FAILURE() << "NotImplemented_: " << name; +} + +void FakeCameraStream::OnBufferCollectionError(zx_status_t status) { + ADD_FAILURE() << "BufferCollection failed."; + if (wait_buffers_allocated_run_loop_) + wait_buffers_allocated_run_loop_->Quit(); + if (wait_free_buffer_run_loop_) + wait_free_buffer_run_loop_->Quit(); +} + +void FakeCameraStream::OnBufferCollectionAllocated( + zx_status_t status, + fuchsia::sysmem::BufferCollectionInfo_2 buffer_collection_info) { + if (status != ZX_OK) { + OnBufferCollectionError(status); + return; + } + + EXPECT_TRUE(buffers_.empty()); + EXPECT_TRUE(buffer_collection_info.settings.has_image_format_constraints); + EXPECT_EQ(buffer_collection_info.settings.image_format_constraints + .pixel_format.type, + fuchsia::sysmem::PixelFormatType::NV12); + + size_t buffer_size = + buffer_collection_info.settings.buffer_settings.size_bytes; + for (size_t i = 0; i < buffer_collection_info.buffer_count; ++i) { + auto& buffer = buffer_collection_info.buffers[i]; + EXPECT_EQ(buffer.vmo_usable_start, 0U); + auto region = base::WritableSharedMemoryRegion::Deserialize( + base::subtle::PlatformSharedMemoryRegion::Take( + std::move(buffer.vmo), + base::subtle::PlatformSharedMemoryRegion::Mode::kWritable, + buffer_size, base::UnguessableToken::Create())); + auto mapping = region.Map(); + EXPECT_TRUE(mapping.IsValid()); + buffers_.push_back(std::make_unique<Buffer>(std::move(mapping))); + } + + if (wait_buffers_allocated_run_loop_) + wait_buffers_allocated_run_loop_->Quit(); +} + +void FakeCameraStream::SendResolution() { + if (!watch_resolution_callback_ || !resolution_update_) + return; + watch_resolution_callback_(resolution_update_.value()); + watch_resolution_callback_ = {}; + resolution_update_.reset(); +} + +void FakeCameraStream::SendOrientation() { + if (!watch_orientation_callback_ || !orientation_update_) + return; + watch_orientation_callback_(orientation_update_.value()); + watch_orientation_callback_ = {}; + orientation_update_.reset(); +} + +void FakeCameraStream::SendBufferCollection() { + if (!watch_buffer_collection_callback_ || !new_buffer_collection_token_) + return; + watch_buffer_collection_callback_( + std::move(new_buffer_collection_token_.value())); + watch_buffer_collection_callback_ = {}; + new_buffer_collection_token_.reset(); +} + +void FakeCameraStream::SendNextFrame() { + if (!get_next_frame_callback_ || !next_frame_) + return; + get_next_frame_callback_(std::move(next_frame_.value())); + get_next_frame_callback_ = {}; + next_frame_.reset(); +} + +void FakeCameraStream::OnZxHandleSignalled(zx_handle_t handle, + zx_signals_t signals) { + EXPECT_EQ(signals, ZX_EVENTPAIR_PEER_CLOSED); + + // Find the buffer that corresponds to the |handle|. + size_t index = buffers_.size(); + for (size_t i = 0; i < buffers_.size(); ++i) { + if (buffers_[i]->release_fence.get() == handle) { + index = i; + break; + } + } + ASSERT_LT(index, buffers_.size()); + buffers_[index]->release_fence = {}; + buffers_[index]->release_fence_watch_controller.StopWatchingZxHandle(); + num_used_buffers_--; + + if (wait_free_buffer_run_loop_) + wait_free_buffer_run_loop_->Quit(); +} +FakeCameraDevice::FakeCameraDevice(FakeCameraStream* stream) + : binding_(this), stream_(stream) {} + +FakeCameraDevice::~FakeCameraDevice() = default; + +void FakeCameraDevice::Bind( + fidl::InterfaceRequest<fuchsia::camera3::Device> request) { + binding_.Bind(std::move(request)); +} + +void FakeCameraDevice::GetIdentifier(GetIdentifierCallback callback) { + callback("Fake Camera"); +} + +void FakeCameraDevice::GetConfigurations(GetConfigurationsCallback callback) { + std::vector<fuchsia::camera3::Configuration> configurations(1); + configurations[0].streams.resize(1); + configurations[0].streams[0].frame_rate.numerator = 30; + configurations[0].streams[0].frame_rate.denominator = 1; + configurations[0].streams[0].image_format.pixel_format.type = + fuchsia::sysmem::PixelFormatType::NV12; + configurations[0].streams[0].image_format.coded_width = 640; + configurations[0].streams[0].image_format.coded_height = 480; + configurations[0].streams[0].image_format.bytes_per_row = 640; + callback(std::move(configurations)); +} + +void FakeCameraDevice::ConnectToStream( + uint32_t index, + fidl::InterfaceRequest<fuchsia::camera3::Stream> request) { + EXPECT_EQ(index, 0U); + stream_->Bind(std::move(request)); +} + +void FakeCameraDevice::NotImplemented_(const std::string& name) { + ADD_FAILURE() << "NotImplemented_: " << name; +} + +} // namespace media \ No newline at end of file
diff --git a/media/fuchsia/camera/fake_fuchsia_camera.h b/media/fuchsia/camera/fake_fuchsia_camera.h new file mode 100644 index 0000000..591082d --- /dev/null +++ b/media/fuchsia/camera/fake_fuchsia_camera.h
@@ -0,0 +1,154 @@ +// 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 MEDIA_FUCHSIA_CAMERA_FAKE_FUCHSIA_CAMERA_H_ +#define MEDIA_FUCHSIA_CAMERA_FAKE_FUCHSIA_CAMERA_H_ + +#include <fuchsia/camera3/cpp/fidl.h> +#include <fuchsia/camera3/cpp/fidl_test_base.h> +#include <lib/fidl/cpp/binding.h> + +#include <vector> + +#include "base/message_loop/message_pump_for_io.h" +#include "base/optional.h" +#include "base/run_loop.h" +#include "ui/gfx/geometry/size.h" + +namespace media { + +class FakeCameraStream : public fuchsia::camera3::testing::Stream_TestBase, + public base::MessagePumpForIO::ZxHandleWatcher { + public: + static const gfx::Size kMaxFrameSize; + static const gfx::Size kDefaultFrameSize; + + // Verifies that the I420 image stored at |data| matches the frame produced + // by ProduceFrame(). + static void ValidateFrameData(const uint8_t* data, + gfx::Size size, + uint8_t salt); + + FakeCameraStream(); + ~FakeCameraStream() final; + + FakeCameraStream(const FakeCameraStream&) = delete; + FakeCameraStream& operator=(const FakeCameraStream&) = delete; + + void Bind(fidl::InterfaceRequest<fuchsia::camera3::Stream> request); + + void SetFakeResolution(gfx::Size resolution); + void SetFakeOrientation(fuchsia::camera3::Orientation orientation); + + // Waits for the buffer collection to be allocated. Returns true if the buffer + // collection was allocated successfully. + bool WaitBuffersAllocated(); + + // Waits until there is at least one free buffer that can be used for the next + // frame. + bool WaitFreeBuffer(); + + void ProduceFrame(base::TimeTicks timestamp, uint8_t salt); + + private: + struct Buffer; + + // fuchsia::camera3::Stream implementation. + void WatchResolution(WatchResolutionCallback callback) final; + void WatchOrientation(WatchOrientationCallback callback) final; + void SetBufferCollection( + fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken> + token_handle) final; + void WatchBufferCollection(WatchBufferCollectionCallback callback) final; + void GetNextFrame(GetNextFrameCallback callback) final; + + // fuchsia::camera3::testing::Stream_TestBase override. + void NotImplemented_(const std::string& name) override; + + void OnBufferCollectionError(zx_status_t status); + + void OnBufferCollectionAllocated( + zx_status_t status, + fuchsia::sysmem::BufferCollectionInfo_2 buffer_collection_info); + + // Calls callback for the pending WatchResolution() if the call is pending and + // resolution has been updated. + void SendResolution(); + + // Calls callback for the pending WatchOrientation() if the call is pending + // and orientation has been updated. + void SendOrientation(); + + // Calls callback for the pending WatchBufferCollection() if we have a new + // token and the call is pending. + void SendBufferCollection(); + + // Calls callback for the pending GetNextFrame() if we have a new frame and + // the call is pending. + void SendNextFrame(); + + // ZxHandleWatcher interface. Used to wait for frame release_fences to get + // notified when the client releases a buffer. + void OnZxHandleSignalled(zx_handle_t handle, zx_signals_t signals) final; + + fidl::Binding<fuchsia::camera3::Stream> binding_; + + gfx::Size resolution_ = kDefaultFrameSize; + fuchsia::camera3::Orientation orientation_ = + fuchsia::camera3::Orientation::UP; + + base::Optional<fuchsia::math::Size> resolution_update_ = fuchsia::math::Size{ + kDefaultFrameSize.width(), kDefaultFrameSize.height()}; + WatchResolutionCallback watch_resolution_callback_; + + base::Optional<fuchsia::camera3::Orientation> orientation_update_ = + fuchsia::camera3::Orientation::UP; + WatchOrientationCallback watch_orientation_callback_; + + base::Optional<fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken>> + new_buffer_collection_token_; + WatchBufferCollectionCallback watch_buffer_collection_callback_; + + base::Optional<fuchsia::camera3::FrameInfo> next_frame_; + GetNextFrameCallback get_next_frame_callback_; + + fuchsia::sysmem::BufferCollectionPtr buffer_collection_; + + base::Optional<base::RunLoop> wait_buffers_allocated_run_loop_; + base::Optional<base::RunLoop> wait_free_buffer_run_loop_; + + std::vector<std::unique_ptr<Buffer>> buffers_; + size_t num_used_buffers_ = 0; + + size_t frame_counter_ = 0; +}; + +class FakeCameraDevice : public fuchsia::camera3::testing::Device_TestBase { + public: + explicit FakeCameraDevice(FakeCameraStream* stream); + ~FakeCameraDevice() final; + + FakeCameraDevice(const FakeCameraDevice&) = delete; + FakeCameraDevice& operator=(const FakeCameraDevice&) = delete; + + void Bind(fidl::InterfaceRequest<fuchsia::camera3::Device> request); + + private: + // fuchsia::camera3::Device implementation. + void GetIdentifier(GetIdentifierCallback callback) final; + void GetConfigurations(GetConfigurationsCallback callback) final; + void ConnectToStream( + uint32_t index, + fidl::InterfaceRequest<fuchsia::camera3::Stream> request) final; + + // fuchsia::camera3::testing::Device_TestBase override. + void NotImplemented_(const std::string& name) override; + + fidl::Binding<fuchsia::camera3::Device> binding_; + FakeCameraStream* const stream_; +}; + +} // namespace media + +#endif // MEDIA_FUCHSIA_CAMERA_FAKE_FUCHSIA_CAMERA_H_
diff --git a/media/gpu/windows/d3d11_video_decoder.cc b/media/gpu/windows/d3d11_video_decoder.cc index 17ad1be..3ba6d9b 100644 --- a/media/gpu/windows/d3d11_video_decoder.cc +++ b/media/gpu/windows/d3d11_video_decoder.cc
@@ -19,7 +19,6 @@ #include "base/threading/sequenced_task_runner_handle.h" #include "base/trace_event/trace_event.h" #include "media/base/bind_to_current_loop.h" -#include "media/base/cdm_context.h" #include "media/base/decoder_buffer.h" #include "media/base/media_log.h" #include "media/base/media_switches.h" @@ -191,7 +190,7 @@ CdmContext* /* cdm_context */, InitCB init_cb, const OutputCB& output_cb, - const WaitingCB& waiting_cb) { + const WaitingCB& /* waiting_cb */) { TRACE_EVENT0("gpu", "D3D11VideoDecoder::Initialize"); if (already_initialized_) AddLifetimeProgressionStage(D3D11LifetimeProgression::kPlaybackSucceeded); @@ -199,14 +198,12 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(output_cb); - DCHECK(waiting_cb); state_ = State::kInitializing; config_ = config; init_cb_ = std::move(init_cb); output_cb_ = output_cb; - waiting_cb_ = waiting_cb; // Verify that |config| matches one of the supported configurations. This // helps us skip configs that are supported by the VDA but not us, since @@ -225,6 +222,11 @@ return; } + if (config.is_encrypted()) { + NotifyError("D3D11VideoDecoder does not support encrypted stream"); + return; + } + // Initialize the video decoder. // Note that we assume that this is the ANGLE device, since we don't implement @@ -333,12 +335,6 @@ return; } - if (config.is_encrypted() && dec_config.guidConfigBitstreamEncryption != - D3D11_DECODER_ENCRYPTION_HW_CENC) { - // For encrypted media, it has to use HW CENC decoder config. - continue; - } - if (config.codec() == kCodecVP9 && dec_config.ConfigBitstreamRaw == 1) { // DXVA VP9 specification mentions ConfigBitstreamRaw "shall be 1". found = true; @@ -364,12 +360,6 @@ return; } - // Ensure that if we are encrypted, that we have a CDM. - if (config_.is_encrypted()) { - NotifyError("Encrypted stream not supported"); - return; - } - hr = InitializeAcceleratedDecoder(config, video_decoder); if (!SUCCEEDED(hr)) { @@ -574,9 +564,8 @@ } CreatePictureBuffers(); } else if (result == media::AcceleratedVideoDecoder::kTryAgain) { - state_ = State::kWaitingForNewKey; - waiting_cb_.Run(WaitingReason::kNoDecryptionKey); - // Another DoDecode() task would be posted in OnCdmContextEvent(). + LOG(ERROR) << "Try again is not supported"; + NotifyError("Try again is not supported"); return; } else { LOG(ERROR) << "VDA Error " << result; @@ -606,21 +595,6 @@ // TODO(liberato): how do we signal an error? accelerated_video_decoder_->Reset(); - if (state_ == State::kWaitingForReset && config_.is_encrypted()) { - // On a hardware context loss event, a new swap chain has to be created (in - // the compositor). By clearing the picture buffers, next DoDecode() call - // will create a new texture. This makes the compositor to create a new swap - // chain. - // More detailed explanation at crbug.com/858286 - picture_buffers_.clear(); - } - - // Transition out of kWaitingForNewKey since the new buffer could be clear or - // have a different key ID. Transition out of kWaitingForReset since reset - // just happened. - if (state_ == State::kWaitingForNewKey || state_ == State::kWaitingForReset) - state_ = State::kRunning; - std::move(closure).Run(); } @@ -794,47 +768,11 @@ frame->metadata()->SetBoolean(VideoFrameMetadata::ALLOW_OVERLAY, allow_overlay); - if (config_.is_encrypted()) { - frame->metadata()->SetBoolean(VideoFrameMetadata::PROTECTED_VIDEO, true); - frame->metadata()->SetBoolean(VideoFrameMetadata::HW_PROTECTED, true); - } - frame->set_color_space(output_color_space); output_cb_.Run(frame); return true; } -void D3D11VideoDecoder::OnCdmContextEvent(CdmContext::Event event) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DVLOG(1) << __func__ << ": event = " << static_cast<int>(event); - - if (state_ == State::kInitializing || state_ == State::kError) { - DVLOG(1) << "Do nothing in " << static_cast<int>(state_) << " state."; - return; - } - - switch (event) { - case CdmContext::Event::kHasAdditionalUsableKey: - // Note that this event may happen before DoDecode() because the key - // acquisition stack runs independently of the media decoding stack. - // So if this isn't in kWaitingForNewKey state no "resuming" is - // required therefore no special action taken here. - if (state_ != State::kWaitingForNewKey) - return; - - state_ = State::kRunning; - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(&D3D11VideoDecoder::DoDecode, - weak_factory_.GetWeakPtr())); - return; - - case CdmContext::Event::kHardwareContextLost: - state_ = State::kWaitingForReset; - waiting_cb_.Run(WaitingReason::kDecoderStateLost); - return; - } -} - // TODO(tmathmeyer) eventually have this take a Status and pass it through // to each of the callbacks. void D3D11VideoDecoder::NotifyError(const char* reason) { @@ -938,10 +876,6 @@ return {}; } - const bool allow_encrypted = - (usable_feature_level > D3D_FEATURE_LEVEL_11_0) && - base::FeatureList::IsEnabled(kHardwareSecureDecryption); - std::vector<SupportedVideoDecoderConfig> configs; // VP9 has no default resolutions since it may not even be supported. ResolutionPair max_h264_resolutions(gfx::Size(1920, 1088), gfx::Size()); @@ -964,7 +898,7 @@ 1), // profile_max min_resolution, // coded_size_min max_h264_resolutions.first, // coded_size_max - allow_encrypted, // allow_encrypted + false, // allow_encrypted false)); // require_encrypted configs.push_back(SupportedVideoDecoderConfig( static_cast<VideoCodecProfile>(H264PROFILE_HIGH10PROFILE + @@ -972,7 +906,7 @@ H264PROFILE_MAX, // profile_max min_resolution, // coded_size_min max_h264_resolutions.first, // coded_size_max - allow_encrypted, // allow_encrypted + false, // allow_encrypted false)); // require_encrypted // portrait @@ -982,7 +916,7 @@ 1), // profile_max min_resolution, // coded_size_min max_h264_resolutions.second, // coded_size_max - allow_encrypted, // allow_encrypted + false, // allow_encrypted false)); // require_encrypted configs.push_back(SupportedVideoDecoderConfig( static_cast<VideoCodecProfile>(H264PROFILE_HIGH10PROFILE + @@ -990,7 +924,7 @@ H264PROFILE_MAX, // profile_max min_resolution, // coded_size_min max_h264_resolutions.second, // coded_size_max - allow_encrypted, // allow_encrypted + false, // allow_encrypted false)); // require_encrypted } @@ -1003,7 +937,7 @@ VP9PROFILE_PROFILE0, // profile_max min_resolution, // coded_size_min max_vp9_profile0_resolutions.first, // coded_size_max - allow_encrypted, // allow_encrypted + false, // allow_encrypted false)); // require_encrypted // portrait configs.push_back(SupportedVideoDecoderConfig( @@ -1011,7 +945,7 @@ VP9PROFILE_PROFILE0, // profile_max min_resolution, // coded_size_min max_vp9_profile0_resolutions.second, // coded_size_max - allow_encrypted, // allow_encrypted + false, // allow_encrypted false)); // require_encrypted } @@ -1023,7 +957,7 @@ VP9PROFILE_PROFILE2, // profile_max min_resolution, // coded_size_min max_vp9_profile2_resolutions.first, // coded_size_max - allow_encrypted, // allow_encrypted + false, // allow_encrypted false)); // require_encrypted // portrait configs.push_back(SupportedVideoDecoderConfig( @@ -1031,12 +965,12 @@ VP9PROFILE_PROFILE2, // profile_max min_resolution, // coded_size_min max_vp9_profile2_resolutions.second, // coded_size_max - allow_encrypted, // allow_encrypted + false, // allow_encrypted false)); // require_encrypted } } - // TODO(liberato): Should we separate out h264, vp9, and encrypted? + // TODO(liberato): Should we separate out h264 and vp9? UMA_HISTOGRAM_ENUMERATION(uma_name, NotSupportedReason::kVideoIsSupported); return configs;
diff --git a/media/gpu/windows/d3d11_video_decoder.h b/media/gpu/windows/d3d11_video_decoder.h index ba8f7164..d9ba26ab 100644 --- a/media/gpu/windows/d3d11_video_decoder.h +++ b/media/gpu/windows/d3d11_video_decoder.h
@@ -200,25 +200,10 @@ // creation is pending. kRunning, - // The decoder cannot make progress because it doesn't have the key to - // decrypt the buffer. Waiting for a new key to be available. - // This should only be transitioned from kRunning, and should only - // transition to kRunning or kWaitingForReset. - kWaitingForNewKey, - - // The decoder cannot make progress because it's waiting for a Reset(). This - // could happen as a result of CdmContext hardware context loss. This should - // only be transitioned from kRunning or kWaitingForNewKey, and should only - // transition to kRunning. - kWaitingForReset, - // A fatal error occurred. A terminal state. kError, }; - // Callback to notify that new CdmContext event is available. - void OnCdmContextEvent(CdmContext::Event event); - // Enter the kError state. This will fail any pending |init_cb_| and / or // pending decode as well. void NotifyError(const char* reason); @@ -242,7 +227,6 @@ VideoDecoderConfig config_; InitCB init_cb_; OutputCB output_cb_; - WaitingCB waiting_cb_; // Callback to be used as a release CB for VideoFrames. Be sure to // BindToCurrentLoop the closure that it takes. @@ -274,9 +258,6 @@ DecodeCB current_decode_cb_; base::TimeDelta current_timestamp_; - // Callback registration to keep the new key callback registered. - std::unique_ptr<CallbackRegistration> new_key_callback_registration_; - // Must be called on the gpu main thread. So, don't call it from here, // since we don't know what thread we're on. base::RepeatingCallback<gpu::CommandBufferStub*()> get_stub_cb_;
diff --git a/media/renderers/paint_canvas_video_renderer.cc b/media/renderers/paint_canvas_video_renderer.cc index 90ce1c9b..5eaa952 100644 --- a/media/renderers/paint_canvas_video_renderer.cc +++ b/media/renderers/paint_canvas_video_renderer.cc
@@ -255,18 +255,6 @@ return SynchronizeAndImportMailbox(gl, mailbox_holder.sync_token, *mailbox); } -// TODO(crbug.com/1023270): Remove this function once we're no longer relying on -// texture ids for Mailbox access as that is only supported on -// RasterImplementationGLES. -GLuint ImportVideoFrameSingleMailbox(gpu::raster::RasterInterface* ri, - VideoFrame* video_frame, - gpu::Mailbox* mailbox) { - const gpu::MailboxHolder& mailbox_holder = - GetVideoFrameMailboxHolder(video_frame); - *mailbox = mailbox_holder.mailbox; - return SynchronizeAndImportMailbox(ri, mailbox_holder.sync_token, *mailbox); -} - gpu::Mailbox SynchronizeVideoFrameSingleMailbox( gpu::raster::RasterInterface* ri, VideoFrame* video_frame) { @@ -1340,13 +1328,8 @@ destination_gl->GenUnverifiedSyncTokenCHROMIUM( mailbox_holder.sync_token.GetData()); - source_ri->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); - - uint32_t shared_texture = - source_ri->CreateAndConsumeForGpuRaster(mailbox_holder.mailbox); - - if (!PrepareVideoFrame(video_frame, raster_context_provider, target, - shared_texture)) { + if (!PrepareVideoFrame(video_frame, raster_context_provider, + mailbox_holder)) { return false; } @@ -1623,9 +1606,7 @@ // We need a new texture ID because skia will destroy the previous one with // the SkImage. texture_ownership_in_skia = false; - source_texture = - SynchronizeAndImportMailbox(raster_context_provider->RasterInterface(), - gpu::SyncToken(), source_mailbox); + source_texture = 0; return true; } @@ -1653,17 +1634,13 @@ auto* ri = raster_context_provider->RasterInterface(); DCHECK(ri); - sk_sp<SkImage> source_image; - if (allow_wrap_texture && video_frame->NumTextures() == 1) { cache_.emplace(video_frame->unique_id()); - cache_->source_texture = ImportVideoFrameSingleMailbox( - ri, video_frame.get(), &cache_->source_mailbox); + const gpu::MailboxHolder& holder = + GetVideoFrameMailboxHolder(video_frame.get()); + cache_->source_mailbox = holder.mailbox; + ri->WaitSyncTokenCHROMIUM(holder.sync_token.GetConstData()); cache_->wraps_video_frame_texture = true; - source_image = - WrapGLTexture(video_frame->mailbox_holder(0).texture_target, - cache_->source_texture, video_frame->coded_size(), - video_frame->ColorSpace(), raster_context_provider); } else { if (cache_ && cache_->raster_context_provider == raster_context_provider && @@ -1674,11 +1651,20 @@ } else { cache_.emplace(video_frame->unique_id()); auto* sii = raster_context_provider->SharedImageInterface(); + + // TODO(nazabris): Sort out what to do when GLES2 is needed but the + // cached shared image is created without it. + uint32_t flags = + gpu::SHARED_IMAGE_USAGE_GLES2 | gpu::SHARED_IMAGE_USAGE_RASTER; + if (raster_context_provider->ContextCapabilities() + .supports_oop_raster) { + flags |= gpu::SHARED_IMAGE_USAGE_OOP_RASTERIZATION; + } cache_->source_mailbox = sii->CreateSharedImage( viz::ResourceFormat::RGBA_8888, video_frame->coded_size(), - gfx::ColorSpace(), gpu::SHARED_IMAGE_USAGE_GLES2); - cache_->source_texture = SynchronizeAndImportMailbox( - ri, sii->GenUnverifiedSyncToken(), cache_->source_mailbox); + gfx::ColorSpace(), flags); + ri->WaitSyncTokenCHROMIUM( + sii->GenUnverifiedSyncToken().GetConstData()); } DCHECK(!cache_->texture_ownership_in_skia); @@ -1689,19 +1675,31 @@ frame_mailbox, cache_->source_mailbox, GL_TEXTURE_2D, 0, 0, 0, 0, video_frame->coded_size().width(), video_frame->coded_size().height(), GL_FALSE, GL_FALSE); - source_image = WrapGLTexture( - GL_TEXTURE_2D, cache_->source_texture, video_frame->coded_size(), - gfx::ColorSpace(), raster_context_provider); } else { - ScopedSharedImageAccess dest_access( - ri, cache_->source_texture, cache_->source_mailbox, - GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM); - source_image = NewSkImageFromVideoFrameYUVTexturesWithExternalBackend( - video_frame.get(), raster_context_provider, GL_TEXTURE_2D, - cache_->source_texture); + gpu::MailboxHolder dest_holder{cache_->source_mailbox, + gpu::SyncToken(), GL_TEXTURE_2D}; + ConvertFromVideoFrameYUV(video_frame.get(), raster_context_provider, + dest_holder); } raster_context_provider->GrContext()->flush(); } + + // TODO(jochin): Don't always generate SkImage here. + DCHECK(cache_->source_texture == 0); + cache_->source_texture = + ri->CreateAndConsumeForGpuRaster(cache_->source_mailbox); + + // TODO(nazabris): Handle scoped access correctly. This follows the + // current pattern but is most likely bugged. Access should last for the + // lifetime of the SkImage. + ScopedSharedImageAccess(ri, cache_->source_texture, + cache_->source_mailbox); + auto source_image = + WrapGLTexture(cache_->wraps_video_frame_texture + ? video_frame->mailbox_holder(0).texture_target + : GL_TEXTURE_2D, + cache_->source_texture, video_frame->coded_size(), + video_frame->ColorSpace(), raster_context_provider); if (!source_image) { // Couldn't create the SkImage. cache_.reset(); @@ -1759,51 +1757,21 @@ bool PaintCanvasVideoRenderer::PrepareVideoFrame( scoped_refptr<VideoFrame> video_frame, viz::RasterContextProvider* raster_context_provider, - unsigned int textureTarget, - unsigned int texture) { - cache_.emplace(video_frame->unique_id()); - auto paint_image_builder = - cc::PaintImageBuilder::WithDefault() - .set_id(renderer_stable_id_) - .set_animation_type(cc::PaintImage::AnimationType::VIDEO) - .set_completion_state(cc::PaintImage::CompletionState::DONE); - + const gpu::MailboxHolder& dest_holder) { // Generate a new image. // Note: Skia will hold onto |video_frame| via |video_generator| only when // |video_frame| is software. // Holding |video_frame| longer than this call when using GPUVideoDecoder // could cause problems since the pool of VideoFrames has a fixed size. if (video_frame->HasTextures()) { - DCHECK(raster_context_provider); - DCHECK(raster_context_provider->GrContext()); - DCHECK(raster_context_provider->RasterInterface()); - sk_sp<SkImage> source_image; if (video_frame->NumTextures() > 1) { - source_image = NewSkImageFromVideoFrameYUVTexturesWithExternalBackend( - video_frame.get(), raster_context_provider, textureTarget, texture); - if (!source_image) { - // Couldn't create the SkImage. - cache_.reset(); - return false; - } + ConvertFromVideoFrameYUV(video_frame.get(), raster_context_provider, + dest_holder); } else { // We don't support Android now. - cache_.reset(); return false; } - cache_->coded_size = video_frame->coded_size(); - cache_->visible_rect = video_frame->visible_rect(); - sk_sp<SkImage> sk_image = - source_image->makeSubset(gfx::RectToSkIRect(cache_->visible_rect)); - paint_image_builder.set_texture_backing( - sk_sp<VideoTextureBacking>( - new VideoTextureBacking(std::move(sk_image))), - cc::PaintImage::GetNextContentId()); - } else { - paint_image_builder.set_paint_image_generator( - sk_make_sp<VideoImageGenerator>(video_frame)); } - cache_deleting_timer_.Reset(); return true; }
diff --git a/media/renderers/paint_canvas_video_renderer.h b/media/renderers/paint_canvas_video_renderer.h index d8ca22e3..d5b1a141 100644 --- a/media/renderers/paint_canvas_video_renderer.h +++ b/media/renderers/paint_canvas_video_renderer.h
@@ -245,8 +245,7 @@ bool PrepareVideoFrame(scoped_refptr<VideoFrame> video_frame, viz::RasterContextProvider* raster_context_provider, - unsigned int textureTarget, - unsigned int texture); + const gpu::MailboxHolder& dest_holder); base::Optional<Cache> cache_;
diff --git a/media/renderers/yuv_util.cc b/media/renderers/yuv_util.cc index b34ad270..3a66d63 100644 --- a/media/renderers/yuv_util.cc +++ b/media/renderers/yuv_util.cc
@@ -9,6 +9,7 @@ #include "components/viz/common/gpu/raster_context_provider.h" #include "gpu/GLES2/gl2extchromium.h" #include "gpu/command_buffer/client/raster_interface.h" +#include "gpu/command_buffer/common/mailbox_holder.h" #include "media/base/video_frame.h" #include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/gpu/GrContext.h" @@ -17,7 +18,27 @@ namespace { +static constexpr size_t kNumNV12Planes = 2; static constexpr size_t kNumYUVPlanes = 3; +using YUVMailboxes = std::array<gpu::MailboxHolder, kNumYUVPlanes>; + +YUVMailboxes GetYUVMailboxes(const VideoFrame* video_frame, + gpu::raster::RasterInterface* ri) { + YUVMailboxes mailboxes; + + for (size_t i = 0; i < video_frame->NumTextures(); ++i) { + mailboxes[i] = video_frame->mailbox_holder(i); + DCHECK(mailboxes[i].texture_target == GL_TEXTURE_2D || + mailboxes[i].texture_target == GL_TEXTURE_EXTERNAL_OES || + mailboxes[i].texture_target == GL_TEXTURE_RECTANGLE_ARB) + << "Unsupported texture target " << std::hex << std::showbase + << mailboxes[i].texture_target; + ri->WaitSyncTokenCHROMIUM(mailboxes[i].sync_token.GetConstData()); + } + + return mailboxes; +} + struct YUVPlaneTextureInfo { GrGLTextureInfo texture = {0, 0}; bool is_shared_image = false; @@ -27,31 +48,24 @@ YUVTexturesInfo GetYUVTexturesInfo( const VideoFrame* video_frame, viz::RasterContextProvider* raster_context_provider) { - YUVTexturesInfo yuv_textures_info; - gpu::raster::RasterInterface* ri = raster_context_provider->RasterInterface(); DCHECK(ri); + YUVMailboxes mailboxes = GetYUVMailboxes(video_frame, ri); + YUVTexturesInfo yuv_textures_info; + GrGLenum skia_texture_format = video_frame->format() == PIXEL_FORMAT_NV12 ? GL_RGB8 : GL_R8_EXT; for (size_t i = 0; i < video_frame->NumTextures(); ++i) { - // Get the texture from the mailbox and wrap it in a GrTexture. - const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(i); - DCHECK(mailbox_holder.texture_target == GL_TEXTURE_2D || - mailbox_holder.texture_target == GL_TEXTURE_EXTERNAL_OES || - mailbox_holder.texture_target == GL_TEXTURE_RECTANGLE_ARB) - << "Unsupported texture target " << std::hex << std::showbase - << mailbox_holder.texture_target; - ri->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); yuv_textures_info[i].texture.fID = - ri->CreateAndConsumeForGpuRaster(mailbox_holder.mailbox); - if (mailbox_holder.mailbox.IsSharedImage()) { + ri->CreateAndConsumeForGpuRaster(mailboxes[i].mailbox); + if (mailboxes[i].mailbox.IsSharedImage()) { yuv_textures_info[i].is_shared_image = true; ri->BeginSharedImageAccessDirectCHROMIUM( yuv_textures_info[i].texture.fID, GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM); } - yuv_textures_info[i].texture.fTarget = mailbox_holder.texture_target; + yuv_textures_info[i].texture.fTarget = mailboxes[i].texture_target; yuv_textures_info[i].texture.fFormat = skia_texture_format; } @@ -71,17 +85,67 @@ } } -} // namespace - -void ConvertFromVideoFrameYUVTextures( +void ConvertFromVideoFrameYUVWithGrContext( const VideoFrame* video_frame, viz::RasterContextProvider* raster_context_provider, - unsigned int texture_out_target, - unsigned int texture_out_id) { - // Let the SkImage fall out of scope and track the result texture using - // texture_out_id. + const gpu::MailboxHolder& dest_mailbox_holder) { + gpu::raster::RasterInterface* ri = raster_context_provider->RasterInterface(); + DCHECK(ri); + ri->WaitSyncTokenCHROMIUM(dest_mailbox_holder.sync_token.GetConstData()); + GLuint dest_tex_id = + ri->CreateAndConsumeForGpuRaster(dest_mailbox_holder.mailbox); + if (dest_mailbox_holder.mailbox.IsSharedImage()) { + ri->BeginSharedImageAccessDirectCHROMIUM( + dest_tex_id, GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM); + } + // Let the SkImage fall out of scope and track the result using dest_tex_id NewSkImageFromVideoFrameYUVTexturesWithExternalBackend( - video_frame, raster_context_provider, texture_out_target, texture_out_id); + video_frame, raster_context_provider, dest_mailbox_holder.texture_target, + dest_tex_id); + if (dest_mailbox_holder.mailbox.IsSharedImage()) + ri->EndSharedImageAccessDirectCHROMIUM(dest_tex_id); + ri->DeleteGpuRasterTexture(dest_tex_id); +} + +SkYUVColorSpace ColorSpaceToSkYUVColorSpace( + const gfx::ColorSpace& color_space) { + // TODO(hubbe): This should really default to rec709. + // https://crbug.com/828599 + SkYUVColorSpace sk_color_space = kRec601_SkYUVColorSpace; + color_space.ToSkYUVColorSpace(&sk_color_space); + return sk_color_space; +} + +} // namespace + +void ConvertFromVideoFrameYUV( + const VideoFrame* video_frame, + viz::RasterContextProvider* raster_context_provider, + const gpu::MailboxHolder& dest_mailbox_holder) { + DCHECK(raster_context_provider); + if (raster_context_provider->GrContext()) { + ConvertFromVideoFrameYUVWithGrContext(video_frame, raster_context_provider, + dest_mailbox_holder); + return; + } + + auto* ri = raster_context_provider->RasterInterface(); + DCHECK(ri); + ri->WaitSyncTokenCHROMIUM(dest_mailbox_holder.sync_token.GetConstData()); + YUVMailboxes mailboxes = GetYUVMailboxes(video_frame, ri); + SkYUVColorSpace color_space = + ColorSpaceToSkYUVColorSpace(video_frame->ColorSpace()); + if (video_frame->format() == PIXEL_FORMAT_I420) { + DCHECK_EQ(video_frame->NumTextures(), kNumYUVPlanes); + ri->ConvertYUVMailboxesToRGB(dest_mailbox_holder.mailbox, color_space, + mailboxes[0].mailbox, mailboxes[1].mailbox, + mailboxes[2].mailbox); + } else { + DCHECK_EQ(video_frame->format(), PIXEL_FORMAT_NV12); + DCHECK_EQ(video_frame->NumTextures(), kNumNV12Planes); + ri->ConvertNV12MailboxesToRGB(dest_mailbox_holder.mailbox, color_space, + mailboxes[0].mailbox, mailboxes[1].mailbox); + } } sk_sp<SkImage> NewSkImageFromVideoFrameYUVTexturesWithExternalBackend( @@ -137,10 +201,7 @@ VideoPixelFormat video_format, GrBackendTexture* yuv_textures, const GrBackendTexture& result_texture) { - // TODO(hubbe): This should really default to rec709. - // https://crbug.com/828599 - SkYUVColorSpace color_space = kRec601_SkYUVColorSpace; - video_color_space.ToSkYUVColorSpace(&color_space); + SkYUVColorSpace color_space = ColorSpaceToSkYUVColorSpace(video_color_space); switch (video_format) { case PIXEL_FORMAT_NV12:
diff --git a/media/renderers/yuv_util.h b/media/renderers/yuv_util.h index 6cf2368..e8fe451 100644 --- a/media/renderers/yuv_util.h +++ b/media/renderers/yuv_util.h
@@ -15,6 +15,10 @@ class GrContext; class SkImage; +namespace gpu { +struct MailboxHolder; +} + namespace viz { class RasterContextProvider; } // namespace viz @@ -23,14 +27,13 @@ class VideoFrame; -// Converts a YUV video frame to RGB format and stored the results in the GL -// texture with ID |texture_out_id|. The caller of this function maintains -// ownership of the out texture. -MEDIA_EXPORT void ConvertFromVideoFrameYUVTextures( +// Converts a YUV video frame to RGB format and stores the results in the +// provided mailbox. The caller of this function maintains ownership of the +// mailbox. +MEDIA_EXPORT void ConvertFromVideoFrameYUV( const VideoFrame* video_frame, viz::RasterContextProvider* raster_context_provider, - unsigned int texture_out_target, - unsigned int texture_out_id); + const gpu::MailboxHolder& dest_mailbox_holder); MEDIA_EXPORT sk_sp<SkImage> NewSkImageFromVideoFrameYUVTexturesWithExternalBackend(
diff --git a/net/disk_cache/disk_cache_fuzzer.cc b/net/disk_cache/disk_cache_fuzzer.cc index f88effda..ee4c103 100644 --- a/net/disk_cache/disk_cache_fuzzer.cc +++ b/net/disk_cache/disk_cache_fuzzer.cc
@@ -22,6 +22,7 @@ #include "base/numerics/checked_math.h" #include "base/strings/string_number_conversions.h" #include "base/test/task_environment.h" +#include "base/test/test_timeouts.h" #include "base/time/time.h" #include "net/base/cache_type.h" #include "net/base/interval.h" @@ -91,6 +92,10 @@ print_comms_ = ::getenv("LPM_DUMP_NATIVE_INPUT"); + // TaskEnvironment requires TestTimeouts initialization to watch for + // problematic long-running tasks. + TestTimeouts::Initialize(); + // Mark this thread as an IO_THREAD with MOCK_TIME, and ensure that Now() // is driven from the same mock clock. task_environment_ = std::make_unique<base::test::TaskEnvironment>(
diff --git a/net/dns/dns_transaction.cc b/net/dns/dns_transaction.cc index 426f49c..7bccf20 100644 --- a/net/dns/dns_transaction.cc +++ b/net/dns/dns_transaction.cc
@@ -334,6 +334,7 @@ const GURL& gurl_without_parameters, bool use_post, URLRequestContext* url_request_context, + const IsolationInfo& isolation_info, RequestPriority request_priority_) : DnsAttempt(doh_server_index), query_(std::move(query)) { GURL url; @@ -404,6 +405,7 @@ request_->SetLoadFlags(request_->load_flags() | LOAD_DISABLE_CACHE | LOAD_BYPASS_PROXY); request_->set_allow_credentials(false); + request_->set_isolation_info(isolation_info); } // DnsAttempt overrides. @@ -557,6 +559,7 @@ const OptRecordRdata* opt_rdata, std::vector<std::unique_ptr<DnsAttempt>>* attempts, URLRequestContext* url_request_context, + const IsolationInfo& isolation_info, RequestPriority request_priority) { DCHECK(url_request_context); @@ -579,7 +582,7 @@ attempts->push_back(std::make_unique<DnsHTTPAttempt>( doh_server_index, std::move(query), doh_config.server_template, gurl_without_parameters, doh_config.use_post, url_request_context, - request_priority)); + isolation_info, request_priority)); } class DnsTCPAttempt : public DnsAttempt { @@ -943,7 +946,7 @@ session_.get(), doh_server_index, formatted_probe_hostname_, dns_protocol::kTypeA, nullptr /* opt_rdata */, &probe_stats->probe_attempts, context_->url_request_context(), - RequestPriority::DEFAULT_PRIORITY); + context_->isolation_info(), RequestPriority::DEFAULT_PRIORITY); probe_stats->probe_attempts.back()->Start(base::BindOnce( &DnsOverHttpsProbeRunner::ProbeComplete, weak_ptr_factory_.GetWeakPtr(), @@ -1233,7 +1236,8 @@ unsigned attempt_number = attempts_.size(); ConstructDnsHTTPAttempt( session_.get(), doh_server_index, qnames_.front(), qtype_, opt_rdata_, - &attempts_, resolve_context_->url_request_context(), request_priority_); + &attempts_, resolve_context_->url_request_context(), + resolve_context_->isolation_info(), request_priority_); ++attempts_count_; int rv = attempts_.back()->Start(base::BindOnce( &DnsTransactionImpl::OnAttemptComplete, base::Unretained(this),
diff --git a/net/dns/dns_transaction_unittest.cc b/net/dns/dns_transaction_unittest.cc index d34bb5b..e3196cf 100644 --- a/net/dns/dns_transaction_unittest.cc +++ b/net/dns/dns_transaction_unittest.cc
@@ -781,6 +781,22 @@ } EXPECT_TRUE(server_found); + EXPECT_TRUE( + request->isolation_info().network_isolation_key().IsTransient()); + + // All DoH requests for the same ResolveContext should use the same + // IsolationInfo, so network objects like sockets can be reused between + // requests. + if (!expect_multiple_isolation_infos_) { + if (!isolation_info_) { + isolation_info_ = + std::make_unique<IsolationInfo>(request->isolation_info()); + } else { + EXPECT_TRUE( + isolation_info_->IsEqualForTesting(request->isolation_info())); + } + } + EXPECT_EQ(PRIVACY_MODE_ENABLED, request->privacy_mode()); EXPECT_TRUE(request->disable_secure_dns()); @@ -858,6 +874,11 @@ filter->ClearHandlers(); } + void set_expect_multiple_isolation_infos( + bool expect_multiple_isolation_infos) { + expect_multiple_isolation_infos_ = expect_multiple_isolation_infos; + } + protected: int GetNextId(int min, int max) { EXPECT_FALSE(transaction_ids_.empty()); @@ -880,6 +901,15 @@ std::unique_ptr<DnsTransactionFactory> transaction_factory_; ResponseModifierCallback response_modifier_; DohJobMakerCallback doh_job_maker_; + + // Whether multiple IsolationInfos should be expected (due to there being + // multiple RequestContexts in use). + bool expect_multiple_isolation_infos_ = false; + + // IsolationInfo used by DoH requests. Populated on first DoH request, and + // compared to IsolationInfo used by all subsequent requests, unless + // |expect_multiple_isolation_infos_| is true. + std::unique_ptr<IsolationInfo> isolation_info_; }; class DnsTransactionTest : public DnsTransactionTestBase, @@ -2750,6 +2780,11 @@ } TEST_F(DnsTransactionTestWithMockTime, MultipleProbeRunners_SeparateContexts) { + // Each RequestContext uses its own transient IsolationInfo. Since there's + // typically only one RequestContext per URLRequestContext, there's no + // advantage in using the same IsolationInfo across RequestContexts. + set_expect_multiple_isolation_infos(true); + ConfigureDohServers(true /* use_post */, 1 /* num_doh_servers */, false /* make_available */); AddQueryAndResponse(4, kT4HostName, kT4Qtype, kT4ResponseDatagram,
diff --git a/net/dns/resolve_context.cc b/net/dns/resolve_context.cc index 7223cdd..fd7f7c6 100644 --- a/net/dns/resolve_context.cc +++ b/net/dns/resolve_context.cc
@@ -99,7 +99,8 @@ ResolveContext::ResolveContext(URLRequestContext* url_request_context, bool enable_caching) : url_request_context_(url_request_context), - host_cache_(enable_caching ? HostCache::CreateDefaultCache() : nullptr) { + host_cache_(enable_caching ? HostCache::CreateDefaultCache() : nullptr), + isolation_info_(IsolationInfo::CreateTransient()) { max_timeout_ = GetMaxTimeout(); }
diff --git a/net/dns/resolve_context.h b/net/dns/resolve_context.h index fc09c172..8b3ec4fd 100644 --- a/net/dns/resolve_context.h +++ b/net/dns/resolve_context.h
@@ -14,6 +14,7 @@ #include "base/observer_list_types.h" #include "base/optional.h" #include "base/time/time.h" +#include "net/base/isolation_info.h" #include "net/base/net_export.h" #include "net/dns/dns_config.h" @@ -143,6 +144,15 @@ return current_session_.get(); } + // Returns IsolationInfo that should be used for DoH requests. Using a single + // transient IsolationInfo ensures that DNS requests aren't pooled with normal + // web requests, but still allows them to be pooled with each other, to allow + // reusing connections to the DoH server across different third party + // contexts. One downside of a transient IsolationInfo is that it means + // metadata about the DoH server itself will not be cached across restarts + // (alternative service info if it supports QUIC, for instance). + const IsolationInfo& isolation_info() const { return isolation_info_; } + private: friend DohDnsServerIterator; friend ClassicDnsServerIterator; @@ -225,6 +235,8 @@ std::vector<ServerStats> classic_server_stats_; // Track runtime statistics of each DoH server. std::vector<ServerStats> doh_server_stats_; + + const IsolationInfo isolation_info_; }; } // namespace net
diff --git a/net/quic/quic_chromium_client_session_test.cc b/net/quic/quic_chromium_client_session_test.cc index 7e6f898..404d815 100644 --- a/net/quic/quic_chromium_client_session_test.cc +++ b/net/quic/quic_chromium_client_session_test.cc
@@ -1899,71 +1899,6 @@ EXPECT_TRUE(new_socket_data.AllWriteDataConsumed()); } -TEST_P(QuicChromiumClientSessionTest, DetectPathDegradingDuringHandshake) { - if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3 || - GetQuicReloadableFlag(quic_use_blackhole_detector)) { - // TODO(nharper, b/112643533): Figure out why this test fails when TLS is - // enabled and fix it. - return; - } - migrate_session_early_v2_ = true; - - MockQuicData quic_data(version_); - quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read - quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1)); - quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(2)); - quic_data.AddSocketDataToFactory(&socket_factory_); - - // Set the crypto handshake mode to cold start and send CHLO packets. - crypto_client_stream_factory_.set_handshake_mode( - MockCryptoClientStream::COLD_START_WITH_CHLO_SENT); - Initialize(); - - session_->CryptoConnect(callback_.callback()); - - // Check retransmission alarm is set after sending the initial CHLO packet. - quic::QuicAlarm* retransmission_alarm = - quic::test::QuicConnectionPeer::GetRetransmissionAlarm( - session_->connection()); - EXPECT_TRUE(retransmission_alarm->IsSet()); - quic::QuicTime retransmission_time = retransmission_alarm->deadline(); - - // Check path degrading alarm is set after sending the initial CHLO packet. - quic::QuicAlarm* path_degrading_alarm = - quic::test::QuicConnectionPeer::GetPathDegradingAlarm( - session_->connection()); - EXPECT_TRUE(path_degrading_alarm->IsSet()); - quic::QuicTime path_degrading_time = path_degrading_alarm->deadline(); - EXPECT_LE(retransmission_time, path_degrading_time); - - // Do not create outgoing stream since encryption is not established. - std::unique_ptr<QuicChromiumClientSession::Handle> handle = - session_->CreateHandle(destination_); - TestCompletionCallback callback; - EXPECT_TRUE(handle->IsConnected()); - EXPECT_FALSE(handle->OneRttKeysAvailable()); - EXPECT_EQ( - ERR_IO_PENDING, - handle->RequestStream(/*require_handshake_confirmation=*/true, - callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS)); - - // Fire the retransmission alarm to retransmit the crypto packet. - quic::QuicTime::Delta delay = retransmission_time - clock_.ApproximateNow(); - clock_.AdvanceTime(delay); - alarm_factory_.FireAlarm(retransmission_alarm); - - // Fire the path degrading alarm to notify session that path is degrading - // during crypto handshake. - delay = path_degrading_time - clock_.ApproximateNow(); - clock_.AdvanceTime(delay); - EXPECT_CALL(*session_.get(), OnPathDegrading()); - alarm_factory_.FireAlarm(path_degrading_alarm); - - EXPECT_TRUE(session_->connection()->IsPathDegrading()); - EXPECT_TRUE(quic_data.AllReadDataConsumed()); - EXPECT_TRUE(quic_data.AllWriteDataConsumed()); -} - TEST_P(QuicChromiumClientSessionTest, GoAwayOnPathDegradingOnlyWhenHandshakeConfirmed) { go_away_on_path_degrading_ = true;
diff --git a/net/quic/quic_flags_list.h b/net/quic/quic_flags_list.h index dbe077d..2ae5a88b 100644 --- a/net/quic/quic_flags_list.h +++ b/net/quic/quic_flags_list.h
@@ -288,11 +288,7 @@ // If true, quic::BandwidthSampler will start in application limited phase. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_bw_sampler_app_limited_starting_value, - false) - -// If true, use blackhole detector in QuicConnection to detect path degrading -// and network blackhole. -QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_use_blackhole_detector, true) + true) // If true, use idle network detector to detect handshake timeout and idle // network timeout. @@ -370,13 +366,13 @@ // If true, notify handshakers when connection closes. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_notify_handshaker_on_connection_close, - false) + true) // If true, for QUIC + TLS, change default encryption level when new encryption // key is available. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_change_default_encryption_level, - false) + true) // If true, do not change ACK in PostProcessAckFrame if an ACK has been queued. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_donot_change_queued_ack, false)
diff --git a/net/quic/quic_network_transaction_unittest.cc b/net/quic/quic_network_transaction_unittest.cc index 5d3378b..5dc3abd 100644 --- a/net/quic/quic_network_transaction_unittest.cc +++ b/net/quic/quic_network_transaction_unittest.cc
@@ -3322,295 +3322,7 @@ EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR)); } -// Verify that if a QUIC connection RTOs, the QuicHttpStream will -// return QUIC_PROTOCOL_ERROR. -TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) { - if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3 || - GetQuicReloadableFlag(quic_use_blackhole_detector)) { - // QUIC with TLS1.3 handshake doesn't support 0-rtt. - // TODO(fayang): Add time driven TOO_MANY_RTOS test. - return; - } - - context_.params()->retry_without_alt_svc_on_quic_errors = false; - context_.params()->connection_options.push_back(quic::k5RTO); - - // The request will initially go out over QUIC. - MockQuicData quic_data(version_); - spdy::SpdyPriority priority = - ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY); - - client_maker_->set_save_packet_frames(true); - client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT); - int packet_number = 1; - if (VersionUsesHttp3(version_.transport_version)) { - quic_data.AddWrite( - SYNCHRONOUS, client_maker_->MakeInitialSettingsPacket(packet_number++)); - } - quic_data.AddWrite( - SYNCHRONOUS, - client_maker_->MakeRequestHeadersPacket( - packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true, - true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr)); - - client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE); - if (VersionUsesHttp3(version_.transport_version)) { - // TLP 1 - quic_data.AddWrite(SYNCHRONOUS, - client_maker_->MakeRetransmissionPacket(1, 3, true)); - // TLP 2 - quic_data.AddWrite(SYNCHRONOUS, - client_maker_->MakeRetransmissionPacket(2, 4, true)); - // RTO 1 - quic_data.AddWrite(SYNCHRONOUS, - client_maker_->MakeRetransmissionPacket(1, 5, true)); - quic_data.AddWrite(SYNCHRONOUS, - client_maker_->MakeRetransmissionPacket(2, 6, true)); - // RTO 2 - quic_data.AddWrite(SYNCHRONOUS, - client_maker_->MakeRetransmissionPacket(1, 7, true)); - quic_data.AddWrite(SYNCHRONOUS, - client_maker_->MakeRetransmissionPacket(2, 8, true)); - // RTO 3 - quic_data.AddWrite(SYNCHRONOUS, - client_maker_->MakeRetransmissionPacket(1, 9, true)); - quic_data.AddWrite(SYNCHRONOUS, - client_maker_->MakeRetransmissionPacket(2, 10, true)); - // RTO 4 - quic_data.AddWrite(SYNCHRONOUS, - client_maker_->MakeRetransmissionPacket(1, 11, true)); - quic_data.AddWrite(SYNCHRONOUS, - client_maker_->MakeRetransmissionPacket(2, 12, true)); - // RTO 5 - quic_data.AddWrite(SYNCHRONOUS, - client_maker_->MakeConnectionClosePacket( - 13, true, quic::QUIC_TOO_MANY_RTOS, - "5 consecutive retransmission timeouts")); - } else { - // TLP 1 - quic_data.AddWrite(SYNCHRONOUS, - client_maker_->MakeRetransmissionPacket(1, 2, true)); - // TLP 2 - quic_data.AddWrite(SYNCHRONOUS, - client_maker_->MakeRetransmissionPacket(1, 3, true)); - // RTO 1 - quic_data.AddWrite(SYNCHRONOUS, - client_maker_->MakeRetransmissionPacket(1, 4, true)); - // RTO 2 - quic_data.AddWrite(SYNCHRONOUS, - client_maker_->MakeRetransmissionPacket(1, 5, true)); - // RTO 3 - quic_data.AddWrite(SYNCHRONOUS, - client_maker_->MakeRetransmissionPacket(1, 6, true)); - // RTO 4 - quic_data.AddWrite(SYNCHRONOUS, - client_maker_->MakeRetransmissionPacket(1, 7, true)); - // RTO 5 - quic_data.AddWrite(SYNCHRONOUS, - client_maker_->MakeConnectionClosePacket( - 8, true, quic::QUIC_TOO_MANY_RTOS, - "5 consecutive retransmission timeouts")); - } - - quic_data.AddRead(ASYNC, OK); - quic_data.AddSocketDataToFactory(&socket_factory_); - - // In order for a new QUIC session to be established via alternate-protocol - // without racing an HTTP connection, we need the host resolution to happen - // synchronously. Of course, even though QUIC *could* perform a 0-RTT - // connection to the the server, in this test we require confirmation - // before encrypting so the HTTP job will still start. - host_resolver_.set_synchronous_mode(true); - host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1", - ""); - - CreateSession(); - // Use a TestTaskRunner to avoid waiting in real time for timeouts. - QuicStreamFactoryPeer::SetAlarmFactory( - session_->quic_stream_factory(), - std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(), - context_.clock())); - - AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT); - - HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get()); - TestCompletionCallback callback; - int rv = trans.Start(&request_, callback.callback(), net_log_.bound()); - EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - - // Pump the message loop to get the request started. - base::RunLoop().RunUntilIdle(); - // Explicitly confirm the handshake. - crypto_client_stream_factory_.last_stream() - ->NotifySessionOneRttKeyAvailable(); - - // Run the QUIC session to completion. - quic_task_runner_->RunUntilIdle(); - - ExpectQuicAlternateProtocolMapping(); - ASSERT_TRUE(quic_data.AllWriteDataConsumed()); - EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR)); -} - -// Verify that if a QUIC connection RTOs, while there are no active streams -// QUIC will not be marked as broken. -TEST_P(QuicNetworkTransactionTest, - TooManyRtosAfterHandshakeConfirmedAndStreamReset) { - if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3 || - GetQuicReloadableFlag(quic_use_blackhole_detector)) { - // QUIC with TLS1.3 handshake doesn't support 0-rtt. - // TODO(fayang): Add time driven TOO_MANY_RTOS test. - return; - } - - context_.params()->connection_options.push_back(quic::k5RTO); - - // The request will initially go out over QUIC. - MockQuicData quic_data(version_); - spdy::SpdyPriority priority = - ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY); - - client_maker_->set_save_packet_frames(true); - client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT); - int packet_number = 1; - if (VersionUsesHttp3(version_.transport_version)) { - quic_data.AddWrite( - SYNCHRONOUS, client_maker_->MakeInitialSettingsPacket(packet_number++)); - } - quic_data.AddWrite( - SYNCHRONOUS, - client_maker_->MakeRequestHeadersPacket( - packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true, - true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr)); - - client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE); - - if (!VersionUsesHttp3(version_.transport_version)) { - quic_data.AddWrite(SYNCHRONOUS, - client_maker_->MakeRstPacket( - packet_number++, true, - GetNthClientInitiatedBidirectionalStreamId(0), - quic::QUIC_STREAM_CANCELLED)); - // TLP 1 - quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket( - 1, packet_number++, true)); - // TLP 2 - quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket( - 2, packet_number++, true)); - // RTO 1 - quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket( - 1, packet_number++, true)); - quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket( - 2, packet_number++, true)); - // RTO 2 - quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket( - 1, packet_number++, true)); - quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket( - 2, packet_number++, true)); - // RTO 3 - quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket( - 1, packet_number++, true)); - quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket( - 2, packet_number++, true)); - // RTO 4 - quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket( - 1, packet_number++, true)); - quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket( - 2, packet_number++, true)); - // RTO 5 - quic_data.AddWrite(SYNCHRONOUS, - client_maker_->MakeConnectionClosePacket( - packet_number++, true, quic::QUIC_TOO_MANY_RTOS, - "5 consecutive retransmission timeouts")); - } else { - quic_data.AddWrite( - SYNCHRONOUS, ConstructClientDataPacket( - packet_number++, GetQpackDecoderStreamId(), true, - false, StreamCancellationQpackDecoderInstruction(0))); - quic_data.AddWrite(SYNCHRONOUS, - client_maker_->MakeRstPacket( - packet_number++, true, - GetNthClientInitiatedBidirectionalStreamId(0), - quic::QUIC_STREAM_CANCELLED)); - client_maker_->RemoveSavedStreamFrames( - GetNthClientInitiatedBidirectionalStreamId(0)); - - // TLP 1 - quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket( - 1, packet_number++, true)); - // TLP 2 - quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket( - 2, packet_number++, true)); - // RTO 1 - quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket( - 3, packet_number++, true)); - quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket( - 4, packet_number++, true)); - // RTO 2 - quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket( - 1, packet_number++, true)); - quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket( - 2, packet_number++, true)); - // RTO 3 - quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket( - 3, packet_number++, true)); - quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket( - 4, packet_number++, true)); - // RTO 4 - quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket( - 1, packet_number++, true)); - quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket( - 2, packet_number++, true)); - // RTO 5 - quic_data.AddWrite(SYNCHRONOUS, - client_maker_->MakeConnectionClosePacket( - packet_number++, true, quic::QUIC_TOO_MANY_RTOS, - "5 consecutive retransmission timeouts")); - } - - quic_data.AddRead(ASYNC, OK); - quic_data.AddSocketDataToFactory(&socket_factory_); - - // In order for a new QUIC session to be established via alternate-protocol - // without racing an HTTP connection, we need the host resolution to happen - // synchronously. Of course, even though QUIC *could* perform a 0-RTT - // connection to the the server, in this test we require confirmation - // before encrypting so the HTTP job will still start. - host_resolver_.set_synchronous_mode(true); - host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1", - ""); - - CreateSession(); - // Use a TestTaskRunner to avoid waiting in real time for timeouts. - QuicStreamFactoryPeer::SetAlarmFactory( - session_->quic_stream_factory(), - std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(), - context_.clock())); - - AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT); - - auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, - session_.get()); - TestCompletionCallback callback; - int rv = trans->Start(&request_, callback.callback(), net_log_.bound()); - EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - - // Pump the message loop to get the request started. - base::RunLoop().RunUntilIdle(); - // Explicitly confirm the handshake. - crypto_client_stream_factory_.last_stream() - ->NotifySessionOneRttKeyAvailable(); - - // Now cancel the request. - trans.reset(); - - // Run the QUIC session to completion. - quic_task_runner_->RunUntilIdle(); - - ExpectQuicAlternateProtocolMapping(); - - ASSERT_TRUE(quic_data.AllWriteDataConsumed()); -} +// TODO(fayang): Add time driven TOO_MANY_RTOS test. // Verify that if a QUIC protocol error occurs after the handshake is confirmed // the request fails with QUIC_PROTOCOL_ERROR.
diff --git a/net/spdy/spdy_http_stream.cc b/net/spdy/spdy_http_stream.cc index 8b2c6b2..8c1b9b04f 100644 --- a/net/spdy/spdy_http_stream.cc +++ b/net/spdy/spdy_http_stream.cc
@@ -452,7 +452,7 @@ } void SpdyHttpStream::OnDataSent() { - if (HasUploadData()) { + if (request_info_ && HasUploadData()) { request_body_buf_size_ = 0; ReadAndSendRequestBodyData(); } else {
diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc index 86e73f84..1da8390 100644 --- a/net/spdy/spdy_network_transaction_unittest.cc +++ b/net/spdy/spdy_network_transaction_unittest.cc
@@ -10372,4 +10372,70 @@ EXPECT_EQ("hello", response_data); } +// Regression test for https://crbug.com/1081955. +// Greasing frame types is enabled, the outgoing HEADERS frame is followed by a +// frame of reserved type, then an empty DATA frame to close the stream. +// Response arrives before reserved frame and DATA frame can be sent. +// SpdyHttpStream::OnDataSent() must not crash. +TEST_F(SpdyNetworkTransactionTest, OnDataSentDoesNotCrashWithGreasedFrameType) { + auto session_deps = std::make_unique<SpdySessionDependencies>(); + + const uint8_t type = 0x0b; + const uint8_t flags = 0xcc; + const std::string payload("foo"); + session_deps->greased_http2_frame = + base::Optional<net::SpdySessionPool::GreasedHttp2Frame>( + {type, flags, payload}); + + NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, + std::move(session_deps)); + + spdy::SpdyHeaderBlock headers( + spdy_util_.ConstructGetHeaderBlock(kDefaultUrl)); + spdy::SpdySerializedFrame req( + spdy_util_.ConstructSpdyHeaders(1, std::move(headers), DEFAULT_PRIORITY, + /* fin = */ false)); + + const char kRawFrameData[] = { + 0x00, 0x00, 0x03, // length + 0x0b, // type + 0xcc, // flags + 0x00, 0x00, 0x00, 0x01, // stream ID + 'f', 'o', 'o' // payload + }; + spdy::SpdySerializedFrame grease(const_cast<char*>(kRawFrameData), + base::size(kRawFrameData), + /* owns_buffer = */ false); + spdy::SpdySerializedFrame empty_body( + spdy_util_.ConstructSpdyDataFrame(1, "", true)); + + MockWrite writes[] = { + CreateMockWrite(req, 0), MockWrite(ASYNC, ERR_IO_PENDING, 2), + CreateMockWrite(grease, 3), CreateMockWrite(empty_body, 4)}; + + spdy::SpdySerializedFrame resp( + spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); + spdy::SpdySerializedFrame response_body( + spdy_util_.ConstructSpdyDataFrame(1, true)); + + MockRead reads[] = {CreateMockRead(resp, 1), CreateMockRead(response_body, 5), + MockRead(ASYNC, 0, 6)}; + + SequencedSocketData data(reads, writes); + helper.RunPreTestSetup(); + helper.AddData(&data); + + TestCompletionCallback callback; + int rv = helper.trans()->Start(&request_, callback.callback(), log_); + base::RunLoop().RunUntilIdle(); + + // Response headers received. Resume sending |grease| and |empty_body|. + data.Resume(); + EXPECT_THAT(callback.GetResult(rv), IsOk()); + + base::RunLoop().RunUntilIdle(); + + helper.VerifyDataConsumed(); +} + } // namespace net
diff --git a/pdf/pdf.h b/pdf/pdf.h index b8bb927..6a1c8c2 100644 --- a/pdf/pdf.h +++ b/pdf/pdf.h
@@ -37,12 +37,16 @@ #endif // defined(OS_CHROMEOS) #if defined(OS_WIN) -// Printing modes - type to convert PDF to for printing +// Printing modes - type to convert PDF to for printing. See PDFium's +// FPDF_SetPrintMode() for details. enum PrintingMode { kEmf = 0, kTextOnly = 1, kPostScript2 = 2, kPostScript3 = 3, + // Values 4 and 5 are similar to |kPostScript2| and |kPostScript3|, but are + // not intended for use in sandboxed environments like Chromium's. + kEmfWithReducedRasterization = 6, }; // |pdf_buffer| is the buffer that contains the entire PDF document to be
diff --git a/pdf/pdfium/pdfium_assert_matching_enums.cc b/pdf/pdfium/pdfium_assert_matching_enums.cc index 5035f5c..a58ecff0 100644 --- a/pdf/pdfium/pdfium_assert_matching_enums.cc +++ b/pdf/pdfium/pdfium_assert_matching_enums.cc
@@ -234,4 +234,6 @@ STATIC_ASSERT_ENUM(chrome_pdf::kTextOnly, FPDF_PRINTMODE_TEXTONLY); STATIC_ASSERT_ENUM(chrome_pdf::kPostScript2, FPDF_PRINTMODE_POSTSCRIPT2); STATIC_ASSERT_ENUM(chrome_pdf::kPostScript3, FPDF_PRINTMODE_POSTSCRIPT3); +STATIC_ASSERT_ENUM(chrome_pdf::kEmfWithReducedRasterization, + FPDF_PRINTMODE_EMF_IMAGE_MASKS); #endif
diff --git a/pdf/pdfium/pdfium_test_base.cc b/pdf/pdfium/pdfium_test_base.cc index 679ba41..293c8e3ca 100644 --- a/pdf/pdfium/pdfium_test_base.cc +++ b/pdf/pdfium/pdfium_test_base.cc
@@ -114,10 +114,11 @@ PDFiumTestBase::InitializeEngineResult::InitializeEngineResult() = default; PDFiumTestBase::InitializeEngineResult::InitializeEngineResult( - InitializeEngineResult&& other) = default; + InitializeEngineResult&& other) noexcept = default; -PDFiumTestBase::InitializeEngineResult& PDFiumTestBase::InitializeEngineResult:: -operator=(InitializeEngineResult&& other) = default; +PDFiumTestBase::InitializeEngineResult& +PDFiumTestBase::InitializeEngineResult::operator=( + InitializeEngineResult&& other) noexcept = default; PDFiumTestBase::InitializeEngineResult::~InitializeEngineResult() = default;
diff --git a/ppapi/tests/test_network_proxy.cc b/ppapi/tests/test_network_proxy.cc index de355730..24ec9f1 100644 --- a/ppapi/tests/test_network_proxy.cc +++ b/ppapi/tests/test_network_proxy.cc
@@ -33,12 +33,15 @@ // Assume no one configures a proxy for localhost. ASSERT_EQ("DIRECT", callback.output().AsString()); - callback.WaitForResult(pp::NetworkProxy::GetProxyForURL( - instance_, pp::Var("https://use.proxy.test/"), callback.GetCallback())); + callback.WaitForResult( + pp::NetworkProxy::GetProxyForURL(instance_, + pp::Var("http://www.google.com"), + callback.GetCallback())); CHECK_CALLBACK_BEHAVIOR(callback); ASSERT_EQ(PP_OK, callback.result()); output = callback.output(); - ASSERT_EQ("PROXY proxy.test:80", callback.output().AsString()); + // Don't know what the proxy might be, but it should be a valid result. + ASSERT_TRUE(output.is_string()); callback.WaitForResult( pp::NetworkProxy::GetProxyForURL(instance_,
diff --git a/printing/pdf_render_settings.h b/printing/pdf_render_settings.h index 1dab726..244a5f1 100644 --- a/printing/pdf_render_settings.h +++ b/printing/pdf_render_settings.h
@@ -21,9 +21,11 @@ GDI_TEXT, POSTSCRIPT_LEVEL2, POSTSCRIPT_LEVEL3, - LAST = POSTSCRIPT_LEVEL3, + EMF_WITH_REDUCED_RASTERIZATION, + EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT, + LAST = EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT #else - LAST = NORMAL, + LAST = NORMAL #endif };
diff --git a/printing/printing_features.cc b/printing/printing_features.cc index be78d3a..ed71b967 100644 --- a/printing/printing_features.cc +++ b/printing/printing_features.cc
@@ -24,6 +24,10 @@ #endif // defined(OS_MACOSX) #if defined(OS_WIN) +// When using GDI printing, avoid rasterization if possible. +const base::Feature kPrintWithReducedRasterization{ + "PrintWithReducedRasterization", base::FEATURE_DISABLED_BY_DEFAULT}; + // Use XPS for printing instead of GDI. const base::Feature kUseXpsForPrinting{"UseXpsForPrinting", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/printing/printing_features.h b/printing/printing_features.h index 8ce0975..777f105 100644 --- a/printing/printing_features.h +++ b/printing/printing_features.h
@@ -25,6 +25,7 @@ #endif // defined(OS_MACOSX) #if defined(OS_WIN) +PRINTING_EXPORT extern const base::Feature kPrintWithReducedRasterization; PRINTING_EXPORT extern const base::Feature kUseXpsForPrinting; PRINTING_EXPORT extern const base::Feature kUseXpsForPrintingFromPdf;
diff --git a/services/metrics/public/cpp/ukm_source_id_unittest.cc b/services/metrics/public/cpp/ukm_source_id_unittest.cc index 16fe8e83..eff8fda 100644 --- a/services/metrics/public/cpp/ukm_source_id_unittest.cc +++ b/services/metrics/public/cpp/ukm_source_id_unittest.cc
@@ -22,7 +22,7 @@ } } -TEST(UkmSourceIdTest, ConvertToSourceId) { +TEST(UkmSourceIdTest, ConvertToNavigationType) { const size_t numIds = 5; SourceId ids[numIds] = {}; @@ -36,4 +36,24 @@ } } +TEST(UkmSourceIdTest, GetSourceIdType) { + // Check that the newly assigned id is defaulted to "UKM" type. + const SourceId new_id = AssignNewSourceId(); + EXPECT_EQ(SourceIdType::UKM, GetSourceIdType(new_id)); + + const int64_t num_types = static_cast<int64_t>(SourceIdType::kMaxValue); + for (int64_t type_index = 0; type_index <= num_types; type_index++) { + const SourceIdType expected_type = SourceIdType(type_index); + if (expected_type == SourceIdType::WEBAPK_ID || + expected_type == SourceIdType::PAYMENT_APP_ID) { + // See comment in ConvertToSourceId regarding these special cases. + continue; + } + // Convert the new id to each existing type and verify that the type + // information is correctly set on the converted id. + const SourceId converted_id = ConvertToSourceId(new_id, expected_type); + EXPECT_EQ(expected_type, GetSourceIdType(converted_id)); + } +} + } // namespace ukm
diff --git a/services/network/network_context.cc b/services/network/network_context.cc index 490fbca..9ab4981 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc
@@ -1624,8 +1624,7 @@ std::move(callback).Run(base::nullopt); } -const net::HttpAuthPreferences* NetworkContext::GetHttpAuthPreferences() const - noexcept { +const net::HttpAuthPreferences* NetworkContext::GetHttpAuthPreferences() const { return &http_auth_merged_preferences_; }
diff --git a/storage/browser/database/database_quota_client_unittest.cc b/storage/browser/database/database_quota_client_unittest.cc index 4e56e2f..b14a36d 100644 --- a/storage/browser/database/database_quota_client_unittest.cc +++ b/storage/browser/database/database_quota_client_unittest.cc
@@ -15,8 +15,9 @@ #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/bind_test_util.h" #include "base/test/task_environment.h" -#include "base/threading/thread_task_runner_handle.h" +#include "base/threading/sequenced_task_runner_handle.h" #include "net/base/completion_once_callback.h" #include "net/base/net_errors.h" #include "storage/browser/database/database_quota_client.h" @@ -41,7 +42,6 @@ : DatabaseTracker(base::FilePath(), false, nullptr, nullptr), delete_called_count_(0), async_delete_(false) { - set_task_runner_for_testing(base::ThreadTaskRunnerHandle::Get()); } bool GetOriginInfo(const std::string& origin_identifier, @@ -71,7 +71,7 @@ net::CompletionOnceCallback callback) override { ++delete_called_count_; if (async_delete()) { - base::ThreadTaskRunnerHandle::Get()->PostTask( + base::SequencedTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&MockDatabaseTracker::AsyncDeleteDataForOrigin, this, std::move(callback))); @@ -136,10 +136,9 @@ usage_ = 0; client->GetOriginUsage( origin, type, - base::AdaptCallbackForRepeating( - base::BindOnce(&DatabaseQuotaClientTest::OnGetOriginUsageComplete, - weak_factory_.GetWeakPtr()))); - base::RunLoop().RunUntilIdle(); + base::BindOnce(&DatabaseQuotaClientTest::OnGetOriginUsageComplete, + weak_factory_.GetWeakPtr())); + task_environment_.RunUntilIdle(); return usage_; } @@ -148,10 +147,9 @@ blink::mojom::StorageType type) { origins_.clear(); client->GetOriginsForType( - type, base::AdaptCallbackForRepeating( - base::BindOnce(&DatabaseQuotaClientTest::OnGetOriginsComplete, - weak_factory_.GetWeakPtr()))); - base::RunLoop().RunUntilIdle(); + type, base::BindOnce(&DatabaseQuotaClientTest::OnGetOriginsComplete, + weak_factory_.GetWeakPtr())); + task_environment_.RunUntilIdle(); return origins_; } @@ -162,10 +160,9 @@ origins_.clear(); client->GetOriginsForHost( type, host, - base::AdaptCallbackForRepeating( - base::BindOnce(&DatabaseQuotaClientTest::OnGetOriginsComplete, - weak_factory_.GetWeakPtr()))); - base::RunLoop().RunUntilIdle(); + base::BindOnce(&DatabaseQuotaClientTest::OnGetOriginsComplete, + weak_factory_.GetWeakPtr())); + task_environment_.RunUntilIdle(); return origins_; } @@ -175,10 +172,9 @@ delete_status_ = blink::mojom::QuotaStatusCode::kUnknown; client->DeleteOriginData( origin, type, - base::AdaptCallbackForRepeating( - base::BindOnce(&DatabaseQuotaClientTest::OnDeleteOriginDataComplete, - weak_factory_.GetWeakPtr()))); - base::RunLoop().RunUntilIdle(); + base::BindOnce(&DatabaseQuotaClientTest::OnDeleteOriginDataComplete, + weak_factory_.GetWeakPtr())); + task_environment_.RunUntilIdle(); return delete_status_ == blink::mojom::QuotaStatusCode::kOk; }
diff --git a/storage/browser/database/database_tracker.h b/storage/browser/database/database_tracker.h index 1951738..6310385ac 100644 --- a/storage/browser/database/database_tracker.h +++ b/storage/browser/database/database_tracker.h
@@ -180,12 +180,6 @@ base::SequencedTaskRunner* task_runner() const { return task_runner_.get(); } - // TODO(jsbell): Remove this; tests should use the normal task runner. - void set_task_runner_for_testing( - scoped_refptr<base::SequencedTaskRunner> task_runner) { - task_runner_ = std::move(task_runner); - } - private: friend class base::RefCountedThreadSafe<DatabaseTracker>; friend class DatabaseTracker_TestHelper_Test;
diff --git a/storage/browser/database/database_tracker_unittest.cc b/storage/browser/database/database_tracker_unittest.cc index c0de5d7..5293254e 100644 --- a/storage/browser/database/database_tracker_unittest.cc +++ b/storage/browser/database/database_tracker_unittest.cc
@@ -7,12 +7,15 @@ #include <memory> +#include "base/callback_helpers.h" #include "base/files/file.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/memory/ptr_util.h" +#include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/bind_test_util.h" #include "base/test/task_environment.h" #include "base/threading/sequenced_task_runner_handle.h" #include "base/time/time.h" @@ -190,86 +193,107 @@ base::MakeRefCounted<DatabaseTracker>( temp_dir.GetPath(), incognito_mode, special_storage_policy.get(), nullptr)); - tracker->set_task_runner_for_testing( - base::SequencedTaskRunnerHandle::Get()); - // Create and open three databases. - int64_t database_size = 0; - const std::string kOrigin1 = GetIdentifierFromOrigin(GURL(kOrigin1Url)); - const std::string kOrigin2 = GetIdentifierFromOrigin(GURL(kOrigin2Url)); - const base::string16 kDB1 = ASCIIToUTF16("db1"); - const base::string16 kDB2 = ASCIIToUTF16("db2"); - const base::string16 kDB3 = ASCIIToUTF16("db3"); - const base::string16 kDescription = ASCIIToUTF16("database_description"); + base::RunLoop run_loop; + tracker->task_runner()->PostTask( + FROM_HERE, base::BindLambdaForTesting([&]() { + base::ScopedClosureRunner quit_runner( + base::BindLambdaForTesting([&]() { run_loop.Quit(); })); - tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, &database_size); - tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, 0, &database_size); - tracker->DatabaseOpened(kOrigin2, kDB3, kDescription, 0, &database_size); + // Create and open three databases. + int64_t database_size = 0; + const std::string kOrigin1 = + GetIdentifierFromOrigin(GURL(kOrigin1Url)); + const std::string kOrigin2 = + GetIdentifierFromOrigin(GURL(kOrigin2Url)); + const base::string16 kDB1 = ASCIIToUTF16("db1"); + const base::string16 kDB2 = ASCIIToUTF16("db2"); + const base::string16 kDB3 = ASCIIToUTF16("db3"); + const base::string16 kDescription = + ASCIIToUTF16("database_description"); - EXPECT_TRUE(base::CreateDirectory(tracker->GetOriginDirectory(kOrigin1))); - EXPECT_TRUE(base::CreateDirectory(tracker->GetOriginDirectory(kOrigin2))); - EXPECT_TRUE( - base::WriteFile(tracker->GetFullDBFilePath(kOrigin1, kDB1), "a")); - EXPECT_TRUE( - base::WriteFile(tracker->GetFullDBFilePath(kOrigin2, kDB2), "aa")); - EXPECT_TRUE( - base::WriteFile(tracker->GetFullDBFilePath(kOrigin2, kDB3), "aaa")); - tracker->DatabaseModified(kOrigin1, kDB1); - tracker->DatabaseModified(kOrigin2, kDB2); - tracker->DatabaseModified(kOrigin2, kDB3); + tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, + &database_size); + tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, 0, + &database_size); + tracker->DatabaseOpened(kOrigin2, kDB3, kDescription, 0, + &database_size); - // Delete db1. Should also delete origin1. - TestObserver observer; - tracker->AddObserver(&observer); - net::TestCompletionCallback callback1; - int result = tracker->DeleteDatabase(kOrigin1, kDB1, callback1.callback()); - EXPECT_EQ(net::ERR_IO_PENDING, result); - ASSERT_FALSE(callback1.have_result()); - EXPECT_TRUE(observer.DidReceiveNewNotification()); - EXPECT_EQ(kOrigin1, observer.GetNotificationOriginIdentifier()); - EXPECT_EQ(kDB1, observer.GetNotificationDatabaseName()); - tracker->DatabaseClosed(kOrigin1, kDB1); - result = callback1.GetResult(result); - EXPECT_EQ(net::OK, result); - EXPECT_FALSE(base::PathExists(tracker->GetOriginDirectory(kOrigin1))); + EXPECT_TRUE( + base::CreateDirectory(tracker->GetOriginDirectory(kOrigin1))); + EXPECT_TRUE( + base::CreateDirectory(tracker->GetOriginDirectory(kOrigin2))); + EXPECT_TRUE( + base::WriteFile(tracker->GetFullDBFilePath(kOrigin1, kDB1), "a")); + EXPECT_TRUE(base::WriteFile( + tracker->GetFullDBFilePath(kOrigin2, kDB2), "aa")); + EXPECT_TRUE(base::WriteFile( + tracker->GetFullDBFilePath(kOrigin2, kDB3), "aaa")); + tracker->DatabaseModified(kOrigin1, kDB1); + tracker->DatabaseModified(kOrigin2, kDB2); + tracker->DatabaseModified(kOrigin2, kDB3); - // Recreate db1. - tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, &database_size); - EXPECT_TRUE(base::CreateDirectory(tracker->GetOriginDirectory(kOrigin1))); - EXPECT_TRUE( - base::WriteFile(tracker->GetFullDBFilePath(kOrigin1, kDB1), "a")); - tracker->DatabaseModified(kOrigin1, kDB1); + // Delete db1. Should also delete origin1. + TestObserver observer; + tracker->AddObserver(&observer); + net::TestCompletionCallback callback1; + int result = + tracker->DeleteDatabase(kOrigin1, kDB1, callback1.callback()); + EXPECT_EQ(net::ERR_IO_PENDING, result); + ASSERT_FALSE(callback1.have_result()); + EXPECT_TRUE(observer.DidReceiveNewNotification()); + EXPECT_EQ(kOrigin1, observer.GetNotificationOriginIdentifier()); + EXPECT_EQ(kDB1, observer.GetNotificationDatabaseName()); + tracker->DatabaseClosed(kOrigin1, kDB1); + result = callback1.GetResult(result); + EXPECT_EQ(net::OK, result); + EXPECT_FALSE(base::PathExists(tracker->GetOriginDirectory(kOrigin1))); - // Setup file modification times. db1 and db2 are modified now, db3 three - // days ago. - base::Time now = base::Time::Now(); - EXPECT_TRUE( - base::TouchFile(tracker->GetFullDBFilePath(kOrigin1, kDB1), now, now)); - EXPECT_TRUE( - base::TouchFile(tracker->GetFullDBFilePath(kOrigin2, kDB2), now, now)); - base::Time three_days_ago = now - base::TimeDelta::FromDays(3); - EXPECT_TRUE(base::TouchFile(tracker->GetFullDBFilePath(kOrigin2, kDB3), - three_days_ago, three_days_ago)); + // Recreate db1. + tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, + &database_size); + EXPECT_TRUE( + base::CreateDirectory(tracker->GetOriginDirectory(kOrigin1))); + EXPECT_TRUE( + base::WriteFile(tracker->GetFullDBFilePath(kOrigin1, kDB1), "a")); + tracker->DatabaseModified(kOrigin1, kDB1); - // Delete databases modified since yesterday. db2 is whitelisted. - base::Time yesterday = base::Time::Now(); - yesterday -= base::TimeDelta::FromDays(1); + // Setup file modification times. db1 and db2 are modified now, db3 + // three days ago. + base::Time now = base::Time::Now(); + EXPECT_TRUE(base::TouchFile( + tracker->GetFullDBFilePath(kOrigin1, kDB1), now, now)); + EXPECT_TRUE(base::TouchFile( + tracker->GetFullDBFilePath(kOrigin2, kDB2), now, now)); + base::Time three_days_ago = now - base::TimeDelta::FromDays(3); + EXPECT_TRUE( + base::TouchFile(tracker->GetFullDBFilePath(kOrigin2, kDB3), + three_days_ago, three_days_ago)); - net::TestCompletionCallback callback2; - result = tracker->DeleteDataModifiedSince(yesterday, callback2.callback()); - EXPECT_EQ(net::ERR_IO_PENDING, result); - ASSERT_FALSE(callback2.have_result()); - EXPECT_TRUE(observer.DidReceiveNewNotification()); - tracker->DatabaseClosed(kOrigin1, kDB1); - tracker->DatabaseClosed(kOrigin2, kDB2); - result = callback2.GetResult(result); - EXPECT_EQ(net::OK, result); - EXPECT_FALSE(base::PathExists(tracker->GetOriginDirectory(kOrigin1))); - EXPECT_TRUE(base::PathExists(tracker->GetFullDBFilePath(kOrigin2, kDB2))); - EXPECT_TRUE(base::PathExists(tracker->GetFullDBFilePath(kOrigin2, kDB3))); + // Delete databases modified since yesterday. db2 is whitelisted. + base::Time yesterday = base::Time::Now(); + yesterday -= base::TimeDelta::FromDays(1); - tracker->DatabaseClosed(kOrigin2, kDB3); - tracker->RemoveObserver(&observer); + net::TestCompletionCallback callback2; + result = + tracker->DeleteDataModifiedSince(yesterday, callback2.callback()); + EXPECT_EQ(net::ERR_IO_PENDING, result); + ASSERT_FALSE(callback2.have_result()); + EXPECT_TRUE(observer.DidReceiveNewNotification()); + tracker->DatabaseClosed(kOrigin1, kDB1); + tracker->DatabaseClosed(kOrigin2, kDB2); + result = callback2.GetResult(result); + EXPECT_EQ(net::OK, result); + EXPECT_FALSE(base::PathExists(tracker->GetOriginDirectory(kOrigin1))); + EXPECT_TRUE( + base::PathExists(tracker->GetFullDBFilePath(kOrigin2, kDB2))); + EXPECT_TRUE( + base::PathExists(tracker->GetFullDBFilePath(kOrigin2, kDB3))); + + tracker->DatabaseClosed(kOrigin2, kDB3); + tracker->RemoveObserver(&observer); + })); + run_loop.Run(); } static void TestDatabaseTracker(bool incognito_mode) { @@ -284,127 +308,147 @@ base::MakeRefCounted<DatabaseTracker>( temp_dir.GetPath(), incognito_mode, special_storage_policy.get(), nullptr)); - tracker->set_task_runner_for_testing( - base::SequencedTaskRunnerHandle::Get()); - // Add two observers. - TestObserver observer1; - TestObserver observer2; - tracker->AddObserver(&observer1); - tracker->AddObserver(&observer2); + base::RunLoop run_loop; + tracker->task_runner()->PostTask( + FROM_HERE, base::BindLambdaForTesting([&]() { + base::ScopedClosureRunner quit_runner( + base::BindLambdaForTesting([&]() { run_loop.Quit(); })); - // Open three new databases. - int64_t database_size = 0; - const std::string kOrigin1 = GetIdentifierFromOrigin(GURL(kOrigin1Url)); - const std::string kOrigin2 = GetIdentifierFromOrigin(GURL(kOrigin2Url)); - const base::string16 kDB1 = ASCIIToUTF16("db1"); - const base::string16 kDB2 = ASCIIToUTF16("db2"); - const base::string16 kDB3 = ASCIIToUTF16("db3"); - const base::string16 kDescription = ASCIIToUTF16("database_description"); + // Add two observers. + TestObserver observer1; + TestObserver observer2; + tracker->AddObserver(&observer1); + tracker->AddObserver(&observer2); - // Get the info for kOrigin1 and kOrigin2 - DatabaseTracker::CachedOriginInfo* origin1_info = - tracker->GetCachedOriginInfo(kOrigin1); - DatabaseTracker::CachedOriginInfo* origin2_info = - tracker->GetCachedOriginInfo(kOrigin1); - EXPECT_TRUE(origin1_info); - EXPECT_TRUE(origin2_info); + // Open three new databases. + int64_t database_size = 0; + const std::string kOrigin1 = + GetIdentifierFromOrigin(GURL(kOrigin1Url)); + const std::string kOrigin2 = + GetIdentifierFromOrigin(GURL(kOrigin2Url)); + const base::string16 kDB1 = ASCIIToUTF16("db1"); + const base::string16 kDB2 = ASCIIToUTF16("db2"); + const base::string16 kDB3 = ASCIIToUTF16("db3"); + const base::string16 kDescription = + ASCIIToUTF16("database_description"); - tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, &database_size); - EXPECT_EQ(0, database_size); - tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, 0, &database_size); - EXPECT_EQ(0, database_size); - tracker->DatabaseOpened(kOrigin1, kDB3, kDescription, 0, &database_size); - EXPECT_EQ(0, database_size); + // Get the info for kOrigin1 and kOrigin2 + DatabaseTracker::CachedOriginInfo* origin1_info = + tracker->GetCachedOriginInfo(kOrigin1); + DatabaseTracker::CachedOriginInfo* origin2_info = + tracker->GetCachedOriginInfo(kOrigin1); + EXPECT_TRUE(origin1_info); + EXPECT_TRUE(origin2_info); - // Write some data to each file and check that the listeners are - // called with the appropriate values. - EXPECT_TRUE(base::CreateDirectory(tracker->GetOriginDirectory(kOrigin1))); - EXPECT_TRUE(base::CreateDirectory(tracker->GetOriginDirectory(kOrigin2))); - EXPECT_TRUE( - base::WriteFile(tracker->GetFullDBFilePath(kOrigin1, kDB1), "a")); - EXPECT_TRUE( - base::WriteFile(tracker->GetFullDBFilePath(kOrigin2, kDB2), "aa")); - EXPECT_TRUE( - base::WriteFile(tracker->GetFullDBFilePath(kOrigin1, kDB3), "aaaa")); - tracker->DatabaseModified(kOrigin1, kDB1); - CheckNotificationReceived(&observer1, kOrigin1, kDB1, 1); - CheckNotificationReceived(&observer2, kOrigin1, kDB1, 1); - tracker->DatabaseModified(kOrigin2, kDB2); - CheckNotificationReceived(&observer1, kOrigin2, kDB2, 2); - CheckNotificationReceived(&observer2, kOrigin2, kDB2, 2); - tracker->DatabaseModified(kOrigin1, kDB3); - CheckNotificationReceived(&observer1, kOrigin1, kDB3, 4); - CheckNotificationReceived(&observer2, kOrigin1, kDB3, 4); + tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, + &database_size); + EXPECT_EQ(0, database_size); + tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, 0, + &database_size); + EXPECT_EQ(0, database_size); + tracker->DatabaseOpened(kOrigin1, kDB3, kDescription, 0, + &database_size); + EXPECT_EQ(0, database_size); - // Close all databases - tracker->DatabaseClosed(kOrigin1, kDB1); - tracker->DatabaseClosed(kOrigin2, kDB2); - tracker->DatabaseClosed(kOrigin1, kDB3); + // Write some data to each file and check that the listeners are + // called with the appropriate values. + EXPECT_TRUE( + base::CreateDirectory(tracker->GetOriginDirectory(kOrigin1))); + EXPECT_TRUE( + base::CreateDirectory(tracker->GetOriginDirectory(kOrigin2))); + EXPECT_TRUE( + base::WriteFile(tracker->GetFullDBFilePath(kOrigin1, kDB1), "a")); + EXPECT_TRUE(base::WriteFile( + tracker->GetFullDBFilePath(kOrigin2, kDB2), "aa")); + EXPECT_TRUE(base::WriteFile( + tracker->GetFullDBFilePath(kOrigin1, kDB3), "aaaa")); + tracker->DatabaseModified(kOrigin1, kDB1); + CheckNotificationReceived(&observer1, kOrigin1, kDB1, 1); + CheckNotificationReceived(&observer2, kOrigin1, kDB1, 1); + tracker->DatabaseModified(kOrigin2, kDB2); + CheckNotificationReceived(&observer1, kOrigin2, kDB2, 2); + CheckNotificationReceived(&observer2, kOrigin2, kDB2, 2); + tracker->DatabaseModified(kOrigin1, kDB3); + CheckNotificationReceived(&observer1, kOrigin1, kDB3, 4); + CheckNotificationReceived(&observer2, kOrigin1, kDB3, 4); - // Open an existing database and check the reported size - tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, &database_size); - EXPECT_EQ(1, database_size); - tracker->DatabaseClosed(kOrigin1, kDB1); + // Close all databases + tracker->DatabaseClosed(kOrigin1, kDB1); + tracker->DatabaseClosed(kOrigin2, kDB2); + tracker->DatabaseClosed(kOrigin1, kDB3); - // Remove an observer; this should clear all caches. - tracker->RemoveObserver(&observer2); + // Open an existing database and check the reported size + tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, + &database_size); + EXPECT_EQ(1, database_size); + tracker->DatabaseClosed(kOrigin1, kDB1); - // Close the tracker database and clear all caches. - // Then make sure that DatabaseOpened() still returns the correct result. - tracker->CloseTrackerDatabaseAndClearCaches(); - tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, &database_size); - EXPECT_EQ(1, database_size); - tracker->DatabaseClosed(kOrigin1, kDB1); + // Remove an observer; this should clear all caches. + tracker->RemoveObserver(&observer2); - // Remove all observers. - tracker->RemoveObserver(&observer1); + // Close the tracker database and clear all caches. + // Then make sure that DatabaseOpened() still returns the correct + // result. + tracker->CloseTrackerDatabaseAndClearCaches(); + tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, + &database_size); + EXPECT_EQ(1, database_size); + tracker->DatabaseClosed(kOrigin1, kDB1); - // Trying to delete a database in use should fail - tracker->DatabaseOpened(kOrigin1, kDB3, kDescription, 0, &database_size); - EXPECT_FALSE(tracker->DeleteClosedDatabase(kOrigin1, kDB3)); - origin1_info = tracker->GetCachedOriginInfo(kOrigin1); - EXPECT_TRUE(origin1_info); - EXPECT_EQ(4, origin1_info->GetDatabaseSize(kDB3)); - tracker->DatabaseClosed(kOrigin1, kDB3); + // Remove all observers. + tracker->RemoveObserver(&observer1); - // Delete a database and make sure the space used by that origin is updated - EXPECT_TRUE(tracker->DeleteClosedDatabase(kOrigin1, kDB3)); - origin1_info = tracker->GetCachedOriginInfo(kOrigin1); - EXPECT_TRUE(origin1_info); - EXPECT_EQ(1, origin1_info->GetDatabaseSize(kDB1)); - EXPECT_EQ(0, origin1_info->GetDatabaseSize(kDB3)); + // Trying to delete a database in use should fail + tracker->DatabaseOpened(kOrigin1, kDB3, kDescription, 0, + &database_size); + EXPECT_FALSE(tracker->DeleteClosedDatabase(kOrigin1, kDB3)); + origin1_info = tracker->GetCachedOriginInfo(kOrigin1); + EXPECT_TRUE(origin1_info); + EXPECT_EQ(4, origin1_info->GetDatabaseSize(kDB3)); + tracker->DatabaseClosed(kOrigin1, kDB3); - // Get all data for all origins - std::vector<OriginInfo> origins_info; - EXPECT_TRUE(tracker->GetAllOriginsInfo(&origins_info)); - EXPECT_EQ(size_t(2), origins_info.size()); - EXPECT_EQ(kOrigin1, origins_info[0].GetOriginIdentifier()); - EXPECT_EQ(1, origins_info[0].TotalSize()); - EXPECT_EQ(1, origins_info[0].GetDatabaseSize(kDB1)); - EXPECT_EQ(0, origins_info[0].GetDatabaseSize(kDB3)); + // Delete a database and make sure the space used by that origin is + // updated + EXPECT_TRUE(tracker->DeleteClosedDatabase(kOrigin1, kDB3)); + origin1_info = tracker->GetCachedOriginInfo(kOrigin1); + EXPECT_TRUE(origin1_info); + EXPECT_EQ(1, origin1_info->GetDatabaseSize(kDB1)); + EXPECT_EQ(0, origin1_info->GetDatabaseSize(kDB3)); - EXPECT_EQ(kOrigin2, origins_info[1].GetOriginIdentifier()); - EXPECT_EQ(2, origins_info[1].TotalSize()); + // Get all data for all origins + std::vector<OriginInfo> origins_info; + EXPECT_TRUE(tracker->GetAllOriginsInfo(&origins_info)); + EXPECT_EQ(size_t(2), origins_info.size()); + EXPECT_EQ(kOrigin1, origins_info[0].GetOriginIdentifier()); + EXPECT_EQ(1, origins_info[0].TotalSize()); + EXPECT_EQ(1, origins_info[0].GetDatabaseSize(kDB1)); + EXPECT_EQ(0, origins_info[0].GetDatabaseSize(kDB3)); - // Trying to delete an origin with databases in use should fail - tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, &database_size); - EXPECT_FALSE(tracker->DeleteOrigin(kOrigin1, false)); - origin1_info = tracker->GetCachedOriginInfo(kOrigin1); - EXPECT_TRUE(origin1_info); - EXPECT_EQ(1, origin1_info->GetDatabaseSize(kDB1)); - tracker->DatabaseClosed(kOrigin1, kDB1); + EXPECT_EQ(kOrigin2, origins_info[1].GetOriginIdentifier()); + EXPECT_EQ(2, origins_info[1].TotalSize()); - // Delete an origin that doesn't have any database in use - EXPECT_TRUE(tracker->DeleteOrigin(kOrigin1, false)); - origins_info.clear(); - EXPECT_TRUE(tracker->GetAllOriginsInfo(&origins_info)); - EXPECT_EQ(size_t(1), origins_info.size()); - EXPECT_EQ(kOrigin2, origins_info[0].GetOriginIdentifier()); + // Trying to delete an origin with databases in use should fail + tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, + &database_size); + EXPECT_FALSE(tracker->DeleteOrigin(kOrigin1, false)); + origin1_info = tracker->GetCachedOriginInfo(kOrigin1); + EXPECT_TRUE(origin1_info); + EXPECT_EQ(1, origin1_info->GetDatabaseSize(kDB1)); + tracker->DatabaseClosed(kOrigin1, kDB1); - origin1_info = tracker->GetCachedOriginInfo(kOrigin1); - EXPECT_TRUE(origin1_info); - EXPECT_EQ(0, origin1_info->TotalSize()); + // Delete an origin that doesn't have any database in use + EXPECT_TRUE(tracker->DeleteOrigin(kOrigin1, false)); + origins_info.clear(); + EXPECT_TRUE(tracker->GetAllOriginsInfo(&origins_info)); + EXPECT_EQ(size_t(1), origins_info.size()); + EXPECT_EQ(kOrigin2, origins_info[0].GetOriginIdentifier()); + + origin1_info = tracker->GetCachedOriginInfo(kOrigin1); + EXPECT_TRUE(origin1_info); + EXPECT_EQ(0, origin1_info->TotalSize()); + })); + run_loop.Run(); } static void DatabaseTrackerQuotaIntegration(bool incognito_mode) { @@ -424,93 +468,108 @@ base::MakeRefCounted<DatabaseTracker>(temp_dir.GetPath(), incognito_mode, nullptr, test_quota_proxy.get())); - tracker->set_task_runner_for_testing( - base::SequencedTaskRunnerHandle::Get()); + base::RunLoop run_loop; + tracker->task_runner()->PostTask( + FROM_HERE, base::BindLambdaForTesting([&]() { + base::ScopedClosureRunner quit_runner( + base::BindLambdaForTesting([&]() { run_loop.Quit(); })); - EXPECT_TRUE(test_quota_proxy->registered_client_); + EXPECT_TRUE(test_quota_proxy->registered_client_); - // Create a database and modify it a couple of times, close it, - // then delete it. Observe the tracker notifies accordingly. + // Create a database and modify it a couple of times, close it, + // then delete it. Observe the tracker notifies accordingly. - int64_t database_size = 0; - tracker->DatabaseOpened(kOriginId, kName, kDescription, 0, &database_size); - EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kOrigin)); - test_quota_proxy->reset(); + int64_t database_size = 0; + tracker->DatabaseOpened(kOriginId, kName, kDescription, 0, + &database_size); + EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kOrigin)); + test_quota_proxy->reset(); - base::FilePath db_file(tracker->GetFullDBFilePath(kOriginId, kName)); - EXPECT_FALSE(base::PathExists(tracker->GetOriginDirectory(kOriginId))); - EXPECT_TRUE(base::CreateDirectory(db_file.DirName())); - EXPECT_TRUE(EnsureFileOfSize(db_file, 10)); - EXPECT_TRUE(base::PathExists(tracker->GetOriginDirectory(kOriginId))); - tracker->DatabaseModified(kOriginId, kName); - EXPECT_TRUE(test_quota_proxy->WasModificationNotified(kOrigin, 10)); - test_quota_proxy->reset(); + base::FilePath db_file(tracker->GetFullDBFilePath(kOriginId, kName)); + EXPECT_FALSE( + base::PathExists(tracker->GetOriginDirectory(kOriginId))); + EXPECT_TRUE(base::CreateDirectory(db_file.DirName())); + EXPECT_TRUE(EnsureFileOfSize(db_file, 10)); + EXPECT_TRUE(base::PathExists(tracker->GetOriginDirectory(kOriginId))); + tracker->DatabaseModified(kOriginId, kName); + EXPECT_TRUE(test_quota_proxy->WasModificationNotified(kOrigin, 10)); + test_quota_proxy->reset(); - EXPECT_TRUE(EnsureFileOfSize(db_file, 100)); - tracker->DatabaseModified(kOriginId, kName); - EXPECT_TRUE(test_quota_proxy->WasModificationNotified(kOrigin, 90)); - test_quota_proxy->reset(); + EXPECT_TRUE(EnsureFileOfSize(db_file, 100)); + tracker->DatabaseModified(kOriginId, kName); + EXPECT_TRUE(test_quota_proxy->WasModificationNotified(kOrigin, 90)); + test_quota_proxy->reset(); - tracker->DatabaseClosed(kOriginId, kName); - EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kOrigin)); - EXPECT_EQ(net::OK, tracker->DeleteDatabase(kOriginId, kName, - net::CompletionOnceCallback())); - EXPECT_TRUE(test_quota_proxy->WasModificationNotified(kOrigin, -100)); - test_quota_proxy->reset(); + tracker->DatabaseClosed(kOriginId, kName); + EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kOrigin)); + EXPECT_EQ(net::OK, + tracker->DeleteDatabase(kOriginId, kName, + net::CompletionOnceCallback())); + EXPECT_TRUE(test_quota_proxy->WasModificationNotified(kOrigin, -100)); + test_quota_proxy->reset(); - EXPECT_FALSE(base::PathExists(tracker->GetOriginDirectory(kOriginId))); + EXPECT_FALSE( + base::PathExists(tracker->GetOriginDirectory(kOriginId))); - // Create a database and modify it, try to delete it while open, - // then close it (at which time deletion will actually occur). - // Observe the tracker notifies accordingly. + // Create a database and modify it, try to delete it while open, + // then close it (at which time deletion will actually occur). + // Observe the tracker notifies accordingly. - tracker->DatabaseOpened(kOriginId, kName, kDescription, 0, &database_size); - EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kOrigin)); - test_quota_proxy->reset(); + tracker->DatabaseOpened(kOriginId, kName, kDescription, 0, + &database_size); + EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kOrigin)); + test_quota_proxy->reset(); - db_file = tracker->GetFullDBFilePath(kOriginId, kName); - EXPECT_FALSE(base::PathExists(tracker->GetOriginDirectory(kOriginId))); - EXPECT_TRUE(base::CreateDirectory(db_file.DirName())); - EXPECT_TRUE(EnsureFileOfSize(db_file, 100)); - EXPECT_TRUE(base::PathExists(tracker->GetOriginDirectory(kOriginId))); - tracker->DatabaseModified(kOriginId, kName); - EXPECT_TRUE(test_quota_proxy->WasModificationNotified(kOrigin, 100)); - test_quota_proxy->reset(); + db_file = tracker->GetFullDBFilePath(kOriginId, kName); + EXPECT_FALSE( + base::PathExists(tracker->GetOriginDirectory(kOriginId))); + EXPECT_TRUE(base::CreateDirectory(db_file.DirName())); + EXPECT_TRUE(EnsureFileOfSize(db_file, 100)); + EXPECT_TRUE(base::PathExists(tracker->GetOriginDirectory(kOriginId))); + tracker->DatabaseModified(kOriginId, kName); + EXPECT_TRUE(test_quota_proxy->WasModificationNotified(kOrigin, 100)); + test_quota_proxy->reset(); - EXPECT_EQ(net::ERR_IO_PENDING, - tracker->DeleteDatabase(kOriginId, kName, - net::CompletionOnceCallback())); - EXPECT_FALSE(test_quota_proxy->WasModificationNotified(kOrigin, -100)); - EXPECT_TRUE(base::PathExists(tracker->GetOriginDirectory(kOriginId))); + EXPECT_EQ(net::ERR_IO_PENDING, + tracker->DeleteDatabase(kOriginId, kName, + net::CompletionOnceCallback())); + EXPECT_FALSE( + test_quota_proxy->WasModificationNotified(kOrigin, -100)); + EXPECT_TRUE(base::PathExists(tracker->GetOriginDirectory(kOriginId))); - tracker->DatabaseClosed(kOriginId, kName); - EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kOrigin)); - EXPECT_TRUE(test_quota_proxy->WasModificationNotified(kOrigin, -100)); - EXPECT_FALSE(base::PathExists(tracker->GetOriginDirectory(kOriginId))); - test_quota_proxy->reset(); + tracker->DatabaseClosed(kOriginId, kName); + EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kOrigin)); + EXPECT_TRUE(test_quota_proxy->WasModificationNotified(kOrigin, -100)); + EXPECT_FALSE( + base::PathExists(tracker->GetOriginDirectory(kOriginId))); + test_quota_proxy->reset(); - // Create a database and up the file size without telling - // the tracker about the modification, than simulate a - // a renderer crash. - // Observe the tracker notifies accordingly. + // Create a database and up the file size without telling + // the tracker about the modification, than simulate a + // a renderer crash. + // Observe the tracker notifies accordingly. - tracker->DatabaseOpened(kOriginId, kName, kDescription, 0, &database_size); - EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kOrigin)); - test_quota_proxy->reset(); - db_file = tracker->GetFullDBFilePath(kOriginId, kName); - EXPECT_FALSE(base::PathExists(tracker->GetOriginDirectory(kOriginId))); - EXPECT_TRUE(base::CreateDirectory(db_file.DirName())); - EXPECT_TRUE(base::PathExists(tracker->GetOriginDirectory(kOriginId))); - EXPECT_TRUE(EnsureFileOfSize(db_file, 100)); - DatabaseConnections crashed_renderer_connections; - crashed_renderer_connections.AddConnection(kOriginId, kName); - EXPECT_FALSE(test_quota_proxy->WasModificationNotified(kOrigin, 100)); - tracker->CloseDatabases(crashed_renderer_connections); - EXPECT_TRUE(test_quota_proxy->WasModificationNotified(kOrigin, 100)); + tracker->DatabaseOpened(kOriginId, kName, kDescription, 0, + &database_size); + EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kOrigin)); + test_quota_proxy->reset(); + db_file = tracker->GetFullDBFilePath(kOriginId, kName); + EXPECT_FALSE( + base::PathExists(tracker->GetOriginDirectory(kOriginId))); + EXPECT_TRUE(base::CreateDirectory(db_file.DirName())); + EXPECT_TRUE(base::PathExists(tracker->GetOriginDirectory(kOriginId))); + EXPECT_TRUE(EnsureFileOfSize(db_file, 100)); + DatabaseConnections crashed_renderer_connections; + crashed_renderer_connections.AddConnection(kOriginId, kName); + EXPECT_FALSE(test_quota_proxy->WasModificationNotified(kOrigin, 100)); + tracker->CloseDatabases(crashed_renderer_connections); + EXPECT_TRUE(test_quota_proxy->WasModificationNotified(kOrigin, 100)); - // Cleanup. - crashed_renderer_connections.RemoveAllConnections(); - test_quota_proxy->SimulateQuotaManagerDestroyed(); + // Cleanup. + crashed_renderer_connections.RemoveAllConnections(); + test_quota_proxy->SimulateQuotaManagerDestroyed(); + })); + run_loop.Run(); } static void DatabaseTrackerClearSessionOnlyDatabasesOnExit() { @@ -535,60 +594,77 @@ base::MakeRefCounted<DatabaseTracker>(temp_dir.GetPath(), false, special_storage_policy.get(), nullptr)); - tracker->set_task_runner_for_testing( - base::SequencedTaskRunnerHandle::Get()); + base::RunLoop run_loop; + tracker->task_runner()->PostTask( + FROM_HERE, base::BindLambdaForTesting([&]() { + base::ScopedClosureRunner quit_runner( + base::BindLambdaForTesting([&]() { run_loop.Quit(); })); - // Open two new databases. - tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, &database_size); - EXPECT_EQ(0, database_size); - tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, 0, &database_size); - EXPECT_EQ(0, database_size); + // Open two new databases. + tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, + &database_size); + EXPECT_EQ(0, database_size); + tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, 0, + &database_size); + EXPECT_EQ(0, database_size); - // Write some data to each file. - base::FilePath db_file; - db_file = tracker->GetFullDBFilePath(kOrigin1, kDB1); - EXPECT_TRUE(base::CreateDirectory(db_file.DirName())); - EXPECT_TRUE(EnsureFileOfSize(db_file, 1)); + // Write some data to each file. + base::FilePath db_file; + db_file = tracker->GetFullDBFilePath(kOrigin1, kDB1); + EXPECT_TRUE(base::CreateDirectory(db_file.DirName())); + EXPECT_TRUE(EnsureFileOfSize(db_file, 1)); - db_file = tracker->GetFullDBFilePath(kOrigin2, kDB2); - EXPECT_TRUE(base::CreateDirectory(db_file.DirName())); - EXPECT_TRUE(EnsureFileOfSize(db_file, 2)); + db_file = tracker->GetFullDBFilePath(kOrigin2, kDB2); + EXPECT_TRUE(base::CreateDirectory(db_file.DirName())); + EXPECT_TRUE(EnsureFileOfSize(db_file, 2)); - // Store the origin database directories as long as they still exist. - origin1_db_dir = tracker->GetFullDBFilePath(kOrigin1, kDB1).DirName(); - origin2_db_dir = tracker->GetFullDBFilePath(kOrigin2, kDB2).DirName(); + // Store the origin database directories as long as they still + // exist. + origin1_db_dir = + tracker->GetFullDBFilePath(kOrigin1, kDB1).DirName(); + origin2_db_dir = + tracker->GetFullDBFilePath(kOrigin2, kDB2).DirName(); - tracker->DatabaseModified(kOrigin1, kDB1); - tracker->DatabaseModified(kOrigin2, kDB2); + tracker->DatabaseModified(kOrigin1, kDB1); + tracker->DatabaseModified(kOrigin2, kDB2); - // Close all databases. - tracker->DatabaseClosed(kOrigin1, kDB1); - tracker->DatabaseClosed(kOrigin2, kDB2); + // Close all databases. + tracker->DatabaseClosed(kOrigin1, kDB1); + tracker->DatabaseClosed(kOrigin2, kDB2); - tracker->Shutdown(); + tracker->Shutdown(); + })); + run_loop.Run(); } // At this point, the database tracker should be gone. Create a new one. scoped_refptr<DatabaseTracker> tracker( base::MakeRefCounted<DatabaseTracker>(temp_dir.GetPath(), false, nullptr, nullptr)); - tracker->set_task_runner_for_testing( - base::SequencedTaskRunnerHandle::Get()); + base::RunLoop run_loop; + tracker->task_runner()->PostTask( + FROM_HERE, base::BindLambdaForTesting([&]() { + base::ScopedClosureRunner quit_runner( + base::BindLambdaForTesting([&]() { run_loop.Quit(); })); - // Get all data for all origins. - std::vector<OriginInfo> origins_info; - EXPECT_TRUE(tracker->GetAllOriginsInfo(&origins_info)); - // kOrigin1 was not session-only, so it survived. kOrigin2 was session-only - // and it got deleted. - EXPECT_EQ(size_t(1), origins_info.size()); - EXPECT_EQ(kOrigin1, origins_info[0].GetOriginIdentifier()); - EXPECT_TRUE(base::PathExists(tracker->GetFullDBFilePath(kOrigin1, kDB1))); - EXPECT_EQ(base::FilePath(), tracker->GetFullDBFilePath(kOrigin2, kDB2)); + // Get all data for all origins. + std::vector<OriginInfo> origins_info; + EXPECT_TRUE(tracker->GetAllOriginsInfo(&origins_info)); + // kOrigin1 was not session-only, so it survived. kOrigin2 was + // session-only and it got deleted. + EXPECT_EQ(size_t(1), origins_info.size()); + EXPECT_EQ(kOrigin1, origins_info[0].GetOriginIdentifier()); + EXPECT_TRUE( + base::PathExists(tracker->GetFullDBFilePath(kOrigin1, kDB1))); + EXPECT_EQ(base::FilePath(), + tracker->GetFullDBFilePath(kOrigin2, kDB2)); - // The origin directory of kOrigin1 remains, but the origin directory of - // kOrigin2 is deleted. - EXPECT_TRUE(base::PathExists(origin1_db_dir)); - EXPECT_FALSE(base::PathExists(origin2_db_dir)); + // The origin directory of kOrigin1 remains, but the origin directory + // of kOrigin2 is deleted. + EXPECT_TRUE(base::PathExists(origin1_db_dir)); + EXPECT_FALSE(base::PathExists(origin2_db_dir)); + })); + run_loop.Run(); } static void DatabaseTrackerSetForceKeepSessionState() { @@ -613,57 +689,75 @@ base::MakeRefCounted<DatabaseTracker>(temp_dir.GetPath(), false, special_storage_policy.get(), nullptr)); - tracker->set_task_runner_for_testing( - base::SequencedTaskRunnerHandle::Get()); - tracker->SetForceKeepSessionState(); + base::RunLoop run_loop; + tracker->task_runner()->PostTask( + FROM_HERE, base::BindLambdaForTesting([&]() { + base::ScopedClosureRunner quit_runner( + base::BindLambdaForTesting([&]() { run_loop.Quit(); })); - // Open two new databases. - tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, &database_size); - EXPECT_EQ(0, database_size); - tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, 0, &database_size); - EXPECT_EQ(0, database_size); + tracker->SetForceKeepSessionState(); - // Write some data to each file. - base::FilePath db_file; - db_file = tracker->GetFullDBFilePath(kOrigin1, kDB1); - EXPECT_TRUE(base::CreateDirectory(db_file.DirName())); - EXPECT_TRUE(EnsureFileOfSize(db_file, 1)); + // Open two new databases. + tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, + &database_size); + EXPECT_EQ(0, database_size); + tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, 0, + &database_size); + EXPECT_EQ(0, database_size); - db_file = tracker->GetFullDBFilePath(kOrigin2, kDB2); - EXPECT_TRUE(base::CreateDirectory(db_file.DirName())); - EXPECT_TRUE(EnsureFileOfSize(db_file, 2)); + // Write some data to each file. + base::FilePath db_file; + db_file = tracker->GetFullDBFilePath(kOrigin1, kDB1); + EXPECT_TRUE(base::CreateDirectory(db_file.DirName())); + EXPECT_TRUE(EnsureFileOfSize(db_file, 1)); - // Store the origin database directories as long as they still exist. - origin1_db_dir = tracker->GetFullDBFilePath(kOrigin1, kDB1).DirName(); - origin2_db_dir = tracker->GetFullDBFilePath(kOrigin2, kDB2).DirName(); + db_file = tracker->GetFullDBFilePath(kOrigin2, kDB2); + EXPECT_TRUE(base::CreateDirectory(db_file.DirName())); + EXPECT_TRUE(EnsureFileOfSize(db_file, 2)); - tracker->DatabaseModified(kOrigin1, kDB1); - tracker->DatabaseModified(kOrigin2, kDB2); + // Store the origin database directories as long as they still + // exist. + origin1_db_dir = + tracker->GetFullDBFilePath(kOrigin1, kDB1).DirName(); + origin2_db_dir = + tracker->GetFullDBFilePath(kOrigin2, kDB2).DirName(); - // Close all databases. - tracker->DatabaseClosed(kOrigin1, kDB1); - tracker->DatabaseClosed(kOrigin2, kDB2); + tracker->DatabaseModified(kOrigin1, kDB1); + tracker->DatabaseModified(kOrigin2, kDB2); - tracker->Shutdown(); + // Close all databases. + tracker->DatabaseClosed(kOrigin1, kDB1); + tracker->DatabaseClosed(kOrigin2, kDB2); + + tracker->Shutdown(); + })); + run_loop.Run(); } // At this point, the database tracker should be gone. Create a new one. scoped_refptr<DatabaseTracker> tracker( base::MakeRefCounted<DatabaseTracker>(temp_dir.GetPath(), false, nullptr, nullptr)); - tracker->set_task_runner_for_testing( - base::SequencedTaskRunnerHandle::Get()); + base::RunLoop run_loop; + tracker->task_runner()->PostTask( + FROM_HERE, base::BindLambdaForTesting([&]() { + base::ScopedClosureRunner quit_runner( + base::BindLambdaForTesting([&]() { run_loop.Quit(); })); - // Get all data for all origins. - std::vector<OriginInfo> origins_info; - EXPECT_TRUE(tracker->GetAllOriginsInfo(&origins_info)); - // No origins were deleted. - EXPECT_EQ(size_t(2), origins_info.size()); - EXPECT_TRUE(base::PathExists(tracker->GetFullDBFilePath(kOrigin1, kDB1))); - EXPECT_TRUE(base::PathExists(tracker->GetFullDBFilePath(kOrigin2, kDB2))); + // Get all data for all origins. + std::vector<OriginInfo> origins_info; + EXPECT_TRUE(tracker->GetAllOriginsInfo(&origins_info)); + // No origins were deleted. + EXPECT_EQ(size_t(2), origins_info.size()); + EXPECT_TRUE( + base::PathExists(tracker->GetFullDBFilePath(kOrigin1, kDB1))); + EXPECT_TRUE( + base::PathExists(tracker->GetFullDBFilePath(kOrigin2, kDB2))); - EXPECT_TRUE(base::PathExists(origin1_db_dir)); - EXPECT_TRUE(base::PathExists(origin2_db_dir)); + EXPECT_TRUE(base::PathExists(origin1_db_dir)); + EXPECT_TRUE(base::PathExists(origin2_db_dir)); + })); + run_loop.Run(); } static void EmptyDatabaseNameIsValid() { @@ -682,39 +776,47 @@ scoped_refptr<DatabaseTracker> tracker( base::MakeRefCounted<DatabaseTracker>( temp_dir.GetPath(), kUseInMemoryTrackerDatabase, nullptr, nullptr)); - tracker->set_task_runner_for_testing( - base::SequencedTaskRunnerHandle::Get()); + base::RunLoop run_loop; + tracker->task_runner()->PostTask( + FROM_HERE, base::BindLambdaForTesting([&]() { + base::ScopedClosureRunner quit_runner( + base::BindLambdaForTesting([&]() { run_loop.Quit(); })); - // Starts off with no databases. - std::vector<OriginInfo> infos; - EXPECT_TRUE(tracker->GetAllOriginsInfo(&infos)); - EXPECT_TRUE(infos.empty()); + // Starts off with no databases. + std::vector<OriginInfo> infos; + EXPECT_TRUE(tracker->GetAllOriginsInfo(&infos)); + EXPECT_TRUE(infos.empty()); - // Create a db with an empty name. - int64_t database_size = -1; - tracker->DatabaseOpened(kOriginId, kEmptyName, kDescription, 0, - &database_size); - EXPECT_EQ(0, database_size); - tracker->DatabaseModified(kOriginId, kEmptyName); - EXPECT_TRUE(tracker->GetAllOriginsInfo(&infos)); - EXPECT_EQ(1u, infos.size()); - EXPECT_EQ(kDescription, infos[0].GetDatabaseDescription(kEmptyName)); - EXPECT_FALSE(tracker->GetFullDBFilePath(kOriginId, kEmptyName).empty()); - tracker->DatabaseOpened(kOriginId, kEmptyName, kChangedDescription, 0, - &database_size); - infos.clear(); - EXPECT_TRUE(tracker->GetAllOriginsInfo(&infos)); - EXPECT_EQ(1u, infos.size()); - EXPECT_EQ(kChangedDescription, infos[0].GetDatabaseDescription(kEmptyName)); - tracker->DatabaseClosed(kOriginId, kEmptyName); - tracker->DatabaseClosed(kOriginId, kEmptyName); + // Create a db with an empty name. + int64_t database_size = -1; + tracker->DatabaseOpened(kOriginId, kEmptyName, kDescription, 0, + &database_size); + EXPECT_EQ(0, database_size); + tracker->DatabaseModified(kOriginId, kEmptyName); + EXPECT_TRUE(tracker->GetAllOriginsInfo(&infos)); + EXPECT_EQ(1u, infos.size()); + EXPECT_EQ(kDescription, infos[0].GetDatabaseDescription(kEmptyName)); + EXPECT_FALSE( + tracker->GetFullDBFilePath(kOriginId, kEmptyName).empty()); + tracker->DatabaseOpened(kOriginId, kEmptyName, kChangedDescription, 0, + &database_size); + infos.clear(); + EXPECT_TRUE(tracker->GetAllOriginsInfo(&infos)); + EXPECT_EQ(1u, infos.size()); + EXPECT_EQ(kChangedDescription, + infos[0].GetDatabaseDescription(kEmptyName)); + tracker->DatabaseClosed(kOriginId, kEmptyName); + tracker->DatabaseClosed(kOriginId, kEmptyName); - // Deleting it should return to the initial state. - EXPECT_EQ(net::OK, tracker->DeleteDatabase(kOriginId, kEmptyName, - net::CompletionOnceCallback())); - infos.clear(); - EXPECT_TRUE(tracker->GetAllOriginsInfo(&infos)); - EXPECT_TRUE(infos.empty()); + // Deleting it should return to the initial state. + EXPECT_EQ(net::OK, + tracker->DeleteDatabase(kOriginId, kEmptyName, + net::CompletionOnceCallback())); + infos.clear(); + EXPECT_TRUE(tracker->GetAllOriginsInfo(&infos)); + EXPECT_TRUE(infos.empty()); + })); + run_loop.Run(); } static void HandleSqliteError() { @@ -731,66 +833,78 @@ scoped_refptr<DatabaseTracker> tracker( base::MakeRefCounted<DatabaseTracker>( temp_dir.GetPath(), kUseInMemoryTrackerDatabase, nullptr, nullptr)); - tracker->set_task_runner_for_testing( - base::SequencedTaskRunnerHandle::Get()); + base::RunLoop run_loop; + tracker->task_runner()->PostTask( + FROM_HERE, base::BindLambdaForTesting([&]() { + base::ScopedClosureRunner quit_runner( + base::BindLambdaForTesting([&]() { run_loop.Quit(); })); - // Setup to observe OnScheduledForDelete notifications. - TestObserver observer(false, true); - tracker->AddObserver(&observer); + // Setup to observe OnScheduledForDelete notifications. + TestObserver observer(false, true); + tracker->AddObserver(&observer); - // Verify does no harm when there is no such database. - tracker->HandleSqliteError(kOriginId, kName, SQLITE_CORRUPT); - EXPECT_FALSE(tracker->IsDatabaseScheduledForDeletion(kOriginId, kName)); - EXPECT_FALSE(observer.DidReceiveNewNotification()); + // Verify does no harm when there is no such database. + tracker->HandleSqliteError(kOriginId, kName, SQLITE_CORRUPT); + EXPECT_FALSE( + tracker->IsDatabaseScheduledForDeletion(kOriginId, kName)); + EXPECT_FALSE(observer.DidReceiveNewNotification()); - // -------------------------------------------------------- - // Create a record of a database in the tracker db and create - // a spoof_db_file on disk in the expected location. - int64_t database_size = 0; - tracker->DatabaseOpened(kOriginId, kName, kDescription, 0, &database_size); - base::FilePath spoof_db_file = tracker->GetFullDBFilePath(kOriginId, kName); - EXPECT_FALSE(tracker->GetFullDBFilePath(kOriginId, kName).empty()); - EXPECT_TRUE(base::CreateDirectory(spoof_db_file.DirName())); - EXPECT_TRUE(EnsureFileOfSize(spoof_db_file, 1)); + // -------------------------------------------------------- + // Create a record of a database in the tracker db and create + // a spoof_db_file on disk in the expected location. + int64_t database_size = 0; + tracker->DatabaseOpened(kOriginId, kName, kDescription, 0, + &database_size); + base::FilePath spoof_db_file = + tracker->GetFullDBFilePath(kOriginId, kName); + EXPECT_FALSE(tracker->GetFullDBFilePath(kOriginId, kName).empty()); + EXPECT_TRUE(base::CreateDirectory(spoof_db_file.DirName())); + EXPECT_TRUE(EnsureFileOfSize(spoof_db_file, 1)); - // Verify does no harm with a non-error is reported. - tracker->HandleSqliteError(kOriginId, kName, SQLITE_OK); - EXPECT_FALSE(tracker->IsDatabaseScheduledForDeletion(kOriginId, kName)); - EXPECT_FALSE(observer.DidReceiveNewNotification()); + // Verify does no harm with a non-error is reported. + tracker->HandleSqliteError(kOriginId, kName, SQLITE_OK); + EXPECT_FALSE( + tracker->IsDatabaseScheduledForDeletion(kOriginId, kName)); + EXPECT_FALSE(observer.DidReceiveNewNotification()); - // Verify that with a connection open, the db is scheduled for deletion, - // but that the file still exists. - tracker->HandleSqliteError(kOriginId, kName, SQLITE_CORRUPT); - EXPECT_TRUE(tracker->IsDatabaseScheduledForDeletion(kOriginId, kName)); - EXPECT_TRUE(observer.DidReceiveNewNotification()); - EXPECT_TRUE(base::PathExists(spoof_db_file)); + // Verify that with a connection open, the db is scheduled for + // deletion, but that the file still exists. + tracker->HandleSqliteError(kOriginId, kName, SQLITE_CORRUPT); + EXPECT_TRUE( + tracker->IsDatabaseScheduledForDeletion(kOriginId, kName)); + EXPECT_TRUE(observer.DidReceiveNewNotification()); + EXPECT_TRUE(base::PathExists(spoof_db_file)); - // Verify that once closed, the file is deleted and the record in the - // tracker db is removed. - tracker->DatabaseClosed(kOriginId, kName); - EXPECT_FALSE(base::PathExists(spoof_db_file)); - EXPECT_TRUE(tracker->GetFullDBFilePath(kOriginId, kName).empty()); + // Verify that once closed, the file is deleted and the record in the + // tracker db is removed. + tracker->DatabaseClosed(kOriginId, kName); + EXPECT_FALSE(base::PathExists(spoof_db_file)); + EXPECT_TRUE(tracker->GetFullDBFilePath(kOriginId, kName).empty()); - // -------------------------------------------------------- - // Create another record of a database in the tracker db and create - // a spoof_db_file on disk in the expected location. - tracker->DatabaseOpened(kOriginId, kName, kDescription, 0, &database_size); - base::FilePath spoof_db_file2 = - tracker->GetFullDBFilePath(kOriginId, kName); - EXPECT_FALSE(tracker->GetFullDBFilePath(kOriginId, kName).empty()); - EXPECT_NE(spoof_db_file, spoof_db_file2); - EXPECT_TRUE(base::CreateDirectory(spoof_db_file2.DirName())); - EXPECT_TRUE(EnsureFileOfSize(spoof_db_file2, 1)); + // -------------------------------------------------------- + // Create another record of a database in the tracker db and create + // a spoof_db_file on disk in the expected location. + tracker->DatabaseOpened(kOriginId, kName, kDescription, 0, + &database_size); + base::FilePath spoof_db_file2 = + tracker->GetFullDBFilePath(kOriginId, kName); + EXPECT_FALSE(tracker->GetFullDBFilePath(kOriginId, kName).empty()); + EXPECT_NE(spoof_db_file, spoof_db_file2); + EXPECT_TRUE(base::CreateDirectory(spoof_db_file2.DirName())); + EXPECT_TRUE(EnsureFileOfSize(spoof_db_file2, 1)); - // Verify that with no connection open, the db is deleted immediately. - tracker->DatabaseClosed(kOriginId, kName); - tracker->HandleSqliteError(kOriginId, kName, SQLITE_CORRUPT); - EXPECT_FALSE(tracker->IsDatabaseScheduledForDeletion(kOriginId, kName)); - EXPECT_FALSE(observer.DidReceiveNewNotification()); - EXPECT_TRUE(tracker->GetFullDBFilePath(kOriginId, kName).empty()); - EXPECT_FALSE(base::PathExists(spoof_db_file2)); + // Verify that with no connection open, the db is deleted immediately. + tracker->DatabaseClosed(kOriginId, kName); + tracker->HandleSqliteError(kOriginId, kName, SQLITE_CORRUPT); + EXPECT_FALSE( + tracker->IsDatabaseScheduledForDeletion(kOriginId, kName)); + EXPECT_FALSE(observer.DidReceiveNewNotification()); + EXPECT_TRUE(tracker->GetFullDBFilePath(kOriginId, kName).empty()); + EXPECT_FALSE(base::PathExists(spoof_db_file2)); - tracker->RemoveObserver(&observer); + tracker->RemoveObserver(&observer); + })); + run_loop.Run(); } };
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index 1bd6e930..02c8b036 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -1723,6 +1723,7 @@ }, "Android arm Builder (dbg)": { "additional_compile_targets": [ + "boundary_interface_example_apk", "dump_syms", "microdump_stackwalk" ],
diff --git a/testing/buildbot/chromium.ci.json b/testing/buildbot/chromium.ci.json index 7418ba7..5f0fc81 100644 --- a/testing/buildbot/chromium.ci.json +++ b/testing/buildbot/chromium.ci.json
@@ -13129,6 +13129,7 @@ }, "Android arm Builder (dbg)": { "additional_compile_targets": [ + "boundary_interface_example_apk", "dump_syms", "microdump_stackwalk" ], @@ -20059,7 +20060,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -20081,10 +20083,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -20107,9 +20110,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -20132,10 +20136,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -20158,10 +20163,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -20184,9 +20190,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -20209,9 +20216,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -20370,7 +20378,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -20392,10 +20401,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -20418,9 +20428,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -20443,10 +20454,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -20469,10 +20481,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -20495,9 +20508,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -20520,9 +20534,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -20681,7 +20696,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -20703,10 +20719,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -20729,9 +20746,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -20754,10 +20772,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -20780,10 +20799,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -20806,9 +20826,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -20831,9 +20852,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -20947,7 +20969,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -20969,10 +20992,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -20995,9 +21019,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -21020,10 +21045,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -21046,10 +21072,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -21072,9 +21099,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -21097,9 +21125,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -21215,7 +21244,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -21238,10 +21268,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -21265,9 +21296,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -21291,10 +21323,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -21318,10 +21351,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -21345,9 +21379,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -21371,9 +21406,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -21535,7 +21571,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -21556,10 +21593,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -21581,9 +21619,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -21605,10 +21644,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -21630,10 +21670,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -21655,9 +21696,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -21679,9 +21721,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -21831,7 +21874,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -21854,10 +21898,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -21881,9 +21926,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -21907,10 +21953,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -21934,10 +21981,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -21961,9 +22009,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -21987,9 +22036,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -22105,7 +22155,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -22126,10 +22177,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -22151,9 +22203,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -22175,10 +22228,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -22200,10 +22254,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -22225,9 +22280,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -22249,9 +22305,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -22361,7 +22418,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -22383,10 +22441,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -22409,9 +22468,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -22434,10 +22494,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -22460,10 +22521,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -22486,9 +22548,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -22511,9 +22574,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -22671,7 +22735,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -22693,10 +22758,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -22719,9 +22785,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -22744,10 +22811,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -22770,10 +22838,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -22796,9 +22865,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -22821,9 +22891,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -22981,7 +23052,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -23003,10 +23075,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -23029,9 +23102,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -23054,10 +23128,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -23080,10 +23155,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -23106,9 +23182,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -23131,9 +23208,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -23247,7 +23325,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -23269,10 +23348,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -23295,9 +23375,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -23320,10 +23401,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -23346,10 +23428,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -23372,9 +23455,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -23397,9 +23481,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -23515,7 +23600,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -23537,10 +23623,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -23563,9 +23650,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -23588,10 +23676,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -23614,10 +23703,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -23640,9 +23730,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -23665,9 +23756,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -23823,7 +23915,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -23845,10 +23938,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -23871,9 +23965,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -23896,10 +23991,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -23922,10 +24018,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -23948,9 +24045,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -23973,9 +24071,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -24131,7 +24230,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -24153,10 +24253,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -24179,9 +24280,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -24204,10 +24306,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -24230,10 +24333,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -24256,9 +24360,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -24281,9 +24386,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -24395,7 +24501,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -24417,10 +24524,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -24443,9 +24551,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -24468,10 +24577,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -24494,10 +24604,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -24520,9 +24631,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -24545,9 +24657,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -24888,6 +25001,26 @@ "test_id_prefix": "ninja://fuchsia/runners:cast_runner_unittests/" }, { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-16.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 2 + }, + "test": "cc_unittests", + "test_id_prefix": "ninja://cc:cc_unittests/" + }, + { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.content_unittests.filter" ], @@ -25759,6 +25892,28 @@ }, { "args": [ + "--device=aemu" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-16.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 2 + }, + "test": "cc_unittests", + "test_id_prefix": "ninja://cc:cc_unittests/" + }, + { + "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.content_unittests.filter", "--device=aemu" ], @@ -26112,7 +26267,8 @@ "os": "Ubuntu-16.04" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 4 }, "test": "net_unittests", "test_id_prefix": "ninja://net:net_unittests/" @@ -129100,6 +129256,7 @@ ], "scripts": [ { + "isolate_profile_data": true, "name": "check_network_annotations", "script": "check_network_annotations.py", "swarming": {} @@ -147066,6 +147223,7 @@ "--use-gpu-in-tests", "--test-launcher-retry-limit=0" ], + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -147102,6 +147260,7 @@ "--test-launcher-jobs=1", "--gtest_filter=CastStreamingApiTestWithPixelOutput.EndToEnd*:TabCaptureApiPixelTest.EndToEnd*" ], + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -147135,6 +147294,7 @@ "args": [ "--use-gpu-in-tests" ], + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -147167,6 +147327,7 @@ "args": [ "--use-gpu-in-tests" ], + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -147199,6 +147360,7 @@ "args": [ "--ignore-runtime-requirements=*" ], + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -147240,6 +147402,7 @@ "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" ], "isolate_name": "telemetry_gpu_integration_test", + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -147280,6 +147443,7 @@ "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" ], "isolate_name": "telemetry_gpu_integration_test", + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -147321,6 +147485,7 @@ "--dont-restore-color-profile-after-test" ], "isolate_name": "telemetry_gpu_integration_test", + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -147361,6 +147526,7 @@ "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" ], "isolate_name": "telemetry_gpu_integration_test", + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -147401,6 +147567,7 @@ "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" ], "isolate_name": "telemetry_gpu_integration_test", + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -147445,6 +147612,7 @@ "1cb3" ], "isolate_name": "telemetry_gpu_integration_test", + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -147489,6 +147657,7 @@ "--git-revision=${got_revision}" ], "isolate_name": "telemetry_gpu_integration_test", + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -147538,6 +147707,7 @@ "--git-revision=${got_revision}" ], "isolate_name": "telemetry_gpu_integration_test", + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -147580,6 +147750,7 @@ "--browser=release_x64" ], "isolate_name": "rendering_representative_perf_tests", + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -147619,6 +147790,7 @@ "--dont-restore-color-profile-after-test" ], "isolate_name": "telemetry_gpu_integration_test", + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -147659,6 +147831,7 @@ "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" ], "isolate_name": "telemetry_gpu_integration_test", + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -147700,6 +147873,7 @@ "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl_conformance_tests_output.json" ], "isolate_name": "telemetry_gpu_integration_test", + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -191991,7 +192165,8 @@ "os": "Ubuntu-16.04" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 4 }, "test": "net_unittests", "test_id_prefix": "ninja://net:net_unittests/" @@ -193698,7 +193873,8 @@ "os": "Ubuntu-16.04" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 4 }, "test": "net_unittests", "test_id_prefix": "ninja://net:net_unittests/"
diff --git a/testing/buildbot/chromium.dawn.json b/testing/buildbot/chromium.dawn.json index 878f417b..9a759676 100644 --- a/testing/buildbot/chromium.dawn.json +++ b/testing/buildbot/chromium.dawn.json
@@ -8,7 +8,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -30,10 +31,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -56,9 +58,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -81,10 +84,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -107,10 +111,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -133,9 +138,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -158,9 +164,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -319,7 +326,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -341,10 +349,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -367,9 +376,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -392,10 +402,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -418,10 +429,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -444,9 +456,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -469,9 +482,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -630,7 +644,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -652,10 +667,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -678,9 +694,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -703,10 +720,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -729,10 +747,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -755,9 +774,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -780,9 +800,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -896,7 +917,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -918,10 +940,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -944,9 +967,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -969,10 +993,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -995,10 +1020,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -1021,9 +1047,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -1046,9 +1073,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -1164,7 +1192,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -1187,10 +1216,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -1214,9 +1244,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -1240,10 +1271,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -1267,10 +1299,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -1294,9 +1327,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -1320,9 +1354,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -1484,7 +1519,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -1505,10 +1541,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -1530,9 +1567,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -1554,10 +1592,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -1579,10 +1618,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -1604,9 +1644,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -1628,9 +1669,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -1780,7 +1822,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -1803,10 +1846,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -1830,9 +1874,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -1856,10 +1901,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -1883,10 +1929,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -1910,9 +1957,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -1936,9 +1984,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -2054,7 +2103,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -2075,10 +2125,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -2100,9 +2151,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -2124,10 +2176,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -2149,10 +2202,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -2174,9 +2228,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -2198,9 +2253,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -2310,7 +2366,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -2332,10 +2389,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -2358,9 +2416,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -2383,10 +2442,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -2409,10 +2469,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -2435,9 +2496,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -2460,9 +2522,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -2620,7 +2683,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -2642,10 +2706,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -2668,9 +2733,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -2693,10 +2759,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -2719,10 +2786,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -2745,9 +2813,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -2770,9 +2839,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -2930,7 +3000,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -2952,10 +3023,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -2978,9 +3050,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -3003,10 +3076,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -3029,10 +3103,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -3055,9 +3130,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -3080,9 +3156,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -3196,7 +3273,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -3218,10 +3296,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -3244,9 +3323,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -3269,10 +3349,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -3295,10 +3376,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -3321,9 +3403,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -3346,9 +3429,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -3464,7 +3548,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -3486,10 +3571,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -3512,9 +3598,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -3537,10 +3624,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -3563,10 +3651,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -3589,9 +3678,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -3614,9 +3704,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -3772,7 +3863,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -3794,10 +3886,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -3820,9 +3913,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -3845,10 +3939,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -3871,10 +3966,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -3897,9 +3993,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -3922,9 +4019,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -4080,7 +4178,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -4102,10 +4201,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -4128,9 +4228,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -4153,10 +4254,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -4179,10 +4281,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -4205,9 +4308,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -4230,9 +4334,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -4344,7 +4449,8 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" + "--test-launcher-retry-limit=0", + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -4366,10 +4472,11 @@ }, { "args": [ + "--no-use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--no-use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -4392,9 +4499,10 @@ }, { "args": [ + "--skip-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--skip-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -4417,10 +4525,11 @@ }, { "args": [ + "--use-spvc", + "--use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -4443,10 +4552,11 @@ }, { "args": [ + "--use-spvc", + "--no-use-spvc-parser", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-spvc", - "--no-use-spvc-parser" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -4469,9 +4579,10 @@ }, { "args": [ + "--enable-backend-validation", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--enable-backend-validation" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [], @@ -4494,9 +4605,10 @@ }, { "args": [ + "--use-wire", "--use-gpu-in-tests", "--test-launcher-retry-limit=0", - "--use-wire" + "--exclusive-device-type-preference=discrete,integrated" ], "merge": { "args": [],
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 8d16c37..8abc49d 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -12842,7 +12842,8 @@ "os": "Ubuntu-16.04" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 4 }, "test": "net_unittests", "test_id_prefix": "ninja://net:net_unittests/" @@ -14549,7 +14550,8 @@ "os": "Ubuntu-16.04" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 4 }, "test": "net_unittests", "test_id_prefix": "ninja://net:net_unittests/"
diff --git a/testing/buildbot/chromium.gpu.json b/testing/buildbot/chromium.gpu.json index 2fe4017..f1da795 100644 --- a/testing/buildbot/chromium.gpu.json +++ b/testing/buildbot/chromium.gpu.json
@@ -4487,6 +4487,7 @@ "--use-gpu-in-tests", "--test-launcher-retry-limit=0" ], + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4523,6 +4524,7 @@ "--test-launcher-jobs=1", "--gtest_filter=CastStreamingApiTestWithPixelOutput.EndToEnd*:TabCaptureApiPixelTest.EndToEnd*" ], + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4556,6 +4558,7 @@ "args": [ "--use-gpu-in-tests" ], + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4588,6 +4591,7 @@ "args": [ "--use-gpu-in-tests" ], + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4620,6 +4624,7 @@ "args": [ "--ignore-runtime-requirements=*" ], + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4661,6 +4666,7 @@ "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" ], "isolate_name": "telemetry_gpu_integration_test", + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -4701,6 +4707,7 @@ "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" ], "isolate_name": "telemetry_gpu_integration_test", + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -4742,6 +4749,7 @@ "--dont-restore-color-profile-after-test" ], "isolate_name": "telemetry_gpu_integration_test", + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -4782,6 +4790,7 @@ "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" ], "isolate_name": "telemetry_gpu_integration_test", + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -4822,6 +4831,7 @@ "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" ], "isolate_name": "telemetry_gpu_integration_test", + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -4866,6 +4876,7 @@ "1cb3" ], "isolate_name": "telemetry_gpu_integration_test", + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -4910,6 +4921,7 @@ "--git-revision=${got_revision}" ], "isolate_name": "telemetry_gpu_integration_test", + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -4959,6 +4971,7 @@ "--git-revision=${got_revision}" ], "isolate_name": "telemetry_gpu_integration_test", + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -5001,6 +5014,7 @@ "--browser=release_x64" ], "isolate_name": "rendering_representative_perf_tests", + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -5040,6 +5054,7 @@ "--dont-restore-color-profile-after-test" ], "isolate_name": "telemetry_gpu_integration_test", + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -5080,6 +5095,7 @@ "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" ], "isolate_name": "telemetry_gpu_integration_test", + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -5121,6 +5137,7 @@ "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl_conformance_tests_output.json" ], "isolate_name": "telemetry_gpu_integration_test", + "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json index 5baaad2..e2658a3 100644 --- a/testing/buildbot/chromium.linux.json +++ b/testing/buildbot/chromium.linux.json
@@ -1985,6 +1985,26 @@ "test_id_prefix": "ninja://fuchsia/runners:cast_runner_unittests/" }, { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-16.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 2 + }, + "test": "cc_unittests", + "test_id_prefix": "ninja://cc:cc_unittests/" + }, + { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.content_unittests.filter" ], @@ -2856,6 +2876,28 @@ }, { "args": [ + "--device=aemu" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-16.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 2 + }, + "test": "cc_unittests", + "test_id_prefix": "ninja://cc:cc_unittests/" + }, + { + "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.content_unittests.filter", "--device=aemu" ], @@ -3209,7 +3251,8 @@ "os": "Ubuntu-16.04" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 4 }, "test": "net_unittests", "test_id_prefix": "ninja://net:net_unittests/"
diff --git a/testing/buildbot/chromium.win.json b/testing/buildbot/chromium.win.json index 223b4b4..60884ad 100644 --- a/testing/buildbot/chromium.win.json +++ b/testing/buildbot/chromium.win.json
@@ -1456,6 +1456,7 @@ ], "scripts": [ { + "isolate_profile_data": true, "name": "check_network_annotations", "script": "check_network_annotations.py", "swarming": {}
diff --git a/testing/buildbot/generate_buildbot_json.py b/testing/buildbot/generate_buildbot_json.py index 438ba19df..22121f64 100755 --- a/testing/buildbot/generate_buildbot_json.py +++ b/testing/buildbot/generate_buildbot_json.py
@@ -601,8 +601,8 @@ elif self.is_chromeos(tester_config) and tester_config.get('use_swarming', True): # The presence of the "device_type" dimension indicates that the tests - # are targetting CrOS hardware and so need the special trigger script. - dimension_sets = tester_config['swarming']['dimension_sets'] + # are targeting CrOS hardware and so need the special trigger script. + dimension_sets = test['swarming']['dimension_sets'] if all('device_type' in ds for ds in dimension_sets): test['trigger_script'] = { 'script': '//testing/trigger_scripts/chromeos_device_trigger.py',
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index f8a809bf..db63c607 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -257,6 +257,10 @@ "script": "//testing/scripts/run_isolated_script_test.py", "type": "script", }, + "boundary_interface_example_apk": { + "label": "//android_webview/support_library/boundary_interfaces:boundary_interface_example_apk", + "type": "additional_compile_target", + }, "devtools_web_tests": { "args": [ "../../third_party/blink/tools/run_web_tests.py",
diff --git a/testing/buildbot/mixins.pyl b/testing/buildbot/mixins.pyl index c6f70ed..a9b1367 100644 --- a/testing/buildbot/mixins.pyl +++ b/testing/buildbot/mixins.pyl
@@ -179,6 +179,24 @@ 'service_account': 'chrome-tester@chops-service-accounts.iam.gserviceaccount.com', }, }, + 'chromeos-amd64-generic': { + 'swarming': { + 'dimensions': { + 'kvm': '1', + 'os': 'Ubuntu-16.04', + 'pool': 'chromium.tests.cros.vm.template', + }, + }, + }, + 'chromeos-kevin': { + 'swarming': { + 'dimensions': { + 'os': 'ChromeOS', + 'device_type': 'kevin', + 'pool': 'chrome-cros-dut.template', + }, + }, + }, # TODO(crbug.com/812428): Remove this mixin after all test pools have migrated # to using templates. 'chromium-template-pool': { @@ -198,6 +216,16 @@ 'service_account': 'chromium-tester@chops-service-accounts.iam.gserviceaccount.com', }, }, + 'dawn_end2end_gpu_test': { + '$mixin_append': { + 'args': [ + '--use-gpu-in-tests', + # Dawn test retries deliberately disabled to prevent flakiness. + '--test-launcher-retry-limit=0', + '--exclusive-device-type-preference=discrete,integrated', + ], + }, + }, 'docker': { 'swarming': { 'dimensions': {
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 60d0c7f..bd252b7 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -579,10 +579,6 @@ ], }, }, - 'remove_from': [ - 'Fuchsia ARM64', # https://crbug.com/1046552 - 'Fuchsia x64', # https://crbug.com/1046552 - ], }, 'checkbins': { 'remove_from': [
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index c6a404f..859f71b 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -1311,6 +1311,9 @@ ], }, 'net_unittests': { + 'swarming': { + 'shards': 4, + }, 'args': [ '--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.net_unittests.filter', ], @@ -1940,149 +1943,55 @@ # GPU gtests that test only Dawn 'gpu_dawn_gtests': { 'dawn_end2end_no_spvc_tests': { - 'desktop_args': [ - '--use-gpu-in-tests', - # Dawn test retries deliberately disabled to prevent flakiness. - '--test-launcher-retry-limit=0', + 'mixins': ['dawn_end2end_gpu_test'], + 'args': [ '--no-use-spvc', '--no-use-spvc-parser', ], 'test': 'dawn_end2end_tests', }, 'dawn_end2end_skip_validation_tests': { - 'desktop_args': [ - '--use-gpu-in-tests', - # Dawn test retries deliberately disabled to prevent flakiness. - '--test-launcher-retry-limit=0', + 'mixins': ['dawn_end2end_gpu_test'], + 'args': [ '--skip-validation', ], 'test': 'dawn_end2end_tests', }, 'dawn_end2end_tests': { - 'desktop_args': [ - '--use-gpu-in-tests', - # Dawn test retries deliberately disabled to prevent flakiness. - '--test-launcher-retry-limit=0', - ], + 'mixins': ['dawn_end2end_gpu_test'], }, 'dawn_end2end_use_spvc_parser_tests': { - 'desktop_args': [ - '--use-gpu-in-tests', - # Dawn test retries deliberately disabled to prevent flakiness. - '--test-launcher-retry-limit=0', + 'mixins': ['dawn_end2end_gpu_test'], + 'args': [ '--use-spvc', '--use-spvc-parser', ], 'test': 'dawn_end2end_tests', }, 'dawn_end2end_use_spvc_tests': { - 'desktop_args': [ - '--use-gpu-in-tests', - # Dawn test retries deliberately disabled to prevent flakiness. - '--test-launcher-retry-limit=0', + 'mixins': ['dawn_end2end_gpu_test'], + 'args': [ '--use-spvc', '--no-use-spvc-parser', ], 'test': 'dawn_end2end_tests', }, 'dawn_end2end_validation_layers_tests': { - 'desktop_args': [ - '--use-gpu-in-tests', - # Dawn test retries deliberately disabled to prevent flakiness. - '--test-launcher-retry-limit=0', + 'mixins': ['dawn_end2end_gpu_test'], + 'args': [ '--enable-backend-validation', ], 'test': 'dawn_end2end_tests', }, 'dawn_end2end_wire_tests': { - 'desktop_args': [ - '--use-gpu-in-tests', - # Dawn test retries deliberately disabled to prevent flakiness. - '--test-launcher-retry-limit=0', + 'mixins': ['dawn_end2end_gpu_test'], + 'args': [ '--use-wire', ], 'test': 'dawn_end2end_tests', }, }, - # GPU gtests that test Dawn and integration with Chromium - # These tests are run both on the CI and trybots which test DEPS Dawn. - 'gpu_dawn_integration_gtests': { - 'dawn_end2end_no_spvc_tests': { - 'desktop_args': [ - '--use-gpu-in-tests', - # Dawn test retries deliberately disabled to prevent flakiness. - '--test-launcher-retry-limit=0', - '--no-use-spvc', - '--no-use-spvc-parser', - ], - 'test': 'dawn_end2end_tests', - }, - 'dawn_end2end_skip_validation_tests': { - 'desktop_args': [ - '--use-gpu-in-tests', - # Dawn test retries deliberately disabled to prevent flakiness. - '--test-launcher-retry-limit=0', - '--skip-validation', - ], - 'test': 'dawn_end2end_tests', - }, - 'dawn_end2end_tests': { - 'desktop_args': [ - '--use-gpu-in-tests', - # Dawn test retries deliberately disabled to prevent flakiness. - '--test-launcher-retry-limit=0', - ], - }, - 'dawn_end2end_use_spvc_parser_tests': { - 'desktop_args': [ - '--use-gpu-in-tests', - # Dawn test retries deliberately disabled to prevent flakiness. - '--test-launcher-retry-limit=0', - '--use-spvc', - '--use-spvc-parser', - ], - 'test': 'dawn_end2end_tests', - }, - 'dawn_end2end_use_spvc_tests': { - 'desktop_args': [ - '--use-gpu-in-tests', - # Dawn test retries deliberately disabled to prevent flakiness. - '--test-launcher-retry-limit=0', - '--use-spvc', - '--no-use-spvc-parser', - ], - 'test': 'dawn_end2end_tests', - }, - 'dawn_end2end_validation_layers_tests': { - 'desktop_args': [ - '--use-gpu-in-tests', - # Dawn test retries deliberately disabled to prevent flakiness. - '--test-launcher-retry-limit=0', - '--enable-backend-validation', - ], - 'test': 'dawn_end2end_tests', - }, - 'dawn_end2end_wire_tests': { - 'desktop_args': [ - '--use-gpu-in-tests', - # Dawn test retries deliberately disabled to prevent flakiness. - '--test-launcher-retry-limit=0', - '--use-wire', - ], - 'test': 'dawn_end2end_tests', - }, - 'gl_tests': { - 'desktop_args': [ - '--use-gpu-in-tests', - ], - }, - 'gl_unittests': { - 'desktop_args': ['--use-gpu-in-tests'], - 'linux_args': ['--no-xvfb'], - }, - }, - 'gpu_dawn_perf_smoke_isolated_scripts': { 'dawn_perf_tests': { 'args': [ @@ -4571,12 +4480,14 @@ 'gpu_gl_renderer_small_telemetry_tests', ], - 'gpu_dawn_deps_isolated_scripts': [ - 'gpu_dawn_perf_smoke_isolated_scripts', - 'gpu_webgpu_integration_isolated_scripts', + # GPU gtests that test Dawn and integration with Chromium + # These tests are run both on the CI and trybots which test DEPS Dawn. + 'gpu_dawn_integration_gtests': [ + 'gpu_dawn_gtests', + 'gpu_common_gtests', ], - 'gpu_dawn_tot_isolated_scripts': [ + 'gpu_dawn_isolated_scripts': [ 'gpu_dawn_perf_smoke_isolated_scripts', 'gpu_webgpu_integration_isolated_scripts', ],
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index a658733..4ae4f04b 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -353,6 +353,7 @@ }, 'Android arm Builder (dbg)': { 'additional_compile_targets': [ + 'boundary_interface_example_apk', 'dump_syms', 'microdump_stackwalk', ], @@ -831,23 +832,15 @@ 'chromiumos_preflight', ], 'browser_config': 'cros-chrome', + 'mixins': [ + 'chromeos-amd64-generic', + ], 'os_type': 'chromeos', 'test_suites': { 'gpu_telemetry_tests': 'gpu_chromeos_telemetry_tests', 'gtest_tests': 'chromeos_vm_gtests', 'isolated_scripts': 'chromeos_isolated_scripts', }, - # TODO(crbug.com/1080809): Move this to a mixin once mixins are no - # longer broken for CrOS builders. - 'swarming': { - 'dimension_sets': [ - { - 'kvm': '1', - 'os': 'Ubuntu-16.04', - 'pool': 'chromium.tests.cros.vm.template', - }, - ], - }, }, 'chromeos-arm-generic-dbg': { 'additional_compile_targets': [ @@ -863,19 +856,9 @@ 'additional_compile_targets': [ 'chromiumos_preflight', ], - # TODO(crbug.com/1080809): Move this to a mixin once mixins are no - # longer broken for CrOS builders. - 'swarming': { - 'dimension_sets': [ - { - 'os': 'ChromeOS', - 'device_type': 'kevin', - # Special pool is needed for the devices since they also run - # swarmbucket builds. - 'pool': 'chrome-cros-dut.template', - }, - ], - }, + 'mixins': [ + 'chromeos-kevin', + ], 'test_suites': { 'gtest_tests': 'chromeos_device_gtests', 'isolated_scripts': 'chromeos_remote_device_isolated_tests', @@ -1288,7 +1271,7 @@ ], 'test_suites': { 'gtest_tests': 'gpu_dawn_integration_gtests', - 'isolated_scripts': 'gpu_dawn_deps_isolated_scripts', + 'isolated_scripts': 'gpu_dawn_isolated_scripts', }, }, 'Dawn Linux x64 DEPS Release (NVIDIA)': { @@ -1299,7 +1282,7 @@ ], 'test_suites': { 'gtest_tests': 'gpu_dawn_integration_gtests', - 'isolated_scripts': 'gpu_dawn_deps_isolated_scripts', + 'isolated_scripts': 'gpu_dawn_isolated_scripts', }, }, 'Dawn Linux x64 Release (Intel HD 630)': { @@ -1310,7 +1293,7 @@ ], 'test_suites': { 'gtest_tests': 'gpu_dawn_gtests', - 'isolated_scripts': 'gpu_dawn_tot_isolated_scripts', + 'isolated_scripts': 'gpu_dawn_isolated_scripts', }, }, 'Dawn Linux x64 Release (NVIDIA)': { @@ -1321,7 +1304,7 @@ ], 'test_suites': { 'gtest_tests': 'gpu_dawn_gtests', - 'isolated_scripts': 'gpu_dawn_tot_isolated_scripts', + 'isolated_scripts': 'gpu_dawn_isolated_scripts', }, }, 'Dawn Mac x64 Builder' : {}, @@ -1334,7 +1317,7 @@ ], 'test_suites': { 'gtest_tests': 'gpu_dawn_integration_gtests', - 'isolated_scripts': 'gpu_dawn_deps_isolated_scripts', + 'isolated_scripts': 'gpu_dawn_isolated_scripts', }, }, 'Dawn Mac x64 DEPS Release (Intel)': { @@ -1345,7 +1328,7 @@ ], 'test_suites': { 'gtest_tests': 'gpu_dawn_integration_gtests', - 'isolated_scripts': 'gpu_dawn_deps_isolated_scripts', + 'isolated_scripts': 'gpu_dawn_isolated_scripts', }, }, 'Dawn Mac x64 Release (AMD)': { @@ -1356,7 +1339,7 @@ ], 'test_suites': { 'gtest_tests': 'gpu_dawn_gtests', - 'isolated_scripts': 'gpu_dawn_tot_isolated_scripts', + 'isolated_scripts': 'gpu_dawn_isolated_scripts', }, }, 'Dawn Mac x64 Release (Intel)': { @@ -1367,7 +1350,7 @@ ], 'test_suites': { 'gtest_tests': 'gpu_dawn_gtests', - 'isolated_scripts': 'gpu_dawn_tot_isolated_scripts', + 'isolated_scripts': 'gpu_dawn_isolated_scripts', }, }, 'Dawn Win10 x64 Builder' : {}, @@ -1380,7 +1363,7 @@ ], 'test_suites': { 'gtest_tests': 'gpu_dawn_integration_gtests', - 'isolated_scripts': 'gpu_dawn_deps_isolated_scripts', + 'isolated_scripts': 'gpu_dawn_isolated_scripts', }, }, 'Dawn Win10 x64 DEPS Release (NVIDIA)': { @@ -1391,7 +1374,7 @@ ], 'test_suites': { 'gtest_tests': 'gpu_dawn_integration_gtests', - 'isolated_scripts': 'gpu_dawn_deps_isolated_scripts', + 'isolated_scripts': 'gpu_dawn_isolated_scripts', }, }, 'Dawn Win10 x64 Release (Intel HD 630)': { @@ -1402,7 +1385,7 @@ ], 'test_suites': { 'gtest_tests': 'gpu_dawn_gtests', - 'isolated_scripts': 'gpu_dawn_tot_isolated_scripts', + 'isolated_scripts': 'gpu_dawn_isolated_scripts', }, }, 'Dawn Win10 x64 Release (NVIDIA)': { @@ -1413,7 +1396,7 @@ ], 'test_suites': { 'gtest_tests': 'gpu_dawn_gtests', - 'isolated_scripts': 'gpu_dawn_tot_isolated_scripts', + 'isolated_scripts': 'gpu_dawn_isolated_scripts', }, }, 'Dawn Win10 x86 Builder' : {}, @@ -1426,7 +1409,7 @@ ], 'test_suites': { 'gtest_tests': 'gpu_dawn_integration_gtests', - 'isolated_scripts': 'gpu_dawn_deps_isolated_scripts', + 'isolated_scripts': 'gpu_dawn_isolated_scripts', }, }, 'Dawn Win10 x86 DEPS Release (NVIDIA)': { @@ -1437,7 +1420,7 @@ ], 'test_suites': { 'gtest_tests': 'gpu_dawn_integration_gtests', - 'isolated_scripts': 'gpu_dawn_deps_isolated_scripts', + 'isolated_scripts': 'gpu_dawn_isolated_scripts', }, }, 'Dawn Win10 x86 Release (Intel HD 630)': { @@ -1448,7 +1431,7 @@ ], 'test_suites': { 'gtest_tests': 'gpu_dawn_gtests', - 'isolated_scripts': 'gpu_dawn_tot_isolated_scripts', + 'isolated_scripts': 'gpu_dawn_isolated_scripts', }, }, 'Dawn Win10 x86 Release (NVIDIA)': { @@ -1459,7 +1442,7 @@ ], 'test_suites': { 'gtest_tests': 'gpu_dawn_gtests', - 'isolated_scripts': 'gpu_dawn_tot_isolated_scripts', + 'isolated_scripts': 'gpu_dawn_isolated_scripts', }, }, } @@ -2785,6 +2768,7 @@ 'browser_config': 'release_x64', 'os_type': 'win', 'mixins': [ + 'isolate_profile_data', 'win10_nvidia_quadro_p400_stable', ], 'test_suites': { @@ -3134,20 +3118,12 @@ 'browser_config': 'cros-chrome', 'os_type': 'chromeos', 'skip_merge_script': True, + 'mixins': [ + 'chromeos-amd64-generic', + ], 'test_suites': { 'gpu_telemetry_tests': 'gpu_noop_sleep_telemetry_test', }, - # TODO(crbug.com/1080809): Move this to a mixin once mixins are no - # longer broken for CrOS builders. - 'swarming': { - 'dimension_sets': [ - { - 'kvm': '1', - 'os': 'Ubuntu-16.04', - 'pool': 'chromium.tests.cros.vm.template', - }, - ], - }, }, 'ChromeOS FYI Release (kevin)': { 'additional_compile_targets': [ @@ -3157,24 +3133,12 @@ 'os_type': 'chromeos', 'skip_merge_script': True, 'mixins': [ + 'chromeos-kevin', 'limited_capacity_bot', ], 'test_suites': { 'gpu_telemetry_tests': 'gpu_noop_sleep_telemetry_test', }, - # TODO(crbug.com/1080809): Move this to a mixin once mixins are no - # longer broken for CrOS builders. - 'swarming': { - 'dimension_sets': [ - { - 'os': 'ChromeOS', - 'device_type': 'kevin', - # Special pool is needed for the devices since they also run - # swarmbucket builds. - 'pool': 'chrome-cros-dut.template', - }, - ], - }, }, 'GPU FYI Fuchsia Builder' : { 'additional_compile_targets': [ @@ -4756,6 +4720,9 @@ }, }, 'Win x64 Builder': { + 'mixins': [ + 'isolate_profile_data', + ], 'additional_compile_targets': [ 'pdf_fuzzers' ],
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index b088788..248a78f4 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -94,6 +94,21 @@ ] } ], + "AndroidDarkSearch": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AndroidDarkSearch" + ] + } + ] + } + ], "AndroidInProductHelpContextualSearchPromotePanelOpen": [ { "platforms": [ @@ -6006,6 +6021,23 @@ ] } ], + "TextfieldFocusOnTapUp": [ + { + "platforms": [ + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "TextfieldFocusOnTapUp" + ] + } + ] + } + ], "TextureLayerSkipWaitForActivation": [ { "platforms": [ @@ -7035,6 +7067,7 @@ }, "enable_features": [ "IPH_WebUITabStrip", + "TextfieldFocusOnTapUp", "WebUITabStrip", "WebUITabStripTabDragIntegration" ]
diff --git a/third_party/blink/common/client_hints/client_hints.cc b/third_party/blink/common/client_hints/client_hints.cc index f491de8f..c23f77b 100644 --- a/third_party/blink/common/client_hints/client_hints.cc +++ b/third_party/blink/common/client_hints/client_hints.cc
@@ -7,11 +7,13 @@ #include <utility> #include <vector> +#include "base/feature_list.h" #include "base/optional.h" #include "base/stl_util.h" #include "base/strings/string_tokenizer.h" #include "base/strings/string_util.h" #include "third_party/blink/public/common/feature_policy/feature_policy.h" +#include "third_party/blink/public/common/features.h" #include "url/origin.h" namespace blink { @@ -34,11 +36,16 @@ "sec-ch-ua-platform-version", }; +const unsigned kClientHintsNumberOfLegacyHints = 4; + const mojom::FeaturePolicyFeature kClientHintsFeaturePolicyMapping[] = { + // Legacy Hints that are sent cross-origin regardless of FeaturePolicy when + // kAllowClientHintsToThirdParty is enabled mojom::FeaturePolicyFeature::kClientHintDeviceMemory, mojom::FeaturePolicyFeature::kClientHintDPR, mojom::FeaturePolicyFeature::kClientHintWidth, mojom::FeaturePolicyFeature::kClientHintViewportWidth, + // End of legacy hints. mojom::FeaturePolicyFeature::kClientHintRTT, mojom::FeaturePolicyFeature::kClientHintDownlink, mojom::FeaturePolicyFeature::kClientHintECT, @@ -119,6 +126,15 @@ return base::make_optional(std::move(result)); } +namespace { + +bool IsClientHintSentByDefault(network::mojom::WebClientHintsType type) { + return (type == network::mojom::WebClientHintsType::kUA || + type == network::mojom::WebClientHintsType::kUAMobile); +} + +} // namespace + // Add a list of Client Hints headers to be removed to the output vector, based // on FeaturePolicy and the url's origin. void FindClientHintsToRemove(const FeaturePolicy* feature_policy, @@ -126,13 +142,22 @@ std::vector<std::string>* removed_headers) { DCHECK(removed_headers); url::Origin origin = url::Origin::Create(url); - for (size_t i = 0; i < blink::kClientHintsMappingsCount; ++i) { - // TODO(yoav): When FeaturePolicy is not present, we need to conserve the - // hints that are sent by default. - // TODO(yoav): We need to take legacy hints into account here. - if (!feature_policy || - !feature_policy->IsFeatureEnabledForOrigin( - blink::kClientHintsFeaturePolicyMapping[i], origin)) { + size_t startHint = 0; + if (base::FeatureList::IsEnabled(features::kAllowClientHintsToThirdParty)) { + // Do not remove any legacy Client Hints + startHint = kClientHintsNumberOfLegacyHints; + } + for (size_t i = startHint; i < blink::kClientHintsMappingsCount; ++i) { + // Remove the hint if any is true: + // * Feature policy is null (we're in a sync XHR case) and the hint is not + // sent by default. + // * Feature policy exists and doesn't allow for the hint. + if ((!feature_policy && + !IsClientHintSentByDefault( + static_cast<network::mojom::WebClientHintsType>(i))) || + (feature_policy && + !feature_policy->IsFeatureEnabledForOrigin( + blink::kClientHintsFeaturePolicyMapping[i], origin))) { removed_headers->push_back(blink::kClientHintsHeaderMapping[i]); } }
diff --git a/third_party/blink/common/client_hints/client_hints_unittest.cc b/third_party/blink/common/client_hints/client_hints_unittest.cc index 022a8515..57674fa 100644 --- a/third_party/blink/common/client_hints/client_hints_unittest.cc +++ b/third_party/blink/common/client_hints/client_hints_unittest.cc
@@ -6,9 +6,12 @@ #include <iostream> +#include "base/test/scoped_feature_list.h" #include "services/network/public/mojom/web_client_hints_types.mojom-shared.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/features.h" +#include "url/gurl.h" using testing::UnorderedElementsAre; @@ -91,4 +94,34 @@ UnorderedElementsAre(network::mojom::WebClientHintsType::kRtt)); } +// Checks that the removed header list doesn't include legacy headers nor the +// on-by-default ones, when the kAllowClientHintsToThirdParty flag is on. +TEST(ClientHintsTest, FindClientHintsToRemoveLegacy) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + features::kAllowClientHintsToThirdParty); + std::vector<std::string> removed_headers; + FindClientHintsToRemove(nullptr, GURL(), &removed_headers); + EXPECT_THAT(removed_headers, + UnorderedElementsAre("rtt", "downlink", "ect", "sec-ch-lang", + "sec-ch-ua-arch", "sec-ch-ua-platform", + "sec-ch-ua-model", "sec-ch-ua-full-version", + "sec-ch-ua-platform-version")); +} + +// Checks that the removed header list includes legacy headers but not the +// on-by-default ones, when the kAllowClientHintsToThirdParty flag is off. +TEST(ClientHintsTest, FindClientHintsToRemoveNoLegacy) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndDisableFeature( + features::kAllowClientHintsToThirdParty); + std::vector<std::string> removed_headers; + FindClientHintsToRemove(nullptr, GURL(), &removed_headers); + EXPECT_THAT(removed_headers, + UnorderedElementsAre( + "device-memory", "dpr", "width", "viewport-width", "rtt", + "downlink", "ect", "sec-ch-lang", "sec-ch-ua-arch", + "sec-ch-ua-platform", "sec-ch-ua-model", + "sec-ch-ua-full-version", "sec-ch-ua-platform-version")); +} } // namespace blink
diff --git a/third_party/blink/common/feature_policy/feature_policy.cc b/third_party/blink/common/feature_policy/feature_policy.cc index e87fd0d..b34f95be 100644 --- a/third_party/blink/common/feature_policy/feature_policy.cc +++ b/third_party/blink/common/feature_policy/feature_policy.cc
@@ -411,7 +411,7 @@ {mojom::FeaturePolicyFeature::kClientHintUAModel, FeatureDefault(FeaturePolicy::FeatureDefault::EnableForSelf)}, {mojom::FeaturePolicyFeature::kClientHintUAMobile, - FeatureDefault(FeaturePolicy::FeatureDefault::EnableForSelf)}, + FeatureDefault(FeaturePolicy::FeatureDefault::EnableForAll)}, {mojom::FeaturePolicyFeature::kClientHintUAFullVersion, FeatureDefault(FeaturePolicy::FeatureDefault::EnableForSelf)}, {mojom::FeaturePolicyFeature::kClientHintUAPlatformVersion,
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index f32e62c8a..6b3098e 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -546,6 +546,17 @@ const base::Feature kResamplingScrollEvents{"ResamplingScrollEvents", base::FEATURE_ENABLED_BY_DEFAULT}; +// Enables the device-memory, resource-width, viewport-width and DPR client +// hints to be sent to third-party origins if the first-party has opted in to +// receiving client hints, regardless of Feature Policy. +#if defined(OS_ANDROID) +const base::Feature kAllowClientHintsToThirdParty{ + "AllowClientHintsToThirdParty", base::FEATURE_ENABLED_BY_DEFAULT}; +#else +const base::Feature kAllowClientHintsToThirdParty{ + "AllowClientHintsToThirdParty", base::FEATURE_DISABLED_BY_DEFAULT}; +#endif + const char kScrollPredictorNameLsq[] = "lsq"; const char kScrollPredictorNameKalman[] = "kalman"; const char kScrollPredictorNameLinearFirst[] = "linear_first";
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h index a74974c..430b6d55 100644 --- a/third_party/blink/public/common/features.h +++ b/third_party/blink/public/common/features.h
@@ -191,6 +191,11 @@ // Enables resampling GestureScroll events on compositor thread. BLINK_COMMON_EXPORT extern const base::Feature kResamplingScrollEvents; +// Enables the device-memory, resource-width, viewport-width and DPR client +// hints to be sent to third-party origins if the first-party has opted in to +// receiving client hints, regardless of Feature Policy. +BLINK_COMMON_EXPORT extern const base::Feature kAllowClientHintsToThirdParty; + // The type of scroll predictor to use for the resampling scroll events. These // values are used as the 'predictor' feature param for // |kResamplingScrollEvents|.
diff --git a/third_party/blink/public/mojom/frame/frame.mojom b/third_party/blink/public/mojom/frame/frame.mojom index c73e52e3..2038cd3 100644 --- a/third_party/blink/public/mojom/frame/frame.mojom +++ b/third_party/blink/public/mojom/frame/frame.mojom
@@ -15,6 +15,7 @@ import "services/network/public/mojom/web_sandbox_flags.mojom"; import "skia/public/mojom/skcolor.mojom"; import "third_party/blink/public/mojom/ad_tagging/ad_frame.mojom"; +import "third_party/blink/public/mojom/messaging/transferable_message.mojom"; import "third_party/blink/public/mojom/choosers/popup_menu.mojom"; import "third_party/blink/public/mojom/devtools/console_message.mojom"; import "third_party/blink/public/mojom/devtools/inspector_issue.mojom"; @@ -501,6 +502,19 @@ // plumbing the multi-screen info via SynchronizeVisualProperties. OnScreensChange(); + // Posts a message from a frame in another process to the current renderer. + // |source_frame_token| is the frame token of the RemoteFrame in the current + // renderer representing the frame (from a different renderer) where this + // message is coming from. |source_origin| is the origin of the source frame + // when the message was sent, and |target_origin| specifies what the origin of + // the target frame must be for the message to be dispatched. An empty string + // allows the message to be dispatched to any origin. |message| is the encoded + // data, and any extra properties such as transferred ports or blobs. + PostMessageEvent(mojo_base.mojom.UnguessableToken? source_frame_token, + mojo_base.mojom.String16 source_origin, + mojo_base.mojom.String16 target_origin, + blink.mojom.TransferableMessage message); + // Requests the index of a character in the frame's text stream at the given // point. The point is in the viewport coordinate space. Replies using // TextInputHost.
diff --git a/third_party/blink/public/mojom/input/input_handler.mojom b/third_party/blink/public/mojom/input/input_handler.mojom index 17364e7..e213ab6 100644 --- a/third_party/blink/public/mojom/input/input_handler.mojom +++ b/third_party/blink/public/mojom/input/input_handler.mojom
@@ -4,6 +4,25 @@ module blink.mojom; +import "cc/mojom/overscroll_behavior.mojom"; +import "cc/mojom/touch_action.mojom"; +import "ui/gfx/geometry/mojom/geometry.mojom"; + +// Represents the current state of overscroll. +struct DidOverscrollParams { + gfx.mojom.Vector2dF accumulated_overscroll; + gfx.mojom.Vector2dF latest_overscroll_delta; + gfx.mojom.Vector2dF current_fling_velocity; + gfx.mojom.PointF causal_event_viewport_point; + cc.mojom.OverscrollBehavior overscroll_behavior; +}; + +// A struct wrapper for the TouchAction enumeration because +// enumerations cannot be optional. +struct TouchActionOptional { + cc.mojom.TouchAction touch_action; +}; + // Types related to sending edit commands to the renderer. struct EditCommand { string name;
diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom index fc30c2f..1d42b26 100644 --- a/third_party/blink/public/mojom/web_feature/web_feature.mojom +++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -2626,6 +2626,10 @@ kGridRowGapPercentIndefinite = 3289, kFlexRowGapPercent = 3290, kFlexRowGapPercentIndefinite = 3291, + kV8RTCRtpSender_CreateEncodedStreams_Method = 3292, + kV8RTCRtpReceiver_CreateEncodedStreams_Method = 3293, + kForceEncodedAudioInsertableStreams = 3294, + kForceEncodedVideoInsertableStreams = 3295, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/public/platform/input/input_handler_proxy.h b/third_party/blink/public/platform/input/input_handler_proxy.h index 2ff848d..0c98a0d 100644 --- a/third_party/blink/public/platform/input/input_handler_proxy.h +++ b/third_party/blink/public/platform/input/input_handler_proxy.h
@@ -76,12 +76,49 @@ cc::OverscrollBehavior overscroll_behavior; }; + // Result codes returned to the client indicating the status of handling the + // event on the compositor. Used to determine further event handling behavior + // (i.e. should the event be forwarded to the main thread, ACK'ed to the + // browser, etc.). enum EventDisposition { + // The event was handled on the compositor and should not be forwarded to + // the main thread. DID_HANDLE, + + // The compositor could not handle the event but the event may still be + // valid for handling so it should be forwarded to the main thread. DID_NOT_HANDLE, + + // Set only from a touchstart that occurred while a fling was in progress. + // Indicates that the rest of the touch stream should be sent non-blocking + // to ensure the scroll remains smooth. Since it's non-blocking, the event + // will be ACK'ed to the browser before being dispatched to the main + // thread. + // TODO(bokan): It's not clear that we need a separate status for this + // case, why can't we just use the DID_HANDLE_NON_BLOCKING below? DID_NOT_HANDLE_NON_BLOCKING_DUE_TO_FLING, + + // Set to indicate that the event needs to be sent to the main thread (e.g. + // because the touch event hits a touch-event handler) but the compositor + // has determined it shouldn't be cancellable (e.g. the event handler is + // passive). Because it isn't cancellable, the event (and future events) + // will be sent non-blocking and be acked to the browser before being + // dispatchehd to the main thread. + // TODO(bokan): The semantics of DID/DID_NOT HANDLE are whether the main + // thread needs to know about the event. In this case, we expect the event + // to be forwarded to the main thread so this should be DID_NOT_HANDLE. DID_HANDLE_NON_BLOCKING, + + // The compositor didn't handle the event but has determined the main + // thread doesn't care about the event either (e.g. it's a touch event and + // the hit point doesn't have a touch handler). In this case, we should ACK + // the event immediately. Both this and DID_HANDLE will avoid forwarding + // the event to the main thread and ACK immediately; the difference is that + // DROP_EVENT tells the client the event wasn't consumed. For example, the + // browser may choose to use this to avoid forwarding touch events if there + // isn't a consumer for them (and send only the scroll events). DROP_EVENT, + // The compositor did handle the scroll event (so it wouldn't forward the // event to the main thread.) but it didn't consume the scroll so it should // pass it to the next consumer (either overscrolling or bubbling the event
diff --git a/third_party/blink/public/platform/webaudiosourceprovider_impl.h b/third_party/blink/public/platform/webaudiosourceprovider_impl.h index 233ca1eb..5383074d 100644 --- a/third_party/blink/public/platform/webaudiosourceprovider_impl.h +++ b/third_party/blink/public/platform/webaudiosourceprovider_impl.h
@@ -99,7 +99,8 @@ PlaybackState state_; // Closure that calls OnSetFormat() on |client_| on the renderer thread. - base::OnceClosure set_format_cb_; + base::RepeatingClosure set_format_cb_; + // When set via setClient() it overrides |sink_| for consuming audio. WebAudioSourceProviderClient* client_;
diff --git a/third_party/blink/public/web/blink.h b/third_party/blink/public/web/blink.h index de948ae2..dd9706b 100644 --- a/third_party/blink/public/web/blink.h +++ b/third_party/blink/public/web/blink.h
@@ -32,6 +32,7 @@ #define THIRD_PARTY_BLINK_PUBLIC_WEB_BLINK_H_ #include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/public/platform/web_string.h" #include "v8/include/v8.h" namespace mojo { @@ -86,12 +87,23 @@ BLINK_EXPORT void MemoryPressureNotificationToWorkerThreadIsolates( v8::MemoryPressureLevel); -// Set the RAIL performance mode on all worker thread isolates. -BLINK_EXPORT void SetRAILModeOnWorkerThreadIsolates(v8::RAILMode); - // Logs Runtime Call Stats table for Blink. BLINK_EXPORT void LogRuntimeCallStats(); +// Allows disabling domain relaxation. +BLINK_EXPORT void SetDomainRelaxationForbidden(bool forbidden, + const WebString& scheme); +// Undos all calls to SetDomainRelaxationForbidden(). +BLINK_EXPORT void ResetDomainRelaxation(); + +// Force the webgl context to fail so that webglcontextcreationerror +// event gets generated/tested. +BLINK_EXPORT void ForceNextWebGLContextCreationToFailForTest(); + +// Force the drawing buffer used by webgl contexts to fail so that the webgl +// context's ability to deal with that failure gracefully can be tested. +BLINK_EXPORT void ForceNextDrawingBufferCreationToFailForTest(); + } // namespace blink #endif
diff --git a/third_party/blink/public/web/web_local_frame.h b/third_party/blink/public/web/web_local_frame.h index 3a1668bd..19a7338 100644 --- a/third_party/blink/public/web/web_local_frame.h +++ b/third_party/blink/public/web/web_local_frame.h
@@ -54,7 +54,6 @@ class WebContentCaptureClient; class WebContentSettingsClient; class WebDocument; -class WebDOMMessageEvent; class WebLocalFrameClient; class WebFrameWidget; class WebInputMethodController; @@ -570,11 +569,6 @@ // Events -------------------------------------------------------------- - // Dispatches a message event on the current DOMWindow in this WebFrame. - virtual void DispatchMessageEventWithOriginCheck( - const WebSecurityOrigin& intended_target_origin, - const WebDOMMessageEvent&) = 0; - // TEMP: Usage count for chrome.loadtimes deprecation. // This will be removed following the deprecation. virtual void UsageCountChromeLoadTimes(const WebString& metric) = 0; @@ -695,6 +689,11 @@ virtual bool CapturePaintPreview(const WebRect& bounds, cc::PaintCanvas* canvas) = 0; + // FrameOverlay ---------------------------------------------------------- + + // Overlay this frame with a solid color. Only valid for the main frame. + virtual void SetMainFrameOverlayColor(SkColor) = 0; + // Focus -------------------------------------------------------------- // Returns whether the keyboard should be suppressed for the currently focused
diff --git a/third_party/blink/public/web/web_view.h b/third_party/blink/public/web/web_view.h index 7a7ad4a56..18ecf79 100644 --- a/third_party/blink/public/web/web_view.h +++ b/third_party/blink/public/web/web_view.h
@@ -146,9 +146,6 @@ virtual bool IsActive() const = 0; virtual void SetIsActive(bool) = 0; - // Allows disabling domain relaxation. - virtual void SetDomainRelaxationForbidden(bool, const WebString& scheme) = 0; - // Allows setting the state of the various bars exposed via BarProp // properties on the window object. The size related fields of // WebWindowFeatures are ignored. @@ -399,11 +396,6 @@ bool is_initial_state) = 0; virtual mojom::PageVisibilityState GetVisibilityState() = 0; - // FrameOverlay ---------------------------------------------------------- - - // Overlay this WebView with a solid color. - virtual void SetMainFrameOverlayColor(SkColor) = 0; - // Page Importance Signals ---------------------------------------------- virtual WebPageImportanceSignals* PageImportanceSignals() { return nullptr; } @@ -427,16 +419,6 @@ virtual void RestorePageFromBackForwardCache( base::TimeTicks navigation_start) = 0; - // Testing functionality for TestRunner --------------------------------- - - // Force the webgl context to fail so that webglcontextcreationerror - // event gets generated/tested. - virtual void ForceNextWebGLContextCreationToFail() = 0; - - // Force the drawing buffer used by webgl contexts to fail so that the webgl - // context's ability to deal with that failure gracefully can be tested. - virtual void ForceNextDrawingBufferCreationToFail() = 0; - // Autoplay configuration ----------------------------------------------- // Sets the autoplay flags for this webview's page.
diff --git a/third_party/blink/renderer/bindings/idl_in_modules.gni b/third_party/blink/renderer/bindings/idl_in_modules.gni index c98039b..2c79c50 100644 --- a/third_party/blink/renderer/bindings/idl_in_modules.gni +++ b/third_party/blink/renderer/bindings/idl_in_modules.gni
@@ -460,8 +460,8 @@ "//third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.idl", "//third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.idl", "//third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event_init.idl", - "//third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.idl", - "//third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.idl", + "//third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame_metadata.idl", + "//third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_metadata.idl", "//third_party/blink/renderer/modules/peerconnection/rtc_error.idl", "//third_party/blink/renderer/modules/peerconnection/rtc_error_event.idl", "//third_party/blink/renderer/modules/peerconnection/rtc_error_event_init.idl",
diff --git a/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_properties.cc.tmpl b/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_properties.cc.tmpl index dff001f..5ad18b5c 100644 --- a/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_properties.cc.tmpl +++ b/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_properties.cc.tmpl
@@ -90,7 +90,15 @@ {% endif %} {% if property.computed_value_comparable %} bool {{class_name}}::ComputedValuesEqual(const ComputedStyle& a, const ComputedStyle& b) const { + {% if property.computed_value_compare_fields %} + {% for field in property.computed_value_compare_fields %} + if (!(a.{{field}}() == b.{{field}}())) + return false; + {% endfor %} + return true; + {% else %} return a.{{property.getter}}() == b.{{property.getter}}(); + {% endif %} } {% endif %} {% if property.direction_aware_options %}
diff --git a/third_party/blink/renderer/controller/blink_initializer.cc b/third_party/blink/renderer/controller/blink_initializer.cc index e67e58d..07881f0 100644 --- a/third_party/blink/renderer/controller/blink_initializer.cc +++ b/third_party/blink/renderer/controller/blink_initializer.cc
@@ -161,6 +161,7 @@ } // namespace +// Function defined in third_party/blink/public/web/blink.h. void Initialize(Platform* platform, mojo::BinderMap* binders, scheduler::WebThreadScheduler* main_thread_scheduler) { @@ -169,6 +170,7 @@ InitializeCommon(platform, binders); } +// Function defined in third_party/blink/public/web/blink.h. void CreateMainThreadAndInitialize(Platform* platform, mojo::BinderMap* binders) { DCHECK(binders);
diff --git a/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.cc b/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.cc index 8d4f6132..4e7b6e5a 100644 --- a/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.cc +++ b/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.cc
@@ -11,6 +11,154 @@ namespace blink { +BlinkAXEventIntent BlinkAXEventIntent::FromClearedSelection( + const SetSelectionBy set_selection_by) { + // |text_boundary| and |move_direction| are not used in this case. + return BlinkAXEventIntent(ax::mojom::blink::Command::kClearSelection, + ax::mojom::blink::TextBoundary::kCharacter, + ax::mojom::blink::MoveDirection::kForward); +} + +BlinkAXEventIntent BlinkAXEventIntent::FromModifiedSelection( + const SelectionModifyAlteration alter, + const SelectionModifyDirection direction, + const TextGranularity granularity, + const SetSelectionBy set_selection_by, + const TextDirection direction_of_selection) { + ax::mojom::blink::Command command; + switch (alter) { + case SelectionModifyAlteration::kExtend: + // Includes the case when the existing selection has been shrunk. + command = ax::mojom::blink::Command::kExtendSelection; + break; + case SelectionModifyAlteration::kMove: + // The existing selection has been move by a specific |granularity|, e.g. + // the caret has been moved to the beginning of the next word. + command = ax::mojom::blink::Command::kMoveSelection; + break; + } + + ax::mojom::blink::MoveDirection move_direction; + switch (direction) { + case SelectionModifyDirection::kBackward: + move_direction = ax::mojom::blink::MoveDirection::kBackward; + break; + case SelectionModifyDirection::kForward: + move_direction = ax::mojom::blink::MoveDirection::kForward; + break; + case SelectionModifyDirection::kLeft: + move_direction = IsLtr(direction_of_selection) + ? ax::mojom::blink::MoveDirection::kBackward + : ax::mojom::blink::MoveDirection::kForward; + break; + case SelectionModifyDirection::kRight: + move_direction = IsLtr(direction_of_selection) + ? ax::mojom::blink::MoveDirection::kForward + : ax::mojom::blink::MoveDirection::kBackward; + break; + } + + ax::mojom::blink::TextBoundary text_boundary; + switch (granularity) { + case TextGranularity::kCharacter: + text_boundary = ax::mojom::blink::TextBoundary::kCharacter; + break; + case TextGranularity::kWord: + switch (move_direction) { + case ax::mojom::blink::MoveDirection::kBackward: + text_boundary = ax::mojom::blink::TextBoundary::kWordStart; + break; + case ax::mojom::blink::MoveDirection::kForward: + text_boundary = ax::mojom::blink::TextBoundary::kWordEnd; + break; + } + break; + case TextGranularity::kSentence: + switch (move_direction) { + case ax::mojom::blink::MoveDirection::kBackward: + text_boundary = ax::mojom::blink::TextBoundary::kSentenceStart; + break; + case ax::mojom::blink::MoveDirection::kForward: + text_boundary = ax::mojom::blink::TextBoundary::kSentenceEnd; + break; + } + break; + case TextGranularity::kLine: + switch (move_direction) { + case ax::mojom::blink::MoveDirection::kBackward: + text_boundary = ax::mojom::blink::TextBoundary::kLineStart; + break; + case ax::mojom::blink::MoveDirection::kForward: + text_boundary = ax::mojom::blink::TextBoundary::kLineEnd; + break; + } + break; + case TextGranularity::kParagraph: + switch (move_direction) { + case ax::mojom::blink::MoveDirection::kBackward: + text_boundary = ax::mojom::blink::TextBoundary::kParagraphStart; + break; + case ax::mojom::blink::MoveDirection::kForward: + text_boundary = ax::mojom::blink::TextBoundary::kParagraphEnd; + break; + } + break; + case TextGranularity::kSentenceBoundary: + text_boundary = ax::mojom::blink::TextBoundary::kSentenceStartOrEnd; + break; + case TextGranularity::kLineBoundary: + text_boundary = ax::mojom::blink::TextBoundary::kLineStartOrEnd; + break; + case TextGranularity::kParagraphBoundary: + text_boundary = ax::mojom::blink::TextBoundary::kParagraphStartOrEnd; + break; + case TextGranularity::kDocumentBoundary: + text_boundary = ax::mojom::blink::TextBoundary::kWebPage; + break; + } + + return BlinkAXEventIntent(command, text_boundary, move_direction); +} + +BlinkAXEventIntent BlinkAXEventIntent::FromNewSelection( + const TextGranularity granularity, + bool is_base_first, + const SetSelectionBy set_selection_by) { + // Unfortunately, when setting a completely new selection, |text_boundary| is + // not always known, or is hard to compute. For example, if a new selection + // has been made using the mouse, it would be expensive to compute any + // meaningful granularity information. + ax::mojom::blink::TextBoundary text_boundary; + switch (granularity) { + case TextGranularity::kCharacter: + text_boundary = ax::mojom::blink::TextBoundary::kCharacter; + break; + case TextGranularity::kWord: + text_boundary = ax::mojom::blink::TextBoundary::kWordStartOrEnd; + break; + case TextGranularity::kSentence: + case TextGranularity::kSentenceBoundary: + text_boundary = ax::mojom::blink::TextBoundary::kSentenceStartOrEnd; + break; + case TextGranularity::kLine: + case TextGranularity::kLineBoundary: + text_boundary = ax::mojom::blink::TextBoundary::kLineStartOrEnd; + break; + case TextGranularity::kParagraph: + case TextGranularity::kParagraphBoundary: + text_boundary = ax::mojom::blink::TextBoundary::kParagraphStartOrEnd; + break; + case TextGranularity::kDocumentBoundary: + text_boundary = ax::mojom::blink::TextBoundary::kWebPage; + break; + } + + return BlinkAXEventIntent( + ax::mojom::blink::Command::kSetSelection, text_boundary, + is_base_first ? ax::mojom::blink::MoveDirection::kForward + : ax::mojom::blink::MoveDirection::kBackward); +} + // Creates an empty (uninitialized) instance. BlinkAXEventIntent::BlinkAXEventIntent() = default; @@ -63,7 +211,7 @@ if (key.IsHashTableDeletedValue()) return std::numeric_limits<unsigned>::max(); - unsigned hash = 0u; + unsigned hash = 1u; WTF::AddIntToHash(hash, static_cast<const unsigned>(key.intent().command)); WTF::AddIntToHash(hash, static_cast<const unsigned>(key.intent().text_boundary));
diff --git a/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.h b/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.h index 0273f04..7b4deac 100644 --- a/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.h +++ b/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.h
@@ -8,6 +8,10 @@ #include <string> #include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/editing/selection_modifier.h" +#include "third_party/blink/renderer/core/editing/set_selection_options.h" +#include "third_party/blink/renderer/core/editing/text_granularity.h" +#include "third_party/blink/renderer/platform/text/text_direction.h" #include "third_party/blink/renderer/platform/wtf/hash_table_deleted_value_type.h" #include "third_party/blink/renderer/platform/wtf/hash_traits.h" #include "ui/accessibility/ax_enums.mojom-blink-forward.h" @@ -24,6 +28,19 @@ // previous word, or it could have been moved to the end of the next line. class CORE_EXPORT BlinkAXEventIntent final { public: + static BlinkAXEventIntent FromClearedSelection( + const SetSelectionBy set_selection_by); + static BlinkAXEventIntent FromModifiedSelection( + const SelectionModifyAlteration alter, + const SelectionModifyDirection direction, + const TextGranularity granularity, + const SetSelectionBy set_selection_by, + const TextDirection direction_of_selection); + static BlinkAXEventIntent FromNewSelection( + const TextGranularity granularity, + bool is_base_first, + const SetSelectionBy set_selection_by); + BlinkAXEventIntent(); BlinkAXEventIntent(ax::mojom::blink::Command command, ax::mojom::blink::TextBoundary text_boundary,
diff --git a/third_party/blink/renderer/core/accessibility/scoped_blink_ax_event_intent.cc b/third_party/blink/renderer/core/accessibility/scoped_blink_ax_event_intent.cc index 8558605..11f599f 100644 --- a/third_party/blink/renderer/core/accessibility/scoped_blink_ax_event_intent.cc +++ b/third_party/blink/renderer/core/accessibility/scoped_blink_ax_event_intent.cc
@@ -13,9 +13,13 @@ const BlinkAXEventIntent& intent, Document* document) : document_(document) { - intents_.push_back(intent); DCHECK(document_); DCHECK(document_->IsActive()); + + if (!intent.is_initialized()) + return; + intents_.push_back(intent); + if (AXObjectCache* cache = document_->ExistingAXObjectCache()) { AXObjectCache::BlinkAXEventIntentsSet& active_intents = cache->ActiveEventIntents(); @@ -34,7 +38,8 @@ cache->ActiveEventIntents(); for (const auto& intent : intents) { - active_intents.insert(intent); + if (intent.is_initialized()) + active_intents.insert(intent); } } }
diff --git a/third_party/blink/renderer/core/core_initializer.cc b/third_party/blink/renderer/core/core_initializer.cc index cb5ad15..04c64c22 100644 --- a/third_party/blink/renderer/core/core_initializer.cc +++ b/third_party/blink/renderer/core/core_initializer.cc
@@ -31,6 +31,7 @@ #include "third_party/blink/renderer/core/core_initializer.h" #include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/public/web/blink.h" #include "third_party/blink/renderer/bindings/core/v8/binding_security.h" #include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h" #include "third_party/blink/renderer/core/css/media_feature_names.h" @@ -67,6 +68,11 @@ CoreInitializer* CoreInitializer::instance_ = nullptr; +// Function defined in third_party/blink/public/web/blink.h. +void ForceNextWebGLContextCreationToFailForTest() { + CoreInitializer::GetInstance().ForceNextWebGLContextCreationToFail(); +} + void CoreInitializer::RegisterEventFactory() { static bool is_registered = false; if (is_registered)
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5 index 1004043f..4121f2e 100644 --- a/third_party/blink/renderer/core/css/css_properties.json5 +++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -163,6 +163,20 @@ valid_type: "bool", }, + // - computed_value_compare_fields + // + // If present, the ComputedStyle fields listed will be used in the + // generated ComputedvaluesEqual function. This is useful if the value + // of a property is stored in multiple fields. For example, for + // vertical-align: + // + // computed_value_compare_fields: ['VerticalAlign', 'GetVerticalAlignLength'] + // + // Has no effect unless computed_value_comparable is true. + computed_value_compare_fields: { + default: [], + }, + // - runtime_flag // The name of the flag on RuntimeEnabledFeatures // (e.g. "CSSOverscrollBehavior") that conditionally enables the @@ -3826,6 +3840,8 @@ typedom_types: ["Keyword", "Length", "Percentage"], keywords: ["baseline", "sub", "super", "text-top", "text-bottom", "middle"], valid_for_first_letter: true, + computed_value_comparable: true, + computed_value_compare_fields: ['VerticalAlign', 'GetVerticalAlignLength'] }, { name: "visibility",
diff --git a/third_party/blink/renderer/core/css/properties/css_property_test.cc b/third_party/blink/renderer/core/css/properties/css_property_test.cc index 308e5ec..7dca63e 100644 --- a/third_party/blink/renderer/core/css/properties/css_property_test.cc +++ b/third_party/blink/renderer/core/css/properties/css_property_test.cc
@@ -141,6 +141,7 @@ const char* color_examples[] = {"red", "green", "#fef", "#faf", nullptr}; const char* direction_examples[] = {"ltr", "rtl", nullptr}; const char* length_or_auto_examples[] = {"auto", "1px", "2px", "5%", nullptr}; +const char* vertical_align_examples[] = {"sub", "super", "1px", "3%", nullptr}; const char* writing_mode_examples[] = {"horizontal-tb", "vertical-rl", nullptr}; struct ComputedValuesEqualData { @@ -157,6 +158,7 @@ {"left", length_or_auto_examples}, {"right", length_or_auto_examples}, {"top", length_or_auto_examples}, + {"vertical-align", vertical_align_examples}, {"writing-mode", writing_mode_examples}, };
diff --git a/third_party/blink/renderer/core/editing/dom_selection.cc b/third_party/blink/renderer/core/editing/dom_selection.cc index 5c6960c..c690a20 100644 --- a/third_party/blink/renderer/core/editing/dom_selection.cc +++ b/third_party/blink/renderer/core/editing/dom_selection.cc
@@ -96,7 +96,7 @@ if (!did_set) return; Element* focused_element = GetFrame()->GetDocument()->FocusedElement(); - frame_selection.DidSetSelectionDeprecated(options); + frame_selection.DidSetSelectionDeprecated(selection, options); if (GetFrame() && GetFrame()->GetDocument() && focused_element != GetFrame()->GetDocument()->FocusedElement()) { UseCounter::Count(GetFrame()->GetDocument(),
diff --git a/third_party/blink/renderer/core/editing/frame_selection.cc b/third_party/blink/renderer/core/editing/frame_selection.cc index b068e2f..902dfca 100644 --- a/third_party/blink/renderer/core/editing/frame_selection.cc +++ b/third_party/blink/renderer/core/editing/frame_selection.cc
@@ -26,7 +26,11 @@ #include "third_party/blink/renderer/core/editing/frame_selection.h" #include <stdio.h> + +#include "base/auto_reset.h" #include "third_party/blink/renderer/core/accessibility/ax_object_cache.h" +#include "third_party/blink/renderer/core/accessibility/blink_ax_event_intent.h" +#include "third_party/blink/renderer/core/accessibility/scoped_blink_ax_event_intent.h" #include "third_party/blink/renderer/core/css/css_property_value_set.h" #include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h" #include "third_party/blink/renderer/core/dom/character_data.h" @@ -83,6 +87,7 @@ #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" +#include "third_party/blink/renderer/platform/text/text_direction.h" #include "third_party/blink/renderer/platform/text/unicode_utilities.h" #define EDIT_DEBUG 0 @@ -186,7 +191,7 @@ void FrameSelection::SetSelection(const SelectionInDOMTree& selection, const SetSelectionOptions& data) { if (SetSelectionDeprecated(selection, data)) - DidSetSelectionDeprecated(data); + DidSetSelectionDeprecated(selection, data); } void FrameSelection::SetSelectionAndEndTyping( @@ -267,9 +272,28 @@ } void FrameSelection::DidSetSelectionDeprecated( + const SelectionInDOMTree& new_selection, const SetSelectionOptions& options) { - const Document& current_document = GetDocument(); - if (!GetSelectionInDOMTree().IsNone() && !options.DoNotSetFocus()) { + Document& current_document = GetDocument(); + const SetSelectionBy set_selection_by = options.GetSetSelectionBy(); + + // Provides details to accessibility about the selection change throughout the + // current call stack. + // + // If the selection is currently being modified via the "Modify" method, we + // should already have more detailed information on the stack than can be + // deduced in this method. + ScopedBlinkAXEventIntent scoped_blink_ax_event_intent( + is_being_modified_ + ? BlinkAXEventIntent() + : new_selection.IsNone() + ? BlinkAXEventIntent::FromClearedSelection(set_selection_by) + : BlinkAXEventIntent::FromNewSelection( + options.Granularity(), new_selection.IsBaseFirst(), + set_selection_by), + ¤t_document); + + if (!new_selection.IsNone() && !options.DoNotSetFocus()) { SetFocusedNodeIfNeeded(); // |setFocusedNodeIfNeeded()| dispatches sync events "FocusOut" and // "FocusIn", |frame_| may associate to another document. @@ -298,7 +322,7 @@ return; } } - const SetSelectionBy set_selection_by = options.GetSetSelectionBy(); + NotifyTextControlOfSelectionChange(set_selection_by); if (set_selection_by == SetSelectionBy::kUser) { const CursorAlignOnScroll align = options.GetCursorAlignOnScroll(); @@ -398,6 +422,15 @@ return true; } + // Provides details to accessibility about the selection change throughout the + // current call stack. + base::AutoReset<bool> is_being_modified_resetter(&is_being_modified_, true); + ScopedBlinkAXEventIntent scoped_blink_ax_event_intent( + BlinkAXEventIntent::FromModifiedSelection( + alter, direction, granularity, set_selection_by, + selection_modifier.DirectionOfSelection()), + &GetDocument()); + // For MacOS only selection is directionless at the beginning. // Selection gets direction on extent. const bool selection_is_directional =
diff --git a/third_party/blink/renderer/core/editing/frame_selection.h b/third_party/blink/renderer/core/editing/frame_selection.h index 263f259..34ba4c4 100644 --- a/third_party/blink/renderer/core/editing/frame_selection.h +++ b/third_party/blink/renderer/core/editing/frame_selection.h
@@ -166,7 +166,8 @@ // be called. bool SetSelectionDeprecated(const SelectionInDOMTree&, const SetSelectionOptions&); - void DidSetSelectionDeprecated(const SetSelectionOptions&); + void DidSetSelectionDeprecated(const SelectionInDOMTree&, + const SetSelectionOptions&); // Call this after doing user-triggered selections to make it easy to delete // the frame you entirely selected. @@ -323,6 +324,10 @@ LayoutUnit x_pos_for_vertical_arrow_navigation_; bool focused_ : 1; + + // The selection is currently being modified via the "Modify" method. + bool is_being_modified_ = false; + bool is_handle_visible_ = false; // TODO(editing-dev): We should change is_directional_ type to enum. // as directional can have three values forward, backward or directionless.
diff --git a/third_party/blink/renderer/core/editing/selection_modifier.h b/third_party/blink/renderer/core/editing/selection_modifier.h index 3aebd05..0beea62 100644 --- a/third_party/blink/renderer/core/editing/selection_modifier.h +++ b/third_party/blink/renderer/core/editing/selection_modifier.h
@@ -61,6 +61,8 @@ // to return |current_selection_|. VisibleSelection Selection() const; + TextDirection DirectionOfSelection() const; + bool Modify(SelectionModifyAlteration, SelectionModifyDirection, TextGranularity); @@ -78,7 +80,6 @@ VisibleSelection PrepareToModifySelection(SelectionModifyAlteration, SelectionModifyDirection) const; TextDirection DirectionOfEnclosingBlock() const; - TextDirection DirectionOfSelection() const; TextDirection LineDirectionOfExtent() const; VisiblePosition PositionForPlatform(bool is_get_start) const; VisiblePosition StartForPlatform() const;
diff --git a/third_party/blink/renderer/core/exported/web_element_test.cc b/third_party/blink/renderer/core/exported/web_element_test.cc index 14f6a43a..febcef1 100644 --- a/third_party/blink/renderer/core/exported/web_element_test.cc +++ b/third_party/blink/renderer/core/exported/web_element_test.cc
@@ -83,21 +83,9 @@ { extends:'button' }); document.body.appendChild( document.createElement('button', { is: 'v1-builtin' })); - - document.registerElement('v0-custom'); - document.body.appendChild(document.createElement('v0-custom')); - document.registerElement('v0-typext', { - prototype: Object.create(HTMLInputElement.prototype), - extends: 'input' }); - document.body.appendChild(document.createElement('input', 'v0-typeext')); )JS"); GetDocument().body()->appendChild(script); - auto* v0typeext = GetDocument().body()->lastChild(); - EXPECT_FALSE(WebElement(To<Element>(v0typeext)).IsAutonomousCustomElement()); - auto* v0autonomous = v0typeext->previousSibling(); - EXPECT_TRUE( - WebElement(To<Element>(v0autonomous)).IsAutonomousCustomElement()); - auto* v1builtin = v0autonomous->previousSibling(); + auto* v1builtin = GetDocument().body()->lastChild(); EXPECT_FALSE(WebElement(To<Element>(v1builtin)).IsAutonomousCustomElement()); auto* v1autonomous = v1builtin->previousSibling(); EXPECT_TRUE(
diff --git a/third_party/blink/renderer/core/exported/web_frame_test.cc b/third_party/blink/renderer/core/exported/web_frame_test.cc index 0e0df46b..05805cc 100644 --- a/third_party/blink/renderer/core/exported/web_frame_test.cc +++ b/third_party/blink/renderer/core/exported/web_frame_test.cc
@@ -35,7 +35,9 @@ #include <memory> #include "base/bind_helpers.h" +#include "base/optional.h" #include "base/stl_util.h" +#include "base/unguessable_token.h" #include "build/build_config.h" #include "cc/input/overscroll_behavior.h" #include "cc/layers/picture_layer.h" @@ -53,6 +55,7 @@ #include "third_party/blink/public/common/context_menu_data/edit_flags.h" #include "third_party/blink/public/common/input/web_coalesced_input_event.h" #include "third_party/blink/public/common/input/web_keyboard_event.h" +#include "third_party/blink/public/common/messaging/transferable_message.h" #include "third_party/blink/public/common/page/launching_process_state.h" #include "third_party/blink/public/mojom/blob/blob.mojom-blink.h" #include "third_party/blink/public/mojom/blob/data_element.mojom-blink.h" @@ -144,6 +147,7 @@ #include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/loader/document_loader.h" #include "third_party/blink/renderer/core/loader/frame_load_request.h" +#include "third_party/blink/renderer/core/messaging/blink_transferable_message.h" #include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/drag_image.h" #include "third_party/blink/renderer/core/page/page.h" @@ -1112,28 +1116,30 @@ << "An invalid selector shouldn't prevent other selectors from matching."; } -TEST_F(WebFrameTest, DispatchMessageEventWithOriginCheck) { +TEST_F(WebFrameTest, PostMessageEvent) { RegisterMockedHttpURLLoad("postmessage_test.html"); frame_test_helpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "postmessage_test.html"); - // Send a message with the correct origin. - WebSecurityOrigin correct_origin( - WebSecurityOrigin::Create(ToKURL(base_url_))); - WebDocument document = web_view_helper.LocalMainFrame()->GetDocument(); WebSerializedScriptValue data(WebSerializedScriptValue::CreateInvalid()); WebDOMMessageEvent message(data, "http://origin.com"); - web_view_helper.GetWebView() - ->MainFrameImpl() - ->DispatchMessageEventWithOriginCheck(correct_origin, message); + auto* frame = + To<LocalFrame>(web_view_helper.GetWebView()->GetPage()->MainFrame()); + + // Send a message with the correct origin. + scoped_refptr<SecurityOrigin> correct_origin = + SecurityOrigin::Create(ToKURL(base_url_)); + frame->PostMessageEvent(base::nullopt, g_empty_string, + correct_origin->ToString(), + ToBlinkTransferableMessage(message.AsMessage())); // Send another message with incorrect origin. - WebSecurityOrigin incorrect_origin( - WebSecurityOrigin::Create(ToKURL(chrome_url_))); - web_view_helper.GetWebView() - ->MainFrameImpl() - ->DispatchMessageEventWithOriginCheck(incorrect_origin, message); + scoped_refptr<SecurityOrigin> incorrect_origin = + SecurityOrigin::Create(ToKURL(chrome_url_)); + frame->PostMessageEvent(base::nullopt, g_empty_string, + incorrect_origin->ToString(), + ToBlinkTransferableMessage(message.AsMessage())); // Verify that only the first addition is in the body of the page. std::string content = WebFrameContentDumper::DumpWebViewAsText(
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc index 54e403b07..ebebe2f 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.cc +++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -146,7 +146,6 @@ #include "third_party/blink/renderer/core/timing/dom_window_performance.h" #include "third_party/blink/renderer/core/timing/window_performance.h" #include "third_party/blink/renderer/platform/fonts/font_cache.h" -#include "third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h" #include "third_party/blink/renderer/platform/graphics/image.h" #include "third_party/blink/renderer/platform/graphics/paint/cull_rect.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h" @@ -160,7 +159,6 @@ #include "third_party/blink/renderer/platform/scheduler/public/page_lifecycle_state.h" #include "third_party/blink/renderer/platform/scheduler/public/page_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" -#include "third_party/blink/renderer/platform/weborigin/scheme_registry.h" #include "third_party/blink/renderer/platform/widget/widget_base.h" #include "ui/gfx/skia_util.h" @@ -2950,12 +2948,6 @@ return GetPage() ? GetPage()->GetFocusController().IsActive() : false; } -void WebViewImpl::SetDomainRelaxationForbidden(bool forbidden, - const WebString& scheme) { - SchemeRegistry::SetDomainRelaxationForbiddenForURLScheme(forbidden, - String(scheme)); -} - void WebViewImpl::SetWindowFeatures(const WebWindowFeatures& features) { AsView().page->SetWindowFeatures(features); } @@ -3099,12 +3091,6 @@ SetZoomLevel(ZoomLevel()); } -void WebViewImpl::SetMainFrameOverlayColor(SkColor color) { - DCHECK(AsView().page->MainFrame()); - if (auto* local_frame = DynamicTo<LocalFrame>(AsView().page->MainFrame())) - local_frame->SetMainFrameColorOverlay(color); -} - Element* WebViewImpl::FocusedElement() const { LocalFrame* frame = AsView().page->GetFocusController().FocusedFrame(); if (!frame) @@ -3335,14 +3321,6 @@ return GetPage()->GetVisibilityState(); } -void WebViewImpl::ForceNextWebGLContextCreationToFail() { - CoreInitializer::GetInstance().ForceNextWebGLContextCreationToFail(); -} - -void WebViewImpl::ForceNextDrawingBufferCreationToFail() { - DrawingBuffer::ForceNextDrawingBufferCreationToFail(); -} - float WebViewImpl::DeviceScaleFactor() const { // TODO(oshima): Investigate if this should return the ScreenInfo's scale // factor rather than page's scale factor, which can be 1 in use-zoom-for-dsf
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.h b/third_party/blink/renderer/core/exported/web_view_impl.h index 1fb22f3..ae5bf52 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.h +++ b/third_party/blink/renderer/core/exported/web_view_impl.h
@@ -134,7 +134,6 @@ void SetTabKeyCyclesThroughElements(bool value) override; bool IsActive() const override; void SetIsActive(bool value) override; - void SetDomainRelaxationForbidden(bool, const WebString& scheme) override; void SetWindowFeatures(const WebWindowFeatures&) override; void SetOpenedByDOM() override; void ResizeWithBrowserControls(const WebSize& main_frame_widget_size, @@ -196,7 +195,6 @@ void DidCloseContextMenu() override; void CancelPagePopup() override; WebPagePopupImpl* GetPagePopup() const override { return page_popup_.get(); } - void SetMainFrameOverlayColor(SkColor) override; void AcceptLanguagesChanged() override; void SetPageFrozen(bool frozen) override; void PutPageIntoBackForwardCache() override; @@ -386,9 +384,6 @@ // changed. void DidUpdateBrowserControls(); - void ForceNextWebGLContextCreationToFail() override; - void ForceNextDrawingBufferCreationToFail() override; - void AddAutoplayFlags(int32_t) override; void ClearAutoplayFlags() override; int32_t AutoplayFlagsForTest() override;
diff --git a/third_party/blink/renderer/core/frame/deprecation.cc b/third_party/blink/renderer/core/frame/deprecation.cc index 7ded8c3..8e50dac6 100644 --- a/third_party/blink/renderer/core/frame/deprecation.cc +++ b/third_party/blink/renderer/core/frame/deprecation.cc
@@ -532,6 +532,44 @@ "details.", MilestoneString(kM84).Ascii().c_str())}; + case WebFeature::kV8RTCRtpSender_CreateEncodedAudioStreams_Method: + return {"V8RTCRtpSender_CreateEncodedAudioStreams_Method", kM85, + ReplacedWillBeRemoved("RTCRtpSender.createEncodedAudioStreams", + "RTCRtpSender.createEncodedStreams", kM85, + "6321945865879552")}; + + case WebFeature::kV8RTCRtpSender_CreateEncodedVideoStreams_Method: + return {"V8RTCRtpSender_CreateEncodedVideoStreams_Method", kM85, + ReplacedWillBeRemoved("RTCRtpSender.createEncodedVideoStreams", + "RTCRtpSender.createEncodedStreams", kM85, + "6321945865879552")}; + + case WebFeature::kV8RTCRtpReceiver_CreateEncodedAudioStreams_Method: + return {"V8RTCRtpReceiver_CreateEncodedAudioStreams_Method", kM85, + ReplacedWillBeRemoved("RTCRtpReceiver.createEncodedAudioStreams", + "RTCRtpReceiver.createEncodedStreams", kM85, + "6321945865879552")}; + + case WebFeature::kV8RTCRtpReceiver_CreateEncodedVideoStreams_Method: + return {"V8RTCRtpReceiver_CreateEncodedVideoStreams_Method", kM85, + ReplacedWillBeRemoved("RTCRtpReceiver.createEncodedVideoStreams", + "RTCRtpReceiver.createEncodedStreams", kM85, + "6321945865879552")}; + + case WebFeature::kForceEncodedAudioInsertableStreams: + return {"ForceEncodedAudioInsertableStreams", kM85, + ReplacedWillBeRemoved( + "RTCConfiguration.forceEncodedAudioInsertableStreams", + "RTCConfiguration.encodedInsertableStreams", kM85, + "6321945865879552")}; + + case WebFeature::kForceEncodedVideoInsertableStreams: + return {"ForceEncodedVideoInsertableStreams", kM85, + ReplacedWillBeRemoved( + "RTCConfiguration.forceEncodedVideoInsertableStreams", + "RTCConfiguration.encodedInsertableStreams", kM85, + "6321945865879552")}; + // Features that aren't deprecated don't have a deprecation message. default: return {"NotDeprecated", kUnknown, ""};
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index 48988d8..453cc538 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -106,6 +106,7 @@ #include "third_party/blink/renderer/core/frame/reporting_context.h" #include "third_party/blink/renderer/core/frame/root_frame_viewport.h" #include "third_party/blink/renderer/core/frame/settings.h" +#include "third_party/blink/renderer/core/frame/user_activation.h" #include "third_party/blink/renderer/core/frame/visual_viewport.h" #include "third_party/blink/renderer/core/frame/web_frame_widget_base.h" #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" @@ -127,6 +128,7 @@ #include "third_party/blink/renderer/core/loader/document_loader.h" #include "third_party/blink/renderer/core/loader/frame_load_request.h" #include "third_party/blink/renderer/core/loader/idleness_detector.h" +#include "third_party/blink/renderer/core/messaging/message_port.h" #include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/drag_controller.h" #include "third_party/blink/renderer/core/page/focus_controller.h" @@ -2601,12 +2603,78 @@ } void LocalFrame::OnScreensChange() { - if (RuntimeEnabledFeatures::ScreenEnumerationEnabled()) { + if (RuntimeEnabledFeatures::WindowPlacementEnabled()) { DomWindow()->DispatchEvent( *Event::Create(event_type_names::kScreenschange)); } } +void LocalFrame::PostMessageEvent( + const base::Optional<base::UnguessableToken>& source_frame_token, + const String& source_origin, + const String& target_origin, + BlinkTransferableMessage message) { + RemoteFrame* source_frame = SourceFrameForOptionalToken(source_frame_token); + + // We must pass in the target_origin to do the security check on this side, + // since it may have changed since the original postMessage call was made. + scoped_refptr<SecurityOrigin> target_security_origin; + if (!target_origin.IsEmpty()) { + target_security_origin = SecurityOrigin::CreateFromString(target_origin); + } + + // Preparation of the MessageEvent. + MessageEvent* message_event = MessageEvent::Create(); + DOMWindow* window = nullptr; + if (source_frame) + window = source_frame->DomWindow(); + MessagePortArray* ports = nullptr; + if (GetDocument()) { + ports = MessagePort::EntanglePorts(*GetDocument()->GetExecutionContext(), + std::move(message.ports)); + } + UserActivation* user_activation = nullptr; + if (message.user_activation) { + user_activation = MakeGarbageCollected<UserActivation>( + message.user_activation->has_been_active, + message.user_activation->was_active); + } + message_event->initMessageEvent( + "message", false, false, std::move(message.message), source_origin, + "" /*lastEventId*/, window, ports, user_activation, + message.transfer_user_activation, message.allow_autoplay); + + // If the agent cluster id had a value it means this was locked when it + // was serialized. + if (message.locked_agent_cluster_id) + message_event->LockToAgentCluster(); + + // Transfer user activation state in the target's renderer when + // |transferUserActivation| is true. + // + // Also do the same as an ad-hoc solution to allow the origin trial of dynamic + // delegation of autoplay capability through postMessages. Note that we + // skipped updating the user activation states in all other copies of the + // frame tree in this case because this is a temporary hack. + // + // TODO(mustaq): Remove the ad-hoc solution when the API shape is + // ready. https://crbug.com/985914 + if ((RuntimeEnabledFeatures::UserActivationPostMessageTransferEnabled() && + message.transfer_user_activation) || + message.allow_autoplay) { + TransferUserActivationFrom(source_frame); + if (message.allow_autoplay) + UseCounter::Count(GetDocument(), WebFeature::kAutoplayDynamicDelegation); + } + + // Finally dispatch the message to the DOM Window. + DomWindow()->DispatchMessageEventWithOriginCheck( + target_security_origin.get(), message_event, + std::make_unique<SourceLocation>(String(), 0, 0, nullptr), + message.locked_agent_cluster_id ? message.locked_agent_cluster_id.value() + : base::UnguessableToken()); +} + void LocalFrame::BindReportingObserver( mojo::PendingReceiver<mojom::blink::ReportingObserver> receiver) { ReportingContext::From(DomWindow())->Bind(std::move(receiver));
diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h index e466b46..a222d33c 100644 --- a/third_party/blink/renderer/core/frame/local_frame.h +++ b/third_party/blink/renderer/core/frame/local_frame.h
@@ -555,6 +555,11 @@ // the next navigation. void DidUpdateFramePolicy(const FramePolicy& frame_policy) final; void OnScreensChange() final; + void PostMessageEvent( + const base::Optional<base::UnguessableToken>& source_frame_token, + const String& source_origin, + const String& target_origin, + BlinkTransferableMessage message) final; void BindReportingObserver( mojo::PendingReceiver<mojom::blink::ReportingObserver> receiver) final;
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc index 13dde79..81a577b 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -3005,11 +3005,13 @@ } WTF::Vector<const TransformPaintPropertyNode*> scroll_translation_nodes; - ForAllNonThrottledLocalFrameViews( - [&scroll_translation_nodes](LocalFrameView& frame_view) { - scroll_translation_nodes.AppendVector( - frame_view.GetScrollTranslationNodes()); - }); + if (RuntimeEnabledFeatures::ScrollUnificationEnabled()) { + ForAllNonThrottledLocalFrameViews( + [&scroll_translation_nodes](LocalFrameView& frame_view) { + scroll_translation_nodes.AppendVector( + frame_view.GetScrollTranslationNodes()); + }); + } paint_artifact_compositor_->Update( paint_controller_->GetPaintArtifactShared(), viewport_properties,
diff --git a/third_party/blink/renderer/core/frame/mhtml_loading_test.cc b/third_party/blink/renderer/core/frame/mhtml_loading_test.cc index ec2b154f..2c22e85 100644 --- a/third_party/blink/renderer/core/frame/mhtml_loading_test.cc +++ b/third_party/blink/renderer/core/frame/mhtml_loading_test.cc
@@ -191,7 +191,6 @@ Document* document = frame->GetDocument(); ASSERT_TRUE(document); - EXPECT_TRUE(IsShadowHost(document->getElementById("h1"))); EXPECT_TRUE(IsShadowHost(document->getElementById("h2"))); // The nested shadow DOM tree is created. EXPECT_TRUE(IsShadowHost(
diff --git a/third_party/blink/renderer/core/frame/remote_frame.h b/third_party/blink/renderer/core/frame/remote_frame.h index 5371736e..dc29695f 100644 --- a/third_party/blink/renderer/core/frame/remote_frame.h +++ b/third_party/blink/renderer/core/frame/remote_frame.h
@@ -34,7 +34,7 @@ class CORE_EXPORT RemoteFrame final : public Frame, public mojom::blink::RemoteFrame { public: - // Returns the RenderFrameProxy for the given |frame_token|. + // Returns the RemoteFrame for the given |frame_token|. static RemoteFrame* FromFrameToken(const base::UnguessableToken& frame_token); // For a description of |inheriting_agent_factory| go see the comment on the
diff --git a/third_party/blink/renderer/core/frame/screen.cc b/third_party/blink/renderer/core/frame/screen.cc index 0970dafd..44100293 100644 --- a/third_party/blink/renderer/core/frame/screen.cc +++ b/third_party/blink/renderer/core/frame/screen.cc
@@ -50,7 +50,7 @@ int Screen::height() const { if (display_) { - DCHECK(RuntimeEnabledFeatures::ScreenEnumerationEnabled()); + DCHECK(RuntimeEnabledFeatures::WindowPlacementEnabled()); return display_->bounds.height(); } LocalFrame* frame = GetFrame(); @@ -67,7 +67,7 @@ int Screen::width() const { if (display_) { - DCHECK(RuntimeEnabledFeatures::ScreenEnumerationEnabled()); + DCHECK(RuntimeEnabledFeatures::WindowPlacementEnabled()); return display_->bounds.width(); } LocalFrame* frame = GetFrame(); @@ -84,7 +84,7 @@ unsigned Screen::colorDepth() const { if (display_) { - DCHECK(RuntimeEnabledFeatures::ScreenEnumerationEnabled()); + DCHECK(RuntimeEnabledFeatures::WindowPlacementEnabled()); return display_->color_depth; } LocalFrame* frame = GetFrame(); @@ -99,7 +99,7 @@ int Screen::availLeft() const { if (display_) { - DCHECK(RuntimeEnabledFeatures::ScreenEnumerationEnabled()); + DCHECK(RuntimeEnabledFeatures::WindowPlacementEnabled()); return display_->work_area.x(); } LocalFrame* frame = GetFrame(); @@ -116,7 +116,7 @@ int Screen::availTop() const { if (display_) { - DCHECK(RuntimeEnabledFeatures::ScreenEnumerationEnabled()); + DCHECK(RuntimeEnabledFeatures::WindowPlacementEnabled()); return display_->work_area.y(); } LocalFrame* frame = GetFrame(); @@ -133,7 +133,7 @@ int Screen::availHeight() const { if (display_) { - DCHECK(RuntimeEnabledFeatures::ScreenEnumerationEnabled()); + DCHECK(RuntimeEnabledFeatures::WindowPlacementEnabled()); return display_->work_area.height(); } LocalFrame* frame = GetFrame(); @@ -150,7 +150,7 @@ int Screen::availWidth() const { if (display_) { - DCHECK(RuntimeEnabledFeatures::ScreenEnumerationEnabled()); + DCHECK(RuntimeEnabledFeatures::WindowPlacementEnabled()); return display_->work_area.width(); } LocalFrame* frame = GetFrame(); @@ -183,7 +183,7 @@ int Screen::left() const { if (display_) { - DCHECK(RuntimeEnabledFeatures::ScreenEnumerationEnabled()); + DCHECK(RuntimeEnabledFeatures::WindowPlacementEnabled()); return display_->bounds.x(); } LocalFrame* frame = GetFrame(); @@ -200,7 +200,7 @@ int Screen::top() const { if (display_) { - DCHECK(RuntimeEnabledFeatures::ScreenEnumerationEnabled()); + DCHECK(RuntimeEnabledFeatures::WindowPlacementEnabled()); return display_->bounds.y(); } LocalFrame* frame = GetFrame(); @@ -217,7 +217,7 @@ bool Screen::internal() const { if (display_) { - DCHECK(RuntimeEnabledFeatures::ScreenEnumerationEnabled()); + DCHECK(RuntimeEnabledFeatures::WindowPlacementEnabled()); return internal_.has_value() && internal_.value(); } // TODO(http://crbug.com/994889): Implement this for |window.screen|? @@ -227,7 +227,7 @@ bool Screen::primary() const { if (display_) { - DCHECK(RuntimeEnabledFeatures::ScreenEnumerationEnabled()); + DCHECK(RuntimeEnabledFeatures::WindowPlacementEnabled()); return primary_.has_value() && primary_.value(); } // TODO(http://crbug.com/994889): Implement this for |window.screen|? @@ -237,7 +237,7 @@ float Screen::scaleFactor() const { if (display_) { - DCHECK(RuntimeEnabledFeatures::ScreenEnumerationEnabled()); + DCHECK(RuntimeEnabledFeatures::WindowPlacementEnabled()); return display_->device_scale_factor; } LocalFrame* frame = GetFrame(); @@ -248,7 +248,7 @@ const String Screen::id() const { if (display_) { - DCHECK(RuntimeEnabledFeatures::ScreenEnumerationEnabled()); + DCHECK(RuntimeEnabledFeatures::WindowPlacementEnabled()); return id_; } // TODO(http://crbug.com/994889): Implement this for |window.screen|? @@ -258,7 +258,7 @@ bool Screen::touchSupport() const { if (display_) { - DCHECK(RuntimeEnabledFeatures::ScreenEnumerationEnabled()); + DCHECK(RuntimeEnabledFeatures::WindowPlacementEnabled()); return display_->touch_support == display::mojom::blink::TouchSupport::AVAILABLE; } @@ -269,7 +269,7 @@ int64_t Screen::DisplayId() const { if (display_) { - DCHECK(RuntimeEnabledFeatures::ScreenEnumerationEnabled()); + DCHECK(RuntimeEnabledFeatures::WindowPlacementEnabled()); return display_->id; } return kInvalidDisplayId;
diff --git a/third_party/blink/renderer/core/frame/screen.idl b/third_party/blink/renderer/core/frame/screen.idl index 8402cd58..9a5e18d 100644 --- a/third_party/blink/renderer/core/frame/screen.idl +++ b/third_party/blink/renderer/core/frame/screen.idl
@@ -44,11 +44,11 @@ // Proposed // https://github.com/webscreens/screen-enumeration - [RuntimeEnabled=ScreenEnumeration] readonly attribute long left; - [RuntimeEnabled=ScreenEnumeration] readonly attribute long top; - [RuntimeEnabled=ScreenEnumeration] readonly attribute boolean internal; - [RuntimeEnabled=ScreenEnumeration] readonly attribute boolean primary; - [RuntimeEnabled=ScreenEnumeration] readonly attribute float scaleFactor; - [RuntimeEnabled=ScreenEnumeration] readonly attribute DOMString id; - [RuntimeEnabled=ScreenEnumeration] readonly attribute boolean touchSupport; + [RuntimeEnabled=WindowPlacement] readonly attribute long left; + [RuntimeEnabled=WindowPlacement] readonly attribute long top; + [RuntimeEnabled=WindowPlacement] readonly attribute boolean internal; + [RuntimeEnabled=WindowPlacement] readonly attribute boolean primary; + [RuntimeEnabled=WindowPlacement] readonly attribute float scaleFactor; + [RuntimeEnabled=WindowPlacement] readonly attribute DOMString id; + [RuntimeEnabled=WindowPlacement] readonly attribute boolean touchSupport; };
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc index 2627293..64803c9 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -119,7 +119,6 @@ #include "third_party/blink/public/web/web_console_message.h" #include "third_party/blink/public/web/web_content_capture_client.h" #include "third_party/blink/public/web/web_document.h" -#include "third_party/blink/public/web/web_dom_message_event.h" #include "third_party/blink/public/web/web_form_element.h" #include "third_party/blink/public/web/web_frame_owner_properties.h" #include "third_party/blink/public/web/web_history_item.h" @@ -2215,41 +2214,6 @@ GetFrame()->DomWindow()->SendOrientationChangeEvent(); } -void WebLocalFrameImpl::DispatchMessageEventWithOriginCheck( - const WebSecurityOrigin& intended_target_origin, - const WebDOMMessageEvent& event) { - DCHECK(!event.IsNull()); - - MessageEvent* msg_event = static_cast<MessageEvent*>((Event*)event); - Frame* source_frame = nullptr; - if (msg_event->source() && msg_event->source()->ToDOMWindow()) - source_frame = msg_event->source()->ToDOMWindow()->GetFrame(); - - // Transfer user activation state in the target's renderer when - // |transferUserActivation| is true. - // - // Also do the same as an ad-hoc solution to allow the origin trial of dynamic - // delegation of autoplay capability through postMessages. Note that we - // skipped updating the user activation states in all other copies of the - // frame tree in this case because this is a temporary hack. - // - // TODO(mustaq): Remove the ad-hoc solution when the API shape is - // ready. crbug.com/985914 - if ((RuntimeEnabledFeatures::UserActivationPostMessageTransferEnabled() && - msg_event->transferUserActivation()) || - msg_event->allowAutoplay()) { - GetFrame()->TransferUserActivationFrom(source_frame); - if (msg_event->allowAutoplay()) - UseCounter::Count(GetDocument(), WebFeature::kAutoplayDynamicDelegation); - } - - GetFrame()->DomWindow()->DispatchMessageEventWithOriginCheck( - intended_target_origin.Get(), msg_event, - std::make_unique<SourceLocation>(String(), 0, 0, nullptr), - event.locked_agent_cluster_id() ? event.locked_agent_cluster_id().value() - : base::UnguessableToken()); -} - WebNode WebLocalFrameImpl::ContextMenuNode() const { return ContextMenuNodeInner(); } @@ -2428,6 +2392,10 @@ return CreateMarkup(end_position, start_position, create_markup_options); } +void WebLocalFrameImpl::SetMainFrameOverlayColor(SkColor color) { + GetFrame()->SetMainFrameColorOverlay(color); +} + bool WebLocalFrameImpl::ShouldSuppressKeyboardForFocusedElement() { if (!autofill_client_) return false;
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.h b/third_party/blink/renderer/core/frame/web_local_frame_impl.h index 66a95b485..5ee856c 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.h +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
@@ -250,9 +250,6 @@ void SetTickmarks(const WebVector<WebRect>&) override; WebNode ContextMenuNode() const override; void CopyImageAtForTesting(const gfx::Point&) override; - void DispatchMessageEventWithOriginCheck( - const WebSecurityOrigin& intended_target_origin, - const WebDOMMessageEvent&) override; void UsageCountChromeLoadTimes(const WebString& metric) override; void OnPortalActivated( const base::UnguessableToken& portal_token, @@ -288,6 +285,7 @@ WebPrintPresetOptions*) override; bool CapturePaintPreview(const WebRect& bounds, cc::PaintCanvas* canvas) override; + void SetMainFrameOverlayColor(SkColor) override; bool ShouldSuppressKeyboardForFocusedElement() override; WebPerformance Performance() const override; bool IsAdSubframe() const override;
diff --git a/third_party/blink/renderer/core/input/touch_action_test.cc b/third_party/blink/renderer/core/input/touch_action_test.cc index f05ee05b..7a766694 100644 --- a/third_party/blink/renderer/core/input/touch_action_test.cc +++ b/third_party/blink/renderer/core/input/touch_action_test.cc
@@ -270,6 +270,8 @@ // debugging). Persistent<DOMRectList> rects = element->getClientRects(); ASSERT_GE(rects->length(), 0u) << failure_context.ToString(); + if (!rects->length()) + continue; Persistent<DOMRect> r = rects->item(0); FloatRect client_float_rect = FloatRect(r->left(), r->top(), r->width(), r->height());
diff --git a/third_party/blink/renderer/core/inspector/BUILD.gn b/third_party/blink/renderer/core/inspector/BUILD.gn index e8a912f..a61b2411 100644 --- a/third_party/blink/renderer/core/inspector/BUILD.gn +++ b/third_party/blink/renderer/core/inspector/BUILD.gn
@@ -28,8 +28,6 @@ "dom_editor.h", "dom_patch_support.cc", "dom_patch_support.h", - "dom_traversal_utils.cc", - "dom_traversal_utils.h", "identifiers_factory.cc", "identifiers_factory.h", "inspect_tools.cc",
diff --git a/third_party/blink/renderer/core/inspector/dom_traversal_utils.cc b/third_party/blink/renderer/core/inspector/dom_traversal_utils.cc deleted file mode 100644 index 71a752e0..0000000 --- a/third_party/blink/renderer/core/inspector/dom_traversal_utils.cc +++ /dev/null
@@ -1,46 +0,0 @@ -#include "third_party/blink/renderer/core/inspector/dom_traversal_utils.h" - -#include "third_party/blink/renderer/core/dom/flat_tree_traversal.h" -#include "third_party/blink/renderer/core/dom/node.h" -#include "third_party/blink/renderer/core/dom/shadow_root.h" - -namespace blink { -namespace dom_traversal_utils { - -Node* FirstChild(const Node& node, bool include_user_agent_shadow_tree) { - DCHECK(include_user_agent_shadow_tree || !node.IsInUserAgentShadowRoot()); - if (!include_user_agent_shadow_tree) { - ShadowRoot* shadow_root = node.GetShadowRoot(); - if (shadow_root && shadow_root->GetType() == ShadowRootType::kUserAgent) { - Node* child = node.firstChild(); - while (child && !child->CanParticipateInFlatTree()) - child = child->nextSibling(); - return child; - } - } - return FlatTreeTraversal::FirstChild(node); -} - -// static -bool HasChildren(const Node& node, bool include_user_agent_shadow_tree) { - return FirstChild(node, include_user_agent_shadow_tree); -} - -// static -Node* NextSibling(const Node& node, bool include_user_agent_shadow_tree) { - DCHECK(include_user_agent_shadow_tree || !node.IsInUserAgentShadowRoot()); - if (!include_user_agent_shadow_tree) { - if (node.ParentElementShadowRoot() && - node.ParentElementShadowRoot()->GetType() == - ShadowRootType::kUserAgent) { - Node* sibling = node.nextSibling(); - while (sibling && !sibling->CanParticipateInFlatTree()) - sibling = sibling->nextSibling(); - return sibling; - } - } - return FlatTreeTraversal::NextSibling(node); -} - -} // namespace dom_traversal_utils -} // namespace blink
diff --git a/third_party/blink/renderer/core/inspector/dom_traversal_utils.h b/third_party/blink/renderer/core/inspector/dom_traversal_utils.h deleted file mode 100644 index d4a52a40..0000000 --- a/third_party/blink/renderer/core/inspector/dom_traversal_utils.h +++ /dev/null
@@ -1,22 +0,0 @@ -// 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_INSPECTOR_DOM_TRAVERSAL_UTILS_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_DOM_TRAVERSAL_UTILS_H_ - -namespace blink { - -class Node; - -namespace dom_traversal_utils { - -// These are deprecated, do not use in new code. Use FlatTreeTraversal directly. -Node* FirstChild(const Node& node, bool include_user_agent_shadow_tree); -bool HasChildren(const Node& node, bool include_user_agent_shadow_tree); -Node* NextSibling(const Node& node, bool include_user_agent_shadow_tree); - -} // namespace dom_traversal_utils -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_DOM_TRAVERSAL_UTILS_H_
diff --git a/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc b/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc index 0e4e1b3..85e99a9 100644 --- a/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc
@@ -141,52 +141,6 @@ return node->GetDocument().Url().GetString(); } -class DOMTreeIterator { - STACK_ALLOCATED(); - - public: - DOMTreeIterator(Node* root, int root_node_id) - : current_(root), path_to_current_node_({root_node_id}) { - DCHECK(current_); - } - - void Advance(int next_node_id) { - DCHECK(current_); - const bool skip_shadow_root = - current_->GetShadowRoot() && current_->GetShadowRoot()->IsUserAgent(); - if (Node* first_child = skip_shadow_root - ? current_->firstChild() - : FlatTreeTraversal::FirstChild(*current_)) { - current_ = first_child; - path_to_current_node_.push_back(next_node_id); - return; - } - // No children, let's try siblings, then ancestor siblings. - while (current_) { - if (Node* node = FlatTreeTraversal::NextSibling(*current_)) { - path_to_current_node_.back() = next_node_id; - current_ = node; - return; - } - current_ = FlatTreeTraversal::Parent(*current_); - path_to_current_node_.pop_back(); - } - DCHECK(path_to_current_node_.IsEmpty()); - } - - Node* CurrentNode() const { return current_; } - - int ParentNodeId() const { - return path_to_current_node_.size() > 1 - ? *(path_to_current_node_.rbegin() + 1) - : -1; - } - - private: - Node* current_; - WTF::Vector<int> path_to_current_node_; -}; - } // namespace // Returns |layout_object|'s bounding box in document coordinates. @@ -463,16 +417,11 @@ std::make_unique<protocol::Array<protocol::Array<double>>>()); } - auto* node_names = document_->getNodes()->getNodeName(nullptr); - for (DOMTreeIterator it(document, node_names->size()); it.CurrentNode(); - it.Advance(node_names->size())) { - DCHECK(!it.CurrentNode()->IsInUserAgentShadowRoot()); - VisitNode(it.CurrentNode(), it.ParentNodeId()); - } + VisitNode(document, -1); documents_->emplace_back(std::move(document_)); } -void InspectorDOMSnapshotAgent::VisitNode(Node* node, int parent_index) { +int InspectorDOMSnapshotAgent::VisitNode(Node* node, int parent_index) { String node_value; switch (node->getNodeType()) { case Node::kTextNode: @@ -559,6 +508,62 @@ image_element->currentSrc()); } } + if (node->IsContainerNode()) + VisitContainerChildren(node, index); + return index; +} + +// static +Node* InspectorDOMSnapshotAgent::FirstChild( + const Node& node, + bool include_user_agent_shadow_tree) { + DCHECK(include_user_agent_shadow_tree || !node.IsInUserAgentShadowRoot()); + if (!include_user_agent_shadow_tree) { + ShadowRoot* shadow_root = node.GetShadowRoot(); + if (shadow_root && shadow_root->GetType() == ShadowRootType::kUserAgent) { + Node* child = node.firstChild(); + while (child && !child->CanParticipateInFlatTree()) + child = child->nextSibling(); + return child; + } + } + return FlatTreeTraversal::FirstChild(node); +} + +// static +bool InspectorDOMSnapshotAgent::HasChildren( + const Node& node, + bool include_user_agent_shadow_tree) { + return FirstChild(node, include_user_agent_shadow_tree); +} + +// static +Node* InspectorDOMSnapshotAgent::NextSibling( + const Node& node, + bool include_user_agent_shadow_tree) { + DCHECK(include_user_agent_shadow_tree || !node.IsInUserAgentShadowRoot()); + if (!include_user_agent_shadow_tree) { + if (node.ParentElementShadowRoot() && + node.ParentElementShadowRoot()->GetType() == + ShadowRootType::kUserAgent) { + Node* sibling = node.nextSibling(); + while (sibling && !sibling->CanParticipateInFlatTree()) + sibling = sibling->nextSibling(); + return sibling; + } + } + return FlatTreeTraversal::NextSibling(node); +} + +void InspectorDOMSnapshotAgent::VisitContainerChildren(Node* container, + int parent_index) { + if (!HasChildren(*container, false)) + return; + + for (Node* child = FirstChild(*container, false); child; + child = NextSibling(*child, false)) { + VisitNode(child, parent_index); + } } void InspectorDOMSnapshotAgent::VisitPseudoElements(Element* parent,
diff --git a/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.h b/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.h index d5ef9a5..8587c61 100644 --- a/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.h +++ b/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.h
@@ -57,6 +57,14 @@ void CharacterDataModified(CharacterData*); void DidInsertDOMNode(Node*); + // Helpers for traversal. + static bool HasChildren(const Node& node, + bool include_user_agent_shadow_tree); + static Node* FirstChild(const Node& node, + bool include_user_agent_shadow_tree); + static Node* NextSibling(const Node& node, + bool include_user_agent_shadow_tree); + // Helpers for rects static PhysicalRect RectInDocument(const LayoutObject* layout_object); static PhysicalRect TextFragmentRectInDocument( @@ -80,8 +88,7 @@ const String& value); void SetRare(protocol::DOMSnapshot::RareBooleanData* data, int index); void VisitDocument(Document*); - - void VisitNode(Node*, int parent_index); + int VisitNode(Node*, int parent_index); void VisitContainerChildren(Node* container, int parent_index); void VisitPseudoElements(Element* parent, int parent_index); std::unique_ptr<protocol::Array<int>> BuildArrayForElementAttributes(Node*); @@ -120,7 +127,6 @@ Member<InspectedFrames> inspected_frames_; Member<InspectorDOMDebuggerAgent> dom_debugger_agent_; InspectorAgentState::Boolean enabled_; - DISALLOW_COPY_AND_ASSIGN(InspectorDOMSnapshotAgent); };
diff --git a/third_party/blink/renderer/core/inspector/inspector_highlight.cc b/third_party/blink/renderer/core/inspector/inspector_highlight.cc index e0b532a..bbdeef3 100644 --- a/third_party/blink/renderer/core/inspector/inspector_highlight.cc +++ b/third_party/blink/renderer/core/inspector/inspector_highlight.cc
@@ -13,8 +13,8 @@ #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/frame/visual_viewport.h" #include "third_party/blink/renderer/core/geometry/dom_rect.h" -#include "third_party/blink/renderer/core/inspector/dom_traversal_utils.h" #include "third_party/blink/renderer/core/inspector/inspector_dom_agent.h" +#include "third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.h" #include "third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h" #include "third_party/blink/renderer/core/layout/layout_box.h" #include "third_party/blink/renderer/core/layout/layout_grid.h" @@ -639,10 +639,10 @@ if (!node->IsContainerNode()) return; - for (Node* child = blink::dom_traversal_utils::FirstChild(*node, false); - child; child = blink::dom_traversal_utils::NextSibling(*child, false)) { + Node* first_child = InspectorDOMSnapshotAgent::FirstChild(*node, false); + for (Node* child = first_child; child; + child = InspectorDOMSnapshotAgent::NextSibling(*child, false)) VisitAndCollectDistanceInfo(child); - } } void InspectorHighlight::VisitAndCollectDistanceInfo(
diff --git a/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc b/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc index e39da97..8970aaf50 100644 --- a/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc +++ b/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc
@@ -27,7 +27,6 @@ #include "third_party/blink/renderer/core/html/html_link_element.h" #include "third_party/blink/renderer/core/html/html_template_element.h" #include "third_party/blink/renderer/core/input_type_names.h" -#include "third_party/blink/renderer/core/inspector/dom_traversal_utils.h" #include "third_party/blink/renderer/core/inspector/identifiers_factory.h" #include "third_party/blink/renderer/core/inspector/inspector_dom_agent.h" #include "third_party/blink/renderer/core/inspector/inspector_dom_debugger_agent.h" @@ -304,16 +303,16 @@ bool include_user_agent_shadow_tree) { auto children = std::make_unique<protocol::Array<int>>(); - if (!blink::dom_traversal_utils::HasChildren(*container, - include_user_agent_shadow_tree)) + if (!InspectorDOMSnapshotAgent::HasChildren(*container, + include_user_agent_shadow_tree)) return nullptr; - Node* child = blink::dom_traversal_utils::FirstChild( + Node* child = InspectorDOMSnapshotAgent::FirstChild( *container, include_user_agent_shadow_tree); while (child) { children->emplace_back(VisitNode(child, include_event_listeners, include_user_agent_shadow_tree)); - child = blink::dom_traversal_utils::NextSibling( + child = InspectorDOMSnapshotAgent::NextSibling( *child, include_user_agent_shadow_tree); }
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc index 648f63b0..ebe7229 100644 --- a/third_party/blink/renderer/core/layout/layout_box.cc +++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -304,6 +304,8 @@ NGFragmentItems::LayoutObjectWillBeDestroyed(*this); ClearFirstInlineFragmentItemIndex(); } + if (measure_result_) + measure_result_->PhysicalFragment().LayoutObjectWillBeDestroyed(); for (auto result : layout_results_) result->PhysicalFragment().LayoutObjectWillBeDestroyed(); } @@ -1078,6 +1080,11 @@ PhysicalRect LayoutBox::PhysicalBackgroundRect( BackgroundRectType rect_type) const { + // If the background transfers to view, the used background of this object + // is transparent. + if (rect_type == kBackgroundKnownOpaqueRect && BackgroundTransfersToView()) + return PhysicalRect(); + EFillBox background_box = EFillBox::kText; // Find the largest background rect of the given opaqueness. if (const FillLayer* current = &(StyleRef().BackgroundLayers())) { @@ -1918,11 +1925,6 @@ bool LayoutBox::BackgroundIsKnownToBeOpaqueInRect( const PhysicalRect& local_rect) const { - // If the background transfers to view, the used background of this object - // is transparent. - if (BackgroundTransfersToView()) - return false; - // If the element has appearance, it might be painted by theme. // We cannot be sure if theme paints the background opaque. // In this case it is safe to not assume opaqueness. @@ -1942,6 +1944,25 @@ .Contains(local_rect); } +// TODO(wangxianzhu): The current rules are very basic. May use more complex +// rules if they can improve LCD text. +bool LayoutBox::TextIsKnownToBeOnOpaqueBackground() const { + // Text may overflow the background area. + if (HasVisualOverflow() && !ShouldClipOverflow()) + return false; + // Same as BackgroundIsKnownToBeOpaqueInRect() about appearance. + if (StyleRef().HasEffectiveAppearance()) + return false; + // Text may be drawn in the corner outside the rounded border. + if (StyleRef().HasBorderRadius() && !ShouldClipOverflow()) + return false; + + PhysicalRect rect = PhysicalBorderBoxRect(); + if (ShouldClipOverflow()) + rect.Intersect(OverflowClipRect(PhysicalOffset())); + return PhysicalBackgroundRect(kBackgroundKnownOpaqueRect).Contains(rect); +} + static bool IsCandidateForOpaquenessTest(const LayoutBox& child_box) { const ComputedStyle& child_style = child_box.StyleRef(); if (child_style.GetPosition() != EPosition::kStatic && @@ -2529,10 +2550,18 @@ if (result->GetConstraintSpaceForCaching().CacheSlot() == NGCacheSlot::kMeasure) { + // We don't early return here, when setting the "measure" result we also + // set the "layout" result. if (measure_result_) InvalidateItems(*measure_result_); measure_result_ = result; - // When setting the "measure" result we also set the "layout" result. + } else { + // We have a "layout" result, and we may need to clear the old "measure" + // result if we needed non-simplified layout. + if (measure_result_ && NeedsLayout() && !NeedsSimplifiedLayoutOnly()) { + InvalidateItems(*measure_result_); + measure_result_ = nullptr; + } } AddLayoutResult(std::move(result), 0);
diff --git a/third_party/blink/renderer/core/layout/layout_box.h b/third_party/blink/renderer/core/layout/layout_box.h index 7783d51..121f4cb 100644 --- a/third_party/blink/renderer/core/layout/layout_box.h +++ b/third_party/blink/renderer/core/layout/layout_box.h
@@ -220,6 +220,7 @@ bool BackgroundIsKnownToBeOpaqueInRect( const PhysicalRect& local_rect) const override; + bool TextIsKnownToBeOnOpaqueBackground() const override; virtual bool BackgroundShouldAlwaysBeClipped() const { return false; }
diff --git a/third_party/blink/renderer/core/layout/layout_box_model_object.h b/third_party/blink/renderer/core/layout/layout_box_model_object.h index 2e33f62..6bf304cf 100644 --- a/third_party/blink/renderer/core/layout/layout_box_model_object.h +++ b/third_party/blink/renderer/core/layout/layout_box_model_object.h
@@ -416,6 +416,9 @@ virtual bool BackgroundIsKnownToBeOpaqueInRect(const PhysicalRect&) const { return false; } + // Returns true if all text in the paint-order subtree will be painted on + // opaque background. + virtual bool TextIsKnownToBeOnOpaqueBackground() const { return false; } // This object's background is transferred to its LayoutView if: // 1. it's the document element, or
diff --git a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc index 007b67d6..0a9c5c01 100644 --- a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc
@@ -861,10 +861,10 @@ available_size.block_size = CalculateFixedCrossSize( available_size.block_size, flex_item.min_max_cross_sizes.value(), margins.BlockSum()); - } else { + } else if (DoesItemStretch(flex_item.ng_input_node)) { // If we are in a row flexbox, and we don't have a fixed block-size - // (yet), use the "measure" cache slot. Typically this will be the - // first layout, and we will use the "layout" cache slot if this gets + // (yet), use the "measure" cache slot. This will be the first + // layout, and we will use the "layout" cache slot if this gets // stretched later. // // Setting the "measure" cache slot on the space writes the result
diff --git a/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc index 0bd022b..25629c701 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc
@@ -427,13 +427,21 @@ MinMaxSizesInput(space.PercentageResolutionBlockSize()), &space); }; + Length min_length = style.LogicalMinWidth(); // TODO(cbiesinger): Audit callers of ResolveMainInlineLength to see // whether they need to respect aspect ratio and consider adding a helper // function for that. LayoutUnit extent = kIndefiniteSize; - if (logical_width.IsAuto()) + if (style.AspectRatio() && logical_width.IsAuto()) extent = ComputeInlineSizeFromAspectRatio(space, style, border_padding); - if (LIKELY(extent == kIndefiniteSize)) { + if (UNLIKELY(extent != kIndefiniteSize)) { + // This means we successfully applied aspect-ratio and now need to check + // if we need to apply the implied minimum size: + // https://drafts.csswg.org/css-sizing-4/#aspect-ratio-minimum + if (style.OverflowInlineDirection() == EOverflow::kVisible && + min_length.IsAuto()) + min_length = Length::MinContent(); + } else { if (logical_width.IsAuto() && space.IsShrinkToFit()) logical_width = Length::FitContent(); extent = ResolveMainInlineLength(space, style, border_padding, @@ -443,9 +451,9 @@ LayoutUnit max = ResolveMaxInlineLength( space, style, border_padding, MinMaxSizesFunc, style.LogicalMaxWidth(), LengthResolvePhase::kLayout); - LayoutUnit min = ResolveMinInlineLength( - space, style, border_padding, MinMaxSizesFunc, style.LogicalMinWidth(), - LengthResolvePhase::kLayout); + LayoutUnit min = + ResolveMinInlineLength(space, style, border_padding, MinMaxSizesFunc, + min_length, LengthResolvePhase::kLayout); return ConstrainByMinMax(extent, min, max); }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_space_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_space_utils.cc index 11eec2a..bcda1289 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_space_utils.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_space_utils.cc
@@ -35,6 +35,7 @@ child.CreatesNewFormattingContext()); SetOrthogonalFallbackInlineSizeIfNeeded(container_style, child, &builder); + builder.SetCacheSlot(NGCacheSlot::kMeasure); builder.SetAvailableSize(indefinite_size); builder.SetPercentageResolutionSize(indefinite_size); builder.SetReplacedPercentageResolutionSize(indefinite_size);
diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context.cc b/third_party/blink/renderer/core/loader/frame_fetch_context.cc index 6d37d4d..96ea9ed 100644 --- a/third_party/blink/renderer/core/loader/frame_fetch_context.cc +++ b/third_party/blink/renderer/core/loader/frame_fetch_context.cc
@@ -42,6 +42,7 @@ #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" #include "third_party/blink/public/common/client_hints/client_hints.h" #include "third_party/blink/public/common/device_memory/approximated_device_memory.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/public/mojom/conversions/conversions.mojom-blink.h" #include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h" @@ -121,26 +122,15 @@ // If that flag is disabled (the default), then all hints are always sent for // first-party subresources, and the kAllowClientHintsToThirdParty feature // controls whether some specific hints are sent to third parties. (Only -// device-memory, resource-width, viewport-width and the limited UA hints are -// sent under this model). This feature is enabled by default on Android, and -// disabled by default on all other platforms. +// device-memory, resource-width, viewport-width and DPR are sent under this +// model). This feature is enabled by default on Android, and disabled by +// default on all other platforms. // // When the runtime flag is enabled, all client hints except UA are controlled // entirely by feature policy on all platforms. In that case, hints will // generally be sent for first-party resources, and not for third-party // resources, unless specifically enabled by policy. -// If kAllowClientHintsToThirdParty is enabled, then device-memory, -// resource-width and viewport-width client hints can be sent to third-party -// origins if the first-party has opted in to receiving client hints. -#if defined(OS_ANDROID) -const base::Feature kAllowClientHintsToThirdParty{ - "AllowClientHintsToThirdParty", base::FEATURE_ENABLED_BY_DEFAULT}; -#else -const base::Feature kAllowClientHintsToThirdParty{ - "AllowClientHintsToThirdParty", base::FEATURE_DISABLED_BY_DEFAULT}; -#endif - // Determines FetchCacheMode for |frame|. This FetchCacheMode should be a base // policy to consider one of each resource belonging to the frame, and should // not count resource specific conditions in. @@ -514,7 +504,7 @@ bool is_1p_origin = IsFirstPartyOrigin(request.Url()); if (!RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled() && - !base::FeatureList::IsEnabled(kAllowClientHintsToThirdParty) && + !base::FeatureList::IsEnabled(features::kAllowClientHintsToThirdParty) && !is_1p_origin) { // No client hints for 3p origins. return; @@ -953,7 +943,7 @@ bool origin_ok; if (mode == ClientHintsMode::kLegacy && - base::FeatureList::IsEnabled(kAllowClientHintsToThirdParty)) { + base::FeatureList::IsEnabled(features::kAllowClientHintsToThirdParty)) { origin_ok = true; } else if (RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled()) { origin_ok =
diff --git a/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc b/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc index e0d48c42..1756053 100644 --- a/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc +++ b/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc
@@ -342,14 +342,19 @@ bool OriginTrialContext::EnableTrialFromName(const String& trial_name, base::Time expiry_time) { + if (!CanEnableTrialFromName(trial_name)) { + DVLOG(1) << "EnableTrialFromName: cannot enable trial " << trial_name; + return false; + } + bool did_enable_feature = false; for (OriginTrialFeature feature : origin_trials::FeaturesForTrial(trial_name)) { - if (!origin_trials::FeatureEnabledForOS(feature)) + if (!origin_trials::FeatureEnabledForOS(feature)) { + DVLOG(1) << "EnableTrialFromName: feature " << static_cast<int>(feature) + << " is disabled on current OS."; continue; - - if (!CanEnableTrialFromName(trial_name)) - continue; + } did_enable_feature = true; enabled_features_.insert(feature); @@ -388,6 +393,8 @@ OriginTrialTokenStatus token_result = trial_token_validator_->ValidateToken( token_string.AsStringPiece(), origin->ToUrlOrigin(), base::Time::Now(), &trial_name_str, &expiry_time); + DVLOG(1) << "EnableTrialFromToken: token_result = " + << static_cast<int>(token_result) << ", token = " << token; if (token_result == OriginTrialTokenStatus::kSuccess) { String trial_name = String::FromUTF8(trial_name_str.data(), trial_name_str.size()); @@ -399,6 +406,7 @@ valid = EnableTrialFromName(trial_name, expiry_time); } else { // Insecure origin and trial is restricted to secure origins. + DVLOG(1) << "EnableTrialFromToken: not secure"; token_result = OriginTrialTokenStatus::kInsecure; } }
diff --git a/third_party/blink/renderer/core/page/page.cc b/third_party/blink/renderer/core/page/page.cc index 1e980df8..608f9d8f 100644 --- a/third_party/blink/renderer/core/page/page.cc +++ b/third_party/blink/renderer/core/page/page.cc
@@ -89,7 +89,7 @@ namespace blink { -// Wrapper function defined in WebKit.h +// Function defined in third_party/blink/public/web/blink.h. void ResetPluginCache(bool reload_pages) { // At this point we already know that the browser has refreshed its list, so // it is not necessary to force it to be regenerated.
diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.cc b/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.cc index 52e1e4fe..7af1b2b 100644 --- a/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.cc +++ b/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.cc
@@ -156,7 +156,9 @@ DCHECK(!text_fragment_selectors.IsEmpty()); DCHECK(frame_->View()); - metrics_->DidCreateAnchor(text_fragment_selectors.size()); + metrics_->DidCreateAnchor( + text_fragment_selectors.size(), + frame.GetDocument()->GetFragmentDirective().length()); text_fragment_finders_.ReserveCapacity(text_fragment_selectors.size()); for (TextFragmentSelector selector : text_fragment_selectors) @@ -236,7 +238,9 @@ FragmentAnchor::Trace(visitor); } -void TextFragmentAnchor::DidFindMatch(const EphemeralRangeInFlatTree& range) { +void TextFragmentAnchor::DidFindMatch( + const EphemeralRangeInFlatTree& range, + const TextFragmentAnchorMetrics::Match match_metrics) { if (search_finished_) return; @@ -293,7 +297,7 @@ DocumentUpdateReason::kFindInPage); } - metrics_->DidFindMatch(PlainText(range)); + metrics_->DidFindMatch(match_metrics); did_find_match_ = true; if (first_match_needs_scroll_) {
diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.h b/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.h index dc8ae255..7878960 100644 --- a/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.h +++ b/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.h
@@ -59,7 +59,9 @@ void Trace(Visitor*) override; // TextFragmentFinder::Client interface - void DidFindMatch(const EphemeralRangeInFlatTree& range) override; + void DidFindMatch( + const EphemeralRangeInFlatTree& range, + const TextFragmentAnchorMetrics::Match match_metrics) override; void DidFindAmbiguousMatch() override; private:
diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics.cc b/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics.cc index 78a1481..9604860 100644 --- a/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics.cc +++ b/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics.cc
@@ -21,14 +21,16 @@ TextFragmentAnchorMetrics::TextFragmentAnchorMetrics(Document* document) : document_(document) {} -void TextFragmentAnchorMetrics::DidCreateAnchor(int selector_count) { +void TextFragmentAnchorMetrics::DidCreateAnchor(int selector_count, + int directive_length) { UseCounter::Count(document_, WebFeature::kTextFragmentAnchor); create_time_ = base::TimeTicks::Now(); selector_count_ = selector_count; + directive_length_ = directive_length; } -void TextFragmentAnchorMetrics::DidFindMatch(const String text) { - matches_.push_back(text); +void TextFragmentAnchorMetrics::DidFindMatch(Match match) { + matches_.push_back(match); } void TextFragmentAnchorMetrics::ResetMatchCount() { @@ -68,6 +70,12 @@ TRACE_EVENT_SCOPE_THREAD, "selector_count", selector_count_); + UMA_HISTOGRAM_COUNTS_1000("TextFragmentAnchor.DirectiveLength", + directive_length_); + TRACE_EVENT_INSTANT1("blink", "TextFragmentAnchorMetrics::ReportMetrics", + TRACE_EVENT_SCOPE_THREAD, "directive_length", + directive_length_); + const int match_rate_percent = static_cast<int>(100 * ((matches_.size() + 0.0) / selector_count_)); UMA_HISTOGRAM_PERCENTAGE("TextFragmentAnchor.MatchRate", match_rate_percent); @@ -75,11 +83,41 @@ TRACE_EVENT_SCOPE_THREAD, "match_rate", match_rate_percent); - for (const String& match : matches_) { - TRACE_EVENT_INSTANT2("blink", "TextFragmentAnchorMetrics::ReportMetrics", - TRACE_EVENT_SCOPE_THREAD, "match_found", - match.Utf8().substr(0, kMaxTraceEventStringLength), - "match_length", match.length()); + for (const Match& match : matches_) { + TRACE_EVENT_INSTANT2( + "blink", "TextFragmentAnchorMetrics::ReportMetrics", + TRACE_EVENT_SCOPE_THREAD, "match_found", + match.text.Utf8().substr(0, kMaxTraceEventStringLength), "match_length", + match.text.length()); + + if (match.selector.Type() == TextFragmentSelector::kExact) { + UMA_HISTOGRAM_COUNTS_1000("TextFragmentAnchor.ExactTextLength", + match.text.length()); + TRACE_EVENT_INSTANT1("blink", "TextFragmentAnchorMetrics::ReportMetrics", + TRACE_EVENT_SCOPE_THREAD, "exact_text_length", + match.text.length()); + } else if (match.selector.Type() == TextFragmentSelector::kRange) { + UMA_HISTOGRAM_COUNTS_1000("TextFragmentAnchor.RangeMatchLength", + match.text.length()); + TRACE_EVENT_INSTANT1("blink", "TextFragmentAnchorMetrics::ReportMetrics", + TRACE_EVENT_SCOPE_THREAD, "range_match_length", + match.text.length()); + + UMA_HISTOGRAM_COUNTS_1000("TextFragmentAnchor.StartTextLength", + match.selector.Start().length()); + TRACE_EVENT_INSTANT1("blink", "TextFragmentAnchorMetrics::ReportMetrics", + TRACE_EVENT_SCOPE_THREAD, "start_text_length", + match.selector.Start().length()); + + UMA_HISTOGRAM_COUNTS_1000("TextFragmentAnchor.EndTextLength", + match.selector.End().length()); + TRACE_EVENT_INSTANT1("blink", "TextFragmentAnchorMetrics::ReportMetrics", + TRACE_EVENT_SCOPE_THREAD, "end_text_length", + match.selector.End().length()); + } + + UMA_HISTOGRAM_ENUMERATION("TextFragmentAnchor.Parameters", + GetParametersForMatch(match)); } UMA_HISTOGRAM_BOOLEAN("TextFragmentAnchor.AmbiguousMatch", ambiguous_match_); @@ -126,4 +164,33 @@ visitor->Trace(document_); } +TextFragmentAnchorMetrics::TextFragmentAnchorParameters +TextFragmentAnchorMetrics::GetParametersForMatch(const Match& match) { + TextFragmentAnchorParameters parameters = + TextFragmentAnchorParameters::kUnknown; + + if (match.selector.Type() == TextFragmentSelector::SelectorType::kExact) { + if (match.selector.Prefix().length() && match.selector.Suffix().length()) + parameters = TextFragmentAnchorParameters::kExactTextWithContext; + else if (match.selector.Prefix().length()) + parameters = TextFragmentAnchorParameters::kExactTextWithPrefix; + else if (match.selector.Suffix().length()) + parameters = TextFragmentAnchorParameters::kExactTextWithSuffix; + else + parameters = TextFragmentAnchorParameters::kExactText; + } else if (match.selector.Type() == + TextFragmentSelector::SelectorType::kRange) { + if (match.selector.Prefix().length() && match.selector.Suffix().length()) + parameters = TextFragmentAnchorParameters::kTextRangeWithContext; + else if (match.selector.Prefix().length()) + parameters = TextFragmentAnchorParameters::kTextRangeWithPrefix; + else if (match.selector.Suffix().length()) + parameters = TextFragmentAnchorParameters::kTextRangeWithSuffix; + else + parameters = TextFragmentAnchorParameters::kTextRange; + } + + return parameters; +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics.h b/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics.h index 64d114d..22a227b 100644 --- a/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics.h +++ b/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics.h
@@ -7,6 +7,7 @@ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/page/scrolling/text_fragment_selector.h" namespace blink { @@ -15,11 +16,33 @@ class CORE_EXPORT TextFragmentAnchorMetrics final : public GarbageCollected<TextFragmentAnchorMetrics> { public: - TextFragmentAnchorMetrics(Document* document); + struct Match { + explicit Match(TextFragmentSelector text_fragment_selector) + : selector(text_fragment_selector) {} - void DidCreateAnchor(int selector_count); + String text; + TextFragmentSelector selector; + }; - void DidFindMatch(const String text); + // An enum to indicate which parameters were specified in the text fragment. + enum class TextFragmentAnchorParameters { + kUnknown = 0, + kExactText = 1, + kExactTextWithPrefix = 2, + kExactTextWithSuffix = 3, + kExactTextWithContext = 4, + kTextRange = 5, + kTextRangeWithPrefix = 6, + kTextRangeWithSuffix = 7, + kTextRangeWithContext = 8, + kMaxValue = kTextRangeWithContext, + }; + + explicit TextFragmentAnchorMetrics(Document* document); + + void DidCreateAnchor(int selector_count, int directive_length); + + void DidFindMatch(Match match); void ResetMatchCount(); void DidFindAmbiguousMatch(); @@ -37,6 +60,8 @@ void Trace(Visitor*); private: + TextFragmentAnchorParameters GetParametersForMatch(const Match& match); + Member<Document> document_; #ifndef NDEBUG @@ -44,7 +69,8 @@ #endif wtf_size_t selector_count_ = 0; - Vector<String> matches_; + wtf_size_t directive_length_ = 0; + Vector<Match> matches_; bool ambiguous_match_ = false; bool scroll_cancelled_ = false; base::TimeTicks create_time_;
diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics_test.cc b/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics_test.cc index e46eb8bf..7f7ab215 100644 --- a/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics_test.cc
@@ -2,11 +2,14 @@ // 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/page/scrolling/text_fragment_anchor_metrics.h" + #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/input/event_handler.h" +#include "third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/core/testing/sim/sim_request.h" #include "third_party/blink/renderer/core/testing/sim/sim_test.h" @@ -103,6 +106,25 @@ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TimeToScrollIntoView", 1); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.DirectiveLength", 1); + histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.DirectiveLength", 18, + 1); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.ExactTextLength", 1); + histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.ExactTextLength", 4, + 1); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.RangeMatchLength", 0); + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.StartTextLength", 0); + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.EndTextLength", 0); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.Parameters", 1); + histogram_tester_.ExpectUniqueSample( + "TextFragmentAnchor.Parameters", + static_cast<int>( + TextFragmentAnchorMetrics::TextFragmentAnchorParameters::kExactText), + 1); } // Test UMA metrics collection when there is no match found @@ -147,6 +169,18 @@ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TimeToScrollIntoView", 0); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.DirectiveLength", 1); + histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.DirectiveLength", 8, + 1); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.ExactTextLength", 0); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.RangeMatchLength", 0); + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.StartTextLength", 0); + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.EndTextLength", 0); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.Parameters", 0); } // Test that we don't collect any metrics when there is no text directive @@ -175,6 +209,18 @@ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TimeToScrollIntoView", 0); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.DirectiveLength", 0); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.ExactTextLength", 0); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.RangeMatchLength", 0); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.StartTextLength", 0); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.EndTextLength", 0); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.Parameters", 0); } // Test that the correct metrics are collected when we found a match but didn't @@ -213,6 +259,207 @@ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TimeToScrollIntoView", 1); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.DirectiveLength", 1); + histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.DirectiveLength", 9, + 1); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.ExactTextLength", 1); + histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.ExactTextLength", 4, + 1); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.RangeMatchLength", 0); + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.StartTextLength", 0); + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.EndTextLength", 0); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.Parameters", 1); + histogram_tester_.ExpectUniqueSample( + "TextFragmentAnchor.Parameters", + static_cast<int>( + TextFragmentAnchorMetrics::TextFragmentAnchorParameters::kExactText), + 1); +} + +// Test that the correct metrics are collected for all possible combinations of +// context terms on an exact text directive. +TEST_F(TextFragmentAnchorMetricsTest, ExactTextParameters) { + SimRequest request( + "https://example.com/" + "test.html#:~:text=this&text=is-,a&text=test,-page&text=with-,some,-" + "content", + "text/html"); + LoadURL( + "https://example.com/" + "test.html#:~:text=this&text=is-,a&text=test,-page&text=with-,some,-" + "content"); + request.Complete(R"HTML( + <!DOCTYPE html> + <p>This is a test page</p> + <p>With some content</p> + )HTML"); + RunAsyncMatchingTasks(); + + Compositor().BeginFrame(); + BeginEmptyFrame(); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.SelectorCount", 1); + histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.SelectorCount", 4, + 1); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.MatchRate", 1); + histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.MatchRate", 100, 1); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.AmbiguousMatch", 1); + histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.AmbiguousMatch", 0, + 1); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.ScrollCancelled", 1); + histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.ScrollCancelled", 0, + 1); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.DidScrollIntoView", 1); + histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.DidScrollIntoView", + 0, 1); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TimeToScrollIntoView", + 1); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.DirectiveLength", 1); + histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.DirectiveLength", 61, + 1); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.ExactTextLength", 4); + // "this", "test", "some" + histogram_tester_.ExpectBucketCount("TextFragmentAnchor.ExactTextLength", 4, + 3); + // "a" + histogram_tester_.ExpectBucketCount("TextFragmentAnchor.ExactTextLength", 1, + 1); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.RangeMatchLength", 0); + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.StartTextLength", 0); + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.EndTextLength", 0); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.Parameters", 4); + histogram_tester_.ExpectBucketCount( + "TextFragmentAnchor.Parameters", + static_cast<int>( + TextFragmentAnchorMetrics::TextFragmentAnchorParameters::kExactText), + 1); + histogram_tester_.ExpectBucketCount( + "TextFragmentAnchor.Parameters", + static_cast<int>(TextFragmentAnchorMetrics::TextFragmentAnchorParameters:: + kExactTextWithPrefix), + 1); + histogram_tester_.ExpectBucketCount( + "TextFragmentAnchor.Parameters", + static_cast<int>(TextFragmentAnchorMetrics::TextFragmentAnchorParameters:: + kExactTextWithSuffix), + 1); + histogram_tester_.ExpectBucketCount( + "TextFragmentAnchor.Parameters", + static_cast<int>(TextFragmentAnchorMetrics::TextFragmentAnchorParameters:: + kExactTextWithContext), + 1); +} + +// Test that the correct metrics are collected for all possible combinations of +// context terms on a range text directive. +TEST_F(TextFragmentAnchorMetricsTest, TextRangeParameters) { + SimRequest request( + "https://example.com/" + "test.html#:~:text=this,is&text=a-,test,page&text=with,some,-content&" + "text=about-,nothing,at,-all", + "text/html"); + LoadURL( + "https://example.com/" + "test.html#:~:text=this,is&text=a-,test,page&text=with,some,-content&" + "text=about-,nothing,at,-all"); + request.Complete(R"HTML( + <!DOCTYPE html> + <p>This is a test page</p> + <p>With some content</p> + <p>About nothing at all</p> + )HTML"); + RunAsyncMatchingTasks(); + + Compositor().BeginFrame(); + BeginEmptyFrame(); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.SelectorCount", 1); + histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.SelectorCount", 4, + 1); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.MatchRate", 1); + histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.MatchRate", 100, 1); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.AmbiguousMatch", 1); + histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.AmbiguousMatch", 0, + 1); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.ScrollCancelled", 1); + histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.ScrollCancelled", 0, + 1); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.DidScrollIntoView", 1); + histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.DidScrollIntoView", + 0, 1); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TimeToScrollIntoView", + 1); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.DirectiveLength", 1); + histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.DirectiveLength", 82, + 1); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.ExactTextLength", 0); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.RangeMatchLength", 4); + // "This is" + histogram_tester_.ExpectBucketCount("TextFragmentAnchor.RangeMatchLength", 7, + 1); + // "test page", "with some" + histogram_tester_.ExpectBucketCount("TextFragmentAnchor.RangeMatchLength", 9, + 2); + // "nothing at" + histogram_tester_.ExpectBucketCount("TextFragmentAnchor.RangeMatchLength", 10, + 1); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.StartTextLength", 4); + // "this", "test", "with" + histogram_tester_.ExpectBucketCount("TextFragmentAnchor.StartTextLength", 4, + 3); + // "nothing" + histogram_tester_.ExpectBucketCount("TextFragmentAnchor.StartTextLength", 7, + 1); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.EndTextLength", 4); + // "is", "at" + histogram_tester_.ExpectBucketCount("TextFragmentAnchor.EndTextLength", 2, 2); + // "page", "some" + histogram_tester_.ExpectBucketCount("TextFragmentAnchor.EndTextLength", 4, 2); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.Parameters", 4); + histogram_tester_.ExpectBucketCount( + "TextFragmentAnchor.Parameters", + static_cast<int>( + TextFragmentAnchorMetrics::TextFragmentAnchorParameters::kTextRange), + 1); + histogram_tester_.ExpectBucketCount( + "TextFragmentAnchor.Parameters", + static_cast<int>(TextFragmentAnchorMetrics::TextFragmentAnchorParameters:: + kTextRangeWithPrefix), + 1); + histogram_tester_.ExpectBucketCount( + "TextFragmentAnchor.Parameters", + static_cast<int>(TextFragmentAnchorMetrics::TextFragmentAnchorParameters:: + kTextRangeWithSuffix), + 1); + histogram_tester_.ExpectBucketCount( + "TextFragmentAnchor.Parameters", + static_cast<int>(TextFragmentAnchorMetrics::TextFragmentAnchorParameters:: + kTextRangeWithContext), + 1); } // Test that the ScrollCancelled metric gets reported when a user scroll cancels @@ -275,6 +522,25 @@ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TimeToScrollIntoView", 0); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.DirectiveLength", 1); + histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.DirectiveLength", 9, + 1); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.ExactTextLength", 1); + histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.ExactTextLength", 4, + 1); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.RangeMatchLength", 0); + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.StartTextLength", 0); + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.EndTextLength", 0); + + histogram_tester_.ExpectTotalCount("TextFragmentAnchor.Parameters", 1); + histogram_tester_.ExpectUniqueSample( + "TextFragmentAnchor.Parameters", + static_cast<int>( + TextFragmentAnchorMetrics::TextFragmentAnchorParameters::kExactText), + 1); } // Test that the TapToDismiss feature gets use counted when the user taps to
diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_finder.cc b/third_party/blink/renderer/core/page/scrolling/text_fragment_finder.cc index a3b1299..275576fe 100644 --- a/third_party/blink/renderer/core/page/scrolling/text_fragment_finder.cc +++ b/third_party/blink/renderer/core/page/scrolling/text_fragment_finder.cc
@@ -177,6 +177,7 @@ const TextFragmentSelector& selector) : client_(client), selector_(selector) { DCHECK(!selector_.Start().IsEmpty()); + DCHECK(selector_.Type() != TextFragmentSelector::SelectorType::kInvalid); } void TextFragmentFinder::FindMatch(Document& document) { @@ -191,7 +192,18 @@ FindMatchFromPosition(document, search_start); if (match.IsNotNull()) { - client_.DidFindMatch(match); + TextFragmentAnchorMetrics::Match match_metrics(selector_); + + if (selector_.Type() == TextFragmentSelector::SelectorType::kExact) { + // If it's an exact match, we don't need to do the PlainText conversion, + // we can just use the text from the selector. + DCHECK_EQ(selector_.Start().length(), PlainText(match).length()); + match_metrics.text = selector_.Start(); + } else if (selector_.Type() == TextFragmentSelector::SelectorType::kRange) { + match_metrics.text = PlainText(match); + } + + client_.DidFindMatch(match, match_metrics); // Continue searching to see if we have an ambiguous selector. // TODO(crbug.com/919204): This is temporary and only for measuring
diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_finder.h b/third_party/blink/renderer/core/page/scrolling/text_fragment_finder.h index d4e2714..a59ebb1 100644 --- a/third_party/blink/renderer/core/page/scrolling/text_fragment_finder.h +++ b/third_party/blink/renderer/core/page/scrolling/text_fragment_finder.h
@@ -7,6 +7,7 @@ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/editing/forward.h" +#include "third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics.h" #include "third_party/blink/renderer/core/page/scrolling/text_fragment_selector.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -21,7 +22,9 @@ public: class Client { public: - virtual void DidFindMatch(const EphemeralRangeInFlatTree& range) = 0; + virtual void DidFindMatch( + const EphemeralRangeInFlatTree& range, + const TextFragmentAnchorMetrics::Match match_metrics) = 0; virtual void DidFindAmbiguousMatch() = 0; };
diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_selector.h b/third_party/blink/renderer/core/page/scrolling/text_fragment_selector.h index 536cdb59..06013500 100644 --- a/third_party/blink/renderer/core/page/scrolling/text_fragment_selector.h +++ b/third_party/blink/renderer/core/page/scrolling/text_fragment_selector.h
@@ -30,7 +30,7 @@ const String& end, const String& prefix, const String& suffix); - TextFragmentSelector(SelectorType type); + explicit TextFragmentSelector(SelectorType type); ~TextFragmentSelector() = default; SelectorType Type() const { return type_; }
diff --git a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc index 1ab49dd..b77dc46 100644 --- a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc +++ b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
@@ -254,6 +254,24 @@ graphics_layer_->SetHitTestable(true); } +void CompositedLayerMapping::UpdateGraphicsLayerContentsOpaque( + bool should_check_children) { + if (BackgroundPaintsOntoGraphicsLayer()) { + bool contents_opaque = owning_layer_.BackgroundIsKnownToBeOpaqueInRect( + CompositedBounds(), should_check_children); + graphics_layer_->SetContentsOpaque(contents_opaque); + if (!contents_opaque) { + graphics_layer_->SetContentsOpaqueForText( + GetLayoutObject().TextIsKnownToBeOnOpaqueBackground()); + } + } else { + // If we only paint the background onto the scrolling contents layer we + // are going to leave a hole in the m_graphicsLayer where the background + // is so it is not opaque. + graphics_layer_->SetContentsOpaque(false); + } +} + void CompositedLayerMapping::UpdateContentsOpaque() { // If there is a foreground layer, children paint into that layer and // not graphics_layer_, and so don't contribute to the opaqueness of the @@ -289,28 +307,34 @@ // TODO(flackr): This should actually check the entire overflow rect // within the scrolling contents layer but since we currently only trigger // this for solid color backgrounds the answer will be the same. - scrolling_contents_layer_->SetContentsOpaque( - owning_layer_.BackgroundIsKnownToBeOpaqueInRect( - ToLayoutBox(GetLayoutObject()).PhysicalPaddingBoxRect(), - should_check_children)); - - if (BackgroundPaintsOntoGraphicsLayer()) { - graphics_layer_->SetContentsOpaque( - owning_layer_.BackgroundIsKnownToBeOpaqueInRect( - CompositedBounds(), should_check_children)); - } else { - // If we only paint the background onto the scrolling contents layer we - // are going to leave a hole in the m_graphicsLayer where the background - // is so it is not opaque. - graphics_layer_->SetContentsOpaque(false); + bool contents_opaque = owning_layer_.BackgroundIsKnownToBeOpaqueInRect( + ToLayoutBox(GetLayoutObject()).PhysicalPaddingBoxRect(), + should_check_children); + scrolling_contents_layer_->SetContentsOpaque(contents_opaque); + if (!contents_opaque) { + scrolling_contents_layer_->SetContentsOpaqueForText( + GetLayoutObject().TextIsKnownToBeOnOpaqueBackground()); } + + UpdateGraphicsLayerContentsOpaque(should_check_children); } else { DCHECK(BackgroundPaintsOntoGraphicsLayer()); if (HasScrollingLayer()) scrolling_contents_layer_->SetContentsOpaque(false); - graphics_layer_->SetContentsOpaque( - owning_layer_.BackgroundIsKnownToBeOpaqueInRect(CompositedBounds(), - should_check_children)); + UpdateGraphicsLayerContentsOpaque(should_check_children); + } + + if (squashing_layer_) { + squashing_layer_->SetContentsOpaque(false); + bool contents_opaque_for_text = true; + for (const GraphicsLayerPaintInfo& squashed_layer : squashed_layers_) { + if (!squashed_layer.paint_layer->GetLayoutObject() + .TextIsKnownToBeOnOpaqueBackground()) { + contents_opaque_for_text = false; + break; + } + } + squashing_layer_->SetContentsOpaqueForText(contents_opaque_for_text); } }
diff --git a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h index 5a4ed36f..93bea76e 100644 --- a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h +++ b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h
@@ -348,6 +348,7 @@ bool UpdateSquashingLayers(bool needs_squashing_layers); void UpdateDrawsContentAndPaintsHitTest(); void UpdateCompositedBounds(); + void UpdateGraphicsLayerContentsOpaque(bool should_check_children); // Also sets subpixelAccumulation on the layer. void ComputeBoundsOfOwningLayer(
diff --git a/third_party/blink/renderer/core/testing/data/mhtml/shadow.mht b/third_party/blink/renderer/core/testing/data/mhtml/shadow.mht index 8669bcd..662c160 100644 --- a/third_party/blink/renderer/core/testing/data/mhtml/shadow.mht +++ b/third_party/blink/renderer/core/testing/data/mhtml/shadow.mht
@@ -18,9 +18,6 @@ <title>A page with shadow DOM content</title> <h1>This page has shadow DOM content</h1> -<p id=3D"h1"> - <template shadowmode=3D"v0">V0</template> -</p> <div id=3D"h2"> <template shadowmode=3D"open" shadowdelegatesfocus=3D"">Parent <p id=3D"h3">
diff --git a/third_party/blink/renderer/core/testing/data/touch-action-tests.js b/third_party/blink/renderer/core/testing/data/touch-action-tests.js index 73bf06e..a3ed94c 100644 --- a/third_party/blink/renderer/core/testing/data/touch-action-tests.js +++ b/third_party/blink/renderer/core/testing/data/touch-action-tests.js
@@ -4,10 +4,6 @@ window.addEventListener('load', function() { // Create any shadow DOM nodes requested by the test. var shadowTrees = document.querySelectorAll('[make-shadow-dom]'); - if (shadowTrees.length > 0 && !HTMLElement.prototype.createShadowRoot) { - document.body.innerHTML = 'ERROR: Shadow DOM not supported!'; - return; - } for (var i = 0; i < shadowTrees.length; i++) { var tree = shadowTrees[i]; var host = tree.previousElementSibling; @@ -16,7 +12,7 @@ return; } tree.parentElement.removeChild(tree); - var shadowRoot = host.createShadowRoot(); + var shadowRoot = host.attachShadow({mode: 'open'}); var style = document.createElement('style'); style.innerText = ' .ta-none { -ms-touch-action: none; touch-action: none; }'; shadowRoot.appendChild(style);
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc index ae44ae1..86fc97fe 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -28,6 +28,8 @@ #include "third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h" +#include <algorithm> + #include "base/auto_reset.h" #include "base/memory/scoped_refptr.h" #include "mojo/public/cpp/bindings/pending_remote.h"
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h index db22d6f..afed1943 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h +++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
@@ -29,7 +29,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_AX_OBJECT_CACHE_IMPL_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_AX_OBJECT_CACHE_IMPL_H_ -#include <algorithm> #include <memory> #include <utility> @@ -299,7 +298,9 @@ ax::mojom::blink::EventFrom event_from, const BlinkAXEventIntentsSet& intents) : target(target), event_type(event_type), event_from(event_from) { - std::copy(intents.begin(), intents.end(), event_intents.begin()); + for (const auto& intent : intents) { + event_intents.insert(intent.key, intent.value); + } } Member<AXObject> target; ax::mojom::blink::Event event_type; @@ -315,7 +316,9 @@ const BlinkAXEventIntentsSet& intents, base::OnceClosure callback) : node(node), event_from(event_from), callback(std::move(callback)) { - std::copy(intents.begin(), intents.end(), event_intents.begin()); + for (const auto& intent : intents) { + event_intents.insert(intent.key, intent.value); + } } WeakMember<Node> node; ax::mojom::blink::EventFrom event_from;
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc b/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc index fb982ee..76192340 100644 --- a/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc +++ b/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
@@ -433,6 +433,13 @@ return; } + if (is_raw_ && !LocalFrame::HasTransientUserActivation(GetLocalFrame())) { + script_promise_resolver_->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kSecurityError, + "Must be handling a user gesture to use raw clipboard")); + return; + } + if (!GetPermissionService()) { script_promise_resolver_->Reject(MakeGarbageCollected<DOMException>( DOMExceptionCode::kNotAllowedError,
diff --git a/third_party/blink/renderer/modules/encryptedmedia/encrypted_media_utils.h b/third_party/blink/renderer/modules/encryptedmedia/encrypted_media_utils.h index 8d7f631..3162ba2 100644 --- a/third_party/blink/renderer/modules/encryptedmedia/encrypted_media_utils.h +++ b/third_party/blink/renderer/modules/encryptedmedia/encrypted_media_utils.h
@@ -17,6 +17,13 @@ namespace blink { +// Reported to UKM. Existing values must not change and new values must be +// added at the end of the list. +enum KeySystemForUkm { + kClearKey = 0, + kWidevine = 1, +}; + // Enum for EME MediaKeySystemAccess, MediaKeys and MediaKeySession APIs. // Reported to UKM. Existing values should NEVER be changed. enum class EmeApiType {
diff --git a/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access.cc b/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access.cc index 74da217..61ff322 100644 --- a/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access.cc +++ b/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access.cc
@@ -9,12 +9,17 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "media/base/eme_constants.h" +#include "services/metrics/public/cpp/ukm_builders.h" +#include "services/metrics/public/cpp/ukm_recorder.h" #include "third_party/blink/public/platform/web_content_decryption_module.h" #include "third_party/blink/public/platform/web_encrypted_media_types.h" #include "third_party/blink/public/platform/web_media_key_system_configuration.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_media_key_system_media_capability.h" +#include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" +#include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/modules/encryptedmedia/content_decryption_module_result_promise.h" #include "third_party/blink/renderer/modules/encryptedmedia/encrypted_media_utils.h" #include "third_party/blink/renderer/modules/encryptedmedia/media_key_session.h" @@ -69,7 +74,7 @@ // These methods are the inverses of those with the same names in // NavigatorRequestMediaKeySystemAccess. -static Vector<String> ConvertInitDataTypes( +Vector<String> ConvertInitDataTypes( const WebVector<media::EmeInitDataType>& init_data_types) { Vector<String> result(SafeCast<wtf_size_t>(init_data_types.size())); for (wtf_size_t i = 0; i < result.size(); i++) @@ -78,7 +83,7 @@ return result; } -static HeapVector<Member<MediaKeySystemMediaCapability>> ConvertCapabilities( +HeapVector<Member<MediaKeySystemMediaCapability>> ConvertCapabilities( const WebVector<WebMediaKeySystemMediaCapability>& capabilities) { HeapVector<Member<MediaKeySystemMediaCapability>> result( SafeCast<wtf_size_t>(capabilities.size())); @@ -117,7 +122,7 @@ return result; } -static Vector<String> ConvertSessionTypes( +Vector<String> ConvertSessionTypes( const WebVector<WebEncryptedMediaSessionType>& session_types) { Vector<String> result(SafeCast<wtf_size_t>(session_types.size())); for (wtf_size_t i = 0; i < result.size(); i++) @@ -125,11 +130,41 @@ return result; } +void ReportMetrics(ExecutionContext* execution_context, + const String& key_system) { + // TODO(xhwang): Report other key systems here and for + // requestMediaKeySystemAccess(). + const char kWidevineKeySystem[] = "com.widevine.alpha"; + if (key_system != kWidevineKeySystem) + return; + + auto* local_dom_window = To<LocalDOMWindow>(execution_context); + if (!local_dom_window) + return; + + Document* document = local_dom_window->document(); + if (!document) + return; + + LocalFrame* frame = document->GetFrame(); + if (!frame) + return; + + ukm::builders::Media_EME_CreateMediaKeys builder(document->UkmSourceID()); + builder.SetKeySystem(KeySystemForUkm::kWidevine); + builder.SetIsAdFrame( + static_cast<int>(frame->IsAdRoot() || frame->IsAdSubframe())); + builder.SetIsCrossOrigin(static_cast<int>(frame->IsCrossOriginToMainFrame())); + builder.SetIsTopFrame(static_cast<int>(frame->IsMainFrame())); + builder.Record(document->UkmRecorder()); +} + } // namespace MediaKeySystemAccess::MediaKeySystemAccess( + const String& key_system, std::unique_ptr<WebContentDecryptionModuleAccess> access) - : access_(std::move(access)) {} + : key_system_(key_system), access_(std::move(access)) {} MediaKeySystemAccess::~MediaKeySystemAccess() = default; @@ -182,9 +217,12 @@ // 2.3 If cdm fails to load or initialize, reject promise with a new // DOMException whose name is the appropriate error name. // (Done if completeWithException() called). + auto* execution_context = ExecutionContext::From(script_state); access_->CreateContentDecryptionModule( - helper->Result(), ExecutionContext::From(script_state) - ->GetTaskRunner(TaskType::kInternalMedia)); + helper->Result(), + execution_context->GetTaskRunner(TaskType::kInternalMedia)); + + ReportMetrics(execution_context, key_system_); // 3. Return promise. return promise;
diff --git a/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access.h b/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access.h index 9de06de..54cebad 100644 --- a/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access.h +++ b/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access.h
@@ -18,8 +18,8 @@ DEFINE_WRAPPERTYPEINFO(); public: - explicit MediaKeySystemAccess( - std::unique_ptr<WebContentDecryptionModuleAccess>); + MediaKeySystemAccess(const String& key_system, + std::unique_ptr<WebContentDecryptionModuleAccess>); ~MediaKeySystemAccess() override; String keySystem() const { return access_->GetKeySystem(); } @@ -31,6 +31,7 @@ } private: + const String key_system_; std::unique_ptr<WebContentDecryptionModuleAccess> access_; };
diff --git a/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access_initializer_base.cc b/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access_initializer_base.cc index 914c8f5..d85c50fe 100644 --- a/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access_initializer_base.cc +++ b/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access_initializer_base.cc
@@ -168,13 +168,6 @@ const char kWidevineKeySystem[] = "com.widevine.alpha"; const char kWidevineHwSecureAllRobustness[] = "HW_SECURE_ALL"; - // Reported to UKM. Existing values must not change and new values must be - // added at the end of the list. - enum KeySystemForUkm { - kClearKey = 0, - kWidevine = 1, - }; - // Only check for widevine key system for now. if (KeySystem() != kWidevineKeySystem) return;
diff --git a/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.cc b/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.cc index f36a3f5c..abbfe69 100644 --- a/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.cc +++ b/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.cc
@@ -84,8 +84,8 @@ if (!IsExecutionContextValid()) return; - resolver_->Resolve( - MakeGarbageCollected<MediaKeySystemAccess>(std::move(access))); + resolver_->Resolve(MakeGarbageCollected<MediaKeySystemAccess>( + KeySystem(), std::move(access))); resolver_.Clear(); }
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 328c7243..4c80885a 100644 --- a/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc +++ b/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc
@@ -151,8 +151,8 @@ // Query the client for smoothness and power efficiency of the video. It // will resolve the promise. std::move(get_perf_callback_) - .Run(resolver_.Get(), - MakeGarbageCollected<MediaKeySystemAccess>(std::move(access))); + .Run(resolver_.Get(), MakeGarbageCollected<MediaKeySystemAccess>( + KeySystem(), std::move(access))); } void RequestNotSupported(const WebString& error_message) override {
diff --git a/third_party/blink/renderer/modules/peerconnection/idls.gni b/third_party/blink/renderer/modules/peerconnection/idls.gni index 006aca8..2ddbb81 100644 --- a/third_party/blink/renderer/modules/peerconnection/idls.gni +++ b/third_party/blink/renderer/modules/peerconnection/idls.gni
@@ -39,6 +39,8 @@ "rtc_data_channel_init.idl", "rtc_dtls_fingerprint.idl", "rtc_dtmf_tone_change_event_init.idl", + "rtc_encoded_audio_frame_metadata.idl", + "rtc_encoded_video_frame_metadata.idl", "rtc_error_event_init.idl", "rtc_error_init.idl", "rtc_ice_candidate_init.idl",
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_configuration.idl b/third_party/blink/renderer/modules/peerconnection/rtc_configuration.idl index 16352f50..ef876c9 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_configuration.idl +++ b/third_party/blink/renderer/modules/peerconnection/rtc_configuration.idl
@@ -54,6 +54,9 @@ [RuntimeEnabled=RtcAudioJitterBufferMaxPackets] long rtcAudioJitterBufferMaxPackets; [RuntimeEnabled=RtcAudioJitterBufferMaxPackets] boolean rtcAudioJitterBufferFastAccelerate; [RuntimeEnabled=RtcAudioJitterBufferMaxPackets] long rtcAudioJitterBufferMinDelayMs; - [RuntimeEnabled=RTCInsertableStreams] boolean forceEncodedAudioInsertableStreams = false; - [RuntimeEnabled=RTCInsertableStreams] boolean forceEncodedVideoInsertableStreams = false; + [RuntimeEnabled=RTCInsertableStreams] boolean encodedInsertableStreams = false; + [DeprecateAs=ForceEncodedAudioInsertableStreams, + RuntimeEnabled=RTCInsertableStreams] boolean forceEncodedAudioInsertableStreams = false; + [DeprecateAs=ForceEncodedVideoInsertableStreams, + RuntimeEnabled=RTCInsertableStreams] boolean forceEncodedVideoInsertableStreams = false; };
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.cc b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.cc index 6dbaa7f..287b4f0 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.cc
@@ -6,6 +6,7 @@ #include <utility> +#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_encoded_audio_frame_metadata.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame_delegate.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" @@ -50,6 +51,14 @@ return frame_data_; } +RTCEncodedAudioFrameMetadata* RTCEncodedAudioFrame::getMetadata() const { + RTCEncodedAudioFrameMetadata* metadata = + RTCEncodedAudioFrameMetadata::Create(); + metadata->setSynchronizationSource(delegate_->Ssrc()); + metadata->setContributingSources(delegate_->ContributingSources()); + return metadata; +} + DOMArrayBuffer* RTCEncodedAudioFrame::additionalData() const { return nullptr; }
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.h b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.h index 1e11e9e..fc7e679 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.h +++ b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.h
@@ -21,6 +21,7 @@ class DOMArrayBuffer; class RTCEncodedAudioFrameDelegate; +class RTCEncodedAudioFrameMetadata; class MODULES_EXPORT RTCEncodedAudioFrame final : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); @@ -36,6 +37,7 @@ // rtc_encoded_audio_frame.idl implementation. uint64_t timestamp() const; DOMArrayBuffer* data() const; + RTCEncodedAudioFrameMetadata* getMetadata() const; DOMArrayBuffer* additionalData() const; void setData(DOMArrayBuffer*); uint32_t synchronizationSource() const;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.idl b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.idl index 5c01a6c..aecf58605 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.idl +++ b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.idl
@@ -12,8 +12,9 @@ ] interface RTCEncodedAudioFrame { readonly attribute unsigned long long timestamp; // microseconds attribute ArrayBuffer data; - // TODO(crbug.com/1052765): Replace the following fields with a dictionary - // with structured data once we have decided what will be exposed. + RTCEncodedAudioFrameMetadata getMetadata(); + // TODO(crbug.com/1052765): Remove the following fields before enabling + // by default. readonly attribute ArrayBuffer additionalData; readonly attribute unsigned long synchronizationSource; readonly attribute FrozenArray<unsigned long> contributingSources;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame_metadata.idl b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame_metadata.idl new file mode 100644 index 0000000..aa8361d --- /dev/null +++ b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame_metadata.idl
@@ -0,0 +1,11 @@ +// 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. + +// https://github.com/alvestrand/webrtc-media-streams/blob/master/explainer.md#api +// TODO(guidou): Add standards link when available. + +dictionary RTCEncodedAudioFrameMetadata { + unsigned long synchronizationSource; + sequence<unsigned long> contributingSources; +};
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.cc b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.cc index 65593da..770b0be2 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.cc
@@ -6,6 +6,7 @@ #include <utility> +#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_encoded_video_frame_metadata.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" @@ -36,6 +37,13 @@ return frame_data_; } +RTCEncodedVideoFrameMetadata* RTCEncodedVideoFrame::getMetadata() const { + RTCEncodedVideoFrameMetadata* metadata = + RTCEncodedVideoFrameMetadata::Create(); + metadata->setSynchronizationSource(delegate_->Ssrc()); + return metadata; +} + DOMArrayBuffer* RTCEncodedVideoFrame::additionalData() const { if (!additional_data_) additional_data_ = delegate_->CreateAdditionalDataBuffer();
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.h b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.h index 5e13b07e..08925a46 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.h +++ b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.h
@@ -21,6 +21,7 @@ class DOMArrayBuffer; class RTCEncodedVideoFrameDelegate; +class RTCEncodedVideoFrameMetadata; class MODULES_EXPORT RTCEncodedVideoFrame final : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); @@ -36,6 +37,7 @@ // Returns the RTP Packet Timestamp for this frame. uint64_t timestamp() const; DOMArrayBuffer* data() const; + RTCEncodedVideoFrameMetadata* getMetadata() const; DOMArrayBuffer* additionalData() const; void setData(DOMArrayBuffer*); uint32_t synchronizationSource() const;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.idl b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.idl index ee618e20..48fb2c12 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.idl +++ b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.idl
@@ -19,8 +19,9 @@ readonly attribute RTCCodedVideoFrameType type; readonly attribute unsigned long long timestamp; // microseconds attribute ArrayBuffer data; - // TODO(crbug.com/1052765): Replace the following fields with a dictionary - // with structured data once we have decided what will be exposed. + RTCEncodedVideoFrameMetadata getMetadata(); + // TODO(crbug.com/1052765): Remove the following fields before enabling + // by default. readonly attribute ArrayBuffer additionalData; readonly attribute unsigned long synchronizationSource; stringifier;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_metadata.idl b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_metadata.idl new file mode 100644 index 0000000..14cb60c0f --- /dev/null +++ b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_metadata.idl
@@ -0,0 +1,18 @@ +// 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. + +// https://github.com/alvestrand/webrtc-media-streams/blob/master/explainer.md#api +// TODO(guidou): Add standards link when available. + +[Serializable] +dictionary RTCEncodedVideoFrameMetadata { + long long frame_id; + sequence<long long> dependencies; + unsigned short width; + unsigned short height; + long spatial_index; + long temporal_index; + unsigned long synchronizationSource; + sequence<unsigned long> contributingSources; +};
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_insertable_streams.idl b/third_party/blink/renderer/modules/peerconnection/rtc_insertable_streams.idl index 5c5a979..943070d 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_insertable_streams.idl +++ b/third_party/blink/renderer/modules/peerconnection/rtc_insertable_streams.idl
@@ -5,7 +5,6 @@ // https://github.com/alvestrand/webrtc-media-streams/blob/master/explainer.md#api // TODO(guidou): Add standards link when available. -[Serializable] dictionary RTCInsertableStreams { ReadableStream readableStream; WritableStream writableStream;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc index 3dbef36..2ec62592 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
@@ -694,9 +694,11 @@ RTCPeerConnection* peer_connection = MakeGarbageCollected<RTCPeerConnection>( context, std::move(configuration), rtc_configuration->hasSdpSemantics(), - rtc_configuration->forceEncodedAudioInsertableStreams(), - rtc_configuration->forceEncodedVideoInsertableStreams(), constraints, - exception_state); + rtc_configuration->forceEncodedAudioInsertableStreams() || + rtc_configuration->encodedInsertableStreams(), + rtc_configuration->forceEncodedVideoInsertableStreams() || + rtc_configuration->encodedInsertableStreams(), + constraints, exception_state); if (exception_state.HadException()) return nullptr;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc index 7eafdc7..0590022 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
@@ -175,6 +175,15 @@ return promise; } +RTCInsertableStreams* RTCRtpReceiver::createEncodedStreams( + ScriptState* script_state, + ExceptionState& exception_state) { + if (track_->kind() == "audio") + return createEncodedAudioStreams(script_state, exception_state); + DCHECK_EQ(track_->kind(), "video"); + return createEncodedVideoStreams(script_state, exception_state); +} + RTCInsertableStreams* RTCRtpReceiver::createEncodedAudioStreams( ScriptState* script_state, ExceptionState& exception_state) {
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h index 5bfb05c..587e4109 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h +++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h
@@ -60,6 +60,8 @@ ScriptState*, ExceptionState&); ScriptPromise getStats(ScriptState*); + RTCInsertableStreams* createEncodedStreams(ScriptState*, ExceptionState&); + // TODO(crbug.com/1069295): Make these methods private. RTCInsertableStreams* createEncodedAudioStreams(ScriptState*, ExceptionState&); RTCInsertableStreams* createEncodedVideoStreams(ScriptState*,
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.idl b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.idl index 9b3698d..c05d953 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.idl +++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.idl
@@ -15,6 +15,14 @@ [CallWith=ScriptState, RaisesException] sequence<RTCRtpSynchronizationSource> getSynchronizationSources(); [CallWith=ScriptState, RaisesException] sequence<RTCRtpContributingSource> getContributingSources(); [CallWith=ScriptState] Promise<RTCStatsReport> getStats(); - [Measure, RuntimeEnabled=RTCInsertableStreams, CallWith=ScriptState, RaisesException] RTCInsertableStreams createEncodedAudioStreams(); - [Measure, RuntimeEnabled=RTCInsertableStreams, CallWith=ScriptState, RaisesException] RTCInsertableStreams createEncodedVideoStreams(); + [Measure, RuntimeEnabled=RTCInsertableStreams, + CallWith=ScriptState, + RaisesException] RTCInsertableStreams createEncodedStreams(); + [DeprecateAs=V8RTCRtpReceiver_CreateEncodedAudioStreams_Method, + RuntimeEnabled=RTCInsertableStreams, + CallWith=ScriptState, RaisesException] RTCInsertableStreams createEncodedAudioStreams(); + [DeprecateAs=V8RTCRtpReceiver_CreateEncodedVideoStreams_Method, + RuntimeEnabled=RTCInsertableStreams, + CallWith=ScriptState, + RaisesException] RTCInsertableStreams createEncodedVideoStreams(); };
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc index d1f190e..4cdeff5 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
@@ -643,6 +643,15 @@ sender_->SetStreams(stream_ids); } +RTCInsertableStreams* RTCRtpSender::createEncodedStreams( + ScriptState* script_state, + ExceptionState& exception_state) { + if (kind_ == "audio") + return createEncodedAudioStreams(script_state, exception_state); + DCHECK_EQ(kind_, "video"); + return createEncodedVideoStreams(script_state, exception_state); +} + RTCInsertableStreams* RTCRtpSender::createEncodedAudioStreams( ScriptState* script_state, ExceptionState& exception_state) {
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.h b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.h index 6f519f7..4c1b10e 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.h +++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.h
@@ -67,6 +67,8 @@ ScriptPromise setParameters(ScriptState*, const RTCRtpSendParameters*); ScriptPromise getStats(ScriptState*); void setStreams(HeapVector<Member<MediaStream>> streams, ExceptionState&); + RTCInsertableStreams* createEncodedStreams(ScriptState*, ExceptionState&); + // TODO(crbug.com/1069295): Make these methods private. RTCInsertableStreams* createEncodedAudioStreams(ScriptState*, ExceptionState&); RTCInsertableStreams* createEncodedVideoStreams(ScriptState*,
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.idl b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.idl index 91f8b28..0972dfa 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.idl +++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.idl
@@ -15,6 +15,16 @@ [Measure] readonly attribute RTCDTMFSender? dtmf; [Measure, RaisesException] void setStreams(MediaStream... streams); [CallWith=ScriptState] Promise<RTCStatsReport> getStats(); - [Measure, RuntimeEnabled=RTCInsertableStreams, CallWith=ScriptState, RaisesException] RTCInsertableStreams createEncodedAudioStreams(); - [Measure, RuntimeEnabled=RTCInsertableStreams, CallWith=ScriptState, RaisesException] RTCInsertableStreams createEncodedVideoStreams(); + [Measure, + RuntimeEnabled=RTCInsertableStreams, + CallWith=ScriptState, + RaisesException] RTCInsertableStreams createEncodedStreams(); + [DeprecateAs=V8RTCRtpSender_CreateEncodedAudioStreams_Method, + RuntimeEnabled=RTCInsertableStreams, + CallWith=ScriptState, + RaisesException] RTCInsertableStreams createEncodedAudioStreams(); + [DeprecateAs=V8RTCRtpSender_CreateEncodedVideoStreams_Method, + RuntimeEnabled=RTCInsertableStreams, + CallWith=ScriptState, + RaisesException] RTCInsertableStreams createEncodedVideoStreams(); };
diff --git a/third_party/blink/renderer/modules/screen_enumeration/screen_enumeration.idl b/third_party/blink/renderer/modules/screen_enumeration/screen_enumeration.idl index 0f7cadd..cf0810d6 100644 --- a/third_party/blink/renderer/modules/screen_enumeration/screen_enumeration.idl +++ b/third_party/blink/renderer/modules/screen_enumeration/screen_enumeration.idl
@@ -5,7 +5,7 @@ // https://github.com/webscreens/screen-enumeration [ SecureContext, - RuntimeEnabled=ScreenEnumeration, + RuntimeEnabled=WindowPlacement, ImplementedAs=GlobalScreenEnumeration ] partial interface Window { [CallWith=ScriptState, RaisesException] Promise<sequence<Screen>> getScreens();
diff --git a/third_party/blink/renderer/modules/webaudio/audio_listener.cc b/third_party/blink/renderer/modules/webaudio/audio_listener.cc index 6a347e4..be09222 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_listener.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_listener.cc
@@ -150,15 +150,15 @@ } bool AudioListener::HasSampleAccurateValues() const { - return positionX()->Handler().HasSampleAccurateValuesTimeline() || - positionY()->Handler().HasSampleAccurateValuesTimeline() || - positionZ()->Handler().HasSampleAccurateValuesTimeline() || - forwardX()->Handler().HasSampleAccurateValuesTimeline() || - forwardY()->Handler().HasSampleAccurateValuesTimeline() || - forwardZ()->Handler().HasSampleAccurateValuesTimeline() || - upX()->Handler().HasSampleAccurateValuesTimeline() || - upY()->Handler().HasSampleAccurateValuesTimeline() || - upZ()->Handler().HasSampleAccurateValuesTimeline(); + return positionX()->Handler().HasSampleAccurateValues() || + positionY()->Handler().HasSampleAccurateValues() || + positionZ()->Handler().HasSampleAccurateValues() || + forwardX()->Handler().HasSampleAccurateValues() || + forwardY()->Handler().HasSampleAccurateValues() || + forwardZ()->Handler().HasSampleAccurateValues() || + upX()->Handler().HasSampleAccurateValues() || + upY()->Handler().HasSampleAccurateValues() || + upZ()->Handler().HasSampleAccurateValues(); } bool AudioListener::IsAudioRate() const {
diff --git a/third_party/blink/renderer/modules/webaudio/audio_param.h b/third_party/blink/renderer/modules/webaudio/audio_param.h index b567526..1c6bb1d5 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_param.h +++ b/third_party/blink/renderer/modules/webaudio/audio_param.h
@@ -179,21 +179,9 @@ void ResetSmoothedValue() { timeline_.SetSmoothedValue(IntrinsicValue()); } + // An AudioParam needs sample accurate processing if there are + // automations scheduled or if there are connections. bool HasSampleAccurateValues() { - if (automation_rate_ != kAudio) - return false; - - bool has_values = - timeline_.HasValues(destination_handler_->CurrentSampleFrame(), - destination_handler_->SampleRate()); - - return has_values || NumberOfRenderingConnections(); - } - - // TODO(crbug.com/1015760) This is like HasSAmpleAccurateValues, but - // we don't check for the rate. When the bug is fixed, - // HasSampleAccurateValues can be removed and this methed renamed. - bool HasSampleAccurateValuesTimeline() { bool has_values = timeline_.HasValues(destination_handler_->CurrentSampleFrame(), destination_handler_->SampleRate());
diff --git a/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc b/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc index 9d3aa72..97d66cd7 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc
@@ -109,7 +109,7 @@ for (const auto& param_name : param_value_map_.Keys()) { auto* const param_handler = param_handler_map_.at(param_name); AudioFloatArray* param_values = param_value_map_.at(param_name); - if (param_handler->HasSampleAccurateValuesTimeline() && + if (param_handler->HasSampleAccurateValues() && param_handler->IsAudioRate()) { param_handler->CalculateSampleAccurateValues( param_values->Data(), static_cast<uint32_t>(frames_to_process));
diff --git a/third_party/blink/renderer/modules/webaudio/biquad_processor.cc b/third_party/blink/renderer/modules/webaudio/biquad_processor.cc index 2fa4094..c9e1417 100644 --- a/third_party/blink/renderer/modules/webaudio/biquad_processor.cc +++ b/third_party/blink/renderer/modules/webaudio/biquad_processor.cc
@@ -63,10 +63,10 @@ filter_coefficients_dirty_ = false; has_sample_accurate_values_ = false; - if (parameter1_->HasSampleAccurateValuesTimeline() || - parameter2_->HasSampleAccurateValuesTimeline() || - parameter3_->HasSampleAccurateValuesTimeline() || - parameter4_->HasSampleAccurateValuesTimeline()) { + if (parameter1_->HasSampleAccurateValues() || + parameter2_->HasSampleAccurateValues() || + parameter3_->HasSampleAccurateValues() || + parameter4_->HasSampleAccurateValues()) { // Coefficients are dirty if any of them has automations or if there are // connections to the AudioParam. filter_coefficients_dirty_ = true;
diff --git a/third_party/blink/renderer/modules/webaudio/constant_source_node.cc b/third_party/blink/renderer/modules/webaudio/constant_source_node.cc index 075b2802..69457f9 100644 --- a/third_party/blink/renderer/modules/webaudio/constant_source_node.cc +++ b/third_party/blink/renderer/modules/webaudio/constant_source_node.cc
@@ -70,7 +70,7 @@ return; } - bool is_sample_accurate = offset_->HasSampleAccurateValuesTimeline(); + bool is_sample_accurate = offset_->HasSampleAccurateValues(); if (is_sample_accurate && offset_->IsAudioRate()) { DCHECK_LE(frames_to_process, sample_accurate_values_.size());
diff --git a/third_party/blink/renderer/modules/webaudio/delay_dsp_kernel.cc b/third_party/blink/renderer/modules/webaudio/delay_dsp_kernel.cc index 1e3e0064..808b9e8 100644 --- a/third_party/blink/renderer/modules/webaudio/delay_dsp_kernel.cc +++ b/third_party/blink/renderer/modules/webaudio/delay_dsp_kernel.cc
@@ -58,6 +58,10 @@ return GetDelayProcessor()->DelayTime().FinalValue(); } +bool DelayDSPKernel::IsAudioRate() { + return GetDelayProcessor()->DelayTime().IsAudioRate(); +} + void DelayDSPKernel::ProcessOnlyAudioParams(uint32_t frames_to_process) { DCHECK_LE(frames_to_process, audio_utilities::kRenderQuantumFrames);
diff --git a/third_party/blink/renderer/modules/webaudio/delay_dsp_kernel.h b/third_party/blink/renderer/modules/webaudio/delay_dsp_kernel.h index e4d0529..c3d1fe4 100644 --- a/third_party/blink/renderer/modules/webaudio/delay_dsp_kernel.h +++ b/third_party/blink/renderer/modules/webaudio/delay_dsp_kernel.h
@@ -42,6 +42,7 @@ void CalculateSampleAccurateValues(float* delay_times, uint32_t frames_to_process) override; double DelayTime(float sample_rate) override; + bool IsAudioRate() override; void ProcessOnlyAudioParams(uint32_t frames_to_process) override;
diff --git a/third_party/blink/renderer/modules/webaudio/gain_node.cc b/third_party/blink/renderer/modules/webaudio/gain_node.cc index acd0b5ba..1ddae96 100644 --- a/third_party/blink/renderer/modules/webaudio/gain_node.cc +++ b/third_party/blink/renderer/modules/webaudio/gain_node.cc
@@ -71,7 +71,7 @@ } else { scoped_refptr<AudioBus> input_bus = Input(0).Bus(); - bool is_sample_accurate = gain_->HasSampleAccurateValuesTimeline(); + bool is_sample_accurate = gain_->HasSampleAccurateValues(); if (is_sample_accurate && gain_->IsAudioRate()) { // Apply sample-accurate gain scaling for precise envelopes, grain
diff --git a/third_party/blink/renderer/modules/webaudio/oscillator_node.cc b/third_party/blink/renderer/modules/webaudio/oscillator_node.cc index c3bc724..98de4c36 100644 --- a/third_party/blink/renderer/modules/webaudio/oscillator_node.cc +++ b/third_party/blink/renderer/modules/webaudio/oscillator_node.cc
@@ -192,8 +192,7 @@ float final_scale = periodic_wave_->RateScale(); - if (frequency_->HasSampleAccurateValuesTimeline() && - frequency_->IsAudioRate()) { + if (frequency_->HasSampleAccurateValues() && frequency_->IsAudioRate()) { has_sample_accurate_values = true; has_frequency_changes = true; @@ -207,7 +206,7 @@ final_scale *= frequency; } - if (detune_->HasSampleAccurateValuesTimeline() && detune_->IsAudioRate()) { + if (detune_->HasSampleAccurateValues() && detune_->IsAudioRate()) { has_sample_accurate_values = true; // Get the sample-accurate detune values.
diff --git a/third_party/blink/renderer/modules/webaudio/panner_node.cc b/third_party/blink/renderer/modules/webaudio/panner_node.cc index cacac039..f5416dea 100644 --- a/third_party/blink/renderer/modules/webaudio/panner_node.cc +++ b/third_party/blink/renderer/modules/webaudio/panner_node.cc
@@ -710,12 +710,12 @@ } bool PannerHandler::HasSampleAccurateValues() const { - return position_x_->HasSampleAccurateValuesTimeline() || - position_y_->HasSampleAccurateValuesTimeline() || - position_z_->HasSampleAccurateValuesTimeline() || - orientation_x_->HasSampleAccurateValuesTimeline() || - orientation_y_->HasSampleAccurateValuesTimeline() || - orientation_z_->HasSampleAccurateValuesTimeline(); + return position_x_->HasSampleAccurateValues() || + position_y_->HasSampleAccurateValues() || + position_z_->HasSampleAccurateValues() || + orientation_x_->HasSampleAccurateValues() || + orientation_y_->HasSampleAccurateValues() || + orientation_z_->HasSampleAccurateValues(); } bool PannerHandler::IsAudioRate() const {
diff --git a/third_party/blink/renderer/modules/webaudio/stereo_panner_node.cc b/third_party/blink/renderer/modules/webaudio/stereo_panner_node.cc index b5698ee..d58c60d3 100644 --- a/third_party/blink/renderer/modules/webaudio/stereo_panner_node.cc +++ b/third_party/blink/renderer/modules/webaudio/stereo_panner_node.cc
@@ -59,7 +59,7 @@ return; } - bool is_sample_accurate = pan_->HasSampleAccurateValuesTimeline(); + bool is_sample_accurate = pan_->HasSampleAccurateValues(); if (is_sample_accurate && pan_->IsAudioRate()) { // Apply sample-accurate panning specified by AudioParam automation.
diff --git a/third_party/blink/renderer/modules/webcodecs/image_decoder.idl b/third_party/blink/renderer/modules/webcodecs/image_decoder.idl index bd42b7d..2d13429 100644 --- a/third_party/blink/renderer/modules/webcodecs/image_decoder.idl +++ b/third_party/blink/renderer/modules/webcodecs/image_decoder.idl
@@ -16,7 +16,12 @@ // method will wait to resolve the promise until the given |frameIndex| is // available or reject the promise if we receive all data or fail before // |frameIndex| is available. - Promise<ImageFrame> decode(optional unsigned long frameIndex = 0); + // + // When |completeFramesOnly| is set to false, partial progressive frames will + // be returned. When in this mode, decode() calls will resolve only once per + // new partial image at |frameIndex| until the frame is complete. + Promise<ImageFrame> decode(optional unsigned long frameIndex = 0, + optional boolean completeFramesOnly = true); // The number of frames in the image. // @@ -36,4 +41,7 @@ // When decoding a ReadableStream the value will be 0 until enough data to // decode the repetition count has been received. readonly attribute unsigned long repetitionCount; + + // True if all available frames have been received by the decoder. + readonly attribute boolean complete; };
diff --git a/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc b/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc index 736c20d..cc08211 100644 --- a/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc +++ b/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc
@@ -35,8 +35,11 @@ ImageDecoderExternal::DecodeRequest::DecodeRequest( ScriptPromiseResolver* resolver, - uint32_t frame_index) - : resolver(resolver), frame_index(frame_index) {} + uint32_t frame_index, + bool complete_frames_only) + : resolver(resolver), + frame_index(frame_index), + complete_frames_only(complete_frames_only) {} void ImageDecoderExternal::DecodeRequest::Trace(Visitor* visitor) { visitor->Trace(resolver); @@ -113,13 +116,14 @@ DVLOG(1) << __func__; } -ScriptPromise ImageDecoderExternal::decode(uint32_t frame_index) { +ScriptPromise ImageDecoderExternal::decode(uint32_t frame_index, + bool complete_frames_only) { DVLOG(1) << __func__; auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state_); auto promise = resolver->Promise(); - pending_decodes_.push_back( - MakeGarbageCollected<DecodeRequest>(resolver, frame_index)); + pending_decodes_.push_back(MakeGarbageCollected<DecodeRequest>( + resolver, frame_index, complete_frames_only)); MaybeSatisfyPendingDecodes(); return promise; } @@ -136,6 +140,10 @@ return repetition_count_; } +bool ImageDecoderExternal::complete() const { + return data_complete_; +} + void ImageDecoderExternal::OnStateChange() { const char* buffer; size_t available; @@ -205,10 +213,17 @@ } // Only satisfy fully complete decode requests. - if (image->GetStatus() != ImageFrame::kFrameComplete) + const bool is_complete = image->GetStatus() == ImageFrame::kFrameComplete; + if (!is_complete && request->complete_frames_only) continue; - auto sk_image = image->FinalizePixelsAndGetImage(); + if (!is_complete && image->GetStatus() != ImageFrame::kFramePartial) + continue; + + // Prefer FinalizePixelsAndGetImage() since that will mark the underlying + // bitmap as immutable, which allows copies to be avoided. + auto sk_image = is_complete ? image->FinalizePixelsAndGetImage() + : SkImage::MakeFromBitmap(image->Bitmap()); if (!sk_image) { request->complete = true; // TODO: Include frameIndex in rejection? @@ -217,6 +232,22 @@ continue; } + if (!is_complete) { + auto generation_id = image->Bitmap().getGenerationID(); + auto it = incomplete_frames_.find(request->frame_index); + if (it == incomplete_frames_.end()) { + incomplete_frames_.Set(request->frame_index, generation_id); + } else { + // Don't fulfill the promise until a new bitmap is seen. + if (it->value == generation_id) + continue; + + it->value = generation_id; + } + } else { + incomplete_frames_.erase(request->frame_index); + } + auto* result = ImageFrameExternal::Create(); result->setImage(MakeGarbageCollected<ImageBitmap>( UnacceleratedStaticBitmapImage::Create(std::move(sk_image), @@ -225,6 +256,7 @@ result->setDuration( decoder_->FrameDurationAtIndex(request->frame_index).InMicroseconds()); result->setOrientation(decoder_->Orientation().Orientation()); + result->setComplete(is_complete); request->complete = true; request->resolver->Resolve(result); }
diff --git a/third_party/blink/renderer/modules/webcodecs/image_decoder_external.h b/third_party/blink/renderer/modules/webcodecs/image_decoder_external.h index aff7f20c..463747a 100644 --- a/third_party/blink/renderer/modules/webcodecs/image_decoder_external.h +++ b/third_party/blink/renderer/modules/webcodecs/image_decoder_external.h
@@ -38,10 +38,11 @@ ~ImageDecoderExternal() override; // image_decoder.idl implementation. - ScriptPromise decode(uint32_t frame_index); + ScriptPromise decode(uint32_t frame_index, bool complete_frames_only); uint32_t frameCount() const; String type() const; uint32_t repetitionCount() const; + bool complete() const; // BytesConsumer::Client implementation. void OnStateChange() override; @@ -74,14 +75,26 @@ // Pending decode() requests. struct DecodeRequest : public GarbageCollected<DecodeRequest> { - DecodeRequest(ScriptPromiseResolver* resolver, uint32_t frame_index); + DecodeRequest(ScriptPromiseResolver* resolver, + uint32_t frame_index, + bool complete_frames_only); void Trace(Visitor*); Member<ScriptPromiseResolver> resolver; uint32_t frame_index; + bool complete_frames_only; bool complete = false; }; HeapVector<Member<DecodeRequest>> pending_decodes_; + + // When decode() of incomplete frames has been requested, we need to track the + // generation id for each SkBitmap that we've handed out. So that we can defer + // resolution of promises until a new bitmap is generated. + HashMap<uint32_t, + uint32_t, + DefaultHash<uint32_t>::Hash, + WTF::UnsignedWithZeroKeyHashTraits<uint32_t>> + incomplete_frames_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/webcodecs/image_frame.idl b/third_party/blink/renderer/modules/webcodecs/image_frame.idl index f816094..a8b3762 100644 --- a/third_party/blink/renderer/modules/webcodecs/image_frame.idl +++ b/third_party/blink/renderer/modules/webcodecs/image_frame.idl
@@ -9,6 +9,9 @@ // Actual decoded image; includes resolution information. required ImageBitmap image; + // Indicates if the decoded image is actually complete. + required boolean complete; + // Expected on screen duration for the image in microseconds. required unsigned long long duration;
diff --git a/third_party/blink/renderer/modules/webgl/webgl_video_texture.cc b/third_party/blink/renderer/modules/webgl/webgl_video_texture.cc index d8eeff65..c781b522 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_video_texture.cc +++ b/third_party/blink/renderer/modules/webgl/webgl_video_texture.cc
@@ -40,7 +40,7 @@ WebGLExtension::Trace(visitor); } -VideoFrameMetadata* WebGLVideoTexture::VideoElementTargetVideoTexture( +VideoFrameMetadata* WebGLVideoTexture::shareVideoImageWEBGL( ExecutionContext* execution_context, unsigned target, HTMLVideoElement* video, @@ -90,10 +90,10 @@ // TODO(shaobo.yan@intel.com) : A fallback path or exception needs to be // added when video is not using gpu decoder. - video->PrepareVideoFrameForWebGL(scoped.Context()->ContextGL(), target, - texture->Object(), already_uploaded_id, - frame_metadata_ptr); - if (!frame_metadata_ptr) { + bool success = video->PrepareVideoFrameForWebGL( + scoped.Context()->ContextGL(), target, texture->Object(), + already_uploaded_id, frame_metadata_ptr); + if (!success) { exception_state.ThrowTypeError("Failed to share video to texture."); return nullptr; } @@ -125,4 +125,13 @@ #endif // defined OS_ANDROID } +bool WebGLVideoTexture::releaseVideoImageWEBGL( + ExecutionContext* execution_context, + unsigned target, + ExceptionState& exception_state) { + // NOTE: In current WEBGL_video_texture status, there is no lock on video + // frame. So this API doesn't need to do anything. + return true; +} + } // namespace blink
diff --git a/third_party/blink/renderer/modules/webgl/webgl_video_texture.h b/third_party/blink/renderer/modules/webgl/webgl_video_texture.h index 93506438..bbd9af6 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_video_texture.h +++ b/third_party/blink/renderer/modules/webgl/webgl_video_texture.h
@@ -27,10 +27,12 @@ // Get video frame from video frame compositor and bind it to platform // texture. - VideoFrameMetadata* VideoElementTargetVideoTexture(ExecutionContext*, - unsigned, - HTMLVideoElement*, - ExceptionState&); + VideoFrameMetadata* shareVideoImageWEBGL(ExecutionContext*, + unsigned, + HTMLVideoElement*, + ExceptionState&); + + bool releaseVideoImageWEBGL(ExecutionContext*, unsigned, ExceptionState&); private: Member<VideoFrameMetadata> current_frame_metadata_;
diff --git a/third_party/blink/renderer/modules/webgl/webgl_video_texture.idl b/third_party/blink/renderer/modules/webgl/webgl_video_texture.idl index 10653798..e53cac6 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_video_texture.idl +++ b/third_party/blink/renderer/modules/webgl/webgl_video_texture.idl
@@ -12,5 +12,6 @@ const GLenum TEXTURE_VIDEO_IMAGE = 0x9248; const GLenum SAMPLER_VIDEO_IMAGE = 0x9249; - [CallWith=ExecutionContext, RaisesException] VideoFrameMetadata VideoElementTargetVideoTexture(GLenum target, HTMLVideoElement video); + [CallWith=ExecutionContext, RaisesException] VideoFrameMetadata shareVideoImageWEBGL(GLenum target, HTMLVideoElement video); + [CallWith=ExecutionContext, RaisesException] boolean releaseVideoImageWEBGL(GLenum target); };
diff --git a/third_party/blink/renderer/modules/webgpu/dawn_object.cc b/third_party/blink/renderer/modules/webgpu/dawn_object.cc index db2e9099..8436a25 100644 --- a/third_party/blink/renderer/modules/webgpu/dawn_object.cc +++ b/third_party/blink/renderer/modules/webgpu/dawn_object.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/webgpu/dawn_object.h" +#include "gpu/command_buffer/client/webgpu_interface.h" #include "third_party/blink/renderer/modules/webgpu/gpu_device.h" namespace blink { @@ -29,8 +30,24 @@ return dawn_control_client_->GetProcs(); } +DawnDeviceClientSerializerHolder::DawnDeviceClientSerializerHolder( + scoped_refptr<DawnControlClientHolder> dawn_control_client, + uint64_t device_client_id) + : dawn_control_client_(std::move(dawn_control_client)), + device_client_id_(device_client_id) {} + +DawnDeviceClientSerializerHolder::~DawnDeviceClientSerializerHolder() { + if (dawn_control_client_->IsDestroyed()) { + return; + } + dawn_control_client_->GetInterface()->RemoveDevice(device_client_id_); +} + DawnObjectImpl::DawnObjectImpl(GPUDevice* device) - : DawnObjectBase(device->GetDawnControlClient()), device_(device) {} + : DawnObjectBase(device->GetDawnControlClient()), + device_(device), + device_client_serializer_holder_( + device->GetDeviceClientSerializerHolder()) {} DawnObjectImpl::~DawnObjectImpl() = default;
diff --git a/third_party/blink/renderer/modules/webgpu/dawn_object.h b/third_party/blink/renderer/modules/webgpu/dawn_object.h index 52543ee..559f9796 100644 --- a/third_party/blink/renderer/modules/webgpu/dawn_object.h +++ b/third_party/blink/renderer/modules/webgpu/dawn_object.h
@@ -42,6 +42,31 @@ scoped_refptr<DawnControlClientHolder> dawn_control_client_; }; +// This class allows objects to hold onto a DawnControlClientHolder and a +// device client id. Now one GPUDevice is related to one WebGPUSerializer in +// the client side of WebGPU context. When the GPUDevice and all the other +// WebGPU objects that are created from the GPUDevice are destroyed, this +// object will be destroyed and in the destructor of this object we will +// trigger the clean-ups to the corresponding WebGPUSerailzer and other data +// structures in the GPU process. +class DawnDeviceClientSerializerHolder + : public RefCounted<DawnDeviceClientSerializerHolder> { + public: + DawnDeviceClientSerializerHolder( + scoped_refptr<DawnControlClientHolder> dawn_control_client, + uint64_t device_client_id); + + private: + friend class RefCounted<DawnDeviceClientSerializerHolder>; + ~DawnDeviceClientSerializerHolder(); + + scoped_refptr<DawnControlClientHolder> dawn_control_client_; + uint64_t device_client_id_; +}; + +// TODO(jiawei.shao@intel.com): Remove the redundant reference of +// scoped_refptr<DawnControlClientHolder> inherited from DawnObjectBase as now +// we can access it from device_client_serializer_holder_. class DawnObjectImpl : public ScriptWrappable, public DawnObjectBase { public: DawnObjectImpl(GPUDevice* device); @@ -51,6 +76,8 @@ protected: Member<GPUDevice> device_; + scoped_refptr<DawnDeviceClientSerializerHolder> + device_client_serializer_holder_; }; template <typename Handle> @@ -66,17 +93,33 @@ Handle const handle_; }; +// TODO(jiawei.shao@intel.com): Remove the redundant reference of +// scoped_refptr<DawnControlClientHolder> inherited from DawnObjectBase as now +// we can access it from device_client_serializer_holder_. template <> class DawnObject<WGPUDevice> : public DawnObjectBase { public: DawnObject(scoped_refptr<DawnControlClientHolder> dawn_control_client, + uint64_t device_client_id, WGPUDevice handle) - : DawnObjectBase(std::move(dawn_control_client)), handle_(handle) {} + : DawnObjectBase(std::move(dawn_control_client)), + handle_(handle), + device_client_serializer_holder_( + base::MakeRefCounted<DawnDeviceClientSerializerHolder>( + GetDawnControlClient(), + device_client_id)) {} WGPUDevice GetHandle() const { return handle_; } + const scoped_refptr<DawnDeviceClientSerializerHolder>& + GetDeviceClientSerializerHolder() const { + return device_client_serializer_holder_; + } + private: WGPUDevice const handle_; + scoped_refptr<DawnDeviceClientSerializerHolder> + device_client_serializer_holder_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_device.cc b/third_party/blink/renderer/modules/webgpu/gpu_device.cc index f8f37f78..22c2d30 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_device.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_device.cc
@@ -40,6 +40,7 @@ const GPUDeviceDescriptor* descriptor) : ExecutionContextClient(execution_context), DawnObject(dawn_control_client, + client_id, dawn_control_client->GetInterface()->GetDevice(client_id)), adapter_(adapter), queue_(MakeGarbageCollected<GPUQueue>( @@ -61,7 +62,6 @@ } queue_ = nullptr; GetProcs().deviceRelease(GetHandle()); - GetInterface()->RemoveDevice(client_id_); } uint64_t GPUDevice::GetClientID() const {
diff --git a/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.cc b/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.cc index 819ca91..9e44ea8 100644 --- a/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.cc +++ b/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.cc
@@ -73,6 +73,10 @@ NOTREACHED(); } +bool AudioDelayDSPKernel::IsAudioRate() { + return true; +} + double AudioDelayDSPKernel::DelayTime(float sample_rate) { return desired_delay_frames_ / sample_rate; } @@ -92,7 +96,7 @@ float sample_rate = this->SampleRate(); double max_time = MaxDelayTime(); - if (HasSampleAccurateValues()) { + if (HasSampleAccurateValues() && IsAudioRate()) { float* delay_times = delay_times_.Data(); CalculateSampleAccurateValues(delay_times, frames_to_process);
diff --git a/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.h b/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.h index e5f1a29..7936d90 100644 --- a/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.h +++ b/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.h
@@ -58,6 +58,7 @@ virtual void CalculateSampleAccurateValues(float* delay_times, uint32_t frames_to_process); virtual double DelayTime(float sample_rate); + virtual bool IsAudioRate(); AudioFloatArray buffer_;
diff --git a/third_party/blink/renderer/platform/bindings/runtime_call_stats.cc b/third_party/blink/renderer/platform/bindings/runtime_call_stats.cc index 7899cd79..8d615937 100644 --- a/third_party/blink/renderer/platform/bindings/runtime_call_stats.cc +++ b/third_party/blink/renderer/platform/bindings/runtime_call_stats.cc
@@ -15,7 +15,7 @@ namespace blink { -// Wrapper function defined in WebKit.h +// Function defined in third_party/blink/public/web/blink.h. void LogRuntimeCallStats() { LOG(INFO) << "\n" << RuntimeCallStats::From(MainThreadIsolate())->ToString().Utf8();
diff --git a/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.cc b/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.cc index 88cfb11..3103fb12 100644 --- a/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.cc +++ b/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.cc
@@ -55,7 +55,7 @@ } // namespace -// Wrapper function defined in blink.h +// Function defined in third_party/blink/public/web/blink.h. v8::Isolate* MainThreadIsolate() { return V8PerIsolateData::MainThreadIsolate(); }
diff --git a/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support_test.cc b/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support_test.cc index c6493f4..50491a11 100644 --- a/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support_test.cc +++ b/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support_test.cc
@@ -280,7 +280,8 @@ } } -TEST_F(OpenTypeMathSupportTest, MathVariantsWithTable) { +// Broken on all platforms by updated to 'operators.woff'. crbug.com/1082250 +TEST_F(OpenTypeMathSupportTest, DISABLED_MathVariantsWithTable) { // operators.woff contains stretchy operators from the MathML operator // dictionary (including left and over braces) represented by squares. // It also contains glyphs h0, h1, h2, h3 and v0, v1, v2, v3 that are
diff --git a/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper_test.cc b/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper_test.cc index b1ebf0d..c04d774c 100644 --- a/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper_test.cc +++ b/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper_test.cc
@@ -51,7 +51,8 @@ // See createStretchy() in // third_party/blink/web_tests/external/wpt/mathml/tools/operator-dictionary.py -TEST_F(StretchyOperatorShaperTest, GlyphVariants) { +// Broken on all platforms by updated to 'operators.woff'. crbug.com/1082250 +TEST_F(StretchyOperatorShaperTest, DISABLED_GlyphVariants) { Font math = CreateMathFont("operators.woff"); StretchyOperatorShaper vertical_shaper(
diff --git a/third_party/blink/renderer/platform/graphics/compositing/layers_as_json.cc b/third_party/blink/renderer/platform/graphics/compositing/layers_as_json.cc index b4b306f3..52e787ac 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/layers_as_json.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/layers_as_json.cc
@@ -48,6 +48,8 @@ if (layer->contents_opaque()) json->SetBoolean("contentsOpaque", true); + else if (layer->contents_opaque_for_text()) + json->SetBoolean("contentsOpaqueForText", true); if (!layer->DrawsContent()) json->SetBoolean("drawsContent", false);
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc index 18b59298..48bc919 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
@@ -1226,6 +1226,8 @@ const ViewportProperties& viewport_properties, const Settings& settings, const Vector<const TransformPaintPropertyNode*>& scroll_translation_nodes) { + DCHECK(scroll_translation_nodes.IsEmpty() || + RuntimeEnabledFeatures::ScrollUnificationEnabled()); DCHECK(NeedsUpdate()); DCHECK(root_layer_); // The tree will be null after detaching and this update can be ignored.
diff --git a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc index ee8aba5..9017db52 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc
@@ -49,6 +49,7 @@ #include "gpu/config/gpu_driver_bug_workaround_type.h" #include "gpu/config/gpu_feature_info.h" #include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/public/web/blink.h" #include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h" #include "third_party/blink/renderer/platform/graphics/canvas_resource.h" #include "third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.h" @@ -71,10 +72,15 @@ const float kResourceAdjustedRatio = 0.5; -static bool g_should_fail_drawing_buffer_creation_for_testing = false; +bool g_should_fail_drawing_buffer_creation_for_testing = false; } // namespace +// Function defined in third_party/blink/public/web/blink.h. +void ForceNextDrawingBufferCreationToFailForTest() { + g_should_fail_drawing_buffer_creation_for_testing = true; +} + scoped_refptr<DrawingBuffer> DrawingBuffer::Create( std::unique_ptr<WebGraphicsContext3DProvider> context_provider, bool using_gpu_compositing, @@ -149,10 +155,6 @@ return drawing_buffer; } -void DrawingBuffer::ForceNextDrawingBufferCreationToFail() { - g_should_fail_drawing_buffer_creation_for_testing = true; -} - DrawingBuffer::DrawingBuffer( std::unique_ptr<WebGraphicsContext3DProvider> context_provider, bool using_gpu_compositing,
diff --git a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h index 9ac03f51..48020990 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h +++ b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h
@@ -138,7 +138,6 @@ ChromiumImageUsage, const CanvasColorParams&, gl::GpuPreference); - static void ForceNextDrawingBufferCreationToFail(); ~DrawingBuffer() override;
diff --git a/third_party/blink/renderer/platform/graphics/graphics_layer.cc b/third_party/blink/renderer/platform/graphics/graphics_layer.cc index 3be2155a..2b833d2 100644 --- a/third_party/blink/renderer/platform/graphics/graphics_layer.cc +++ b/third_party/blink/renderer/platform/graphics/graphics_layer.cc
@@ -567,6 +567,10 @@ contents_layer_->SetContentsOpaque(opaque); } +void GraphicsLayer::SetContentsOpaqueForText(bool opaque) { + CcLayer()->SetContentsOpaqueForText(opaque); +} + void GraphicsLayer::SetMaskLayer(GraphicsLayer* mask_layer) { if (mask_layer == mask_layer_) return;
diff --git a/third_party/blink/renderer/platform/graphics/graphics_layer.h b/third_party/blink/renderer/platform/graphics/graphics_layer.h index 47601313..6ca0af1 100644 --- a/third_party/blink/renderer/platform/graphics/graphics_layer.h +++ b/third_party/blink/renderer/platform/graphics/graphics_layer.h
@@ -151,6 +151,7 @@ // Opaque means that we know the layer contents have no alpha. bool ContentsOpaque() const; void SetContentsOpaque(bool); + void SetContentsOpaqueForText(bool); void SetHitTestable(bool); bool GetHitTestable() const { return hit_testable_; }
diff --git a/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.cc b/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.cc index 43cf2969..0f10eb0 100644 --- a/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.cc +++ b/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.cc
@@ -292,7 +292,6 @@ ImageFrame& buffer = frame_buffer_cache_[index]; DCHECK_NE(buffer.GetStatus(), ImageFrame::kFrameComplete); - buffer.SetHasAlpha(!!image->alphaPlane); if (decode_to_half_float_) buffer.SetPixelFormat(ImageFrame::PixelFormat::kRGBA_F16); @@ -319,6 +318,7 @@ } buffer.SetPixelsChanged(true); + buffer.SetHasAlpha(!!image->alphaPlane); buffer.SetStatus(ImageFrame::kFrameComplete); }
diff --git a/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder_test.cc b/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder_test.cc index a0a6e06..9a8f00e 100644 --- a/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder_test.cc +++ b/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder_test.cc
@@ -13,7 +13,6 @@ #include "third_party/blink/renderer/platform/wtf/shared_buffer.h" #include "third_party/libavif/src/include/avif/avif.h" -#define FIXME_HAS_ALPHA_ALWAYS_RETURNS_TRUE 0 #define FIXME_SUPPORT_10BIT_IMAGE_WITH_ALPHA 0 #define FIXME_SUPPORT_12BIT_IMAGE_WITH_ALPHA 0 #define FIXME_CRASH_IF_COLOR_TRANSFORMATION_IS_ENABLED 0 @@ -546,11 +545,9 @@ // TODO(ryoh): How should we treat imir(mirroring), irot(rotation) and // clap(cropping)? // EXPECT_EQ(xxxx, decoder->Orientation()); -#if FIXME_HAS_ALPHA_ALWAYS_RETURNS_TRUE EXPECT_EQ(param.color_type == ColorType::kRgbA || param.color_type == ColorType::kMonoA, frame->HasAlpha()); -#endif auto get_color_channel = [](SkColorChannel channel, SkColor color) { switch (channel) { case SkColorChannel::kR:
diff --git a/third_party/blink/renderer/platform/instrumentation/memory_pressure_listener.cc b/third_party/blink/renderer/platform/instrumentation/memory_pressure_listener.cc index 8db1836..3cca4cb 100644 --- a/third_party/blink/renderer/platform/instrumentation/memory_pressure_listener.cc +++ b/third_party/blink/renderer/platform/instrumentation/memory_pressure_listener.cc
@@ -26,7 +26,7 @@ namespace blink { -// Wrapper function defined in WebKit.h +// Function defined in third_party/blink/public/web/blink.h. void DecommitFreeableMemory() { CHECK(IsMainThread()); base::PartitionAllocMemoryReclaimer::Instance()->Reclaim();
diff --git a/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc b/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc index b3ddb84..a1e014c 100644 --- a/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc +++ b/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc
@@ -75,8 +75,34 @@ int Render(base::TimeDelta delay, base::TimeTicks delay_timestamp, int prior_frames_skipped, - media::AudioBus* dest) override; - void OnRenderError() override; + media::AudioBus* audio_bus) override { + DCHECK(initialized()); + + const int num_rendered_frames = renderer_->Render( + delay, delay_timestamp, prior_frames_skipped, audio_bus); + + // Avoid taking the copy lock for the vast majority of cases. + if (copy_required_) { + base::AutoLock auto_lock(copy_lock_); + if (!copy_audio_bus_callback_.is_null()) { + const int64_t frames_delayed = + media::AudioTimestampHelper::TimeToFrames(delay, sample_rate_); + std::unique_ptr<media::AudioBus> bus_copy = + media::AudioBus::Create(audio_bus->channels(), audio_bus->frames()); + audio_bus->CopyTo(bus_copy.get()); + copy_audio_bus_callback_.Run(std::move(bus_copy), + static_cast<uint32_t>(frames_delayed), + sample_rate_); + } + } + + return num_rendered_frames; + } + + void OnRenderError() override { + DCHECK(initialized()); + renderer_->OnRenderError(); + } bool initialized() const { return !!renderer_; } int channels() const { return channels_; } @@ -135,7 +161,7 @@ // The client will now take control by calling provideInput() periodically. client_ = client; - set_format_cb_ = media::BindToCurrentLoop(WTF::Bind( + set_format_cb_ = media::BindToCurrentLoop(WTF::BindRepeating( &WebAudioSourceProviderImpl::OnSetFormat, weak_factory_.GetWeakPtr())); // If |tee_filter_| is Initialize()d - then run |set_format_cb_| to send @@ -143,13 +169,17 @@ // called when Initialize() is called. Note: Always using |set_format_cb_| // ensures we have the same locking order when calling into |client_|. if (tee_filter_->initialized()) - std::move(set_format_cb_).Run(); + set_format_cb_.Run(); return; } // Drop client, but normal playback can't be restored. This is okay, the only // way to disconnect a client is internally at time of destruction. client_ = nullptr; + + // We need to invalidate WeakPtr references on the renderer thread. + set_format_cb_.Reset(); + weak_factory_.InvalidateWeakPtrs(); } void WebAudioSourceProviderImpl::ProvideInput( @@ -197,7 +227,7 @@ sink_->Initialize(params, tee_filter_.get()); if (set_format_cb_) - std::move(set_format_cb_).Run(); + set_format_cb_.Run(); } void WebAudioSourceProviderImpl::Start() { @@ -311,37 +341,4 @@ client_->SetFormat(tee_filter_->channels(), tee_filter_->sample_rate()); } -int WebAudioSourceProviderImpl::TeeFilter::Render( - base::TimeDelta delay, - base::TimeTicks delay_timestamp, - int prior_frames_skipped, - media::AudioBus* audio_bus) { - DCHECK(initialized()); - - const int num_rendered_frames = renderer_->Render( - delay, delay_timestamp, prior_frames_skipped, audio_bus); - - // Avoid taking the copy lock for the vast majority of cases. - if (copy_required_) { - base::AutoLock auto_lock(copy_lock_); - if (!copy_audio_bus_callback_.is_null()) { - const int64_t frames_delayed = - media::AudioTimestampHelper::TimeToFrames(delay, sample_rate_); - std::unique_ptr<media::AudioBus> bus_copy = - media::AudioBus::Create(audio_bus->channels(), audio_bus->frames()); - audio_bus->CopyTo(bus_copy.get()); - copy_audio_bus_callback_.Run(std::move(bus_copy), - static_cast<uint32_t>(frames_delayed), - sample_rate_); - } - } - - return num_rendered_frames; -} - -void WebAudioSourceProviderImpl::TeeFilter::OnRenderError() { - DCHECK(initialized()); - renderer_->OnRenderError(); -} - } // namespace blink
diff --git a/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl_test.cc b/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl_test.cc index 870c3d2..1f0c69d7 100644 --- a/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl_test.cc +++ b/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl_test.cc
@@ -267,4 +267,57 @@ testing::Mock::VerifyAndClear(mock_sink_.get()); } +TEST_F(WebAudioSourceProviderImplTest, MultipleInitializeWithSetClient) { + // setClient() with a nullptr client should do nothing if no client is set. + wasp_impl_->SetClient(nullptr); + + // When Initialize() is called after setClient(), the params should propagate + // to the client via setFormat() during the call. + EXPECT_TRUE(wasp_impl_->IsOptimizedForHardwareParameters()); + EXPECT_CALL(*this, SetFormat(params_.channels(), params_.sample_rate())); + wasp_impl_->Initialize(params_, &fake_callback_); + base::RunLoop().RunUntilIdle(); + + // If |mock_sink_| is not null, it should be stopped during setClient(this). + if (mock_sink_) + EXPECT_CALL(*mock_sink_.get(), Stop()); + + // setClient() with the same client should do nothing. + wasp_impl_->SetClient(this); + base::RunLoop().RunUntilIdle(); + + // Stop allows Initialize() to be called again. + wasp_impl_->Stop(); + + // It's possible that due to media change or just the change in the return + // value for IsOptimizedForHardwareParameters() that different params are + // given. Ensure this doesn't crash. + EXPECT_FALSE(wasp_impl_->IsOptimizedForHardwareParameters()); + auto stream_params = media::AudioParameters( + media::AudioParameters::AUDIO_PCM_LINEAR, media::CHANNEL_LAYOUT_MONO, + kTestSampleRate * 2, 64); + + EXPECT_CALL(*this, + SetFormat(stream_params.channels(), stream_params.sample_rate())); + wasp_impl_->Initialize(stream_params, &fake_callback_); + base::RunLoop().RunUntilIdle(); + + wasp_impl_->Start(); + wasp_impl_->Play(); + + auto bus1 = media::AudioBus::Create(stream_params); + auto bus2 = media::AudioBus::Create(stream_params); + + // Point the WebVector into memory owned by |bus1|. + WebVector<float*> audio_data(static_cast<size_t>(bus1->channels())); + for (size_t i = 0; i < audio_data.size(); ++i) + audio_data[i] = bus1->channel(static_cast<int>(i)); + + // Verify provideInput() doesn't return silence and doesn't crash. + bus1->channel(0)[0] = 1; + bus2->Zero(); + wasp_impl_->ProvideInput(audio_data, params_.frames_per_buffer()); + ASSERT_FALSE(CompareBusses(bus1.get(), bus2.get())); +} + } // namespace blink
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 8a93109..578251c 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1569,12 +1569,6 @@ name: "SameSiteByDefaultCookies", status: "test", }, - // Exposes the displays connected to the device and provides the display - // properties needed for window placement features. - { - name: "ScreenEnumeration", - status: "experimental", - }, { name: "ScreenWakeLock", status: "stable", @@ -2013,7 +2007,8 @@ depends_on: ["WebXRARModule"], status: "experimental", }, - // Extends window placement functionality for multi-screen devices. + // Extends window placement functionality for multi-screen devices. Also + // exposes requisite information about displays connected to the device. { name: "WindowPlacement", status: "experimental",
diff --git a/third_party/blink/renderer/platform/web_test_support.cc b/third_party/blink/renderer/platform/web_test_support.cc index 2f705df..068aa761 100644 --- a/third_party/blink/renderer/platform/web_test_support.cc +++ b/third_party/blink/renderer/platform/web_test_support.cc
@@ -35,7 +35,8 @@ namespace blink { -// Wrapper functions defined in blink.h +// ==== Functions defined in third_party/blink/public/web/blink.h. ==== + void SetWebTestMode(bool value) { WebTestSupport::SetIsRunningWebTest(value); } @@ -52,6 +53,8 @@ return WebTestSupport::IsFontAntialiasingEnabledForTest(); } +// ==== State methods defined in WebTestSupport. ==== + static bool g_is_running_web_test = false; static bool g_is_font_antialiasing_enabled = false; static bool g_is_subpixel_positioning_allowed = true;
diff --git a/third_party/blink/renderer/platform/weborigin/scheme_registry.cc b/third_party/blink/renderer/platform/weborigin/scheme_registry.cc index 5e53886..adb0629 100644 --- a/third_party/blink/renderer/platform/weborigin/scheme_registry.cc +++ b/third_party/blink/renderer/platform/weborigin/scheme_registry.cc
@@ -26,6 +26,8 @@ #include "third_party/blink/renderer/platform/weborigin/scheme_registry.h" +#include "third_party/blink/public/platform/web_string.h" +#include "third_party/blink/public/web/blink.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" #include "third_party/blink/renderer/platform/wtf/thread_specific.h" @@ -35,6 +37,17 @@ namespace blink { +// Function defined in third_party/blink/public/web/blink.h. +void SetDomainRelaxationForbidden(bool forbidden, const WebString& scheme) { + SchemeRegistry::SetDomainRelaxationForbiddenForURLScheme(forbidden, + String(scheme)); +} + +// Function defined in third_party/blink/public/web/blink.h. +void ResetDomainRelaxation() { + SchemeRegistry::ResetDomainRelaxation(); +} + namespace { struct PolicyAreasHashTraits : HashTraits<SchemeRegistry::PolicyAreas> { @@ -185,6 +198,11 @@ } } +void SchemeRegistry::ResetDomainRelaxation() { + GetMutableURLSchemesRegistry() + .schemes_forbidden_from_domain_relaxation.clear(); +} + bool SchemeRegistry::IsDomainRelaxationForbiddenForURLScheme( const String& scheme) { DCHECK_EQ(scheme, scheme.LowerASCII());
diff --git a/third_party/blink/renderer/platform/weborigin/scheme_registry.h b/third_party/blink/renderer/platform/weborigin/scheme_registry.h index 3a6f7734..32f165e 100644 --- a/third_party/blink/renderer/platform/weborigin/scheme_registry.h +++ b/third_party/blink/renderer/platform/weborigin/scheme_registry.h
@@ -71,6 +71,7 @@ static void SetDomainRelaxationForbiddenForURLScheme(bool forbidden, const String&); + static void ResetDomainRelaxation(); static bool IsDomainRelaxationForbiddenForURLScheme(const String&); // Such schemes should delegate to SecurityOrigin::canRequest for any URL
diff --git a/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc b/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc index 16c9b02..c4c7a7d 100644 --- a/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc +++ b/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc
@@ -290,25 +290,44 @@ } if (currently_active_gesture_device_.has_value()) { - bool is_from_set_non_blocking_touch = + // Scroll updates should typically be queued and wait until a + // BeginImplFrame to dispatch. However, the first scroll update to be + // generated from a *blocking* touch sequence will have waited for the + // touch event to be ACK'ed by the renderer as unconsumed. Queueing here + // again until BeginImplFrame means we'll likely add a whole frame of + // latency to so we flush the queue immediately. This happens only for the + // first scroll update because once a scroll starts touch events are + // dispatched non-blocking so scroll updates don't wait for a touch ACK. + // The |is_source_touch_event_set_non_blocking| bit is set based on the + // renderer's reply that a blocking touch stream should be made + // non-blocking. Note: unlike wheel events below, the first GSU in a touch + // may have come from a non-blocking touch sequence, e.g. if the earlier + // touchstart determined we're in a |touch-action: pan-y| region. Because + // of this, we can't simply look at the first GSU like wheels do. + bool is_from_blocking_touch = gesture_event.SourceDevice() == WebGestureDevice::kTouchscreen && gesture_event.is_source_touch_event_set_non_blocking; + + // TODO(bokan): This was added in https://crrev.com/c/557463 before async + // wheel events. It's not clear to me why flushing on a scroll end would + // help or why this is specific to wheel events but I suspect it's no + // longer needed now that wheel scrolling uses non-blocking events. bool is_scroll_end_from_wheel = gesture_event.SourceDevice() == WebGestureDevice::kTouchpad && gesture_event.GetType() == WebGestureEvent::Type::kGestureScrollEnd; - bool scroll_update_has_blocking_wheel_source = + + // Wheel events have the same issue as the blocking touch issue above. + // However, all wheel events are initially sent blocking and become non- + // blocking on the first unconsumed event. We can therefore simply look for + // the first scroll update in a wheel gesture. + bool is_first_wheel_scroll_update = gesture_event.SourceDevice() == WebGestureDevice::kTouchpad && is_first_gesture_scroll_update; - if (is_from_set_non_blocking_touch || is_scroll_end_from_wheel || - scroll_update_has_blocking_wheel_source || synchronous_input_handler_) { - // 1. Gesture events was already delayed by blocking events in rAF aligned - // queue. We want to avoid additional one frame delay by flushing the - // VSync queue immediately. - // The first GSU latency was tracked by: - // |smoothness.tough_scrolling_cases:first_gesture_scroll_update_latency|. - // 2. |synchronous_input_handler_| is WebView only. WebView has different - // mechanisms and we want to forward all events immediately. + // |synchronous_input_handler_| is WebView only. WebView has different + // mechanisms and we want to forward all events immediately. + if (is_from_blocking_touch || is_scroll_end_from_wheel || + is_first_wheel_scroll_update || synchronous_input_handler_) { compositor_event_queue_->Queue(std::move(event_with_callback), tick_clock_->NowTicks()); DispatchQueuedInputEvents();
diff --git a/third_party/blink/tools/blinkpy/common/config/builders.json b/third_party/blink/tools/blinkpy/common/config/builders.json index 6eb01c7..a0abbad 100644 --- a/third_party/blink/tools/blinkpy/common/config/builders.json +++ b/third_party/blink/tools/blinkpy/common/config/builders.json
@@ -114,15 +114,5 @@ "port_name": "win-win10", "specifiers": ["Win10", "Release"], "is_try_builder": true - }, - "android-weblayer-pie-arm64-fyi-rel": { - "port_name": "android-android-pie", - "specifiers": ["Android", "android_weblayer", "Release"], - "is_try_builder": true - }, - "android-webview-pie-arm64-fyi-rel": { - "port_name": "android-android-pie", - "specifiers": ["Android", "android_webview", "chrome_android", "Release"], - "is_try_builder": true } }
diff --git a/third_party/blink/tools/blinkpy/common/net/results_fetcher.py b/third_party/blink/tools/blinkpy/common/net/results_fetcher.py index fb9fd6f..4670cc1f 100644 --- a/third_party/blink/tools/blinkpy/common/net/results_fetcher.py +++ b/third_party/blink/tools/blinkpy/common/net/results_fetcher.py
@@ -118,19 +118,18 @@ builder_name) + '/results/layout-test-results' @memoized - def fetch_results(self, build, full=False, step_name=None): + def fetch_results(self, build, full=False): """Returns a WebTestResults object for results from a given Build. Uses full_results.json if full is True, otherwise failing_results.json. """ if not build.builder_name or not build.build_number: _log.debug('Builder name or build number is None') return None - step_name = step_name or self.get_layout_test_step_name(build) return self.fetch_web_test_results( self.results_url( build.builder_name, build.build_number, - step_name=step_name), full, step_name) + step_name=self.get_layout_test_step_name(build)), full) @memoized def get_layout_test_step_name(self, build): @@ -175,7 +174,7 @@ return suites[0] @memoized - def fetch_web_test_results(self, results_url, full=False, step_name=None): + def fetch_web_test_results(self, results_url, full=False): """Returns a WebTestResults object for results fetched from a given URL. Uses full_results.json if full is True, otherwise failing_results.json. """ @@ -186,7 +185,7 @@ _log.debug('Got 404 response from:\n%s/%s', results_url, base_filename) return None - return WebTestResults.results_from_string(results_file, step_name) + return WebTestResults.results_from_string(results_file) def fetch_webdriver_test_results(self, build, master): if not build.builder_name or not build.build_number or not master:
diff --git a/third_party/blink/tools/blinkpy/common/net/results_fetcher_mock.py b/third_party/blink/tools/blinkpy/common/net/results_fetcher_mock.py index e51edde..c3b6f520 100644 --- a/third_party/blink/tools/blinkpy/common/net/results_fetcher_mock.py +++ b/third_party/blink/tools/blinkpy/common/net/results_fetcher_mock.py
@@ -26,11 +26,8 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -from collections import namedtuple - from blinkpy.common.net.results_fetcher import TestResultsFetcher -BuilderStep = namedtuple('BuilderStep', ['build', 'step_name']) # TODO(qyearsley): To be consistent with other fake ("mock") classes, this # could be changed so it's not a subclass of TestResultsFetcher. @@ -44,16 +41,12 @@ self.fetched_webdriver_builds = [] self._layout_test_step_name = 'blink_web_tests (with patch)' - def set_results(self, build, results, step_name=None): - step_name = step_name or self.get_layout_test_step_name(build) - step = BuilderStep(build=build, step_name=step_name) - self._canned_results[step] = results + def set_results(self, build, results): + self._canned_results[build] = results - def fetch_results(self, build, full=False, step_name=None): - step_name = step_name or self.get_layout_test_step_name(build) - step = BuilderStep(build=build, step_name=step_name) - self.fetched_builds.append(step) - return self._canned_results.get(step) + def fetch_results(self, build, full=False): + self.fetched_builds.append(build) + return self._canned_results.get(build) def set_webdriver_test_results(self, build, master, results): self._webdriver_results[(build, master)] = results
diff --git a/third_party/blink/tools/blinkpy/common/net/web_test_results.py b/third_party/blink/tools/blinkpy/common/net/web_test_results.py index 4e5421a..deb8d985 100644 --- a/third_party/blink/tools/blinkpy/common/net/web_test_results.py +++ b/third_party/blink/tools/blinkpy/common/net/web_test_results.py
@@ -113,7 +113,7 @@ # This doesn't belong in common.net, but we don't have a better place for it yet. class WebTestResults(object): @classmethod - def results_from_string(cls, string, step_name=None): + def results_from_string(cls, string): """Creates a WebTestResults object from a test result JSON string. Args: @@ -128,15 +128,11 @@ if not json_dict: return None - return cls(json_dict, step_name=step_name) + return cls(json_dict) - def __init__(self, parsed_json, chromium_revision=None, step_name=None): + def __init__(self, parsed_json, chromium_revision=None): self._results = parsed_json self._chromium_revision = chromium_revision - self._step_name = step_name - - def step_name(self): - return self._step_name def run_was_interrupted(self): return self._results['interrupted']
diff --git a/third_party/blink/tools/blinkpy/tool/commands/rebaseline_cl.py b/third_party/blink/tools/blinkpy/tool/commands/rebaseline_cl.py index 2a2075a..10a4d280 100644 --- a/third_party/blink/tools/blinkpy/tool/commands/rebaseline_cl.py +++ b/third_party/blink/tools/blinkpy/tool/commands/rebaseline_cl.py
@@ -173,8 +173,7 @@ def selected_try_bots(self): if self._selected_try_bots: return self._selected_try_bots - return frozenset(self._tool.builders.filter_builders( - is_try=True, exclude_specifiers={'android'})) + return frozenset(self._tool.builders.all_try_builder_names()) def _get_issue_number(self): """Returns the current CL issue number, or None."""
diff --git a/third_party/blink/tools/blinkpy/w3c/android_wpt_expectations_updater.py b/third_party/blink/tools/blinkpy/w3c/android_wpt_expectations_updater.py deleted file mode 100644 index b945d01..0000000 --- a/third_party/blink/tools/blinkpy/w3c/android_wpt_expectations_updater.py +++ /dev/null
@@ -1,190 +0,0 @@ -# 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. -"""Updates expectations for Android WPT bots. - -Specifically, this class fetches results from try bots for the current CL, then -(1) updates browser specific expectation files for Androids browsers like Weblayer. - -We needed an Android flavour of the WPTExpectationsUpdater class because -(1) Android bots don't currently produce output that can be baselined, therefore - we only update expectations in the class below. -(2) For Android we write test expectations to browser specific expectation files, - not the regular web test's TestExpectation and NeverFixTests file. -(3) WPTExpectationsUpdater can only update expectations for the blink_web_tests - and webdriver_test_suite steps. Android bots may run several WPT steps, so - the script needs to be able to update expectations for multiple steps. -""" - -import logging -from collections import defaultdict, namedtuple - -from blinkpy.common.host import Host -from blinkpy.common.memoized import memoized -from blinkpy.common.system.executive import ScriptError -from blinkpy.w3c.wpt_expectations_updater import WPTExpectationsUpdater -from blinkpy.web_tests.models.test_expectations import TestExpectations -from blinkpy.web_tests.models.typ_types import Expectation -from blinkpy.web_tests.port.android import ( - PRODUCTS, PRODUCTS_TO_STEPNAMES, PRODUCTS_TO_BROWSER_TAGS, - PRODUCTS_TO_EXPECTATION_FILE_PATHS) - -_log = logging.getLogger(__name__) - -AndroidConfig = namedtuple('AndroidConfig', ['port_name', 'browser']) - - -class AndroidWPTExpectationsUpdater(WPTExpectationsUpdater): - MARKER_COMMENT = '# Add untriaged failures in this block' - UMBRELLA_BUG = 'crbug.com/1050754' - - def __init__(self, host, args=None): - super(AndroidWPTExpectationsUpdater, self).__init__(host, args) - expectations_dict = {} - for product in self.options.android_product: - path = PRODUCTS_TO_EXPECTATION_FILE_PATHS[product] - expectations_dict.update( - {path: self.host.filesystem.read_text_file(path)}) - - self._test_expectations = TestExpectations( - self.port, expectations_dict=expectations_dict) - - def _get_web_test_results(self, build): - """Gets web tests results for Android builders. We need to - bypass the step which gets the step names for the builder - since it does not currently work for Android. - - Args: - build: Named tuple containing builder name and number - - Returns: - returns: List of web tests results for each web test step - in build. - """ - results_sets = [] - build_specifiers = self._get_build_specifiers(build) - for product in self.options.android_product: - if product in build_specifiers: - step_name = PRODUCTS_TO_STEPNAMES[product] - results_sets.append(self.host.results_fetcher.fetch_results( - build, True, '%s (with patch)' % step_name)) - return filter(None, results_sets) - - def get_builder_configs(self, build, results_set=None): - """Gets step name from WebTestResults instance and uses - that to create AndroidConfig instances. It also only - returns valid configs for the android products passed - through the --android-product command line argument. - - Args: - build: Build object that contains the builder name and - build number. - results_set: WebTestResults instance. If this variable - then it will return a list of android configs for - each product passed through the --android-product - command line argument. - - Returns: - List of valid android configs for products passed through - the --android-product command line argument.""" - configs = [] - if not results_set: - build_specifiers = self._get_build_specifiers(build) - products = build_specifiers & { - s.lower() for s in self.options.android_product} - else: - step_name = results_set.step_name() - step_name = step_name[: step_name.index(' (with patch)')] - product = {s: p for p, s in PRODUCTS_TO_STEPNAMES.items()}[step_name] - products = {product} - - for product in products: - browser = PRODUCTS_TO_BROWSER_TAGS[product] - configs.append( - AndroidConfig(port_name=self.port_name(build), browser=browser)) - return configs - - @memoized - def _get_build_specifiers(self, build): - return {s.lower() for s in - self.host.builders.specifiers_for_builder(build.builder_name)} - - def can_rebaseline(self, *_): - """Return False since we cannot rebaseline tests for - Android at the moment.""" - return False - - @memoized - def _get_marker_line_number(self, path): - for line in self._test_expectations.get_updated_lines(path): - if line.to_string() == self.MARKER_COMMENT: - return line.lineno - raise ScriptError('Marker comment does not exist in %s' % path) - - def write_to_test_expectations(self, test_to_results): - """Each expectations file is browser specific, and currently only - runs on pie. Therefore we do not need any configuration specifiers - to anotate expectations for certain builds. - - Args: - test_to_results: A dictionary that maps test names to another - dictionary which maps a tuple of build configurations and to - a test result. - """ - browser_to_exp_path = { - browser: PRODUCTS_TO_EXPECTATION_FILE_PATHS[product] - for product, browser in PRODUCTS_TO_BROWSER_TAGS.items()} - untriaged_exps = defaultdict(dict) - - for path in self._test_expectations.expectations_dict: - marker_lineno = self._get_marker_line_number(path) - exp_lines = self._test_expectations.get_updated_lines(path) - for i in range(marker_lineno, len(exp_lines)): - if (not exp_lines[i].to_string().strip() or - exp_lines[i].to_string().startswith('#')): - break - untriaged_exps[path][exp_lines[i].test] = exp_lines[i] - - for path, test_exps in untriaged_exps.items(): - self._test_expectations.remove_expectations( - path, test_exps.values()) - - for results_test_name, platform_results in test_to_results.items(): - exps_test_name = 'external/wpt/%s' % results_test_name - for configs, test_results in platform_results.items(): - for config in configs: - path = browser_to_exp_path[config.browser] - # no system specifiers are necessary because we are - # writing to browser specific expectations files for - # only one Android version. - unexpected_results = {r for r in test_results.actual.split() - if r not in test_results.expected.split()} - - if exps_test_name not in untriaged_exps[path]: - untriaged_exps[path][exps_test_name] = Expectation( - test=exps_test_name, reason=self.UMBRELLA_BUG, - results=unexpected_results) - else: - untriaged_exps[path][exps_test_name].add_expectations( - unexpected_results, reason=self.UMBRELLA_BUG) - - for path in untriaged_exps: - marker_lineno = self._get_marker_line_number(path) - self._test_expectations.add_expectations( - path, - sorted(untriaged_exps[path].values(), key=lambda e: e.test), - marker_lineno) - - self._test_expectations.commit_changes() - - def _is_wpt_test(self, _): - """On Android we use the wpt executable. The test results do not include - the external/wpt prefix. Therefore we need to override this function for - Android and return True for all tests since we only run WPT on Android. - """ - return True - - @memoized - def _get_try_bots(self): - return self.host.builders.filter_builders( - is_try=True, include_specifiers=self.options.android_product)
diff --git a/third_party/blink/tools/blinkpy/w3c/android_wpt_expectations_updater_unittest.py b/third_party/blink/tools/blinkpy/w3c/android_wpt_expectations_updater_unittest.py deleted file mode 100644 index e3c70e4..0000000 --- a/third_party/blink/tools/blinkpy/w3c/android_wpt_expectations_updater_unittest.py +++ /dev/null
@@ -1,323 +0,0 @@ -# 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. - -import logging - -from blinkpy.common.host_mock import MockHost -from blinkpy.common.net.git_cl import TryJobStatus -from blinkpy.common.net.git_cl_mock import MockGitCL -from blinkpy.common.net.results_fetcher import Build -from blinkpy.common.net.web_test_results import WebTestResults -from blinkpy.common.system.log_testing import LoggingTestCase -from blinkpy.web_tests.builder_list import BuilderList -from blinkpy.web_tests.port.factory_mock import MockPortFactory -from blinkpy.web_tests.port.android import PRODUCTS_TO_EXPECTATION_FILE_PATHS -from blinkpy.w3c.android_wpt_expectations_updater import ( - AndroidWPTExpectationsUpdater) - - -class AndroidWPTExpectationsUpdaterTest(LoggingTestCase): - - _raw_android_expectations = ( - '# results: [ Failure Crash Timeout]\n' - '\n' - '# Add untriaged failures in this block\n' - 'external/wpt/abc.html [ Failure ]\n' - 'crbug.com/1050754 external/wpt/def.html [ Crash ]\n' - 'crbug.com/1050754 external/wpt/ghi.html [ Timeout ]\n' - 'crbug.com/1111111 external/wpt/jkl.html [ Failure ]\n' - 'external/wpt/www.html [ Crash Failure ]\n' - 'crbug.com/1050754 external/wpt/cat.html [ Failure ]\n' - 'external/wpt/dog.html [ Crash Timeout ]\n' - 'crbug.com/6789043 external/wpt/van.html [ Failure ]\n' - '\n' - '# This comment will not be deleted\n' - 'crbug.com/111111 external/wpt/hello_world.html [ Crash ]\n') - - def _setup_host(self): - """Returns a mock host with fake values set up for testing.""" - self.set_logging_level(logging.DEBUG) - host = MockHost() - host.port_factory = MockPortFactory(host) - - # Set up a fake list of try builders. - host.builders = BuilderList({ - 'MOCK Try Precise': { - 'port_name': 'test-linux-precise', - 'specifiers': ['Precise', 'Release'], - 'is_try_builder': True, - }, - 'MOCK Android Weblayer - Pie': { - 'port_name': 'test-android-pie', - 'specifiers': ['Precise', 'Release', - 'anDroid', 'android_Weblayer'], - 'is_try_builder': True, - }, - 'MOCK Android Pie': { - 'port_name': 'test-android-pie', - 'specifiers': ['Precise', 'Release', 'anDroid', - 'Android_Webview', 'Chrome_Android'], - 'is_try_builder': True, - }, - }) - # Write dummy expectations - for path in PRODUCTS_TO_EXPECTATION_FILE_PATHS.values(): - host.filesystem.write_text_file( - path, self._raw_android_expectations) - return host - - def testUpdateTestExpectationsForWebview(self): - host = self._setup_host() - host.results_fetcher.set_results( - Build('MOCK Android Pie', 123), - WebTestResults({ - 'tests': { - 'abc.html': { - 'expected': 'PASS', - 'actual': 'CRASH TIMEOUT', - 'is_unexpected': True, - }, - 'jkl.html': { - 'expected': 'PASS', - 'actual': 'FAIL', - 'is_unexpected': True, - }, - 'cat.html': { - 'expected': 'PASS', - 'actual': 'CRASH CRASH TIMEOUT', - 'is_unexpected': True, - }, - }, - }, step_name='system_webview_wpt (with patch)'), - step_name='system_webview_wpt (with patch)') - updater = AndroidWPTExpectationsUpdater( - host, ['-vvv', '--android-product', 'android_webview']) - updater.git_cl = MockGitCL(host, { - Build('MOCK Android Pie', 123): - TryJobStatus('COMPLETED', 'FAILURE')}) - # Run command - updater.run() - # Get new expectations - content = host.filesystem.read_text_file( - PRODUCTS_TO_EXPECTATION_FILE_PATHS['android_webview']) - self.assertEqual( - content, - ('# results: [ Failure Crash Timeout]\n' - '\n' - '# Add untriaged failures in this block\n' - 'crbug.com/1050754 external/wpt/abc.html [ Crash Failure Timeout ]\n' - 'crbug.com/1050754 external/wpt/cat.html [ Crash Failure Timeout ]\n' - 'crbug.com/1050754 external/wpt/def.html [ Crash ]\n' - 'external/wpt/dog.html [ Crash Timeout ]\n' - 'crbug.com/1050754 external/wpt/ghi.html [ Timeout ]\n' - 'crbug.com/1111111 crbug.com/1050754' - ' external/wpt/jkl.html [ Failure ]\n' - 'crbug.com/6789043 external/wpt/van.html [ Failure ]\n' - 'external/wpt/www.html [ Crash Failure ]\n' - '\n' - '# This comment will not be deleted\n' - 'crbug.com/111111 external/wpt/hello_world.html [ Crash ]\n')) - # check that chrome android's expectation file was not modified - # since the same bot is used to update chrome android & webview - # expectations - self.assertEqual( - host.filesystem.read_text_file( - PRODUCTS_TO_EXPECTATION_FILE_PATHS['chrome_android']), - self._raw_android_expectations) - # Check logs - logs = ''.join(self.logMessages()).lower() - self.assertNotIn('weblayer', logs) - self.assertNotIn('chrome', logs) - - def testUpdateTestExpectationsForWeblayer(self): - host = self._setup_host() - host.results_fetcher.set_results( - Build('MOCK Android Weblayer - Pie', 123), - WebTestResults({ - 'tests': { - 'abc.html': { - 'expected': 'PASS', - 'actual': 'CRASH TIMEOUT', - 'is_unexpected': True, - }, - 'jkl.html': { - 'expected': 'PASS', - 'actual': 'FAIL', - 'is_unexpected': True, - }, - 'cat.html': { - 'expected': 'PASS', - 'actual': 'CRASH CRASH TIMEOUT', - 'is_unexpected': True, - }, - 'new.html': { - 'expected': 'PASS', - 'actual': 'CRASH CRASH FAIL', - 'is_unexpected': True, - }, - }, - }, step_name='weblayer_shell_wpt (with patch)'), - step_name='weblayer_shell_wpt (with patch)') - updater = AndroidWPTExpectationsUpdater( - host, ['-vvv', '--android-product', 'android_weblayer']) - updater.git_cl = MockGitCL(host, { - Build('MOCK Android Weblayer - Pie', 123): - TryJobStatus('COMPLETED', 'FAILURE')}) - # Run command - updater.run() - # Get new expectations - content = host.filesystem.read_text_file( - PRODUCTS_TO_EXPECTATION_FILE_PATHS['android_weblayer']) - self.assertEqual( - content, - ('# results: [ Failure Crash Timeout]\n' - '\n' - '# Add untriaged failures in this block\n' - 'crbug.com/1050754 external/wpt/abc.html [ Crash Failure Timeout ]\n' - 'crbug.com/1050754 external/wpt/cat.html [ Crash Failure Timeout ]\n' - 'crbug.com/1050754 external/wpt/def.html [ Crash ]\n' - 'external/wpt/dog.html [ Crash Timeout ]\n' - 'crbug.com/1050754 external/wpt/ghi.html [ Timeout ]\n' - 'crbug.com/1111111 crbug.com/1050754' - ' external/wpt/jkl.html [ Failure ]\n' - 'crbug.com/1050754 external/wpt/new.html [ Failure Crash ]\n' - 'crbug.com/6789043 external/wpt/van.html [ Failure ]\n' - 'external/wpt/www.html [ Crash Failure ]\n' - '\n' - '# This comment will not be deleted\n' - 'crbug.com/111111 external/wpt/hello_world.html [ Crash ]\n')) - # Check logs - logs = ''.join(self.logMessages()).lower() - self.assertNotIn('webview', logs) - self.assertNotIn('chrome', logs) - - def testUpdateTestExpectationsForAll(self): - host = self._setup_host() - # Add results for Weblayer - host.results_fetcher.set_results( - Build('MOCK Android Weblayer - Pie', 123), - WebTestResults({ - 'tests': { - 'abc.html': { - 'expected': 'PASS', - 'actual': 'CRASH TIMEOUT', - 'is_unexpected': True, - }, - 'weblayer_only.html': { - 'expected': 'PASS', - 'actual': 'CRASH CRASH FAIL', - 'is_unexpected': True, - }, - }, - }, step_name='weblayer_shell_wpt (with patch)'), - step_name='weblayer_shell_wpt (with patch)') - # Add Results for Webview - host.results_fetcher.set_results( - Build('MOCK Android Pie', 101), - WebTestResults({ - 'tests': { - 'cat.html': { - 'expected': 'PASS', - 'actual': 'CRASH FAIL TIMEOUT', - 'is_unexpected': True, - }, - 'webview_only.html': { - 'expected': 'PASS', - 'actual': 'TIMEOUT', - 'is_unexpected': True, - }, - }, - }, step_name='system_webview_wpt (with patch)'), - step_name='system_webview_wpt (with patch)') - # Add Results for Chrome - host.results_fetcher.set_results( - Build('MOCK Android Pie', 101), - WebTestResults({ - 'tests': { - 'jkl.html': { - 'expected': 'PASS', - 'actual': 'FAIL', - 'is_unexpected': True, - }, - 'chrome_only.html': { - 'expected': 'PASS', - 'actual': 'CRASH CRASH TIMEOUT', - 'is_unexpected': True, - }, - }, - }, step_name='chrome_public_wpt (with patch)'), - step_name='chrome_public_wpt (with patch)') - updater = AndroidWPTExpectationsUpdater( - host, ['-vvv', - '--android-product', 'android_weblayer', - '--android-product', 'chrome_android', - '--android-product', 'android_webview']) - updater.git_cl = MockGitCL(host, { - Build('MOCK Android Weblayer - Pie', 123): - TryJobStatus('COMPLETED', 'FAILURE'), - Build('MOCK Android Pie', 101): - TryJobStatus('COMPLETED', 'FAILURE')}) - # Run command - updater.run() - # Check expectations for weblayer - content = host.filesystem.read_text_file( - PRODUCTS_TO_EXPECTATION_FILE_PATHS['android_weblayer']) - self.assertEqual( - content, - ('# results: [ Failure Crash Timeout]\n' - '\n' - '# Add untriaged failures in this block\n' - 'crbug.com/1050754 external/wpt/abc.html [ Crash Failure Timeout ]\n' - 'crbug.com/1050754 external/wpt/cat.html [ Failure ]\n' - 'crbug.com/1050754 external/wpt/def.html [ Crash ]\n' - 'external/wpt/dog.html [ Crash Timeout ]\n' - 'crbug.com/1050754 external/wpt/ghi.html [ Timeout ]\n' - 'crbug.com/1111111 external/wpt/jkl.html [ Failure ]\n' - 'crbug.com/6789043 external/wpt/van.html [ Failure ]\n' - 'crbug.com/1050754 external/wpt/weblayer_only.html [ Failure Crash ]\n' - 'external/wpt/www.html [ Crash Failure ]\n' - '\n' - '# This comment will not be deleted\n' - 'crbug.com/111111 external/wpt/hello_world.html [ Crash ]\n')) - # Check expectations for webview - content = host.filesystem.read_text_file( - PRODUCTS_TO_EXPECTATION_FILE_PATHS['android_webview']) - self.assertEqual( - content, - ('# results: [ Failure Crash Timeout]\n' - '\n' - '# Add untriaged failures in this block\n' - 'external/wpt/abc.html [ Failure ]\n' - 'crbug.com/1050754 external/wpt/cat.html [ Crash Failure Timeout ]\n' - 'crbug.com/1050754 external/wpt/def.html [ Crash ]\n' - 'external/wpt/dog.html [ Crash Timeout ]\n' - 'crbug.com/1050754 external/wpt/ghi.html [ Timeout ]\n' - 'crbug.com/1111111 external/wpt/jkl.html [ Failure ]\n' - 'crbug.com/6789043 external/wpt/van.html [ Failure ]\n' - 'crbug.com/1050754 external/wpt/webview_only.html [ Timeout ]\n' - 'external/wpt/www.html [ Crash Failure ]\n' - '\n' - '# This comment will not be deleted\n' - 'crbug.com/111111 external/wpt/hello_world.html [ Crash ]\n')) - # Check expectations chrome - content = host.filesystem.read_text_file( - PRODUCTS_TO_EXPECTATION_FILE_PATHS['chrome_android']) - self.assertEqual( - content, - ('# results: [ Failure Crash Timeout]\n' - '\n' - '# Add untriaged failures in this block\n' - 'external/wpt/abc.html [ Failure ]\n' - 'crbug.com/1050754 external/wpt/cat.html [ Failure ]\n' - 'crbug.com/1050754 external/wpt/chrome_only.html [ Crash Timeout ]\n' - 'crbug.com/1050754 external/wpt/def.html [ Crash ]\n' - 'external/wpt/dog.html [ Crash Timeout ]\n' - 'crbug.com/1050754 external/wpt/ghi.html [ Timeout ]\n' - 'crbug.com/1111111 crbug.com/1050754' - ' external/wpt/jkl.html [ Failure ]\n' - 'crbug.com/6789043 external/wpt/van.html [ Failure ]\n' - 'external/wpt/www.html [ Crash Failure ]\n' - '\n' - '# This comment will not be deleted\n' - 'crbug.com/111111 external/wpt/hello_world.html [ Crash ]\n'))
diff --git a/third_party/blink/tools/blinkpy/w3c/import_notifier.py b/third_party/blink/tools/blinkpy/w3c/import_notifier.py index 2496eb8..183dadf7 100644 --- a/third_party/blink/tools/blinkpy/w3c/import_notifier.py +++ b/third_party/blink/tools/blinkpy/w3c/import_notifier.py
@@ -20,13 +20,14 @@ from blinkpy.w3c.common import WPT_GH_URL from blinkpy.w3c.directory_owners_extractor import DirectoryOwnersExtractor from blinkpy.w3c.monorail import MonorailAPI, MonorailIssue -from blinkpy.w3c.wpt_expectations_updater import WPTExpectationsUpdater +from blinkpy.w3c.wpt_expectations_updater import UMBRELLA_BUG _log = logging.getLogger(__name__) GITHUB_COMMIT_PREFIX = WPT_GH_URL + 'commit/' SHORT_GERRIT_PREFIX = 'https://crrev.com/c/' + class ImportNotifier(object): def __init__(self, host, chromium_git, local_wpt): self.host = host @@ -354,6 +355,6 @@ assert self.failure_type == self.NEW_EXPECTATION # TODO(robertma): Are there saner ways to remove the link to the umbrella bug? line = self.expectation_line - if line.startswith(WPTExpectationsUpdater.UMBRELLA_BUG): - line = line[len(WPTExpectationsUpdater.UMBRELLA_BUG):].lstrip() + if line.startswith(UMBRELLA_BUG): + line = line[len(UMBRELLA_BUG):].lstrip() return line
diff --git a/third_party/blink/tools/blinkpy/w3c/import_notifier_unittest.py b/third_party/blink/tools/blinkpy/w3c/import_notifier_unittest.py index 4612f67..18a9ee9 100644 --- a/third_party/blink/tools/blinkpy/w3c/import_notifier_unittest.py +++ b/third_party/blink/tools/blinkpy/w3c/import_notifier_unittest.py
@@ -12,10 +12,8 @@ from blinkpy.common.system.filesystem_mock import MockFileSystem from blinkpy.w3c.local_wpt_mock import MockLocalWPT from blinkpy.w3c.import_notifier import ImportNotifier, TestFailure -from blinkpy.w3c.wpt_expectations_updater import WPTExpectationsUpdater +from blinkpy.w3c.wpt_expectations_updater import UMBRELLA_BUG - -UMBRELLA_BUG = WPTExpectationsUpdater.UMBRELLA_BUG MOCK_WEB_TESTS = '/mock-checkout/' + RELATIVE_WEB_TESTS
diff --git a/third_party/blink/tools/blinkpy/w3c/test_importer.py b/third_party/blink/tools/blinkpy/w3c/test_importer.py index 034b678..5010b58d 100644 --- a/third_party/blink/tools/blinkpy/w3c/test_importer.py +++ b/third_party/blink/tools/blinkpy/w3c/test_importer.py
@@ -282,8 +282,7 @@ def blink_try_bots(self): """Returns the collection of builders used for updating expectations.""" - return self.host.builders.filter_builders( - is_try=True, exclude_specifiers={'android'}) + return self.host.builders.all_try_builder_names() def parse_args(self, argv): parser = argparse.ArgumentParser()
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater.py b/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater.py index ab5250a..dce09b8 100644 --- a/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater.py +++ b/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater.py
@@ -18,50 +18,31 @@ from blinkpy.common.path_finder import PathFinder from blinkpy.common.system.executive import ScriptError from blinkpy.common.system.log_utils import configure_logging -from blinkpy.web_tests.port.android import PRODUCTS _log = logging.getLogger(__name__) +MARKER_COMMENT = '# ====== New tests from wpt-importer added here ======' +UMBRELLA_BUG = 'crbug.com/626703' # TODO(robertma): Investigate reusing web_tests.models.test_expectations and # alike in this module. -SimpleTestResult = namedtuple('SimpleTestResult', ['expected', 'actual', 'bug']) - -DesktopConfig = namedtuple('DesktopConfig', ['port_name']) +SimpleTestResult = namedtuple('SimpleTestResult', + ['expected', 'actual', 'bug']) class WPTExpectationsUpdater(object): - MARKER_COMMENT = '# ====== New tests from wpt-importer added here ======' - UMBRELLA_BUG = 'crbug.com/626703' - - def __init__(self, host, args=None): + def __init__(self, host): self.host = host self.port = self.host.port_factory.get() self.git_cl = GitCL(host) self.finder = PathFinder(self.host.filesystem) - self.configs_with_no_results = [] - self.configs_with_all_pass = [] + self.ports_with_no_results = set() + self.ports_with_all_pass = set() self.patchset = None - # Get options from command line arguments. + def run(self, args=None): parser = argparse.ArgumentParser(description=__doc__) - self.add_arguments(parser) - self.options = parser.parse_args(args or []) - - def run(self): - """Does required setup before calling update_expectations(). - Do not override this function! - """ - log_level = logging.DEBUG if self.options.verbose else logging.INFO - configure_logging(logging_level=log_level, include_time=True) - - self.patchset = self.options.patchset - self.update_expectations() - - return 0 - - def add_arguments(self, parser): parser.add_argument( '--patchset', default=None, @@ -71,14 +52,15 @@ '--verbose', action='store_true', help='More verbose logging.') - # TODO(rmhasan): Move this argument to the - # AndroidWPTExpectationsUpdater add_arguments implementation. - # Also look into using sub parsers to separate android and - # desktop specific arguments. - parser.add_argument( - '--android-product', action='append', default=[], - help='Android products whose baselines will be updated.', - choices=PRODUCTS) + args = parser.parse_args(args) + + log_level = logging.DEBUG if args.verbose else logging.INFO + configure_logging(logging_level=log_level, include_time=True) + + self.patchset = args.patchset + self.update_expectations() + + return 0 def update_expectations(self): """Downloads text new baselines and adds test expectations lines. @@ -101,21 +83,11 @@ test_expectations = {} for build, job_status in build_to_status.iteritems(): if job_status.result == 'SUCCESS': - self.configs_with_all_pass.extend( - self.get_builder_configs(build)) - continue - result_dicts = self.get_failing_results_dicts(build) - for result_dict in result_dicts: - test_expectations = self.merge_dicts( - test_expectations, result_dict) + self.ports_with_all_pass.add(self.port_name(build)) + port_results = self.get_failing_results_dict(build) + test_expectations = self.merge_dicts(test_expectations, + port_results) - # At this point, test_expectations looks like: { - # 'test-with-failing-result': { - # config1: SimpleTestResult, - # config2: SimpleTestResult, - # config3: AnotherSimpleTestResult - # } - # } # And then we merge results for different platforms that had the same results. for test_name, platform_result in test_expectations.iteritems(): # platform_result is a dict mapping platforms to results. @@ -124,15 +96,16 @@ # At this point, test_expectations looks like: { # 'test-with-failing-result': { - # (config1, config2): SimpleTestResult, - # (config3,): AnotherSimpleTestResult + # ('port-name1', 'port-name2'): SimpleTestResult, + # 'port-name3': AnotherSimpleTestResult # } # } rebaselined_tests, test_expectations = self.download_text_baselines( test_expectations) - self.write_to_test_expectations(test_expectations) - return rebaselined_tests, test_expectations + test_expectation_lines = self.create_line_dict(test_expectations) + self.write_to_test_expectations(test_expectation_lines) + return rebaselined_tests, test_expectation_lines def get_issue_number(self): """Returns current CL number. Can be replaced in unit tests.""" @@ -143,8 +116,8 @@ return self.git_cl.latest_try_jobs( builder_names=self._get_try_bots(), patchset=self.patchset) - def get_failing_results_dicts(self, build): - """Returns a list of nested dicts of failing test results. + def get_failing_results_dict(self, build): + """Returns a nested dict of failing test results. Retrieves a full list of web test results from a builder result URL. Collects the builder name, platform and a list of tests that did not @@ -154,125 +127,80 @@ build: A Build object. Returns: - A list of dictionaries that have the following structure. - - { + A dictionary with the structure: { 'test-with-failing-result': { - config: SimpleTestResult + 'full-port-name': SimpleTestResult } } - If results could be fetched but none are failing, - this will return an empty list. + this will return an empty dictionary. """ + port_name = self.port_name(build) + if port_name in self.ports_with_all_pass: + # All tests passed, so there should be no failing results. + return {} - test_results_list = self._get_web_test_results(build) - + test_result_list = [self.host.results_fetcher.fetch_results(build)] has_webdriver_tests = self.host.builders.has_webdriver_tests_for_builder( build.builder_name) - if has_webdriver_tests: master = self.host.builders.master_for_builder(build.builder_name) - test_results_list.append( + test_result_list.append( self.host.results_fetcher.fetch_webdriver_test_results( build, master)) - test_results_list = filter(None, test_results_list) - if not test_results_list: + test_result_list = filter(None, test_result_list) + if not test_result_list: _log.warning('No results for build %s', build) - self.configs_with_no_results.extend(self.get_builder_configs(build)) - return [] + self.ports_with_no_results.add(self.port_name(build)) + return {} failing_test_results = [] - for results_set in test_results_list: - results_dict = self.generate_failing_results_dict( - build, results_set) - if results_dict: - failing_test_results.append(results_dict) - return failing_test_results + for test_result in test_result_list: + failing_test_results += [ + result + for result in test_result.didnt_run_as_expected_results() + if not result.did_pass() + ] - def _get_web_test_results(self, build): - """Gets web tests results for a builder. - - Args: - build: Named tuple containing builder name and number - - Returns: - List of web tests results for each web test step - in build. - """ - return [self.host.results_fetcher.fetch_results(build)] - - def get_builder_configs(self, build, *_): - return [DesktopConfig(port_name=self.port_name(build))] + return self.generate_results_dict( + self.port_name(build), failing_test_results) @memoized def port_name(self, build): return self.host.builders.port_name_for_builder_name( build.builder_name) - def generate_failing_results_dict(self, build, web_test_results): + def generate_results_dict(self, full_port_name, web_test_results): """Makes a dict with results for one platform. Args: - builder: Builder instance containing builder information.. + full_port_name: The fully-qualified port name, e.g. "win-win10". web_test_results: A list of WebTestResult objects. Returns: A dictionary with the structure: { 'test-name': { - ('full-port-name',): SimpleTestResult + 'full-port-name': SimpleTestResult } } """ test_dict = {} - configs = self.get_builder_configs(build, web_test_results) - _log.debug('Getting failing results dictionary' - ' for %s step in latest %s build' % ( - web_test_results.step_name(), build.builder_name)) - - if len(configs) > 1: - raise ScriptError('More than one configs were produced for' - ' builder and web tests step combination') - if not configs: - raise ScriptError('No configuration was found for builder and web test' - ' step combination ') - config = configs[0] - if config in self.configs_with_all_pass: - return {} - - for result in web_test_results.didnt_run_as_expected_results(): - # TODO(rmhasan) If a test fails unexpectedly then it runs multiple - # times until, it passes or a retry limit is reached. Even though - # it passed we there are still flaky failures that we are not - # creating test expectations for. Maybe we should add a mode - # which creates expectations for tests that are flaky but still - # pass in a web test step. - if result.did_pass(): - continue - + for result in web_test_results: test_name = result.test_name() - if not self._is_wpt_test(test_name): + + if not self.port.is_wpt_test(test_name): continue + test_dict[test_name] = { - config: + full_port_name: SimpleTestResult( expected=result.expected_results(), actual=result.actual_results(), - bug=self.UMBRELLA_BUG) + bug=UMBRELLA_BUG) } return test_dict - def _is_wpt_test(self, test_name): - """In blink web tests results, each test name is relative to - the web_tests directory instead of the wpt directory. We - need to use the port.is_wpt_test() function to find out if a test - is from the WPT suite. - - Returns: True if a test is in the external/wpt subdirectory of - the web_tests directory.""" - return self.port.is_wpt_test(test_name) - def merge_dicts(self, target, source, path=None): """Recursively merges nested dictionaries. @@ -328,7 +256,7 @@ current_key = keys[0] found_match = False if current_key == keys[-1]: - merged_dict[tuple([current_key])] = dictionary[current_key] + merged_dict[current_key] = dictionary[current_key] keys.remove(current_key) break @@ -339,13 +267,13 @@ if next_item == keys[-1]: if found_match: - merged_dict[ - tuple(matching_value_keys)] = dictionary[current_key] + merged_dict[tuple( + matching_value_keys)] = dictionary[current_key] keys = [ k for k in keys if k not in matching_value_keys ] else: - merged_dict[tuple([current_key])] = dictionary[current_key] + merged_dict[current_key] = dictionary[current_key] keys.remove(current_key) matching_value_keys = set() return merged_dict @@ -400,8 +328,8 @@ merged_results: A dictionary with the format: { 'test-with-failing-result': { - (config1, config2): SimpleTestResult, - (config3,): SimpleTestResult + ('port-name1', 'port-name2'): SimpleTestResult, + 'port-name3': SimpleTestResult } } @@ -410,23 +338,23 @@ (each SimpleTestResult turns into a line). """ line_dict = defaultdict(list) - for test_name, test_results in sorted(merged_results.iteritems()): - if not self._is_wpt_test(test_name): + for test_name, port_results in sorted(merged_results.iteritems()): + if not self.port.is_wpt_test(test_name): _log.warning( 'Non-WPT test "%s" unexpectedly passed to create_line_dict.', test_name) continue - for configs, result in sorted(test_results.iteritems()): + for port_names, result in sorted(port_results.iteritems()): line_dict[test_name].extend( - self._create_lines(test_name, configs, result)) + self._create_lines(test_name, port_names, result)) return line_dict - def _create_lines(self, test_name, configs, result): + def _create_lines(self, test_name, port_names, result): """Constructs test expectation line strings. Args: test_name: The test name string. - configs: A list of full configs that the line should apply to. + port_names: A list of full port names that the line should apply to. result: A SimpleTestResult. Returns: @@ -434,20 +362,22 @@ |test_name|. """ lines = [] + port_names = self.tuple_or_value_to_list(port_names) + # The set of ports with no results is assumed to have have no # overlap with the set of port names passed in here. - assert set(configs) & set(self.configs_with_no_results) == set() + assert (set(port_names) & self.ports_with_no_results) == set() # The ports with no results are generally ports of builders that # failed, maybe for unrelated reasons. At this point, we add ports # with no results to the list of platforms because we're guessing # that this new expectation might be cross-platform and should # also apply to any ports that we weren't able to get results for. - configs = tuple(list(configs) + self.configs_with_no_results) + port_names.extend(self.ports_with_no_results) expectations = '[ %s ]' % \ ' '.join(self.get_expectations(result, test_name)) - for specifier in self.normalized_specifiers(test_name, configs): + for specifier in self.normalized_specifiers(test_name, port_names): line_parts = [] if specifier: line_parts.append('[ %s ]' % specifier) @@ -456,28 +386,27 @@ line_parts.append(expectations) # Only add the bug link if the expectations do not include WontFix. - if 'WontFix' not in expectations and result.bug: + if 'WontFix' not in expectations: line_parts.insert(0, result.bug) lines.append(' '.join(line_parts)) return lines - def normalized_specifiers(self, test_name, configs): + def normalized_specifiers(self, test_name, port_names): """Converts and simplifies ports into platform specifiers. Args: test_name: The test name string. - configs: A list of full configs that the line should apply to. + port_names: A list of full port names that the line should apply to. Returns: A list of specifier string, e.g. ["Mac", "Win"]. [''] will be returned if the line should apply to all platforms. """ specifiers = [] - for config in configs: + for name in sorted(port_names): specifiers.append( - self.host.builders.version_specifier_for_port_name( - config.port_name)) + self.host.builders.version_specifier_for_port_name(name)) if self.specifiers_can_extend_to_all_platforms(specifiers, test_name): return [''] @@ -488,6 +417,13 @@ return [''] return specifiers + @staticmethod + def tuple_or_value_to_list(tuple_or_value): + """Converts a tuple to a list, and a string value to a one-item list.""" + if isinstance(tuple_or_value, tuple): + return list(tuple_or_value) + return [tuple_or_value] + def specifiers_can_extend_to_all_platforms(self, specifiers, test_name): """Tests whether a list of specifiers can be extended to all platforms. @@ -564,7 +500,7 @@ builder_name).lower()) return frozenset(all_platform_specifiers) - def write_to_test_expectations(self, test_expectations): + def write_to_test_expectations(self, line_dict): """Writes the given lines to the TestExpectations file. The place in the file where the new lines are inserted is after a marker @@ -575,14 +511,11 @@ file. Args: - test_expectations: A dictionary mapping test names to a dictionary - mapping platforms and test results. + line_dict: A dictionary from test names to a list of test expectation lines. """ - line_dict = self.create_line_dict(test_expectations) if not line_dict: _log.info( - 'No lines to write to TestExpectations,' - ' WebdriverExpectations or NeverFixTests.' + 'No lines to write to TestExpectations, WebdriverExpectations or NeverFixTests.' ) return @@ -612,9 +545,9 @@ file_contents = self.host.filesystem.read_text_file( expectations_file_path) - marker_comment_index = file_contents.find(self.MARKER_COMMENT) + marker_comment_index = file_contents.find(MARKER_COMMENT) if marker_comment_index == -1: - file_contents += '\n%s\n' % self.MARKER_COMMENT + file_contents += '\n%s\n' % MARKER_COMMENT file_contents += '\n'.join(lines) else: end_of_marker_line = (file_contents[marker_comment_index:]. @@ -730,7 +663,5 @@ """Checks whether a given test is a WebDriver test.""" return self.finder.is_webdriver_test_path(test_name) - @memoized def _get_try_bots(self): - return self.host.builders.filter_builders( - is_try=True, exclude_specifiers={'android'}) + return self.host.builders.all_try_builder_names()
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater_unittest.py b/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater_unittest.py index efd64b8..80ed262 100644 --- a/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater_unittest.py +++ b/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater_unittest.py
@@ -9,16 +9,12 @@ from blinkpy.common.net.git_cl import TryJobStatus from blinkpy.common.net.git_cl_mock import MockGitCL from blinkpy.common.net.results_fetcher import Build -from blinkpy.common.net.results_fetcher_mock import ( - MockTestResultsFetcher, BuilderStep) +from blinkpy.common.net.results_fetcher_mock import MockTestResultsFetcher from blinkpy.common.net.web_test_results import WebTestResult, WebTestResults from blinkpy.common.system.executive import ScriptError from blinkpy.common.system.log_testing import LoggingTestCase - -from blinkpy.w3c.wpt_expectations_updater import ( - WPTExpectationsUpdater, SimpleTestResult, DesktopConfig) +from blinkpy.w3c.wpt_expectations_updater import WPTExpectationsUpdater, SimpleTestResult, MARKER_COMMENT from blinkpy.w3c.wpt_manifest import BASE_MANIFEST_NAME - from blinkpy.web_tests.builder_list import BuilderList from blinkpy.web_tests.port.factory_mock import MockPortFactory @@ -97,7 +93,7 @@ expectations_path = \ host.port_factory.get().path_to_generic_test_expectations_file() host.filesystem.write_text_file(expectations_path, - WPTExpectationsUpdater.MARKER_COMMENT + '\n') + MARKER_COMMENT + '\n') # Set up fake try job results. updater = WPTExpectationsUpdater(host) @@ -138,12 +134,11 @@ } } })) - self.assertEqual(0, updater.run()) + self.assertEqual(0, updater.run(args=[])) # Results are only fetched for failing builds. self.assertEqual(host.results_fetcher.fetched_builds, - [BuilderStep(Build('MOCK Try Mac10.10', 333), - 'blink_web_tests (with patch)')]) + [Build('MOCK Try Mac10.10', 333)]) self.assertEqual( host.filesystem.read_text_file(expectations_path), @@ -170,8 +165,9 @@ }, })) updater = WPTExpectationsUpdater(host) - self.assertFalse( - updater.get_failing_results_dicts(Build('MOCK Try Mac10.10', 123))) + self.assertEqual( + updater.get_failing_results_dict(Build('MOCK Try Mac10.10', 123)), + {}) def test_get_failing_results_dict_unexpected_pass(self): host = self.mock_host() @@ -193,16 +189,18 @@ }, })) updater = WPTExpectationsUpdater(host) - self.assertFalse( - updater.get_failing_results_dicts(Build('MOCK Try Mac10.10', 123))) + self.assertEqual( + updater.get_failing_results_dict(Build('MOCK Try Mac10.10', 123)), + {}) def test_get_failing_results_dict_no_results(self): host = self.mock_host() host.results_fetcher = MockTestResultsFetcher() host.results_fetcher.set_results(Build('MOCK Try Mac10.10', 123), None) updater = WPTExpectationsUpdater(host) - self.assertFalse( - updater.get_failing_results_dicts(Build('MOCK Try Mac10.10', 123))) + self.assertEqual( + updater.get_failing_results_dict(Build('MOCK Try Mac10.10', 123)), + {}) def test_get_failing_results_dict_some_failing_results(self): host = self.mock_host() @@ -224,19 +222,19 @@ }, })) updater = WPTExpectationsUpdater(host) - results = updater.get_failing_results_dicts( + results_dict = updater.get_failing_results_dict( Build('MOCK Try Mac10.10', 123)) self.assertEqual( - results, [{ + results_dict, { 'external/wpt/x/failing-test.html': { - DesktopConfig(port_name='test-mac-mac10.10'): + 'test-mac-mac10.10': SimpleTestResult( actual='IMAGE', expected='PASS', bug='crbug.com/626703', ), }, - }]) + }) def test_get_failing_results_dict_non_wpt_test(self): host = self.mock_host() @@ -254,9 +252,9 @@ }, })) updater = WPTExpectationsUpdater(host) - results_dict = updater.get_failing_results_dicts( + results_dict = updater.get_failing_results_dict( Build('MOCK Try Mac10.10', 123)) - self.assertEqual(results_dict, []) + self.assertEqual(results_dict, {}) def test_get_failing_results_dict_webdriver_failing_results_(self): host = self.mock_host() @@ -296,28 +294,29 @@ }, })) updater = WPTExpectationsUpdater(host) - results = updater.get_failing_results_dicts( + results_dict = updater.get_failing_results_dict( Build('MOCK Try Trusty', 123)) - self.assertEqual(len(results), 2) + + self.assertEqual(len(results_dict.keys()), 2) self.assertEqual( - results, [{ + results_dict, { 'external/wpt/x/failing-test.html': { - DesktopConfig('test-linux-trusty'): + 'test-linux-trusty': SimpleTestResult( actual='IMAGE', expected='PASS', bug='crbug.com/626703', ), - }}, { + }, 'external/wpt/y/webdriver-fail.html': { - DesktopConfig('test-linux-trusty'): + 'test-linux-trusty': SimpleTestResult( actual='FAIL', expected='PASS', bug='crbug.com/626703', ), }, - }]) + }) def test_merge_same_valued_keys_all_match(self): updater = WPTExpectationsUpdater(self.mock_host()) @@ -357,7 +356,7 @@ 'expected': 'FAIL', 'actual': 'PASS' }, - ('two',): { + 'two': { 'expected': 'FAIL', 'actual': 'TIMEOUT' }, @@ -421,10 +420,10 @@ updater = WPTExpectationsUpdater(self.mock_host()) results = { 'fake/test/path.html': { - tuple([DesktopConfig(port_name='one')]): + 'one': SimpleTestResult( expected='FAIL', actual='PASS', bug='crbug.com/test'), - tuple([DesktopConfig(port_name='two')]): + 'two': SimpleTestResult( expected='FAIL', actual='PASS', bug='crbug.com/test'), } @@ -437,20 +436,20 @@ updater = WPTExpectationsUpdater(self.mock_host()) results = { 'external/wpt/test/zzzz.html': { - tuple([DesktopConfig(port_name='test-mac-mac10.10')]): + 'test-mac-mac10.10': SimpleTestResult( expected='PASS', actual='TEXT', bug='crbug.com/test'), }, 'virtual/foo/external/wpt/test/zzzz.html': { - tuple([DesktopConfig(port_name='test-linux-trusty')]): + 'test-linux-trusty': SimpleTestResult( expected='FAIL', actual='PASS', bug='crbug.com/test'), - tuple([DesktopConfig(port_name='test-mac-mac10.11')]): + 'test-mac-mac10.11': SimpleTestResult( expected='FAIL', actual='TIMEOUT', bug='crbug.com/test'), }, 'unrelated/test.html': { - tuple([DesktopConfig(port_name='test-linux-trusty')]): + 'test-linux-trusty': SimpleTestResult( expected='FAIL', actual='PASS', bug='crbug.com/test'), }, @@ -471,10 +470,10 @@ updater = WPTExpectationsUpdater(self.mock_host()) results = { 'virtual/foo/external/wpt/test/aa-manual.html': { - tuple([DesktopConfig(port_name='test-linux-trusty')]): + 'test-linux-trusty': SimpleTestResult( expected='PASS', actual='TIMEOUT', bug='crbug.com/test'), - tuple([DesktopConfig(port_name='test-mac-mac10.11')]): + 'test-mac-mac10.11': SimpleTestResult( expected='FAIL', actual='TIMEOUT', bug='crbug.com/test'), }, @@ -493,7 +492,7 @@ results = { 'external/wpt/html/dom/interfaces.https.html?exclude=(Document.*|HTML.*)': { - tuple([DesktopConfig(port_name='test-linux-trusty')]): + 'test-linux-trusty': SimpleTestResult( expected='PASS', actual='FAIL', bug='crbug.com/test'), }, @@ -509,14 +508,13 @@ def test_normalized_specifiers(self): updater = WPTExpectationsUpdater(self.mock_host()) self.assertEqual( - updater.normalized_specifiers('x/y.html', [DesktopConfig(port_name='test-mac-mac10.10')]), + updater.normalized_specifiers('x/y.html', ['test-mac-mac10.10']), ['Mac10.10']) self.assertEqual(updater.normalized_specifiers('x/y.html', []), ['']) self.assertEqual( updater.normalized_specifiers( - 'x/y.html', [DesktopConfig(port_name='test-mac-mac10.10'), - DesktopConfig(port_name='test-win-win7')]), + 'x/y.html', ['test-mac-mac10.10', 'test-win-win7']), ['Mac10.10', 'Win7']) def test_skipped_specifiers_when_test_is_skip(self): @@ -620,19 +618,15 @@ self.assertEqual( updater.normalized_specifiers( 'external/wpt/test.html', - [DesktopConfig(port_name='test-mac-mac10.10'), - DesktopConfig(port_name='test-win-win7'), - DesktopConfig(port_name='test-win-win10')]), + ['test-mac-mac10.10', 'test-win-win7', 'test-win-win10']), ['']) self.assertEqual( updater.normalized_specifiers('external/wpt/test.html', - [DesktopConfig(port_name='test-win-win7'), - DesktopConfig(port_name='test-win-win10')]), + ['test-win-win7', 'test-win-win10']), ['Win']) self.assertEqual( updater.normalized_specifiers('external/wpt/another.html', - [DesktopConfig('test-win-win7'), - DesktopConfig('test-win-win10')]), + ['test-win-win7', 'test-win-win10']), ['Win']) def test_merge_dicts_with_conflict_raise_exception(self): @@ -707,28 +701,22 @@ output = updater.merge_dicts(two, three) self.assertEqual(output, two) - def test_generate_failing_results_dict(self): + def test_generate_results_dict(self): updater = WPTExpectationsUpdater(self.mock_host()) - web_test_list = WebTestResults( - { - "tests": { - "external/wpt/test/name.html": { - "expected": "bar", - "actual": "foo", - "is_unexpected": True, - "has_stderr": True - } - } - }, - step_name='blink_web_tests (with patch)') - - updater.port_name = lambda b: b.builder_name + web_test_list = [ + WebTestResult( + 'external/wpt/test/name.html', { + 'expected': 'bar', + 'actual': 'foo', + 'is_unexpected': True, + 'has_stderr': True, + }) + ] self.assertEqual( - updater.generate_failing_results_dict( - Build(builder_name='test-mac-mac10.10', build_number=1), web_test_list), + updater.generate_results_dict('test-mac-mac10.10', web_test_list), { 'external/wpt/test/name.html': { - DesktopConfig(port_name='test-mac-mac10.10'): + 'test-mac-mac10.10': SimpleTestResult( expected='bar', actual='foo', @@ -742,20 +730,21 @@ expectations_path = \ host.port_factory.get().path_to_generic_test_expectations_file() host.filesystem.write_text_file(expectations_path, - WPTExpectationsUpdater.MARKER_COMMENT + '\n') + MARKER_COMMENT + '\n') updater = WPTExpectationsUpdater(host) - test_expectations = {'external/wpt/fake/file/path.html': { - tuple([DesktopConfig(port_name='test-linux-trusty')]): - SimpleTestResult(actual='PASS', expected='', bug='crbug.com/123')}} + line_dict = { + 'fake/file/path.html': + ['crbug.com/123 [ Trusty ] fake/file/path.html [ Pass ]'] + } skip_path = host.port_factory.get().path_to_never_fix_tests_file() skip_value_origin = host.filesystem.read_text_file(skip_path) - updater.write_to_test_expectations(test_expectations) + updater.write_to_test_expectations(line_dict) value = host.filesystem.read_text_file(expectations_path) self.assertMultiLineEqual( - value, (WPTExpectationsUpdater.MARKER_COMMENT + '\n' - 'crbug.com/123 [ Trusty ] external/wpt/fake/file/path.html [ Pass ]\n')) + value, (MARKER_COMMENT + '\n' + 'crbug.com/123 [ Trusty ] fake/file/path.html [ Pass ]\n')) skip_value = host.filesystem.read_text_file(skip_path) self.assertMultiLineEqual(skip_value, skip_value_origin) @@ -765,12 +754,13 @@ webdriver_expectations_path = \ host.port_factory.get().path_to_webdriver_expectations_file() host.filesystem.write_text_file(webdriver_expectations_path, - WPTExpectationsUpdater.MARKER_COMMENT + '\n') + MARKER_COMMENT + '\n') updater = WPTExpectationsUpdater(host) - - test_expectations = {'external/wpt/webdriver/fake/file/path.html': { - tuple([DesktopConfig(port_name='test-linux-trusty')]): - SimpleTestResult(actual='PASS', expected='', bug='crbug.com/123')}} + line_dict = { + 'external/wpt/webdriver/fake/file/path.html': [ + 'crbug.com/123 [ Trusty ] external/wpt/webdriver/fake/file/path.html [ Pass ]' + ] + } expectations_path = \ host.port_factory.get().path_to_generic_test_expectations_file() @@ -780,11 +770,11 @@ skip_path = host.port_factory.get().path_to_never_fix_tests_file() skip_value_origin = host.filesystem.read_text_file(skip_path) - updater.write_to_test_expectations(test_expectations) + updater.write_to_test_expectations(line_dict) value = host.filesystem.read_text_file(webdriver_expectations_path) self.assertMultiLineEqual(value, ( - WPTExpectationsUpdater.MARKER_COMMENT + '\n' + MARKER_COMMENT + '\n' 'crbug.com/123 [ Trusty ] external/wpt/webdriver/fake/file/path.html [ Pass ]\n' )) @@ -803,19 +793,20 @@ expectations_path, 'crbug.com/111 [ Trusty ] foo/bar.html [ Failure ]\n') updater = WPTExpectationsUpdater(host) - test_expectations = {'external/wpt/fake/file/path.html': { - tuple([DesktopConfig(port_name='test-linux-trusty')]): - SimpleTestResult(actual='PASS', expected='', bug='crbug.com/123')}} + line_dict = { + 'fake/file/path.html': + ['crbug.com/123 [ Trusty ] fake/file/path.html [ Pass ]'] + } skip_path = host.port_factory.get().path_to_never_fix_tests_file() skip_value_origin = host.filesystem.read_text_file(skip_path) - updater.write_to_test_expectations(test_expectations) + updater.write_to_test_expectations(line_dict) value = host.filesystem.read_text_file(expectations_path) self.assertMultiLineEqual( value, ('crbug.com/111 [ Trusty ] foo/bar.html [ Failure ]\n' - '\n' + WPTExpectationsUpdater.MARKER_COMMENT + '\n' - 'crbug.com/123 [ Trusty ] external/wpt/fake/file/path.html [ Pass ]')) + '\n' + MARKER_COMMENT + '\n' + 'crbug.com/123 [ Trusty ] fake/file/path.html [ Pass ]')) skip_value = host.filesystem.read_text_file(skip_path) self.assertMultiLineEqual(skip_value, skip_value_origin) @@ -824,7 +815,7 @@ expectations_path = \ host.port_factory.get().path_to_generic_test_expectations_file() host.filesystem.write_text_file( - expectations_path, WPTExpectationsUpdater.MARKER_COMMENT + '\n' + + expectations_path, MARKER_COMMENT + '\n' + 'crbug.com/123 [ Trusty ] fake/file/path.html [ Pass ]\n') skip_path = host.port_factory.get().path_to_never_fix_tests_file() skip_value_origin = host.filesystem.read_text_file(skip_path) @@ -834,7 +825,7 @@ value = host.filesystem.read_text_file(expectations_path) self.assertMultiLineEqual( - value, WPTExpectationsUpdater.MARKER_COMMENT + '\n' + + value, MARKER_COMMENT + '\n' + 'crbug.com/123 [ Trusty ] fake/file/path.html [ Pass ]\n') skip_value = host.filesystem.read_text_file(skip_path) self.assertMultiLineEqual(skip_value, skip_value_origin) @@ -844,47 +835,48 @@ expectations_path = \ host.port_factory.get().path_to_generic_test_expectations_file() skip_path = host.port_factory.get().path_to_never_fix_tests_file() - - test_expectations = {'external/wpt/fake/file/path-manual.html': { - tuple([DesktopConfig(port_name='test-linux-trusty')]): - SimpleTestResult(actual='TIMEOUT', expected={}, bug='')}} + line_dict = { + 'fake/file/path-manual.html': + ['[ Trusty ] fake/file/path-manual.html [ Skip ]'] + } host.filesystem.write_text_file(expectations_path, - WPTExpectationsUpdater.MARKER_COMMENT + '\n') + MARKER_COMMENT + '\n') host.filesystem.write_text_file( - skip_path, '[ Trusty ] external/wpt/fake/file/path-manual.html [ Skip ]\n') + skip_path, '[ Trusty ] fake/file/path-manual.html [ Skip ]\n') updater = WPTExpectationsUpdater(host) - updater.write_to_test_expectations(test_expectations) + updater.write_to_test_expectations(line_dict) expectations_value = host.filesystem.read_text_file(expectations_path) skip_value = host.filesystem.read_text_file(skip_path) - self.assertMultiLineEqual(expectations_value, WPTExpectationsUpdater.MARKER_COMMENT + '\n') + self.assertMultiLineEqual(expectations_value, MARKER_COMMENT + '\n') self.assertMultiLineEqual( - skip_value, '[ Trusty ] external/wpt/fake/file/path-manual.html [ Skip ]\n' - '[ Trusty ] external/wpt/fake/file/path-manual.html [ Skip ]\n') + skip_value, '[ Trusty ] fake/file/path-manual.html [ Skip ]\n' + '[ Trusty ] fake/file/path-manual.html [ Skip ]\n') def test_write_to_test_expectations_without_newline(self): host = self.mock_host() expectations_path = \ host.port_factory.get().path_to_generic_test_expectations_file() skip_path = host.port_factory.get().path_to_never_fix_tests_file() - test_expectations = {'external/wpt/fake/file/path-manual.html': { - tuple([DesktopConfig(port_name='test-linux-trusty')]): - SimpleTestResult(actual='TIMEOUT', expected={}, bug='')}} + line_dict = { + 'fake/file/path-manual.html': + ['[ Trusty ] fake/file/path-manual.html [ Skip ]'] + } host.filesystem.write_text_file(expectations_path, - WPTExpectationsUpdater.MARKER_COMMENT + '\n') + MARKER_COMMENT + '\n') host.filesystem.write_text_file( - skip_path, '[ Trusty ] external/wpt/fake/file/path-manual.html [ Skip ]') + skip_path, '[ Trusty ] fake/file/path-manual.html [ Skip ]') updater = WPTExpectationsUpdater(host) - updater.write_to_test_expectations(test_expectations) + updater.write_to_test_expectations(line_dict) expectations_value = host.filesystem.read_text_file(expectations_path) skip_value = host.filesystem.read_text_file(skip_path) - self.assertMultiLineEqual(expectations_value, WPTExpectationsUpdater.MARKER_COMMENT + '\n') + self.assertMultiLineEqual(expectations_value, MARKER_COMMENT + '\n') self.assertMultiLineEqual( - skip_value, '[ Trusty ] external/wpt/fake/file/path-manual.html [ Skip ]\n' - '[ Trusty ] external/wpt/fake/file/path-manual.html [ Skip ]\n') + skip_value, '[ Trusty ] fake/file/path-manual.html [ Skip ]\n' + '[ Trusty ] fake/file/path-manual.html [ Skip ]\n') def test_is_reference_test_given_testharness_test(self): updater = WPTExpectationsUpdater(self.mock_host()) @@ -1023,14 +1015,14 @@ updater = WPTExpectationsUpdater(self.mock_host()) updater.git_cl = MockGitCL(updater.host, issue_number='None') with self.assertRaises(ScriptError) as e: - updater.run() + updater.run(args=[]) self.assertEqual(e.exception.message, 'No issue on current branch.') def test_run_no_try_results(self): updater = WPTExpectationsUpdater(self.mock_host()) updater.git_cl = MockGitCL(updater.host, {}) with self.assertRaises(ScriptError) as e: - updater.run() + updater.run(args=[]) self.assertEqual(e.exception.message, 'No try job information was collected.') @@ -1040,12 +1032,12 @@ results = { 'external/wpt/x-manual.html': { ( - DesktopConfig('test-linux-precise'), - DesktopConfig('test-linux-trusty'), - DesktopConfig('test-mac-mac10.10'), - DesktopConfig('test-mac-mac10.11'), - DesktopConfig('test-win-win7'), - DesktopConfig('test-win-win10'), + 'test-linux-precise', + 'test-linux-trusty', + 'test-mac-mac10.10', + 'test-mac-mac10.11', + 'test-win-win7', + 'test-win-win10', ): SimpleTestResult( expected='PASS', actual='MISSING', bug='crbug.com/test') @@ -1069,16 +1061,15 @@ results = { 'external/wpt/x.html': { ( - DesktopConfig(port_name='test-linux-precise'), - DesktopConfig(port_name='test-linux-trusty'), - DesktopConfig(port_name='test-mac-mac10.11'), + 'test-linux-precise', + 'test-linux-trusty', + 'test-mac-mac10.11', ): SimpleTestResult( expected='PASS', actual='TEXT', bug='crbug.com/test') } } - updater.configs_with_no_results = [ - DesktopConfig(port_name='test-mac-mac10.10')] + updater.ports_with_no_results = {'test-mac-mac10.10'} self.assertEqual( updater.create_line_dict(results), { 'external/wpt/x.html': [ @@ -1093,11 +1084,11 @@ results = { 'external/wpt/x.html': { ( - DesktopConfig('test-linux-precise'), - DesktopConfig('test-linux-trusty'), - DesktopConfig('test-mac-mac10.10'), - DesktopConfig('test-mac-mac10.11'), - DesktopConfig('test-win-win7'), + 'test-linux-precise', + 'test-linux-trusty', + 'test-mac-mac10.10', + 'test-mac-mac10.11', + 'test-win-win7', ): SimpleTestResult( expected='PASS', actual='TEXT', bug='crbug.com/test')
diff --git a/third_party/blink/tools/blinkpy/web_tests/builder_list.py b/third_party/blink/tools/blinkpy/web_tests/builder_list.py index 56d3635..8128ca9 100644 --- a/third_party/blink/tools/blinkpy/web_tests/builder_list.py +++ b/third_party/blink/tools/blinkpy/web_tests/builder_list.py
@@ -42,10 +42,10 @@ The given dictionary maps builder names to dicts with the keys: "port_name": A fully qualified port name. - "specifiers": A list of specifiers used to describe a builder. - The specifiers list will at the very least have a valid - port version specifier like "Mac10.15" and and a valid build - type specifier like "Release". + "specifiers": A two-item list: [version specifier, build type specifier]. + Valid values for the version specifier can be found in + TestExpectationsParser._configuration_tokens_list, and valid + values for the build type specifier include "Release" and "Debug". "is_try_builder": Whether the builder is a trybot. "master": The master name of the builder. It is deprecated, but still required by test-results.appspot.com API." @@ -57,11 +57,8 @@ """ self._builders = builders_dict for builder in builders_dict: - specifiers = { - s.lower() for s in builders_dict[builder].get('specifiers', {})} assert 'port_name' in builders_dict[builder] - assert ('android' in specifiers or - len(builders_dict[builder]['specifiers']) == 2) + assert len(builders_dict[builder]['specifiers']) == 2 @staticmethod def load_default_builder_list(filesystem): @@ -75,29 +72,12 @@ return sorted(self._builders) def all_try_builder_names(self): - return self.filter_builders(is_try=True) + return sorted(b for b in self._builders + if self._builders[b].get('is_try_builder')) def all_continuous_builder_names(self): - return self.filter_builders(is_try=False) - - def filter_builders(self, exclude_specifiers=None, include_specifiers=None, - is_try=False): - _lower_specifiers = lambda specifiers: {s.lower() for s in specifiers} - exclude_specifiers = _lower_specifiers(exclude_specifiers or {}) - include_specifiers = _lower_specifiers(include_specifiers or {}) - builders = [] - for b in self._builders: - builder_specifiers = _lower_specifiers( - self._builders[b].get('specifiers', {})) - if self._builders[b].get('is_try_builder', False) != is_try: - continue - if builder_specifiers & exclude_specifiers: - continue - if (include_specifiers and - not include_specifiers & builder_specifiers): - continue - builders.append(b) - return sorted(builders) + return sorted(b for b in self._builders + if not self._builders[b].get('is_try_builder')) def all_port_names(self): return sorted({b['port_name'] for b in self._builders.values()})
diff --git a/third_party/blink/tools/blinkpy/web_tests/models/test_expectations.py b/third_party/blink/tools/blinkpy/web_tests/models/test_expectations.py index 3bebfe6..2d82253 100644 --- a/third_party/blink/tools/blinkpy/web_tests/models/test_expectations.py +++ b/third_party/blink/tools/blinkpy/web_tests/models/test_expectations.py
@@ -382,13 +382,11 @@ # test to be whatever the bot thinks they should be. Is this a # good thing? bot_expectations = self._port.bot_expectations() - if bot_expectations: - raw_expectations = ( - '# results: [ Failure Pass Crash Skip Timeout ]\n') - for test, results in bot_expectations.items(): - raw_expectations += typ_types.Expectation( - test=test, results=results).to_string() + '\n' - self.merge_raw_expectations(raw_expectations) + raw_expectations = '# results: [ Failure Pass Crash Skip Timeout ]\n' + for test, results in bot_expectations.items(): + raw_expectations += typ_types.Expectation( + test=test, results=results).to_string() + '\n' + self.merge_raw_expectations(raw_expectations) def remove_expectations(self, path, exps): """This method removes Expectation instances from an expectations file.
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/android.py b/third_party/blink/tools/blinkpy/web_tests/port/android.py index 29daffff..a5a6f6b 100644 --- a/third_party/blink/tools/blinkpy/web_tests/port/android.py +++ b/third_party/blink/tools/blinkpy/web_tests/port/android.py
@@ -38,7 +38,6 @@ from blinkpy.common import exit_codes from blinkpy.common.path_finder import RELATIVE_WEB_TESTS from blinkpy.common.path_finder import WEB_TESTS_LAST_COMPONENT -from blinkpy.common.path_finder import get_blink_dir from blinkpy.common.path_finder import get_chromium_src_dir from blinkpy.common.system.executive import ScriptError from blinkpy.common.system.profiler import SingleFileOutputProfiler @@ -64,37 +63,6 @@ perf_control = None # pylint: enable=invalid-name -# product constants used by the wpt runner. -ANDROID_WEBLAYER = 'android_weblayer' -ANDROID_WEBVIEW = 'android_webview' -CHROME_ANDROID = 'chrome_android' - -PRODUCTS = [ANDROID_WEBLAYER, ANDROID_WEBVIEW, CHROME_ANDROID] - -PRODUCTS_TO_STEPNAMES = { - ANDROID_WEBLAYER: 'weblayer_shell_wpt', - ANDROID_WEBVIEW: 'system_webview_wpt', - CHROME_ANDROID: 'chrome_public_wpt', -} - -PRODUCTS_TO_BROWSER_TAGS = { - ANDROID_WEBLAYER: 'weblayer', - ANDROID_WEBVIEW: 'webview', - CHROME_ANDROID: 'chrome', -} - -# Android web tests directory, which contains override expectation files -ANDROID_WEB_TESTS_DIR = os.path.join(get_blink_dir(), 'web_tests', 'android') - -PRODUCTS_TO_EXPECTATION_FILE_PATHS = { - ANDROID_WEBLAYER: os.path.join( - ANDROID_WEB_TESTS_DIR, 'WeblayerWPTOverrideExpectations'), - ANDROID_WEBVIEW: os.path.join( - ANDROID_WEB_TESTS_DIR, 'WebviewWPTOverrideExpectations'), - CHROME_ANDROID: os.path.join( - ANDROID_WEB_TESTS_DIR, 'ClankWPTOverrideExpectations'), -} - _friendly_browser_names = { 'weblayershell': 'weblayer', 'systemwebviewshell': 'webview', @@ -345,10 +313,6 @@ for serial in prepared_devices: self._devices.set_device_prepared(serial) - def bot_expectations(self): - # TODO(rmhasan) Add bot expectations to WPT metadata. - return {} - def get_platform_tags(self): _sanitize_tag = lambda t: t.replace('_', '-').replace(' ', '-') return frozenset(
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/android_unittest.py b/third_party/blink/tools/blinkpy/web_tests/port/android_unittest.py index 3ee10e20..37c584d 100644 --- a/third_party/blink/tools/blinkpy/web_tests/port/android_unittest.py +++ b/third_party/blink/tools/blinkpy/web_tests/port/android_unittest.py
@@ -40,7 +40,6 @@ from blinkpy.web_tests.port import android from blinkpy.web_tests.port import driver_unittest from blinkpy.web_tests.port import port_testcase -from blinkpy.web_tests.models.test_expectations import TestExpectations _DEVIL_ROOT = os.path.join(get_chromium_src_dir(), 'third_party', 'catapult', 'devil') @@ -122,14 +121,6 @@ self.assertEquals(6, port_default.default_child_processes()) self.assertEquals(1, port_fixed_device.default_child_processes()) - def test_no_bot_expectations_searched(self): - # We don't support bot expectations at the moment - host = MockSystemHost() - port = android.AndroidPort(host, apk='apks/WebLayerShell.apk') - port.expectations_dict = lambda: {} - test_expectations = TestExpectations(port) - self.assertFalse(test_expectations._expectations) - def test_weblayer_expectation_tags(self): host = MockSystemHost() port = android.AndroidPort(host, apk='apks/WebLayerShell.apk')
diff --git a/third_party/blink/tools/wpt_update_expectations.py b/third_party/blink/tools/wpt_update_expectations.py index 48231ac6..b21dbce 100755 --- a/third_party/blink/tools/wpt_update_expectations.py +++ b/third_party/blink/tools/wpt_update_expectations.py
@@ -5,25 +5,9 @@ import sys -from blinkpy.common.host import Host +from blinkpy.common import host from blinkpy.w3c.wpt_expectations_updater import WPTExpectationsUpdater -from blinkpy.w3c.android_wpt_expectations_updater import ( - AndroidWPTExpectationsUpdater) - -def get_updater(host=None, args=None): - host = host or Host() - if any(arg.startswith('--android-product') for arg in args or []): - return AndroidWPTExpectationsUpdater(host, args) - else: - return WPTExpectationsUpdater(host, args) - - -def main(args): - host = Host() - updater = get_updater(host, args) - return updater.run() - - -if __name__ == '__main__': - sys.exit(main(sys.argv[1:])) +if __name__ == "__main__": + updater = WPTExpectationsUpdater(host.Host()) + sys.exit(updater.run(sys.argv[1:]))
diff --git a/third_party/blink/web_tests/FlagExpectations/composite-after-paint b/third_party/blink/web_tests/FlagExpectations/composite-after-paint index b47df91c..bc1e9f3 100644 --- a/third_party/blink/web_tests/FlagExpectations/composite-after-paint +++ b/third_party/blink/web_tests/FlagExpectations/composite-after-paint
@@ -12,6 +12,7 @@ virtual/layout_ng_block_frag/* [ Skip ] virtual/layout_ng_fieldset/* [ Skip ] virtual/layout_ng_flex_box/* [ Skip ] +virtual/layout_ng_fragment_traversal/* [ Skip ] virtual/prefer_compositing_to_lcd_text/compositing/overflow/* [ Skip ] virtual/stable/* [ Skip ]
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng index 8e0011c6..c1f7807 100644 --- a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng +++ b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
@@ -112,6 +112,10 @@ crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/block-aspect-ratio-012.tentative.html [ Failure ] crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/block-aspect-ratio-013.tentative.html [ Failure ] crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/block-aspect-ratio-014.tentative.html [ Failure ] +crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/block-aspect-ratio-015.tentative.html [ Failure ] +crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/block-aspect-ratio-016.tentative.html [ Failure ] +crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/block-aspect-ratio-017.tentative.html [ Failure ] +crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/block-aspect-ratio-018.tentative.html [ Failure ] crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-001.tentative.html [ Failure ] crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-002.tentative.html [ Failure ] crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-003.tentative.html [ Failure ]
diff --git a/third_party/blink/web_tests/LeakExpectations b/third_party/blink/web_tests/LeakExpectations index 142b8ca..e16c9cb 100644 --- a/third_party/blink/web_tests/LeakExpectations +++ b/third_party/blink/web_tests/LeakExpectations
@@ -150,9 +150,6 @@ crbug.com/1068175 [ Linux ] external/wpt/referrer-policy/gen/worker-classic.http-rp/no-referrer-when-downgrade/worker-module.http.html [ Pass Timeout ] crbug.com/1068175 [ Linux ] external/wpt/referrer-policy/gen/worker-classic.http-rp/unset/worker-module.http.html [ Pass Timeout ] -# Sheriff 2020-05-05 -crbug.com/998948 [ Linux ] external/wpt/pointerevents/pointerevent_releasepointercapture_invalid_pointerid.html [ Pass Failure ] - # Sheriff 2020-05-06 crbug.com/1078769 [ Linux ] external/wpt/wasm/jsapi/idlharness.any.html [ Pass Failure ]
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests index 5457919..080494eb 100644 --- a/third_party/blink/web_tests/NeverFixTests +++ b/third_party/blink/web_tests/NeverFixTests
@@ -95,8 +95,6 @@ [ Win ] editing/input/linux_ltr_composition_underline.html [ Skip ] [ Mac ] editing/input/linux_rtl_composition_underline.html [ Skip ] [ Win ] editing/input/linux_rtl_composition_underline.html [ Skip ] -[ Mac ] editing/selection/linux_selection_color.html [ Skip ] -[ Win ] editing/selection/linux_selection_color.html [ Skip ] [ Mac ] virtual/text-antialias/chromium-linux-fontconfig-renderstyle.html [ Skip ] [ Win ] virtual/text-antialias/chromium-linux-fontconfig-renderstyle.html [ Skip ] [ Mac ] virtual/text-antialias/international/arabic-vertical-offset.html [ Skip ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index d904fde..cb5afe7 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -71,106 +71,11 @@ crbug.com/887140 virtual/hdr/color-profile-video.html [ Failure ] crbug.com/887140 virtual/hdr/video-canvas-alpha.html [ Failure ] -crbug.com/1014421 crbug.com/1075614 external/wpt/css/cssom-view/MediaQueryList-addListener-handleEvent.html [ Pass Failure Timeout ] +crbug.com/1014421 external/wpt/css/cssom-view/MediaQueryList-addListener-handleEvent.html [ Timeout ] # Tested by paint/background/root-element-background-transparency.html for now. external/wpt/css/compositing/root-element-background-transparency.html [ Failure ] -# Now that the accessibility serializer is turned on for all web tests, it is -# causing new failures, crashes and timeouts. -# These failing tests are tested by virtual/disable-ax-serializer for now. -# See https://crrev.com/c/2181915/ for more info. -# TODO(aleventhal) Burn down this list. -crbug.com/1075614 virtual/disable-ax-serializer/* [ Pass ] -crbug.com/1045672 crbug.com/1006759 virtual/disable-ax-serializer/fast/forms/select/listbox-tap.html [ Failure ] -crbug.com/1075614 accessibility/aom-click-action.html [ Crash Timeout ] -crbug.com/1075614 accessibility/aom-virtual.html [ Crash Timeout ] -crbug.com/1075614 accessibility/clickable.html [ Pass Failure ] -crbug.com/1075614 external/wpt/css/css-text/text-transform/text-transform-upperlower-041.html [ Pass Failure Crash ] -crbug.com/1075614 external/wpt/css/css-text/text-transform/text-transform-upperlower-043.html [ Pass Failure Crash ] -crbug.com/1075614 external/wpt/css/css-text/text-transform/text-transform-upperlower-044.html [ Pass Failure Crash ] -crbug.com/1075614 external/wpt/css/cssom-view/MediaQueryList-addListener-removeListener.html [ Pass Failure ] -crbug.com/1075614 external/wpt/css/cssom-view/MediaQueryList-extends-EventTarget.html [ Pass Failure ] -crbug.com/1075614 external/wpt/css/cssom-view/MediaQueryList-extends-EventTarget-interop.html [ Pass Failure ] -crbug.com/1075614 external/wpt/css/cssom-view/MediaQueryListEvent.html [ Pass Failure ] -crbug.com/1075614 external/wpt/dom/ranges/Range-mutations-replaceData.html [ Crash ] -crbug.com/1075614 external/wpt/html/user-activation/consumption-crossorigin.sub.tentative.html [ Pass Timeout ] -crbug.com/1075614 external/wpt/web-animations/timing-model/timelines/update-and-send-events-replacement.html [ Failure ] -crbug.com/1075614 fast/forms/select_detached_textarea_crash.html [ Crash ] -crbug.com/1075614 fast/forms/time-multiple-fields/time-multiple-fields-losing-renderer-on-click.html [ Pass Crash ] -crbug.com/1075614 http/tests/devtools/console/console-context-selector.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/console/console-error-on-call-frame.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/debugger/fetch-breakpoints.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/elements/accessibility/autocomplete-attribute.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/elements/accessibility/edit-aria-attributes.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger-async/async-await/async-pause-on-exception.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger-async/async-callstack.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger-async/async-callstack-in-console.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger-breakpoints/breakpoints-ui-navigation.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger-breakpoints/debugger-breakpoints-not-activated-on-reload.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger-breakpoints/dom-breakpoints-reload.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger-breakpoints/dom-breakpoints.js [ Pass Failure Crash Timeout ] -crbug.com/1075614 http/tests/devtools/sources/debugger-breakpoints/provisional-breakpoints.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger-breakpoints/restore-locations-for-breakpoint-with-broken-source-map.js [ Pass Failure Crash ] -crbug.com/1075614 [ Release ] http/tests/devtools/sources/debugger-breakpoints/set-breakpoint.js [ Pass Failure Timeout ] -crbug.com/1075614 [ Release ] http/tests/devtools/sources/debugger-breakpoints/set-conditional-breakpoint.js [ Pass Failure Timeout ] -crbug.com/1075614 http/tests/devtools/sources/debugger-breakpoints/set-logpoint.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger-console/debug-console-command.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger-frameworks/frameworks-dom-xhr-event-breakpoints.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger-frameworks/frameworks-skip-step-in.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger-frameworks/frameworks-sourcemap.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger-frameworks/frameworks-step-into-skips-setTimeout.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger-frameworks/frameworks-steppings.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger-pause/debugger-pause-infinite-loop.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger-pause/debugger-pause-on-promise-rejection.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger-pause/pause-in-internal-script.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger-step/debugger-step-into-custom-element-callbacks.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger-step/debugger-step-into-event-listener.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger-step/debugger-step-out-custom-element-callbacks.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger-step/debugger-step-out-event-listener.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger-step/debugger-step-through-promises.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger-ui/custom-element-lifecycle-events.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger-ui/debugger-inline-values.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger-ui/debugger-inline-values-frames.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger-ui/reveal-not-skipped.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger-ui/script-formatter-breakpoints-2.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger/debugger-proto-property.js [ Pass Failure Crash Timeout ] -crbug.com/1075614 http/tests/devtools/sources/debugger/live-edit.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger/mutation-observer-suspend-while-paused.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger/source-frame-breakpoint-decorations.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/devtools/sources/debugger/source-frame-inline-breakpoint-decorations.js [ Pass Failure Crash ] -crbug.com/1075614 http/tests/inspector-protocol/side-effects/evaluate-embedder-side-effect-free-attributes.js [ Timeout ] -crbug.com/1075614 http/tests/misc/object-image-error.html [ Pass Failure Crash ] -crbug.com/1075614 inspector-protocol/runtime/runtime-console-special-functions.js [ Skip ] -crbug.com/1075614 plugins/focus.html [ Failure ] -crbug.com/1075614 storage/indexeddb/cursor-continue-validity.html [ Pass Failure Timeout ] -crbug.com/1075614 [ Release ] storage/indexeddb/index-cursor.html [ Pass Failure Timeout ] -crbug.com/1075614 storage/indexeddb/mozilla/indexes.html [ Pass Failure Timeout ] -crbug.com/1075614 storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html [ Pass Failure Timeout ] -crbug.com/1075614 storage/indexeddb/objectstore-cursor.html [ Pass Failure Timeout ] -crbug.com/1075614 storage/indexeddb/mozilla/cursors.html [ Pass Failure Timeout ] -crbug.com/1075614 storage/indexeddb/objectstore-keycursor.html [ Pass Failure Timeout ] -crbug.com/1075614 virtual/controls-refresh/calendar-picker/date-picker-ax.html [ Failure ] -crbug.com/1075614 virtual/disable-ax-serializer/http/tests/devtools/sources/debugger-breakpoints/breakpoints-ui-shifted-breakpoint.js [ Pass Failure Timeout ] -crbug.com/1075614 virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-basic-movement.html [ Timeout Failure ] -crbug.com/1075614 virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-dont-send-keyboard-events.html [ Timeout Failure ] -crbug.com/1075614 virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-enter-exit-focus.html [ Timeout Failure ] -# crbug.com/1075614 virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-enter-from-interest.html [ Timeout Failure ] -crbug.com/1075614 virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-form-does-not-submit.html [ Timeout Failure ] -crbug.com/1075614 virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-form-state-on-click.html [ Timeout Failure ] -crbug.com/1075614 virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-navigate-from-focus.html [ Timeout Failure ] -crbug.com/1075614 virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-video-on-click-a11y.html [ Timeout Failure ] -crbug.com/1075614 virtual/text-antialias/text-transform-lower-turkic.html [ Crash ] -crbug.com/1075614 virtual/text-antialias/text-transform-upper-lithuanian.html [ Crash ] -crbug.com/1075614 wpt_internal/display-lock/css-content-visibility/content-visibility-026.html [ Failure ] -crbug.com/1075614 virtual/form-controls-refresh-disabled/fast/forms/calendar-picker/calendar-picker-mouse-operations.html [ Pass Timeout Crash ] -crbug.com/1075614 virtual/form-controls-refresh-disabled/fast/forms/calendar-picker/week-picker-mouse-operations.html [ Skip ] -# The following line causes a redundant warning in presubmit, but is necessary to avoid test breakage: -crbug.com/1075614 virtual/not-site-per-process/external/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects.html [ Pass Timeout ] -crbug.com/1075614 virtual/scalefactor200/css3/filters/backdrop-filter-svg.html [ Skip ] -crbug.com/1075614 virtual/web-components-v0-disabled/external/wpt/dom/ranges/Range-mutations-replaceData.html [ Skip ] -crbug.com/963183 crbug.com/1075614 virtual/disable-ax-serializer/http/tests/devtools/sources/debugger-breakpoints/disable-breakpoints.js [ Pass Failure ] - # ====== Site Isolation failures from here ====== # See also third_party/blink/web_tests/virtual/not-site-per-process/README.md # @@ -359,7 +264,7 @@ crbug.com/968791 crbug.com/1051044 virtual/scalefactor200/external/wpt/css/filter-effects/effect-reference-feimage-001.html [ Failure ] crbug.com/968791 crbug.com/1051044 virtual/scalefactor200/external/wpt/css/filter-effects/effect-reference-feimage-002.html [ Failure ] crbug.com/968791 crbug.com/1051044 virtual/scalefactor200/external/wpt/css/filter-effects/effect-reference-feimage-003.html [ Failure ] -crbug.com/968791 virtual/scalefactor200/external/wpt/css/filter-effects/filters-test-brightness-003.html [ Pass Failure ] +crbug.com/968791 virtual/scalefactor200/external/wpt/css/filter-effects/filters-test-brightness-003.html [ Failure ] # Copying these from elsewhere in TestExpectations (for non-scalefactor200 virtual suite) crbug.com/591099 virtual/scalefactor200/external/wpt/css/filter-effects/filtered-inline-applies-to-float.html [ Failure ] @@ -1561,7 +1466,7 @@ crbug.com/1035582 [ Mac10.10 ] virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/select/select-multiple-appearance-basic.html [ Skip ] # Bug in FormControlsRefresh <select multiple> tap behavior: -crbug.com/1045672 fast/forms/select/listbox-tap.html [ Pass Failure ] +crbug.com/1045672 fast/forms/select/listbox-tap.html [ Failure ] ### sheriff 2019-07-16 crbug.com/983799 [ Win ] http/tests/navigation/redirect-on-back-updates-history-item.html [ Timeout Pass ] @@ -1895,7 +1800,7 @@ crbug.com/1049641 [ Debug ] http/tests/devtools/sources/debugger/js-with-inline-stylesheets.js [ Pass Failure ] crbug.com/1049641 [ Debug ] http/tests/devtools/sources/debugger-breakpoints/set-breakpoint.js [ Pass Failure ] crbug.com/1049641 [ Debug ] http/tests/devtools/sources/debugger-breakpoints/set-conditional-breakpoint.js [ Pass Failure ] -crbug.com/1049641 crbug.com/1075614 http/tests/devtools/sources/debugger/debugger-disable-enable.js [ Pass Timeout Crash ] +crbug.com/1049641 http/tests/devtools/sources/debugger/debugger-disable-enable.js [ Pass Timeout ] # Sheriff 2019-08-19 crbug.com/626703 [ Win7 ] external/wpt/xhr/responsexml-document-properties.htm [ Failure ] @@ -1975,7 +1880,7 @@ crbug.com/400829 virtual/stable/media/stable/video-object-fit-stable.html [ Failure ] # Source map asyncification requires some 3-way changes with the DevTools frontend. -crbug.com/1032016 crbug.com/1075614 http/tests/devtools/sources/debugger-breakpoints/breakpoints-ui-shifted-breakpoint.js [ Pass Failure Timeout Crash ] +crbug.com/1032016 http/tests/devtools/sources/debugger-breakpoints/breakpoints-ui-shifted-breakpoint.js [ Pass Failure Timeout ] # Renaming front_end/protocol to front_end/protocol_client requires a 3-way change. Temporarliy disable web tests that use |Protocol| crbug.com/1011811 http/tests/devtools/inspector-backend-commands.js [ Pass Failure ] @@ -3152,7 +3057,7 @@ crbug.com/626703 external/wpt/xhr/event-readystatechange-loaded.any.html [ Timeout Failure ] crbug.com/626703 external/wpt/css/css-sizing/image-min-max-content-intrinsic-size-change-005.html [ Failure ] crbug.com/626703 external/wpt/css/css-sizing/image-min-max-content-intrinsic-size-change-008.html [ Failure ] -crbug.com/626703 external/wpt/css/css-animations/animationevent-marker-pseudoelement.html [ Pass Timeout ] +crbug.com/626703 external/wpt/css/css-animations/animationevent-marker-pseudoelement.html [ Timeout ] crbug.com/626703 external/wpt/css/css-text/overflow-wrap/overflow-wrap-normal-keep-all-001.html [ Failure ] crbug.com/626703 external/wpt/html/semantics/embedded-content/media-elements/src_object_blob.html [ Timeout ] crbug.com/626703 external/wpt/css/css-lists/list-item-definition.html [ Failure ] @@ -4175,7 +4080,7 @@ # snav tests fail because of a DCHECK crbug.com/985520 virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-enter-from-interest-a11y.html [ Crash ] -crbug.com/985520 virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-enter-from-interest.html [ Crash Failure ] +crbug.com/985520 virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-enter-from-interest.html [ Crash ] # User-Agent is not able to be set on XHR/fetch crbug.com/571722 external/wpt/xhr/preserve-ua-header-on-redirect.htm [ Failure ] @@ -4939,7 +4844,6 @@ # cases it seems like a problem around test expectation timing rather than real bugs affecting # production code. Because such timing bugs are relatively common in tests and it would thus be very # difficult to land the dispatch change without some temporary breakage, these tests are disabled -crbug.com/922951 external/wpt/pointerevents/pointerevent_capture_mouse.html [ Failure Pass Timeout Crash ] crbug.com/922951 external/wpt/pointerevents/pointerevent_setpointercapture_disconnected.html [ Failure Pass Timeout Crash ] crbug.com/922951 external/wpt/pointerevents/pointerevent_setpointercapture_invalid_pointerid.html [ Failure Pass Timeout Crash ] crbug.com/922951 fast/css/pseudo-hover-active-display-none.html [ Failure Pass Timeout Crash ] @@ -5610,7 +5514,7 @@ crbug.com/1040270 http/tests/devtools/elements/styles-1/disable-property-workingcopy-update.js [ Pass Timeout ] # Broken in https://chromium-review.googlesource.com/c/chromium/src/+/1636716 -crbug.com/963183 crbug.com/1075614 http/tests/devtools/sources/debugger-breakpoints/disable-breakpoints.js [ Pass Failure Timeout Crash ] +crbug.com/963183 http/tests/devtools/sources/debugger-breakpoints/disable-breakpoints.js [ Pass Failure Timeout ] crbug.com/836300 fast/css3-text/css3-text-decoration/text-decoration-skip-ink-links.html [ Pass Failure ] @@ -6030,3 +5934,7 @@ # Sheriff 2020-05-06 crbug.com/1078863 [ Mac ] fast/speech/scripted/speechrecognition-restart-onend.html [ Pass Timeout ] crbug.com/1071915 fast/hidpi/image-srcset-png-canvas.html [ Pass Failure ] + +# Sheriff 2020-05-13 +# Flaking on Webkit Linux Leak +crbug.com/998948 [ Linux ] external/wpt/pointerevents/pointerevent_capture_mouse.html [ Pass Failure ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 8e7640b..28941de 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -500,7 +500,6 @@ "prefix": "focusless-spat-nav", "bases": [], "args": ["--enable-blink-features=FocuslessSpatialNavigation", - "--disable-ax-serializer", "--enable-spatial-navigation"] }, { @@ -733,6 +732,11 @@ "args": ["--enable-features=AllowClientHintsToThirdParty"] }, { + "prefix": "disable-user-agent-client-hint-feature", + "bases": ["external/wpt/client-hints", "wpt_internal/client-hints"], + "args": ["--disable-features=UserAgentClientHint"] + }, + { "prefix": "legacy-client-hints-no-fp-delegation", "bases": [ "external/wpt/client-hints" ], "args": [ "--enable-features=AllowClientHintsToThirdParty", @@ -762,84 +766,5 @@ "prefix": "media-devtools", "bases": [ "inspector-protocol/media" ], "args": ["--enable-features=MediaInspectorLogging"] - }, - { - "prefix": "disable-ax-serializer", - "bases": [ - "accessibility/aom-click-action.html", - "accessibility/aom-virtual.html", - "accessibility/clickable.html", - "external/wpt/css/css-text/text-transform/text-transform-upperlower-041.html", - "external/wpt/css/css-text/text-transform/text-transform-upperlower-043.html", - "external/wpt/css/css-text/text-transform/text-transform-upperlower-044.html", - "external/wpt/css/cssom-view/MediaQueryList-addListener-removeListener.html", - "external/wpt/css/cssom-view/MediaQueryList-extends-EventTarget-interop.html", - "external/wpt/css/cssom-view/MediaQueryList-extends-EventTarget.html", - "external/wpt/css/cssom-view/MediaQueryListEvent.html", - "external/wpt/dom/ranges/Range-mutations-replaceData.html", - "external/wpt/web-animations/timing-model/timelines/update-and-send-events-replacement.html", - "fast/forms/select/listbox-tap.html", - "fast/forms/select_detached_textarea_crash.html", - "fast/forms/time-multiple-fields/time-multiple-fields-losing-renderer-on-click.html", - "http/tests/devtools/console/console-context-selector.js", - "http/tests/devtools/console/console-error-on-call-frame.js", - "http/tests/devtools/debugger/fetch-breakpoints.js", - "http/tests/devtools/elements/accessibility/autocomplete-attribute.js", - "http/tests/devtools/elements/accessibility/edit-aria-attributes.js", - "http/tests/devtools/sources/debugger-async/async-await/async-pause-on-exception.js", - "http/tests/devtools/sources/debugger-async/async-callstack-in-console.js", - "http/tests/devtools/sources/debugger-async/async-callstack.js", - "http/tests/devtools/sources/debugger-breakpoints/breakpoints-ui-navigation.js", - "http/tests/devtools/sources/debugger-breakpoints/breakpoints-ui-shifted-breakpoint.js", - "http/tests/devtools/sources/debugger-breakpoints/debugger-breakpoints-not-activated-on-reload.js", - "http/tests/devtools/sources/debugger-breakpoints/disable-breakpoints.js", - "http/tests/devtools/sources/debugger-breakpoints/dom-breakpoints-reload.js", - "http/tests/devtools/sources/debugger-breakpoints/dom-breakpoints.js", - "http/tests/devtools/sources/debugger-breakpoints/provisional-breakpoints.js", - "http/tests/devtools/sources/debugger-breakpoints/restore-locations-for-breakpoint-with-broken-source-map.js", - "http/tests/devtools/sources/debugger-breakpoints/set-breakpoint.js", - "http/tests/devtools/sources/debugger-breakpoints/set-conditional-breakpoint.js", - "http/tests/devtools/sources/debugger-breakpoints/set-logpoint.js", - "http/tests/devtools/sources/debugger-console/debug-console-command.js", - "http/tests/devtools/sources/debugger-frameworks/frameworks-dom-xhr-event-breakpoints.js", - "http/tests/devtools/sources/debugger-frameworks/frameworks-skip-step-in.js", - "http/tests/devtools/sources/debugger-frameworks/frameworks-sourcemap.js", - "http/tests/devtools/sources/debugger-frameworks/frameworks-step-into-skips-setTimeout.js", - "http/tests/devtools/sources/debugger-frameworks/frameworks-steppings.js", - "http/tests/devtools/sources/debugger-pause/debugger-pause-infinite-loop.js", - "http/tests/devtools/sources/debugger-pause/debugger-pause-on-promise-rejection.js", - "http/tests/devtools/sources/debugger-pause/pause-in-internal-script.js", - "http/tests/devtools/sources/debugger-step/debugger-step-into-custom-element-callbacks.js", - "http/tests/devtools/sources/debugger-step/debugger-step-into-event-listener.js", - "http/tests/devtools/sources/debugger-step/debugger-step-out-custom-element-callbacks.js", - "http/tests/devtools/sources/debugger-step/debugger-step-out-event-listener.js", - "http/tests/devtools/sources/debugger-step/debugger-step-through-promises.js", - "http/tests/devtools/sources/debugger-ui/custom-element-lifecycle-events.js", - "http/tests/devtools/sources/debugger-ui/debugger-inline-values-frames.js", - "http/tests/devtools/sources/debugger-ui/debugger-inline-values.js", - "http/tests/devtools/sources/debugger-ui/reveal-not-skipped.js", - "http/tests/devtools/sources/debugger-ui/script-formatter-breakpoints-2.js", - "http/tests/devtools/sources/debugger/debugger-disable-enable.js", - "http/tests/devtools/sources/debugger/debugger-proto-property.js", - "http/tests/devtools/sources/debugger/live-edit.js", - "http/tests/devtools/sources/debugger/mutation-observer-suspend-while-paused.js", - "http/tests/devtools/sources/debugger/source-frame-breakpoint-decorations.js", - "http/tests/devtools/sources/debugger/source-frame-inline-breakpoint-decorations.js", - "http/tests/inspector-protocol/side-effects/evaluate-embedder-side-effect-free-attributes.js", - "http/tests/misc/object-image-error.html", - "inspector-protocol/runtime/runtime-console-special-functions.js", - "plugins/focus.html", - "storage/indexeddb/cursor-continue-validity.html", - "storage/indexeddb/index-cursor.html", - "storage/indexeddb/mozilla/indexes.html", - "storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html", - "storage/indexeddb/objectstore-cursor.html", - "storage/indexeddb/objectstore-keycursor.html", - "virtual/controls-refresh/calendar-picker/date-picker-ax.html", - "virtual/text-antialias/text-transform-lower-turkic.html", - "virtual/text-antialias/text-transform-upper-lithuanian.html", - "wpt_internal/display-lock/css-content-visibility/content-visibility-026.html" - ], - "args": ["--disable-ax-serializer-for-testing"] } ]
diff --git a/third_party/blink/web_tests/accessibility/contenteditable-notifications.html b/third_party/blink/web_tests/accessibility/contenteditable-notifications.html index c18c32ee..1836c35 100644 --- a/third_party/blink/web_tests/accessibility/contenteditable-notifications.html +++ b/third_party/blink/web_tests/accessibility/contenteditable-notifications.html
@@ -1,54 +1,59 @@ -<!DOCTYPE HTML> -<html> -<head> +<!DOCTYPE html> <script src="../resources/accessibility-helper.js"></script> <script src="../resources/testharness.js"></script> <script src="../resources/testharnessreport.js"></script> -</head> -<body> -<div id="textbox" contentEditable="true">First<p>Second</p></div> +<div id="textbox" contenteditable="true"> + First<p>Second</p> +</div> <script> +'use strict'; + async_test((t) => { - // TODO(aboxhall): No longer necessary when updates are processed after layout. - // Ensure entire a11y tree has already been seen. - traverseAccessibilityTree(accessibilityController.rootElement); + // TODO(aboxhall): No longer necessary when updates are processed after layout. + // Ensure entire a11y tree has already been seen. + traverseAccessibilityTree(accessibilityController.rootElement); - // Focus the contenteditable text box and move the cursor to the end. - var textbox = document.getElementById("textbox"); - textbox.focus(); - eventSender.keyDown("ArrowDown", []); - eventSender.keyDown("ArrowDown", []); + const textbox = document.getElementById('textbox'); + const axTextBox = accessibilityController.accessibleElementById('textbox'); + let valueChangedCount = 0; + let selectedTextChangedCount = 0; + const expectedIntents = []; - var axTextBox = accessibilityController.focusedElement; + axTextBox.setNotificationListener(t.step_func((notification, intents) => { + if (notification == "ValueChanged") { + ++valueChangedCount; + } else if (notification == "SelectedTextChanged") { + assert_array_equals(intents, [expectedIntents[selectedTextChangedCount]]); + ++selectedTextChangedCount; + } - var valueChangedCount = 0; - var selectedTextChangedCount = 0; + if (valueChangedCount >= 8 && selectedTextChangedCount >= 9) { + t.done(); + } + })); - // Defer the main part of the test so that the notification listener - // doesn't catch any notifications still in the queue from loading the - // page and initially setting focus. - axTextBox.addNotificationListener(t.step_func((notification) => { - if (notification == "ValueChanged") - valueChangedCount++; - else if (notification == "SelectedTextChanged") - selectedTextChangedCount++; - - if (valueChangedCount >= 8 && selectedTextChangedCount >= 4) { - t.done(); - } - })); - - eventSender.keyDown("ArrowLeft", []); - eventSender.keyDown("ArrowLeft", []); - eventSender.keyDown("w", []); - eventSender.keyDown("x", []); - eventSender.keyDown("y", []); - eventSender.keyDown("z", []); -}, "This test ensures that moving the cursor in a contentEditable sends a selected text change notification, and typing in a contentEditable sends both a value changed and selected text changed notification - both on the root element that's marked as contentEditable."); + textbox.focus(); + // Initial setting of the selection. + expectedIntents.push('AXEventIntent(setSelection,character,forward)'); + eventSender.keyDown("ArrowDown", []); + expectedIntents.push('AXEventIntent(moveSelection,lineEnd,forward)'); + eventSender.keyDown("ArrowDown", []); + expectedIntents.push('AXEventIntent(moveSelection,lineEnd,forward)'); + eventSender.keyDown("ArrowLeft", []); + expectedIntents.push('AXEventIntent(moveSelection,character,backward)'); + eventSender.keyDown("ArrowLeft", []); + expectedIntents.push('AXEventIntent(moveSelection,character,backward)'); + eventSender.keyDown("w", []); + // TODO(nektar): Support an intent for the typing command. + expectedIntents.push('AXEventIntent(setSelection,character,forward)'); + eventSender.keyDown("x", []); + expectedIntents.push('AXEventIntent(setSelection,character,forward)'); + eventSender.keyDown("y", []); + expectedIntents.push('AXEventIntent(setSelection,character,forward)'); + eventSender.keyDown("z", []); + expectedIntents.push('AXEventIntent(setSelection,character,forward)'); +}, 'This test ensures that moving the cursor in a contentEditable sends a selected text change notification, and typing in a contentEditable sends both a value changed and selected text changed notification.'); </script> - -</body> -</html>
diff --git a/third_party/blink/web_tests/accessibility/selection-change-notification-aria-textbox.html b/third_party/blink/web_tests/accessibility/selection-change-notification-aria-textbox.html index b4a8eab5..10a1f49 100644 --- a/third_party/blink/web_tests/accessibility/selection-change-notification-aria-textbox.html +++ b/third_party/blink/web_tests/accessibility/selection-change-notification-aria-textbox.html
@@ -1,10 +1,6 @@ -<!DOCTYPE HTML> -<html> -<head> +<!DOCTYPE html> <script src="../resources/testharness.js"></script> <script src="../resources/testharnessreport.js"></script> -</head> -<body id="static_eventTarget"> <div id="ariaTextbox" role="textbox" tabIndex="0"> <p>Before</p> @@ -12,39 +8,40 @@ <p>After</p> </div> -<div id="console"></div> <script> +'use strict'; + async_test((t) => { - // This forces building the accessibility tree, because selection change - // events only fire on elements that already exist. - accessibilityController.accessibleElementById('dummy'); + // This forces building the accessibility tree, because selection change + // events only fire on elements that already exist. + accessibilityController.accessibleElementById('dummy'); - var element = document.getElementById('ariaTextbox'); - element.focus(); + const element = document.getElementById('ariaTextbox'); + element.focus(); - var axElement = accessibilityController.accessibleElementById('ariaTextbox'); - axElement.addNotificationListener(t.step_func((notification) => { - // Focus notification will come asynchronously after layout - if (notification == 'Focus') - return; + const axElement = accessibilityController.accessibleElementById('ariaTextbox'); + axElement.setNotificationListener(t.step_func((notification, intents) => { + // Focus notification will come asynchronously after layout + if (notification == 'Focus') + return; - if (notification == 'SelectedTextChanged') { - axElement.removeNotificationListener(); - t.done(); - return; - }; - assert_unreached('Unexpected notification: ' + notification); - })); + if (notification == 'SelectedTextChanged') { + assert_array_equals(intents, + ['AXEventIntent(setSelection,character,forward)']); + axElement.unsetNotificationListener(); + t.done(); + return; + } - var p = document.getElementById('p'); - var range = document.createRange(); - range.setStart(p.firstChild, 0); - range.setEnd(p.firstChild, 1); - window.getSelection().removeAllRanges(); - window.getSelection().addRange(range); -}, "Tests that a 'selected text changed' notification fires on a focusable element with role=textbox when the user moves the cursor within it."); + assert_unreached('Unexpected notification: ' + notification); + })); + + const p = document.getElementById('p'); + const range = document.createRange(); + range.setStart(p.firstChild, 0); + range.setEnd(p.firstChild, 1); + window.getSelection().removeAllRanges(); + window.getSelection().addRange(range); +}); </script> - -</body> -</html>
diff --git a/third_party/blink/web_tests/accessibility/selection-change-notification-contenteditable.html b/third_party/blink/web_tests/accessibility/selection-change-notification-contenteditable.html index 0422c4c..28aae43e 100644 --- a/third_party/blink/web_tests/accessibility/selection-change-notification-contenteditable.html +++ b/third_party/blink/web_tests/accessibility/selection-change-notification-contenteditable.html
@@ -1,11 +1,7 @@ -<!DOCTYPE HTML> -<html> -<head> +<!DOCTYPE html> <script src="../resources/testharness.js"></script> <script src="../resources/testharnessreport.js"></script> <script src="../resources/run-after-layout-and-paint.js"></script> -</head> -<body id="static_eventTarget"> <div id="contentEditable" contentEditable="true"> <p>Before</p> @@ -14,34 +10,36 @@ </div> <script> +'use strict'; + // Wait until layout has settled to avoid notification spam. async_test_after_layout_and_paint((t) => { - var element = document.getElementById('contentEditable'); - element.focus(); + const element = document.getElementById('contentEditable'); + element.focus(); - var axElement = accessibilityController.accessibleElementById('contentEditable'); - axElement.addNotificationListener(t.step_func((notification) => { - // Focus notification will come asynchronously after layout - if (notification == 'Focus') - return; + const axElement = accessibilityController.accessibleElementById('contentEditable'); + axElement.setNotificationListener(t.step_func((notification, intents) => { + // Focus notification will come asynchronously after layout + if (notification == 'Focus') + return; - if (notification == 'SelectedTextChanged') { - axElement.removeNotificationListener(); - t.done(); - return; - } - assert_unreached('Unexpected notification: ' + notification); - })); + if (notification == 'SelectedTextChanged') { + assert_array_equals(intents, + ['AXEventIntent(setSelection,character,forward)']); + axElement.unsetNotificationListener(); + t.done(); + return; + } - var p = document.getElementById('p'); - var range = document.createRange(); - range.setStart(p.firstChild, 0); - range.setEnd(p.firstChild, 1); - window.getSelection().removeAllRanges(); - window.getSelection().addRange(range); -}, "Tests that a 'selected text changed' notification fires on a contentEditable element when the user moves the cursor within it."); + assert_unreached('Unexpected notification: ' + notification); + })); + + const p = document.getElementById('p'); + const range = document.createRange(); + range.setStart(p.firstChild, 0); + range.setEnd(p.firstChild, 1); + window.getSelection().removeAllRanges(); + window.getSelection().addRange(range); +}); </script> - -</body> -</html>
diff --git a/third_party/blink/web_tests/accessibility/selection-change-notification-input.html b/third_party/blink/web_tests/accessibility/selection-change-notification-input.html index 6a7066a..7a72ccd 100644 --- a/third_party/blink/web_tests/accessibility/selection-change-notification-input.html +++ b/third_party/blink/web_tests/accessibility/selection-change-notification-input.html
@@ -1,56 +1,49 @@ -<!DOCTYPE HTML> -<html> -<head> +<!DOCTYPE html> <script src="../resources/testharness.js"></script> <script src="../resources/testharnessreport.js"></script> -</head> -<body id="static_eventTarget"> -<input id="input" value="input"> +<input autofocus id="input" value="input"> -<div id="console"></div> <script> -window.jsTestIsAsync = true; +'use strict'; async_test((t) => { - // This forces building the accessibility tree, because selection change - // events only fire on elements that already exist. - accessibilityController.accessibleElementById('dummy'); + // This forces building the accessibility tree, because selection change + // events only fire on elements that already exist. + accessibilityController.accessibleElementById('dummy'); - var inputElement = document.getElementById('input'); - var axRootElement = accessibilityController.rootElement; - var axInputElement = accessibilityController.accessibleElementById('input'); - inputElement.focus(); + const inputElement = document.getElementById('input'); + const axRootElement = accessibilityController.rootElement; + const axInputElement = accessibilityController.accessibleElementById('input'); - var gotDocumentSelectionChanged = false; - var gotSelectedTextChanged = false; - succeedIfDone = t.step_func(() => { - if (gotDocumentSelectionChanged && gotSelectedTextChanged) - t.done(); - }); + let gotDocumentSelectionChanged = false; + let gotSelectedTextChanged = false; + const succeedIfDone = t.step_func(() => { + if (gotDocumentSelectionChanged && gotSelectedTextChanged) + t.done(); + }); - axRootElement.addNotificationListener(function(notification) { - if (notification == 'DocumentSelectionChanged') { - console.log('Got DocumentSelectionChanged notification on root element.'); - gotDocumentSelectionChanged = true; - axRootElement.removeNotificationListener(); - succeedIfDone(); - } - }); + axRootElement.setNotificationListener(function(notification, intents) { + if (notification == 'DocumentSelectionChanged') { + assert_array_equals(intents, + ['AXEventIntent(setSelection,character,forward)']); + gotDocumentSelectionChanged = true; + axRootElement.unsetNotificationListener(); + succeedIfDone(); + } + }); - axInputElement.addNotificationListener(function(notification) { - if (notification == 'SelectedTextChanged') { - console.log('Got SelectedTextChanged notification on input element.'); - gotSelectedTextChanged = true; - axInputElement.removeNotificationListener(); - succeedIfDone(); - } - }); + axInputElement.setNotificationListener(function(notification, intents) { + if (notification == 'SelectedTextChanged') { + assert_array_equals(intents, + ['AXEventIntent(setSelection,character,forward)']); + gotSelectedTextChanged = true; + axInputElement.unsetNotificationListener(); + succeedIfDone(); + } + }); - inputElement.setSelectionRange(0, 1); -}, "Tests that a 'selected text changed' notification fires on an input element when the user moves the cursor."); + inputElement.setSelectionRange(0, 1); +}); </script> - -</body> -</html>
diff --git a/third_party/blink/web_tests/accessibility/selection-change-notification-on-selection-removed.html b/third_party/blink/web_tests/accessibility/selection-change-notification-on-selection-removed.html index 2dfc79d..ad2b042 100644 --- a/third_party/blink/web_tests/accessibility/selection-change-notification-on-selection-removed.html +++ b/third_party/blink/web_tests/accessibility/selection-change-notification-on-selection-removed.html
@@ -10,28 +10,34 @@ </div> <script> - setup(() => { - textbox.focus(); - let selectionRange = document.createRange(); - selectionRange.selectNodeContents(textbox); - getSelection().removeAllRanges(); - getSelection().addRange(selectionRange); +'use strict'; + +setup(() => { + const textbox = document.getElementById('textbox'); + textbox.focus(); + const selectionRange = document.createRange(); + selectionRange.selectNodeContents(textbox); + getSelection().removeAllRanges(); + getSelection().addRange(selectionRange); +}); + +async_test_after_layout_and_paint((t) => { + const axRoot = accessibilityController.rootElement; + + axRoot.setNotificationListener(t.step_func((notification, intents) => { + if (notification == 'DocumentSelectionChanged') { + assert_array_equals(intents, + ['AXEventIntent(clearSelection,character,forward)']); + axRoot.unsetNotificationListener(); + assert_equals(axRoot.selectionAnchorObject, null, 'selectionAnchorObject'); + assert_equals(axRoot.selectionAnchorOffset, -1, 'selectionAnchorOffset'); + assert_equals(axRoot.selectionFocusObject, null, 'selectionFocusObject'); + assert_equals(axRoot.selectionFocusOffset, -1, 'selectionFocusOffset'); + t.done(); + } + })); + + getSelection().removeAllRanges(); }); - - async_test_after_layout_and_paint((t) => { - let axRoot = accessibilityController.rootElement; - - axRoot.addNotificationListener(t.step_func((notification) => { - if (notification == 'DocumentSelectionChanged') { - axRoot.removeNotificationListener(); - assert_equals(axRoot.selectionAnchorObject, null, 'selectionAnchorObject'); - assert_equals(axRoot.selectionAnchorOffset, -1, 'selectionAnchorOffset'); - assert_equals(axRoot.selectionFocusObject, null, 'selectionFocusObject'); - assert_equals(axRoot.selectionFocusOffset, -1, 'selectionFocusOffset'); - t.done(); - } - })); - - getSelection().removeAllRanges(); - }, "Tests that a 'selected text changed' notification fires on the document object when the selection is removed."); + </script>
diff --git a/third_party/blink/web_tests/accessibility/selection-change-notification-statictext.html b/third_party/blink/web_tests/accessibility/selection-change-notification-statictext.html index 0e9a9a4..9036cda9 100644 --- a/third_party/blink/web_tests/accessibility/selection-change-notification-statictext.html +++ b/third_party/blink/web_tests/accessibility/selection-change-notification-statictext.html
@@ -1,33 +1,29 @@ -<!DOCTYPE HTML> -<html> -<head> +<!DOCTYPE html> <script src="../resources/testharness.js"></script> <script src="../resources/testharnessreport.js"></script> -</head> -<body id="static_eventTarget"> <p id="p">One paragraph in the document</p> -<div id="console"></div> <script> -async_test((t) => { - var axElement = accessibilityController.rootElement; - axElement.addNotificationListener(t.step_func(function(notification) { - if (notification == 'SelectedTextChanged') { - axElement.removeNotificationListener(); - t.done(); - } - })); +'use strict'; - var p = document.getElementById('p'); - var range = document.createRange(); - range.setStart(p.firstChild, 0); - range.setEnd(p.firstChild, 1); - window.getSelection().removeAllRanges(); - window.getSelection().addRange(range); -}, "Tests that a 'selected text changed' notification fires on a contentEditable element when the user moves the cursor within it."); +async_test((t) => { + const axElement = accessibilityController.rootElement; + axElement.setNotificationListener(t.step_func(function(notification, intents) { + if (notification == 'SelectedTextChanged') { + assert_array_equals(intents, + ['AXEventIntent(setSelection,character,forward)']); + axElement.unsetNotificationListener(); + t.done(); + } + })); + + const p = document.getElementById('p'); + const range = document.createRange(); + range.setStart(p.firstChild, 0); + range.setEnd(p.firstChild, 1); + window.getSelection().removeAllRanges(); + window.getSelection().addRange(range); +}); </script> - -</body> -</html>
diff --git a/third_party/blink/web_tests/accessibility/selection-change-notification-textarea.html b/third_party/blink/web_tests/accessibility/selection-change-notification-textarea.html index 1596574..4b929ef8 100644 --- a/third_party/blink/web_tests/accessibility/selection-change-notification-textarea.html +++ b/third_party/blink/web_tests/accessibility/selection-change-notification-textarea.html
@@ -1,38 +1,30 @@ -<!DOCTYPE HTML> -<html> -<head> +<!DOCTYPE html> <script src="../resources/testharness.js"></script> <script src="../resources/testharnessreport.js"></script> -</head> -<body id="static_eventTarget"> -<textarea id="textarea">textarea</textarea> +<textarea autofocus id="textarea">textarea</textarea> -<div id="console"></div> <script> +'use strict'; + async_test((t) => { - // This forces building the accessibility tree, because selection change - // events only fire on elements that already exist. - accessibilityController.accessibleElementById('dummy'); + // This forces building the accessibility tree, because selection change + // events only fire on elements that already exist. + accessibilityController.accessibleElementById('dummy'); - var element = document.getElementById('textarea'); - var axElement = accessibilityController.accessibleElementById('textarea'); - element.focus(); + const element = document.getElementById('textarea'); + const axElement = accessibilityController.accessibleElementById('textarea'); - axElement.addNotificationListener(t.step_func((notification) => { - if (notification == 'SelectedTextChanged') { - axElement.removeNotificationListener(); - t.done(); - } - })); + axElement.setNotificationListener(t.step_func((notification, intents) => { + if (notification == 'SelectedTextChanged') { + assert_array_equals(intents, + ['AXEventIntent(setSelection,character,forward)']); + axElement.unsetNotificationListener(); + t.done(); + } + })); - element.setSelectionRange(0, 1); - - // Fail rather than time out. - window.setTimeout(() => { assert_unreached('Did not receive notification after 1000ms'); }, 1000); -}, "Tests that a 'selected text changed' notification fires on an textarea element when the user moves the cursor."); + element.setSelectionRange(0, 1); +}); </script> - -</body> -</html>
diff --git a/third_party/blink/web_tests/accessibility/selection-dom-events.html b/third_party/blink/web_tests/accessibility/selection-dom-events.html index 99eb785..9a08d241 100644 --- a/third_party/blink/web_tests/accessibility/selection-dom-events.html +++ b/third_party/blink/web_tests/accessibility/selection-dom-events.html
@@ -7,15 +7,15 @@ <script> test(() => { - var para = document.getElementById('para'); - var selectstartCount = 0; + let para = document.getElementById('para'); + let selectstartCount = 0; para.addEventListener('selectstart', (e) => { selectstartCount++; if (selectstartCount === 1) e.preventDefault(); }, true); - var axPara = accessibilityController.accessibleElementById('para'); + let axPara = accessibilityController.accessibleElementById('para'); assert_false(axPara.setSelection(axPara, 0, axPara, 1)); assert_true(axPara.setSelection(axPara, 0, axPara, 1)); }, 'Test that setting the selection via the accessibility API can be canceled by JavaScript running on the page.');
diff --git a/third_party/blink/web_tests/accessibility/selection-follows-focus.html b/third_party/blink/web_tests/accessibility/selection-follows-focus.html index 20c03dd..c7cae166 100644 --- a/third_party/blink/web_tests/accessibility/selection-follows-focus.html +++ b/third_party/blink/web_tests/accessibility/selection-follows-focus.html
@@ -37,7 +37,6 @@ assert_equals(axOption1.isSelected, true); }, "Selection follows activedescendant in a single selection container"); - test(function(t) { var axOption = axElementById("opt2.1"); assert_equals(axOption.isSelectable, true);
diff --git a/third_party/blink/web_tests/clipboard/async-clipboard/async-platform-specific-write-read.tentative.https.html b/third_party/blink/web_tests/clipboard/async-clipboard/async-platform-specific-write-read.tentative.https.html index 2478d03e..701f923 100644 --- a/third_party/blink/web_tests/clipboard/async-clipboard/async-platform-specific-write-read.tentative.https.html +++ b/third_party/blink/web_tests/clipboard/async-clipboard/async-platform-specific-write-read.tentative.https.html
@@ -2,9 +2,13 @@ <meta charset="utf-8"> <title>Async Clipboard raw platform-specific write -> read tests</title> <link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> +<body>Body needed for test_driver.click()</body> <script src="../../resources/testharness.js"></script> <script src="../../resources/testharnessreport.js"></script> <script src="../../http/tests/resources/permissions-helper.js"></script> +<script src="../../resources/testdriver.js"></script> +<script src="../../resources/testdriver-vendor.js"></script> +<script src="resources/user-activation.js"></script> <script> 'use strict'; @@ -12,6 +16,7 @@ const format = 'RawClipboardDisabledFormat'; const blob = new Blob(['RawClipboardDisabled'], {type: format}); const clipboardItem = new ClipboardItem({[format]: blob}, {raw: true}); + await waitForUserActivation(); await navigator.clipboard.write([clipboardItem]); } @@ -29,7 +34,6 @@ await PermissionsHelper.setPermission('clipboard-read-write', 'granted'); await PermissionsHelper.setPermission('clipboard-sanitized-write', 'granted'); - // This extra raw write is used to create consistency in the error message // when the RawClipboard flag isn't enabled. // TODO(https://crbug.com/897289): Remove this after RawClipboard is enabled @@ -43,9 +47,11 @@ assert_equals(blobInput.type, format.toLowerCase()); const clipboardItemInput = new ClipboardItem( {[format]: blobInput}, {raw: true}); + await waitForUserActivation(); await navigator.clipboard.write([clipboardItemInput]); // Items should be readable on a raw clipboard after raw write. + await waitForUserActivation(); const clipboardItems = await navigator.clipboard.read({raw: true}); assert_equals(clipboardItems.length, 1); const clipboardItem = clipboardItems[0]; @@ -62,6 +68,5 @@ // accessible as text. const textOutput = await navigator.clipboard.readText(); assert_equals(textOutput, dataToWrite); - }, 'Verify write and read clipboard given platform-specific raw input'); </script>
diff --git a/third_party/blink/web_tests/clipboard/async-clipboard/async-raw-write-read.tentative.https.html b/third_party/blink/web_tests/clipboard/async-clipboard/async-raw-write-read.tentative.https.html index 085d90d..a6bd291 100644 --- a/third_party/blink/web_tests/clipboard/async-clipboard/async-raw-write-read.tentative.https.html +++ b/third_party/blink/web_tests/clipboard/async-clipboard/async-raw-write-read.tentative.https.html
@@ -2,9 +2,13 @@ <meta charset="utf-8"> <title>Async Clipboard raw write -> Async Clipboard raw read test</title> <link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> +<body>Body needed for test_driver.click()</body> <script src="../../resources/testharness.js"></script> <script src="../../resources/testharnessreport.js"></script> <script src="../../http/tests/resources/permissions-helper.js"></script> +<script src="../../resources/testdriver.js"></script> +<script src="../../resources/testdriver-vendor.js"></script> +<script src="resources/user-activation.js"></script> <script> 'use strict'; @@ -20,6 +24,7 @@ const blobInput2 = new Blob(['input data 2'], {type: format2}); const clipboardItemInput = new ClipboardItem( {[format1]: blobInput1, [format2]: blobInput2}, {raw: true}); + await waitForUserActivation(); await navigator.clipboard.write([clipboardItemInput]); // Items may not be readable on the sanitized clipboard after raw write. @@ -27,6 +32,7 @@ navigator.clipboard.read({raw: false})); // Items should be readable on a raw clipboard after raw write. + await waitForUserActivation(); const clipboardItems = await navigator.clipboard.read({raw: true}); assert_equals(clipboardItems.length, 1); const clipboardItem = clipboardItems[0]; @@ -43,8 +49,6 @@ assert_equals(blobOutput2.type, format2); const data2 = await (new Response(blobOutput2)).text(); assert_equals(data2, 'input data 2'); - }, 'Verify write and read clipboard given 2 platform-neutral raw inputs'); - </script>
diff --git a/third_party/blink/web_tests/clipboard/async-clipboard/resources/user-activation.js b/third_party/blink/web_tests/clipboard/async-clipboard/resources/user-activation.js new file mode 100644 index 0000000..babd5b2 --- /dev/null +++ b/third_party/blink/web_tests/clipboard/async-clipboard/resources/user-activation.js
@@ -0,0 +1,21 @@ +'use strict'; + +// In order to use this function, please import testdriver.js and +// testdriver-vendor.js, and include a <body> element. +async function waitForUserActivation() { + const loadedPromise = new Promise(resolve => { + if(document.readyState == 'complete') { + resolve(); + return; + } + window.addEventListener('load', resolve, {once: true}); + }); + await loadedPromise; + + const clickedPromise = new Promise(resolve => { + document.body.addEventListener('click', resolve, {once: true}); + }); + + test_driver.click(document.body); + await clickedPromise; +}
diff --git a/third_party/blink/web_tests/compositing/contents-opaque/hidden-with-visible-child-expected.txt b/third_party/blink/web_tests/compositing/contents-opaque/hidden-with-visible-child-expected.txt index 48287d7..53c44b9 100644 --- a/third_party/blink/web_tests/compositing/contents-opaque/hidden-with-visible-child-expected.txt +++ b/third_party/blink/web_tests/compositing/contents-opaque/hidden-with-visible-child-expected.txt
@@ -9,6 +9,7 @@ { "name": "LayoutNGBlockFlow (positioned) DIV id='caption'", "bounds": [200, 100], + "contentsOpaqueForText": true, "backgroundColor": "#008000", "transform": 1 }
diff --git a/third_party/blink/web_tests/compositing/contents-opaque/hidden-with-visible-text-expected.txt b/third_party/blink/web_tests/compositing/contents-opaque/hidden-with-visible-text-expected.txt index 64989bc..e067d17 100644 --- a/third_party/blink/web_tests/compositing/contents-opaque/hidden-with-visible-text-expected.txt +++ b/third_party/blink/web_tests/compositing/contents-opaque/hidden-with-visible-text-expected.txt
@@ -10,6 +10,7 @@ { "name": "LayoutNGBlockFlow (positioned) DIV id='caption'", "bounds": [200, 100], + "contentsOpaqueForText": true, "backgroundColor": "#008000", "transform": 1 }
diff --git a/third_party/blink/web_tests/compositing/contents-opaque/overflow-hidden-child-layers-expected.txt b/third_party/blink/web_tests/compositing/contents-opaque/overflow-hidden-child-layers-expected.txt index e224f78..7fcfc716 100644 --- a/third_party/blink/web_tests/compositing/contents-opaque/overflow-hidden-child-layers-expected.txt +++ b/third_party/blink/web_tests/compositing/contents-opaque/overflow-hidden-child-layers-expected.txt
@@ -10,6 +10,7 @@ "name": "LayoutNGBlockFlow DIV class='box'", "position": [-30, -30], "bounds": [160, 160], + "contentsOpaqueForText": true, "backgroundColor": "#0000FF", "transform": 1 }
diff --git a/third_party/blink/web_tests/compositing/filters/sw-layer-overlaps-hw-shadow-expected.txt b/third_party/blink/web_tests/compositing/filters/sw-layer-overlaps-hw-shadow-expected.txt index cdec5f9..e15a950 100644 --- a/third_party/blink/web_tests/compositing/filters/sw-layer-overlaps-hw-shadow-expected.txt +++ b/third_party/blink/web_tests/compositing/filters/sw-layer-overlaps-hw-shadow-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV id='software')", "position": [-105, -105], "bounds": [100, 100], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/compositing/filters/sw-nested-shadow-overlaps-hw-nested-shadow-expected.txt b/third_party/blink/web_tests/compositing/filters/sw-nested-shadow-overlaps-hw-nested-shadow-expected.txt index 456e769..67c2210 100644 --- a/third_party/blink/web_tests/compositing/filters/sw-nested-shadow-overlaps-hw-nested-shadow-expected.txt +++ b/third_party/blink/web_tests/compositing/filters/sw-nested-shadow-overlaps-hw-nested-shadow-expected.txt
@@ -10,12 +10,14 @@ "name": "LayoutNGBlockFlow (positioned) DIV id='composited-parent'", "position": [-100, -100], "bounds": [200, 200], + "contentsOpaqueForText": true, "backgroundColor": "#000000", "transform": 1 }, { "name": "LayoutNGBlockFlow (positioned) DIV id='software-parent'", "bounds": [200, 200], + "contentsOpaqueForText": true, "backgroundColor": "#008000" } ],
diff --git a/third_party/blink/web_tests/compositing/fixed-position-changed-to-absolute-expected.txt b/third_party/blink/web_tests/compositing/fixed-position-changed-to-absolute-expected.txt index 6f79804..a9c6934 100644 --- a/third_party/blink/web_tests/compositing/fixed-position-changed-to-absolute-expected.txt +++ b/third_party/blink/web_tests/compositing/fixed-position-changed-to-absolute-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV id='layer-A')", "position": [12, 7], "bounds": [226, 180], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/compositing/geometry/bounds-ignores-hidden-composited-descendant-expected.txt b/third_party/blink/web_tests/compositing/geometry/bounds-ignores-hidden-composited-descendant-expected.txt index a581645..919e3d4 100644 --- a/third_party/blink/web_tests/compositing/geometry/bounds-ignores-hidden-composited-descendant-expected.txt +++ b/third_party/blink/web_tests/compositing/geometry/bounds-ignores-hidden-composited-descendant-expected.txt
@@ -9,12 +9,14 @@ { "name": "LayoutNGBlockFlow (positioned) DIV class='composited'", "position": [10, 10], - "bounds": [590, 210] + "bounds": [590, 210], + "contentsOpaqueForText": true }, { "name": "LayoutNGBlockFlow (positioned) DIV class='composited'", "position": [10, 10], "bounds": [590, 210], + "contentsOpaqueForText": true, "transform": 1 }, {
diff --git a/third_party/blink/web_tests/compositing/geometry/bounds-ignores-hidden-dynamic-expected.txt b/third_party/blink/web_tests/compositing/geometry/bounds-ignores-hidden-dynamic-expected.txt index 82e2ff1..3b6ff35 100644 --- a/third_party/blink/web_tests/compositing/geometry/bounds-ignores-hidden-dynamic-expected.txt +++ b/third_party/blink/web_tests/compositing/geometry/bounds-ignores-hidden-dynamic-expected.txt
@@ -9,7 +9,8 @@ { "name": "LayoutNGBlockFlow (positioned) DIV class='composited'", "position": [10, 10], - "bounds": [540, 240] + "bounds": [540, 240], + "contentsOpaqueForText": true }, { "name": "LayoutNGBlockFlow (positioned) DIV class='composited'",
diff --git a/third_party/blink/web_tests/compositing/geometry/clip-expected.txt b/third_party/blink/web_tests/compositing/geometry/clip-expected.txt index 985efdd..e85e966 100644 --- a/third_party/blink/web_tests/compositing/geometry/clip-expected.txt +++ b/third_party/blink/web_tests/compositing/geometry/clip-expected.txt
@@ -12,6 +12,7 @@ "name": "LayoutNGBlockFlow (positioned) DIV class='composited box'", "position": [-5, -5], "bounds": [110, 110], + "contentsOpaqueForText": true, "backgroundColor": "#808080", "transform": 2 },
diff --git a/third_party/blink/web_tests/compositing/geometry/foreground-layer-expected.txt b/third_party/blink/web_tests/compositing/geometry/foreground-layer-expected.txt index 33e0231e..ee143eb 100644 --- a/third_party/blink/web_tests/compositing/geometry/foreground-layer-expected.txt +++ b/third_party/blink/web_tests/compositing/geometry/foreground-layer-expected.txt
@@ -30,6 +30,7 @@ "name": "LayoutNGBlockFlow (relative positioned) DIV class='main box'", "position": [-30, -30], "bounds": [340, 340], + "contentsOpaqueForText": true, "backgroundColor": "#FF0000", "transform": 4 },
diff --git a/third_party/blink/web_tests/compositing/iframes/become-composited-nested-iframes-expected.txt b/third_party/blink/web_tests/compositing/iframes/become-composited-nested-iframes-expected.txt index b5d4661..a57eae1 100644 --- a/third_party/blink/web_tests/compositing/iframes/become-composited-nested-iframes-expected.txt +++ b/third_party/blink/web_tests/compositing/iframes/become-composited-nested-iframes-expected.txt
@@ -24,6 +24,7 @@ { "name": "LayoutView #document", "bounds": [250, 170], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 4 }, @@ -52,6 +53,7 @@ { "name": "LayoutView #document", "bounds": [250, 170], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 9 },
diff --git a/third_party/blink/web_tests/compositing/iframes/become-overlapped-iframe-expected.txt b/third_party/blink/web_tests/compositing/iframes/become-overlapped-iframe-expected.txt index 9f3e0359..4c0ba73 100644 --- a/third_party/blink/web_tests/compositing/iframes/become-overlapped-iframe-expected.txt +++ b/third_party/blink/web_tests/compositing/iframes/become-overlapped-iframe-expected.txt
@@ -14,6 +14,7 @@ { "name": "Scrolling Contents Layer", "bounds": [305, 230], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 2 },
diff --git a/third_party/blink/web_tests/compositing/iframes/composited-parent-iframe-expected.txt b/third_party/blink/web_tests/compositing/iframes/composited-parent-iframe-expected.txt index 7406b4a..041d768 100644 --- a/third_party/blink/web_tests/compositing/iframes/composited-parent-iframe-expected.txt +++ b/third_party/blink/web_tests/compositing/iframes/composited-parent-iframe-expected.txt
@@ -15,6 +15,7 @@ { "name": "Scrolling Contents Layer", "bounds": [285, 230], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 2 },
diff --git a/third_party/blink/web_tests/compositing/iframes/connect-compositing-iframe-delayed-expected.txt b/third_party/blink/web_tests/compositing/iframes/connect-compositing-iframe-delayed-expected.txt index 95b0269..e7a3749 100644 --- a/third_party/blink/web_tests/compositing/iframes/connect-compositing-iframe-delayed-expected.txt +++ b/third_party/blink/web_tests/compositing/iframes/connect-compositing-iframe-delayed-expected.txt
@@ -17,6 +17,7 @@ { "name": "Scrolling Contents Layer", "bounds": [285, 230], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 2 },
diff --git a/third_party/blink/web_tests/compositing/iframes/connect-compositing-iframe-expected.txt b/third_party/blink/web_tests/compositing/iframes/connect-compositing-iframe-expected.txt index 386df91..64c99bd0 100644 --- a/third_party/blink/web_tests/compositing/iframes/connect-compositing-iframe-expected.txt +++ b/third_party/blink/web_tests/compositing/iframes/connect-compositing-iframe-expected.txt
@@ -15,6 +15,7 @@ { "name": "Scrolling Contents Layer", "bounds": [285, 230], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 2 },
diff --git a/third_party/blink/web_tests/compositing/iframes/connect-compositing-iframe2-expected.txt b/third_party/blink/web_tests/compositing/iframes/connect-compositing-iframe2-expected.txt index af40059..617fb2e 100644 --- a/third_party/blink/web_tests/compositing/iframes/connect-compositing-iframe2-expected.txt +++ b/third_party/blink/web_tests/compositing/iframes/connect-compositing-iframe2-expected.txt
@@ -15,6 +15,7 @@ { "name": "Scrolling Contents Layer", "bounds": [285, 230], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 2 },
diff --git a/third_party/blink/web_tests/compositing/iframes/connect-compositing-iframe3-expected.txt b/third_party/blink/web_tests/compositing/iframes/connect-compositing-iframe3-expected.txt index 02b6bc8..6246f59 100644 --- a/third_party/blink/web_tests/compositing/iframes/connect-compositing-iframe3-expected.txt +++ b/third_party/blink/web_tests/compositing/iframes/connect-compositing-iframe3-expected.txt
@@ -15,6 +15,7 @@ { "name": "Scrolling Contents Layer", "bounds": [285, 230], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 2 },
diff --git a/third_party/blink/web_tests/compositing/iframes/enter-compositing-iframe-expected.txt b/third_party/blink/web_tests/compositing/iframes/enter-compositing-iframe-expected.txt index 386df91..64c99bd0 100644 --- a/third_party/blink/web_tests/compositing/iframes/enter-compositing-iframe-expected.txt +++ b/third_party/blink/web_tests/compositing/iframes/enter-compositing-iframe-expected.txt
@@ -15,6 +15,7 @@ { "name": "Scrolling Contents Layer", "bounds": [285, 230], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 2 },
diff --git a/third_party/blink/web_tests/compositing/iframes/iframe-resize-expected.txt b/third_party/blink/web_tests/compositing/iframes/iframe-resize-expected.txt index e08b6e4..955eef70 100644 --- a/third_party/blink/web_tests/compositing/iframes/iframe-resize-expected.txt +++ b/third_party/blink/web_tests/compositing/iframes/iframe-resize-expected.txt
@@ -15,6 +15,7 @@ { "name": "Scrolling Contents Layer", "bounds": [385, 230], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 2 },
diff --git a/third_party/blink/web_tests/compositing/iframes/iframe-size-from-zero-expected.txt b/third_party/blink/web_tests/compositing/iframes/iframe-size-from-zero-expected.txt index 4ede04f3..dd60a9c 100644 --- a/third_party/blink/web_tests/compositing/iframes/iframe-size-from-zero-expected.txt +++ b/third_party/blink/web_tests/compositing/iframes/iframe-size-from-zero-expected.txt
@@ -14,6 +14,7 @@ { "name": "Scrolling Contents Layer", "bounds": [285, 230], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 2 },
diff --git a/third_party/blink/web_tests/compositing/iframes/overlapped-iframe-expected.txt b/third_party/blink/web_tests/compositing/iframes/overlapped-iframe-expected.txt index 4da9cd5..6e665fd 100644 --- a/third_party/blink/web_tests/compositing/iframes/overlapped-iframe-expected.txt +++ b/third_party/blink/web_tests/compositing/iframes/overlapped-iframe-expected.txt
@@ -15,6 +15,7 @@ { "name": "Scrolling Contents Layer", "bounds": [285, 230], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 2 },
diff --git a/third_party/blink/web_tests/compositing/iframes/overlapped-iframe-iframe-expected.txt b/third_party/blink/web_tests/compositing/iframes/overlapped-iframe-iframe-expected.txt index a5557d0..d19bac0 100644 --- a/third_party/blink/web_tests/compositing/iframes/overlapped-iframe-iframe-expected.txt +++ b/third_party/blink/web_tests/compositing/iframes/overlapped-iframe-iframe-expected.txt
@@ -13,6 +13,7 @@ { "name": "LayoutView #document", "bounds": [300, 300], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 1 },
diff --git a/third_party/blink/web_tests/compositing/iframes/overlapped-nested-iframes-expected.txt b/third_party/blink/web_tests/compositing/iframes/overlapped-nested-iframes-expected.txt index d4f2564..7eba977 100644 --- a/third_party/blink/web_tests/compositing/iframes/overlapped-nested-iframes-expected.txt +++ b/third_party/blink/web_tests/compositing/iframes/overlapped-nested-iframes-expected.txt
@@ -25,6 +25,7 @@ { "name": "LayoutView #document", "bounds": [250, 170], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 5 }, @@ -53,6 +54,7 @@ { "name": "LayoutView #document", "bounds": [250, 170], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 10 },
diff --git a/third_party/blink/web_tests/compositing/iframes/resizer-expected.txt b/third_party/blink/web_tests/compositing/iframes/resizer-expected.txt index 6f876793..3e163113e 100644 --- a/third_party/blink/web_tests/compositing/iframes/resizer-expected.txt +++ b/third_party/blink/web_tests/compositing/iframes/resizer-expected.txt
@@ -14,6 +14,7 @@ { "name": "Scrolling Contents Layer", "bounds": [285, 230], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 2 },
diff --git a/third_party/blink/web_tests/compositing/iframes/scrolling-iframe-expected.txt b/third_party/blink/web_tests/compositing/iframes/scrolling-iframe-expected.txt index 01933db..c6dc8a9 100644 --- a/third_party/blink/web_tests/compositing/iframes/scrolling-iframe-expected.txt +++ b/third_party/blink/web_tests/compositing/iframes/scrolling-iframe-expected.txt
@@ -15,6 +15,7 @@ { "name": "Scrolling Contents Layer", "bounds": [508, 608], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 3 },
diff --git a/third_party/blink/web_tests/compositing/layer-creation/animation-overlap-with-children-expected.txt b/third_party/blink/web_tests/compositing/layer-creation/animation-overlap-with-children-expected.txt index 55b0b64..a75813a 100644 --- a/third_party/blink/web_tests/compositing/layer-creation/animation-overlap-with-children-expected.txt +++ b/third_party/blink/web_tests/compositing/layer-creation/animation-overlap-with-children-expected.txt
@@ -25,6 +25,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='test1 box')", "position": [5, 15], "bounds": [100, 100], + "contentsOpaqueForText": true, "transform": 3 }, {
diff --git a/third_party/blink/web_tests/compositing/layer-creation/overflow-scroll-overlap-expected.txt b/third_party/blink/web_tests/compositing/layer-creation/overflow-scroll-overlap-expected.txt index fe614ef..f53f728 100644 --- a/third_party/blink/web_tests/compositing/layer-creation/overflow-scroll-overlap-expected.txt +++ b/third_party/blink/web_tests/compositing/layer-creation/overflow-scroll-overlap-expected.txt
@@ -31,6 +31,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV class='box')", "position": [23, 213], "bounds": [210, 100], + "contentsOpaqueForText": true, "transform": 3 } ],
diff --git a/third_party/blink/web_tests/compositing/layer-creation/overlap-animation-container-expected.txt b/third_party/blink/web_tests/compositing/layer-creation/overlap-animation-container-expected.txt index e2ca5dd..f3f9fce 100644 --- a/third_party/blink/web_tests/compositing/layer-creation/overlap-animation-container-expected.txt +++ b/third_party/blink/web_tests/compositing/layer-creation/overlap-animation-container-expected.txt
@@ -18,6 +18,7 @@ "name": "LayoutNGBlockFlow (relative positioned) DIV class='container'", "position": [-11, 0], "bounds": [144, 452], + "contentsOpaqueForText": true, "backgroundColor": "#FFFFFF", "transform": 3 }, @@ -32,6 +33,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV class='box yellow')", "position": [-51, 451], "bounds": [100, 100], + "contentsOpaqueForText": true, "transform": 4 }, {
diff --git a/third_party/blink/web_tests/compositing/layer-creation/overlap-child-layer-expected.txt b/third_party/blink/web_tests/compositing/layer-creation/overlap-child-layer-expected.txt index 58cb1762..15c9db14 100644 --- a/third_party/blink/web_tests/compositing/layer-creation/overlap-child-layer-expected.txt +++ b/third_party/blink/web_tests/compositing/layer-creation/overlap-child-layer-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV id='green')", "position": [-400, 0], "bounds": [300, 300], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/compositing/layer-creation/overlap-clipping-expected.txt b/third_party/blink/web_tests/compositing/layer-creation/overlap-clipping-expected.txt index e8bd8b6..a8e735b 100644 --- a/third_party/blink/web_tests/compositing/layer-creation/overlap-clipping-expected.txt +++ b/third_party/blink/web_tests/compositing/layer-creation/overlap-clipping-expected.txt
@@ -24,6 +24,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV id='overlap')", "position": [400, 0], "bounds": [100, 100], + "contentsOpaqueForText": true, "transform": 2 } ],
diff --git a/third_party/blink/web_tests/compositing/layer-creation/overlap-transformed-3d-expected.txt b/third_party/blink/web_tests/compositing/layer-creation/overlap-transformed-3d-expected.txt index 9621269..ea68e25d 100644 --- a/third_party/blink/web_tests/compositing/layer-creation/overlap-transformed-3d-expected.txt +++ b/third_party/blink/web_tests/compositing/layer-creation/overlap-transformed-3d-expected.txt
@@ -58,6 +58,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='box top left')", "position": [-100, -100], "bounds": [300, 300], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/compositing/layer-creation/overlap-transformed-and-clipped-expected.txt b/third_party/blink/web_tests/compositing/layer-creation/overlap-transformed-and-clipped-expected.txt index b8d83ba..006d1f9 100644 --- a/third_party/blink/web_tests/compositing/layer-creation/overlap-transformed-and-clipped-expected.txt +++ b/third_party/blink/web_tests/compositing/layer-creation/overlap-transformed-and-clipped-expected.txt
@@ -21,6 +21,7 @@ { "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='over')", "bounds": [100, 100], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/compositing/layer-creation/overlap-transformed-preserved-3d-expected.txt b/third_party/blink/web_tests/compositing/layer-creation/overlap-transformed-preserved-3d-expected.txt index 3059f9b..a9c18d0 100644 --- a/third_party/blink/web_tests/compositing/layer-creation/overlap-transformed-preserved-3d-expected.txt +++ b/third_party/blink/web_tests/compositing/layer-creation/overlap-transformed-preserved-3d-expected.txt
@@ -279,7 +279,8 @@ { "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='box top right')", "position": [8, 8], - "bounds": [300, 300] + "bounds": [300, 300], + "contentsOpaqueForText": true } ], "transforms": [
diff --git a/third_party/blink/web_tests/compositing/layer-creation/spanOverlapsCanvas-expected.txt b/third_party/blink/web_tests/compositing/layer-creation/spanOverlapsCanvas-expected.txt index cf64eced..f809a9c 100644 --- a/third_party/blink/web_tests/compositing/layer-creation/spanOverlapsCanvas-expected.txt +++ b/third_party/blink/web_tests/compositing/layer-creation/spanOverlapsCanvas-expected.txt
@@ -19,6 +19,7 @@ { "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV id='output')", "bounds": [100, 50], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/compositing/layer-creation/squashing-into-ancestor-clipping-layer-change-expected.txt b/third_party/blink/web_tests/compositing/layer-creation/squashing-into-ancestor-clipping-layer-change-expected.txt index e1be4b3..5735ef17 100644 --- a/third_party/blink/web_tests/compositing/layer-creation/squashing-into-ancestor-clipping-layer-change-expected.txt +++ b/third_party/blink/web_tests/compositing/layer-creation/squashing-into-ancestor-clipping-layer-change-expected.txt
@@ -16,6 +16,7 @@ { "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='squashed')", "bounds": [100, 100], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/compositing/masks/mask-layer-size-expected.txt b/third_party/blink/web_tests/compositing/masks/mask-layer-size-expected.txt index edee064..0e7cda63 100644 --- a/third_party/blink/web_tests/compositing/masks/mask-layer-size-expected.txt +++ b/third_party/blink/web_tests/compositing/masks/mask-layer-size-expected.txt
@@ -9,6 +9,7 @@ { "name": "LayoutNGBlockFlow DIV id='masked'", "bounds": [400, 200], + "contentsOpaqueForText": true, "backgroundColor": "#000000", "transform": 1 },
diff --git a/third_party/blink/web_tests/compositing/overflow/scroll-parent-with-non-stacking-context-composited-ancestor-expected.txt b/third_party/blink/web_tests/compositing/overflow/scroll-parent-with-non-stacking-context-composited-ancestor-expected.txt index b61dced..3262079e 100644 --- a/third_party/blink/web_tests/compositing/overflow/scroll-parent-with-non-stacking-context-composited-ancestor-expected.txt +++ b/third_party/blink/web_tests/compositing/overflow/scroll-parent-with-non-stacking-context-composited-ancestor-expected.txt
@@ -40,6 +40,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV class='scrolled')", "position": [5, 49], "bounds": [60, 128], + "contentsOpaqueForText": true, "backfaceVisibility": "hidden", "transform": 1 },
diff --git a/third_party/blink/web_tests/compositing/overflow/universal-accelerated-overflow-scroll-expected.txt b/third_party/blink/web_tests/compositing/overflow/universal-accelerated-overflow-scroll-expected.txt index 5e9f4d8..fde4736 100644 --- a/third_party/blink/web_tests/compositing/overflow/universal-accelerated-overflow-scroll-expected.txt +++ b/third_party/blink/web_tests/compositing/overflow/universal-accelerated-overflow-scroll-expected.txt
@@ -39,6 +39,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV id='positioned-absolute-grandchildren-not-contained' class='positionAbsolute positioned')", "position": [25, 65], "bounds": [80, 40], + "contentsOpaqueForText": true, "transform": 1 }, { @@ -53,6 +54,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='scrolled-absolute-grandchildren-not-contained' class='scrolled')", "position": [6, 90], "bounds": [75, 24], + "contentsOpaqueForText": true, "transform": 2 }, { @@ -96,6 +98,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='scrolled-absolute-grandchildren' class='scrolled')", "position": [6, 34], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 4 }, { @@ -125,6 +128,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV id='positioned-absolute-not-contained' class='positionAbsolute positioned')", "position": [25, 65], "bounds": [80, 40], + "contentsOpaqueForText": true, "transform": 5 }, { @@ -139,6 +143,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='scrolled-absolute-not-contained' class='scrolled')", "position": [6, 90], "bounds": [75, 24], + "contentsOpaqueForText": true, "transform": 6 }, { @@ -174,6 +179,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV id='positioned-absolute-sibling-grandchildren-not-contained' class='positionAbsolute positioned')", "position": [25, 65], "bounds": [80, 40], + "contentsOpaqueForText": true, "transform": 7 }, { @@ -188,6 +194,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='scrolled-absolute-sibling-grandchildren-not-contained' class='scrolled')", "position": [6, 90], "bounds": [75, 24], + "contentsOpaqueForText": true, "transform": 8 }, { @@ -231,6 +238,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='scrolled-absolute-sibling-grandchildren' class='scrolled')", "position": [6, 34], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 10 }, { @@ -260,6 +268,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV id='positioned-absolute-sibling-not-contained' class='positionAbsolute positioned')", "position": [25, 65], "bounds": [80, 40], + "contentsOpaqueForText": true, "transform": 11 }, { @@ -274,6 +283,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='scrolled-absolute-sibling-not-contained' class='scrolled')", "position": [6, 90], "bounds": [75, 24], + "contentsOpaqueForText": true, "transform": 12 }, { @@ -311,6 +321,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='scrolled-absolute-sibling' class='scrolled')", "position": [6, 34], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 14 }, { @@ -348,6 +359,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='scrolled-absolute' class='scrolled')", "position": [6, 34], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 16 }, { @@ -398,6 +410,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='scrolled-fixed-sibling-grandchildren' class='scrolled')", "position": [6, 90], "bounds": [75, 24], + "contentsOpaqueForText": true, "transform": 18 }, { @@ -442,6 +455,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='scrolled-fixed-sibling' class='scrolled')", "position": [6, 90], "bounds": [75, 24], + "contentsOpaqueForText": true, "transform": 22 }, { @@ -492,6 +506,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='scrolled-fixed-grandchildren' class='scrolled')", "position": [6, 90], "bounds": [75, 24], + "contentsOpaqueForText": true, "transform": 24 }, { @@ -536,6 +551,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='scrolled-fixed' class='scrolled')", "position": [6, 90], "bounds": [75, 24], + "contentsOpaqueForText": true, "transform": 28 }, { @@ -592,6 +608,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='scrolled-absolute-grandchildren-not-contained' class='scrolled onTop')", "position": [6, 62], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 2 }, { @@ -606,6 +623,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='scrolled-absolute-grandchildren' class='scrolled onTop')", "position": [6, 62], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 4 }, { @@ -620,6 +638,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='scrolled-absolute-not-contained' class='scrolled onTop')", "position": [6, 62], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 6 }, { @@ -634,6 +653,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='scrolled-absolute-sibling-grandchildren-not-contained' class='scrolled onTop')", "position": [6, 62], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 8 }, { @@ -648,6 +668,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='scrolled-absolute-sibling-grandchildren' class='scrolled onTop')", "position": [6, 62], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 10 }, { @@ -662,6 +683,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='scrolled-absolute-sibling-not-contained' class='scrolled onTop')", "position": [6, 62], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 12 }, { @@ -676,6 +698,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='scrolled-absolute-sibling' class='scrolled onTop')", "position": [6, 62], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 14 }, { @@ -690,6 +713,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='scrolled-absolute' class='scrolled onTop')", "position": [6, 62], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 16 }, { @@ -704,6 +728,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='scrolled-fixed-sibling-grandchildren' class='scrolled onTop')", "position": [6, 62], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 18 }, { @@ -718,6 +743,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='scrolled-fixed-sibling' class='scrolled onTop')", "position": [6, 62], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 22 }, { @@ -732,6 +758,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='scrolled-fixed-grandchildren' class='scrolled onTop')", "position": [6, 62], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 24 }, { @@ -746,6 +773,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='scrolled-fixed' class='scrolled onTop')", "position": [6, 62], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 28 }, {
diff --git a/third_party/blink/web_tests/compositing/rtl/rtl-iframe-absolute-expected.txt b/third_party/blink/web_tests/compositing/rtl/rtl-iframe-absolute-expected.txt index 00cd8d5..39d25c02 100644 --- a/third_party/blink/web_tests/compositing/rtl/rtl-iframe-absolute-expected.txt +++ b/third_party/blink/web_tests/compositing/rtl/rtl-iframe-absolute-expected.txt
@@ -13,6 +13,7 @@ { "name": "LayoutView #document", "bounds": [400, 400], + "contentsOpaqueForText": true, "backgroundColor": "#FF0000" }, {
diff --git a/third_party/blink/web_tests/compositing/rtl/rtl-iframe-absolute-overflow-expected.txt b/third_party/blink/web_tests/compositing/rtl/rtl-iframe-absolute-overflow-expected.txt index 9176798..6f417cf 100644 --- a/third_party/blink/web_tests/compositing/rtl/rtl-iframe-absolute-overflow-expected.txt +++ b/third_party/blink/web_tests/compositing/rtl/rtl-iframe-absolute-overflow-expected.txt
@@ -14,6 +14,7 @@ "name": "Scrolling Contents Layer", "position": [15, 0], "bounds": [1000, 1000], + "contentsOpaqueForText": true, "backgroundColor": "#FF0000", "transform": 1 },
diff --git a/third_party/blink/web_tests/compositing/rtl/rtl-iframe-absolute-overflow-scrolled-expected.txt b/third_party/blink/web_tests/compositing/rtl/rtl-iframe-absolute-overflow-scrolled-expected.txt index 66ed47ff..ffe54b6 100644 --- a/third_party/blink/web_tests/compositing/rtl/rtl-iframe-absolute-overflow-scrolled-expected.txt +++ b/third_party/blink/web_tests/compositing/rtl/rtl-iframe-absolute-overflow-scrolled-expected.txt
@@ -14,6 +14,7 @@ "name": "Scrolling Contents Layer", "position": [15, 0], "bounds": [1000, 1000], + "contentsOpaqueForText": true, "backgroundColor": "#FF0000", "transform": 1 },
diff --git a/third_party/blink/web_tests/compositing/rtl/rtl-iframe-fixed-expected.txt b/third_party/blink/web_tests/compositing/rtl/rtl-iframe-fixed-expected.txt index 00cd8d5..39d25c02 100644 --- a/third_party/blink/web_tests/compositing/rtl/rtl-iframe-fixed-expected.txt +++ b/third_party/blink/web_tests/compositing/rtl/rtl-iframe-fixed-expected.txt
@@ -13,6 +13,7 @@ { "name": "LayoutView #document", "bounds": [400, 400], + "contentsOpaqueForText": true, "backgroundColor": "#FF0000" }, {
diff --git a/third_party/blink/web_tests/compositing/rtl/rtl-iframe-fixed-overflow-expected.txt b/third_party/blink/web_tests/compositing/rtl/rtl-iframe-fixed-overflow-expected.txt index 0a240a1..4756200 100644 --- a/third_party/blink/web_tests/compositing/rtl/rtl-iframe-fixed-overflow-expected.txt +++ b/third_party/blink/web_tests/compositing/rtl/rtl-iframe-fixed-overflow-expected.txt
@@ -14,6 +14,7 @@ "name": "Scrolling Contents Layer", "position": [15, 0], "bounds": [1000, 1000], + "contentsOpaqueForText": true, "backgroundColor": "#FF0000", "transform": 1 },
diff --git a/third_party/blink/web_tests/compositing/rtl/rtl-iframe-fixed-overflow-scrolled-expected.txt b/third_party/blink/web_tests/compositing/rtl/rtl-iframe-fixed-overflow-scrolled-expected.txt index 0a240a1..4756200 100644 --- a/third_party/blink/web_tests/compositing/rtl/rtl-iframe-fixed-overflow-scrolled-expected.txt +++ b/third_party/blink/web_tests/compositing/rtl/rtl-iframe-fixed-overflow-scrolled-expected.txt
@@ -14,6 +14,7 @@ "name": "Scrolling Contents Layer", "position": [15, 0], "bounds": [1000, 1000], + "contentsOpaqueForText": true, "backgroundColor": "#FF0000", "transform": 1 },
diff --git a/third_party/blink/web_tests/compositing/squashing/add-remove-squashed-layers-expected.txt b/third_party/blink/web_tests/compositing/squashing/add-remove-squashed-layers-expected.txt index 958018c..33359ebe 100644 --- a/third_party/blink/web_tests/compositing/squashing/add-remove-squashed-layers-expected.txt +++ b/third_party/blink/web_tests/compositing/squashing/add-remove-squashed-layers-expected.txt
@@ -20,6 +20,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV id='A' class='overlap1')", "position": [80, 80], "bounds": [180, 180], + "contentsOpaqueForText": true, "transform": 1 } ], @@ -56,6 +57,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV id='A' class='overlap1')", "position": [80, 80], "bounds": [260, 260], + "contentsOpaqueForText": true, "invalidations": [ [160, 160, 100, 100] ], @@ -95,6 +97,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV id='A' class='overlap1')", "position": [80, 80], "bounds": [260, 260], + "contentsOpaqueForText": true, "invalidations": [ [80, 80, 100, 100] ], @@ -134,6 +137,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV id='C' class='overlap3')", "position": [240, 240], "bounds": [100, 100], + "contentsOpaqueForText": true, "invalidations": [ [0, 0, 100, 100] ], @@ -173,6 +177,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV id='B' class='overlap2')", "position": [160, 160], "bounds": [180, 180], + "contentsOpaqueForText": true, "invalidations": [ [80, 80, 100, 100], [0, 0, 100, 100] @@ -213,6 +218,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV id='A' class='overlap1')", "position": [80, 80], "bounds": [180, 180], + "contentsOpaqueForText": true, "invalidations": [ [80, 80, 100, 100], [0, 0, 100, 100]
diff --git a/third_party/blink/web_tests/compositing/squashing/composited-bounds-for-negative-z-expected.txt b/third_party/blink/web_tests/compositing/squashing/composited-bounds-for-negative-z-expected.txt index 4ad77c82..096c5a5 100644 --- a/third_party/blink/web_tests/compositing/squashing/composited-bounds-for-negative-z-expected.txt +++ b/third_party/blink/web_tests/compositing/squashing/composited-bounds-for-negative-z-expected.txt
@@ -35,6 +35,7 @@ { "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV)", "bounds": [285, 1000], + "contentsOpaqueForText": true, "transform": 2 } ],
diff --git a/third_party/blink/web_tests/compositing/squashing/invisible-layers-should-not-affect-geometry-expected.txt b/third_party/blink/web_tests/compositing/squashing/invisible-layers-should-not-affect-geometry-expected.txt index 3243f60..80134ac 100644 --- a/third_party/blink/web_tests/compositing/squashing/invisible-layers-should-not-affect-geometry-expected.txt +++ b/third_party/blink/web_tests/compositing/squashing/invisible-layers-should-not-affect-geometry-expected.txt
@@ -16,6 +16,7 @@ { "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='box')", "bounds": [100, 100], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/compositing/squashing/move-squashing-layer-expected.txt b/third_party/blink/web_tests/compositing/squashing/move-squashing-layer-expected.txt index d5d97db..2ebadc3 100644 --- a/third_party/blink/web_tests/compositing/squashing/move-squashing-layer-expected.txt +++ b/third_party/blink/web_tests/compositing/squashing/move-squashing-layer-expected.txt
@@ -26,6 +26,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='squashed')", "position": [-92, -92], "bounds": [100, 100], + "contentsOpaqueForText": true, "transform": 2 } ],
diff --git a/third_party/blink/web_tests/compositing/squashing/no-squashing-for-filters-expected.txt b/third_party/blink/web_tests/compositing/squashing/no-squashing-for-filters-expected.txt index 3b8eccd..cc569f5d 100644 --- a/third_party/blink/web_tests/compositing/squashing/no-squashing-for-filters-expected.txt +++ b/third_party/blink/web_tests/compositing/squashing/no-squashing-for-filters-expected.txt
@@ -22,7 +22,8 @@ { "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='trysquashed')", "position": [50, 50], - "bounds": [50, 50] + "bounds": [50, 50], + "contentsOpaqueForText": true } ], "transforms": [
diff --git a/third_party/blink/web_tests/compositing/squashing/opacity-squashed-owner-expected.txt b/third_party/blink/web_tests/compositing/squashing/opacity-squashed-owner-expected.txt index a89d894a..9c8813d 100644 --- a/third_party/blink/web_tests/compositing/squashing/opacity-squashed-owner-expected.txt +++ b/third_party/blink/web_tests/compositing/squashing/opacity-squashed-owner-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='squashed')", "position": [8, -4], "bounds": [40, 90], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/compositing/squashing/repaint-child-of-squashed-expected.txt b/third_party/blink/web_tests/compositing/squashing/repaint-child-of-squashed-expected.txt index 6a3a279..3118b322 100644 --- a/third_party/blink/web_tests/compositing/squashing/repaint-child-of-squashed-expected.txt +++ b/third_party/blink/web_tests/compositing/squashing/repaint-child-of-squashed-expected.txt
@@ -18,6 +18,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='box top')", "position": [80, 80], "bounds": [100, 100], + "contentsOpaqueForText": true, "transform": 1 } ], @@ -54,6 +55,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='box top')", "position": [80, 80], "bounds": [100, 100], + "contentsOpaqueForText": true, "invalidations": [ [10, 10, 50, 50] ],
diff --git a/third_party/blink/web_tests/compositing/squashing/squash-above-fixed-1-expected.txt b/third_party/blink/web_tests/compositing/squashing/squash-above-fixed-1-expected.txt index e13c02d..e82a3f8 100644 --- a/third_party/blink/web_tests/compositing/squashing/squash-above-fixed-1-expected.txt +++ b/third_party/blink/web_tests/compositing/squashing/squash-above-fixed-1-expected.txt
@@ -28,7 +28,8 @@ { "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='paragraph-c' class='overlapping cyan')", "position": [0, 200], - "bounds": [200, 300] + "bounds": [200, 300], + "contentsOpaqueForText": true }, { "name": "ContentsLayer for Vertical Scrollbar Layer", @@ -86,6 +87,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='paragraph-d' class='overlapping lime')", "position": [0, 300], "bounds": [200, 300], + "contentsOpaqueForText": true, "invalidations": [ [0, 0, 200, 300] ], @@ -149,6 +151,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='paragraph-d' class='overlapping lime')", "position": [0, 300], "bounds": [200, 300], + "contentsOpaqueForText": true, "transform": 1 }, { @@ -216,6 +219,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (relative positioned) DIV id='paragraph-e' class='overlapping cyan')", "position": [0, 400], "bounds": [200, 300], + "contentsOpaqueForText": true, "invalidations": [ [0, 0, 200, 300] ],
diff --git a/third_party/blink/web_tests/compositing/squashing/squash-above-fixed-3-expected.txt b/third_party/blink/web_tests/compositing/squashing/squash-above-fixed-3-expected.txt index 54faad23..7a0e7610 100644 --- a/third_party/blink/web_tests/compositing/squashing/squash-above-fixed-3-expected.txt +++ b/third_party/blink/web_tests/compositing/squashing/squash-above-fixed-3-expected.txt
@@ -146,6 +146,7 @@ "name": "LayoutNGBlockFlow (positioned) DIV id='container'", "position": [100, 100], "bounds": [200, 4000], + "contentsOpaqueForText": true, "backgroundColor": "#008000", "invalidations": [ [100, 0, 100, 100]
diff --git a/third_party/blink/web_tests/compositing/squashing/squash-compositing-hover-expected.txt b/third_party/blink/web_tests/compositing/squashing/squash-compositing-hover-expected.txt index b697378..d60a249 100644 --- a/third_party/blink/web_tests/compositing/squashing/squash-compositing-hover-expected.txt +++ b/third_party/blink/web_tests/compositing/squashing/squash-compositing-hover-expected.txt
@@ -26,6 +26,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='box middle')", "position": [80, 80], "bounds": [260, 260], + "contentsOpaqueForText": true, "transform": 2 } ], @@ -84,6 +85,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='box middle2')", "position": [80, 80], "bounds": [180, 180], + "contentsOpaqueForText": true, "transform": 3 } ], @@ -144,6 +146,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='box middle')", "position": [80, 80], "bounds": [100, 100], + "contentsOpaqueForText": true, "transform": 2 }, { @@ -157,6 +160,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='box top')", "position": [80, 80], "bounds": [100, 100], + "contentsOpaqueForText": true, "transform": 3 } ], @@ -217,6 +221,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='box middle')", "position": [80, 80], "bounds": [180, 180], + "contentsOpaqueForText": true, "transform": 2 }, { @@ -284,6 +289,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='box middle')", "position": [80, 80], "bounds": [260, 260], + "contentsOpaqueForText": true, "transform": 2 } ],
diff --git a/third_party/blink/web_tests/compositing/squashing/squash-onto-nephew-expected.txt b/third_party/blink/web_tests/compositing/squashing/squash-onto-nephew-expected.txt index ea1a072c..2be3caa3 100644 --- a/third_party/blink/web_tests/compositing/squashing/squash-onto-nephew-expected.txt +++ b/third_party/blink/web_tests/compositing/squashing/squash-onto-nephew-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='box middle')", "position": [-85, -85], "bounds": [180, 190], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/compositing/squashing/squash-onto-transform-backing-expected.txt b/third_party/blink/web_tests/compositing/squashing/squash-onto-transform-backing-expected.txt index d179a0c..64e8132 100644 --- a/third_party/blink/web_tests/compositing/squashing/squash-onto-transform-backing-expected.txt +++ b/third_party/blink/web_tests/compositing/squashing/squash-onto-transform-backing-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='box middle')", "position": [-80, -80], "bounds": [260, 260], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/compositing/squashing/squash-simple-expected.txt b/third_party/blink/web_tests/compositing/squashing/squash-simple-expected.txt index 0898cd8..ed4c98f 100644 --- a/third_party/blink/web_tests/compositing/squashing/squash-simple-expected.txt +++ b/third_party/blink/web_tests/compositing/squashing/squash-simple-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='box middle')", "position": [-80, -80], "bounds": [260, 260], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/compositing/squashing/squash-three-layers-expected.txt b/third_party/blink/web_tests/compositing/squashing/squash-three-layers-expected.txt index f84dcb6f..059cf4a2 100644 --- a/third_party/blink/web_tests/compositing/squashing/squash-three-layers-expected.txt +++ b/third_party/blink/web_tests/compositing/squashing/squash-three-layers-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='box middle')", "position": [-60, -60], "bounds": [180, 190], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/compositing/squashing/squash-transform-expected.txt b/third_party/blink/web_tests/compositing/squashing/squash-transform-expected.txt index 5f38153f..784274ab 100644 --- a/third_party/blink/web_tests/compositing/squashing/squash-transform-expected.txt +++ b/third_party/blink/web_tests/compositing/squashing/squash-transform-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='box middle')", "position": [-101, -101], "bounds": [281, 281], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/compositing/squashing/squash-transform-repainting-child-expected.txt b/third_party/blink/web_tests/compositing/squashing/squash-transform-repainting-child-expected.txt index 7640493..d979e9cf 100644 --- a/third_party/blink/web_tests/compositing/squashing/squash-transform-repainting-child-expected.txt +++ b/third_party/blink/web_tests/compositing/squashing/squash-transform-repainting-child-expected.txt
@@ -18,6 +18,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='box middle')", "position": [-101, -101], "bounds": [281, 281], + "contentsOpaqueForText": true, "transform": 1 } ], @@ -54,6 +55,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='box middle')", "position": [-101, -101], "bounds": [281, 281], + "contentsOpaqueForText": true, "invalidations": [ [0, 0, 142, 142] ], @@ -93,6 +95,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='box middle')", "position": [-101, -101], "bounds": [281, 281], + "contentsOpaqueForText": true, "invalidations": [ [0, 0, 142, 142] ],
diff --git a/third_party/blink/web_tests/compositing/squashing/squash-transform-repainting-transformed-child-expected.txt b/third_party/blink/web_tests/compositing/squashing/squash-transform-repainting-transformed-child-expected.txt index 657c371..2159751 100644 --- a/third_party/blink/web_tests/compositing/squashing/squash-transform-repainting-transformed-child-expected.txt +++ b/third_party/blink/web_tests/compositing/squashing/squash-transform-repainting-transformed-child-expected.txt
@@ -18,6 +18,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='box middle')", "position": [-96, -96], "bounds": [276, 276], + "contentsOpaqueForText": true, "transform": 1 } ], @@ -54,6 +55,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='box middle')", "position": [-96, -96], "bounds": [276, 276], + "contentsOpaqueForText": true, "invalidations": [ [0, 0, 132, 132] ], @@ -93,6 +95,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='box middle')", "position": [-96, -96], "bounds": [276, 276], + "contentsOpaqueForText": true, "invalidations": [ [0, 0, 132, 132] ],
diff --git a/third_party/blink/web_tests/compositing/squashing/squashed-layer-loses-graphicslayer-expected.txt b/third_party/blink/web_tests/compositing/squashing/squashed-layer-loses-graphicslayer-expected.txt index 808afd3..b5aa81279 100644 --- a/third_party/blink/web_tests/compositing/squashing/squashed-layer-loses-graphicslayer-expected.txt +++ b/third_party/blink/web_tests/compositing/squashing/squashed-layer-loses-graphicslayer-expected.txt
@@ -20,6 +20,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV id='A' class='overlap1')", "position": [80, 80], "bounds": [260, 260], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/compositing/squashing/squashed-repaints-expected.txt b/third_party/blink/web_tests/compositing/squashing/squashed-repaints-expected.txt index 90f8b5e..a736840b 100644 --- a/third_party/blink/web_tests/compositing/squashing/squashed-repaints-expected.txt +++ b/third_party/blink/web_tests/compositing/squashing/squashed-repaints-expected.txt
@@ -20,6 +20,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV id='A' class='overlap1')", "position": [80, 80], "bounds": [260, 260], + "contentsOpaqueForText": true, "transform": 1 } ], @@ -56,6 +57,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV id='A' class='overlap1')", "position": [80, 80], "bounds": [260, 260], + "contentsOpaqueForText": true, "invalidations": [ [0, 0, 100, 100] ], @@ -95,6 +97,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV id='A' class='overlap1')", "position": [80, 80], "bounds": [260, 260], + "contentsOpaqueForText": true, "invalidations": [ [80, 80, 100, 100], [0, 0, 100, 100] @@ -135,6 +138,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV id='A' class='overlap1')", "position": [80, 80], "bounds": [260, 260], + "contentsOpaqueForText": true, "invalidations": [ [160, 160, 100, 100], [80, 80, 100, 100] @@ -175,6 +179,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV id='A' class='overlap1')", "position": [80, 80], "bounds": [260, 260], + "contentsOpaqueForText": true, "invalidations": [ [160, 160, 100, 100], [0, 0, 100, 100]
diff --git a/third_party/blink/web_tests/compositing/squashing/squashing-sparsity-heuristic-expected.txt b/third_party/blink/web_tests/compositing/squashing/squashing-sparsity-heuristic-expected.txt index fe1693d8..168713d4 100644 --- a/third_party/blink/web_tests/compositing/squashing/squashing-sparsity-heuristic-expected.txt +++ b/third_party/blink/web_tests/compositing/squashing/squashing-sparsity-heuristic-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV id='A' class='overlap1')", "position": [80, 80], "bounds": [10, 10], + "contentsOpaqueForText": true, "transform": 1 }, { @@ -29,7 +30,8 @@ { "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV id='C' class='overlap3')", "position": [220, 300], - "bounds": [25, 10] + "bounds": [25, 10], + "contentsOpaqueForText": true } ], "transforms": [
diff --git a/third_party/blink/web_tests/css3/blending/mix-blend-mode-composited-reason-children-expected.txt b/third_party/blink/web_tests/css3/blending/mix-blend-mode-composited-reason-children-expected.txt index 33da06e..01509ac6 100644 --- a/third_party/blink/web_tests/css3/blending/mix-blend-mode-composited-reason-children-expected.txt +++ b/third_party/blink/web_tests/css3/blending/mix-blend-mode-composited-reason-children-expected.txt
@@ -21,6 +21,7 @@ { "name": "LayoutNGBlockFlow DIV class='blended'", "bounds": [160, 90], + "contentsOpaqueForText": true, "backgroundColor": "#0000FF", "transform": 1 },
diff --git a/third_party/blink/web_tests/editing/selection/linux_selection_color-expected.png b/third_party/blink/web_tests/editing/selection/linux_selection_color-expected.png deleted file mode 100644 index f91f864..0000000 --- a/third_party/blink/web_tests/editing/selection/linux_selection_color-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/editing/selection/linux_selection_color.html b/third_party/blink/web_tests/editing/selection/linux_selection_color.html deleted file mode 100644 index 8e90091a..0000000 --- a/third_party/blink/web_tests/editing/selection/linux_selection_color.html +++ /dev/null
@@ -1,21 +0,0 @@ -<html> -<body> -<div> -<p id="text"> -This tests that the methods that set selection colors for Linux work correctly. -</p> -<p>(All the text in the above sentence should be highlighted red with green text)</p> -</div> -<script> -if (window.testRunner) { - testRunner.forceRedSelectionColors() -} - -var div = document.getElementById("text"); -var sel = window.getSelection(); -var range = document.createRange(); -range.selectNode(div); -sel.addRange(range); -</script> -</body> -</html>
diff --git a/third_party/blink/web_tests/external/wpt/client-hints/accept-ch-stickiness/cross-origin-subresource-redirect-with-fp-delegation.https.html b/third_party/blink/web_tests/external/wpt/client-hints/accept-ch-stickiness/cross-origin-subresource-redirect-with-fp-delegation.https.html index 8e94bba..dd7b9fa 100644 --- a/third_party/blink/web_tests/external/wpt/client-hints/accept-ch-stickiness/cross-origin-subresource-redirect-with-fp-delegation.https.html +++ b/third_party/blink/web_tests/external/wpt/client-hints/accept-ch-stickiness/cross-origin-subresource-redirect-with-fp-delegation.https.html
@@ -9,7 +9,7 @@ <script> // Make sure a cross origin subresource that gets redirected with Feature Policy delegation keeps the initial request's Client Hints. -const test_name = "cross-origin subresource redirect with Feature Policy delegaation"; +const test_name = "cross-origin subresource redirect with Feature Policy delegation"; verify_subresource_state("resources/accept-ch-and-redir.py?url=" + get_host_info()["HTTPS_REMOTE_ORIGIN"] + "/client-hints/accept-ch-stickiness/resources/expect-received.py", test_name); </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/client-hints/accept-ch-stickiness/resources/expect-received.py b/third_party/blink/web_tests/external/wpt/client-hints/accept-ch-stickiness/resources/expect-received.py index 7a2874e..bec3bffc 100644 --- a/third_party/blink/web_tests/external/wpt/client-hints/accept-ch-stickiness/resources/expect-received.py +++ b/third_party/blink/web_tests/external/wpt/client-hints/accept-ch-stickiness/resources/expect-received.py
@@ -5,7 +5,7 @@ verify_navigation_state() in accept-ch-test.js """ - if "device-memory" in request.headers: + if "device-memory" in request.headers and "sec-ch-ua" in request.headers and "sec-ch-ua-mobile" in request.headers: result = "PASS" else: result = "FAIL"
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-platform-specific-write-read.tentative.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-platform-specific-write-read.tentative.https.html index c1e8323..685b5a58 100644 --- a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-platform-specific-write-read.tentative.https.html +++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-platform-specific-write-read.tentative.https.html
@@ -2,8 +2,12 @@ <meta charset="utf-8"> <title>Async Clipboard raw platform-specific write -> read tests</title> <link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> +<body>Body needed for test_driver.click()</body> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="resources/user-activation.js"></script> <script> 'use strict'; @@ -11,6 +15,7 @@ const format = 'RawClipboardDisabledFormat'; const blob = new Blob(['RawClipboardDisabled'], {type: format}); const clipboardItem = new ClipboardItem({[format]: blob}, {raw: true}); + await waitForUserActivation(); await navigator.clipboard.write([clipboardItem]); } @@ -38,9 +43,11 @@ assert_equals(blobInput.type, format.toLowerCase()); const clipboardItemInput = new ClipboardItem( {[format]: blobInput}, {raw: true}); + await waitForUserActivation(); await navigator.clipboard.write([clipboardItemInput]); // Items should be readable on a raw clipboard after raw write. + await waitForUserActivation(); const clipboardItems = await navigator.clipboard.read({raw: true}); assert_equals(clipboardItems.length, 1); const clipboardItem = clipboardItems[0]; @@ -57,7 +64,6 @@ // accessible as text. const textOutput = await navigator.clipboard.readText(); assert_equals(textOutput, dataToWrite); - }, 'Verify write and read clipboard given platform-specific raw input'); </script> <p>
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-raw-write-read.tentative.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-raw-write-read.tentative.https.html index bd11a7f0..e6882b3 100644 --- a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-raw-write-read.tentative.https.html +++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-raw-write-read.tentative.https.html
@@ -2,8 +2,12 @@ <meta charset="utf-8"> <title>Async Clipboard raw write -> Async Clipboard raw read test</title> <link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> +<body>Body needed for test_driver.click()</body> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="resources/user-activation.js"></script> <script> 'use strict'; @@ -16,6 +20,7 @@ const blobInput2 = new Blob(['input data 2'], {type: format2}); const clipboardItemInput = new ClipboardItem( {[format1]: blobInput1, [format2]: blobInput2}, {raw: true}); + await waitForUserActivation(); await navigator.clipboard.write([clipboardItemInput]); // Items may not be readable on the sanitized clipboard after raw write. @@ -23,6 +28,7 @@ navigator.clipboard.read({raw: false})); // Items should be readable on a raw clipboard after raw write. + await waitForUserActivation(); const clipboardItems = await navigator.clipboard.read({raw: true}); assert_equals(clipboardItems.length, 1); const clipboardItem = clipboardItems[0]; @@ -41,7 +47,6 @@ assert_equals(data2, 'input data 2'); }, 'Verify write and read clipboard given 2 platform-neutral raw inputs'); - </script> <p> Note: This is a manual test because it writes/reads to the shared system
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/resources/user-activation.js b/third_party/blink/web_tests/external/wpt/clipboard-apis/resources/user-activation.js new file mode 100644 index 0000000..babd5b2 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/resources/user-activation.js
@@ -0,0 +1,21 @@ +'use strict'; + +// In order to use this function, please import testdriver.js and +// testdriver-vendor.js, and include a <body> element. +async function waitForUserActivation() { + const loadedPromise = new Promise(resolve => { + if(document.readyState == 'complete') { + resolve(); + return; + } + window.addEventListener('load', resolve, {once: true}); + }); + await loadedPromise; + + const clickedPromise = new Promise(resolve => { + document.body.addEventListener('click', resolve, {once: true}); + }); + + test_driver.click(document.body); + await clickedPromise; +}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/align-items-008.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/align-items-008.html new file mode 100644 index 0000000..88aa106 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/align-items-008.html
@@ -0,0 +1,12 @@ +<!DOCTYPE html> +<link rel="match" href="../reference/ref-filled-green-100px-square.xht" /> +<link rel="help" href="https://crbug.com/1081086" /> +<meta name="assert" content="Tests that certain dynamic changes don't lead to an incorrectly sized flex-item." /> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div id="target" style="display: flex; min-height: 200px;"> + <div style="width: 100px; min-height: 100px; background: green;"></div> +</div> +<script> +document.body.offsetTop; +document.getElementById('target').style.alignItems = 'flex-start'; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/orthogonal-flex-item-crash.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/orthogonal-flex-item-crash.html new file mode 100644 index 0000000..056d6588 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/orthogonal-flex-item-crash.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<link rel="help" href="https://crbug.com/1081086" /> +<meta name="assert" content="This test ensures that orthogonal flex and flex-items does not crash." /> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<body style="width: 100px; height: 100px; font: 12px/1 Ahem;"> + <div style="display: flex; writing-mode: vertical-rl;"> + text text + <div style="min-height: 0; writing-mode: horizontal-tb;"> + <span id="target"></span> + text + </div> + </div> +</body> +<script> +document.body.offsetTop; +const target = document.getElementById('target'); +target.parentElement.appendChild(target); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-sizing/aspect-ratio/block-aspect-ratio-015.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-sizing/aspect-ratio/block-aspect-ratio-015.tentative.html new file mode 100644 index 0000000..3f9e833f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-sizing/aspect-ratio/block-aspect-ratio-015.tentative.html
@@ -0,0 +1,11 @@ +<!DOCTYPE html> +<title>CSS aspect-ratio: div inline size + min-width: auto</title> +<link rel="author" title="Google LLC" href="https://www.google.com/"> +<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio"> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht" /> + +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> + +<div style="background: green; height: 100px; aspect-ratio: 1/2;"> + <div style="width: 100px;"></div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-sizing/aspect-ratio/block-aspect-ratio-016.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-sizing/aspect-ratio/block-aspect-ratio-016.tentative.html new file mode 100644 index 0000000..7bd21e91 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-sizing/aspect-ratio/block-aspect-ratio-016.tentative.html
@@ -0,0 +1,12 @@ +<!DOCTYPE html> +<title>CSS aspect-ratio: div inline size + min-width: auto</title> +<link rel="author" title="Google LLC" href="https://www.google.com/"> +<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio"> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht" /> +<meta name="assert" content="With min-width: auto and content smaller than the aspect ratio size, we should still size per aspect-ratio"> + +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> + +<div style="background: green; height: 100px; aspect-ratio: 1/1;"> + <div style="width: 50px"></div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-sizing/aspect-ratio/block-aspect-ratio-017.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-sizing/aspect-ratio/block-aspect-ratio-017.tentative.html new file mode 100644 index 0000000..4ea0d69 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-sizing/aspect-ratio/block-aspect-ratio-017.tentative.html
@@ -0,0 +1,11 @@ +<!DOCTYPE html> +<title>CSS aspect-ratio: div inline size + min-width: auto</title> +<link rel="author" title="Google LLC" href="https://www.google.com/"> +<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio"> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht" /> + +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> + +<div style="writing-mode: vertical-lr; background: green; width: 100px; aspect-ratio: 2/1;"> + <div style="height: 100px"></div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-sizing/aspect-ratio/block-aspect-ratio-018.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-sizing/aspect-ratio/block-aspect-ratio-018.tentative.html new file mode 100644 index 0000000..6c92b32 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-sizing/aspect-ratio/block-aspect-ratio-018.tentative.html
@@ -0,0 +1,13 @@ +<!DOCTYPE html> +<title>CSS aspect-ratio: div inline size + min-width: auto</title> +<link rel="author" title="Google LLC" href="https://www.google.com/"> +<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio"> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht" /> +<meta name="assert" content="Setting overflow to non-visible/clip should not apply min-width: auto"> + +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> + +<div style="background: green; height: 100px; aspect-ratio: 1/1; overflow: hidden;"> + <div style="width: 100px; display: inline-block;"></div> + <div style="width: 500px; display: inline-block; background: red;"></div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/event-timing/auxclick.html b/third_party/blink/web_tests/external/wpt/event-timing/auxclick.html index f0d8326..b88328e2a 100644 --- a/third_party/blink/web_tests/external/wpt/event-timing/auxclick.html +++ b/third_party/blink/web_tests/external/wpt/event-timing/auxclick.html
@@ -9,7 +9,6 @@ <script src=/resources/testdriver-vendor.js></script> <script src=resources/event-timing-test-utils.js></script> <div id='target'>Click me</div> -<button id='button'>Click me</button> <script> promise_test(async t => { return testEventType(t, 'auxclick');
diff --git a/third_party/blink/web_tests/external/wpt/event-timing/click.html b/third_party/blink/web_tests/external/wpt/event-timing/click.html new file mode 100644 index 0000000..e3eecab --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/event-timing/click.html
@@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html> +<meta charset=utf-8 /> +<title>Event Timing click.</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src=/resources/testdriver.js></script> +<script src=/resources/testdriver-actions.js></script> +<script src=/resources/testdriver-vendor.js></script> +<script src=resources/event-timing-test-utils.js></script> +<div id='target'>Click me</div> +<script> + promise_test(async t => { + return testEventType(t, 'click'); + }) +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/event-timing/contextmenu.html b/third_party/blink/web_tests/external/wpt/event-timing/contextmenu.html new file mode 100644 index 0000000..9aa05a3 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/event-timing/contextmenu.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<html> +<meta charset=utf-8 /> +<title>Event Timing contextmenu.</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src=/resources/testdriver.js></script> +<script src=/resources/testdriver-actions.js></script> +<script src=/resources/testdriver-vendor.js></script> +<script src=resources/event-timing-test-utils.js></script> +<div id='target' contextmenu="mymenu">Menu +<menu type="context" id="mymenu"> + <menuitem label="label"></menuitem> +</menu> +</div> +<script> + promise_test(async t => { + return testEventType(t, 'contextmenu'); + }) +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/event-timing/dblclick.html b/third_party/blink/web_tests/external/wpt/event-timing/dblclick.html new file mode 100644 index 0000000..d33fcfd3 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/event-timing/dblclick.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<meta charset=utf-8 /> +<title>Event Timing dblclick.</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src=/resources/testdriver.js></script> +<script src=/resources/testdriver-actions.js></script> +<script src=/resources/testdriver-vendor.js></script> +<script src=resources/event-timing-test-utils.js></script> +<div>Outside target!</div> +<div id='target'>Click me</div> +<script> + promise_test(async t => { + return testEventType(t, 'dblclick'); + }) +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/event-timing/mousedown.html b/third_party/blink/web_tests/external/wpt/event-timing/mousedown.html new file mode 100644 index 0000000..e0f14f4c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/event-timing/mousedown.html
@@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html> +<meta charset=utf-8 /> +<title>Event Timing mousedown.</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src=/resources/testdriver.js></script> +<script src=/resources/testdriver-actions.js></script> +<script src=/resources/testdriver-vendor.js></script> +<script src=resources/event-timing-test-utils.js></script> +<div id='target'>Click me</div> +<script> + promise_test(async t => { + return testEventType(t, 'mousedown'); + }) +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/event-timing/mouseenter.html b/third_party/blink/web_tests/external/wpt/event-timing/mouseenter.html new file mode 100644 index 0000000..804d574 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/event-timing/mouseenter.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<meta charset=utf-8 /> +<title>Event Timing mouseenter.</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src=/resources/testdriver.js></script> +<script src=/resources/testdriver-actions.js></script> +<script src=/resources/testdriver-vendor.js></script> +<script src=resources/event-timing-test-utils.js></script> +<div>Outside target!</div> +<div id='target'>Target</div> +<script> + promise_test(async t => { + return testEventType(t, 'mouseenter'); + }) +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/event-timing/mouseleave.html b/third_party/blink/web_tests/external/wpt/event-timing/mouseleave.html new file mode 100644 index 0000000..202cf73 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/event-timing/mouseleave.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<meta charset=utf-8 /> +<title>Event Timing mouseleave.</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src=/resources/testdriver.js></script> +<script src=/resources/testdriver-actions.js></script> +<script src=/resources/testdriver-vendor.js></script> +<script src=resources/event-timing-test-utils.js></script> +<div>Outside target!</div> +<div id='target'>Target</div> +<script> + promise_test(async t => { + return testEventType(t, 'mouseleave'); + }) +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/event-timing/mouseout.html b/third_party/blink/web_tests/external/wpt/event-timing/mouseout.html new file mode 100644 index 0000000..dd32193 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/event-timing/mouseout.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<meta charset=utf-8 /> +<title>Event Timing mouseout.</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src=/resources/testdriver.js></script> +<script src=/resources/testdriver-actions.js></script> +<script src=/resources/testdriver-vendor.js></script> +<script src=resources/event-timing-test-utils.js></script> +<div>Outside target!</div> +<div id='target'>Target</div> +<script> + promise_test(async t => { + return testEventType(t, 'mouseout', true /* looseCount */); + }) +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/event-timing/mouseover.html b/third_party/blink/web_tests/external/wpt/event-timing/mouseover.html new file mode 100644 index 0000000..741ee2d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/event-timing/mouseover.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<meta charset=utf-8 /> +<title>Event Timing mouseover.</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src=/resources/testdriver.js></script> +<script src=/resources/testdriver-actions.js></script> +<script src=/resources/testdriver-vendor.js></script> +<script src=resources/event-timing-test-utils.js></script> +<div>Outside target!</div> +<div id='target'>Target</div> +<script> + promise_test(async t => { + return testEventType(t, 'mouseover', true /* looseCount */); + }) +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/event-timing/mouseup.html b/third_party/blink/web_tests/external/wpt/event-timing/mouseup.html new file mode 100644 index 0000000..653bef8f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/event-timing/mouseup.html
@@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html> +<meta charset=utf-8 /> +<title>Event Timing mouseup.</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src=/resources/testdriver.js></script> +<script src=/resources/testdriver-actions.js></script> +<script src=/resources/testdriver-vendor.js></script> +<script src=resources/event-timing-test-utils.js></script> +<div id='target'>Target</div> +<script> + promise_test(async t => { + return testEventType(t, 'mouseup'); + }) +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/event-timing/pointerdown.html b/third_party/blink/web_tests/external/wpt/event-timing/pointerdown.html new file mode 100644 index 0000000..3d7dcbe8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/event-timing/pointerdown.html
@@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html> +<meta charset=utf-8 /> +<title>Event Timing pointerdown.</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src=/resources/testdriver.js></script> +<script src=/resources/testdriver-actions.js></script> +<script src=/resources/testdriver-vendor.js></script> +<script src=resources/event-timing-test-utils.js></script> +<div id='target'>Target</div> +<script> + promise_test(async t => { + return testEventType(t, 'pointerdown'); + }) +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/event-timing/pointerenter.html b/third_party/blink/web_tests/external/wpt/event-timing/pointerenter.html new file mode 100644 index 0000000..bae1c51 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/event-timing/pointerenter.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<meta charset=utf-8 /> +<title>Event Timing pointerenter.</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src=/resources/testdriver.js></script> +<script src=/resources/testdriver-actions.js></script> +<script src=/resources/testdriver-vendor.js></script> +<script src=resources/event-timing-test-utils.js></script> +<div>Outside target!</div> +<div id='target'>Target</div> +<script> + promise_test(async t => { + return testEventType(t, 'pointerenter'); + }) +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/event-timing/pointerleave.html b/third_party/blink/web_tests/external/wpt/event-timing/pointerleave.html new file mode 100644 index 0000000..81e8f15 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/event-timing/pointerleave.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<meta charset=utf-8 /> +<title>Event Timing pointerleave.</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src=/resources/testdriver.js></script> +<script src=/resources/testdriver-actions.js></script> +<script src=/resources/testdriver-vendor.js></script> +<script src=resources/event-timing-test-utils.js></script> +<div>Outside target!</div> +<div id='target'>Target</div> +<script> + promise_test(async t => { + return testEventType(t, 'pointerleave'); + }) +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/event-timing/pointerout.html b/third_party/blink/web_tests/external/wpt/event-timing/pointerout.html new file mode 100644 index 0000000..b08f5769 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/event-timing/pointerout.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<meta charset=utf-8 /> +<title>Event Timing pointerout.</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src=/resources/testdriver.js></script> +<script src=/resources/testdriver-actions.js></script> +<script src=/resources/testdriver-vendor.js></script> +<script src=resources/event-timing-test-utils.js></script> +<div>Outside target!</div> +<div id='target'>Target</div> +<script> + promise_test(async t => { + return testEventType(t, 'pointerout', true /* looseCount */); + }) +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/event-timing/pointerover.html b/third_party/blink/web_tests/external/wpt/event-timing/pointerover.html new file mode 100644 index 0000000..0e17122 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/event-timing/pointerover.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<meta charset=utf-8 /> +<title>Event Timing pointerover.</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src=/resources/testdriver.js></script> +<script src=/resources/testdriver-actions.js></script> +<script src=/resources/testdriver-vendor.js></script> +<script src=resources/event-timing-test-utils.js></script> +<div>Outside target!</div> +<div id='target'>Target</div> +<script> + promise_test(async t => { + return testEventType(t, 'pointerover', true /* looseCount */); + }) +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/event-timing/pointerup.html b/third_party/blink/web_tests/external/wpt/event-timing/pointerup.html new file mode 100644 index 0000000..4324a5b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/event-timing/pointerup.html
@@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html> +<meta charset=utf-8 /> +<title>Event Timing pointerup.</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src=/resources/testdriver.js></script> +<script src=/resources/testdriver-actions.js></script> +<script src=/resources/testdriver-vendor.js></script> +<script src=resources/event-timing-test-utils.js></script> +<div id='target'>Target</div> +<script> + promise_test(async t => { + return testEventType(t, 'pointerup'); + }) +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/event-timing/resources/event-timing-test-utils.js b/third_party/blink/web_tests/external/wpt/event-timing/resources/event-timing-test-utils.js index 9f4a8171..d034258 100644 --- a/third_party/blink/web_tests/external/wpt/event-timing/resources/event-timing-test-utils.js +++ b/third_party/blink/web_tests/external/wpt/event-timing/resources/event-timing-test-utils.js
@@ -22,8 +22,8 @@ // to check that the event also happens to correspond to the first event. In this case, the // timings of the 'first-input' entry should be equal to those of this entry. |minDuration| // is used to compared against entry.duration. -function verifyEvent(entry, eventType, targetId, isFirst=false, minDuration=104) { - assert_true(entry.cancelable); +function verifyEvent(entry, eventType, targetId, isFirst=false, minDuration=104, notCancelable=false) { + assert_equals(entry.cancelable, !notCancelable, 'cancelable property'); assert_equals(entry.name, eventType); assert_equals(entry.entryType, 'event'); assert_greater_than_equal(entry.duration, minDuration, @@ -122,51 +122,131 @@ return Promise.all([observerPromise, clicksPromise]); } -function applyAction(actions, eventType, target) { +// Apply events that trigger an event of the given |eventType| to be dispatched to the +// |target|. Some of these assume that the target is not on the top left corner of the +// screen, which means that (0, 0) of the viewport is outside of the |target|. +function applyAction(eventType, target) { + const actions = new test_driver.Actions(); if (eventType === 'auxclick') { actions.pointerMove(0, 0, {origin: target}) .pointerDown({button: actions.ButtonType.MIDDLE}) .pointerUp({button: actions.ButtonType.MIDDLE}); + } else if (eventType === 'click' || eventType === 'mousedown' || eventType === 'mouseup' + || eventType === 'pointerdown' || eventType === 'pointerup' + || eventType === 'touchstart' || eventType === 'touchend') { + actions.pointerMove(0, 0, {origin: target}) + .pointerDown() + .pointerUp(); + } else if (eventType === 'contextmenu') { + actions.pointerMove(0, 0, {origin: target}) + .pointerDown({button: actions.ButtonType.RIGHT}) + .pointerUp({button: actions.ButtonType.RIGHT}); + } else if (eventType === 'dblclick') { + actions.pointerMove(0, 0, {origin: target}) + .pointerDown() + .pointerUp() + .pointerDown() + .pointerUp() + // Reset by clicking outside of the target. + .pointerMove(0, 0) + .pointerDown() + .pointerUp(); + } else if (eventType === 'mouseenter' || eventType === 'mouseover' + || eventType === 'pointerenter' || eventType === 'pointerover') { + // Move outside of the target and then back inside. + actions.pointerMove(0, 0) + .pointerMove(0, 0, {origin: target}); + } else if (eventType === 'mouseleave' || eventType === 'mouseout' + || eventType === 'pointerleave' || eventType === 'pointerout') { + actions.pointerMove(0, 0, {origin: target}) + .pointerMove(0, 0); } else { assert_unreached('The event type ' + eventType + ' is not supported.'); } + return actions.send(); } -// Tests the given |eventType| by creating events whose target are the element with id 'target'. -// The test assumes that such element already exists. -async function testEventType(t, eventType) { +function requiresListener(eventType) { + return ['mouseenter', + 'mouseleave', + 'pointerdown', + 'pointerenter', + 'pointerleave', + 'pointerout', + 'pointerover', + 'pointerup' + ].includes(eventType); +} + +function notCancelable(eventType) { + return ['mouseenter', 'mouseleave', 'pointerenter', 'pointerleave'].includes(eventType); +} + +// Tests the given |eventType| by creating events whose target are the element with id +// 'target'. The test assumes that such element already exists. |looseCount| is set for +// eventTypes for which events would occur for other elements besides the target, so the +// counts will be larger. +async function testEventType(t, eventType, looseCount=false) { assert_implements(window.EventCounts, "Event Counts isn't supported"); assert_equals(performance.eventCounts.get(eventType), 0); const target = document.getElementById('target'); - const actions = new test_driver.Actions(); + if (requiresListener(eventType)) { + target.addEventListener(eventType, () =>{}); + } + assert_equals(performance.eventCounts.get(eventType), 0, 'No events yet.'); // Trigger two 'fast' events of the type. - applyAction(actions, eventType, target); - applyAction(actions, eventType, target); - await actions.send(); - assert_equals(performance.eventCounts.get('auxclick'), 2); + await applyAction(eventType, target); + await applyAction(eventType, target); + if (looseCount) { + assert_greater_than_equal(performance.eventCounts.get(eventType), 2, + `Should have at least 2 ${eventType} events`) + } else { + assert_equals(performance.eventCounts.get(eventType), 2, + `Should have 2 ${eventType} events`); + } // The durationThreshold used by the observer. A slow events needs to be slower than that. const durationThreshold = 16; // Now add an event handler to cause a slow event. target.addEventListener(eventType, () => { mainThreadBusy(durationThreshold + 4); }); - return new Promise(async resolve => { + const observerPromise = new Promise(async resolve => { new PerformanceObserver(t.step_func(entryList => { let eventTypeEntries = entryList.getEntriesByName(eventType); if (eventTypeEntries.length === 0) return; - assert_equals(eventTypeEntries.length, 1); - verifyEvent(eventTypeEntries[0], + let entry = null; + if (!looseCount) { + entry = eventTypeEntries[0]; + assert_equals(eventTypeEntries.length, 1); + } else { + // The other events could also be considered slow. Find the one with the correct + // target. + eventTypeEntries.forEach(e => { + if (e.target === document.getElementById('target')) + entry = e; + }); + if (!entry) + return; + } + verifyEvent(entry, eventType, 'target', false /* isFirst */, - durationThreshold); - assert_equals(performance.eventCounts.get(eventType), 3); + durationThreshold, + notCancelable(eventType)); + if (looseCount) { + assert_greater_than_equal(performance.eventCounts.get(eventType), 3, + `Should have at least 3 ${eventType} events`) + } else { + assert_equals(performance.eventCounts.get(eventType), 3, + `Should have 3 ${eventType} events`); + } resolve(); })).observe({type: 'event', durationThreshold: durationThreshold}); - // Cause a slow event. - applyAction(actions, eventType, target); - actions.send(); }); -} \ No newline at end of file + // Cause a slow event. + let actionPromise = applyAction(eventType, target); + return Promise.all([actionPromise, observerPromise]); +}
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/feature-policy-for-sandbox/feature-propagation-to-auxiliary-context.html b/third_party/blink/web_tests/external/wpt/feature-policy/feature-policy-for-sandbox/feature-propagation-to-auxiliary-context.html index 118ccac..86cdcb3 100644 --- a/third_party/blink/web_tests/external/wpt/feature-policy/feature-policy-for-sandbox/feature-propagation-to-auxiliary-context.html +++ b/third_party/blink/web_tests/external/wpt/feature-policy/feature-policy-for-sandbox/feature-propagation-to-auxiliary-context.html
@@ -1,6 +1,5 @@ <!DOCTYPE html> <head> -<meta name="timeout" content="long"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> </head> @@ -16,48 +15,57 @@ const window_url_main = "/feature-policy/feature-policy-for-sandbox/resources/opened_window.html"; promise_test( async () => { - for (const feature of features_that_propagate) { - const iframe = await add_iframe( - {src: iframe_src, allow: `${feature} 'none'`}); - iframe.contentWindow.postMessage({type: "feature", feature: feature}, "*"); - const iframe_state = await feature_update(feature); - assert_false(iframe_state, `'${feature}' is not disabled in <iframe>.'`); - iframe.contentWindow.postMessage({ - type: "open_window", - url: `${window_url_main}?${feature}` - }, "*"); - const window_state = await feature_update(feature); - assert_false(window_state, - `'${feature}' is not disabled in new window.`); - const did_close = await close_aux_window(iframe); - assert_true(did_close); - iframe.parentElement.removeChild(iframe); - } + const iframe = await add_iframe({ + src: iframe_src, + allow: features_that_propagate.map(feature => `${feature} 'none'`).join(", ") + }); + + iframe.contentWindow.postMessage( + {type: "features", features: features_that_propagate}, "*"); + const iframe_states = await feature_update(); + for (const [feature, state] of iframe_states) + assert_false(state, `'${feature}' is not disabled in <iframe>.'`); + + iframe.contentWindow.postMessage({ + type: "open_window", + url: `${window_url_main}?${features_that_propagate.join("&")}` + }, "*"); + const window_states = await feature_update(); + for (const [feature, state] of iframe_states) + assert_false(state, `'${feature}' is not disabled in new window.`); + + const did_close = await close_aux_window(iframe); + assert_true(did_close); + iframe.parentElement.removeChild(iframe); }, "Verify feature policies are inherited by the auxiliary browsing context " + "if opened from a non-sandboxed same-origin <iframe>."); -promise_test( async() => { - for (const feature of features_that_propagate) { - const iframe = await add_iframe({ - src: iframe_src, - allow: `${feature} 'none'`, - sandbox: "allow-scripts allow-popups allow-popups-to-escape-sandbox"}); - iframe.contentWindow.postMessage({type: "feature", feature: feature}, "*"); - const iframe_state = await feature_update(feature); - assert_false(iframe_state, - `'${feature}' is not disabled in <iframe>.'`); - iframe.contentWindow.postMessage({ - type: "open_window", - url: `${window_url_main}?${feature}` - }, "*"); - const window_state = await feature_update(feature); - assert_true(window_state, `'${feature}' is disabled.`); - const did_close = await close_aux_window(iframe); - assert_true(did_close); - iframe.parentElement.removeChild(iframe); - } +promise_test( async () => { + const iframe = await add_iframe({ + src: iframe_src, + allow: features_that_propagate.map(feature => `${feature} 'none'`).join(", "), + sandbox: "allow-scripts allow-popups allow-popups-to-escape-sandbox" + }); + + iframe.contentWindow.postMessage( + {type: "features", features: features_that_propagate}, "*"); + const iframe_states = await feature_update(); + for (const [feature, state] of iframe_states) + assert_false(state, `'${feature}' is not disabled in <iframe>.'`); + + iframe.contentWindow.postMessage({ + type: "open_window", + url: `${window_url_main}?${features_that_propagate.join("&")}` + }, "*"); + const window_states = await feature_update(); + for (const [feature, state] of window_states) + assert_true(state, `'${feature}' is disabled in new window.`); + + const did_close = await close_aux_window(iframe); + assert_true(did_close); + iframe.parentElement.removeChild(iframe); }, "Verify feature policies are NOT inherited by the auxiliary browsing " + - "context if opened from a sandboxed same-origin <iframe> which allows " + - "popups to escape sandbox."); + "context if opened from a sandboxed same-origin <iframe> which allows " + + "popups to escape sandbox."); </script> -</body> \ No newline at end of file +</body>
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/feature-policy-for-sandbox/resources/helper.js b/third_party/blink/web_tests/external/wpt/feature-policy/feature-policy-for-sandbox/resources/helper.js index eec1898..4c55352 100644 --- a/third_party/blink/web_tests/external/wpt/feature-policy/feature-policy-for-sandbox/resources/helper.js +++ b/third_party/blink/web_tests/external/wpt/feature-policy/feature-policy-for-sandbox/resources/helper.js
@@ -52,29 +52,30 @@ } // Returns a promise which is resolved with the next/already received message -// with feature update for |feature|. The resolved value is the state of the -// feature |feature|. If |optional_timeout| is provided, after the given delay +// with features update for |features|. The resolved value is the state of the +// features |features|. If |optional_timeout| is provided, after the given delay // (in terms of rafs) the promise is resolved with false. -function feature_update(feature, optional_timeout_rafs) { +function feature_update(optional_timeout_rafs) { function reset_for_next_update() { return new Promise((r) => { - const state = last_feature_message.state; + const states = last_feature_message.states; last_feature_message = null; - r(state); + r(states); }); } - if (last_feature_message && last_feature_message.feature === feature) + + if (last_feature_message) return reset_for_next_update(); if (optional_timeout_rafs) { wait_for_raf_count(optional_timeout_rafs).then (() => { - last_feature_message = {state: false}; + last_feature_message = {states: []}; on_new_feature_callback(); }); } return new Promise((r) => on_new_feature_callback = r) - .then(() => reset_for_next_update()); + .then(reset_for_next_update); } function close_aux_window(iframe) { @@ -88,7 +89,7 @@ var msg = e.data; assert_true("type" in msg); switch (msg.type) { - case "feature": + case "features": on_feature_msg(msg); break; case "close_window": @@ -98,9 +99,8 @@ } function on_feature_msg(msg) { - assert_true("feature" in msg); - assert_true("state" in msg); - last_feature_message = msg + assert_true("states" in msg); + last_feature_message = msg; if (on_new_feature_callback) { on_new_feature_callback(); on_new_feature_callback = null;
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/feature-policy-for-sandbox/resources/opened_window.js b/third_party/blink/web_tests/external/wpt/feature-policy/feature-policy-for-sandbox/resources/opened_window.js index 189eb155..d69c75c 100644 --- a/third_party/blink/web_tests/external/wpt/feature-policy/feature-policy-for-sandbox/resources/opened_window.js +++ b/third_party/blink/web_tests/external/wpt/feature-policy/feature-policy-for-sandbox/resources/opened_window.js
@@ -1,7 +1,9 @@ -var feature = window.location.search.substr(1); -var state = document.featurePolicy.allowsFeature(feature); +const features = window.location.search.substr(1).split("&"); +const states = features + .map(feature => [feature, document.featurePolicy.allowsFeature(feature)]); + // TODO(ekaramad): We might at some point choose a different propagation // strategy with rel=noopener. This test should adapt accordingly (perhaps use // broadcast channels). window.opener.parent.postMessage( - {type: "feature", feature: feature, state: state}, "*"); + {type: "features", states: states}, "*");
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/feature-policy-for-sandbox/resources/window_opener.js b/third_party/blink/web_tests/external/wpt/feature-policy/feature-policy-for-sandbox/resources/window_opener.js index 263a17b..6788c25 100644 --- a/third_party/blink/web_tests/external/wpt/feature-policy/feature-policy-for-sandbox/resources/window_opener.js +++ b/third_party/blink/web_tests/external/wpt/feature-policy/feature-policy-for-sandbox/resources/window_opener.js
@@ -2,12 +2,13 @@ window.addEventListener("message", (e) => { var msg = e.data; switch (msg.type) { - case "feature": - var state = document.featurePolicy.allowsFeature(msg.feature); + case "features": e.source.postMessage({ - type: "feature", - feature: msg.feature, - state: state}, "*"); + type: "features", + states: + msg.features + .map(feature => [feature, document.featurePolicy.allowsFeature(feature)]) + }, "*"); break; case "open_window": auxiliary_context = window.open(msg.url);
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/feature-policy-for-sandbox/sandbox-policies-in-allow-attribute.html b/third_party/blink/web_tests/external/wpt/feature-policy/feature-policy-for-sandbox/sandbox-policies-in-allow-attribute.html index a29d43e5..c9e2d711 100644 --- a/third_party/blink/web_tests/external/wpt/feature-policy/feature-policy-for-sandbox/sandbox-policies-in-allow-attribute.html +++ b/third_party/blink/web_tests/external/wpt/feature-policy/feature-policy-for-sandbox/sandbox-policies-in-allow-attribute.html
@@ -12,35 +12,53 @@ const iframe_src = "/feature-policy/feature-policy-for-sandbox/resources/window_opener.html"; promise_test( async () => { - for (const feature of sandbox_features) { - // For the test to work correctly we need "scripts"; - const sandbox_flags = feature === "scripts" ? "" : "allow-scripts"; - const iframe = await add_iframe( - {src: iframe_src, allow: `${feature} *`, sandbox: sandbox_flags}); - iframe.contentWindow.postMessage({type: "feature", feature: feature}, "*"); - const iframe_state = await feature_update(feature); - assert_true(iframe_state, - `'${feature}' should not be disabled in <iframe>.'`); - iframe.parentElement.removeChild(iframe); - } + const iframe = await add_iframe({ + src: iframe_src, + allow: sandbox_features.map(feature => `${feature} *`).join(", "), + sandbox: "" + }); + + iframe.contentWindow.postMessage({type: "features", features: sandbox_features}, "*"); + const iframe_states = await feature_update(); + for (const [feature, state] of iframe_states) + assert_true(state, `'${feature}' should not be disabled in <iframe>.'`); + + iframe.parentElement.removeChild(iframe); }, "Verify that when a sandbox related feature is enabled in 'allow' then " + " the feature will be enabled regardless of sandbox attribute's value."); -promise_test( async() => { - for (const feature of sandbox_features) { - const sandbox_flags = `allow-${feature} allow-scripts`; - const iframe = await add_iframe( - {src: iframe_src, allow: `${feature} 'none'`, sandbox: sandbox_flags}); - iframe.contentWindow.postMessage({type: "feature", feature: feature}, "*"); - // 'scripts' will block running code in the subframe and no update can be - // sent. A timeout determines the feature is disabled. - const timeout = (feature === "scripts") ? 10 : false; - const iframe_state = await feature_update(feature, timeout); - assert_false(iframe_state, - `'${feature}' should be disabled in <iframe>.'`); - iframe.parentElement.removeChild(iframe); - } -}, "Verify that when a sandbox related feature is disabled in 'allow' then " + +promise_test( async () => { + const non_script_sandbox_features = + sandbox_features.filter(feature => feature !== "scripts"); + const sandbox_flags = + sandbox_features.map(feature => `allow-${feature}`).join(" "); + const allow_attribute = + non_script_sandbox_features.map(feature => `${feature} 'none'`).join(", "); + + const iframe = await add_iframe( + {src: iframe_src, allow: allow_attribute, sandbox: sandbox_flags}); + + iframe.contentWindow.postMessage( + {type: "features", features: non_script_sandbox_features}, "*"); + const iframe_states = await feature_update(); + for (const [feature, state] of iframe_states) + assert_false(state, `'${feature}' should be disabled in <iframe>.'`); + + iframe.parentElement.removeChild(iframe); +}, "Verify that when a sandbox related feature (except scripts) is disabled in 'allow' then " + " the feature will be disabled regardless of sandbox attribute's value."); + +promise_test( async () => { + const iframe = await add_iframe( + {src: iframe_src, allow: "scripts 'none'", sandbox: "allow-scripts"}); + + iframe.contentWindow.postMessage( + {type: "features", features: ['scripts']}, "*"); + const iframe_states = await feature_update(10); + + assert_equals(iframe_states.length, 0); + iframe.parentElement.removeChild(iframe); +}, "Verify that when scripts is disabled in 'allow' then " + + " the feature will be disabled regardless of sandbox attribute's value."); </script> -</body> \ No newline at end of file +</body>
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_capture_mouse.html b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_capture_mouse.html index 32056f0..03b1ba6 100644 --- a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_capture_mouse.html +++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_capture_mouse.html
@@ -40,6 +40,7 @@ var ownEventForTheCapturedTargetGot = false; var count=0; var event_log = []; + var actions_promise; var detected_pointertypes = {}; add_completion_callback(end_of_test); @@ -69,7 +70,9 @@ }); on_event(target0, 'lostpointercapture', function(e) { - test_lostpointercapture.done(); + actions_promise.then( () => { + test_lostpointercapture.done(); + }); isPointerCapture = false; event_log.push('lostpointercapture@target0'); }); @@ -84,11 +87,13 @@ on_event(target0, "pointermove", function (event) { detected_pointertypes[ event.pointerType ] = true; if(!pointermoveNoCaptureGot0) { - test_pointermove0.done(); - event_log.push('pointermove@target0'); - pointermoveNoCaptureGot0 = true; - // Second dispatch a pointer move to target1. - new test_driver.Actions().pointerMove(0, 0, {origin: target1}).send(); + actions_promise = actions_promise.then( () => { + test_pointermove0.done(); + event_log.push('pointermove@target0'); + pointermoveNoCaptureGot0 = true; + // Second dispatch a pointer move to target1. + return new test_driver.Actions().pointerMove(0, 0, {origin: target1}).send(); + }); } if(isPointerCapture) { if(!pointermoveCaptureGot0) { @@ -105,7 +110,9 @@ event_log.push('pointermove@target0'); pointermoveCaptureGot0 = true; // Fourth dispatch a pointer move to target0. - new test_driver.Actions().pointerMove(0, 0, {origin: target0}).send(); + actions_promise = actions_promise.then( () => { + new test_driver.Actions().pointerMove(0, 0, {origin: target0}).send(); + }); } if((event.clientX > target0.getBoundingClientRect().left)&& (event.clientX < target0.getBoundingClientRect().right)&& @@ -122,7 +129,7 @@ }); // First dispatch a pointer move to target0. - new test_driver.Actions().pointerMove(0, 0, {origin: target0}).send(); + actions_promise = new test_driver.Actions().pointerMove(0, 0, {origin: target0}).send(); on_event(target1, "pointermove", function (event) { test(function() { @@ -130,17 +137,19 @@ }, "pointermove shouldn't trigger for the purple rectangle while the black rectangle has capture"); if(!pointermoveNoCaptureGot1) { - test_pointermove1.done(); - event_log.push('pointermove@target1'); - pointermoveNoCaptureGot1 = true; - // Third, drag the mouse from btnCapture, target1 to target0. - new test_driver.Actions() - .pointerMove(0, 0, {origin: btnCapture}) - .pointerDown() - .pointerMove(0, 0, {origin: target1}) - .pointerMove(0, 0, {origin: target0}) - .pointerUp() - .send(); + actions_promise = actions_promise.then( () => { + test_pointermove1.done(); + event_log.push('pointermove@target1'); + pointermoveNoCaptureGot1 = true; + // Third, drag the mouse from btnCapture, target1 to target0. + return new test_driver.Actions() + .pointerMove(0, 0, {origin: btnCapture}) + .pointerDown() + .pointerMove(0, 0, {origin: target1}) + .pointerMove(0, 0, {origin: target0}) + .pointerUp() + .send(); + }); } }); }
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_releasepointercapture_invalid_pointerid.html b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_releasepointercapture_invalid_pointerid.html index f51674cb..71de198 100644 --- a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_releasepointercapture_invalid_pointerid.html +++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_releasepointercapture_invalid_pointerid.html
@@ -26,6 +26,7 @@ add_completion_callback(showPointerTypes); var INVALID_POINTERID = 314159265358973923; + var actions_promise; function run() { var target0 = document.getElementById("target0"); @@ -41,7 +42,10 @@ "It should not be possible to release capture an invalid pointer id"); }); - test_pointerEvent.done(); // complete test + // Make sure the test finishes after all the input actions are completed. + actions_promise.then( () => { + test_pointerEvent.done(); + }); }); // set pointer capture @@ -51,7 +55,7 @@ }); // Inject mouse inputs. - new test_driver.Actions() + actions_promise = new test_driver.Actions() .pointerMove(0, 0, {origin: target0}) .pointerDown() .pointerMove(10, 0, {origin: target0})
diff --git a/third_party/blink/web_tests/fast/events/pointerevents/mouse-pointer-event-properties.html b/third_party/blink/web_tests/fast/events/pointerevents/mouse-pointer-event-properties.html index 4f63e4c..788bd44 100644 --- a/third_party/blink/web_tests/fast/events/pointerevents/mouse-pointer-event-properties.html +++ b/third_party/blink/web_tests/fast/events/pointerevents/mouse-pointer-event-properties.html
@@ -15,6 +15,8 @@ <div id="console"></div> <script> +// TODO(crbug.com/1076938): This test cannot be automated using current test_driver APIs. + window.name = "mainWindow"; description("Verifies that pointer event parameters are correct when fired through mouse events.");
diff --git a/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection-insertable-streams-audio.html b/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection-insertable-streams-audio.html index ca52c18..76f33b2 100644 --- a/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection-insertable-streams-audio.html +++ b/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection-insertable-streams-audio.html
@@ -10,9 +10,9 @@ <body> <script> async function testAudioFlow(t, negotiationFunction) { - const caller = new RTCPeerConnection({forceEncodedAudioInsertableStreams:true}); + const caller = new RTCPeerConnection({encodedInsertableStreams:true}); t.add_cleanup(() => caller.close()); - const callee = new RTCPeerConnection({forceEncodedAudioInsertableStreams:true}); + const callee = new RTCPeerConnection({encodedInsertableStreams:true}); t.add_cleanup(() => callee.close()); const stream = await navigator.mediaDevices.getUserMedia({audio:true}); @@ -20,7 +20,7 @@ t.add_cleanup(() => audioTrack.stop()); const audioSender = caller.addTrack(audioTrack) - const senderStreams = audioSender.createEncodedAudioStreams(); + const senderStreams = audioSender.createEncodedStreams(); const senderReader = senderStreams.readableStream.getReader(); const senderWriter = senderStreams.writableStream.getWriter(); @@ -36,7 +36,7 @@ assert_true(audioReceiver !== undefined); const receiverStreams = - audioReceiver.createEncodedAudioStreams(); + audioReceiver.createEncodedStreams(); const receiverReader = receiverStreams.readableStream.getReader(); const receiverWriter = receiverStreams.writableStream.getWriter(); @@ -68,9 +68,10 @@ const result = await senderReader.read() frameInfos.push({ data: result.value.data, - synchronizationSource: result.value.synchronizationSource, timestamp: result.value.timestamp, type: result.value.type, + metadata: result.value.getMetadata(), + getMetadata() { return this.metadata; } }); senderWriter.write(result.value); } @@ -86,9 +87,10 @@ result.value.data = buffer; frameInfos.push({ data: result.value.data, - synchronizationSource: result.value.synchronizationSource, timestamp: result.value.timestamp, type: result.value.type, + metadata: result.value.getMetadata(), + getMetadata() { return this.metadata; } }); senderWriter.write(result.value); } @@ -101,9 +103,10 @@ frameInfos.push({ data: result.value.data, - synchronizationSource: result.value.synchronizationSource, timestamp: result.value.timestamp, type: result.value.type, + metadata: result.value.getMetadata(), + getMetadata() { return this.metadata; } }); senderWriter.write(result.value); } @@ -132,8 +135,8 @@ await doSignalingHandshake(caller, callee); const audioSender = caller.addTrack(audioTrack); - assert_throws_dom("InvalidStateError", () => audioSender.createEncodedAudioStreams()); -}, 'RTCRtpSender.createEncodedAudioStream() throws if not requested in PC configuration'); + assert_throws_dom("InvalidStateError", () => audioSender.createEncodedStreams()); +}, 'RTCRtpSender.createEncodedStream() throws if not requested in PC configuration'); promise_test(async t => { const caller = new RTCPeerConnection(); @@ -149,7 +152,7 @@ callee.ontrack = t.step_func(() => { const audioReceiver = callee.getReceivers().find(r => r.track.kind === 'audio'); assert_true(audioReceiver !== undefined); - assert_throws_dom("InvalidStateError", () => audioReceiver.createEncodedAudioStreams()); + assert_throws_dom("InvalidStateError", () => audioReceiver.createEncodedStreams()); resolve(); }); }); @@ -157,10 +160,10 @@ exchangeIceCandidates(caller, callee); await doSignalingHandshake(caller, callee); return ontrackPromise; -}, 'RTCRtpReceiver.createEncodedAudioStream() throws if not requested in PC configuration'); +}, 'RTCRtpReceiver.createEncodedStream() throws if not requested in PC configuration'); promise_test(async t => { - const caller = new RTCPeerConnection({forceEncodedAudioInsertableStreams:true}); + const caller = new RTCPeerConnection({encodedInsertableStreams:true}); t.add_cleanup(() => caller.close()); const callee = new RTCPeerConnection(); t.add_cleanup(() => callee.close()); @@ -170,7 +173,7 @@ t.add_cleanup(() => track.stop()); const sender = caller.addTrack(track) - const senderStreams = sender.createEncodedAudioStreams(); + const senderStreams = sender.createEncodedStreams(); const senderWorker = new Worker('RTCPeerConnection-sender-worker-single-frame.js') senderWorker.postMessage( @@ -210,7 +213,7 @@ }, 'RTCRtpSender readable stream transferred to a Worker and the Worker sends an RTCEncodedAudioFrame back'); promise_test(async t => { - const caller = new RTCPeerConnection({forceEncodedAudioInsertableStreams:true}); + const caller = new RTCPeerConnection({encodedInsertableStreams:true}); t.add_cleanup(() => caller.close()); const callee = new RTCPeerConnection(); t.add_cleanup(() => callee.close()); @@ -220,7 +223,7 @@ t.add_cleanup(() => track.stop()); const sender = caller.addTrack(track) - const streams = sender.createEncodedAudioStreams(); + const streams = sender.createEncodedStreams(); const transformer = new TransformStream({ transform(frame, controller) { // Inserting the same frame twice will result in failure since the frame @@ -238,6 +241,51 @@ streams.readableStream.pipeThrough(transformer).pipeTo(streams.writableStream)); }, 'Enqueuing the same frame twice fails'); +promise_test(async t => { + const caller = new RTCPeerConnection({forceEncodedAudioInsertableStreams:true}); + t.add_cleanup(() => caller.close()); + const callee = new RTCPeerConnection({forceEncodedAudioInsertableStreams:true}); + t.add_cleanup(() => callee.close()); + + const stream = await navigator.mediaDevices.getUserMedia({audio:true}); + const audioTrack = stream.getAudioTracks()[0]; + t.add_cleanup(() => audioTrack.stop()); + + const audioSender = caller.addTrack(audioTrack) + const senderStreams = audioSender.createEncodedAudioStreams(); + const senderReader = senderStreams.readableStream.getReader(); + const senderWriter = senderStreams.writableStream.getWriter(); + + let sentFrameInfo = null; + const ontrackPromise = new Promise(resolve => { + callee.ontrack = e => { + const audioReceiver = e.receiver; + + const receiverStreams = audioReceiver.createEncodedAudioStreams(); + const receiverReader = receiverStreams.readableStream.getReader(); + receiverReader.read().then(t.step_func(receivedResult => { + assert_true(areFrameInfosEqual(receivedResult.value, sentFrameInfo)); + resolve(); + })); + } + }); + + exchangeIceCandidates(caller, callee); + await doSignalingHandshake(caller, callee); + + // Pass frames as they come from the encoder. + const result = await senderReader.read() + sentFrameInfo = { + timestamp: result.value.timestamp, + data: result.value.data, + metadata: result.value.getMetadata(), + getMetadata() { return this.metadata; } + } + senderWriter.write(result.value); + + return ontrackPromise; +}, 'Legacy API works'); + </script> </body> </html>
diff --git a/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection-insertable-streams-simulcast.html b/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection-insertable-streams-simulcast.html index 43590f0e..9a4b6144 100644 --- a/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection-insertable-streams-simulcast.html +++ b/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection-insertable-streams-simulcast.html
@@ -10,9 +10,9 @@ // Test based on wpt/webrtc/simulcast/basic.https.html promise_test(async t => { const rids = [0, 1, 2]; - const pc1 = new RTCPeerConnection({forceEncodedVideoInsertableStreams:true}); + const pc1 = new RTCPeerConnection({encodedInsertableStreams:true}); t.add_cleanup(() => pc1.close()); - const pc2 = new RTCPeerConnection({forceEncodedVideoInsertableStreams:true}); + const pc2 = new RTCPeerConnection({encodedInsertableStreams:true}); t.add_cleanup(() => pc2.close()); exchangeIceCandidates(pc1, pc2); @@ -22,12 +22,13 @@ pc2.ontrack = t.step_func(e => { const receiverTransformer = new TransformStream({ async transform(chunk, controller) { - if (receiverSSRCs.indexOf(chunk.synchronizationSource) == -1) - receiverSSRCs.push(chunk.synchronizationSource); + let ssrc = chunk.getMetadata().synchronizationSource; + if (receiverSSRCs.indexOf(ssrc) == -1) + receiverSSRCs.push(ssrc); controller.enqueue(chunk); } }); - const receiverStreams = e.receiver.createEncodedVideoStreams(); + const receiverStreams = e.receiver.createEncodedStreams(); receiverStreams.readableStream .pipeThrough(receiverTransformer) .pipeTo(receiverStreams.writableStream); @@ -50,7 +51,7 @@ streams: [stream], sendEncodings: rids.map(rid => {rid}), }); - const senderStreams = transceiver.sender.createEncodedVideoStreams(); + const senderStreams = transceiver.sender.createEncodedStreams(); let senderSSRCs = []; const senderTransformer = new TransformStream({ async transform(chunk, controller) {
diff --git a/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection-insertable-streams.html b/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection-insertable-streams.html index 901f8d6b..9a636dc5 100644 --- a/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection-insertable-streams.html +++ b/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection-insertable-streams.html
@@ -13,9 +13,9 @@ // Insertable Streams spec is mature enough. async function testVideoFlow(t, negotiationFunction) { - const caller = new RTCPeerConnection({forceEncodedVideoInsertableStreams:true}); + const caller = new RTCPeerConnection({encodedInsertableStreams:true}); t.add_cleanup(() => caller.close()); - const callee = new RTCPeerConnection({forceEncodedVideoInsertableStreams:true}); + const callee = new RTCPeerConnection({encodedInsertableStreams:true}); t.add_cleanup(() => callee.close()); const stream = await navigator.mediaDevices.getUserMedia({video:true}); @@ -23,7 +23,7 @@ t.add_cleanup(() => videoTrack.stop()); const videoSender = caller.addTrack(videoTrack) - const senderStreams = videoSender.createEncodedVideoStreams(); + const senderStreams = videoSender.createEncodedStreams(); const senderReader = senderStreams.readableStream.getReader(); const senderWriter = senderStreams.writableStream.getWriter(); @@ -39,7 +39,7 @@ assert_true(videoReceiver !== undefined); const receiverStreams = - videoReceiver.createEncodedVideoStreams(); + videoReceiver.createEncodedStreams(); const receiverReader = receiverStreams.readableStream.getReader(); const receiverWriter = receiverStreams.writableStream.getWriter(); @@ -72,7 +72,8 @@ frameInfos.push({ timestamp: result.value.timestamp, data: result.value.data, - synchronizationSource: result.value.synchronizationSource + metadata: result.value.getMetadata(), + getMetadata() { return this.metadata; } }); senderWriter.write(result.value); } @@ -88,7 +89,8 @@ frameInfos.push({ timestamp: result.value.timestamp, data: result.value.data, - synchronizationSource: result.value.synchronizationSource + metadata: result.value.getMetadata(), + getMetadata() { return this.metadata; } }); senderWriter.write(result.value); } @@ -102,7 +104,8 @@ frameInfos.push({ timestamp: result.value.timestamp, data: result.value.data, - synchronizationSource: result.value.synchronizationSource + metadata: result.value.getMetadata(), + getMetadata() { return this.metadata; } }); senderWriter.write(result.value); } @@ -131,8 +134,8 @@ await doSignalingHandshake(caller, callee); const videoSender = caller.addTrack(videoTrack); - assert_throws_dom("InvalidStateError", () => videoSender.createEncodedVideoStreams()); -}, 'RTCRtpSender.createEncodedVideoStream() throws if not requested in PC configuration'); + assert_throws_dom("InvalidStateError", () => videoSender.createEncodedStreams()); +}, 'RTCRtpSender.createEncodedStream() throws if not requested in PC configuration'); promise_test(async t => { const caller = new RTCPeerConnection(); @@ -148,7 +151,7 @@ callee.ontrack = t.step_func(() => { const videoReceiver = callee.getReceivers().find(r => r.track.kind === 'video'); assert_true(videoReceiver !== undefined); - assert_throws_dom("InvalidStateError", () => videoReceiver.createEncodedVideoStreams()); + assert_throws_dom("InvalidStateError", () => videoReceiver.createEncodedStreams()); resolve(); }); }); @@ -156,10 +159,10 @@ exchangeIceCandidates(caller, callee); await doSignalingHandshake(caller, callee); return ontrackPromise; -}, 'RTCRtpReceiver.createEncodedVideoStream() throws if not requested in PC configuration'); +}, 'RTCRtpReceiver.createEncodedStream() throws if not requested in PC configuration'); promise_test(async t => { - const caller = new RTCPeerConnection({forceEncodedVideoInsertableStreams:true}); + const caller = new RTCPeerConnection({encodedInsertableStreams:true}); t.add_cleanup(() => caller.close()); const callee = new RTCPeerConnection(); t.add_cleanup(() => callee.close()); @@ -169,7 +172,7 @@ t.add_cleanup(() => videoTrack.stop()); const videoSender = caller.addTrack(videoTrack) - const senderStreams = videoSender.createEncodedVideoStreams(); + const senderStreams = videoSender.createEncodedStreams(); const senderWorker = new Worker('RTCPeerConnection-sender-worker-single-frame.js') senderWorker.postMessage( @@ -196,7 +199,7 @@ assert_equals(message.data.type, expectedFrameData.type); assert_equals(message.data.timestamp, expectedFrameData.timestamp); assert_true(areArrayBuffersEqual(message.data.data, expectedFrameData.data)); - assert_true(areArrayBuffersEqual(message.data.additionalData, expectedFrameData.additionalData)); + assert_equals(message.data.getMetadata().synchronizationSource, expectedFrameData.metadata.synchronizationSource); if (++numVerifiedFrames == 2) resolve(); } @@ -263,9 +266,9 @@ }, 'Video flows when insertable streams is enabled for audio and disabled for audio.'); promise_test(async t => { - const caller = new RTCPeerConnection({forceEncodedVideoInsertableStreams:true}); + const caller = new RTCPeerConnection({encodedInsertableStreams:true}); t.add_cleanup(() => caller.close()); - const callee = new RTCPeerConnection({forceEncodedVideoInsertableStreams:true}); + const callee = new RTCPeerConnection({encodedInsertableStreams:true}); t.add_cleanup(() => callee.close()); const stream = await navigator.mediaDevices.getUserMedia({video:true}); @@ -273,14 +276,14 @@ t.add_cleanup(() => track.stop()); const sender = caller.addTrack(track) - const senderStreams = sender.createEncodedVideoStreams(); + const senderStreams = sender.createEncodedStreams(); const senderReader = senderStreams.readableStream.getReader(); const senderWriter = senderStreams.writableStream.getWriter(); const numFramesToSend = 20; const ontrackPromise = new Promise((resolve, reject) => { callee.ontrack = async e => { - const receiverStreams = e.receiver.createEncodedVideoStreams(); + const receiverStreams = e.receiver.createEncodedStreams(); const receiverReader = receiverStreams.readableStream.getReader(); let numReceivedKeyFrames = 0; @@ -324,7 +327,7 @@ }, 'Key and Delta frames are sent and received'); promise_test(async t => { - const caller = new RTCPeerConnection({forceEncodedVideoInsertableStreams:true}); + const caller = new RTCPeerConnection({encodedInsertableStreams:true}); t.add_cleanup(() => caller.close()); const callee = new RTCPeerConnection(); t.add_cleanup(() => callee.close()); @@ -334,7 +337,7 @@ t.add_cleanup(() => track.stop()); const sender = caller.addTrack(track) - const streams = sender.createEncodedVideoStreams(); + const streams = sender.createEncodedStreams(); const transformer = new TransformStream({ transform(frame, controller) { // Inserting the same frame twice will result in failure since the frame @@ -352,6 +355,51 @@ streams.readableStream.pipeThrough(transformer).pipeTo(streams.writableStream)); }, 'Enqueuing the same frame twice fails'); +promise_test(async t => { + const caller = new RTCPeerConnection({forceEncodedVideoInsertableStreams:true}); + t.add_cleanup(() => caller.close()); + const callee = new RTCPeerConnection({forceEncodedVideoInsertableStreams:true}); + t.add_cleanup(() => callee.close()); + + const stream = await navigator.mediaDevices.getUserMedia({video:true}); + const videoTrack = stream.getVideoTracks()[0]; + t.add_cleanup(() => videoTrack.stop()); + + const videoSender = caller.addTrack(videoTrack) + const senderStreams = videoSender.createEncodedVideoStreams(); + const senderReader = senderStreams.readableStream.getReader(); + const senderWriter = senderStreams.writableStream.getWriter(); + + let sentFrameInfo = null; + const ontrackPromise = new Promise(resolve => { + callee.ontrack = t.step_func(async e => { + const videoReceiver = e.receiver; + + const receiverStreams = videoReceiver.createEncodedVideoStreams(); + const receiverReader = receiverStreams.readableStream.getReader(); + receiverReader.read().then(t.step_func(receivedResult => { + assert_true(areFrameInfosEqual(receivedResult.value, sentFrameInfo)); + resolve(); + })); + }); + }); + + exchangeIceCandidates(caller, callee); + await doSignalingHandshake(caller, callee); + + // Pass frames as they come from the encoder. + const result = await senderReader.read() + sentFrameInfo = { + timestamp: result.value.timestamp, + data: result.value.data, + metadata: result.value.getMetadata(), + getMetadata() { return this.metadata; } + } + senderWriter.write(result.value); + + return ontrackPromise; +}, 'Legacy API works'); + </script> </body> </html>
diff --git a/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection-insertable-streams.js b/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection-insertable-streams.js index b92bc952..a89e0a1 100644 --- a/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection-insertable-streams.js +++ b/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection-insertable-streams.js
@@ -13,9 +13,13 @@ return true; } +function areMetadataEqual(metadata1, metadata2) { + return metadata1.synchronizationSource === metadata2.synchronizationSource; +} + function areFrameInfosEqual(frame1, frame2) { - return frame1.synchronizationSource === frame2.synchronizationSource && - frame1.timestamp === frame2.timestamp && + return frame1.timestamp === frame2.timestamp && + areMetadataEqual(frame1.getMetadata(), frame2.getMetadata()) && areArrayBuffersEqual(frame1.data, frame2.data); } @@ -44,4 +48,3 @@ await pc2.setRemoteDescription(answer); await pc1.setLocalDescription(answer); } -
diff --git a/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection-sender-worker-single-frame.js b/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection-sender-worker-single-frame.js index 2448ea1..de65e01 100644 --- a/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection-sender-worker-single-frame.js +++ b/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection-sender-worker-single-frame.js
@@ -1,7 +1,8 @@ onmessage = async (event) => { const readableStream = event.data.readableStream; const reader = readableStream.getReader(); - const result = await reader.read() + const result = await reader.read(); + console.log('WORKER metadata = ', result.value.getMetadata().synchronizationSource); // Post an object with individual fields so that the test side has // values to verify the serialization of the RTCEncodedVideoFrame. @@ -9,7 +10,7 @@ type: result.value.type, timestamp: result.value.timestamp, data: result.value.data, - additionalData: result.value.additionalData + metadata: result.value.getMetadata(), }); // Send the frame twice to verify that the frame does not change after the
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/compositing/video/video-controls-layer-creation-expected.png b/third_party/blink/web_tests/flag-specific/composite-after-paint/compositing/video/video-controls-layer-creation-expected.png index 091fbab..8c55a16 100644 --- a/third_party/blink/web_tests/flag-specific/composite-after-paint/compositing/video/video-controls-layer-creation-expected.png +++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/compositing/video/video-controls-layer-creation-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/fast/multicol/composited-opacity-2nd-and-3rd-column-expected.png b/third_party/blink/web_tests/flag-specific/composite-after-paint/fast/multicol/composited-opacity-2nd-and-3rd-column-expected.png index c19f445..02b2f1f 100644 --- a/third_party/blink/web_tests/flag-specific/composite-after-paint/fast/multicol/composited-opacity-2nd-and-3rd-column-expected.png +++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/fast/multicol/composited-opacity-2nd-and-3rd-column-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/fast/table/multiple-captions-display-expected.png b/third_party/blink/web_tests/flag-specific/composite-after-paint/fast/table/multiple-captions-display-expected.png index ed49aad2..20660354 100644 --- a/third_party/blink/web_tests/flag-specific/composite-after-paint/fast/table/multiple-captions-display-expected.png +++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/fast/table/multiple-captions-display-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/accessibility/element-role-mapping-normal-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/accessibility/element-role-mapping-normal-expected.txt index 1e0f8d0..b26a991 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/accessibility/element-role-mapping-normal-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/accessibility/element-role-mapping-normal-expected.txt
@@ -43,157 +43,152 @@ This is a footer. -End of test - This test make sure that unfocuasable elements are mapped implicitly to AX roles. On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". -AXRole: AXWebArea +AXRole: AXGenericContainer + AXRole: AXHeader + AXRole: AXStaticText "This is a Header for this page" + AXRole: AXInlineTextBox "This is a Header for this page" + AXRole: AXHeading "Heading" + AXRole: AXStaticText "Heading" + AXRole: AXInlineTextBox "Heading" AXRole: AXGenericContainer - AXRole: AXHeader - AXRole: AXStaticText "This is a Header for this page" - AXRole: AXInlineTextBox "This is a Header for this page" - AXRole: AXHeading "Heading" - AXRole: AXStaticText "Heading" - AXRole: AXInlineTextBox "Heading" - AXRole: AXGenericContainer - AXRole: AXStaticText "Division" - AXRole: AXInlineTextBox "Division" - AXRole: AXParagraph - AXRole: AXStaticText "Paragraph" - AXRole: AXInlineTextBox "Paragraph" - AXRole: AXRuby - AXRole: AXRubyAnnotation - AXRole: AXStaticText "한êµ" - AXRole: AXInlineTextBox "한êµ" - AXRole: AXStaticText "韓國" - AXRole: AXInlineTextBox "韓國" - AXRole: AXDescriptionList - AXRole: AXDescriptionListTerm - AXRole: AXStaticText "Coffee" - AXRole: AXInlineTextBox "Coffee" - AXRole: AXDescriptionListDetail - AXRole: AXStaticText "- black hot drink" - AXRole: AXInlineTextBox "- black hot drink" - AXRole: AXDescriptionListTerm - AXRole: AXStaticText "Milk" - AXRole: AXInlineTextBox "Milk" - AXRole: AXDescriptionListDetail - AXRole: AXStaticText "- white cold drink" - AXRole: AXInlineTextBox "- white cold drink" - AXRole: AXMath - AXRole: AXStaticText "x " - AXRole: AXInlineTextBox "x " - AXRole: AXStaticText "+ " - AXRole: AXInlineTextBox "+ " - AXRole: AXStaticText "a " - AXRole: AXInlineTextBox "a " - AXRole: AXStaticText "/ " - AXRole: AXInlineTextBox "/ " - AXRole: AXStaticText "b" - AXRole: AXInlineTextBox "b" - AXRole: AXMain - AXRole: AXArticle - AXRole: AXHeaderAsNonLandmark - AXRole: AXHeading "Most important heading here" - AXRole: AXStaticText "Most important heading here" - AXRole: AXInlineTextBox "Most important heading here" - AXRole: AXHeading "Google Chrome" - AXRole: AXStaticText "Google Chrome" - AXRole: AXInlineTextBox "Google Chrome" - AXRole: AXParagraph - AXRole: AXStaticText "Google Chrome is a free, open-source web browser developed by Google, released in 2008." - AXRole: AXInlineTextBox "Google Chrome is a free, open-source web browser developed by Google, " - AXRole: AXInlineTextBox "released in 2008." - AXRole: AXFooterAsNonLandmark - AXRole: AXParagraph - AXRole: AXStaticText "Footer in article" - AXRole: AXInlineTextBox "Footer in article" - AXRole: AXNavigation - AXRole: AXLink "HTML" - AXRole: AXStaticText "HTML" - AXRole: AXInlineTextBox "HTML" - AXRole: AXStaticText " | " - AXRole: AXInlineTextBox " | " - AXRole: AXLink "CSS" - AXRole: AXStaticText "CSS" - AXRole: AXInlineTextBox "CSS" - AXRole: AXStaticText " | " - AXRole: AXInlineTextBox " | " - AXRole: AXLink "JavaScript" - AXRole: AXStaticText "JavaScript" - AXRole: AXInlineTextBox "JavaScript" - AXRole: AXStaticText " |" - AXRole: AXInlineTextBox " |" - AXRole: AXComplementary - AXRole: AXParagraph - AXRole: AXStaticText "Text that appears under aside" - AXRole: AXInlineTextBox "Text that appears under aside" - AXRole: AXPre - AXRole: AXStaticText "Text in a pre -element -" - AXRole: AXInlineTextBox "Text in a pre" - AXRole: AXInlineTextBox " -" - AXRole: AXInlineTextBox "element" - AXRole: AXInlineTextBox " -" - AXRole: AXSection + AXRole: AXStaticText "Division" + AXRole: AXInlineTextBox "Division" + AXRole: AXParagraph + AXRole: AXStaticText "Paragraph" + AXRole: AXInlineTextBox "Paragraph" + AXRole: AXRuby + AXRole: AXRubyAnnotation + AXRole: AXStaticText "한êµ" + AXRole: AXInlineTextBox "한êµ" + AXRole: AXStaticText "韓國" + AXRole: AXInlineTextBox "韓國" + AXRole: AXDescriptionList + AXRole: AXDescriptionListTerm + AXRole: AXStaticText "Coffee" + AXRole: AXInlineTextBox "Coffee" + AXRole: AXDescriptionListDetail + AXRole: AXStaticText "- black hot drink" + AXRole: AXInlineTextBox "- black hot drink" + AXRole: AXDescriptionListTerm + AXRole: AXStaticText "Milk" + AXRole: AXInlineTextBox "Milk" + AXRole: AXDescriptionListDetail + AXRole: AXStaticText "- white cold drink" + AXRole: AXInlineTextBox "- white cold drink" + AXRole: AXMath + AXRole: AXStaticText "x " + AXRole: AXInlineTextBox "x " + AXRole: AXStaticText "+ " + AXRole: AXInlineTextBox "+ " + AXRole: AXStaticText "a " + AXRole: AXInlineTextBox "a " + AXRole: AXStaticText "/ " + AXRole: AXInlineTextBox "/ " + AXRole: AXStaticText "b" + AXRole: AXInlineTextBox "b" + AXRole: AXMain + AXRole: AXArticle AXRole: AXHeaderAsNonLandmark AXRole: AXHeading "Most important heading here" AXRole: AXStaticText "Most important heading here" AXRole: AXInlineTextBox "Most important heading here" + AXRole: AXHeading "Google Chrome" + AXRole: AXStaticText "Google Chrome" + AXRole: AXInlineTextBox "Google Chrome" AXRole: AXParagraph - AXRole: AXStaticText "Section" - AXRole: AXInlineTextBox "Section" + AXRole: AXStaticText "Google Chrome is a free, open-source web browser developed by Google, released in 2008." + AXRole: AXInlineTextBox "Google Chrome is a free, open-source web browser developed by Google, " + AXRole: AXInlineTextBox "released in 2008." AXRole: AXFooterAsNonLandmark AXRole: AXParagraph - AXRole: AXStaticText "Footer in section" - AXRole: AXInlineTextBox "Footer in section" - AXRole: AXGenericContainer - AXRole: AXStaticText "Written by Julie" - AXRole: AXInlineTextBox "Written by Julie" - AXRole: AXLineBreak " -" - AXRole: AXInlineTextBox " -" - AXRole: AXStaticText "Visit us at:www.chromium.org" - AXRole: AXInlineTextBox "Visit us at:www.chromium.org" - AXRole: AXLineBreak " -" - AXRole: AXInlineTextBox " -" + AXRole: AXStaticText "Footer in article" + AXRole: AXInlineTextBox "Footer in article" + AXRole: AXNavigation + AXRole: AXLink "HTML" + AXRole: AXStaticText "HTML" + AXRole: AXInlineTextBox "HTML" + AXRole: AXStaticText " | " + AXRole: AXInlineTextBox " | " + AXRole: AXLink "CSS" + AXRole: AXStaticText "CSS" + AXRole: AXInlineTextBox "CSS" + AXRole: AXStaticText " | " + AXRole: AXInlineTextBox " | " + AXRole: AXLink "JavaScript" + AXRole: AXStaticText "JavaScript" + AXRole: AXInlineTextBox "JavaScript" + AXRole: AXStaticText " |" + AXRole: AXInlineTextBox " |" + AXRole: AXComplementary AXRole: AXParagraph - AXRole: AXStaticText "January" - AXRole: AXInlineTextBox "January" - AXRole: AXDialog - AXRole: AXStaticText "This is an open dialog window" - AXRole: AXInlineTextBox "This is an open dialog window" - AXRole: AXTable "Caption" - AXRole: AXCaption - AXRole: AXStaticText "Caption" - AXRole: AXInlineTextBox "Caption" - AXRole: AXRow - AXRole: AXCell "Cell1" - AXRole: AXStaticText "Cell1" - AXRole: AXInlineTextBox "Cell1" - AXRole: AXCell "Cell2" - AXRole: AXStaticText "Cell2" - AXRole: AXInlineTextBox "Cell2" - AXRole: AXFigure "Fig1. - Blue Box" - AXRole: AXImage "blue" - AXRole: AXFigcaption - AXRole: AXStaticText "Fig1. - Blue Box" - AXRole: AXInlineTextBox "Fig1. - Blue Box" - AXRole: AXEmbeddedObject - AXRole: AXFooter + AXRole: AXStaticText "Text that appears under aside" + AXRole: AXInlineTextBox "Text that appears under aside" + AXRole: AXPre + AXRole: AXStaticText "Text in a pre +element +" + AXRole: AXInlineTextBox "Text in a pre" + AXRole: AXInlineTextBox " +" + AXRole: AXInlineTextBox "element" + AXRole: AXInlineTextBox " +" + AXRole: AXSection + AXRole: AXHeaderAsNonLandmark + AXRole: AXHeading "Most important heading here" + AXRole: AXStaticText "Most important heading here" + AXRole: AXInlineTextBox "Most important heading here" + AXRole: AXParagraph + AXRole: AXStaticText "Section" + AXRole: AXInlineTextBox "Section" + AXRole: AXFooterAsNonLandmark AXRole: AXParagraph - AXRole: AXStaticText "This is a footer." - AXRole: AXInlineTextBox "This is a footer." + AXRole: AXStaticText "Footer in section" + AXRole: AXInlineTextBox "Footer in section" + AXRole: AXGenericContainer + AXRole: AXStaticText "Written by Julie" + AXRole: AXInlineTextBox "Written by Julie" + AXRole: AXLineBreak " +" + AXRole: AXInlineTextBox " +" + AXRole: AXStaticText "Visit us at:www.chromium.org" + AXRole: AXInlineTextBox "Visit us at:www.chromium.org" + AXRole: AXLineBreak " +" + AXRole: AXInlineTextBox " +" + AXRole: AXParagraph + AXRole: AXStaticText "January" + AXRole: AXInlineTextBox "January" + AXRole: AXDialog + AXRole: AXStaticText "This is an open dialog window" + AXRole: AXInlineTextBox "This is an open dialog window" + AXRole: AXTable "Caption" + AXRole: AXCaption + AXRole: AXStaticText "Caption" + AXRole: AXInlineTextBox "Caption" + AXRole: AXRow + AXRole: AXCell "Cell1" + AXRole: AXStaticText "Cell1" + AXRole: AXInlineTextBox "Cell1" + AXRole: AXCell "Cell2" + AXRole: AXStaticText "Cell2" + AXRole: AXInlineTextBox "Cell2" + AXRole: AXFigure "Fig1. - Blue Box" + AXRole: AXImage "blue" + AXRole: AXFigcaption + AXRole: AXStaticText "Fig1. - Blue Box" + AXRole: AXInlineTextBox "Fig1. - Blue Box" + AXRole: AXEmbeddedObject + AXRole: AXFooter AXRole: AXParagraph - AXRole: AXStaticText "End of test" + AXRole: AXStaticText "This is a footer." + AXRole: AXInlineTextBox "This is a footer." PASS successfullyParsed is true
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/contents-opaque/hidden-with-visible-child-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/contents-opaque/hidden-with-visible-child-expected.txt index db5de1d1..a8bf64b3b 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/contents-opaque/hidden-with-visible-child-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/contents-opaque/hidden-with-visible-child-expected.txt
@@ -9,6 +9,7 @@ { "name": "LayoutBlockFlow (positioned) DIV id='caption'", "bounds": [200, 100], + "contentsOpaqueForText": true, "backgroundColor": "#008000", "transform": 1 }
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/contents-opaque/hidden-with-visible-text-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/contents-opaque/hidden-with-visible-text-expected.txt index 81b2ae5..b1d9a9df 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/contents-opaque/hidden-with-visible-text-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/contents-opaque/hidden-with-visible-text-expected.txt
@@ -10,6 +10,7 @@ { "name": "LayoutBlockFlow (positioned) DIV id='caption'", "bounds": [200, 100], + "contentsOpaqueForText": true, "backgroundColor": "#008000", "transform": 1 }
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/contents-opaque/overflow-hidden-child-layers-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/contents-opaque/overflow-hidden-child-layers-expected.txt index 9aaa1cc..b305113 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/contents-opaque/overflow-hidden-child-layers-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/contents-opaque/overflow-hidden-child-layers-expected.txt
@@ -10,6 +10,7 @@ "name": "LayoutBlockFlow DIV class='box'", "position": [-30, -30], "bounds": [160, 160], + "contentsOpaqueForText": true, "backgroundColor": "#0000FF", "transform": 1 }
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/filters/sw-layer-overlaps-hw-shadow-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/filters/sw-layer-overlaps-hw-shadow-expected.txt index 1f45360..ba07638c 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/filters/sw-layer-overlaps-hw-shadow-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/filters/sw-layer-overlaps-hw-shadow-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV id='software')", "position": [-105, -105], "bounds": [100, 100], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/filters/sw-nested-shadow-overlaps-hw-nested-shadow-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/filters/sw-nested-shadow-overlaps-hw-nested-shadow-expected.txt index b23b04e..b970c17 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/filters/sw-nested-shadow-overlaps-hw-nested-shadow-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/filters/sw-nested-shadow-overlaps-hw-nested-shadow-expected.txt
@@ -10,12 +10,14 @@ "name": "LayoutBlockFlow (positioned) DIV id='composited-parent'", "position": [-100, -100], "bounds": [200, 200], + "contentsOpaqueForText": true, "backgroundColor": "#000000", "transform": 1 }, { "name": "LayoutBlockFlow (positioned) DIV id='software-parent'", "bounds": [200, 200], + "contentsOpaqueForText": true, "backgroundColor": "#008000" } ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/fixed-position-changed-to-absolute-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/fixed-position-changed-to-absolute-expected.txt index b2f373fb..64e74bc 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/fixed-position-changed-to-absolute-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/fixed-position-changed-to-absolute-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV id='layer-A')", "position": [12, 7], "bounds": [226, 180], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/geometry/bounds-ignores-hidden-composited-descendant-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/geometry/bounds-ignores-hidden-composited-descendant-expected.txt index 3d33847..e432a70 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/geometry/bounds-ignores-hidden-composited-descendant-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/geometry/bounds-ignores-hidden-composited-descendant-expected.txt
@@ -9,12 +9,14 @@ { "name": "LayoutBlockFlow (positioned) DIV class='composited'", "position": [10, 10], - "bounds": [590, 210] + "bounds": [590, 210], + "contentsOpaqueForText": true }, { "name": "LayoutBlockFlow (positioned) DIV class='composited'", "position": [10, 10], "bounds": [590, 210], + "contentsOpaqueForText": true, "transform": 1 }, {
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/geometry/bounds-ignores-hidden-dynamic-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/geometry/bounds-ignores-hidden-dynamic-expected.txt index f9beb847..1a69a38 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/geometry/bounds-ignores-hidden-dynamic-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/geometry/bounds-ignores-hidden-dynamic-expected.txt
@@ -9,7 +9,8 @@ { "name": "LayoutBlockFlow (positioned) DIV class='composited'", "position": [10, 10], - "bounds": [540, 240] + "bounds": [540, 240], + "contentsOpaqueForText": true }, { "name": "LayoutBlockFlow (positioned) DIV class='composited'",
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/geometry/clip-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/geometry/clip-expected.txt index e1486a7d..cde5b38 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/geometry/clip-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/geometry/clip-expected.txt
@@ -12,6 +12,7 @@ "name": "LayoutBlockFlow (positioned) DIV class='composited box'", "position": [-5, -5], "bounds": [110, 110], + "contentsOpaqueForText": true, "backgroundColor": "#808080", "transform": 2 },
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/geometry/foreground-layer-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/geometry/foreground-layer-expected.txt index 4fba7e9..b65abd37 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/geometry/foreground-layer-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/geometry/foreground-layer-expected.txt
@@ -30,6 +30,7 @@ "name": "LayoutBlockFlow (relative positioned) DIV class='main box'", "position": [-30, -30], "bounds": [340, 340], + "contentsOpaqueForText": true, "backgroundColor": "#FF0000", "transform": 4 },
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/become-composited-nested-iframes-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/become-composited-nested-iframes-expected.txt index a2a6ac5f..b608fa4 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/become-composited-nested-iframes-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/become-composited-nested-iframes-expected.txt
@@ -24,6 +24,7 @@ { "name": "LayoutView #document", "bounds": [250, 170], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 4 }, @@ -52,6 +53,7 @@ { "name": "LayoutView #document", "bounds": [250, 170], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 9 },
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/become-overlapped-iframe-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/become-overlapped-iframe-expected.txt index a6487a3..eaf56d8 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/become-overlapped-iframe-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/become-overlapped-iframe-expected.txt
@@ -14,6 +14,7 @@ { "name": "Scrolling Contents Layer", "bounds": [305, 230], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 2 },
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/composited-parent-iframe-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/composited-parent-iframe-expected.txt index 64fc1028..fc89b98 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/composited-parent-iframe-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/composited-parent-iframe-expected.txt
@@ -15,6 +15,7 @@ { "name": "Scrolling Contents Layer", "bounds": [285, 230], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 2 },
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/connect-compositing-iframe-delayed-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/connect-compositing-iframe-delayed-expected.txt index 61117227..d387ba1 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/connect-compositing-iframe-delayed-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/connect-compositing-iframe-delayed-expected.txt
@@ -17,6 +17,7 @@ { "name": "Scrolling Contents Layer", "bounds": [285, 230], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 2 },
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/connect-compositing-iframe-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/connect-compositing-iframe-expected.txt index 62bea23..67fc6aa2 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/connect-compositing-iframe-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/connect-compositing-iframe-expected.txt
@@ -15,6 +15,7 @@ { "name": "Scrolling Contents Layer", "bounds": [285, 230], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 2 },
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/connect-compositing-iframe2-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/connect-compositing-iframe2-expected.txt index c9b9e8f..6fee012 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/connect-compositing-iframe2-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/connect-compositing-iframe2-expected.txt
@@ -15,6 +15,7 @@ { "name": "Scrolling Contents Layer", "bounds": [285, 230], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 2 },
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/connect-compositing-iframe3-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/connect-compositing-iframe3-expected.txt index 763e69a9..34707d1 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/connect-compositing-iframe3-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/connect-compositing-iframe3-expected.txt
@@ -15,6 +15,7 @@ { "name": "Scrolling Contents Layer", "bounds": [285, 230], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 2 },
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/enter-compositing-iframe-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/enter-compositing-iframe-expected.txt index 62bea23..67fc6aa2 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/enter-compositing-iframe-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/enter-compositing-iframe-expected.txt
@@ -15,6 +15,7 @@ { "name": "Scrolling Contents Layer", "bounds": [285, 230], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 2 },
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/iframe-resize-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/iframe-resize-expected.txt index 4765f97..88bcd13 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/iframe-resize-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/iframe-resize-expected.txt
@@ -15,6 +15,7 @@ { "name": "Scrolling Contents Layer", "bounds": [385, 230], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 2 },
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/iframe-size-from-zero-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/iframe-size-from-zero-expected.txt index afc5bab..b617955 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/iframe-size-from-zero-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/iframe-size-from-zero-expected.txt
@@ -14,6 +14,7 @@ { "name": "Scrolling Contents Layer", "bounds": [285, 230], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 2 },
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/invisible-nested-iframe-show-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/invisible-nested-iframe-show-expected.txt index ee5fded..0452294 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/invisible-nested-iframe-show-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/invisible-nested-iframe-show-expected.txt
@@ -25,6 +25,7 @@ { "name": "LayoutView #document", "bounds": [250, 170], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 4 },
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/overlapped-iframe-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/overlapped-iframe-expected.txt index 00e4863d..32bb4be1d 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/overlapped-iframe-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/overlapped-iframe-expected.txt
@@ -15,6 +15,7 @@ { "name": "Scrolling Contents Layer", "bounds": [285, 230], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 2 },
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/overlapped-iframe-iframe-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/overlapped-iframe-iframe-expected.txt index 48518a6..9ce944e 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/overlapped-iframe-iframe-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/overlapped-iframe-iframe-expected.txt
@@ -13,6 +13,7 @@ { "name": "LayoutView #document", "bounds": [300, 300], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 1 },
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/overlapped-nested-iframes-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/overlapped-nested-iframes-expected.txt index acbd9c8..85700baf 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/overlapped-nested-iframes-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/overlapped-nested-iframes-expected.txt
@@ -25,6 +25,7 @@ { "name": "LayoutView #document", "bounds": [250, 170], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 5 }, @@ -53,6 +54,7 @@ { "name": "LayoutView #document", "bounds": [250, 170], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 10 },
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/resizer-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/resizer-expected.txt index 8cb0c91..8caecdc 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/resizer-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/resizer-expected.txt
@@ -14,6 +14,7 @@ { "name": "Scrolling Contents Layer", "bounds": [285, 230], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 2 },
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/scrolling-iframe-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/scrolling-iframe-expected.txt index 7a79ff6..93f32529 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/scrolling-iframe-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/iframes/scrolling-iframe-expected.txt
@@ -15,6 +15,7 @@ { "name": "Scrolling Contents Layer", "bounds": [508, 608], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 3 },
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/animation-overlap-with-children-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/animation-overlap-with-children-expected.txt index 2b4239b5..4581f188 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/animation-overlap-with-children-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/animation-overlap-with-children-expected.txt
@@ -25,6 +25,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='test1 box')", "position": [5, 15], "bounds": [100, 100], + "contentsOpaqueForText": true, "transform": 3 }, {
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/overflow-scroll-overlap-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/overflow-scroll-overlap-expected.txt index da3a57c..6600cf8 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/overflow-scroll-overlap-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/overflow-scroll-overlap-expected.txt
@@ -31,6 +31,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV class='box')", "position": [23, 213], "bounds": [210, 100], + "contentsOpaqueForText": true, "transform": 3 } ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/overlap-animation-container-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/overlap-animation-container-expected.txt index b4deb11..d5fdf83f 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/overlap-animation-container-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/overlap-animation-container-expected.txt
@@ -18,6 +18,7 @@ "name": "LayoutBlockFlow (relative positioned) DIV class='container'", "position": [-11, 0], "bounds": [144, 452], + "contentsOpaqueForText": true, "backgroundColor": "#FFFFFF", "transform": 3 }, @@ -32,6 +33,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV class='box yellow')", "position": [-51, 451], "bounds": [100, 100], + "contentsOpaqueForText": true, "transform": 4 }, {
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/overlap-child-layer-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/overlap-child-layer-expected.txt index 69f7a6fb..45dc991 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/overlap-child-layer-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/overlap-child-layer-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV id='green')", "position": [-400, 0], "bounds": [300, 300], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/overlap-clipping-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/overlap-clipping-expected.txt index 9b99b9c..a1831c0f 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/overlap-clipping-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/overlap-clipping-expected.txt
@@ -24,6 +24,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV id='overlap')", "position": [400, 0], "bounds": [100, 100], + "contentsOpaqueForText": true, "transform": 2 } ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/overlap-transformed-3d-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/overlap-transformed-3d-expected.txt index d70e370..3662802e 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/overlap-transformed-3d-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/overlap-transformed-3d-expected.txt
@@ -58,6 +58,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box top left')", "position": [-100, -100], "bounds": [300, 300], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/overlap-transformed-and-clipped-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/overlap-transformed-and-clipped-expected.txt index f498850..17fc827 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/overlap-transformed-and-clipped-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/overlap-transformed-and-clipped-expected.txt
@@ -21,6 +21,7 @@ { "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='over')", "bounds": [100, 100], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/overlap-transformed-preserved-3d-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/overlap-transformed-preserved-3d-expected.txt index d9ffd777..5c9e9703 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/overlap-transformed-preserved-3d-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/overlap-transformed-preserved-3d-expected.txt
@@ -279,7 +279,8 @@ { "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box top right')", "position": [8, 8], - "bounds": [300, 300] + "bounds": [300, 300], + "contentsOpaqueForText": true } ], "transforms": [
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/spanOverlapsCanvas-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/spanOverlapsCanvas-expected.txt index 51451f2..bdde85bc 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/spanOverlapsCanvas-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/spanOverlapsCanvas-expected.txt
@@ -19,6 +19,7 @@ { "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV id='output')", "bounds": [100, 50], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/squashing-into-ancestor-clipping-layer-change-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/squashing-into-ancestor-clipping-layer-change-expected.txt index d13b85f1..0ff02b1 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/squashing-into-ancestor-clipping-layer-change-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/squashing-into-ancestor-clipping-layer-change-expected.txt
@@ -16,6 +16,7 @@ { "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='squashed')", "bounds": [100, 100], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/masks/mask-layer-size-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/masks/mask-layer-size-expected.txt index 1930db8..087f844 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/masks/mask-layer-size-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/masks/mask-layer-size-expected.txt
@@ -9,6 +9,7 @@ { "name": "LayoutBlockFlow DIV id='masked'", "bounds": [400, 200], + "contentsOpaqueForText": true, "backgroundColor": "#000000", "transform": 1 },
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/overflow/scroll-parent-with-non-stacking-context-composited-ancestor-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/overflow/scroll-parent-with-non-stacking-context-composited-ancestor-expected.txt index 62b1dfe..0a2ca6f 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/overflow/scroll-parent-with-non-stacking-context-composited-ancestor-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/overflow/scroll-parent-with-non-stacking-context-composited-ancestor-expected.txt
@@ -40,6 +40,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV class='scrolled')", "position": [5, 49], "bounds": [60, 128], + "contentsOpaqueForText": true, "backfaceVisibility": "hidden", "transform": 1 },
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/overflow/universal-accelerated-overflow-scroll-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/overflow/universal-accelerated-overflow-scroll-expected.txt index 6afd6c70..2d3c0f0 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/overflow/universal-accelerated-overflow-scroll-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/overflow/universal-accelerated-overflow-scroll-expected.txt
@@ -39,6 +39,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV id='positioned-absolute-grandchildren-not-contained' class='positionAbsolute positioned')", "position": [25, 65], "bounds": [80, 40], + "contentsOpaqueForText": true, "transform": 1 }, { @@ -53,6 +54,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='scrolled-absolute-grandchildren-not-contained' class='scrolled')", "position": [6, 90], "bounds": [75, 24], + "contentsOpaqueForText": true, "transform": 2 }, { @@ -96,6 +98,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='scrolled-absolute-grandchildren' class='scrolled')", "position": [6, 34], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 4 }, { @@ -125,6 +128,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV id='positioned-absolute-not-contained' class='positionAbsolute positioned')", "position": [25, 65], "bounds": [80, 40], + "contentsOpaqueForText": true, "transform": 5 }, { @@ -139,6 +143,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='scrolled-absolute-not-contained' class='scrolled')", "position": [6, 90], "bounds": [75, 24], + "contentsOpaqueForText": true, "transform": 6 }, { @@ -174,6 +179,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV id='positioned-absolute-sibling-grandchildren-not-contained' class='positionAbsolute positioned')", "position": [25, 65], "bounds": [80, 40], + "contentsOpaqueForText": true, "transform": 7 }, { @@ -188,6 +194,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='scrolled-absolute-sibling-grandchildren-not-contained' class='scrolled')", "position": [6, 90], "bounds": [75, 24], + "contentsOpaqueForText": true, "transform": 8 }, { @@ -231,6 +238,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='scrolled-absolute-sibling-grandchildren' class='scrolled')", "position": [6, 34], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 10 }, { @@ -260,6 +268,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV id='positioned-absolute-sibling-not-contained' class='positionAbsolute positioned')", "position": [25, 65], "bounds": [80, 40], + "contentsOpaqueForText": true, "transform": 11 }, { @@ -274,6 +283,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='scrolled-absolute-sibling-not-contained' class='scrolled')", "position": [6, 90], "bounds": [75, 24], + "contentsOpaqueForText": true, "transform": 12 }, { @@ -311,6 +321,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='scrolled-absolute-sibling' class='scrolled')", "position": [6, 34], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 14 }, { @@ -348,6 +359,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='scrolled-absolute' class='scrolled')", "position": [6, 34], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 16 }, { @@ -398,6 +410,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='scrolled-fixed-sibling-grandchildren' class='scrolled')", "position": [6, 90], "bounds": [75, 24], + "contentsOpaqueForText": true, "transform": 18 }, { @@ -442,6 +455,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='scrolled-fixed-sibling' class='scrolled')", "position": [6, 90], "bounds": [75, 24], + "contentsOpaqueForText": true, "transform": 22 }, { @@ -492,6 +506,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='scrolled-fixed-grandchildren' class='scrolled')", "position": [6, 90], "bounds": [75, 24], + "contentsOpaqueForText": true, "transform": 24 }, { @@ -536,6 +551,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='scrolled-fixed' class='scrolled')", "position": [6, 90], "bounds": [75, 24], + "contentsOpaqueForText": true, "transform": 28 }, { @@ -592,6 +608,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='scrolled-absolute-grandchildren-not-contained' class='scrolled onTop')", "position": [6, 62], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 2 }, { @@ -606,6 +623,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='scrolled-absolute-grandchildren' class='scrolled onTop')", "position": [6, 62], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 4 }, { @@ -620,6 +638,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='scrolled-absolute-not-contained' class='scrolled onTop')", "position": [6, 62], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 6 }, { @@ -634,6 +653,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='scrolled-absolute-sibling-grandchildren-not-contained' class='scrolled onTop')", "position": [6, 62], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 8 }, { @@ -648,6 +668,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='scrolled-absolute-sibling-grandchildren' class='scrolled onTop')", "position": [6, 62], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 10 }, { @@ -662,6 +683,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='scrolled-absolute-sibling-not-contained' class='scrolled onTop')", "position": [6, 62], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 12 }, { @@ -676,6 +698,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='scrolled-absolute-sibling' class='scrolled onTop')", "position": [6, 62], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 14 }, { @@ -690,6 +713,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='scrolled-absolute' class='scrolled onTop')", "position": [6, 62], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 16 }, { @@ -704,6 +728,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='scrolled-fixed-sibling-grandchildren' class='scrolled onTop')", "position": [6, 62], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 18 }, { @@ -718,6 +743,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='scrolled-fixed-sibling' class='scrolled onTop')", "position": [6, 62], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 22 }, { @@ -732,6 +758,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='scrolled-fixed-grandchildren' class='scrolled onTop')", "position": [6, 62], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 24 }, { @@ -746,6 +773,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='scrolled-fixed' class='scrolled onTop')", "position": [6, 62], "bounds": [75, 80], + "contentsOpaqueForText": true, "transform": 28 }, {
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/rtl/rtl-iframe-absolute-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/rtl/rtl-iframe-absolute-expected.txt index 2ea79aa..162857d 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/rtl/rtl-iframe-absolute-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/rtl/rtl-iframe-absolute-expected.txt
@@ -13,6 +13,7 @@ { "name": "LayoutView #document", "bounds": [400, 400], + "contentsOpaqueForText": true, "backgroundColor": "#FF0000" }, {
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/rtl/rtl-iframe-absolute-overflow-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/rtl/rtl-iframe-absolute-overflow-expected.txt index 5984e94..770669a 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/rtl/rtl-iframe-absolute-overflow-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/rtl/rtl-iframe-absolute-overflow-expected.txt
@@ -14,6 +14,7 @@ "name": "Scrolling Contents Layer", "position": [15, 0], "bounds": [1000, 1000], + "contentsOpaqueForText": true, "backgroundColor": "#FF0000", "transform": 1 },
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/rtl/rtl-iframe-absolute-overflow-scrolled-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/rtl/rtl-iframe-absolute-overflow-scrolled-expected.txt index eca78de..6c01cc9f 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/rtl/rtl-iframe-absolute-overflow-scrolled-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/rtl/rtl-iframe-absolute-overflow-scrolled-expected.txt
@@ -14,6 +14,7 @@ "name": "Scrolling Contents Layer", "position": [15, 0], "bounds": [1000, 1000], + "contentsOpaqueForText": true, "backgroundColor": "#FF0000", "transform": 1 },
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/rtl/rtl-iframe-fixed-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/rtl/rtl-iframe-fixed-expected.txt index 2ea79aa..162857d 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/rtl/rtl-iframe-fixed-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/rtl/rtl-iframe-fixed-expected.txt
@@ -13,6 +13,7 @@ { "name": "LayoutView #document", "bounds": [400, 400], + "contentsOpaqueForText": true, "backgroundColor": "#FF0000" }, {
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/rtl/rtl-iframe-fixed-overflow-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/rtl/rtl-iframe-fixed-overflow-expected.txt index 4b9a3be0d..394e57a 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/rtl/rtl-iframe-fixed-overflow-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/rtl/rtl-iframe-fixed-overflow-expected.txt
@@ -14,6 +14,7 @@ "name": "Scrolling Contents Layer", "position": [15, 0], "bounds": [1000, 1000], + "contentsOpaqueForText": true, "backgroundColor": "#FF0000", "transform": 1 },
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/rtl/rtl-iframe-fixed-overflow-scrolled-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/rtl/rtl-iframe-fixed-overflow-scrolled-expected.txt index 4b9a3be0d..394e57a 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/rtl/rtl-iframe-fixed-overflow-scrolled-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/rtl/rtl-iframe-fixed-overflow-scrolled-expected.txt
@@ -14,6 +14,7 @@ "name": "Scrolling Contents Layer", "position": [15, 0], "bounds": [1000, 1000], + "contentsOpaqueForText": true, "backgroundColor": "#FF0000", "transform": 1 },
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/add-remove-squashed-layers-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/add-remove-squashed-layers-expected.txt index 982d1f2..9ef2bfa 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/add-remove-squashed-layers-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/add-remove-squashed-layers-expected.txt
@@ -20,6 +20,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV id='A' class='overlap1')", "position": [80, 80], "bounds": [180, 180], + "contentsOpaqueForText": true, "transform": 1 } ], @@ -56,6 +57,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV id='A' class='overlap1')", "position": [80, 80], "bounds": [260, 260], + "contentsOpaqueForText": true, "invalidations": [ [160, 160, 100, 100] ], @@ -95,6 +97,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV id='A' class='overlap1')", "position": [80, 80], "bounds": [260, 260], + "contentsOpaqueForText": true, "invalidations": [ [80, 80, 100, 100] ], @@ -134,6 +137,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV id='C' class='overlap3')", "position": [240, 240], "bounds": [100, 100], + "contentsOpaqueForText": true, "invalidations": [ [0, 0, 100, 100] ], @@ -173,6 +177,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV id='B' class='overlap2')", "position": [160, 160], "bounds": [180, 180], + "contentsOpaqueForText": true, "invalidations": [ [80, 80, 100, 100], [0, 0, 100, 100] @@ -213,6 +218,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV id='A' class='overlap1')", "position": [80, 80], "bounds": [180, 180], + "contentsOpaqueForText": true, "invalidations": [ [80, 80, 100, 100], [0, 0, 100, 100]
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/composited-bounds-for-negative-z-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/composited-bounds-for-negative-z-expected.txt index db2561c..bd7726e 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/composited-bounds-for-negative-z-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/composited-bounds-for-negative-z-expected.txt
@@ -35,6 +35,7 @@ { "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV)", "bounds": [285, 1000], + "contentsOpaqueForText": true, "transform": 2 } ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/invisible-layers-should-not-affect-geometry-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/invisible-layers-should-not-affect-geometry-expected.txt index 0a94427..e133745 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/invisible-layers-should-not-affect-geometry-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/invisible-layers-should-not-affect-geometry-expected.txt
@@ -16,6 +16,7 @@ { "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box')", "bounds": [100, 100], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/move-squashing-layer-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/move-squashing-layer-expected.txt index 5c610a81..7f9f65c 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/move-squashing-layer-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/move-squashing-layer-expected.txt
@@ -26,6 +26,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='squashed')", "position": [-92, -92], "bounds": [100, 100], + "contentsOpaqueForText": true, "transform": 2 } ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/no-squashing-for-filters-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/no-squashing-for-filters-expected.txt index 1676f50..581c6fc 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/no-squashing-for-filters-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/no-squashing-for-filters-expected.txt
@@ -22,7 +22,8 @@ { "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='trysquashed')", "position": [50, 50], - "bounds": [50, 50] + "bounds": [50, 50], + "contentsOpaqueForText": true } ], "transforms": [
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/opacity-squashed-owner-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/opacity-squashed-owner-expected.txt index d616b34..15db889 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/opacity-squashed-owner-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/opacity-squashed-owner-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='squashed')", "position": [8, -4], "bounds": [40, 90], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/repaint-child-of-squashed-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/repaint-child-of-squashed-expected.txt index ec70799..9991965 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/repaint-child-of-squashed-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/repaint-child-of-squashed-expected.txt
@@ -18,6 +18,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box top')", "position": [80, 80], "bounds": [100, 100], + "contentsOpaqueForText": true, "transform": 1 } ], @@ -54,6 +55,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box top')", "position": [80, 80], "bounds": [100, 100], + "contentsOpaqueForText": true, "invalidations": [ [10, 10, 50, 50] ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/selection-repaint-with-gaps-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/selection-repaint-with-gaps-expected.txt index f33b949..78299bb 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/selection-repaint-with-gaps-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/selection-repaint-with-gaps-expected.txt
@@ -16,6 +16,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='item')", "position": [7, 27], "bounds": [100, 210], + "contentsOpaqueForText": true, "invalidations": [ [0, 80, 40, 39] ], @@ -52,6 +53,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='item')", "position": [7, 27], "bounds": [100, 210], + "contentsOpaqueForText": true, "invalidations": [ [0, 80, 42, 39], [0, 160, 40, 39]
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-above-fixed-1-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-above-fixed-1-expected.txt index 275841b..0d9acc8 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-above-fixed-1-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-above-fixed-1-expected.txt
@@ -28,7 +28,8 @@ { "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='paragraph-c' class='overlapping cyan')", "position": [0, 200], - "bounds": [200, 300] + "bounds": [200, 300], + "contentsOpaqueForText": true }, { "name": "ContentsLayer for Vertical Scrollbar Layer", @@ -86,6 +87,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='paragraph-d' class='overlapping lime')", "position": [0, 300], "bounds": [200, 300], + "contentsOpaqueForText": true, "invalidations": [ [0, 0, 200, 300] ], @@ -149,6 +151,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='paragraph-d' class='overlapping lime')", "position": [0, 300], "bounds": [200, 300], + "contentsOpaqueForText": true, "transform": 1 }, { @@ -216,6 +219,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='paragraph-e' class='overlapping cyan')", "position": [0, 400], "bounds": [200, 300], + "contentsOpaqueForText": true, "invalidations": [ [0, 0, 200, 300] ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-above-fixed-3-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-above-fixed-3-expected.txt index e306c8053..e9fc06a 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-above-fixed-3-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-above-fixed-3-expected.txt
@@ -146,6 +146,7 @@ "name": "LayoutBlockFlow (positioned) DIV id='container'", "position": [100, 100], "bounds": [200, 4000], + "contentsOpaqueForText": true, "backgroundColor": "#008000", "invalidations": [ [100, 0, 100, 100]
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-compositing-hover-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-compositing-hover-expected.txt index 7eb47f1..87757b2 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-compositing-hover-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-compositing-hover-expected.txt
@@ -26,6 +26,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')", "position": [80, 80], "bounds": [260, 260], + "contentsOpaqueForText": true, "transform": 2 } ], @@ -84,6 +85,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle2')", "position": [80, 80], "bounds": [180, 180], + "contentsOpaqueForText": true, "transform": 3 } ], @@ -144,6 +146,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')", "position": [80, 80], "bounds": [100, 100], + "contentsOpaqueForText": true, "transform": 2 }, { @@ -157,6 +160,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box top')", "position": [80, 80], "bounds": [100, 100], + "contentsOpaqueForText": true, "transform": 3 } ], @@ -217,6 +221,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')", "position": [80, 80], "bounds": [180, 180], + "contentsOpaqueForText": true, "transform": 2 }, { @@ -284,6 +289,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')", "position": [80, 80], "bounds": [260, 260], + "contentsOpaqueForText": true, "transform": 2 } ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-onto-nephew-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-onto-nephew-expected.txt index 0fde92b..00b11c6 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-onto-nephew-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-onto-nephew-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')", "position": [-85, -85], "bounds": [180, 190], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-onto-transform-backing-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-onto-transform-backing-expected.txt index 6a1f58a..e0f8c56 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-onto-transform-backing-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-onto-transform-backing-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')", "position": [-80, -80], "bounds": [260, 260], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-simple-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-simple-expected.txt index ed8c296..6c091ce 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-simple-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-simple-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')", "position": [-80, -80], "bounds": [260, 260], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-three-layers-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-three-layers-expected.txt index a3935bb..65344f0b 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-three-layers-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-three-layers-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')", "position": [-60, -60], "bounds": [180, 190], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-transform-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-transform-expected.txt index e3b77d38..f6706d0 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-transform-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-transform-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')", "position": [-101, -101], "bounds": [281, 281], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-transform-repainting-child-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-transform-repainting-child-expected.txt index dd86b55..6e1ae70 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-transform-repainting-child-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-transform-repainting-child-expected.txt
@@ -18,6 +18,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')", "position": [-101, -101], "bounds": [281, 281], + "contentsOpaqueForText": true, "transform": 1 } ], @@ -54,6 +55,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')", "position": [-101, -101], "bounds": [281, 281], + "contentsOpaqueForText": true, "invalidations": [ [0, 0, 142, 142] ], @@ -93,6 +95,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')", "position": [-101, -101], "bounds": [281, 281], + "contentsOpaqueForText": true, "invalidations": [ [0, 0, 142, 142] ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-transform-repainting-transformed-child-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-transform-repainting-transformed-child-expected.txt index dae71b8f..26d5f10 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-transform-repainting-transformed-child-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squash-transform-repainting-transformed-child-expected.txt
@@ -18,6 +18,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')", "position": [-96, -96], "bounds": [276, 276], + "contentsOpaqueForText": true, "transform": 1 } ], @@ -54,6 +55,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')", "position": [-96, -96], "bounds": [276, 276], + "contentsOpaqueForText": true, "invalidations": [ [0, 0, 132, 132] ], @@ -93,6 +95,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')", "position": [-96, -96], "bounds": [276, 276], + "contentsOpaqueForText": true, "invalidations": [ [0, 0, 132, 132] ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squashed-layer-loses-graphicslayer-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squashed-layer-loses-graphicslayer-expected.txt index b0ab39b..7cfa125d 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squashed-layer-loses-graphicslayer-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squashed-layer-loses-graphicslayer-expected.txt
@@ -20,6 +20,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV id='A' class='overlap1')", "position": [80, 80], "bounds": [260, 260], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squashed-repaints-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squashed-repaints-expected.txt index ec96575..7a4a3a0 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squashed-repaints-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squashed-repaints-expected.txt
@@ -20,6 +20,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV id='A' class='overlap1')", "position": [80, 80], "bounds": [260, 260], + "contentsOpaqueForText": true, "transform": 1 } ], @@ -56,6 +57,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV id='A' class='overlap1')", "position": [80, 80], "bounds": [260, 260], + "contentsOpaqueForText": true, "invalidations": [ [0, 0, 100, 100] ], @@ -95,6 +97,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV id='A' class='overlap1')", "position": [80, 80], "bounds": [260, 260], + "contentsOpaqueForText": true, "invalidations": [ [80, 80, 100, 100], [0, 0, 100, 100] @@ -135,6 +138,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV id='A' class='overlap1')", "position": [80, 80], "bounds": [260, 260], + "contentsOpaqueForText": true, "invalidations": [ [160, 160, 100, 100], [80, 80, 100, 100] @@ -175,6 +179,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV id='A' class='overlap1')", "position": [80, 80], "bounds": [260, 260], + "contentsOpaqueForText": true, "invalidations": [ [160, 160, 100, 100], [0, 0, 100, 100]
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squashing-sparsity-heuristic-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squashing-sparsity-heuristic-expected.txt index 36e80cb..8ab6eea 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squashing-sparsity-heuristic-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/squashing/squashing-sparsity-heuristic-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV id='A' class='overlap1')", "position": [80, 80], "bounds": [10, 10], + "contentsOpaqueForText": true, "transform": 1 }, { @@ -29,7 +30,8 @@ { "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV id='C' class='overlap3')", "position": [220, 300], - "bounds": [25, 10] + "bounds": [25, 10], + "contentsOpaqueForText": true } ], "transforms": [
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/css3/blending/mix-blend-mode-composited-layers-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/css3/blending/mix-blend-mode-composited-layers-expected.txt index 2b4da3a..9f03295 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/css3/blending/mix-blend-mode-composited-layers-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/css3/blending/mix-blend-mode-composited-layers-expected.txt
@@ -7,6 +7,7 @@ { "name": "LayoutBlockFlow DIV", "bounds": [10, 10], + "contentsOpaqueForText": true, "backgroundColor": "#0000FF", "transform": 1 },
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/css3/blending/mix-blend-mode-composited-reason-children-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/css3/blending/mix-blend-mode-composited-reason-children-expected.txt index d5508ac..0cf2cea 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/css3/blending/mix-blend-mode-composited-reason-children-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/css3/blending/mix-blend-mode-composited-reason-children-expected.txt
@@ -21,6 +21,7 @@ { "name": "LayoutBlockFlow DIV class='blended'", "bounds": [160, 90], + "contentsOpaqueForText": true, "backgroundColor": "#0000FF", "transform": 1 },
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/linux_selection_color-expected.png b/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/linux_selection_color-expected.png deleted file mode 100644 index 4110ca40..0000000 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/linux_selection_color-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/change-clip-composited-layer-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/change-clip-composited-layer-expected.txt index 6c348a91b..9e59e46 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/change-clip-composited-layer-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/change-clip-composited-layer-expected.txt
@@ -9,6 +9,7 @@ { "name": "LayoutBlockFlow DIV id='target'", "bounds": [100, 10], + "contentsOpaqueForText": true, "invalidations": [ [0, 0, 50, 10] ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/clip/clip-path-in-mask-layer-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/clip/clip-path-in-mask-layer-expected.txt index 583e2ee..508ace34 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/clip/clip-path-in-mask-layer-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/clip/clip-path-in-mask-layer-expected.txt
@@ -9,6 +9,7 @@ { "name": "LayoutBlockFlow DIV", "bounds": [200, 200], + "contentsOpaqueForText": true, "backgroundColor": "#0000FF", "invalidations": [ [0, 0, 200, 200]
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/child-of-sub-pixel-offset-composited-layer-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/child-of-sub-pixel-offset-composited-layer-expected.txt index 559f356..f1645998 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/child-of-sub-pixel-offset-composited-layer-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/child-of-sub-pixel-offset-composited-layer-expected.txt
@@ -9,6 +9,7 @@ { "name": "LayoutBlockFlow (positioned) DIV class='container'", "bounds": [14, 14], + "contentsOpaqueForText": true, "backgroundColor": "#FF0000", "invalidations": [ [0, 0, 14, 14]
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/containing-block-added-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/containing-block-added-expected.txt index fbdf692..426e350 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/containing-block-added-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/containing-block-added-expected.txt
@@ -12,6 +12,7 @@ { "name": "LayoutBlockFlow (positioned) DIV id='container'", "bounds": [125, 125], + "contentsOpaqueForText": true, "backgroundColor": "#0000FF", "invalidations": [ [0, 0, 100, 100],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/containing-block-added-individual-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/containing-block-added-individual-expected.txt index fbdf692..426e350 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/containing-block-added-individual-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/containing-block-added-individual-expected.txt
@@ -12,6 +12,7 @@ { "name": "LayoutBlockFlow (positioned) DIV id='container'", "bounds": [125, 125], + "contentsOpaqueForText": true, "backgroundColor": "#0000FF", "invalidations": [ [0, 0, 100, 100],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/fixed-pos-inside-composited-intermediate-layer-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/fixed-pos-inside-composited-intermediate-layer-expected.txt index d8dd844..c60fc1cd 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/fixed-pos-inside-composited-intermediate-layer-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/fixed-pos-inside-composited-intermediate-layer-expected.txt
@@ -18,6 +18,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='containerOverlapsComposited')", "position": [12, 12], "bounds": [100, 30000], + "contentsOpaqueForText": true, "transform": 2 }, {
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/invalidate-when-leaving-squashed-layer-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/invalidate-when-leaving-squashed-layer-expected.txt index 0151590..9c83fbc9 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/invalidate-when-leaving-squashed-layer-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/invalidate-when-leaving-squashed-layer-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV)", "position": [42, 42], "bounds": [200, 200], + "contentsOpaqueForText": true, "invalidations": [ [0, 0, 200, 200] ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/invalidation-for-subpixel-offset-of-squashed-layer-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/invalidation-for-subpixel-offset-of-squashed-layer-expected.txt index 2811bba..3cda02a 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/invalidation-for-subpixel-offset-of-squashed-layer-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/invalidation-for-subpixel-offset-of-squashed-layer-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV)", "position": [42, 42], "bounds": [251, 251], + "contentsOpaqueForText": true, "invalidations": [ [50, 50, 201, 201] ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/overlap-test-with-filter-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/overlap-test-with-filter-expected.txt index e8af0fb6a..2f4b1ca 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/overlap-test-with-filter-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/overlap-test-with-filter-expected.txt
@@ -13,6 +13,7 @@ { "name": "LayoutView #document", "bounds": [300, 100], + "contentsOpaqueForText": true, "backgroundColor": "#FFFF00" }, {
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/repaint-overflow-scrolled-squashed-content-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/repaint-overflow-scrolled-squashed-content-expected.txt index 011ff15..c67b40f 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/repaint-overflow-scrolled-squashed-content-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/repaint-overflow-scrolled-squashed-content-expected.txt
@@ -16,6 +16,7 @@ { "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV id='foo')", "bounds": [100, 1000], + "contentsOpaqueForText": true, "invalidations": [ [0, 0, 100, 1000] ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/repaint-via-layout-offset-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/repaint-via-layout-offset-expected.txt index b2931b4..3e3f25cc 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/repaint-via-layout-offset-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/repaint-via-layout-offset-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) SPAN class='child')", "position": [42, 42], "bounds": [50, 50], + "contentsOpaqueForText": true, "invalidations": [ [0, 0, 50, 50] ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/resize-squashing-layer-that-needs-full-repaint-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/resize-squashing-layer-that-needs-full-repaint-expected.txt index e4f856f..9306b06 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/resize-squashing-layer-that-needs-full-repaint-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/resize-squashing-layer-that-needs-full-repaint-expected.txt
@@ -16,6 +16,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV)", "position": [47, 47], "bounds": [500, 500], + "contentsOpaqueForText": true, "invalidations": [ [0, 0, 500, 500] ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/squash-partial-repaint-inside-squashed-layer-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/squash-partial-repaint-inside-squashed-layer-expected.txt index 97852b7..ec85b9bb 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/squash-partial-repaint-inside-squashed-layer-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/squash-partial-repaint-inside-squashed-layer-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')", "position": [80, 80], "bounds": [262, 200], + "contentsOpaqueForText": true, "invalidations": [ [80, 80, 182, 29] ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/squashing-inside-preserve-3d-element-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/squashing-inside-preserve-3d-element-expected.txt index bd2eda0e..f8aba91 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/squashing-inside-preserve-3d-element-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/squashing-inside-preserve-3d-element-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV id='target')", "position": [20, 20], "bounds": [100, 100], + "contentsOpaqueForText": true, "invalidations": [ [0, 0, 100, 100] ],
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/scroll/composited-iframe-scroll-repaint-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/scroll/composited-iframe-scroll-repaint-expected.txt index cd63182..88b1be5 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/scroll/composited-iframe-scroll-repaint-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/scroll/composited-iframe-scroll-repaint-expected.txt
@@ -14,6 +14,7 @@ { "name": "Scrolling Contents Layer", "bounds": [300, 516], + "contentsOpaqueForText": true, "backgroundColor": "#EEEEEE", "transform": 3 },
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/table/composited-table-background-composited-row-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/table/composited-table-background-composited-row-expected.txt index 635df9d..a31d501 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/table/composited-table-background-composited-row-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/table/composited-table-background-composited-row-expected.txt
@@ -10,6 +10,7 @@ "name": "LayoutTableRow TR id='target'", "position": [8, 96], "bounds": [186, 64], + "contentsOpaqueForText": true, "backgroundColor": "#ADD8E6", "invalidations": [ [0, 0, 186, 64]
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt index 635df9d..a31d501 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt
@@ -10,6 +10,7 @@ "name": "LayoutTableRow TR id='target'", "position": [8, 96], "bounds": [186, 64], + "contentsOpaqueForText": true, "backgroundColor": "#ADD8E6", "invalidations": [ [0, 0, 186, 64]
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt index 6014755..48f4c5e 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt
@@ -10,6 +10,7 @@ "name": "LayoutTableSection TBODY id='target'", "position": [8, 28], "bounds": [186, 134], + "contentsOpaqueForText": true, "backgroundColor": "#ADD8E6", "invalidations": [ [0, 0, 186, 134]
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt index 6014755..48f4c5e 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt
@@ -10,6 +10,7 @@ "name": "LayoutTableSection TBODY id='target'", "position": [8, 28], "bounds": [186, 134], + "contentsOpaqueForText": true, "backgroundColor": "#ADD8E6", "invalidations": [ [0, 0, 186, 134]
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/table/composited-table-background-section-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/table/composited-table-background-section-expected.txt index 55002c3..179e081f 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/table/composited-table-background-section-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/table/composited-table-background-section-expected.txt
@@ -10,6 +10,7 @@ "name": "LayoutTableSection TBODY id='target'", "position": [8, 28], "bounds": [186, 134], + "contentsOpaqueForText": true, "backgroundColor": "#ADD8E6", "invalidations": [ [0, 0, 186, 134]
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt index 55002c3..179e081f 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt
@@ -10,6 +10,7 @@ "name": "LayoutTableSection TBODY id='target'", "position": [8, 28], "bounds": [186, 134], + "contentsOpaqueForText": true, "backgroundColor": "#ADD8E6", "invalidations": [ [0, 0, 186, 134]
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/table/fixed-table-overflow-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/table/fixed-table-overflow-expected.txt index d70d88e..17f2484 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/table/fixed-table-overflow-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/table/fixed-table-overflow-expected.txt
@@ -15,6 +15,7 @@ "name": "LayoutBlockFlow (positioned) TD id='moveMe' class='fixed'", "position": [-100, 0], "bounds": [200, 100], + "contentsOpaqueForText": true, "backgroundColor": "#008000", "invalidations": [ [0, 0, 200, 100]
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/prefer_compositing_to_lcd_text/compositing/overflow/scroll-parent-with-non-stacking-context-composited-ancestor-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/prefer_compositing_to_lcd_text/compositing/overflow/scroll-parent-with-non-stacking-context-composited-ancestor-expected.txt new file mode 100644 index 0000000..0a2ca6f --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/prefer_compositing_to_lcd_text/compositing/overflow/scroll-parent-with-non-stacking-context-composited-ancestor-expected.txt
@@ -0,0 +1,67 @@ +{ + "layers": [ + { + "name": "Scrolling Contents Layer", + "bounds": [800, 600], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF" + }, + { + "name": "LayoutBlockFlow DIV id='intervening'", + "bounds": [300, 300], + "contentsOpaque": true, + "backfaceVisibility": "hidden", + "backgroundColor": "#FFEFD5", + "transform": 1 + }, + { + "name": "LayoutBlockFlow DIV id='scroller'", + "bounds": [102, 102], + "backfaceVisibility": "hidden", + "transform": 1 + }, + { + "name": "LayoutBlockFlow (positioned) DIV id='fixed'", + "position": [60, 60], + "bounds": [80, 80], + "contentsOpaque": true, + "backgroundColor": "#008000" + }, + { + "name": "LayoutBlockFlow (relative positioned) DIV class='scrolled'", + "position": [5, 5], + "bounds": [60, 40], + "contentsOpaque": true, + "backfaceVisibility": "hidden", + "backgroundColor": "#0000FF", + "transform": 1 + }, + { + "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV class='scrolled')", + "position": [5, 49], + "bounds": [60, 128], + "contentsOpaqueForText": true, + "backfaceVisibility": "hidden", + "transform": 1 + }, + { + "name": "ContentsLayer for Vertical Scrollbar Layer", + "position": [94, 1], + "bounds": [7, 100], + "backfaceVisibility": "hidden", + "transform": 1 + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [98, 90, 0, 1] + ] + } + ] +} +
diff --git a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt index c5a25b0..1684c94a 100644 --- a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt +++ b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -786,6 +786,7 @@ method getColorSettings interface ImageDecoder attribute @@toStringTag + getter complete getter frameCount getter repetitionCount getter type
diff --git a/third_party/blink/web_tests/inspector-protocol/dom-snapshot/captureSnapshot-ua-shadow-tree2-expected.txt b/third_party/blink/web_tests/inspector-protocol/dom-snapshot/captureSnapshot-ua-shadow-tree2-expected.txt deleted file mode 100644 index f7a6815f..0000000 --- a/third_party/blink/web_tests/inspector-protocol/dom-snapshot/captureSnapshot-ua-shadow-tree2-expected.txt +++ /dev/null
@@ -1,343 +0,0 @@ -Blocked access to external URL http://example.com/A.png -Blocked access to external URL http://example.com/B.png -Blocked access to external URL http://example.com/C.png -Tests that DOMSnapshot skips UA shadow root when traversing the DOM tree -{ - documents : [ - [0] : { - baseURL : 0 - contentHeight : 600 - contentLanguage : -1 - contentWidth : 800 - documentURL : <number> - encodingName : 1 - frameId : <number> - layout : { - bounds : [ - [0] : [ - [0] : 0 - [1] : 0 - [2] : 800 - [3] : 600 - ] - [1] : [ - [0] : 0 - [1] : 0 - [2] : 800 - [3] : 600 - ] - [2] : [ - [0] : 8 - [1] : 8 - [2] : 784 - [3] : 584 - ] - [3] : [ - [0] : 8 - [1] : 8 - [2] : 16 - [3] : 16 - ] - [4] : [ - [0] : 24 - [1] : 16 - [2] : 10 - [3] : 10 - ] - [5] : [ - [0] : 34 - [1] : 8 - [2] : 16 - [3] : 16 - ] - [6] : [ - [0] : 50 - [1] : 16 - [2] : 10 - [3] : 10 - ] - [7] : [ - [0] : 60 - [1] : 8 - [2] : 16 - [3] : 16 - ] - [8] : [ - [0] : 0 - [1] : 0 - [2] : 0 - [3] : 0 - ] - ] - nodeIndex : [ - [0] : 0 - [1] : 1 - [2] : 6 - [3] : 8 - [4] : 9 - [5] : 10 - [6] : 11 - [7] : 12 - [8] : 13 - ] - stackingContexts : { - index : [ - [0] : 0 - [1] : 1 - ] - } - styles : [ - [0] : [ - ] - [1] : [ - ] - [2] : [ - ] - [3] : [ - ] - [4] : [ - ] - [5] : [ - ] - [6] : [ - ] - [7] : [ - ] - [8] : [ - ] - ] - text : [ - [0] : -1 - [1] : -1 - [2] : -1 - [3] : -1 - [4] : 9 - [5] : -1 - [6] : 9 - [7] : -1 - [8] : 20 - ] - } - nodes : { - attributes : [ - [0] : [ - ] - [1] : [ - ] - [2] : [ - ] - [3] : [ - ] - [4] : [ - ] - [5] : [ - ] - [6] : [ - ] - [7] : [ - ] - [8] : [ - [0] : 12 - [1] : 13 - [2] : 14 - [3] : 15 - ] - [9] : [ - ] - [10] : [ - [0] : 12 - [1] : 16 - [2] : 14 - [3] : 17 - ] - [11] : [ - ] - [12] : [ - [0] : 12 - [1] : 18 - [2] : 14 - [3] : 19 - ] - [13] : [ - ] - ] - backendNodeId : <object> - contentDocumentIndex : { - index : [ - ] - value : [ - ] - } - currentSourceURL : { - index : [ - [0] : 8 - [1] : 10 - [2] : 12 - ] - value : [ - [0] : -1 - [1] : -1 - [2] : -1 - ] - } - inputChecked : { - index : [ - ] - } - inputValue : { - index : [ - ] - value : [ - ] - } - isClickable : { - index : [ - ] - } - nodeName : [ - [0] : 3 - [1] : 4 - [2] : 5 - [3] : 6 - [4] : 7 - [5] : 7 - [6] : 10 - [7] : 7 - [8] : 11 - [9] : 7 - [10] : 11 - [11] : 7 - [12] : 11 - [13] : 7 - ] - nodeType : [ - [0] : 9 - [1] : 1 - [2] : 1 - [3] : 1 - [4] : 3 - [5] : 3 - [6] : 1 - [7] : 3 - [8] : 1 - [9] : 3 - [10] : 1 - [11] : 3 - [12] : 1 - [13] : 3 - ] - nodeValue : [ - [0] : -1 - [1] : -1 - [2] : -1 - [3] : -1 - [4] : 8 - [5] : 9 - [6] : -1 - [7] : 9 - [8] : -1 - [9] : 9 - [10] : -1 - [11] : 9 - [12] : -1 - [13] : 20 - ] - optionSelected : { - index : [ - ] - } - originURL : { - index : [ - ] - value : [ - ] - } - parentIndex : [ - [0] : -1 - [1] : 0 - [2] : 1 - [3] : 2 - [4] : 3 - [5] : 2 - [6] : 1 - [7] : 6 - [8] : 6 - [9] : 6 - [10] : 6 - [11] : 6 - [12] : 6 - [13] : 6 - ] - pseudoType : { - index : [ - ] - value : [ - ] - } - textValue : { - index : [ - ] - value : [ - ] - } - } - publicId : -1 - scrollOffsetX : 0 - scrollOffsetY : 0 - systemId : -1 - textBoxes : { - bounds : [ - [0] : [ - [0] : 24 - [1] : 16 - [2] : 10 - [3] : 10 - ] - [1] : [ - [0] : 50 - [1] : 16 - [2] : 10 - [3] : 10 - ] - ] - layoutIndex : [ - [0] : 4 - [1] : 6 - ] - length : [ - [0] : 1 - [1] : 1 - ] - start : [ - [0] : 0 - [1] : 0 - ] - } - title : -1 - } - ] - strings : [ - [0] : - [1] : windows-1252 - [2] : - [3] : #document - [4] : HTML - [5] : HEAD - [6] : STYLE - [7] : #text - [8] : body { font: 10px Ahem; } - [9] : - [10] : BODY - [11] : IMG - [12] : id - [13] : one - [14] : src - [15] : http://example.com/A.png - [16] : two - [17] : http://example.com/B.png - [18] : three - [19] : http://example.com/C.png - [20] : - ] -} -
diff --git a/third_party/blink/web_tests/inspector-protocol/dom-snapshot/captureSnapshot-ua-shadow-tree2.js b/third_party/blink/web_tests/inspector-protocol/dom-snapshot/captureSnapshot-ua-shadow-tree2.js deleted file mode 100644 index 2a3c507e..0000000 --- a/third_party/blink/web_tests/inspector-protocol/dom-snapshot/captureSnapshot-ua-shadow-tree2.js +++ /dev/null
@@ -1,25 +0,0 @@ -(async function(testRunner) { - var {page, session, dp} = await testRunner.startHTML(` - <html> - <style> - body { font: 10px Ahem; } - </style> - <body> - <img id="one" src="http://example.com/A.png"/> - <img id="two" src="http://example.com/B.png"/> - <img id="three" src="http://example.com/C.png"/> - </body> - </html>`, 'Tests that DOMSnapshot skips UA shadow root when traversing the DOM tree'); - - var response = await dp.DOMSnapshot.captureSnapshot({computedStyles: []}); - if (response.error) { - testRunner.log(response); - } else { - response.result.strings[response.result.documents[0].documentURL] = ''; - response.result.strings[response.result.documents[0].frameId] = ''; - testRunner.log( - response.result, undefined, - ['documentURL', 'frameId', 'backendNodeId']); - } - testRunner.completeTest(); -})
diff --git a/third_party/blink/web_tests/paint/invalidation/change-clip-composited-layer-expected.txt b/third_party/blink/web_tests/paint/invalidation/change-clip-composited-layer-expected.txt index c180aec..978e28c 100644 --- a/third_party/blink/web_tests/paint/invalidation/change-clip-composited-layer-expected.txt +++ b/third_party/blink/web_tests/paint/invalidation/change-clip-composited-layer-expected.txt
@@ -9,6 +9,7 @@ { "name": "LayoutNGBlockFlow DIV id='target'", "bounds": [100, 10], + "contentsOpaqueForText": true, "invalidations": [ [0, 0, 50, 10] ],
diff --git a/third_party/blink/web_tests/paint/invalidation/clip/clip-path-in-mask-layer-expected.txt b/third_party/blink/web_tests/paint/invalidation/clip/clip-path-in-mask-layer-expected.txt index 1f1d520..22a1e74 100644 --- a/third_party/blink/web_tests/paint/invalidation/clip/clip-path-in-mask-layer-expected.txt +++ b/third_party/blink/web_tests/paint/invalidation/clip/clip-path-in-mask-layer-expected.txt
@@ -9,6 +9,7 @@ { "name": "LayoutNGBlockFlow DIV", "bounds": [200, 200], + "contentsOpaqueForText": true, "backgroundColor": "#0000FF", "invalidations": [ [0, 0, 200, 200]
diff --git a/third_party/blink/web_tests/paint/invalidation/compositing/child-of-sub-pixel-offset-composited-layer-expected.txt b/third_party/blink/web_tests/paint/invalidation/compositing/child-of-sub-pixel-offset-composited-layer-expected.txt index 6f27e50a..37d8d42 100644 --- a/third_party/blink/web_tests/paint/invalidation/compositing/child-of-sub-pixel-offset-composited-layer-expected.txt +++ b/third_party/blink/web_tests/paint/invalidation/compositing/child-of-sub-pixel-offset-composited-layer-expected.txt
@@ -9,6 +9,7 @@ { "name": "LayoutNGBlockFlow (positioned) DIV class='container'", "bounds": [14, 14], + "contentsOpaqueForText": true, "backgroundColor": "#FF0000", "invalidations": [ [0, 0, 14, 14]
diff --git a/third_party/blink/web_tests/paint/invalidation/compositing/containing-block-added-expected.txt b/third_party/blink/web_tests/paint/invalidation/compositing/containing-block-added-expected.txt index 26e9564f..7ceba83 100644 --- a/third_party/blink/web_tests/paint/invalidation/compositing/containing-block-added-expected.txt +++ b/third_party/blink/web_tests/paint/invalidation/compositing/containing-block-added-expected.txt
@@ -12,6 +12,7 @@ { "name": "LayoutNGBlockFlow (positioned) DIV id='container'", "bounds": [125, 125], + "contentsOpaqueForText": true, "backgroundColor": "#0000FF", "invalidations": [ [0, 0, 100, 100],
diff --git a/third_party/blink/web_tests/paint/invalidation/compositing/containing-block-added-individual-expected.txt b/third_party/blink/web_tests/paint/invalidation/compositing/containing-block-added-individual-expected.txt index 26e9564f..7ceba83 100644 --- a/third_party/blink/web_tests/paint/invalidation/compositing/containing-block-added-individual-expected.txt +++ b/third_party/blink/web_tests/paint/invalidation/compositing/containing-block-added-individual-expected.txt
@@ -12,6 +12,7 @@ { "name": "LayoutNGBlockFlow (positioned) DIV id='container'", "bounds": [125, 125], + "contentsOpaqueForText": true, "backgroundColor": "#0000FF", "invalidations": [ [0, 0, 100, 100],
diff --git a/third_party/blink/web_tests/paint/invalidation/compositing/fixed-pos-inside-composited-intermediate-layer-expected.txt b/third_party/blink/web_tests/paint/invalidation/compositing/fixed-pos-inside-composited-intermediate-layer-expected.txt index 3f8ba64..5ebccff 100644 --- a/third_party/blink/web_tests/paint/invalidation/compositing/fixed-pos-inside-composited-intermediate-layer-expected.txt +++ b/third_party/blink/web_tests/paint/invalidation/compositing/fixed-pos-inside-composited-intermediate-layer-expected.txt
@@ -18,6 +18,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='containerOverlapsComposited')", "position": [12, 12], "bounds": [100, 30000], + "contentsOpaqueForText": true, "transform": 2 }, {
diff --git a/third_party/blink/web_tests/paint/invalidation/compositing/invalidate-when-leaving-squashed-layer-expected.txt b/third_party/blink/web_tests/paint/invalidation/compositing/invalidate-when-leaving-squashed-layer-expected.txt index c421690..7736a42 100644 --- a/third_party/blink/web_tests/paint/invalidation/compositing/invalidate-when-leaving-squashed-layer-expected.txt +++ b/third_party/blink/web_tests/paint/invalidation/compositing/invalidate-when-leaving-squashed-layer-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV)", "position": [42, 42], "bounds": [200, 200], + "contentsOpaqueForText": true, "invalidations": [ [0, 0, 200, 200] ],
diff --git a/third_party/blink/web_tests/paint/invalidation/compositing/invalidation-for-subpixel-offset-of-squashed-layer-expected.txt b/third_party/blink/web_tests/paint/invalidation/compositing/invalidation-for-subpixel-offset-of-squashed-layer-expected.txt index bc106d1..d52436a 100644 --- a/third_party/blink/web_tests/paint/invalidation/compositing/invalidation-for-subpixel-offset-of-squashed-layer-expected.txt +++ b/third_party/blink/web_tests/paint/invalidation/compositing/invalidation-for-subpixel-offset-of-squashed-layer-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV)", "position": [42, 42], "bounds": [251, 251], + "contentsOpaqueForText": true, "invalidations": [ [50, 50, 201, 201] ],
diff --git a/third_party/blink/web_tests/paint/invalidation/compositing/overlap-test-with-filter-expected.txt b/third_party/blink/web_tests/paint/invalidation/compositing/overlap-test-with-filter-expected.txt index 988776a9..4a384b5 100644 --- a/third_party/blink/web_tests/paint/invalidation/compositing/overlap-test-with-filter-expected.txt +++ b/third_party/blink/web_tests/paint/invalidation/compositing/overlap-test-with-filter-expected.txt
@@ -13,6 +13,7 @@ { "name": "LayoutView #document", "bounds": [300, 100], + "contentsOpaqueForText": true, "backgroundColor": "#FFFF00" }, {
diff --git a/third_party/blink/web_tests/paint/invalidation/compositing/repaint-overflow-scrolled-squashed-content-expected.txt b/third_party/blink/web_tests/paint/invalidation/compositing/repaint-overflow-scrolled-squashed-content-expected.txt index 9d86bbc3..b4b85a3 100644 --- a/third_party/blink/web_tests/paint/invalidation/compositing/repaint-overflow-scrolled-squashed-content-expected.txt +++ b/third_party/blink/web_tests/paint/invalidation/compositing/repaint-overflow-scrolled-squashed-content-expected.txt
@@ -16,6 +16,7 @@ { "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV id='foo')", "bounds": [100, 1000], + "contentsOpaqueForText": true, "invalidations": [ [0, 0, 100, 1000] ],
diff --git a/third_party/blink/web_tests/paint/invalidation/compositing/repaint-via-layout-offset-expected.txt b/third_party/blink/web_tests/paint/invalidation/compositing/repaint-via-layout-offset-expected.txt index 86a609c3..8dfd3f5d 100644 --- a/third_party/blink/web_tests/paint/invalidation/compositing/repaint-via-layout-offset-expected.txt +++ b/third_party/blink/web_tests/paint/invalidation/compositing/repaint-via-layout-offset-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) SPAN class='child')", "position": [42, 42], "bounds": [50, 50], + "contentsOpaqueForText": true, "invalidations": [ [0, 0, 50, 50] ],
diff --git a/third_party/blink/web_tests/paint/invalidation/compositing/resize-squashing-layer-that-needs-full-repaint-expected.txt b/third_party/blink/web_tests/paint/invalidation/compositing/resize-squashing-layer-that-needs-full-repaint-expected.txt index f207c0ee..d86375a3c 100644 --- a/third_party/blink/web_tests/paint/invalidation/compositing/resize-squashing-layer-that-needs-full-repaint-expected.txt +++ b/third_party/blink/web_tests/paint/invalidation/compositing/resize-squashing-layer-that-needs-full-repaint-expected.txt
@@ -16,6 +16,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV)", "position": [47, 47], "bounds": [500, 500], + "contentsOpaqueForText": true, "invalidations": [ [0, 0, 500, 500] ],
diff --git a/third_party/blink/web_tests/paint/invalidation/compositing/squash-partial-repaint-inside-squashed-layer-expected.txt b/third_party/blink/web_tests/paint/invalidation/compositing/squash-partial-repaint-inside-squashed-layer-expected.txt index fa9c08c..d4b703c 100644 --- a/third_party/blink/web_tests/paint/invalidation/compositing/squash-partial-repaint-inside-squashed-layer-expected.txt +++ b/third_party/blink/web_tests/paint/invalidation/compositing/squash-partial-repaint-inside-squashed-layer-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='box middle')", "position": [80, 80], "bounds": [262, 200], + "contentsOpaqueForText": true, "invalidations": [ [80, 80, 182, 29] ],
diff --git a/third_party/blink/web_tests/paint/invalidation/compositing/squashing-inside-preserve-3d-element-expected.txt b/third_party/blink/web_tests/paint/invalidation/compositing/squashing-inside-preserve-3d-element-expected.txt index 8e4eaae..d01421a9 100644 --- a/third_party/blink/web_tests/paint/invalidation/compositing/squashing-inside-preserve-3d-element-expected.txt +++ b/third_party/blink/web_tests/paint/invalidation/compositing/squashing-inside-preserve-3d-element-expected.txt
@@ -17,6 +17,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV id='target')", "position": [20, 20], "bounds": [100, 100], + "contentsOpaqueForText": true, "invalidations": [ [0, 0, 100, 100] ],
diff --git a/third_party/blink/web_tests/paint/invalidation/scroll/composited-iframe-scroll-repaint-expected.txt b/third_party/blink/web_tests/paint/invalidation/scroll/composited-iframe-scroll-repaint-expected.txt index 6b1e65d..32b322a 100644 --- a/third_party/blink/web_tests/paint/invalidation/scroll/composited-iframe-scroll-repaint-expected.txt +++ b/third_party/blink/web_tests/paint/invalidation/scroll/composited-iframe-scroll-repaint-expected.txt
@@ -14,6 +14,7 @@ { "name": "Scrolling Contents Layer", "bounds": [300, 516], + "contentsOpaqueForText": true, "backgroundColor": "#EEEEEE", "transform": 3 },
diff --git a/third_party/blink/web_tests/paint/invalidation/svg/transform-focus-ring-repaint-expected.txt b/third_party/blink/web_tests/paint/invalidation/svg/transform-focus-ring-repaint-expected.txt index 3885b032..681d8c8ed 100644 --- a/third_party/blink/web_tests/paint/invalidation/svg/transform-focus-ring-repaint-expected.txt +++ b/third_party/blink/web_tests/paint/invalidation/svg/transform-focus-ring-repaint-expected.txt
@@ -21,6 +21,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV)", "position": [100, 100], "bounds": [300, 440], + "contentsOpaqueForText": true, "transform": 1 } ],
diff --git a/third_party/blink/web_tests/paint/invalidation/table/fixed-table-overflow-expected.txt b/third_party/blink/web_tests/paint/invalidation/table/fixed-table-overflow-expected.txt index 791ca5d..f34c13e 100644 --- a/third_party/blink/web_tests/paint/invalidation/table/fixed-table-overflow-expected.txt +++ b/third_party/blink/web_tests/paint/invalidation/table/fixed-table-overflow-expected.txt
@@ -15,6 +15,7 @@ "name": "LayoutNGBlockFlow (positioned) TD id='moveMe' class='fixed'", "position": [-100, 0], "bounds": [200, 100], + "contentsOpaqueForText": true, "backgroundColor": "#008000", "invalidations": [ [0, 0, 200, 100]
diff --git a/third_party/blink/web_tests/paint/invalidation/table/invalidate-cell-in-row-with-offset-expected.txt b/third_party/blink/web_tests/paint/invalidation/table/invalidate-cell-in-row-with-offset-expected.txt index 3b0b40b..dd22202 100644 --- a/third_party/blink/web_tests/paint/invalidation/table/invalidate-cell-in-row-with-offset-expected.txt +++ b/third_party/blink/web_tests/paint/invalidation/table/invalidate-cell-in-row-with-offset-expected.txt
@@ -9,6 +9,7 @@ { "name": "LayoutTableRow TR", "position": [8, 18], + "contentsOpaqueForText": true, "drawsContent": false, "backgroundColor": "#0000FF" }, @@ -16,12 +17,14 @@ "name": "LayoutTableRow TR", "position": [8, 28], "bounds": [234, 102], + "contentsOpaqueForText": true, "backgroundColor": "#0000FF" }, { "name": "LayoutTableRow TR class='shadow-inset'", "position": [8, 140], "bounds": [234, 102], + "contentsOpaqueForText": true, "backgroundColor": "#0000FF", "invalidations": [ [10, 0, 102, 102]
diff --git a/third_party/blink/web_tests/platform/linux/compositing/squashing/selection-repaint-with-gaps-expected.txt b/third_party/blink/web_tests/platform/linux/compositing/squashing/selection-repaint-with-gaps-expected.txt index 07d5d63..7db08957 100644 --- a/third_party/blink/web_tests/platform/linux/compositing/squashing/selection-repaint-with-gaps-expected.txt +++ b/third_party/blink/web_tests/platform/linux/compositing/squashing/selection-repaint-with-gaps-expected.txt
@@ -16,6 +16,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='item')", "position": [7, 27], "bounds": [100, 210], + "contentsOpaqueForText": true, "invalidations": [ [0, 80, 40, 40] ], @@ -52,6 +53,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='item')", "position": [7, 27], "bounds": [100, 210], + "contentsOpaqueForText": true, "invalidations": [ [0, 160, 40, 40], [0, 80, 40, 40]
diff --git a/third_party/blink/web_tests/platform/linux/editing/selection/linux_selection_color-expected.png b/third_party/blink/web_tests/platform/linux/editing/selection/linux_selection_color-expected.png deleted file mode 100644 index 7606783..0000000 --- a/third_party/blink/web_tests/platform/linux/editing/selection/linux_selection_color-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/block/float/float-in-float-painting-expected.png b/third_party/blink/web_tests/platform/linux/fast/block/float/float-in-float-painting-expected.png index ff0b89be..12b51af 100644 --- a/third_party/blink/web_tests/platform/linux/fast/block/float/float-in-float-painting-expected.png +++ b/third_party/blink/web_tests/platform/linux/fast/block/float/float-in-float-painting-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/box-shadow/box-shadow-expected.png b/third_party/blink/web_tests/platform/linux/fast/box-shadow/box-shadow-expected.png index f6b3806..3d9e5f7d 100644 --- a/third_party/blink/web_tests/platform/linux/fast/box-shadow/box-shadow-expected.png +++ b/third_party/blink/web_tests/platform/linux/fast/box-shadow/box-shadow-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/clip/nestedTransparencyClip-expected.png b/third_party/blink/web_tests/platform/linux/fast/clip/nestedTransparencyClip-expected.png index b56cf3c..aafee3b4 100644 --- a/third_party/blink/web_tests/platform/linux/fast/clip/nestedTransparencyClip-expected.png +++ b/third_party/blink/web_tests/platform/linux/fast/clip/nestedTransparencyClip-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/forms/select/basic-selects-expected.png b/third_party/blink/web_tests/platform/linux/fast/forms/select/basic-selects-expected.png index 8d192ef4..a379506 100644 --- a/third_party/blink/web_tests/platform/linux/fast/forms/select/basic-selects-expected.png +++ b/third_party/blink/web_tests/platform/linux/fast/forms/select/basic-selects-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/forms/select/disabled-select-change-index-expected.png b/third_party/blink/web_tests/platform/linux/fast/forms/select/disabled-select-change-index-expected.png index 1708e60..90a2c00c 100644 --- a/third_party/blink/web_tests/platform/linux/fast/forms/select/disabled-select-change-index-expected.png +++ b/third_party/blink/web_tests/platform/linux/fast/forms/select/disabled-select-change-index-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/forms/select/listbox-appearance-basic-expected.png b/third_party/blink/web_tests/platform/linux/fast/forms/select/listbox-appearance-basic-expected.png index 36305b93..ee4b437 100644 --- a/third_party/blink/web_tests/platform/linux/fast/forms/select/listbox-appearance-basic-expected.png +++ b/third_party/blink/web_tests/platform/linux/fast/forms/select/listbox-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/forms/select/select-disabled-appearance-expected.png b/third_party/blink/web_tests/platform/linux/fast/forms/select/select-disabled-appearance-expected.png index 95ac2c2a..8cf2461 100644 --- a/third_party/blink/web_tests/platform/linux/fast/forms/select/select-disabled-appearance-expected.png +++ b/third_party/blink/web_tests/platform/linux/fast/forms/select/select-disabled-appearance-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/layers/opacity-outline-expected.png b/third_party/blink/web_tests/platform/linux/fast/layers/opacity-outline-expected.png index aba91bf5..a18ab6d 100644 --- a/third_party/blink/web_tests/platform/linux/fast/layers/opacity-outline-expected.png +++ b/third_party/blink/web_tests/platform/linux/fast/layers/opacity-outline-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/multicol/layers-in-multicol-expected.png b/third_party/blink/web_tests/platform/linux/fast/multicol/layers-in-multicol-expected.png index e9188de..ee4d480 100644 --- a/third_party/blink/web_tests/platform/linux/fast/multicol/layers-in-multicol-expected.png +++ b/third_party/blink/web_tests/platform/linux/fast/multicol/layers-in-multicol-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/overflow/overflow-of-video-outline-expected.png b/third_party/blink/web_tests/platform/linux/fast/overflow/overflow-of-video-outline-expected.png index 87e6c31e..6ae3ca2 100644 --- a/third_party/blink/web_tests/platform/linux/fast/overflow/overflow-of-video-outline-expected.png +++ b/third_party/blink/web_tests/platform/linux/fast/overflow/overflow-of-video-outline-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/table/dynamic-caption-add-before-child-expected.png b/third_party/blink/web_tests/platform/linux/fast/table/dynamic-caption-add-before-child-expected.png index 6b855552..0e7c8e3 100644 --- a/third_party/blink/web_tests/platform/linux/fast/table/dynamic-caption-add-before-child-expected.png +++ b/third_party/blink/web_tests/platform/linux/fast/table/dynamic-caption-add-before-child-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/table/multiple-captions-display-expected.png b/third_party/blink/web_tests/platform/linux/fast/table/multiple-captions-display-expected.png index 3e582f3..882f715 100644 --- a/third_party/blink/web_tests/platform/linux/fast/table/multiple-captions-display-expected.png +++ b/third_party/blink/web_tests/platform/linux/fast/table/multiple-captions-display-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/http/tests/media/video-buffered-range-contains-currentTime-expected.png b/third_party/blink/web_tests/platform/linux/http/tests/media/video-buffered-range-contains-currentTime-expected.png index cbabde0..b9aaf65 100644 --- a/third_party/blink/web_tests/platform/linux/http/tests/media/video-buffered-range-contains-currentTime-expected.png +++ b/third_party/blink/web_tests/platform/linux/http/tests/media/video-buffered-range-contains-currentTime-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/media/audio-controls-rendering-expected.png b/third_party/blink/web_tests/platform/linux/media/audio-controls-rendering-expected.png index 30291bf..9de967c2 100644 --- a/third_party/blink/web_tests/platform/linux/media/audio-controls-rendering-expected.png +++ b/third_party/blink/web_tests/platform/linux/media/audio-controls-rendering-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/media/controls-layout-direction-expected.png b/third_party/blink/web_tests/platform/linux/media/controls-layout-direction-expected.png index 46e8c046..41316d0 100644 --- a/third_party/blink/web_tests/platform/linux/media/controls-layout-direction-expected.png +++ b/third_party/blink/web_tests/platform/linux/media/controls-layout-direction-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/media/media-controls-clone-expected.png b/third_party/blink/web_tests/platform/linux/media/media-controls-clone-expected.png index 86a52d6..d562e98 100644 --- a/third_party/blink/web_tests/platform/linux/media/media-controls-clone-expected.png +++ b/third_party/blink/web_tests/platform/linux/media/media-controls-clone-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/media/media-controls-grey-scrubber-expected.png b/third_party/blink/web_tests/platform/linux/media/media-controls-grey-scrubber-expected.png index 3f1fa64..3d2ca93 100644 --- a/third_party/blink/web_tests/platform/linux/media/media-controls-grey-scrubber-expected.png +++ b/third_party/blink/web_tests/platform/linux/media/media-controls-grey-scrubber-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/media/media-document-audio-repaint-expected.png b/third_party/blink/web_tests/platform/linux/media/media-document-audio-repaint-expected.png index ffd0d1b..fd66e00f 100644 --- a/third_party/blink/web_tests/platform/linux/media/media-document-audio-repaint-expected.png +++ b/third_party/blink/web_tests/platform/linux/media/media-document-audio-repaint-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/media/video-empty-source-expected.png b/third_party/blink/web_tests/platform/linux/media/video-empty-source-expected.png index dea11403..80304120 100644 --- a/third_party/blink/web_tests/platform/linux/media/video-empty-source-expected.png +++ b/third_party/blink/web_tests/platform/linux/media/video-empty-source-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/paint/frames/frameset-with-stacking-context-and-not-stacking-context-children-expected.png b/third_party/blink/web_tests/platform/linux/paint/frames/frameset-with-stacking-context-and-not-stacking-context-children-expected.png index 7cacffd3..5cf5268 100644 --- a/third_party/blink/web_tests/platform/linux/paint/frames/frameset-with-stacking-context-and-not-stacking-context-children-expected.png +++ b/third_party/blink/web_tests/platform/linux/paint/frames/frameset-with-stacking-context-and-not-stacking-context-children-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/paint/frames/frameset-with-stacking-contexts-expected.png b/third_party/blink/web_tests/platform/linux/paint/frames/frameset-with-stacking-contexts-expected.png index df70011e..f7d38c4 100644 --- a/third_party/blink/web_tests/platform/linux/paint/frames/frameset-with-stacking-contexts-expected.png +++ b/third_party/blink/web_tests/platform/linux/paint/frames/frameset-with-stacking-contexts-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/blink/web_tests/platform/linux/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png index 8ec0a966..2672511 100644 --- a/third_party/blink/web_tests/platform/linux/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png +++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-composited-row-expected.txt b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-composited-row-expected.txt index 82ba6cb..61342a1 100644 --- a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-composited-row-expected.txt +++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-composited-row-expected.txt
@@ -10,6 +10,7 @@ "name": "LayoutTableRow TR id='target'", "position": [8, 96], "bounds": [186, 64], + "contentsOpaqueForText": true, "backgroundColor": "#ADD8E6", "invalidations": [ [0, 0, 186, 64]
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt index 82ba6cb..61342a1 100644 --- a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt +++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt
@@ -10,6 +10,7 @@ "name": "LayoutTableRow TR id='target'", "position": [8, 96], "bounds": [186, 64], + "contentsOpaqueForText": true, "backgroundColor": "#ADD8E6", "invalidations": [ [0, 0, 186, 64]
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt index 688e9cd..d5ea68a9 100644 --- a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt +++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt
@@ -10,6 +10,7 @@ "name": "LayoutTableSection TBODY id='target'", "position": [8, 28], "bounds": [186, 134], + "contentsOpaqueForText": true, "backgroundColor": "#ADD8E6", "invalidations": [ [0, 0, 186, 134]
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt index 688e9cd..d5ea68a9 100644 --- a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt +++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt
@@ -10,6 +10,7 @@ "name": "LayoutTableSection TBODY id='target'", "position": [8, 28], "bounds": [186, 134], + "contentsOpaqueForText": true, "backgroundColor": "#ADD8E6", "invalidations": [ [0, 0, 186, 134]
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-expected.txt b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-expected.txt index 4b0ea00..c8e8349e 100644 --- a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-expected.txt +++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-expected.txt
@@ -10,6 +10,7 @@ "name": "LayoutTableSection TBODY id='target'", "position": [8, 28], "bounds": [186, 134], + "contentsOpaqueForText": true, "backgroundColor": "#ADD8E6", "invalidations": [ [0, 0, 186, 134]
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt index 4b0ea00..c8e8349e 100644 --- a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt +++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt
@@ -10,6 +10,7 @@ "name": "LayoutTableSection TBODY id='target'", "position": [8, 28], "bounds": [186, 134], + "contentsOpaqueForText": true, "backgroundColor": "#ADD8E6", "invalidations": [ [0, 0, 186, 134]
diff --git a/third_party/blink/web_tests/platform/linux/printing/composited-thead-tfoot-repeat-expected.png b/third_party/blink/web_tests/platform/linux/printing/composited-thead-tfoot-repeat-expected.png index 9857d35..f93627a 100644 --- a/third_party/blink/web_tests/platform/linux/printing/composited-thead-tfoot-repeat-expected.png +++ b/third_party/blink/web_tests/platform/linux/printing/composited-thead-tfoot-repeat-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png b/third_party/blink/web_tests/platform/linux/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png index a043fa03..fe4c60fb 100644 --- a/third_party/blink/web_tests/platform/linux/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png +++ b/third_party/blink/web_tests/platform/linux/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1/masking-opacity-01-b-expected.png b/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1/masking-opacity-01-b-expected.png index 498ceee..6c491e7 100644 --- a/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1/masking-opacity-01-b-expected.png +++ b/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1/masking-opacity-01-b-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1/render-groups-01-b-expected.png b/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1/render-groups-01-b-expected.png index 5666fff..b3995ccb 100644 --- a/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1/render-groups-01-b-expected.png +++ b/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1/render-groups-01-b-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1/text-text-08-b-expected.png b/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1/text-text-08-b-expected.png index ce23397..55f35dd 100644 --- a/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1/text-text-08-b-expected.png +++ b/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1/text-text-08-b-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/svg/batik/text/verticalText-expected.png b/third_party/blink/web_tests/platform/linux/svg/batik/text/verticalText-expected.png index 30e28db..bd948f2 100644 --- a/third_party/blink/web_tests/platform/linux/svg/batik/text/verticalText-expected.png +++ b/third_party/blink/web_tests/platform/linux/svg/batik/text/verticalText-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/svg/custom/container-opacity-clip-viewBox-expected.png b/third_party/blink/web_tests/platform/linux/svg/custom/container-opacity-clip-viewBox-expected.png index e1d8e15..f54ebb7 100644 --- a/third_party/blink/web_tests/platform/linux/svg/custom/container-opacity-clip-viewBox-expected.png +++ b/third_party/blink/web_tests/platform/linux/svg/custom/container-opacity-clip-viewBox-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/svg/custom/text-image-opacity-expected.png b/third_party/blink/web_tests/platform/linux/svg/custom/text-image-opacity-expected.png index 1c343cf..1c26e2b 100644 --- a/third_party/blink/web_tests/platform/linux/svg/custom/text-image-opacity-expected.png +++ b/third_party/blink/web_tests/platform/linux/svg/custom/text-image-opacity-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/svg/text/text-selection-text-08-b-expected.png b/third_party/blink/web_tests/platform/linux/svg/text/text-selection-text-08-b-expected.png index f20e8f2..7fb679e7 100644 --- a/third_party/blink/web_tests/platform/linux/svg/text/text-selection-text-08-b-expected.png +++ b/third_party/blink/web_tests/platform/linux/svg/text/text-selection-text-08-b-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/transforms/2d/hindi-rotated-expected.png b/third_party/blink/web_tests/platform/linux/transforms/2d/hindi-rotated-expected.png index 110569a..64a946b 100644 --- a/third_party/blink/web_tests/platform/linux/transforms/2d/hindi-rotated-expected.png +++ b/third_party/blink/web_tests/platform/linux/transforms/2d/hindi-rotated-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/transforms/transform-on-inline-expected.png b/third_party/blink/web_tests/platform/linux/transforms/transform-on-inline-expected.png index 124b3a1..3dfbe67 100644 --- a/third_party/blink/web_tests/platform/linux/transforms/transform-on-inline-expected.png +++ b/third_party/blink/web_tests/platform/linux/transforms/transform-on-inline-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/transforms/transform-table-row-expected.png b/third_party/blink/web_tests/platform/linux/transforms/transform-table-row-expected.png index 4941704c..64e3a69 100644 --- a/third_party/blink/web_tests/platform/linux/transforms/transform-table-row-expected.png +++ b/third_party/blink/web_tests/platform/linux/transforms/transform-table-row-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/cascade/fast/forms/select/basic-selects-expected.png b/third_party/blink/web_tests/platform/linux/virtual/cascade/fast/forms/select/basic-selects-expected.png index 8d192ef4..a379506 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/cascade/fast/forms/select/basic-selects-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/cascade/fast/forms/select/basic-selects-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh/calendar-picker/date-picker-month-appearance-expected.png b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh/calendar-picker/date-picker-month-appearance-expected.png index 4081f58..5b8b5148 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh/calendar-picker/date-picker-month-appearance-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh/calendar-picker/date-picker-month-appearance-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh/calendar-picker/date-picker-month-selection-changed-appearance-expected.png b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh/calendar-picker/date-picker-month-selection-changed-appearance-expected.png index f90b700d..1041a40 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh/calendar-picker/date-picker-month-selection-changed-appearance-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh/calendar-picker/date-picker-month-selection-changed-appearance-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh/color-scheme/select/select-inpage-appearance-basic-expected.png b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh/color-scheme/select/select-inpage-appearance-basic-expected.png index 28936ae..a474dfb 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh/color-scheme/select/select-inpage-appearance-basic-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh/color-scheme/select/select-inpage-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh/color-scheme/select/select-multiple-appearance-basic-expected.png b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh/color-scheme/select/select-multiple-appearance-basic-expected.png index 92f2cea..27ef2f3 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh/color-scheme/select/select-multiple-appearance-basic-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh/color-scheme/select/select-multiple-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/form-controls-refresh-disabled/fast/forms/indeterminate-expected.png b/third_party/blink/web_tests/platform/linux/virtual/form-controls-refresh-disabled/fast/forms/indeterminate-expected.png index bf27ceb..e79c5ce 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/form-controls-refresh-disabled/fast/forms/indeterminate-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/form-controls-refresh-disabled/fast/forms/indeterminate-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/text-antialias/complex-text-opacity-expected.png b/third_party/blink/web_tests/platform/linux/virtual/text-antialias/complex-text-opacity-expected.png index 8279354a..60e20707 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/text-antialias/complex-text-opacity-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/text-antialias/complex-text-opacity-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/text-antialias/letter-spacing-negative-opacity-expected.png b/third_party/blink/web_tests/platform/linux/virtual/text-antialias/letter-spacing-negative-opacity-expected.png index 2cb1129..6f68bf8 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/text-antialias/letter-spacing-negative-opacity-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/text-antialias/letter-spacing-negative-opacity-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/threaded/printing/composited-thead-tfoot-repeat-expected.png b/third_party/blink/web_tests/platform/linux/virtual/threaded/printing/composited-thead-tfoot-repeat-expected.png index 9857d35..f93627a 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/threaded/printing/composited-thead-tfoot-repeat-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/threaded/printing/composited-thead-tfoot-repeat-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/threaded/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png b/third_party/blink/web_tests/platform/linux/virtual/threaded/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png index a043fa03..fe4c60fb 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/threaded/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/threaded/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/use-common-select-popup/virtual/controls-refresh/color-scheme/select/select-inpage-appearance-basic-expected.png b/third_party/blink/web_tests/platform/linux/virtual/use-common-select-popup/virtual/controls-refresh/color-scheme/select/select-inpage-appearance-basic-expected.png new file mode 100644 index 0000000..a474dfb --- /dev/null +++ b/third_party/blink/web_tests/platform/linux/virtual/use-common-select-popup/virtual/controls-refresh/color-scheme/select/select-inpage-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/use-common-select-popup/virtual/controls-refresh/color-scheme/select/select-multiple-appearance-basic-expected.png b/third_party/blink/web_tests/platform/linux/virtual/use-common-select-popup/virtual/controls-refresh/color-scheme/select/select-multiple-appearance-basic-expected.png new file mode 100644 index 0000000..27ef2f3 --- /dev/null +++ b/third_party/blink/web_tests/platform/linux/virtual/use-common-select-popup/virtual/controls-refresh/color-scheme/select/select-multiple-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/transforms/2d/hindi-rotated-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/transforms/2d/hindi-rotated-expected.png index a714b45..7cd99ca 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.10/transforms/2d/hindi-rotated-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac10.10/transforms/2d/hindi-rotated-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/calendar-picker/date-picker-month-appearance-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/calendar-picker/date-picker-month-appearance-expected.png index e9b641ba..8212f3fd 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/calendar-picker/date-picker-month-appearance-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/calendar-picker/date-picker-month-appearance-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/calendar-picker/date-picker-month-selection-changed-appearance-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/calendar-picker/date-picker-month-selection-changed-appearance-expected.png index 3f5b5e2f..4f55e515 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/calendar-picker/date-picker-month-selection-changed-appearance-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/calendar-picker/date-picker-month-selection-changed-appearance-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/form-controls-refresh-disabled/fast/forms/indeterminate-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/form-controls-refresh-disabled/fast/forms/indeterminate-expected.png index c1647a8..bcf5896 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/form-controls-refresh-disabled/fast/forms/indeterminate-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/form-controls-refresh-disabled/fast/forms/indeterminate-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/threaded/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/layout_ng_block_frag/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png similarity index 100% rename from third_party/blink/web_tests/virtual/threaded/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png rename to third_party/blink/web_tests/platform/mac-mac10.10/virtual/layout_ng_block_frag/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/text-antialias/complex-text-opacity-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/text-antialias/complex-text-opacity-expected.png index 69403d38..180707c 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/text-antialias/complex-text-opacity-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/text-antialias/complex-text-opacity-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/text-antialias/letter-spacing-negative-opacity-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/text-antialias/letter-spacing-negative-opacity-expected.png index 17c5569..ec4075f 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/text-antialias/letter-spacing-negative-opacity-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/text-antialias/letter-spacing-negative-opacity-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/fast/overflow/overflow-of-video-outline-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/fast/overflow/overflow-of-video-outline-expected.png index b1ce1f32..d1605bc 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.12/fast/overflow/overflow-of-video-outline-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac10.12/fast/overflow/overflow-of-video-outline-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/http/tests/media/video-buffered-range-contains-currentTime-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/http/tests/media/video-buffered-range-contains-currentTime-expected.png index 9c053a8..ce541f4 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.12/http/tests/media/video-buffered-range-contains-currentTime-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac10.12/http/tests/media/video-buffered-range-contains-currentTime-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/media/audio-controls-rendering-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/media/audio-controls-rendering-expected.png index 4259328..660f1fc0 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.12/media/audio-controls-rendering-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac10.12/media/audio-controls-rendering-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/media/controls-layout-direction-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/media/controls-layout-direction-expected.png index 405fdb0..627167f 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.12/media/controls-layout-direction-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac10.12/media/controls-layout-direction-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/media/media-controls-clone-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/media/media-controls-clone-expected.png index 3da3f2a..d6c34f99 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.12/media/media-controls-clone-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac10.12/media/media-controls-clone-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/media/media-controls-grey-scrubber-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/media/media-controls-grey-scrubber-expected.png index 04007161..562dab3 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.12/media/media-controls-grey-scrubber-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac10.12/media/media-controls-grey-scrubber-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/media/media-document-audio-repaint-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/media/media-document-audio-repaint-expected.png index ddf962c..413020d 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.12/media/media-document-audio-repaint-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac10.12/media/media-document-audio-repaint-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/media/video-empty-source-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/media/video-empty-source-expected.png index ded125b..a861e1e 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.12/media/video-empty-source-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac10.12/media/video-empty-source-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/printing/composited-thead-tfoot-repeat-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/printing/composited-thead-tfoot-repeat-expected.png deleted file mode 100644 index 797ef0d..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.12/printing/composited-thead-tfoot-repeat-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png index 8a62543..a013c17 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.12/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac10.12/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/text-antialias/complex-text-opacity-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/text-antialias/complex-text-opacity-expected.png index e3f3451..5a8181e 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/text-antialias/complex-text-opacity-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/text-antialias/complex-text-opacity-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/text-antialias/letter-spacing-negative-opacity-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/text-antialias/letter-spacing-negative-opacity-expected.png index 95d48f1..44efdbc 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/text-antialias/letter-spacing-negative-opacity-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/text-antialias/letter-spacing-negative-opacity-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/threaded/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/threaded/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png index 8a62543..a013c17 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/threaded/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/threaded/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/fast/forms/select/listbox-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/fast/forms/select/listbox-appearance-basic-expected.png index f7cd5e6..71ff04d 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.13/fast/forms/select/listbox-appearance-basic-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac10.13/fast/forms/select/listbox-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/svg/text/text-selection-text-08-b-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/svg/text/text-selection-text-08-b-expected.png index 59cea57f..c734057 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.13/svg/text/text-selection-text-08-b-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac10.13/svg/text/text-selection-text-08-b-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/controls-refresh/color-scheme/select/select-multiple-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/controls-refresh/color-scheme/select/select-multiple-appearance-basic-expected.png index 62aaa80..721cb3d 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/controls-refresh/color-scheme/select/select-multiple-appearance-basic-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/controls-refresh/color-scheme/select/select-multiple-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/form-controls-refresh-disabled/fast/forms/indeterminate-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/form-controls-refresh-disabled/fast/forms/indeterminate-expected.png index 12f91d7..1d4b719 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/form-controls-refresh-disabled/fast/forms/indeterminate-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/form-controls-refresh-disabled/fast/forms/indeterminate-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/text-antialias/complex-text-opacity-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/text-antialias/complex-text-opacity-expected.png index 3e439f9..444d132a 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/text-antialias/complex-text-opacity-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/text-antialias/complex-text-opacity-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/text-antialias/letter-spacing-negative-opacity-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/text-antialias/letter-spacing-negative-opacity-expected.png index 1d02806d..bbd70e5 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/text-antialias/letter-spacing-negative-opacity-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/text-antialias/letter-spacing-negative-opacity-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/use-common-select-popup/virtual/controls-refresh/color-scheme/select/select-multiple-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/use-common-select-popup/virtual/controls-refresh/color-scheme/select/select-multiple-appearance-basic-expected.png new file mode 100644 index 0000000..721cb3d --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/use-common-select-popup/virtual/controls-refresh/color-scheme/select/select-multiple-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/compositing/iframes/invisible-nested-iframe-show-expected.txt b/third_party/blink/web_tests/platform/mac/compositing/iframes/invisible-nested-iframe-show-expected.txt index 9a1af90..89de0cee 100644 --- a/third_party/blink/web_tests/platform/mac/compositing/iframes/invisible-nested-iframe-show-expected.txt +++ b/third_party/blink/web_tests/platform/mac/compositing/iframes/invisible-nested-iframe-show-expected.txt
@@ -25,6 +25,7 @@ { "name": "LayoutView #document", "bounds": [250, 170], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 4 },
diff --git a/third_party/blink/web_tests/platform/mac/compositing/squashing/selection-repaint-with-gaps-expected.txt b/third_party/blink/web_tests/platform/mac/compositing/squashing/selection-repaint-with-gaps-expected.txt index 45a1428..f4c48a14 100644 --- a/third_party/blink/web_tests/platform/mac/compositing/squashing/selection-repaint-with-gaps-expected.txt +++ b/third_party/blink/web_tests/platform/mac/compositing/squashing/selection-repaint-with-gaps-expected.txt
@@ -16,6 +16,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='item')", "position": [7, 27], "bounds": [100, 210], + "contentsOpaqueForText": true, "invalidations": [ [0, 80, 42, 36] ], @@ -52,6 +53,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='item')", "position": [7, 27], "bounds": [100, 210], + "contentsOpaqueForText": true, "invalidations": [ [0, 160, 42, 36], [0, 80, 42, 36]
diff --git a/third_party/blink/web_tests/platform/mac/css3/blending/mix-blend-mode-composited-layers-expected.txt b/third_party/blink/web_tests/platform/mac/css3/blending/mix-blend-mode-composited-layers-expected.txt index a172d8f..7265b2e 100644 --- a/third_party/blink/web_tests/platform/mac/css3/blending/mix-blend-mode-composited-layers-expected.txt +++ b/third_party/blink/web_tests/platform/mac/css3/blending/mix-blend-mode-composited-layers-expected.txt
@@ -7,6 +7,7 @@ { "name": "LayoutNGBlockFlow DIV", "bounds": [10, 10], + "contentsOpaqueForText": true, "backgroundColor": "#0000FF", "transform": 1 },
diff --git a/third_party/blink/web_tests/platform/mac/fast/box-shadow/box-shadow-expected.png b/third_party/blink/web_tests/platform/mac/fast/box-shadow/box-shadow-expected.png index f34462d..79aa74d 100644 --- a/third_party/blink/web_tests/platform/mac/fast/box-shadow/box-shadow-expected.png +++ b/third_party/blink/web_tests/platform/mac/fast/box-shadow/box-shadow-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/clip/nestedTransparencyClip-expected.png b/third_party/blink/web_tests/platform/mac/fast/clip/nestedTransparencyClip-expected.png index 98a8e4e..3825a9b 100644 --- a/third_party/blink/web_tests/platform/mac/fast/clip/nestedTransparencyClip-expected.png +++ b/third_party/blink/web_tests/platform/mac/fast/clip/nestedTransparencyClip-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/forms/select/basic-selects-expected.png b/third_party/blink/web_tests/platform/mac/fast/forms/select/basic-selects-expected.png index b2268dd..8eeb70d 100644 --- a/third_party/blink/web_tests/platform/mac/fast/forms/select/basic-selects-expected.png +++ b/third_party/blink/web_tests/platform/mac/fast/forms/select/basic-selects-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/forms/select/disabled-select-change-index-expected.png b/third_party/blink/web_tests/platform/mac/fast/forms/select/disabled-select-change-index-expected.png index 352f206..2a2d3d37 100644 --- a/third_party/blink/web_tests/platform/mac/fast/forms/select/disabled-select-change-index-expected.png +++ b/third_party/blink/web_tests/platform/mac/fast/forms/select/disabled-select-change-index-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/forms/select/listbox-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac/fast/forms/select/listbox-appearance-basic-expected.png index 80c04c4..be160b16 100644 --- a/third_party/blink/web_tests/platform/mac/fast/forms/select/listbox-appearance-basic-expected.png +++ b/third_party/blink/web_tests/platform/mac/fast/forms/select/listbox-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/forms/select/select-disabled-appearance-expected.png b/third_party/blink/web_tests/platform/mac/fast/forms/select/select-disabled-appearance-expected.png index 2d042fe..fd3a3704 100644 --- a/third_party/blink/web_tests/platform/mac/fast/forms/select/select-disabled-appearance-expected.png +++ b/third_party/blink/web_tests/platform/mac/fast/forms/select/select-disabled-appearance-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/layers/opacity-outline-expected.png b/third_party/blink/web_tests/platform/mac/fast/layers/opacity-outline-expected.png index 94157645..5159ec1 100644 --- a/third_party/blink/web_tests/platform/mac/fast/layers/opacity-outline-expected.png +++ b/third_party/blink/web_tests/platform/mac/fast/layers/opacity-outline-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/overflow/overflow-of-video-outline-expected.png b/third_party/blink/web_tests/platform/mac/fast/overflow/overflow-of-video-outline-expected.png index 279dbdb8..76d2b83 100644 --- a/third_party/blink/web_tests/platform/mac/fast/overflow/overflow-of-video-outline-expected.png +++ b/third_party/blink/web_tests/platform/mac/fast/overflow/overflow-of-video-outline-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/http/tests/media/video-buffered-range-contains-currentTime-expected.png b/third_party/blink/web_tests/platform/mac/http/tests/media/video-buffered-range-contains-currentTime-expected.png index 5266e67..cb8803f6 100644 --- a/third_party/blink/web_tests/platform/mac/http/tests/media/video-buffered-range-contains-currentTime-expected.png +++ b/third_party/blink/web_tests/platform/mac/http/tests/media/video-buffered-range-contains-currentTime-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/media/audio-controls-rendering-expected.png b/third_party/blink/web_tests/platform/mac/media/audio-controls-rendering-expected.png index 029faa5..2f2e5c6 100644 --- a/third_party/blink/web_tests/platform/mac/media/audio-controls-rendering-expected.png +++ b/third_party/blink/web_tests/platform/mac/media/audio-controls-rendering-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/media/controls-layout-direction-expected.png b/third_party/blink/web_tests/platform/mac/media/controls-layout-direction-expected.png index 5dbdb4f..d1cfea2a 100644 --- a/third_party/blink/web_tests/platform/mac/media/controls-layout-direction-expected.png +++ b/third_party/blink/web_tests/platform/mac/media/controls-layout-direction-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/media/media-controls-clone-expected.png b/third_party/blink/web_tests/platform/mac/media/media-controls-clone-expected.png index 314ee140..53bb82c 100644 --- a/third_party/blink/web_tests/platform/mac/media/media-controls-clone-expected.png +++ b/third_party/blink/web_tests/platform/mac/media/media-controls-clone-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/media/media-controls-grey-scrubber-expected.png b/third_party/blink/web_tests/platform/mac/media/media-controls-grey-scrubber-expected.png index deccb02..877187d3 100644 --- a/third_party/blink/web_tests/platform/mac/media/media-controls-grey-scrubber-expected.png +++ b/third_party/blink/web_tests/platform/mac/media/media-controls-grey-scrubber-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/media/media-document-audio-repaint-expected.png b/third_party/blink/web_tests/platform/mac/media/media-document-audio-repaint-expected.png index 0d087479..f894dea 100644 --- a/third_party/blink/web_tests/platform/mac/media/media-document-audio-repaint-expected.png +++ b/third_party/blink/web_tests/platform/mac/media/media-document-audio-repaint-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/media/video-empty-source-expected.png b/third_party/blink/web_tests/platform/mac/media/video-empty-source-expected.png index dba91d8..f2a2c837 100644 --- a/third_party/blink/web_tests/platform/mac/media/video-empty-source-expected.png +++ b/third_party/blink/web_tests/platform/mac/media/video-empty-source-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/blink/web_tests/platform/mac/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png index 206f0f0..a98af7a2 100644 --- a/third_party/blink/web_tests/platform/mac/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png +++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-composited-row-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-composited-row-expected.txt index edbe923..ada917a 100644 --- a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-composited-row-expected.txt +++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-composited-row-expected.txt
@@ -10,6 +10,7 @@ "name": "LayoutTableRow TR id='target'", "position": [8, 94], "bounds": [186, 64], + "contentsOpaqueForText": true, "backgroundColor": "#ADD8E6", "invalidations": [ [0, 0, 186, 64]
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt index edbe923..ada917a 100644 --- a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt +++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt
@@ -10,6 +10,7 @@ "name": "LayoutTableRow TR id='target'", "position": [8, 94], "bounds": [186, 64], + "contentsOpaqueForText": true, "backgroundColor": "#ADD8E6", "invalidations": [ [0, 0, 186, 64]
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt index 8dc03134c..f39c733 100644 --- a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt +++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt
@@ -10,6 +10,7 @@ "name": "LayoutTableSection TBODY id='target'", "position": [8, 26], "bounds": [186, 134], + "contentsOpaqueForText": true, "backgroundColor": "#ADD8E6", "invalidations": [ [0, 0, 186, 134]
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt index 8dc03134c..f39c733 100644 --- a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt +++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt
@@ -10,6 +10,7 @@ "name": "LayoutTableSection TBODY id='target'", "position": [8, 26], "bounds": [186, 134], + "contentsOpaqueForText": true, "backgroundColor": "#ADD8E6", "invalidations": [ [0, 0, 186, 134]
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-expected.txt index 0149375..f71b826 100644 --- a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-expected.txt +++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-expected.txt
@@ -10,6 +10,7 @@ "name": "LayoutTableSection TBODY id='target'", "position": [8, 26], "bounds": [186, 134], + "contentsOpaqueForText": true, "backgroundColor": "#ADD8E6", "invalidations": [ [0, 0, 186, 134]
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt index 0149375..f71b826 100644 --- a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt +++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt
@@ -10,6 +10,7 @@ "name": "LayoutTableSection TBODY id='target'", "position": [8, 26], "bounds": [186, 134], + "contentsOpaqueForText": true, "backgroundColor": "#ADD8E6", "invalidations": [ [0, 0, 186, 134]
diff --git a/third_party/blink/web_tests/platform/mac/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png b/third_party/blink/web_tests/platform/mac/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png index 04b7d55..4540dcc 100644 --- a/third_party/blink/web_tests/platform/mac/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png +++ b/third_party/blink/web_tests/platform/mac/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/svg/W3C-SVG-1.1/masking-opacity-01-b-expected.png b/third_party/blink/web_tests/platform/mac/svg/W3C-SVG-1.1/masking-opacity-01-b-expected.png index c396c630..ae2b041 100644 --- a/third_party/blink/web_tests/platform/mac/svg/W3C-SVG-1.1/masking-opacity-01-b-expected.png +++ b/third_party/blink/web_tests/platform/mac/svg/W3C-SVG-1.1/masking-opacity-01-b-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/svg/batik/text/verticalText-expected.png b/third_party/blink/web_tests/platform/mac/svg/batik/text/verticalText-expected.png index f66bc22..1579827e 100644 --- a/third_party/blink/web_tests/platform/mac/svg/batik/text/verticalText-expected.png +++ b/third_party/blink/web_tests/platform/mac/svg/batik/text/verticalText-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/svg/custom/container-opacity-clip-viewBox-expected.png b/third_party/blink/web_tests/platform/mac/svg/custom/container-opacity-clip-viewBox-expected.png index 172e1de..ac0e003 100644 --- a/third_party/blink/web_tests/platform/mac/svg/custom/container-opacity-clip-viewBox-expected.png +++ b/third_party/blink/web_tests/platform/mac/svg/custom/container-opacity-clip-viewBox-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/svg/text/text-selection-text-08-b-expected.png b/third_party/blink/web_tests/platform/mac/svg/text/text-selection-text-08-b-expected.png index 89a2feac..6d6d188 100644 --- a/third_party/blink/web_tests/platform/mac/svg/text/text-selection-text-08-b-expected.png +++ b/third_party/blink/web_tests/platform/mac/svg/text/text-selection-text-08-b-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/transforms/2d/hindi-rotated-expected.png b/third_party/blink/web_tests/platform/mac/transforms/2d/hindi-rotated-expected.png index 1ce9b39..ce866d95 100644 --- a/third_party/blink/web_tests/platform/mac/transforms/2d/hindi-rotated-expected.png +++ b/third_party/blink/web_tests/platform/mac/transforms/2d/hindi-rotated-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/cascade/fast/forms/select/basic-selects-expected.png b/third_party/blink/web_tests/platform/mac/virtual/cascade/fast/forms/select/basic-selects-expected.png index b2268dd..8eeb70d 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/cascade/fast/forms/select/basic-selects-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/cascade/fast/forms/select/basic-selects-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/calendar-picker/date-picker-month-appearance-expected.png b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/calendar-picker/date-picker-month-appearance-expected.png index 991c592..ae72f250 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/calendar-picker/date-picker-month-appearance-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/calendar-picker/date-picker-month-appearance-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/calendar-picker/date-picker-month-selection-changed-appearance-expected.png b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/calendar-picker/date-picker-month-selection-changed-appearance-expected.png index 1262a2a5..8138b2d 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/calendar-picker/date-picker-month-selection-changed-appearance-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/calendar-picker/date-picker-month-selection-changed-appearance-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/color-scheme/select/select-inpage-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/color-scheme/select/select-inpage-appearance-basic-expected.png index 23a5832..299681d1 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/color-scheme/select/select-inpage-appearance-basic-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/color-scheme/select/select-inpage-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/color-scheme/select/select-multiple-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/color-scheme/select/select-multiple-appearance-basic-expected.png index 7a45d88..e96cdac 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/color-scheme/select/select-multiple-appearance-basic-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/color-scheme/select/select-multiple-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/form-controls-refresh-disabled/fast/forms/indeterminate-expected.png b/third_party/blink/web_tests/platform/mac/virtual/form-controls-refresh-disabled/fast/forms/indeterminate-expected.png index 121ad81..09005ae 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/form-controls-refresh-disabled/fast/forms/indeterminate-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/form-controls-refresh-disabled/fast/forms/indeterminate-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/text-antialias/complex-text-opacity-expected.png b/third_party/blink/web_tests/platform/mac/virtual/text-antialias/complex-text-opacity-expected.png index befe4c2d..562f5c3 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/text-antialias/complex-text-opacity-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/text-antialias/complex-text-opacity-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/text-antialias/letter-spacing-negative-opacity-expected.png b/third_party/blink/web_tests/platform/mac/virtual/text-antialias/letter-spacing-negative-opacity-expected.png index 2a6aeab2..1c35f81 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/text-antialias/letter-spacing-negative-opacity-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/text-antialias/letter-spacing-negative-opacity-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/threaded/printing/composited-thead-tfoot-repeat-expected.png b/third_party/blink/web_tests/platform/mac/virtual/threaded/printing/composited-thead-tfoot-repeat-expected.png deleted file mode 100644 index 797ef0d..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/threaded/printing/composited-thead-tfoot-repeat-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/threaded/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png b/third_party/blink/web_tests/platform/mac/virtual/threaded/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png deleted file mode 100644 index 04b7d55..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/threaded/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/compositing/iframes/invisible-nested-iframe-show-expected.txt b/third_party/blink/web_tests/platform/win/compositing/iframes/invisible-nested-iframe-show-expected.txt index c28db90d..e66a738 100644 --- a/third_party/blink/web_tests/platform/win/compositing/iframes/invisible-nested-iframe-show-expected.txt +++ b/third_party/blink/web_tests/platform/win/compositing/iframes/invisible-nested-iframe-show-expected.txt
@@ -25,6 +25,7 @@ { "name": "LayoutView #document", "bounds": [250, 170], + "contentsOpaqueForText": true, "backgroundColor": "#C0C0C0", "transform": 4 },
diff --git a/third_party/blink/web_tests/platform/win/compositing/squashing/selection-repaint-with-gaps-expected.txt b/third_party/blink/web_tests/platform/win/compositing/squashing/selection-repaint-with-gaps-expected.txt index 5c0b27b..faa3d96 100644 --- a/third_party/blink/web_tests/platform/win/compositing/squashing/selection-repaint-with-gaps-expected.txt +++ b/third_party/blink/web_tests/platform/win/compositing/squashing/selection-repaint-with-gaps-expected.txt
@@ -16,6 +16,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='item')", "position": [7, 27], "bounds": [100, 210], + "contentsOpaqueForText": true, "invalidations": [ [0, 80, 38, 40] ], @@ -52,6 +53,7 @@ "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV class='item')", "position": [7, 27], "bounds": [100, 210], + "contentsOpaqueForText": true, "invalidations": [ [0, 160, 38, 40], [0, 80, 38, 40]
diff --git a/third_party/blink/web_tests/platform/win/css3/blending/mix-blend-mode-composited-layers-expected.txt b/third_party/blink/web_tests/platform/win/css3/blending/mix-blend-mode-composited-layers-expected.txt index 2be66e4c..8a6a959 100644 --- a/third_party/blink/web_tests/platform/win/css3/blending/mix-blend-mode-composited-layers-expected.txt +++ b/third_party/blink/web_tests/platform/win/css3/blending/mix-blend-mode-composited-layers-expected.txt
@@ -7,6 +7,7 @@ { "name": "LayoutNGBlockFlow DIV", "bounds": [10, 10], + "contentsOpaqueForText": true, "backgroundColor": "#0000FF", "transform": 1 },
diff --git a/third_party/blink/web_tests/platform/win/fast/box-shadow/box-shadow-expected.png b/third_party/blink/web_tests/platform/win/fast/box-shadow/box-shadow-expected.png index 209f0d5..efe954e0 100644 --- a/third_party/blink/web_tests/platform/win/fast/box-shadow/box-shadow-expected.png +++ b/third_party/blink/web_tests/platform/win/fast/box-shadow/box-shadow-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/clip/nestedTransparencyClip-expected.png b/third_party/blink/web_tests/platform/win/fast/clip/nestedTransparencyClip-expected.png index 844a006..2f64eba1 100644 --- a/third_party/blink/web_tests/platform/win/fast/clip/nestedTransparencyClip-expected.png +++ b/third_party/blink/web_tests/platform/win/fast/clip/nestedTransparencyClip-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/forms/select/basic-selects-expected.png b/third_party/blink/web_tests/platform/win/fast/forms/select/basic-selects-expected.png index 7022d4f..f1acb10 100644 --- a/third_party/blink/web_tests/platform/win/fast/forms/select/basic-selects-expected.png +++ b/third_party/blink/web_tests/platform/win/fast/forms/select/basic-selects-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/forms/select/disabled-select-change-index-expected.png b/third_party/blink/web_tests/platform/win/fast/forms/select/disabled-select-change-index-expected.png index 9bc666db..c4b6024 100644 --- a/third_party/blink/web_tests/platform/win/fast/forms/select/disabled-select-change-index-expected.png +++ b/third_party/blink/web_tests/platform/win/fast/forms/select/disabled-select-change-index-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/forms/select/listbox-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win/fast/forms/select/listbox-appearance-basic-expected.png index 6b75d3b..971a26a 100644 --- a/third_party/blink/web_tests/platform/win/fast/forms/select/listbox-appearance-basic-expected.png +++ b/third_party/blink/web_tests/platform/win/fast/forms/select/listbox-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/forms/select/select-disabled-appearance-expected.png b/third_party/blink/web_tests/platform/win/fast/forms/select/select-disabled-appearance-expected.png index ab738af..dcf5405 100644 --- a/third_party/blink/web_tests/platform/win/fast/forms/select/select-disabled-appearance-expected.png +++ b/third_party/blink/web_tests/platform/win/fast/forms/select/select-disabled-appearance-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/layers/opacity-outline-expected.png b/third_party/blink/web_tests/platform/win/fast/layers/opacity-outline-expected.png index 6ed1d13..0665e08 100644 --- a/third_party/blink/web_tests/platform/win/fast/layers/opacity-outline-expected.png +++ b/third_party/blink/web_tests/platform/win/fast/layers/opacity-outline-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/overflow/overflow-of-video-outline-expected.png b/third_party/blink/web_tests/platform/win/fast/overflow/overflow-of-video-outline-expected.png index 44c26fb..48cd305 100644 --- a/third_party/blink/web_tests/platform/win/fast/overflow/overflow-of-video-outline-expected.png +++ b/third_party/blink/web_tests/platform/win/fast/overflow/overflow-of-video-outline-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/http/tests/media/video-buffered-range-contains-currentTime-expected.png b/third_party/blink/web_tests/platform/win/http/tests/media/video-buffered-range-contains-currentTime-expected.png index 8f20ff3a..6b9ac5e 100644 --- a/third_party/blink/web_tests/platform/win/http/tests/media/video-buffered-range-contains-currentTime-expected.png +++ b/third_party/blink/web_tests/platform/win/http/tests/media/video-buffered-range-contains-currentTime-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/media/audio-controls-rendering-expected.png b/third_party/blink/web_tests/platform/win/media/audio-controls-rendering-expected.png index 294931da..95c461c 100644 --- a/third_party/blink/web_tests/platform/win/media/audio-controls-rendering-expected.png +++ b/third_party/blink/web_tests/platform/win/media/audio-controls-rendering-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/media/controls-layout-direction-expected.png b/third_party/blink/web_tests/platform/win/media/controls-layout-direction-expected.png index c256b1eb..819ef75 100644 --- a/third_party/blink/web_tests/platform/win/media/controls-layout-direction-expected.png +++ b/third_party/blink/web_tests/platform/win/media/controls-layout-direction-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/media/media-controls-clone-expected.png b/third_party/blink/web_tests/platform/win/media/media-controls-clone-expected.png index 8667261..cdf4e047 100644 --- a/third_party/blink/web_tests/platform/win/media/media-controls-clone-expected.png +++ b/third_party/blink/web_tests/platform/win/media/media-controls-clone-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/media/media-controls-grey-scrubber-expected.png b/third_party/blink/web_tests/platform/win/media/media-controls-grey-scrubber-expected.png index 0abd097..8e06338 100644 --- a/third_party/blink/web_tests/platform/win/media/media-controls-grey-scrubber-expected.png +++ b/third_party/blink/web_tests/platform/win/media/media-controls-grey-scrubber-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/media/media-document-audio-repaint-expected.png b/third_party/blink/web_tests/platform/win/media/media-document-audio-repaint-expected.png index 2f532c1f..20f5e529 100644 --- a/third_party/blink/web_tests/platform/win/media/media-document-audio-repaint-expected.png +++ b/third_party/blink/web_tests/platform/win/media/media-document-audio-repaint-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/media/video-empty-source-expected.png b/third_party/blink/web_tests/platform/win/media/video-empty-source-expected.png index 92eec92..78be5a4b 100644 --- a/third_party/blink/web_tests/platform/win/media/video-empty-source-expected.png +++ b/third_party/blink/web_tests/platform/win/media/video-empty-source-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/blink/web_tests/platform/win/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png index 3a4e36d..ffcec115 100644 --- a/third_party/blink/web_tests/platform/win/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png +++ b/third_party/blink/web_tests/platform/win/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-composited-row-expected.txt b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-composited-row-expected.txt index 061f65cd..d27dd864 100644 --- a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-composited-row-expected.txt +++ b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-composited-row-expected.txt
@@ -10,6 +10,7 @@ "name": "LayoutTableRow TR id='target'", "position": [8, 96], "bounds": [184, 64], + "contentsOpaqueForText": true, "backgroundColor": "#ADD8E6", "invalidations": [ [0, 0, 184, 64]
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt index 061f65cd..d27dd864 100644 --- a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt +++ b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt
@@ -10,6 +10,7 @@ "name": "LayoutTableRow TR id='target'", "position": [8, 96], "bounds": [184, 64], + "contentsOpaqueForText": true, "backgroundColor": "#ADD8E6", "invalidations": [ [0, 0, 184, 64]
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt index 84a782c..9f33106c 100644 --- a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt +++ b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt
@@ -10,6 +10,7 @@ "name": "LayoutTableSection TBODY id='target'", "position": [8, 28], "bounds": [184, 134], + "contentsOpaqueForText": true, "backgroundColor": "#ADD8E6", "invalidations": [ [0, 0, 184, 134]
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt index 84a782c..9f33106c 100644 --- a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt +++ b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt
@@ -10,6 +10,7 @@ "name": "LayoutTableSection TBODY id='target'", "position": [8, 28], "bounds": [184, 134], + "contentsOpaqueForText": true, "backgroundColor": "#ADD8E6", "invalidations": [ [0, 0, 184, 134]
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-expected.txt b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-expected.txt index bb5baed0..70a648e 100644 --- a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-expected.txt +++ b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-expected.txt
@@ -10,6 +10,7 @@ "name": "LayoutTableSection TBODY id='target'", "position": [8, 28], "bounds": [184, 134], + "contentsOpaqueForText": true, "backgroundColor": "#ADD8E6", "invalidations": [ [0, 0, 184, 134]
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt index bb5baed0..70a648e 100644 --- a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt +++ b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt
@@ -10,6 +10,7 @@ "name": "LayoutTableSection TBODY id='target'", "position": [8, 28], "bounds": [184, 134], + "contentsOpaqueForText": true, "backgroundColor": "#ADD8E6", "invalidations": [ [0, 0, 184, 134]
diff --git a/third_party/blink/web_tests/platform/win/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png b/third_party/blink/web_tests/platform/win/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png index d2feeb47..a099336 100644 --- a/third_party/blink/web_tests/platform/win/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png +++ b/third_party/blink/web_tests/platform/win/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/svg/W3C-SVG-1.1/masking-opacity-01-b-expected.png b/third_party/blink/web_tests/platform/win/svg/W3C-SVG-1.1/masking-opacity-01-b-expected.png index 891796d..fea2c473 100644 --- a/third_party/blink/web_tests/platform/win/svg/W3C-SVG-1.1/masking-opacity-01-b-expected.png +++ b/third_party/blink/web_tests/platform/win/svg/W3C-SVG-1.1/masking-opacity-01-b-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/svg/batik/text/verticalText-expected.png b/third_party/blink/web_tests/platform/win/svg/batik/text/verticalText-expected.png index fa79ddb..06e3032 100644 --- a/third_party/blink/web_tests/platform/win/svg/batik/text/verticalText-expected.png +++ b/third_party/blink/web_tests/platform/win/svg/batik/text/verticalText-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/svg/custom/container-opacity-clip-viewBox-expected.png b/third_party/blink/web_tests/platform/win/svg/custom/container-opacity-clip-viewBox-expected.png index 4eee57b..a4baca7 100644 --- a/third_party/blink/web_tests/platform/win/svg/custom/container-opacity-clip-viewBox-expected.png +++ b/third_party/blink/web_tests/platform/win/svg/custom/container-opacity-clip-viewBox-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/svg/text/text-selection-text-08-b-expected.png b/third_party/blink/web_tests/platform/win/svg/text/text-selection-text-08-b-expected.png index 0da3cab..4a149de 100644 --- a/third_party/blink/web_tests/platform/win/svg/text/text-selection-text-08-b-expected.png +++ b/third_party/blink/web_tests/platform/win/svg/text/text-selection-text-08-b-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/transforms/2d/hindi-rotated-expected.png b/third_party/blink/web_tests/platform/win/transforms/2d/hindi-rotated-expected.png index 7a7e2069..7a9bba8 100644 --- a/third_party/blink/web_tests/platform/win/transforms/2d/hindi-rotated-expected.png +++ b/third_party/blink/web_tests/platform/win/transforms/2d/hindi-rotated-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/cascade/fast/forms/select/basic-selects-expected.png b/third_party/blink/web_tests/platform/win/virtual/cascade/fast/forms/select/basic-selects-expected.png index 7022d4f..f1acb10 100644 --- a/third_party/blink/web_tests/platform/win/virtual/cascade/fast/forms/select/basic-selects-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/cascade/fast/forms/select/basic-selects-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/controls-refresh/calendar-picker/date-picker-month-appearance-expected.png b/third_party/blink/web_tests/platform/win/virtual/controls-refresh/calendar-picker/date-picker-month-appearance-expected.png index d756b29ede..3c4cf0b5 100644 --- a/third_party/blink/web_tests/platform/win/virtual/controls-refresh/calendar-picker/date-picker-month-appearance-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/controls-refresh/calendar-picker/date-picker-month-appearance-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/controls-refresh/calendar-picker/date-picker-month-selection-changed-appearance-expected.png b/third_party/blink/web_tests/platform/win/virtual/controls-refresh/calendar-picker/date-picker-month-selection-changed-appearance-expected.png index 8941875..68975d3d 100644 --- a/third_party/blink/web_tests/platform/win/virtual/controls-refresh/calendar-picker/date-picker-month-selection-changed-appearance-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/controls-refresh/calendar-picker/date-picker-month-selection-changed-appearance-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/controls-refresh/color-scheme/select/select-inpage-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win/virtual/controls-refresh/color-scheme/select/select-inpage-appearance-basic-expected.png index 7be838c..53964f5 100644 --- a/third_party/blink/web_tests/platform/win/virtual/controls-refresh/color-scheme/select/select-inpage-appearance-basic-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/controls-refresh/color-scheme/select/select-inpage-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/controls-refresh/color-scheme/select/select-multiple-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win/virtual/controls-refresh/color-scheme/select/select-multiple-appearance-basic-expected.png index d2dd786..7df8b42 100644 --- a/third_party/blink/web_tests/platform/win/virtual/controls-refresh/color-scheme/select/select-multiple-appearance-basic-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/controls-refresh/color-scheme/select/select-multiple-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/form-controls-refresh-disabled/fast/forms/indeterminate-expected.png b/third_party/blink/web_tests/platform/win/virtual/form-controls-refresh-disabled/fast/forms/indeterminate-expected.png index 8854479c..7f2aa9bb 100644 --- a/third_party/blink/web_tests/platform/win/virtual/form-controls-refresh-disabled/fast/forms/indeterminate-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/form-controls-refresh-disabled/fast/forms/indeterminate-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/text-antialias/complex-text-opacity-expected.png b/third_party/blink/web_tests/platform/win/virtual/text-antialias/complex-text-opacity-expected.png index 2d2eb02..31a16b7 100644 --- a/third_party/blink/web_tests/platform/win/virtual/text-antialias/complex-text-opacity-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/text-antialias/complex-text-opacity-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/text-antialias/letter-spacing-negative-opacity-expected.png b/third_party/blink/web_tests/platform/win/virtual/text-antialias/letter-spacing-negative-opacity-expected.png index be0d78a4..8f41d22 100644 --- a/third_party/blink/web_tests/platform/win/virtual/text-antialias/letter-spacing-negative-opacity-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/text-antialias/letter-spacing-negative-opacity-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/select/listbox-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/select/listbox-appearance-basic-expected.png new file mode 100644 index 0000000..ec1b0ff6 --- /dev/null +++ b/third_party/blink/web_tests/platform/win7/fast/forms/select/listbox-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/select/select-disabled-appearance-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/select/select-disabled-appearance-expected.png new file mode 100644 index 0000000..81e4fc4 --- /dev/null +++ b/third_party/blink/web_tests/platform/win7/fast/forms/select/select-disabled-appearance-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/blink/web_tests/platform/win7/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png index 3469af3..82b4f032 100644 --- a/third_party/blink/web_tests/platform/win7/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png +++ b/third_party/blink/web_tests/platform/win7/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png b/third_party/blink/web_tests/platform/win7/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png deleted file mode 100644 index d2feeb47..0000000 --- a/third_party/blink/web_tests/platform/win7/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/batik/text/verticalText-expected.png b/third_party/blink/web_tests/platform/win7/svg/batik/text/verticalText-expected.png index 07cce28..950ec8d 100644 --- a/third_party/blink/web_tests/platform/win7/svg/batik/text/verticalText-expected.png +++ b/third_party/blink/web_tests/platform/win7/svg/batik/text/verticalText-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/text/text-selection-text-08-b-expected.png b/third_party/blink/web_tests/platform/win7/svg/text/text-selection-text-08-b-expected.png index 8daeedab6..fcce118 100644 --- a/third_party/blink/web_tests/platform/win7/svg/text/text-selection-text-08-b-expected.png +++ b/third_party/blink/web_tests/platform/win7/svg/text/text-selection-text-08-b-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/transforms/2d/hindi-rotated-expected.png b/third_party/blink/web_tests/platform/win7/transforms/2d/hindi-rotated-expected.png index ae876c32..8cb90b73 100644 --- a/third_party/blink/web_tests/platform/win7/transforms/2d/hindi-rotated-expected.png +++ b/third_party/blink/web_tests/platform/win7/transforms/2d/hindi-rotated-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh/calendar-picker/date-picker-month-appearance-expected.png b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh/calendar-picker/date-picker-month-appearance-expected.png index ac3273f2..6cc5cdc7 100644 --- a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh/calendar-picker/date-picker-month-appearance-expected.png +++ b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh/calendar-picker/date-picker-month-appearance-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh/calendar-picker/date-picker-month-selection-changed-appearance-expected.png b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh/calendar-picker/date-picker-month-selection-changed-appearance-expected.png index a6f7b58..fb87ed3a 100644 --- a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh/calendar-picker/date-picker-month-selection-changed-appearance-expected.png +++ b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh/calendar-picker/date-picker-month-selection-changed-appearance-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/complex-text-opacity-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/complex-text-opacity-expected.png index 71baf4e9..62139ae 100644 --- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/complex-text-opacity-expected.png +++ b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/complex-text-opacity-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/letter-spacing-negative-opacity-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/letter-spacing-negative-opacity-expected.png index eb2de72..b94d481 100644 --- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/letter-spacing-negative-opacity-expected.png +++ b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/letter-spacing-negative-opacity-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/threaded/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png b/third_party/blink/web_tests/platform/win7/virtual/threaded/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png deleted file mode 100644 index d2feeb47..0000000 --- a/third_party/blink/web_tests/platform/win7/virtual/threaded/printing/fixed-positioned-headers-and-footers-inside-transform-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/virtual/disable-ax-serializer/README.md b/third_party/blink/web_tests/virtual/disable-ax-serializer/README.md deleted file mode 100644 index 1c0048f..0000000 --- a/third_party/blink/web_tests/virtual/disable-ax-serializer/README.md +++ /dev/null
@@ -1 +0,0 @@ -This directory contains tests that will only pass when accessibility serialization is turned off.
diff --git a/third_party/blink/web_tests/virtual/disable-user-agent-client-hint-feature/README.md b/third_party/blink/web_tests/virtual/disable-user-agent-client-hint-feature/README.md new file mode 100644 index 0000000..379ed78 --- /dev/null +++ b/third_party/blink/web_tests/virtual/disable-user-agent-client-hint-feature/README.md
@@ -0,0 +1,2 @@ +This virtual test suite ensures the UserAgentClientHint feature and runtime +feature disable correctly.
diff --git a/third_party/blink/web_tests/virtual/disable-user-agent-client-hint-feature/external/wpt/client-hints/accept-ch-feature-policy.sub.https-expected.txt b/third_party/blink/web_tests/virtual/disable-user-agent-client-hint-feature/external/wpt/client-hints/accept-ch-feature-policy.sub.https-expected.txt new file mode 100644 index 0000000..0119d57d --- /dev/null +++ b/third_party/blink/web_tests/virtual/disable-user-agent-client-hint-feature/external/wpt/client-hints/accept-ch-feature-policy.sub.https-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +FAIL Accept-CH header test assert_true: expected true got false +PASS Cross-Origin Accept-CH header test +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/disable-user-agent-client-hint-feature/external/wpt/client-hints/accept-ch-stickiness/cross-origin-iframe-redirect-with-fp-delegation.https-expected.txt b/third_party/blink/web_tests/virtual/disable-user-agent-client-hint-feature/external/wpt/client-hints/accept-ch-stickiness/cross-origin-iframe-redirect-with-fp-delegation.https-expected.txt new file mode 100644 index 0000000..166cdfce --- /dev/null +++ b/third_party/blink/web_tests/virtual/disable-user-agent-client-hint-feature/external/wpt/client-hints/accept-ch-stickiness/cross-origin-iframe-redirect-with-fp-delegation.https-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Iframe redirect with Feature Policy delegation got client hints according to expectations. assert_equals: message from opened frame expected "PASS" but got "FAIL" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-stickiness/cross-origin-subresource-redirect-with-fp-delegation.https-expected.txt b/third_party/blink/web_tests/virtual/disable-user-agent-client-hint-feature/external/wpt/client-hints/accept-ch-stickiness/cross-origin-subresource-redirect-with-fp-delegation.https-expected.txt similarity index 61% rename from third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-stickiness/cross-origin-subresource-redirect-with-fp-delegation.https-expected.txt rename to third_party/blink/web_tests/virtual/disable-user-agent-client-hint-feature/external/wpt/client-hints/accept-ch-stickiness/cross-origin-subresource-redirect-with-fp-delegation.https-expected.txt index a59069e3..cea54bbdd 100644 --- a/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-stickiness/cross-origin-subresource-redirect-with-fp-delegation.https-expected.txt +++ b/third_party/blink/web_tests/virtual/disable-user-agent-client-hint-feature/external/wpt/client-hints/accept-ch-stickiness/cross-origin-subresource-redirect-with-fp-delegation.https-expected.txt
@@ -1,4 +1,4 @@ This is a testharness.js-based test. -FAIL cross-origin subresource redirect with Feature Policy delegaation got client hints according to expectations. assert_true: expected true got false +FAIL cross-origin subresource redirect with Feature Policy delegation got client hints according to expectations. assert_true: expected true got false Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/virtual/disable-user-agent-client-hint-feature/external/wpt/client-hints/accept-ch-stickiness/same-origin-navigation-redirect.https-expected.txt b/third_party/blink/web_tests/virtual/disable-user-agent-client-hint-feature/external/wpt/client-hints/accept-ch-stickiness/same-origin-navigation-redirect.https-expected.txt new file mode 100644 index 0000000..73d7a83 --- /dev/null +++ b/third_party/blink/web_tests/virtual/disable-user-agent-client-hint-feature/external/wpt/client-hints/accept-ch-stickiness/same-origin-navigation-redirect.https-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +PASS redirect on navigation precondition: Test that the browser does not have client hints preferences cached +FAIL redirect on navigation got client hints according to expectations. assert_equals: message from opened page expected "PASS" but got "FAIL" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/disable-user-agent-client-hint-feature/external/wpt/client-hints/accept-ch-stickiness/same-origin-subresource-redirect-opted-in.https-expected.txt b/third_party/blink/web_tests/virtual/disable-user-agent-client-hint-feature/external/wpt/client-hints/accept-ch-stickiness/same-origin-subresource-redirect-opted-in.https-expected.txt new file mode 100644 index 0000000..dad4461 --- /dev/null +++ b/third_party/blink/web_tests/virtual/disable-user-agent-client-hint-feature/external/wpt/client-hints/accept-ch-stickiness/same-origin-subresource-redirect-opted-in.https-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL same-origin subresource redirect with opt-in got client hints according to expectations. assert_true: expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/disable-user-agent-client-hint-feature/external/wpt/client-hints/sec-ch-ua.https-expected.txt b/third_party/blink/web_tests/virtual/disable-user-agent-client-hint-feature/external/wpt/client-hints/sec-ch-ua.https-expected.txt new file mode 100644 index 0000000..0bed3d3b --- /dev/null +++ b/third_party/blink/web_tests/virtual/disable-user-agent-client-hint-feature/external/wpt/client-hints/sec-ch-ua.https-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +FAIL Open HTTPS window prior to opt-in: `Sec-CH-UA` header with minor version. assert_not_equals: The `Sec-CH-UA` header is delivered. got disallowed value "" +FAIL Open HTTPS window post-opt-in: `Sec-CH-UA` header with minor version. assert_not_equals: The `Sec-CH-UA` header is delivered. got disallowed value "" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-stickiness/cross-origin-subresource-redirect.https-expected.txt b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-stickiness/cross-origin-subresource-redirect.https-expected.txt new file mode 100644 index 0000000..1a32d8c --- /dev/null +++ b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-stickiness/cross-origin-subresource-redirect.https-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL cross-origin subresource redirect got client hints according to expectations. assert_true: expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-stickiness/cross-origin-syncxhr-redirect.https-expected.txt b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-stickiness/cross-origin-syncxhr-redirect.https-expected.txt new file mode 100644 index 0000000..bc27661 --- /dev/null +++ b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-stickiness/cross-origin-syncxhr-redirect.https-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL cross-origin sync XHR redirect got client hints according to expectations. assert_true: expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/legacy-client-hints/external/wpt/client-hints/accept-ch-stickiness/cross-origin-subresource-redirect.https-expected.txt b/third_party/blink/web_tests/virtual/legacy-client-hints/external/wpt/client-hints/accept-ch-stickiness/cross-origin-subresource-redirect.https-expected.txt new file mode 100644 index 0000000..1a32d8c --- /dev/null +++ b/third_party/blink/web_tests/virtual/legacy-client-hints/external/wpt/client-hints/accept-ch-stickiness/cross-origin-subresource-redirect.https-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL cross-origin subresource redirect got client hints according to expectations. assert_true: expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/legacy-client-hints/external/wpt/client-hints/accept-ch-stickiness/cross-origin-syncxhr-redirect.https-expected.txt b/third_party/blink/web_tests/virtual/legacy-client-hints/external/wpt/client-hints/accept-ch-stickiness/cross-origin-syncxhr-redirect.https-expected.txt new file mode 100644 index 0000000..bc27661 --- /dev/null +++ b/third_party/blink/web_tests/virtual/legacy-client-hints/external/wpt/client-hints/accept-ch-stickiness/cross-origin-syncxhr-redirect.https-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL cross-origin sync XHR redirect got client hints according to expectations. assert_true: expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt index fc613ee..dceb7235 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -729,6 +729,7 @@ [Worker] method getColorSettings [Worker] interface ImageDecoder [Worker] attribute @@toStringTag +[Worker] getter complete [Worker] getter frameCount [Worker] getter repetitionCount [Worker] getter type
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 4e66d1b..0823355 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
@@ -4577,6 +4577,7 @@ method getColorSettings interface ImageDecoder attribute @@toStringTag + getter complete getter frameCount getter repetitionCount getter type @@ -6347,6 +6348,7 @@ getter synchronizationSource getter timestamp method constructor + method getMetadata method toString setter data interface RTCEncodedVideoFrame @@ -6357,6 +6359,7 @@ getter timestamp getter type method constructor + method getMetadata method toString setter data interface RTCError : DOMException @@ -6536,6 +6539,7 @@ getter transport method constructor method createEncodedAudioStreams + method createEncodedStreams method createEncodedVideoStreams method getContributingSources method getParameters @@ -6551,6 +6555,7 @@ getter transport method constructor method createEncodedAudioStreams + method createEncodedStreams method createEncodedVideoStreams method getParameters method getStats
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt index 37eedd1..e76692b 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -716,6 +716,7 @@ [Worker] method getColorSettings [Worker] interface ImageDecoder [Worker] attribute @@toStringTag +[Worker] getter complete [Worker] getter frameCount [Worker] getter repetitionCount [Worker] getter type
diff --git a/third_party/schema_org/overrides.jsonld b/third_party/schema_org/overrides.jsonld index be68125f..9529ea3a 100644 --- a/third_party/schema_org/overrides.jsonld +++ b/third_party/schema_org/overrides.jsonld
@@ -87,6 +87,43 @@ ], "rdfs:comment": "The duration of the item (movie, audio recording, event, etc.) in <a href=\"http://en.wikipedia.org/wiki/ISO_8601\">ISO 8601 date format</a>.", "rdfs:label": "duration" + }, + { + "@id": "http://schema.org/value", + "@type": "rdf:Property", + "http://purl.org/dc/terms/source": { + "@id": "http://www.w3.org/wiki/WebSchemas/SchemaDotOrgSources#source_GoodRelationsTerms" + }, + "http://schema.org/domainIncludes": [ + { + "@id": "http://schema.org/QuantitativeValue" + }, + { + "@id": "http://schema.org/MonetaryAmount" + }, + { + "@id": "http://schema.org/PropertyValue" + } + ], + "http://schema.org/rangeIncludes": [ + { + "@id": "http://schema.org/Number" + }, + { + "@id": "http://schema.org/Text" + }, + { + "@id": "http://schema.org/StructuredValue" + }, + { + "@id": "http://schema.org/Boolean" + }, + { + "@id": "http://schema.org/URL" + } + ], + "rdfs:comment": "The value of the quantitative value or property value node.<br/><br/>\n\n<ul>\n<li>For <a class=\"localLink\" href=\"http://schema.org/QuantitativeValue\">QuantitativeValue</a> and <a class=\"localLink\" href=\"http://schema.org/MonetaryAmount\">MonetaryAmount</a>, the recommended type for values is 'Number'.</li>\n<li>For <a class=\"localLink\" href=\"http://schema.org/PropertyValue\">PropertyValue</a>, it can be 'Text;', 'Number', 'Boolean', or 'StructuredValue'.</li>\n<li>Use values from 0123456789 (Unicode 'DIGIT ZERO' (U+0030) to 'DIGIT NINE' (U+0039)) rather than superficially similiar Unicode symbols.</li>\n<li>Use '.' (Unicode 'FULL STOP' (U+002E)) rather than ',' to indicate a decimal point. Avoid using these symbols as a readability separator.</li>\n</ul>\n", + "rdfs:label": "value" } ] }
diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec index 60d84aab..535829b 100644 --- a/tools/gritsettings/resource_ids.spec +++ b/tools/gritsettings/resource_ids.spec
@@ -289,7 +289,7 @@ # src_internal is available. Lower bound is that we bundle ~100 images for # offline articles with the app, as well as strings in every language (74), # and bundled content in the top 25 languages (25 x 2). - "chromeos/components/help_app_ui/resources/app/help_app_bundle_resources.grd": { + "chromeos/components/help_app_ui/resources/prod/help_app_bundle_resources.grd": { "META": {"sizes": {"includes": [300],}}, # Relies on src-internal. "includes": [2540], },
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 0f06d674..51053e5 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -14137,6 +14137,13 @@ </description> </action> +<action name="MobileShareQRCode"> + <owner>seblalancette@chromium.org</owner> + <description> + The user initiated the Share action for the generated QR code image. + </description> +</action> + <action name="MobileShortcutAllBookmarks"> <obsolete>Deprecated as of 5/2015</obsolete> <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 79b57e2..c3f972a 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -2788,6 +2788,8 @@ <int value="7" label="App Management main view (Chrome app)"/> <int value="8" label="App Management main view (Web App)"/> <int value="9" label="OS Settings main page"/> + <int value="10" label="App Management main view (Plugin VM)"/> + <int value="11" label="DBus Service (Plugin VM)"/> </enum> <enum name="AppManagementUserAction"> @@ -2808,6 +2810,8 @@ <int value="14" label="Contacts turned off"/> <int value="15" label="Storage turned on"/> <int value="16" label="Storage turned off"/> + <int value="17" label="Printing turned on"/> + <int value="18" label="Printing turned off"/> </enum> <enum name="AppPromoAction"> @@ -20223,6 +20227,8 @@ <int value="702" label="ReportDeviceAppInfo"/> <int value="703" label="AccessibilityImageLabelsEnabled"/> <int value="704" label="AppCacheForceEnabled"/> + <int value="705" label="UserPluginVmAllowed"/> + <int value="706" label="PrintRasterizationMode"/> </enum> <enum name="EnterprisePolicyDeviceIdValidity"> @@ -22920,6 +22926,8 @@ <int value="1468" label="AUTOTESTPRIVATE_STOPSMOOTHNESSTRACKING"/> <int value="1469" label="ACCESSIBILITY_PRIVATE_UPDATESWITCHACCESSBUBBLE"/> <int value="1470" label="TERMINALPRIVATE_OPENOPTIONSPAGE"/> + <int value="1471" label="DECLARATIVENETREQUEST_UPDATEENABLEDRULESETS"/> + <int value="1472" label="DECLARATIVENETREQUEST_GETENABLEDRULESETS"/> </enum> <enum name="ExtensionIconState"> @@ -27312,6 +27320,10 @@ <int value="3289" label="GridRowGapPercentIndefinite"/> <int value="3290" label="FlexRowGapPercent"/> <int value="3291" label="FlexRowGapPercentIndefinite"/> + <int value="3292" label="V8RTCRtpSender_CreateEncodedStreams_Method"/> + <int value="3293" label="V8RTCRtpReceiver_CreateEncodedStreams_Method"/> + <int value="3294" label="ForceEncodedAudioInsertableStreams"/> + <int value="3295" label="ForceEncodedVideoInsertableStreams"/> </enum> <enum name="FeaturePolicyAllowlistType"> @@ -37870,6 +37882,12 @@ <int value="3" label="Last item"/> </enum> +<enum name="LiveCaptionsSessionEvent"> + <int value="0" label="Stream started"/> + <int value="1" label="Stream finished"/> + <int value="2" label="User closed bubble"/> +</enum> + <enum name="LoadingPredictorOptimizationHintsReceiveStatus"> <int value="0" label="Unknown"/> <int value="1" label="Before navigation finish"/> @@ -38352,7 +38370,6 @@ <int value="-1939003674" label="NetworkServiceInProcess:disabled"/> <int value="-1938263248" label="enable-extension-info-dialog"/> <int value="-1937077699" label="http-form-warning"/> - <int value="-1936630125" label="BluetoothKernelSuspendNotifier:enabled"/> <int value="-1936032607" label="enable-experimental-webassembly-features"/> <int value="-1934661084" label="ForceUnifiedConsentBump:disabled"/> <int value="-1933425042" label="OfflinePreviews:enabled"/> @@ -38758,7 +38775,6 @@ <int value="-1472825316" label="ContextualSearchLongpressResolve:enabled"/> <int value="-1471021059" label="OmniboxUIExperimentShowSuggestionFavicons:disabled"/> - <int value="-1470178735" label="BluetoothKernelSuspendNotifier:disabled"/> <int value="-1469536698" label="ChromeHomeDoodle:enabled"/> <int value="-1469228683" label="QuickUnlockPinSignin:disabled"/> <int value="-1468126425" label="ResourceLoadScheduler:disabled"/> @@ -38944,6 +38960,8 @@ <int value="-1288130734" label="OpenVR:disabled"/> <int value="-1287511172" label="OmniboxUIExperimentHideSteadyStateUrlSchemeAndSubdomains:disabled"/> + <int value="-1286038936" + label="AutofillEnableCardNicknameManagement:enabled"/> <int value="-1285021473" label="save-page-as-mhtml"/> <int value="-1284637134" label="pull-to-refresh"/> <int value="-1282992935" @@ -39637,10 +39655,13 @@ <int value="-513305102" label="LanguagesPreference:enabled"/> <int value="-513066193" label="SyncUSSPasswords:enabled"/> <int value="-512971943" label="disable-one-copy"/> + <int value="-512702391" + label="AutofillEnableCardNicknameManagement:disabled"/> <int value="-510488450" label="disable-pnacl"/> <int value="-508346329" label="TerminalSystemAppLegacySettings:disabled"/> <int value="-508250572" label="ServiceWorkerLongRunningMessage:disabled"/> <int value="-508143738" label="disable-accelerated-fixed-root-background"/> + <int value="-507066244" label="AndroidDarkSearch:enabled"/> <int value="-506706655" label="respect-autocomplete-off-autofill"/> <int value="-506366023" label="VizHitTest:enabled"/> <int value="-505679399" label="FontCacheScaling:enabled"/> @@ -39740,6 +39761,7 @@ <int value="-395606844" label="enable-site-settings"/> <int value="-395454065" label="DisablePostScriptPrinting:disabled"/> <int value="-387606010" label="ArcBootCompletedBroadcast:enabled"/> + <int value="-386971711" label="ChromeSharingHubV15:disabled"/> <int value="-385337473" label="enable-fast-unload"/> <int value="-384589459" label="disable-supervised-user-safesites"/> <int value="-381181808" label="DragAppsInTabletMode:enabled"/> @@ -40641,6 +40663,7 @@ <int value="656864700" label="FillOnAccountSelectHttp:disabled"/> <int value="659086147" label="OverlayScrollbarFlashWhenMouseEnter:enabled"/> <int value="661020875" label="AutofillSaveCardShowNoThanks:disabled"/> + <int value="662331859" label="ConversionMeasurement:enabled"/> <int value="663027937" label="NewTabPageCustomLinks:enabled"/> <int value="663069508" label="TabToGTSAnimation:enabled"/> <int value="663294302" label="ForceUseAPDownloadProtection:disabled"/> @@ -40730,6 +40753,7 @@ <int value="749516419" label="DragToSnapInClamshellMode:disabled"/> <int value="752194066" label="enable-app-window-cycling"/> <int value="752939691" label="disable-tab-for-desktop-share"/> + <int value="757645375" label="AndroidDarkSearch:disabled"/> <int value="760542355" label="ServiceWorkerScriptFullCodeCache:enabled"/> <int value="762700519" label="enable-checker-imaging"/> <int value="763947368" label="HomepageLocationPolicy:disabled"/> @@ -40845,6 +40869,7 @@ <int value="913138924" label="RecurrentInterstitialFeature:disabled"/> <int value="913855453" label="VirtualKeyboardFloatingResizable:disabled"/> <int value="916316159" label="disable-new-app-list-mixer"/> + <int value="917561046" label="ConversionMeasurement:disabled"/> <int value="918046854" label="NtlmV2Enabled:disabled"/> <int value="921536672" label="OfflinePagesDescriptiveFailStatus:enabled"/> <int value="921561616" label="WebAssemblyTiering:disabled"/> @@ -41444,6 +41469,7 @@ <int value="1594664550" label="NTPModernLayout:enabled"/> <int value="1595208893" label="AudioWorkletRealtimeThread:enabled"/> <int value="1597880096" label="FocusMode:disabled"/> + <int value="1597972555" label="ChromeSharingHubV15:enabled"/> <int value="1600850069" label="MobileIdentityConsistency:disabled"/> <int value="1600926040" label="TranslateCompactUI:enabled"/> <int value="1602869271" label="ChromeShareScreenshot:disabled"/> @@ -41775,6 +41801,7 @@ label="AutofillEnableFixedPaymentsBubbleLogging:enabled"/> <int value="1964816410" label="AndroidPayIntegrationV2:enabled"/> <int value="1965055310" label="SyncSetupFriendlySettings:enabled"/> + <int value="1965534355" label="conversions-debug-mode"/> <int value="1965976546" label="NewOverviewAnimations:disabled"/> <int value="1966730288" label="disable-threaded-compositing"/> <int value="1968199744" label="PrintJobManagementApp:disabled"/> @@ -43823,6 +43850,11 @@ <int value="3" label="kInvalidPlayerState"/> </enum> +<enum name="MediaKeySystem"> + <int value="0" label="Clear Key"/> + <int value="1" label="Widevine"/> +</enum> + <enum name="MediaKeySystemSupportStatus"> <int value="0" label="Queried"/> <int value="1" label="Supported"/> @@ -48094,6 +48126,10 @@ label="Clicked on the Refresh button in the all dismissed state"/> <int value="11" label="Opened an explore sites tile"/> <int value="12" label="Opened the manage interests page from the feed"/> + <int value="13" + label="Triggered a block content action, which typically results in the + content being removed from the feed, and a setting written + server side to avoid serving that content again."/> </enum> <enum name="NewTabPageActioniOS"> @@ -65989,6 +66025,21 @@ </int> </enum> +<enum name="TextFragmentAnchorParameters"> + <summary> + Indicates which parameters were specified in a text fragment anchor. + </summary> + <int value="0" label="Unknown"/> + <int value="1" label="ExactText"/> + <int value="2" label="ExactTextWithPrefix"/> + <int value="3" label="ExactTextWithSuffix"/> + <int value="4" label="ExactTextWithContext"/> + <int value="5" label="TextRange"/> + <int value="6" label="TextRangeWithPrefix"/> + <int value="7" label="TextRangeWithSuffix"/> + <int value="8" label="TextRangeWithContext"/> +</enum> + <enum name="TextToSpeechEvent"> <int value="0" label="Start"/> <int value="1" label="End"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index a101443..d35489d 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -631,6 +631,20 @@ </summary> </histogram> +<histogram name="Accessibility.LiveCaptions.Session" + enum="LiveCaptionsSessionEvent" expires_after="2021-04-30"> + <owner>katie@chromium.org</owner> + <owner>abigailbklein@google.com</owner> + <owner>evliu@google.com</owner> + <owner>chrome-a11y-core@google.com</owner> + <summary> + Logged when there's a change in the lifetime of a Live Captions audio + stream: When a session started and captions began arriving from the service, + when a session ended because the audio stream finished, or when the session + ended because a user clicked the close button on the caption bubble. + </summary> +</histogram> + <histogram name="Accessibility.LiveCaptions.ToggleEnabled" enum="BooleanEnabled" expires_after="2021-04-30"> <owner>katie@chromium.org</owner> @@ -4783,6 +4797,18 @@ </summary> </histogram> +<histogram name="Android.WebView.DevUi.AppLaunch" enum="Boolean" + expires_after="2021-01-20"> + <owner>ntfschr@chromium.org</owner> + <owner>hazems@chromium.org</owner> + <owner>src/android_webview/OWNERS</owner> + <summary> + Records the number of times the developer UI app was launched. This only + ever logs the value "true" because we only care about the total + count. This is logged in the developer UI app during Activity#onCreate. + </summary> +</histogram> + <histogram name="Android.WebView.DevUi.DeveloperModeBlockingTime" units="ms" expires_after="2021-01-20"> <owner>ntfschr@chromium.org</owner> @@ -29039,6 +29065,16 @@ </summary> </histogram> +<histogram name="ContentSuggestions.Feed.NoticeCardFulfilled" enum="Boolean" + expires_after="2021-01-01"> + <owner>frechette@chromium.org</owner> + <owner>feed@chromium.org</owner> + <summary> + Android: Whether the notice card for feed action reporting has been + fulfilled. + </summary> +</histogram> + <histogram name="ContentSuggestions.Feed.Offline.GetStatusCount" units="count" expires_after="2020-10-01"> <owner>carlosk@chromium.org</owner> @@ -56966,7 +57002,10 @@ </histogram> <histogram name="Extensions.Toolbar.PinnedExtensionCount" - units="pinned extensions" expires_after="2021-06-30"> + units="pinned extensions" expires_after="M84"> + <obsolete> + Replaced by Extensions.Toolbar.PinnedExtensionCount2 in 2020/05. + </obsolete> <owner>rdevlin.cronin@chromium.org</owner> <owner>extensions-core@chromium.org</owner> <summary> @@ -56975,8 +57014,22 @@ </summary> </histogram> +<histogram name="Extensions.Toolbar.PinnedExtensionCount2" + units="pinned extensions" expires_after="2021-06-30"> + <owner>rdevlin.cronin@chromium.org</owner> + <owner>extensions-core@chromium.org</owner> + <summary> + The number of extensions that the user has pinned on the toolbar. Recorded + once per profile during initialization if the user has at least one + extension with an action in the toolbar. + </summary> +</histogram> + <histogram name="Extensions.Toolbar.PinnedExtensionPercentage" units="%" expires_after="2021-06-30"> + <obsolete> + Replaced by Extensions.Toolbar.PinnedExtensionPercentage2 in 2020/05. + </obsolete> <owner>rdevlin.cronin@chromium.org</owner> <owner>extensions-core@chromium.org</owner> <summary> @@ -56986,6 +57039,18 @@ </summary> </histogram> +<histogram name="Extensions.Toolbar.PinnedExtensionPercentage2" units="%" + expires_after="2021-06-30"> + <owner>rdevlin.cronin@chromium.org</owner> + <owner>extensions-core@chromium.org</owner> + <summary> + The percentage of extensions that the user has pinned to the toolbar (i.e., + this will be 100 if the user has every extension pinned). Recorded once per + profile during initialization if the user has at least one extension with an + action in the toolbar. + </summary> +</histogram> + <histogram name="Extensions.ToolstripLoadTime" units="ms" expires_after="2016-04-29"> <obsolete> @@ -63288,6 +63353,17 @@ <summary>Counts user actions when a 3D API info bar is raised.</summary> </histogram> +<histogram name="GPU.Vulkan.QueueSubmitPerSwapBuffers" units="units" + expires_after="2020-12-01"> + <owner>backer@chromium.org</owner> + <owner>penghuang@chromium.org</owner> + <owner>vasilyt@chromium.org</owner> + <summary> + The number of vkQueueSubmit() calls per SwapBuffers. It is recorded when + SwapBuffers() call is completed or skipped. + </summary> +</histogram> + <histogram name="GPU.VulkanExtSupport.VK_KHR_external_memory_win32" enum="BooleanSupported" expires_after="2020-12-01"> <owner>vmiura@chromium.org</owner> @@ -64338,8 +64414,12 @@ <histogram name="History.ClearBrowsingData.Duration.PartialDeletion" units="ms" expires_after="M83"> -<!-- expires-never: tracked as an important privacy metric. --> - + <obsolete> + Removed May 2020, replaced with more detailed histograms: + History.ClearBrowsingData.Duration.TimeRangeDeletion, + History.ClearBrowsingData.Duration.OriginDeletion, + History.ClearBrowsingData.Duration.FilteredDeletion. + </obsolete> <owner>dullweber@chromium.org</owner> <owner>msramek@chromium.org</owner> <summary> @@ -66344,7 +66424,7 @@ </histogram> <histogram name="ImportantFile.FileDeleteRetryExceededError" - units="PlatformFileError" expires_after="2021-01-19"> + enum="PlatformFileError" expires_after="2021-01-19"> <owner>grt@chromium.org</owner> <owner>xaerox@yandex-team.ru</owner> <summary> @@ -103950,9 +104030,10 @@ expires_after="never"> <!-- expires-never: part of top-line metric (internal: go/chrome-browser-nsm) --> - <owner>dbeam@chromium.org</owner> + <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> <owner>chrome-analysis-team@google.com</owner> + <owner>chrome-desktop-ntp@google.com</owner> <summary> The number of clicks on the static/call-to-action/animated logo on the NTP. @@ -104393,21 +104474,25 @@ </histogram> <histogram name="NewTabPage.Promos.RequestLatency2" units="ms" - expires_after="M82"> - <owner>dbeam@chromium.org</owner> + expires_after="2021-01-01"> + <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> + <owner>chrome-desktop-ntp@google.com</owner> <summary> The time it took until a request from the New Tab page for the middle slot - promo script was served. Recorded only on the local NTP. + promo script was served. Recorded on the local and WebUI NTP. </summary> </histogram> -<histogram name="NewTabPage.Promos.ShownTime" units="ms" expires_after="M82"> - <owner>dbeam@chromium.org</owner> +<histogram name="NewTabPage.Promos.ShownTime" units="ms" + expires_after="2021-01-01"> + <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> + <owner>chrome-desktop-ntp@google.com</owner> <summary> Histogram of the time, in milliseconds since navigation start, it took until - a middle slot promo showed up on the NTP. Recorded only on the local NTP. + a middle slot promo showed up on the NTP. Recorded on the local and WebUI + NTP. </summary> </histogram> @@ -113248,6 +113333,42 @@ </summary> </histogram> +<histogram name="PageLoad.Clients.Ads.AdDensity.MaxPercentByArea" units="%" + expires_after="2020-10-08"> + <owner>justinmron@chromium.org</owner> + <owner>johnidel@chromium.org</owner> + <summary> + The page's maximum ad density by area over its lifecycle as a percent from + 0-100. The density measurement is throttled in page load metrics propagation + from renderer to browser and in the ads page load metrics observer, this may + lead to inaccurate maximum density. Recorded at the time a page is + destroyed. + </summary> +</histogram> + +<histogram name="PageLoad.Clients.Ads.AdDensity.MaxPercentByHeight" units="%" + expires_after="2020-10-08"> + <owner>justinmron@chromium.org</owner> + <owner>johnidel@chromium.org</owner> + <summary> + The page's maximum ad density by height over its lifecycle as a percent from + 0-100. The density measurement is throttled in page load metrics propagation + from renderer to browser and in the ads page load metrics observer, this may + lead to inaccurate maximum density. Recorded at the time a page is + destroyed. + </summary> +</histogram> + +<histogram name="PageLoad.Clients.Ads.AdDensity.Recorded" units="Boolean" + expires_after="2020-10-08"> + <owner>justinmron@chromium.org</owner> + <owner>johnidel@chromium.org</owner> + <summary> + Whether the ad density was recorded on the page for both density by area and + density by height. Recorded at the time a page is destroyed. + </summary> +</histogram> + <histogram name="PageLoad.Clients.Ads.All.Navigations.AdFrameRenavigatedToAd" enum="DidNavigateToAd" expires_after="2018-07-13"> <obsolete> @@ -130704,25 +130825,50 @@ </summary> </histogram> -<histogram name="Printing.ConversionSize.Emf" units="KB" expires_after="M90"> +<histogram name="Printing.ConversionSize.Emf" units="KB" + expires_after="2021-04-30"> <owner>thestig@chromium.org</owner> + <owner>awscreen@chromium.org</owner> <summary> On Windows, the average size of a printed page after converting to EMF. </summary> </histogram> <histogram name="Printing.ConversionSize.EmfWithGdiText" units="KB" - expires_after="M90"> + expires_after="2021-04-30"> <owner>thestig@chromium.org</owner> + <owner>awscreen@chromium.org</owner> <summary> On Windows, the average size of a printed page after converting to EMF with the GDI Text experiment turned on. </summary> </histogram> -<histogram name="Printing.ConversionSize.PostScript2" units="KB" - expires_after="M90"> +<histogram name="Printing.ConversionSize.EmfWithReducedRasterization" + units="KB" expires_after="2021-04-30"> <owner>thestig@chromium.org</owner> + <owner>awscreen@chromium.org</owner> + <summary> + On Windows, the average size of a printed page after converting to EMF with + the reduced rasterization feature turned on. + </summary> +</histogram> + +<histogram name="Printing.ConversionSize.EmfWithReducedRasterizationAndGdiText" + units="KB" expires_after="2021-04-30"> + <owner>thestig@chromium.org</owner> + <owner>awscreen@chromium.org</owner> + <summary> + On Windows, the average size of a printed page after converting to EMF with + the reduced rasterization feature turned on and the GDI Text experiment + turned on. + </summary> +</histogram> + +<histogram name="Printing.ConversionSize.PostScript2" units="KB" + expires_after="2021-04-30"> + <owner>thestig@chromium.org</owner> + <owner>awscreen@chromium.org</owner> <summary> On Windows, the average size of a printed page after converting to level 2 PostScript. @@ -130730,16 +130876,19 @@ </histogram> <histogram name="Printing.ConversionSize.PostScript3" units="KB" - expires_after="M90"> + expires_after="2021-04-30"> <owner>thestig@chromium.org</owner> + <owner>awscreen@chromium.org</owner> <summary> On Windows, the average size of a printed page after converting to level 3 PostScript. </summary> </histogram> -<histogram name="Printing.ConversionSize.Pwg" units="KB" expires_after="M90"> +<histogram name="Printing.ConversionSize.Pwg" units="KB" + expires_after="2021-04-30"> <owner>thestig@chromium.org</owner> + <owner>awscreen@chromium.org</owner> <summary> On desktop, the average size of a printed page after converting to PWG Raster format. @@ -170466,7 +170615,10 @@ expires_after="2020-12-31"> <owner>nburris@chromium.org</owner> <owner>bokan@chromium.org</owner> - <summary>Whether we found multiple matches for a selector.</summary> + <summary> + Whether we found multiple matches for a selector. Recorded when + TextFragmentAnchor finishes searching once the page is loaded. + </summary> </histogram> <histogram name="TextFragmentAnchor.DidScrollIntoView" enum="Boolean" @@ -170475,7 +170627,20 @@ <owner>bokan@chromium.org</owner> <summary> Whether the page did a non-zero scroll in order to scroll the match into - view. Only recorded if we found a match and scrolled it into view. + view. Only recorded if we found a match and scrolled it into view. Recorded + when TextFragmentAnchor finishes searching once the page is loaded. + </summary> +</histogram> + +<histogram name="TextFragmentAnchor.DirectiveLength" units="characters" + expires_after="2020-12-31"> + <owner>nburris@chromium.org</owner> + <owner>bokan@chromium.org</owner> + <summary> + The raw length of the directive in the URL (e.g. spaces count as the three + characters '%20'), regardless of how many text= terms there are. Recorded if + there was a text directive, regardless of whether a match was found. + Recorded when TextFragmentAnchor finishes searching once the page is loaded. </summary> </histogram> @@ -170490,12 +170655,57 @@ </summary> </histogram> +<histogram name="TextFragmentAnchor.EndTextLength" units="characters" + expires_after="2020-12-31"> + <owner>nburris@chromium.org</owner> + <owner>bokan@chromium.org</owner> + <summary> + The length of the end parameter, in the case of a range match. Only recorded + if a match was found. Recorded when TextFragmentAnchor finishes searching + once the page is loaded. + </summary> +</histogram> + +<histogram name="TextFragmentAnchor.ExactTextLength" units="characters" + expires_after="2020-12-31"> + <owner>nburris@chromium.org</owner> + <owner>bokan@chromium.org</owner> + <summary> + The length of the matched text, in the case of an exact match. Only recorded + if a match was found. Recorded when TextFragmentAnchor finishes searching + once the page is loaded. + </summary> +</histogram> + <histogram name="TextFragmentAnchor.MatchRate" units="%" expires_after="2020-12-31"> <owner>nburris@chromium.org</owner> <owner>bokan@chromium.org</owner> <summary> The percentage of selectors for which a match was found in the document. + Recorded when TextFragmentAnchor finishes searching once the page is loaded. + </summary> +</histogram> + +<histogram name="TextFragmentAnchor.Parameters" + enum="TextFragmentAnchorParameters" expires_after="2020-12-31"> + <owner>nburris@chromium.org</owner> + <owner>bokan@chromium.org</owner> + <summary> + An enum indicating which parameters were specified in the text fragment + anchor. Only recorded if a match was found. Recorded when TextFragmentAnchor + finishes searching once the page is loaded. + </summary> +</histogram> + +<histogram name="TextFragmentAnchor.RangeMatchLength" units="characters" + expires_after="2020-12-31"> + <owner>nburris@chromium.org</owner> + <owner>bokan@chromium.org</owner> + <summary> + The length of the matched text, in the case of a range match. Only recorded + if a match was found. Recorded when TextFragmentAnchor finishes searching + once the page is loaded. </summary> </histogram> @@ -170505,7 +170715,8 @@ <owner>bokan@chromium.org</owner> <summary> Whether the scroll into view was cancelled by a user gesture or programmatic - scroll. + scroll. Recorded when TextFragmentAnchor finishes searching once the page is + loaded. </summary> </histogram> @@ -170515,6 +170726,18 @@ <owner>bokan@chromium.org</owner> <summary> The number of selectors in the text fragment anchor if it is present. + Recorded when TextFragmentAnchor finishes searching once the page is loaded. + </summary> +</histogram> + +<histogram name="TextFragmentAnchor.StartTextLength" units="characters" + expires_after="2020-12-31"> + <owner>nburris@chromium.org</owner> + <owner>bokan@chromium.org</owner> + <summary> + The length of the start parameter, in the case of a range match. Only + recorded if a match was found. Recorded when TextFragmentAnchor finishes + searching once the page is loaded. </summary> </histogram> @@ -170525,7 +170748,8 @@ <summary> The time between creating the TextFragmentAnchor (i.e. when it is parsed) and scrolling the target into view. Only recorded if there is a match and we - scroll it into view. + scroll it into view. Recorded when TextFragmentAnchor finishes searching + once the page is loaded. </summary> </histogram> @@ -188508,6 +188732,7 @@ <histogram_suffixes name="AppType" separator="."> <suffix name="ArcApp" label="Android app"/> <suffix name="ChromeApp" label="Chrome app"/> + <suffix name="PluginVmApp" label="Plugin VM app"/> <suffix name="WebApp" label="Web app"/> <affected-histogram name="AppManagement.AppDetailViews"/> </histogram_suffixes> @@ -200386,6 +200611,9 @@ <histogram_suffixes name="PasswordSecurityOrigin" separator="."> <suffix name="InsecureOrigin" label="The recording took place on an insecure origin."/> + <suffix name="MixedForm" + label="The recording took place on a secure origin, but the form action + was an insecure origin."/> <suffix name="SecureOrigin" label="The recording took place on a secure origin."/> <affected-histogram name="PasswordManager.FillingAssistance"/>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index fbc1f7f47..614e090 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -281,6 +281,22 @@ bucket (with a bucket ratio of 1.3). </summary> </metric> + <metric name="MaxAdDensityByArea"> + <summary> + The estimated maximum density of ads on a page by area. Calculated as the + area of ads on the page * 100 / page area. This counts each overlapping + area once, it may be inaccurate due to updates and calculations being + throttled. + </summary> + </metric> + <metric name="MaxAdDensityByHeight"> + <summary> + The estimated maximum density of ads on a page by height. Calculated as + the combined height of ads on the page * 100 / page height. This counts + each overlapping area once, it may be inaccurate due to updates and + calculations being throttled. + </summary> + </metric> <metric name="TotalBytes"> <summary> Amount of network bytes used to load resources on the page. Includes @@ -5422,6 +5438,63 @@ </metric> </event> +<event name="Media.EME.CreateMediaKeys"> + <owner>xhwang@chromium.org</owner> + <owner>media-dev@chromium.org</owner> + <summary> + Event recorded when createMediaKeys() is called as part of Encrypted Media + Extensions (EME) API. + </summary> + <metric name="IsAdFrame" enum="Boolean"> + <summary> + Whether the frame is an ad frame. + </summary> + <aggregation> + <history> + <statistics> + <enumeration/> + </statistics> + </history> + </aggregation> + </metric> + <metric name="IsCrossOrigin" enum="Boolean"> + <summary> + Whether the frame is Cross-Origin to the main frame. + </summary> + <aggregation> + <history> + <statistics> + <enumeration/> + </statistics> + </history> + </aggregation> + </metric> + <metric name="IsTopFrame" enum="Boolean"> + <summary> + Whether the frame is the main frame. + </summary> + <aggregation> + <history> + <statistics> + <enumeration/> + </statistics> + </history> + </aggregation> + </metric> + <metric name="KeySystem" enum="MediaKeySystem"> + <summary> + The key system associated with this call. + </summary> + <aggregation> + <history> + <statistics> + <enumeration/> + </statistics> + </history> + </aggregation> + </metric> +</event> + <event name="Media.EME.RequestMediaKeySystemAccess"> <owner>xhwang@chromium.org</owner> <owner>media-dev@chromium.org</owner> @@ -5465,7 +5538,7 @@ </history> </aggregation> </metric> - <metric name="KeySystem"> + <metric name="KeySystem" enum="MediaKeySystem"> <summary> The key system passed in requestMediaKeySystemAccess() call. </summary>
diff --git a/ui/accessibility/ax_enum_util.cc b/ui/accessibility/ax_enum_util.cc index 69b7f1b3..35bbef5 100644 --- a/ui/accessibility/ax_enum_util.cc +++ b/ui/accessibility/ax_enum_util.cc
@@ -2144,14 +2144,14 @@ return "insert"; case ax::mojom::Command::kMarker: return "marker"; + case ax::mojom::Command::kMoveSelection: + return "moveSelection"; case ax::mojom::Command::kPaste: return "paste"; case ax::mojom::Command::kReplace: return "replace"; case ax::mojom::Command::kSetSelection: return "setSelection"; - case ax::mojom::Command::kShrinkSelection: - return "shrinkSelection"; case ax::mojom::Command::kType: return "type"; } @@ -2176,14 +2176,14 @@ return ax::mojom::Command::kInsert; if (0 == strcmp(command, "marker")) return ax::mojom::Command::kMarker; + if (0 == strcmp(command, "moveSelection")) + return ax::mojom::Command::kMoveSelection; if (0 == strcmp(command, "paste")) return ax::mojom::Command::kPaste; if (0 == strcmp(command, "replace")) return ax::mojom::Command::kReplace; if (0 == strcmp(command, "setSelection")) return ax::mojom::Command::kSetSelection; - if (0 == strcmp(command, "shrinkSelection")) - return ax::mojom::Command::kShrinkSelection; if (0 == strcmp(command, "type")) return ax::mojom::Command::kType;
diff --git a/ui/accessibility/ax_enums.mojom b/ui/accessibility/ax_enums.mojom index aaad6fe..a5c0fc5 100644 --- a/ui/accessibility/ax_enums.mojom +++ b/ui/accessibility/ax_enums.mojom
@@ -846,14 +846,14 @@ kCut, kDelete, kDictate, - kExtendSelection, + kExtendSelection, // The existing selection has been extended or shrunk. kFormat, // The text attributes, such as font size, have changed. kInsert, kMarker, // A document marker has been added or removed. + kMoveSelection, // The selection has been moved by a specific granularity. kPaste, kReplace, kSetSelection, // A completely new selection has been set. - kShrinkSelection, kType, kNone = kType };
diff --git a/ui/aura/window_event_dispatcher.cc b/ui/aura/window_event_dispatcher.cc index 4cefcf7..47ed7c1 100644 --- a/ui/aura/window_event_dispatcher.cc +++ b/ui/aura/window_event_dispatcher.cc
@@ -195,8 +195,11 @@ } void WindowEventDispatcher::HoldPointerMoves() { - if (!move_hold_count_) + if (!move_hold_count_) { + // |synthesize_mouse_events_| is explicitly not changed. It is handled and + // reset in ReleasePointerMoves. held_event_factory_.InvalidateWeakPtrs(); + } ++move_hold_count_; TRACE_EVENT_ASYNC_BEGIN0("ui", "WindowEventDispatcher::HoldPointerMoves", this); @@ -206,6 +209,11 @@ --move_hold_count_; DCHECK_GE(move_hold_count_, 0); if (!move_hold_count_) { + // HoldPointerMoves cancels the pending synthesized mouse move if any. + // So ReleasePointerMoves should ensure that |synthesize_mouse_move_| + // resets. Otherwise, PostSynthesizeMouseMove is blocked indefintely. + const bool pending_synthesize_mouse_move = synthesize_mouse_move_; + synthesize_mouse_move_ = false; if (held_move_event_) { // We don't want to call DispatchHeldEvents directly, because this might // be called from a deep stack while another event, in which case @@ -220,6 +228,11 @@ } else { if (did_dispatch_held_move_event_callback_) std::move(did_dispatch_held_move_event_callback_).Run(); + if (pending_synthesize_mouse_move) { + // Schedule a synthesized mouse move event when there is no held mouse + // move and we should generate one. + PostSynthesizeMouseMove(); + } } } TRACE_EVENT_ASYNC_END0("ui", "WindowEventDispatcher::HoldPointerMoves", this); @@ -313,10 +326,7 @@ // coordinate system. if (!target) target = window(); - ui::MouseEvent translated_event(event, - target, - mouse_moved_handler_, - type, + ui::MouseEvent translated_event(event, target, mouse_moved_handler_, type, event.flags() | ui::EF_IS_SYNTHESIZED); return DispatchEvent(mouse_moved_handler_, &translated_event); } @@ -694,8 +704,10 @@ Window::ConvertRectToTarget(window->parent(), host_->window(), &new_bounds_in_root); gfx::Point last_mouse_location = GetLastMouseLocationInRoot(); - if (old_bounds_in_root.Contains(last_mouse_location) != - new_bounds_in_root.Contains(last_mouse_location)) { + if ((old_bounds_in_root.Contains(last_mouse_location) != + new_bounds_in_root.Contains(last_mouse_location)) || + (new_bounds_in_root.Contains(last_mouse_location) && + new_bounds_in_root.origin() != old_bounds_in_root.origin())) { PostSynthesizeMouseMove(); } } @@ -875,8 +887,7 @@ // We allow synthesized mouse exit events through even if mouse events are // disabled. This ensures that hover state, etc on controls like buttons is // cleared. - if (cursor_client && - !cursor_client->IsMouseEventsEnabled() && + if (cursor_client && !cursor_client->IsMouseEventsEnabled() && (event->flags() & ui::EF_IS_SYNTHESIZED) && (event->type() != ui::ET_MOUSE_EXITED)) { event->SetHandled();
diff --git a/ui/aura/window_event_dispatcher_unittest.cc b/ui/aura/window_event_dispatcher_unittest.cc index 1fdc873..ef8dcda8 100644 --- a/ui/aura/window_event_dispatcher_unittest.cc +++ b/ui/aura/window_event_dispatcher_unittest.cc
@@ -56,11 +56,8 @@ class NonClientDelegate : public test::TestWindowDelegate { public: NonClientDelegate() - : non_client_count_(0), - mouse_event_count_(0), - mouse_event_flags_(0x0) { - } - ~NonClientDelegate() override {} + : non_client_count_(0), mouse_event_count_(0), mouse_event_flags_(0x0) {} + ~NonClientDelegate() override = default; int non_client_count() const { return non_client_count_; } const gfx::Point& non_client_location() const { return non_client_location_; } @@ -260,9 +257,8 @@ EXPECT_EQ("100,100", root.location().ToString()); EXPECT_EQ("100,100", root.root_location().ToString()); - ui::MouseEvent translated_event( - root, static_cast<Window*>(root_window()), w1.get(), - ui::ET_MOUSE_ENTERED, root.flags()); + ui::MouseEvent translated_event(root, static_cast<Window*>(root_window()), + w1.get(), ui::ET_MOUSE_ENTERED, root.flags()); EXPECT_EQ("50,50", translated_event.location().ToString()); EXPECT_EQ("100,100", translated_event.root_location().ToString()); } @@ -275,8 +271,7 @@ static const int kLockWindowId = 200; explicit TestEventClient(Window* root_window) - : root_window_(root_window), - lock_(false) { + : root_window_(root_window), lock_(false) { client::SetEventClient(root_window_, this); Window* lock_window = test::CreateTestWindowWithBounds(root_window_->bounds(), root_window_); @@ -289,12 +284,8 @@ // Starts/stops locking. Locking prevents windows other than those inside // the lock container from receiving events, getting focus etc. - void Lock() { - lock_ = true; - } - void Unlock() { - lock_ = false; - } + void Lock() { lock_ = true; } + void Unlock() { lock_ = false; } Window* GetLockWindow() { return const_cast<Window*>( @@ -310,9 +301,9 @@ private: // Overridden from client::EventClient: bool CanProcessEventsWithinSubtree(const Window* window) const override { - return lock_ ? - window->Contains(GetLockWindow()) || GetLockWindow()->Contains(window) : - true; + return lock_ ? window->Contains(GetLockWindow()) || + GetLockWindow()->Contains(window) + : true; } ui::EventTarget* GetToplevelEventTarget() override { return NULL; } @@ -464,24 +455,14 @@ w1->SetBounds(gfx::Rect(20, 20, 40, 40)); // A scroll event on the root-window itself is dispatched. - ui::ScrollEvent scroll1(ui::ET_SCROLL, - gfx::Point(10, 10), - now, - 0, - 0, -10, - 0, -10, - 2); + ui::ScrollEvent scroll1(ui::ET_SCROLL, gfx::Point(10, 10), now, 0, 0, -10, 0, + -10, 2); DispatchEventUsingWindowDispatcher(&scroll1); EXPECT_EQ(1, handler.num_scroll_events()); // Scroll event on a window should be dispatched properly. - ui::ScrollEvent scroll2(ui::ET_SCROLL, - gfx::Point(25, 30), - now, - 0, - -10, 0, - -10, 0, - 2); + ui::ScrollEvent scroll2(ui::ET_SCROLL, gfx::Point(25, 30), now, 0, -10, 0, + -10, 0, 2); DispatchEventUsingWindowDispatcher(&scroll2); EXPECT_EQ(2, handler.num_scroll_events()); root_window()->RemovePreTargetHandler(&handler); @@ -498,8 +479,7 @@ EventFilterRecorder() : wait_until_event_(ui::ET_UNKNOWN), - last_touch_may_cause_scrolling_(false) { - } + last_touch_may_cause_scrolling_(false) {} const Events& events() const { return events_; } @@ -691,7 +671,8 @@ RunAllPendingInMessageLoop(); // Necessitated by RepostEvent(). // Mouse moves/enters may be generated. We only care about a pressed. EXPECT_TRUE(EventTypesToString(recorder.events()).find("MOUSE_PRESSED") != - std::string::npos) << EventTypesToString(recorder.events()); + std::string::npos) + << EventTypesToString(recorder.events()); window->RemovePreTargetHandler(&recorder); } @@ -989,10 +970,8 @@ public: HoldPointerOnScrollHandler(WindowEventDispatcher* dispatcher, EventFilterRecorder* filter) - : dispatcher_(dispatcher), - filter_(filter), - holding_moves_(false) {} - ~HoldPointerOnScrollHandler() override {} + : dispatcher_(dispatcher), filter_(filter), holding_moves_(false) {} + ~HoldPointerOnScrollHandler() override = default; private: // ui::test::TestEventHandler: @@ -1026,9 +1005,8 @@ window->AddPreTargetHandler(&handler); ui::test::EventGenerator generator(root_window()); - generator.GestureScrollSequence( - gfx::Point(60, 60), gfx::Point(10, 60), - base::TimeDelta::FromMilliseconds(100), 25); + generator.GestureScrollSequence(gfx::Point(60, 60), gfx::Point(10, 60), + base::TimeDelta::FromMilliseconds(100), 25); // |handler| will have reset |filter| and started holding the touch-move // events when scrolling started. At the end of the scroll (i.e. upon @@ -1212,12 +1190,36 @@ EXPECT_EQ(ui::EF_IS_SYNTHESIZED, recorder.mouse_event_flags().back()); recorder.Reset(); + // Update the window bounds so that cursor is back inside the window. + // The origin of window bounds change so this should trigger a synthetic + // event. + gfx::Rect bounds2(5, 5, 100, 100); + window->SetBounds(bounds2); + RunAllPendingInMessageLoop(); + ASSERT_FALSE(recorder.events().empty()); + ASSERT_FALSE(recorder.mouse_event_flags().empty()); + EXPECT_EQ(ui::ET_MOUSE_MOVED, recorder.events().back()); + EXPECT_EQ(ui::EF_IS_SYNTHESIZED, recorder.mouse_event_flags().back()); + recorder.Reset(); + + // Update the window bounds so that cursor is still inside the window. + // The origin of window bounds doesn't change so this should not trigger + // a synthetic event. + gfx::Rect bounds3(5, 5, 200, 200); + window->SetBounds(bounds3); + RunAllPendingInMessageLoop(); + EXPECT_TRUE(recorder.events().empty()); + recorder.Reset(); + // Set window to ignore events. window->SetEventTargetingPolicy(EventTargetingPolicy::kNone); - // Update the window bounds so that cursor is back inside the window. - // This should not trigger a synthetic event. - gfx::Rect bounds2(5, 5, 100, 100); + // Update the window bounds so that cursor is from outside to inside the + // window. This should not trigger a synthetic event. + window->SetBounds(bounds1); + RunAllPendingInMessageLoop(); + EXPECT_TRUE(recorder.events().empty()); + recorder.Reset(); window->SetBounds(bounds2); RunAllPendingInMessageLoop(); EXPECT_TRUE(recorder.events().empty()); @@ -1348,9 +1350,8 @@ class DeletingEventFilter : public ui::EventHandler { public: - DeletingEventFilter() - : delete_during_pre_handle_(false) {} - ~DeletingEventFilter() override {} + DeletingEventFilter() : delete_during_pre_handle_(false) {} + ~DeletingEventFilter() override = default; void Reset(bool delete_during_pre_handle) { delete_during_pre_handle_ = delete_during_pre_handle; @@ -1376,10 +1377,8 @@ class DeletingWindowDelegate : public test::TestWindowDelegate { public: DeletingWindowDelegate() - : window_(NULL), - delete_during_handle_(false), - got_event_(false) {} - ~DeletingWindowDelegate() override {} + : window_(nullptr), delete_during_handle_(false), got_event_(false) {} + ~DeletingWindowDelegate() override = default; void Reset(Window* window, bool delete_during_handle) { window_ = window; @@ -1563,16 +1562,13 @@ ui::GestureEventDetails details(ui::ET_GESTURE_TAP_DOWN); gfx::Point point(10, 10); - ui::GestureEvent event(point.x(), - point.y(), - 0, - ui::EventTimeForNow(), + ui::GestureEvent event(point.x(), point.y(), 0, ui::EventTimeForNow(), details); host()->dispatcher()->RepostEvent(&event); RunAllPendingInMessageLoop(); // TODO(rbyers): Currently disabled - crbug.com/170987 EXPECT_FALSE(EventTypesToString(recorder.events()).find("GESTURE_TAP_DOWN") != - std::string::npos); + std::string::npos); recorder.Reset(); root_window()->RemovePreTargetHandler(&recorder); } @@ -1636,12 +1632,13 @@ TEST_F(WindowEventDispatcherTest, GestureRepostEventOrder) { // Expected events at the end for the repost_target window defined below. const char kExpectedTargetEvents[] = - // TODO)(rbyers): Gesture event reposting is disabled - crbug.com/279039. - // "GESTURE_BEGIN GESTURE_TAP_DOWN " - "TOUCH_PRESSED GESTURE_BEGIN GESTURE_TAP_DOWN TOUCH_MOVED " - "GESTURE_TAP_CANCEL GESTURE_SCROLL_BEGIN GESTURE_SCROLL_UPDATE TOUCH_MOVED " - "GESTURE_SCROLL_UPDATE TOUCH_MOVED GESTURE_SCROLL_UPDATE TOUCH_RELEASED " - "GESTURE_SCROLL_END GESTURE_END"; + // TODO)(rbyers): Gesture event reposting is disabled - crbug.com/279039. + // "GESTURE_BEGIN GESTURE_TAP_DOWN " + "TOUCH_PRESSED GESTURE_BEGIN GESTURE_TAP_DOWN TOUCH_MOVED " + "GESTURE_TAP_CANCEL GESTURE_SCROLL_BEGIN GESTURE_SCROLL_UPDATE " + "TOUCH_MOVED " + "GESTURE_SCROLL_UPDATE TOUCH_MOVED GESTURE_SCROLL_UPDATE TOUCH_RELEASED " + "GESTURE_SCROLL_END GESTURE_END"; // We create two windows. // The first window (repost_source) is the one to which the initial tap // gesture is sent. It reposts this event to the second window @@ -1667,10 +1664,8 @@ ui::test::EventGenerator scroll_generator(root_window(), repost_target.get()); scroll_generator.GestureScrollSequence( - gfx::Point(80, 80), - gfx::Point(100, 100), - base::TimeDelta::FromMilliseconds(100), - 3); + gfx::Point(80, 80), gfx::Point(100, 100), + base::TimeDelta::FromMilliseconds(100), 3); RunAllPendingInMessageLoop(); int tap_down_count = 0; @@ -1831,9 +1826,7 @@ public: ValidRootDuringDestructionWindowObserver(bool* got_destroying, bool* has_valid_root) - : got_destroying_(got_destroying), - has_valid_root_(has_valid_root) { - } + : got_destroying_(got_destroying), has_valid_root_(has_valid_root) {} // WindowObserver: void OnWindowDestroying(aura::Window* window) override { @@ -1875,9 +1868,8 @@ class DontResetHeldEventWindowDelegate : public test::TestWindowDelegate { public: explicit DontResetHeldEventWindowDelegate(aura::Window* root) - : root_(root), - mouse_event_count_(0) {} - ~DontResetHeldEventWindowDelegate() override {} + : root_(root), mouse_event_count_(0) {} + ~DontResetHeldEventWindowDelegate() override = default; int mouse_event_count() const { return mouse_event_count_; } @@ -1929,15 +1921,11 @@ namespace { // See description above DeleteHostFromHeldMouseEvent for details. -class DeleteHostFromHeldMouseEventDelegate - : public test::TestWindowDelegate { +class DeleteHostFromHeldMouseEventDelegate : public test::TestWindowDelegate { public: explicit DeleteHostFromHeldMouseEventDelegate(WindowTreeHost* host) - : host_(host), - got_mouse_event_(false), - got_destroy_(false) { - } - ~DeleteHostFromHeldMouseEventDelegate() override {} + : host_(host), got_mouse_event_(false), got_destroy_(false) {} + ~DeleteHostFromHeldMouseEventDelegate() override = default; bool got_mouse_event() const { return got_mouse_event_; } bool got_destroy() const { return got_destroy_; } @@ -2135,10 +2123,11 @@ window2->SetCapture(); - EXPECT_EQ("TOUCH_PRESSED GESTURE_BEGIN GESTURE_TAP_DOWN TOUCH_MOVED " - "GESTURE_TAP_CANCEL GESTURE_SCROLL_BEGIN GESTURE_SCROLL_UPDATE " - "TOUCH_CANCELLED GESTURE_SCROLL_END GESTURE_END", - EventTypesToString(recorder1.events())); + EXPECT_EQ( + "TOUCH_PRESSED GESTURE_BEGIN GESTURE_TAP_DOWN TOUCH_MOVED " + "GESTURE_TAP_CANCEL GESTURE_SCROLL_BEGIN GESTURE_SCROLL_UPDATE " + "TOUCH_CANCELLED GESTURE_SCROLL_END GESTURE_END", + EventTypesToString(recorder1.events())); EXPECT_TRUE(recorder2.events().empty()); @@ -2161,9 +2150,7 @@ capture_window_->SetCapture(); } - void reset() { - capture_window_.reset(); - } + void reset() { capture_window_.reset(); } void OnCaptureLost() override { capture_window_.reset(); } @@ -2180,7 +2167,7 @@ DISALLOW_COPY_AND_ASSIGN(CaptureWindowTracker); }; -} +} // namespace // Verifies handling loss of capture by the capture window being hidden. TEST_F(WindowEventDispatcherTest, CaptureWindowHidden) { @@ -2418,9 +2405,8 @@ window->AddPreTargetHandler(&handler); ui::test::EventGenerator generator(root_window()); - generator.GestureScrollSequence( - gfx::Point(120, 120), gfx::Point(20, 120), - base::TimeDelta::FromMilliseconds(100), 25); + generator.GestureScrollSequence(gfx::Point(120, 120), gfx::Point(20, 120), + base::TimeDelta::FromMilliseconds(100), 25); // |handler| will have reset |filter| and started holding the touch-move // events when scrolling started. At the end of the scroll (i.e. upon @@ -2533,19 +2519,16 @@ TEST_F(WindowEventDispatcherTest, SynthesizedLocatedEvent) { ui::test::EventGenerator generator(root_window()); generator.MoveMouseTo(10, 10); - EXPECT_EQ("10,10", - Env::GetInstance()->last_mouse_location().ToString()); + EXPECT_EQ("10,10", Env::GetInstance()->last_mouse_location().ToString()); // Synthesized event should not update the mouse location. ui::MouseEvent mouseev(ui::ET_MOUSE_MOVED, gfx::Point(), gfx::Point(), ui::EventTimeForNow(), ui::EF_IS_SYNTHESIZED, 0); generator.Dispatch(&mouseev); - EXPECT_EQ("10,10", - Env::GetInstance()->last_mouse_location().ToString()); + EXPECT_EQ("10,10", Env::GetInstance()->last_mouse_location().ToString()); generator.MoveMouseTo(0, 0); - EXPECT_EQ("0,0", - Env::GetInstance()->last_mouse_location().ToString()); + EXPECT_EQ("0,0", Env::GetInstance()->last_mouse_location().ToString()); // Make sure the location gets updated when a syntheiszed enter // event destroyed the window. @@ -2557,8 +2540,7 @@ generator.MoveMouseTo(100, 100); EXPECT_FALSE(delegate.has_window()); - EXPECT_EQ("100,100", - Env::GetInstance()->last_mouse_location().ToString()); + EXPECT_EQ("100,100", Env::GetInstance()->last_mouse_location().ToString()); } // Tests that the window which has capture can get destroyed as a result of @@ -2585,9 +2567,8 @@ class StaticFocusClient : public client::FocusClient { public: - explicit StaticFocusClient(Window* focused) - : focused_(focused) {} - ~StaticFocusClient() override {} + explicit StaticFocusClient(Window* focused) : focused_(focused) {} + ~StaticFocusClient() override = default; private: // client::FocusClient: @@ -2623,11 +2604,11 @@ class DispatchEventHandler : public ui::EventHandler { public: explicit DispatchEventHandler(Window* target) - : target_(target), - dispatched_(false) {} - ~DispatchEventHandler() override {} + : target_(target), dispatched_(false) {} + ~DispatchEventHandler() override = default; bool dispatched() const { return dispatched_; } + private: // ui::EventHandler: void OnMouseEvent(ui::MouseEvent* mouse) override { @@ -2655,9 +2636,8 @@ class MoveWindowHandler : public ui::EventHandler { public: MoveWindowHandler(Window* window, Window* root_window) - : window_to_move_(window), - root_window_to_move_to_(root_window) {} - ~MoveWindowHandler() override {} + : window_to_move_(window), root_window_to_move_to_(root_window) {} + ~MoveWindowHandler() override = default; private: // ui::EventHandler: @@ -2836,9 +2816,8 @@ AsyncWindowDelegate(WindowEventDispatcher* dispatcher) : dispatcher_(dispatcher), window_(nullptr) {} - void set_window(Window* window) { - window_ = window; - } + void set_window(Window* window) { window_ = window; } + private: void OnTouchEvent(ui::TouchEvent* event) override { // Convert touch event back to root window coordinates.
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn index 37f1b4df..547ecab 100644 --- a/ui/base/BUILD.gn +++ b/ui/base/BUILD.gn
@@ -507,8 +507,8 @@ if (!is_chromeos) { # These Aura X11 files aren't used on ChromeOS. sources += [ - "dragdrop/os_exchange_data_provider_aurax11.cc", - "dragdrop/os_exchange_data_provider_aurax11.h", + "dragdrop/os_exchange_data_provider_x11.cc", + "dragdrop/os_exchange_data_provider_x11.h", ] } } @@ -1170,7 +1170,7 @@ if (use_x11) { sources += [ - "dragdrop/os_exchange_data_provider_aurax11_unittest.cc", + "dragdrop/os_exchange_data_provider_x11_unittest.cc", "x/selection_requestor_unittest.cc", ] }
diff --git a/ui/base/dragdrop/os_exchange_data_provider_aurax11.h b/ui/base/dragdrop/os_exchange_data_provider_aurax11.h deleted file mode 100644 index 56a0564..0000000 --- a/ui/base/dragdrop/os_exchange_data_provider_aurax11.h +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright (c) 2012 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 UI_BASE_DRAGDROP_OS_EXCHANGE_DATA_PROVIDER_AURAX11_H_ -#define UI_BASE_DRAGDROP_OS_EXCHANGE_DATA_PROVIDER_AURAX11_H_ - -#include "ui/base/x/x11_os_exchange_data_provider.h" -#include "ui/events/platform/x11/x11_event_source.h" - -namespace ui { - -// OSExchangeDataProvider implementation for aura on linux. -class UI_BASE_EXPORT OSExchangeDataProviderAuraX11 - : public XOSExchangeDataProvider, - public XEventDispatcher { - public: - // |x_window| is the window the cursor is over, and |selection| is the set of - // data being offered. - OSExchangeDataProviderAuraX11(XID x_window, - const SelectionFormatMap& selection); - - // Creates a Provider for sending drag information. This creates its own, - // hidden X11 window to own send data. - OSExchangeDataProviderAuraX11(); - - ~OSExchangeDataProviderAuraX11() override; - - OSExchangeDataProviderAuraX11(const OSExchangeDataProviderAuraX11&) = delete; - OSExchangeDataProviderAuraX11& operator=( - const OSExchangeDataProviderAuraX11&) = delete; - - // OSExchangeDataProvider: - std::unique_ptr<OSExchangeDataProvider> Clone() const override; - void SetFileContents(const base::FilePath& filename, - const std::string& file_contents) override; - - // XEventDispatcher: - bool DispatchXEvent(XEvent* xev) override; - - private: - friend class OSExchangeDataProviderAuraX11Test; -}; - -} // namespace ui - -#endif // UI_BASE_DRAGDROP_OS_EXCHANGE_DATA_PROVIDER_AURAX11_H_
diff --git a/ui/base/dragdrop/os_exchange_data_provider_factory.cc b/ui/base/dragdrop/os_exchange_data_provider_factory.cc index 724f27f8..52efa7c 100644 --- a/ui/base/dragdrop/os_exchange_data_provider_factory.cc +++ b/ui/base/dragdrop/os_exchange_data_provider_factory.cc
@@ -8,7 +8,7 @@ #include "build/build_config.h" #if defined(USE_X11) -#include "ui/base/dragdrop/os_exchange_data_provider_aurax11.h" +#include "ui/base/dragdrop/os_exchange_data_provider_x11.h" #elif defined(OS_LINUX) #if defined(USE_OZONE) #include "ui/base/dragdrop/os_exchange_data_provider_factory_ozone.h" @@ -26,7 +26,7 @@ std::unique_ptr<OSExchangeDataProvider> OSExchangeDataProviderFactory::CreateProvider() { #if defined(USE_X11) - return std::make_unique<OSExchangeDataProviderAuraX11>(); + return std::make_unique<OSExchangeDataProviderX11>(); #elif defined(OS_LINUX) #if defined(USE_OZONE) // The instance can be nullptr in tests that do not instantiate the platform,
diff --git a/ui/base/dragdrop/os_exchange_data_provider_aurax11.cc b/ui/base/dragdrop/os_exchange_data_provider_x11.cc similarity index 81% rename from ui/base/dragdrop/os_exchange_data_provider_aurax11.cc rename to ui/base/dragdrop/os_exchange_data_provider_x11.cc index dbcb9d5..f336655 100644 --- a/ui/base/dragdrop/os_exchange_data_provider_aurax11.cc +++ b/ui/base/dragdrop/os_exchange_data_provider_x11.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ui/base/dragdrop/os_exchange_data_provider_aurax11.h" +#include "ui/base/dragdrop/os_exchange_data_provider_x11.h" #include <utility> @@ -14,29 +14,29 @@ namespace ui { -OSExchangeDataProviderAuraX11::OSExchangeDataProviderAuraX11( +OSExchangeDataProviderX11::OSExchangeDataProviderX11( XID x_window, const SelectionFormatMap& selection) : XOSExchangeDataProvider(x_window, selection) {} -OSExchangeDataProviderAuraX11::OSExchangeDataProviderAuraX11() { +OSExchangeDataProviderX11::OSExchangeDataProviderX11() { X11EventSource::GetInstance()->AddXEventDispatcher(this); } -OSExchangeDataProviderAuraX11::~OSExchangeDataProviderAuraX11() { +OSExchangeDataProviderX11::~OSExchangeDataProviderX11() { if (own_window()) X11EventSource::GetInstance()->RemoveXEventDispatcher(this); } -std::unique_ptr<OSExchangeDataProvider> OSExchangeDataProviderAuraX11::Clone() +std::unique_ptr<OSExchangeDataProvider> OSExchangeDataProviderX11::Clone() const { - std::unique_ptr<OSExchangeDataProviderAuraX11> ret( - new OSExchangeDataProviderAuraX11()); + std::unique_ptr<OSExchangeDataProviderX11> ret( + new OSExchangeDataProviderX11()); ret->set_format_map(format_map()); return std::move(ret); } -void OSExchangeDataProviderAuraX11::SetFileContents( +void OSExchangeDataProviderX11::SetFileContents( const base::FilePath& filename, const std::string& file_contents) { DCHECK(!filename.empty()); @@ -69,7 +69,7 @@ base::RefCountedString::TakeString(&file_contents_copy))); } -bool OSExchangeDataProviderAuraX11::DispatchXEvent(XEvent* xev) { +bool OSExchangeDataProviderX11::DispatchXEvent(XEvent* xev) { if (xev->type == SelectionRequest && xev->xany.window == x_window()) { selection_owner().OnSelectionRequest(*xev); return true;
diff --git a/ui/base/dragdrop/os_exchange_data_provider_x11.h b/ui/base/dragdrop/os_exchange_data_provider_x11.h new file mode 100644 index 0000000..980b384c --- /dev/null +++ b/ui/base/dragdrop/os_exchange_data_provider_x11.h
@@ -0,0 +1,45 @@ +// Copyright (c) 2012 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 UI_BASE_DRAGDROP_OS_EXCHANGE_DATA_PROVIDER_X11_H_ +#define UI_BASE_DRAGDROP_OS_EXCHANGE_DATA_PROVIDER_X11_H_ + +#include "ui/base/x/x11_os_exchange_data_provider.h" +#include "ui/events/platform/x11/x11_event_source.h" + +namespace ui { + +// OSExchangeDataProvider implementation for x11 linux. +class UI_BASE_EXPORT OSExchangeDataProviderX11 : public XOSExchangeDataProvider, + public XEventDispatcher { + public: + // |x_window| is the window the cursor is over, and |selection| is the set of + // data being offered. + OSExchangeDataProviderX11(XID x_window, const SelectionFormatMap& selection); + + // Creates a Provider for sending drag information. This creates its own, + // hidden X11 window to own send data. + OSExchangeDataProviderX11(); + + ~OSExchangeDataProviderX11() override; + + OSExchangeDataProviderX11(const OSExchangeDataProviderX11&) = delete; + OSExchangeDataProviderX11& operator=(const OSExchangeDataProviderX11&) = + delete; + + // OSExchangeDataProvider: + std::unique_ptr<OSExchangeDataProvider> Clone() const override; + void SetFileContents(const base::FilePath& filename, + const std::string& file_contents) override; + + // XEventDispatcher: + bool DispatchXEvent(XEvent* xev) override; + + private: + friend class OSExchangeDataProviderX11Test; +}; + +} // namespace ui + +#endif // UI_BASE_DRAGDROP_OS_EXCHANGE_DATA_PROVIDER_X11_H_
diff --git a/ui/base/dragdrop/os_exchange_data_provider_aurax11_unittest.cc b/ui/base/dragdrop/os_exchange_data_provider_x11_unittest.cc similarity index 85% rename from ui/base/dragdrop/os_exchange_data_provider_aurax11_unittest.cc rename to ui/base/dragdrop/os_exchange_data_provider_x11_unittest.cc index 6f190a1..82f9c71a 100644 --- a/ui/base/dragdrop/os_exchange_data_provider_aurax11_unittest.cc +++ b/ui/base/dragdrop/os_exchange_data_provider_x11_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ui/base/dragdrop/os_exchange_data_provider_aurax11.h" +#include "ui/base/dragdrop/os_exchange_data_provider_x11.h" #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" @@ -21,9 +21,9 @@ namespace ui { -class OSExchangeDataProviderAuraX11Test : public testing::Test { +class OSExchangeDataProviderX11Test : public testing::Test { public: - OSExchangeDataProviderAuraX11Test() + OSExchangeDataProviderX11Test() : task_environment_(base::test::TaskEnvironment::MainThreadType::UI), event_source(gfx::GetXDisplay()) {} @@ -38,10 +38,10 @@ protected: base::test::TaskEnvironment task_environment_; X11EventSource event_source; - OSExchangeDataProviderAuraX11 provider; + OSExchangeDataProviderX11 provider; }; -TEST_F(OSExchangeDataProviderAuraX11Test, MozillaURL) { +TEST_F(OSExchangeDataProviderX11Test, MozillaURL) { // Check that we can get titled entries. provider.SetURL(GURL(kGoogleURL), base::ASCIIToUTF16(kGoogleTitle)); { @@ -65,7 +65,7 @@ } } -TEST_F(OSExchangeDataProviderAuraX11Test, FilesArentURLs) { +TEST_F(OSExchangeDataProviderX11Test, FilesArentURLs) { AddURLList(kFileURL); EXPECT_TRUE(provider.HasFile()); @@ -73,7 +73,7 @@ EXPECT_FALSE(provider.HasURL(ui::DO_NOT_CONVERT_FILENAMES)); } -TEST_F(OSExchangeDataProviderAuraX11Test, HTTPURLsArentFiles) { +TEST_F(OSExchangeDataProviderX11Test, HTTPURLsArentFiles) { AddURLList(kGoogleURL); EXPECT_FALSE(provider.HasFile()); @@ -81,7 +81,7 @@ EXPECT_TRUE(provider.HasURL(ui::DO_NOT_CONVERT_FILENAMES)); } -TEST_F(OSExchangeDataProviderAuraX11Test, URIListWithBoth) { +TEST_F(OSExchangeDataProviderX11Test, URIListWithBoth) { AddURLList("file:///home/user/file.txt\nhttp://www.google.com"); EXPECT_TRUE(provider.HasFile()); @@ -103,7 +103,7 @@ EXPECT_EQ(kGoogleURL, out_gurl.spec()); } -TEST_F(OSExchangeDataProviderAuraX11Test, OnlyStringURLIsUnfiltered) { +TEST_F(OSExchangeDataProviderX11Test, OnlyStringURLIsUnfiltered) { const base::string16 file_url = base::UTF8ToUTF16(kFileURL); provider.SetString(file_url); @@ -111,7 +111,7 @@ EXPECT_FALSE(provider.HasURL(ui::DO_NOT_CONVERT_FILENAMES)); } -TEST_F(OSExchangeDataProviderAuraX11Test, StringAndURIListFilterString) { +TEST_F(OSExchangeDataProviderX11Test, StringAndURIListFilterString) { const base::string16 file_url = base::UTF8ToUTF16(kFileURL); provider.SetString(file_url); AddURLList(kFileURL);
diff --git a/ui/base/x/x11_os_exchange_data_provider.h b/ui/base/x/x11_os_exchange_data_provider.h index 12cc70b..6763eb0 100644 --- a/ui/base/x/x11_os_exchange_data_provider.h +++ b/ui/base/x/x11_os_exchange_data_provider.h
@@ -23,7 +23,7 @@ namespace ui { -class OSExchangeDataProviderAuraX11Test; +class OSExchangeDataProviderX11Test; // Generic OSExchangeDataProvider implementation for X11. Lacks the event // handling; the subclass should listen for SelectionRequest X events and @@ -93,8 +93,8 @@ gfx::Vector2d GetDragImageOffset() const override; protected: - friend class OSExchangeDataProviderAuraX11Test; - typedef std::map<ClipboardFormatType, base::Pickle> PickleData; + friend class OSExchangeDataProviderX11Test; + using PickleData = std::map<ClipboardFormatType, base::Pickle>; bool own_window() const { return own_window_; } XID x_window() const { return x_window_; }
diff --git a/ui/base/x/x11_util.cc b/ui/base/x/x11_util.cc index 4d0238a..4f35d362 100644 --- a/ui/base/x/x11_util.cc +++ b/ui/base/x/x11_util.cc
@@ -13,6 +13,7 @@ #include <sys/shm.h> #include <bitset> +#include <limits> #include <list> #include <map> #include <utility> @@ -57,6 +58,7 @@ #include "ui/gfx/image/image_skia_rep.h" #include "ui/gfx/skia_util.h" #include "ui/gfx/switches.h" +#include "ui/gfx/x/connection.h" #include "ui/gfx/x/x11.h" #include "ui/gfx/x/x11_atom_cache.h" #include "ui/gfx/x/x11_error_tracker.h" @@ -96,12 +98,11 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&x11::LogErrorEventDescription, *e)); } else { - LOG(ERROR) - << "X error received: " - << "serial " << e->serial << ", " - << "error_code " << static_cast<int>(e->error_code) << ", " - << "request_code " << static_cast<int>(e->request_code) << ", " - << "minor_code " << static_cast<int>(e->minor_code); + LOG(ERROR) << "X error received: " + << "serial " << e->serial << ", " + << "error_code " << static_cast<int>(e->error_code) << ", " + << "request_code " << static_cast<int>(e->request_code) << ", " + << "minor_code " << static_cast<int>(e->minor_code); } return 0; } @@ -112,18 +113,47 @@ _exit(1); } -// Note: The caller should free the resulting value data. -bool GetProperty(XID window, const std::string& property_name, long max_length, - XAtom* type, int* format, unsigned long* num_items, - unsigned char** property) { - XAtom property_atom = gfx::GetAtom(property_name.c_str()); - unsigned long remaining_bytes = 0; - return XGetWindowProperty(gfx::GetXDisplay(), window, property_atom, - 0, // offset into property data to read - max_length, // max length to get - x11::False, // deleted - AnyPropertyType, type, format, num_items, - &remaining_bytes, property); +template <typename T> +bool GetProperty(XID window, const std::string& property_name, T* value) { + static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4, ""); + auto response = x11::Connection::Get() + ->GetProperty({ + .window = static_cast<x11::Window>(window), + .property = static_cast<x11::Atom>( + gfx::GetAtom(property_name.c_str())), + .long_length = std::max<uint32_t>(1, sizeof(T) / 4), + }) + .Sync(); + if (!response || response->format != 8 * sizeof(T) || + response->value.size() != sizeof(T)) { + return false; + } + + DCHECK_EQ(response->format / 8 * response->value_len, response->value.size()); + memcpy(value, response->value.data(), sizeof(T)); + return true; +} + +template <typename T> +bool GetArrayProperty(XID window, + const std::string& property_name, + std::vector<T>* value) { + static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4, ""); + auto response = x11::Connection::Get() + ->GetProperty({ + .window = static_cast<x11::Window>(window), + .property = static_cast<x11::Atom>( + gfx::GetAtom(property_name.c_str())), + .long_length = std::numeric_limits<uint32_t>::max(), + }) + .Sync(); + if (!response || response->format != 8 * sizeof(T)) + return false; + + DCHECK_EQ(response->format / 8 * response->value_len, response->value.size()); + value->resize(response->value_len); + memcpy(value->data(), response->value.data(), response->value.size()); + return true; } bool SupportsEWMH() { @@ -133,8 +163,7 @@ supports_ewmh_cached = true; int wm_window = 0u; - if (!GetIntProperty(GetX11RootWindow(), - "_NET_SUPPORTING_WM_CHECK", + if (!GetIntProperty(GetX11RootWindow(), "_NET_SUPPORTING_WM_CHECK", &wm_window)) { supports_ewmh = false; return false; @@ -151,10 +180,9 @@ // we check that too. gfx::X11ErrorTracker err_tracker; int wm_window_property = 0; - bool result = GetIntProperty( - wm_window, "_NET_SUPPORTING_WM_CHECK", &wm_window_property); - supports_ewmh = !err_tracker.FoundNewError() && - result && + bool result = GetIntProperty(wm_window, "_NET_SUPPORTING_WM_CHECK", + &wm_window_property); + supports_ewmh = !err_tracker.FoundNewError() && result && wm_window_property == wm_window; } @@ -167,15 +195,14 @@ return false; int wm_window = 0; - if (!GetIntProperty(GetX11RootWindow(), - "_NET_SUPPORTING_WM_CHECK", + if (!GetIntProperty(GetX11RootWindow(), "_NET_SUPPORTING_WM_CHECK", &wm_window)) { return false; } gfx::X11ErrorTracker err_tracker; - bool result = GetStringProperty( - static_cast<XID>(wm_window), "_NET_WM_NAME", wm_name); + bool result = + GetStringProperty(static_cast<XID>(wm_window), "_NET_WM_NAME", wm_name); return !err_tracker.FoundNewError() && result; } @@ -209,18 +236,14 @@ return xcursor; } - void Ref(::Cursor cursor) { - cache_[cursor]->Ref(); - } + void Ref(::Cursor cursor) { cache_[cursor]->Ref(); } void Unref(::Cursor cursor) { if (cache_[cursor]->Unref()) cache_.erase(cursor); } - void Clear() { - cache_.clear(); - } + void Clear() { cache_.clear(); } const XcursorImage* GetXcursorImage(::Cursor cursor) const { return cache_.find(cursor)->second->image(); @@ -232,9 +255,7 @@ class XCustomCursor { public: // This takes ownership of the image. - XCustomCursor(XcursorImage* image) - : image_(image), - ref_(1) { + explicit XCustomCursor(XcursorImage* image) : image_(image), ref_(1) { cursor_ = XcursorImageLoadCursor(gfx::GetXDisplay(), image); } @@ -245,9 +266,7 @@ ::Cursor cursor() const { return cursor_; } - void Ref() { - ++ref_; - } + void Ref() { ++ref_; } // Returns true if the cursor was destroyed because of the unref. bool Unref() { @@ -268,12 +287,10 @@ DISALLOW_COPY_AND_ASSIGN(XCustomCursor); }; - XCustomCursorCache() {} - ~XCustomCursorCache() { - Clear(); - } + XCustomCursorCache() = default; + ~XCustomCursorCache() { Clear(); } - std::map< ::Cursor, XCustomCursor*> cache_; + std::map<::Cursor, XCustomCursor*> cache_; DISALLOW_COPY_AND_ASSIGN(XCustomCursorCache); }; @@ -357,8 +374,8 @@ else scale = kMaxPixel / converted.height(); - scaled = skia::ImageOperations::Resize(converted, - skia::ImageOperations::RESIZE_BETTER, + scaled = skia::ImageOperations::Resize( + converted, skia::ImageOperations::RESIZE_BETTER, static_cast<int>(converted.width() * scale), static_cast<int>(converted.height() * scale)); hotspot_point = gfx::ScaleToFlooredPoint(hotspot, scale); @@ -372,8 +389,7 @@ if (bitmap.width() && bitmap.height()) { // The |bitmap| contains ARGB image, so just copy it. - memcpy(image->pixels, - bitmap.getPixels(), + memcpy(image->pixels, bitmap.getPixels(), bitmap.width() * bitmap.height() * 4); } @@ -478,14 +494,13 @@ ::Cursor CreateInvisibleCursor() { XDisplay* xdisplay = gfx::GetXDisplay(); ::Cursor invisible_cursor; - char nodata[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + char nodata[] = {0, 0, 0, 0, 0, 0, 0, 0}; XColor black; black.red = black.green = black.blue = 0; - Pixmap blank = XCreateBitmapFromData(xdisplay, - DefaultRootWindow(xdisplay), + Pixmap blank = XCreateBitmapFromData(xdisplay, DefaultRootWindow(xdisplay), nodata, 8, 8); - invisible_cursor = XCreatePixmapCursor(xdisplay, blank, blank, - &black, &black, 0, 0); + invisible_cursor = + XCreatePixmapCursor(xdisplay, blank, blank, &black, &black, 0, 0); XFreePixmap(xdisplay, blank); return invisible_cursor; } @@ -511,14 +526,10 @@ motif_hints.decorations = use_os_window_frame ? 1 : 0; XAtom hint_atom = gfx::GetAtom("_MOTIF_WM_HINTS"); - XChangeProperty(gfx::GetXDisplay(), - window, - hint_atom, - hint_atom, - 32, + XChangeProperty(gfx::GetXDisplay(), window, hint_atom, hint_atom, 32, PropModeReplace, reinterpret_cast<unsigned char*>(&motif_hints), - sizeof(MotifWmHints)/sizeof(long)); + sizeof(MotifWmHints) / sizeof(long)); } bool IsShapeExtensionAvailable() { @@ -559,11 +570,8 @@ XGCValues gc_values = {0}; gc_values.foreground = BlackPixel(display, DefaultScreen(display)); GC gc = XCreateGC(display, root_window, GCForeground, &gc_values); - XFillRectangle(display, root_window, gc, - root_bounds.x(), - root_bounds.y(), - root_bounds.width(), - root_bounds.height()); + XFillRectangle(display, root_window, gc, root_bounds.x(), root_bounds.y(), + root_bounds.width(), root_bounds.height()); XFreeGC(display, gc); } @@ -589,8 +597,7 @@ int window_desktop, current_desktop; return (!GetWindowDesktop(window, &window_desktop) || !GetCurrentDesktop(¤t_desktop) || - window_desktop == kAllDesktops || - window_desktop == current_desktop); + window_desktop == kAllDesktops || window_desktop == current_desktop); } bool GetInnerWindowBounds(XID window, gfx::Rect* rect) { @@ -599,12 +606,12 @@ unsigned int width, height; unsigned int border_width, depth; - if (!XGetGeometry(gfx::GetXDisplay(), window, &root, &x, &y, - &width, &height, &border_width, &depth)) + if (!XGetGeometry(gfx::GetXDisplay(), window, &root, &x, &y, &width, &height, + &border_width, &depth)) return false; - if (!XTranslateCoordinates(gfx::GetXDisplay(), window, root, - 0, 0, &x, &y, &child)) + if (!XTranslateCoordinates(gfx::GetXDisplay(), window, root, 0, 0, &x, &y, + &child)) return false; *rect = gfx::Rect(x, y, width, height); @@ -640,7 +647,6 @@ return true; } - bool WindowContainsPoint(XID window, gfx::Point screen_loc) { TRACE_EVENT0("ui", "WindowContainsPoint"); @@ -668,13 +674,11 @@ // included in both the default input region and the client bounding region // will not be included in the effective input region on the screen. int rectangle_kind[] = {ShapeInput, ShapeBounding}; - for (size_t kind_index = 0; kind_index < base::size(rectangle_kind); - kind_index++) { + for (int kind_index : rectangle_kind) { int dummy; int shape_rects_size = 0; gfx::XScopedPtr<XRectangle[]> shape_rects(XShapeGetRectangles( - gfx::GetXDisplay(), window, rectangle_kind[kind_index], - &shape_rects_size, &dummy)); + gfx::GetXDisplay(), window, kind_index, &shape_rects_size, &dummy)); if (!shape_rects) { // The shape is empty. This can occur when |window| is minimized. DCHECK_EQ(0, shape_rects_size); @@ -699,20 +703,16 @@ return true; } - bool PropertyExists(XID window, const std::string& property_name) { - XAtom type = x11::None; - int format = 0; // size in bits of each item in 'property' - unsigned long num_items = 0; - unsigned char* property = nullptr; - - int result = GetProperty(window, property_name, 1, - &type, &format, &num_items, &property); - gfx::XScopedPtr<unsigned char> scoped_property(property); - if (result != x11::Success) - return false; - - return num_items > 0; + auto response = x11::Connection::Get() + ->GetProperty({ + .window = static_cast<x11::Window>(window), + .property = static_cast<x11::Atom>( + gfx::GetAtom(property_name.c_str())), + .long_length = 1, + }) + .Sync(); + return response && response->format; } bool GetRawBytesOfProperty(XID window, @@ -768,110 +768,41 @@ } bool GetIntProperty(XID window, const std::string& property_name, int* value) { - XAtom type = x11::None; - int format = 0; // size in bits of each item in 'property' - unsigned long num_items = 0; - unsigned char* property = nullptr; - - int result = GetProperty(window, property_name, 1, - &type, &format, &num_items, &property); - gfx::XScopedPtr<unsigned char> scoped_property(property); - if (result != x11::Success) - return false; - - if (format != 32 || num_items != 1) - return false; - - *value = static_cast<int>(*(reinterpret_cast<long*>(property))); - return true; + return GetProperty(window, property_name, value); } bool GetXIDProperty(XID window, const std::string& property_name, XID* value) { - XAtom type = x11::None; - int format = 0; // size in bits of each item in 'property' - unsigned long num_items = 0; - unsigned char* property = nullptr; - - int result = GetProperty(window, property_name, 1, - &type, &format, &num_items, &property); - gfx::XScopedPtr<unsigned char> scoped_property(property); - if (result != x11::Success) + uint32_t xid; + if (!GetProperty(window, property_name, &xid)) return false; - - if (format != 32 || num_items != 1) - return false; - - *value = *(reinterpret_cast<XID*>(property)); + *value = xid; return true; } bool GetIntArrayProperty(XID window, const std::string& property_name, std::vector<int>* value) { - XAtom type = x11::None; - int format = 0; // size in bits of each item in 'property' - unsigned long num_items = 0; - unsigned char* properties = nullptr; - - int result = GetProperty(window, property_name, - (~0L), // (all of them) - &type, &format, &num_items, &properties); - gfx::XScopedPtr<unsigned char> scoped_properties(properties); - if (result != x11::Success) - return false; - - if (format != 32) - return false; - - long* int_properties = reinterpret_cast<long*>(properties); - value->clear(); - for (unsigned long i = 0; i < num_items; ++i) { - value->push_back(static_cast<int>(int_properties[i])); - } - return true; + return GetArrayProperty(window, property_name, value); } bool GetAtomArrayProperty(XID window, const std::string& property_name, std::vector<XAtom>* value) { - XAtom type = x11::None; - int format = 0; // size in bits of each item in 'property' - unsigned long num_items = 0; - unsigned char* properties = nullptr; - - int result = GetProperty(window, property_name, - (~0L), // (all of them) - &type, &format, &num_items, &properties); - gfx::XScopedPtr<unsigned char> scoped_properties(properties); - if (result != x11::Success) + std::vector<uint32_t> value32; + if (!GetArrayProperty(window, property_name, &value32)) return false; - - if (type != XA_ATOM) - return false; - - XAtom* atom_properties = reinterpret_cast<XAtom*>(properties); - value->clear(); - value->insert(value->begin(), atom_properties, atom_properties + num_items); + *value = std::vector<XAtom>(value32.begin(), value32.end()); return true; } -bool GetStringProperty( - XID window, const std::string& property_name, std::string* value) { - XAtom type = x11::None; - int format = 0; // size in bits of each item in 'property' - unsigned long num_items = 0; - unsigned char* property = nullptr; - - int result = GetProperty(window, property_name, 1024, - &type, &format, &num_items, &property); - gfx::XScopedPtr<unsigned char> scoped_property(property); - if (result != x11::Success) +bool GetStringProperty(XID window, + const std::string& property_name, + std::string* value) { + std::vector<char> str; + if (!GetArrayProperty(window, property_name, &str)) return false; - if (format != 8) - return false; - - value->assign(reinterpret_cast<char*>(property), num_items); + value->assign(str.data(), str.size()); return true; } @@ -897,10 +828,7 @@ data[i] = value[i]; gfx::X11ErrorTracker err_tracker; - XChangeProperty(gfx::GetXDisplay(), - window, - name_atom, - type_atom, + XChangeProperty(gfx::GetXDisplay(), window, name_atom, type_atom, 32, // size in bits of items in 'value' PropModeReplace, reinterpret_cast<const unsigned char*>(data.get()), @@ -930,10 +858,7 @@ data[i] = value[i]; gfx::X11ErrorTracker err_tracker; - XChangeProperty(gfx::GetXDisplay(), - window, - name_atom, - type_atom, + XChangeProperty(gfx::GetXDisplay(), window, name_atom, type_atom, 32, // size in bits of items in 'value' PropModeReplace, reinterpret_cast<const unsigned char*>(data.get()), @@ -946,14 +871,9 @@ XAtom type, const std::string& value) { gfx::X11ErrorTracker err_tracker; - XChangeProperty(gfx::GetXDisplay(), - window, - property, - type, - 8, - PropModeReplace, - reinterpret_cast<const unsigned char*>(value.c_str()), - value.size()); + XChangeProperty( + gfx::GetXDisplay(), window, property, type, 8, PropModeReplace, + reinterpret_cast<const unsigned char*>(value.c_str()), value.size()); return !err_tracker.FoundNewError(); } @@ -1041,21 +961,14 @@ // Also disable custom frames for (at-least-partially-)EWMH-supporting tiling // window managers. ui::WindowManagerName wm = GuessWindowManager(); - if (wm == WM_AWESOME || - wm == WM_I3 || - wm == WM_ION3 || - wm == WM_MATCHBOX || - wm == WM_NOTION || - wm == WM_QTILE || - wm == WM_RATPOISON || - wm == WM_STUMPWM || - wm == WM_WMII) + if (wm == WM_AWESOME || wm == WM_I3 || wm == WM_ION3 || wm == WM_MATCHBOX || + wm == WM_NOTION || wm == WM_QTILE || wm == WM_RATPOISON || + wm == WM_STUMPWM || wm == WM_WMII) return false; // Handle a few more window managers that don't get along well with custom // frames. - if (wm == WM_ICE_WM || - wm == WM_KWIN) + if (wm == WM_ICE_WM || wm == WM_KWIN) return false; // For everything else, use custom frames. @@ -1121,8 +1034,10 @@ return true; } -bool EnumerateChildren(EnumerateWindowsDelegate* delegate, XID window, - const int max_depth, int depth) { +bool EnumerateChildren(EnumerateWindowsDelegate* delegate, + XID window, + const int max_depth, + int depth) { if (depth > max_depth) return false; @@ -1197,27 +1112,13 @@ } bool GetXWindowStack(Window window, std::vector<XID>* windows) { - windows->clear(); - - Atom type; - int format; - unsigned long count; - unsigned char* data = nullptr; - if (GetProperty(window, "_NET_CLIENT_LIST_STACKING", ~0L, &type, &format, - &count, &data) != x11::Success) { + std::vector<uint32_t> value32; + if (!GetArrayProperty(window, "_NET_CLIENT_LIST_STACKING", &value32)) return false; - } - gfx::XScopedPtr<unsigned char> scoped_data(data); - - bool result = false; - if (type == XA_WINDOW && format == 32 && data && count > 0) { - result = true; - XID* stack = reinterpret_cast<XID*>(data); - for (long i = static_cast<long>(count) - 1; i >= 0; i--) - windows->push_back(stack[i]); - } - - return result; + // It's more common to iterate from lowest window to highest, + // so reverse the vector. + *windows = std::vector<XID>(value32.rbegin(), value32.rend()); + return true; } WindowManagerName GuessWindowManager() { @@ -1297,9 +1198,7 @@ XAtom fullscreen_atom = gfx::GetAtom("_NET_WM_STATE_FULLSCREEN"); if (WmSupportsHint(fullscreen_atom)) { std::vector<XAtom> atom_properties; - if (GetAtomArrayProperty(window, - "_NET_WM_STATE", - &atom_properties)) { + if (GetAtomArrayProperty(window, "_NET_WM_STATE", &atom_properties)) { return base::Contains(atom_properties, fullscreen_atom); } } @@ -1325,8 +1224,7 @@ return false; std::vector<XAtom> supported_atoms; - if (!GetAtomArrayProperty(GetX11RootWindow(), - "_NET_SUPPORTED", + if (!GetAtomArrayProperty(GetX11RootWindow(), "_NET_SUPPORTED", &supported_atoms)) { return false; } @@ -1417,8 +1315,7 @@ } XRefcountedMemory::XRefcountedMemory(unsigned char* x11_data, size_t length) - : x11_data_(length ? x11_data : nullptr), length_(length) { -} + : x11_data_(length ? x11_data : nullptr), length_(length) {} const unsigned char* XRefcountedMemory::front() const { return x11_data_.get(); @@ -1428,13 +1325,10 @@ return length_; } -XRefcountedMemory::~XRefcountedMemory() { -} +XRefcountedMemory::~XRefcountedMemory() = default; XScopedCursor::XScopedCursor(::Cursor cursor, XDisplay* display) - : cursor_(cursor), - display_(display) { -} + : cursor_(cursor), display_(display) {} XScopedCursor::~XScopedCursor() { reset(0U); @@ -1459,7 +1353,7 @@ const XcursorImage* GetCachedXcursorImage(::Cursor cursor) { return XCustomCursorCache::GetInstance()->GetXcursorImage(cursor); } -} +} // namespace test // ---------------------------------------------------------------------------- // These functions are declared in x11_util_internal.h because they require @@ -1482,11 +1376,9 @@ templ.direct.alphaMask = 0; static const unsigned long kMask = - PictFormatType | PictFormatDepth | - PictFormatRed | PictFormatRedMask | - PictFormatGreen | PictFormatGreenMask | - PictFormatBlue | PictFormatBlueMask | - PictFormatAlphaMask; + PictFormatType | PictFormatDepth | PictFormatRed | PictFormatRedMask | + PictFormatGreen | PictFormatGreenMask | PictFormatBlue | + PictFormatBlueMask | PictFormatAlphaMask; pictformat = XRenderFindFormat(dpy, kMask, &templ, 0 /* first result */); @@ -1503,8 +1395,8 @@ void SetX11ErrorHandlers(XErrorHandler error_handler, XIOErrorHandler io_error_handler) { XSetErrorHandler(error_handler ? error_handler : DefaultX11ErrorHandler); - XSetIOErrorHandler( - io_error_handler ? io_error_handler : DefaultX11IOErrorHandler); + XSetIOErrorHandler(io_error_handler ? io_error_handler + : DefaultX11IOErrorHandler); } // static @@ -1557,7 +1449,7 @@ DCHECK(visuals_.find(transparent_visual_id_) != visuals_.end()); } -XVisualManager::~XVisualManager() {} +XVisualManager::~XVisualManager() = default; void XVisualManager::ChooseVisualForWindow(bool want_argb_visual, Visual** visual, @@ -1628,7 +1520,8 @@ if (depth) *depth = visual_info.depth; if (colormap) - *colormap = is_default_visual ? CopyFromParent : visual_data.GetColormap(); + *colormap = + is_default_visual ? 0 /* CopyFromParent */ : visual_data.GetColormap(); if (visual_has_alpha) { auto popcount = [](auto x) { return std::bitset<8 * sizeof(decltype(x))>(x).count(); @@ -1642,16 +1535,15 @@ } XVisualManager::XVisualData::XVisualData(XVisualInfo visual_info) - : visual_info(visual_info), colormap_(CopyFromParent) {} + : visual_info(visual_info), colormap_(0 /* CopyFromParent */) {} -XVisualManager::XVisualData::~XVisualData() { - // Do not XFreeColormap as this would uninstall the colormap even for - // non-Chromium clients. -} +// Do not XFreeColormap as this would uninstall the colormap even for +// non-Chromium clients. +XVisualManager::XVisualData::~XVisualData() = default; Colormap XVisualManager::XVisualData::GetColormap() { XDisplay* display = gfx::GetXDisplay(); - if (colormap_ == CopyFromParent) { + if (colormap_ == 0 /* CopyFromParent */) { colormap_ = XCreateColormap(display, DefaultRootWindow(display), visual_info.visual, AllocNone); } @@ -1661,5 +1553,4 @@ // ---------------------------------------------------------------------------- // End of x11_util_internal.h - } // namespace ui
diff --git a/ui/chromeos/events/event_rewriter_chromeos.cc b/ui/chromeos/events/event_rewriter_chromeos.cc index 477ed16..ea666e61 100644 --- a/ui/chromeos/events/event_rewriter_chromeos.cc +++ b/ui/chromeos/events/event_rewriter_chromeos.cc
@@ -39,8 +39,6 @@ // Hotrod controller vendor/product ids. const int kHotrodRemoteVendorId = 0x0471; const int kHotrodRemoteProductId = 0x21cc; -const int kUnknownVendorId = -1; -const int kUnknownProductId = -1; // Flag masks for remapping alt+click or search+click to right click. constexpr int kAltLeftButton = (EF_ALT_DOWN | EF_LEFT_MOUSE_BUTTON); @@ -109,6 +107,30 @@ {EF_NONE, DomCode::LAUNCH_ASSISTANT, DomKey::LAUNCH_ASSISTANT, VKEY_ASSISTANT}}}; +const EventRewriterChromeOS::MutableKeyState kCustomTopRowLayoutFKeys[] = { + {EF_NONE, DomCode::F1, DomKey::F1, VKEY_F1}, + {EF_NONE, DomCode::F2, DomKey::F2, VKEY_F2}, + {EF_NONE, DomCode::F3, DomKey::F3, VKEY_F3}, + {EF_NONE, DomCode::F4, DomKey::F4, VKEY_F4}, + {EF_NONE, DomCode::F5, DomKey::F5, VKEY_F5}, + {EF_NONE, DomCode::F6, DomKey::F6, VKEY_F6}, + {EF_NONE, DomCode::F7, DomKey::F7, VKEY_F7}, + {EF_NONE, DomCode::F8, DomKey::F8, VKEY_F8}, + {EF_NONE, DomCode::F9, DomKey::F9, VKEY_F9}, + {EF_NONE, DomCode::F10, DomKey::F10, VKEY_F10}, + {EF_NONE, DomCode::F11, DomKey::F11, VKEY_F11}, + {EF_NONE, DomCode::F12, DomKey::F12, VKEY_F12}, + {EF_NONE, DomCode::F13, DomKey::F13, VKEY_F13}, + {EF_NONE, DomCode::F14, DomKey::F14, VKEY_F14}, + {EF_NONE, DomCode::F15, DomKey::F15, VKEY_F15}, +}; +const size_t kAllFKeysSize = base::size(kCustomTopRowLayoutFKeys); +constexpr KeyboardCode kMaxCustomTopRowLayoutFKeyCode = VKEY_F15; + +bool IsCustomLayoutFunctionKey(KeyboardCode key_code) { + return key_code >= VKEY_F1 && key_code <= kMaxCustomTopRowLayoutFKeyCode; +} + const ModifierRemapping* kModifierRemappingNeoMod3 = &kModifierRemappings[1]; // Gets a remapped key for |pref_name| key. For example, to find out which @@ -295,7 +317,27 @@ return true; } +// Returns true if |value| is replaced with the specific device attribute value +// without getting an error. |device_path| should be obtained from the +// |InputDevice.sys_path| field. +bool GetDeviceAttributeRecursive(const base::FilePath& device_path, + const char* key, + std::string* value) { + device::ScopedUdevPtr udev(device::udev_new()); + if (!udev.get()) + return false; + + device::ScopedUdevDevicePtr device(device::udev_device_new_from_syspath( + udev.get(), device_path.value().c_str())); + if (!device.get()) + return false; + + *value = device::UdevDeviceRecursiveGetSysattrValue(device.get(), key); + return true; +} + constexpr char kLayoutProperty[] = "CROS_KEYBOARD_TOP_ROW_LAYOUT"; +constexpr char kCustomTopRowLayoutAttribute[] = "function_row_physmap"; bool GetTopRowLayoutProperty(const InputDevice& keyboard_device, std::string* out_prop) { @@ -328,6 +370,56 @@ return true; } +// Parses the custom top row layout string. The string contains a space +// separated list of scan codes in hex. eg "aa ab ac" for F1, F2, F3, etc. +// Returns true if the string can be parsed. +bool ParseCustomTopRowLayoutMap( + const std::string& layout, + base::flat_map<uint32_t, EventRewriterChromeOS::MutableKeyState>* + out_scan_code_map) { + const std::vector<std::string> scan_code_strings = base::SplitString( + layout, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + if (scan_code_strings.size() == 0 || + scan_code_strings.size() > kAllFKeysSize) { + return false; + } + + base::flat_map<uint32_t, EventRewriterChromeOS::MutableKeyState> + scan_code_map; + for (size_t i = 0; i < scan_code_strings.size(); i++) { + uint32_t scan_code = 0; + if (!base::HexStringToUInt(scan_code_strings[i], &scan_code)) { + return false; + } + + scan_code_map[scan_code] = kCustomTopRowLayoutFKeys[i]; + } + + *out_scan_code_map = std::move(scan_code_map); + return true; +} + +bool GetCustomTopRowLayoutAttribute(const InputDevice& keyboard_device, + std::string* out_prop) { + bool result = GetDeviceAttributeRecursive( + keyboard_device.sys_path, kCustomTopRowLayoutAttribute, out_prop); + + if (result && out_prop->size() > 0) { + VLOG(1) << "Identified custom top row keyboard layout: sys_path=" + << keyboard_device.sys_path << " layout=" << *out_prop; + return true; + } + + return false; +} + +bool HasCustomTopRowLayout(const InputDevice& keyboard_device) { + std::string layout; + base::flat_map<uint32_t, EventRewriterChromeOS::MutableKeyState> top_row_map; + return GetCustomTopRowLayoutAttribute(keyboard_device, &layout) && + ParseCustomTopRowLayoutMap(layout, &top_row_map); +} + // Returns whether |key_code| appears as one of the key codes that might be // remapped by table mappings. bool IsKeyCodeInMappings(KeyboardCode key_code, @@ -424,14 +516,18 @@ EventRewriterChromeOS::KeyboardTopRowLayout* out_layout) { std::string layout_string; EventRewriterChromeOS::KeyboardTopRowLayout layout; - if (!GetTopRowLayoutProperty(keyboard_device, &layout_string) || - !ParseKeyboardTopRowLayout(layout_string, &layout)) { + const bool has_custom_top_row = HasCustomTopRowLayout(keyboard_device); + if (has_custom_top_row) { + layout = EventRewriterChromeOS::kKbdTopRowLayoutCustom; + } else if (!GetTopRowLayoutProperty(keyboard_device, &layout_string) || + !ParseKeyboardTopRowLayout(layout_string, &layout)) { *out_type = EventRewriterChromeOS::kDeviceUnknown; *out_layout = EventRewriterChromeOS::kKbdTopRowLayoutDefault; return false; } - *out_type = IdentifyKeyboardType(keyboard_device, !layout_string.empty()); + *out_type = IdentifyKeyboardType( + keyboard_device, has_custom_top_row || !layout_string.empty()); *out_layout = layout; return true; } @@ -477,23 +573,8 @@ EventRewriterChromeOS::~EventRewriterChromeOS() {} -void EventRewriterChromeOS::KeyboardDeviceAddedForTesting( - int device_id, - const std::string& device_name, - const std::string& layout_name, - InputDeviceType device_type) { - // Tests must avoid XI2 reserved device IDs. - DCHECK((device_id < 0) || (device_id > 1)); - InputDevice keyboard_device(device_id, device_type, device_name); - keyboard_device.vendor_id = kUnknownVendorId; - keyboard_device.product_id = kUnknownProductId; - - KeyboardTopRowLayout layout; - if (ParseKeyboardTopRowLayout(layout_name, &layout)) { - KeyboardDeviceAddedInternal( - device_id, IdentifyKeyboardType(keyboard_device, !layout_name.empty()), - layout); - } +void EventRewriterChromeOS::KeyboardDeviceAddedForTesting(int device_id) { + KeyboardDeviceAdded(device_id); } void EventRewriterChromeOS::ResetStateForTesting() { @@ -545,7 +626,7 @@ void EventRewriterChromeOS::BuildRewrittenKeyEvent( const KeyEvent& key_event, const MutableKeyState& state, - std::unique_ptr<ui::Event>* rewritten_event) { + std::unique_ptr<Event>* rewritten_event) { auto key_event_ptr = std::make_unique<KeyEvent>( key_event.type(), state.key_code, state.code, state.flags, state.key, key_event.time_stamp()); @@ -1226,7 +1307,13 @@ } const bool search_is_pressed = (state->flags & EF_COMMAND_DOWN) != 0; - if (layout == kKbdTopRowLayoutWilco || layout == kKbdTopRowLayoutDrallion) { + if (layout == kKbdTopRowLayoutCustom) { + if (RewriteTopRowKeysForCustomLayout(key_event.source_device_id(), + key_event, search_is_pressed, state)) { + return; + } + } else if (layout == kKbdTopRowLayoutWilco || + layout == kKbdTopRowLayoutDrallion) { if (RewriteTopRowKeysForLayoutWilco(key_event, search_is_pressed, state, layout)) { return; @@ -1545,6 +1632,82 @@ return SendEvent(continuation, &key_event); } +bool EventRewriterChromeOS::StoreCustomTopRowMapping( + const InputDevice& keyboard_device) { + std::string layout; + if (!GetCustomTopRowLayoutAttribute(keyboard_device, &layout)) { + LOG(WARNING) << "Could not read top row layout map for device " + << keyboard_device.id; + return false; + } + + base::flat_map<uint32_t, MutableKeyState> top_row_map; + if (!ParseCustomTopRowLayoutMap(layout, &top_row_map)) { + LOG(WARNING) << "Could not parse top row layout map: " << layout; + return false; + } + + top_row_scan_code_map_[keyboard_device.id] = std::move(top_row_map); + return true; +} + +// New CrOS keyboards differ from previous Chrome OS keyboards in a few +// ways. Previous keyboards always sent F1-Fxx keys and allowed Chrome to +// decide how to interpret them. New CrOS keyboards now always send action +// keys (eg. Back, Refresh, Overview). So while the default previously was +// to always expect to remap F-Key to action key, for these devices respect +// what the keyboard sends unless the user overrides with either the Search +// key or the "Top Row is always F-Key" setting. +// +// Additionally, these keyboards provide the mapping via sysfs so each +// new keyboard does not need to be explicitly special cased in the future. +// +// Search Force function keys Key code Result +// ------- ------------------- -------- ------ +// No No Function Unchanged +// Yes No Function Unchanged +// No Yes Function Unchanged +// Yes Yes Function Unchanged +// No No Action Unchanged +// Yes No Action Action -> Fn +// No Yes Action Action -> Fn +// Yes Yes Action Unchanged +bool EventRewriterChromeOS::RewriteTopRowKeysForCustomLayout( + int device_id, + const KeyEvent& key_event, + bool search_is_pressed, + EventRewriterChromeOS::MutableKeyState* state) { + // Incoming function keys are never remapped. + if (IsCustomLayoutFunctionKey(key_event.key_code())) { + return true; + } + + const auto& scan_code_map_iter = top_row_scan_code_map_.find(device_id); + if (scan_code_map_iter == top_row_scan_code_map_.end()) { + LOG(WARNING) << "Found no top row key mapping for device " << device_id; + return false; + } + + const base::flat_map<uint32_t, MutableKeyState>& scan_code_map = + scan_code_map_iter->second; + const auto& key_iter = scan_code_map.find(key_event.scan_code()); + + // If the scan code appears in the top row mapping it is an action key. + const bool is_action_key = (key_iter != scan_code_map.end()); + if (is_action_key) { + if (search_is_pressed != ForceTopRowAsFunctionKeys()) { + ApplyRemapping(key_iter->second, state); + } + + // Clear command/search key if pressed. It's been consumed in the remapping + // or wasn't pressed. + state->flags &= ~EF_COMMAND_DOWN; + return true; + } + + return false; +} + // The keyboard layout for Wilco has a slightly different top-row layout, emits // both Fn and action keys from kernel and has key events with Dom codes and no // VKey value == VKEY_UNKNOWN. Depending on the state of the search key and @@ -1699,15 +1862,6 @@ return false; } -void EventRewriterChromeOS::KeyboardDeviceAddedInternal( - int device_id, - DeviceType type, - KeyboardTopRowLayout layout) { - // Always overwrite the existing device_id since the X server may reuse a - // device id for an unattached device. - device_id_to_info_[device_id] = {type, layout}; -} - bool EventRewriterChromeOS::ForceTopRowAsFunctionKeys() const { return delegate_ && delegate_->TopRowKeysAreFunctionKeys(); } @@ -1719,19 +1873,30 @@ const std::vector<InputDevice>& keyboard_devices = DeviceDataManager::GetInstance()->GetKeyboardDevices(); for (const auto& keyboard : keyboard_devices) { - if (keyboard.id == device_id) { - DeviceType type; - KeyboardTopRowLayout layout; - if (IdentifyKeyboard(keyboard, &type, &layout)) { - // Don't store a device info when an error occurred while reading from - // udev. This gives a chance to reattempt reading from udev on - // subsequent key events, rather than being stuck in a bad state until - // next reboot. crbug.com/783166. - KeyboardDeviceAddedInternal(keyboard.id, type, layout); - } + if (keyboard.id != device_id) + continue; + DeviceType type; + KeyboardTopRowLayout layout; + // Don't store a device info when an error occurred while reading from + // udev. This gives a chance to reattempt reading from udev on + // subsequent key events, rather than being stuck in a bad state until + // next reboot. crbug.com/783166. + if (!IdentifyKeyboard(keyboard, &type, &layout)) { return type; } + + // For custom layouts, parse and save the top row mapping. + if (layout == EventRewriterChromeOS::kKbdTopRowLayoutCustom) { + if (!StoreCustomTopRowMapping(keyboard)) { + return type; + } + } + + // Always overwrite the existing device_id since the X server may + // reuse a device id for an unattached device. + device_id_to_info_[keyboard.id] = {type, layout}; + return type; } return kDeviceUnknown; }
diff --git a/ui/chromeos/events/event_rewriter_chromeos.h b/ui/chromeos/events/event_rewriter_chromeos.h index 332741e5..296259c12 100644 --- a/ui/chromeos/events/event_rewriter_chromeos.h +++ b/ui/chromeos/events/event_rewriter_chromeos.h
@@ -57,6 +57,8 @@ // Browser Back, Browser Forward, Refresh, Full Screen, Overview, // Brightness Down, Brightness Up, Mute, Volume Down, Volume Up. kKbdTopRowLayout1 = 1, + kKbdTopRowLayoutDefault = kKbdTopRowLayout1, + kKbdTopRowLayoutMin = kKbdTopRowLayout1, // 2017 keyboard layout: Browser Forward is gone and Play/Pause // key is added between Brightness Up and Mute. kKbdTopRowLayout2 = 2, @@ -64,9 +66,10 @@ kKbdTopRowLayoutWilco = 3, kKbdTopRowLayoutDrallion = 4, - kKbdTopRowLayoutDefault = kKbdTopRowLayout1, - kKbdTopRowLayoutMin = kKbdTopRowLayout1, - kKbdTopRowLayoutMax = kKbdTopRowLayoutDrallion + // Handling for all keyboards that support supplying a custom layout + // via sysfs attribute (aka Vivaldi). See crbug.com/1076241 + kKbdTopRowLayoutCustom = 5, + kKbdTopRowLayoutMax = kKbdTopRowLayoutCustom }; // Things that keyboard-related rewriter phases can change about an Event. @@ -124,12 +127,8 @@ bool privacy_screen_supported); ~EventRewriterChromeOS() override; - // Calls KeyboardDeviceAddedInternal. - void KeyboardDeviceAddedForTesting( - int device_id, - const std::string& device_name, - const std::string& layout_string = std::string(), - InputDeviceType device_type = INPUT_DEVICE_INTERNAL); + // Calls KeyboardDeviceAdded. + void KeyboardDeviceAddedForTesting(int device_id); // Reset the internal rewriter state so that next set of tests can be ran on // the same rewriter, if needed. @@ -199,11 +198,6 @@ // even if it wasn't stored in |device_id_to_info_|. DeviceType KeyboardDeviceAdded(int device_id); - // Inserts a new entry to |device_id_to_info_|. - void KeyboardDeviceAddedInternal(int device_id, - DeviceType type, - KeyboardTopRowLayout layout); - // Returns true if |last_keyboard_device_id_| is Hotrod remote. bool IsHotrodRemote() const; // Returns true if |last_keyboard_device_id_| is of given |device_type|. @@ -244,6 +238,19 @@ int RewriteLocatedEvent(const Event& event); int RewriteModifierClick(const MouseEvent& event, int* flags); + // Reads the keyboard mapping for new CrOS keyboards that support + // supplying a custom layout via sysfs and stores it mapped to + // |keyboard_device| in |top_row_scan_code_map_|. + bool StoreCustomTopRowMapping(const ui::InputDevice& keyboard_device); + + // Handle Function <-> Action key remapping for new CrOS keyboards that + // support supplying a custom layout via sysfs. + bool RewriteTopRowKeysForCustomLayout( + int device_id, + const ui::KeyEvent& key_event, + bool search_is_pressed, + ui::EventRewriterChromeOS::MutableKeyState* state); + // Handle Fn/Action key remapping for Wilco keyboard layout. bool RewriteTopRowKeysForLayoutWilco(const KeyEvent& key_event, bool search_is_pressed, @@ -269,6 +276,12 @@ std::map<int, DeviceInfo> device_id_to_info_; + // Maps a device ID to a mapping of scan_code to MutableKeyState on keyboards + // that supply it via a sysfs attribute. + // eg. map<device_id, Map<scan_code, MutableKeyState>>. + base::flat_map<int, base::flat_map<uint32_t, MutableKeyState>> + top_row_scan_code_map_; + // The |source_device_id()| of the most recent keyboard event, // used to interpret modifiers on pointer events. int last_keyboard_device_id_;
diff --git a/ui/chromeos/search_box/search_box_view_base.cc b/ui/chromeos/search_box/search_box_view_base.cc index 6c95d61cf2..f672fcad 100644 --- a/ui/chromeos/search_box/search_box_view_base.cc +++ b/ui/chromeos/search_box/search_box_view_base.cc
@@ -537,16 +537,22 @@ void SearchBoxViewBase::HandleSearchBoxEvent(ui::LocatedEvent* located_event) { if (located_event->type() == ui::ET_MOUSE_PRESSED || located_event->type() == ui::ET_GESTURE_TAP) { - bool event_is_in_searchbox_bounds = + const bool event_is_in_searchbox_bounds = GetWidget()->GetWindowBoundsInScreen().Contains( located_event->root_location()); - if (is_search_box_active_ || !event_is_in_searchbox_bounds || - !search_box_->GetText().empty()) + // Don't handle an event out of the searchbox bounds. + if (!event_is_in_searchbox_bounds) return; - // If the event was within the searchbox bounds and in an inactive empty - // search box, enable the search box. - SetSearchBoxActive(true, located_event->type()); + // If the event is in an inactive empty search box, enable the search box. + if (!is_search_box_active_ && search_box_->GetText().empty()) { + SetSearchBoxActive(true, located_event->type()); + return; + } + + // Otherwise, update the keyboard in case it was hidden. Tapping again + // should reopen it. + UpdateKeyboardVisibility(); } located_event->SetHandled(); }
diff --git a/ui/gfx/x/gen_xproto.py b/ui/gfx/x/gen_xproto.py index 41d7b500..4a34901 100644 --- a/ui/gfx/x/gen_xproto.py +++ b/ui/gfx/x/gen_xproto.py
@@ -410,6 +410,8 @@ tmp_id = self.new_uid() self.write('auto& tmp%d = %s.%s;' % (tmp_id, obj, field_name)) self.write('auto& %s = tmp%d;' % (field_name, tmp_id)) + elif field.for_list: + self.write('%s %s;' % (self.fieldtype(field), field_name)) else: self.write('auto& %s = %s.%s;' % (field_name, obj, field_name)) @@ -613,7 +615,7 @@ t = field.type name = safe_name(field.field_name) - if not field.wire or not field.visible: + if not field.wire or not field.visible or field.for_list: return if t.is_switch: @@ -640,6 +642,11 @@ self.write('Pad(&buf, %d);' % t.nmemb) elif not field.visible: self.copy_special_field(field) + elif field.for_list: + if not self.is_read: + self.write('%s = %s.size();' % + (name, safe_name(field.for_list.field_name))) + self.copy_primitive(name) elif t.is_switch: self.copy_switch(field) elif t.is_list: @@ -843,10 +850,16 @@ for field in fields.values(): field.parent = t + field.for_list = None if field.type.is_switch or field.type.is_case_or_bitcase: self.resolve_type(field.type, field.field_type) elif field.type.is_list: self.resolve_type(field.type.member, field.type.member.name) + expr = field.type.expr + if not expr.op and expr.lenfield_name in fields: + fields[expr.lenfield_name].for_list = field + else: + self.resolve_type(field.type, field.type.name) if isinstance(t, self.xcbgen.xtypes.Request) and t.reply: self.resolve_type(t.reply, t.reply.name) @@ -868,6 +881,9 @@ del self.enum_types[x] for t in self.types: + # Lots of fields have types like uint8_t. Ignore these. + if len(t) == 1: + continue l = list(self.types[t]) # For some reason, FDs always have distint types so they appear # duplicated in the set. If the set contains only FDs, then bail.
diff --git a/ui/gfx/x/x11_atom_cache.cc b/ui/gfx/x/x11_atom_cache.cc index 2b32f0e4..75f18c1 100644 --- a/ui/gfx/x/x11_atom_cache.cc +++ b/ui/gfx/x/x11_atom_cache.cc
@@ -14,6 +14,7 @@ #include "base/memory/singleton.h" #include "base/metrics/histogram_functions.h" #include "base/stl_util.h" +#include "ui/gfx/x/connection.h" namespace { @@ -251,37 +252,39 @@ return base::Singleton<X11AtomCache>::get(); } -X11AtomCache::X11AtomCache() : xdisplay_(gfx::GetXDisplay()) { +X11AtomCache::X11AtomCache() : connection_(x11::Connection::Get()) { for (const auto& predefined_atom : kPredefinedAtoms) cached_atoms_[predefined_atom.atom_name] = predefined_atom.atom_value; - // Grab all the atoms we need now to minimize roundtrips to the X11 server. - std::vector<XAtom> cached_atoms(kCacheCount); - XInternAtoms(xdisplay_, const_cast<char**>(kAtomsToCache), kCacheCount, False, - cached_atoms.data()); - - for (int i = 0; i < kCacheCount; ++i) - cached_atoms_[kAtomsToCache[i]] = cached_atoms[i]; + std::vector<x11::Future<x11::XProto::InternAtomReply>> requests; + requests.reserve(kCacheCount); + for (const char* name : kAtomsToCache) + requests.push_back(connection_->InternAtom({.name = name})); + for (size_t i = 0; i < kCacheCount; ++i) { + if (auto response = requests[i].Sync()) + cached_atoms_[kAtomsToCache[i]] = static_cast<XAtom>(response->atom); + } } -X11AtomCache::~X11AtomCache() {} +X11AtomCache::~X11AtomCache() = default; XAtom X11AtomCache::GetAtom(const char* name) const { + DCHECK(name); const auto it = cached_atoms_.find(name); if (it != cached_atoms_.end()) return it->second; - // XInternAtom returns None on failure. Source: - // https://www.x.org/releases/X11R7.5/doc/man/man3/XInternAtom.3.html - XAtom atom = XInternAtom(xdisplay_, name, False); - if (atom == None) { + XAtom atom = 0; + if (auto response = connection_->InternAtom({.name = name}).Sync()) { + atom = static_cast<XAtom>(response->atom); + cached_atoms_.emplace(name, atom); + } else { static int error_count = 0; ++error_count; // TODO(https://crbug.com/1000919): Evaluate and remove UMA metrics after // enough data is gathered. base::UmaHistogramCounts100("X11.XInternAtomFailure", error_count); } - cached_atoms_.emplace(name, atom); return atom; }
diff --git a/ui/gfx/x/x11_atom_cache.h b/ui/gfx/x/x11_atom_cache.h index 9d2bc07..b04608a 100644 --- a/ui/gfx/x/x11_atom_cache.h +++ b/ui/gfx/x/x11_atom_cache.h
@@ -17,6 +17,10 @@ struct DefaultSingletonTraits; } +namespace x11 { +class Connection; +} + namespace gfx { // Gets the X atom for default display corresponding to atom_name. @@ -41,7 +45,7 @@ // On failure, x11::None is returned. XAtom GetAtom(const char*) const; - XDisplay* xdisplay_; + x11::Connection* connection_; // Using std::map, as it is possible for thousands of atoms to be registered. mutable std::map<std::string, XAtom> cached_atoms_;
diff --git a/ui/views/controls/button/button_unittest.cc b/ui/views/controls/button/button_unittest.cc index 54e0cad3..fbab18d 100644 --- a/ui/views/controls/button/button_unittest.cc +++ b/ui/views/controls/button/button_unittest.cc
@@ -159,6 +159,22 @@ DISALLOW_COPY_AND_ASSIGN(TestButtonObserver); }; +TestInkDrop* AddTestInkDrop(TestButton* button) { + auto owned_ink_drop = std::make_unique<TestInkDrop>(); + TestInkDrop* ink_drop = owned_ink_drop.get(); + InkDropHostViewTestApi(button).SetInkDrop(std::move(owned_ink_drop)); + return ink_drop; +} + +// TODO(tluk): remove when the appropriate ownership APIs have been added for +// Widget's SetContentsView(). +template <typename T> +T* AddContentsView(Widget* widget, std::unique_ptr<T> view) { + T* view_ptr = view.get(); + widget->SetContentsView(view.release()); + return view_ptr; +} + } // namespace class ButtonTest : public ViewsTestBase { @@ -179,8 +195,7 @@ widget_->Init(std::move(params)); widget_->Show(); - button_ = std::make_unique<TestButton>(false); - widget_->SetContentsView(button_.get()); + button_ = AddContentsView(widget(), std::make_unique<TestButton>(false)); event_generator_ = std::make_unique<ui::test::EventGenerator>(GetRootWindow(widget())); @@ -192,37 +207,35 @@ button_->RemoveButtonObserver(button_observer_.get()); button_observer_.reset(); - button_.reset(); widget_.reset(); ViewsTestBase::TearDown(); } - void CreateButtonWithInkDrop(std::unique_ptr<InkDrop> ink_drop, - bool has_ink_drop_action_on_click) { - button_ = std::make_unique<TestButton>(has_ink_drop_action_on_click); - InkDropHostViewTestApi(button_.get()).SetInkDrop(std::move(ink_drop)); - widget_->SetContentsView(button_.get()); + TestInkDrop* CreateButtonWithInkDrop(bool has_ink_drop_action_on_click) { + button_ = AddContentsView( + widget(), std::make_unique<TestButton>(has_ink_drop_action_on_click)); + widget_->SetContentsView(button_); + return AddTestInkDrop(button_); } void CreateButtonWithRealInkDrop() { - button_ = std::make_unique<TestButton>(false); - InkDropHostViewTestApi(button_.get()) - .SetInkDrop( - std::make_unique<InkDropImpl>(button_.get(), button_->size())); - widget_->SetContentsView(button_.get()); + button_ = AddContentsView(widget(), std::make_unique<TestButton>(false)); + InkDropHostViewTestApi(button_).SetInkDrop( + std::make_unique<InkDropImpl>(button_, button_->size())); + widget_->SetContentsView(button_); } void CreateButtonWithObserver() { - button_ = std::make_unique<TestButton>(false); + button_ = AddContentsView(widget(), std::make_unique<TestButton>(false)); button_observer_ = std::make_unique<TestButtonObserver>(); button_->AddButtonObserver(button_observer_.get()); - widget_->SetContentsView(button_.get()); + widget_->SetContentsView(button_); } protected: Widget* widget() { return widget_.get(); } - TestButton* button() { return button_.get(); } + TestButton* button() { return button_; } TestButtonObserver* button_observer() { return button_observer_.get(); } ui::test::EventGenerator* event_generator() { return event_generator_.get(); } void SetDraggedView(View* dragged_view) { @@ -231,7 +244,7 @@ private: std::unique_ptr<Widget> widget_; - std::unique_ptr<TestButton> button_; + TestButton* button_; std::unique_ptr<TestButtonObserver> button_observer_; std::unique_ptr<ui::test::EventGenerator> event_generator_; @@ -458,8 +471,7 @@ // Note: Ink drop is not hidden upon release because Button descendants // may enter a different ink drop state. TEST_F(ButtonTest, ButtonClickTogglesInkDrop) { - TestInkDrop* ink_drop = new TestInkDrop(); - CreateButtonWithInkDrop(base::WrapUnique(ink_drop), false); + TestInkDrop* ink_drop = CreateButtonWithInkDrop(false); event_generator()->MoveMouseTo(button()->GetBoundsInScreen().CenterPoint()); event_generator()->PressLeftButton(); @@ -472,8 +484,7 @@ // Tests that pressing a button shows and releasing capture hides ink drop. // Releasing capture should also reset PRESSED button state to NORMAL. TEST_F(ButtonTest, CaptureLossHidesInkDrop) { - TestInkDrop* ink_drop = new TestInkDrop(); - CreateButtonWithInkDrop(base::WrapUnique(ink_drop), false); + TestInkDrop* ink_drop = CreateButtonWithInkDrop(false); event_generator()->MoveMouseTo(button()->GetBoundsInScreen().CenterPoint()); event_generator()->PressLeftButton(); @@ -489,8 +500,7 @@ } TEST_F(ButtonTest, HideInkDropWhenShowingContextMenu) { - TestInkDrop* ink_drop = new TestInkDrop(); - CreateButtonWithInkDrop(base::WrapUnique(ink_drop), false); + TestInkDrop* ink_drop = CreateButtonWithInkDrop(false); TestContextMenuController context_menu_controller; button()->set_context_menu_controller(&context_menu_controller); button()->set_hide_ink_drop_when_showing_context_menu(true); @@ -505,8 +515,7 @@ } TEST_F(ButtonTest, DontHideInkDropWhenShowingContextMenu) { - TestInkDrop* ink_drop = new TestInkDrop(); - CreateButtonWithInkDrop(base::WrapUnique(ink_drop), false); + TestInkDrop* ink_drop = CreateButtonWithInkDrop(false); TestContextMenuController context_menu_controller; button()->set_context_menu_controller(&context_menu_controller); button()->set_hide_ink_drop_when_showing_context_menu(false); @@ -523,8 +532,7 @@ TEST_F(ButtonTest, HideInkDropOnBlur) { gfx::Point center(10, 10); - TestInkDrop* ink_drop = new TestInkDrop(); - CreateButtonWithInkDrop(base::WrapUnique(ink_drop), false); + TestInkDrop* ink_drop = CreateButtonWithInkDrop(false); button()->OnFocus(); @@ -543,8 +551,7 @@ } TEST_F(ButtonTest, HideInkDropHighlightOnDisable) { - TestInkDrop* ink_drop = new TestInkDrop(); - CreateButtonWithInkDrop(base::WrapUnique(ink_drop), false); + TestInkDrop* ink_drop = CreateButtonWithInkDrop(false); event_generator()->MoveMouseTo(button()->GetBoundsInScreen().CenterPoint()); EXPECT_TRUE(ink_drop->is_hovered()); @@ -555,8 +562,7 @@ } TEST_F(ButtonTest, InkDropAfterTryingToShowContextMenu) { - TestInkDrop* ink_drop = new TestInkDrop(); - CreateButtonWithInkDrop(base::WrapUnique(ink_drop), false); + TestInkDrop* ink_drop = CreateButtonWithInkDrop(false); button()->set_context_menu_controller(nullptr); ink_drop->SetHovered(true); @@ -569,34 +575,31 @@ } TEST_F(ButtonTest, HideInkDropHighlightWhenRemoved) { - views::View test_container; - test_container.set_owned_by_client(); - TestInkDrop* ink_drop = new TestInkDrop(); - CreateButtonWithInkDrop(base::WrapUnique(ink_drop), false); - // Mark the button as owned by client so we can remove it from widget() - // without it being deleted. - button()->set_owned_by_client(); + View* contents_view = AddContentsView(widget(), std::make_unique<View>()); + + TestButton* button = + contents_view->AddChildView(std::make_unique<TestButton>(false)); + button->SetBounds(0, 0, 200, 200); + TestInkDrop* ink_drop = AddTestInkDrop(button); // Make sure that the button ink drop is hidden after the button gets removed. - widget()->SetContentsView(&test_container); - test_container.AddChildView(button()); - event_generator()->MoveMouseTo(button()->GetBoundsInScreen().origin()); + event_generator()->MoveMouseTo(button->GetBoundsInScreen().origin()); event_generator()->MoveMouseBy(2, 2); EXPECT_TRUE(ink_drop->is_hovered()); // Set ink-drop state to ACTIVATED to make sure that removing the container // sets it back to HIDDEN. ink_drop->AnimateToState(InkDropState::ACTIVATED); - test_container.RemoveAllChildViews(false); + auto owned_button = contents_view->RemoveChildViewT(button); + button = nullptr; + EXPECT_FALSE(ink_drop->is_hovered()); EXPECT_EQ(InkDropState::HIDDEN, ink_drop->GetTargetInkDropState()); // Make sure hiding the ink drop happens even if the button is indirectly // being removed. - views::View parent_test_container; - parent_test_container.set_owned_by_client(); - widget()->SetContentsView(&parent_test_container); - parent_test_container.AddChildView(&test_container); - test_container.AddChildView(button()); + View* parent_view = contents_view->AddChildView(std::make_unique<View>()); + parent_view->SetBounds(0, 0, 400, 400); + button = parent_view->AddChildView(std::move(owned_button)); // Trigger hovering and then remove from the indirect parent. This should // propagate down to Button which should remove the highlight effect. @@ -606,17 +609,9 @@ // Set ink-drop state to ACTIVATED to make sure that removing the container // sets it back to HIDDEN. ink_drop->AnimateToState(InkDropState::ACTIVATED); - parent_test_container.RemoveAllChildViews(false); + auto owned_parent = contents_view->RemoveChildViewT(parent_view); EXPECT_EQ(InkDropState::HIDDEN, ink_drop->GetTargetInkDropState()); EXPECT_FALSE(ink_drop->is_hovered()); - - // Remove references to and delete button() which cannot be removed by owned - // containers as it's permanently set as owned by client. - test_container.RemoveAllChildViews(false); - - // Set the widget contents view to a new View so widget() doesn't contain a - // stale reference to the test containers that are about to go out of scope. - widget()->SetContentsView(new View()); } // Tests that when button is set to notify on release, dragging mouse out and @@ -625,8 +620,7 @@ gfx::Point center(10, 10); gfx::Point oob(-1, -1); - TestInkDrop* ink_drop = new TestInkDrop(); - CreateButtonWithInkDrop(base::WrapUnique(ink_drop), false); + TestInkDrop* ink_drop = CreateButtonWithInkDrop(false); button()->button_controller()->set_notify_action( ButtonController::NotifyAction::kOnRelease); @@ -667,8 +661,7 @@ gfx::Point center(10, 10); gfx::Point oob(-1, -1); - TestInkDrop* ink_drop = new TestInkDrop(); - CreateButtonWithInkDrop(base::WrapUnique(ink_drop), true); + TestInkDrop* ink_drop = CreateButtonWithInkDrop(true); button()->button_controller()->set_notify_action( ButtonController::NotifyAction::kOnPress); @@ -708,8 +701,7 @@ gfx::Point center(10, 10); gfx::Point oob(-1, -1); - TestInkDrop* ink_drop = new TestInkDrop(); - CreateButtonWithInkDrop(base::WrapUnique(ink_drop), false); + TestInkDrop* ink_drop = CreateButtonWithInkDrop(false); button()->OnMousePressed(ui::MouseEvent( ui::ET_MOUSE_PRESSED, center, center, ui::EventTimeForNow(), @@ -738,35 +730,51 @@ SetDraggedView(nullptr); } +// VisibilityTestButton tests to see if an ink drop or a layer has been added to +// the button at any point during the visibility state changes of its Widget. +class VisibilityTestButton : public TestButton { + public: + VisibilityTestButton() : TestButton(false) {} + ~VisibilityTestButton() override { + if (layer()) + ADD_FAILURE(); + } + + // TestButton: + void AddInkDropLayer(ui::Layer* ink_drop_layer) override { + ADD_FAILURE(); + TestButton::AddInkDropLayer(ink_drop_layer); + } + void RemoveInkDropLayer(ui::Layer* ink_drop_layer) override { + ADD_FAILURE(); + TestButton::RemoveInkDropLayer(ink_drop_layer); + } +}; + // Test that hiding or closing a Widget doesn't attempt to add a layer due to // changed visibility states. TEST_F(ButtonTest, NoLayerAddedForWidgetVisibilityChanges) { - CreateButtonWithRealInkDrop(); + VisibilityTestButton* button = + AddContentsView(widget(), std::make_unique<VisibilityTestButton>()); - EXPECT_TRUE(button()->GetVisible()); - EXPECT_FALSE(button()->layer()); + // Ensure no layers are created during construction. + EXPECT_TRUE(button->GetVisible()); + EXPECT_FALSE(button->layer()); + // Ensure no layers are created when hiding the widget. widget()->Hide(); - EXPECT_FALSE(button()->layer()); - EXPECT_EQ(0, button()->ink_drop_layer_add_count()); - EXPECT_EQ(0, button()->ink_drop_layer_remove_count()); + EXPECT_FALSE(button->layer()); + // Ensure no layers are created when the widget is reshown. widget()->Show(); - EXPECT_FALSE(button()->layer()); - EXPECT_EQ(0, button()->ink_drop_layer_add_count()); - EXPECT_EQ(0, button()->ink_drop_layer_remove_count()); + EXPECT_FALSE(button->layer()); - // Allow the button to be interrogated after the view hierarchy is torn down. - button()->set_owned_by_client(); + // Ensure no layers are created during the closing of the Widget. widget()->Close(); // Start an asynchronous close. - EXPECT_FALSE(button()->layer()); - EXPECT_EQ(0, button()->ink_drop_layer_add_count()); - EXPECT_EQ(0, button()->ink_drop_layer_remove_count()); + EXPECT_FALSE(button->layer()); + // Ensure no layers are created following the Widget's destruction. base::RunLoop().RunUntilIdle(); // Complete the Close(). - EXPECT_FALSE(button()->layer()); - EXPECT_EQ(0, button()->ink_drop_layer_add_count()); - EXPECT_EQ(0, button()->ink_drop_layer_remove_count()); } // Verify that the Space key clicks the button on key-press on Mac, and
diff --git a/ui/views/controls/menu/menu_scroll_view_container.h b/ui/views/controls/menu/menu_scroll_view_container.h index 5f87cfa5..e0dc860 100644 --- a/ui/views/controls/menu/menu_scroll_view_container.h +++ b/ui/views/controls/menu/menu_scroll_view_container.h
@@ -31,8 +31,6 @@ // External function to check if the bubble border is used. bool HasBubbleBorder() const; - void SetFootnoteView(View* view); - // View overrides. gfx::Size CalculatePreferredSize() const override; void OnPaintBackground(gfx::Canvas* canvas) override;
diff --git a/ui/views/controls/tabbed_pane/tabbed_pane.h b/ui/views/controls/tabbed_pane/tabbed_pane.h index e06e0db..4c42c23 100644 --- a/ui/views/controls/tabbed_pane/tabbed_pane.h +++ b/ui/views/controls/tabbed_pane/tabbed_pane.h
@@ -24,7 +24,7 @@ namespace test { class TabbedPaneAccessibilityMacTest; -class TabbedPaneTest; +class TabbedPaneWithWidgetTest; } // namespace test // TabbedPane is a view that shows tabs. When the user clicks on a tab, the @@ -100,7 +100,7 @@ friend class FocusTraversalTest; friend class Tab; friend class TabStrip; - friend class test::TabbedPaneTest; + friend class test::TabbedPaneWithWidgetTest; friend class test::TabbedPaneAccessibilityMacTest; // Adds a new tab at |index| with |title|. |contents| is the view displayed
diff --git a/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc b/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc index 51cfc08..808afa4 100644 --- a/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc +++ b/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc
@@ -43,14 +43,75 @@ } // namespace -class TabbedPaneTest : public ViewsTestBase { +using TabbedPaneTest = ViewsTestBase; + +// Tests tab orientation. +TEST_F(TabbedPaneTest, HorizontalOrientationDefault) { + auto tabbed_pane = std::make_unique<TabbedPane>(); + EXPECT_EQ(tabbed_pane->GetOrientation(), + TabbedPane::Orientation::kHorizontal); +} + +// Tests tab orientation. +TEST_F(TabbedPaneTest, VerticalOrientation) { + auto tabbed_pane = std::make_unique<TabbedPane>( + TabbedPane::Orientation::kVertical, TabbedPane::TabStripStyle::kBorder); + EXPECT_EQ(tabbed_pane->GetOrientation(), TabbedPane::Orientation::kVertical); +} + +// Tests tab strip style. +TEST_F(TabbedPaneTest, TabStripBorderStyle) { + auto tabbed_pane = std::make_unique<TabbedPane>(); + EXPECT_EQ(tabbed_pane->GetStyle(), TabbedPane::TabStripStyle::kBorder); +} + +// Tests tab strip style. +TEST_F(TabbedPaneTest, TabStripHighlightStyle) { + auto tabbed_pane = + std::make_unique<TabbedPane>(TabbedPane::Orientation::kVertical, + TabbedPane::TabStripStyle::kHighlight); + EXPECT_EQ(tabbed_pane->GetStyle(), TabbedPane::TabStripStyle::kHighlight); +} + +// Tests the preferred size and layout when tabs are aligned vertically.. +TEST_F(TabbedPaneTest, SizeAndLayoutInVerticalOrientation) { + auto tabbed_pane = std::make_unique<TabbedPane>( + TabbedPane::Orientation::kVertical, TabbedPane::TabStripStyle::kBorder); + View* child1 = + tabbed_pane->AddTab(ASCIIToUTF16("tab1"), + std::make_unique<StaticSizedView>(gfx::Size(20, 10))); + View* child2 = tabbed_pane->AddTab( + ASCIIToUTF16("tab2"), std::make_unique<StaticSizedView>(gfx::Size(5, 5))); + tabbed_pane->SelectTabAt(0); + + // |tabbed_pane_| reserves extra width for the tab strip in vertical mode. + EXPECT_GT(tabbed_pane->GetPreferredSize().width(), 20); + // |tabbed_pane_| height should match the largest child in vertical mode. + EXPECT_EQ(tabbed_pane->GetPreferredSize().height(), 10); + + // The child views should resize to fit in larger tabbed panes. + tabbed_pane->SetBounds(0, 0, 100, 200); + + EXPECT_GT(child1->bounds().width(), 0); + // |tabbed_pane_| reserves extra width for the tab strip. Therefore the + // children's width should be smaller than the |tabbed_pane_|'s width. + EXPECT_LT(child1->bounds().width(), 100); + // |tabbed_pane_| has no border. Therefore the children should be as high as + // the |tabbed_pane_|. + EXPECT_EQ(child1->bounds().height(), 200); + + // If we switch to the other tab, it should get assigned the same bounds. + tabbed_pane->SelectTabAt(1); + EXPECT_EQ(child1->bounds(), child2->bounds()); +} + +class TabbedPaneWithWidgetTest : public ViewsTestBase { public: - TabbedPaneTest() = default; + TabbedPaneWithWidgetTest() = default; void SetUp() override { ViewsTestBase::SetUp(); - tabbed_pane_ = std::make_unique<TabbedPane>(); - tabbed_pane_->set_owned_by_client(); + auto tabbed_pane = std::make_unique<TabbedPane>(); // Create a widget so that accessibility data will be returned correctly. widget_ = std::make_unique<Widget>(); @@ -59,22 +120,17 @@ params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; params.bounds = gfx::Rect(0, 0, 650, 650); widget_->Init(std::move(params)); - widget_->SetContentsView(tabbed_pane_.get()); + tabbed_pane_ = tabbed_pane.get(); + widget_->SetContentsView(tabbed_pane.release()); } void TearDown() override { - tabbed_pane_.reset(); + tabbed_pane_ = nullptr; widget_.reset(); ViewsTestBase::TearDown(); } protected: - void MakeTabbedPane(TabbedPane::Orientation orientation, - TabbedPane::TabStripStyle style) { - tabbed_pane_ = std::make_unique<TabbedPane>(orientation, style); - tabbed_pane_->set_owned_by_client(); - } - Tab* GetTabAt(size_t index) { return static_cast<Tab*>(tabbed_pane_->tab_strip_->children()[index]); } @@ -90,41 +146,16 @@ } std::unique_ptr<Widget> widget_; - std::unique_ptr<TabbedPane> tabbed_pane_; + TabbedPane* tabbed_pane_; private: - DISALLOW_COPY_AND_ASSIGN(TabbedPaneTest); + DISALLOW_COPY_AND_ASSIGN(TabbedPaneWithWidgetTest); }; -// Tests tab orientation. -TEST_F(TabbedPaneTest, HorizontalOrientation) { - EXPECT_EQ(tabbed_pane_->GetOrientation(), - TabbedPane::Orientation::kHorizontal); -} - -// Tests tab orientation. -TEST_F(TabbedPaneTest, VerticalOrientation) { - MakeTabbedPane(TabbedPane::Orientation::kVertical, - TabbedPane::TabStripStyle::kBorder); - EXPECT_EQ(tabbed_pane_->GetOrientation(), TabbedPane::Orientation::kVertical); -} - -// Tests tab strip style. -TEST_F(TabbedPaneTest, TabStripBorderStyle) { - EXPECT_EQ(tabbed_pane_->GetStyle(), TabbedPane::TabStripStyle::kBorder); -} - -// Tests tab strip style. -TEST_F(TabbedPaneTest, TabStripHighlightStyle) { - MakeTabbedPane(TabbedPane::Orientation::kVertical, - TabbedPane::TabStripStyle::kHighlight); - EXPECT_EQ(tabbed_pane_->GetStyle(), TabbedPane::TabStripStyle::kHighlight); -} - // Tests the preferred size and layout when tabs are aligned horizontally. // TabbedPane requests a size that fits the largest child or the minimum size // necessary to display the tab titles, whichever is larger. -TEST_F(TabbedPaneTest, SizeAndLayout) { +TEST_F(TabbedPaneWithWidgetTest, SizeAndLayout) { View* child1 = tabbed_pane_->AddTab( ASCIIToUTF16("tab1"), std::make_unique<StaticSizedView>(gfx::Size(20, 10))); @@ -165,39 +196,7 @@ EXPECT_EQ(child2->bounds(), child3->bounds()); } -// Tests the preferred size and layout when tabs are aligned vertically.. -TEST_F(TabbedPaneTest, SizeAndLayoutInVerticalOrientation) { - MakeTabbedPane(TabbedPane::Orientation::kVertical, - TabbedPane::TabStripStyle::kBorder); - View* child1 = tabbed_pane_->AddTab( - ASCIIToUTF16("tab1"), - std::make_unique<StaticSizedView>(gfx::Size(20, 10))); - View* child2 = tabbed_pane_->AddTab( - ASCIIToUTF16("tab2"), std::make_unique<StaticSizedView>(gfx::Size(5, 5))); - tabbed_pane_->SelectTabAt(0); - - // |tabbed_pane_| reserves extra width for the tab strip in vertical mode. - EXPECT_GT(tabbed_pane_->GetPreferredSize().width(), 20); - // |tabbed_pane_| height should match the largest child in vertical mode. - EXPECT_EQ(tabbed_pane_->GetPreferredSize().height(), 10); - - // The child views should resize to fit in larger tabbed panes. - tabbed_pane_->SetBounds(0, 0, 100, 200); - RunPendingMessages(); - EXPECT_GT(child1->bounds().width(), 0); - // |tabbed_pane_| reserves extra width for the tab strip. Therefore the - // children's width should be smaller than the |tabbed_pane_|'s width. - EXPECT_LT(child1->bounds().width(), 100); - // |tabbed_pane_| has no border. Therefore the children should be as high as - // the |tabbed_pane_|. - EXPECT_EQ(child1->bounds().height(), 200); - - // If we switch to the other tab, it should get assigned the same bounds. - tabbed_pane_->SelectTabAt(1); - EXPECT_EQ(child1->bounds(), child2->bounds()); -} - -TEST_F(TabbedPaneTest, AddAndSelect) { +TEST_F(TabbedPaneWithWidgetTest, AddAndSelect) { // Add several tabs; only the first should be selected automatically. for (size_t i = 0; i < 3; ++i) { tabbed_pane_->AddTab(DefaultTabTitle(), std::make_unique<View>()); @@ -218,7 +217,7 @@ EXPECT_NE(0u, tabbed_pane_->GetSelectedTabIndex()); } -TEST_F(TabbedPaneTest, ArrowKeyBindings) { +TEST_F(TabbedPaneWithWidgetTest, ArrowKeyBindings) { // Add several tabs; only the first should be selected automatically. for (size_t i = 0; i < 3; ++i) { tabbed_pane_->AddTab(DefaultTabTitle(), std::make_unique<View>()); @@ -246,7 +245,7 @@ // Use TabbedPane::HandleAccessibleAction() to select tabs and make sure their // a11y information is correct. -TEST_F(TabbedPaneTest, SelectTabWithAccessibleAction) { +TEST_F(TabbedPaneWithWidgetTest, SelectTabWithAccessibleAction) { constexpr size_t kNumTabs = 3; for (size_t i = 0; i < kNumTabs; ++i) { tabbed_pane_->AddTab(DefaultTabTitle(), std::make_unique<View>()); @@ -281,17 +280,17 @@ EXPECT_EQ(1u, tabbed_pane_->GetSelectedTabIndex()); } -TEST_F(TabbedPaneTest, AccessiblePaneTitleTracksActiveTabTitle) { +TEST_F(TabbedPaneWithWidgetTest, AccessiblePaneTitleTracksActiveTabTitle) { const base::string16 kFirstTitle = ASCIIToUTF16("Tab1"); const base::string16 kSecondTitle = ASCIIToUTF16("Tab2"); tabbed_pane_->AddTab(kFirstTitle, std::make_unique<View>()); tabbed_pane_->AddTab(kSecondTitle, std::make_unique<View>()); - EXPECT_EQ(kFirstTitle, GetAccessibleName(tabbed_pane_.get())); + EXPECT_EQ(kFirstTitle, GetAccessibleName(tabbed_pane_)); tabbed_pane_->SelectTabAt(1); - EXPECT_EQ(kSecondTitle, GetAccessibleName(tabbed_pane_.get())); + EXPECT_EQ(kSecondTitle, GetAccessibleName(tabbed_pane_)); } -TEST_F(TabbedPaneTest, AccessiblePaneContentsTitleTracksTabTitle) { +TEST_F(TabbedPaneWithWidgetTest, AccessiblePaneContentsTitleTracksTabTitle) { const base::string16 kFirstTitle = ASCIIToUTF16("Tab1"); const base::string16 kSecondTitle = ASCIIToUTF16("Tab2"); View* const tab1_contents = @@ -302,7 +301,7 @@ EXPECT_EQ(kSecondTitle, GetAccessibleName(tab2_contents)); } -TEST_F(TabbedPaneTest, AccessiblePaneContentsRoleIsTab) { +TEST_F(TabbedPaneWithWidgetTest, AccessiblePaneContentsRoleIsTab) { const base::string16 kFirstTitle = ASCIIToUTF16("Tab1"); const base::string16 kSecondTitle = ASCIIToUTF16("Tab2"); View* const tab1_contents =
diff --git a/ui/views/controls/textfield/textfield_unittest.cc b/ui/views/controls/textfield/textfield_unittest.cc index e14b9d6..456cecaba 100644 --- a/ui/views/controls/textfield/textfield_unittest.cc +++ b/ui/views/controls/textfield/textfield_unittest.cc
@@ -13,6 +13,7 @@ #include <vector> #include "base/command_line.h" +#include "base/feature_list.h" #include "base/format_macros.h" #include "base/i18n/rtl.h" #include "base/pickle.h" @@ -53,6 +54,7 @@ #include "ui/views/test/test_views_delegate.h" #include "ui/views/test/views_test_base.h" #include "ui/views/test/widget_test.h" +#include "ui/views/views_features.h" #include "ui/views/widget/widget.h" #include "ui/views/widget/widget_utils.h" #include "url/gurl.h" @@ -779,6 +781,19 @@ // an event when it updates the cursor position. void MoveMouseTo(const gfx::Point& where) { mouse_position_ = where; } + // Tap on the textfield. + void TapAtCursor(ui::EventPointerType pointer_type) { + ui::GestureEventDetails tap_down_details(ui::ET_GESTURE_TAP_DOWN); + tap_down_details.set_primary_pointer_type(pointer_type); + GestureEventForTest tap_down(GetCursorPositionX(0), 0, tap_down_details); + textfield_->OnGestureEvent(&tap_down); + + ui::GestureEventDetails tap_up_details(ui::ET_GESTURE_TAP); + tap_up_details.set_primary_pointer_type(pointer_type); + GestureEventForTest tap_up(GetCursorPositionX(0), 0, tap_up_details); + textfield_->OnGestureEvent(&tap_up); + } + // We need widget to populate wrapper class. Widget* widget_ = nullptr; @@ -3741,11 +3756,7 @@ EXPECT_EQ(ui::TextInputClient::FOCUS_REASON_NONE, textfield_->GetFocusReason()); - ui::GestureEventDetails tap_details(ui::ET_GESTURE_TAP_DOWN); - tap_details.set_primary_pointer_type(ui::EventPointerType::kTouch); - GestureEventForTest tap(GetCursorPositionX(0), 0, tap_details); - textfield_->OnGestureEvent(&tap); - + TapAtCursor(ui::EventPointerType::kTouch); EXPECT_EQ(ui::TextInputClient::FOCUS_REASON_TOUCH, textfield_->GetFocusReason()); } @@ -3756,11 +3767,7 @@ EXPECT_EQ(ui::TextInputClient::FOCUS_REASON_NONE, textfield_->GetFocusReason()); - ui::GestureEventDetails tap_details(ui::ET_GESTURE_TAP_DOWN); - tap_details.set_primary_pointer_type(ui::EventPointerType::kPen); - GestureEventForTest tap(GetCursorPositionX(0), 0, tap_details); - textfield_->OnGestureEvent(&tap); - + TapAtCursor(ui::EventPointerType::kPen); EXPECT_EQ(ui::TextInputClient::FOCUS_REASON_PEN, textfield_->GetFocusReason()); } @@ -3771,21 +3778,8 @@ EXPECT_EQ(ui::TextInputClient::FOCUS_REASON_NONE, textfield_->GetFocusReason()); - // Pen tap, followed by a touch tap - { - ui::GestureEventDetails tap_details(ui::ET_GESTURE_TAP_DOWN); - tap_details.set_primary_pointer_type(ui::EventPointerType::kPen); - GestureEventForTest tap(GetCursorPositionX(0), 0, tap_details); - textfield_->OnGestureEvent(&tap); - } - - { - ui::GestureEventDetails tap_details(ui::ET_GESTURE_TAP_DOWN); - tap_details.set_primary_pointer_type(ui::EventPointerType::kTouch); - GestureEventForTest tap(GetCursorPositionX(0), 0, tap_details); - textfield_->OnGestureEvent(&tap); - } - + TapAtCursor(ui::EventPointerType::kPen); + TapAtCursor(ui::EventPointerType::kTouch); EXPECT_EQ(ui::TextInputClient::FOCUS_REASON_PEN, textfield_->GetFocusReason()); } @@ -3797,13 +3791,8 @@ textfield_->GetFocusReason()); // Pen tap, blur, then programmatic focus. - ui::GestureEventDetails tap_details(ui::ET_GESTURE_TAP_DOWN); - tap_details.set_primary_pointer_type(ui::EventPointerType::kPen); - GestureEventForTest tap(GetCursorPositionX(0), 0, tap_details); - textfield_->OnGestureEvent(&tap); - + TapAtCursor(ui::EventPointerType::kPen); widget_->GetFocusManager()->ClearFocus(); - textfield_->RequestFocus(); EXPECT_EQ(ui::TextInputClient::FOCUS_REASON_OTHER, @@ -3813,11 +3802,7 @@ TEST_F(TextfieldTest, KeyboardObserverForPenInput) { InitTextfield(); - ui::GestureEventDetails tap_details(ui::ET_GESTURE_TAP_DOWN); - tap_details.set_primary_pointer_type(ui::EventPointerType::kPen); - GestureEventForTest tap(GetCursorPositionX(0), 0, tap_details); - textfield_->OnGestureEvent(&tap); - + TapAtCursor(ui::EventPointerType::kPen); EXPECT_EQ(1, input_method_->count_show_virtual_keyboard()); }
diff --git a/ui/views/corewm/tooltip_controller.cc b/ui/views/corewm/tooltip_controller.cc index 5b911f1..c19d229 100644 --- a/ui/views/corewm/tooltip_controller.cc +++ b/ui/views/corewm/tooltip_controller.cc
@@ -141,9 +141,12 @@ } void TooltipController::UpdateTooltip(aura::Window* target) { - // If tooltip is visible, we may want to hide it. If it is not, we are ok. - if (tooltip_window_ == target && tooltip_->IsVisible()) + // Ensure relevant tooltip is updated when it is visible or scheduled to + // show. Otherwise, a stale tooltip might be shown. + if (tooltip_window_ == target && + (tooltip_->IsVisible() || tooltip_defer_timer_.IsRunning())) { UpdateIfRequired(); + } // Reset |tooltip_window_at_mouse_press_| if the moving within the same window // but over a region that has different tooltip text.
diff --git a/ui/views/corewm/tooltip_controller_test_helper.cc b/ui/views/corewm/tooltip_controller_test_helper.cc index ebe6642..d641255 100644 --- a/ui/views/corewm/tooltip_controller_test_helper.cc +++ b/ui/views/corewm/tooltip_controller_test_helper.cc
@@ -44,6 +44,11 @@ return controller_->IsTooltipVisible(); } +void TooltipControllerTestHelper::SetTooltipShowDelayEnable( + bool tooltip_show_delay) { + controller_->tooltip_show_delayed_ = tooltip_show_delay; +} + TooltipTestView::TooltipTestView() = default; TooltipTestView::~TooltipTestView() = default;
diff --git a/ui/views/corewm/tooltip_controller_test_helper.h b/ui/views/corewm/tooltip_controller_test_helper.h index e62aaad..3c29095 100644 --- a/ui/views/corewm/tooltip_controller_test_helper.h +++ b/ui/views/corewm/tooltip_controller_test_helper.h
@@ -38,6 +38,7 @@ void FireTooltipShownTimer(); bool IsTooltipShownTimerRunning(); bool IsTooltipVisible(); + void SetTooltipShowDelayEnable(bool tooltip_show_delay); private: TooltipController* controller_;
diff --git a/ui/views/corewm/tooltip_controller_unittest.cc b/ui/views/corewm/tooltip_controller_unittest.cc index eee55c8..30ba48c 100644 --- a/ui/views/corewm/tooltip_controller_unittest.cc +++ b/ui/views/corewm/tooltip_controller_unittest.cc
@@ -325,6 +325,36 @@ EXPECT_FALSE(helper_->IsTooltipVisible()); } +TEST_F(TooltipControllerTest, TooltipUpdateWhenTooltipDeferTimerIsRunning) { + view_->set_tooltip_text(ASCIIToUTF16("Tooltip Text for view 1")); + EXPECT_EQ(base::string16(), helper_->GetTooltipText()); + EXPECT_EQ(nullptr, helper_->GetTooltipWindow()); + + TooltipTestView* view2 = PrepareSecondView(); + view2->set_tooltip_text(ASCIIToUTF16("Tooltip Text for view 2")); + + aura::Window* window = GetWindow(); + + // Tooltips show up with delay + helper_->SetTooltipShowDelayEnable(true); + + // Tooltip 1 is scheduled and invisibled + generator_->MoveMouseRelativeTo(window, view_->bounds().CenterPoint()); + EXPECT_FALSE(helper_->IsTooltipVisible()); + EXPECT_FALSE(helper_->IsTooltipShownTimerRunning()); + + // Tooltip 2 is scheduled and invisible, the expected tooltip is tooltip 2 + generator_->MoveMouseRelativeTo(window, view2->bounds().CenterPoint()); + EXPECT_FALSE(helper_->IsTooltipVisible()); + EXPECT_FALSE(helper_->IsTooltipShownTimerRunning()); + base::string16 expected_tooltip = ASCIIToUTF16("Tooltip Text for view 2"); + EXPECT_EQ(expected_tooltip, wm::GetTooltipText(window)); + EXPECT_EQ(expected_tooltip, helper_->GetTooltipText()); + EXPECT_EQ(window, helper_->GetTooltipWindow()); + + helper_->SetTooltipShowDelayEnable(false); +} + TEST_F(TooltipControllerTest, TooltipHidesOnKeyPressAndStaysHiddenUntilChange) { view_->set_tooltip_text(ASCIIToUTF16("Tooltip Text for view 1")); EXPECT_EQ(base::string16(), helper_->GetTooltipText());
diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc index 6d082fb..3ee330f3 100644 --- a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc +++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
@@ -21,7 +21,7 @@ #include "ui/base/cursor/mojom/cursor_type.mojom-shared.h" #include "ui/base/dragdrop/drop_target_event.h" #include "ui/base/dragdrop/os_exchange_data.h" -#include "ui/base/dragdrop/os_exchange_data_provider_aurax11.h" +#include "ui/base/dragdrop/os_exchange_data_provider_x11.h" #include "ui/base/layout.h" #include "ui/base/x/selection_utils.h" #include "ui/base/x/x11_drag_context.h" @@ -283,7 +283,7 @@ DCHECK(target_current_context()); *data = std::make_unique<OSExchangeData>( - std::make_unique<ui::OSExchangeDataProviderAuraX11>( + std::make_unique<ui::OSExchangeDataProviderX11>( xwindow(), target_current_context()->fetched_targets())); gfx::Point location = root_location; aura::Window::ConvertPointToTarget(root_window_, target_window_, &location); @@ -398,7 +398,7 @@ aura::client::GetDragDropDelegate(target_window_); if (delegate) { auto data(std::make_unique<ui::OSExchangeData>( - std::make_unique<ui::OSExchangeDataProviderAuraX11>( + std::make_unique<ui::OSExchangeDataProviderX11>( xwindow(), target_current_context()->fetched_targets()))); ui::DropTargetEvent drop_event(
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc index 57b7083..44e9eef3 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
@@ -31,7 +31,7 @@ #include "ui/aura/window_event_dispatcher.h" #include "ui/base/buildflags.h" #include "ui/base/class_property.h" -#include "ui/base/dragdrop/os_exchange_data_provider_aurax11.h" +#include "ui/base/dragdrop/os_exchange_data_provider_x11.h" #include "ui/base/hit_test.h" #include "ui/base/ime/input_method.h" #include "ui/base/layout.h"
diff --git a/ui/views/widget/native_widget_mac_unittest.mm b/ui/views/widget/native_widget_mac_unittest.mm index 9009c049d..9a6b9ac6 100644 --- a/ui/views/widget/native_widget_mac_unittest.mm +++ b/ui/views/widget/native_widget_mac_unittest.mm
@@ -232,30 +232,6 @@ DISALLOW_COPY_AND_ASSIGN(WidgetChangeObserver); }; -class NativeHostHolder { - public: - NativeHostHolder() - : view_([[NSView alloc] init]), host_(new NativeViewHost()) { - host_->set_owned_by_client(); - } - - void AttachNativeView() { - DCHECK(!host_->native_view()); - host_->Attach(view_.get()); - } - - void Detach() { host_->Detach(); } - - NSView* view() const { return view_.get(); } - NativeViewHost* host() const { return host_.get(); } - - private: - base::scoped_nsobject<NSView> view_; - std::unique_ptr<NativeViewHost> host_; - - DISALLOW_COPY_AND_ASSIGN(NativeHostHolder); -}; - // This class gives public access to the protected ctor of // BubbleDialogDelegateView. class SimpleBubbleView : public BubbleDialogDelegateView { @@ -2247,6 +2223,29 @@ NativeWidgetMacViewsOrderTest() {} protected: + class NativeHostHolder { + public: + static std::unique_ptr<NativeHostHolder> CreateAndAddToParent( + View* parent) { + std::unique_ptr<NativeHostHolder> holder(new NativeHostHolder( + parent->AddChildView(std::make_unique<NativeViewHost>()))); + holder->host()->Attach(holder->view()); + return holder; + } + + NSView* view() const { return view_.get(); } + NativeViewHost* host() const { return host_; } + + private: + NativeHostHolder(NativeViewHost* host) + : host_(host), view_([[NSView alloc] init]) {} + + NativeViewHost* const host_; + base::scoped_nsobject<NSView> view_; + + DISALLOW_COPY_AND_ASSIGN(NativeHostHolder); + }; + // testing::Test: void SetUp() override { WidgetTest::SetUp(); @@ -2261,10 +2260,8 @@ const size_t kNativeViewCount = 3; for (size_t i = 0; i < kNativeViewCount; ++i) { - auto holder = std::make_unique<NativeHostHolder>(); - native_host_parent_->AddChildView(holder->host()); - holder->AttachNativeView(); - hosts_.push_back(std::move(holder)); + hosts_.push_back( + NativeHostHolder::CreateAndAddToParent(native_host_parent_)); } EXPECT_EQ(kNativeViewCount, native_host_parent_->children().size()); EXPECT_NSEQ([widget_->GetNativeView().GetNativeNSView() subviews], @@ -2275,6 +2272,7 @@ void TearDown() override { widget_->CloseNow(); + hosts_.clear(); WidgetTest::TearDown(); } @@ -2296,13 +2294,14 @@ // Test that NativeViewHost::Attach()/Detach() method saves the NativeView // z-order. TEST_F(NativeWidgetMacViewsOrderTest, NativeViewAttached) { - hosts_[1]->Detach(); + NativeHostHolder* second_host = hosts_[1].get(); + second_host->host()->Detach(); EXPECT_NSEQ([GetContentNativeView() subviews], ([GetStartingSubviews() arrayByAddingObjectsFromArray:@[ hosts_[0]->view(), hosts_[2]->view() ]])); - hosts_[1]->AttachNativeView(); + second_host->host()->Attach(second_host->view()); EXPECT_NSEQ([GetContentNativeView() subviews], ([GetStartingSubviews() arrayByAddingObjectsFromArray:@[ hosts_[0]->view(), hosts_[1]->view(), hosts_[2]->view()
diff --git a/ui/webui/resources/cr_components/chromeos/network/onc_mojo.js b/ui/webui/resources/cr_components/chromeos/network/onc_mojo.js index 25016e162ae3..16847b7 100644 --- a/ui/webui/resources/cr_components/chromeos/network/onc_mojo.js +++ b/ui/webui/resources/cr_components/chromeos/network/onc_mojo.js
@@ -590,6 +590,7 @@ security: mojom.SecurityType.kNone, signalStrength: 0, ssid: '', + isSyncable: false, }; break; default: @@ -727,6 +728,7 @@ ssid: OncMojo.createManagedString(''), security: mojom.SecurityType.kNone, signalStrength: 0, + isSyncable: false, } }; break;
diff --git a/ui/webui/resources/cr_elements/BUILD.gn b/ui/webui/resources/cr_elements/BUILD.gn index fd3701b..b57828b 100644 --- a/ui/webui/resources/cr_elements/BUILD.gn +++ b/ui/webui/resources/cr_elements/BUILD.gn
@@ -19,6 +19,7 @@ "cr_icon_button:closure_compile", "cr_input:closure_compile", "cr_link_row:closure_compile", + "cr_lottie:closure_compile", "cr_profile_avatar_selector:closure_compile", "cr_radio_button:closure_compile", "cr_radio_group:closure_compile", @@ -44,6 +45,7 @@ "cr_input:closure_compile_module", "cr_lazy_render:closure_compile_module", "cr_link_row:closure_compile_module", + "cr_lottie:closure_compile_module", "cr_profile_avatar_selector:closure_compile_module", "cr_radio_button:closure_compile_module", "cr_radio_group:closure_compile_module", @@ -171,6 +173,7 @@ "cr_input:polymer3_elements", "cr_lazy_render:cr_lazy_render_module", "cr_link_row:cr_link_row_module", + "cr_lottie:cr_lottie_module", "cr_profile_avatar_selector:polymer3_elements", "cr_radio_button:polymer3_elements", "cr_radio_group:cr_radio_group_module",
diff --git a/ui/webui/resources/cr_elements/chromeos/BUILD.gn b/ui/webui/resources/cr_elements/chromeos/BUILD.gn index ce4559bd..33cc937 100644 --- a/ui/webui/resources/cr_elements/chromeos/BUILD.gn +++ b/ui/webui/resources/cr_elements/chromeos/BUILD.gn
@@ -9,7 +9,6 @@ group("closure_compile") { deps = [ - "cr_lottie:closure_compile", "cr_picture:closure_compile", # Targets for auto-generated Polymer3/JS Modules
diff --git a/ui/webui/resources/cr_elements/chromeos/cr_lottie/BUILD.gn b/ui/webui/resources/cr_elements/chromeos/cr_lottie/BUILD.gn deleted file mode 100644 index e7927334..0000000 --- a/ui/webui/resources/cr_elements/chromeos/cr_lottie/BUILD.gn +++ /dev/null
@@ -1,10 +0,0 @@ -import("//third_party/closure_compiler/compile_js.gni") - -js_type_check("closure_compile") { - deps = [ ":cr_lottie" ] -} - -js_library("cr_lottie") { - deps = [ "//ui/webui/resources/js:cr" ] - externs_list = [ "$externs_path/pending.js" ] -}
diff --git a/ui/webui/resources/cr_elements/cr_lottie/BUILD.gn b/ui/webui/resources/cr_elements/cr_lottie/BUILD.gn new file mode 100644 index 0000000..d6fac4a --- /dev/null +++ b/ui/webui/resources/cr_elements/cr_lottie/BUILD.gn
@@ -0,0 +1,42 @@ +# 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. + +import("//third_party/closure_compiler/compile_js.gni") +import("//tools/polymer/polymer.gni") + +js_type_check("closure_compile") { + deps = [ ":cr_lottie" ] +} + +js_library("cr_lottie") { + deps = [ + "//ui/webui/resources/js:assert", + "//ui/webui/resources/js:cr", + ] + externs_list = [ "$externs_path/pending.js" ] +} + +polymer_modulizer("cr_lottie") { + js_file = "cr_lottie.js" + html_file = "cr_lottie.html" + html_type = "dom-module" + auto_imports = [ "ui/webui/resources/html/assert.html|assert" ] +} + +js_type_check("closure_compile_module") { + is_polymer3 = true + deps = [ ":cr_lottie.m" ] +} + +js_library("cr_lottie.m") { + sources = [ + "$root_gen_dir/ui/webui/resources/cr_elements/cr_lottie/cr_lottie.m.js", + ] + deps = [ + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:assert.m", + ] + extra_deps = [ ":cr_lottie_module" ] + externs_list = [ "$externs_path/pending.js" ] +}
diff --git a/ui/webui/resources/cr_elements/chromeos/cr_lottie/cr_lottie.html b/ui/webui/resources/cr_elements/cr_lottie/cr_lottie.html similarity index 68% rename from ui/webui/resources/cr_elements/chromeos/cr_lottie/cr_lottie.html rename to ui/webui/resources/cr_elements/cr_lottie/cr_lottie.html index 5cad057..b6510ba4 100644 --- a/ui/webui/resources/cr_elements/chromeos/cr_lottie/cr_lottie.html +++ b/ui/webui/resources/cr_elements/cr_lottie/cr_lottie.html
@@ -1,5 +1,5 @@ -<link rel="import" href="../../../html/assert.html"> -<link rel="import" href="../../../html/polymer.html"> +<link rel="import" href="../../html/assert.html"> +<link rel="import" href="../../html/polymer.html"> <dom-module id="cr-lottie"> <template>
diff --git a/ui/webui/resources/cr_elements/chromeos/cr_lottie/cr_lottie.js b/ui/webui/resources/cr_elements/cr_lottie/cr_lottie.js similarity index 97% rename from ui/webui/resources/cr_elements/chromeos/cr_lottie/cr_lottie.js rename to ui/webui/resources/cr_elements/cr_lottie/cr_lottie.js index 2e65ac5..7100161 100644 --- a/ui/webui/resources/cr_elements/chromeos/cr_lottie/cr_lottie.js +++ b/ui/webui/resources/cr_elements/cr_lottie/cr_lottie.js
@@ -4,7 +4,8 @@ /** * @fileoverview 'cr-lottie' is a wrapper around the player for lottie - * animations. + * animations. Since the player runs on a worker thread, 'cr-lottie' requires + * the document CSP to be set to "worker-src blob: 'self';". * Fires a 'cr-lottie-initialized' event when the animation was successfully * initialized. * Fires a 'cr-lottie-playing' event when the animation starts playing.
diff --git a/ui/webui/resources/cr_elements_resources.grdp b/ui/webui/resources/cr_elements_resources.grdp index 297b652..8412a9d 100644 --- a/ui/webui/resources/cr_elements_resources.grdp +++ b/ui/webui/resources/cr_elements_resources.grdp
@@ -223,15 +223,15 @@ file="cr_elements/chromeos/cr_picture/icons.html" type="chrome_html" compress="gzip" /> - <structure name="IDR_CR_ELEMENTS_CHROMEOS_CR_LOTTIE_HTML" - file="cr_elements/chromeos/cr_lottie/cr_lottie.html" - type="chrome_html" - compress="gzip" /> - <structure name="IDR_CR_ELEMENTS_CHROMEOS_CR_LOTTIE_JS" - file="cr_elements/chromeos/cr_lottie/cr_lottie.js" - type="chrome_html" - compress="gzip" /> </if> + <structure name="IDR_CR_ELEMENTS_CR_LOTTIE_HTML" + file="cr_elements/cr_lottie/cr_lottie.html" + type="chrome_html" + compress="gzip" /> + <structure name="IDR_CR_ELEMENTS_CR_LOTTIE_JS" + file="cr_elements/cr_lottie/cr_lottie.js" + type="chrome_html" + compress="gzip" /> <structure name="IDR_CR_ELEMENTS_CR_POLICY_INDICATOR_HTML" file="cr_elements/policy/cr_policy_indicator.html" type="chrome_html"
diff --git a/ui/webui/resources/cr_elements_resources_v3.grdp b/ui/webui/resources/cr_elements_resources_v3.grdp index 5b3873f..21351ddf 100644 --- a/ui/webui/resources/cr_elements_resources_v3.grdp +++ b/ui/webui/resources/cr_elements_resources_v3.grdp
@@ -253,4 +253,9 @@ type="BINDATA" compress="gzip" /> </if> + <include name="IDR_CR_ELEMENTS_LOTTIE_M_JS" + file="${root_gen_dir}/ui/webui/resources/cr_elements/cr_lottie/cr_lottie.m.js" + use_base_dir="false" + type="BINDATA" + compress="gzip" /> </grit-part>
diff --git a/ui/webui/resources/webui_resources.grd b/ui/webui/resources/webui_resources.grd index 2fc7d8699..4ef5362 100644 --- a/ui/webui/resources/webui_resources.grd +++ b/ui/webui/resources/webui_resources.grd
@@ -452,7 +452,7 @@ compress="gzip" /> </if> - <if expr="chromeos"> + <if expr="not is_android and not is_ios"> <structure name="IDR_LOTTIE_LOTTIE_WORKER_MIN_JS" file="../../../third_party/lottie/lottie_worker.min.js" type="chrome_html"
diff --git a/weblayer/BUILD.gn b/weblayer/BUILD.gn index ceb8fa638..e4a5b42 100644 --- a/weblayer/BUILD.gn +++ b/weblayer/BUILD.gn
@@ -452,6 +452,7 @@ "//android_webview:generate_aw_strings", "//components/android_system_error_page", "//components/autofill/android:provider", + "//components/browser_ui/site_settings/android", "//components/cdm/browser", "//components/content_settings/android", "//components/crash/android:crash_android",
diff --git a/weblayer/browser/android/javatests/BUILD.gn b/weblayer/browser/android/javatests/BUILD.gn index cbf538c..3492e50 100644 --- a/weblayer/browser/android/javatests/BUILD.gn +++ b/weblayer/browser/android/javatests/BUILD.gn
@@ -88,6 +88,8 @@ sources = [ "src/org/chromium/weblayer/test/BoundedCountDownLatch.java", "src/org/chromium/weblayer/test/InstrumentationActivityTestRule.java", + "src/org/chromium/weblayer/test/MinWebLayerVersion.java", + "src/org/chromium/weblayer/test/MinWebLayerVersionSkipCheck.java", "src/org/chromium/weblayer/test/NavigationWaiter.java", "src/org/chromium/weblayer/test/ResourceUtil.java", "src/org/chromium/weblayer/test/WebLayerJUnit4ClassRunner.java", @@ -182,7 +184,14 @@ android_test_apk("weblayer_bundle_test_apk") { apk_name = "WebLayerBundleTest" android_manifest = "AndroidManifest_bundle.xml" - sources = [ "src/org/chromium/weblayer/test/BundleLanguageTest.java" ] + sources = [ + "src/org/chromium/weblayer/test/BundleLanguageTest.java", + + # This is run both in the bundle tests and the standard instrumentation + # tests to make sure bundles don't do anything weird with WebLayer/WebView + # compatibility. + "src/org/chromium/weblayer/test/WebViewCompatibilityTest.java", + ] deps = [ ":weblayer_java_test_support", "//third_party/android_support_test_runner:rules_java", @@ -210,5 +219,7 @@ ] android_test_apk = ":weblayer_bundle_test_apk" android_test_apk_name = "WebLayerBundleTest" + additional_apks = [ "//net/android:net_test_support_apk" ] + data = [ "//weblayer/test/data/" ] never_incremental = true }
diff --git a/weblayer/browser/android/javatests/skew/expectations.txt b/weblayer/browser/android/javatests/skew/expectations.txt index 701d99a..8c36a0b7 100644 --- a/weblayer/browser/android/javatests/skew/expectations.txt +++ b/weblayer/browser/android/javatests/skew/expectations.txt
@@ -11,16 +11,6 @@ # Tests against older WebLayer implementations. # --------------------------------------------- -# Cookie manager was added in M83. -[ impl_lte_82 ] org.chromium.weblayer.test.CookieManagerTest#testCookieChanged [ Skip ] -[ impl_lte_82 ] org.chromium.weblayer.test.CookieManagerTest#testCookieChangedRemoveCallback [ Skip ] -[ impl_lte_82 ] org.chromium.weblayer.test.CookieManagerTest#testCookieChangedRemoveCallbackAfterProfileDestroyed [ Skip ] -[ impl_lte_82 ] org.chromium.weblayer.test.CookieManagerTest#testGetCookie [ Skip ] -[ impl_lte_82 ] org.chromium.weblayer.test.CookieManagerTest#testSetCookie [ Skip ] -[ impl_lte_82 ] org.chromium.weblayer.test.CookieManagerTest#testSetCookieInvalid [ Skip ] -[ impl_lte_82 ] org.chromium.weblayer.test.CookieManagerTest#testSetCookieNotSet [ Skip ] -[ impl_lte_82 ] org.chromium.weblayer.test.CookieManagerTest#testSetCookieNullCallback [ Skip ] - # Strict mode violation was fixed in M83 in https://crrev.com/c/2108603. [ impl_lte_82 ] org.chromium.weblayer.test.InputTypesTest#testColorInput [ Skip ] @@ -35,22 +25,12 @@ [ impl_lte_83 ] org.chromium.weblayer.test.TabTest#testBeforeUnloadNoHandler [ Skip ] [ impl_lte_83 ] org.chromium.weblayer.test.TabTest#testBeforeUnloadNoInteraction [ Skip ] -# Implemented in https://crrev.com/c/2170425. -[ impl_lte_83 ] org.chromium.weblayer.test.TabTest#testCaptureScreenShot [ Skip ] -[ impl_lte_83 ] org.chromium.weblayer.test.TabTest#testCaptureScreenShotDoesNotHang [ Skip ] - -# New API added in crbug.com/1033029. -[ impl_lte_83 ] org.chromium.weblayer.test.WebLayerTest#getUserAgentString [ Skip ] - # Replace was removed in https://crrev.com/c/2150968, see https://crbug.com/1070851. [ impl_lte_83 ] org.chromium.weblayer.test.NavigationTest#testReplace [ Skip ] # Fixed in https://crrev.com/c/2180022, see https://crbug.com/1077243. [ impl_lte_83 ] org.chromium.weblayer.test.FullscreenCallbackTest#testExitFullscreenWhenTabDestroyed [ Skip ] -# Implemented in https://crrev.com/f933c913dd25657b0d6ed6201f14 -[ impl_lte_81 ] org.chromium.weblayer.test.FindInPageTest#testHideOnNavigate [ Skip ] - # https://crbug.com/1079489. [ impl_lte_83 ] org.chromium.weblayer.test.BottomControlsTest#testBasic [ Skip ] [ impl_lte_83 ] org.chromium.weblayer.test.BottomControlsTest#testNoTopControl [ Skip ] @@ -58,9 +38,6 @@ # https://crbug.com/1079491. [ impl_lte_83 ] org.chromium.weblayer.test.NavigationTest#testSetUserAgentString [ Skip ] -# Implemented in https://crrev.com/0193f6791133ee7a90d034aa4009 -[ impl_lte_81 ] org.chromium.weblayer.test.TabTest#testBeforeUnload [ Skip ] - # DownloadCallback moved from Tab to Profile in M83: https://crrev.com/cc967e92032594c0e54d02e31824f92aff5f30cd [ impl_lte_82 ] org.chromium.weblayer.test.DownloadCallbackTest#testBasic [ Skip ] [ impl_lte_82 ] org.chromium.weblayer.test.DownloadCallbackTest#testInterceptDownloadByContentDisposition [ Skip ]
diff --git a/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/CookieManagerTest.java b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/CookieManagerTest.java index a9be620..1b59f76 100644 --- a/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/CookieManagerTest.java +++ b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/CookieManagerTest.java
@@ -46,6 +46,7 @@ @Test @SmallTest + @MinWebLayerVersion(83) public void testSetCookie() throws Exception { Assert.assertTrue(setCookie("foo=bar")); @@ -57,6 +58,7 @@ @Test @SmallTest + @MinWebLayerVersion(83) public void testSetCookieInvalid() throws Exception { TestThreadUtils.runOnUiThreadBlocking(() -> { try { @@ -70,12 +72,14 @@ @Test @SmallTest + @MinWebLayerVersion(83) public void testSetCookieNotSet() throws Exception { Assert.assertFalse(setCookie("foo=bar; Secure")); } @Test @SmallTest + @MinWebLayerVersion(83) public void testSetCookieNullCallback() throws Exception { TestThreadUtils.runOnUiThreadBlocking( () -> { mCookieManager.setCookie(mBaseUri, "foo=bar", null); }); @@ -91,6 +95,7 @@ @Test @SmallTest + @MinWebLayerVersion(83) public void testGetCookie() throws Exception { Assert.assertEquals(getCookie(), ""); Assert.assertTrue(setCookie("foo=")); @@ -101,6 +106,7 @@ @Test @SmallTest + @MinWebLayerVersion(83) public void testCookieChanged() throws Exception { CookieChangedCallbackHelper helper = new CookieChangedCallbackHelper(); TestThreadUtils.runOnUiThreadBlocking( @@ -121,6 +127,7 @@ @Test @SmallTest + @MinWebLayerVersion(83) public void testCookieChangedRemoveCallback() throws Exception { CookieChangedCallbackHelper helper = new CookieChangedCallbackHelper(); Runnable remove = TestThreadUtils.runOnUiThreadBlocking(() -> { @@ -143,6 +150,7 @@ @Test @SmallTest + @MinWebLayerVersion(83) public void testCookieChangedRemoveCallbackAfterProfileDestroyed() throws Exception { // Removing change callback should be a no-op after the profile is destroyed. TestThreadUtils.runOnUiThreadBlocking(() -> {
diff --git a/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/FindInPageTest.java b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/FindInPageTest.java index 2c5b08f6..38f466a 100644 --- a/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/FindInPageTest.java +++ b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/FindInPageTest.java
@@ -127,6 +127,7 @@ @Test @SmallTest + @MinWebLayerVersion(82) public void testHideOnNavigate() { setUp("shakespeare.html");
diff --git a/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/MinWebLayerVersion.java b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/MinWebLayerVersion.java new file mode 100644 index 0000000..db4f789 --- /dev/null +++ b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/MinWebLayerVersion.java
@@ -0,0 +1,18 @@ +// 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.weblayer.test; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Inherited +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.TYPE}) +public @interface MinWebLayerVersion { + int value() default 0; +}
diff --git a/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/MinWebLayerVersionSkipCheck.java b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/MinWebLayerVersionSkipCheck.java new file mode 100644 index 0000000..b8381c5f --- /dev/null +++ b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/MinWebLayerVersionSkipCheck.java
@@ -0,0 +1,45 @@ +// 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.weblayer.test; + +import org.junit.runners.model.FrameworkMethod; + +import org.chromium.base.CommandLine; +import org.chromium.base.Log; +import org.chromium.base.test.util.AnnotationProcessingUtils; +import org.chromium.base.test.util.SkipCheck; + +/** + * Checks the WebLayer version against any specified minimum requirement. + */ +public class MinWebLayerVersionSkipCheck extends SkipCheck { + private static final String TAG = "MinWebLayerVersionSC"; + + /** + * If {@link MinWebLayerVersion} is present, checks its value + * against the WebLayer version. + * + * @param testCase The test to check. + * @return true if WebLayer's version is below the specified minimum. + */ + @Override + public boolean shouldSkip(FrameworkMethod frameworkMethod) { + int minWebLayerVersion = 0; + for (MinWebLayerVersion m : AnnotationProcessingUtils.getAnnotations( + frameworkMethod.getMethod(), MinWebLayerVersion.class)) { + minWebLayerVersion = Math.max(minWebLayerVersion, m.value()); + } + String stringVersion = CommandLine.getInstance().getSwitchValue("impl-version", "-1"); + int version = Integer.valueOf(stringVersion); + if (version != -1 && version < minWebLayerVersion) { + Log.i(TAG, + "Test " + frameworkMethod.getDeclaringClass().getName() + "#" + + frameworkMethod.getName() + " is not enabled at WebLayer version " + + version + "."); + return true; + } + return false; + } +}
diff --git a/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/TabTest.java b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/TabTest.java index d786454..89b3670 100644 --- a/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/TabTest.java +++ b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/TabTest.java
@@ -33,6 +33,7 @@ @Test @SmallTest + @MinWebLayerVersion(82) public void testBeforeUnload() { String url = mActivityTestRule.getTestDataURL("before_unload.html"); mActivity = mActivityTestRule.launchShellWithUrl(url); @@ -137,6 +138,7 @@ @Test @SmallTest + @MinWebLayerVersion(84) public void testCaptureScreenShot() throws TimeoutException { String url = mActivityTestRule.getTestDataURL("quadrant_colors.html"); mActivity = mActivityTestRule.launchShellWithUrl(url); @@ -153,6 +155,7 @@ @Test @SmallTest + @MinWebLayerVersion(84) public void testCaptureScreenShotDoesNotHang() throws TimeoutException { String startupUrl = "about:blank"; mActivity = mActivityTestRule.launchShellWithUrl(startupUrl);
diff --git a/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/WebLayerJUnit4ClassRunner.java b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/WebLayerJUnit4ClassRunner.java index bc59e72f..ff0c7bb 100644 --- a/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/WebLayerJUnit4ClassRunner.java +++ b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/WebLayerJUnit4ClassRunner.java
@@ -10,6 +10,7 @@ import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.BaseTestResult.PreTestHook; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.SkipCheck; import java.util.List; @@ -35,6 +36,11 @@ } @Override + protected List<SkipCheck> getSkipChecks() { + return addToList(super.getSkipChecks(), new MinWebLayerVersionSkipCheck()); + } + + @Override protected void initCommandLineForTest() { CommandLineInitUtil.initCommandLine(CommandLineFlags.getTestCmdLineFile()); }
diff --git a/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/WebLayerTest.java b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/WebLayerTest.java index 0ea7038..16a67160 100644 --- a/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/WebLayerTest.java +++ b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/WebLayerTest.java
@@ -24,6 +24,7 @@ @Test @SmallTest + @MinWebLayerVersion(84) public void getUserAgentString() { final String userAgent = TestThreadUtils.runOnUiThreadBlockingNoException( () -> { return mActivityTestRule.getWebLayer().getUserAgentString(); });
diff --git a/weblayer/browser/android/javatests/weblayer_instrumentation_test_versions.py b/weblayer/browser/android/javatests/weblayer_instrumentation_test_versions.py index 07ba5e9..87286c1 100755 --- a/weblayer/browser/android/javatests/weblayer_instrumentation_test_versions.py +++ b/weblayer/browser/android/javatests/weblayer_instrumentation_test_versions.py
@@ -182,8 +182,14 @@ '--additional-apk', os.path.join(args.client_outdir, 'apks/ChromiumNetTestSupport.apk')] - cmd = [executable_path] + executable_args + remaining_args - cmd = [sys.executable] + cmd + cmd = [sys.executable, executable_path] + executable_args + remaining_args + + # Pass along the implementation version if it's set so that tests can + # be filtered through the @MinWebLayerVersion annotation. + # Note: The Chrome Android command line library requires the flag be passed + # with "=" rather than as two arguments. + if args.impl_version != 'trunk': + cmd.append('--impl-version=%s' % args.impl_version) tests = [] if args.test_expectations:
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/BrowserImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/BrowserImpl.java index 509c885d..069ae28 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/BrowserImpl.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/BrowserImpl.java
@@ -24,7 +24,6 @@ import org.chromium.weblayer_private.interfaces.IBrowser; import org.chromium.weblayer_private.interfaces.IBrowserClient; import org.chromium.weblayer_private.interfaces.IObjectWrapper; -import org.chromium.weblayer_private.interfaces.IProfile; import org.chromium.weblayer_private.interfaces.ITab; import org.chromium.weblayer_private.interfaces.IUrlBarController; import org.chromium.weblayer_private.interfaces.ObjectWrapper; @@ -209,7 +208,7 @@ } @Override - public IProfile getProfile() { + public ProfileImpl getProfile() { StrictModeWorkaround.apply(); return mProfile; }
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/DownloadImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/DownloadImpl.java index e61b1ac..770416ac 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/DownloadImpl.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/DownloadImpl.java
@@ -401,7 +401,9 @@ long totalBytes = getTotalBytes(); boolean indeterminate = totalBytes == -1; int progressCurrent = -1; - if (!indeterminate) progressCurrent = (int) (bytes * 100 / totalBytes); + if (!indeterminate && totalBytes != 0) { + progressCurrent = (int) (bytes * 100 / totalBytes); + } String contentText; String bytesString = DownloadUtils.getStringForBytes(context, bytes);
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java index 6c3bc04..5bed92a 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java
@@ -35,6 +35,7 @@ import org.chromium.components.url_formatter.UrlFormatter; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.NavigationHandle; +import org.chromium.content_public.browser.SelectionClient; import org.chromium.content_public.browser.SelectionPopupController; import org.chromium.content_public.browser.ViewEventSink; import org.chromium.content_public.browser.Visibility; @@ -103,10 +104,12 @@ private FindInPageBridge mFindInPageBridge; private FindResultBar mFindResultBar; // See usage note in {@link #onFindResultAvailable}. - boolean mWaitingForMatchRects; + private boolean mWaitingForMatchRects; private InterceptNavigationDelegateClientImpl mInterceptNavigationDelegateClient; private InterceptNavigationDelegateImpl mInterceptNavigationDelegate; + private boolean mPostContainerViewInitDone; + private static class InternalAccessDelegateImpl implements ViewEventSink.InternalAccessDelegate { @Override @@ -219,6 +222,16 @@ sTabMap.put(mId, this); } + private void doInitAfterSettingContainerView() { + if (mPostContainerViewInitDone) return; + + mPostContainerViewInitDone = true; + SelectionPopupController controller = + SelectionPopupController.fromWebContents(mWebContents); + controller.setActionModeCallback(new ActionModeCallback(mWebContents)); + controller.setSelectionClient(SelectionClient.createSmartSelectionClient(mWebContents)); + } + public ProfileImpl getProfile() { return mProfile; } @@ -233,14 +246,12 @@ public void attachToBrowser(BrowserImpl browser) { mBrowser = browser; updateFromBrowser(); - SelectionPopupController controller = - SelectionPopupController.fromWebContents(mWebContents); - controller.setActionModeCallback(new ActionModeCallback(mWebContents)); } public void updateFromBrowser() { mWebContents.setTopLevelNativeWindow(mBrowser.getWindowAndroid()); mViewAndroidDelegate.setContainerView(mBrowser.getViewAndroidDelegateContainerView()); + doInitAfterSettingContainerView(); updateWebContentsVisibility(); boolean attached = (mBrowser.getContext() != null);
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/UrlBarControllerImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/UrlBarControllerImpl.java index eab5f34a..31f973d9 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/UrlBarControllerImpl.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/UrlBarControllerImpl.java
@@ -27,6 +27,7 @@ import org.chromium.components.omnibox.SecurityStatusIcon; import org.chromium.components.page_info.PageInfoController; import org.chromium.components.page_info.PageInfoControllerDelegate; +import org.chromium.components.page_info.PermissionParamsListBuilderDelegate; import org.chromium.weblayer_private.interfaces.IObjectWrapper; import org.chromium.weblayer_private.interfaces.IUrlBarController; import org.chromium.weblayer_private.interfaces.ObjectWrapper; @@ -172,7 +173,8 @@ new AutocompleteSchemeClassifierImpl(), /** vrHandler= */ null, /** isSiteSettingsAvailable= */ false, - /** cookieControlsShown= */ false)); + /** cookieControlsShown= */ false), + new PermissionParamsListBuilderDelegate(mBrowserImpl.getProfile())); } @DrawableRes
diff --git a/weblayer/grit_strings_whitelist.txt b/weblayer/grit_strings_whitelist.txt index c146d25..ec8affc4 100644 --- a/weblayer/grit_strings_whitelist.txt +++ b/weblayer/grit_strings_whitelist.txt
@@ -168,11 +168,34 @@ IDS_PAGE_INFO_SERIAL_PORT_SECONDARY_LABEL IDS_PAGE_INFO_SOCIAL_ENGINEERING_DETAILS IDS_PAGE_INFO_SOCIAL_ENGINEERING_SUMMARY +IDS_PAGE_INFO_TYPE_ADS +IDS_PAGE_INFO_TYPE_AR +IDS_PAGE_INFO_TYPE_BACKGROUND_SYNC +IDS_PAGE_INFO_TYPE_BLUETOOTH IDS_PAGE_INFO_TYPE_BLUETOOTH_SCANNING +IDS_PAGE_INFO_TYPE_CAMERA +IDS_PAGE_INFO_TYPE_CAMERA_PAN_TILT_ZOOM +IDS_PAGE_INFO_TYPE_CLIPBOARD +IDS_AUTOMATIC_DOWNLOADS_TAB_LABEL +IDS_PAGE_INFO_TYPE_FLASH +IDS_PAGE_INFO_TYPE_IMAGES +IDS_PAGE_INFO_TYPE_JAVASCRIPT +IDS_PAGE_INFO_TYPE_LOCATION +IDS_PAGE_INFO_TYPE_PROTECTED_MEDIA_IDENTIFIER +IDS_PAGE_INFO_TYPE_MIC +IDS_PAGE_INFO_TYPE_MIDI_SYSEX IDS_PAGE_INFO_TYPE_MOTION_SENSORS IDS_PAGE_INFO_TYPE_NATIVE_FILE_SYSTEM_WRITE +IDS_PAGE_INFO_TYPE_NFC +IDS_PAGE_INFO_TYPE_NOTIFICATIONS +IDS_PAGE_INFO_TYPE_POPUPS_REDIRECTS IDS_PAGE_INFO_TYPE_PROTECTED_MEDIA_IDENTIFIER IDS_PAGE_INFO_TYPE_SENSORS +IDS_PAGE_INFO_TYPE_SERIAL +IDS_PAGE_INFO_TYPE_SOUND +IDS_PAGE_INFO_TYPE_USB +IDS_PAGE_INFO_TYPE_VR +IDS_PAGE_INFO_TYPE_WINDOW_PLACEMENT IDS_PAGE_INFO_UNWANTED_SOFTWARE_DETAILS IDS_PAGE_INFO_UNWANTED_SOFTWARE_SUMMARY IDS_PAGE_INFO_USB_DEVICE_ALLOWED_BY_POLICY_LABEL