diff --git a/DEPS b/DEPS index b76ce37e..13a3814 100644 --- a/DEPS +++ b/DEPS
@@ -253,19 +253,19 @@ # 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': 'edef5d08370b5c6e4d07de6c5470ba339c9f8420', + 'skia_revision': '72a425bab711d109a9b663966eaaa1197025b0a8', # 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': '26f24ed839473cab9e9a46405895f5a8047ca173', + 'v8_revision': '4e1875f07b4c8f59714d190c6e7999115c8af430', # 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': '7ca11287a056d4150cba96c9c9b964153ad539cb', + 'angle_revision': 'cbdefd93309d9fa43ce4f6825aa4a971ae941b8c', # 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': '5f5faa3a2aad1a4cdc88633af60c4171efc022e2', + 'swiftshader_revision': '89c498edff683c68df6be0dd224848f4b4af5ae7', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -320,7 +320,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': '820618f8e66b7b805add7b2dcc17d626c2d034b7', + 'catapult_revision': '74c0bf3d684ebb866442b4c5cd7f4ba3230d67d0', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -328,7 +328,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': '1ec82bbc40ba52cdf37748634e360f8979f4d9e4', + 'devtools_frontend_revision': '70ffb7f7bd7d6a9043ac24a12bc9d3fbe504ab9b', # 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. @@ -431,7 +431,7 @@ 'libcxx_revision': '79a2e924d96e2fc1e4b937c42efd08898fa472d7', # GN CIPD package version. - 'gn_version': 'git_revision:d0f8bc99e0584cd33ea8030441d58ee875af7842', + 'gn_version': 'git_revision:ced9fbfe6943854e65ada4ac1849d1fa4cb19348', } # Only these hosts are allowed for dependencies in this DEPS file. @@ -1086,7 +1086,7 @@ # Tools used when building Chrome for Chrome OS. This affects both the Simple # Chrome workflow, as well as the chromeos-chrome ebuild. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '9d31e041e4da66cdf7a29bfde5878d2bfbe7e969', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '934e272af4e31445384aa64d349cc7a954e25f54', 'condition': 'checkout_chromeos', }, @@ -1716,7 +1716,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'd54181c886109c3e1e34930fbeb03ece2c1e56e4', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'e92378eb713f9e7fa04be79723463d7d0e3a40df', + Var('webrtc_git') + '/src.git' + '@' + 'b767350e486cb850a4e39f57b461f0cbaf25bb51', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1786,7 +1786,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@54c05a98c8d0823b927e8fe00424709fab6ae5b7', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@82e17f7a45a28363a30d0bbc9fe23ada6f44ee2e', 'condition': 'checkout_src_internal', }, @@ -1816,7 +1816,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/help_app/app', - 'version': 'x5xriSsMxbxuiMiHyvYHB3eCGl5SVUFsbXL4eLySjyoC', + 'version': '2njwfd0cp005czv-0MkLB7d72N-Qac0ngx_OhybmWyEC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -1827,7 +1827,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/media_app/app', - 'version': 'bKA01vsty7Q_1nNAqrdzNd3jAqNlNLsXdCXlT3VIhOcC', + 'version': 'AZc5cK_Jpknph6yWOLJBkz4dCAYhBiC39iHNSzocwCIC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/android_webview/browser/gfx/hardware_renderer_viz.cc b/android_webview/browser/gfx/hardware_renderer_viz.cc index 20c529d..f460fa1 100644 --- a/android_webview/browser/gfx/hardware_renderer_viz.cc +++ b/android_webview/browser/gfx/hardware_renderer_viz.cc
@@ -400,7 +400,8 @@ // ANGLE will restore GL context state for us, so we don't need to call // GrContext::resetContext(). - if (!gl::GLSurfaceEGL::IsANGLEExternalContextAndSurfaceSupported()) { + if (!gl::GLSurfaceEGL::GetGLDisplayEGL() + ->IsANGLEExternalContextAndSurfaceSupported()) { DCHECK(output_surface_provider_.shared_context_state()); output_surface_provider_.shared_context_state() ->PessimisticallyResetGrContext();
diff --git a/android_webview/browser/gfx/output_surface_provider_webview.cc b/android_webview/browser/gfx/output_surface_provider_webview.cc index 573e43e..4ecb9ec3 100644 --- a/android_webview/browser/gfx/output_surface_provider_webview.cc +++ b/android_webview/browser/gfx/output_surface_provider_webview.cc
@@ -119,8 +119,8 @@ // If EGL supports EGL_ANGLE_external_context_and_surface, then we will create // an ANGLE context for the current native GL context. const bool is_angle = - !enable_vulkan_ && - gl::GLSurfaceEGL::IsANGLEExternalContextAndSurfaceSupported(); + !enable_vulkan_ && gl::GLSurfaceEGL::GetGLDisplayEGL() + ->IsANGLEExternalContextAndSurfaceSupported(); GLSurfaceContextPair real_context; if (enable_vulkan_) {
diff --git a/android_webview/browser/gfx/scoped_app_gl_state_restore.cc b/android_webview/browser/gfx/scoped_app_gl_state_restore.cc index b4ce2d80..1289f30 100644 --- a/android_webview/browser/gfx/scoped_app_gl_state_restore.cc +++ b/android_webview/browser/gfx/scoped_app_gl_state_restore.cc
@@ -31,7 +31,8 @@ g_current_instance = this; TRACE_EVENT0("android_webview", "AppGLStateSave"); - if (gl::GLSurfaceEGL::IsANGLEExternalContextAndSurfaceSupported()) { + if (gl::GLSurfaceEGL::GetGLDisplayEGL() + ->IsANGLEExternalContextAndSurfaceSupported()) { impl_ = std::make_unique<internal::ScopedAppGLStateRestoreImplAngle>( mode, save_restore); } else {
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/services/JsSandboxServiceTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/services/JsSandboxServiceTest.java index 31d1ab7..7a9f28f 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/services/JsSandboxServiceTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/services/JsSandboxServiceTest.java
@@ -16,51 +16,33 @@ import org.chromium.android_webview.js_sandbox.client.AwJsIsolate; import org.chromium.android_webview.js_sandbox.client.AwJsSandbox; +import org.chromium.android_webview.js_sandbox.client.JsEvaluationException; import org.chromium.android_webview.test.AwJUnit4ClassRunner; import org.chromium.base.ContextUtils; -import org.chromium.base.test.util.CallbackHelper; +import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; /** Instrumentation test for JsSandboxService. */ @RunWith(AwJUnit4ClassRunner.class) public class JsSandboxServiceTest { - private class TestExecutionCallback implements AwJsIsolate.ExecutionCallback { - public CallbackHelper helper = new CallbackHelper(); - public String result; - public String error; - - @Override - public void reportResult(String result) { - this.result = result; - helper.notifyCalled(); - } - - @Override - public void reportError(String error) { - this.error = error; - helper.notifyCalled(); - } - } - @Test @MediumTest public void testSimpleJsEvaluation() throws Throwable { final String code = "'PASS'"; final String expected = "PASS"; - TestExecutionCallback callback = new TestExecutionCallback(); Context context = ContextUtils.getApplicationContext(); ListenableFuture<AwJsSandbox> awJsSandboxFuture = AwJsSandbox.newConnectedInstanceForTesting(context); AwJsSandbox jsSandbox = awJsSandboxFuture.get(5, TimeUnit.SECONDS); AwJsIsolate jsIsolate = jsSandbox.createIsolate(); - jsIsolate.evaluateJavascript(code, callback); - callback.helper.waitForCallback("Timed out waiting for reportResult() to be called", 0); + ListenableFuture<String> resultFuture = jsIsolate.evaluateJavascript(code); + String result = resultFuture.get(5, TimeUnit.SECONDS); jsIsolate.close(); jsSandbox.close(); - Assert.assertEquals(expected, callback.result); + Assert.assertEquals(expected, result); } @Test @@ -68,7 +50,6 @@ public void testClosingOneIsolate() throws Throwable { final String code = "'PASS'"; final String expected = "PASS"; - TestExecutionCallback callback = new TestExecutionCallback(); Context context = ContextUtils.getApplicationContext(); ListenableFuture<AwJsSandbox> awJsSandboxFuture = @@ -77,12 +58,12 @@ AwJsIsolate jsIsolate1 = jsSandbox.createIsolate(); AwJsIsolate jsIsolate2 = jsSandbox.createIsolate(); jsIsolate1.close(); - jsIsolate2.evaluateJavascript(code, callback); - callback.helper.waitForCallback("Timed out waiting for reportResult() to be called", 0); + ListenableFuture<String> resultFuture = jsIsolate2.evaluateJavascript(code); + String result = resultFuture.get(5, TimeUnit.SECONDS); jsIsolate2.close(); jsSandbox.close(); - Assert.assertEquals(expected, callback.result); + Assert.assertEquals(expected, result); } @Test @@ -92,28 +73,24 @@ final String expected1 = "PASS"; final String code2 = "this.x = 'SUPER_PASS';\n"; final String expected2 = "SUPER_PASS"; - TestExecutionCallback callback1 = new TestExecutionCallback(); - TestExecutionCallback callback2 = new TestExecutionCallback(); + Context context = ContextUtils.getApplicationContext(); ListenableFuture<AwJsSandbox> awJsSandboxFuture = AwJsSandbox.newConnectedInstanceForTesting(context); AwJsSandbox jsSandbox = awJsSandboxFuture.get(5, TimeUnit.SECONDS); AwJsIsolate jsIsolate1 = jsSandbox.createIsolate(); - jsIsolate1.evaluateJavascript(code1, callback1); + ListenableFuture<String> resultFuture1 = jsIsolate1.evaluateJavascript(code1); + String result1 = resultFuture1.get(5, TimeUnit.SECONDS); AwJsIsolate jsIsolate2 = jsSandbox.createIsolate(); - jsIsolate2.evaluateJavascript(code2, callback2); - - callback1.helper.waitForCallback( - "Timed out waiting for reportResult() to be called for first case", 0); - callback2.helper.waitForCallback( - "Timed out waiting for reportResult() to be called for second case", 0); + ListenableFuture<String> resultFuture2 = jsIsolate2.evaluateJavascript(code2); + String result2 = resultFuture2.get(5, TimeUnit.SECONDS); jsIsolate1.close(); jsIsolate2.close(); jsSandbox.close(); - Assert.assertEquals(expected1, callback1.result); - Assert.assertEquals(expected2, callback2.result); + Assert.assertEquals(expected1, result1); + Assert.assertEquals(expected2, result2); } @Test @@ -123,28 +100,23 @@ final String expected1 = "PASS"; final String code2 = "this.y = this.y + ' PASS';\n"; final String expected2 = "undefined PASS"; - TestExecutionCallback callback1 = new TestExecutionCallback(); - TestExecutionCallback callback2 = new TestExecutionCallback(); Context context = ContextUtils.getApplicationContext(); ListenableFuture<AwJsSandbox> awJsSandboxFuture = AwJsSandbox.newConnectedInstanceForTesting(context); AwJsSandbox jsSandbox = awJsSandboxFuture.get(5, TimeUnit.SECONDS); AwJsIsolate jsIsolate1 = jsSandbox.createIsolate(); - jsIsolate1.evaluateJavascript(code1, callback1); + ListenableFuture<String> resultFuture1 = jsIsolate1.evaluateJavascript(code1); + String result1 = resultFuture1.get(5, TimeUnit.SECONDS); AwJsIsolate jsIsolate2 = jsSandbox.createIsolate(); - jsIsolate2.evaluateJavascript(code2, callback2); - - callback1.helper.waitForCallback( - "Timed out waiting for reportResult() to be called for first case", 0); - callback2.helper.waitForCallback( - "Timed out waiting for reportResult() to be called for second case", 0); + ListenableFuture<String> resultFuture2 = jsIsolate2.evaluateJavascript(code2); + String result2 = resultFuture2.get(5, TimeUnit.SECONDS); jsIsolate1.close(); jsIsolate2.close(); jsSandbox.close(); - Assert.assertEquals(expected1, callback1.result); - Assert.assertEquals(expected2, callback2.result); + Assert.assertEquals(expected1, result1); + Assert.assertEquals(expected2, result2); } @Test @@ -154,25 +126,21 @@ final String expected1 = "PASS"; final String code2 = "this.z = this.z + ' PASS';\n"; final String expected2 = "PASS PASS"; - TestExecutionCallback callback1 = new TestExecutionCallback(); - TestExecutionCallback callback2 = new TestExecutionCallback(); Context context = ContextUtils.getApplicationContext(); ListenableFuture<AwJsSandbox> awJsSandboxFuture = AwJsSandbox.newConnectedInstanceForTesting(context); AwJsSandbox jsSandbox = awJsSandboxFuture.get(5, TimeUnit.SECONDS); AwJsIsolate jsIsolate1 = jsSandbox.createIsolate(); - jsIsolate1.evaluateJavascript(code1, callback1); - jsIsolate1.evaluateJavascript(code2, callback2); - callback1.helper.waitForCallback( - "Timed out waiting for reportResult() to be called for first case", 0); - callback2.helper.waitForCallback( - "Timed out waiting for reportResult() to be called for second case", 0); + ListenableFuture<String> resultFuture1 = jsIsolate1.evaluateJavascript(code1); + String result1 = resultFuture1.get(5, TimeUnit.SECONDS); + ListenableFuture<String> resultFuture2 = jsIsolate1.evaluateJavascript(code2); + String result2 = resultFuture2.get(5, TimeUnit.SECONDS); jsIsolate1.close(); jsSandbox.close(); - Assert.assertEquals(expected1, callback1.result); - Assert.assertEquals(expected2, callback2.result); + Assert.assertEquals(expected1, result1); + Assert.assertEquals(expected2, result2); } @Test @@ -180,18 +148,26 @@ public void testJsEvaluationError() throws Throwable { final String code = "."; final String contains = "SyntaxError"; - TestExecutionCallback callback = new TestExecutionCallback(); Context context = ContextUtils.getApplicationContext(); ListenableFuture<AwJsSandbox> awJsSandboxFuture = AwJsSandbox.newConnectedInstanceForTesting(context); AwJsSandbox jsSandbox = awJsSandboxFuture.get(5, TimeUnit.SECONDS); AwJsIsolate jsIsolate = jsSandbox.createIsolate(); - jsIsolate.evaluateJavascript(code, callback); - callback.helper.waitForCallback("Timed out waiting for reportError() to be called", 0); + ListenableFuture<String> resultFuture = jsIsolate.evaluateJavascript(code); + boolean isOfTypeJsEvaluationException = false; + String error = ""; + try { + String result = resultFuture.get(5, TimeUnit.SECONDS); + } catch (ExecutionException e) { + isOfTypeJsEvaluationException = + e.getCause().getClass().equals(JsEvaluationException.class); + error = e.getCause().getMessage(); + } jsIsolate.close(); jsSandbox.close(); - Assert.assertTrue(callback.error.contains(contains)); + Assert.assertTrue(isOfTypeJsEvaluationException); + Assert.assertTrue(error.contains(contains)); } }
diff --git a/android_webview/js_sandbox/BUILD.gn b/android_webview/js_sandbox/BUILD.gn index d1f9e7a..b23af3c 100644 --- a/android_webview/js_sandbox/BUILD.gn +++ b/android_webview/js_sandbox/BUILD.gn
@@ -44,6 +44,7 @@ sources = [ "java/src/org/chromium/android_webview/js_sandbox/client/AwJsIsolate.java", "java/src/org/chromium/android_webview/js_sandbox/client/AwJsSandbox.java", + "java/src/org/chromium/android_webview/js_sandbox/client/JsEvaluationException.java", "java/src/org/chromium/android_webview/js_sandbox/common/ExecutionErrorTypes.java", ]
diff --git a/android_webview/js_sandbox/java/src/org/chromium/android_webview/js_sandbox/client/AwJsIsolate.java b/android_webview/js_sandbox/java/src/org/chromium/android_webview/js_sandbox/client/AwJsIsolate.java index 7902724..c79db5f8 100644 --- a/android_webview/js_sandbox/java/src/org/chromium/android_webview/js_sandbox/client/AwJsIsolate.java +++ b/android_webview/js_sandbox/java/src/org/chromium/android_webview/js_sandbox/client/AwJsIsolate.java
@@ -8,24 +8,45 @@ import android.os.RemoteException; import android.util.Log; +import androidx.concurrent.futures.CallbackToFutureAdapter; + +import com.google.common.util.concurrent.ListenableFuture; + import org.chromium.android_webview.js_sandbox.common.ExecutionErrorTypes; import org.chromium.android_webview.js_sandbox.common.IJsSandboxIsolate; import org.chromium.android_webview.js_sandbox.common.IJsSandboxIsolateCallback; +import java.util.concurrent.Executor; + /** Provides a sandboxed execution Isolate. */ public class AwJsIsolate implements AutoCloseable { private static final String TAG = "AwJsIsolate"; private IJsSandboxIsolate mJsIsolateStub; private android.util.CloseGuard mGuard; + private Executor mExecutor; - /** Used to report the results of the JS evaluation. */ - public interface ExecutionCallback { - void reportResult(String result); + private static class IJsSandboxIsolateCallbackStubWrapper + extends IJsSandboxIsolateCallback.Stub { + private CallbackToFutureAdapter.Completer mCompleter; - void reportError(String error); + IJsSandboxIsolateCallbackStubWrapper(CallbackToFutureAdapter.Completer completer) { + mCompleter = completer; + } + + @Override + public void reportResult(String result) { + mCompleter.set(result); + } + + @Override + public void reportError(@ExecutionErrorTypes int type, String error) { + assert type == IJsSandboxIsolateCallback.JS_EVALUATION_ERROR; + mCompleter.setException(new JsEvaluationException(error)); + } } - AwJsIsolate(IJsSandboxIsolate jsIsolateStub) { + AwJsIsolate(IJsSandboxIsolate jsIsolateStub, Executor executor) { + mExecutor = executor; mJsIsolateStub = jsIsolateStub; if (Build.VERSION.SDK_INT >= 30) { mGuard = new android.util.CloseGuard(); @@ -35,31 +56,27 @@ } /** - * Evaluates the Javascript code and calls the callback with the result of the execution. + * Evaluates the Javascript code and returns a ListenableFuture for the result of execution. * TODO(crbug.com/1297672): Add timeouts for requests. */ - public void evaluateJavascript(String code, ExecutionCallback callback) { + public ListenableFuture<String> evaluateJavascript(String code) { if (mJsIsolateStub == null) { throw new IllegalStateException( "Calling evaluateJavascript() after closing the Isolate"); } - IJsSandboxIsolateCallback.Stub callbackStub = new IJsSandboxIsolateCallback.Stub() { - @Override - public void reportResult(String result) { - callback.reportResult(result); + + return CallbackToFutureAdapter.getFuture(completer -> { + IJsSandboxIsolateCallbackStubWrapper callbackStub = + new IJsSandboxIsolateCallbackStubWrapper(completer); + try { + mJsIsolateStub.evaluateJavascript(code, callbackStub); + } catch (RemoteException e) { + completer.setException(e.rethrowAsRuntimeException()); } - @Override - public void reportError(@ExecutionErrorTypes int type, String error) { - assert type == IJsSandboxIsolateCallback.JS_EVALUATION_ERROR; - callback.reportError(error); - } - }; - try { - mJsIsolateStub.evaluateJavascript(code, callbackStub); - } catch (RemoteException e) { - throw e.rethrowAsRuntimeException(); - } + // Debug string. + return "evaluateJavascript Future"; + }); } @Override
diff --git a/android_webview/js_sandbox/java/src/org/chromium/android_webview/js_sandbox/client/AwJsSandbox.java b/android_webview/js_sandbox/java/src/org/chromium/android_webview/js_sandbox/client/AwJsSandbox.java index 8a390b9..b29074b 100644 --- a/android_webview/js_sandbox/java/src/org/chromium/android_webview/js_sandbox/client/AwJsSandbox.java +++ b/android_webview/js_sandbox/java/src/org/chromium/android_webview/js_sandbox/client/AwJsSandbox.java
@@ -163,7 +163,13 @@ } try { IJsSandboxIsolate isolateStub = mJsSandboxService.createIsolate(); - return new AwJsIsolate(isolateStub); + Executor mainExecutor; + if (Build.VERSION.SDK_INT >= 28) { + mainExecutor = mConnection.mContext.getMainExecutor(); + } else { + mainExecutor = ContextCompat.getMainExecutor(mConnection.mContext); + } + return new AwJsIsolate(isolateStub, mainExecutor); } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); }
diff --git a/android_webview/js_sandbox/java/src/org/chromium/android_webview/js_sandbox/client/JsEvaluationException.java b/android_webview/js_sandbox/java/src/org/chromium/android_webview/js_sandbox/client/JsEvaluationException.java new file mode 100644 index 0000000..860d1a6 --- /dev/null +++ b/android_webview/js_sandbox/java/src/org/chromium/android_webview/js_sandbox/client/JsEvaluationException.java
@@ -0,0 +1,12 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.android_webview.js_sandbox.client; + +/** Wrapper for the exception thrown by the JS evaluation engine. */ +public class JsEvaluationException extends Exception { + public JsEvaluationException(String error) { + super(error); + } +}
diff --git a/android_webview/js_sandbox/javatests/src/org/chromium/webview_js_sandbox_test/test/WebViewJsSandboxTest.java b/android_webview/js_sandbox/javatests/src/org/chromium/webview_js_sandbox_test/test/WebViewJsSandboxTest.java index f286625f..4427fd2 100644 --- a/android_webview/js_sandbox/javatests/src/org/chromium/webview_js_sandbox_test/test/WebViewJsSandboxTest.java +++ b/android_webview/js_sandbox/javatests/src/org/chromium/webview_js_sandbox_test/test/WebViewJsSandboxTest.java
@@ -16,50 +16,32 @@ import org.chromium.android_webview.js_sandbox.client.AwJsIsolate; import org.chromium.android_webview.js_sandbox.client.AwJsSandbox; +import org.chromium.android_webview.js_sandbox.client.JsEvaluationException; import org.chromium.base.ContextUtils; import org.chromium.base.test.BaseJUnit4ClassRunner; -import org.chromium.base.test.util.CallbackHelper; +import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; /** Instrumentation test for JsSandboxService. */ @RunWith(BaseJUnit4ClassRunner.class) public class WebViewJsSandboxTest { - private class TestExecutionCallback implements AwJsIsolate.ExecutionCallback { - public CallbackHelper helper = new CallbackHelper(); - public String result; - public String error; - - @Override - public void reportResult(String result) { - this.result = result; - helper.notifyCalled(); - } - - @Override - public void reportError(String error) { - this.error = error; - helper.notifyCalled(); - } - } - @Test @MediumTest public void testSimpleJsEvaluation() throws Throwable { final String code = "'PASS'"; final String expected = "PASS"; - TestExecutionCallback callback = new TestExecutionCallback(); Context context = ContextUtils.getApplicationContext(); ListenableFuture<AwJsSandbox> awJsSandboxFuture = AwJsSandbox.newConnectedInstance(context); AwJsSandbox jsSandbox = awJsSandboxFuture.get(5, TimeUnit.SECONDS); AwJsIsolate jsIsolate = jsSandbox.createIsolate(); - jsIsolate.evaluateJavascript(code, callback); - callback.helper.waitForCallback("Timed out waiting for reportResult() to be called", 0); + ListenableFuture<String> resultFuture = jsIsolate.evaluateJavascript(code); + String result = resultFuture.get(5, TimeUnit.SECONDS); jsIsolate.close(); jsSandbox.close(); - Assert.assertEquals(expected, callback.result); + Assert.assertEquals(expected, result); } @Test @@ -67,7 +49,6 @@ public void testClosingOneIsolate() throws Throwable { final String code = "'PASS'"; final String expected = "PASS"; - TestExecutionCallback callback = new TestExecutionCallback(); Context context = ContextUtils.getApplicationContext(); ListenableFuture<AwJsSandbox> awJsSandboxFuture = AwJsSandbox.newConnectedInstance(context); @@ -75,12 +56,12 @@ AwJsIsolate jsIsolate1 = jsSandbox.createIsolate(); AwJsIsolate jsIsolate2 = jsSandbox.createIsolate(); jsIsolate1.close(); - jsIsolate2.evaluateJavascript(code, callback); - callback.helper.waitForCallback("Timed out waiting for reportResult() to be called", 0); + ListenableFuture<String> resultFuture = jsIsolate2.evaluateJavascript(code); + String result = resultFuture.get(5, TimeUnit.SECONDS); jsIsolate2.close(); jsSandbox.close(); - Assert.assertEquals(expected, callback.result); + Assert.assertEquals(expected, result); } @Test @@ -90,27 +71,23 @@ final String expected1 = "PASS"; final String code2 = "this.x = 'SUPER_PASS';\n"; final String expected2 = "SUPER_PASS"; - TestExecutionCallback callback1 = new TestExecutionCallback(); - TestExecutionCallback callback2 = new TestExecutionCallback(); + Context context = ContextUtils.getApplicationContext(); ListenableFuture<AwJsSandbox> awJsSandboxFuture = AwJsSandbox.newConnectedInstance(context); AwJsSandbox jsSandbox = awJsSandboxFuture.get(5, TimeUnit.SECONDS); AwJsIsolate jsIsolate1 = jsSandbox.createIsolate(); - jsIsolate1.evaluateJavascript(code1, callback1); + ListenableFuture<String> resultFuture1 = jsIsolate1.evaluateJavascript(code1); + String result1 = resultFuture1.get(5, TimeUnit.SECONDS); AwJsIsolate jsIsolate2 = jsSandbox.createIsolate(); - jsIsolate2.evaluateJavascript(code2, callback2); - - callback1.helper.waitForCallback( - "Timed out waiting for reportResult() to be called for first case", 0); - callback2.helper.waitForCallback( - "Timed out waiting for reportResult() to be called for second case", 0); + ListenableFuture<String> resultFuture2 = jsIsolate2.evaluateJavascript(code2); + String result2 = resultFuture2.get(5, TimeUnit.SECONDS); jsIsolate1.close(); jsIsolate2.close(); jsSandbox.close(); - Assert.assertEquals(expected1, callback1.result); - Assert.assertEquals(expected2, callback2.result); + Assert.assertEquals(expected1, result1); + Assert.assertEquals(expected2, result2); } @Test @@ -120,27 +97,22 @@ final String expected1 = "PASS"; final String code2 = "this.y = this.y + ' PASS';\n"; final String expected2 = "undefined PASS"; - TestExecutionCallback callback1 = new TestExecutionCallback(); - TestExecutionCallback callback2 = new TestExecutionCallback(); Context context = ContextUtils.getApplicationContext(); ListenableFuture<AwJsSandbox> awJsSandboxFuture = AwJsSandbox.newConnectedInstance(context); AwJsSandbox jsSandbox = awJsSandboxFuture.get(5, TimeUnit.SECONDS); AwJsIsolate jsIsolate1 = jsSandbox.createIsolate(); - jsIsolate1.evaluateJavascript(code1, callback1); + ListenableFuture<String> resultFuture1 = jsIsolate1.evaluateJavascript(code1); + String result1 = resultFuture1.get(5, TimeUnit.SECONDS); AwJsIsolate jsIsolate2 = jsSandbox.createIsolate(); - jsIsolate2.evaluateJavascript(code2, callback2); - - callback1.helper.waitForCallback( - "Timed out waiting for reportResult() to be called for first case", 0); - callback2.helper.waitForCallback( - "Timed out waiting for reportResult() to be called for second case", 0); + ListenableFuture<String> resultFuture2 = jsIsolate2.evaluateJavascript(code2); + String result2 = resultFuture2.get(5, TimeUnit.SECONDS); jsIsolate1.close(); jsIsolate2.close(); jsSandbox.close(); - Assert.assertEquals(expected1, callback1.result); - Assert.assertEquals(expected2, callback2.result); + Assert.assertEquals(expected1, result1); + Assert.assertEquals(expected2, result2); } @Test @@ -150,24 +122,20 @@ final String expected1 = "PASS"; final String code2 = "this.z = this.z + ' PASS';\n"; final String expected2 = "PASS PASS"; - TestExecutionCallback callback1 = new TestExecutionCallback(); - TestExecutionCallback callback2 = new TestExecutionCallback(); Context context = ContextUtils.getApplicationContext(); ListenableFuture<AwJsSandbox> awJsSandboxFuture = AwJsSandbox.newConnectedInstance(context); AwJsSandbox jsSandbox = awJsSandboxFuture.get(5, TimeUnit.SECONDS); AwJsIsolate jsIsolate1 = jsSandbox.createIsolate(); - jsIsolate1.evaluateJavascript(code1, callback1); - jsIsolate1.evaluateJavascript(code2, callback2); - callback1.helper.waitForCallback( - "Timed out waiting for reportResult() to be called for first case", 0); - callback2.helper.waitForCallback( - "Timed out waiting for reportResult() to be called for second case", 0); + ListenableFuture<String> resultFuture1 = jsIsolate1.evaluateJavascript(code1); + String result1 = resultFuture1.get(5, TimeUnit.SECONDS); + ListenableFuture<String> resultFuture2 = jsIsolate1.evaluateJavascript(code2); + String result2 = resultFuture2.get(5, TimeUnit.SECONDS); jsIsolate1.close(); jsSandbox.close(); - Assert.assertEquals(expected1, callback1.result); - Assert.assertEquals(expected2, callback2.result); + Assert.assertEquals(expected1, result1); + Assert.assertEquals(expected2, result2); } @Test @@ -175,17 +143,25 @@ public void testJsEvaluationError() throws Throwable { final String code = "."; final String contains = "SyntaxError"; - TestExecutionCallback callback = new TestExecutionCallback(); Context context = ContextUtils.getApplicationContext(); ListenableFuture<AwJsSandbox> awJsSandboxFuture = AwJsSandbox.newConnectedInstance(context); AwJsSandbox jsSandbox = awJsSandboxFuture.get(5, TimeUnit.SECONDS); AwJsIsolate jsIsolate = jsSandbox.createIsolate(); - jsIsolate.evaluateJavascript(code, callback); - callback.helper.waitForCallback("Timed out waiting for reportError() to be called", 0); + ListenableFuture<String> resultFuture = jsIsolate.evaluateJavascript(code); + boolean isOfTypeJsEvaluationException = false; + String error = ""; + try { + String result = resultFuture.get(5, TimeUnit.SECONDS); + } catch (ExecutionException e) { + isOfTypeJsEvaluationException = + e.getCause().getClass().equals(JsEvaluationException.class); + error = e.getCause().getMessage(); + } jsIsolate.close(); jsSandbox.close(); - Assert.assertTrue(callback.error.contains(contains)); + Assert.assertTrue(isOfTypeJsEvaluationException); + Assert.assertTrue(error.contains(contains)); } }
diff --git a/ash/ambient/backdrop/ambient_backend_controller_impl.cc b/ash/ambient/backdrop/ambient_backend_controller_impl.cc index 20b39a8..afa9d74a 100644 --- a/ash/ambient/backdrop/ambient_backend_controller_impl.cc +++ b/ash/ambient/backdrop/ambient_backend_controller_impl.cc
@@ -28,6 +28,7 @@ #include "base/time/time.h" #include "chromeos/assistant/internal/ambient/backdrop_client_config.h" #include "chromeos/assistant/internal/proto/backdrop/backdrop.pb.h" +#include "chromeos/assistant/internal/proto/backdrop/imax_service.pb.h" #include "components/prefs/pref_service.h" #include "components/user_manager/user_manager.h" #include "net/base/load_flags.h" @@ -653,6 +654,42 @@ weak_factory_.GetWeakPtr(), on_done)); } +void AmbientBackendControllerImpl::StartToGetGooglePhotosAlbumsPreview( + const std::vector<std::string>& album_ids, + int preview_width, + int preview_height, + int num_previews, + GetGooglePhotosAlbumsPreviewCallback callback, + const std::string& gaia_id, + const std::string& access_token) { + BackdropClientConfig::Request request = + backdrop_client_config_.CreateGetGooglePhotosAlbumsPreviewRequest( + gaia_id, access_token, album_ids, preview_width, preview_height, + num_previews); + std::unique_ptr<network::ResourceRequest> resource_request = + CreateResourceRequest(request); + auto backdrop_url_loader = std::make_unique<BackdropURLLoader>(); + auto* loader_ptr = backdrop_url_loader.get(); + loader_ptr->Start( + std::move(resource_request), request.body, NO_TRAFFIC_ANNOTATION_YET, + base::BindOnce( + &AmbientBackendControllerImpl::OnGetGooglePhotosAlbumsPreview, + weak_factory_.GetWeakPtr(), std::move(callback), + std::move(backdrop_url_loader))); +} + +void AmbientBackendControllerImpl::GetGooglePhotosAlbumsPreview( + const std::vector<std::string>& album_ids, + int preview_width, + int preview_height, + int num_previews, + GetGooglePhotosAlbumsPreviewCallback callback) { + Shell::Get()->ambient_controller()->RequestAccessToken(base::BindOnce( + &AmbientBackendControllerImpl::StartToGetGooglePhotosAlbumsPreview, + weak_factory_.GetWeakPtr(), album_ids, preview_width, preview_height, + num_previews, std::move(callback))); +} + void AmbientBackendControllerImpl::OnSettingsFetched( base::RepeatingClosure on_done, const absl::optional<ash::AmbientSettings>& settings) { @@ -672,4 +709,23 @@ std::move(callback).Run(settings_, std::move(personal_albums_)); } +void AmbientBackendControllerImpl::OnGetGooglePhotosAlbumsPreview( + GetGooglePhotosAlbumsPreviewCallback callback, + std::unique_ptr<BackdropURLLoader> backdrop_url_loader, + std::unique_ptr<std::string> response) { + DCHECK(backdrop_url_loader); + + backdrop::GetGooglePhotosAlbumsPreviewResponse + get_google_photos_albums_preview_response; + if (!get_google_photos_albums_preview_response.ParseFromString(*response)) + std::move(callback).Run(std::vector<GURL>()); + + std::vector<GURL> preview_urls; + for (const std::string& preview_url : + get_google_photos_albums_preview_response.preview_url()) { + preview_urls.push_back(GURL(preview_url)); + } + std::move(callback).Run(preview_urls); +} + } // namespace ash
diff --git a/ash/ambient/backdrop/ambient_backend_controller_impl.h b/ash/ambient/backdrop/ambient_backend_controller_impl.h index 965f613..1d9d4df 100644 --- a/ash/ambient/backdrop/ambient_backend_controller_impl.h +++ b/ash/ambient/backdrop/ambient_backend_controller_impl.h
@@ -49,6 +49,13 @@ void FetchWeather(FetchWeatherCallback callback) override; const std::array<const char*, 2>& GetBackupPhotoUrls() const override; + void GetGooglePhotosAlbumsPreview( + const std::vector<std::string>& album_ids, + int preview_width, + int preview_height, + int num_previews, + GetGooglePhotosAlbumsPreviewCallback callback) override; + private: using BackdropClientConfig = chromeos::ambient::BackdropClientConfig; void RequestAccessToken(AmbientClient::GetAccessTokenCallback callback); @@ -104,6 +111,20 @@ void OnSettingsAndAlbumsFetched(OnSettingsAndAlbumsFetchedCallback callback); + void StartToGetGooglePhotosAlbumsPreview( + const std::vector<std::string>& album_ids, + int preview_width, + int preview_height, + int num_previews, + GetGooglePhotosAlbumsPreviewCallback callback, + const std::string& gaia_id, + const std::string& access_token); + + void OnGetGooglePhotosAlbumsPreview( + GetGooglePhotosAlbumsPreviewCallback callback, + std::unique_ptr<BackdropURLLoader> backdrop_url_loader, + std::unique_ptr<std::string> response); + // Temporary store for FetchSettingsAndAlbums() when |GetSettingsCallback| // called. |settings_| will be absl::nullopt if server returns with error. absl::optional<ash::AmbientSettings> settings_;
diff --git a/ash/app_list/views/ghost_image_view.cc b/ash/app_list/views/ghost_image_view.cc index 08108b2..a24f0965 100644 --- a/ash/app_list/views/ghost_image_view.cc +++ b/ash/app_list/views/ghost_image_view.cc
@@ -75,11 +75,9 @@ void GhostImageView::OnPaint(gfx::Canvas* canvas) { cc::PaintFlags flags; flags.setAntiAlias(true); - // TODO(crbug.com/1255369): Get the highlight color from the ash color - // provider once it is implemented. flags.setColor(AshColorProvider::Get()->IsDarkModeEnabled() ? gfx::kGoogleGrey200 - : gfx::kGoogleGrey700); + : gfx::kGoogleGrey900); flags.setAlpha(kGhostColorOpacity); flags.setStyle(cc::PaintFlags::kStroke_Style); flags.setStrokeWidth(kGhostCircleStrokeWidth);
diff --git a/ash/app_list/views/paged_apps_grid_view.cc b/ash/app_list/views/paged_apps_grid_view.cc index d72ad79..fe9a691 100644 --- a/ash/app_list/views/paged_apps_grid_view.cc +++ b/ash/app_list/views/paged_apps_grid_view.cc
@@ -22,6 +22,7 @@ #include "ash/public/cpp/app_list/app_list_config.h" #include "ash/public/cpp/app_list/app_list_features.h" #include "ash/public/cpp/pagination/pagination_controller.h" +#include "ash/style/ash_color_provider.h" #include "base/barrier_closure.h" #include "base/bind.h" #include "base/callback.h" @@ -197,8 +198,9 @@ if (features::IsProductivityLauncherEnabled() && is_active_page_) { // Draw a border around the active page. - flags.setColor(SK_ColorWHITE); - flags.setAlpha(0x66); + const bool dark_mode = AshColorProvider::Get()->IsDarkModeEnabled(); + flags.setColor(dark_mode ? SK_ColorWHITE : SK_ColorBLACK); + flags.setAlpha(dark_mode ? 0x29 /*16%*/ : 0x1F /*12%*/); flags.setStyle(cc::PaintFlags::kStroke_Style); flags.setStrokeWidth(kBackgroundCardBorderStrokeWidth); flags.setAntiAlias(true);
diff --git a/ash/app_list/views/privacy_info_view.cc b/ash/app_list/views/privacy_info_view.cc index ad5a6fe..f01f215 100644 --- a/ash/app_list/views/privacy_info_view.cc +++ b/ash/app_list/views/privacy_info_view.cc
@@ -266,7 +266,6 @@ // underline font style to be applied when the link is focused. This is done // manually because default focus handling remains on the search box. views::StyledLabel::RangeStyleInfo link_style; - link_style.disable_line_wrapping = true; auto custom_view = std::make_unique<views::Link>(link); custom_view->SetCallback(base::BindRepeating(&PrivacyInfoView::LinkClicked, base::Unretained(this)));
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index 40d0266b..391bea6 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -1627,7 +1627,7 @@ base::FeatureList::IsEnabled(kLauncherItemColorSync); } -bool IsConsumerAutoUpdateAllowed() { +bool IsConsumerAutoUpdateToggleAllowed() { return base::FeatureList::IsEnabled(kConsumerAutoUpdateToggleAllowed); }
diff --git a/ash/projector/projector_annotation_tray.cc b/ash/projector/projector_annotation_tray.cc index b996898..ca2f767dc 100644 --- a/ash/projector/projector_annotation_tray.cc +++ b/ash/projector/projector_annotation_tray.cc
@@ -100,8 +100,7 @@ image_view_->SetHorizontalAlignment(views::ImageView::Alignment::kCenter); image_view_->SetVerticalAlignment(views::ImageView::Alignment::kCenter); image_view_->SetPreferredSize(gfx::Size(kTrayItemSize, kTrayItemSize)); - // The default pen color upon creation is magenta. - current_pen_color_ = kProjectorMagentaPenColor; + ResetTray(); } ProjectorAnnotationTray::~ProjectorAnnotationTray() = default; @@ -232,8 +231,7 @@ void ProjectorAnnotationTray::HideAnnotationTray() { SetVisiblePreferred(false); UpdateIcon(); - // Reset pen color to default color. - current_pen_color_ = kProjectorMagentaPenColor; + ResetTray(); } void ProjectorAnnotationTray::ToggleAnnotator() { @@ -295,4 +293,11 @@ return IDS_RED_COLOR_BUTTON; } +void ProjectorAnnotationTray::ResetTray() { + // Set current pen to default pen color + current_pen_color_ = kProjectorMagentaPenColor; + // Disable the tray icon. It is enabled once the ink canvas is initialized. + SetEnabled(false); +} + } // namespace ash
diff --git a/ash/projector/projector_annotation_tray.h b/ash/projector/projector_annotation_tray.h index 2d12670..aeee44e5 100644 --- a/ash/projector/projector_annotation_tray.h +++ b/ash/projector/projector_annotation_tray.h
@@ -59,6 +59,9 @@ // Returns the message ID of the accessible name for the color. int GetAccessibleNameForColor(SkColor color); + // Resets the tray to its default state. + void ResetTray(); + // Image view of the tray icon. views::ImageView* const image_view_;
diff --git a/ash/projector/projector_controller_impl.cc b/ash/projector/projector_controller_impl.cc index 3d0aefe..8ec0f4db 100644 --- a/ash/projector/projector_controller_impl.cc +++ b/ash/projector/projector_controller_impl.cc
@@ -283,6 +283,10 @@ // Projector toolbar. } +void ProjectorControllerImpl::OnCanvasInitialized(bool success) { + ui_controller_->OnCanvasInitialized(success); +} + void ProjectorControllerImpl::OnRecordingStarted(bool is_in_projector_mode) { if (!is_in_projector_mode) { OnNewScreencastPreconditionChanged();
diff --git a/ash/projector/projector_controller_impl.h b/ash/projector/projector_controller_impl.h index 65bb943..def9107 100644 --- a/ash/projector/projector_controller_impl.h +++ b/ash/projector/projector_controller_impl.h
@@ -71,6 +71,7 @@ void OnToolSet(const AnnotatorTool& tool) override; void OnUndoRedoAvailabilityChanged(bool undo_available, bool redo_available) override; + void OnCanvasInitialized(bool success) override; // Create the screencast container directory. If there is an error, the // callback will be triggered with an empty FilePath.
diff --git a/ash/projector/projector_ui_controller.cc b/ash/projector/projector_ui_controller.cc index adc8dcf..e6c91a9c 100644 --- a/ash/projector/projector_ui_controller.cc +++ b/ash/projector/projector_ui_controller.cc
@@ -162,6 +162,14 @@ } } +void ProjectorUiController::OnCanvasInitialized(bool success) { + auto* projector_annotation_tray = Shell::GetPrimaryRootWindowController() + ->GetStatusAreaWidget() + ->projector_annotation_tray(); + DCHECK(projector_annotation_tray); + projector_annotation_tray->SetEnabled(success); +} + void ProjectorUiController::OnProjectorSessionActiveStateChanged(bool active) { if (!active) ResetTools();
diff --git a/ash/projector/projector_ui_controller.h b/ash/projector/projector_ui_controller.h index ccf80876..e1021f2 100644 --- a/ash/projector/projector_ui_controller.h +++ b/ash/projector/projector_ui_controller.h
@@ -42,6 +42,8 @@ virtual void SetAnnotatorTool(const AnnotatorTool& tool); // Resets and disables the annotator tools and clears the canvas. void ResetTools(); + // Invoked when the canvas has either succeeded or failed to initialize. + void OnCanvasInitialized(bool success); bool is_annotator_enabled() { return annotator_enabled_; }
diff --git a/ash/projector/projector_ui_controller_unittest.cc b/ash/projector/projector_ui_controller_unittest.cc index 83e3f18e..8893cf04 100644 --- a/ash/projector/projector_ui_controller_unittest.cc +++ b/ash/projector/projector_ui_controller_unittest.cc
@@ -229,4 +229,18 @@ /*count=*/2); } +TEST_F(ProjectorUiControllerTest, OnCanvasInitialized) { + auto* projector_annotation_tray = Shell::GetPrimaryRootWindowController() + ->GetStatusAreaWidget() + ->projector_annotation_tray(); + + EXPECT_FALSE(projector_annotation_tray->GetEnabled()); + + controller_->OnCanvasInitialized(/*success=*/true); + EXPECT_TRUE(projector_annotation_tray->GetEnabled()); + + controller_->OnCanvasInitialized(/*success=*/false); + EXPECT_FALSE(projector_annotation_tray->GetEnabled()); +} + } // namespace ash
diff --git a/ash/public/cpp/ambient/ambient_backend_controller.h b/ash/public/cpp/ambient/ambient_backend_controller.h index 6c28235..4d487a5d 100644 --- a/ash/public/cpp/ambient/ambient_backend_controller.h +++ b/ash/public/cpp/ambient/ambient_backend_controller.h
@@ -15,6 +15,7 @@ #include "base/callback_forward.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/gfx/geometry/size.h" +#include "url/gurl.h" namespace ash { @@ -107,6 +108,9 @@ using FetchWeatherCallback = base::OnceCallback<void(const absl::optional<WeatherInfo>& weather_info)>; + using GetGooglePhotosAlbumsPreviewCallback = + base::OnceCallback<void(const std::vector<GURL>& preview_urls)>; + static AmbientBackendController* Get(); AmbientBackendController(); @@ -152,6 +156,13 @@ // Fetch the weather information. virtual void FetchWeather(FetchWeatherCallback) = 0; + virtual void GetGooglePhotosAlbumsPreview( + const std::vector<std::string>& album_ids, + int preview_width, + int preview_height, + int num_previews, + GetGooglePhotosAlbumsPreviewCallback callback) = 0; + // Get stock photo urls to cache in advance in case Ambient mode is started // without internet access. virtual const std::array<const char*, 2>& GetBackupPhotoUrls() const = 0;
diff --git a/ash/public/cpp/ambient/fake_ambient_backend_controller_impl.cc b/ash/public/cpp/ambient/fake_ambient_backend_controller_impl.cc index 2b5dddf..fffdb51 100644 --- a/ash/public/cpp/ambient/fake_ambient_backend_controller_impl.cc +++ b/ash/public/cpp/ambient/fake_ambient_backend_controller_impl.cc
@@ -15,6 +15,7 @@ #include "base/check.h" #include "base/threading/sequenced_task_runner_handle.h" #include "third_party/abseil-cpp/absl/types/optional.h" +#include "url/gurl.h" namespace ash { @@ -166,6 +167,15 @@ std::move(callback).Run(weather_info_); } +void FakeAmbientBackendControllerImpl::GetGooglePhotosAlbumsPreview( + const std::vector<std::string>& album_ids, + int preview_width, + int preview_height, + int num_previews, + GetGooglePhotosAlbumsPreviewCallback callback) { + std::move(callback).Run({GURL("http://example.com/0")}); +} + const std::array<const char*, 2>& FakeAmbientBackendControllerImpl::GetBackupPhotoUrls() const { return kFakeBackupPhotoUrls;
diff --git a/ash/public/cpp/ambient/fake_ambient_backend_controller_impl.h b/ash/public/cpp/ambient/fake_ambient_backend_controller_impl.h index 5608bcd..8ca9dae 100644 --- a/ash/public/cpp/ambient/fake_ambient_backend_controller_impl.h +++ b/ash/public/cpp/ambient/fake_ambient_backend_controller_impl.h
@@ -45,6 +45,12 @@ int num_albums, OnSettingsAndAlbumsFetchedCallback callback) override; void FetchWeather(FetchWeatherCallback callback) override; + void GetGooglePhotosAlbumsPreview( + const std::vector<std::string>& album_ids, + int preview_width, + int preview_height, + int num_previews, + GetGooglePhotosAlbumsPreviewCallback callback) override; const std::array<const char*, 2>& GetBackupPhotoUrls() const override; // Simulate to reply the request of FetchSettingsAndAlbums().
diff --git a/ash/public/cpp/app_list/app_list_notifier.h b/ash/public/cpp/app_list/app_list_notifier.h index f107ab9..7cd9840 100644 --- a/ash/public/cpp/app_list/app_list_notifier.h +++ b/ash/public/cpp/app_list/app_list_notifier.h
@@ -86,6 +86,11 @@ // Called to indicate the user has updated the search query to |query|. virtual void NotifySearchQueryChanged(const std::u16string& query) = 0; + + // Fires a timer to report search result impression for the provided + // location, if an impression update was scheduled. Returns whether a timer + // was fired. + virtual bool FireImpressionTimerForTesting(Location location) = 0; }; } // namespace ash
diff --git a/ash/public/cpp/projector/projector_controller.h b/ash/public/cpp/projector/projector_controller.h index fcab963..a4bce550 100644 --- a/ash/public/cpp/projector/projector_controller.h +++ b/ash/public/cpp/projector/projector_controller.h
@@ -90,6 +90,8 @@ // Callback indicating availability of undo and redo functionalities. virtual void OnUndoRedoAvailabilityChanged(bool undo_available, bool redo_available) = 0; + // Called when the ink canvas has either succeeded or failed in initializing. + virtual void OnCanvasInitialized(bool success) = 0; }; } // namespace ash
diff --git a/ash/public/cpp/test/mock_projector_controller.h b/ash/public/cpp/test/mock_projector_controller.h index d535390..3d9fd3a 100644 --- a/ash/public/cpp/test/mock_projector_controller.h +++ b/ash/public/cpp/test/mock_projector_controller.h
@@ -33,6 +33,7 @@ MOCK_METHOD1(OnToolSet, void(const AnnotatorTool& tool)); MOCK_METHOD2(OnUndoRedoAvailabilityChanged, void(bool undo_available, bool redo_available)); + MOCK_METHOD1(OnCanvasInitialized, void(bool success)); }; } // namespace ash
diff --git a/ash/public/cpp/wallpaper/wallpaper_controller.h b/ash/public/cpp/wallpaper/wallpaper_controller.h index a3e226d..2c26351 100644 --- a/ash/public/cpp/wallpaper/wallpaper_controller.h +++ b/ash/public/cpp/wallpaper/wallpaper_controller.h
@@ -128,8 +128,11 @@ // |account_id|: The user's account id. // |show_wallpaper|: If false, don't show the new wallpaper now but only // update cache. + // |callback|: Called with a boolean to indicate success when the default + // wallpaper is read and decoded. virtual void SetDefaultWallpaper(const AccountId& account_id, - bool show_wallpaper) = 0; + bool show_wallpaper, + SetWallpaperCallback callback) = 0; // Sets the paths of the customized default wallpaper to be used wherever a // default wallpaper is needed. If a default wallpaper is being shown, updates
diff --git a/ash/public/cpp/wallpaper/wallpaper_controller_client.h b/ash/public/cpp/wallpaper/wallpaper_controller_client.h index f9c8a7e..5a45b75 100644 --- a/ash/public/cpp/wallpaper/wallpaper_controller_client.h +++ b/ash/public/cpp/wallpaper/wallpaper_controller_client.h
@@ -33,8 +33,10 @@ virtual void MaybeClosePreviewWallpaper() = 0; // Sets the default wallpaper and removes the file for the previous wallpaper. - virtual void SetDefaultWallpaper(const AccountId& account_id, - bool show_wallpaper) = 0; + virtual void SetDefaultWallpaper( + const AccountId& account_id, + bool show_wallpaper, + base::OnceCallback<void(bool success)> callback) = 0; // Retrieves the current collection id from the Wallpaper Picker Chrome App // for migration and returns it via |result_callback|. The string in
diff --git a/ash/shelf/hotseat_widget.cc b/ash/shelf/hotseat_widget.cc index 52d4a22e..417a5cc 100644 --- a/ash/shelf/hotseat_widget.cc +++ b/ash/shelf/hotseat_widget.cc
@@ -593,8 +593,9 @@ } } - if (translucent_background_->layer()->GetTargetBounds() != background_bounds) - translucent_background_->SetBoundsRect(background_bounds); + const gfx::Rect mirrored_bounds = GetMirroredRect(background_bounds); + if (translucent_background_->layer()->GetTargetBounds() != mirrored_bounds) + translucent_background_->SetBoundsRect(mirrored_bounds); } void HotseatWidget::DelegateView::SetBackgroundBlur(bool enable_blur) {
diff --git a/ash/shelf/kiosk_app_instruction_bubble.cc b/ash/shelf/kiosk_app_instruction_bubble.cc index 63ccc07..7520652a 100644 --- a/ash/shelf/kiosk_app_instruction_bubble.cc +++ b/ash/shelf/kiosk_app_instruction_bubble.cc
@@ -11,6 +11,7 @@ #include "ash/system/tray/tray_utils.h" #include "base/callback_helpers.h" #include "components/strings/grit/components_strings.h" +#include "ui/accessibility/ax_node_data.h" #include "ui/base/l10n/l10n_util.h" #include "ui/views/controls/label.h" #include "ui/views/layout/fill_layout.h" @@ -19,8 +20,8 @@ namespace ash { namespace { -// The preferred width of the kiosk app instruction bubble. -constexpr int kBubblePreferredWidth = 150; +// The preferred internal width of the kiosk app instruction bubble. +constexpr int kBubblePreferredInternalWidth = 150; views::BubbleBorder::Arrow GetArrow(ShelfAlignment alignment) { switch (alignment) { @@ -63,6 +64,7 @@ TrayPopupUtils::FontStyle::kSmallTitle); title_->SetText(l10n_util::GetStringUTF16(IDS_SHELF_KIOSK_APP_INSTRUCTION)); title_->SetMultiLine(true); + title_->SetHorizontalAlignment(gfx::ALIGN_LEFT); CreateBubble(); @@ -85,9 +87,17 @@ title_->SetEnabledColor(label_color); } +void KioskAppInstructionBubble::GetAccessibleNodeData( + ui::AXNodeData* node_data) { + node_data->role = ax::mojom::Role::kStaticText; + node_data->SetName(l10n_util::GetStringUTF8(IDS_SHELF_KIOSK_APP_INSTRUCTION)); +} + gfx::Size KioskAppInstructionBubble::CalculatePreferredSize() const { - return gfx::Size(kBubblePreferredWidth, - GetHeightForWidth(kBubblePreferredWidth)); + const int bubble_margin = views::LayoutProvider::Get()->GetDistanceMetric( + views::DISTANCE_DIALOG_CONTENT_MARGIN_TOP_CONTROL); + const int width = kBubblePreferredInternalWidth + 2 * bubble_margin; + return gfx::Size(width, GetHeightForWidth(width)); } bool KioskAppInstructionBubble::ShouldCloseOnPressDown() {
diff --git a/ash/shelf/kiosk_app_instruction_bubble.h b/ash/shelf/kiosk_app_instruction_bubble.h index 482a093..3431ebd 100644 --- a/ash/shelf/kiosk_app_instruction_bubble.h +++ b/ash/shelf/kiosk_app_instruction_bubble.h
@@ -34,6 +34,7 @@ // views::View: void OnThemeChanged() override; gfx::Size CalculatePreferredSize() const override; + void GetAccessibleNodeData(ui::AXNodeData* node_data) override; // ShelfBubble: bool ShouldCloseOnPressDown() override;
diff --git a/ash/shortcut_viewer/views/keyboard_shortcut_item_view.cc b/ash/shortcut_viewer/views/keyboard_shortcut_item_view.cc index be8906b..78ede94 100644 --- a/ash/shortcut_viewer/views/keyboard_shortcut_item_view.cc +++ b/ash/shortcut_viewer/views/keyboard_shortcut_item_view.cc
@@ -175,7 +175,6 @@ const std::u16string separator_string = u"+ "; for (size_t i = 0; i < offsets.size(); ++i) { views::StyledLabel::RangeStyleInfo style_info; - style_info.disable_line_wrapping = true; const std::u16string& replacement_string = replacement_strings[i]; std::unique_ptr<views::View> custom_view = replacement_string == separator_string
diff --git a/ash/system/geolocation/geolocation_controller.cc b/ash/system/geolocation/geolocation_controller.cc index b71560a..21d0c58 100644 --- a/ash/system/geolocation/geolocation_controller.cc +++ b/ash/system/geolocation/geolocation_controller.cc
@@ -7,6 +7,7 @@ #include <algorithm> #include "ash/components/geolocation/geoposition.h" +#include "ash/shell.h" #include "ash/system/time/time_of_day.h" #include "base/bind.h" #include "base/logging.h" @@ -17,8 +18,6 @@ namespace { -GeolocationController* g_geolocation_controller = nullptr; - // Delay to wait for a response to our geolocation request, if we get a response // after which, we will consider the request a failure. constexpr base::TimeDelta kGeolocationRequestTimeout = base::Seconds(60); @@ -47,19 +46,18 @@ auto* timezone_settings = chromeos::system::TimezoneSettings::GetInstance(); current_timezone_id_ = timezone_settings->GetCurrentTimezoneID(); timezone_settings->AddObserver(this); - g_geolocation_controller = this; } GeolocationController::~GeolocationController() { chromeos::system::TimezoneSettings::GetInstance()->RemoveObserver(this); - DCHECK_EQ(g_geolocation_controller, this); - g_geolocation_controller = nullptr; } // static GeolocationController* GeolocationController::Get() { - DCHECK(g_geolocation_controller); - return g_geolocation_controller; + GeolocationController* controller = + ash::Shell::Get()->geolocation_controller(); + DCHECK(controller); + return controller; } void GeolocationController::AddObserver(Observer* observer) {
diff --git a/ash/system/geolocation/geolocation_controller.h b/ash/system/geolocation/geolocation_controller.h index d5297a89..43178ce7 100644 --- a/ash/system/geolocation/geolocation_controller.h +++ b/ash/system/geolocation/geolocation_controller.h
@@ -91,6 +91,12 @@ network::SharedURLLoaderFactory* GetFactoryForTesting() { return factory_; } + base::OneShotTimer* GetTimerForTesting() { return timer_.get(); } + + bool HasObserverForTesting(const Observer* obs) const { + return observers_.HasObserver(obs); + } + void SetTimerForTesting(std::unique_ptr<base::OneShotTimer> timer); void SetClockForTesting(base::Clock* clock);
diff --git a/ash/system/geolocation/geolocation_controller_test_util.cc b/ash/system/geolocation/geolocation_controller_test_util.cc index f9adfff..bfa071a 100644 --- a/ash/system/geolocation/geolocation_controller_test_util.cc +++ b/ash/system/geolocation/geolocation_controller_test_util.cc
@@ -18,12 +18,14 @@ // ----------------------------------------------------------------------------- // GeopositionResponsesWaiter: -GeopositionResponsesWaiter::GeopositionResponsesWaiter() { - GeolocationController::Get()->AddObserver(this); +GeopositionResponsesWaiter::GeopositionResponsesWaiter( + GeolocationController* controller) + : controller_(controller) { + controller_->AddObserver(this); } GeopositionResponsesWaiter::~GeopositionResponsesWaiter() { - GeolocationController::Get()->RemoveObserver(this); + controller_->RemoveObserver(this); } void GeopositionResponsesWaiter::Wait() {
diff --git a/ash/system/geolocation/geolocation_controller_test_util.h b/ash/system/geolocation/geolocation_controller_test_util.h index d8ba1c6..92e172dd 100644 --- a/ash/system/geolocation/geolocation_controller_test_util.h +++ b/ash/system/geolocation/geolocation_controller_test_util.h
@@ -36,11 +36,11 @@ bool possible_change_in_timezone_ = false; }; -// Used for waiting for the geoposition to be responded from the server to all -// observers. +// Used for waiting for the geolocation controller to send geoposition fetched +// from the server to all observers. class GeopositionResponsesWaiter : public GeolocationController::Observer { public: - GeopositionResponsesWaiter(); + explicit GeopositionResponsesWaiter(GeolocationController* controller); GeopositionResponsesWaiter(const GeopositionResponsesWaiter&) = delete; GeopositionResponsesWaiter& operator=(const GeopositionResponsesWaiter&) = @@ -54,6 +54,7 @@ void OnGeopositionChanged(bool possible_change_in_timezone) override; private: + GeolocationController* const controller_; base::RunLoop run_loop_; };
diff --git a/ash/system/geolocation/geolocation_controller_unittest.cc b/ash/system/geolocation/geolocation_controller_unittest.cc index d763400..9b09483 100644 --- a/ash/system/geolocation/geolocation_controller_unittest.cc +++ b/ash/system/geolocation/geolocation_controller_unittest.cc
@@ -9,6 +9,7 @@ #include "ash/system/geolocation/test_geolocation_url_loader_factory.h" #include "ash/system/time/time_of_day.h" #include "ash/test/ash_test_base.h" +#include "ash/test_shell_delegate.h" #include "base/strings/utf_string_conversions.h" #include "base/test/simple_test_clock.h" #include "base/time/clock.h" @@ -44,15 +45,14 @@ // AshTestBase: void SetUp() override { AshTestBase::SetUp(); - controller_ = ash::Shell::Get()->geolocation_controller(); + controller_ = std::make_unique<GeolocationController>( + static_cast<scoped_refptr<network::SharedURLLoaderFactory>>( + base::MakeRefCounted<TestGeolocationUrlLoaderFactory>())); test_clock_.SetNow(base::Time::Now()); - - std::unique_ptr<base::MockOneShotTimer> mock_timer = - std::make_unique<base::MockOneShotTimer>(); - mock_timer_ptr_ = mock_timer.get(); - controller_->SetTimerForTesting(std::move(mock_timer)); controller_->SetClockForTesting(&test_clock_); + timer_ptr_ = controller_->GetTimerForTesting(); + factory_ = static_cast<TestGeolocationUrlLoaderFactory*>( controller_->GetFactoryForTesting()); @@ -66,22 +66,20 @@ SetServerPosition(position); } - GeolocationController* controller() const { return controller_; } + GeolocationController* controller() const { return controller_.get(); } base::SimpleTestClock* test_clock() { return &test_clock_; } - base::MockOneShotTimer* mock_timer_ptr() const { return mock_timer_ptr_; } + base::OneShotTimer* timer_ptr() const { return timer_ptr_; } const Geoposition& position() const { return position_; } // Fires the timer of the scheduler to request geoposition and wait for all // observers to receive the latest geoposition from the server. void FireTimerToFetchGeoposition() { - GeopositionResponsesWaiter waiter; - // Make sure that the timer is running indicating that the client runs - // the scheduler. - EXPECT_TRUE(mock_timer_ptr()->IsRunning()); + GeopositionResponsesWaiter waiter(controller()); + EXPECT_TRUE(timer_ptr()->IsRunning()); // Fast forward the scheduler to reach the time when the controller // requests for geoposition from the server in // `GeolocationController::RequestGeoposition`. - mock_timer_ptr_->Fire(); + timer_ptr_->FireNow(); // Waits for the observers to receive the geoposition from the server. waiter.Wait(); } @@ -94,9 +92,9 @@ } private: - GeolocationController* controller_; + std::unique_ptr<GeolocationController> controller_; base::SimpleTestClock test_clock_; - base::MockOneShotTimer* mock_timer_ptr_; + base::OneShotTimer* timer_ptr_; TestGeolocationUrlLoaderFactory* factory_; Geoposition position_; }; @@ -104,7 +102,7 @@ // Tests adding and removing an observer should request and stop receiving // a position update. TEST_F(GeolocationControllerTest, Observer) { - EXPECT_FALSE(mock_timer_ptr()->IsRunning()); + EXPECT_FALSE(timer_ptr()->IsRunning()); // Add an observer should start the timer requesting the geoposition. GeolocationControllerObserver observer; @@ -113,18 +111,18 @@ EXPECT_EQ(1, observer.position_received_num()); // Check that the timer fires another schedule after a successful request. - EXPECT_TRUE(mock_timer_ptr()->IsRunning()); + EXPECT_TRUE(timer_ptr()->IsRunning()); // Removing an observer should stop the timer. controller()->RemoveObserver(&observer); - EXPECT_FALSE(mock_timer_ptr()->IsRunning()); + EXPECT_FALSE(timer_ptr()->IsRunning()); EXPECT_EQ(1, observer.position_received_num()); } // Tests adding and removing observer and make sure that only observing ones // receive the position updates. TEST_F(GeolocationControllerTest, MultipleObservers) { - EXPECT_FALSE(mock_timer_ptr()->IsRunning()); + EXPECT_FALSE(timer_ptr()->IsRunning()); // Add an observer should start the timer requesting for the first // geoposition request. @@ -132,14 +130,14 @@ controller()->AddObserver(&observer1); FireTimerToFetchGeoposition(); EXPECT_EQ(1, observer1.position_received_num()); - EXPECT_TRUE(mock_timer_ptr()->IsRunning()); + EXPECT_TRUE(timer_ptr()->IsRunning()); // Since `OnGeoposition()` handling a geoposition update always schedule // the next geoposition request, the timer should keep running and // update position periodically. FireTimerToFetchGeoposition(); EXPECT_EQ(2, observer1.position_received_num()); - EXPECT_TRUE(mock_timer_ptr()->IsRunning()); + EXPECT_TRUE(timer_ptr()->IsRunning()); // Adding `observer2` should not interrupt the request flow. Check that both // observers receive the new position. @@ -148,7 +146,7 @@ FireTimerToFetchGeoposition(); EXPECT_EQ(3, observer1.position_received_num()); EXPECT_EQ(1, observer2.position_received_num()); - EXPECT_TRUE(mock_timer_ptr()->IsRunning()); + EXPECT_TRUE(timer_ptr()->IsRunning()); // Remove `observer1` and make sure that the timer is still running. // Only `observer2` should receive the new position. @@ -156,12 +154,12 @@ FireTimerToFetchGeoposition(); EXPECT_EQ(3, observer1.position_received_num()); EXPECT_EQ(2, observer2.position_received_num()); - EXPECT_TRUE(mock_timer_ptr()->IsRunning()); + EXPECT_TRUE(timer_ptr()->IsRunning()); // Removing `observer2` should stop the timer. The request count should // not change. controller()->RemoveObserver(&observer2); - EXPECT_FALSE(mock_timer_ptr()->IsRunning()); + EXPECT_FALSE(timer_ptr()->IsRunning()); EXPECT_EQ(3, observer1.position_received_num()); EXPECT_EQ(2, observer2.position_received_num()); } @@ -173,25 +171,25 @@ Geoposition invalid_position(position()); invalid_position.error_code = 10; SetServerPosition(invalid_position); - EXPECT_FALSE(mock_timer_ptr()->IsRunning()); + EXPECT_FALSE(timer_ptr()->IsRunning()); controller()->AddObserver(&observer); // If the position is invalid, the controller won't push the geoposition // update to its observers. - EXPECT_TRUE(mock_timer_ptr()->IsRunning()); - mock_timer_ptr()->Fire(); + EXPECT_TRUE(timer_ptr()->IsRunning()); + timer_ptr()->FireNow(); // Wait for the request and response to finish. base::RunLoop().RunUntilIdle(); EXPECT_EQ(0, observer.position_received_num()); // With error response, the server will retry with another timer which we // have no control over, so `mock_timer_ptr_` will not be running (refers to // `SimpleGeolocationRequest::Retry()` for more detail). - EXPECT_FALSE(mock_timer_ptr()->IsRunning()); + EXPECT_FALSE(timer_ptr()->IsRunning()); } // Tests that timezone changes result. TEST_F(GeolocationControllerTest, TimezoneChanges) { - EXPECT_FALSE(mock_timer_ptr()->IsRunning()); + EXPECT_FALSE(timer_ptr()->IsRunning()); controller()->SetCurrentTimezoneIdForTesting(u"America/Los_Angeles"); // Add an observer. @@ -201,7 +199,7 @@ FireTimerToFetchGeoposition(); EXPECT_EQ(1, observer.position_received_num()); EXPECT_EQ(u"America/Los_Angeles", controller()->current_timezone_id()); - EXPECT_TRUE(mock_timer_ptr()->IsRunning()); + EXPECT_TRUE(timer_ptr()->IsRunning()); // A new timezone results in new geoposition request. auto timezone = CreateTimezone("Asia/Tokyo"); @@ -210,7 +208,7 @@ FireTimerToFetchGeoposition(); EXPECT_EQ(2, observer.position_received_num()); EXPECT_EQ(GetTimezoneId(*timezone), controller()->current_timezone_id()); - EXPECT_TRUE(mock_timer_ptr()->IsRunning()); + EXPECT_TRUE(timer_ptr()->IsRunning()); } // Tests obtaining sunset/sunrise time when there is no valid geoposition, for @@ -245,7 +243,7 @@ // updated until the timer is fired. GeolocationControllerObserver observer1; controller()->AddObserver(&observer1); - EXPECT_TRUE(mock_timer_ptr()->IsRunning()); + EXPECT_TRUE(timer_ptr()->IsRunning()); EXPECT_NE(controller()->GetSunsetTime(), sunset); EXPECT_NE(controller()->GetSunriseTime(), sunrise); EXPECT_EQ(0, observer1.position_received_num()); @@ -265,7 +263,7 @@ EXPECT_EQ(1, observer1.position_received_num()); EXPECT_EQ(controller()->GetSunsetTime(), sunset); EXPECT_EQ(controller()->GetSunriseTime(), sunrise); - EXPECT_TRUE(mock_timer_ptr()->IsRunning()); + EXPECT_TRUE(timer_ptr()->IsRunning()); } } // namespace
diff --git a/ash/system/message_center/ash_notification_view.h b/ash/system/message_center/ash_notification_view.h index efca803..347d200a 100644 --- a/ash/system/message_center/ash_notification_view.h +++ b/ash/system/message_center/ash_notification_view.h
@@ -55,7 +55,8 @@ // collapse state. void AnimateGroupedChildExpandedCollapse(bool expanded); - // Toggle the expand state of the notification. + // Toggle the expand state of the notification. This function should only be + // used to handle user manually expand/collapse a notification. void ToggleExpand(); // Called when a child notificaiton's preferred size changes.
diff --git a/ash/system/message_center/ash_notification_view_unittest.cc b/ash/system/message_center/ash_notification_view_unittest.cc index 50087e1..406c2e7 100644 --- a/ash/system/message_center/ash_notification_view_unittest.cc +++ b/ash/system/message_center/ash_notification_view_unittest.cc
@@ -409,6 +409,14 @@ GetMessageLabelInExpandedState(notification_view())->GetVisible()); } +TEST_F(AshNotificationViewTest, ManuallyExpandedOrCollapsed) { + // Test |manually_expanded_or_collapsed| being set when the toggle is done by + // user interaction. + EXPECT_FALSE(notification_view()->IsManuallyExpandedOrCollapsed()); + notification_view()->ToggleExpand(); + EXPECT_TRUE(notification_view()->IsManuallyExpandedOrCollapsed()); +} + TEST_F(AshNotificationViewTest, GroupedNotificationStartsCollapsed) { auto notification = CreateTestNotification(); notification_view()->UpdateWithNotification(*notification);
diff --git a/ash/system/scheduled_feature/scheduled_feature_unittest.cc b/ash/system/scheduled_feature/scheduled_feature_unittest.cc index 21869f61..014beed 100644 --- a/ash/system/scheduled_feature/scheduled_feature_unittest.cc +++ b/ash/system/scheduled_feature/scheduled_feature_unittest.cc
@@ -14,6 +14,7 @@ #include "ash/session/session_controller_impl.h" #include "ash/session/test_session_controller_client.h" #include "ash/shell.h" +#include "ash/style/dark_mode_controller.h" #include "ash/system/geolocation/geolocation_controller.h" #include "ash/system/geolocation/geolocation_controller_test_util.h" #include "ash/system/geolocation/test_geolocation_url_loader_factory.h" @@ -28,7 +29,6 @@ #include "base/test/scoped_feature_list.h" #include "base/test/simple_test_clock.h" #include "base/time/time.h" -#include "base/timer/mock_timer.h" #include "components/prefs/pref_service.h" #include "ui/compositor/layer.h" #include "ui/gfx/geometry/vector3d_f.h" @@ -93,15 +93,28 @@ return geolocation_controller_; } base::SimpleTestClock* test_clock() { return &test_clock_; } - const base::MockOneShotTimer* mock_timer_ptr() const { - return mock_timer_ptr_; - } + const base::OneShotTimer* timer_ptr() const { return timer_ptr_; } TestGeolocationUrlLoaderFactory* factory() const { return factory_; } // AshTestBase: void SetUp() override { NoSessionAshTestBase::SetUp(); + base::Time now; + EXPECT_TRUE(base::Time::FromUTCString("23 Dec 2021 12:00:00", &now)); + test_clock()->SetNow(now); + + // Set the clock of geolocation controller to our test clock to control the + // time now. + geolocation_controller_ = ash::Shell::Get()->geolocation_controller(); + geolocation_controller()->SetClockForTesting(&test_clock_); + + // Every feature that is auto scheduled by default needs to set test clock. + // Otherwise the tests will fails `DCHECK_GE(start_time, now)` in + // `ScheduledFeature::RefreshScheduleTimer()` when the new user session + // is entered and `InitFromUserPrefs()` triggers `RefreshScheduleTimer()`. + ash::Shell::Get()->dark_mode_controller()->SetClockForTesting(&test_clock_); + CreateTestUserSessions(); // Simulate user 1 login. @@ -117,20 +130,7 @@ feature_->OnActiveUserPrefServiceChanged( Shell::Get()->session_controller()->GetActivePrefService()); - // Set the clock of geolocation controller to our test clock to control the - // time now. - geolocation_controller_ = ash::Shell::Get()->geolocation_controller(); - base::Time now; - EXPECT_TRUE(base::Time::FromUTCString("23 Dec 2021 12:00:00", &now)); - test_clock()->SetNow(now); - geolocation_controller()->SetClockForTesting(&test_clock_); - - // Set the timer of geolocation controller to `mock_timer` to allow us to - // trigger new geoposition receiving. - std::unique_ptr<base::MockOneShotTimer> mock_timer = - std::make_unique<base::MockOneShotTimer>(); - mock_timer_ptr_ = mock_timer.get(); - geolocation_controller()->SetTimerForTesting(std::move(mock_timer)); + timer_ptr_ = geolocation_controller()->GetTimerForTesting(); // `factory_` allows the test to control the value of geoposition // that the geolocation provider sends back upon geolocation request. @@ -185,14 +185,12 @@ // Fires the timer of the scheduler to request geoposition and wait for all // observers to receive the latest geoposition from the server. void FireTimerToFetchGeoposition() { - GeopositionResponsesWaiter waiter; - // Make sure that the timer is running indicating that the client runs - // the scheduler. - EXPECT_TRUE(mock_timer_ptr()->IsRunning()); + GeopositionResponsesWaiter waiter(geolocation_controller_); + EXPECT_TRUE(timer_ptr()->IsRunning()); // Fast forward the scheduler to reach the time when the controller // requests for geoposition from the server in // `GeolocationController::RequestGeoposition`. - mock_timer_ptr_->Fire(); + timer_ptr_->FireNow(); // Waits for the observers to receive the geoposition from the server. waiter.Wait(); } @@ -204,11 +202,16 @@ factory_->set_position(position_); } + // Checks if the feature is observing geoposition changes. + bool IsFeatureObservingGeoposition() { + return geolocation_controller()->HasObserverForTesting(feature()); + } + private: std::unique_ptr<TestScheduledFeature> feature_; GeolocationController* geolocation_controller_; base::SimpleTestClock test_clock_; - base::MockOneShotTimer* mock_timer_ptr_; + base::OneShotTimer* timer_ptr_; TestGeolocationUrlLoaderFactory* factory_; Geoposition position_; }; @@ -250,9 +253,9 @@ const ScheduledFeature::ScheduleType user1_schedule_type = ScheduledFeature::ScheduleType::kNone; EXPECT_EQ(user1_schedule_type, GetScheduleType()); - // Check that the geolocation controller does not fire a geoposition request - // timer when the schedule type is `kNone`. - EXPECT_FALSE(mock_timer_ptr()->IsRunning()); + // Check that the feature does not observe the geoposition when the schedule + // type is `kNone`. + EXPECT_FALSE(IsFeatureObservingGeoposition()); // Update user2's schedule type pref to sunset-to-sunrise. const ScheduledFeature::ScheduleType user2_schedule_type = @@ -262,19 +265,20 @@ // Switching to user2 should update the schedule type to sunset-to-sunrise. SwitchActiveUser(kUser2Email); EXPECT_EQ(user2_schedule_type, GetScheduleType()); - // Check that the geolocation controller fires a geoposition request timer - // when the schedule type is `kSunsetToSunrise`. - EXPECT_TRUE(mock_timer_ptr()->IsRunning()); + // Check that the feature starts observing geoposition when the schedule + // type is changed to `kSunsetToSunrise`. + EXPECT_TRUE(IsFeatureObservingGeoposition()); // Set custom schedule to test that once we switch to the user1 with `kNone` // schedule type, the feature should remove itself from a geolocation // observer. feature()->SetScheduleType(ScheduledFeature::ScheduleType::kCustom); - // Make sure that switching back to user1 remove itself from geolocation - // observer which results in geolocation controller timer stops running. + EXPECT_TRUE(IsFeatureObservingGeoposition()); + // Make sure that switching back to user1 makes it remove itself from the + // geoposition observer. SwitchActiveUser(kUser1Email); EXPECT_EQ(user1_schedule_type, GetScheduleType()); - EXPECT_FALSE(mock_timer_ptr()->IsRunning()); + EXPECT_FALSE(IsFeatureObservingGeoposition()); } // Tests transitioning from kNone to kCustom and back to kNone schedule @@ -467,7 +471,7 @@ GeolocationControllerObserver observer1; geolocation_controller()->AddObserver(&observer1); - EXPECT_TRUE(mock_timer_ptr()->IsRunning()); + EXPECT_TRUE(timer_ptr()->IsRunning()); EXPECT_FALSE(observer1.possible_change_in_timezone()); // Prepare a valid geoposition. @@ -478,7 +482,6 @@ SetServerPosition(position); FireTimerToFetchGeoposition(); EXPECT_TRUE(observer1.possible_change_in_timezone()); - EXPECT_TRUE(mock_timer_ptr()->IsRunning()); const base::Time sunset_time1 = geolocation_controller()->GetSunsetTime(); const base::Time sunrise_time1 = geolocation_controller()->GetSunriseTime(); // Our assumption is that GeolocationController gives us sunrise time @@ -493,6 +496,7 @@ EXPECT_FALSE(feature()->GetEnabled()); feature()->SetScheduleType(ScheduledFeature::ScheduleType::kSunsetToSunrise); EXPECT_FALSE(feature()->GetEnabled()); + EXPECT_TRUE(IsFeatureObservingGeoposition()); EXPECT_TRUE(feature()->timer()->IsRunning()); EXPECT_EQ(base::Hours(4), feature()->timer()->GetCurrentDelay()); @@ -523,7 +527,7 @@ SetServerPosition(position2); FireTimerToFetchGeoposition(); EXPECT_TRUE(observer1.possible_change_in_timezone()); - EXPECT_TRUE(mock_timer_ptr()->IsRunning()); + EXPECT_TRUE(IsFeatureObservingGeoposition()); const base::Time sunset_time2 = geolocation_controller()->GetSunsetTime(); const base::Time sunrise_time2 = geolocation_controller()->GetSunriseTime();
diff --git a/ash/wallpaper/test_wallpaper_controller_client.cc b/ash/wallpaper/test_wallpaper_controller_client.cc index 852ff68..aebeb14 100644 --- a/ash/wallpaper/test_wallpaper_controller_client.cc +++ b/ash/wallpaper/test_wallpaper_controller_client.cc
@@ -67,8 +67,10 @@ void TestWallpaperControllerClient::SetDefaultWallpaper( const AccountId& account_id, - bool show_wallpaper) { + bool show_wallpaper, + base::OnceCallback<void(bool success)> callback) { set_default_wallpaper_count_++; + std::move(callback).Run(/*success=*/true); } void TestWallpaperControllerClient::MigrateCollectionIdFromChromeApp(
diff --git a/ash/wallpaper/test_wallpaper_controller_client.h b/ash/wallpaper/test_wallpaper_controller_client.h index 4896af08..23e53bb5 100644 --- a/ash/wallpaper/test_wallpaper_controller_client.h +++ b/ash/wallpaper/test_wallpaper_controller_client.h
@@ -10,6 +10,7 @@ #include <unordered_map> #include "ash/public/cpp/wallpaper/wallpaper_controller_client.h" +#include "base/callback_forward.h" #include "base/containers/flat_map.h" #include "components/account_id/account_id.h" @@ -80,8 +81,10 @@ // WallpaperControllerClient: void OpenWallpaperPicker() override; void MaybeClosePreviewWallpaper() override; - void SetDefaultWallpaper(const AccountId& account_id, - bool show_wallpaper) override; + void SetDefaultWallpaper( + const AccountId& account_id, + bool show_wallpaper, + base::OnceCallback<void(bool success)> callback) override; void MigrateCollectionIdFromChromeApp( const AccountId& account_id, base::OnceCallback<void(const std::string&)> result_callback) override;
diff --git a/ash/wallpaper/wallpaper_controller_impl.cc b/ash/wallpaper/wallpaper_controller_impl.cc index 119a5dfc..c56284e 100644 --- a/ash/wallpaper/wallpaper_controller_impl.cc +++ b/ash/wallpaper/wallpaper_controller_impl.cc
@@ -1164,7 +1164,7 @@ const base::FilePath& wallpaper_path) { if (wallpaper_path.empty()) { // Fallback to default if the path is empty. - SetDefaultWallpaperImpl(account_id, show_wallpaper); + SetDefaultWallpaperImpl(account_id, show_wallpaper, base::DoNothing()); return; } @@ -1369,10 +1369,14 @@ } } -void WallpaperControllerImpl::SetDefaultWallpaper(const AccountId& account_id, - bool show_wallpaper) { - if (!CanSetUserWallpaper(account_id)) +void WallpaperControllerImpl::SetDefaultWallpaper( + const AccountId& account_id, + bool show_wallpaper, + SetWallpaperCallback callback) { + if (!CanSetUserWallpaper(account_id)) { + std::move(callback).Run(/*success=*/false); return; + } update_wallpaper_timer_.Stop(); @@ -1381,8 +1385,12 @@ LOG(ERROR) << "Initializing user wallpaper info fails. This should never " "happen except in tests."; } - if (show_wallpaper) - SetDefaultWallpaperImpl(account_id, /*show_wallpaper=*/true); + if (show_wallpaper) { + SetDefaultWallpaperImpl(account_id, /*show_wallpaper=*/true, + std::move(callback)); + } else { + std::move(callback).Run(/*success=*/true); + } } void WallpaperControllerImpl::SetCustomizedDefaultWallpaperPaths( @@ -1398,7 +1406,7 @@ // Customized default wallpapers are subject to the same restrictions as other // default wallpapers, e.g. they should not be set during guest sessions. - SetDefaultWallpaperImpl(EmptyAccountId(), show_wallpaper); + SetDefaultWallpaperImpl(EmptyAccountId(), show_wallpaper, base::DoNothing()); } void WallpaperControllerImpl::SetPolicyWallpaper( @@ -1543,7 +1551,8 @@ } if (info.type == WallpaperType::kDefault) { - SetDefaultWallpaperImpl(account_id, /*show_wallpaper=*/true); + SetDefaultWallpaperImpl(account_id, /*show_wallpaper=*/true, + base::DoNothing()); return; } @@ -1593,7 +1602,8 @@ if (ShouldSetDevicePolicyWallpaper()) SetDevicePolicyWallpaper(); else - SetDefaultWallpaperImpl(EmptyAccountId(), /*show_wallpaper=*/true); + SetDefaultWallpaperImpl(EmptyAccountId(), /*show_wallpaper=*/true, + base::DoNothing()); } void WallpaperControllerImpl::ShowOneShotWallpaper( @@ -1647,7 +1657,7 @@ // Removes the wallpaper info so that the user is no longer policy controlled, // otherwise setting default wallpaper is not allowed. RemoveUserWallpaperInfo(account_id); - SetDefaultWallpaper(account_id, show_wallpaper); + SetDefaultWallpaper(account_id, show_wallpaper, base::DoNothing()); } void WallpaperControllerImpl::GetOfflineWallpaperList( @@ -1935,7 +1945,8 @@ } void WallpaperControllerImpl::ShowDefaultWallpaperForTesting() { - SetDefaultWallpaperImpl(EmptyAccountId(), /*show_wallpaper=*/true); + SetDefaultWallpaperImpl(EmptyAccountId(), /*show_wallpaper=*/true, + base::DoNothing()); } void WallpaperControllerImpl::CreateEmptyWallpaperForTesting() { @@ -2084,10 +2095,13 @@ void WallpaperControllerImpl::SetDefaultWallpaperImpl( const AccountId& account_id, - bool show_wallpaper) { + bool show_wallpaper, + SetWallpaperCallback callback) { // There is no visible wallpaper in kiosk mode. - if (IsInKioskMode()) + if (IsInKioskMode()) { + std::move(callback).Run(/*success=*/false); return; + } wallpaper_cache_map_.erase(account_id); @@ -2129,12 +2143,13 @@ if (!cached_default_wallpaper_.image.isNull() && cached_default_wallpaper_.file_path == file_path) { OnDefaultWallpaperDecoded(file_path, layout, show_wallpaper, + std::move(callback), cached_default_wallpaper_.image); } else { ReadAndDecodeWallpaper( base::BindOnce(&WallpaperControllerImpl::OnDefaultWallpaperDecoded, weak_factory_.GetWeakPtr(), file_path, layout, - show_wallpaper), + show_wallpaper, std::move(callback)), file_path); } } @@ -2319,7 +2334,9 @@ sequenced_task_runner_->PostTask( FROM_HERE, base::BindOnce(&DeleteGooglePhotosCache, params.account_id)); - SetDefaultWallpaperImpl(params.account_id, /*show_wallpaper=*/true); + SetDefaultWallpaperImpl(params.account_id, /*show_wallpaper=*/true, + base::DoNothing()); + return; } std::move(callback).Run(false); return; @@ -2352,7 +2369,8 @@ if (success) { // If the request succeeded, but no photos came back, then the album is // empty or deleted. Reset to default as a fallback. - SetDefaultWallpaper(account_id, /*show_wallpaper=*/true); + SetDefaultWallpaper(account_id, /*show_wallpaper=*/true, + base::DoNothing()); } else { // If the request simply failed, retry in an hour. StartUpdateWallpaperTimer(base::Hours(1)); @@ -2529,7 +2547,7 @@ // `WallpaperType::kDefault` types. In unexpected cases, revert to default // wallpaper to fail safely. See crosbug.com/38429. LOG(ERROR) << "Wallpaper reverts to default unexpected."; - SetDefaultWallpaperImpl(account_id, show_wallpaper); + SetDefaultWallpaperImpl(account_id, show_wallpaper, base::DoNothing()); return; } @@ -2539,7 +2557,7 @@ // were created directly in local state (for testing). Ignore such // errors i.e. allow such type of debug configurations on the desktop. LOG(WARNING) << "User wallpaper info is empty: " << account_id.Serialize(); - SetDefaultWallpaperImpl(account_id, show_wallpaper); + SetDefaultWallpaperImpl(account_id, show_wallpaper, base::DoNothing()); return; } @@ -2592,6 +2610,7 @@ const base::FilePath& path, WallpaperLayout layout, bool show_wallpaper, + SetWallpaperCallback callback, const gfx::ImageSkia& image) { if (image.isNull()) { // Create a solid color wallpaper if the default wallpaper decoding fails. @@ -2603,6 +2622,11 @@ cached_default_wallpaper_.file_path = path; } + // Setting default wallpaper always succeeds even if the intended image failed + // decoding. Run the callback before doing the final step of showing the + // wallpaper to be consistent with other wallpaper controller methods. + std::move(callback).Run(/*success=*/true); + if (show_wallpaper) { WallpaperInfo info(cached_default_wallpaper_.file_path.value(), layout, WallpaperType::kDefault, base::Time::Now()); @@ -2728,7 +2752,7 @@ if (image.isNull()) { LOG(ERROR) << "Failed to decode user wallpaper at " << path.value() << " Falls back to default wallpaper. "; - SetDefaultWallpaperImpl(account_id, show_wallpaper); + SetDefaultWallpaperImpl(account_id, show_wallpaper, base::DoNothing()); return; } @@ -2913,7 +2937,8 @@ if (image.isNull()) { // If device policy wallpaper failed decoding, fall back to the default // wallpaper. - SetDefaultWallpaperImpl(EmptyAccountId(), /*show_wallpaper=*/true); + SetDefaultWallpaperImpl(EmptyAccountId(), /*show_wallpaper=*/true, + base::DoNothing()); } else { WallpaperInfo info = {device_policy_wallpaper_path_.value(), WALLPAPER_LAYOUT_CENTER_CROPPED, @@ -3314,7 +3339,7 @@ if (!photo) { sequenced_task_runner_->PostTask( FROM_HERE, base::BindOnce(&DeleteGooglePhotosCache, account_id)); - SetDefaultWallpaper(account_id, /*show_wallpaper=*/true); + SetDefaultWallpaper(account_id, /*show_wallpaper=*/true, base::DoNothing()); } else { StartGooglePhotosStalenessTimer(); }
diff --git a/ash/wallpaper/wallpaper_controller_impl.h b/ash/wallpaper/wallpaper_controller_impl.h index f2bc6d9..c4676bc 100644 --- a/ash/wallpaper/wallpaper_controller_impl.h +++ b/ash/wallpaper/wallpaper_controller_impl.h
@@ -269,7 +269,8 @@ void SetGooglePhotosWallpaper(const GooglePhotosWallpaperParams& params, SetWallpaperCallback callback) override; void SetDefaultWallpaper(const AccountId& account_id, - bool show_wallpaper) override; + bool show_wallpaper, + SetWallpaperCallback callback) override; void SetCustomizedDefaultWallpaperPaths( const base::FilePath& customized_default_small_path, const base::FilePath& customized_default_large_path) override; @@ -422,7 +423,8 @@ // |show_wallpaper| is true. Otherwise just save the defaut wallpaper to // cache. void SetDefaultWallpaperImpl(const AccountId& account_id, - bool show_wallpaper); + bool show_wallpaper, + SetWallpaperCallback callback); // When kiosk app is running or policy is enforced, setting a user wallpaper // is not allowed. @@ -540,6 +542,7 @@ void OnDefaultWallpaperDecoded(const base::FilePath& path, WallpaperLayout layout, bool show_wallpaper, + SetWallpaperCallback callback, const gfx::ImageSkia& image); // Saves |image| to disk if the user's data is not ephemeral, or if it is a
diff --git a/ash/wallpaper/wallpaper_controller_unittest.cc b/ash/wallpaper/wallpaper_controller_unittest.cc index 6de6066..08aee7eb 100644 --- a/ash/wallpaper/wallpaper_controller_unittest.cc +++ b/ash/wallpaper/wallpaper_controller_unittest.cc
@@ -33,6 +33,7 @@ #include "ash/wm/overview/overview_controller.h" #include "ash/wm/window_cycle/window_cycle_controller.h" #include "ash/wm/window_state.h" +#include "base/callback_helpers.h" #include "base/command_line.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" @@ -375,6 +376,7 @@ } // WallpaperControllerObserver + void OnWallpaperChanged() override { ++wallpaper_changed_count_; } void OnWallpaperColorsChanged() override { ++colors_changed_count_; } void OnWallpaperBlurChanged() override { ++blur_changed_count_; } void OnFirstWallpaperShown() override { ++first_shown_count_; } @@ -382,12 +384,14 @@ int colors_changed_count() const { return colors_changed_count_; } int blur_changed_count() const { return blur_changed_count_; } int first_shown_count() const { return first_shown_count_; } + int wallpaper_changed_count() const { return wallpaper_changed_count_; } private: WallpaperController* controller_; int colors_changed_count_ = 0; int blur_changed_count_ = 0; int first_shown_count_ = 0; + int wallpaper_changed_count_ = 0; }; } // namespace @@ -1561,7 +1565,8 @@ RunAllTasksUntilIdle(); ClearWallpaperCount(); ClearDecodeFilePaths(); - controller_->SetDefaultWallpaper(account_id_1, true /*show_wallpaper=*/); + controller_->SetDefaultWallpaper(account_id_1, true /*show_wallpaper=*/, + base::DoNothing()); RunAllTasksUntilIdle(); EXPECT_EQ(1, GetWallpaperCount()); EXPECT_EQ(controller_->GetWallpaperType(), WallpaperType::kDefault); @@ -1581,7 +1586,8 @@ RunAllTasksUntilIdle(); ClearWallpaperCount(); ClearDecodeFilePaths(); - controller_->SetDefaultWallpaper(account_id_1, true /*show_wallpaper=*/); + controller_->SetDefaultWallpaper(account_id_1, true /*show_wallpaper=*/, + base::DoNothing()); RunAllTasksUntilIdle(); EXPECT_EQ(1, GetWallpaperCount()); EXPECT_EQ(controller_->GetWallpaperType(), WallpaperType::kDefault); @@ -1601,7 +1607,8 @@ RunAllTasksUntilIdle(); ClearWallpaperCount(); ClearDecodeFilePaths(); - controller_->SetDefaultWallpaper(account_id_1, true /*show_wallpaper=*/); + controller_->SetDefaultWallpaper(account_id_1, true /*show_wallpaper=*/, + base::DoNothing()); RunAllTasksUntilIdle(); EXPECT_EQ(1, GetWallpaperCount()); EXPECT_EQ(controller_->GetWallpaperType(), WallpaperType::kDefault); @@ -1625,7 +1632,8 @@ RunAllTasksUntilIdle(); ClearWallpaperCount(); ClearDecodeFilePaths(); - controller_->SetDefaultWallpaper(kChildAccountId, true /*show_wallpaper=*/); + controller_->SetDefaultWallpaper(kChildAccountId, true /*show_wallpaper=*/, + base::DoNothing()); RunAllTasksUntilIdle(); EXPECT_EQ(1, GetWallpaperCount()); EXPECT_EQ(controller_->GetWallpaperType(), WallpaperType::kDefault); @@ -1639,7 +1647,8 @@ RunAllTasksUntilIdle(); ClearWallpaperCount(); ClearDecodeFilePaths(); - controller_->SetDefaultWallpaper(kChildAccountId, true /*show_wallpaper=*/); + controller_->SetDefaultWallpaper(kChildAccountId, true /*show_wallpaper=*/, + base::DoNothing()); RunAllTasksUntilIdle(); EXPECT_EQ(1, GetWallpaperCount()); EXPECT_EQ(controller_->GetWallpaperType(), WallpaperType::kDefault); @@ -1671,7 +1680,8 @@ const AccountId guest_id = AccountId::FromUserEmail(user_manager::kGuestUserName); fake_user_manager_->AddGuestUser(guest_id); - controller_->SetDefaultWallpaper(guest_id, /*show_wallpaper=*/true); + controller_->SetDefaultWallpaper(guest_id, /*show_wallpaper=*/true, + base::DoNothing()); WallpaperInfo wallpaper_info; WallpaperInfo default_wallpaper_info( @@ -1738,7 +1748,8 @@ RunAllTasksUntilIdle(); ClearWallpaperCount(); ClearDecodeFilePaths(); - controller_->SetDefaultWallpaper(guest_id, true /*show_wallpaper=*/); + controller_->SetDefaultWallpaper(guest_id, true /*show_wallpaper=*/, + base::DoNothing()); RunAllTasksUntilIdle(); EXPECT_EQ(1, GetWallpaperCount()); EXPECT_EQ(controller_->GetWallpaperType(), WallpaperType::kDefault); @@ -1752,7 +1763,8 @@ RunAllTasksUntilIdle(); ClearWallpaperCount(); ClearDecodeFilePaths(); - controller_->SetDefaultWallpaper(guest_id, true /*show_wallpaper=*/); + controller_->SetDefaultWallpaper(guest_id, true /*show_wallpaper=*/, + base::DoNothing()); RunAllTasksUntilIdle(); EXPECT_EQ(1, GetWallpaperCount()); EXPECT_EQ(controller_->GetWallpaperType(), WallpaperType::kDefault); @@ -1761,6 +1773,34 @@ GetDecodeFilePaths()[0]); } +TEST_P(WallpaperControllerTest, SetDefaultWallpaperCallbackTiming) { + SetBypassDecode(); + SimulateUserLogin(account_id_1); + + // First, simulate setting a user custom wallpaper. + SimulateSettingCustomWallpaper(account_id_1); + WallpaperInfo wallpaper_info; + EXPECT_TRUE(controller_->GetUserWallpaperInfo(account_id_1, &wallpaper_info)); + EXPECT_NE(wallpaper_info.type, WallpaperType::kDefault); + + TestWallpaperControllerObserver observer(controller_); + + // Set default wallpaper and wait for success callback. + base::RunLoop loop; + controller_->SetDefaultWallpaper( + account_id_1, /*show_wallpaper=*/true, + base::BindLambdaForTesting([&loop, &observer](bool success) { + ASSERT_TRUE(success); + // Success callback should run before wallpaper observer is notified of + // change. + ASSERT_EQ(0, observer.wallpaper_changed_count()); + loop.Quit(); + })); + loop.Run(); + // Wallpaper observer should have been notified of wallpaper change. + EXPECT_EQ(1, observer.wallpaper_changed_count()); +} + TEST_P(WallpaperControllerTest, IgnoreWallpaperRequestInKioskMode) { gfx::ImageSkia image = CreateImage(640, 480, kWallpaperColor); SimulateUserLogin("kiosk", user_manager::USER_TYPE_KIOSK_APP); @@ -1801,7 +1841,8 @@ // Verify that |SetDefaultWallpaper| doesn't set wallpaper in kiosk mode, and // |account_id_1|'s wallpaper info is not updated. ClearWallpaperCount(); - controller_->SetDefaultWallpaper(account_id_1, true /*show_wallpaper=*/); + controller_->SetDefaultWallpaper(account_id_1, true /*show_wallpaper=*/, + base::DoNothing()); RunAllTasksUntilIdle(); EXPECT_EQ(0, GetWallpaperCount()); EXPECT_FALSE( @@ -1916,7 +1957,8 @@ // Verify that |SetDefaultWallpaper| doesn't set wallpaper when policy is // enforced, and the user wallpaper info is not updated. ClearWallpaperCount(); - controller_->SetDefaultWallpaper(account_id_1, true /*show_wallpaper=*/); + controller_->SetDefaultWallpaper(account_id_1, true /*show_wallpaper=*/, + base::DoNothing()); RunAllTasksUntilIdle(); EXPECT_EQ(0, GetWallpaperCount()); EXPECT_TRUE( @@ -1961,7 +2003,8 @@ EXPECT_TRUE(controller_->GetPathFromCache(account_id_1, &path)); // Verify |SetDefaultWallpaper| clears wallpaper cache. - controller_->SetDefaultWallpaper(account_id_1, true /*show_wallpaper=*/); + controller_->SetDefaultWallpaper(account_id_1, true /*show_wallpaper=*/, + base::DoNothing()); EXPECT_FALSE( controller_->GetWallpaperFromCache(account_id_1, &cached_wallpaper)); EXPECT_FALSE(controller_->GetPathFromCache(account_id_1, &path)); @@ -2292,7 +2335,8 @@ // Now login another user and set a default wallpaper for the user. SimulateUserLogin(account_id_2); - controller_->SetDefaultWallpaper(account_id_2, true /*show_wallpaper=*/); + controller_->SetDefaultWallpaper(account_id_2, true /*show_wallpaper=*/, + base::DoNothing()); // Simulate the removal of |kUser2|. controller_->RemoveUserWallpaper(account_id_2);
diff --git a/ash/webui/camera_app_ui/resources/js/externs/types.d.ts b/ash/webui/camera_app_ui/resources/js/externs/types.d.ts index 036880d..8d65d4e3 100644 --- a/ash/webui/camera_app_ui/resources/js/externs/types.d.ts +++ b/ash/webui/camera_app_ui/resources/js/externs/types.d.ts
@@ -25,17 +25,6 @@ // still in working draft stage. // https://wicg.github.io/file-system-access/ -// close() is only implemented in Chrome so it's not in upstream type -// definitions. Ref: -// https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/827. -interface WritableStream { - close(): Promise<void>; -} - -interface FileSystemHandleBase { - readonly name: string; -} - type FileSystemWriteChunkType = Blob|BufferSource|string; interface FileSystemWritableFileStream extends WritableStream { @@ -48,33 +37,15 @@ keepExistingData?: boolean; } -interface FileSystemFileHandle extends FileSystemHandleBase { - readonly kind: 'file'; +interface FileSystemFileHandle { createWritable(options?: FileSystemCreateWritableOptions): Promise<FileSystemWritableFileStream>; - getFile(): Promise<File>; } -interface FileSystemGetDirectoryOptions { - create?: boolean; -} - -interface FileSystemGetFileOptions { - create?: boolean; -} - -interface FileSystemDirectoryHandle extends FileSystemHandleBase { - readonly kind: 'directory'; - getDirectoryHandle(name: string, options?: FileSystemGetDirectoryOptions): - Promise<FileSystemDirectoryHandle>; - getFileHandle(name: string, options?: FileSystemGetFileOptions): - Promise<FileSystemFileHandle>; - removeEntry(name: string): Promise<void>; +interface FileSystemDirectoryHandle { values(): IterableIterator<FileSystemHandle>; } -type FileSystemHandle = FileSystemDirectoryHandle|FileSystemFileHandle; - interface StorageManager { getDirectory(): Promise<FileSystemDirectoryHandle>; }
diff --git a/ash/webui/camera_app_ui/resources/js/models/file_system.ts b/ash/webui/camera_app_ui/resources/js/models/file_system.ts index 20232a3..9fc2d9d 100644 --- a/ash/webui/camera_app_ui/resources/js/models/file_system.ts +++ b/ash/webui/camera_app_ui/resources/js/models/file_system.ts
@@ -105,7 +105,7 @@ await idb.set(idb.KEY_CAMERA_DIRECTORY_HANDLE, dir); window.sessionStorage.setItem('IsConsumedHandle', 'true'); - handle.signal(dir); + handle.signal(dir as FileSystemDirectoryHandle); }); } const dir = await handle.wait();
diff --git a/ash/webui/camera_app_ui/resources/js/models/file_system_access_entry.ts b/ash/webui/camera_app_ui/resources/js/models/file_system_access_entry.ts index 9213c81..09c361d9 100644 --- a/ash/webui/camera_app_ui/resources/js/models/file_system_access_entry.ts +++ b/ash/webui/camera_app_ui/resources/js/models/file_system_access_entry.ts
@@ -157,7 +157,7 @@ const results = []; for await (const handle of this.handle.values()) { if (handle.kind === 'file') { - results.push(new FileAccessEntry(handle, this)); + results.push(new FileAccessEntry(handle as FileSystemFileHandle, this)); } } return results; @@ -167,7 +167,8 @@ const results = []; for await (const handle of this.handle.values()) { if (handle.kind === 'directory') { - results.push(new DirectoryAccessEntryImpl(handle)); + results.push( + new DirectoryAccessEntryImpl(handle as FileSystemDirectoryHandle)); } } return results;
diff --git a/ash/webui/personalization_app/mojom/personalization_app.mojom b/ash/webui/personalization_app/mojom/personalization_app.mojom index 8c83328..802d8f75 100644 --- a/ash/webui/personalization_app/mojom/personalization_app.mojom +++ b/ash/webui/personalization_app/mojom/personalization_app.mojom
@@ -474,6 +474,10 @@ // Notifies the JS side about the current albums. OnAlbumsChanged(array<AmbientModeAlbum> albums); + + // Notifies the JS side about the previews of the selected Google Photos + // albums. + OnGooglePhotosAlbumsPreviewsFetched(array<url.mojom.Url> previews); }; // Provides APIs to expose Ambient mode settings.
diff --git a/ash/webui/personalization_app/resources/trusted/ambient/ambient_actions.ts b/ash/webui/personalization_app/resources/trusted/ambient/ambient_actions.ts index d180cd1..3516a9a8 100644 --- a/ash/webui/personalization_app/resources/trusted/ambient/ambient_actions.ts +++ b/ash/webui/personalization_app/resources/trusted/ambient/ambient_actions.ts
@@ -3,6 +3,7 @@ // found in the LICENSE file. import {Action} from 'chrome://resources/js/cr/ui/store.js'; +import {Url} from 'chrome://resources/mojo/url/mojom/url.mojom-webui.js'; import {AmbientModeAlbum, AnimationTheme, TemperatureUnit, TopicSource} from '../personalization_app.mojom-webui.js'; @@ -15,13 +16,15 @@ SET_ALBUM_SELECTED = 'set_album_selected', SET_AMBIENT_MODE_ENABLED = 'set_ambient_mode_enabled', SET_ANIMATION_THEME = 'set_animation_theme', + SET_GOOGLE_PHOTOS_ALBUMS_PREVIEWS = 'set_google_photos_albums_previews', SET_TEMPERATURE_UNIT = 'set_temperature_unit', SET_TOPIC_SOURCE = 'set_topic_source', } export type AmbientActions = SetAlbumsAction|SetAlbumSelectedAction|SetAmbientModeEnabledAction| - SetAnimationThemeAction|SetTopicSourceAction|SetTemperatureUnitAction; + SetAnimationThemeAction|SetGooglePhotosAlbumsPreviewsAction| + SetTopicSourceAction|SetTemperatureUnitAction; export type SetAlbumsAction = Action&{ name: AmbientActionName.SET_ALBUMS, @@ -42,6 +45,11 @@ animationTheme: AnimationTheme, }; +export type SetGooglePhotosAlbumsPreviewsAction = Action&{ + name: AmbientActionName.SET_GOOGLE_PHOTOS_ALBUMS_PREVIEWS, + previews: Url[], +}; + export type SetTemperatureUnitAction = Action&{ name: AmbientActionName.SET_TEMPERATURE_UNIT, temperatureUnit: TemperatureUnit, @@ -80,6 +88,14 @@ } /** + * Sets the current value of Google Photos albums previews. + */ +export function setGooglePhotosAlbumsPreviewsAction(previews: Url[]): + SetGooglePhotosAlbumsPreviewsAction { + return {name: AmbientActionName.SET_GOOGLE_PHOTOS_ALBUMS_PREVIEWS, previews}; +} + +/** * Sets the current value of the topic source. */ export function setTopicSourceAction(topicSource: TopicSource):
diff --git a/ash/webui/personalization_app/resources/trusted/ambient/ambient_observer.ts b/ash/webui/personalization_app/resources/trusted/ambient/ambient_observer.ts index 2d36a883..1ae5943 100644 --- a/ash/webui/personalization_app/resources/trusted/ambient/ambient_observer.ts +++ b/ash/webui/personalization_app/resources/trusted/ambient/ambient_observer.ts
@@ -2,10 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {Url} from 'chrome://resources/mojo/url/mojom/url.mojom-webui.js'; import {AmbientModeAlbum, AmbientObserverInterface, AmbientObserverReceiver, AmbientProviderInterface, AnimationTheme, TemperatureUnit, TopicSource} from '../personalization_app.mojom-webui.js'; import {PersonalizationStore} from '../personalization_store.js'; -import {setAlbumsAction, setAmbientModeEnabledAction, setAnimationThemeAction, setTemperatureUnitAction, setTopicSourceAction} from './ambient_actions.js'; +import {setAlbumsAction, setAmbientModeEnabledAction, setAnimationThemeAction, setGooglePhotosAlbumsPreviewsAction, setTemperatureUnitAction, setTopicSourceAction} from './ambient_actions.js'; import {getAmbientProvider} from './ambient_interface_provider.js'; /** @fileoverview listens for updates on color mode changes. */ @@ -62,4 +63,9 @@ const store = PersonalizationStore.getInstance(); store.dispatch(setAlbumsAction(albums)); } + + onGooglePhotosAlbumsPreviewsFetched(previews: Url[]) { + const store = PersonalizationStore.getInstance(); + store.dispatch(setGooglePhotosAlbumsPreviewsAction(previews)); + } }
diff --git a/ash/webui/personalization_app/resources/trusted/ambient/ambient_preview_element.html b/ash/webui/personalization_app/resources/trusted/ambient/ambient_preview_element.html index 76c71db2..6ec2b73 100644 --- a/ash/webui/personalization_app/resources/trusted/ambient/ambient_preview_element.html +++ b/ash/webui/personalization_app/resources/trusted/ambient/ambient_preview_element.html
@@ -228,10 +228,10 @@ [[getAlbumDescription_(topicSource_, previewAlbums_)]] </span> </h2> - <div id="collageContainer" class$="[[getContainerClass_(previewAlbums_)]]"> - <template is="dom-repeat" items="[[getCollageItems_(previewAlbums_)]]"> + <div id="collageContainer" class$="[[getCollageContainerClass_(collageImages_)]]"> + <template is="dom-repeat" items="[[collageImages_]]"> <img class="collage-item" is="cr-auto-img" - auto-src="[[getPreviewImage_(item)]]" is-google-photos> + auto-src="[[item.url]]" is-google-photos> </template> </div> </template>
diff --git a/ash/webui/personalization_app/resources/trusted/ambient/ambient_preview_element.ts b/ash/webui/personalization_app/resources/trusted/ambient/ambient_preview_element.ts index 5d4ca09..dfa9c20 100644 --- a/ash/webui/personalization_app/resources/trusted/ambient/ambient_preview_element.ts +++ b/ash/webui/personalization_app/resources/trusted/ambient/ambient_preview_element.ts
@@ -14,6 +14,7 @@ import '../cros_button_style.js'; import {assert} from 'chrome://resources/js/assert_ts.js'; +import {Url} from 'chrome://resources/mojo/url/mojom/url.mojom-webui.js'; import {isNonEmptyArray} from '../../common/utils.js'; import {AmbientModeAlbum, TopicSource} from '../personalization_app.mojom-webui.js'; import {logAmbientModeOptInUMA} from '../personalization_metrics_logger.js'; @@ -60,7 +61,17 @@ }, loading_: { type: Boolean, - computed: 'computeLoading_(ambientModeEnabled_, albums_, topicSource_)', + computed: + 'computeLoading_(ambientModeEnabled_, albums_, topicSource_, googlePhotosAlbumsPreviews_)', + }, + googlePhotosAlbumsPreviews_: { + type: Array, + value: null, + }, + collageImages_: { + type: Array, + computed: + 'computeCollageImages_(topicSource_, previewAlbums_, googlePhotosAlbumsPreviews_)', } }; } @@ -73,6 +84,8 @@ private previewAlbums_: AmbientModeAlbum[]|null; private firstPreviewAlbum_: AmbientModeAlbum|null; private loading_: boolean; + private googlePhotosAlbumsPreviews_: Url[]|null; + private collageImages_: Url[]; override ready() { super.ready(); @@ -84,13 +97,16 @@ this.watch( 'ambientModeEnabled_', state => state.ambient.ambientModeEnabled); this.watch('albums_', state => state.ambient.albums); + this.watch( + 'googlePhotosAlbumsPreviews_', + state => state.ambient.googlePhotosAlbumsPreviews); this.watch('topicSource_', state => state.ambient.topicSource); this.updateFromStore(); } private computeLoading_(): boolean { return this.ambientModeEnabled_ === null || this.albums_ === null || - this.topicSource_ === null; + this.topicSource_ === null || this.googlePhotosAlbumsPreviews_ === null; } /** Enable ambient mode and navigates to the ambient subpage. */ @@ -109,6 +125,34 @@ PersonalizationRouter.instance().goToRoute(Paths.Ambient); } + /** + * Return the array of images that form the collage. + * When topic source is Google Photos: + * - if |googlePhotosAlbumsPreviews_| is non-empty but contains fewer than 4 + * images, only return one of them; otherwise return the first 4. + * - if ||googlePhotosAlbumsPreviews_| is empty: + * - if |previewAlbums_| contains fewer than 4 albums, return one of + * their previews; otherwise return the first 4. + */ + private computeCollageImages_(): Url[] { + switch (this.topicSource_) { + case TopicSource.kArtGallery: + return (this.previewAlbums_ || []).map(album => album.url); + case TopicSource.kGooglePhotos: + if (isNonEmptyArray(this.googlePhotosAlbumsPreviews_)) { + return this.googlePhotosAlbumsPreviews_.length < 4 ? + [this.googlePhotosAlbumsPreviews_[0]] : + this.googlePhotosAlbumsPreviews_.slice(0, 4); + } + if (isNonEmptyArray(this.previewAlbums_)) { + return this.previewAlbums_.length < 4 ? + [this.previewAlbums_[0].url] : + this.previewAlbums_.map(album => album.url).slice(0, 4); + } + } + return []; + } + private computePreviewAlbums_(): AmbientModeAlbum[]|null { return (this.albums_ || []) .filter( @@ -128,8 +172,8 @@ ''; } - private getContainerClass_(): string { - return `collage-${this.getCollageItems_().length}`; + private getCollageContainerClass_(): string { + return `collage-${this.collageImages_.length}`; } private getCollageItems_(): AmbientModeAlbum[] {
diff --git a/ash/webui/personalization_app/resources/trusted/ambient/ambient_reducers.ts b/ash/webui/personalization_app/resources/trusted/ambient/ambient_reducers.ts index abbf841..6c32227 100644 --- a/ash/webui/personalization_app/resources/trusted/ambient/ambient_reducers.ts +++ b/ash/webui/personalization_app/resources/trusted/ambient/ambient_reducers.ts
@@ -50,6 +50,17 @@ } } +export function googlePhotosAlbumsPreviewsReducer( + state: AmbientState['googlePhotosAlbumsPreviews'], action: Actions, + _: PersonalizationState): AmbientState['googlePhotosAlbumsPreviews'] { + switch (action.name) { + case AmbientActionName.SET_GOOGLE_PHOTOS_ALBUMS_PREVIEWS: + return action.previews; + default: + return state; + } +} + export function temperatureUnitReducer( state: AmbientState['temperatureUnit'], action: Actions, _: PersonalizationState): AmbientState['temperatureUnit'] { @@ -77,6 +88,7 @@ albums: albumsReducer, ambientModeEnabled: ambientModeEnabledReducer, animationTheme: animationThemeReducer, + googlePhotosAlbumsPreviews: googlePhotosAlbumsPreviewsReducer, temperatureUnit: temperatureUnitReducer, topicSource: topicSourceReducer, };
diff --git a/ash/webui/personalization_app/resources/trusted/ambient/ambient_state.ts b/ash/webui/personalization_app/resources/trusted/ambient/ambient_state.ts index e30dec7..9ffdb0b1 100644 --- a/ash/webui/personalization_app/resources/trusted/ambient/ambient_state.ts +++ b/ash/webui/personalization_app/resources/trusted/ambient/ambient_state.ts
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {Url} from 'chrome://resources/mojo/url/mojom/url.mojom-webui.js'; import {AmbientModeAlbum, AnimationTheme, TemperatureUnit, TopicSource} from '../personalization_app.mojom-webui.js'; /** @@ -11,6 +12,7 @@ albums: AmbientModeAlbum[]|null; ambientModeEnabled: boolean|null; animationTheme: AnimationTheme|null; + googlePhotosAlbumsPreviews: Url[]|null; temperatureUnit: TemperatureUnit|null; topicSource: TopicSource|null; } @@ -20,6 +22,7 @@ albums: null, ambientModeEnabled: null, animationTheme: null, + googlePhotosAlbumsPreviews: null, temperatureUnit: null, topicSource: null, };
diff --git a/ash/webui/personalization_app/resources/trusted/personalization_app.ts b/ash/webui/personalization_app/resources/trusted/personalization_app.ts index 8d2ec3a..d49488d 100644 --- a/ash/webui/personalization_app/resources/trusted/personalization_app.ts +++ b/ash/webui/personalization_app/resources/trusted/personalization_app.ts
@@ -50,7 +50,7 @@ export {ImagesGrid} from '../untrusted/images_grid.js'; export {AlbumList} from './ambient/album_list_element.js'; export {AlbumsSubpage} from './ambient/albums_subpage_element.js'; -export {AmbientActionName, AmbientActions, SetAlbumsAction, setAlbumsAction, SetAlbumSelectedAction, setAlbumSelectedAction, SetAmbientModeEnabledAction, setAmbientModeEnabledAction, SetAnimationThemeAction, setAnimationThemeAction, SetTemperatureUnitAction, setTemperatureUnitAction, SetTopicSourceAction, setTopicSourceAction} from './ambient/ambient_actions.js'; +export {AmbientActionName, AmbientActions, SetAlbumsAction, setAlbumsAction, SetAlbumSelectedAction, setAlbumSelectedAction, SetAmbientModeEnabledAction, setAmbientModeEnabledAction, SetAnimationThemeAction, setAnimationThemeAction, SetGooglePhotosAlbumsPreviewsAction, setGooglePhotosAlbumsPreviewsAction, SetTemperatureUnitAction, setTemperatureUnitAction, SetTopicSourceAction, setTopicSourceAction} from './ambient/ambient_actions.js'; export {setAmbientProviderForTesting} from './ambient/ambient_interface_provider.js'; export {AmbientObserver} from './ambient/ambient_observer.js'; export {AmbientPreview} from './ambient/ambient_preview_element.js'; @@ -92,6 +92,7 @@ export {GooglePhotosPhotos, GooglePhotosPhotosRow, GooglePhotosPhotosSection} from './wallpaper/google_photos_photos_element.js'; export {GooglePhotosZeroState} from './wallpaper/google_photos_zero_state_element.js'; export {LocalImages} from './wallpaper/local_images_element.js'; + export * from './wallpaper/wallpaper_actions.js'; export {WallpaperCollections} from './wallpaper/wallpaper_collections_element.js'; export {cancelPreviewWallpaper, confirmPreviewWallpaper, fetchCollections, fetchGooglePhotosAlbum, fetchGooglePhotosAlbums, fetchGooglePhotosPhotos, fetchLocalData, getDailyRefreshCollectionId, getLocalImages, initializeBackdropData, initializeGooglePhotosData, selectWallpaper, setCurrentWallpaperLayout, setDailyRefreshCollectionId, updateDailyRefreshWallpaper} from './wallpaper/wallpaper_controller.js';
diff --git a/ash/webui/personalization_app/search/search_handler.cc b/ash/webui/personalization_app/search/search_handler.cc index a4620c9..248fff2 100644 --- a/ash/webui/personalization_app/search/search_handler.cc +++ b/ash/webui/personalization_app/search/search_handler.cc
@@ -28,6 +28,7 @@ namespace { +// Sorts search results descending. bool CompareSearchResults(const mojom::SearchResultPtr& a, const mojom::SearchResultPtr& b) { return a->relevance_score > b->relevance_score; @@ -121,9 +122,11 @@ /*relevance_score=*/local_result.score)); } - // Limit to top |max_num_results| results. Array is small so sort and take - // |max_num_results| front. - std::sort(search_results.begin(), search_results.end(), CompareSearchResults); + // Limit to top |max_num_results| results. Use partial_sort and then resize. + std::partial_sort( + search_results.begin(), + std::min(search_results.begin() + max_num_results, search_results.end()), + search_results.end(), CompareSearchResults); search_results.resize( std::min(static_cast<size_t>(max_num_results), search_results.size()));
diff --git a/ash/webui/personalization_app/search/search_handler_unittest.cc b/ash/webui/personalization_app/search/search_handler_unittest.cc index dad6484..0f83d33 100644 --- a/ash/webui/personalization_app/search/search_handler_unittest.cc +++ b/ash/webui/personalization_app/search/search_handler_unittest.cc
@@ -6,6 +6,7 @@ #include <memory> #include <string> +#include <utility> #include <vector> #include "ash/constants/ash_features.h" @@ -15,8 +16,11 @@ #include "ash/webui/personalization_app/search/search.mojom-test-utils.h" #include "ash/webui/personalization_app/search/search.mojom.h" #include "ash/webui/personalization_app/search/search_concept.h" +#include "ash/webui/personalization_app/search/search_tag_registry.h" #include "base/callback.h" +#include "base/run_loop.h" #include "base/strings/string_number_conversions.h" +#include "base/test/bind.h" #include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "chromeos/components/local_search_service/public/cpp/local_search_service_proxy.h" @@ -108,6 +112,25 @@ search_handler_remote_.BindNewPipeAndPassReceiver()); } + std::vector<mojom::SearchResultPtr> SimulateSearchCompleted( + uint32_t max_num_results, + ::chromeos::local_search_service::ResponseStatus response_status, + const absl::optional< + std::vector<::chromeos::local_search_service::Result>>& + local_search_service_results) { + std::vector<mojom::SearchResultPtr> result; + base::RunLoop loop; + search_handler_->OnLocalSearchDone( + base::BindLambdaForTesting( + [&result, done = loop.QuitClosure()]( + std::vector<mojom::SearchResultPtr> search_results) { + result = std::move(search_results); + std::move(done).Run(); + }), + max_num_results, response_status, local_search_service_results); + return result; + } + SearchHandler* search_handler() { return search_handler_.get(); } SearchTagRegistry* search_tag_registry() { @@ -277,5 +300,53 @@ } } +TEST_F(PersonalizationAppSearchHandlerTest, SortsAndTruncatesResults) { + // Test search concepts. + std::vector<const SearchConcept> test_search_concepts = { + {.message_id = IDS_PERSONALIZATION_APP_WALLPAPER_LABEL}, + {.message_id = IDS_PERSONALIZATION_APP_PERSONALIZATION_HUB_TITLE}, + {.message_id = IDS_PERSONALIZATION_APP_SCREENSAVER_LABEL}, + {.message_id = IDS_PERSONALIZATION_APP_AVATAR_LABEL}, + }; + SearchTagRegistry::SearchConceptUpdates updates; + for (const auto& concept : test_search_concepts) { + updates.insert(std::make_pair(&concept, true)); + } + search_tag_registry()->UpdateSearchConcepts(updates); + + // Scores that correspond to each of the |test_search_concepts|. + std::vector<double> scores = {0.33, 0.5, 0.1, 0.99}; + std::vector<::chromeos::local_search_service::Result> fake_local_results; + for (size_t i = 0; i < scores.size(); i++) { + std::vector<::chromeos::local_search_service::Position> positions; + positions.emplace_back(/*content_id=*/base::NumberToString( + test_search_concepts.at(i).message_id), + /*start=*/0, /*length=*/0); + fake_local_results.emplace_back( + /*id=*/base::NumberToString(test_search_concepts.at(i).message_id), + /*score=*/scores.at(i), std::move(positions)); + } + + constexpr size_t maxNumResults = 2; + auto results = SimulateSearchCompleted( + /*max_num_results=*/maxNumResults, + ::chromeos::local_search_service::ResponseStatus::kSuccess, + absl::make_optional(fake_local_results)); + + // Capped at |maxNumResults|. + EXPECT_EQ(maxNumResults, results.size()); + + // First result is top scoring result. + EXPECT_EQ(l10n_util::GetStringUTF16(IDS_PERSONALIZATION_APP_AVATAR_LABEL), + results.at(0)->text); + EXPECT_EQ(0.99, results.at(0)->relevance_score); + + // Next result is second best score. + EXPECT_EQ(l10n_util::GetStringUTF16( + IDS_PERSONALIZATION_APP_PERSONALIZATION_HUB_TITLE), + results.at(1)->text); + EXPECT_EQ(0.5, results.at(1)->relevance_score); +} + } // namespace personalization_app } // namespace ash
diff --git a/ash/webui/projector_app/annotator_message_handler.cc b/ash/webui/projector_app/annotator_message_handler.cc index e2a520a..5a80037a1 100644 --- a/ash/webui/projector_app/annotator_message_handler.cc +++ b/ash/webui/projector_app/annotator_message_handler.cc
@@ -30,6 +30,11 @@ base::Unretained(this))); web_ui()->RegisterMessageCallback( + "onCanvasInitialized", + base::BindRepeating(&AnnotatorMessageHandler::OnCanvasInitialized, + base::Unretained(this))); + + web_ui()->RegisterMessageCallback( "onError", base::BindRepeating(&AnnotatorMessageHandler::OnError, base::Unretained(this))); } @@ -68,6 +73,13 @@ args[1].GetBool()); } +void AnnotatorMessageHandler::OnCanvasInitialized( + const base::Value::List& args) { + DCHECK_EQ(args.size(), 1u); + DCHECK(args[0].is_bool()); + ProjectorController::Get()->OnCanvasInitialized(args[0].GetBool()); +} + void AnnotatorMessageHandler::OnError(const base::Value::List& args) { // TODO(b/200846160): The annotator is in an error state. Show creation flow // error notification and trigger a reload of the WebContent hosting the
diff --git a/ash/webui/projector_app/annotator_message_handler.h b/ash/webui/projector_app/annotator_message_handler.h index 8cec25ea..b97186f 100644 --- a/ash/webui/projector_app/annotator_message_handler.h +++ b/ash/webui/projector_app/annotator_message_handler.h
@@ -39,6 +39,7 @@ private: void OnToolSet(const base::Value::List& args); void OnUndoRedoAvailabilityChanged(const base::Value::List& args); + void OnCanvasInitialized(const base::Value::List& args); void OnError(const base::Value::List& args); };
diff --git a/ash/webui/projector_app/resources/annotator/trusted/trusted_annotator_comm_factory.js b/ash/webui/projector_app/resources/annotator/trusted/trusted_annotator_comm_factory.js index 770a8143..ad38f07c 100644 --- a/ash/webui/projector_app/resources/annotator/trusted/trusted_annotator_comm_factory.js +++ b/ash/webui/projector_app/resources/annotator/trusted/trusted_annotator_comm_factory.js
@@ -74,6 +74,13 @@ return this.browserProxy_.onUndoRedoAvailabilityChanged( values[0], values[1]); }); + + this.registerMethod('onCanvasInitialized', (values) => { + if (!values || values.length != 1) { + return; + } + return this.browserProxy_.onCanvasInitialized(values[0]); + }); } }
diff --git a/ash/webui/projector_app/resources/annotator/untrusted/untrusted_annotator_comm_factory.js b/ash/webui/projector_app/resources/annotator/untrusted/untrusted_annotator_comm_factory.js index 8400ebfb..045d528 100644 --- a/ash/webui/projector_app/resources/annotator/untrusted/untrusted_annotator_comm_factory.js +++ b/ash/webui/projector_app/resources/annotator/untrusted/untrusted_annotator_comm_factory.js
@@ -37,6 +37,15 @@ return this.callApiFn( 'onUndoRedoAvailabilityChanged', [undoAvailable, redoAvailable]); } + + /** + * Notifies the native UI that the canvas has initialized. + * @param {boolean} success + * @return {Promise} + */ + onCanvasInitialized(success) { + return this.callApiFn('onCanvasInitialized', [success]); + } } /** @@ -103,6 +112,9 @@ AnnotatorUntrustedCommFactory.client_.onUndoRedoAvailabilityChanged( undoAvailable, redoAvailable); }); + elem.addCanvasInitializationCallback((success) => { + AnnotatorUntrustedCommFactory.client_.onCanvasInitialized(success); + }); } /**
diff --git a/ash/webui/projector_app/resources/communication/projector_app.externs.js b/ash/webui/projector_app/resources/communication/projector_app.externs.js index 5dd0bac..3e09c81 100644 --- a/ash/webui/projector_app/resources/communication/projector_app.externs.js +++ b/ash/webui/projector_app/resources/communication/projector_app.externs.js
@@ -70,6 +70,15 @@ projectorApp.AnnotatorApi.prototype.addUndoRedoListener = function(listener) {}; /** + * Attaches the callback that should be executed when the canvas has succeeded + * or failed initialization. + * @param {function(boolean):undefined} callback Expects a boolean indicating if + * canvas initialization has succeeded or failed. + */ +projectorApp.AnnotatorApi.prototype.addCanvasInitializationCallback = function( + callback) {}; + +/** * Structure for Account information. * @record * @struct
diff --git a/ash/webui/projector_app/resources/communication/projector_browser_proxy.js b/ash/webui/projector_app/resources/communication/projector_browser_proxy.js index d76d71af..0ee2b80 100644 --- a/ash/webui/projector_app/resources/communication/projector_browser_proxy.js +++ b/ash/webui/projector_app/resources/communication/projector_browser_proxy.js
@@ -26,6 +26,13 @@ onUndoRedoAvailabilityChanged(undoAvailable, redoAvailable) {} /** + * Notifies the embedder content that the canvas has either succeeded or + * failed to initialize. + * @param {boolean} success + */ + onCanvasInitialized(success) {} + + /** * Gets the list of primary and secondary accounts currently available on the * device. * @return {Promise<Array<!projectorApp.Account>>} @@ -139,6 +146,11 @@ } /** @override */ + onCanvasInitialized(success) { + return chrome.send('onCanvasInitialized', [success]); + } + + /** @override */ getAccounts() { return sendWithPromise('getAccounts'); }
diff --git a/ash/webui/projector_app/test/annotator_message_handler_unittest.cc b/ash/webui/projector_app/test/annotator_message_handler_unittest.cc index 21baa31..cc0a9a5 100644 --- a/ash/webui/projector_app/test/annotator_message_handler_unittest.cc +++ b/ash/webui/projector_app/test/annotator_message_handler_unittest.cc
@@ -53,6 +53,12 @@ web_ui().HandleReceivedMessage("onUndoRedoAvailabilityChanged", &list_args); } + void SendCanvasInitialized(bool success) { + base::ListValue list_args; + list_args.Append(base::Value(success)); + web_ui().HandleReceivedMessage("onCanvasInitialized", &list_args); + } + content::TestWebUI& web_ui() { return web_ui_; } AnnotatorMessageHandler* handler() { return message_handler_.get(); } MockProjectorController& controller() { return controller_; } @@ -113,4 +119,12 @@ SendUndoRedoAvailableChanged(false, true); } +TEST_F(AnnotatorMessageHandlerTest, CanvasInitialized) { + EXPECT_CALL(controller(), OnCanvasInitialized(true)); + SendCanvasInitialized(true); + + EXPECT_CALL(controller(), OnCanvasInitialized(false)); + SendCanvasInitialized(false); +} + } // namespace ash
diff --git a/ash/webui/shimless_rma/resources/shimless_rma.js b/ash/webui/shimless_rma/resources/shimless_rma.js index ff833bd9..9649931 100644 --- a/ash/webui/shimless_rma/resources/shimless_rma.js +++ b/ash/webui/shimless_rma/resources/shimless_rma.js
@@ -451,8 +451,7 @@ if (this.handleStandardAndCriticalError_(stateResult.error)) { return; } - this.showState_( - stateResult.state, stateResult.canCancel, stateResult.canGoBack); + this.showState_(stateResult); } /** @param {!RmadErrorCode} error */ @@ -469,7 +468,13 @@ handleStandardAndCriticalError_(error) { // Critical error - expected to be in RMA. if (error === RmadErrorCode.kRmaNotRequired) { - this.showState_(State.kUnknown, false, false); + const errorState = { + state: State.kUnknown, + canCancel: false, + canGoBack: false, + error: RmadErrorCode.kRmaNotRequired + }; + this.showState_(errorState); return true; } @@ -477,60 +482,48 @@ } /** - * @param {!State} state - * @param {boolean} canCancel - * @param {boolean} canGoBack + * @param {!StateResult} stateResult * @private */ - showState_(state, canCancel, canGoBack) { - const pageInfo = StateComponentMapping[state]; - assert(pageInfo); + showState_(stateResult) { + // Reset clicked variables to hide the spinners. this.nextButtonClicked_ = false; this.backButtonClicked_ = false; this.cancelButtonClicked_ = false; - if (!canCancel) { - pageInfo.buttonCancel = ButtonState.HIDDEN; + + const nextStatePageInfo = StateComponentMapping[stateResult.state]; + assert(nextStatePageInfo); + + if (this.currentPage_.requiresReloadWhenShown) { + this.removeComponent_(this.currentPage_.componentIs); } - if (!canGoBack) { - pageInfo.buttonBack = ButtonState.HIDDEN; - } + // Only perform the below actions if the page needs to change or reload. + const shouldLoadNextPage = this.currentPage_ !== nextStatePageInfo || + this.currentPage_.requiresReloadWhenShown; + if (shouldLoadNextPage) { + this.hideAllComponents_(); - // TODO(gavindodd): Replace this with 'dom-if' in html. - if (!!this.currentPage_ && this.currentPage_.requiresReloadWhenShown) { - let component = - this.shadowRoot.querySelector(`#${this.currentPage_.componentIs}`); - if (component !== null) { - component.remove(); - component = null; + // Set the next page as the current page. + this.currentPage_ = nextStatePageInfo; + if (!stateResult.canCancel) { + this.currentPage_.buttonCancel = ButtonState.HIDDEN; } - } else if (pageInfo == this.currentPage_) { - this.setAllButtonsState_( - /* shouldDisableButtons= */ false, /* showBusyStateOverlay= */ false); - // Make sure all button states are correct. - this.notifyPath('currentPage_.buttonNext'); - this.notifyPath('currentPage_.buttonBack'); - this.notifyPath('currentPage_.buttonCancel'); - return; - } - this.currentPage_ = pageInfo; - let component = - this.shadowRoot.querySelector(`#${this.currentPage_.componentIs}`); - if (component === null) { - component = this.loadComponent_(this.currentPage_.componentIs); + if (!stateResult.canGoBack) { + this.currentPage_.buttonBack = ButtonState.HIDDEN; + } + + // Load the next page so it's visible. + const currentPageComponent = + this.loadComponent_(this.currentPage_.componentIs); + currentPageComponent.hidden = false; + + // A special case for the landing page, which has its own navigation + // buttons. + currentPageComponent.getStartedButtonClicked = false; + currentPageComponent.landingCancelButtonClicked = false; } - // A special case for the landing page, which has its own navigation - // buttons. - if (component.getStartedButtonClicked) { - component.getStartedButtonClicked = false; - } - if (component.landingCancelButtonClicked) { - component.landingCancelButtonClicked = false; - } - - this.hideAllComponents_(); - component.hidden = false; this.setAllButtonsState_( /* shouldDisableButtons= */ false, /* showBusyStateOverlay= */ false); } @@ -545,10 +538,27 @@ /** * @param {string} componentIs + * @private + */ + removeComponent_(componentIs) { + const currentPageComponent = + this.shadowRoot.querySelector(`#${componentIs}`); + assert(!!currentPageComponent); + currentPageComponent.remove(); + } + + /** + * @param {string} componentIs * @return {!Element} * @private */ loadComponent_(componentIs) { + const alreadyLoadedComponent = + this.shadowRoot.querySelector(`#${componentIs}`); + if (alreadyLoadedComponent) { + return alreadyLoadedComponent; + } + const shimlessBody = this.shadowRoot.querySelector('#contentContainer'); /** @type {!Element} */
diff --git a/ash/webui/shimless_rma/shimless_rma.cc b/ash/webui/shimless_rma/shimless_rma.cc index 13fcce9..ad05613 100644 --- a/ash/webui/shimless_rma/shimless_rma.cc +++ b/ash/webui/shimless_rma/shimless_rma.cc
@@ -116,18 +116,10 @@ IDS_SHIMLESS_RMA_UPDATE_OS_UNQUALIFIED_COMPONENTS_TOP}, {"osUpdateUnqualifiedComponentsBottomText", IDS_SHIMLESS_RMA_UPDATE_OS_UNQUALIFIED_COMPONENTS_BOTTOM}, - {"osUpdateVeryOutOfDateDescriptionText", - IDS_SHIMLESS_RMA_UPDATE_OS_VERY_OUT_OF_DATE}, {"osUpdateOutOfDateDescriptionText", IDS_SHIMLESS_RMA_UPDATE_OS_OUT_OF_DATE}, - {"osUpdateNetworkUnavailableText", - IDS_SHIMLESS_RMA_UPDATE_OS_NETWORK_UNAVAILABLE}, - {"osUpdateFailedToStartText", IDS_SHIMLESS_RMA_UPDATE_OS_FAILED_TO_START}, - {"currentVersionText", IDS_SHIMLESS_RMA_CURRENT_VERSION}, {"currentVersionOutOfDateText", IDS_SHIMLESS_RMA_CURRENT_VERSION_OUT_OF_DATE}, - {"currentVersionUpToDateText", - IDS_SHIMLESS_RMA_CURRENT_VERSION_UP_TO_DATE}, {"updateVersionRestartLabel", IDS_SHIMLESS_RMA_UPDATE_VERSION_AND_RESTART}, {"updatingOsVersionText", IDS_SHIMLESS_RMA_UPDATING_OS_VERSION},
diff --git a/base/BUILD.gn b/base/BUILD.gn index bbfc011..4740e8e 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -3768,6 +3768,7 @@ if (use_allocator_shim) { sources += [ "allocator/allocator_shim_unittest.cc", + "sampling_heap_profiler/poisson_allocation_sampler_unittest.cc", "sampling_heap_profiler/sampling_heap_profiler_unittest.cc", ]
diff --git a/base/sampling_heap_profiler/poisson_allocation_sampler.cc b/base/sampling_heap_profiler/poisson_allocation_sampler.cc index d20757f..47d239d 100644 --- a/base/sampling_heap_profiler/poisson_allocation_sampler.cc +++ b/base/sampling_heap_profiler/poisson_allocation_sampler.cc
@@ -402,7 +402,7 @@ // Make sure hooks have been installed, so that the only order of operations // that needs to be handled is Install Hooks -> Remove Hooks For Testing -> // Reinstall Hooks. - PoissonAllocationSampler::InstallAllocatorHooksOnce(); + PoissonAllocationSampler::Get()->InstallAllocatorHooksOnce(); RemoveStandardAllocatorHooksForTesting(); // IN-TEST @@ -438,7 +438,6 @@ }(); } -// static void PoissonAllocationSampler::InstallAllocatorHooksOnce() { [[maybe_unused]] static bool hook_installed = [] { InstallStandardAllocatorHooks(); @@ -447,6 +446,9 @@ // SetHooksInstallCallback already ran, so run the callback now. g_hooks_install_callback(); } + // The allocator hooks use `g_sampled_address_set` so it had better be + // initialized. + DCHECK(g_sampled_addresses_set.load(std::memory_order_acquire)); return true; }(); }
diff --git a/base/sampling_heap_profiler/poisson_allocation_sampler.h b/base/sampling_heap_profiler/poisson_allocation_sampler.h index 7cc6d9b..0d80c084 100644 --- a/base/sampling_heap_profiler/poisson_allocation_sampler.h +++ b/base/sampling_heap_profiler/poisson_allocation_sampler.h
@@ -148,8 +148,15 @@ PoissonAllocationSampler(); ~PoissonAllocationSampler() = delete; - static void InstallAllocatorHooksOnce(); + // Installs allocator hooks if they weren't already installed. This is not + // static to ensure that allocator hooks can't be installed unless the + // PoissonAllocationSampler singleton exists. + void InstallAllocatorHooksOnce(); + static size_t GetNextSampleInterval(size_t base_interval); + + // Return the set of sampled addresses. This is only valid to call after + // Init(). static LockFreeAddressHashSet& sampled_addresses_set(); void DoRecordAlloc(intptr_t accumulated_bytes, @@ -174,6 +181,7 @@ friend class heap_profiling::HeapProfilerControllerTest; friend class NoDestructor<PoissonAllocationSampler>; friend class SamplingHeapProfilerTest; + FRIEND_TEST_ALL_PREFIXES(PoissonAllocationSamplerTest, MuteHooksWithoutInit); FRIEND_TEST_ALL_PREFIXES(SamplingHeapProfilerTest, HookedAllocatorMuted); };
diff --git a/base/sampling_heap_profiler/poisson_allocation_sampler_unittest.cc b/base/sampling_heap_profiler/poisson_allocation_sampler_unittest.cc new file mode 100644 index 0000000..a6d7c77 --- /dev/null +++ b/base/sampling_heap_profiler/poisson_allocation_sampler_unittest.cc
@@ -0,0 +1,27 @@ +// Copyright 2022 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/sampling_heap_profiler/poisson_allocation_sampler.h" + +#include <stdlib.h> + +#include "testing/gtest/include/gtest/gtest.h" + +namespace base { + +TEST(PoissonAllocationSamplerTest, MuteHooksWithoutInit) { + // ScopedMuteHookedSamplesForTesting updates the allocator hooks. Make sure + // is safe to call from tests that might not call + // PoissonAllocationSampler::Get() to initialize the rest of the + // PoissonAllocationSampler. + EXPECT_FALSE(PoissonAllocationSampler::AreHookedSamplesMuted()); + void* volatile p = nullptr; + { + PoissonAllocationSampler::ScopedMuteHookedSamplesForTesting mute_hooks; + p = malloc(10000); + } + free(p); +} + +} // namespace base
diff --git a/build/android/pylib/instrumentation/instrumentation_test_instance.py b/build/android/pylib/instrumentation/instrumentation_test_instance.py index 29656c8..0c931ee 100644 --- a/build/android/pylib/instrumentation/instrumentation_test_instance.py +++ b/build/android/pylib/instrumentation/instrumentation_test_instance.py
@@ -513,7 +513,7 @@ for dump in dex_dumps: for package_name, package_info in six.iteritems(dump): for class_name, class_info in six.iteritems(package_info['classes']): - if class_name.endswith('Test'): + if class_name.endswith('Test') and not class_info['is_abstract']: tests.append({ 'class': '%s.%s' % (package_name, class_name), 'annotations': {},
diff --git a/build/android/pylib/utils/dexdump.py b/build/android/pylib/utils/dexdump.py index 4e6588d..fb4142a 100644 --- a/build/android/pylib/utils/dexdump.py +++ b/build/android/pylib/utils/dexdump.py
@@ -29,7 +29,9 @@ <package_name>: { 'classes': { <class_name>: { - 'methods': [<method_1>, <method_2>] + 'methods': [<method_1>, <method_2>], + 'superclass': <string>, + 'is_abstract': <boolean> } } } @@ -105,10 +107,14 @@ { 'classes': { <class_1>: { - 'methods': [<method_1>, <method_2>] + 'methods': [<method_1>, <method_2>], + 'superclass': <string>, + 'is_abstract': <boolean> }, <class_2>: { - 'methods': [<method_1>, <method_2>] + 'methods': [<method_1>, <method_2>], + 'superclass': <string>, + 'is_abstract': <boolean> }, } } @@ -126,11 +132,17 @@ Returns: A dict in the format: { - 'methods': [<method_1>, <method_2>] + 'methods': [<method_1>, <method_2>], + 'superclass': <string>, + 'is_abstract': <boolean> } """ methods = [] for child in class_node: if child.tag == 'method' and child.attrib['visibility'] == 'public': methods.append(child.attrib['name']) - return {'methods': methods, 'superclass': class_node.attrib['extends']} + return { + 'methods': methods, + 'superclass': class_node.attrib['extends'], + 'is_abstract': class_node.attrib.get('abstract') == 'true' + }
diff --git a/build/android/pylib/utils/dexdump_test.py b/build/android/pylib/utils/dexdump_test.py index 1eacac2c..fb04164d 100755 --- a/build/android/pylib/utils/dexdump_test.py +++ b/build/android/pylib/utils/dexdump_test.py
@@ -14,80 +14,85 @@ class DexdumpXMLParseTest(unittest.TestCase): def testParseRootXmlNode(self): - example_xml_string = ( - '<api>' - '<package name="com.foo.bar1">' - '<class' - ' name="Class1"' - ' extends="java.lang.Object"' - ' abstract="false"' - ' static="false"' - ' final="true"' - ' visibility="public">' - '<method' - ' name="class1Method1"' - ' return="java.lang.String"' - ' abstract="false"' - ' native="false"' - ' synchronized="false"' - ' static="false"' - ' final="false"' - ' visibility="public">' - '</method>' - '<method' - ' name="class1Method2"' - ' return="viod"' - ' abstract="false"' - ' native="false"' - ' synchronized="false"' - ' static="false"' - ' final="false"' - ' visibility="public">' - '</method>' - '</class>' - '<class' - ' name="Class2"' - ' extends="java.lang.Object"' - ' abstract="false"' - ' static="false"' - ' final="true"' - ' visibility="public">' - '<method' - ' name="class2Method1"' - ' return="java.lang.String"' - ' abstract="false"' - ' native="false"' - ' synchronized="false"' - ' static="false"' - ' final="false"' - ' visibility="public">' - '</method>' - '</class>' - '</package>' - '<package name="com.foo.bar2">' - '</package>' - '<package name="com.foo.bar3">' - '</package>' - '</api>') + example_xml_string = ('<api>' + '<package name="com.foo.bar1">' + '<class' + ' name="Class1"' + ' extends="java.lang.Object"' + ' abstract="false"' + ' static="false"' + ' final="true"' + ' visibility="public">' + '<method' + ' name="class1Method1"' + ' return="java.lang.String"' + ' abstract="false"' + ' native="false"' + ' synchronized="false"' + ' static="false"' + ' final="false"' + ' visibility="public">' + '</method>' + '<method' + ' name="class1Method2"' + ' return="viod"' + ' abstract="false"' + ' native="false"' + ' synchronized="false"' + ' static="false"' + ' final="false"' + ' visibility="public">' + '</method>' + '</class>' + '<class' + ' name="Class2"' + ' extends="java.lang.Object"' + ' abstract="true"' + ' static="false"' + ' final="true"' + ' visibility="public">' + '<method' + ' name="class2Method1"' + ' return="java.lang.String"' + ' abstract="false"' + ' native="false"' + ' synchronized="false"' + ' static="false"' + ' final="false"' + ' visibility="public">' + '</method>' + '</class>' + '</package>' + '<package name="com.foo.bar2">' + '</package>' + '<package name="com.foo.bar3">' + '</package>' + '</api>') actual = dexdump._ParseRootNode( ElementTree.fromstring(example_xml_string)) expected = { - 'com.foo.bar1' : { - 'classes': { - 'Class1': { - 'methods': ['class1Method1', 'class1Method2'], - 'superclass': 'java.lang.Object', - }, - 'Class2': { - 'methods': ['class2Method1'], - 'superclass': 'java.lang.Object', - } + 'com.foo.bar1': { + 'classes': { + 'Class1': { + 'methods': ['class1Method1', 'class1Method2'], + 'superclass': 'java.lang.Object', + 'is_abstract': False, + }, + 'Class2': { + 'methods': ['class2Method1'], + 'superclass': 'java.lang.Object', + 'is_abstract': True, + } + }, }, - }, - 'com.foo.bar2' : {'classes': {}}, - 'com.foo.bar3' : {'classes': {}}, + 'com.foo.bar2': { + 'classes': {} + }, + 'com.foo.bar3': { + 'classes': {} + }, } self.assertEqual(expected, actual) @@ -96,7 +101,7 @@ '<package name="com.foo.bar">' '<class name="Class1" extends="java.lang.Object">' '</class>' - '<class name="Class2" extends="java.lang.Object">' + '<class name="Class2" extends="java.lang.Object" abstract="true">' '</class>' '</package>') @@ -105,16 +110,18 @@ ElementTree.fromstring(example_xml_string)) expected = { - 'classes': { - 'Class1': { - 'methods': [], - 'superclass': 'java.lang.Object', + 'classes': { + 'Class1': { + 'methods': [], + 'superclass': 'java.lang.Object', + 'is_abstract': False, + }, + 'Class2': { + 'methods': [], + 'superclass': 'java.lang.Object', + 'is_abstract': True, + }, }, - 'Class2': { - 'methods': [], - 'superclass': 'java.lang.Object', - }, - }, } self.assertEqual(expected, actual) @@ -132,8 +139,9 @@ ElementTree.fromstring(example_xml_string)) expected = { - 'methods': ['method1', 'method2'], - 'superclass': 'java.lang.Object', + 'methods': ['method1', 'method2'], + 'superclass': 'java.lang.Object', + 'is_abstract': False, } self.assertEqual(expected, actual)
diff --git a/build/config/sanitizers/BUILD.gn b/build/config/sanitizers/BUILD.gn index 265a0379..52b12b95 100644 --- a/build/config/sanitizers/BUILD.gn +++ b/build/config/sanitizers/BUILD.gn
@@ -56,7 +56,7 @@ "ASan is only supported in 64-bit builds on Windows.") if ((is_apple || is_win) && is_asan) { - if (is_mac) { + if (is_mac || (is_ios && target_environment == "catalyst")) { _clang_rt_dso_path = "darwin/libclang_rt.asan_osx_dynamic.dylib" } else if (is_ios) { _clang_rt_dso_path = "darwin/libclang_rt.asan_iossim_dynamic.dylib"
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index e0b6e68a..0e5a5761 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -8.20220426.0.1 +8.20220426.1.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index e0b6e68a..0e5a5761 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -8.20220426.0.1 +8.20220426.1.1
diff --git a/build/sanitizers/sanitizer_options.cc b/build/sanitizers/sanitizer_options.cc index dfc35c5..1f9df52 100644 --- a/build/sanitizers/sanitizer_options.cc +++ b/build/sanitizers/sanitizer_options.cc
@@ -52,6 +52,10 @@ "external_symbolizer_path=%d/../../third_party/llvm-build/Release+Asserts/" "bin/llvm-symbolizer"; +#elif BUILDFLAG(IS_ANDROID) +const char* kAsanDefaultOptions = + // This causes out-of-memory errors on Android (crbug.com/1319387). + "detect_stack_use_after_return=0"; #elif BUILDFLAG(IS_APPLE) const char* kAsanDefaultOptions = "check_printf=1 use_sigaltstack=1 strip_path_prefix=/../../ " @@ -66,7 +70,7 @@ #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_APPLE) || \ - BUILDFLAG(IS_WIN) + BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) // Allow NaCl to override the default asan options. extern const char* kAsanDefaultOptionsNaCl; __attribute__((weak)) const char* kAsanDefaultOptionsNaCl = nullptr;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java index de10080..ebcab69 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java
@@ -51,7 +51,9 @@ import org.chromium.ui.base.LocalizationUtils; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; /** * This class handles managing the positions and behavior of all tabs in a tab strip. It is @@ -177,6 +179,7 @@ // Id of the selected tab that was closed. private Integer mSelectedTabIdWhenTabClosed; private Boolean mClosedAllTabs; + private final Set<Integer> mTabsClosedFromTabStrip; /** * Creates an instance of the {@link StripLayoutHelper}. @@ -189,6 +192,7 @@ LayoutRenderHost renderHost, boolean incognito) { mTabOverlapWidth = TAB_OVERLAP_WIDTH_DP; mNewTabButtonWidth = NEW_TAB_BUTTON_WIDTH_DP; + mTabsClosedFromTabStrip = new HashSet<>(); mRightMargin = LocalizationUtils.isLayoutRtl() ? 0 : mNewTabButtonWidth; mLeftMargin = LocalizationUtils.isLayoutRtl() ? mNewTabButtonWidth : 0; @@ -571,7 +575,7 @@ /** * Called when all tabs are closed at once. */ - public void willCloseAllTabs() { + public void willCloseAllTabs(boolean tabSwitcherActive) { if (!mIncognito) { int selTabIndex = mModel.index(); mClosedAllTabs = true; @@ -579,6 +583,7 @@ Tab tab = mModel.getTabAt(selTabIndex); if (tab != null) { mSelectedTabIdWhenTabClosed = tab.getId(); + if (!tabSwitcherActive) mTabsClosedFromTabStrip.add(tab.getId()); } } } @@ -600,10 +605,15 @@ TabModelUtils.getTabIndexById(mModel, mSelectedTabIdWhenTabClosed), false); resetSelectionsForUndo(); } + if (mTabsClosedFromTabStrip.contains(id)) { + RecordUserAction.record("TabletTabStrip.UndoCloseTab"); + mTabsClosedFromTabStrip.remove(id); + } } protected void tabClosureCommited() { resetSelectionsForUndo(); + mTabsClosedFromTabStrip.clear(); } /** @@ -1713,11 +1723,16 @@ * When a tab is being closed, this keeps track of whether it was selected or not. If the tab * closure is undone, that helps us decide whether to select it or not. * @param tabId Id of the tab that will be closed. + * @param tabSwitcherActive If the tab switcher interface is showing. This is used to identify + * the tabs closed from the tab strip for metrics. */ - protected void willCloseTab(int tabId) { + protected void willCloseTab(int tabId, boolean tabSwitcherActive) { // If all tabs are closed, return early as this method gets called multiple times and the // mModel.index() value is inaccurate. allTabsClosed() method handles that case. if (mClosedAllTabs != null) return; + if (!tabSwitcherActive) { + mTabsClosedFromTabStrip.add(tabId); + } int selTabIndex = mModel.index(); if (selTabIndex > -1 && selTabIndex < mModel.getCount()) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java index 31dbe8bb..2926b22 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java
@@ -93,6 +93,7 @@ private final StripScrim mStripScrim; private boolean mBrowserScrimShowing; + private boolean mTabSwitcherActive; private ValueAnimator mScrimFadeAnimation; private TabStripSceneLayer mTabStripTreeProvider; @@ -187,6 +188,18 @@ } @Override + public void onFinishedShowing(int layoutType) { + if (layoutType != LayoutType.TAB_SWITCHER) return; + mTabSwitcherActive = true; + } + + @Override + public void onFinishedHiding(int layoutType) { + if (layoutType != LayoutType.TAB_SWITCHER) return; + mTabSwitcherActive = false; + } + + @Override public void onStartedHiding( @LayoutType int layoutType, boolean showToolbar, boolean delayAnimation) { if (layoutType != LayoutType.TAB_SWITCHER) return; @@ -569,13 +582,14 @@ @Override public void willCloseTab(Tab tab, boolean animate) { if (!tab.isIncognito()) { - getStripLayoutHelper(tab.isIncognito()).willCloseTab(tab.getId()); + getStripLayoutHelper(tab.isIncognito()) + .willCloseTab(tab.getId(), mTabSwitcherActive); } } @Override public void willCloseAllTabs(boolean incognito) { - getStripLayoutHelper(incognito).willCloseAllTabs(); + getStripLayoutHelper(incognito).willCloseAllTabs(mTabSwitcherActive); updateModelSwitcherButton(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ChromePaymentRequestService.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ChromePaymentRequestService.java index 6bcad1e..d37ee95c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ChromePaymentRequestService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ChromePaymentRequestService.java
@@ -332,7 +332,7 @@ // Implements BrowserPaymentRequest: @Override - public String onShowCalledAndAppsQueriedAndDetailsFinalized(boolean isUserGestureShow) { + public String onShowCalledAndAppsQueriedAndDetailsFinalized() { WindowAndroid windowAndroid = mDelegate.getWindowAndroid(mRenderFrameHost); if (windowAndroid == null) return ErrorStrings.WINDOW_NOT_FOUND; Context context = mDelegate.getContext(mRenderFrameHost);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java index 6b72c7e..0c442bf8 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java
@@ -8,7 +8,10 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.Activity; @@ -26,6 +29,8 @@ import org.robolectric.Robolectric; import org.robolectric.annotation.Config; +import org.chromium.base.metrics.UmaRecorder; +import org.chromium.base.metrics.UmaRecorderHolder; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.Feature; import org.chromium.chrome.R; @@ -53,6 +58,9 @@ public TestRule mFeaturesProcessorRule = new Features.JUnitProcessor(); @Mock private LayoutUpdateHost mUpdateHost; @Mock private LayoutRenderHost mRenderHost; + @Mock + private UmaRecorder mUmaRecorder; + private Activity mActivity; private TestTabModel mModel = new TestTabModel(); private StripLayoutHelper mStripLayoutHelper; @@ -63,6 +71,7 @@ private static final String IDENTIFIER_SELECTED = "Selected Tab"; private static final String INCOGNITO_IDENTIFIER = "Incognito Tab"; private static final String INCOGNITO_IDENTIFIER_SELECTED = "Selected Incognito Tab"; + private static final String UNDO_CLOSE_TAB_USER_ACTION = "TabletTabStrip.UndoCloseTab"; private static final float SCREEN_WIDTH = 800.f; private static final float SCREEN_HEIGHT = 1600.f; private static final float TAB_WIDTH_1 = 140.f; @@ -75,6 +84,8 @@ @Before public void beforeTest() { MockitoAnnotations.initMocks(this); + UmaRecorderHolder.setNonNativeDelegate(mUmaRecorder); + mActivity = Robolectric.buildActivity(Activity.class).setup().get(); TabUiFeatureUtilities.setTabMinWidthForTesting(null); } @@ -165,7 +176,7 @@ mModel.closeAllTabs(); // Notify strip of tab closure - mStripLayoutHelper.willCloseAllTabs(); + mStripLayoutHelper.willCloseAllTabs(false); // Verify strip has no tabs. assertTrue(mStripLayoutHelper.getStripLayoutTabs().length == 0); @@ -403,7 +414,7 @@ initializeTest(true, true, 3); // Act: Close fourth tab (selected) and undo closed tab. - mStripLayoutHelper.willCloseTab(3); + mStripLayoutHelper.willCloseTab(3, false); // When the third tab is closed, the second one should be selected. mModel.setIndex(2); // Undo 4th tab closure. @@ -422,7 +433,7 @@ mStripLayoutHelper.setStripLayoutTabsForTest(tabs); // Act: Close fourth tab (not selected) and undo closed tab. - mStripLayoutHelper.willCloseTab(3); + mStripLayoutHelper.willCloseTab(3, false); // Undo 4th tab closure. mStripLayoutHelper.tabClosureCancelled(TIMESTAMP, 3); @@ -439,7 +450,7 @@ mStripLayoutHelper.setStripLayoutTabsForTest(tabs); // Act: Close all tabs and undo closure - mStripLayoutHelper.willCloseAllTabs(); + mStripLayoutHelper.willCloseAllTabs(false); // Undo closure. cancelAllTabClosure(tabs); @@ -456,7 +467,7 @@ mStripLayoutHelper.setStripLayoutTabsForTest(tabs); // Act: Close all tabs and undo closure - mStripLayoutHelper.willCloseAllTabs(); + mStripLayoutHelper.willCloseAllTabs(false); // Undo closure. cancelAllTabClosure(tabs); @@ -464,7 +475,7 @@ assertEquals(mModel.index(), 3); // Act 2: Close just the fourth tab and undo. - mStripLayoutHelper.willCloseTab(3); + mStripLayoutHelper.willCloseTab(3, false); // After fourth tab is closed, the third one should be selected. mModel.setIndex(2); // Undo tab closure. @@ -483,7 +494,7 @@ mStripLayoutHelper.setStripLayoutTabsForTest(tabs); // Act 1: Close just the fourth tab and undo. - mStripLayoutHelper.willCloseTab(3); + mStripLayoutHelper.willCloseTab(3, false); // After fourth tab is closed, the third one should be selected. mModel.setIndex(2); // Undo tab closure. @@ -493,7 +504,7 @@ assertEquals(3, mModel.index()); // Act 2: Close all tabs and undo closure - mStripLayoutHelper.willCloseAllTabs(); + mStripLayoutHelper.willCloseAllTabs(false); // Undo closure. cancelAllTabClosure(tabs); @@ -511,7 +522,7 @@ mStripLayoutHelper.setStripLayoutTabsForTest(tabs); // Act 1: Close just the fourth tab, click on the second tab, and undo. - mStripLayoutHelper.willCloseTab(3); + mStripLayoutHelper.willCloseTab(3, false); // After fourth tab is closed, the third one should be automatically selected. mModel.setIndex(2); // User manually selects the second tab before undoing the tab closure. @@ -523,6 +534,65 @@ assertEquals(1, mModel.index()); } + @Test + public void testUndoTabClose_TabStrip_RecordsUserAction() { + initializeTest(true, true, 3); + + // Act: Close tab and undo closed tab. + mStripLayoutHelper.willCloseTab(3, false); + mStripLayoutHelper.tabClosureCancelled(TIMESTAMP, 3); + + // Assert: User action is recorded. + verify(mUmaRecorder).recordUserAction(Mockito.eq(UNDO_CLOSE_TAB_USER_ACTION), anyLong()); + } + + @Test + public void testUndoTabClose_TabSwitcher_DoesNotRecordUserAction() { + // Arrange: Initialize tabs with fourth tab selected. + initializeTest(true, true, 3); + + // Act: Close tab and undo closed tab. + mStripLayoutHelper.willCloseTab(3, true); + mStripLayoutHelper.tabClosureCancelled(TIMESTAMP, 3); + + // Assert: User action is not recorded. + verify(mUmaRecorder, Mockito.never()) + .recordUserAction(Mockito.eq(UNDO_CLOSE_TAB_USER_ACTION), anyLong()); + } + + @Test + public void testUndoTabClose_TabSwitcherAndTabStrip_RecordsUserAction() { + // Arrange: Initialize tabs with fourth tab selected. + initializeTest(true, true, 3); + + // Act: Close tab and undo closed tab. + mStripLayoutHelper.willCloseTab(3, true); + mStripLayoutHelper.willCloseTab(2, false); + + mStripLayoutHelper.tabClosureCancelled(TIMESTAMP, 2); + mStripLayoutHelper.tabClosureCancelled(TIMESTAMP, 3); + + // Assert: User action is not recorded. + verify(mUmaRecorder, times(1)) + .recordUserAction(Mockito.eq(UNDO_CLOSE_TAB_USER_ACTION), anyLong()); + } + + @Test + public void testUndoAllTabClose_RecordsSingleUserAction() { + // Arrange: Initialize tabs with fourth tab selected. + initializeTest(true, false, 3); + StripLayoutTab[] tabs = getMockedStripLayoutTabs(TAB_WIDTH_2, 150.f, 5); + mStripLayoutHelper.setStripLayoutTabsForTest(tabs); + + // Act: Close all tabs and undo. + mStripLayoutHelper.willCloseAllTabs(false); + cancelAllTabClosure(tabs); + + // Assert: User action is recorded exactly once. + verify(mUmaRecorder, times(1)) + .recordUserAction(Mockito.eq(UNDO_CLOSE_TAB_USER_ACTION), anyLong()); + } + private void mockClickOnTab(int index) { mModel.setIndex(index); mStripLayoutHelper.tabSelected(TIMESTAMP, 1, 2);
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 9873db5..ec5054f 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -3694,8 +3694,8 @@ <message name="IDS_CERT_EXT_MS_NTDS_REPLICATION" desc="description of extension Microsoft Domain GUID"> Microsoft Domain GUID </message> - <message name="IDS_CERT_EKU_ANY_EKU" desc="description of extended key usage anyExtendedKeyUsage"> - Any Extended Key Usage + <message name="IDS_CERT_EKU_ANY_EKU" desc="description of X.509 certificate extended key usage value `anyExtendedKeyUsage`. This indicates that the certificate may be used for any purpose."> + Any </message> <message name="IDS_CERT_EKU_TLS_WEB_SERVER_AUTHENTICATION" desc="description of extended key usage TLS WWW Server Authentication"> TLS WWW Server Authentication
diff --git a/chrome/app/generated_resources_grd/IDS_CERT_EKU_ANY_EKU.png.sha1 b/chrome/app/generated_resources_grd/IDS_CERT_EKU_ANY_EKU.png.sha1 index 7d65f85..0844bf2 100644 --- a/chrome/app/generated_resources_grd/IDS_CERT_EKU_ANY_EKU.png.sha1 +++ b/chrome/app/generated_resources_grd/IDS_CERT_EKU_ANY_EKU.png.sha1
@@ -1 +1 @@ -13abe83bbb13a529b5596b7d48eec7facc2baef4 \ No newline at end of file +9f767357eae7627820397bb3328e7e6b259cb311 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp index eda6761..7b5bca1 100644 --- a/chrome/app/os_settings_strings.grdp +++ b/chrome/app/os_settings_strings.grdp
@@ -225,6 +225,24 @@ <message name="IDS_SETTINGS_ABOUT_PAGE_FIRMWARE_UPDATES" desc="Text of the button for the surface which allows users to update all their peripheral firmwares in one place."> Firmware updates </message> + <message name="IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_TITLE" desc="Text of the auto update toggle feature."> + Updates + </message> + <message name="IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_DESCRIPTION" desc="Text of the auto update toggle feature description."> + Get the latest features and security improvements. + </message> + <message name="IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_DIALOG_TITLE" desc="Text of the auto update toggle feature dialog."> + Turn off automatic updates? + </message> + <message name="IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_DIALOG_DESCRIPTION" desc="Text of the auto update toggle feature dialog description."> + Your device may no longer work properly, and you may experience security and performance issues. Key features in your apps may also stop working when they become outdated and you’ll lose your right to make legal claims. + </message> + <message name="IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_TURN_OFF_BUTTON" desc="Text of the auto update toggle feature dialog turn off button."> + Turn off + </message> + <message name="IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_KEEP_UPDATES_BUTTON" desc="Text of the auto update toggle feature dialog keep update button."> + Keep updates + </message> <!-- People (OS settings) --> <message name="IDS_OS_SETTINGS_PROFILE_NAME" desc="Label with device account first name, showing which user is currently signed in.">
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_DESCRIPTION.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_DESCRIPTION.png.sha1 new file mode 100644 index 0000000..cf3fff3 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_DESCRIPTION.png.sha1
@@ -0,0 +1 @@ +192e7031cd59f48652539d3f6534d2dc52b8e9e7 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_DIALOG_DESCRIPTION.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_DIALOG_DESCRIPTION.png.sha1 new file mode 100644 index 0000000..c5dc647 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_DIALOG_DESCRIPTION.png.sha1
@@ -0,0 +1 @@ +88417d7c3108d657ac2aec202ecefa040b76eee5 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_DIALOG_TITLE.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_DIALOG_TITLE.png.sha1 new file mode 100644 index 0000000..c5dc647 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_DIALOG_TITLE.png.sha1
@@ -0,0 +1 @@ +88417d7c3108d657ac2aec202ecefa040b76eee5 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_KEEP_UPDATES_BUTTON.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_KEEP_UPDATES_BUTTON.png.sha1 new file mode 100644 index 0000000..0908ba3 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_KEEP_UPDATES_BUTTON.png.sha1
@@ -0,0 +1 @@ +4d0debafad58c18d05a16edbbcc1b8a05d027868 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_TITLE.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_TITLE.png.sha1 new file mode 100644 index 0000000..cf3fff3 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_TITLE.png.sha1
@@ -0,0 +1 @@ +192e7031cd59f48652539d3f6534d2dc52b8e9e7 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_TURN_OFF_BUTTON.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_TURN_OFF_BUTTON.png.sha1 new file mode 100644 index 0000000..0908ba3 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_TURN_OFF_BUTTON.png.sha1
@@ -0,0 +1 @@ +4d0debafad58c18d05a16edbbcc1b8a05d027868 \ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 5ecce12..0dc40a86 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -1171,6 +1171,8 @@ "policy/messaging_layer/public/report_client.h", "policy/messaging_layer/upload/dm_server_upload_service.cc", "policy/messaging_layer/upload/dm_server_upload_service.h", + "policy/messaging_layer/upload/event_upload_size_controller.cc", + "policy/messaging_layer/upload/event_upload_size_controller.h", "policy/messaging_layer/upload/network_condition_service.cc", "policy/messaging_layer/upload/network_condition_service.h", "policy/messaging_layer/upload/record_handler_impl.cc", @@ -2937,10 +2939,6 @@ "android/send_tab_to_self/android_notification_handler.h", "android/send_tab_to_self/metrics_recorder.cc", "android/send_tab_to_self/send_tab_to_self_android_bridge.cc", - "android/send_tab_to_self/send_tab_to_self_entry_bridge.cc", - "android/send_tab_to_self/send_tab_to_self_entry_bridge.h", - "android/send_tab_to_self/send_tab_to_self_model_observer_bridge.cc", - "android/send_tab_to_self/send_tab_to_self_model_observer_bridge.h", "android/service_tab_launcher.cc", "android/service_tab_launcher.h", "android/shortcut_helper.cc",
diff --git a/chrome/browser/android/send_tab_to_self/send_tab_to_self_android_bridge.cc b/chrome/browser/android/send_tab_to_self/send_tab_to_self_android_bridge.cc index 2c459132..307c231 100644 --- a/chrome/browser/android/send_tab_to_self/send_tab_to_self_android_bridge.cc +++ b/chrome/browser/android/send_tab_to_self/send_tab_to_self_android_bridge.cc
@@ -10,7 +10,6 @@ #include "base/metrics/histogram_macros.h" #include "base/time/time.h" #include "chrome/browser/android/send_tab_to_self/android_notification_handler.h" -#include "chrome/browser/android/send_tab_to_self/send_tab_to_self_entry_bridge.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_android.h" #include "chrome/browser/send_tab_to_self/receiving_ui_handler_registry.h" @@ -106,9 +105,9 @@ model->DeleteAllEntries(); } -// Adds a new entry with the specified parameters. Returns the persisted -// version which contains additional information such as GUID. -static ScopedJavaLocalRef<jobject> JNI_SendTabToSelfAndroidBridge_AddEntry( +// Adds a new entry with the specified parameters. Returns whether the +// the persistent entry in the bridge was created. +static jboolean JNI_SendTabToSelfAndroidBridge_AddEntry( JNIEnv* env, const JavaParamRef<jobject>& j_profile, const JavaParamRef<jstring>& j_url, @@ -122,39 +121,8 @@ base::Time navigation_time = base::Time::FromJavaTime(j_navigation_time); SendTabToSelfModel* model = GetModel(j_profile); - if (!model->IsReady()) { - return nullptr; - } - - const SendTabToSelfEntry* persisted_entry = model->AddEntry( - GURL(url), title, navigation_time, target_device_sync_cache_guid); - - if (persisted_entry == nullptr) { - return nullptr; - } - return CreateJavaSendTabToSelfEntry(env, persisted_entry); -} - -// Returns the entry associated with a GUID. May return nullptr if none is -// found. -static ScopedJavaLocalRef<jobject> -JNI_SendTabToSelfAndroidBridge_GetEntryByGUID( - JNIEnv* env, - const JavaParamRef<jobject>& j_profile, - const JavaParamRef<jstring>& j_guid) { - SendTabToSelfModel* model = GetModel(j_profile); - if (!model->IsReady()) { - return nullptr; - } - - const std::string guid = ConvertJavaStringToUTF8(env, j_guid); - const SendTabToSelfEntry* found_entry = model->GetEntryByGUID(guid); - - if (found_entry == nullptr) { - return nullptr; - } - - return CreateJavaSendTabToSelfEntry(env, found_entry); + return model->IsReady() && model->AddEntry(GURL(url), title, navigation_time, + target_device_sync_cache_guid); } // Deletes the entry associated with the passed in GUID.
diff --git a/chrome/browser/android/send_tab_to_self/send_tab_to_self_entry_bridge.cc b/chrome/browser/android/send_tab_to_self/send_tab_to_self_entry_bridge.cc deleted file mode 100644 index 2e3f69a3..0000000 --- a/chrome/browser/android/send_tab_to_self/send_tab_to_self_entry_bridge.cc +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/android/send_tab_to_self/send_tab_to_self_entry_bridge.h" - -#include "base/android/jni_array.h" -#include "base/android/jni_string.h" -#include "chrome/browser/share/android/jni_headers/SendTabToSelfEntry_jni.h" -#include "components/send_tab_to_self/send_tab_to_self_entry.h" - -using base::android::AttachCurrentThread; -using base::android::ConvertUTF8ToJavaString; -using base::android::JavaParamRef; -using base::android::JavaRef; -using base::android::ScopedJavaGlobalRef; -using base::android::ScopedJavaLocalRef; - -namespace send_tab_to_self { - -ScopedJavaLocalRef<jobject> CreateJavaSendTabToSelfEntry( - JNIEnv* env, - const SendTabToSelfEntry* entry) { - return Java_SendTabToSelfEntry_createSendTabToSelfEntry( - env, ConvertUTF8ToJavaString(env, entry->GetGUID()), - ConvertUTF8ToJavaString(env, entry->GetURL().spec()), - ConvertUTF8ToJavaString(env, entry->GetTitle()), - entry->GetSharedTime().ToJavaTime(), - entry->GetOriginalNavigationTime().ToJavaTime(), - ConvertUTF8ToJavaString(env, entry->GetDeviceName()), - ConvertUTF8ToJavaString(env, entry->GetTargetDeviceSyncCacheGuid())); -} - -} // namespace send_tab_to_self
diff --git a/chrome/browser/android/send_tab_to_self/send_tab_to_self_entry_bridge.h b/chrome/browser/android/send_tab_to_self/send_tab_to_self_entry_bridge.h deleted file mode 100644 index c9a4d328..0000000 --- a/chrome/browser/android/send_tab_to_self/send_tab_to_self_entry_bridge.h +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_ANDROID_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_ENTRY_BRIDGE_H_ -#define CHROME_BROWSER_ANDROID_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_ENTRY_BRIDGE_H_ - -#include "base/android/jni_android.h" - -namespace send_tab_to_self { -class SendTabToSelfEntry; - -// Function to convert the native version of SendTabToSelfEntry into the Java -// version. -base::android::ScopedJavaLocalRef<jobject> CreateJavaSendTabToSelfEntry( - JNIEnv* env, - const SendTabToSelfEntry* entry); - -} // namespace send_tab_to_self - -#endif // CHROME_BROWSER_ANDROID_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_ENTRY_BRIDGE_H_
diff --git a/chrome/browser/android/send_tab_to_self/send_tab_to_self_model_observer_bridge.cc b/chrome/browser/android/send_tab_to_self/send_tab_to_self_model_observer_bridge.cc deleted file mode 100644 index 2250342..0000000 --- a/chrome/browser/android/send_tab_to_self/send_tab_to_self_model_observer_bridge.cc +++ /dev/null
@@ -1,112 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/android/send_tab_to_self/send_tab_to_self_model_observer_bridge.h" - -#include <string> -#include <vector> - -#include "base/android/jni_array.h" -#include "base/android/jni_string.h" -#include "base/time/time.h" -#include "chrome/browser/android/send_tab_to_self/send_tab_to_self_entry_bridge.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/profiles/profile_android.h" -#include "chrome/browser/share/android/jni_headers/SendTabToSelfModelObserverBridge_jni.h" -#include "chrome/browser/sync/send_tab_to_self_sync_service_factory.h" -#include "components/send_tab_to_self/send_tab_to_self_entry.h" -#include "components/send_tab_to_self/send_tab_to_self_model.h" -#include "components/send_tab_to_self/send_tab_to_self_sync_service.h" -#include "content/public/browser/web_contents.h" -#include "url/gurl.h" - -using base::android::AttachCurrentThread; -using base::android::ConvertUTF8ToJavaString; -using base::android::JavaParamRef; -using base::android::JavaRef; -using base::android::ScopedJavaGlobalRef; -using base::android::ScopedJavaLocalRef; - -namespace send_tab_to_self { - -SendTabToSelfModelObserverBridge::SendTabToSelfModelObserverBridge( - JNIEnv* env, - const JavaRef<jobject>& obj, - const JavaRef<jobject>& j_profile) - : weak_java_ref_(env, obj), send_tab_to_self_model_(nullptr) { - Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile); - send_tab_to_self_model_ = SendTabToSelfSyncServiceFactory::GetInstance() - ->GetForProfile(profile) - ->GetSendTabToSelfModel(); - send_tab_to_self_model_->AddObserver(this); -} - -static jlong JNI_SendTabToSelfModelObserverBridge_Init( - JNIEnv* env, - const JavaParamRef<jobject>& obj, - const JavaParamRef<jobject>& j_profile) { - SendTabToSelfModelObserverBridge* bridge = - new SendTabToSelfModelObserverBridge(env, obj, j_profile); - return reinterpret_cast<intptr_t>(bridge); -} - -void SendTabToSelfModelObserverBridge::Destroy(JNIEnv*) { - delete this; -} - -SendTabToSelfModelObserverBridge::~SendTabToSelfModelObserverBridge() { - send_tab_to_self_model_->RemoveObserver(this); -} - -void SendTabToSelfModelObserverBridge::SendTabToSelfModelLoaded() { - JNIEnv* env = AttachCurrentThread(); - ScopedJavaLocalRef<jobject> obj = weak_java_ref_.get(env); - if (obj.is_null()) { - return; - } - - Java_SendTabToSelfModelObserverBridge_modelLoaded(env, obj); -} - -void SendTabToSelfModelObserverBridge::EntriesAddedRemotely( - const std::vector<const SendTabToSelfEntry*>& new_entries) { - JNIEnv* env = AttachCurrentThread(); - ScopedJavaLocalRef<jobject> obj = weak_java_ref_.get(env); - if (obj.is_null()) { - return; - } - - ScopedJavaLocalRef<jobject> j_entry_list = - Java_SendTabToSelfModelObserverBridge_createEmptyJavaEntryList(env, obj); - - for (std::vector<const SendTabToSelfEntry*>::const_iterator it = - new_entries.begin(); - it != new_entries.end(); ++it) { - Java_SendTabToSelfModelObserverBridge_addToEntryList( - env, obj, j_entry_list, CreateJavaSendTabToSelfEntry(env, *it)); - } - Java_SendTabToSelfModelObserverBridge_entriesAddedRemotely(env, obj, - j_entry_list); -} - -void SendTabToSelfModelObserverBridge::EntriesRemovedRemotely( - const std::vector<std::string>& guids) { - JNIEnv* env = AttachCurrentThread(); - ScopedJavaLocalRef<jobject> obj = weak_java_ref_.get(env); - if (obj.is_null()) { - return; - } - ScopedJavaLocalRef<jobject> j_guid_list = - Java_SendTabToSelfModelObserverBridge_createEmptyJavaGuidList(env, obj); - - for (std::vector<const std::string>::iterator it = guids.begin(); - it != guids.end(); ++it) { - ScopedJavaLocalRef<jstring> j_guid = ConvertUTF8ToJavaString(env, *it); - Java_SendTabToSelfModelObserverBridge_addToGuidList(env, obj, j_guid_list, - j_guid); - } - Java_SendTabToSelfModelObserverBridge_entriesRemovedRemotely(env, obj, - j_guid_list); -} -} // namespace send_tab_to_self
diff --git a/chrome/browser/android/send_tab_to_self/send_tab_to_self_model_observer_bridge.h b/chrome/browser/android/send_tab_to_self/send_tab_to_self_model_observer_bridge.h deleted file mode 100644 index d64b6e7..0000000 --- a/chrome/browser/android/send_tab_to_self/send_tab_to_self_model_observer_bridge.h +++ /dev/null
@@ -1,53 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_ANDROID_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_MODEL_OBSERVER_BRIDGE_H_ -#define CHROME_BROWSER_ANDROID_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_MODEL_OBSERVER_BRIDGE_H_ - -#include "base/android/jni_android.h" -#include "base/android/jni_weak_ref.h" -#include "base/memory/raw_ptr.h" -#include "components/send_tab_to_self/send_tab_to_self_model_observer.h" - -namespace send_tab_to_self { - -class SendTabToSelfModel; - -// The delegate to observe for SendTabToSelf model changes and forward them to -// observers of this class. The class is owned by the SendTabToSelf Java -// counterpart and lives for the duration of the life of that class. -class SendTabToSelfModelObserverBridge : public SendTabToSelfModelObserver { - public: - SendTabToSelfModelObserverBridge( - JNIEnv* env, - const base::android::JavaRef<jobject>& obj, - const base::android::JavaRef<jobject>& j_profile); - - SendTabToSelfModelObserverBridge(const SendTabToSelfModelObserverBridge&) = - delete; - SendTabToSelfModelObserverBridge& operator=( - const SendTabToSelfModelObserverBridge&) = delete; - - void Destroy(JNIEnv*); - - // SendTabToSelfModelObserver implementation. - void SendTabToSelfModelLoaded() override; - void EntriesAddedRemotely( - const std::vector<const SendTabToSelfEntry*>& new_entries) override; - void EntriesRemovedRemotely(const std::vector<std::string>& guids) override; - - protected: - ~SendTabToSelfModelObserverBridge() override; - - private: - JavaObjectWeakGlobalRef weak_java_ref_; - // Set during the constructor and owned by the SendTabToSelfSyncServiceFactory - // is based off the KeyedServiceFactory which lives for the length of the - // profile. SendTabToSelf is not supported for the Incognito profile. - raw_ptr<SendTabToSelfModel> send_tab_to_self_model_; -}; - -} // namespace send_tab_to_self - -#endif // CHROME_BROWSER_ANDROID_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_MODEL_OBSERVER_BRIDGE_H_
diff --git a/chrome/browser/ash/app_mode/web_app/web_kiosk_app_launcher.cc b/chrome/browser/ash/app_mode/web_app/web_kiosk_app_launcher.cc index caa1d2de..174cf36 100644 --- a/chrome/browser/ash/app_mode/web_app/web_kiosk_app_launcher.cc +++ b/chrome/browser/ash/app_mode/web_app/web_kiosk_app_launcher.cc
@@ -73,7 +73,6 @@ DCHECK(!is_installed_); install_task_ = std::make_unique<web_app::WebAppInstallTask>( profile_, - /*install_manager=*/nullptr, /*install_finalizer=*/nullptr, data_retriever_factory_.Run(), /*registrar=*/nullptr, webapps::WebappInstallSource::MANAGEMENT_API); install_task_->LoadAndRetrieveWebAppInstallInfoWithIcons(
diff --git a/chrome/browser/ash/arc/wallpaper/arc_wallpaper_service.cc b/chrome/browser/ash/arc/wallpaper/arc_wallpaper_service.cc index 7a48602..4b348224 100644 --- a/chrome/browser/ash/arc/wallpaper/arc_wallpaper_service.cc +++ b/chrome/browser/ash/arc/wallpaper/arc_wallpaper_service.cc
@@ -153,7 +153,7 @@ UserManager::Get()->GetPrimaryUser(); WallpaperControllerClientImpl::Get()->SetDefaultWallpaper( primary_user->GetAccountId(), - primary_user->is_active() /*show_wallpaper=*/); + primary_user->is_active() /*show_wallpaper=*/, base::DoNothing()); } void ArcWallpaperService::GetWallpaper(GetWallpaperCallback callback) {
diff --git a/chrome/browser/ash/dbus/encrypted_reporting_service_provider.cc b/chrome/browser/ash/dbus/encrypted_reporting_service_provider.cc index 510e138..2329a16 100644 --- a/chrome/browser/ash/dbus/encrypted_reporting_service_provider.cc +++ b/chrome/browser/ash/dbus/encrypted_reporting_service_provider.cc
@@ -14,6 +14,7 @@ #include "base/task/bind_post_task.h" #include "base/task/sequenced_task_runner.h" #include "base/task/thread_pool.h" +#include "chrome/browser/policy/messaging_layer/upload/event_upload_size_controller.h" #include "chrome/browser/policy/messaging_layer/upload/upload_client.h" #include "chrome/browser/policy/messaging_layer/upload/upload_provider.h" #include "chromeos/dbus/missive/missive_client.h" @@ -156,9 +157,16 @@ return; } + reporting::EventUploadSizeController event_upload_size_controller( + network_condition_service_, /*enabled=*/false); auto records = std::make_unique<std::vector<reporting::EncryptedRecord>>(); for (auto& record : request.encrypted_record()) { records->push_back(std::move(record)); + // Check if we have uploaded enough records after adding each record + event_upload_size_controller.AccountForRecord(record); + if (event_upload_size_controller.IsMaximumUploadSizeReached()) { + break; + } } DCHECK(upload_provider_); MissiveClient* const missive_client = MissiveClient::Get();
diff --git a/chrome/browser/ash/dbus/encrypted_reporting_service_provider.h b/chrome/browser/ash/dbus/encrypted_reporting_service_provider.h index 079177e..1ff37f8d 100644 --- a/chrome/browser/ash/dbus/encrypted_reporting_service_provider.h +++ b/chrome/browser/ash/dbus/encrypted_reporting_service_provider.h
@@ -14,6 +14,7 @@ #include "base/task/sequenced_task_runner.h" #include "base/threading/platform_thread.h" #include "base/threading/thread_task_runner_handle.h" +#include "chrome/browser/policy/messaging_layer/upload/network_condition_service.h" #include "chrome/browser/policy/messaging_layer/upload/upload_client.h" #include "chrome/browser/policy/messaging_layer/upload/upload_provider.h" #include "chromeos/ash/components/dbus/services/cros_dbus_service.h" @@ -80,6 +81,9 @@ const std::unique_ptr<::reporting::EncryptedReportingUploadProvider> upload_provider_; + // Network condition service. + ::reporting::NetworkConditionService network_condition_service_; + // Keep this last so that all weak pointers will be invalidated at the // beginning of destruction. base::WeakPtrFactory<EncryptedReportingServiceProvider> weak_ptr_factory_{
diff --git a/chrome/browser/ash/dbus/encrypted_reporting_service_provider_unittest.cc b/chrome/browser/ash/dbus/encrypted_reporting_service_provider_unittest.cc index 8ce7b510..da0f9da 100644 --- a/chrome/browser/ash/dbus/encrypted_reporting_service_provider_unittest.cc +++ b/chrome/browser/ash/dbus/encrypted_reporting_service_provider_unittest.cc
@@ -11,7 +11,6 @@ #include "base/memory/ref_counted.h" #include "base/task/thread_pool.h" #include "base/test/scoped_feature_list.h" -#include "base/test/task_environment.h" #include "chrome/browser/policy/messaging_layer/upload/fake_upload_client.h" #include "chrome/browser/policy/messaging_layer/upload/upload_client.h" #include "chrome/browser/policy/messaging_layer/util/test_request_payload.h" @@ -21,6 +20,7 @@ #include "components/policy/core/common/cloud/dm_token.h" #include "components/policy/core/common/cloud/mock_cloud_policy_client.h" #include "components/reporting/proto/interface.pb.h" +#include "content/public/test/browser_task_environment.h" #include "dbus/exported_object.h" #include "dbus/message.h" #include "testing/gmock/include/gmock/gmock.h" @@ -161,7 +161,7 @@ } // Must be initialized before any other class member. - base::test::TaskEnvironment task_environment_; + content::BrowserTaskEnvironment task_environment_; policy::MockCloudPolicyClient cloud_policy_client_; reporting::EncryptedRecord record_;
diff --git a/chrome/browser/ash/login/existing_user_controller.cc b/chrome/browser/ash/login/existing_user_controller.cc index 3d10ed59..dd54c21d 100644 --- a/chrome/browser/ash/login/existing_user_controller.cc +++ b/chrome/browser/ash/login/existing_user_controller.cc
@@ -48,6 +48,7 @@ #include "chrome/browser/ash/login/easy_unlock/easy_unlock_service.h" #include "chrome/browser/ash/login/enterprise_user_session_metrics.h" #include "chrome/browser/ash/login/helper.h" +#include "chrome/browser/ash/login/profile_auth_data.h" #include "chrome/browser/ash/login/quick_unlock/pin_salt_storage.h" #include "chrome/browser/ash/login/quick_unlock/pin_storage_cryptohome.h" #include "chrome/browser/ash/login/reauth_stats.h" @@ -146,9 +147,6 @@ const char kAutoLaunchNotifierId[] = "ash.managed_guest_session-auto_launch"; -// Delay for transferring the auth cache to the system profile. -const long int kAuthCacheTransferDelayMs = 2000; - // Delay for restarting the ui if safe-mode login has failed. const long int kSafeModeRestartUiDelayMs = 30000; @@ -167,15 +165,6 @@ FROM_HERE, base::BindOnce(&RefreshPoliciesOnUIThread)); } -void TransferHttpAuthCacheToSystemNetworkContext( - base::RepeatingClosure completion_callback, - const base::UnguessableToken& cache_key) { - network::mojom::NetworkContext* system_network_context = - g_browser_process->system_network_context_manager()->GetContext(); - system_network_context->LoadHttpAuthCacheProxyEntries(cache_key, - completion_callback); -} - // Copies any authentication details that were entered in the login profile to // the main profile to make sure all subsystems of Chrome can access the network // with the provided authentication which are possibly for a proxy server. @@ -523,7 +512,7 @@ VLOG(1) << "Authentication was entered manually, possibly for proxyauth."; base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, base::BindOnce(&TransferHttpAuthCaches), - base::Milliseconds(kAuthCacheTransferDelayMs)); + kAuthCacheTransferDelayMs); } ////////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/ash/login/profile_auth_data.cc b/chrome/browser/ash/login/profile_auth_data.cc index 7efa5ad..c36b695 100644 --- a/chrome/browser/ash/login/profile_auth_data.cc +++ b/chrome/browser/ash/login/profile_auth_data.cc
@@ -7,6 +7,9 @@ #include "base/barrier_closure.h" #include "base/bind.h" #include "base/callback.h" +#include "base/unguessable_token.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/net/system_network_context_manager.h" #include "components/google/core/common/google_util.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/storage_partition.h" @@ -32,19 +35,6 @@ cache_key, completion_callback); } -// Starts tranferring `from_partition`'s http auth cache's proxy entries into -// `to_partition`. -void TransferHttpAuthCacheProxyEntries( - base::RepeatingClosure completion_callback, - content::StoragePartition* from_partition, - content::StoragePartition* to_partition) { - // `to_partition` will outlive the call to `completion_callback`. - // See ProfileAuthData::Transfer. - from_partition->GetNetworkContext()->SaveHttpAuthCacheProxyEntries( - base::BindOnce(&OnTargetHttpAuthCacheProxyEntriesSaved, - completion_callback, base::Unretained(to_partition))); -} - // Given a `cookie` set during login, returns true if the cookie may have been // set by GAIA. The main criterion is the `cookie`'s domain. If the domain // is *google.<TLD> or *youtube.<TLD>, the cookie is considered to have been set @@ -178,6 +168,15 @@ } // namespace +void TransferHttpAuthCacheToSystemNetworkContext( + base::RepeatingClosure completion_callback, + const base::UnguessableToken& cache_key) { + network::mojom::NetworkContext* system_network_context = + g_browser_process->system_network_context_manager()->GetContext(); + system_network_context->LoadHttpAuthCacheProxyEntries(cache_key, + completion_callback); +} + void ProfileAuthData::Transfer( content::StoragePartition* from_partition, content::StoragePartition* to_partition, @@ -202,4 +201,15 @@ transfer_saml_auth_cookies_on_subsequent_login); } +void ProfileAuthData::TransferHttpAuthCacheProxyEntries( + base::RepeatingClosure completion_callback, + content::StoragePartition* from_partition, + content::StoragePartition* to_partition) { + // `to_partition` will outlive the call to `completion_callback`. + // See ProfileAuthData::Transfer. + from_partition->GetNetworkContext()->SaveHttpAuthCacheProxyEntries( + base::BindOnce(&OnTargetHttpAuthCacheProxyEntriesSaved, + completion_callback, base::Unretained(to_partition))); +} + } // namespace ash
diff --git a/chrome/browser/ash/login/profile_auth_data.h b/chrome/browser/ash/login/profile_auth_data.h index b72341c4..f907a216 100644 --- a/chrome/browser/ash/login/profile_auth_data.h +++ b/chrome/browser/ash/login/profile_auth_data.h
@@ -6,6 +6,11 @@ #define CHROME_BROWSER_ASH_LOGIN_PROFILE_AUTH_DATA_H_ #include "base/callback_forward.h" +#include "base/time/time.h" + +namespace base { +class UnguessableToken; +} namespace content { class StoragePartition; @@ -13,6 +18,19 @@ namespace ash { +// Delay for transferring the auth cache to the system profile. +inline constexpr base::TimeDelta kAuthCacheTransferDelayMs = + base::Milliseconds(2000); + +// Timeout to delay first notification about offline state when authenticating +// to a proxy. +inline constexpr base::TimeDelta kProxyAuthTimeout = base::Seconds(5); + +// Transfers auth cache to system network context. +void TransferHttpAuthCacheToSystemNetworkContext( + base::RepeatingClosure completion_callback, + const base::UnguessableToken& cache_key); + // Helper class that transfers authentication-related data from a BrowserContext // used for authentication to the user's actual BrowserContext. class ProfileAuthData { @@ -40,6 +58,14 @@ bool transfer_auth_cookies_on_first_login, bool transfer_saml_auth_cookies_on_subsequent_login, base::OnceClosure completion_callback); + + // Transfers proxy authentication state from `from_partition` to + // `to_partition` and and invokes `completion_callback` on the UI thread when + // the operation has completed. + static void TransferHttpAuthCacheProxyEntries( + base::RepeatingClosure completion_callback, + content::StoragePartition* from_partition, + content::StoragePartition* to_partition); }; } // namespace ash
diff --git a/chrome/browser/ash/login/saml/lockscreen_reauth_dialog_test_helper.cc b/chrome/browser/ash/login/saml/lockscreen_reauth_dialog_test_helper.cc index ebf419e..319d4df 100644 --- a/chrome/browser/ash/login/saml/lockscreen_reauth_dialog_test_helper.cc +++ b/chrome/browser/ash/login/saml/lockscreen_reauth_dialog_test_helper.cc
@@ -91,7 +91,7 @@ ADD_FAILURE() << "Could not retrieve LockScreenStartReauthUI"; return false; } - main_handler_ = reauth_webui_controller_->GetMainHandlerForTests(); + main_handler_ = reauth_webui_controller_->GetMainHandler(); if (!main_handler_) { ADD_FAILURE() << "Could not retrieve LockScreenReauthHandler"; return false;
diff --git a/chrome/browser/ash/login/saml/saml_lockscreen_browsertest.cc b/chrome/browser/ash/login/saml/saml_lockscreen_browsertest.cc index aaee0e3b..8c58fc6c 100644 --- a/chrome/browser/ash/login/saml/saml_lockscreen_browsertest.cc +++ b/chrome/browser/ash/login/saml/saml_lockscreen_browsertest.cc
@@ -14,6 +14,8 @@ #include "chrome/browser/ash/login/test/logged_in_user_mixin.h" #include "chrome/browser/ash/login/test/test_condition_waiter.h" #include "chrome/browser/ash/login/users/test_users.h" +#include "chrome/browser/chrome_notification_types.h" +#include "chrome/browser/ui/login/login_handler.h" #include "chrome/test/base/mixin_based_in_process_browser_test.h" #include "chromeos/dbus/shill/fake_shill_manager_client.h" #include "chromeos/network/network_connection_handler.h" @@ -23,9 +25,11 @@ #include "chromeos/network/network_state_test_helper.h" #include "components/account_id/account_id.h" #include "components/network_session_configurator/common/network_switches.h" +#include "content/public/common/content_switches.h" #include "content/public/test/browser_test.h" #include "content/public/test/test_utils.h" #include "net/dns/mock_host_resolver.h" +#include "net/test/spawned_test_server/spawned_test_server.h" #include "testing/gtest/include/gtest/gtest.h" namespace ash { @@ -349,4 +353,89 @@ reauth_dialog_helper->ExpectVerifyAccountScreenHidden(); } +// Sets up proxy server which requires authentication. +class ProxyAuthLockscreenWebUiTest : public LockscreenWebUiTest { + public: + ProxyAuthLockscreenWebUiTest() + : proxy_server_(net::SpawnedTestServer::TYPE_BASIC_AUTH_PROXY, + base::FilePath()), + login_handler_(nullptr) {} + + ProxyAuthLockscreenWebUiTest(const ProxyAuthLockscreenWebUiTest&) = delete; + ProxyAuthLockscreenWebUiTest& operator=(const ProxyAuthLockscreenWebUiTest&) = + delete; + + ~ProxyAuthLockscreenWebUiTest() override = default; + + void SetUpCommandLine(base::CommandLine* command_line) override { + LockscreenWebUiTest::SetUpCommandLine(command_line); + command_line->AppendSwitchASCII(::switches::kProxyServer, + proxy_server_.host_port_pair().ToString()); + } + + void SetUpOnMainThread() override { + LockscreenWebUiTest::SetUpOnMainThread(); + // Proxy authentication will be required as soon as we request any url from + // lock screen's webview. This observer will notice it and allow us to + // access corresponding `LoginHandler` object. + auth_needed_observer_ = + std::make_unique<content::WindowedNotificationObserver>( + chrome::NOTIFICATION_AUTH_NEEDED, + base::BindRepeating(&ProxyAuthLockscreenWebUiTest::OnAuthRequested, + base::Unretained(this))); + } + + void SetUp() override { + proxy_server_.set_redirect_connect_to_localhost(true); + ASSERT_TRUE(proxy_server_.Start()); + LockscreenWebUiTest::SetUp(); + } + + void WaitForLoginHandler() { auth_needed_observer_->Wait(); } + + LoginHandler* login_handler() const { return login_handler_; } + + private: + bool OnAuthRequested(const content::NotificationSource& /* source */, + const content::NotificationDetails& details) { + login_handler_ = + content::Details<LoginNotificationDetails>(details)->handler(); + return true; + } + + net::SpawnedTestServer proxy_server_; + std::unique_ptr<content::WindowedNotificationObserver> auth_needed_observer_; + // Used for proxy server authentication. + LoginHandler* login_handler_; +}; + +// TODO(andreydav@): Investigate why we never get +// `NetworkStateInformer::PROXY_AUTH_REQUIRED` state from +// `NetworkStateInformer::UpdateState()` with current test setup. This prevents +// us from writing tests where we would switch to to a network behind proxy on a +// network screen or where we would cancel proxy auth to choose another network. +IN_PROC_BROWSER_TEST_F(ProxyAuthLockscreenWebUiTest, ProxyAuth) { + Login(); + + LOG(INFO) << "ScreenLockerTester().Lock()"; + // Lock the screen and trigger the lock screen SAML reauth dialog. + ScreenLockerTester().Lock(); + LOG(INFO) << "LockScreenReauthDialogTestHelper::ShowDialogAndWait()"; + absl::optional<LockScreenReauthDialogTestHelper> reauth_dialog_helper = + LockScreenReauthDialogTestHelper::ShowDialogAndWait(); + ASSERT_TRUE(reauth_dialog_helper); + + reauth_dialog_helper->ForceSamlRedirect(); + + reauth_dialog_helper->WaitForVerifyAccountScreen(); + reauth_dialog_helper->ClickVerifyButton(); + + reauth_dialog_helper->WaitForSamlScreen(); + reauth_dialog_helper->ExpectVerifyAccountScreenHidden(); + + // Appearance of login handler means that proxy authentication was requested + WaitForLoginHandler(); + ASSERT_TRUE(login_handler()); +} + } // namespace ash
diff --git a/chrome/browser/ash/policy/networking/network_policy_application_browsertest.cc b/chrome/browser/ash/policy/networking/network_policy_application_browsertest.cc index 0029264c..d58c9ea 100644 --- a/chrome/browser/ash/policy/networking/network_policy_application_browsertest.cc +++ b/chrome/browser/ash/policy/networking/network_policy_application_browsertest.cc
@@ -27,6 +27,7 @@ #include "chromeos/network/network_cert_loader.h" #include "chromeos/network/network_handler.h" #include "chromeos/network/network_policy_observer.h" +#include "chromeos/system/fake_statistics_provider.h" #include "components/account_id/account_id.h" #include "components/policy/core/browser/browser_policy_connector.h" #include "components/policy/core/common/mock_configuration_policy_provider.h" @@ -408,7 +409,7 @@ // Set up two services. shill_service_client_test_->AddService( kServiceWifi1, "wifi_orig_guid_1", "WifiOne", shill::kTypeWifi, - shill::kStateOnline, true /* add_to_visible */); + shill::kStateOnline, /*add_to_visible=*/true); shill_service_client_test_->SetServiceProperty( kServiceWifi1, shill::kSSIDProperty, base::Value("WifiOne")); shill_service_client_test_->SetServiceProperty( @@ -417,7 +418,7 @@ shill_service_client_test_->AddService( kServiceWifi2, "wifi_orig_guid_2", "WifiTwo", shill::kTypeWifi, - shill::kStateOnline, true /* add_to_visible */); + shill::kStateOnline, /*add_to_visible=*/true); shill_service_client_test_->SetServiceProperty( kServiceWifi2, shill::kSSIDProperty, base::Value("WifiTwo")); shill_service_client_test_->SetServiceProperty( @@ -599,7 +600,7 @@ // Set up two services. shill_service_client_test_->AddService( kServiceWifi1, "wifi_orig_guid_1", "WifiOne", shill::kTypeWifi, - shill::kStateOnline, true /* add_to_visible */); + shill::kStateOnline, /*add_to_visible=*/true); shill_service_client_test_->SetServiceProperty( kServiceWifi1, shill::kSSIDProperty, base::Value("WifiOne")); shill_service_client_test_->SetServiceProperty( @@ -608,7 +609,7 @@ shill_service_client_test_->AddService( kServiceWifi2, "wifi_orig_guid_2", "WifiTwo", shill::kTypeWifi, - shill::kStateOnline, true /* add_to_visible */); + shill::kStateOnline, /*add_to_visible=*/true); shill_service_client_test_->SetServiceProperty( kServiceWifi2, shill::kSSIDProperty, base::Value("WifiTwo")); shill_service_client_test_->SetServiceProperty( @@ -690,7 +691,7 @@ // Set up a policy-managed EAP wifi with a certificate already selected. shill_service_client_test_->AddService( kServiceWifi1, "DeviceLevelWifiGuidOrig", "DeviceLevelWifiSsid", - shill::kTypeWifi, shill::kStateOnline, true /* add_to_visible */); + shill::kTypeWifi, shill::kStateOnline, /*add_to_visible=*/true); shill_service_client_test_->SetServiceProperty( kServiceWifi1, shill::kSSIDProperty, base::Value("DeviceLevelWifiSsid")); shill_service_client_test_->SetServiceProperty( @@ -768,4 +769,213 @@ ElementsAre("identity_1", "identity_2")); } +// Configures a device-wide network that uses variable expansions +// (https://chromium.googlesource.com/chromium/src/+/main/components/onc/docs/onc_spec.md#string-expansions) +// and then tests that these variables are replaced with their values in the +// config pushed to shill. +IN_PROC_BROWSER_TEST_F(NetworkPolicyApplicationTest, + DevicePolicyProfileWideVariableExpansions) { + const std::string kSerialNumber = "test_serial"; + chromeos::system::ScopedFakeStatisticsProvider fake_statistics_provider_; + fake_statistics_provider_.SetMachineStatistic( + chromeos::system::kSerialNumberKeyForTest, kSerialNumber); + + shill_service_client_test_->AddService( + kServiceWifi1, "DeviceLevelWifiGuidOrig", "DeviceLevelWifiSsid", + shill::kTypeWifi, shill::kStateOnline, /*add_to_visible=*/true); + shill_service_client_test_->SetServiceProperty( + kServiceWifi1, shill::kSSIDProperty, base::Value("DeviceLevelWifiSsid")); + shill_service_client_test_->SetServiceProperty( + kServiceWifi1, shill::kSecurityClassProperty, + base::Value(shill::kSecurity8021x)); + + const char kDeviceONC1[] = R"( + { + "NetworkConfigurations": [ + { + "GUID": "{DeviceLevelWifiGuid}", + "Name": "DeviceLevelWifiName", + "Type": "WiFi", + "WiFi": { + "AutoConnect": false, + "EAP": { + "Outer": "EAP-TLS", + "ClientCertType": "Pattern", + "Identity": "${DEVICE_SERIAL_NUMBER}", + "ClientCertPattern": { + "Issuer": { + "Organization": "Example Inc." + } + } + }, + "SSID": "DeviceLevelWifiSsid", + "Security": "WPA-EAP" + } + } + ] + })"; + { + ScopedNetworkPolicyApplicationObserver network_policy_application_observer; + SetDeviceOpenNetworkConfiguration(kDeviceONC1); + network_policy_application_observer.WaitPoliciesApplied( + /*userhash=*/std::string()); + } + + { + const base::Value* wifi_service_properties = + shill_service_client_test_->GetServiceProperties(kServiceWifi1); + ASSERT_TRUE(wifi_service_properties); + EXPECT_THAT(*wifi_service_properties, + DictionaryHasValue(shill::kGuidProperty, + base::Value("{DeviceLevelWifiGuid}"))); + // Expect that the EAP.Identity has been replaced + const std::string* eap_identity = + wifi_service_properties->FindStringKey(shill::kEapIdentityProperty); + ASSERT_TRUE(eap_identity); + EXPECT_EQ(*eap_identity, kSerialNumber); + + // TODO(b/209084821): Also test DEVICE_ASSET_ID when it's easily + // configurable in a browsertest. + } +} + +// Configures a network that uses variable expansions with variables based on a +// client certificate selected using a CertificatePattern. +// The network is device-wide because that is easier to set up in the test. +IN_PROC_BROWSER_TEST_F(NetworkPolicyApplicationTest, + DevicePolicyCertBasedVariableExpansions) { + const char* kCertKeyFilename = "client_3.pk8"; + const char* kCertFilename = "client_3.pem"; + const char* kCertIssuerCommonName = "E CA"; + const char* kIdentityPolicyValue = + "${CERT_SUBJECT_COMMON_NAME}/${CERT_SAN_UPN}/${CERT_SAN_EMAIL}"; + const char* kExpectedIdentity = + "Client Cert F/santest@ad.corp.example.com/santest@example.com"; + ASSERT_NO_FATAL_FAILURE(ImportCert(net::GetTestCertsDirectory(), + kCertFilename, kCertKeyFilename)); + + shill_service_client_test_->AddService( + kServiceWifi1, "DeviceLevelWifiGuidOrig", "DeviceLevelWifiSsid", + shill::kTypeWifi, shill::kStateOnline, /*add_to_visible=*/true); + shill_service_client_test_->SetServiceProperty( + kServiceWifi1, shill::kSSIDProperty, base::Value("DeviceLevelWifiSsid")); + shill_service_client_test_->SetServiceProperty( + kServiceWifi1, shill::kSecurityClassProperty, + base::Value(shill::kSecurity8021x)); + + std::string kDeviceONC1 = + base::StringPrintf(R"( + { + "NetworkConfigurations": [ + { + "GUID": "{DeviceLevelWifiGuid}", + "Name": "DeviceLevelWifiName", + "Type": "WiFi", + "WiFi": { + "AutoConnect": false, + "EAP": { + "Outer": "EAP-TLS", + "ClientCertType": "Pattern", + "Identity": "%s", + "ClientCertPattern": { + "Issuer": { + "CommonName": "%s" + } + } + }, + "SSID": "DeviceLevelWifiSsid", + "Security": "WPA-EAP" + } + } + ] + })", + kIdentityPolicyValue, kCertIssuerCommonName); + { + ScopedNetworkPolicyApplicationObserver network_policy_application_observer; + SetDeviceOpenNetworkConfiguration(kDeviceONC1); + network_policy_application_observer.WaitPoliciesApplied( + /*userhash=*/std::string()); + } + + { + const base::Value* wifi_service_properties = + shill_service_client_test_->GetServiceProperties(kServiceWifi1); + ASSERT_TRUE(wifi_service_properties); + EXPECT_THAT(*wifi_service_properties, + DictionaryHasValue(shill::kGuidProperty, + base::Value("{DeviceLevelWifiGuid}"))); + // Expect that the EAP.Identity has been replaced + const std::string* eap_identity = + wifi_service_properties->FindStringKey(shill::kEapIdentityProperty); + ASSERT_TRUE(eap_identity); + EXPECT_EQ(*eap_identity, kExpectedIdentity); + } +} + +// Configures a user-specific network that uses variable expansions +// (https://chromium.googlesource.com/chromium/src/+/main/components/onc/docs/onc_spec.md#string-expansions) +// and then tests that these variables are replaced with their values in the +// config pushed to shill. +IN_PROC_BROWSER_TEST_F(NetworkPolicyApplicationTest, + UserPolicyProfileWideVariableExpansions) { + shill_service_client_test_->AddService( + kServiceWifi1, "UserLevelWifiGuidOrig", "UserLevelWifiSsid", + shill::kTypeWifi, shill::kStateOnline, /*add_to_visible=*/true); + shill_service_client_test_->SetServiceProperty( + kServiceWifi1, shill::kSSIDProperty, base::Value("UserLevelWifiSsid")); + shill_service_client_test_->SetServiceProperty( + kServiceWifi1, shill::kSecurityClassProperty, + base::Value(shill::kSecurity8021x)); + + std::string user_hash = ash::ProfileHelper::GetUserIdHashByUserIdForTesting( + test_account_id_.GetUserEmail()); + LoginUser(test_account_id_); + shill_profile_client_test_->AddProfile(kUserProfilePath, user_hash); + + const char kUserONC1[] = R"( + { + "NetworkConfigurations": [ + { + "GUID": "{UserLevelWifiGuid}", + "Name": "UserLevelWifiName", + "Type": "WiFi", + "WiFi": { + "AutoConnect": false, + "EAP": { + "Outer": "EAP-TLS", + "ClientCertType": "Pattern", + "Identity": "${LOGIN_EMAIL}", + "ClientCertPattern": { + "Issuer": { + "Organization": "Example Inc." + } + } + }, + "SSID": "UserLevelWifiSsid", + "Security": "WPA-EAP" + } + } + ] + })"; + { + ScopedNetworkPolicyApplicationObserver network_policy_application_observer; + SetUserOpenNetworkConfiguration(kUserONC1); + network_policy_application_observer.WaitPoliciesApplied(user_hash); + } + + { + const base::Value* wifi_service_properties = + shill_service_client_test_->GetServiceProperties(kServiceWifi1); + ASSERT_TRUE(wifi_service_properties); + EXPECT_THAT(*wifi_service_properties, + DictionaryHasValue(shill::kGuidProperty, + base::Value("{UserLevelWifiGuid}"))); + // Expect that the EAP.Identity has been replaced + const std::string* eap_identity = + wifi_service_properties->FindStringKey(shill::kEapIdentityProperty); + ASSERT_TRUE(eap_identity); + EXPECT_EQ(*eap_identity, test_account_id_.GetUserEmail()); + } +} + } // namespace policy
diff --git a/chrome/browser/ash/preferences.cc b/chrome/browser/ash/preferences.cc index 1496941..a6d5cdb6 100644 --- a/chrome/browser/ash/preferences.cc +++ b/chrome/browser/ash/preferences.cc
@@ -49,6 +49,9 @@ #include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "chromeos/ash/components/dbus/pciguard/pciguard_client.h" +#include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/update_engine/update_engine.pb.h" +#include "chromeos/dbus/update_engine/update_engine_client.h" #include "chromeos/system/devicemode.h" #include "chromeos/system/statistics_provider.h" #include "components/drive/drive_pref_names.h" @@ -119,6 +122,7 @@ Preferences::~Preferences() { prefs_->RemoveObserver(this); user_manager::UserManager::Get()->RemoveSessionStateObserver(this); + DBusThreadManager::Get()->GetUpdateEngineClient()->RemoveObserver(this); } // static @@ -147,6 +151,7 @@ registry->RegisterBooleanPref(prefs::kDeviceI18nShortcutsEnabled, true); registry->RegisterBooleanPref(prefs::kChromadToCloudMigrationEnabled, false); registry->RegisterBooleanPref(prefs::kLoginScreenWebUILazyLoading, false); + registry->RegisterBooleanPref(::prefs::kConsumerAutoUpdateToggle, true); RegisterLocalStatePrefs(registry); } @@ -587,6 +592,10 @@ prefs::kLocalStateDevicePeripheralDataAccessEnabled, g_browser_process->local_state(), callback); + consumer_auto_update_toggle_pref_.Init(::prefs::kConsumerAutoUpdateToggle, + g_browser_process->local_state(), + callback); + pref_change_registrar_.Init(prefs); pref_change_registrar_.Add(::prefs::kUserTimezone, callback); pref_change_registrar_.Add(::prefs::kResolveTimezoneByGeolocationMethod, @@ -611,6 +620,14 @@ user_manager::UserManager::Get()->AddSessionStateObserver(this); + auto* update_engine_client = + DBusThreadManager::Get()->GetUpdateEngineClient(); + update_engine_client->AddObserver(this); + update_engine_client->IsFeatureEnabled( + update_engine::kFeatureConsumerAutoUpdate, + base::BindOnce(&Preferences::OnIsConsumerAutoUpdateEnabled, + weak_ptr_factory_.GetWeakPtr())); + UserSessionManager* session_manager = UserSessionManager::GetInstance(); DCHECK(session_manager); ime_state_ = session_manager->GetDefaultIMEState(profile); @@ -669,6 +686,10 @@ InitUserPrefs(prefs); + auto* update_engine_client = + DBusThreadManager::Get()->GetUpdateEngineClient(); + update_engine_client->AddObserver(this); + input_method_syncer_ = std::make_unique<input_method::InputMethodSyncer>(prefs, ime_state_); input_method_syncer_->Initialize(); @@ -1186,4 +1207,32 @@ ApplyPreferences(REASON_ACTIVE_USER_CHANGED, ""); } +void Preferences::UpdateStatusChanged( + const update_engine::StatusResult& status) { + DVLOG(1) << "UpdateStatusChanged"; + for (int i = 0; i < status.features_size(); ++i) { + const update_engine::Feature& feature = status.features(i); + bool enabled = feature.enabled(); + DVLOG(1) << "Feature name=" << feature.name() << " enabled=" << enabled; + if (feature.name() == update_engine::kFeatureConsumerAutoUpdate) { + // Writes into this preference are only flushed by listening to + // platform side signals. This means Chrome side writes into this + // preference will not be visible outside of Chrome. This preference + // should be updated by making DBus calls into the platform side, which + // will signal out the true value of this preference as the true value is + // managed by the update_engine daemon. + consumer_auto_update_toggle_pref_.SetValue(enabled); + } + } +} + +void Preferences::OnIsConsumerAutoUpdateEnabled(absl::optional<bool> enabled) { + DVLOG(1) << "OnIsConsumerAutoUpdateEnabled"; + if (!enabled.has_value()) { + VLOG(1) << "Failed to retrieve consumer auto update feature value."; + return; + } + consumer_auto_update_toggle_pref_.SetValue(enabled.value()); +} + } // namespace ash
diff --git a/chrome/browser/ash/preferences.h b/chrome/browser/ash/preferences.h index 54ca0da2d..882d54f0 100644 --- a/chrome/browser/ash/preferences.h +++ b/chrome/browser/ash/preferences.h
@@ -8,7 +8,9 @@ #include <string> #include "ash/public/mojom/cros_display_config.mojom.h" +#include "base/memory/weak_ptr.h" #include "chrome/browser/ash/language_preferences.h" +#include "chromeos/dbus/update_engine/update_engine_client.h" #include "components/prefs/pref_change_registrar.h" #include "components/prefs/pref_member.h" #include "components/sync_preferences/pref_service_syncable_observer.h" @@ -42,7 +44,8 @@ // the preferences. These include touchpad settings, etc. // When the preferences change, we change the settings to reflect the new value. class Preferences : public sync_preferences::PrefServiceSyncableObserver, - public user_manager::UserManager::UserSessionStateObserver { + public user_manager::UserManager::UserSessionStateObserver, + public UpdateEngineClient::Observer { public: Preferences(); explicit Preferences( @@ -61,6 +64,7 @@ // |user| is the user owning this preferences. void Init(Profile* profile, const user_manager::User* user); + void InitPrefsForTesting(sync_preferences::PrefServiceSyncable* prefs); void InitUserPrefsForTesting( sync_preferences::PrefServiceSyncable* prefs, const user_manager::User* user, @@ -125,6 +129,10 @@ // Overriden form user_manager::UserManager::UserSessionStateObserver. void ActiveUserChanged(user_manager::User* active_user) override; + // UpdateEngineClient::Observer implementation. + void UpdateStatusChanged(const update_engine::StatusResult& status) override; + void OnIsConsumerAutoUpdateEnabled(absl::optional<bool> enabled); + sync_preferences::PrefServiceSyncable* prefs_; input_method::InputMethodManager* input_method_manager_; @@ -172,6 +180,8 @@ BooleanPrefMember pci_data_access_enabled_pref_; + BooleanPrefMember consumer_auto_update_toggle_pref_; + PrefChangeRegistrar pref_change_registrar_; // User owning these preferences. @@ -186,6 +196,10 @@ std::unique_ptr<input_method::InputMethodSyncer> input_method_syncer_; mojo::Remote<mojom::CrosDisplayConfigController> cros_display_config_; + + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory<Preferences> weak_ptr_factory_{this}; }; } // namespace ash
diff --git a/chrome/browser/ash/preferences_unittest.cc b/chrome/browser/ash/preferences_unittest.cc index 5316cfd..d7d409b 100644 --- a/chrome/browser/ash/preferences_unittest.cc +++ b/chrome/browser/ash/preferences_unittest.cc
@@ -22,6 +22,8 @@ #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile_manager.h" +#include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/update_engine/fake_update_engine_client.h" #include "components/language/core/browser/pref_names.h" #include "components/prefs/pref_member.h" #include "components/sync/base/client_tag_hash.h" @@ -172,11 +174,22 @@ current_input_method_.Init( prefs::kLanguageCurrentInputMethod, pref_service_); current_input_method_.SetValue("KeyboardB"); + consumer_auto_update_toggle_.Init(::prefs::kConsumerAutoUpdateToggle, + g_browser_process->local_state()); + consumer_auto_update_toggle_.SetValue(true); mock_manager_ = new input_method::MyMockInputMethodManager( &previous_input_method_, ¤t_input_method_); input_method::InitializeForTesting(mock_manager_); + if (!chromeos::DBusThreadManager::IsInitialized()) { + chromeos::DBusThreadManager::Initialize(); + } + fake_update_engine_client_ = new chromeos::FakeUpdateEngineClient(); + chromeos::DBusThreadManager::GetSetterForTesting()->SetUpdateEngineClient( + std::unique_ptr<chromeos::UpdateEngineClient>( + fake_update_engine_client_)); + prefs_ = std::make_unique<Preferences>(mock_manager_); } @@ -200,12 +213,14 @@ std::unique_ptr<Preferences> prefs_; StringPrefMember previous_input_method_; StringPrefMember current_input_method_; + BooleanPrefMember consumer_auto_update_toggle_; // Not owned. const user_manager::User* test_user_; TestingProfile* test_profile_; sync_preferences::TestingPrefServiceSyncable* pref_service_; input_method::MyMockInputMethodManager* mock_manager_; + chromeos::FakeUpdateEngineClient* fake_update_engine_client_; }; TEST_F(PreferencesTest, TestUpdatePrefOnBrowserScreenDetails) { @@ -217,6 +232,28 @@ EXPECT_EQ("KeyboardB", mock_manager_->last_input_method_id_); } +TEST_F(PreferencesTest, TestConsumerAutoUpdateToggleOnSignals) { + InitPreferences(); + + auto CreateCAUFeatureStatus = [](bool enabled) { + update_engine::StatusResult status; + auto* feature = status.add_features(); + feature->set_name(update_engine::kFeatureConsumerAutoUpdate); + feature->set_enabled(enabled); + return status; + }; + + consumer_auto_update_toggle_.SetValue(true); + + fake_update_engine_client_->NotifyObserversThatStatusChanged( + CreateCAUFeatureStatus(false)); + EXPECT_FALSE(consumer_auto_update_toggle_.GetValue()); + + fake_update_engine_client_->NotifyObserversThatStatusChanged( + CreateCAUFeatureStatus(true)); + EXPECT_TRUE(consumer_auto_update_toggle_.GetValue()); +} + class InputMethodPreferencesTest : public PreferencesTest, public ::testing::WithParamInterface<bool> { public:
diff --git a/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.cc b/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.cc index 4960d4e..964983e 100644 --- a/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.cc +++ b/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.cc
@@ -591,16 +591,14 @@ signin::ScopeSet scopes; scopes.insert(GaiaConstants::kPhotosModuleOAuth2Scope); - DCHECK(token_fetchers_.find(service_url) == token_fetchers_.end()); - token_fetchers_[service_url] = - std::make_unique<signin::PrimaryAccountAccessTokenFetcher>( - "wallpaper_google_photos_fetcher", identity_manager_, scopes, - base::BindOnce( - &GooglePhotosFetcher::OnTokenReceived, - base::Unretained(this), /*`this` owns `token_fetchers_`.*/ - service_url, /*start_time=*/base::TimeTicks::Now()), - signin::PrimaryAccountAccessTokenFetcher::Mode::kImmediate, - signin::ConsentLevel::kSignin); + auto fetcher = std::make_unique<signin::PrimaryAccountAccessTokenFetcher>( + "wallpaper_google_photos_fetcher", identity_manager_, scopes, + signin::PrimaryAccountAccessTokenFetcher::Mode::kImmediate, + signin::ConsentLevel::kSignin); + auto* fetcher_ptr = fetcher.get(); + fetcher_ptr->Start(base::BindOnce( + &GooglePhotosFetcher::OnTokenReceived, weak_factory_.GetWeakPtr(), + std::move(fetcher), service_url, /*start_time=*/base::TimeTicks::Now())); } template <typename T> @@ -611,6 +609,7 @@ template <typename T> void GooglePhotosFetcher<T>::OnTokenReceived( + std::unique_ptr<signin::PrimaryAccountAccessTokenFetcher> fetcher, const GURL& service_url, base::TimeTicks start_time, GoogleServiceAuthError error, @@ -633,26 +632,27 @@ resource_request->headers.SetHeader(net::HttpRequestHeaders::kAuthorization, "Bearer " + token_info.token); - DCHECK(url_loaders_.find(service_url) == url_loaders_.end()); - url_loaders_[service_url] = network::SimpleURLLoader::Create( - std::move(resource_request), traffic_annotation_); - url_loaders_[service_url]->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + auto loader = network::SimpleURLLoader::Create(std::move(resource_request), + traffic_annotation_); + auto* loader_ptr = loader.get(); + loader_ptr->DownloadToStringOfUnboundedSizeUntilCrashAndDie( profile_->GetURLLoaderFactory().get(), base::BindOnce(&GooglePhotosFetcher::OnJsonReceived, - base::Unretained(this), /*`this` owns `url_loaders_`.*/ - service_url, start_time)); + weak_factory_.GetWeakPtr(), std::move(loader), service_url, + start_time)); } template <typename T> void GooglePhotosFetcher<T>::OnJsonReceived( + std::unique_ptr<network::SimpleURLLoader> loader, const GURL& service_url, base::TimeTicks start_time, std::unique_ptr<std::string> response_body) { - const int net_error = url_loaders_[service_url]->NetError(); + const int net_error = loader->NetError(); if (net_error != net::OK || !response_body) { LOG(ERROR) << "Google Photos API request to " << service_url.spec() << " failed."; - auto* response_info = url_loaders_[service_url]->ResponseInfo(); + auto* response_info = loader->ResponseInfo(); absl::optional<base::Value> error_response; if (response_info && response_info->headers) { LOG(ERROR) << "HTTP response code: " @@ -703,9 +703,6 @@ for (auto& callback : pending_client_callbacks_[service_url]) std::move(callback).Run(mojo::Clone(result)); - - token_fetchers_.erase(service_url); - url_loaders_.erase(service_url); pending_client_callbacks_.erase(service_url); }
diff --git a/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.h b/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.h index 61a3466..105e5cd3 100644 --- a/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.h +++ b/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.h
@@ -181,11 +181,14 @@ virtual absl::optional<base::Value> CreateErrorResponse(int error_code); private: - void OnTokenReceived(const GURL& service_url, - base::TimeTicks start_time, - GoogleServiceAuthError error, - signin::AccessTokenInfo token_info); - void OnJsonReceived(const GURL& service_url, + void OnTokenReceived( + std::unique_ptr<signin::PrimaryAccountAccessTokenFetcher> fetcher, + const GURL& service_url, + base::TimeTicks start_time, + GoogleServiceAuthError error, + signin::AccessTokenInfo token_info); + void OnJsonReceived(std::unique_ptr<network::SimpleURLLoader> loader, + const GURL& service_url, base::TimeTicks start_time, std::unique_ptr<std::string> response_body); void OnResponseReady(const GURL& service_url, @@ -209,15 +212,6 @@ // successfully or in error. std::map<GURL, std::vector<ClientCallback>> pending_client_callbacks_; - // OAuth2 access token fetcher for each distinct query this fetcher has been - // asked to make. A URL's fetcher exists until its callbacks have been called. - std::map<GURL, std::unique_ptr<signin::PrimaryAccountAccessTokenFetcher>> - token_fetchers_; - - // Used to download the client's desired information from the Google Photos - // service. A URL's loader exists until its callbacks have been called. - std::map<GURL, std::unique_ptr<network::SimpleURLLoader>> url_loaders_; - base::WeakPtrFactory<GooglePhotosFetcher> weak_factory_{this}; };
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_ambient_provider_impl.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_ambient_provider_impl.cc index d38b309a..61c66f83 100644 --- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_ambient_provider_impl.cc +++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_ambient_provider_impl.cc
@@ -11,6 +11,7 @@ #include "ash/constants/ambient_animation_theme.h" #include "ash/constants/ash_features.h" +#include "ash/public/cpp/ambient/ambient_backend_controller.h" #include "ash/public/cpp/ambient/ambient_client.h" #include "ash/public/cpp/ambient/ambient_metrics.h" #include "ash/public/cpp/ambient/ambient_prefs.h" @@ -21,6 +22,7 @@ #include "base/barrier_closure.h" #include "base/bind.h" #include "base/callback.h" +#include "base/check.h" #include "base/logging.h" #include "base/memory/ref_counted_memory.h" #include "base/notreached.h" @@ -50,6 +52,8 @@ constexpr int kMaxRetries = 3; +constexpr char kRecentHighlightsPhotoContainerId[] = "RECENT_PHOTOS"; + constexpr net::BackoffEntry::Policy kRetryBackoffPolicy = { 0, // Number of initial errors to ignore. 500, // Initial delay in ms. @@ -195,7 +199,13 @@ settings_->selected_album_ids.clear(); for (const auto& personal_album : personal_albums_.albums) { if (personal_album.selected) { - settings_->selected_album_ids.emplace_back(personal_album.album_id); + std::string album_id = personal_album.album_id; + + // Convert the fake album ID back to actual ID from IMAX so we can + // download the previews. + if (album_id == ash::kAmbientModeRecentHighlightsAlbumId) + album_id = kRecentHighlightsPhotoContainerId; + settings_->selected_album_ids.emplace_back(album_id); } } @@ -266,6 +276,14 @@ if (!ambient_observer_remote_.is_bound()) return; + // First, empty the WebUI store so it doesn't show the previously selected + // albums' previews. If |settings_->topic_source| is Google photos, refetch + // the previews because the selected albums may have changed. Otherwise, we + // fallback to the preview urls that comes with the albums. + OnGooglePhotosAlbumsPreviewsFetched(std::vector<GURL>()); + if (settings_->topic_source == ash::AmbientModeTopicSource::kGooglePhotos) + FetchGooglePhotosAlbumsPreviews(settings_->selected_album_ids); + ambient_observer_remote_->OnTopicSourceChanged(settings_->topic_source); } @@ -557,6 +575,24 @@ return; } +void PersonalizationAppAmbientProviderImpl::FetchGooglePhotosAlbumsPreviews( + const std::vector<std::string>& album_ids) { + DCHECK(!album_ids.empty()); + google_photos_albums_previews_weak_factory_.InvalidateWeakPtrs(); + ash::AmbientBackendController::Get()->GetGooglePhotosAlbumsPreview( + album_ids, kBannerWidthPx, kBannerHeightPx, + /*num_previews=*/4, + base::BindOnce(&PersonalizationAppAmbientProviderImpl:: + OnGooglePhotosAlbumsPreviewsFetched, + google_photos_albums_previews_weak_factory_.GetWeakPtr())); +} + +void PersonalizationAppAmbientProviderImpl::OnGooglePhotosAlbumsPreviewsFetched( + const std::vector<GURL>& preview_urls) { + DVLOG(4) << __func__ << " preview_urls_size=" << preview_urls.size(); + ambient_observer_remote_->OnGooglePhotosAlbumsPreviewsFetched(preview_urls); +} + void PersonalizationAppAmbientProviderImpl:: DownloadRecentHighlightsPreviewImages( const std::vector<std::string>& urls) { @@ -622,6 +658,7 @@ write_weak_factory_.InvalidateWeakPtrs(); read_weak_factory_.InvalidateWeakPtrs(); album_preview_weak_factory_.InvalidateWeakPtrs(); + google_photos_albums_previews_weak_factory_.InvalidateWeakPtrs(); recent_highlights_previews_weak_factory_.InvalidateWeakPtrs(); settings_.reset();
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_ambient_provider_impl.h b/chrome/browser/ash/web_applications/personalization_app/personalization_app_ambient_provider_impl.h index 9b133eb..d928efe 100644 --- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_ambient_provider_impl.h +++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_ambient_provider_impl.h
@@ -19,6 +19,7 @@ #include "mojo/public/cpp/bindings/remote.h" #include "net/base/backoff_entry.h" #include "third_party/abseil-cpp/absl/types/optional.h" +#include "url/gurl.h" namespace gfx { class ImageSkia; @@ -110,6 +111,10 @@ void OnAlbumPreviewImageDownloaded(const std::string& album_id, const gfx::ImageSkia& image); + void FetchGooglePhotosAlbumsPreviews( + const std::vector<std::string>& album_ids); + void OnGooglePhotosAlbumsPreviewsFetched(const std::vector<GURL>& preview_urls); + ash::PersonalAlbum* FindPersonalAlbumById(const std::string& album_id); ash::ArtSetting* FindArtAlbumById(const std::string& album_id); @@ -169,6 +174,8 @@ base::WeakPtrFactory<PersonalizationAppAmbientProviderImpl> album_preview_weak_factory_{this}; base::WeakPtrFactory<PersonalizationAppAmbientProviderImpl> + google_photos_albums_previews_weak_factory_{this}; + base::WeakPtrFactory<PersonalizationAppAmbientProviderImpl> recent_highlights_previews_weak_factory_{this}; };
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_ambient_provider_impl_unittest.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_ambient_provider_impl_unittest.cc index f476f43..a5936b03 100644 --- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_ambient_provider_impl_unittest.cc +++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_ambient_provider_impl_unittest.cc
@@ -30,6 +30,7 @@ #include "mojo/public/cpp/bindings/remote.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/webui/web_ui_util.h" +#include "url/gurl.h" namespace ash { namespace personalization_app { @@ -65,6 +66,11 @@ temperature_unit_ = temperature_unit; } + void OnGooglePhotosAlbumsPreviewsFetched( + const std::vector<GURL>& previews) override { + previews_ = std::move(previews); + } + mojo::PendingRemote<ash::personalization_app::mojom::AmbientObserver> pending_remote() { if (ambient_observer_receiver_.is_bound()) { @@ -99,6 +105,11 @@ return temperature_unit_; } + std::vector<GURL> google_photos_albums_previews() { + ambient_observer_receiver_.FlushForTesting(); + return previews_; + } + private: mojo::Receiver<ash::personalization_app::mojom::AmbientObserver> ambient_observer_receiver_{this}; @@ -111,6 +122,7 @@ ash::AmbientModeTemperatureUnit temperature_unit_ = ash::AmbientModeTemperatureUnit::kFahrenheit; std::vector<ash::personalization_app::mojom::AmbientModeAlbumPtr> albums_; + std::vector<GURL> previews_; }; } // namespace @@ -197,6 +209,11 @@ return test_ambient_observer_.temperature_unit(); } + std::vector<GURL> ObservedGooglePhotosAlbumsPreviews() { + ambient_provider_remote_.FlushForTesting(); + return test_ambient_observer_.google_photos_albums_previews(); + } + absl::optional<ash::AmbientSettings>& settings() { return ambient_provider_->settings_; } @@ -398,6 +415,7 @@ ambient_provider_remote().FlushForTesting(); ReplyFetchSettingsAndAlbums(/*success=*/true); EXPECT_EQ(ash::AmbientModeTopicSource::kGooglePhotos, ObservedTopicSource()); + EXPECT_FALSE(ObservedGooglePhotosAlbumsPreviews().empty()); SetTopicSource(ash::AmbientModeTopicSource::kArtGallery); EXPECT_EQ(ash::AmbientModeTopicSource::kArtGallery, ObservedTopicSource()); @@ -412,6 +430,7 @@ // The fake albums are set in FakeAmbientBackendControllerImpl. Hidden setting // will be sent to JS side. EXPECT_EQ(4u, albums.size()); + EXPECT_FALSE(ObservedGooglePhotosAlbumsPreviews().empty()); } TEST_F(PersonalizationAppAmbientProviderImplTest,
diff --git a/chrome/browser/chromeos/extensions/wallpaper_private_api.cc b/chrome/browser/chromeos/extensions/wallpaper_private_api.cc index 65298571..51c7835 100644 --- a/chrome/browser/chromeos/extensions/wallpaper_private_api.cc +++ b/chrome/browser/chromeos/extensions/wallpaper_private_api.cc
@@ -13,6 +13,7 @@ #include "ash/public/cpp/wallpaper/wallpaper_controller.h" #include "ash/webui/personalization_app/proto/backdrop_wallpaper.pb.h" #include "base/bind.h" +#include "base/callback_helpers.h" #include "base/command_line.h" #include "base/containers/span.h" #include "base/files/file_enumerator.h" @@ -393,7 +394,7 @@ user_manager::UserManager::Get()->GetActiveUser()->GetAccountId(); WallpaperControllerClientImpl::Get()->SetDefaultWallpaper( - account_id, true /* show_wallpaper */); + account_id, true /* show_wallpaper */, base::DoNothing()); return RespondNow(NoArguments()); }
diff --git a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc index ffc468a..ff68833 100644 --- a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc +++ b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc
@@ -523,7 +523,10 @@ // CalculateEventResult(data_.settings, result_.page_result, should_warn)); if (!result_.page_result) { - if (should_warn) { + if (result == BinaryUploadService::Result::FILE_TOO_LARGE) { + UpdateFinalResult(ContentAnalysisDelegateBase::FinalResult::LARGE_FILES, + tag); + } else if (should_warn) { page_warning_ = true; page_response_ = std::move(response); UpdateFinalResult(ContentAnalysisDelegateBase::FinalResult::WARNING, tag);
diff --git a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate_browsertest.cc b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate_browsertest.cc index 79a9c6c..2d39779 100644 --- a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate_browsertest.cc +++ b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate_browsertest.cc
@@ -98,14 +98,35 @@ if (should_automatically_authorize_) ReturnAuthorizedResponse(); } else { + Request* request_raw = request.get(); std::string file = request->filename(); - if (file.empty()) { - request->FinishRequest(prepared_text_result_, prepared_text_response_); - } else { - ASSERT_TRUE(prepared_file_results_.count(file)); - ASSERT_TRUE(prepared_file_responses_.count(file)); - request->FinishRequest(prepared_file_results_[file], - prepared_file_responses_[file]); + switch (request->analysis_connector()) { + case AnalysisConnector::FILE_ATTACHED: + ASSERT_FALSE(file.empty()); + ASSERT_TRUE(prepared_file_results_.count(file)); + ASSERT_TRUE(prepared_file_responses_.count(file)); + request->FinishRequest(prepared_file_results_[file], + prepared_file_responses_[file]); + break; + case AnalysisConnector::BULK_DATA_ENTRY: + request->FinishRequest(prepared_text_result_, + prepared_text_response_); + break; + case AnalysisConnector::PRINT: + // Since this path is only used for prints that are too large, calling + // GetRequestData should then call FinishRequest with FILE_TOO_LARGE. + request_raw->GetRequestData(base::BindOnce( + [](std::unique_ptr<BinaryUploadService::Request> request, + BinaryUploadService::Result result, + BinaryUploadService::Request::Data data) { + ASSERT_EQ(result, BinaryUploadService::Result::FILE_TOO_LARGE); + request->FinishRequest(result, ContentAnalysisResponse()); + }, + std::move(request))); + break; + case AnalysisConnector::ANALYSIS_CONNECTOR_UNSPECIFIED: + case AnalysisConnector::FILE_DOWNLOADED: + NOTREACHED(); } } } @@ -884,6 +905,68 @@ } IN_PROC_BROWSER_TEST_P(ContentAnalysisDelegateBlockingSettingBrowserTest, + BlockLargePages) { + base::ScopedAllowBlockingForTesting allow_blocking; + + // Set up delegate and upload service. + EnableUploadsScanningAndReporting(); + constexpr char kBlockLargePagesPref[] = R"({ + "service_provider": "google", + "enable": [ + { + "url_list": ["*"], + "tags": ["dlp"] + } + ], + "block_until_verdict": 1, + "block_large_files": %s + })"; + safe_browsing::SetAnalysisConnector( + browser()->profile()->GetPrefs(), PRINT, + base::StringPrintf(kBlockLargePagesPref, bool_setting_value()), + machine_scope()); + + ContentAnalysisDelegate::SetFactoryForTesting( + base::BindRepeating(&MinimalFakeContentAnalysisDelegate::Create)); + + FakeBinaryUploadServiceStorage()->SetAuthorized(true); + + // Create the large page. + ContentAnalysisDelegate::Data data; + constexpr int64_t kLargeSize = 51 * 1024 * 1024; + base::MappedReadOnlyRegion page = + base::ReadOnlySharedMemoryRegion::Create(kLargeSize); + memset(page.mapping.memory(), 'a', kLargeSize); + data.page = std::move(page.region); + + ASSERT_TRUE(ContentAnalysisDelegate::IsEnabled(browser()->profile(), + GURL(kTestUrl), &data, PRINT)); + + bool called = false; + base::RunLoop run_loop; + SetQuitClosure(run_loop.QuitClosure()); + + // Start test. + ContentAnalysisDelegate::CreateForWebContents( + browser()->tab_strip_model()->GetActiveWebContents(), std::move(data), + base::BindLambdaForTesting( + [this, &called](const ContentAnalysisDelegate::Data& data, + const ContentAnalysisDelegate::Result& result) { + ASSERT_TRUE(result.paths_results.empty()); + ASSERT_TRUE(result.text_results.empty()); + ASSERT_EQ(result.page_result, expected_result()); + + called = true; + }), + safe_browsing::DeepScanAccessPoint::PRINT); + + FakeBinaryUploadServiceStorage()->ReturnAuthorizedResponse(); + + run_loop.Run(); + EXPECT_TRUE(called); +} + +IN_PROC_BROWSER_TEST_P(ContentAnalysisDelegateBlockingSettingBrowserTest, BlockUntilVerdict) { base::ScopedAllowBlockingForTesting allow_blocking;
diff --git a/chrome/browser/extensions/api/favicon/favicon_apitest.cc b/chrome/browser/extensions/api/favicon/favicon_apitest.cc index 3718296..cc67ac1 100644 --- a/chrome/browser/extensions/api/favicon/favicon_apitest.cc +++ b/chrome/browser/extensions/api/favicon/favicon_apitest.cc
@@ -3,6 +3,7 @@ // // found in the LICENSE file. #include "base/test/scoped_feature_list.h" +#include "build/build_config.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/test/base/ui_test_utils.h" #include "components/version_info/channel.h" @@ -31,8 +32,15 @@ ScopedCurrentChannel current_cnannel_{version_info::Channel::CANARY}; }; +// TODO(crbug.com/1319934): Test is flaky on Mac. +#if BUILDFLAG(IS_MAC) +#define MAYBE_Extension DISABLED_Extension +#else +#define MAYBE_Extension Extension +#endif + // Fetch favicon from an extension with the correct permission. -IN_PROC_BROWSER_TEST_F(FaviconApiTest, Extension) { +IN_PROC_BROWSER_TEST_F(FaviconApiTest, MAYBE_Extension) { // Cache the favicon by loading a test page, then fetch the favicon. GURL page_url = embedded_test_server()->GetURL( "www.example.com", "/extensions/favicon/test_file.html");
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc index d433eb2..b229181 100644 --- a/chrome/browser/extensions/api/settings_private/prefs_util.cc +++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -813,6 +813,8 @@ settings_api::PrefType::PREF_TYPE_LIST; (*s_allowlist)[ash::prefs::kPowerAdaptiveChargingEnabled] = settings_api::PrefType::PREF_TYPE_BOOLEAN; + (*s_allowlist)[::prefs::kConsumerAutoUpdateToggle] = + settings_api::PrefType::PREF_TYPE_BOOLEAN; // Native Printing settings. (*s_allowlist)[::prefs::kUserPrintersAllowed] =
diff --git a/chrome/browser/extensions/service_worker_apitest.cc b/chrome/browser/extensions/service_worker_apitest.cc index 1e1fd4e..8a9dc73 100644 --- a/chrome/browser/extensions/service_worker_apitest.cc +++ b/chrome/browser/extensions/service_worker_apitest.cc
@@ -2458,8 +2458,17 @@ EXPECT_TRUE(moved_tab_listener.WaitUntilSatisfied()); } +// TODO(crbug.com/1319942): Test flaky on Linux. +#if BUILDFLAG(IS_LINUX) +#define MAYBE_PRE_WebRequestAfterRestart DISABLED_PRE_WebRequestAfterRestart +#define MAYBE_WebRequestAfterRestart DISABLED_WebRequestAfterRestart +#else +#define MAYBE_PRE_WebRequestAfterRestart PRE_WebRequestAfterRestart +#define MAYBE_WebRequestAfterRestart DISABLED_WebRequestAfterRestart +#endif + IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, - PRE_WebRequestAfterRestart) { + MAYBE_PRE_WebRequestAfterRestart) { ExtensionTestMessageListener event_added_listener("listener-added", false); base::FilePath extension_path = test_data_dir_.AppendASCII("service_worker") @@ -2474,7 +2483,7 @@ // After browser restarts, this test step ensures that navigating a tab fires // the webRequest listener. IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, - WebRequestAfterRestart) { + MAYBE_WebRequestAfterRestart) { ExtensionTestMessageListener event_added_listener("listener-added", false); EXPECT_TRUE(event_added_listener.WaitUntilSatisfied()); // Navigate and expect the listener in the extension to be triggered.
diff --git a/chrome/browser/login_detection/login_detection_tab_helper.cc b/chrome/browser/login_detection/login_detection_tab_helper.cc index 2a6669f..3de3f25 100644 --- a/chrome/browser/login_detection/login_detection_tab_helper.cc +++ b/chrome/browser/login_detection/login_detection_tab_helper.cc
@@ -13,7 +13,6 @@ #include "chrome/browser/profiles/profile.h" #include "components/prefs/pref_service.h" #include "components/site_isolation/site_isolation_policy.h" -#include "components/ukm/content/source_url_recorder.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/navigation_handle.h" @@ -59,7 +58,8 @@ content::WebContents* web_contents) : content::WebContentsObserver(web_contents), content::WebContentsUserData<LoginDetectionTabHelper>(*web_contents), - oauth_login_detector_(std::make_unique<OAuthLoginDetector>()) { + oauth_login_detector_(std::make_unique<OAuthLoginDetector>()), + ukm_source_id_(web_contents->GetMainFrame()->GetPageUkmSourceId()) { DCHECK(IsLoginDetectionFeatureEnabled()); } @@ -129,12 +129,15 @@ oauth_login_detector_->DidOpenAsPopUp(opener_navigation_url); } +void LoginDetectionTabHelper::PrimaryPageChanged(content::Page& page) { + ukm_source_id_ = page.GetMainDocument().GetPageUkmSourceId(); +} + void LoginDetectionTabHelper::WebContentsDestroyed() { if (auto signedin_site = oauth_login_detector_->GetPopUpLoginFlowSite()) { ProcessNewSignedInSite(*signedin_site); RecordLoginDetectionMetrics( - LoginDetectionType::kOauthPopUpFirstTimeLoginFlow, - ukm::GetSourceIdForWebContentsDocument(web_contents())); + LoginDetectionType::kOauthPopUpFirstTimeLoginFlow, ukm_source_id_); } oauth_login_detector_.reset(); }
diff --git a/chrome/browser/login_detection/login_detection_tab_helper.h b/chrome/browser/login_detection/login_detection_tab_helper.h index c49f2552..5159ba7 100644 --- a/chrome/browser/login_detection/login_detection_tab_helper.h +++ b/chrome/browser/login_detection/login_detection_tab_helper.h
@@ -47,6 +47,7 @@ ui::PageTransition transition, bool started_from_context_menu, bool renderer_initiated) override; + void PrimaryPageChanged(content::Page& page) override; void WebContentsDestroyed() override; // Called when a new signed-in site has just been discovered from one of the @@ -56,6 +57,11 @@ // Detects successful OAuth login flows. std::unique_ptr<OAuthLoginDetector> oauth_login_detector_; + // The UKM source id for the primary page. We may need to log something in + // WebContentsDestroyed and retrieving the UKM source ID then would be too + // late. + ukm::SourceId ukm_source_id_; + WEB_CONTENTS_USER_DATA_KEY_DECL(); };
diff --git a/chrome/browser/net/proxy_config_monitor.cc b/chrome/browser/net/proxy_config_monitor.cc index 88fad98..d05a82a 100644 --- a/chrome/browser/net/proxy_config_monitor.cc +++ b/chrome/browser/net/proxy_config_monitor.cc
@@ -35,10 +35,11 @@ profile_ = profile; #endif -// If this is the ChromeOS sign-in profile, just create the tracker from global -// state. +// If this is the ChromeOS sign-in or lock screen profile, just create the +// tracker from global state. #if BUILDFLAG(IS_CHROMEOS_ASH) - if (ash::ProfileHelper::IsSigninProfile(profile)) { + if (ash::ProfileHelper::IsSigninProfile(profile) || + ash::ProfileHelper::IsLockScreenProfile(profile)) { pref_proxy_config_tracker_ = ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState( g_browser_process->local_state());
diff --git a/chrome/browser/new_tab_page/new_tab_page_browsertest.cc b/chrome/browser/new_tab_page/new_tab_page_browsertest.cc index a696049..a12fb56 100644 --- a/chrome/browser/new_tab_page/new_tab_page_browsertest.cc +++ b/chrome/browser/new_tab_page/new_tab_page_browsertest.cc
@@ -193,7 +193,7 @@ }; // TODO(crbug.com/1250156): NewTabPageTest.LandingPagePixelTest is flaky -#if BUILDFLAG(IS_WIN) +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) #define MAYBE_LandingPagePixelTest DISABLED_LandingPagePixelTest #else #define MAYBE_LandingPagePixelTest LandingPagePixelTest
diff --git a/chrome/browser/policy/messaging_layer/upload/event_upload_size_controller.cc b/chrome/browser/policy/messaging_layer/upload/event_upload_size_controller.cc new file mode 100644 index 0000000..5bb3349 --- /dev/null +++ b/chrome/browser/policy/messaging_layer/upload/event_upload_size_controller.cc
@@ -0,0 +1,52 @@ +// Copyright 2022 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/policy/messaging_layer/upload/event_upload_size_controller.h" + +#include <algorithm> +#include <limits> + +#include "chrome/browser/policy/messaging_layer/upload/network_condition_service.h" +#include "components/reporting/proto/synced/record.pb.h" + +namespace reporting { + +EventUploadSizeController::EventUploadSizeController( + const NetworkConditionService& network_condition_service, + bool enabled) + : enabled_(enabled), + max_upload_size_(ComputeMaxUploadSize(network_condition_service)) {} + +bool EventUploadSizeController::IsMaximumUploadSizeReached() const { + return enabled_ && uploaded_size_ >= max_upload_size_; +} + +void EventUploadSizeController::AccountForRecord( + const EncryptedRecord& record) { + uploaded_size_ += record.ByteSizeLong(); +} + +uint64_t EventUploadSizeController::GetUploadRate( + const NetworkConditionService& network_condition_service) { + return std::min(network_condition_service.GetUploadRate(), + // This is to ensure ComputeMaxUploadSize won't overflow + std::numeric_limits<uint64_t>::max() / kTimeCeiling); +} + +uint64_t EventUploadSizeController::GetNewEventRate() { + return 1UL; +} + +uint64_t EventUploadSizeController::GetRemainingStorageCapacity() { + return std::numeric_limits<uint64_t>::max(); +} + +uint64_t EventUploadSizeController::ComputeMaxUploadSize( + const NetworkConditionService& network_condition_service) { + // Estimated acceptable time that a single connection can remain open. + const uint64_t time_open = + std::min(GetRemainingStorageCapacity() / GetNewEventRate(), kTimeCeiling); + return GetUploadRate(network_condition_service) * time_open - kOverhead; +} +} // namespace reporting
diff --git a/chrome/browser/policy/messaging_layer/upload/event_upload_size_controller.h b/chrome/browser/policy/messaging_layer/upload/event_upload_size_controller.h new file mode 100644 index 0000000..cd7dd9e --- /dev/null +++ b/chrome/browser/policy/messaging_layer/upload/event_upload_size_controller.h
@@ -0,0 +1,73 @@ +// Copyright 2022 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_POLICY_MESSAGING_LAYER_UPLOAD_EVENT_UPLOAD_SIZE_CONTROLLER_H_ +#define CHROME_BROWSER_POLICY_MESSAGING_LAYER_UPLOAD_EVENT_UPLOAD_SIZE_CONTROLLER_H_ + +#include <cstddef> + +#include "base/gtest_prod_util.h" +#include "chrome/browser/policy/messaging_layer/upload/network_condition_service.h" +#include "components/reporting/proto/synced/record.pb.h" + +namespace reporting { + +// Control how large upload size is and whether it is OK to continue uploading +// after a specified set of records has been uploaded. +class EventUploadSizeController { + public: + // |enabled| should always be false in production code. + // TODO(b/214039157): A policy needs to be + // added to control whether to enable this feature. + explicit EventUploadSizeController( + const NetworkConditionService& network_condition_service, + bool enabled = false); + + // Has the set maximum upload size been reached? Always returns false if + // adjustment based on network condition is not enabled. + bool IsMaximumUploadSizeReached() const; + + // Bumps up by the size of the record to be uploaded. + void AccountForRecord(const EncryptedRecord& record); + + private: + friend class EventUploadSizeControllerTest; + FRIEND_TEST_ALL_PREFIXES(EventUploadSizeControllerTest, + AccountForRecordAddUp); + + // The maximum time in seconds during which a single connection should + // remain open, a constant set heuristically. + static constexpr uint64_t kTimeCeiling = 60; + // Size of overheads in each upload in bytes. Heuristically set by a human. + static constexpr uint64_t kOverhead = 32; + + // Estimates upload rate (bytes/sec). + static uint64_t GetUploadRate( + const NetworkConditionService& network_condition_service); + // Estimates the rate at which new events are coming in (bytes/sec). For now, + // use a low new event rate, which means no local storage limit is taken + // into consideration. + static uint64_t GetNewEventRate(); + // Estimates the remaining storage capacity (bytes) here. For now, use a high + // remaining storage capacity, which means no local storage limit is taken + // into consideration. + static uint64_t GetRemainingStorageCapacity(); + // Computes the maximum upload size. + static uint64_t ComputeMaxUploadSize( + const NetworkConditionService& network_condition_service); + + // Bumps up recorded already uploaded size. + void RecordUploadedSize(uint64_t uploaded_size); + + // Is adjustment based on network condition enabled? + const bool enabled_; + // maximum upload size. + const uint64_t max_upload_size_; + // Already uploaded size. + uint64_t uploaded_size_ = 0; +}; + +} // namespace reporting + +#endif // CHROME_BROWSER_POLICY_MESSAGING_LAYER_UPLOAD_EVENT_UPLOAD_SIZE_CONTROLLER_H_
diff --git a/chrome/browser/policy/messaging_layer/upload/event_upload_size_controller_unittest.cc b/chrome/browser/policy/messaging_layer/upload/event_upload_size_controller_unittest.cc new file mode 100644 index 0000000..9258c51 --- /dev/null +++ b/chrome/browser/policy/messaging_layer/upload/event_upload_size_controller_unittest.cc
@@ -0,0 +1,70 @@ +// Copyright 2022 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 <cstddef> +#include <string> + +#include "chrome/browser/policy/messaging_layer/upload/event_upload_size_controller.h" +#include "chrome/browser/policy/messaging_layer/upload/testing_network_condition_service.h" +#include "components/reporting/proto/synced/record.pb.h" +#include "content/public/test/browser_task_environment.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace reporting { + +// Testing |EventUploadSizeController|. Since a big portion of the class is +// simply applying a formula, there is no reason to repeat the formula here. +// This test focuses on the dynamic elements (such as |AccountForRecord|). +class EventUploadSizeControllerTest : public ::testing::Test { + protected: + // Needed by NetworkConditionService. + content::BrowserTaskEnvironment task_environment_; +}; + +TEST_F(EventUploadSizeControllerTest, AccountForRecordAddUp) { + TestingNetworkConditionService network_condition_service(&task_environment_); + network_condition_service.SetUploadRate(10000); + EventUploadSizeController event_upload_size_controller( + network_condition_service, /*enabled=*/true); + // This number may change from time to time if we adapt the formula in the + // future. + const uint64_t max_upload_size = + EventUploadSizeController::ComputeMaxUploadSize( + network_condition_service); + LOG(INFO) << "The computed max upload size is " << max_upload_size; + + EncryptedRecord record; + record.set_encrypted_wrapped_record(std::string(100, 'A')); + const auto record_size = record.ByteSizeLong(); + // Maximum number of records of size of "record" before + // |IsMaximumUploadSizeReached| returns true: + // |IsMaximumUploadSizeReached| return false if < max_num_of_records + // |records are accounted for. + // Otherwise, |IsMaximumUploadSizeReached| returns true. + const uint64_t max_num_of_records = + max_upload_size / record_size + (max_upload_size % record_size != 0); + // A sanity check. Because the formula may change from time to time, the + // following is satisfied for the thoroughness of this test. + ASSERT_GE(max_num_of_records, 2U) + << "The test is tuned to only allow less than 2 records before the " + "maximum upload size is reached. However, the parameter must be set " + "so that the maximum upload size is reached after no less than 2 " + "records is uploaded for the throughness of this test."; + // Add each record at a time, make sure |IsMaximumUploadSizeReached| gives the + // correct answer. + for (uint64_t i = 0; i < max_num_of_records; ++i) { + ASSERT_FALSE(event_upload_size_controller.IsMaximumUploadSizeReached()) + << "The maximum upload size is reached when " << i + << " records of size " << record_size + << " have been accounted for, less than " << max_num_of_records + << " records."; + event_upload_size_controller.AccountForRecord(record); + } + ASSERT_TRUE(event_upload_size_controller.IsMaximumUploadSizeReached()) + << "The maximum upload size is not reached when " << max_num_of_records + << " records of size " << record_size << " have been accounted for."; +} + +} // namespace reporting
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/injected/api_implementation.js b/chrome/browser/resources/chromeos/accessibility/chromevox/injected/api_implementation.js index cc42da7..dd61d52b 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/injected/api_implementation.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/injected/api_implementation.js
@@ -9,7 +9,6 @@ goog.provide('ApiImplementation'); -goog.require('ChromeVox'); goog.require('ContentExtensionBridge'); goog.require('ScriptInstaller');
diff --git a/chrome/browser/resources/chromeos/password_change/lock_screen_reauth.js b/chrome/browser/resources/chromeos/password_change/lock_screen_reauth.js index ec9c33a..31d3bde 100644 --- a/chrome/browser/resources/chromeos/password_change/lock_screen_reauth.js +++ b/chrome/browser/resources/chromeos/password_change/lock_screen_reauth.js
@@ -206,6 +206,15 @@ }, /** + * Reloads the page. + */ + reloadAuthenticator() { + this.signinFrame_.clearData({since: 0}, clearDataType, () => { + this.authenticator_.resetStates(); + }); + }, + + /** * @return {!Element} * @private */
diff --git a/chrome/browser/resources/new_tab_page/app.ts b/chrome/browser/resources/new_tab_page/app.ts index d3096a5..d9101f0 100644 --- a/chrome/browser/resources/new_tab_page/app.ts +++ b/chrome/browser/resources/new_tab_page/app.ts
@@ -291,9 +291,6 @@ private backgroundImageLoadStartEpoch_: number; private backgroundImageLoadStart_: number = 0; - // Suppress TypeScript's error TS2376 to intentionally allow calling - // performance.mark() before calling super(). - // @ts-ignore:next-line constructor() { performance.mark('app-creation-start'); super();
diff --git a/chrome/browser/resources/new_tab_page/logo.ts b/chrome/browser/resources/new_tab_page/logo.ts index 193ca84..e101d2e 100644 --- a/chrome/browser/resources/new_tab_page/logo.ts +++ b/chrome/browser/resources/new_tab_page/logo.ts
@@ -156,9 +156,6 @@ private interactionLogUrl_: Url|null = null; private shareId_: string|null = null; - // Suppress TypeScript's error TS2376 to intentionally allow calling - // performance.mark() before calling super(). - // @ts-ignore:next-line constructor() { performance.mark('logo-creation-start'); super();
diff --git a/chrome/browser/resources/new_tab_page/realbox/realbox.ts b/chrome/browser/resources/new_tab_page/realbox/realbox.ts index ce191bc..135d937 100644 --- a/chrome/browser/resources/new_tab_page/realbox/realbox.ts +++ b/chrome/browser/resources/new_tab_page/realbox/realbox.ts
@@ -202,9 +202,6 @@ private autocompleteResultChangedListenerId_: number|null = null; private autocompleteMatchImageAvailableListenerId_: number|null = null; - // Suppress TypeScript's error TS2376 to intentionally allow calling - // performance.mark() before calling super(). - // @ts-ignore:next-line constructor() { performance.mark('realbox-creation-start'); super();
diff --git a/chrome/browser/resources/settings/chromeos/BUILD.gn b/chrome/browser/resources/settings/chromeos/BUILD.gn index 3bddadee..7060d35 100644 --- a/chrome/browser/resources/settings/chromeos/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/BUILD.gn
@@ -525,6 +525,7 @@ "chromeos/os_a11y_page/switch_access_subpage.js", "chromeos/os_a11y_page/tts_subpage.js", "chromeos/os_about_page/channel_switcher_dialog.js", + "chromeos/os_about_page/consumer_auto_update_toggle_dialog.js", "chromeos/os_about_page/detailed_build_info.js", "chromeos/os_about_page/edit_hostname_dialog.js", "chromeos/os_about_page/os_about_page.js",
diff --git a/chrome/browser/resources/settings/chromeos/os_about_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_about_page/BUILD.gn index d250f59..4dfb886 100644 --- a/chrome/browser/resources/settings/chromeos/os_about_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/os_about_page/BUILD.gn
@@ -7,6 +7,7 @@ import("../os_settings.gni") polymer_element_files = [ + "consumer_auto_update_toggle_dialog.js", "channel_switcher_dialog.js", "detailed_build_info.js", "edit_hostname_dialog.js", @@ -20,6 +21,7 @@ deps = [ ":about_page_browser_proxy", ":channel_switcher_dialog", + ":consumer_auto_update_toggle_dialog", ":detailed_build_info", ":device_name_browser_proxy", ":device_name_util", @@ -42,14 +44,22 @@ ] } +js_library("consumer_auto_update_toggle_dialog") { + deps = [ + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + ] +} + js_library("detailed_build_info") { deps = [ ":about_page_browser_proxy", ":channel_switcher_dialog", + ":consumer_auto_update_toggle_dialog", ":device_name_util", ":edit_hostname_dialog", "..:deep_linking_behavior", "..:os_route", + "..:prefs_behavior", "..:route_observer_behavior", "../..:router", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
diff --git a/chrome/browser/resources/settings/chromeos/os_about_page/about_page_browser_proxy.js b/chrome/browser/resources/settings/chromeos/os_about_page/about_page_browser_proxy.js index 236e6e7f..e8d3869 100644 --- a/chrome/browser/resources/settings/chromeos/os_about_page/about_page_browser_proxy.js +++ b/chrome/browser/resources/settings/chromeos/os_about_page/about_page_browser_proxy.js
@@ -233,6 +233,17 @@ * @return {!Promise<boolean>} */ checkInternetConnection() {} + + /** @return {!Promise<boolean>} */ + isManagedAutoUpdateEnabled() {} + + /** @return {!Promise<boolean>} */ + isConsumerAutoUpdateEnabled() {} + + /** + * @param {boolean} enable + */ + setConsumerAutoUpdate(enable) {} } /** @@ -327,6 +338,21 @@ chrome.send('refreshTPMFirmwareUpdateStatus'); } + /** @override */ + isManagedAutoUpdateEnabled() { + return sendWithPromise('isManagedAutoUpdateEnabled'); + } + + /** @override */ + isConsumerAutoUpdateEnabled() { + return sendWithPromise('isConsumerAutoUpdateEnabled'); + } + + /** @override */ + setConsumerAutoUpdate(enable) { + chrome.send('setConsumerAutoUpdate', [enable]); + } + /** @return {!AboutPageBrowserProxy} */ static getInstance() { return instance || (instance = new AboutPageBrowserProxyImpl());
diff --git a/chrome/browser/resources/settings/chromeos/os_about_page/consumer_auto_update_toggle_dialog.html b/chrome/browser/resources/settings/chromeos/os_about_page/consumer_auto_update_toggle_dialog.html new file mode 100644 index 0000000..46c3c3cd3 --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/os_about_page/consumer_auto_update_toggle_dialog.html
@@ -0,0 +1,23 @@ +<style include="settings-shared"> + #warningSelector > :not(.iron-selected) { + display: none; + } +</style> +<cr-dialog id="dialog" close-text="$i18n{close}"> + <div slot="title">$i18n{aboutConsumerAutoUpdateToggleDialogTitle}</div> + <div slot="body">$i18n{aboutConsumerAutoUpdateToggleDialogDescription}</div> + <div slot="button-container"> + <cr-button + id="turnOffButton" + class="cancel-button" + on-click="onTurnOffTap_"> + $i18n{aboutConsumerAutoUpdateToggleTurnOffButton} + </cr-button> + <cr-button + id="keepUpdatesButton" + class="action-button" + on-click="onKeepUpdatesTap_"> + $i18n{aboutConsumerAutoUpdateToggleKeepUpdatesButton} + </cr-button> + </div> +</cr-dialog>
diff --git a/chrome/browser/resources/settings/chromeos/os_about_page/consumer_auto_update_toggle_dialog.js b/chrome/browser/resources/settings/chromeos/os_about_page/consumer_auto_update_toggle_dialog.js new file mode 100644 index 0000000..fd7f5d1 --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/os_about_page/consumer_auto_update_toggle_dialog.js
@@ -0,0 +1,57 @@ +// Copyright 2022 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 '//resources/cr_elements/cr_dialog/cr_dialog.m.js'; + +import {html, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +/** @polymer */ +class SettingsConsumerAutoUpdateToggleDialogElement extends PolymerElement { + static get is() { + return 'settings-consumer-auto-update-toggle-dialog'; + } + + static get template() { + return html`{__html_template__}`; + } + + constructor() { + super(); + } + + /** @override */ + connectedCallback() { + super.connectedCallback(); + + this.$.dialog.showModal(); + } + + /** @private */ + onTurnOffTap_() { + this.dispatchEvent(new CustomEvent('set-consumer-auto-update', { + bubbles: true, + composed: true, + detail: { + item: false, + }, + })); + this.$.dialog.close(); + } + + /** @private */ + onKeepUpdatesTap_() { + this.dispatchEvent(new CustomEvent('set-consumer-auto-update', { + bubbles: true, + composed: true, + detail: { + item: true, + }, + })); + this.$.dialog.close(); + } +} + +customElements.define( + SettingsConsumerAutoUpdateToggleDialogElement.is, + SettingsConsumerAutoUpdateToggleDialogElement);
diff --git a/chrome/browser/resources/settings/chromeos/os_about_page/detailed_build_info.html b/chrome/browser/resources/settings/chromeos/os_about_page/detailed_build_info.html index 3730ba4..c7ff0d22 100644 --- a/chrome/browser/resources/settings/chromeos/os_about_page/detailed_build_info.html +++ b/chrome/browser/resources/settings/chromeos/os_about_page/detailed_build_info.html
@@ -70,8 +70,35 @@ icon-aria-label="$i18n{aboutManagedEndOfLifeSubtitle}" tooltip-position="bottom"> </cr-tooltip-icon> + <cr-toggle + id="managedAutoUpdateToggle" + checked="[[isManagedAutoUpdateEnabled_]]" + disabled> + </cr-toggle> </div> </template> +<template is="dom-if" if="[[!isManaged_]]"> + <div class="settings-box two-line" + on-click="onConsumerAutoUpdateToggledSettingsBox_"> + <div class="start" aria-hidden="true"> + <div role="heading">$i18n{aboutConsumerAutoUpdateToggleTitle}</div> + <div class="secondary"> + $i18n{aboutConsumerAutoUpdateToggleDescription} + </div> + </div> + <cr-toggle + id="consumerAutoUpdateToggle" + checked="{{prefs.settings.consumer_auto_update_toggle.value}}" + disabled="[[!isConsumerAutoUpdateTogglingAllowed_]]" + on-change="onConsumerAutoUpdateToggled_"> + </cr-toggle> + </div> + <template is="dom-if" if="[[showConsumerAutoUpdateToggleDialog_]]" restamp> + <settings-consumer-auto-update-toggle-dialog + on-close="onConsumerAutoUpdateToggleDialogClosed_"> + </settings-consumer-auto-update-toggle-dialog> + </template> +</template> <template is="dom-if" if="[[isHostnameSettingEnabled_]]"> <div class="settings-box two-line"> <div class="start">
diff --git a/chrome/browser/resources/settings/chromeos/os_about_page/detailed_build_info.js b/chrome/browser/resources/settings/chromeos/os_about_page/detailed_build_info.js index f7edb2f..8bf555f 100644 --- a/chrome/browser/resources/settings/chromeos/os_about_page/detailed_build_info.js +++ b/chrome/browser/resources/settings/chromeos/os_about_page/detailed_build_info.js
@@ -10,9 +10,11 @@ import '//resources/cr_elements/cr_button/cr_button.m.js'; import '//resources/cr_elements/policy/cr_policy_indicator.m.js'; import '//resources/cr_elements/policy/cr_tooltip_icon.m.js'; +import '../../prefs/prefs.js'; import '../../settings_shared_css.js'; import '//resources/cr_components/localized_link/localized_link.js'; import './channel_switcher_dialog.js'; +import './consumer_auto_update_toggle_dialog.js'; import './edit_hostname_dialog.js'; import {CrPolicyIndicatorType} from '//resources/cr_elements/policy/cr_policy_indicator_behavior.m.js'; @@ -26,6 +28,7 @@ import {Route} from '../../router.js'; import {DeepLinkingBehavior, DeepLinkingBehaviorInterface} from '../deep_linking_behavior.js'; import {routes} from '../os_route.js'; +import {PrefsBehavior, PrefsBehaviorInterface} from '../prefs_behavior.js'; import {RouteObserverBehavior} from '../route_observer_behavior.js'; import {AboutPageBrowserProxy, AboutPageBrowserProxyImpl, browserChannelToI18nId, ChannelInfo, VersionInfo} from './about_page_browser_proxy.js'; @@ -38,12 +41,14 @@ * @implements {I18nBehaviorInterface} * @implements {WebUIListenerBehaviorInterface} * @implements {DeepLinkingBehaviorInterface} + * @implements {PrefsBehaviorInterface} */ const SettingsDetailedBuildInfoBase = mixinBehaviors( [ DeepLinkingBehavior, WebUIListenerBehavior, I18nBehavior, + PrefsBehavior, RouteObserverBehavior, ], PolymerElement); @@ -60,6 +65,12 @@ static get properties() { return { + /** Preferences state. */ + prefs: { + type: Object, + notify: true, + }, + /** @private {!VersionInfo} */ versionInfo_: Object, @@ -81,6 +92,12 @@ /** @private */ canChangeChannel_: Boolean, + /** @private */ + isManagedAutoUpdateEnabled_: Boolean, + + /** @private */ + showConsumerAutoUpdateToggleDialog_: Boolean, + eolMessageWithMonthAndYear: { type: String, value: '', @@ -126,6 +143,18 @@ }, readOnly: true, }, + + /** + * Whether or not the consumer auto update toggling is allowed. + * @private + */ + isConsumerAutoUpdateTogglingAllowed_: { + type: Boolean, + value() { + return loadTimeData.getBoolean('isConsumerAutoUpdateTogglingAllowed'); + }, + readOnly: true, + }, }; } @@ -144,6 +173,20 @@ super.ready(); this.aboutPageBrowserProxy_.pageReady(); + this.addEventListener('set-consumer-auto-update', e => { + this.aboutPageBrowserProxy_.setConsumerAutoUpdate(e.detail.item); + }); + + if (this.isManaged_) { + this.syncManagedAutoUpdateToggle_(); + } else { + // This is to keep the Chrome pref in sync in case it becomes stale. + // For example, if users toggle the consumer auto update, but the settings + // page happened to crash/close before it got flushed out this would + // assure a sync between the Chrome pref and the platform pref. + this.syncConsumerAutoUpdateToggle_(); + } + this.aboutPageBrowserProxy_.getVersionInfo().then(versionInfo => { this.versionInfo_ = versionInfo; }); @@ -198,6 +241,21 @@ }); } + /** @private */ + syncManagedAutoUpdateToggle_() { + this.aboutPageBrowserProxy_.isManagedAutoUpdateEnabled().then( + isManagedAutoUpdateEnabled => { + this.isManagedAutoUpdateEnabled_ = isManagedAutoUpdateEnabled; + }); + } + + /** @private */ + syncConsumerAutoUpdateToggle_() { + this.aboutPageBrowserProxy_.isConsumerAutoUpdateEnabled().then(enabled => { + this.aboutPageBrowserProxy_.setConsumerAutoUpdate(enabled); + }); + } + /** * @param {!DeviceNameMetadata} data * @private @@ -253,6 +311,14 @@ } /** + * @return {boolean} + * @private + */ + shouldShowConsumerAutoUpdateToggle_() { + return !this.isManaged_; + } + + /** * @return {string} * @private */ @@ -356,6 +422,45 @@ * @param {!Event} e * @private */ + onConsumerAutoUpdateToggled_(e) { + if (!this.isConsumerAutoUpdateTogglingAllowed_) { + return; + } + this.showDialogOrFlushConsumerAutoUpdateToggle(); + } + + /** @private */ + onConsumerAutoUpdateToggledSettingsBox_() { + if (!this.isConsumerAutoUpdateTogglingAllowed_) { + return; + } + // Copy how cr-toggle negates the `checked` field. + this.setPrefValue( + 'settings.consumer_auto_update_toggle', + !this.getPref('settings.consumer_auto_update_toggle').value); + this.showDialogOrFlushConsumerAutoUpdateToggle(); + } + + /** @private */ + showDialogOrFlushConsumerAutoUpdateToggle() { + if (!this.getPref('settings.consumer_auto_update_toggle').value) { + // Only show dialog when turning the toggle off. + this.showConsumerAutoUpdateToggleDialog_ = true; + return; + } + // Turning the toggle on requires no dialog. + this.aboutPageBrowserProxy_.setConsumerAutoUpdate(true); + } + + /** @private */ + onConsumerAutoUpdateToggleDialogClosed_() { + this.showConsumerAutoUpdateToggleDialog_ = false; + } + + /** + * @param {!Event} e + * @private + */ onVisitBuildDetailsPageTap_(e) { e.preventDefault(); window.open('chrome://version');
diff --git a/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.html b/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.html index aacaf49..b4fe552 100644 --- a/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.html +++ b/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.html
@@ -185,7 +185,8 @@ <settings-subpage page-title="$i18n{aboutDetailedBuildInfo}"> <settings-detailed-build-info eol-message-with-month-and-year= - "[[eolMessageWithMonthAndYear_]]"> + "[[eolMessageWithMonthAndYear_]]" + prefs="{{prefs}}"> </settings-detailed-build-info> </settings-subpage> </template>
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_search_box/os_search_result_row.js b/chrome/browser/resources/settings/chromeos/os_settings_search_box/os_search_result_row.js index ed28fed..af22c64 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings_search_box/os_search_result_row.js +++ b/chrome/browser/resources/settings/chromeos/os_settings_search_box/os_search_result_row.js
@@ -194,7 +194,7 @@ computeResultText_() { // The C++ layer stores the text result as an array of 16 bit char codes, // so it must be converted to a JS String. - return String.fromCharCode.apply(null, this.searchResult.resultText.data); + return String.fromCharCode.apply(null, this.searchResult.text.data); }, /**
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_search_box/os_settings_search_box.js b/chrome/browser/resources/settings/chromeos/os_settings_search_box/os_settings_search_box.js index 9d13777..1f82ced 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings_search_box/os_settings_search_box.js +++ b/chrome/browser/resources/settings/chromeos/os_settings_search_box/os_settings_search_box.js
@@ -213,9 +213,9 @@ }, /** - * Overrides chromeos.settings.mojom.SearchResultsObserverInterfaces + * Overrides chromeos.settings.mojom.SearchResultsObserverInterface */ - onSearchResultAvailabilityChanged() { + onSearchResultsChanged() { this.fetchSearchResults_(); },
diff --git a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/shared_css.html b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/shared_css.html index 1a6aa2b..73c67436 100644 --- a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/shared_css.html +++ b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/shared_css.html
@@ -45,7 +45,7 @@ --cr-icon-button-margin-start: 4px; --cr-icon-button-size: 36px; margin-inline-start: 16px; - margin-top: 0; + margin-top: 4px; position: relative; z-index: 1; }
diff --git a/chrome/browser/share/BUILD.gn b/chrome/browser/share/BUILD.gn index c9c8f5f..7dd8e30 100644 --- a/chrome/browser/share/BUILD.gn +++ b/chrome/browser/share/BUILD.gn
@@ -35,6 +35,7 @@ if (is_android) { sources += [ "bitmap_download_request.cc", + "crow_bridge.cc", "default_ranking_android.cc", "editor_screenshot_task.cc", "link_to_text_bridge.cc", @@ -44,6 +45,7 @@ deps += [ ":jni_headers", "//chrome/browser/share/android:jni_headers", + "//components/history/core/browser:browser", "//components/ukm/content:content", "//ui/android", "//url:gurl_android",
diff --git a/chrome/browser/share/android/BUILD.gn b/chrome/browser/share/android/BUILD.gn index 4b4590d..01d4c30 100644 --- a/chrome/browser/share/android/BUILD.gn +++ b/chrome/browser/share/android/BUILD.gn
@@ -39,6 +39,7 @@ generate_jni("jni_headers") { sources = [ "java/src/org/chromium/chrome/browser/share/BitmapDownloadRequest.java", + "java/src/org/chromium/chrome/browser/share/crow/CrowBridge.java", "java/src/org/chromium/chrome/browser/share/link_to_text/LinkToTextBridge.java", "java/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/LongScreenshotsTabService.java", "java/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/LongScreenshotsTabServiceFactory.java", @@ -47,8 +48,6 @@ "java/src/org/chromium/chrome/browser/share/send_tab_to_self/MetricsRecorder.java", "java/src/org/chromium/chrome/browser/share/send_tab_to_self/NotificationManager.java", "java/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfAndroidBridge.java", - "java/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfEntry.java", - "java/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfModelObserverBridge.java", "java/src/org/chromium/chrome/browser/share/send_tab_to_self/TargetDeviceInfo.java", ] }
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/crow/CrowBridge.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/crow/CrowBridge.java new file mode 100644 index 0000000..b835269 --- /dev/null +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/crow/CrowBridge.java
@@ -0,0 +1,44 @@ +// Copyright 2022 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.share.crow; + +import org.chromium.base.Callback; +import org.chromium.base.annotations.NativeMethods; +import org.chromium.url.GURL; + +/** + * Class providing access to functionality provided by the Crow native component. + */ +class CrowBridge { + /** Container for past visit counts. */ + static class VisitCounts { + /** The total number of visits. */ + public final int visits; + /** The number of per day boolean visits (days when at least one visit happened) */ + public final int dailyVisits; + + VisitCounts(int visits, int dailyVisits) { + this.visits = visits; + this.dailyVisits = dailyVisits; + } + } + + /** + * Obtains visit information for a website within a limited number of days in the past. + * @param url The URL for which the host will be queried for past visits. + * @param numDays The number of days to look back on. + * @param callback The callback to receive the past visits query results. + * Upon failure, VisitCounts is populated with 0 visits. + */ + static void getVisitCountsToHost(GURL url, int numDays, Callback<VisitCounts> callback) { + CrowBridgeJni.get().getRecentVisitCountsToHost( + url, numDays, (result) -> callback.onResult(new VisitCounts(result[0], result[1]))); + } + + @NativeMethods + interface Natives { + void getRecentVisitCountsToHost(GURL url, int numDays, Callback<int[]> callback); + } +}
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/crow/CrowIphController.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/crow/CrowIphController.java index 7377381b..baf8c65 100644 --- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/crow/CrowIphController.java +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/crow/CrowIphController.java
@@ -10,6 +10,7 @@ import org.chromium.base.supplier.ObservableSupplier; import org.chromium.chrome.R; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.tab.CurrentTabObserver; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; @@ -23,6 +24,11 @@ * Controls when the the Share Experiment IPH is shown. */ public class CrowIphController { + // TODO(crbug/1314455): Adjust these numbers. + private static final int MIN_DAYS = 1; + private static final int MIN_VISITS = 1; + private static final int NUM_HISTORY_DAYS = 7; + private final Activity mActivity; private final AppMenuHandler mAppMenuHandler; private final CurrentTabObserver mPageLoadObserver; @@ -47,10 +53,10 @@ mPageLoadObserver = new CurrentTabObserver(tabSupplier, new EmptyTabObserver() { @Override public void onPageLoadFinished(Tab tab, GURL url) { - if (tab.isShowingErrorPage() || !shouldShowCrowIph()) { + if (tab.isShowingErrorPage()) { return; } - showCrowIph(); + maybeShowCrowIph(tab.getUrl()); } }); } @@ -59,12 +65,19 @@ mPageLoadObserver.destroy(); } - private boolean shouldShowCrowIph() { - // TODO(crbug/1314455): Implement this. - return false; + private void maybeShowCrowIph(GURL url) { + // TODO(crbug/1314455): Finish implementing heuristics for showing the IPH. + if (!ChromeFeatureList.isEnabled(ChromeFeatureList.SHARE_CROW_BUTTON)) { + return; + } + CrowBridge.getVisitCountsToHost(url, NUM_HISTORY_DAYS, result -> { + if (result.dailyVisits >= MIN_DAYS && result.visits >= MIN_VISITS) { + requestShowCrowIph(); + } + }); } - private void showCrowIph() { + private void requestShowCrowIph() { mUserEducationHelper.requestShowIPH( new IPHCommandBuilder(mActivity.getResources(), FeatureConstants.CROW_FEATURE, // TODO(crbug/1314530): Fix IPH strings once they are finalized.
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfAndroidBridge.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfAndroidBridge.java index 07be7d3..f085043 100644 --- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfAndroidBridge.java +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfAndroidBridge.java
@@ -4,8 +4,6 @@ package org.chromium.chrome.browser.share.send_tab_to_self; -import androidx.annotation.Nullable; - import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.NativeMethods; @@ -66,8 +64,8 @@ * @param navigationTime Time the user navigated to the page * @return If the persistent entry in the bridge was created. */ - public static SendTabToSelfEntry addEntry(Profile profile, String url, String title, - long navigationTime, String targetDeviceSyncCacheGuid) { + public static boolean addEntry(Profile profile, String url, String title, long navigationTime, + String targetDeviceSyncCacheGuid) { // TODO(https://crbug.com/942549): Add this assertion back in once the code to load is in // place. assert mIsNativeSendTabToSelfModelLoaded; return SendTabToSelfAndroidBridgeJni.get().addEntry( @@ -75,20 +73,6 @@ } /** - * Return the entry associated with a particular GUID - * - * @param profile Profile of the user to get entry for. - * @param guid The GUID to retrieve the entry for - * @return The found entry or null if none exists - */ - @Nullable - public static SendTabToSelfEntry getEntryByGUID(Profile profile, String guid) { - // TODO(https://crbug.com/942549): Add this assertion back in once the code to load is in - // place. assert mIsNativeSendTabToSelfModelLoaded; - return SendTabToSelfAndroidBridgeJni.get().getEntryByGUID(profile, guid); - } - - /** * Deletes the entry associated with the GUID. * * @param profile Profile of the user to delete entry for. @@ -162,7 +146,7 @@ @NativeMethods public interface Natives { - SendTabToSelfEntry addEntry(Profile profile, String url, String title, long navigationTime, + boolean addEntry(Profile profile, String url, String title, long navigationTime, String targetDeviceSyncCacheGuid); void getAllGuids(Profile profile, List<String> guids); @@ -175,8 +159,6 @@ void markEntryOpened(Profile profile, String guid); - SendTabToSelfEntry getEntryByGUID(Profile profile, String guid); - boolean isFeatureAvailable(WebContents webContents); void getAllTargetDeviceInfos(Profile profile, List<TargetDeviceInfo> guids);
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfEntry.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfEntry.java deleted file mode 100644 index 286788c..0000000 --- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfEntry.java +++ /dev/null
@@ -1,49 +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. - -package org.chromium.chrome.browser.share.send_tab_to_self; - -import org.chromium.base.annotations.CalledByNative; - -/** - * SendTabToSelfEntry mirrors the native struct send_tab_to_self::SendTabToSelfEntry declared in - * //components/send_tab_to_self/send_tab_to_self_entry.h. This provides useful getters and methods - * called by native code. - */ -public class SendTabToSelfEntry { - /** The unique random id for the entry. */ - public final String guid; - /** The mUrl of the page the user would like to send to themselves. */ - public final String url; - /** The mTitle of the entry. Might be empty. */ - public final String title; - /** The name of the device that originated the sent tab. */ - public final String deviceName; - /** The time that the tab was shared. */ - public final long sharedTime; - /** The time that the tab was navigated to. */ - public final long originalNavigationTime; - /** The cache guid of the target device. */ - public final String targetDeviceSyncCacheGuid; - - public SendTabToSelfEntry(String guid, String url, String title, long sharedTime, - long originalNavigationTime, String deviceName, String targetDeviceSyncCacheGuid) { - this.guid = guid; - this.url = url; - this.title = title; - this.sharedTime = sharedTime; - this.originalNavigationTime = originalNavigationTime; - this.deviceName = deviceName; - this.targetDeviceSyncCacheGuid = targetDeviceSyncCacheGuid; - } - - /** Used by native code in order to create a new object of this type. */ - @CalledByNative - private static SendTabToSelfEntry createSendTabToSelfEntry(String mGuid, String mUrl, - String mTitle, long mSharedTime, long mOriginalNavigationTime, String mDeviceName, - String targetDeviceSyncCacheGuid) { - return new SendTabToSelfEntry(mGuid, mUrl, mTitle, mSharedTime, mOriginalNavigationTime, - mDeviceName, targetDeviceSyncCacheGuid); - } -}
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfModelObserverBridge.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfModelObserverBridge.java deleted file mode 100644 index 4e315b3..0000000 --- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfModelObserverBridge.java +++ /dev/null
@@ -1,158 +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. - -package org.chromium.chrome.browser.share.send_tab_to_self; - -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.chrome.browser.profiles.Profile; - -import java.util.ArrayList; -import java.util.List; - -/** - * Bridge to interface with send_tab_to_self_model_observer_bridge which interacts with the - * corresponding model observer. This is used by the SendTabToSelfInfobarController to listen - * for model changes and show an infobar to the user. - */ -@JNINamespace("send_tab_to_self") -public class SendTabToSelfModelObserverBridge { - private long mNativeModelObserverBridge; - - private final List<SendTabToSelfObserver> mObservers; - - /** - * Java version of the observer that implementors can use to listen for model changes. - */ - public abstract class SendTabToSelfObserver { - /** - * Corresponds to the EntriesAddedRemotely function in SendTabToSelfModelObserver. - * @param entries Entries removed remotely. - */ - public abstract void entriesAddedRemotely(List<SendTabToSelfEntry> entries); - - /** - * Corresponds to the EntriesRemovedRemotely function in SendTabToSelfModelObserver. - * @param guids Guids of the entries that were removed. - */ - public abstract void entriesRemovedRemotely(List<String> guids); - - /** - * Corresponds to the ModelLoaded function in SendTabToSelfModelObserver. - * @return whether the model is loaded or not. - */ - public abstract boolean modelLoaded(); - } - - /** - * Constructs a new bridge for the profile provided. - * @param profile Profile to construct the bridge for. - */ - public SendTabToSelfModelObserverBridge(Profile profile) { - Natives jni = SendTabToSelfModelObserverBridgeJni.get(); - mNativeModelObserverBridge = jni.init(this, profile); - mObservers = new ArrayList<SendTabToSelfObserver>(); - } - - /** Destroys this instance so no further calls can be executed. */ - public void destroy() { - if (mNativeModelObserverBridge != 0) { - Natives jni = SendTabToSelfModelObserverBridgeJni.get(); - jni.destroy(mNativeModelObserverBridge); - mNativeModelObserverBridge = 0; - } - } - - /** - * Adds an observer to listen for model changes. - * @param observer Observer to listen for model changes. - */ - public void addObserver(SendTabToSelfObserver observer) { - mObservers.add(observer); - } - - /** - * Removes an observer to no longer listen for model changes. - * @param observer Observer to remove. - */ - public void removeObserver(SendTabToSelfObserver observer) { - mObservers.remove(observer); - } - - /** - * @return An empty array list to be populated by native code with SendTabToSelfEntries. - */ - @CalledByNative - private List<SendTabToSelfEntry> createEmptyJavaEntryList() { - return new ArrayList<SendTabToSelfEntry>(); - } - - /** - * Adds an entry to the list of entries. Called by native code. - * @param entries List to add to. - * @param entry Entry to add to the list. - */ - @CalledByNative - private void addToEntryList(List<SendTabToSelfEntry> entries, SendTabToSelfEntry entry) { - entries.add(entry); - } - - /** - * @return An empty array list to be populated by native code with Guids (strings). - */ - @CalledByNative - private List<String> createEmptyJavaGuidList() { - return new ArrayList<String>(); - } - - /** - * Adds a guid to the list of Guids. Called by native code. - * @param guids List to add to. - * @param guid Guid to add to the list. - */ - @CalledByNative - private void addToGuidList(List<String> guids, String guid) { - guids.add(guid); - } - - /** - * Called by native code in send_tab_to_self_model_observer when the model has a new entry. - * @param newEntries The new entries pushed by the model. - */ - @CalledByNative - private void entriesAddedRemotely(List<SendTabToSelfEntry> newEntries) { - for (SendTabToSelfObserver observer : mObservers) { - observer.entriesAddedRemotely(newEntries); - } - } - - /** - * Called by the native code in send_tab_to_self_model_observer when the model has a deletion - * update. - * @param guids Guids corresponding to the entries that were removed. - */ - @CalledByNative - private void entriesRemovedRemotely(List<String> guids) { - for (SendTabToSelfObserver observer : mObservers) { - observer.entriesRemovedRemotely(guids); - } - } - /** - * Called by the native code in send_tab_to_self_model_observer when the model is loaded. - */ - @CalledByNative - private void modelLoaded() { - for (SendTabToSelfObserver observer : mObservers) { - observer.modelLoaded(); - } - } - - @NativeMethods - interface Natives { - long init(SendTabToSelfModelObserverBridge bridge, Profile profile); - - void destroy(long nativeSendTabToSelfModelObserverBridge); - } -}
diff --git a/chrome/browser/share/android/java_sources.gni b/chrome/browser/share/android/java_sources.gni index 302fabbc1..8a0a94f6 100644 --- a/chrome/browser/share/android/java_sources.gni +++ b/chrome/browser/share/android/java_sources.gni
@@ -8,6 +8,7 @@ "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/BaseScreenshotCoordinator.java", "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/BitmapDownloadRequest.java", "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/SaveBitmapDelegate.java", + "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/crow/CrowBridge.java", "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/crow/CrowIphController.java", "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/link_to_text/LinkToTextBridge.java", "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/link_to_text/LinkToTextCoordinator.java", @@ -68,8 +69,6 @@ "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/NotificationSharedPrefManager.java", "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfAndroidBridge.java", "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfCoordinator.java", - "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfEntry.java", - "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfModelObserverBridge.java", "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/TargetDeviceInfo.java", "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java", "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetBottomSheetContent.java",
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfAndroidBridgeTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfAndroidBridgeTest.java index 537c5af..2119c9e 100644 --- a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfAndroidBridgeTest.java +++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfAndroidBridgeTest.java
@@ -6,7 +6,6 @@ import static org.mockito.AdditionalAnswers.answerVoid; import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.verify; @@ -120,26 +119,6 @@ @Test @SmallTest - public void testGetEntryByGUID() { - SendTabToSelfEntry expected = new SendTabToSelfEntry(GUID, URL, TITLE, SHARE_TIME_MS, - NAVIGATION_TIME_MS, DEVICE_NAME, TARGET_DEVICE_SYNC_CACHE_GUID); - when(mNativeMock.getEntryByGUID(eq(mProfile), anyString())).thenReturn(expected); - // Note that the GUID passed in this function does not match the GUID of the returned entry. - // This is okay because the purpose of the test is to make sure that the JNI layer passes - // the entry returned by the native code. The native code does the actual matching of - // the GUID but since that is mocked out and not the purpose of the test, this is fine. - SendTabToSelfEntry actual = SendTabToSelfAndroidBridge.getEntryByGUID(mProfile, "guid"); - Assert.assertEquals(expected.guid, actual.guid); - Assert.assertEquals(expected.url, actual.url); - Assert.assertEquals(expected.title, actual.title); - Assert.assertEquals(expected.sharedTime, actual.sharedTime); - Assert.assertEquals(expected.originalNavigationTime, actual.originalNavigationTime); - Assert.assertEquals(expected.deviceName, actual.deviceName); - Assert.assertEquals(expected.targetDeviceSyncCacheGuid, actual.targetDeviceSyncCacheGuid); - } - - @Test - @SmallTest public void testDeleteAllEntries() { SendTabToSelfAndroidBridge.deleteAllEntries(mProfile); verify(mNativeMock).deleteAllEntries(eq(mProfile));
diff --git a/chrome/browser/share/crow_bridge.cc b/chrome/browser/share/crow_bridge.cc new file mode 100644 index 0000000..97254dfc --- /dev/null +++ b/chrome/browser/share/crow_bridge.cc
@@ -0,0 +1,58 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/android/callback_android.h" +#include "base/android/jni_android.h" +#include "base/android/jni_array.h" +#include "base/no_destructor.h" +#include "base/task/cancelable_task_tracker.h" +#include "chrome/browser/history/history_service_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/share/android/jni_headers/CrowBridge_jni.h" +#include "components/history/core/browser/history_service.h" +#include "components/history/core/browser/history_types.h" +#include "url/android/gurl_android.h" + +base::CancelableTaskTracker& TaskTracker() { + static base::NoDestructor<base::CancelableTaskTracker> task_tracker; + return *task_tracker; +} + +static void JNI_CrowBridge_GetRecentVisitCountsToHost( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& j_url, + jint j_num_days, + const base::android::JavaParamRef<jobject>& j_callback) { + auto adaptor = [](const base::android::JavaRef<jobject>& callback, + history::DailyVisitsResult result) { + JNIEnv* env = base::android::AttachCurrentThread(); + base::android::RunObjectCallbackAndroid( + callback, base::android::ToJavaIntArray( + env, std::vector<int>({result.total_visits, + result.days_with_visits}))); + }; + base::OnceCallback<void(history::DailyVisitsResult)> callback = + base::BindOnce(adaptor, + base::android::ScopedJavaGlobalRef<jobject>(j_callback)); + + Profile* profile = ProfileManager::GetLastUsedProfile(); + history::HistoryService* history_service = nullptr; + if (profile) { + history_service = HistoryServiceFactory::GetForProfile( + profile, ServiceAccessType::IMPLICIT_ACCESS); + } + if (!history_service) { + std::move(callback).Run({}); + return; + } + + // Ignore any visits within the last hour so that we do not count the current + // visit to the page. + auto end_time = base::Time::Now() - base::Hours(1); + auto begin_time = base::Time::Now() - base::Days(j_num_days); + history_service->GetDailyVisitsToHost( + *url::GURLAndroid::ToNativeGURL(env, j_url), begin_time, end_time, + std::move(callback), &TaskTracker()); +}
diff --git a/chrome/browser/themes/browser_theme_pack.cc b/chrome/browser/themes/browser_theme_pack.cc index 737f062..7cd81e5 100644 --- a/chrome/browser/themes/browser_theme_pack.cc +++ b/chrome/browser/themes/browser_theme_pack.cc
@@ -97,7 +97,7 @@ // changed default theme assets, if you need themes to recreate their generated // images (which are cached), if you changed how missing values are // generated, or if you changed any constants. -const int kThemePackVersion = 98; +const int kThemePackVersion = 99; // IDs that are in the DataPack won't clash with the positive integer // uint16_t. kHeaderID should always have the maximum value because we want the @@ -266,7 +266,6 @@ TP::COLOR_WINDOW_CONTROL_BUTTON_BACKGROUND_INCOGNITO_ACTIVE, TP::COLOR_WINDOW_CONTROL_BUTTON_BACKGROUND_INCOGNITO_INACTIVE, TP::COLOR_INFOBAR, - TP::COLOR_INFOBAR_TEXT, TP::COLOR_DOWNLOAD_SHELF, TP::COLOR_TOOLBAR_BUTTON_ICON_HOVERED, TP::COLOR_TOOLBAR_BUTTON_ICON_PRESSED, @@ -1076,7 +1075,6 @@ {TP::COLOR_FRAME_ACTIVE, ui::kColorFrameActive}, {TP::COLOR_FRAME_INACTIVE, ui::kColorFrameInactive}, {TP::COLOR_INFOBAR, kColorInfoBarBackground}, - {TP::COLOR_INFOBAR_TEXT, kColorInfoBarForeground}, {TP::COLOR_NTP_BACKGROUND, kColorNewTabPageBackground}, {TP::COLOR_NTP_HEADER, kColorNewTabPageHeader}, {TP::COLOR_NTP_LINK, kColorNewTabPageLink}, @@ -1589,7 +1587,6 @@ SkColor toolbar_text_color; if (GetColor(TP::COLOR_TOOLBAR_TEXT, &toolbar_text_color)) { SetColorIfUnspecified(TP::COLOR_BOOKMARK_TEXT, toolbar_text_color); - SetColor(TP::COLOR_INFOBAR_TEXT, toolbar_text_color); SetColorIfUnspecified(TP::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_ACTIVE, toolbar_text_color); }
diff --git a/chrome/browser/themes/increased_contrast_theme_supplier.cc b/chrome/browser/themes/increased_contrast_theme_supplier.cc index 39d45e0..85aa8d4d 100644 --- a/chrome/browser/themes/increased_contrast_theme_supplier.cc +++ b/chrome/browser/themes/increased_contrast_theme_supplier.cc
@@ -54,7 +54,6 @@ return true; case ThemeProperties::COLOR_DOWNLOAD_SHELF_CONTENT_AREA_SEPARATOR: case ThemeProperties::COLOR_INFOBAR_CONTENT_AREA_SEPARATOR: - case ThemeProperties::COLOR_INFOBAR_TEXT: case ThemeProperties::COLOR_LOCATION_BAR_BORDER: case ThemeProperties::COLOR_SIDE_PANEL_CONTENT_AREA_SEPARATOR: case ThemeProperties::COLOR_TOOLBAR_CONTENT_AREA_SEPARATOR:
diff --git a/chrome/browser/themes/theme_helper.cc b/chrome/browser/themes/theme_helper.cc index 44208d98..c9e8e00 100644 --- a/chrome/browser/themes/theme_helper.cc +++ b/chrome/browser/themes/theme_helper.cc
@@ -24,6 +24,10 @@ #include "ui/native_theme/common_theme.h" #include "ui/native_theme/native_theme.h" +#if BUILDFLAG(IS_LINUX) +#include "ui/views/linux_ui/linux_ui.h" +#endif + namespace { using TP = ThemeProperties; @@ -351,24 +355,11 @@ case TP::COLOR_TAB_STROKE_FRAME_INACTIVE: return GetColor(TP::COLOR_TOOLBAR_TOP_SEPARATOR_FRAME_INACTIVE, incognito, theme_supplier); - case TP::COLOR_DOWNLOAD_SHELF_BUTTON_BACKGROUND: - return GetColor(TP::COLOR_DOWNLOAD_SHELF, incognito, theme_supplier); - case TP::COLOR_DOWNLOAD_SHELF_BUTTON_TEXT: { - const SkColor download_shelf_color = - GetColor(TP::COLOR_DOWNLOAD_SHELF_BUTTON_BACKGROUND, incognito, - theme_supplier); - return color_utils::PickGoogleColor( - color_utils::IsDark(download_shelf_color) ? gfx::kGoogleBlue300 - : gfx::kGoogleBlue600, - download_shelf_color, color_utils::kMinimumReadableContrastRatio); - } case TP::COLOR_DOWNLOAD_SHELF_CONTENT_AREA_SEPARATOR: return color_utils::AlphaBlend( GetColor(TP::COLOR_TOOLBAR_BUTTON_ICON, incognito, theme_supplier), GetColor(TP::COLOR_DOWNLOAD_SHELF, incognito, theme_supplier), SkAlpha{0x3A}); - case TP::COLOR_DOWNLOAD_SHELF_FOREGROUND: - return GetColor(TP::COLOR_TOOLBAR_TEXT, incognito, theme_supplier); case TP::COLOR_STATUS_BUBBLE_ACTIVE: return GetColor(TP::COLOR_TAB_BACKGROUND_INACTIVE_FRAME_ACTIVE, incognito, theme_supplier); @@ -414,7 +405,6 @@ return color_utils::HSLShift(get_frame_color(/*active=*/false), GetTint(ThemeProperties::TINT_BACKGROUND_TAB, incognito, theme_supplier)); - case TP::COLOR_BOOKMARK_BUTTON_ICON: case TP::COLOR_TOOLBAR_BUTTON_ICON: case TP::COLOR_TOOLBAR_BUTTON_ICON_HOVERED: case TP::COLOR_TOOLBAR_BUTTON_ICON_PRESSED: @@ -495,8 +485,22 @@ bool ThemeHelper::UseDarkModeColors(const CustomThemeSupplier* theme_supplier) { // Dark mode is disabled for custom themes so they apply atop a predictable // state. - return !IsCustomTheme(theme_supplier) && - ui::NativeTheme::GetInstanceForNativeUi()->ShouldUseDarkColors(); + if (IsCustomTheme(theme_supplier)) + return false; + + ui::NativeTheme const* native_theme = + ui::NativeTheme::GetInstanceForNativeUi(); +#if BUILDFLAG(IS_LINUX) + if (const auto* linux_ui = views::LinuxUI::instance()) { + // We rely on the fact that the system theme is in use iff `theme_supplier` + // is non-null, but this is cheating. In the future this might not hold + // after we fully migrate to the color provider and remove SystemThemeLinux. + native_theme = linux_ui->GetNativeTheme( + theme_supplier && + theme_supplier->get_theme_type() == CustomThemeSupplier::NATIVE_X11); + } +#endif + return native_theme->ShouldUseDarkColors(); } gfx::Image ThemeHelper::GetImageNamed(
diff --git a/chrome/browser/themes/theme_helper_win.cc b/chrome/browser/themes/theme_helper_win.cc index c6b77ce3..9d7a4b4 100644 --- a/chrome/browser/themes/theme_helper_win.cc +++ b/chrome/browser/themes/theme_helper_win.cc
@@ -65,10 +65,8 @@ break; // Button Text Foreground - case ThemeProperties::COLOR_BOOKMARK_BUTTON_ICON: case ThemeProperties::COLOR_DOWNLOAD_SHELF_CONTENT_AREA_SEPARATOR: case ThemeProperties::COLOR_INFOBAR_CONTENT_AREA_SEPARATOR: - case ThemeProperties::COLOR_INFOBAR_TEXT: case ThemeProperties::COLOR_OMNIBOX_BUBBLE_OUTLINE: case ThemeProperties:: COLOR_OMNIBOX_BUBBLE_OUTLINE_EXPERIMENTAL_KEYWORD_MODE:
diff --git a/chrome/browser/themes/theme_properties.cc b/chrome/browser/themes/theme_properties.cc index 6680a32..8d735ad6 100644 --- a/chrome/browser/themes/theme_properties.cc +++ b/chrome/browser/themes/theme_properties.cc
@@ -72,7 +72,6 @@ return gfx::kGoogleGrey300; case ThemeProperties::COLOR_HOVER_CARD_NO_PREVIEW_BACKGROUND: return gfx::kGoogleGrey050; - case ThemeProperties::COLOR_INFOBAR_TEXT: case ThemeProperties::COLOR_TAB_FOREGROUND_INACTIVE_FRAME_ACTIVE: case ThemeProperties::COLOR_TAB_FOREGROUND_INACTIVE_FRAME_INACTIVE: case ThemeProperties::COLOR_TOOLBAR_TEXT: @@ -167,7 +166,6 @@ case ThemeProperties::COLOR_HOVER_CARD_NO_PREVIEW_BACKGROUND: case ThemeProperties::COLOR_NTP_SHORTCUT: return gfx::kGoogleGrey900; - case ThemeProperties::COLOR_INFOBAR_TEXT: case ThemeProperties::COLOR_TOOLBAR_TEXT: return SK_ColorWHITE; case ThemeProperties::COLOR_NTP_TEXT:
diff --git a/chrome/browser/themes/theme_properties.h b/chrome/browser/themes/theme_properties.h index 85dcc4e..599ca7f 100644 --- a/chrome/browser/themes/theme_properties.h +++ b/chrome/browser/themes/theme_properties.h
@@ -132,15 +132,11 @@ // Colors used for various 'shelves' and 'bars'. // Download shelf colors. COLOR_DOWNLOAD_SHELF, - COLOR_DOWNLOAD_SHELF_BUTTON_BACKGROUND, - COLOR_DOWNLOAD_SHELF_BUTTON_TEXT, COLOR_DOWNLOAD_SHELF_CONTENT_AREA_SEPARATOR, - COLOR_DOWNLOAD_SHELF_FOREGROUND, // Infobar colors. COLOR_INFOBAR, COLOR_INFOBAR_CONTENT_AREA_SEPARATOR, - COLOR_INFOBAR_TEXT, COLOR_SIDE_PANEL_CONTENT_AREA_SEPARATOR, @@ -311,7 +307,6 @@ // Colors used for the Bookmark bar COLOR_BOOKMARK_BAR_BACKGROUND, - COLOR_BOOKMARK_BUTTON_ICON, // If COLOR_TOOLBAR_BUTTON_ICON is defined in the custom theme, that color // will be returned, otherwise it will be transparent so the default // favicon color is retained.
diff --git a/chrome/browser/themes/theme_service.cc b/chrome/browser/themes/theme_service.cc index a2ce4025..b2f2f64 100644 --- a/chrome/browser/themes/theme_service.cc +++ b/chrome/browser/themes/theme_service.cc
@@ -98,18 +98,13 @@ {TP::COLOR_ACCENT_BORDER_INACTIVE, kColorAccentBorderInactive}, #endif // BUILDFLAG(IS_WIN) {TP::COLOR_BOOKMARK_BAR_BACKGROUND, kColorBookmarkBarBackground}, - {TP::COLOR_BOOKMARK_BUTTON_ICON, kColorBookmarkButtonIcon}, {TP::COLOR_BOOKMARK_FAVICON, kColorBookmarkFavicon}, {TP::COLOR_BOOKMARK_SEPARATOR, kColorBookmarkBarSeparator}, {TP::COLOR_BOOKMARK_TEXT, kColorBookmarkBarForeground}, {TP::COLOR_CONTROL_BUTTON_BACKGROUND, kColorCaptionButtonBackground}, {TP::COLOR_DOWNLOAD_SHELF, kColorDownloadShelfBackground}, - {TP::COLOR_DOWNLOAD_SHELF_BUTTON_BACKGROUND, - kColorDownloadShelfButtonBackground}, - {TP::COLOR_DOWNLOAD_SHELF_BUTTON_TEXT, kColorDownloadShelfButtonText}, {TP::COLOR_DOWNLOAD_SHELF_CONTENT_AREA_SEPARATOR, kColorDownloadShelfContentAreaSeparator}, - {TP::COLOR_DOWNLOAD_SHELF_FOREGROUND, kColorDownloadShelfForeground}, {TP::COLOR_FEATURE_PROMO_BUBBLE_BACKGROUND, kColorFeaturePromoBubbleBackground}, {TP::COLOR_FEATURE_PROMO_BUBBLE_BUTTON_BORDER, @@ -131,7 +126,6 @@ {TP::COLOR_INFOBAR, kColorInfoBarBackground}, {TP::COLOR_INFOBAR_CONTENT_AREA_SEPARATOR, kColorInfoBarContentAreaSeparator}, - {TP::COLOR_INFOBAR_TEXT, kColorInfoBarForeground}, {TP::COLOR_LOCATION_BAR_BORDER, kColorLocationBarBorder}, {TP::COLOR_LOCATION_BAR_BORDER_OPAQUE, kColorLocationBarBorderOpaque}, {TP::COLOR_NTP_BACKGROUND, kColorNewTabPageBackground},
diff --git a/chrome/browser/themes/theme_service_linux_unittest.cc b/chrome/browser/themes/theme_service_linux_unittest.cc index f697179..1bf7acc 100644 --- a/chrome/browser/themes/theme_service_linux_unittest.cc +++ b/chrome/browser/themes/theme_service_linux_unittest.cc
@@ -6,7 +6,7 @@ #include <cmath> -#include "base/containers/fixed_flat_map.h" +#include "base/containers/fixed_flat_set.h" #include "base/memory/raw_ptr.h" #include "base/memory/scoped_refptr.h" #include "base/run_loop.h" @@ -117,15 +117,25 @@ // TODO(crbug.com/1310397): There're mismatched colors in some GTK themes. // Enable this test after fixing them. -TEST_F(ThemeProviderRedirectedEquivalenceLinuxTest, DISABLED_GetColor) { +TEST_F(ThemeProviderRedirectedEquivalenceLinuxTest, GetColor) { const ui::ThemeProvider& theme_provider = ThemeService::GetThemeProviderForProfile(profile()); + static constexpr const auto ignored_color_ids = base::MakeFixedFlatSet< + ui::ColorId>( + {// Ignore IPH colors due to behavior change. + // Original: always Google blue, redirected: follow the accent color. + ThemeProperties::COLOR_FEATURE_PROMO_BUBBLE_BACKGROUND, + ThemeProperties::COLOR_FEATURE_PROMO_BUBBLE_CLOSE_BUTTON_INK_DROP, + ThemeProperties::COLOR_FEATURE_PROMO_BUBBLE_DEFAULT_BUTTON_FOREGROUND}); + std::vector<std::string> gtk_themes = linux_ui_->GetAvailableSystemThemeNamesForTest(); for (const std::string& gtk_theme : gtk_themes) { linux_ui_->SetSystemThemeByNameForTest(gtk_theme); for (auto color_id : theme_service::test::kTestColorIds) { + if (ignored_color_ids.contains(color_id)) + continue; std::string error_message = base::StrCat({"GTK theme ", gtk_theme, ": ", theme_service::test::ColorIdToString(color_id),
diff --git a/chrome/browser/ui/app_list/app_list_client_impl.cc b/chrome/browser/ui/app_list/app_list_client_impl.cc index d108ea2..ed5082c 100644 --- a/chrome/browser/ui/app_list/app_list_client_impl.cc +++ b/chrome/browser/ui/app_list/app_list_client_impl.cc
@@ -401,8 +401,6 @@ void AppListClientImpl::OnAppListVisibilityChanged(bool visible) { app_list_visible_ = visible; if (visible) { - if (search_controller_) - search_controller_->AppListShown(); MaybeRecordViewShown(); } else if (current_model_updater_) { current_model_updater_->OnAppListHidden();
diff --git a/chrome/browser/ui/app_list/app_list_notifier_impl.cc b/chrome/browser/ui/app_list/app_list_notifier_impl.cc index ba478873..441ac9f 100644 --- a/chrome/browser/ui/app_list/app_list_notifier_impl.cc +++ b/chrome/browser/ui/app_list/app_list_notifier_impl.cc
@@ -95,6 +95,14 @@ } } +bool AppListNotifierImpl::FireImpressionTimerForTesting(Location location) { + auto timer_it = timers_.find(location); + if (timer_it == timers_.end() || !timer_it->second->IsRunning()) + return false; + timer_it->second->FireNow(); + return true; +} + void AppListNotifierImpl::OnAppListVisibilityWillChange(bool shown, int64_t display_id) { if (shown_ == shown)
diff --git a/chrome/browser/ui/app_list/app_list_notifier_impl.h b/chrome/browser/ui/app_list/app_list_notifier_impl.h index 64135b3..7e8a710 100644 --- a/chrome/browser/ui/app_list/app_list_notifier_impl.h +++ b/chrome/browser/ui/app_list/app_list_notifier_impl.h
@@ -141,6 +141,7 @@ void NotifyResultsUpdated(Location location, const std::vector<Result>& results) override; void NotifySearchQueryChanged(const std::u16string& query) override; + bool FireImpressionTimerForTesting(Location location) override; // AppListControllerObserver: void OnAppListVisibilityWillChange(bool shown, int64_t display_id) override;
diff --git a/chrome/browser/ui/app_list/app_list_notifier_impl_old.cc b/chrome/browser/ui/app_list/app_list_notifier_impl_old.cc index e2d3272..7ffa48c 100644 --- a/chrome/browser/ui/app_list/app_list_notifier_impl_old.cc +++ b/chrome/browser/ui/app_list/app_list_notifier_impl_old.cc
@@ -80,6 +80,14 @@ } } +bool AppListNotifierImplOld::FireImpressionTimerForTesting(Location location) { + auto timer_it = timers_.find(location); + if (timer_it == timers_.end() || !timer_it->second->IsRunning()) + return false; + timer_it->second->FireNow(); + return true; +} + void AppListNotifierImplOld::OnViewStateChanged(ash::AppListViewState view) { // We should ignore certain view state changes entirely: //
diff --git a/chrome/browser/ui/app_list/app_list_notifier_impl_old.h b/chrome/browser/ui/app_list/app_list_notifier_impl_old.h index e8f2b98..313fc1c 100644 --- a/chrome/browser/ui/app_list/app_list_notifier_impl_old.h +++ b/chrome/browser/ui/app_list/app_list_notifier_impl_old.h
@@ -143,6 +143,7 @@ void NotifyResultsUpdated(Location location, const std::vector<Result>& results) override; void NotifySearchQueryChanged(const std::u16string& query) override; + bool FireImpressionTimerForTesting(Location location) override; // AppListControllerObserver: void OnAppListVisibilityWillChange(bool shown, int64_t display_id) override;
diff --git a/chrome/browser/ui/app_list/search/files/zero_state_drive_provider_unittest.cc b/chrome/browser/ui/app_list/search/files/zero_state_drive_provider_unittest.cc index dbfb0182..5c69d3f 100644 --- a/chrome/browser/ui/app_list/search/files/zero_state_drive_provider_unittest.cc +++ b/chrome/browser/ui/app_list/search/files/zero_state_drive_provider_unittest.cc
@@ -78,7 +78,6 @@ TEST_F(ZeroStateDriveProviderTest, HypotheticalQueryIntervals) { histogram_tester_.ExpectTotalCount(kHypotheticalQueryHistogram, 0); - provider_->AppListShown(); provider_->ViewClosing(); histogram_tester_.ExpectBucketCount( kHypotheticalQueryHistogram, @@ -94,7 +93,6 @@ ZeroStateDriveProvider::ThrottleInterval::kThirtyMinutes, 1); FastForwardByMinutes(5); - provider_->AppListShown(); provider_->ViewClosing(); histogram_tester_.ExpectBucketCount( kHypotheticalQueryHistogram, @@ -110,7 +108,6 @@ ZeroStateDriveProvider::ThrottleInterval::kThirtyMinutes, 1); FastForwardByMinutes(5); - provider_->AppListShown(); provider_->ViewClosing(); histogram_tester_.ExpectBucketCount( kHypotheticalQueryHistogram, @@ -126,7 +123,6 @@ ZeroStateDriveProvider::ThrottleInterval::kThirtyMinutes, 1); FastForwardByMinutes(5); - provider_->AppListShown(); provider_->ViewClosing(); histogram_tester_.ExpectBucketCount( kHypotheticalQueryHistogram, @@ -142,7 +138,6 @@ ZeroStateDriveProvider::ThrottleInterval::kThirtyMinutes, 1); FastForwardByMinutes(15); - provider_->AppListShown(); provider_->ViewClosing(); histogram_tester_.ExpectBucketCount( kHypotheticalQueryHistogram,
diff --git a/chrome/browser/ui/app_list/search/help_app_provider.cc b/chrome/browser/ui/app_list/search/help_app_provider.cc index 55e0690..22e4f5f 100644 --- a/chrome/browser/ui/app_list/search/help_app_provider.cc +++ b/chrome/browser/ui/app_list/search/help_app_provider.cc
@@ -10,6 +10,7 @@ #include "ash/public/cpp/app_list/app_list_config.h" #include "ash/public/cpp/app_list/app_list_features.h" #include "ash/public/cpp/app_list/app_list_metrics.h" +#include "ash/public/cpp/app_list/vector_icons/vector_icons.h" #include "ash/webui/help_app_ui/help_app_manager.h" #include "ash/webui/help_app_ui/help_app_manager_factory.h" #include "ash/webui/help_app_ui/search/search_handler.h" @@ -191,14 +192,18 @@ base::PersistentHash(help_app_content_id_)); } -HelpAppProvider::HelpAppProvider(Profile* profile) - : profile_(profile), search_handler_(nullptr) { +HelpAppProvider::HelpAppProvider(Profile* profile, + ash::AppListNotifier* notifier) + : profile_(profile), notifier_(notifier), search_handler_(nullptr) { DCHECK(profile_); app_service_proxy_ = apps::AppServiceProxyFactory::GetForProfile(profile_); Observe(&app_service_proxy_->AppRegistryCache()); LoadIcon(); + if (notifier_) + notifier_->AddObserver(this); + if (!base::FeatureList::IsEnabled( chromeos::features::kHelpAppLauncherSearch)) { // Only get the help app manager if the launcher search feature is enabled. @@ -214,7 +219,10 @@ search_results_observer_receiver_.BindNewPipeAndPassRemote()); } -HelpAppProvider::~HelpAppProvider() = default; +HelpAppProvider::~HelpAppProvider() { + if (notifier_) + notifier_->RemoveObserver(this); +} void HelpAppProvider::Start(const std::u16string& query) { ClearResultsSilently(); @@ -304,19 +312,6 @@ SwapResults(&search_results); } -// TODO(b/171828539): Consider using AppListNotifier for better proxy of -// impressions. -void HelpAppProvider::AppListShown() { - for (auto& result : results()) { - if (result->id() == kHelpAppDiscoverResult) { - DecreaseTimesLeftToShowDiscoverTabSuggestionChip(profile_); - } else if (result->id() == kHelpAppUpdatesResult) { - ash::ReleaseNotesStorage(profile_) - .DecreaseTimesLeftToShowSuggestionChip(); - } - } -} - ash::AppListSearchResultType HelpAppProvider::ResultType() const { return ash::AppListSearchResultType::kHelpApp; } @@ -337,6 +332,23 @@ Observe(nullptr); } +void HelpAppProvider::OnImpression( + ash::AppListNotifier::Location location, + const std::vector<ash::AppListNotifier::Result>& results, + const std::u16string& query) { + if (location != ash::AppListNotifier::Location::kChip) + return; + + for (const auto& result : results) { + if (result.id == kHelpAppDiscoverResult) { + DecreaseTimesLeftToShowDiscoverTabSuggestionChip(profile_); + } else if (result.id == kHelpAppUpdatesResult) { + ash::ReleaseNotesStorage(profile_) + .DecreaseTimesLeftToShowSuggestionChip(); + } + } +} + // If the availability of search results changed, start a new search. void HelpAppProvider::OnSearchResultAvailabilityChanged() { if (last_query_.empty())
diff --git a/chrome/browser/ui/app_list/search/help_app_provider.h b/chrome/browser/ui/app_list/search/help_app_provider.h index be2f2d8..3dd4fa1 100644 --- a/chrome/browser/ui/app_list/search/help_app_provider.h +++ b/chrome/browser/ui/app_list/search/help_app_provider.h
@@ -8,6 +8,7 @@ #include <string> #include <vector> +#include "ash/public/cpp/app_list/app_list_notifier.h" #include "ash/webui/help_app_ui/search/search.mojom.h" #include "base/memory/weak_ptr.h" #include "base/time/time.h" @@ -67,9 +68,10 @@ // zero-state results. class HelpAppProvider : public SearchProvider, public apps::AppRegistryCache::Observer, + public ash::AppListNotifier::Observer, public ash::help_app::mojom::SearchResultsObserver { public: - explicit HelpAppProvider(Profile* profile); + HelpAppProvider(Profile* profile, ash::AppListNotifier* notifier); ~HelpAppProvider() override; HelpAppProvider(const HelpAppProvider&) = delete; @@ -79,7 +81,6 @@ void Start(const std::u16string& query) override; void StartZeroState() override; void ViewClosing() override; - void AppListShown() override; ash::AppListSearchResultType ResultType() const override; bool ShouldBlockZeroState() const override; @@ -88,6 +89,11 @@ void OnAppRegistryCacheWillBeDestroyed( apps::AppRegistryCache* cache) override; + // ash::AppListNotifier::Observer: + void OnImpression(ash::AppListNotifier::Location location, + const std::vector<ash::AppListNotifier::Result>& results, + const std::u16string& query) override; + // mojom::SearchResultsObserver: void OnSearchResultAvailabilityChanged() override; @@ -100,6 +106,8 @@ void LoadIcon(); Profile* const profile_; + ash::AppListNotifier* const notifier_; + ash::help_app::SearchHandler* search_handler_; apps::AppServiceProxy* app_service_proxy_; gfx::ImageSkia icon_;
diff --git a/chrome/browser/ui/app_list/search/help_app_provider_unittest.cc b/chrome/browser/ui/app_list/search/help_app_provider_unittest.cc index a0f942f..8d3c65c 100644 --- a/chrome/browser/ui/app_list/search/help_app_provider_unittest.cc +++ b/chrome/browser/ui/app_list/search/help_app_provider_unittest.cc
@@ -9,9 +9,13 @@ #include "ash/constants/ash_features.h" #include "base/feature_list.h" +#include "base/logging.h" #include "base/test/scoped_feature_list.h" +#include "chrome/browser/ui/app_list/app_list_notifier_impl_old.h" #include "chrome/browser/ui/app_list/app_list_test_util.h" #include "chrome/browser/ui/app_list/search/chrome_search_result.h" +#include "chrome/browser/ui/app_list/search/test/test_search_controller.h" +#include "chrome/browser/ui/app_list/test/test_app_list_controller.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/testing_profile.h" #include "chromeos/strings/grit/chromeos_strings.h" @@ -22,8 +26,12 @@ namespace test { namespace { + +constexpr char kDiscoverTabResultId[] = "help-app://discover"; +constexpr char kReleaseNotesResultId[] = "help-app://updates"; + void ExpectDiscoverTabChip(ChromeSearchResult* result) { - EXPECT_EQ("help-app://discover", result->id()); + EXPECT_EQ(kDiscoverTabResultId, result->id()); EXPECT_EQ( l10n_util::GetStringUTF16(IDS_HELP_APP_DISCOVER_TAB_SUGGESTION_CHIP), result->title()); @@ -31,33 +39,51 @@ EXPECT_EQ(ash::SearchResultDisplayType::kChip, result->display_type()); } -void ExpectReleaseNotesChip(ChromeSearchResult* result) { - EXPECT_EQ("help-app://updates", result->id()); +void ExpectReleaseNotesChip(ChromeSearchResult* result, + ash::SearchResultDisplayType display_type) { + EXPECT_EQ(kReleaseNotesResultId, result->id()); EXPECT_EQ(l10n_util::GetStringUTF16(IDS_HELP_APP_WHATS_NEW_SUGGESTION_CHIP), result->title()); EXPECT_EQ(ash::AppListSearchResultType::kHelpApp, result->result_type()); - EXPECT_EQ(ash::SearchResultDisplayType::kChip, result->display_type()); + EXPECT_EQ(display_type, result->display_type()); } } // namespace class HelpAppProviderTest : public AppListTestBase { public: - HelpAppProviderTest() {} - ~HelpAppProviderTest() override = default; - - void SetUp() override { - AppListTestBase::SetUp(); - - provider_ = std::make_unique<HelpAppProvider>(profile()); + HelpAppProviderTest() { scoped_feature_list_.InitWithFeatures( /*enabled_features=*/{chromeos::features::kHelpAppDiscoverTab, chromeos::features::kReleaseNotesSuggestionChip}, /*disabled_features=*/{}); } + ~HelpAppProviderTest() override = default; + + void SetUp() override { + AppListTestBase::SetUp(); + + app_list_notifier_ = + std::make_unique<AppListNotifierImplOld>(&app_list_controller_); + + provider_ = + std::make_unique<HelpAppProvider>(profile(), app_list_notifier_.get()); + provider_->set_controller(&search_controller_); + } + + const app_list::Results& GetLatestResults() { return provider()->results(); } + + ::test::TestAppListController* app_list_controller() { + return &app_list_controller_; + } + + ash::AppListNotifier* app_list_notifier() { return app_list_notifier_.get(); } HelpAppProvider* provider() { return provider_.get(); } private: + ::test::TestAppListController app_list_controller_; + std::unique_ptr<ash::AppListNotifier> app_list_notifier_; + TestSearchController search_controller_; std::unique_ptr<HelpAppProvider> provider_; base::test::ScopedFeatureList scoped_feature_list_; }; @@ -71,7 +97,7 @@ provider()->StartZeroState(); - EXPECT_TRUE(provider()->results().empty()); + EXPECT_TRUE(GetLatestResults().empty()); } TEST_F(HelpAppProviderTest, @@ -83,8 +109,8 @@ provider()->StartZeroState(); - EXPECT_EQ(1u, provider()->results().size()); - ChromeSearchResult* result = provider()->results().at(0).get(); + ASSERT_EQ(1u, GetLatestResults().size()); + ChromeSearchResult* result = GetLatestResults().at(0).get(); ExpectDiscoverTabChip(result); } @@ -97,9 +123,9 @@ provider()->StartZeroState(); - EXPECT_EQ(1u, provider()->results().size()); - ChromeSearchResult* result = provider()->results().at(0).get(); - ExpectReleaseNotesChip(result); + ASSERT_EQ(1u, GetLatestResults().size()); + ChromeSearchResult* result = GetLatestResults().at(0).get(); + ExpectReleaseNotesChip(result, ash::SearchResultDisplayType::kChip); } TEST_F(HelpAppProviderTest, PrioritizesDiscoverTabChipForEmptyQuery) { @@ -110,8 +136,9 @@ provider()->StartZeroState(); - EXPECT_EQ(1u, provider()->results().size()); - ChromeSearchResult* result = provider()->results().at(0).get(); + ASSERT_EQ(1u, GetLatestResults().size()); + + ChromeSearchResult* result = GetLatestResults().at(0).get(); ExpectDiscoverTabChip(result); } @@ -121,7 +148,23 @@ prefs::kDiscoverTabSuggestionChipTimesLeftToShow, 3); provider()->StartZeroState(); - provider()->AppListShown(); + + ASSERT_EQ(1u, GetLatestResults().size()); + ChromeSearchResult* result = GetLatestResults().at(0).get(); + ExpectDiscoverTabChip(result); + + app_list_controller()->ShowAppList(); + EXPECT_EQ(3, profile()->GetPrefs()->GetInteger( + prefs::kDiscoverTabSuggestionChipTimesLeftToShow)); + + app_list_notifier()->NotifyResultsUpdated( + ash::AppListNotifier::Location::kChip, + {ash::AppListNotifier::Result(kDiscoverTabResultId, + ash::HELP_APP_UPDATES)}); + EXPECT_EQ(3, profile()->GetPrefs()->GetInteger( + prefs::kDiscoverTabSuggestionChipTimesLeftToShow)); + ASSERT_TRUE(app_list_notifier()->FireImpressionTimerForTesting( + ash::AppListNotifier::Location::kChip)); EXPECT_EQ(2, profile()->GetPrefs()->GetInteger( prefs::kDiscoverTabSuggestionChipTimesLeftToShow)); @@ -133,7 +176,23 @@ prefs::kReleaseNotesSuggestionChipTimesLeftToShow, 3); provider()->StartZeroState(); - provider()->AppListShown(); + + ASSERT_EQ(1u, GetLatestResults().size()); + + ChromeSearchResult* result = GetLatestResults().at(0).get(); + ExpectReleaseNotesChip(result, ash::SearchResultDisplayType::kChip); + + app_list_controller()->ShowAppList(); + EXPECT_EQ(3, profile()->GetPrefs()->GetInteger( + prefs::kReleaseNotesSuggestionChipTimesLeftToShow)); + + app_list_notifier()->NotifyResultsUpdated( + ash::SearchResultDisplayType::kChip, + {ash::AppListNotifier::Result(kReleaseNotesResultId, + ash::HELP_APP_UPDATES)}); + + ASSERT_TRUE(app_list_notifier()->FireImpressionTimerForTesting( + ash::SearchResultDisplayType::kChip)); EXPECT_EQ(2, profile()->GetPrefs()->GetInteger( prefs::kReleaseNotesSuggestionChipTimesLeftToShow)); @@ -145,7 +204,8 @@ provider()->StartZeroState(); - ChromeSearchResult* result = provider()->results().at(0).get(); + ASSERT_EQ(1u, GetLatestResults().size()); + ChromeSearchResult* result = GetLatestResults().at(0).get(); result->Open(/*event_flags=*/0); EXPECT_EQ(0, profile()->GetPrefs()->GetInteger( @@ -158,7 +218,7 @@ provider()->StartZeroState(); - ChromeSearchResult* result = provider()->results().at(0).get(); + ChromeSearchResult* result = GetLatestResults().at(0).get(); result->Open(/*event_flags=*/0); EXPECT_EQ(0, profile()->GetPrefs()->GetInteger( @@ -167,15 +227,12 @@ class HelpAppProviderWithDiscoverTabDisabledTest : public HelpAppProviderTest { public: - HelpAppProviderWithDiscoverTabDisabledTest() {} - ~HelpAppProviderWithDiscoverTabDisabledTest() override = default; - - void SetUp() override { - HelpAppProviderTest::SetUp(); + HelpAppProviderWithDiscoverTabDisabledTest() { scoped_feature_list_.InitWithFeatures( /*enabled_features=*/{chromeos::features::kReleaseNotesSuggestionChip}, /*disabled_features=*/{chromeos::features::kHelpAppDiscoverTab}); } + ~HelpAppProviderWithDiscoverTabDisabledTest() override = default; private: base::test::ScopedFeatureList scoped_feature_list_; @@ -190,7 +247,7 @@ provider()->StartZeroState(); - EXPECT_TRUE(provider()->results().empty()); + EXPECT_TRUE(GetLatestResults().empty()); } } // namespace test
diff --git a/chrome/browser/ui/app_list/search/help_app_search_browsertest.cc b/chrome/browser/ui/app_list/search/help_app_search_browsertest.cc index 9bbc9b1..6ddfcc63 100644 --- a/chrome/browser/ui/app_list/search/help_app_search_browsertest.cc +++ b/chrome/browser/ui/app_list/search/help_app_search_browsertest.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "ash/constants/ash_features.h" +#include "ash/public/cpp/app_list/app_list_notifier.h" #include "ash/webui/help_app_ui/help_app_manager.h" #include "ash/webui/help_app_ui/help_app_manager_factory.h" #include "ash/webui/help_app_ui/search/search.mojom.h" @@ -135,6 +136,9 @@ GetClient()->ShowAppList(); SearchAndWaitForProviders("", {ResultType::kHelpApp}); + EXPECT_TRUE(GetClient()->GetNotifier()->FireImpressionTimerForTesting( + ash::AppListNotifier::Location::kChip)); + const int times_left_to_show = GetProfile()->GetPrefs()->GetInteger( prefs::kReleaseNotesSuggestionChipTimesLeftToShow); EXPECT_EQ(times_left_to_show, 2);
diff --git a/chrome/browser/ui/app_list/search/os_settings_provider.cc b/chrome/browser/ui/app_list/search/os_settings_provider.cc index f24c726..71d90c1 100644 --- a/chrome/browser/ui/app_list/search/os_settings_provider.cc +++ b/chrome/browser/ui/app_list/search/os_settings_provider.cc
@@ -126,8 +126,8 @@ set_id(kOsSettingsResultPrefix + url_path_); SetCategory(Category::kSettings); set_relevance(relevance_score); - SetTitle(result->canonical_result_text); - SetTitleTags(CalculateTags(query, result->canonical_result_text)); + SetTitle(result->canonical_text); + SetTitleTags(CalculateTags(query, result->canonical_text)); SetResultType(ResultType::kOsSettings); SetDisplayType(DisplayType::kList); SetMetricsType(ash::OS_SETTINGS); @@ -349,7 +349,7 @@ Observe(nullptr); } -void OsSettingsProvider::OnSearchResultAvailabilityChanged() { +void OsSettingsProvider::OnSearchResultsChanged() { if (last_query_.empty()) return; @@ -376,7 +376,7 @@ // results meeting extra requirements. Perform this check before checking // for duplicates to ensure a rejected alternate result doesn't preclude a // canonical result with a lower score from being shown. - if (result->result_text != result->canonical_result_text && + if (result->text != result->canonical_text && (!accept_alternate_matches_ || query.size() < min_query_length_for_alternates_ || result->relevance_score < min_score_for_alternates_)) {
diff --git a/chrome/browser/ui/app_list/search/os_settings_provider.h b/chrome/browser/ui/app_list/search/os_settings_provider.h index 7449024a..824bc03 100644 --- a/chrome/browser/ui/app_list/search/os_settings_provider.h +++ b/chrome/browser/ui/app_list/search/os_settings_provider.h
@@ -81,7 +81,7 @@ apps::AppRegistryCache* cache) override; // mojom::SearchResultsObserver: - void OnSearchResultAvailabilityChanged() override; + void OnSearchResultsChanged() override; private: void OnSearchReturned(
diff --git a/chrome/browser/ui/app_list/search/search_controller.h b/chrome/browser/ui/app_list/search/search_controller.h index c5bd10b..072cbe9 100644 --- a/chrome/browser/ui/app_list/search/search_controller.h +++ b/chrome/browser/ui/app_list/search/search_controller.h
@@ -107,9 +107,6 @@ // Sends training signal to each |providers_| virtual void Train(LaunchData&& launch_data) = 0; - // Invoked when the app list is shown. - virtual void AppListShown() = 0; - // Gets the length of the most recent query. // TODO(crbug.com/1199206): This should be replaced with calls to // get_query().size().
diff --git a/chrome/browser/ui/app_list/search/search_controller_factory.cc b/chrome/browser/ui/app_list/search/search_controller_factory.cc index 3e67702..c3ee67bd 100644 --- a/chrome/browser/ui/app_list/search/search_controller_factory.cc +++ b/chrome/browser/ui/app_list/search/search_controller_factory.cc
@@ -188,7 +188,7 @@ size_t help_app_group_id = controller->AddGroup(kGenericMaxResults); controller->AddProvider(help_app_group_id, - std::make_unique<HelpAppProvider>(profile)); + std::make_unique<HelpAppProvider>(profile, notifier)); if (search_features::IsLauncherGameSearchEnabled()) { size_t games_group_id = controller->AddGroup(kGenericMaxResults);
diff --git a/chrome/browser/ui/app_list/search/search_controller_impl.cc b/chrome/browser/ui/app_list/search/search_controller_impl.cc index c62e1e4..86fdb3d 100644 --- a/chrome/browser/ui/app_list/search/search_controller_impl.cc +++ b/chrome/browser/ui/app_list/search/search_controller_impl.cc
@@ -259,11 +259,6 @@ mixer_->Train(launch_data); } -void SearchControllerImpl::AppListShown() { - for (const auto& provider : providers_) - provider->AppListShown(); -} - void SearchControllerImpl::AddObserver(Observer* observer) { observer_list_.AddObserver(observer); }
diff --git a/chrome/browser/ui/app_list/search/search_controller_impl.h b/chrome/browser/ui/app_list/search/search_controller_impl.h index 2c1ddef..738bab5 100644 --- a/chrome/browser/ui/app_list/search/search_controller_impl.h +++ b/chrome/browser/ui/app_list/search/search_controller_impl.h
@@ -70,7 +70,6 @@ ChromeSearchResult* GetResultByTitleForTest( const std::string& title) override; void Train(LaunchData&& launch_data) override; - void AppListShown() override; int GetLastQueryLength() const override; void OnSearchResultsImpressionMade( const std::u16string& trimmed_query,
diff --git a/chrome/browser/ui/app_list/search/search_controller_impl_new.cc b/chrome/browser/ui/app_list/search/search_controller_impl_new.cc index 3a42a29..f23711d 100644 --- a/chrome/browser/ui/app_list/search/search_controller_impl_new.cc +++ b/chrome/browser/ui/app_list/search/search_controller_impl_new.cc
@@ -512,11 +512,6 @@ ranker_->Train(launch_data); } -void SearchControllerImplNew::AppListShown() { - for (const auto& provider : providers_) - provider->AppListShown(); -} - void SearchControllerImplNew::ViewClosing() { for (const auto& provider : providers_) provider->ViewClosing();
diff --git a/chrome/browser/ui/app_list/search/search_controller_impl_new.h b/chrome/browser/ui/app_list/search/search_controller_impl_new.h index 13ca9b8..5f2936b 100644 --- a/chrome/browser/ui/app_list/search/search_controller_impl_new.h +++ b/chrome/browser/ui/app_list/search/search_controller_impl_new.h
@@ -72,7 +72,6 @@ ChromeSearchResult* GetResultByTitleForTest( const std::string& title) override; void Train(LaunchData&& launch_data) override; - void AppListShown() override; void ViewClosing() override; int GetLastQueryLength() const override; void OnSearchResultsImpressionMade(
diff --git a/chrome/browser/ui/app_list/search/search_provider.h b/chrome/browser/ui/app_list/search/search_provider.h index 052c5ef..401ad0a 100644 --- a/chrome/browser/ui/app_list/search/search_provider.h +++ b/chrome/browser/ui/app_list/search/search_provider.h
@@ -42,9 +42,6 @@ // training signals for results of any |RankingItemType|, so it is the // |SearchProvider|'s responsibility to check |type| and ignore if necessary. virtual void Train(const std::string& id, RankingItemType type) {} - // Invoked when the app list is shown. This can optionally be used by a - // provider to eg. warm up a cache of results. - virtual void AppListShown() {} // Returns the main result type created by this provider. virtual ash::AppListSearchResultType ResultType() const = 0;
diff --git a/chrome/browser/ui/app_list/search/test/test_search_controller.cc b/chrome/browser/ui/app_list/search/test/test_search_controller.cc index b193153..e6fe341 100644 --- a/chrome/browser/ui/app_list/search/test/test_search_controller.cc +++ b/chrome/browser/ui/app_list/search/test/test_search_controller.cc
@@ -52,8 +52,6 @@ void TestSearchController::Train(LaunchData&& launch_data) {} -void TestSearchController::AppListShown() {} - int TestSearchController::GetLastQueryLength() const { return 0; }
diff --git a/chrome/browser/ui/app_list/search/test/test_search_controller.h b/chrome/browser/ui/app_list/search/test/test_search_controller.h index aa2b82e0..6176112 100644 --- a/chrome/browser/ui/app_list/search/test/test_search_controller.h +++ b/chrome/browser/ui/app_list/search/test/test_search_controller.h
@@ -41,7 +41,6 @@ ChromeSearchResult* GetResultByTitleForTest( const std::string& title) override; void Train(LaunchData&& launch_data) override; - void AppListShown() override; int GetLastQueryLength() const override; void OnSearchResultsImpressionMade( const std::u16string& trimmed_query,
diff --git a/chrome/browser/ui/app_list/test/test_app_list_controller.cc b/chrome/browser/ui/app_list/test/test_app_list_controller.cc index b127051..3341aba2 100644 --- a/chrome/browser/ui/app_list/test/test_app_list_controller.cc +++ b/chrome/browser/ui/app_list/test/test_app_list_controller.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/ui/app_list/test/test_app_list_controller.h" +#include "ash/public/cpp/app_list/app_list_controller_observer.h" #include "chrome/browser/ui/app_list/app_list_client_impl.h" #include "chrome/browser/ui/app_list/app_list_model_updater.h" @@ -16,20 +17,38 @@ return AppListClientImpl::GetInstance(); } +void TestAppListController::AddObserver( + ash::AppListControllerObserver* observer) { + observers_.AddObserver(observer); +} + +void TestAppListController::RemoveObserver( + ash::AppListControllerObserver* observer) { + observers_.RemoveObserver(observer); +} + aura::Window* TestAppListController::GetWindow() { NOTIMPLEMENTED(); return nullptr; } +void TestAppListController::ShowAppList() { + visible_ = true; + NotifyAppListVisibilityChanged(); +} + +void TestAppListController::DismissAppList() { + visible_ = false; + NotifyAppListVisibilityChanged(); +} + bool TestAppListController::IsVisible( const absl::optional<int64_t>& display_id) { - NOTIMPLEMENTED(); - return false; + return visible_; } bool TestAppListController::IsVisible() { - NOTIMPLEMENTED(); - return false; + return visible_; } void TestAppListController::UpdateAppListWithNewTemporarySortOrder( @@ -45,4 +64,14 @@ std::move(update_position_closure).Run(); } +void TestAppListController::NotifyAppListVisibilityChanged() { + for (auto& observer : observers_) { + observer.OnAppListVisibilityWillChange(visible_, /*display_id=*/-1); + } + for (auto& observer : observers_) { + observer.OnAppListVisibilityWillChange(visible_, + /*display_id=*/-1); + } +} + } // namespace test
diff --git a/chrome/browser/ui/app_list/test/test_app_list_controller.h b/chrome/browser/ui/app_list/test/test_app_list_controller.h index f36fd13e..f637318 100644 --- a/chrome/browser/ui/app_list/test/test_app_list_controller.h +++ b/chrome/browser/ui/app_list/test/test_app_list_controller.h
@@ -7,10 +7,18 @@ #include "ash/public/cpp/app_list/app_list_controller.h" +#include "base/observer_list.h" + +namespace ash { +class AppListControllerObserver; +} + namespace test { // A fake app list controller used by browser side unit tests to emulate the // interaction between browser and ash in tests. +// Currently, it only tracks app list visibility updates using ShowAppList() and +// DismissAppList(). class TestAppListController : public ash::AppListController { public: TestAppListController(); @@ -21,17 +29,17 @@ // ash::AppListController: void SetClient(ash::AppListClient* client) override {} ash::AppListClient* GetClient() override; - void AddObserver(ash::AppListControllerObserver* observer) override {} - void RemoveObserver(ash::AppListControllerObserver* obsever) override {} + void AddObserver(ash::AppListControllerObserver* observer) override; + void RemoveObserver(ash::AppListControllerObserver* obsever) override; void SetActiveModel(int profile_id, ash::AppListModel* model, ash::SearchModel* search_model) override {} void ClearActiveModel() override {} void NotifyProcessSyncChangesFinished() override {} - void DismissAppList() override {} + void ShowAppList() override; + void DismissAppList() override; void GetAppInfoDialogBounds( GetAppInfoDialogBoundsCallback callback) override {} - void ShowAppList() override {} aura::Window* GetWindow() override; bool IsVisible(const absl::optional<int64_t>& display_id) override; bool IsVisible() override; @@ -40,6 +48,14 @@ bool animate, base::OnceClosure update_position_closure) override; void HideContinueSection() override {} + + private: + void NotifyAppListVisibilityChanged(); + + // The visibility state set using (Show|Dismiss)AppList. + bool visible_ = false; + + base::ObserverList<ash::AppListControllerObserver> observers_; }; } // namespace test
diff --git a/chrome/browser/ui/ash/holding_space/BUILD.gn b/chrome/browser/ui/ash/holding_space/BUILD.gn index 974b67e..4224d6fb 100644 --- a/chrome/browser/ui/ash/holding_space/BUILD.gn +++ b/chrome/browser/ui/ash/holding_space/BUILD.gn
@@ -60,6 +60,7 @@ "//base/test:test_support", "//chrome/browser", "//chrome/browser/ash", + "//chrome/browser/chromeos:test_support", "//chrome/browser/extensions", "//chrome/browser/ui", "//chrome/browser/web_applications:browser_tests_base",
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_browsertest_base.cc b/chrome/browser/ui/ash/holding_space/holding_space_browsertest_base.cc index 66e1a10..84dd77d1 100644 --- a/chrome/browser/ui/ash/holding_space/holding_space_browsertest_base.cc +++ b/chrome/browser/ui/ash/holding_space/holding_space_browsertest_base.cc
@@ -18,6 +18,7 @@ #include "base/test/bind.h" #include "base/unguessable_token.h" #include "chrome/browser/ash/file_manager/path_util.h" +#include "chrome/browser/ash/login/test/session_manager_state_waiter.h" #include "chrome/browser/extensions/component_loader.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/ash/holding_space/holding_space_keyed_service.h" @@ -80,46 +81,6 @@ return CreateFile(profile, "png"); } -// SessionStateWaiter ---------------------------------------------------------- - -// Utility class which allows waiting for a `session_manager::SessionState`. -class SessionStateWaiter : public session_manager::SessionManagerObserver { - public: - SessionStateWaiter() { - session_manager_observation_.Observe( - session_manager::SessionManager::Get()); - } - - void WaitFor(session_manager::SessionState state) { - if (session_state() == state) - return; - - state_ = state; - - wait_loop_ = std::make_unique<base::RunLoop>(); - wait_loop_->Run(); - wait_loop_.reset(); - } - - private: - // session_manager::SessionManagerObserver: - void OnSessionStateChanged() override { - if (wait_loop_ && session_state() == state_) - wait_loop_->Quit(); - } - - session_manager::SessionState session_state() const { - return session_manager::SessionManager::Get()->session_state(); - } - - session_manager::SessionState state_ = session_manager::SessionState::UNKNOWN; - std::unique_ptr<base::RunLoop> wait_loop_; - - base::ScopedObservation<session_manager::SessionManager, - session_manager::SessionManagerObserver> - session_manager_observation_{this}; -}; - } // namespace // HoldingSpaceBrowserTestBase ------------------------------------------------- @@ -214,7 +175,7 @@ return; chromeos::SessionManagerClient::Get()->RequestLockScreen(); - SessionStateWaiter().WaitFor(session_manager::SessionState::LOCKED); + SessionStateWaiter(session_manager::SessionState::LOCKED).Wait(); } } // namespace ash
diff --git a/chrome/browser/ui/ash/test_wallpaper_controller.cc b/chrome/browser/ui/ash/test_wallpaper_controller.cc index df61114..2ad449a 100644 --- a/chrome/browser/ui/ash/test_wallpaper_controller.cc +++ b/chrome/browser/ui/ash/test_wallpaper_controller.cc
@@ -97,9 +97,12 @@ NOTIMPLEMENTED(); } -void TestWallpaperController::SetDefaultWallpaper(const AccountId& account_id, - bool show_wallpaper) { +void TestWallpaperController::SetDefaultWallpaper( + const AccountId& account_id, + bool show_wallpaper, + SetWallpaperCallback callback) { ++set_default_wallpaper_count_; + std::move(callback).Run(/*success=*/true); } void TestWallpaperController::SetCustomizedDefaultWallpaperPaths(
diff --git a/chrome/browser/ui/ash/test_wallpaper_controller.h b/chrome/browser/ui/ash/test_wallpaper_controller.h index e0fdfb4..e912f8a1 100644 --- a/chrome/browser/ui/ash/test_wallpaper_controller.h +++ b/chrome/browser/ui/ash/test_wallpaper_controller.h
@@ -9,6 +9,7 @@ #include "ash/public/cpp/wallpaper/online_wallpaper_params.h" #include "ash/public/cpp/wallpaper/wallpaper_controller.h" #include "ash/public/cpp/wallpaper/wallpaper_types.h" +#include "base/files/file_path.h" #include "base/observer_list.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/gfx/image/image_skia.h" @@ -85,7 +86,8 @@ void SetGooglePhotosWallpaper(const ash::GooglePhotosWallpaperParams& params, SetWallpaperCallback callback) override; void SetDefaultWallpaper(const AccountId& account_id, - bool show_wallpaper) override; + bool show_wallpaper, + SetWallpaperCallback callback) override; void SetCustomizedDefaultWallpaperPaths( const base::FilePath& customized_default_small_path, const base::FilePath& customized_default_large_path) override;
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc b/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc index 6a8a4ee..d4bcb07a 100644 --- a/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc +++ b/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc
@@ -701,11 +701,13 @@ void WallpaperControllerClientImpl::SetDefaultWallpaper( const AccountId& account_id, - bool show_wallpaper) { + bool show_wallpaper, + ash::WallpaperController::SetWallpaperCallback callback) { if (!IsKnownUser(account_id)) return; - wallpaper_controller_->SetDefaultWallpaper(account_id, show_wallpaper); + wallpaper_controller_->SetDefaultWallpaper(account_id, show_wallpaper, + std::move(callback)); } void WallpaperControllerClientImpl::MigrateCollectionIdFromChromeApp(
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client_impl.h b/chrome/browser/ui/ash/wallpaper_controller_client_impl.h index e6f1e4a1..a8c9654 100644 --- a/chrome/browser/ui/ash/wallpaper_controller_client_impl.h +++ b/chrome/browser/ui/ash/wallpaper_controller_client_impl.h
@@ -63,8 +63,10 @@ // ash::WallpaperControllerClient: void OpenWallpaperPicker() override; void MaybeClosePreviewWallpaper() override; - void SetDefaultWallpaper(const AccountId& account_id, - bool show_wallpaper) override; + void SetDefaultWallpaper( + const AccountId& account_id, + bool show_wallpaper, + ash::WallpaperController::SetWallpaperCallback callback) override; void MigrateCollectionIdFromChromeApp( const AccountId& account_id, base::OnceCallback<void(const std::string&)> result_callback) override;
diff --git a/chrome/browser/ui/blocked_content/tab_under_navigation_throttle.cc b/chrome/browser/ui/blocked_content/tab_under_navigation_throttle.cc index 0d190c8..1424ba9 100644 --- a/chrome/browser/ui/blocked_content/tab_under_navigation_throttle.cc +++ b/chrome/browser/ui/blocked_content/tab_under_navigation_throttle.cc
@@ -27,7 +27,6 @@ #include "components/content_settings/core/common/content_settings.h" #include "components/content_settings/core/common/content_settings_types.h" #include "components/pref_registry/pref_registry_syncable.h" -#include "components/ukm/content/source_url_recorder.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_frame_host.h" @@ -94,7 +93,7 @@ // previous navigation commit. ukm::UkmRecorder* ukm_recorder = ukm::UkmRecorder::Get(); ukm::SourceId opener_source_id = - ukm::GetSourceIdForWebContentsDocument(handle->GetWebContents()); + handle->GetWebContents()->GetMainFrame()->GetPageUkmSourceId(); if (opener_source_id != ukm::kInvalidSourceId && ukm_recorder) { ukm::builders::AbusiveExperienceHeuristic_TabUnder(opener_source_id) .SetDidTabUnder(true)
diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h index 1ce30e7..221fc4e3 100644 --- a/chrome/browser/ui/browser_window.h +++ b/chrome/browser/ui/browser_window.h
@@ -70,7 +70,6 @@ } namespace qrcode_generator { -class QRCodeGeneratorBubbleController; class QRCodeGeneratorBubbleView; } // namespace qrcode_generator @@ -79,14 +78,11 @@ } namespace send_tab_to_self { -class SendTabToSelfBubbleController; class SendTabToSelfBubbleView; } // namespace send_tab_to_self namespace sharing_hub { -class ScreenshotCapturedBubbleController; class ScreenshotCapturedBubble; -class SharingHubBubbleController; class SharingHubBubbleView; } // namespace sharing_hub @@ -425,22 +421,18 @@ // Shows the Screenshot bubble. virtual sharing_hub::ScreenshotCapturedBubble* ShowScreenshotCapturedBubble( content::WebContents* contents, - const gfx::Image& image, - sharing_hub::ScreenshotCapturedBubbleController* controller) = 0; + const gfx::Image& image) = 0; // Shows the QR Code generator bubble. |url| is the URL for the initial code. virtual qrcode_generator::QRCodeGeneratorBubbleView* - ShowQRCodeGeneratorBubble( - content::WebContents* contents, - qrcode_generator::QRCodeGeneratorBubbleController* controller, - const GURL& url, - bool show_back_button) = 0; + ShowQRCodeGeneratorBubble(content::WebContents* contents, + const GURL& url, + bool show_back_button) = 0; // Shows the "send tab to self" bubble. This must only be called as a direct // result of user action. virtual send_tab_to_self::SendTabToSelfBubbleView* ShowSendTabToSelfBubble( - content::WebContents* contents, - send_tab_to_self::SendTabToSelfBubbleController* controller) = 0; + content::WebContents* contents) = 0; #if BUILDFLAG(IS_CHROMEOS_ASH) // Returns the PageActionIconView for the Sharing Hub. @@ -449,8 +441,7 @@ // Shows the Sharing Hub bubble. This must only be called as a direct result // of user action. virtual sharing_hub::SharingHubBubbleView* ShowSharingHubBubble( - content::WebContents* contents, - sharing_hub::SharingHubBubbleController* controller) = 0; + content::WebContents* contents) = 0; #endif // Shows the translate bubble.
diff --git a/chrome/browser/ui/color/chrome_color_id.h b/chrome/browser/ui/color/chrome_color_id.h index 36cb2e92..58b01d5 100644 --- a/chrome/browser/ui/color/chrome_color_id.h +++ b/chrome/browser/ui/color/chrome_color_id.h
@@ -29,7 +29,7 @@ ThemeProperties::COLOR_BOOKMARK_BAR_BACKGROUND) \ E(kColorBookmarkBarForeground, ThemeProperties::COLOR_BOOKMARK_TEXT) \ E(kColorBookmarkBarSeparator, ThemeProperties::COLOR_BOOKMARK_SEPARATOR) \ - E(kColorBookmarkButtonIcon, ThemeProperties::COLOR_BOOKMARK_BUTTON_ICON) \ + E_CPONLY(kColorBookmarkButtonIcon) \ E_CPONLY(kColorBookmarkDragImageBackground) \ E_CPONLY(kColorBookmarkDragImageCountBackground) \ E_CPONLY(kColorBookmarkDragImageCountForeground) \ @@ -53,16 +53,13 @@ E_CPONLY(kColorDownloadItemProgressRingBackground) \ E_CPONLY(kColorDownloadItemProgressRingForeground) \ E(kColorDownloadShelfBackground, ThemeProperties::COLOR_DOWNLOAD_SHELF) \ - E(kColorDownloadShelfButtonBackground, \ - ThemeProperties::COLOR_DOWNLOAD_SHELF_BUTTON_BACKGROUND) \ - E(kColorDownloadShelfButtonText, \ - ThemeProperties::COLOR_DOWNLOAD_SHELF_BUTTON_TEXT) \ + E_CPONLY(kColorDownloadShelfButtonBackground) \ + E_CPONLY(kColorDownloadShelfButtonText) \ E_CPONLY(kColorDownloadShelfButtonIcon) \ E_CPONLY(kColorDownloadShelfButtonIconDisabled) \ E(kColorDownloadShelfContentAreaSeparator, \ ThemeProperties::COLOR_DOWNLOAD_SHELF_CONTENT_AREA_SEPARATOR) \ - E(kColorDownloadShelfForeground, \ - ThemeProperties::COLOR_DOWNLOAD_SHELF_FOREGROUND) \ + E_CPONLY(kColorDownloadShelfForeground) \ E_CPONLY(kColorDownloadStartedAnimationForeground) \ E_CPONLY(kColorDownloadToolbarButtonActive) \ E_CPONLY(kColorDownloadToolbarButtonInactive) \ @@ -119,7 +116,7 @@ E_CPONLY(kColorInfoBarButtonIconDisabled) \ E(kColorInfoBarContentAreaSeparator, \ ThemeProperties::COLOR_INFOBAR_CONTENT_AREA_SEPARATOR) \ - E(kColorInfoBarForeground, ThemeProperties::COLOR_INFOBAR_TEXT) \ + E_CPONLY(kColorInfoBarForeground) \ /* Location bar colors. */ \ E(kColorLocationBarBorder, ThemeProperties::COLOR_LOCATION_BAR_BORDER) \ E(kColorLocationBarBorderOpaque, \
diff --git a/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.cc b/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.cc index 97e6e34..bf98067 100644 --- a/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.cc +++ b/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.cc
@@ -15,7 +15,6 @@ #include "components/password_manager/core/browser/well_known_change_password_state.h" #include "components/password_manager/core/browser/well_known_change_password_util.h" #include "components/password_manager/core/common/password_manager_features.h" -#include "components/ukm/content/source_url_recorder.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/page_navigator.h" @@ -82,7 +81,7 @@ : NavigationThrottle(handle), request_url_(handle->GetURL()), source_id_( - ukm::GetSourceIdForWebContentsDocument(handle->GetWebContents())) { + handle->GetWebContents()->GetMainFrame()->GetPageUkmSourceId()) { // If this is a prerender navigation, we're only constructing the throttle // so it can cancel the prerender. if (handle->IsInPrerenderedMainFrame())
diff --git a/chrome/browser/ui/qrcode_generator/qrcode_generator_bubble_controller.cc b/chrome/browser/ui/qrcode_generator/qrcode_generator_bubble_controller.cc index 751d729..bfb37053c 100644 --- a/chrome/browser/ui/qrcode_generator/qrcode_generator_bubble_controller.cc +++ b/chrome/browser/ui/qrcode_generator/qrcode_generator_bubble_controller.cc
@@ -50,7 +50,7 @@ bubble_shown_ = true; qrcode_generator_bubble_ = browser->window()->ShowQRCodeGeneratorBubble( - &GetWebContents(), this, url, show_back_button); + &GetWebContents(), url, show_back_button); UpdateIcon(); }
diff --git a/chrome/browser/ui/send_tab_to_self/send_tab_to_self_bubble_controller.cc b/chrome/browser/ui/send_tab_to_self/send_tab_to_self_bubble_controller.cc index 7d7ba22..c1d409b 100644 --- a/chrome/browser/ui/send_tab_to_self/send_tab_to_self_bubble_controller.cc +++ b/chrome/browser/ui/send_tab_to_self/send_tab_to_self_bubble_controller.cc
@@ -64,7 +64,7 @@ bubble_shown_ = true; Browser* browser = chrome::FindBrowserWithWebContents(&GetWebContents()); send_tab_to_self_bubble_view_ = - browser->window()->ShowSendTabToSelfBubble(&GetWebContents(), this); + browser->window()->ShowSendTabToSelfBubble(&GetWebContents()); if (sharing_hub::SharingHubOmniboxEnabled( GetWebContents().GetBrowserContext())) {
diff --git a/chrome/browser/ui/sharing_hub/screenshot/screenshot_captured_bubble_controller.cc b/chrome/browser/ui/sharing_hub/screenshot/screenshot_captured_bubble_controller.cc index 4ffc547c..8f6f619 100644 --- a/chrome/browser/ui/sharing_hub/screenshot/screenshot_captured_bubble_controller.cc +++ b/chrome/browser/ui/sharing_hub/screenshot/screenshot_captured_bubble_controller.cc
@@ -35,7 +35,7 @@ .WriteImage(*captured_image.ToSkBitmap()); Browser* browser = chrome::FindBrowserWithWebContents(&GetWebContents()); browser->window()->ShowScreenshotCapturedBubble(&GetWebContents(), - captured_image, this); + captured_image); } void ScreenshotCapturedBubbleController::HideBubble() {
diff --git a/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.cc b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.cc index 898ee54c..f2c45d6 100644 --- a/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.cc +++ b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.cc
@@ -125,7 +125,7 @@ ShowSharesheet(browser->window()->GetSharingHubIconButton()); #else sharing_hub_bubble_view_ = - browser->window()->ShowSharingHubBubble(web_contents(), this); + browser->window()->ShowSharingHubBubble(web_contents()); #endif share::LogShareSourceDesktop(share::ShareSourceDesktop::kOmniboxSharingHub);
diff --git a/chrome/browser/ui/views/autofill/payments/card_unmask_otp_input_dialog_views.cc b/chrome/browser/ui/views/autofill/payments/card_unmask_otp_input_dialog_views.cc index 3448afd1..abd7173 100644 --- a/chrome/browser/ui/views/autofill/payments/card_unmask_otp_input_dialog_views.cc +++ b/chrome/browser/ui/views/autofill/payments/card_unmask_otp_input_dialog_views.cc
@@ -282,7 +282,6 @@ &CardUnmaskOtpInputDialogViews::OnNewCodeLinkClicked, weak_ptr_factory_.GetWeakPtr())); } else { - style_info.disable_line_wrapping = true; style_info.text_style = views::style::STYLE_DISABLED; } footer_label_->AddStyleRange(
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc index ac275bdf..3b3ea70b 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
@@ -2061,7 +2061,7 @@ apps_page_shortcut_->SetEnabledTextColors(color); const SkColor overflow_color = - theme_provider->GetColor(ThemeProperties::COLOR_BOOKMARK_BUTTON_ICON); + GetColorProvider()->GetColor(kColorBookmarkButtonIcon); const bool touch_ui = ui::TouchUiController::Get()->touch_ui(); overflow_button_->SetImageModel( views::Button::STATE_NORMAL,
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index e40fe07..7a0d81b 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -2290,11 +2290,11 @@ } qrcode_generator::QRCodeGeneratorBubbleView* -BrowserView::ShowQRCodeGeneratorBubble( - content::WebContents* contents, - qrcode_generator::QRCodeGeneratorBubbleController* controller, - const GURL& url, - bool show_back_button) { +BrowserView::ShowQRCodeGeneratorBubble(content::WebContents* contents, + const GURL& url, + bool show_back_button) { + auto* controller = + qrcode_generator::QRCodeGeneratorBubbleController::Get(contents); base::OnceClosure on_closing = controller->GetOnBubbleClosedCallback(); base::OnceClosure on_back_button_pressed; if (show_back_button) { @@ -2302,14 +2302,13 @@ } PageActionIconType icon_type = - sharing_hub::SharingHubOmniboxEnabled(contents->GetBrowserContext()) + sharing_hub::SharingHubOmniboxEnabled(browser_->profile()) ? PageActionIconType::kSharingHub : PageActionIconType::kQRCodeGenerator; - qrcode_generator::QRCodeGeneratorBubble* bubble = - new qrcode_generator::QRCodeGeneratorBubble( - toolbar_button_provider()->GetAnchorView(icon_type), contents, - std::move(on_closing), std::move(on_back_button_pressed), url); + auto* bubble = new qrcode_generator::QRCodeGeneratorBubble( + toolbar_button_provider()->GetAnchorView(icon_type), contents, + std::move(on_closing), std::move(on_back_button_pressed), url); PageActionIconView* icon_view = toolbar_button_provider()->GetPageActionIconView(icon_type); @@ -2323,16 +2322,12 @@ } sharing_hub::ScreenshotCapturedBubble* -BrowserView::ShowScreenshotCapturedBubble( - content::WebContents* contents, - const gfx::Image& image, - sharing_hub::ScreenshotCapturedBubbleController* controller) { - sharing_hub::ScreenshotCapturedBubble* bubble = - new sharing_hub::ScreenshotCapturedBubble( - toolbar_button_provider()->GetAnchorView( - PageActionIconType::kSharingHub), - contents, image, browser_->profile(), - base::BindOnce(base::IgnoreResult(&Navigate))); +BrowserView::ShowScreenshotCapturedBubble(content::WebContents* contents, + const gfx::Image& image) { + auto* bubble = new sharing_hub::ScreenshotCapturedBubble( + toolbar_button_provider()->GetAnchorView(PageActionIconType::kSharingHub), + contents, image, browser_->profile(), + base::BindOnce(base::IgnoreResult(&Navigate))); views::BubbleDialogDelegateView::CreateBubble(bubble); bubble->ShowForReason(LocationBarBubbleDelegateView::USER_GESTURE); @@ -2353,17 +2348,14 @@ } send_tab_to_self::SendTabToSelfBubbleView* BrowserView::ShowSendTabToSelfBubble( - content::WebContents* web_contents, - send_tab_to_self::SendTabToSelfBubbleController* controller) { + content::WebContents* web_contents) { PageActionIconType icon_type = - sharing_hub::SharingHubOmniboxEnabled(web_contents->GetBrowserContext()) + sharing_hub::SharingHubOmniboxEnabled(browser_->profile()) ? PageActionIconType::kSharingHub : PageActionIconType::kSendTabToSelf; - send_tab_to_self::SendTabToSelfBubbleViewImpl* bubble = - new send_tab_to_self::SendTabToSelfBubbleViewImpl( - toolbar_button_provider()->GetAnchorView(icon_type), web_contents, - controller); + auto* bubble = new send_tab_to_self::SendTabToSelfBubbleViewImpl( + toolbar_button_provider()->GetAnchorView(icon_type), web_contents); PageActionIconView* icon_view = toolbar_button_provider()->GetPageActionIconView(icon_type); if (icon_view) @@ -2382,13 +2374,10 @@ } #else sharing_hub::SharingHubBubbleView* BrowserView::ShowSharingHubBubble( - content::WebContents* web_contents, - sharing_hub::SharingHubBubbleController* controller) { - sharing_hub::SharingHubBubbleViewImpl* bubble = - new sharing_hub::SharingHubBubbleViewImpl( - toolbar_button_provider()->GetAnchorView( - PageActionIconType::kSharingHub), - web_contents, controller); + content::WebContents* web_contents) { + auto* bubble = new sharing_hub::SharingHubBubbleViewImpl( + toolbar_button_provider()->GetAnchorView(PageActionIconType::kSharingHub), + web_contents); PageActionIconView* icon_view = toolbar_button_provider()->GetPageActionIconView( PageActionIconType::kSharingHub);
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h index 9c94904..1198262 100644 --- a/chrome/browser/ui/views/frame/browser_view.h +++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -491,22 +491,18 @@ void ShowBookmarkBubble(const GURL& url, bool already_bookmarked) override; sharing_hub::ScreenshotCapturedBubble* ShowScreenshotCapturedBubble( content::WebContents* contents, - const gfx::Image& image, - sharing_hub::ScreenshotCapturedBubbleController* controller) override; + const gfx::Image& image) override; qrcode_generator::QRCodeGeneratorBubbleView* ShowQRCodeGeneratorBubble( content::WebContents* contents, - qrcode_generator::QRCodeGeneratorBubbleController* controller, const GURL& url, bool show_back_button) override; send_tab_to_self::SendTabToSelfBubbleView* ShowSendTabToSelfBubble( - content::WebContents* contents, - send_tab_to_self::SendTabToSelfBubbleController* controller) override; + content::WebContents* contents) override; #if BUILDFLAG(IS_CHROMEOS_ASH) views::Button* GetSharingHubIconButton() override; #else sharing_hub::SharingHubBubbleView* ShowSharingHubBubble( - content::WebContents* contents, - sharing_hub::SharingHubBubbleController* controller) override; + content::WebContents* contents) override; #endif ShowTranslateBubbleResult ShowTranslateBubble( content::WebContents* contents,
diff --git a/chrome/browser/ui/views/page_info/security_information_view.cc b/chrome/browser/ui/views/page_info/security_information_view.cc index 5a6232a..1b619db 100644 --- a/chrome/browser/ui/views/page_info/security_information_view.cc +++ b/chrome/browser/ui/views/page_info/security_information_view.cc
@@ -153,7 +153,6 @@ views::StyledLabel::RangeStyleInfo link_style = views::StyledLabel::RangeStyleInfo::CreateForLink( reset_decisions_callback); - link_style.disable_line_wrapping = false; reset_cert_decisions_label->AddStyleRange(link_range, link_style); // Adjust this label's width to the width of the label above.
diff --git a/chrome/browser/ui/views/passwords/password_generation_confirmation_view.cc b/chrome/browser/ui/views/passwords/password_generation_confirmation_view.cc index 7880b022..1933748 100644 --- a/chrome/browser/ui/views/passwords/password_generation_confirmation_view.cc +++ b/chrome/browser/ui/views/passwords/password_generation_confirmation_view.cc
@@ -47,7 +47,6 @@ views::StyledLabel::RangeStyleInfo::CreateForLink(base::BindRepeating( &PasswordGenerationConfirmationView::StyledLabelLinkClicked, base::Unretained(this))); - link_style.disable_line_wrapping = false; label->AddStyleRange(controller_.save_confirmation_link_range(), link_style);
diff --git a/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl.cc b/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl.cc index 9b9b7959..a6f4759d 100644 --- a/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl.cc +++ b/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl.cc
@@ -59,10 +59,11 @@ SendTabToSelfBubbleViewImpl::SendTabToSelfBubbleViewImpl( views::View* anchor_view, - content::WebContents* web_contents, - SendTabToSelfBubbleController* controller) + content::WebContents* web_contents) : LocationBarBubbleDelegateView(anchor_view, web_contents), - controller_(controller->AsWeakPtr()) { + controller_(SendTabToSelfBubbleController::CreateOrGetFromWebContents( + web_contents) + ->AsWeakPtr()) { DCHECK(controller_); SetButtons(ui::DIALOG_BUTTON_NONE); set_fixed_width(ChromeLayoutProvider::Get()->GetDistanceMetric(
diff --git a/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl.h b/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl.h index 4faa506a..82e81a48 100644 --- a/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl.h +++ b/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl.h
@@ -35,8 +35,7 @@ public: // Bubble will be anchored to |anchor_view|. SendTabToSelfBubbleViewImpl(views::View* anchor_view, - content::WebContents* web_contents, - SendTabToSelfBubbleController* controller); + content::WebContents* web_contents); SendTabToSelfBubbleViewImpl(const SendTabToSelfBubbleViewImpl&) = delete; SendTabToSelfBubbleViewImpl& operator=(const SendTabToSelfBubbleViewImpl&) =
diff --git a/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl_browsertest.cc b/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl_browsertest.cc index 5d5571d..57df828 100644 --- a/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl_browsertest.cc +++ b/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl_browsertest.cc
@@ -63,13 +63,11 @@ void ShowUi(const std::string& name) override { content::WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); - // Owned by WebContents. - TestSendTabToSelfBubbleController* controller = - new TestSendTabToSelfBubbleController(web_contents); - web_contents->SetUserData(TestSendTabToSelfBubbleController::UserDataKey(), - base::WrapUnique(controller)); + web_contents->SetUserData( + TestSendTabToSelfBubbleController::UserDataKey(), + std::make_unique<TestSendTabToSelfBubbleController>(web_contents)); BrowserView::GetBrowserViewForBrowser(browser())->ShowSendTabToSelfBubble( - web_contents, controller); + web_contents); } };
diff --git a/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl_unittest.cc b/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl_unittest.cc index 02e877c..f5079ca 100644 --- a/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl_unittest.cc +++ b/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl_unittest.cc
@@ -77,7 +77,7 @@ base::WrapUnique(controller_.get())); bubble_ = new SendTabToSelfBubbleViewImpl(anchor_widget_->GetContentsView(), - nullptr, controller_.get()); + web_contents_.get()); views::BubbleDialogDelegateView::CreateBubble(bubble_); }
diff --git a/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.cc b/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.cc index 233477d..ca381c19 100644 --- a/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.cc +++ b/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.cc
@@ -39,15 +39,15 @@ SharingHubBubbleViewImpl::SharingHubBubbleViewImpl( views::View* anchor_view, - content::WebContents* web_contents, - SharingHubBubbleController* controller) + content::WebContents* web_contents) : LocationBarBubbleDelegateView(anchor_view, web_contents), - controller_(controller) { + controller_(SharingHubBubbleController::CreateOrGetFromWebContents( + web_contents)) { SetButtons(ui::DIALOG_BUTTON_NONE); set_fixed_width(views::LayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_BUBBLE_PREFERRED_WIDTH)); SetEnableArrowKeyTraversal(true); - DCHECK(controller); + DCHECK(controller_); } SharingHubBubbleViewImpl::~SharingHubBubbleViewImpl() = default;
diff --git a/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.h b/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.h index e2a90e1..6220d23 100644 --- a/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.h +++ b/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.h
@@ -33,8 +33,7 @@ public: // Bubble will be anchored to |anchor_view|. SharingHubBubbleViewImpl(views::View* anchor_view, - content::WebContents* web_contents, - SharingHubBubbleController* controller); + content::WebContents* web_contents); SharingHubBubbleViewImpl(const SharingHubBubbleViewImpl&) = delete; SharingHubBubbleViewImpl& operator=(const SharingHubBubbleViewImpl&) = delete;
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.cc b/chrome/browser/ui/views/tabs/tab_drag_controller.cc index 6c14f996..705245e 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller.cc +++ b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
@@ -1977,12 +1977,16 @@ } // If source window was maximized - maximize the new window as well. -#if !BUILDFLAG(IS_WIN) && !BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS) +#if !BUILDFLAG(IS_WIN) && !BUILDFLAG(IS_LINUX) && \ + !BUILDFLAG(IS_CHROMEOS_LACROS) && !BUILDFLAG(IS_MAC) // Keeping maximized state breaks snap to Grid on Windows when dragging // tabs from maximized windows. TODO:(crbug.com/727051) Explore doing this // for other desktop OS's. kMaximizedStateRetainedOnTabDrag in // tab_drag_controller_interactive_uitest.cc will need to be initialized // to false on each desktop OS that changes this behavior. + // macOS opts out since this maps maximize to fullscreen, which can + // violate user expectations and interacts poorly with some window + // management actions. // // TODO(https://crbug.com/1252941): Remove the lacros if-clause above when // lacros understands the snapped window state types (eg
diff --git a/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_dialogs.cc b/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_dialogs.cc index f15643f..3398c117f 100644 --- a/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_dialogs.cc +++ b/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_dialogs.cc
@@ -11,25 +11,32 @@ #include "base/bind.h" #include "base/json/json_writer.h" #include "chrome/browser/ash/login/helper.h" +#include "chrome/browser/ash/login/profile_auth_data.h" #include "chrome/browser/ash/login/saml/in_session_password_sync_manager.h" #include "chrome/browser/ash/login/saml/in_session_password_sync_manager_factory.h" #include "chrome/browser/ash/login/ui/oobe_dialog_size_utils.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/webui/chromeos/in_session_password_change/base_lock_dialog.h" #include "chrome/browser/ui/webui/chromeos/in_session_password_change/confirm_password_change_handler.h" #include "chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_captive_portal_dialog.h" #include "chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_network_dialog.h" +#include "chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_handler.h" +#include "chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_start_reauth_ui.h" #include "chrome/common/webui_url_constants.h" #include "chrome/grit/browser_resources.h" #include "chrome/grit/generated_resources.h" +#include "chromeos/network/network_connection_handler.h" #include "chromeos/network/network_handler.h" #include "chromeos/network/network_state_handler.h" #include "components/web_modal/web_contents_modal_dialog_manager.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/notification_service.h" #include "content/public/browser/web_ui_data_source.h" +#include "services/network/public/mojom/network_context.mojom.h" #include "ui/aura/window.h" #include "ui/strings/grit/ui_strings.h" @@ -188,8 +195,10 @@ } void LockScreenStartReauthDialog::DismissLockScreenNetworkDialog() { - if (lock_screen_network_dialog_) + if (is_network_dialog_visible_ && lock_screen_network_dialog_) { + is_network_dialog_visible_ = false; lock_screen_network_dialog_->Dismiss(); + } } void LockScreenStartReauthDialog::DismissLockScreenCaptivePortalDialog() { @@ -249,6 +258,13 @@ base::MakeRefCounted<chromeos::NetworkStateInformer>()) { network_state_informer_->Init(); scoped_observation_.Observe(network_state_informer_.get()); + + registrar_.Add(this, chrome::NOTIFICATION_AUTH_NEEDED, + content::NotificationService::AllSources()); + registrar_.Add(this, chrome::NOTIFICATION_AUTH_SUPPLIED, + content::NotificationService::AllSources()); + registrar_.Add(this, chrome::NOTIFICATION_AUTH_CANCELLED, + content::NotificationService::AllSources()); } LockScreenStartReauthDialog::~LockScreenStartReauthDialog() { @@ -260,17 +276,31 @@ void LockScreenStartReauthDialog::UpdateState( NetworkError::ErrorReason reason) { + if (is_proxy_auth_in_progress_) + return; + const NetworkStateInformer::State state = network_state_informer_->state(); if (state == NetworkStateInformer::OFFLINE) { ShowLockScreenNetworkDialog(); } else if (state == NetworkStateInformer::CAPTIVE_PORTAL) { ShowLockScreenCaptivePortalDialog(); + } else if (state == NetworkStateInformer::PROXY_AUTH_REQUIRED) { + if (is_network_dialog_visible_) { + should_reload_gaia_ = true; + } } else { DismissLockScreenCaptivePortalDialog(); - if (is_network_dialog_visible_ && lock_screen_network_dialog_) { - is_network_dialog_visible_ = false; - lock_screen_network_dialog_->Close(); + DismissLockScreenNetworkDialog(); + } + if (should_reload_gaia_) { + DismissLockScreenNetworkDialog(); + LockScreenReauthHandler* reauth_handler = + static_cast<LockScreenStartReauthUI*>(webui()->GetController()) + ->GetMainHandler(); + if (reauth_handler->IsAuthenticatorLoaded({})) { + reauth_handler->ReloadGaia(); + should_reload_gaia_ = false; } } } @@ -308,4 +338,74 @@ modal_dialog_host_observer_list_.RemoveObserver(observer); } +void LockScreenStartReauthDialog::TransferHttpAuthCaches() { + content::StoragePartition* webview_storage_partition = + login::SigninPartitionManager::Factory::GetForBrowserContext(profile_) + ->GetCurrentStoragePartition(); + if (webview_storage_partition) { + // Transfer auth cache to system network context. This allows to preserve + // proxy credentials between different unlock attempts. + webview_storage_partition->GetNetworkContext() + ->SaveHttpAuthCacheProxyEntries( + base::BindOnce(&ash::TransferHttpAuthCacheToSystemNetworkContext, + base::DoNothing())); + + const user_manager::User* user = + user_manager::UserManager::Get()->GetActiveUser(); + Profile* profile = ProfileHelper::Get()->GetProfileByUser(user); + // Transfer auth cache to the active user's profile so that there is no need + // to enter them again after unlocking the device. + ash::ProfileAuthData::TransferHttpAuthCacheProxyEntries( + base::DoNothing(), webview_storage_partition, + profile->GetDefaultStoragePartition()); + } +} + +void LockScreenStartReauthDialog::Observe( + int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) { + switch (type) { + case chrome::NOTIFICATION_AUTH_NEEDED: { + is_proxy_auth_in_progress_ = true; + break; + } + case chrome::NOTIFICATION_AUTH_SUPPLIED: { + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce(&LockScreenStartReauthDialog::ReenableNetworkUpdates, + weak_factory_.GetWeakPtr()), + ash::kProxyAuthTimeout); + + base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce(&LockScreenStartReauthDialog::TransferHttpAuthCaches, + weak_factory_.GetWeakPtr()), + ash::kAuthCacheTransferDelayMs); + g_dialog->Focus(); + break; + } + case chrome::NOTIFICATION_AUTH_CANCELLED: { + ReenableNetworkUpdates(); + should_reload_gaia_ = true; + // If proxy authentication is canceled we disconnect from current network + // and it triggers offline state which leads to us showing network screen + // through `LockScreenStartReauthDialog::UpdateState`. + const std::string network_path = NetworkHandler::Get() + ->network_state_handler() + ->DefaultNetwork() + ->path(); + NetworkHandler::Get()->network_connection_handler()->DisconnectNetwork( + network_path, base::DoNothing(), network_handler::ErrorCallback()); + break; + } + default: + NOTREACHED() << "Unexpected notification " << type; + } +} + +void LockScreenStartReauthDialog::ReenableNetworkUpdates() { + is_proxy_auth_in_progress_ = false; +} + } // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_dialogs.h b/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_dialogs.h index d714d97..dd0f612c 100644 --- a/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_dialogs.h +++ b/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_dialogs.h
@@ -15,6 +15,8 @@ #include "chromeos/network/network_state_handler.h" #include "chromeos/network/network_state_handler_observer.h" #include "components/web_modal/web_contents_modal_dialog_host.h" +#include "content/public/browser/notification_observer.h" +#include "content/public/browser/notification_registrar.h" #include "ui/web_dialogs/web_dialog_ui.h" namespace chromeos { @@ -26,7 +28,8 @@ : public BaseLockDialog, public NetworkStateInformer::NetworkStateInformerObserver, public ChromeWebModalDialogManagerDelegate, - public web_modal::WebContentsModalDialogHost { + public web_modal::WebContentsModalDialogHost, + public content::NotificationObserver { public: LockScreenStartReauthDialog(); LockScreenStartReauthDialog(LockScreenStartReauthDialog const&) = delete; @@ -86,10 +89,23 @@ void AddObserver(web_modal::ModalDialogHostObserver* observer) override; void RemoveObserver(web_modal::ModalDialogHostObserver* observer) override; + // content::NotificationObserver: + void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) override; + + // Copies proxy authentication details that were entered in the lock screen + // profile to system network context and to the profile of active user. + void TransferHttpAuthCaches(); + + void ReenableNetworkUpdates(); + void OnCaptivePortalDialogReadyForTesting(); scoped_refptr<chromeos::NetworkStateInformer> network_state_informer_; bool is_network_dialog_visible_ = false; + bool is_proxy_auth_in_progress_ = false; + bool should_reload_gaia_ = false; base::ScopedObservation<NetworkStateInformer, NetworkStateInformerObserver> scoped_observation_{this}; @@ -99,6 +115,8 @@ std::unique_ptr<LockScreenCaptivePortalDialog> captive_portal_dialog_; + content::NotificationRegistrar registrar_; + // Callbacks that are used to notify tests that the corresponding dialog is // loaded. base::OnceClosure on_network_dialog_loaded_callback_for_testing_;
diff --git a/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_handler.cc b/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_handler.cc index 2dcae7bc..4852651 100644 --- a/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_handler.cc +++ b/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_handler.cc
@@ -318,6 +318,10 @@ CallJavascriptFunction(std::string(kMainElement) + "passwordChanged"); } +void LockScreenReauthHandler::ReloadGaia() { + CallJavascriptFunction(std::string(kMainElement) + "reloadAuthenticator"); +} + void LockScreenReauthHandler::RegisterMessages() { web_ui()->RegisterMessageCallback( "initialize",
diff --git a/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_handler.h b/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_handler.h index 45c64e2..931224090 100644 --- a/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_handler.h +++ b/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_handler.h
@@ -25,6 +25,8 @@ void ShowPasswordChangedScreen(); + void ReloadGaia(); + // WebUI message handlers. void HandleInitialize(const base::Value::List&); void HandleCompleteAuthentication(const base::Value::List&);
diff --git a/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_start_reauth_ui.h b/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_start_reauth_ui.h index e69dcf79..aa44120 100644 --- a/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_start_reauth_ui.h +++ b/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_start_reauth_ui.h
@@ -17,7 +17,7 @@ explicit LockScreenStartReauthUI(content::WebUI* web_ui); ~LockScreenStartReauthUI() override; - LockScreenReauthHandler* GetMainHandlerForTests() { return main_handler_; } + LockScreenReauthHandler* GetMainHandler() { return main_handler_; } private: // The main message handler.
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc index 33fb983..9837ea2 100644 --- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -36,6 +36,7 @@ #include "chrome/browser/ash/login/hwid_checker.h" #include "chrome/browser/ash/login/lock/screen_locker.h" #include "chrome/browser/ash/login/lock_screen_utils.h" +#include "chrome/browser/ash/login/profile_auth_data.h" #include "chrome/browser/ash/login/reauth_stats.h" #include "chrome/browser/ash/login/screens/gaia_screen.h" #include "chrome/browser/ash/login/screens/network_error.h" @@ -100,10 +101,6 @@ // current network. constexpr base::TimeDelta kOfflineTimeout = base::Seconds(1); -// Timeout to delay first notification about offline state when authenticating -// to a proxy. -constexpr base::TimeDelta kProxyAuthTimeout = base::Seconds(5); - // Timeout used to prevent infinite connecting to a flaky network. constexpr base::TimeDelta kConnectingTimeout = base::Seconds(60); @@ -422,7 +419,7 @@ base::BindOnce( &SigninScreenHandler::ReenableNetworkStateUpdatesAfterProxyAuth, weak_factory_.GetWeakPtr()), - kProxyAuthTimeout); + ash::kProxyAuthTimeout); } break; }
diff --git a/chrome/browser/ui/webui/chromeos/system_web_dialog_delegate.cc b/chrome/browser/ui/webui/chromeos/system_web_dialog_delegate.cc index 25433aa..918bb79 100644 --- a/chrome/browser/ui/webui/chromeos/system_web_dialog_delegate.cc +++ b/chrome/browser/ui/webui/chromeos/system_web_dialog_delegate.cc
@@ -39,13 +39,22 @@ } // Creates default initial parameters. The system web dialog has 12 dip corner -// radius by default. If the window has a non-client frame view, we don't need -// to set shadow, since the bubble frame view will help draw the shadow. -views::Widget::InitParams CreateWidgetParams() { +// radius by default. If the the dialog uses a non client type frame, we should +// build a drop shadow. If use a dialog type frame, we don't have to set a +// shadow since the dialog frame's border has its own shadow. +views::Widget::InitParams CreateWidgetParams( + SystemWebDialogDelegate::FrameKind frame_kind) { views::Widget::InitParams params; params.corner_radius = kSystemDialogCornerRadiusDp; - // Dialog frame view has its own shadow. - params.shadow_type = views::Widget::InitParams::ShadowType::kNone; + // Set shadow type according to the frame kind. + switch (frame_kind) { + case SystemWebDialogDelegate::FrameKind::kNonClient: + params.shadow_type = views::Widget::InitParams::ShadowType::kDrop; + break; + case SystemWebDialogDelegate::FrameKind::kDialog: + params.shadow_type = views::Widget::InitParams::ShadowType::kNone; + break; + } return params; } @@ -220,7 +229,8 @@ void SystemWebDialogDelegate::ShowSystemDialogForBrowserContext( content::BrowserContext* browser_context, gfx::NativeWindow parent) { - views::Widget::InitParams extra_params = CreateWidgetParams(); + views::Widget::InitParams extra_params = + CreateWidgetParams(GetWebDialogFrameKind()); // If unparented and not modal, keep it on top (see header comment). if (!parent && GetDialogModalType() == ui::MODAL_TYPE_NONE)
diff --git a/chrome/browser/ui/webui/sanitized_image_source.cc b/chrome/browser/ui/webui/sanitized_image_source.cc index 834182a5..75618ac7 100644 --- a/chrome/browser/ui/webui/sanitized_image_source.cc +++ b/chrome/browser/ui/webui/sanitized_image_source.cc
@@ -11,6 +11,7 @@ #include "base/containers/contains.h" #include "base/memory/ref_counted_memory.h" #include "base/strings/strcat.h" +#include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/task/task_traits.h" #include "base/task/thread_pool.h" @@ -60,6 +61,20 @@ return params; } +bool IsGooglePhotosUrl(const GURL& url) { + static const char* const kGooglePhotosHostSuffixes[] = { + ".ggpht.com", + ".google.com", + ".googleusercontent.com", + }; + + for (const char* const suffix : kGooglePhotosHostSuffixes) { + if (base::EndsWith(url.host_piece(), suffix)) + return true; + } + return false; +} + } // namespace SanitizedImageSource::SanitizedImageSource(Profile* profile) @@ -109,8 +124,10 @@ image_url = GURL(url_it->second); auto google_photos_it = params.find("isGooglePhotos"); - if (google_photos_it != params.end() && google_photos_it->second == "true") + if (google_photos_it != params.end() && + google_photos_it->second == "true" && IsGooglePhotosUrl(image_url)) { send_auth_token = true; + } } // Download the image body.
diff --git a/chrome/browser/ui/webui/sanitized_image_source_unittest.cc b/chrome/browser/ui/webui/sanitized_image_source_unittest.cc index 5c34eb0..77a2455 100644 --- a/chrome/browser/ui/webui/sanitized_image_source_unittest.cc +++ b/chrome/browser/ui/webui/sanitized_image_source_unittest.cc
@@ -172,7 +172,7 @@ // Verifies that the image source sends a Google Photos auth token with its data // request if and only if asked to by URL specification. TEST_F(SanitizedImageSourceTest, GooglePhotosImage) { - constexpr char kImageUrl[] = "https://foo.com/img.png"; + constexpr char kImageUrl[] = "https://lh3.googleusercontent.com/img.png"; base::MockCallback<content::URLDataSource::GotDataCallback> callback; signin::IdentityTestEnvironment identity_test_env; identity_test_env.MakePrimaryAccountAvailable("test@gmail.com", @@ -194,8 +194,7 @@ url::RawCanonOutputT<char> encoded_url; url::EncodeURIComponent(kImageUrl, std::size(kImageUrl), &encoded_url); EXPECT_GT(encoded_url.length(), 0); - auto encoded_url_str = - base::StringPiece(encoded_url.data(), encoded_url.length()); + base::StringPiece encoded_url_str(encoded_url.data(), encoded_url.length()); // Verify that param-formatted requests can be sent with auth tokens. sanitized_image_source_->StartDataRequest( @@ -244,4 +243,23 @@ GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED)); EXPECT_FALSE(identity_test_env.IsAccessTokenRequestPending()); ASSERT_EQ(4, test_url_loader_factory_.NumPending()); + + // Verify that no auth token is sent for URLs not served by Google Photos. + constexpr char kBadImageUrl[] = "https://foo.com/img.png"; + url::RawCanonOutputT<char> encoded_bad_url; + url::EncodeURIComponent(kBadImageUrl, std::size(kBadImageUrl), + &encoded_bad_url); + EXPECT_GT(encoded_bad_url.length(), 0); + base::StringPiece encoded_bad_url_str(encoded_bad_url.data(), + encoded_bad_url.length()); + + sanitized_image_source_->StartDataRequest( + GURL(base::StrCat({chrome::kChromeUIImageURL, "?url=", + encoded_bad_url_str, "&isGooglePhotos=true"})), + content::WebContents::Getter(), callback.Get()); + EXPECT_FALSE(identity_test_env.IsAccessTokenRequestPending()); + ASSERT_EQ(5, test_url_loader_factory_.NumPending()); + EXPECT_FALSE( + test_url_loader_factory_.GetPendingRequest(4)->request.headers.HasHeader( + net::HttpRequestHeaders::kAuthorization)); }
diff --git a/chrome/browser/ui/webui/settings/about_handler.cc b/chrome/browser/ui/webui/settings/about_handler.cc index bf0151be..e5a142c 100644 --- a/chrome/browser/ui/webui/settings/about_handler.cc +++ b/chrome/browser/ui/webui/settings/about_handler.cc
@@ -70,6 +70,7 @@ #include "chromeos/network/network_state_handler.h" #include "chromeos/system/statistics_provider.h" #include "components/user_manager/user_manager.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/chromeos/devicetype_utils.h" #endif @@ -335,6 +336,18 @@ "checkInternetConnection", base::BindRepeating(&AboutHandler::HandleCheckInternetConnection, base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "isManagedAutoUpdateEnabled", + base::BindRepeating(&AboutHandler::HandleIsManagedAutoUpdateEnabled, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "isConsumerAutoUpdateEnabled", + base::BindRepeating(&AboutHandler::HandleIsConsumerAutoUpdateEnabled, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "setConsumerAutoUpdate", + base::BindRepeating(&AboutHandler::HandleSetConsumerAutoUpdate, + base::Unretained(this))); #endif #if BUILDFLAG(IS_MAC) web_ui()->RegisterMessageCallback( @@ -644,6 +657,49 @@ ResolveJavascriptCallback(base::Value(callback_id), response); } +void AboutHandler::HandleIsManagedAutoUpdateEnabled( + const base::Value::List& args) { + CHECK_EQ(1U, args.size()); + const std::string& callback_id = args[0].GetString(); + ResolveJavascriptCallback( + base::Value(callback_id), + base::Value(version_updater_->IsManagedAutoUpdateEnabled())); +} + +void AboutHandler::HandleIsConsumerAutoUpdateEnabled( + const base::Value::List& args) { + CHECK_EQ(1U, args.size()); + const std::string& callback_id = args[0].GetString(); + const std::string& feature = update_engine::kFeatureConsumerAutoUpdate; + version_updater_->IsFeatureEnabled( + feature, + base::BindOnce(&AboutHandler::OnIsConsumerAutoUpdateEnabled, + weak_factory_.GetWeakPtr(), callback_id, feature)); +} + +void AboutHandler::OnIsConsumerAutoUpdateEnabled(std::string callback_id, + std::string feature, + absl::optional<bool> enabled) { + if (!enabled.has_value()) { + LOG(ERROR) << "Failed to get feature value for " << feature + << " defaulting to enabled"; + enabled = true; + } + ResolveJavascriptCallback(base::Value(callback_id), + base::Value(enabled.value())); +} + +void AboutHandler::HandleSetConsumerAutoUpdate(const base::Value::List& args) { + CHECK_EQ(1U, args.size()); + if (!args[0].is_bool()) { + LOG(ERROR) << "Can't parse SetConsumerAutoUpdate() args"; + return; + } + bool enable = args[0].GetBool(); + const std::string& feature = update_engine::kFeatureConsumerAutoUpdate; + version_updater_->ToggleFeature(feature, enable); +} + #endif // BUILDFLAG(IS_CHROMEOS_ASH) void AboutHandler::RequestUpdate() {
diff --git a/chrome/browser/ui/webui/settings/about_handler.h b/chrome/browser/ui/webui/settings/about_handler.h index 2113639..1990ef0 100644 --- a/chrome/browser/ui/webui/settings/about_handler.h +++ b/chrome/browser/ui/webui/settings/about_handler.h
@@ -180,6 +180,19 @@ // Callbacks for version_updater_->GetEolInfo calls. void OnGetEndOfLifeInfo(std::string callback_id, chromeos::UpdateEngineClient::EolInfo eol_info); + + // Get the managed auto update cros setting. + void HandleIsManagedAutoUpdateEnabled(const base::Value::List& args); + + // Get the consumer auto update pref from update_engine. + void HandleIsConsumerAutoUpdateEnabled(const base::Value::List& args); + + // Callbacks for version_updater_->IsConsumerAutoUpdateEnabled calls. + void OnIsConsumerAutoUpdateEnabled(std::string callback_id, + std::string feature, + absl::optional<bool> enabled); + + void HandleSetConsumerAutoUpdate(const base::Value::List& args); #endif raw_ptr<Profile> profile_;
diff --git a/chrome/browser/ui/webui/settings/chromeos/about_section.cc b/chrome/browser/ui/webui/settings/chromeos/about_section.cc index ae21496..ffe802c 100644 --- a/chrome/browser/ui/webui/settings/chromeos/about_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/about_section.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/ui/webui/settings/chromeos/about_section.h" #include "ash/constants/ash_features.h" +#include "base/callback_helpers.h" #include "base/command_line.h" #include "base/feature_list.h" #include "base/i18n/message_formatter.h" @@ -17,6 +18,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/obsolete_system/obsolete_system.h" +#include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/ui/webui/management/management_ui.h" #include "chrome/browser/ui/webui/settings/about_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/device_name_handler.h" @@ -30,6 +32,8 @@ #include "chrome/grit/generated_resources.h" #include "chromeos/dbus/constants/dbus_switches.h" #include "components/prefs/pref_service.h" +#include "components/signin/public/identity_manager/identity_manager.h" +#include "components/signin/public/identity_manager/tribool.h" #include "components/strings/grit/components_chromium_strings.h" #include "components/strings/grit/components_strings.h" #include "components/user_manager/user_manager.h" @@ -209,6 +213,9 @@ base::BindRepeating(&AboutSection::UpdateReportIssueSearchTags, base::Unretained(this))); UpdateReportIssueSearchTags(); + + pref_change_registrar_.Add(prefs::kConsumerAutoUpdateToggle, + base::DoNothingAs<void()>()); } #endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) @@ -340,6 +347,20 @@ {"aboutUpgradeTryAgain", IDS_SETTINGS_UPGRADE_TRY_AGAIN}, {"aboutUpgradeDownloadError", IDS_SETTINGS_UPGRADE_DOWNLOAD_ERROR}, {"aboutUpgradeAdministrator", IDS_SETTINGS_UPGRADE_ADMINISTRATOR_ERROR}, + + // About page auto update toggle. + {"aboutConsumerAutoUpdateToggleTitle", + IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_TITLE}, + {"aboutConsumerAutoUpdateToggleDescription", + IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_DESCRIPTION}, + {"aboutConsumerAutoUpdateToggleDialogTitle", + IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_DIALOG_TITLE}, + {"aboutConsumerAutoUpdateToggleDialogDescription", + IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_DIALOG_DESCRIPTION}, + {"aboutConsumerAutoUpdateToggleTurnOffButton", + IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_TURN_OFF_BUTTON}, + {"aboutConsumerAutoUpdateToggleKeepUpdatesButton", + IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_KEEP_UPDATES_BUTTON}, }; html_source->AddLocalizedStrings(kLocalizedStrings); @@ -354,11 +375,30 @@ html_source->AddString("deviceManager", GetDeviceManager()); if (user_manager::UserManager::IsInitialized()) { + bool is_enterprise_managed = webui::IsEnterpriseManaged(); user_manager::UserManager* user_manager = user_manager::UserManager::Get(); - if (!webui::IsEnterpriseManaged() && !user_manager->IsCurrentUserOwner()) { + bool is_current_owner = user_manager->IsCurrentUserOwner(); + + if (!is_enterprise_managed && !is_current_owner) { html_source->AddString("ownerEmail", user_manager->GetOwnerAccountId().GetUserEmail()); } + + // Enterprise/Non-owners cannot toggle by default. + bool cau_toggle = false; + if (!is_enterprise_managed && is_current_owner) { + auto* identity_manager = IdentityManagerFactory::GetForProfile(profile()); + const std::string& gaia_id = + user_manager->GetOwnerAccountId().GetGaiaId(); + const AccountInfo account_info = + identity_manager->FindExtendedAccountInfoByGaiaId(gaia_id); + cau_toggle = (account_info.capabilities.can_toggle_auto_updates() == + signin::Tribool::kTrue); + VLOG(1) << "Account can toggle auto updates: " << cau_toggle; + } + html_source->AddBoolean( + "isConsumerAutoUpdateTogglingAllowed", + chromeos::features::IsConsumerAutoUpdateToggleAllowed() && cau_toggle); } html_source->AddString(
diff --git a/chrome/browser/ui/webui/settings/chromeos/hierarchy.cc b/chrome/browser/ui/webui/settings/chromeos/hierarchy.cc index db70223..0c6d7fd3 100644 --- a/chrome/browser/ui/webui/settings/chromeos/hierarchy.cc +++ b/chrome/browser/ui/webui/settings/chromeos/hierarchy.cc
@@ -202,8 +202,8 @@ mojom::SearchResultPtr Hierarchy::SubpageMetadata::ToSearchResult( double relevance_score) const { return mojom::SearchResult::New( - /*result_text=*/l10n_util::GetStringUTF16(name_message_id_), - /*canonical_result_text=*/l10n_util::GetStringUTF16(name_message_id_), + /*text=*/l10n_util::GetStringUTF16(name_message_id_), + /*canonical_text=*/l10n_util::GetStringUTF16(name_message_id_), hierarchy_->ModifySearchResultUrl( section, mojom::SearchResultType::kSubpage, {.subpage = subpage_}, unmodified_url_path_with_parameters_), @@ -281,7 +281,7 @@ hierarchy_strings.push_back( GetSubpageMetadata(*subpage_metadata.parent_subpage) .ToSearchResult(kDummyRelevanceScore) - ->result_text); + ->text); return hierarchy_strings; } @@ -299,7 +299,7 @@ hierarchy_strings.push_back( GetSubpageMetadata(*setting_metadata.primary.second) .ToSearchResult(kDummyRelevanceScore) - ->result_text); + ->text); return hierarchy_strings; } @@ -308,9 +308,8 @@ std::vector<std::u16string> hierarchy_strings; hierarchy_strings.push_back( l10n_util::GetStringUTF16(IDS_INTERNAL_APP_SETTINGS)); - hierarchy_strings.push_back(GetSectionMetadata(section) - .ToSearchResult(kDummyRelevanceScore) - ->result_text); + hierarchy_strings.push_back( + GetSectionMetadata(section).ToSearchResult(kDummyRelevanceScore)->text); return hierarchy_strings; }
diff --git a/chrome/browser/ui/webui/settings/chromeos/os_settings_section.cc b/chrome/browser/ui/webui/settings/chromeos/os_settings_section.cc index e4d45de..ee1b3e7 100644 --- a/chrome/browser/ui/webui/settings/chromeos/os_settings_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/os_settings_section.cc
@@ -54,8 +54,8 @@ mojom::SearchResultPtr OsSettingsSection::GenerateSectionSearchResult( double relevance_score) const { return mojom::SearchResult::New( - /*result_text=*/l10n_util::GetStringUTF16(GetSectionNameMessageId()), - /*canonical_result_text=*/ + /*text=*/l10n_util::GetStringUTF16(GetSectionNameMessageId()), + /*canonical_text=*/ l10n_util::GetStringUTF16(GetSectionNameMessageId()), ModifySearchResultUrl(mojom::SearchResultType::kSection, {.section = GetSection()}, GetSectionPath()),
diff --git a/chrome/browser/ui/webui/settings/chromeos/search/search.mojom b/chrome/browser/ui/webui/settings/chromeos/search/search.mojom index d63ae03..7de9a4cd 100644 --- a/chrome/browser/ui/webui/settings/chromeos/search/search.mojom +++ b/chrome/browser/ui/webui/settings/chromeos/search/search.mojom
@@ -58,13 +58,13 @@ struct SearchResult { // String to be displayed as a result in the UI. Meant to be displayed // directly (i.e., not an ID but rather the actual text). - mojo_base.mojom.String16 result_text; + mojo_base.mojom.String16 text; // String for the "canonical" version of this result. Some search results use // alternate text (e.g., "Monitor" instead of "Display"). Note that it is - // often the case that |result_text| and |canonical_result_text| are the same + // often the case that |text| and |canonical_text| are the same // string. - mojo_base.mojom.String16 canonical_result_text; + mojo_base.mojom.String16 canonical_text; // The URL path containing the relevant setting, which may or may not contain // URL parameters. For example, the Wi-Fi list settings page is @@ -110,7 +110,7 @@ // called whenever the user plugs in or unplugs a USB modem. Clients can use // this function to ensure that they do not show "stale" results which are no // longer actionable by the user. - OnSearchResultAvailabilityChanged(); + OnSearchResultsChanged(); }; // Provides settings search results. Implemented in the browser process;
diff --git a/chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc b/chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc index 34fc3c59..72ef6534 100644 --- a/chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc
@@ -91,7 +91,7 @@ void SearchHandler::OnRegistryUpdated() { for (auto& observer : observers_) - observer->OnSearchResultAvailabilityChanged(); + observer->OnSearchResultsChanged(); } std::vector<mojom::SearchResultPtr> SearchHandler::GenerateSearchResultsArray( @@ -210,7 +210,7 @@ // Don't add a result for a parent section if it has the exact same text as // the child result, since this results in a broken-looking UI. - if (section_result->result_text == child_result->result_text) + if (section_result->text == child_result->text) return curr_position; return results->insert(curr_position + 1, std::move(section_result)); @@ -233,7 +233,7 @@ // Don't add a result for a parent subpage if it has the exact same text as // the child result, since this results in a broken-looking UI. - if (subpage_result->result_text == child_result->result_text) + if (subpage_result->text == child_result->text) return curr_position; return results->insert( @@ -289,8 +289,8 @@ } return mojom::SearchResult::New( - /*result_text=*/l10n_util::GetStringUTF16(content_id), - /*canonical_result_text=*/ + /*text=*/l10n_util::GetStringUTF16(content_id), + /*canonical_text=*/ l10n_util::GetStringUTF16(concept->canonical_message_id), url, concept->icon, result.score, hierarchy_strings, concept->default_rank, /*was_generated_from_text_match=*/true, concept->type,
diff --git a/chrome/browser/ui/webui/settings/chromeos/search/search_handler_unittest.cc b/chrome/browser/ui/webui/settings/chromeos/search/search_handler_unittest.cc index c298276..3ece90c 100644 --- a/chrome/browser/ui/webui/settings/chromeos/search/search_handler_unittest.cc +++ b/chrome/browser/ui/webui/settings/chromeos/search/search_handler_unittest.cc
@@ -37,7 +37,7 @@ private: // mojom::SearchResultsObserver: - void OnSearchResultAvailabilityChanged() override { ++num_calls_; } + void OnSearchResultsChanged() override { ++num_calls_; } size_t num_calls_ = 0; mojo::Receiver<mojom::SearchResultsObserver> receiver_{this}; @@ -74,8 +74,8 @@ // Creates a result with some default values. mojom::SearchResultPtr CreateDummyResult() { return mojom::SearchResult::New( - /*result_text=*/std::u16string(), - /*canonical_result_text=*/std::u16string(), /*url=*/"", + /*text=*/std::u16string(), + /*canonical_text=*/std::u16string(), /*url=*/"", mojom::SearchResultIcon::kPrinter, /*relevance_score=*/0.5, /*hierarchy_strings=*/std::vector<std::u16string>(), mojom::SearchResultDefaultRank::kMedium, @@ -221,9 +221,9 @@ // Verify the result text and canonical restult text. EXPECT_EQ(l10n_util::GetStringUTF16(IDS_OS_SETTINGS_TAG_PRINTING_ALT2), - search_results[0]->result_text); + search_results[0]->text); EXPECT_EQ(l10n_util::GetStringUTF16(IDS_OS_SETTINGS_TAG_PRINTING), - search_results[0]->canonical_result_text); + search_results[0]->canonical_text); } TEST_F(SearchHandlerTest, AllowParentResult) { @@ -262,7 +262,7 @@ // it should be the *last* result returned even though it has a higher // relevance score. EXPECT_EQ(l10n_util::GetStringUTF16(IDS_OS_SETTINGS_TAG_PRINTING), - search_results[2]->result_text); + search_results[2]->text); } // Regression test for https://crbug.com/1090184.
diff --git a/chrome/browser/web_applications/web_app_install_manager.cc b/chrome/browser/web_applications/web_app_install_manager.cc index 5f792b4..2eb3fca 100644 --- a/chrome/browser/web_applications/web_app_install_manager.cc +++ b/chrome/browser/web_applications/web_app_install_manager.cc
@@ -114,7 +114,7 @@ if (!started_) return; - auto task = std::make_unique<WebAppInstallTask>(profile_, this, finalizer_, + auto task = std::make_unique<WebAppInstallTask>(profile_, finalizer_, data_retriever_factory_.Run(), registrar_, install_surface); @@ -136,7 +136,7 @@ if (!started_) return; - auto task = std::make_unique<WebAppInstallTask>(profile_, this, finalizer_, + auto task = std::make_unique<WebAppInstallTask>(profile_, finalizer_, data_retriever_factory_.Run(), registrar_, install_surface); task->InstallWebAppFromManifest( @@ -156,7 +156,7 @@ if (!started_) return; - auto task = std::make_unique<WebAppInstallTask>(profile_, this, finalizer_, + auto task = std::make_unique<WebAppInstallTask>(profile_, finalizer_, data_retriever_factory_.Run(), registrar_, install_surface); task->InstallWebAppFromManifestWithFallback( @@ -178,7 +178,7 @@ // app_id is made available. auto task = std::make_unique<WebAppInstallTask>( - profile_, this, finalizer_, data_retriever_factory_.Run(), registrar_, + profile_, finalizer_, data_retriever_factory_.Run(), registrar_, webapps::WebappInstallSource::SUB_APP); WebAppInstallParams params; @@ -224,7 +224,7 @@ if (!started_) return; - auto task = std::make_unique<WebAppInstallTask>(profile_, this, finalizer_, + auto task = std::make_unique<WebAppInstallTask>(profile_, finalizer_, data_retriever_factory_.Run(), registrar_, install_surface); if (install_params) { @@ -246,7 +246,7 @@ if (!started_) return; - auto task = std::make_unique<WebAppInstallTask>(profile_, this, finalizer_, + auto task = std::make_unique<WebAppInstallTask>(profile_, finalizer_, data_retriever_factory_.Run(), registrar_, install_surface); task->InstallWebAppWithParams( @@ -285,7 +285,7 @@ GURL start_url = web_application_info->start_url; auto task = std::make_unique<WebAppInstallTask>( - profile_, this, finalizer_, data_retriever_factory_.Run(), registrar_, + profile_, finalizer_, data_retriever_factory_.Run(), registrar_, webapps::WebappInstallSource::SYNC); task->ExpectAppId(sync_app_id); @@ -433,7 +433,7 @@ // Install failed. Do the fallback install from info fetching just icon URLs. auto task = std::make_unique<WebAppInstallTask>( - profile_, this, finalizer_, data_retriever_factory_.Run(), registrar_, + profile_, finalizer_, data_retriever_factory_.Run(), registrar_, webapps::WebappInstallSource::SYNC); // Set the expect app id for fallback install too. This can avoid duplicate // installs.
diff --git a/chrome/browser/web_applications/web_app_install_manager_unittest.cc b/chrome/browser/web_applications/web_app_install_manager_unittest.cc index b254452d..25c8fc9 100644 --- a/chrome/browser/web_applications/web_app_install_manager_unittest.cc +++ b/chrome/browser/web_applications/web_app_install_manager_unittest.cc
@@ -142,7 +142,6 @@ std::unique_ptr<WebAppInstallTask> CreateDummyTask() { return std::make_unique<WebAppInstallTask>( /*profile=*/nullptr, - /*install_manager=*/nullptr, /*install_finalizer=*/nullptr, /*data_retriever=*/nullptr, /*registrar=*/nullptr, webapps::WebappInstallSource::SYNC);
diff --git a/chrome/browser/web_applications/web_app_install_task.cc b/chrome/browser/web_applications/web_app_install_task.cc index 444e94c3..14b480b 100644 --- a/chrome/browser/web_applications/web_app_install_task.cc +++ b/chrome/browser/web_applications/web_app_install_task.cc
@@ -22,7 +22,6 @@ #include "chrome/browser/web_applications/web_app_helpers.h" #include "chrome/browser/web_applications/web_app_icon_generator.h" #include "chrome/browser/web_applications/web_app_install_info.h" -#include "chrome/browser/web_applications/web_app_install_manager.h" #include "chrome/browser/web_applications/web_app_install_task.h" #include "chrome/browser/web_applications/web_app_install_utils.h" #include "chrome/browser/web_applications/web_app_installation_utils.h" @@ -165,13 +164,11 @@ WebAppInstallTask::WebAppInstallTask( Profile* profile, - WebAppInstallManager* install_manager, WebAppInstallFinalizer* install_finalizer, std::unique_ptr<WebAppDataRetriever> data_retriever, WebAppRegistrar* registrar, webapps::WebappInstallSource install_surface) : data_retriever_(std::move(data_retriever)), - install_manager_(install_manager), install_finalizer_(install_finalizer), profile_(profile), registrar_(registrar),
diff --git a/chrome/browser/web_applications/web_app_install_task.h b/chrome/browser/web_applications/web_app_install_task.h index 1b5da4f8..0d4be131 100644 --- a/chrome/browser/web_applications/web_app_install_task.h +++ b/chrome/browser/web_applications/web_app_install_task.h
@@ -60,7 +60,6 @@ using WebAppInstallFlow = WebAppInstallManager::WebAppInstallFlow; WebAppInstallTask(Profile* profile, - WebAppInstallManager* install_manager, WebAppInstallFinalizer* install_finalizer, std::unique_ptr<WebAppDataRetriever> data_retriever, WebAppRegistrar* registrar, @@ -296,7 +295,6 @@ const DownloadedIconsHttpResults& icons_http_results); std::unique_ptr<WebAppDataRetriever> data_retriever_; - raw_ptr<WebAppInstallManager> install_manager_; raw_ptr<WebAppInstallFinalizer> install_finalizer_; const raw_ptr<Profile> profile_; raw_ptr<WebAppRegistrar> registrar_;
diff --git a/chrome/browser/web_applications/web_app_install_task_unittest.cc b/chrome/browser/web_applications/web_app_install_task_unittest.cc index 251c88f308..b74a5d2a 100644 --- a/chrome/browser/web_applications/web_app_install_task_unittest.cc +++ b/chrome/browser/web_applications/web_app_install_task_unittest.cc
@@ -192,8 +192,8 @@ data_retriever_ = static_cast<FakeDataRetriever*>(data_retriever.get()); install_task_ = std::make_unique<WebAppInstallTask>( - profile(), &install_manager(), install_finalizer_.get(), - std::move(data_retriever), ®istrar(), install_surface); + profile(), install_finalizer_.get(), std::move(data_retriever), + ®istrar(), install_surface); } void SetInstallFinalizerForTesting() { @@ -1213,9 +1213,8 @@ /*scope=*/GURL{}); auto install_task = std::make_unique<WebAppInstallTask>( - guest_profile, &install_manager(), install_finalizer_.get(), - std::move(data_retriever), ®istrar(), - webapps::WebappInstallSource::EXTERNAL_DEFAULT); + guest_profile, install_finalizer_.get(), std::move(data_retriever), + ®istrar(), webapps::WebappInstallSource::EXTERNAL_DEFAULT); base::RunLoop run_loop; install_task->InstallWebAppWithParams( @@ -1412,9 +1411,8 @@ url_loader().SetNextLoadUrlResult(url, WebAppUrlLoader::Result::kUrlLoaded); auto task = std::make_unique<WebAppInstallTask>( - profile(), &install_manager(), install_finalizer_.get(), - std::move(data_retriever), ®istrar(), - webapps::WebappInstallSource::MENU_BROWSER_TAB); + profile(), install_finalizer_.get(), std::move(data_retriever), + ®istrar(), webapps::WebappInstallSource::MENU_BROWSER_TAB); task->LoadAndRetrieveWebAppInstallInfoWithIcons( url, &url_loader(),
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 8247608..6e794c7 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1650974392-deb57ad941f3f40f4c89ac603192559c2e8a4148.profdata +chrome-win64-main-1650985015-6310edfb8eafc2937ffb18731a4797fa5265b548.profdata
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 5451ea2b..8ef3705 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -3452,4 +3452,8 @@ const char kSCTAuditingHashdanceReportCount[] = "sct_auditing.hashdance_report_count"; +#if BUILDFLAG(IS_CHROMEOS_ASH) +const char kConsumerAutoUpdateToggle[] = "settings.consumer_auto_update_toggle"; +#endif + } // namespace prefs
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index c4b2126..607109e1 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -1214,6 +1214,10 @@ extern const char kForceMajorVersionToMinorPositionInUserAgent[]; extern const char kSCTAuditingHashdanceReportCount[]; + +#if BUILDFLAG(IS_CHROMEOS_ASH) +extern const char kConsumerAutoUpdateToggle[]; +#endif } // namespace prefs #endif // CHROME_COMMON_PREF_NAMES_H_
diff --git a/chrome/installer/linux/debian/dist_package_versions.json b/chrome/installer/linux/debian/dist_package_versions.json index 426215d0..340c9a01 100644 --- a/chrome/installer/linux/debian/dist_package_versions.json +++ b/chrome/installer/linux/debian/dist_package_versions.json
@@ -4,21 +4,22 @@ "libatk-bridge2.0-0": "2.30.0-5", "libatk1.0-0": "2.30.0-2", "libatspi2.0-0": "2.30.0-7", - "libc6": "2.28-10", + "libc6": "2.28-10+deb10u1", "libcairo2": "1.16.0-4+deb10u1", - "libcups2": "2.2.10-6+deb10u4", + "libcups2": "2.2.10-6+deb10u5", "libdbus-1-3": "1.12.20-0+deb10u1", "libdrm2": "2.4.97-1", - "libexpat1": "2.2.6-2+deb10u1", + "libexpat1": "2.2.6-2+deb10u4", "libgbm1": "18.3.6-2+deb10u1", "libgcc1": "1:8.3.0-6", "libglib2.0-0": "2.58.3-2+deb10u3", "libnspr4": "2:4.20-1", - "libnss3": "2:3.42.1-1+deb10u3", + "libnss3": "2:3.42.1-1+deb10u5", "libpango-1.0-0": "1.42.4-7~deb10u1", "libpangocairo-1.0-0": "1.42.4-7~deb10u1", "libstdc++6": "8.3.0-6", "libuuid1": "2.33.1-0.1", + "libwayland-client0": "1.16.0-1", "libx11-6": "2:1.6.7-1+deb10u2", "libx11-xcb1": "2:1.6.7-1+deb10u2", "libxcb-dri3-0": "1.13.1-2", @@ -46,16 +47,17 @@ "libcups2": "2.2.1-8+deb9u7", "libdbus-1-3": "1.10.28-0+deb9u1", "libdrm2": "2.4.74-1", - "libexpat1": "2.2.0-2+deb9u3", + "libexpat1": "2.2.0-2+deb9u5", "libgbm1": "13.0.6-1+b2", "libgcc1": "1:6.3.0-18+deb9u1", "libglib2.0-0": "2.50.3-2+deb9u2", "libnspr4": "2:4.12-6", - "libnss3": "2:3.26.2-1.1+deb9u2", + "libnss3": "2:3.26.2-1.1+deb9u5", "libpango-1.0-0": "1.40.5-1", "libpangocairo-1.0-0": "1.40.5-1", "libstdc++6": "6.3.0-18+deb9u1", "libuuid1": "2.29.2-1+deb9u1", + "libwayland-client0": "1.12.0-1+deb9u1", "libx11-6": "2:1.6.4-3+deb9u4", "libx11-xcb1": "2:1.6.4-3+deb9u4", "libxcb-dri3-0": "1.12-1", @@ -93,6 +95,7 @@ "libpangocairo-1.0-0": "1.36.3-1ubuntu1.1", "libstdc++6": "4.8.4-2ubuntu1~14.04.4", "libuuid1": "2.20.1-5.1ubuntu20.9", + "libwayland-client0": "1.4.0-1ubuntu1.1", "libx11-6": "2:1.6.2-1ubuntu2.1", "libx11-xcb1": "2:1.6.2-1ubuntu2.1", "libxcb-dri3-0": "1.10-2ubuntu1", @@ -130,6 +133,7 @@ "libpangocairo-1.0-0": "1.38.1-1", "libstdc++6": "5.4.0-6ubuntu1~16.04.12", "libuuid1": "2.27.1-6ubuntu3.10", + "libwayland-client0": "1.12.0-1~ubuntu16.04.3", "libx11-6": "2:1.6.3-1ubuntu2.2", "libx11-xcb1": "2:1.6.3-1ubuntu2.2", "libxcb-dri3-0": "1.11.1-1ubuntu1", @@ -152,21 +156,22 @@ "libatk-bridge2.0-0": "2.26.2-1", "libatk1.0-0": "2.28.1-1", "libatspi2.0-0": "2.28.0-1", - "libc6": "2.27-3ubuntu1.2", + "libc6": "2.27-3ubuntu1.5", "libcairo2": "1.15.10-2ubuntu0.1", "libcups2": "2.2.7-1ubuntu2.8", "libdbus-1-3": "1.12.2-1ubuntu1.2", "libdrm2": "2.4.99-1ubuntu1~18.04.2", - "libexpat1": "2.2.5-3ubuntu0.2", + "libexpat1": "2.2.5-3ubuntu0.7", "libgbm1": "19.2.8-0ubuntu0~18.04.2", "libgcc1": "1:8.4.0-1ubuntu1~18.04", - "libglib2.0-0": "2.56.4-0ubuntu0.18.04.8", + "libglib2.0-0": "2.56.4-0ubuntu0.18.04.9", "libnspr4": "2:4.18-1ubuntu1", - "libnss3": "2:3.35-2ubuntu2.12", + "libnss3": "2:3.35-2ubuntu2.13", "libpango-1.0-0": "1.40.14-1ubuntu0.1", "libpangocairo-1.0-0": "1.40.14-1ubuntu0.1", "libstdc++6": "8.4.0-1ubuntu1~18.04", "libuuid1": "2.31.1-0.4ubuntu3.7", + "libwayland-client0": "1.16.0-1ubuntu1.1~18.04.3", "libx11-6": "2:1.6.4-3ubuntu0.4", "libx11-xcb1": "2:1.6.4-3ubuntu0.4", "libxcb-dri3-0": "1.13-2~ubuntu18.04", @@ -185,25 +190,26 @@ "libxtst6": "2:1.2.3-1" }, "Ubuntu 20.04 (Focal)": { - "libasound2": "1.2.2-2.1ubuntu2.4", + "libasound2": "1.2.2-2.1ubuntu2.5", "libatk-bridge2.0-0": "2.34.2-0ubuntu2~20.04.1", "libatk1.0-0": "2.35.1-1ubuntu2", "libatspi2.0-0": "2.36.0-2", - "libc6": "2.31-0ubuntu9.2", + "libc6": "2.31-0ubuntu9.7", "libcairo2": "1.16.0-4ubuntu1", "libcups2": "2.3.1-9ubuntu1.1", "libdbus-1-3": "1.12.16-2ubuntu2.1", - "libdrm2": "2.4.105-3~20.04.2", - "libexpat1": "2.2.9-1build1", - "libgbm1": "21.0.3-0ubuntu0.3~20.04.3", + "libdrm2": "2.4.107-8ubuntu1~20.04.2", + "libexpat1": "2.2.9-1ubuntu0.4", + "libgbm1": "21.2.6-0ubuntu0.1~20.04.2", "libgcc1": "1:10.3.0-1ubuntu1~20.04", "libglib2.0-0": "2.64.6-1~ubuntu20.04.3", "libnspr4": "2:4.25-1", - "libnss3": "2:3.49.1-1ubuntu1.5", + "libnss3": "2:3.49.1-1ubuntu1.6", "libpango-1.0-0": "1.44.7-2ubuntu4", "libpangocairo-1.0-0": "1.44.7-2ubuntu4", "libstdc++6": "10.3.0-1ubuntu1~20.04", - "libuuid1": "2.34-0.1ubuntu9.1", + "libuuid1": "2.34-0.1ubuntu9.3", + "libwayland-client0": "1.18.0-1", "libx11-6": "2:1.6.9-2ubuntu1.2", "libx11-xcb1": "2:1.6.9-2ubuntu1.2", "libxcb-dri3-0": "1.14-2",
diff --git a/chrome/installer/linux/debian/repo_signing_keys.gpg b/chrome/installer/linux/debian/repo_signing_keys.gpg index 17d1a41..01d1177 100644 --- a/chrome/installer/linux/debian/repo_signing_keys.gpg +++ b/chrome/installer/linux/debian/repo_signing_keys.gpg Binary files differ
diff --git a/chrome/installer/linux/debian/update_dist_package_versions.py b/chrome/installer/linux/debian/update_dist_package_versions.py index 0c1aa90..a5520e2 100755 --- a/chrome/installer/linux/debian/update_dist_package_versions.py +++ b/chrome/installer/linux/debian/update_dist_package_versions.py
@@ -55,6 +55,7 @@ "libpangocairo-1.0-0", "libstdc++6", "libuuid1", + "libwayland-client0", "libx11-6", "libx11-xcb1", "libxcb1",
diff --git a/chrome/installer/linux/rpm/additional_deps b/chrome/installer/linux/rpm/additional_deps index 9c7f0fa..6b99719c 100644 --- a/chrome/installer/linux/rpm/additional_deps +++ b/chrome/installer/linux/rpm/additional_deps
@@ -44,3 +44,6 @@ # For OS integration. xdg-utils + +# For ANGLE with Wayland support +libwayland-client
diff --git a/chrome/installer/linux/rpm/dist_package_provides.json b/chrome/installer/linux/rpm/dist_package_provides.json index cb04011..b4b0498 100644 --- a/chrome/installer/linux/rpm/dist_package_provides.json +++ b/chrome/installer/linux/rpm/dist_package_provides.json
@@ -270,6 +270,7 @@ "libuuid.so.1(UUID_1.0)(64bit)", "libuuid.so.1(UUID_2.20)(64bit)", "libuuid.so.1(UUID_2.31)(64bit)", + "libwayland-client.so.0()(64bit)", "libxcb-dri3.so.0()(64bit)", "libxcb.so.1()(64bit)", "libxkbcommon.so.0()(64bit)", @@ -556,6 +557,7 @@ "libuuid.so.1(UUID_2.20)(64bit)", "libuuid.so.1(UUID_2.31)(64bit)", "libuuid.so.1(UUID_2.36)(64bit)", + "libwayland-client.so.0()(64bit)", "libxcb-dri3.so.0()(64bit)", "libxcb.so.1()(64bit)", "libxkbcommon.so.0()(64bit)", @@ -732,6 +734,7 @@ "libnss3.so(NSS_3.66)(64bit)", "libnss3.so(NSS_3.7)(64bit)", "libnss3.so(NSS_3.7.1)(64bit)", + "libnss3.so(NSS_3.77)(64bit)", "libnss3.so(NSS_3.8)(64bit)", "libnss3.so(NSS_3.9)(64bit)", "libnss3.so(NSS_3.9.2)(64bit)", @@ -846,6 +849,7 @@ "libuuid.so.1(UUID_2.20)(64bit)", "libuuid.so.1(UUID_2.31)(64bit)", "libuuid.so.1(UUID_2.36)(64bit)", + "libwayland-client.so.0()(64bit)", "libxcb-dri3.so.0()(64bit)", "libxcb.so.1()(64bit)", "libxkbcommon.so.0()(64bit)", @@ -1396,6 +1400,8 @@ "libuuid.so.1(UUID_2.20)(64bit)", "libuuid.so.1(UUID_2.31)", "libuuid.so.1(UUID_2.31)(64bit)", + "libwayland-client.so.0", + "libwayland-client.so.0()(64bit)", "libxcb-dri3.so.0", "libxcb-dri3.so.0()(64bit)", "libxcb.so.1", @@ -1965,6 +1971,8 @@ "libuuid.so.1(UUID_2.31)(64bit)", "libuuid.so.1(UUID_2.36)", "libuuid.so.1(UUID_2.36)(64bit)", + "libwayland-client.so.0", + "libwayland-client.so.0()(64bit)", "libxcb-dri3.so.0", "libxcb-dri3.so.0()(64bit)", "libxcb.so.1",
diff --git a/chrome/installer/linux/rpm/update_package_provides.py b/chrome/installer/linux/rpm/update_package_provides.py index c09a7c1..ccc28ea7 100755 --- a/chrome/installer/linux/rpm/update_package_provides.py +++ b/chrome/installer/linux/rpm/update_package_provides.py
@@ -56,6 +56,7 @@ "libsmime3.so", "libstdc++.so", "libuuid.so", + "libwayland-client.so", "libxcb.so", "libxcb-dri3.so.0", "libxkbcommon.so.0",
diff --git a/chrome/renderer/safe_browsing/phishing_classifier_delegate_browsertest.cc b/chrome/renderer/safe_browsing/phishing_classifier_delegate_browsertest.cc index 8c36726..19c68397 100644 --- a/chrome/renderer/safe_browsing/phishing_classifier_delegate_browsertest.cc +++ b/chrome/renderer/safe_browsing/phishing_classifier_delegate_browsertest.cc
@@ -128,7 +128,8 @@ MOCK_CONST_METHOD2( ApplyVisualTfLiteModel, void(const SkBitmap& bitmap, - base::OnceCallback<void(std::vector<double>)> callback)); + base::OnceCallback<void(base::flat_map<std::string, double>)> + callback)); MOCK_CONST_METHOD0(model_version, int()); MOCK_CONST_METHOD0(HasVisualTfLiteModel, bool()); MOCK_CONST_METHOD0(find_page_word_callback,
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index f4d773d..183a943 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -5124,6 +5124,7 @@ "../browser/policy/messaging_layer/public/report_client_test_util.h", "../browser/policy/messaging_layer/public/report_client_unittest.cc", "../browser/policy/messaging_layer/upload/dm_server_upload_service_unittest.cc", + "../browser/policy/messaging_layer/upload/event_upload_size_controller_unittest.cc", "../browser/policy/messaging_layer/upload/network_condition_service_unittest.cc", "../browser/policy/messaging_layer/upload/record_handler_impl_unittest.cc", "../browser/policy/messaging_layer/upload/record_upload_request_builder_unittest.cc",
diff --git a/chrome/test/base/test_browser_window.cc b/chrome/test/base/test_browser_window.cc index e3f224d..e3bff60 100644 --- a/chrome/test/base/test_browser_window.cc +++ b/chrome/test/base/test_browser_window.cc
@@ -250,11 +250,9 @@ } qrcode_generator::QRCodeGeneratorBubbleView* -TestBrowserWindow::ShowQRCodeGeneratorBubble( - content::WebContents* contents, - qrcode_generator::QRCodeGeneratorBubbleController* controller, - const GURL& url, - bool show_back_button) { +TestBrowserWindow::ShowQRCodeGeneratorBubble(content::WebContents* contents, + const GURL& url, + bool show_back_button) { return nullptr; } @@ -266,18 +264,14 @@ #if !BUILDFLAG(IS_ANDROID) sharing_hub::ScreenshotCapturedBubble* -TestBrowserWindow::ShowScreenshotCapturedBubble( - content::WebContents* contents, - const gfx::Image& image, - sharing_hub::ScreenshotCapturedBubbleController* controller) { +TestBrowserWindow::ShowScreenshotCapturedBubble(content::WebContents* contents, + const gfx::Image& image) { return nullptr; } #endif send_tab_to_self::SendTabToSelfBubbleView* -TestBrowserWindow::ShowSendTabToSelfBubble( - content::WebContents* contents, - send_tab_to_self::SendTabToSelfBubbleController* controller) { +TestBrowserWindow::ShowSendTabToSelfBubble(content::WebContents* contents) { return nullptr; } @@ -287,8 +281,7 @@ } #else sharing_hub::SharingHubBubbleView* TestBrowserWindow::ShowSharingHubBubble( - content::WebContents* contents, - sharing_hub::SharingHubBubbleController* controller) { + content::WebContents* contents) { return nullptr; } #endif
diff --git a/chrome/test/base/test_browser_window.h b/chrome/test/base/test_browser_window.h index b78520b3..fc63706 100644 --- a/chrome/test/base/test_browser_window.h +++ b/chrome/test/base/test_browser_window.h
@@ -29,17 +29,14 @@ class OmniboxView; namespace qrcode_generator { -class QRCodeGeneratorBubbleController; class QRCodeGeneratorBubbleView; } // namespace qrcode_generator namespace send_tab_to_self { -class SendTabToSelfBubbleController; class SendTabToSelfBubbleView; } // namespace send_tab_to_self namespace sharing_hub { -class SharingHubBubbleController; class SharingHubBubbleView; } // namespace sharing_hub @@ -148,14 +145,12 @@ void ShowBookmarkBubble(const GURL& url, bool already_bookmarked) override {} qrcode_generator::QRCodeGeneratorBubbleView* ShowQRCodeGeneratorBubble( content::WebContents* contents, - qrcode_generator::QRCodeGeneratorBubbleController* controller, const GURL& url, bool show_back_button) override; #if !BUILDFLAG(IS_ANDROID) sharing_hub::ScreenshotCapturedBubble* ShowScreenshotCapturedBubble( content::WebContents* contents, - const gfx::Image& image, - sharing_hub::ScreenshotCapturedBubbleController* controller) override; + const gfx::Image& image) override; void ShowIntentPickerBubble( std::vector<apps::IntentPickerAppInfo> app_info, bool show_stay_in_chrome, @@ -165,14 +160,12 @@ IntentPickerResponse callback) override {} #endif // !define(OS_ANDROID) send_tab_to_self::SendTabToSelfBubbleView* ShowSendTabToSelfBubble( - content::WebContents* contents, - send_tab_to_self::SendTabToSelfBubbleController* controller) override; + content::WebContents* contents) override; #if BUILDFLAG(IS_CHROMEOS_ASH) views::Button* GetSharingHubIconButton() override; #else sharing_hub::SharingHubBubbleView* ShowSharingHubBubble( - content::WebContents* contents, - sharing_hub::SharingHubBubbleController* controller) override; + content::WebContents* contents) override; #endif ShowTranslateBubbleResult ShowTranslateBubble( content::WebContents* contents,
diff --git a/chrome/test/data/webui/chromeos/personalization_app/ambient_preview_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/ambient_preview_element_test.ts index 59413b4..0df10dc2 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/ambient_preview_element_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/ambient_preview_element_test.ts
@@ -42,7 +42,9 @@ personalizationStore.data.ambient.albums = ambientProvider.albums; personalizationStore.data.ambient.topicSource = TopicSource.kArtGallery; personalizationStore.data.ambient.ambientModeEnabled = false; - const ambientPreviewElement = initElement(AmbientPreview); + personalizationStore.data.ambient.googlePhotosAlbumsPreviews = + ambientProvider.googlePhotosAlbumsPreviews; + ambientPreviewElement = initElement(AmbientPreview); personalizationStore.notifyObservers(); await waitAfterNextRender(ambientPreviewElement); @@ -63,7 +65,9 @@ personalizationStore.data.ambient.albums = ambientProvider.albums; personalizationStore.data.ambient.topicSource = TopicSource.kArtGallery; personalizationStore.data.ambient.ambientModeEnabled = false; - const ambientPreviewElement = initElement(AmbientPreview); + personalizationStore.data.ambient.googlePhotosAlbumsPreviews = + ambientProvider.googlePhotosAlbumsPreviews; + ambientPreviewElement = initElement(AmbientPreview); personalizationStore.notifyObservers(); await waitAfterNextRender(ambientPreviewElement);
diff --git a/chrome/test/data/webui/chromeos/personalization_app/ambient_subpage_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/ambient_subpage_element_test.ts index ed63d09..9c6e1497 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/ambient_subpage_element_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/ambient_subpage_element_test.ts
@@ -8,6 +8,7 @@ import {AlbumsSubpage, AmbientActionName, AmbientModeAlbum, AmbientObserver, AmbientSubpage, AnimationTheme, AnimationThemeItem, emptyState, Paths, PersonalizationRouter, SetAlbumsAction, SetAmbientModeEnabledAction, SetAnimationThemeAction, SetTemperatureUnitAction, SetTopicSourceAction, TemperatureUnit, TopicSource, TopicSourceItem, WallpaperGridItem} from 'chrome://personalization/trusted/personalization_app.js'; import {CrRadioButtonElement} from 'chrome://resources/cr_elements/cr_radio_button/cr_radio_button.m.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; +import {Url} from 'chrome://resources/mojo/url/mojom/url.mojom-webui.js'; import {assertDeepEquals, assertEquals, assertFalse, assertNotEquals, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js'; import {waitAfterNextRender} from 'chrome://webui-test/test_util.js'; @@ -49,12 +50,15 @@ async function displayMainSettings( topicSource: TopicSource|null, temperatureUnit: TemperatureUnit|null, ambientModeEnabled: boolean|null, - animationTheme = AnimationTheme.kSlideshow): Promise<AmbientSubpage> { + animationTheme = AnimationTheme.kSlideshow, + googlePhotosAlbumsPreviews: Url[] = []): Promise<AmbientSubpage> { personalizationStore.data.ambient.albums = ambientProvider.albums; personalizationStore.data.ambient.animationTheme = animationTheme; personalizationStore.data.ambient.topicSource = topicSource; personalizationStore.data.ambient.temperatureUnit = temperatureUnit; personalizationStore.data.ambient.ambientModeEnabled = ambientModeEnabled; + personalizationStore.data.ambient.googlePhotosAlbumsPreviews = + googlePhotosAlbumsPreviews; const ambientSubpage = initElement(AmbientSubpage, {path: Paths.Ambient, queryParams: {}}); personalizationStore.notifyObservers(); @@ -454,7 +458,7 @@ const reloadCalledPromise = new Promise<void>((resolve) => { PersonalizationRouter.reloadAtAmbient = resolve; }); - let albumsSubpageElement = initElement(AlbumsSubpage); + const albumsSubpageElement = initElement(AlbumsSubpage); personalizationStore.data.ambient.ambientModeEnabled = false; personalizationStore.notifyObservers(); await waitAfterNextRender(albumsSubpageElement); @@ -680,6 +684,74 @@ assertEquals('2', previewAlbumTitle.innerText.replace(/\s/g, '')); }); + test( + 'displays 4 image collage when there are enough photos in Google photos album', + async () => { + ambientSubpageElement = await displayMainSettings( + TopicSource.kGooglePhotos, TemperatureUnit.kFahrenheit, + /*ambientModeEnabled=*/ true); + personalizationStore.data.ambient.googlePhotosAlbumsPreviews = + ambientProvider.googlePhotosAlbumsPreviews; + personalizationStore.notifyObservers(); + await waitAfterNextRender(ambientSubpageElement); + + const ambientPreview = + ambientSubpageElement.shadowRoot!.querySelector('ambient-preview'); + assertTrue(!!ambientPreview); + + const collageImages = + ambientPreview.shadowRoot!.querySelectorAll<HTMLImageElement>( + '.collage-item'); + assertTrue(!!collageImages); + assertEquals(4, collageImages.length); + }); + + test( + 'displays 1 image collage when there are not enough photos in Google photos album', + async () => { + ambientSubpageElement = await displayMainSettings( + TopicSource.kGooglePhotos, TemperatureUnit.kFahrenheit, + /*ambientModeEnabled=*/ true); + personalizationStore.data.ambient.googlePhotosAlbumsPreviews = [ + ambientProvider.googlePhotosAlbumsPreviews[0], + ambientProvider.googlePhotosAlbumsPreviews[1] + ]; + personalizationStore.notifyObservers(); + await waitAfterNextRender(ambientSubpageElement); + + const ambientPreview = + ambientSubpageElement.shadowRoot!.querySelector('ambient-preview'); + assertTrue(!!ambientPreview); + + const collageImages = + ambientPreview.shadowRoot!.querySelectorAll<HTMLImageElement>( + '.collage-item'); + assertTrue(!!collageImages); + assertEquals(1, collageImages.length); + }); + + test( + 'displays preview urls from selected albums when there are zero preview photos in Google photos album', + async () => { + ambientSubpageElement = await displayMainSettings( + TopicSource.kGooglePhotos, TemperatureUnit.kFahrenheit, + /*ambientModeEnabled=*/ true); + personalizationStore.data.ambient.googlePhotosAlbumsPreviews = []; + personalizationStore.notifyObservers(); + await waitAfterNextRender(ambientSubpageElement); + + const ambientPreview = + ambientSubpageElement.shadowRoot!.querySelector('ambient-preview'); + assertTrue(!!ambientPreview); + + const collageImages = + ambientPreview.shadowRoot!.querySelectorAll<HTMLImageElement>( + '.collage-item'); + assertTrue(!!collageImages); + assertEquals(1, collageImages.length); + assertTrue(collageImages[0]!.src.includes('test_url3')); + }); + test('displays zero state when ambient mode is disabled', async () => { ambientSubpageElement = await displayMainSettings( TopicSource.kArtGallery, TemperatureUnit.kFahrenheit,
diff --git a/chrome/test/data/webui/chromeos/personalization_app/test_ambient_interface_provider.ts b/chrome/test/data/webui/chromeos/personalization_app/test_ambient_interface_provider.ts index 7db98830..240822d 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/test_ambient_interface_provider.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/test_ambient_interface_provider.ts
@@ -3,6 +3,7 @@ // found in the LICENSE file. import {AmbientModeAlbum, AmbientObserverInterface, AmbientObserverRemote, AmbientProviderInterface, AnimationTheme, TemperatureUnit, TopicSource} from 'chrome://personalization/trusted/personalization_app.js'; +import {Url} from 'chrome://resources/mojo/url/mojom/url.mojom-webui.js'; import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js'; export class TestAmbientProvider extends TestBrowserProxy implements @@ -37,7 +38,7 @@ }, { id: '3', - checked: false, + checked: true, title: '3', description: '3', numberOfPhotos: 1, @@ -46,6 +47,13 @@ } ]; + public googlePhotosAlbumsPreviews: Url[] = [ + {url: 'http://preview0'}, + {url: 'http://preview1'}, + {url: 'http://preview2'}, + {url: 'http://preview#'}, + ]; + constructor() { super([ 'isAmbientModeEnabled', @@ -82,6 +90,8 @@ this.ambientObserverRemote!.onTopicSourceChanged(TopicSource.kArtGallery); this.ambientObserverRemote!.onTemperatureUnitChanged( TemperatureUnit.kFahrenheit); + this.ambientObserverRemote!.onGooglePhotosAlbumsPreviewsFetched( + this.googlePhotosAlbumsPreviews); } setAmbientModeEnabled(ambientModeEnabled: boolean) {
diff --git a/chrome/test/data/webui/chromeos/personalization_app/test_personalization_store.ts b/chrome/test/data/webui/chromeos/personalization_app/test_personalization_store.ts index 89a6a61..f92b4079 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/test_personalization_store.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/test_personalization_store.ts
@@ -20,13 +20,6 @@ super(data, PersonalizationStore, emptyState(), reduce); this.actions_ = []; this.states_ = []; - - // manually override `reduce_` method because it's private. - this['reduce_'] = (action: Action) => { - super['reduce_'](action); - this.actions_.push(action); - this.states_.push(this.data); - }; } get actions() { @@ -37,6 +30,12 @@ return this.states_; } + override reduce(action: Action) { + super.reduce(action); + this.actions_.push(action); + this.states_.push(this.data); + } + override replaceSingleton() { PersonalizationStore.setInstance(this); }
diff --git a/chrome/test/data/webui/settings/chromeos/fake_settings_search_handler.js b/chrome/test/data/webui/settings/chromeos/fake_settings_search_handler.js index 6c839e9..200dcec2 100644 --- a/chrome/test/data/webui/settings/chromeos/fake_settings_search_handler.js +++ b/chrome/test/data/webui/settings/chromeos/fake_settings_search_handler.js
@@ -37,9 +37,9 @@ this.observer_ = observer; } - simulateSearchResultAvailabilityChanged() { + simulateSearchResultsChanged() { if (this.observer_) { - this.observer_.onSearchResultAvailabilityChanged(); + this.observer_.onSearchResultsChanged(); } } }
diff --git a/chrome/test/data/webui/settings/chromeos/os_about_page_tests.js b/chrome/test/data/webui/settings/chromeos/os_about_page_tests.js index e65c6cac..386335e 100644 --- a/chrome/test/data/webui/settings/chromeos/os_about_page_tests.js +++ b/chrome/test/data/webui/settings/chromeos/os_about_page_tests.js
@@ -570,6 +570,108 @@ checkEndOfLifeSection(); }); + function getBuildInfoPage() { + page.scroller = page.offsetParent; + assertTrue(!!page.$['detailed-build-info-trigger']); + page.$['detailed-build-info-trigger'].click(); + const buildInfoPage = + page.shadowRoot.querySelector('settings-detailed-build-info'); + assertTrue(!!buildInfoPage); + return buildInfoPage; + } + + test('Managed user auto update toggle in build info page', async () => { + loadTimeData.overrideValues({ + isManaged: true, + }); + + async function checkManagedAutoUpdateToggle(isToggleEnabled) { + // Create the page. + await initNewPage(); + // Set overrides + response values. + aboutBrowserProxy.setManagedAutoUpdate(isToggleEnabled); + // Go to the build info page. + const buildInfoPage = getBuildInfoPage(); + // Wait for overrides + response values. + await aboutBrowserProxy.whenCalled('isManagedAutoUpdateEnabled'); + + const mau_toggle = buildInfoPage.$$('#managedAutoUpdateToggle'); + assertTrue(!!mau_toggle); + // Managed auto update toggle should always be disabled to toggle. + assertTrue(!!mau_toggle.hasAttribute('disabled')); + assertEquals(isToggleEnabled, mau_toggle.checked); + // Consumer auto update toggle should not exist. + assertFalse(!!buildInfoPage.$$('#consumerAutoUpdateToggle')); + } + + await checkManagedAutoUpdateToggle(true); + await checkManagedAutoUpdateToggle(false); + }); + + test('Consumer user auto update toggle in build info page', async () => { + loadTimeData.overrideValues({ + isManaged: false, + }); + + async function checkConsumerAutoUpdateToggle(isEnabled, isTogglingAllowed) { + // Create the page. + await initNewPage(); + // Set overrides + response values. + loadTimeData.overrideValues({ + isConsumerAutoUpdateTogglingAllowed: isTogglingAllowed, + }); + aboutBrowserProxy.resetConsumerAutoUpdate(isEnabled); + const prefs = { + 'settings': { + 'consumer_auto_update_toggle': { + key: 'consumer_auto_update_toggle', + type: chrome.settingsPrivate.PrefType.BOOLEAN, + value: isEnabled, + }, + }, + }; + // Go to the build info page. + const buildInfoPage = getBuildInfoPage(); + // Wait for overrides + response values. + buildInfoPage.prefs = Object.assign({}, prefs); + await Promise.all([ + aboutBrowserProxy.whenCalled('isConsumerAutoUpdateEnabled'), + aboutBrowserProxy.whenCalled('setConsumerAutoUpdate'), + ]); + + // Managed auto update toggle should not exist. + assertFalse(!!buildInfoPage.$$('#managedAutoUpdateToggle')); + const cau_toggle = buildInfoPage.$$('#consumerAutoUpdateToggle'); + assertTrue(!!cau_toggle); + assertEquals(isTogglingAllowed, !cau_toggle.disabled); + assertEquals(isEnabled, cau_toggle.checked); + + // Check dialog popup when toggling off. + if (isEnabled) { + let dialog = buildInfoPage.shadowRoot.querySelector( + 'settings-consumer-auto-update-toggle-dialog'); + assertFalse(!!dialog); + + cau_toggle.click(); + flush(); + + dialog = buildInfoPage.shadowRoot.querySelector( + 'settings-consumer-auto-update-toggle-dialog'); + // Only when toggling is allowed, should the dialog popup. + if (isTogglingAllowed) { + assertTrue(!!dialog); + } else { + assertFalse(!!dialog); + } + } + } + + await checkConsumerAutoUpdateToggle(true, true); + await checkConsumerAutoUpdateToggle(true, false); + await checkConsumerAutoUpdateToggle(false, true); + await checkConsumerAutoUpdateToggle(false, false); + }); + test('GetHelp', function() { assertTrue(!!page.$.help); page.$.help.click(); @@ -682,11 +784,34 @@ }); test('Initialization', async () => { + loadTimeData.overrideValues({ + isManaged: false, + }); + page = document.createElement('settings-detailed-build-info'); document.body.appendChild(page); await Promise.all([ browserProxy.whenCalled('pageReady'), + browserProxy.whenCalled('isConsumerAutoUpdateEnabled'), + browserProxy.whenCalled('setConsumerAutoUpdate'), + browserProxy.whenCalled('canChangeChannel'), + browserProxy.whenCalled('getChannelInfo'), + browserProxy.whenCalled('getVersionInfo'), + ]); + }); + + test('InitializationManaged', async () => { + loadTimeData.overrideValues({ + isManaged: true, + }); + + page = document.createElement('settings-detailed-build-info'); + document.body.appendChild(page); + + await Promise.all([ + browserProxy.whenCalled('pageReady'), + browserProxy.whenCalled('isManagedAutoUpdateEnabled'), browserProxy.whenCalled('canChangeChannel'), browserProxy.whenCalled('getChannelInfo'), browserProxy.whenCalled('getVersionInfo'), @@ -1241,6 +1366,53 @@ }); }); +suite('Consumer auto update dialog popup', function() { + let dialog = null; + let browserProxy = null; + let events; + + setup(function() { + events = []; + browserProxy = new TestAboutPageBrowserProxyChromeOS(); + AboutPageBrowserProxyImpl.setInstance(browserProxy); + PolymerTest.clearBody(); + dialog = + document.createElement('settings-consumer-auto-update-toggle-dialog'); + document.body.appendChild(dialog); + }); + + teardown(function() { + dialog.remove(); + }); + + function getButtonEventPromise() { + return new Promise( + (resolve) => + dialog.addEventListener('set-consumer-auto-update', (e) => { + events.push(e); + resolve(); + })); + } + + async function clickButton(buttonId, shouldEnable) { + const ButtonEventPromise = getButtonEventPromise(); + const button = dialog.shadowRoot.querySelector(buttonId); + assertTrue(!!button); + button.click(); + await ButtonEventPromise; + assertEquals(1, events.length); + assertEquals(shouldEnable, events[0].detail.item); + } + + test('click turn off button fires disable event', async function() { + await clickButton('#turnOffButton', false); + }); + + test('click keep updates button fires enable event', async function() { + await clickButton('#keepUpdatesButton', true); + }); +}); + suite('AboutPageTest_OfficialBuild', function() { let page = null; let browserProxy = null;
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_search_box_test.js b/chrome/test/data/webui/settings/chromeos/os_settings_search_box_test.js index d87add2..1378fb05 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_search_box_test.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_search_box_test.js
@@ -106,7 +106,7 @@ } /** - * @param {string} resultText Exact string of the result to be displayed. + * @param {string} text Exact string of the result to be displayed. * @param {string} path Url path with optional params. * @param {?chromeos.settings.mojom.SearchResultIcon} icon Result icon enum. * @param {?Boolean} wasGeneratedFromTextMatch If result was generated by @@ -114,10 +114,13 @@ * @return {!chromeos.settings.mojom.SearchResult} A search result. */ function fakeResult( - resultText, urlPathWithParameters, icon, wasGeneratedFromTextMatch) { + text, urlPathWithParameters, icon, wasGeneratedFromTextMatch) { return /** @type {!mojom.SearchResult} */ ({ - resultText: { - data: Array.from(resultText, c => c.charCodeAt()), + text: { + data: Array.from(text, c => c.charCodeAt()), + }, + canonicalText: { + data: Array.from(text, c => c.charCodeAt()), }, urlPathWithParameters: urlPathWithParameters, icon: icon ? icon : chromeos.settings.mojom.SearchResultIcon.MIN_VALUE, @@ -187,7 +190,7 @@ // Check that the list updates when the dropdown is open, and the dropdown // remains open. - settingsSearchHandler.simulateSearchResultAvailabilityChanged(); + settingsSearchHandler.simulateSearchResultsChanged(); await waitForResultsFetched(); assertTrue(dropDown.opened); assertEquals(searchBox.searchResults_.length, 2); @@ -202,7 +205,7 @@ // Check that the list updates when the dropdown is closed, and the dropdown // remains closed. - settingsSearchHandler.simulateSearchResultAvailabilityChanged(); + settingsSearchHandler.simulateSearchResultsChanged(); await waitForResultsFetched(); assertFalse(dropDown.opened); assertEquals(searchBox.searchResults_.length, 1);
diff --git a/chrome/test/data/webui/settings/chromeos/test_about_page_browser_proxy_chromeos.js b/chrome/test/data/webui/settings/chromeos/test_about_page_browser_proxy_chromeos.js index 05554d34..aa3c3d9 100644 --- a/chrome/test/data/webui/settings/chromeos/test_about_page_browser_proxy_chromeos.js +++ b/chrome/test/data/webui/settings/chromeos/test_about_page_browser_proxy_chromeos.js
@@ -26,6 +26,9 @@ 'requestUpdate', 'setChannel', 'openFirmwareUpdatesPage', + 'isManagedAutoUpdateEnabled', + 'isConsumerAutoUpdateEnabled', + 'setConsumerAutoUpdate', ]); /** @private {!UpdateStatus} */ @@ -62,6 +65,12 @@ hasEndOfLife: false, aboutPageEndOfLifeMessage: '', }; + + /** @private {!boolean} */ + this.managedAutoUpdateEnabled_ = true; + + /** @private {!boolean} */ + this.consumerAutoUpdateEnabled_ = true; } /** @param {!UpdateStatus} updateStatus */ @@ -82,6 +91,16 @@ }); } + /** @param {boolean} enabled */ + setManagedAutoUpdate(enabled) { + this.managedAutoUpdateEnabled_ = enabled; + } + + /** @param {boolean} enabled */ + resetConsumerAutoUpdate(enabled) { + this.consumerAutoUpdateEnabled_ = enabled; + } + /** @override */ pageReady() { this.methodCalled('pageReady'); @@ -221,4 +240,22 @@ openFirmwareUpdatesPage() { this.methodCalled('openFirmwareUpdatesPage'); } + + /** @override */ + isManagedAutoUpdateEnabled() { + this.methodCalled('isManagedAutoUpdateEnabled'); + return Promise.resolve(this.managedAutoUpdateEnabled_); + } + + /** @override */ + isConsumerAutoUpdateEnabled() { + this.methodCalled('isConsumerAutoUpdateEnabled'); + return Promise.resolve(this.consumerAutoUpdateEnabled_); + } + + /** @override */ + setConsumerAutoUpdate(enable) { + this.consumerAutoUpdateEnabled_ = enable; + this.methodCalled('setConsumerAutoUpdate'); + } }
diff --git a/chrome/test/data/webui/test_store.js b/chrome/test/data/webui/test_store.js index 2c0d0bbf..aaec6525 100644 --- a/chrome/test/data/webui/test_store.js +++ b/chrome/test/data/webui/test_store.js
@@ -62,10 +62,10 @@ } /** @override */ - reduce_(action) { + reduce(action) { this.lastAction_ = action; if (this.enableReducers_) { - this.storeImplClass.prototype.reduce_.call(this, action); + this.storeImplClass.prototype.reduce.call(this, action); } if (this.resolverMap_.has(action.name)) { this.resolverMap_.get(action.name).resolve(action);
diff --git a/chrome/updater/util.cc b/chrome/updater/util.cc index cbb8677..7bb0ea3 100644 --- a/chrome/updater/util.cc +++ b/chrome/updater/util.cc
@@ -209,11 +209,6 @@ : absl::nullopt; } -std::string GetAPFromAppArgs(const std::string& app_id) { - const absl::optional<tagging::AppArgs> app_args = GetAppArgs(app_id); - return app_args ? app_args->ap : std::string(); -} - std::string GetInstallDataIndexFromAppArgs(const std::string& app_id) { const absl::optional<tagging::AppArgs> app_args = GetAppArgs(app_id); return app_args ? app_args->install_data_index : std::string();
diff --git a/chrome/updater/util.h b/chrome/updater/util.h index f0b9d426..90016bbb 100644 --- a/chrome/updater/util.h +++ b/chrome/updater/util.h
@@ -118,10 +118,6 @@ // Returns the arguments corresponding to `app_id` from the command line tag. absl::optional<tagging::AppArgs> GetAppArgs(const std::string& app_id); -// Returns the "ap" corresponding to `app_id` from the command line tag, or an -// empty string if no tag or "ap" is specified. -std::string GetAPFromAppArgs(const std::string& app_id); - std::string GetInstallDataIndexFromAppArgs(const std::string& app_id); // Returns true if the user running the updater also owns the `path`.
diff --git a/chrome/updater/util_unittest.cc b/chrome/updater/util_unittest.cc index b42cfad5..86994f87 100644 --- a/chrome/updater/util_unittest.cc +++ b/chrome/updater/util_unittest.cc
@@ -33,12 +33,6 @@ EXPECT_STREQ(app_args->app_id.c_str(), "8a69f345-c564-463c-aff1-a69d9e530f96"); EXPECT_STREQ(app_args->app_name.c_str(), "TestApp"); - - // Test GetAPFromAppArgs. - EXPECT_STREQ(GetAPFromAppArgs("NonExistentAppId").c_str(), ""); - EXPECT_STREQ( - GetAPFromAppArgs("8a69f345-c564-463c-aff1-a69d9e530f96").c_str(), - "TestAP"); } }
diff --git a/chrome/updater/win/app_install_controller.cc b/chrome/updater/win/app_install_controller.cc index fbae2a0..fafb948 100644 --- a/chrome/updater/win/app_install_controller.cc +++ b/chrome/updater/win/app_install_controller.cc
@@ -490,7 +490,12 @@ RegistrationRequest request; request.app_id = app_id_; - request.ap = GetAPFromAppArgs(app_id_); + absl::optional<tagging::AppArgs> app_args = GetAppArgs(app_id_); + absl::optional<tagging::TagArgs> tag_args = GetTagArgs().tag_args; + if (app_args) + request.ap = app_args->ap; + if (tag_args) + request.brand_code = tag_args->brand_code; update_service_->RegisterApp( request,
diff --git a/chromecast/android/BUILD.gn b/chromecast/android/BUILD.gn index 481e39e4..24eb583 100644 --- a/chromecast/android/BUILD.gn +++ b/chromecast/android/BUILD.gn
@@ -105,17 +105,11 @@ group("internal_android_deps") { testonly = true public_deps = [ - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:com_android_support_design_java", - "//third_party/android_deps:com_android_support_support_annotations_java", - "//third_party/android_deps:com_google_code_findbugs_jsr305_java", "//third_party/android_deps:protobuf_lite_runtime_java", "//third_party/androidx:androidx_annotation_annotation_java", - "//third_party/androidx:androidx_appcompat_appcompat_java", "//third_party/androidx:androidx_core_core_java", - "//third_party/androidx:androidx_drawerlayout_drawerlayout_java", "//third_party/androidx:androidx_fragment_fragment_java", - "//third_party/androidx:androidx_interpolator_interpolator_java", "//third_party/androidx:androidx_leanback_leanback_preference_java", "//third_party/androidx:androidx_legacy_legacy_support_v4_java", "//third_party/androidx:androidx_lifecycle_lifecycle_common_java",
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd index 98002342..71de70a 100644 --- a/chromeos/chromeos_strings.grd +++ b/chromeos/chromeos_strings.grd
@@ -2937,40 +2937,25 @@ Calibration complete </message> <!-- OS update page --> - <message name="IDS_SHIMLESS_RMA_UPDATE_OS_PAGE_TITLE" translateable="false" desc="Title of ChromeOS update page."> - Make sure ChromeOS is up to date + <message name="IDS_SHIMLESS_RMA_UPDATE_OS_PAGE_TITLE" desc="Title of ChromeOS update page."> + Make sure Chrome OS is up to date </message> - <message name="IDS_SHIMLESS_RMA_UPDATE_OS_UNQUALIFIED_COMPONENTS_TOP" translateable="false" desc="Description when components not qualified for ChromeOS are detected."> - <ph name="LINK_BEGIN"><a id="unqualifiedComponentsLink"></ph>Unqualified components<ph name="LINK_END"></a></ph> found. To make sure all qualified componets are identified, update your ChromeOS to the latest version. + <message name="IDS_SHIMLESS_RMA_UPDATE_OS_UNQUALIFIED_COMPONENTS_TOP" desc="Description when components not qualified for ChromeOS are detected."> + <ph name="LINK_BEGIN"><a id="unqualifiedComponentsLink"></ph>Unqualified components<ph name="LINK_END"></a></ph> found. To make sure all qualified components are identified, update your Chrome OS to the latest version. </message> - <message name="IDS_SHIMLESS_RMA_UPDATE_OS_UNQUALIFIED_COMPONENTS_BOTTOM" translateable="false" desc="Description when components not qualified for ChromeOS are detected."> + <message name="IDS_SHIMLESS_RMA_UPDATE_OS_UNQUALIFIED_COMPONENTS_BOTTOM" desc="Description when components not qualified for ChromeOS are detected."> If you still see the issue after the update, it's possible the component is newly qualified and hasn't made it to the database yet. </message> - <message name="IDS_SHIMLESS_RMA_UPDATE_OS_VERY_OUT_OF_DATE" translateable="false" desc="Description when the installed OS is too many versions behind the update."> - ChromeOS needs an additional update to get fully up to date + <message name="IDS_SHIMLESS_RMA_UPDATE_OS_OUT_OF_DATE" desc="The instructions shown when there is a ChromeOS update available."> + Update to the latest version of Chrome OS for an optimized repair process </message> - <message name="IDS_SHIMLESS_RMA_UPDATE_OS_OUT_OF_DATE" translateable="false" desc="The instructions shown when there is a ChromeOS update available."> - Update to the latest version of ChromeOS for an optimized repair process - </message> - <message name="IDS_SHIMLESS_RMA_UPDATE_OS_NETWORK_UNAVAILABLE" translateable="false" desc="Notice that no network is available when attempting to update ChromeOS."> - To check if OS is up to date, connect to the internet in previous screen - </message> - <message name="IDS_SHIMLESS_RMA_UPDATE_OS_FAILED_TO_START" translateable="false" desc="Notice when the call to update ChromeOS fails unexpectedly."> - Failed to start ChromeOS update. - </message> - <message name="IDS_SHIMLESS_RMA_CURRENT_VERSION" translateable="false" desc="Label that shows the current installed version of ChromeOS."> - Current version <ph name="VERSION_NUMBER">$1<ex>90.0.1234.56</ex></ph> - </message> - <message name="IDS_SHIMLESS_RMA_CURRENT_VERSION_OUT_OF_DATE" translateable="false" desc="Label that shows the when the currently installed version of ChromeOS is out of date."> + <message name="IDS_SHIMLESS_RMA_CURRENT_VERSION_OUT_OF_DATE" desc="Label that shows the when the currently installed version of ChromeOS is out of date."> Current version <ph name="VERSION_NUMBER">$1<ex>90.0.1234.56</ex></ph> is out of date </message> - <message name="IDS_SHIMLESS_RMA_CURRENT_VERSION_UP_TO_DATE" translateable="false" desc="Label that shows the when the currently installed version of ChromeOS is up to date."> - Current version <ph name="VERSION_NUMBER">$1<ex>90.0.1234.56</ex></ph> is up to date - </message> - <message name="IDS_SHIMLESS_RMA_UPDATE_VERSION_AND_RESTART" translateable="false" desc="Label for the button that updates the device to the latest version of ChromeOS then restarts the device."> + <message name="IDS_SHIMLESS_RMA_UPDATE_VERSION_AND_RESTART" desc="Label for the button that updates the device to the latest version of ChromeOS then restarts the device."> Update to <ph name="VERSION_NUMBER">$1</ph> & restart </message> - <message name="IDS_SHIMLESS_RMA_UPDATING_OS_VERSION" translateable="false" desc="The message shown while updating the device's OS version."> + <message name="IDS_SHIMLESS_RMA_UPDATING_OS_VERSION" desc="The message shown while updating the device's OS version."> Updating OS version </message> <!-- Manually disable wp page -->
diff --git a/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_CURRENT_VERSION_OUT_OF_DATE.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_CURRENT_VERSION_OUT_OF_DATE.png.sha1 new file mode 100644 index 0000000..bcff6a6 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_CURRENT_VERSION_OUT_OF_DATE.png.sha1
@@ -0,0 +1 @@ +7fda36db85906440ce14289d82c70c04ca36ed35 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_UPDATE_OS_OUT_OF_DATE.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_UPDATE_OS_OUT_OF_DATE.png.sha1 new file mode 100644 index 0000000..b1184ff --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_UPDATE_OS_OUT_OF_DATE.png.sha1
@@ -0,0 +1 @@ +15909968779fc03e5f88cf0dafc1c67074a36e1f \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_UPDATE_OS_PAGE_TITLE.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_UPDATE_OS_PAGE_TITLE.png.sha1 new file mode 100644 index 0000000..83a94fbc --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_UPDATE_OS_PAGE_TITLE.png.sha1
@@ -0,0 +1 @@ +e1838ed243e69c2fdb82e5f2ee866a9bf042d9ff \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_UPDATE_OS_UNQUALIFIED_COMPONENTS_BOTTOM.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_UPDATE_OS_UNQUALIFIED_COMPONENTS_BOTTOM.png.sha1 new file mode 100644 index 0000000..61730df --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_UPDATE_OS_UNQUALIFIED_COMPONENTS_BOTTOM.png.sha1
@@ -0,0 +1 @@ +589c4f82d209e483bf7bdcf3be2f5ef0e6934a05 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_UPDATE_OS_UNQUALIFIED_COMPONENTS_TOP.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_UPDATE_OS_UNQUALIFIED_COMPONENTS_TOP.png.sha1 new file mode 100644 index 0000000..5e98ce3 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_UPDATE_OS_UNQUALIFIED_COMPONENTS_TOP.png.sha1
@@ -0,0 +1 @@ +fcd8a073a4dbf8c81e61dc477b0bf170906298fc \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_UPDATE_VERSION_AND_RESTART.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_UPDATE_VERSION_AND_RESTART.png.sha1 new file mode 100644 index 0000000..c5aabdb6 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_UPDATE_VERSION_AND_RESTART.png.sha1
@@ -0,0 +1 @@ +b0b3f3f12ee21ab0e65b58074cc59335f1352406 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_UPDATING_OS_VERSION.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_UPDATING_OS_VERSION.png.sha1 new file mode 100644 index 0000000..653af01c2 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_UPDATING_OS_VERSION.png.sha1
@@ -0,0 +1 @@ +d403ea21d9869fe70e06fdb4ec2e361b46de9082 \ No newline at end of file
diff --git a/components/blocked_content/popup_tracker.cc b/components/blocked_content/popup_tracker.cc index 6ebb1ac..9d64027 100644 --- a/components/blocked_content/popup_tracker.cc +++ b/components/blocked_content/popup_tracker.cc
@@ -11,7 +11,6 @@ #include "base/metrics/histogram_macros.h" #include "base/time/default_tick_clock.h" #include "components/blocked_content/popup_opener_tab_helper.h" -#include "components/ukm/content/source_url_recorder.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/web_contents.h" #include "services/metrics/public/cpp/metrics_utils.h" @@ -51,7 +50,7 @@ visibility_tracker_( base::DefaultTickClock::GetInstance(), contents->GetVisibility() != content::Visibility::HIDDEN), - opener_source_id_(ukm::GetSourceIdForWebContentsDocument(opener)), + opener_source_id_(opener->GetMainFrame()->GetPageUkmSourceId()), window_open_disposition_(disposition) { if (auto* popup_opener = PopupOpenerTabHelper::FromWebContents(opener)) popup_opener->OnOpenedPopup(this);
diff --git a/components/cast_streaming/DEPS b/components/cast_streaming/DEPS index 8d7da29..fd36333 100644 --- a/components/cast_streaming/DEPS +++ b/components/cast_streaming/DEPS
@@ -1,7 +1,6 @@ include_rules = [ "+content/public/common", "+net", - "+services/network/public", # The browser and renderer code may not depend on eachother, and can only # depend on shared "public" code.
diff --git a/components/exo/wayland/BUILD.gn b/components/exo/wayland/BUILD.gn index 98b6af7..76204c9 100644 --- a/components/exo/wayland/BUILD.gn +++ b/components/exo/wayland/BUILD.gn
@@ -220,6 +220,7 @@ "//services/device/wake_lock/power_save_blocker", "//third_party/wayland-protocols:idle_inhibit_protocol", "//ui/base/cursor/mojom:cursor_type", + "//ui/base/wayland:wayland_server_input_types", "//ui/events/ozone/layout", ] } @@ -721,6 +722,7 @@ "//ui/gfx:gfx", "//ui/gfx/linux:drm", "//ui/gfx/linux:gbm", + "//ui/gl", ] }
diff --git a/components/exo/wayland/clients/client_base.cc b/components/exo/wayland/clients/client_base.cc index ca63c74..637026b 100644 --- a/components/exo/wayland/clients/client_base.cc +++ b/components/exo/wayland/clients/client_base.cc
@@ -563,11 +563,14 @@ make_current_ = std::make_unique<ui::ScopedMakeCurrent>(gl_context_.get(), gl_surface_.get()); - if (gl::GLSurfaceEGL::HasEGLExtension("EGL_EXT_image_flush_external") || - gl::GLSurfaceEGL::HasEGLExtension("EGL_ARM_implicit_external_sync")) { + if (gl::GLSurfaceEGL::GetGLDisplayEGL()->HasEGLExtension( + "EGL_EXT_image_flush_external") || + gl::GLSurfaceEGL::GetGLDisplayEGL()->HasEGLExtension( + "EGL_ARM_implicit_external_sync")) { egl_sync_type_ = EGL_SYNC_FENCE_KHR; } - if (gl::GLSurfaceEGL::HasEGLExtension("EGL_ANDROID_native_fence_sync")) { + if (gl::GLSurfaceEGL::GetGLDisplayEGL()->HasEGLExtension( + "EGL_ANDROID_native_fence_sync")) { egl_sync_type_ = EGL_SYNC_NATIVE_FENCE_ANDROID; }
diff --git a/components/exo/wayland/server.cc b/components/exo/wayland/server.cc index 91f84a5..c95043c 100644 --- a/components/exo/wayland/server.cc +++ b/components/exo/wayland/server.cc
@@ -383,7 +383,7 @@ zcr_text_input_extension_data_ = std::make_unique<WaylandTextInputExtension>(); - wl_global_create(wl_display_.get(), &zcr_text_input_extension_v1_interface, 1, + wl_global_create(wl_display_.get(), &zcr_text_input_extension_v1_interface, 2, zcr_text_input_extension_data_.get(), bind_text_input_extension);
diff --git a/components/exo/wayland/zwp_text_input_manager.cc b/components/exo/wayland/zwp_text_input_manager.cc index afb1c709..acd824d 100644 --- a/components/exo/wayland/zwp_text_input_manager.cc +++ b/components/exo/wayland/zwp_text_input_manager.cc
@@ -20,6 +20,7 @@ #include "components/exo/wayland/server_util.h" #include "components/exo/xkb_tracker.h" #include "ui/base/ime/utf_offset.h" +#include "ui/base/wayland/wayland_server_input_types.h" #include "ui/events/event.h" #include "ui/events/keycodes/dom/keycode_converter.h" #include "ui/events/ozone/layout/xkb/xkb_modifier_converter.h" @@ -63,6 +64,8 @@ return weak_factory_.GetWeakPtr(); } + wl_resource* resource() { return text_input_; } + private: wl_client* client() { return wl_resource_get_client(text_input_); } @@ -271,6 +274,8 @@ delegate_->set_extended_text_input(nullptr); } + WaylandTextInputDelegate* delegate() { return delegate_.get(); } + private: base::WeakPtr<WaylandTextInputDelegate> delegate_; }; @@ -478,8 +483,40 @@ wl_resource_destroy(resource); } +void extended_text_input_set_input_type(wl_client* client, + wl_resource* resource, + uint32_t input_type, + uint32_t input_mode, + uint32_t input_flags, + uint32_t learning_mode) { + auto* delegate = + GetUserDataAs<WaylandExtendedTextInput>(resource)->delegate(); + if (!delegate) + return; + + // If unknown value is passed, fall back to the default one. + auto ui_type = + ui::wayland::ConvertToTextInputType( + static_cast<zcr_extended_text_input_v1_input_type>(input_type)) + .value_or(ui::TEXT_INPUT_TYPE_TEXT); + auto ui_mode = + ui::wayland::ConvertToTextInputMode( + static_cast<zcr_extended_text_input_v1_input_mode>(input_mode)) + .value_or(ui::TEXT_INPUT_MODE_DEFAULT); + // Ignore unknown flags. + auto ui_flags = ui::wayland::ConvertToTextInputFlags(input_flags).first; + bool should_do_learning = + learning_mode == ZCR_EXTENDED_TEXT_INPUT_V1_LEARNING_MODE_ENABLED; + + auto* text_input = GetUserDataAs<TextInput>(delegate->resource()); + text_input->SetTypeModeFlags(ui_type, ui_mode, ui_flags, should_do_learning); +} + constexpr struct zcr_extended_text_input_v1_interface - extended_text_input_implementation = {extended_text_input_destroy}; + extended_text_input_implementation = { + extended_text_input_destroy, + extended_text_input_set_input_type, +}; //////////////////////////////////////////////////////////////////////////////// // text_input_extension_v1 interface:
diff --git a/components/omnibox/browser/BUILD.gn b/components/omnibox/browser/BUILD.gn index 15bcf29..77ca28f 100644 --- a/components/omnibox/browser/BUILD.gn +++ b/components/omnibox/browser/BUILD.gn
@@ -416,6 +416,7 @@ "android/java/src/org/chromium/components/omnibox/SecurityButtonAnimationDelegate.java", "android/java/src/org/chromium/components/omnibox/SecurityStatusIcon.java", "android/java/src/org/chromium/components/omnibox/SuggestionAnswer.java", + "android/java/src/org/chromium/components/omnibox/action/HistoryClustersAction.java", "android/java/src/org/chromium/components/omnibox/action/OmniboxPedal.java", ] @@ -456,6 +457,7 @@ "android/java/src/org/chromium/components/omnibox/AutocompleteSchemeClassifier.java", "android/java/src/org/chromium/components/omnibox/OmniboxUrlEmphasizer.java", "android/java/src/org/chromium/components/omnibox/SuggestionAnswer.java", + "android/java/src/org/chromium/components/omnibox/action/HistoryClustersAction.java", "android/java/src/org/chromium/components/omnibox/action/OmniboxPedal.java", ] }
diff --git a/components/omnibox/browser/actions/history_clusters_action.cc b/components/omnibox/browser/actions/history_clusters_action.cc index 3f46f58..6fd27bb 100644 --- a/components/omnibox/browser/actions/history_clusters_action.cc +++ b/components/omnibox/browser/actions/history_clusters_action.cc
@@ -46,7 +46,7 @@ base::EscapeQueryParamValue(query, /*use_plus=*/false) .c_str()))) { #if BUILDFLAG(IS_ANDROID) - CreateOrUpdateJavaObject(); + CreateOrUpdateJavaObject(query); #endif } @@ -74,10 +74,11 @@ return j_omnibox_action_; } - void CreateOrUpdateJavaObject() { - j_omnibox_action_.Reset(BuildOmniboxPedal( + void CreateOrUpdateJavaObject(const std::string& query) { + j_omnibox_action_.Reset(BuildHistoryClustersAction( GetID(), strings_.hint, strings_.suggestion_contents, - strings_.accessibility_suffix, strings_.accessibility_hint, url_)); + strings_.accessibility_suffix, strings_.accessibility_hint, url_, + query)); } #endif
diff --git a/components/omnibox/browser/actions/omnibox_pedal_jni_wrapper.cc b/components/omnibox/browser/actions/omnibox_pedal_jni_wrapper.cc index f1efbd6..ed87ac22 100644 --- a/components/omnibox/browser/actions/omnibox_pedal_jni_wrapper.cc +++ b/components/omnibox/browser/actions/omnibox_pedal_jni_wrapper.cc
@@ -5,6 +5,7 @@ #include "components/history_clusters/core/history_clusters_service.h" #include "base/android/jni_string.h" +#include "components/omnibox/browser/jni_headers/HistoryClustersAction_jni.h" #include "components/omnibox/browser/jni_headers/OmniboxPedal_jni.h" #include "url/android/gurl_android.h" @@ -23,3 +24,21 @@ base::android::ConvertUTF16ToJavaString(env, accessibility_hint), url::GURLAndroid::FromNativeGURL(env, url))); } + +base::android::ScopedJavaGlobalRef<jobject> BuildHistoryClustersAction( + int id, + std::u16string hint, + std::u16string suggestion_contents, + std::u16string accessibility_suffix, + std::u16string accessibility_hint, + GURL url, + std::string query) { + JNIEnv* env = base::android::AttachCurrentThread(); + return base::android::ScopedJavaGlobalRef(Java_HistoryClustersAction_build( + env, id, base::android::ConvertUTF16ToJavaString(env, hint), + base::android::ConvertUTF16ToJavaString(env, suggestion_contents), + base::android::ConvertUTF16ToJavaString(env, accessibility_suffix), + base::android::ConvertUTF16ToJavaString(env, accessibility_hint), + url::GURLAndroid::FromNativeGURL(env, url), + base::android::ConvertUTF8ToJavaString(env, query))); +}
diff --git a/components/omnibox/browser/actions/omnibox_pedal_jni_wrapper.h b/components/omnibox/browser/actions/omnibox_pedal_jni_wrapper.h index 3916896..b658583 100644 --- a/components/omnibox/browser/actions/omnibox_pedal_jni_wrapper.h +++ b/components/omnibox/browser/actions/omnibox_pedal_jni_wrapper.h
@@ -13,4 +13,13 @@ std::u16string accessibility_hint, GURL url); +base::android::ScopedJavaGlobalRef<jobject> BuildHistoryClustersAction( + int id, + std::u16string hint, + std::u16string suggestion_contents, + std::u16string accessibility_suffix, + std::u16string accessibility_hint, + GURL url, + std::string query); + #endif // COMPONENTS_OMNIBOX_BROWSER_ACTIONS_OMNIBOX_PEDAL_JNI_WRAPPER_H_
diff --git a/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/action/HistoryClustersAction.java b/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/action/HistoryClustersAction.java new file mode 100644 index 0000000..6721fca6 --- /dev/null +++ b/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/action/HistoryClustersAction.java
@@ -0,0 +1,38 @@ +// Copyright 2022 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.components.omnibox.action; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import org.chromium.base.annotations.CalledByNative; +import org.chromium.url.GURL; + +/** + * Omnibox action for showing the history clusters (journeys) UI. This exists as a separate class so + * that it can expose the associated query directly. + */ +public class HistoryClustersAction extends OmniboxPedal { + private final String mQuery; + + public HistoryClustersAction(int id, @NonNull String hint, @NonNull String suggestionContents, + @NonNull String accessibilitySuffix, @NonNull String accessibilityHint, + @Nullable GURL url, @NonNull String query) { + super(id, hint, suggestionContents, accessibilitySuffix, accessibilityHint, url); + mQuery = query; + } + + public String getQuery() { + return mQuery; + } + + @CalledByNative + private static HistoryClustersAction build(int id, @NonNull String hint, + @NonNull String suggestionContents, @NonNull String accessibilitySuffix, + @NonNull String accessibilityHint, @Nullable GURL url, @NonNull String query) { + return new HistoryClustersAction( + id, hint, suggestionContents, accessibilitySuffix, accessibilityHint, url, query); + } +}
diff --git a/components/page_load_metrics/browser/observers/use_counter/ukm_features.cc b/components/page_load_metrics/browser/observers/use_counter/ukm_features.cc index f761e58..0d59416 100644 --- a/components/page_load_metrics/browser/observers/use_counter/ukm_features.cc +++ b/components/page_load_metrics/browser/observers/use_counter/ukm_features.cc
@@ -224,6 +224,9 @@ WebFeature::kOpenWebDatabaseInsecureContext, WebFeature::kPrivateNetworkAccessIgnoredPreflightError, WebFeature::kWebBluetoothGetAvailability, + WebFeature::kCookieHasNotBeenRefreshedIn201To300Days, + WebFeature::kCookieHasNotBeenRefreshedIn301To350Days, + WebFeature::kCookieHasNotBeenRefreshedIn351To400Days, })); return *opt_in_features; }
diff --git a/components/payments/content/android/java/src/org/chromium/components/payments/BrowserPaymentRequest.java b/components/payments/content/android/java/src/org/chromium/components/payments/BrowserPaymentRequest.java index d3dc9b7..d9a06a1 100644 --- a/components/payments/content/android/java/src/org/chromium/components/payments/BrowserPaymentRequest.java +++ b/components/payments/content/android/java/src/org/chromium/components/payments/BrowserPaymentRequest.java
@@ -123,10 +123,9 @@ * Called when these conditions are satisfied: (1) show() has been called, (2) payment apps * are all queried, and (3) PaymentDetails is finalized. * @return The error if it fails; null otherwise. - * @param isUserGestureShow Whether PaymentRequest.show() was invoked with a user gesture. */ @Nullable - default String onShowCalledAndAppsQueriedAndDetailsFinalized(boolean isUserGestureShow) { + default String onShowCalledAndAppsQueriedAndDetailsFinalized() { return null; }
diff --git a/components/payments/content/android/java/src/org/chromium/components/payments/InvalidPaymentRequest.java b/components/payments/content/android/java/src/org/chromium/components/payments/InvalidPaymentRequest.java index 382ccf77..55b7de1 100644 --- a/components/payments/content/android/java/src/org/chromium/components/payments/InvalidPaymentRequest.java +++ b/components/payments/content/android/java/src/org/chromium/components/payments/InvalidPaymentRequest.java
@@ -30,6 +30,11 @@ @Override public void show(boolean unusedIsUserGesture, boolean unusedWaitForUpdatedDetails) { + showNew(unusedWaitForUpdatedDetails); + } + + @Override + public void showNew(boolean unusedWaitForUpdatedDetails) { if (mClient != null) { mClient.onError(PaymentErrorReason.USER_CANCEL, ErrorStrings.WEB_PAYMENT_API_DISABLED); mClient.close();
diff --git a/components/payments/content/android/java/src/org/chromium/components/payments/JniPaymentApp.java b/components/payments/content/android/java/src/org/chromium/components/payments/JniPaymentApp.java index 5464887..e414d7a2 100644 --- a/components/payments/content/android/java/src/org/chromium/components/payments/JniPaymentApp.java +++ b/components/payments/content/android/java/src/org/chromium/components/payments/JniPaymentApp.java
@@ -139,11 +139,6 @@ } @Override - public boolean isUserGestureRequiredToSkipUi() { - return JniPaymentAppJni.get().isUserGestureRequiredToSkipUi(mNativeObject); - } - - @Override public void invokePaymentApp(String id, String merchantName, String origin, String iframeOrigin, @Nullable byte[][] certificateChain, Map<String, PaymentMethodData> methodDataMap, PaymentItem total, List<PaymentItem> displayItems, @@ -234,7 +229,6 @@ String getCountryCode(long nativeJniPaymentApp); boolean canMakePayment(long nativeJniPaymentApp); boolean canPreselect(long nativeJniPaymentApp); - boolean isUserGestureRequiredToSkipUi(long nativeJniPaymentApp); void invokePaymentApp(long nativeJniPaymentApp, JniPaymentApp callback); void updateWith(long nativeJniPaymentApp, ByteBuffer responseByteBuffer); void onPaymentDetailsNotUpdated(long nativeJniPaymentApp);
diff --git a/components/payments/content/android/java/src/org/chromium/components/payments/MojoPaymentRequestGateKeeper.java b/components/payments/content/android/java/src/org/chromium/components/payments/MojoPaymentRequestGateKeeper.java index 7b39066..3b071c8 100644 --- a/components/payments/content/android/java/src/org/chromium/components/payments/MojoPaymentRequestGateKeeper.java +++ b/components/payments/content/android/java/src/org/chromium/components/payments/MojoPaymentRequestGateKeeper.java
@@ -65,8 +65,14 @@ // Implement PaymentRequest: @Override public void show(boolean isUserGesture, boolean waitForUpdatedDetails) { + showNew(waitForUpdatedDetails); + } + + // Implement PaymentRequest: + @Override + public void showNew(boolean waitForUpdatedDetails) { if (mPaymentRequestService == null) return; - mPaymentRequestService.show(isUserGesture, waitForUpdatedDetails); + mPaymentRequestService.show(waitForUpdatedDetails); } // Implement PaymentRequest:
diff --git a/components/payments/content/android/java/src/org/chromium/components/payments/PaymentApp.java b/components/payments/content/android/java/src/org/chromium/components/payments/PaymentApp.java index 3c5747f46..e787bd1 100644 --- a/components/payments/content/android/java/src/org/chromium/components/payments/PaymentApp.java +++ b/components/payments/content/android/java/src/org/chromium/components/payments/PaymentApp.java
@@ -201,11 +201,6 @@ return true; } - /** @return Whether skip-UI flow with this app requires a user gesture. */ - public boolean isUserGestureRequiredToSkipUi() { - return true; - } - /** * Invoke the payment app to retrieve the payment details. *
diff --git a/components/payments/content/android/java/src/org/chromium/components/payments/PaymentRequestService.java b/components/payments/content/android/java/src/org/chromium/components/payments/PaymentRequestService.java index 29ca872..5ffc026 100644 --- a/components/payments/content/android/java/src/org/chromium/components/payments/PaymentRequestService.java +++ b/components/payments/content/android/java/src/org/chromium/components/payments/PaymentRequestService.java
@@ -111,9 +111,6 @@ /** Internal reason for why PaymentRequest.show() should be rejected. */ private @AppCreationFailureReason int mRejectShowErrorReason = AppCreationFailureReason.UNKNOWN; - /** Whether PaymentRequest.show() was invoked with a user gesture. */ - private boolean mIsUserGestureShow; - // mClient is null only when it has closed. @Nullable private PaymentRequestClient mClient; @@ -941,8 +938,7 @@ return ErrorStrings.SPC_AUTHN_UI_SUPPRESSED; } } - return mBrowserPaymentRequest.onShowCalledAndAppsQueriedAndDetailsFinalized( - mIsUserGestureShow); + return mBrowserPaymentRequest.onShowCalledAndAppsQueriedAndDetailsFinalized(); } private boolean isSecurePaymentConfirmationApplicable() { @@ -1174,7 +1170,7 @@ * The component part of the {@link PaymentRequest#show} implementation. Check {@link * PaymentRequest#show} for the parameters' specification. */ - /* package */ void show(boolean isUserGesture, boolean waitForUpdatedDetails) { + /* package */ void show(boolean waitForUpdatedDetails) { if (mBrowserPaymentRequest == null) return; assert mSpec != null; assert !mSpec.isDestroyed() : "mSpec is destroyed only after close()."; @@ -1199,7 +1195,6 @@ sShowingPaymentRequest = this; mJourneyLogger.recordCheckoutStep(CheckoutFunnelStep.SHOW_CALLED); mIsShowCalled = true; - mIsUserGestureShow = isUserGesture; mIsShowWaitingForUpdatedDetails = waitForUpdatedDetails; mJourneyLogger.setTriggerTime(); @@ -1275,10 +1270,7 @@ && allApps.size() >= 1 && onlySingleAppCanProvideAllRequiredInformation(mSpec.getPaymentOptions(), allApps) // Skip to payment app only if it can be pre-selected. - && selectedApp != null - // Skip to payment app only if user gesture is provided when it is required to - // skip-UI. - && (mIsUserGestureShow || !selectedApp.isUserGestureRequiredToSkipUi()); + && selectedApp != null; } // Implements PaymentDetailsConverter.MethodChecker:
diff --git a/components/payments/content/android/jni_payment_app.cc b/components/payments/content/android/jni_payment_app.cc index e3f6e47c..a4660ce 100644 --- a/components/payments/content/android/jni_payment_app.cc +++ b/components/payments/content/android/jni_payment_app.cc
@@ -120,11 +120,6 @@ return payment_app_->CanPreselect(); } -bool JniPaymentApp::IsUserGestureRequiredToSkipUi(JNIEnv* env) { - // All payment apps require a user gesture to skip UI by default. - return true; -} - void JniPaymentApp::InvokePaymentApp(JNIEnv* env, const JavaParamRef<jobject>& jcallback) { invoke_callback_ = jcallback;
diff --git a/components/payments/content/android/jni_payment_app.h b/components/payments/content/android/jni_payment_app.h index 81ef2a1e..9cdb695 100644 --- a/components/payments/content/android/jni_payment_app.h +++ b/components/payments/content/android/jni_payment_app.h
@@ -46,8 +46,6 @@ bool CanPreselect(JNIEnv* env); - bool IsUserGestureRequiredToSkipUi(JNIEnv* env); - void InvokePaymentApp(JNIEnv* env, const base::android::JavaParamRef<jobject>& jcallback);
diff --git a/components/payments/content/android/junit/src/org/chromium/components/payments/PaymentRequestServiceTest.java b/components/payments/content/android/junit/src/org/chromium/components/payments/PaymentRequestServiceTest.java index ba52106e..a95c00a 100644 --- a/components/payments/content/android/junit/src/org/chromium/components/payments/PaymentRequestServiceTest.java +++ b/components/payments/content/android/junit/src/org/chromium/components/payments/PaymentRequestServiceTest.java
@@ -65,7 +65,6 @@ private boolean mWarnNoFaviconCalled; private boolean mIsClientClosed; private MojoException mConnectionError; - private boolean mIsUserGestureDefaultValue = true; private boolean mWaitForUpdatedDetailsDefaultValue; private PaymentAppService mPaymentAppService; private PaymentAppFactoryDelegate mPaymentAppFactoryDelegate; @@ -115,11 +114,6 @@ @Override public void dismissInstrument() {} - - @Override - public boolean isUserGestureRequiredToSkipUi() { - return false; - } }; Mockito.doReturn(app).when(mBrowserPaymentRequest).getSelectedPaymentApp(); List<PaymentApp> apps = new ArrayList(); @@ -225,7 +219,7 @@ } private void show(PaymentRequestService service) { - service.show(mIsUserGestureDefaultValue, mWaitForUpdatedDetailsDefaultValue); + service.show(mWaitForUpdatedDetailsDefaultValue); } private void updateWith(PaymentRequestService service) { @@ -351,7 +345,7 @@ @Feature({"Payments"}) public void testNullDetailsFailsUpdateWith() { PaymentRequestService service = defaultBuilder().build(); - service.show(mIsUserGestureDefaultValue, false); + service.show(false); assertNoError(); service.updateWith(null); assertErrorAndReason(ErrorStrings.INVALID_PAYMENT_DETAILS, @@ -364,7 +358,7 @@ @Feature({"Payments"}) public void testDetailsWithIdFailsUpdateWith() { PaymentRequestService service = defaultBuilder().build(); - service.show(mIsUserGestureDefaultValue, false); + service.show(false); PaymentDetails details = getDefaultPaymentDetailsUpdate(); details.id = "testId"; assertNoError(); @@ -379,7 +373,7 @@ @Feature({"Payments"}) public void testOnPaymentDetailsUpdatedIsInvoked() { PaymentRequestService service = defaultBuilder().build(); - service.show(mIsUserGestureDefaultValue, false); + service.show(false); updateWith(service); assertNoError(); Mockito.verify(mBrowserPaymentRequest, Mockito.times(1)) @@ -390,7 +384,7 @@ @Feature({"Payments"}) public void testNullDetailsFailsContinueShow() { PaymentRequestService service = defaultBuilder().build(); - service.show(mIsUserGestureDefaultValue, true); + service.show(true); assertNoError(); service.updateWith(null); assertErrorAndReason(ErrorStrings.INVALID_PAYMENT_DETAILS, PaymentErrorReason.USER_CANCEL); @@ -401,7 +395,7 @@ @Feature({"Payments"}) public void testDetailsWithIdFailsContinueShow() { PaymentRequestService service = defaultBuilder().build(); - service.show(mIsUserGestureDefaultValue, true); + service.show(true); assertNoError(); PaymentDetails details = getDefaultPaymentDetailsUpdate(); details.id = "testId"; @@ -414,7 +408,7 @@ @Feature({"Payments"}) public void testContinueShowIsInvoked() { PaymentRequestService service = defaultBuilder().build(); - service.show(mIsUserGestureDefaultValue, true); + service.show(true); updateWith(service); assertNoError(); verifyContinuedShowWithUpdatedDetails(1); @@ -625,10 +619,10 @@ PaymentRequestService service = defaultBuilder().build(); show(service); Mockito.verify(mBrowserPaymentRequest, Mockito.never()) - .onShowCalledAndAppsQueriedAndDetailsFinalized(Mockito.anyBoolean()); + .onShowCalledAndAppsQueriedAndDetailsFinalized(); queryPaymentApps(); Mockito.verify(mBrowserPaymentRequest, Mockito.times(1)) - .onShowCalledAndAppsQueriedAndDetailsFinalized(Mockito.anyBoolean()); + .onShowCalledAndAppsQueriedAndDetailsFinalized(); verifyJourneyLoggerRecordedTransactionAmount(); } @@ -637,15 +631,15 @@ @Feature({"Payments"}) public void testWaitingForUpdatedDetailsDeterUiSkipMethod() { PaymentRequestService service = defaultBuilder().build(); - service.show(mIsUserGestureDefaultValue, true); + service.show(true); Mockito.verify(mBrowserPaymentRequest, Mockito.never()) - .onShowCalledAndAppsQueriedAndDetailsFinalized(Mockito.anyBoolean()); + .onShowCalledAndAppsQueriedAndDetailsFinalized(); queryPaymentApps(); Mockito.verify(mBrowserPaymentRequest, Mockito.never()) - .onShowCalledAndAppsQueriedAndDetailsFinalized(Mockito.anyBoolean()); + .onShowCalledAndAppsQueriedAndDetailsFinalized(); updateWith(service); Mockito.verify(mBrowserPaymentRequest, Mockito.times(1)) - .onShowCalledAndAppsQueriedAndDetailsFinalized(Mockito.anyBoolean()); + .onShowCalledAndAppsQueriedAndDetailsFinalized(); verifyJourneyLoggerRecordedTransactionAmount(); } @@ -654,15 +648,15 @@ @Feature({"Payments"}) public void testQueryFinishCanTriggerUiSkipped() { PaymentRequestService service = defaultBuilder().build(); - service.show(mIsUserGestureDefaultValue, true); + service.show(true); Mockito.verify(mBrowserPaymentRequest, Mockito.never()) - .onShowCalledAndAppsQueriedAndDetailsFinalized(Mockito.anyBoolean()); + .onShowCalledAndAppsQueriedAndDetailsFinalized(); updateWith(service); Mockito.verify(mBrowserPaymentRequest, Mockito.never()) - .onShowCalledAndAppsQueriedAndDetailsFinalized(Mockito.anyBoolean()); + .onShowCalledAndAppsQueriedAndDetailsFinalized(); queryPaymentApps(); Mockito.verify(mBrowserPaymentRequest, Mockito.times(1)) - .onShowCalledAndAppsQueriedAndDetailsFinalized(Mockito.anyBoolean()); + .onShowCalledAndAppsQueriedAndDetailsFinalized(); verifyJourneyLoggerRecordedTransactionAmount(); }
diff --git a/components/payments/content/payment_request.cc b/components/payments/content/payment_request.cc index 982c2fc..8667e80 100644 --- a/components/payments/content/payment_request.cc +++ b/components/payments/content/payment_request.cc
@@ -276,6 +276,10 @@ } void PaymentRequest::Show(bool is_user_gesture, bool wait_for_updated_details) { + ShowNew(wait_for_updated_details); +} + +void PaymentRequest::ShowNew(bool wait_for_updated_details) { if (!IsInitialized()) { log_.Error(errors::kCannotShowWithoutInit); ResetAndDeleteThis(); @@ -320,8 +324,6 @@ return; } - is_show_user_gesture_ = is_user_gesture; - if (wait_for_updated_details) { // Put |spec_| into uninitialized state, so the UI knows to show a spinner. // This method does not block. @@ -341,7 +343,6 @@ if (!spec_->IsAppStoreBillingAlsoRequested()) display_handle_->Show(weak_ptr_factory_.GetWeakPtr()); - state_->set_is_show_user_gesture(is_show_user_gesture_); state_->AreRequestedMethodsSupported( base::BindOnce(&PaymentRequest::AreRequestedMethodsSupportedCallback, weak_ptr_factory_.GetWeakPtr())); @@ -747,8 +748,7 @@ delegate_->SkipUiForBasicCard()) && base::FeatureList::IsEnabled(features::kWebPaymentsSingleAppUiSkip) && base::FeatureList::IsEnabled(::features::kServiceWorkerPaymentApps) && - is_show_user_gesture_ && state()->IsInitialized() && - spec()->IsInitialized() && + state()->IsInitialized() && spec()->IsInitialized() && OnlySingleAppCanProvideAllRequiredInformation() && // The available app should be preselectable. state()->selected_app() != nullptr;
diff --git a/components/payments/content/payment_request.h b/components/payments/content/payment_request.h index 8a6c6a55..75be47c 100644 --- a/components/payments/content/payment_request.h +++ b/components/payments/content/payment_request.h
@@ -95,6 +95,7 @@ mojom::PaymentDetailsPtr details, mojom::PaymentOptionsPtr options) override; void Show(bool is_user_gesture, bool wait_for_updated_details) override; + void ShowNew(bool wait_for_updated_details) override; void Retry(mojom::PaymentValidationErrorsPtr errors) override; void UpdateWith(mojom::PaymentDetailsPtr details) override; void OnPaymentDetailsNotUpdated() override; @@ -142,7 +143,6 @@ void OnPaymentHandlerOpenWindowCalled(); bool skipped_payment_request_ui() { return skipped_payment_request_ui_; } - bool is_show_user_gesture() const { return is_show_user_gesture_; } SPCTransactionMode spc_transaction_mode() const { return spc_transaction_mode_; } @@ -255,11 +255,6 @@ // Whether a completion was already recorded for this Payment Request. bool has_recorded_completion_ = false; - // Whether PaymentRequest.show() was invoked with a user gesture. - // TODO(crbug.com/825270): Remove this member now that user gesture is always - // required for show(). - bool is_show_user_gesture_ = false; - // Whether PaymentRequest.show() was invoked by skipping payment request UI. bool skipped_payment_request_ui_ = false;
diff --git a/components/payments/content/payment_request_state.h b/components/payments/content/payment_request_state.h index 589f6ab..3a243e1 100644 --- a/components/payments/content/payment_request_state.h +++ b/components/payments/content/payment_request_state.h
@@ -299,10 +299,6 @@ base::WeakPtr<PaymentRequestState> AsWeakPtr(); - void set_is_show_user_gesture(bool is_show_user_gesture) { - is_show_user_gesture_ = is_show_user_gesture; - } - private: // Fetches the Autofill Profiles for this user from the PersonalDataManager, // and stores copies of them, owned by this PaymentRequestState, in @@ -416,9 +412,6 @@ base::ObserverList<Observer>::Unchecked observers_; - // Whether PaymentRequest.show() was invoked with a user gesture. - bool is_show_user_gesture_ = false; - // If set to true, then both GetCanMakePaymentValue() and // GetHasEnrolledInstrumentValue() will return true, regardless of presence of // payment apps. This is used by secure payment confirmation, where
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index 9d1dfcd5..5594bd0f 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -6821,7 +6821,7 @@ { 'name': 'BlockPopups', 'value': 2, - 'caption': '''Do not allow any site to show popups''', + 'caption': '''Do not allow any site to show pop-ups''', }, ], 'supported_on': [ @@ -6836,7 +6836,7 @@ }, 'example_value': 1, 'id': 52, - 'caption': '''Default popups setting''', + 'caption': '''Default pop-ups setting''', 'tags': [], 'desc': '''Setting the policy to 1 lets websites display pop-ups. Setting the policy to 2 denies pop-ups. @@ -8549,7 +8549,7 @@ }, 'example_value': ['https://www.example.com', '[*.]example.edu'], 'id': 75, - 'caption': '''Allow popups on these sites''', + 'caption': '''Allow pop-ups on these sites''', 'tags': [], 'desc': '''Setting the policy lets you set a list of URL patterns that specify the sites that can open pop-ups. @@ -8618,7 +8618,7 @@ }, 'example_value': ['https://www.example.com', '[*.]example.edu'], 'id': 76, - 'caption': '''Block popups on these sites''', + 'caption': '''Block pop-ups on these sites''', 'tags': [], 'desc': '''Setting the policy lets you set a list of URL patterns that specify the sites that can't open pop-ups. @@ -9314,11 +9314,11 @@ 'items': [ { 'value': True, - 'caption': 'Only allow popups opened with a target of <ph name="BLANK_PAGE_NAME">_blank</ph> to interact with the page that opened the popup if the opener page explicitly opts-in to such interaction', + 'caption': 'Only allow pop-ups opened with a target of <ph name="BLANK_PAGE_NAME">_blank</ph> to interact with the page that opened the pop-up if the opener page explicitly opts-in to such interaction', }, { 'value': False, - 'caption': 'Allow all popups opened with a target of <ph name="BLANK_PAGE_NAME">_blank</ph> to interact the page that requested to open the popup unless the opener page explicitly opts-out of such interaction ', + 'caption': 'Allow all pop-ups opened with a target of <ph name="BLANK_PAGE_NAME">_blank</ph> to interact the page that requested to open the pop-up unless the opener page explicitly opts-out of such interaction ', }, ], 'deprecated': True, @@ -9327,7 +9327,7 @@ 'id': 802, 'caption': '''Do not set <ph name="WINDOW_OPENER_PROPERTY">window.opener</ph> for links targeting <ph name="BLANK_PAGE_NAME">_blank</ph>''', 'tags': [], - 'desc': '''Setting the policy to Disabled allows popups targeting <ph name="BLANK_PAGE_NAME">_blank</ph> to access (via JavaScript) the page that requested to open the popup. + 'desc': '''Setting the policy to Disabled allows pop-ups targeting <ph name="BLANK_PAGE_NAME">_blank</ph> to access (via JavaScript) the page that requested to open the pop-up. Setting the policy to Enabled or leaving it unset causes the <ph name="WINDOW_OPENER_PROPERTY">window.opener</ph> property to be set to <ph name="NULL_VALUE">null</ph> unless the anchor specifies <ph name="REL_OPENER_ATTRIBUTE">rel="opener"</ph>. @@ -23786,7 +23786,7 @@ 'default_for_enterprise_users': False, 'example_value': False, 'id': 533, - 'caption': '''Allows a page to show popups during its unloading''', + 'caption': '''Allows a page to show pop-ups during its unloading''', 'tags': [], 'desc': '''Setting the policy to True allows pages to show pop-ups while the pages unload. @@ -27418,7 +27418,7 @@ 'default': True, 'example_value': True, 'id': 981, - 'caption': '''Control the URL parameter filter feature.''', + 'caption': '''Control the URL parameter filter feature''', 'tags': [], 'desc': '''When enabled or not set, the URL parameter filter may remove some parameters when a user selects "Open Link in Incognito Window" from the context menu. When disabled, no filtering is performed. @@ -31559,7 +31559,7 @@ { 'id': 12, 'name': 'PopupsSettings', - 'caption': '''Popups settings''', + 'caption': '''Pop-ups settings''', 'policies': [ 'DefaultPopupsSetting', 'PopupsAllowedForUrls',
diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc index 3a134ef..f0f4f9b 100644 --- a/components/printing/renderer/print_render_frame_helper.cc +++ b/components/printing/renderer/print_render_frame_helper.cc
@@ -1707,6 +1707,13 @@ return CREATE_FAIL; } + // If tagged PDF exporting is enabled, we also need to capture an + // accessibility tree. AXTreeSnapshotter should stay alive through the end of + // the scope of printing, because text drawing commands are only annotated + // with a DOMNodeId if accessibility is enabled. + if (delegate_->ShouldGenerateTaggedPDF()) + snapshotter_ = render_frame()->CreateAXTreeSnapshotter(ui::AXMode::kPDF); + double scale_factor = GetScaleFactor(print_params.scale_factor, /*is_pdf=*/!print_preview_context_.IsModifiable()); @@ -2591,13 +2598,6 @@ const bool is_modifiable = print_preview_context_.IsModifiable(); const bool has_selection = print_preview_context_.HasSelection(); - // If tagged PDF exporting is enabled, we also need to capture an - // accessibility tree. AXTreeSnapshotter should stay alive through the end of - // the scope of printing, because text drawing commands are only annotated - // with a DOMNodeId if accessibility is enabled. - if (delegate_->ShouldGenerateTaggedPDF()) - snapshotter_ = render_frame()->CreateAXTreeSnapshotter(ui::AXMode::kPDF); - auto params = mojom::RequestPrintPreviewParams::New(); #if BUILDFLAG(IS_CHROMEOS_ASH) params->is_from_arc = is_from_arc;
diff --git a/components/printing/test/print_render_frame_helper_browsertest.cc b/components/printing/test/print_render_frame_helper_browsertest.cc index 51d0750..02049e1 100644 --- a/components/printing/test/print_render_frame_helper_browsertest.cc +++ b/components/printing/test/print_render_frame_helper_browsertest.cc
@@ -153,6 +153,11 @@ mojo::PendingAssociatedRemote<mojom::PrintPreviewUI> BindReceiver() { return receiver_.BindNewEndpointAndPassDedicatedRemote(); } + void ResetPreviewStatus() { + // Make sure there is no active request. + DCHECK(!quit_closure_); + preview_status_ = PreviewStatus::kNone; + } // Waits until the preview request is failed, canceled, invalid, or done. void WaitUntilPreviewUpdate() { // If |preview_status_| is updated, it doesn't need to wait. @@ -427,6 +432,13 @@ std::move(callback).Run(preview_ui_->ShouldCancelRequest()); } #endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) +#if BUILDFLAG(ENABLE_TAGGED_PDF) + void SetAccessibilityTree( + int32_t cookie, + const ui::AXTreeUpdate& accessibility_tree) override { + ++accessibility_tree_set_count_; + } +#endif bool IsSetupScriptedPrintPreview() { return is_setup_scripted_print_preview_; @@ -457,6 +469,12 @@ } #endif +#if BUILDFLAG(ENABLE_TAGGED_PDF) + int accessibility_tree_set_count() const { + return accessibility_tree_set_count_; + } +#endif + private: void Init(content::RenderFrame* frame) { frame->GetRemoteAssociatedInterfaces()->OverrideBinderForTesting( @@ -484,9 +502,24 @@ base::OnceClosure quit_closure_; // True to simulate user clicking print. False to cancel. bool print_dialog_user_response_ = true; +#if BUILDFLAG(ENABLE_TAGGED_PDF) + int accessibility_tree_set_count_ = 0; +#endif mojo::AssociatedReceiver<mojom::PrintManagerHost> receiver_{this}; }; +class ScopedGenerateTaggedPDF { + public: + ScopedGenerateTaggedPDF() { + PrintTestContentRendererClient::SetGenerateTaggedPDFs(true); + } + ScopedGenerateTaggedPDF(const ScopedGenerateTaggedPDF&) = delete; + ScopedGenerateTaggedPDF& operator=(const ScopedGenerateTaggedPDF&) = delete; + ~ScopedGenerateTaggedPDF() { + PrintTestContentRendererClient::SetGenerateTaggedPDFs(false); + } +}; + } // namespace class PrintRenderFrameHelperTestBase : public content::RenderViewTest { @@ -969,15 +1002,19 @@ print_render_frame_helper->InitiatePrintPreview( mojo::NullAssociatedRemote(), false); print_render_frame_helper->PrintPreview(print_settings_.Clone()); - WaitForPreviewMessages(); + preview_ui()->WaitUntilPreviewUpdate(); + } + + void OnPrintPreviewRerender() { + preview_ui()->ResetPreviewStatus(); + GetPrintRenderFrameHelper()->PrintPreview(print_settings_.Clone()); + preview_ui()->WaitUntilPreviewUpdate(); } void OnClosePrintPreviewDialog() { GetPrintRenderFrameHelper()->OnPrintPreviewDialogClosed(); } - void WaitForPreviewMessages() { preview_ui()->WaitUntilPreviewUpdate(); } - void VerifyPreviewRequest(bool expect_request) { EXPECT_EQ(expect_request, print_manager()->IsSetupScriptedPrintPreview()); } @@ -1764,6 +1801,76 @@ ExpectOneBeforeOneAfterPrintEvent(); } +TEST_F(PrintRenderFrameHelperPreviewTest, + PrintPreviewRerenderWithNoTaggedPDFGeneration) { + LoadHTML(kHelloWorldHTML); + + OnPrintPreview(); + + EXPECT_EQ(0u, preview_ui()->print_preview_pages_remaining()); + VerifyDidPreviewPage(true, 0); + VerifyPreviewPageCount(1); + VerifyDefaultPageLayout(540, 720, 36, 36, 36, 36, false); + VerifyPrintPreviewCancelled(false); + VerifyPrintPreviewFailed(false); + VerifyPrintPreviewGenerated(true); + VerifyPagesPrinted(false); +#if BUILDFLAG(ENABLE_TAGGED_PDF) + EXPECT_EQ(0, print_manager()->accessibility_tree_set_count()); +#endif + + print_settings().SetIntKey(kSettingScaleFactor, 200); + OnPrintPreviewRerender(); + + EXPECT_EQ(0u, preview_ui()->print_preview_pages_remaining()); + VerifyDidPreviewPage(true, 0); + VerifyPreviewPageCount(1); + VerifyDefaultPageLayout(540, 720, 36, 36, 36, 36, false); + VerifyPrintPreviewCancelled(false); + VerifyPrintPreviewFailed(false); + VerifyPrintPreviewGenerated(true); + VerifyPagesPrinted(false); +#if BUILDFLAG(ENABLE_TAGGED_PDF) + EXPECT_EQ(0, print_manager()->accessibility_tree_set_count()); +#endif +} + +TEST_F(PrintRenderFrameHelperPreviewTest, + PrintPreviewRerenderGeneratesTaggedPDF) { + ScopedGenerateTaggedPDF generate_tagged_pdf; + + LoadHTML(kHelloWorldHTML); + + OnPrintPreview(); + + EXPECT_EQ(0u, preview_ui()->print_preview_pages_remaining()); + VerifyDidPreviewPage(true, 0); + VerifyPreviewPageCount(1); + VerifyDefaultPageLayout(540, 720, 36, 36, 36, 36, false); + VerifyPrintPreviewCancelled(false); + VerifyPrintPreviewFailed(false); + VerifyPrintPreviewGenerated(true); + VerifyPagesPrinted(false); +#if BUILDFLAG(ENABLE_TAGGED_PDF) + EXPECT_EQ(1, print_manager()->accessibility_tree_set_count()); +#endif + + print_settings().SetIntKey(kSettingScaleFactor, 200); + OnPrintPreviewRerender(); + + EXPECT_EQ(0u, preview_ui()->print_preview_pages_remaining()); + VerifyDidPreviewPage(true, 0); + VerifyPreviewPageCount(1); + VerifyDefaultPageLayout(540, 720, 36, 36, 36, 36, false); + VerifyPrintPreviewCancelled(false); + VerifyPrintPreviewFailed(false); + VerifyPrintPreviewGenerated(true); + VerifyPagesPrinted(false); +#if BUILDFLAG(ENABLE_TAGGED_PDF) + EXPECT_EQ(2, print_manager()->accessibility_tree_set_count()); +#endif +} + #endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) #endif // !BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/components/printing/test/print_test_content_renderer_client.cc b/components/printing/test/print_test_content_renderer_client.cc index 8bf504f..f6afe16 100644 --- a/components/printing/test/print_test_content_renderer_client.cc +++ b/components/printing/test/print_test_content_renderer_client.cc
@@ -14,9 +14,11 @@ namespace { +bool g_generate_tagged_pdfs = false; + class PrintRenderFrameHelperDelegate : public PrintRenderFrameHelper::Delegate { public: - ~PrintRenderFrameHelperDelegate() override {} + ~PrintRenderFrameHelperDelegate() override = default; blink::WebElement GetPdfElement(blink::WebLocalFrame* frame) override { return blink::WebElement(); @@ -28,15 +30,19 @@ return false; #endif } + bool ShouldGenerateTaggedPDF() override { return g_generate_tagged_pdfs; } bool OverridePrint(blink::WebLocalFrame* frame) override { return false; } }; } // namespace -PrintTestContentRendererClient::PrintTestContentRendererClient() { -} +PrintTestContentRendererClient::PrintTestContentRendererClient() = default; -PrintTestContentRendererClient::~PrintTestContentRendererClient() { +PrintTestContentRendererClient::~PrintTestContentRendererClient() = default; + +// static +void PrintTestContentRendererClient::SetGenerateTaggedPDFs(bool generate) { + g_generate_tagged_pdfs = generate; } void PrintTestContentRendererClient::RenderFrameCreated(
diff --git a/components/printing/test/print_test_content_renderer_client.h b/components/printing/test/print_test_content_renderer_client.h index 646117a..e1ed43a 100644 --- a/components/printing/test/print_test_content_renderer_client.h +++ b/components/printing/test/print_test_content_renderer_client.h
@@ -14,6 +14,9 @@ PrintTestContentRendererClient(); ~PrintTestContentRendererClient() override; + static void SetGenerateTaggedPDFs(bool generate); + + // content::ContentRendererClient: void RenderFrameCreated(content::RenderFrame* render_frame) override; };
diff --git a/components/safe_browsing/content/renderer/phishing_classifier/flatbuffer_scorer.cc b/components/safe_browsing/content/renderer/phishing_classifier/flatbuffer_scorer.cc index d93c10e..d6b8848 100644 --- a/components/safe_browsing/content/renderer/phishing_classifier/flatbuffer_scorer.cc +++ b/components/safe_browsing/content/renderer/phishing_classifier/flatbuffer_scorer.cc
@@ -178,7 +178,8 @@ #if BUILDFLAG(BUILD_WITH_TFLITE_LIB) void FlatBufferModelScorer::ApplyVisualTfLiteModel( const SkBitmap& bitmap, - base::OnceCallback<void(std::vector<double>)> callback) const { + base::OnceCallback<void(base::flat_map<std::string, double>)> callback) + const { DCHECK(content::RenderThread::IsMainThread()); if (visual_tflite_model_.IsValid()) { base::Time start_post_task_time = base::Time::Now(); @@ -196,7 +197,7 @@ "SBClientPhishing.TfLiteModelLoadTime.FlatbufferScorer", base::Time::Now() - start_post_task_time); } else { - std::move(callback).Run(std::vector<double>()); + std::move(callback).Run(base::flat_map<std::string, double>()); } } #endif
diff --git a/components/safe_browsing/content/renderer/phishing_classifier/flatbuffer_scorer.h b/components/safe_browsing/content/renderer/phishing_classifier/flatbuffer_scorer.h index b4622f91..3bb5f79 100644 --- a/components/safe_browsing/content/renderer/phishing_classifier/flatbuffer_scorer.h +++ b/components/safe_browsing/content/renderer/phishing_classifier/flatbuffer_scorer.h
@@ -51,7 +51,8 @@ #if BUILDFLAG(BUILD_WITH_TFLITE_LIB) void ApplyVisualTfLiteModel( const SkBitmap& bitmap, - base::OnceCallback<void(std::vector<double>)> callback) const override; + base::OnceCallback<void(base::flat_map<std::string, double>)> callback) + const override; #endif int model_version() const override;
diff --git a/components/safe_browsing/content/renderer/phishing_classifier/phishing_classifier.cc b/components/safe_browsing/content/renderer/phishing_classifier/phishing_classifier.cc index 9fcd0153..d9787dec 100644 --- a/components/safe_browsing/content/renderer/phishing_classifier/phishing_classifier.cc +++ b/components/safe_browsing/content/renderer/phishing_classifier/phishing_classifier.cc
@@ -316,23 +316,27 @@ void PhishingClassifier::OnVisualTfLiteModelDone( std::unique_ptr<ClientPhishingRequest> verdict, - std::vector<double> result) { - if (static_cast<int>(result.size()) > scorer_->tflite_thresholds().size()) { - // Model is misconfigured, so bail out. - RunFailureCallback(); - return; - } - + base::flat_map<std::string, double> result) { verdict->set_tflite_model_version(scorer_->tflite_model_version()); - for (size_t i = 0; i < result.size(); i++) { + for (const TfLiteModelMetadata::Threshold& label_and_threshold : + scorer_->tflite_thresholds()) { ClientPhishingRequest::CategoryScore* category = verdict->add_tflite_model_scores(); - category->set_label(scorer_->tflite_thresholds().at(i).label()); - category->set_value(result[i]); + category->set_label(label_and_threshold.label()); - if (result[i] >= scorer_->tflite_thresholds().at(i).threshold()) { - verdict->set_is_phishing(true); - verdict->set_is_tflite_match(true); + auto it = result.find(label_and_threshold.label()); + if (it == result.end()) { + // Model is misconfigured, so bail out. The class names from + // `visual_model.tflite` should exactly match the threshold labels in + // `client_model.pb` + RunFailureCallback(); + return; + } else { + category->set_value(it->second); + if (it->second >= label_and_threshold.threshold()) { + verdict->set_is_phishing(true); + verdict->set_is_tflite_match(true); + } } }
diff --git a/components/safe_browsing/content/renderer/phishing_classifier/phishing_classifier.h b/components/safe_browsing/content/renderer/phishing_classifier/phishing_classifier.h index add37ba..9d32f37f 100644 --- a/components/safe_browsing/content/renderer/phishing_classifier/phishing_classifier.h +++ b/components/safe_browsing/content/renderer/phishing_classifier/phishing_classifier.h
@@ -26,6 +26,7 @@ #include <vector> #include "base/callback.h" +#include "base/containers/flat_map.h" #include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -138,7 +139,7 @@ // Callback when the visual TFLite model has been applied, and returned a list // of scores. void OnVisualTfLiteModelDone(std::unique_ptr<ClientPhishingRequest> verdict, - std::vector<double> result); + base::flat_map<std::string, double> result); // Helper method to run the DoneCallback and clear the state. void RunCallback(const ClientPhishingRequest& verdict);
diff --git a/components/safe_browsing/content/renderer/phishing_classifier/protobuf_scorer.cc b/components/safe_browsing/content/renderer/phishing_classifier/protobuf_scorer.cc index cf6e038..9c8a780 100644 --- a/components/safe_browsing/content/renderer/phishing_classifier/protobuf_scorer.cc +++ b/components/safe_browsing/content/renderer/phishing_classifier/protobuf_scorer.cc
@@ -100,7 +100,8 @@ #if BUILDFLAG(BUILD_WITH_TFLITE_LIB) void ProtobufModelScorer::ApplyVisualTfLiteModel( const SkBitmap& bitmap, - base::OnceCallback<void(std::vector<double>)> callback) const { + base::OnceCallback<void(base::flat_map<std::string, double>)> callback) + const { DCHECK(content::RenderThread::IsMainThread()); if (visual_tflite_model_.IsValid()) { base::Time start_post_task_time = base::Time::Now(); @@ -118,7 +119,7 @@ "SBClientPhishing.TfLiteModelLoadTime.ProtobufScorer", base::Time::Now() - start_post_task_time); } else { - std::move(callback).Run(std::vector<double>()); + std::move(callback).Run(base::flat_map<std::string, double>()); } } #endif
diff --git a/components/safe_browsing/content/renderer/phishing_classifier/protobuf_scorer.h b/components/safe_browsing/content/renderer/phishing_classifier/protobuf_scorer.h index db968ac..df35a75 100644 --- a/components/safe_browsing/content/renderer/phishing_classifier/protobuf_scorer.h +++ b/components/safe_browsing/content/renderer/phishing_classifier/protobuf_scorer.h
@@ -49,7 +49,8 @@ #if BUILDFLAG(BUILD_WITH_TFLITE_LIB) void ApplyVisualTfLiteModel( const SkBitmap& bitmap, - base::OnceCallback<void(std::vector<double>)> callback) const override; + base::OnceCallback<void(base::flat_map<std::string, double>)> callback) + const override; #endif int model_version() const override;
diff --git a/components/safe_browsing/content/renderer/phishing_classifier/scorer.cc b/components/safe_browsing/content/renderer/phishing_classifier/scorer.cc index 4962a8ff..8980c63 100644 --- a/components/safe_browsing/content/renderer/phishing_classifier/scorer.cc +++ b/components/safe_browsing/content/renderer/phishing_classifier/scorer.cc
@@ -127,7 +127,7 @@ int input_height, std::unique_ptr<tflite::task::vision::ImageClassifier> classifier, scoped_refptr<base::SequencedTaskRunner> callback_task_runner, - base::OnceCallback<void(std::vector<double>)> callback) { + base::OnceCallback<void(base::flat_map<std::string, double>)> callback) { base::Time before_operation = base::Time::Now(); tflite::task::vision::FrameBuffer::Plane plane{ reinterpret_cast<const tflite::uint8*>(model_input.data()), @@ -142,15 +142,15 @@ if (!statusor_result.ok()) { VLOG(1) << statusor_result.status().ToString(); callback_task_runner->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), std::vector<double>())); + FROM_HERE, base::BindOnce(std::move(callback), + base::flat_map<std::string, double>())); return; } - std::vector<double> scores( - statusor_result->classifications(0).classes().size()); + base::flat_map<std::string, double> scores; for (const tflite::task::vision::Class& clas : statusor_result->classifications(0).classes()) { - scores[clas.index()] = clas.score(); + scores[clas.class_name()] = clas.score(); } callback_task_runner->PostTask( @@ -163,12 +163,13 @@ int input_height, std::unique_ptr<tflite::task::vision::ImageClassifier> classifier, scoped_refptr<base::SequencedTaskRunner> callback_task_runner, - base::OnceCallback<void(std::vector<double>)> callback) { + base::OnceCallback<void(base::flat_map<std::string, double>)> callback) { base::Time before_operation = base::Time::Now(); std::string model_input = GetModelInput(bitmap, input_width, input_height); if (model_input.empty()) { callback_task_runner->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), std::vector<double>())); + FROM_HERE, base::BindOnce(std::move(callback), + base::flat_map<std::string, double>())); return; } base::UmaHistogramTimes("SBClientPhishing.ApplyTfliteTime.GetModelInput", @@ -192,7 +193,7 @@ int input_height, std::string model_data, scoped_refptr<base::SequencedTaskRunner> callback_task_runner, - base::OnceCallback<void(std::vector<double>)> callback) { + base::OnceCallback<void(base::flat_map<std::string, double>)> callback) { TRACE_EVENT0("safe_browsing", "ApplyVisualTfLiteModel"); base::Time before_operation = base::Time::Now(); before_operation = base::Time::Now(); @@ -202,7 +203,8 @@ base::Time::Now() - before_operation); if (!classifier) { callback_task_runner->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), std::vector<double>())); + FROM_HERE, base::BindOnce(std::move(callback), + base::flat_map<std::string, double>())); return; }
diff --git a/components/safe_browsing/content/renderer/phishing_classifier/scorer.h b/components/safe_browsing/content/renderer/phishing_classifier/scorer.h index 6a34763..951bb728 100644 --- a/components/safe_browsing/content/renderer/phishing_classifier/scorer.h +++ b/components/safe_browsing/content/renderer/phishing_classifier/scorer.h
@@ -74,7 +74,8 @@ // order as `tflite_thresholds()`. virtual void ApplyVisualTfLiteModel( const SkBitmap& bitmap, - base::OnceCallback<void(std::vector<double>)> callback) const = 0; + base::OnceCallback<void(base::flat_map<std::string, double>)> callback) + const = 0; #endif // Returns the version number of the loaded client model. @@ -133,7 +134,7 @@ int input_height, std::string model_data, scoped_refptr<base::SequencedTaskRunner> callback_task_runner, - base::OnceCallback<void(std::vector<double>)> callback); + base::OnceCallback<void(base::flat_map<std::string, double>)> callback); base::MemoryMappedFile visual_tflite_model_; base::WeakPtrFactory<Scorer> weak_ptr_factory_{this};
diff --git a/components/services/storage/public/mojom/indexed_db_control_test.mojom b/components/services/storage/public/mojom/indexed_db_control_test.mojom index 6637a74..e3c413bc 100644 --- a/components/services/storage/public/mojom/indexed_db_control_test.mojom +++ b/components/services/storage/public/mojom/indexed_db_control_test.mojom
@@ -4,6 +4,7 @@ module storage.mojom; +import "components/services/storage/public/mojom/buckets/bucket_locator.mojom"; import "mojo/public/mojom/base/file_path.mojom"; import "mojo/public/mojom/base/values.mojom"; import "mojo/public/mojom/base/time.mojom"; @@ -60,19 +61,19 @@ (V2SchemaCorruptionStatus status); // Does a direct write to a database with a given key/value pair. - WriteToIndexedDBForTesting(blink.mojom.StorageKey storage_key, string key, - string value) => (); + WriteToIndexedDBForTesting(storage.mojom.BucketLocator bucket_locator, + string key, string value) => (); // Returns the number of blobs for a given `storage_key`. GetBlobCountForTesting(blink.mojom.StorageKey storage_key) => (int64 num_blobs); // Returns the next blob id for a given `storage_key`. - GetNextBlobNumberForTesting(blink.mojom.StorageKey storage_key, + GetNextBlobNumberForTesting(storage.mojom.BucketLocator bucket_locator, int64 database_id) => (int64 next_blob_number); // Returns the path for a given key/database/blob. - GetPathForBlobForTesting(blink.mojom.StorageKey storage_key, + GetPathForBlobForTesting(storage.mojom.BucketLocator bucket_locator, int64 database_id, int64 blob_number) => (mojo_base.mojom.FilePath path);
diff --git a/components/viz/service/display_embedder/compositor_gpu_thread.cc b/components/viz/service/display_embedder/compositor_gpu_thread.cc index 6e5914b..ad24c340 100644 --- a/components/viz/service/display_embedder/compositor_gpu_thread.cc +++ b/components/viz/service/display_embedder/compositor_gpu_thread.cc
@@ -47,7 +47,8 @@ // currently always enables this extension, we are adding DCHECK() to ensure // that instead of enabling/disabling DrDc based on the extension. if (gl::GetGLImplementation() == gl::kGLImplementationEGLANGLE) - DCHECK(gl::GLSurfaceEGL::IsANGLEContextVirtualizationSupported()); + DCHECK(gl::GLSurfaceEGL::GetGLDisplayEGL() + ->IsANGLEContextVirtualizationSupported()); #endif scoped_refptr<VulkanContextProvider> vulkan_context_provider;
diff --git a/components/viz/service/display_embedder/output_presenter.cc b/components/viz/service/display_embedder/output_presenter.cc index 1c38275..0c9aced7 100644 --- a/components/viz/service/display_embedder/output_presenter.cc +++ b/components/viz/service/display_embedder/output_presenter.cc
@@ -84,12 +84,13 @@ // The Flush now takes place in finishPaintCurrentBuffer on the CPU side. // check if end_semaphores is not empty then flush here DCHECK(scoped_skia_write_access_); - if (!end_semaphores_.empty() || force_flush) { + auto end_state = scoped_skia_write_access_->TakeEndState(); + if (!end_semaphores_.empty() || end_state || force_flush) { GrFlushInfo flush_info = { .fNumSemaphores = end_semaphores_.size(), .fSignalSemaphores = end_semaphores_.data(), }; - scoped_skia_write_access_->surface()->flush(flush_info); + scoped_skia_write_access_->surface()->flush(flush_info, end_state.get()); auto* direct_context = scoped_skia_write_access_->surface() ->recordingContext() ->asDirectContext();
diff --git a/content/browser/attribution_reporting/attribution_parser_test_utils.cc b/content/browser/attribution_reporting/attribution_parser_test_utils.cc new file mode 100644 index 0000000..3f2be7c --- /dev/null +++ b/content/browser/attribution_reporting/attribution_parser_test_utils.cc
@@ -0,0 +1,70 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/attribution_reporting/attribution_parser_test_utils.h" + +#include <ostream> + +#include "base/strings/string_piece.h" + +namespace content { + +AttributionParserErrorManager::AttributionParserErrorManager( + std::ostream& stream) + : error_stream_(stream) {} + +AttributionParserErrorManager::~AttributionParserErrorManager() = default; + +AttributionParserErrorManager::ScopedContext::ScopedContext(ContextPath& path, + Context context) + : path_(path) { + path_.push_back(context); +} + +AttributionParserErrorManager::ScopedContext::~ScopedContext() { + path_.pop_back(); +} + +AttributionParserErrorManager::ErrorWriter::ErrorWriter(std::ostream& stream) + : stream_(stream) {} + +AttributionParserErrorManager::ErrorWriter::~ErrorWriter() { + stream_ << std::endl; +} + +std::ostream& AttributionParserErrorManager::ErrorWriter::operator*() { + return stream_; +} + +void AttributionParserErrorManager::ErrorWriter::operator()( + base::StringPiece key) { + stream_ << "[\"" << key << "\"]"; +} + +void AttributionParserErrorManager::ErrorWriter::operator()(size_t index) { + stream_ << '[' << index << ']'; +} + +AttributionParserErrorManager::ScopedContext +AttributionParserErrorManager::PushContext(Context context) { + return ScopedContext(context_path_, context); +} + +AttributionParserErrorManager::ErrorWriter +AttributionParserErrorManager::Error() { + has_error_ = true; + + if (context_path_.empty()) + error_stream_ << "input root"; + + ErrorWriter writer(error_stream_); + for (Context context : context_path_) { + absl::visit(writer, context); + } + + error_stream_ << ": "; + return writer; +} + +} // namespace content
diff --git a/content/browser/attribution_reporting/attribution_parser_test_utils.h b/content/browser/attribution_reporting/attribution_parser_test_utils.h new file mode 100644 index 0000000..b29c7757 --- /dev/null +++ b/content/browser/attribution_reporting/attribution_parser_test_utils.h
@@ -0,0 +1,88 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_PARSER_TEST_UTILS_H_ +#define CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_PARSER_TEST_UTILS_H_ + +#include <stddef.h> + +#include <iosfwd> +#include <vector> + +#include "base/strings/string_piece_forward.h" +#include "third_party/abseil-cpp/absl/types/variant.h" + +namespace content { + +class AttributionParserErrorManager { + public: + using Context = absl::variant<base::StringPiece, size_t>; + using ContextPath = std::vector<Context>; + + explicit AttributionParserErrorManager(std::ostream& stream); + ~AttributionParserErrorManager(); + + AttributionParserErrorManager(const AttributionParserErrorManager&) = delete; + AttributionParserErrorManager(AttributionParserErrorManager&&) = delete; + + AttributionParserErrorManager& operator=( + const AttributionParserErrorManager&) = delete; + AttributionParserErrorManager& operator=(AttributionParserErrorManager&&) = + delete; + + class ScopedContext { + public: + ScopedContext(ContextPath& path, Context context); + + ~ScopedContext(); + + ScopedContext(const ScopedContext&) = delete; + ScopedContext(ScopedContext&&) = delete; + + ScopedContext& operator=(const ScopedContext&) = delete; + ScopedContext& operator=(ScopedContext&&) = delete; + + private: + ContextPath& path_; + }; + + // Writes a newline on destruction. + class ErrorWriter { + public: + explicit ErrorWriter(std::ostream& stream); + + ~ErrorWriter(); + + ErrorWriter(const ErrorWriter&) = delete; + ErrorWriter(ErrorWriter&&) = default; + + ErrorWriter& operator=(const ErrorWriter&) = delete; + ErrorWriter& operator=(ErrorWriter&&) = delete; + + std::ostream& operator*(); + + void operator()(base::StringPiece key); + + void operator()(size_t index); + + private: + std::ostream& stream_; + }; + + [[nodiscard]] ScopedContext PushContext(Context context); + + ErrorWriter Error(); + + bool has_error() const { return has_error_; } + + private: + std::ostream& error_stream_; + + ContextPath context_path_; + bool has_error_ = false; +}; + +} // namespace content + +#endif // CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_PARSER_TEST_UTILS_H_
diff --git a/content/browser/attribution_reporting/attributions_browsertest.cc b/content/browser/attribution_reporting/attributions_browsertest.cc index de4862f..fc3c8a82 100644 --- a/content/browser/attribution_reporting/attributions_browsertest.cc +++ b/content/browser/attribution_reporting/attributions_browsertest.cc
@@ -213,70 +213,6 @@ loop.Run(); } - void CreateAndClickSource(WebContents* web_contents, - const GURL& href, - const GURL& attribution_src) { - CreateAndClickSourceInFrame(web_contents, web_contents->GetMainFrame(), - href, attribution_src, - /*target=*/"_top"); - } - - WebContents* CreateAndClickPopupSource(WebContents* web_contents, - const GURL& href, - const GURL& attribution_src, - const std::string& target) { - return CreateAndClickSourceInFrame(nullptr, web_contents->GetMainFrame(), - href, attribution_src, target); - } - - WebContents* CreateAndClickSourceInFrame(WebContents* web_contents, - RenderFrameHost* rfh, - const GURL& href, - const GURL& attribution_src, - const std::string& target) { - EXPECT_TRUE(ExecJs(rfh, JsReplace(R"( - createAttributionSrcAnchor({id: 'link', - url: $1, - attributionsrc: $2, - target: $3});)", - href, attribution_src, target))); - - MockAttributionObserver source_observer; - base::ScopedObservation<AttributionManager, AttributionObserver> - observation(&source_observer); - observation.Observe(attribution_manager()); - - base::RunLoop loop; - bool received = false; - EXPECT_CALL(source_observer, - OnSourceHandled(_, StorableSource::Result::kSuccess)) - .WillOnce([&]() { - received = true; - loop.Quit(); - }); - - WebContents* popup_contents = nullptr; - if (!web_contents) { - ShellAddedObserver new_shell_observer; - TestNavigationObserver observer(nullptr); - observer.StartWatchingNewWebContents(); - EXPECT_TRUE(ExecJs(rfh, "simulateClick('link');")); - popup_contents = new_shell_observer.GetShell()->web_contents(); - observer.Wait(); - } else { - TestNavigationObserver observer(web_contents); - EXPECT_TRUE(ExecJs(rfh, "simulateClick('link');")); - observer.Wait(); - } - - // If the source wasn't processed, wait to ensure we handle events in test - // order. See https://crbug.com/1309173. - if (!received) - loop.Run(); - - return popup_contents; - } - private: std::unique_ptr<net::EmbeddedTestServer> https_server_; @@ -295,8 +231,8 @@ ExpectedReportWaiter expected_report( GURL("https://a.test/.well-known/attribution-reporting/" "report-event-attribution"), - /*attribution_destination=*/"https://d.test", - /*source_event_id=*/"5", /*source_type=*/"navigation", + /*attribution_destination=*/"https://b.test", + /*source_event_id=*/"1", /*source_type=*/"navigation", /*trigger_data=*/"7", https_server()); ASSERT_TRUE(https_server()->Start()); @@ -307,11 +243,19 @@ // Create an anchor tag with impression attributes and click the link. By // default the target is set to "_top". GURL conversion_url = https_server()->GetURL( - "d.test", "/attribution_reporting/page_with_conversion_redirect.html"); - GURL register_source_url = https_server()->GetURL( - "a.test", "/attribution_reporting/register_source_headers.html"); + "b.test", "/attribution_reporting/page_with_conversion_redirect.html"); + EXPECT_TRUE( + ExecJs(web_contents(), + JsReplace(R"( + createImpressionTag({id: 'link', + url: $1, + data: '1', + destination: $2});)", + conversion_url, url::Origin::Create(conversion_url)))); - CreateAndClickSource(web_contents(), conversion_url, register_source_url); + TestNavigationObserver observer(web_contents()); + EXPECT_TRUE(ExecJs(shell(), "simulateClick('link');")); + observer.Wait(); GURL register_trigger_url = https_server()->GetURL( "a.test", "/attribution_reporting/register_trigger_headers.html"); @@ -400,8 +344,8 @@ ExpectedReportWaiter expected_report( GURL("https://a.test/.well-known/attribution-reporting/" "report-event-attribution"), - /*attribution_destination=*/"https://d.test", - /*source_event_id=*/"5", /*source_type=*/"navigation", + /*attribution_destination=*/"https://b.test", + /*source_event_id=*/"1", /*source_type=*/"navigation", /*trigger_data=*/"7", https_server()); ASSERT_TRUE(https_server()->Start()); @@ -416,15 +360,24 @@ NavigateIframeToURL(web_contents(), "test_iframe", subframe_url); RenderFrameHost* subframe = ChildFrameAt(web_contents()->GetMainFrame(), 0); - GURL conversion_url = https_server()->GetURL( - "d.test", "/attribution_reporting/page_with_conversion_redirect.html"); - GURL register_source_url = https_server()->GetURL( - "a.test", "/attribution_reporting/register_source_headers.html"); - // Create an impression tag in the subframe and target a popup window. - auto* popup_contents = CreateAndClickSourceInFrame( - /*web-contents=*/nullptr, subframe, conversion_url, register_source_url, - /*target=*/"new_frame"); + GURL conversion_url = https_server()->GetURL( + "b.test", "/attribution_reporting/page_with_conversion_redirect.html"); + EXPECT_TRUE(ExecJs(subframe, JsReplace(R"( + createImpressionTag({id: 'link', + url: $1, + data: '1', + destination: $2, + target: 'new_frame'});)", + conversion_url, + url::Origin::Create(conversion_url)))); + + ShellAddedObserver new_shell_observer; + TestNavigationObserver observer(nullptr); + observer.StartWatchingNewWebContents(); + EXPECT_TRUE(ExecJs(subframe, "simulateClick('link');")); + WebContents* popup_contents = new_shell_observer.GetShell()->web_contents(); + observer.Wait(); GURL register_trigger_url = https_server()->GetURL( "a.test", "/attribution_reporting/register_trigger_headers.html"); @@ -439,8 +392,8 @@ ExpectedReportWaiter expected_report( GURL("https://a.test/.well-known/attribution-reporting/" "report-event-attribution"), - /*attribution_destination=*/"https://d.test", - /*source_event_id=*/"5", /*source_type=*/"navigation", + /*attribution_destination=*/"https://b.test", + /*source_event_id=*/"1", /*source_type=*/"navigation", /*trigger_data=*/"7", https_server()); ASSERT_TRUE(https_server()->Start()); @@ -449,13 +402,23 @@ EXPECT_TRUE(NavigateToURL(web_contents(), impression_url)); GURL conversion_url = https_server()->GetURL( - "d.test", "/attribution_reporting/page_with_conversion_redirect.html"); - GURL register_source_url = https_server()->GetURL( - "a.test", "/attribution_reporting/register_source_headers.html"); + "b.test", "/attribution_reporting/page_with_conversion_redirect.html"); // target="_blank" navs are rel="noopener" by default. - CreateAndClickPopupSource(web_contents(), conversion_url, register_source_url, - /*target=*/"_blank"); + EXPECT_TRUE( + ExecJs(web_contents(), + JsReplace(R"( + createImpressionTag({id: 'link', + url: $1, + data: '1', + destination: $2, + target: '_blank'});)", + conversion_url, url::Origin::Create(conversion_url)))); + + TestNavigationObserver observer(nullptr); + observer.StartWatchingNewWebContents(); + EXPECT_TRUE(ExecJs(shell(), "simulateClick('link');")); + observer.Wait(); GURL register_trigger_url = https_server()->GetURL( "a.test", "/attribution_reporting/register_trigger_headers.html"); @@ -470,26 +433,39 @@ ImpressionConversionSameDomain_ReportSent) { // Expected reports must be registered before the server starts. ExpectedReportWaiter expected_report( - GURL("https://d.test/.well-known/attribution-reporting/" + GURL("https://a.test/.well-known/attribution-reporting/" "report-event-attribution"), - /*attribution_destination=*/"https://d.test", - /*source_event_id=*/"5", /*source_type=*/"navigation", + /*attribution_destination=*/"https://b.test", + /*source_event_id=*/"1", /*source_type=*/"navigation", /*trigger_data=*/"7", https_server()); ASSERT_TRUE(https_server()->Start()); GURL impression_url = https_server()->GetURL( - "d.test", "/attribution_reporting/page_with_impression_creator.html"); + "a.test", "/attribution_reporting/page_with_impression_creator.html"); EXPECT_TRUE(NavigateToURL(web_contents(), impression_url)); + // Create an anchor tag with impression attributes and click the link. By + // default the target is set to "_top". GURL conversion_url = https_server()->GetURL( - "d.test", "/attribution_reporting/page_with_conversion_redirect.html"); - GURL register_source_url = https_server()->GetURL( - "d.test", "/attribution_reporting/register_source_headers.html"); + "b.test", "/attribution_reporting/page_with_conversion_redirect.html"); + GURL conversion_dest_url = https_server()->GetURL( + "sub.b.test", + "/attribution_reporting/page_with_conversion_redirect.html"); + EXPECT_TRUE(ExecJs( + web_contents(), + JsReplace(R"( + createImpressionTag({id: 'link', + url: $1, + data: '1', + destination: $2});)", + conversion_url, url::Origin::Create(conversion_dest_url)))); - CreateAndClickSource(web_contents(), conversion_url, register_source_url); + TestNavigationObserver observer(web_contents()); + EXPECT_TRUE(ExecJs(shell(), "simulateClick('link');")); + observer.Wait(); GURL register_trigger_url = https_server()->GetURL( - "d.test", "/attribution_reporting/register_trigger_headers.html"); + "a.test", "/attribution_reporting/register_trigger_headers.html"); EXPECT_TRUE(ExecJs(web_contents(), JsReplace("createAttributionSrcImg($1);", register_trigger_url))); @@ -503,8 +479,8 @@ ExpectedReportWaiter expected_report( GURL("https://a.test/.well-known/attribution-reporting/" "report-event-attribution"), - /*attribution_destination=*/"https://d.test", - /*source_event_id=*/"5", /*source_type=*/"navigation", + /*attribution_destination=*/"https://b.test", + /*source_event_id=*/"1", /*source_type=*/"navigation", /*trigger_data=*/"7", https_server()); ASSERT_TRUE(https_server()->Start()); @@ -512,20 +488,32 @@ "a.test", "/attribution_reporting/page_with_impression_creator.html"); EXPECT_TRUE(NavigateToURL(web_contents(), impression_url)); - GURL conversion_url = https_server()->GetURL( - "sub.d.test", + // Create an anchor tag with impression attributes and click the link. By + // default the target is set to "_top". + GURL conversion_landing_url = https_server()->GetURL( + "b.test", "/attribution_reporting/page_with_conversion_redirect.html"); + GURL conversion_dest_url = https_server()->GetURL( + "sub.b.test", "/attribution_reporting/page_with_conversion_redirect.html"); - GURL register_source_url = https_server()->GetURL( - "a.test", "/attribution_reporting/register_source_headers.html"); + EXPECT_TRUE(ExecJs(web_contents(), + JsReplace(R"( + createImpressionTag({id: 'link', + url: $1, + data: '1', + destination: $2});)", + conversion_landing_url, + url::Origin::Create(conversion_dest_url)))); - CreateAndClickSource(web_contents(), conversion_url, register_source_url); + TestNavigationObserver observer(web_contents()); + EXPECT_TRUE(ExecJs(shell(), "simulateClick('link');")); + observer.Wait(); // Navigate to a same domain origin that is different than the landing page // for the click and convert there. A report should still be sent. - GURL other_conversion_url = https_server()->GetURL( - "other.d.test", + GURL conversion_url = https_server()->GetURL( + "other.b.test", "/attribution_reporting/page_with_conversion_redirect.html"); - EXPECT_TRUE(NavigateToURL(web_contents(), other_conversion_url)); + EXPECT_TRUE(NavigateToURL(web_contents(), conversion_url)); GURL register_trigger_url = https_server()->GetURL( "a.test", "/attribution_reporting/register_trigger_headers.html"); @@ -539,9 +527,9 @@ AttributionsBrowserTest, MultipleImpressionsPerConversion_ReportSentWithAttribution) { ExpectedReportWaiter expected_report( - GURL("https://b.test/.well-known/attribution-reporting/" + GURL("https://d.test/.well-known/attribution-reporting/" "report-event-attribution"), - /*attribution_destination=*/"https://d.test", + /*attribution_destination=*/"https://b.test", /*source_event_id=*/"2", /*source_type=*/"navigation", /*trigger_data=*/"7", https_server()); ASSERT_TRUE(https_server()->Start()); @@ -557,67 +545,96 @@ GURL(), nullptr, gfx::Size(100, 100)); EXPECT_TRUE(NavigateToURL(shell2->web_contents(), second_impression_url)); - GURL conversion_url = https_server()->GetURL( - "d.test", "/attribution_reporting/page_with_conversion_redirect.html"); - GURL register_source_url = https_server()->GetURL( - "b.test", "/attribution_reporting/register_source_headers.html"); - - CreateAndClickSource(shell()->web_contents(), conversion_url, - register_source_url); - - GURL register_source_url_2 = https_server()->GetURL( - "b.test", "/attribution_reporting/register_source_headers_2.html"); - CreateAndClickSource(shell2->web_contents(), conversion_url, - register_source_url_2); - - GURL register_trigger_url = https_server()->GetURL( - "b.test", "/attribution_reporting/register_trigger_headers.html"); - EXPECT_TRUE(ExecJs( - shell2, JsReplace("createAttributionSrcImg($1);", register_trigger_url))); - - expected_report.WaitForReport(); -} - -IN_PROC_BROWSER_TEST_F( - AttributionsBrowserTest, - MultipleImpressionsPerConversion_ReportSentWithHighestPriority) { - // Report will be sent for the impression with highest priority. - ExpectedReportWaiter expected_report( - GURL("https://b.test/.well-known/attribution-reporting/" - "report-event-attribution"), - /*attribution_destination=*/"https://d.test", - /*source_event_id=*/"3", /*source_type=*/"navigation", - /*trigger_data=*/"7", https_server()); - ASSERT_TRUE(https_server()->Start()); - - GURL first_impression_url = https_server()->GetURL( - "a.test", "/attribution_reporting/page_with_impression_creator.html"); - EXPECT_TRUE(NavigateToURL(web_contents(), first_impression_url)); - - GURL second_impression_url = https_server()->GetURL( - "c.test", "/attribution_reporting/page_with_impression_creator.html"); - Shell* shell2 = - Shell::CreateNewWindow(shell()->web_contents()->GetBrowserContext(), - GURL(), nullptr, gfx::Size(100, 100)); - EXPECT_TRUE(NavigateToURL(shell2->web_contents(), second_impression_url)); - // Register impressions from both windows. GURL conversion_url = https_server()->GetURL( - "d.test", "/attribution_reporting/page_with_conversion_redirect.html"); - GURL register_source_url = https_server()->GetURL( - "b.test", - "/attribution_reporting/register_source_headers_high_priority.html"); + "b.test", "/attribution_reporting/page_with_conversion_redirect.html"); + url::Origin reporting_origin = + url::Origin::Create(https_server()->GetURL("d.test", "/")); + std::string impression_js = R"( + createImpressionTag({id: 'link', + url: $1, + data: $2, + destination: $3, + reportOrigin: $4});)"; - CreateAndClickSource(shell()->web_contents(), conversion_url, - register_source_url); + TestNavigationObserver first_nav_observer(shell()->web_contents()); + EXPECT_TRUE( + ExecJs(shell(), + JsReplace(impression_js, conversion_url, "1" /* impression_data */, + url::Origin::Create(conversion_url), reporting_origin))); + EXPECT_TRUE(ExecJs(shell(), "simulateClick('link');")); + first_nav_observer.Wait(); - GURL register_source_url_2 = https_server()->GetURL( - "b.test", "/attribution_reporting/register_source_headers.html"); - CreateAndClickSource(shell2->web_contents(), conversion_url, - register_source_url_2); + TestNavigationObserver second_nav_observer(shell2->web_contents()); + EXPECT_TRUE( + ExecJs(shell2, + JsReplace(impression_js, conversion_url, "2" /* impression_data */, + url::Origin::Create(conversion_url), reporting_origin))); + EXPECT_TRUE(ExecJs(shell2, "simulateClick('link');")); + second_nav_observer.Wait(); GURL register_trigger_url = https_server()->GetURL( - "b.test", "/attribution_reporting/register_trigger_headers.html"); + "d.test", "/attribution_reporting/register_trigger_headers.html"); + EXPECT_TRUE(ExecJs( + shell2, JsReplace("createAttributionSrcImg($1);", register_trigger_url))); + + expected_report.WaitForReport(); +} + +IN_PROC_BROWSER_TEST_F( + AttributionsBrowserTest, + MultipleImpressionsPerConversion_ReportSentWithHighestPriority) { + // Report will be sent for the impression with highest priority. + ExpectedReportWaiter expected_report( + GURL("https://d.test/.well-known/attribution-reporting/" + "report-event-attribution"), + /*attribution_destination=*/"https://b.test", + /*source_event_id=*/"1", /*source_type=*/"navigation", + /*trigger_data=*/"7", https_server()); + ASSERT_TRUE(https_server()->Start()); + + GURL first_impression_url = https_server()->GetURL( + "a.test", "/attribution_reporting/page_with_impression_creator.html"); + EXPECT_TRUE(NavigateToURL(web_contents(), first_impression_url)); + + GURL second_impression_url = https_server()->GetURL( + "c.test", "/attribution_reporting/page_with_impression_creator.html"); + Shell* shell2 = + Shell::CreateNewWindow(shell()->web_contents()->GetBrowserContext(), + GURL(), nullptr, gfx::Size(100, 100)); + EXPECT_TRUE(NavigateToURL(shell2->web_contents(), second_impression_url)); + + // Register impressions from both windows. + GURL conversion_url = https_server()->GetURL( + "b.test", "/attribution_reporting/page_with_conversion_redirect.html"); + url::Origin reporting_origin = + url::Origin::Create(https_server()->GetURL("d.test", "/")); + std::string impression_js = R"( + createImpressionTag({id: 'link', + url: $1, + data: $2, + destination: $3, + reportOrigin: $4, + priority: $5});)"; + + TestNavigationObserver first_nav_observer(shell()->web_contents()); + EXPECT_TRUE(ExecJs(shell(), JsReplace(impression_js, conversion_url, + "1" /* impression_data */, + url::Origin::Create(conversion_url), + reporting_origin, 10 /* priority */))); + EXPECT_TRUE(ExecJs(shell(), "simulateClick('link');")); + first_nav_observer.Wait(); + + TestNavigationObserver second_nav_observer(shell2->web_contents()); + EXPECT_TRUE(ExecJs(shell2, JsReplace(impression_js, conversion_url, + "2" /* impression_data */, + url::Origin::Create(conversion_url), + reporting_origin, 5 /* priority */))); + EXPECT_TRUE(ExecJs(shell2, "simulateClick('link');")); + second_nav_observer.Wait(); + + GURL register_trigger_url = https_server()->GetURL( + "d.test", "/attribution_reporting/register_trigger_headers.html"); EXPECT_TRUE(ExecJs( shell2, JsReplace("createAttributionSrcImg($1);", register_trigger_url))); @@ -792,6 +809,7 @@ EXPECT_TRUE(ExecJs( web_contents(), + JsReplace(R"(createAndClickAttributionSrcAnchor({url: $1, attributionsrc: $2});)", https_server()->GetURL( @@ -820,15 +838,15 @@ ExpectedReportWaiter expected_report1( GURL("https://a.test/.well-known/attribution-reporting/" "report-event-attribution"), - /*attribution_destination=*/"https://d.test", - /*source_event_id=*/"5", /*source_type=*/"navigation", + /*attribution_destination=*/"https://b.test", + /*source_event_id=*/"1", /*source_type=*/"navigation", /*trigger_data=*/"1", https_server()); // 12 below is sanitized to 4 here by `SanitizeTriggerData()`. ExpectedReportWaiter expected_report2( GURL("https://a.test/.well-known/attribution-reporting/" "report-event-attribution"), - /*attribution_destination=*/"https://d.test", - /*source_event_id=*/"5", /*source_type=*/"navigation", + /*attribution_destination=*/"https://b.test", + /*source_event_id=*/"1", /*source_type=*/"navigation", /*trigger_data=*/"7", https_server()); ASSERT_TRUE(https_server()->Start()); @@ -836,12 +854,22 @@ "a.test", "/attribution_reporting/page_with_impression_creator.html"); EXPECT_TRUE(NavigateToURL(web_contents(), impression_url)); + // Create an anchor tag with impression attributes and click the link. By + // default the target is set to "_top". GURL conversion_url = https_server()->GetURL( - "d.test", "/attribution_reporting/page_with_conversion_redirect.html"); - GURL register_source_url = https_server()->GetURL( - "a.test", "/attribution_reporting/register_source_headers.html"); + "b.test", "/attribution_reporting/page_with_conversion_redirect.html"); + EXPECT_TRUE( + ExecJs(web_contents(), + JsReplace(R"( + createImpressionTag({id: 'link', + url: $1, + data: '1', + destination: $2});)", + conversion_url, url::Origin::Create(conversion_url)))); - CreateAndClickSource(web_contents(), conversion_url, register_source_url); + TestNavigationObserver observer(web_contents()); + EXPECT_TRUE(ExecJs(shell(), "simulateClick('link');")); + observer.Wait(); GURL register_trigger_with_dedup_url = https_server()->GetURL( "a.test", "/attribution_reporting/register_trigger_headers_dedup.html");
diff --git a/content/browser/indexed_db/cursor_impl.cc b/content/browser/indexed_db/cursor_impl.cc index 16ac5db26..4a48299 100644 --- a/content/browser/indexed_db/cursor_impl.cc +++ b/content/browser/indexed_db/cursor_impl.cc
@@ -15,11 +15,11 @@ namespace content { CursorImpl::CursorImpl(std::unique_ptr<IndexedDBCursor> cursor, - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, IndexedDBDispatcherHost* dispatcher_host, scoped_refptr<base::SequencedTaskRunner> idb_runner) : dispatcher_host_(dispatcher_host), - storage_key_(storage_key), + bucket_locator_(bucket_locator), idb_runner_(std::move(idb_runner)), cursor_(std::move(cursor)) { DCHECK(idb_runner_);
diff --git a/content/browser/indexed_db/cursor_impl.h b/content/browser/indexed_db/cursor_impl.h index 802a446..2815b61 100644 --- a/content/browser/indexed_db/cursor_impl.h +++ b/content/browser/indexed_db/cursor_impl.h
@@ -10,8 +10,8 @@ #include "base/memory/raw_ptr.h" #include "base/memory/ref_counted.h" #include "base/sequence_checker.h" +#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "third_party/blink/public/common/indexeddb/indexeddb_key.h" -#include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h" namespace base { @@ -26,7 +26,7 @@ class CursorImpl : public blink::mojom::IDBCursor { public: CursorImpl(std::unique_ptr<IndexedDBCursor> cursor, - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, IndexedDBDispatcherHost* dispatcher_host, scoped_refptr<base::SequencedTaskRunner> idb_runner); @@ -53,7 +53,7 @@ // This raw pointer is safe because all CursorImpl instances are owned by an // IndexedDBDispatcherHost. raw_ptr<IndexedDBDispatcherHost> dispatcher_host_; - const blink::StorageKey storage_key_; + const storage::BucketLocator bucket_locator_; scoped_refptr<base::SequencedTaskRunner> idb_runner_; std::unique_ptr<IndexedDBCursor> cursor_;
diff --git a/content/browser/indexed_db/database_impl.cc b/content/browser/indexed_db/database_impl.cc index 6139018..c1e98b10 100644 --- a/content/browser/indexed_db/database_impl.cc +++ b/content/browser/indexed_db/database_impl.cc
@@ -41,18 +41,20 @@ } // namespace DatabaseImpl::DatabaseImpl(std::unique_ptr<IndexedDBConnection> connection, - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, IndexedDBDispatcherHost* dispatcher_host, scoped_refptr<base::SequencedTaskRunner> idb_runner) : dispatcher_host_(dispatcher_host), indexed_db_context_(dispatcher_host->context()), connection_(std::move(connection)), - storage_key_(storage_key), + bucket_locator_(bucket_locator), idb_runner_(std::move(idb_runner)) { DCHECK(idb_runner_->RunsTasksInCurrentSequence()); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(connection_); - indexed_db_context_->ConnectionOpened(storage_key_, connection_.get()); + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. + indexed_db_context_->ConnectionOpened(bucket_locator_.storage_key, + connection_.get()); } DatabaseImpl::~DatabaseImpl() { @@ -62,10 +64,13 @@ status = connection_->AbortTransactionsAndClose( IndexedDBConnection::CloseErrorHandling::kAbortAllReturnLastError); } - indexed_db_context_->ConnectionClosed(storage_key_, connection_.get()); + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. + indexed_db_context_->ConnectionClosed(bucket_locator_.storage_key, + connection_.get()); if (!status.ok()) { + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. indexed_db_context_->GetIDBFactory()->OnDatabaseError( - storage_key_, status, "Error during rollbacks."); + bucket_locator_.storage_key, status, "Error during rollbacks."); } } @@ -134,7 +139,8 @@ connection_->database()->RegisterAndScheduleTransaction(transaction); dispatcher_host_->CreateAndBindTransactionImpl( - std::move(transaction_receiver), storage_key_, transaction->AsWeakPtr()); + std::move(transaction_receiver), bucket_locator_, + transaction->AsWeakPtr()); } void DatabaseImpl::Close() { @@ -146,8 +152,9 @@ IndexedDBConnection::CloseErrorHandling::kReturnOnFirstError); if (!status.ok()) { + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. indexed_db_context_->GetIDBFactory()->OnDatabaseError( - storage_key_, status, "Error during rollbacks."); + bucket_locator_.storage_key, status, "Error during rollbacks."); } } @@ -468,7 +475,7 @@ transaction->ScheduleTask( BindWeakOperation(&IndexedDBDatabase::OpenCursorOperation, connection_->database()->AsWeakPtr(), std::move(params), - storage_key_, dispatcher_host_->AsWeakPtr())); + bucket_locator_, dispatcher_host_->AsWeakPtr())); } void DatabaseImpl::Count( @@ -480,8 +487,8 @@ pending_callbacks) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); auto callbacks = base::MakeRefCounted<IndexedDBCallbacks>( - dispatcher_host_->AsWeakPtr(), storage_key_, std::move(pending_callbacks), - idb_runner_); + dispatcher_host_->AsWeakPtr(), bucket_locator_, + std::move(pending_callbacks), idb_runner_); if (!connection_->IsConnected()) return; @@ -514,8 +521,8 @@ pending_callbacks) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); auto callbacks = base::MakeRefCounted<IndexedDBCallbacks>( - dispatcher_host_->AsWeakPtr(), storage_key_, std::move(pending_callbacks), - idb_runner_); + dispatcher_host_->AsWeakPtr(), bucket_locator_, + std::move(pending_callbacks), idb_runner_); if (!connection_->IsConnected()) return; @@ -546,8 +553,8 @@ pending_callbacks) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); auto callbacks = base::MakeRefCounted<IndexedDBCallbacks>( - dispatcher_host_->AsWeakPtr(), storage_key_, std::move(pending_callbacks), - idb_runner_); + dispatcher_host_->AsWeakPtr(), bucket_locator_, + std::move(pending_callbacks), idb_runner_); if (!connection_->IsConnected()) return; @@ -578,8 +585,8 @@ pending_callbacks) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); auto callbacks = base::MakeRefCounted<IndexedDBCallbacks>( - dispatcher_host_->AsWeakPtr(), storage_key_, std::move(pending_callbacks), - idb_runner_); + dispatcher_host_->AsWeakPtr(), bucket_locator_, + std::move(pending_callbacks), idb_runner_); if (!connection_->IsConnected()) return;
diff --git a/content/browser/indexed_db/database_impl.h b/content/browser/indexed_db/database_impl.h index a9092fe3..f8dfd06f 100644 --- a/content/browser/indexed_db/database_impl.h +++ b/content/browser/indexed_db/database_impl.h
@@ -12,11 +12,11 @@ #include "base/memory/raw_ptr.h" #include "base/memory/ref_counted.h" #include "base/sequence_checker.h" +#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "mojo/public/cpp/bindings/pending_associated_receiver.h" #include "mojo/public/cpp/bindings/pending_associated_remote.h" #include "third_party/blink/public/common/indexeddb/indexeddb_key.h" #include "third_party/blink/public/common/indexeddb/indexeddb_key_path.h" -#include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h" namespace base { @@ -35,7 +35,7 @@ class DatabaseImpl : public blink::mojom::IDBDatabase { public: explicit DatabaseImpl(std::unique_ptr<IndexedDBConnection> connection, - const blink::StorageKey& storage_key, + const storage::BucketLocator& storage_key, IndexedDBDispatcherHost* dispatcher_host, scoped_refptr<base::SequencedTaskRunner> idb_runner); @@ -136,7 +136,7 @@ raw_ptr<IndexedDBDispatcherHost> dispatcher_host_; scoped_refptr<IndexedDBContextImpl> indexed_db_context_; std::unique_ptr<IndexedDBConnection> connection_; - const blink::StorageKey storage_key_; + const storage::BucketLocator bucket_locator_; scoped_refptr<base::SequencedTaskRunner> idb_runner_; SEQUENCE_CHECKER(sequence_checker_);
diff --git a/content/browser/indexed_db/indexed_db_backing_store.cc b/content/browser/indexed_db/indexed_db_backing_store.cc index 61fe4625..e5422cb 100644 --- a/content/browser/indexed_db/indexed_db_backing_store.cc +++ b/content/browser/indexed_db/indexed_db_backing_store.cc
@@ -133,8 +133,10 @@ return path; } -std::string ComputeOriginIdentifier(const blink::StorageKey& storage_key) { - return storage::GetIdentifierFromOrigin(storage_key.origin()) + "@1"; +std::string ComputeOriginIdentifier( + const storage::BucketLocator& bucket_locator) { + return storage::GetIdentifierFromOrigin(bucket_locator.storage_key.origin()) + + "@1"; } // TODO(ericu): Error recovery. If we persistently can't read the @@ -626,7 +628,7 @@ IndexedDBBackingStore::IndexedDBBackingStore( Mode backing_store_mode, TransactionalLevelDBFactory* transactional_leveldb_factory, - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, const base::FilePath& blob_path, std::unique_ptr<TransactionalLevelDBDatabase> db, storage::mojom::BlobStorageContext* blob_storage_context, @@ -637,13 +639,13 @@ scoped_refptr<base::SequencedTaskRunner> idb_task_runner) : backing_store_mode_(backing_store_mode), transactional_leveldb_factory_(transactional_leveldb_factory), - storage_key_(storage_key), + bucket_locator_(bucket_locator), blob_path_(backing_store_mode == Mode::kInMemory ? base::FilePath() : blob_path), blob_storage_context_(blob_storage_context), file_system_access_context_(file_system_access_context), filesystem_proxy_(std::move(filesystem_proxy)), - origin_identifier_(ComputeOriginIdentifier(storage_key)), + origin_identifier_(ComputeOriginIdentifier(bucket_locator)), idb_task_runner_(std::move(idb_task_runner)), db_(std::move(db)), blob_files_cleaned_(std::move(blob_files_cleaned)) { @@ -709,7 +711,9 @@ INTERNAL_READ_ERROR(SET_UP_METADATA); return s; } - indexed_db::ReportSchemaVersion(db_schema_version, storage_key_); + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. + indexed_db::ReportSchemaVersion(db_schema_version, + bucket_locator_.storage_key); if (!found) { // Initialize new backing store. db_schema_version = indexed_db::kLatestKnownSchemaVersion; @@ -789,9 +793,10 @@ s = db_->Write(write_batch.get()); write_batch.reset(); if (!s.ok()) { + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. indexed_db::ReportOpenStatus( indexed_db::INDEXED_DB_BACKING_STORE_OPEN_FAILED_METADATA_SETUP, - storage_key_); + bucket_locator_.storage_key); INTERNAL_WRITE_ERROR(SET_UP_METADATA); return s; } @@ -799,10 +804,11 @@ if (clean_active_journal) { s = CleanUpBlobJournal(ActiveBlobJournalKey::Encode()); if (!s.ok()) { + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. indexed_db::ReportOpenStatus( indexed_db:: INDEXED_DB_BACKING_STORE_OPEN_FAILED_CLEANUP_JOURNAL_ERROR, - storage_key_); + bucket_locator_.storage_key); } } #if DCHECK_IS_ON() @@ -3188,7 +3194,7 @@ const std::string schema_version_key = SchemaVersionKey::Encode(); Status s; - if (storage_key_.origin().host() != "docs.google.com") { + if (bucket_locator_.storage_key.origin().host() != "docs.google.com") { s = ValidateBlobFiles(db_.get()); if (!s.ok()) { INTERNAL_CONSISTENCY_ERROR(SET_UP_METADATA);
diff --git a/content/browser/indexed_db/indexed_db_backing_store.h b/content/browser/indexed_db/indexed_db_backing_store.h index bc73164d..53563f18 100644 --- a/content/browser/indexed_db/indexed_db_backing_store.h +++ b/content/browser/indexed_db/indexed_db_backing_store.h
@@ -27,6 +27,7 @@ #include "base/time/time.h" #include "base/timer/timer.h" #include "components/services/storage/indexed_db/locks/leveled_lock.h" +#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "components/services/storage/public/cpp/filesystem/filesystem_proxy.h" #include "components/services/storage/public/mojom/blob_storage_context.mojom-forward.h" #include "components/services/storage/public/mojom/file_system_access_context.mojom-forward.h" @@ -38,18 +39,18 @@ #include "storage/browser/blob/blob_data_handle.h" #include "storage/common/file_system/file_system_mount_option.h" #include "third_party/blink/public/common/indexeddb/indexeddb_key.h" -#include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h" #include "third_party/leveldatabase/src/include/leveldb/status.h" #include "url/gurl.h" namespace base { class SequencedTaskRunner; -} +} // namespace base namespace blink { class IndexedDBKeyRange; struct IndexedDBDatabaseMetadata; +class StorageKey; } // namespace blink namespace content { @@ -388,7 +389,7 @@ IndexedDBBackingStore( Mode backing_store_mode, TransactionalLevelDBFactory* transactional_leveldb_factory, - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, const base::FilePath& blob_path, std::unique_ptr<TransactionalLevelDBDatabase> db, storage::mojom::BlobStorageContext* blob_storage_context, @@ -407,7 +408,9 @@ // operations or method calls on this object. leveldb::Status Initialize(bool clean_active_blob_journal); - const blink::StorageKey& storage_key() const { return storage_key_; } + const storage::BucketLocator& bucket_locator() const { + return bucket_locator_; + } base::SequencedTaskRunner* idb_task_runner() const { return idb_task_runner_.get(); } @@ -663,7 +666,7 @@ const Mode backing_store_mode_; const raw_ptr<TransactionalLevelDBFactory> transactional_leveldb_factory_; - const blink::StorageKey storage_key_; + const storage::BucketLocator bucket_locator_; const base::FilePath blob_path_; // IndexedDB can store blobs and File System Access handles. These mojo
diff --git a/content/browser/indexed_db/indexed_db_backing_store_unittest.cc b/content/browser/indexed_db/indexed_db_backing_store_unittest.cc index fea887f..aec1bcc5 100644 --- a/content/browser/indexed_db/indexed_db_backing_store_unittest.cc +++ b/content/browser/indexed_db/indexed_db_backing_store_unittest.cc
@@ -35,6 +35,7 @@ #include "components/services/storage/indexed_db/scopes/varint_coding.h" #include "components/services/storage/indexed_db/transactional_leveldb/leveldb_write_batch.h" #include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_database.h" +#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "components/services/storage/public/mojom/indexed_db_control.mojom-test-utils.h" #include "content/browser/indexed_db/indexed_db_bucket_state.h" #include "content/browser/indexed_db/indexed_db_class_factory.h" @@ -71,7 +72,7 @@ TestableIndexedDBBackingStore( IndexedDBBackingStore::Mode backing_store_mode, TransactionalLevelDBFactory* leveldb_factory, - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, const base::FilePath& blob_path, std::unique_ptr<TransactionalLevelDBDatabase> db, storage::mojom::BlobStorageContext* blob_storage_context, @@ -82,7 +83,7 @@ scoped_refptr<base::SequencedTaskRunner> idb_task_runner) : IndexedDBBackingStore(backing_store_mode, leveldb_factory, - storage_key, + bucket_locator, blob_path, std::move(db), blob_storage_context, @@ -140,7 +141,7 @@ std::unique_ptr<IndexedDBBackingStore> CreateBackingStore( IndexedDBBackingStore::Mode backing_store_mode, TransactionalLevelDBFactory* leveldb_factory, - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, const base::FilePath& blob_path, std::unique_ptr<TransactionalLevelDBDatabase> db, storage::mojom::BlobStorageContext*, @@ -154,7 +155,7 @@ // than the versions that were passed in to this method. This way tests can // use a different context from what is stored in the IndexedDBContext. return std::make_unique<TestableIndexedDBBackingStore>( - backing_store_mode, leveldb_factory, storage_key, blob_path, + backing_store_mode, leveldb_factory, bucket_locator, blob_path, std::move(db), blob_storage_context_, file_system_access_context_, std::move(filesystem_proxy), std::move(blob_files_cleaned), std::move(report_outstanding_blobs), std::move(idb_task_runner)); @@ -336,6 +337,8 @@ void CreateFactoryAndBackingStore() { const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); + auto bucket_locator = storage::BucketLocator(); + bucket_locator.storage_key = storage_key; idb_factory_ = std::make_unique<TestIDBFactory>( idb_context_.get(), blob_context_.get(), file_system_access_context_.get()); @@ -343,7 +346,7 @@ leveldb::Status s; std::tie(bucket_state_handle_, s, std::ignore, data_loss_info_, std::ignore) = - idb_factory_->GetOrOpenBucketFactory(storage_key, + idb_factory_->GetOrOpenBucketFactory(bucket_locator, idb_context_->data_path(), /*create_if_missing=*/true); if (!bucket_state_handle_.IsHeld()) {
diff --git a/content/browser/indexed_db/indexed_db_browsertest.cc b/content/browser/indexed_db/indexed_db_browsertest.cc index 67fce13..b323b3d 100644 --- a/content/browser/indexed_db/indexed_db_browsertest.cc +++ b/content/browser/indexed_db/indexed_db_browsertest.cc
@@ -28,6 +28,8 @@ #include "base/time/time.h" #include "build/build_config.h" #include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_database.h" +#include "components/services/storage/public/cpp/buckets/bucket_id.h" +#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "components/services/storage/public/mojom/indexed_db_control.mojom-test-utils.h" #include "components/services/storage/public/mojom/indexed_db_control_test.mojom.h" #include "components/services/storage/public/mojom/storage_usage_info.mojom.h" @@ -273,13 +275,13 @@ } // Synchronously writes to the IndexedDB database at the given storage_key. - void WriteToIndexedDB(const blink::StorageKey& storage_key, + void WriteToIndexedDB(const storage::BucketLocator& bucket_locator, std::string key, std::string value) { auto control_test = GetControlTest(); base::RunLoop loop; control_test->WriteToIndexedDBForTesting( - storage_key, std::move(key), std::move(value), loop.QuitClosure()); + bucket_locator, std::move(key), std::move(value), loop.QuitClosure()); loop.Run(); } @@ -378,6 +380,9 @@ const GURL database_open_url = GetTestUrl("indexeddb", "database_test.html"); const blink::StorageKey kTestStorageKey = blink::StorageKey(url::Origin::Create(database_open_url)); + auto bucket_locator = storage::BucketLocator(); + bucket_locator.id = storage::BucketId::FromUnsafeValue(1); + bucket_locator.storage_key = kTestStorageKey; // Create the database. SimpleTest(database_open_url); // -10, little endian. @@ -394,7 +399,7 @@ })); loop.Run(); - WriteToIndexedDB(kTestStorageKey, key, value); + WriteToIndexedDB(bucket_locator, key, value); // Crash the tab to ensure no old navigations are picked up. CrashTab(shell()->web_contents()); SimpleTest(GetTestUrl("indexeddb", "open_bad_db.html")); @@ -404,6 +409,9 @@ const GURL database_open_url = GetTestUrl("indexeddb", "database_test.html"); const blink::StorageKey kTestStorageKey = blink::StorageKey(url::Origin::Create(database_open_url)); + auto bucket_locator = storage::BucketLocator(); + bucket_locator.id = storage::BucketId::FromUnsafeValue(1); + bucket_locator.storage_key = kTestStorageKey; // Create the database. SimpleTest(database_open_url); // -10, little endian. @@ -420,7 +428,7 @@ })); loop.Run(); - WriteToIndexedDB(kTestStorageKey, key, value); + WriteToIndexedDB(bucket_locator, key, value); // Crash the tab to ensure no old navigations are picked up. CrashTab(shell()->web_contents()); SimpleTest(GetTestUrl("indexeddb", "open_bad_db.html")); @@ -1192,14 +1200,14 @@ // This test is for https://crbug.com/1039446. class IndexedDBBrowserTestBlobKeyCorruption : public IndexedDBBrowserTest { public: - int64_t GetNextBlobNumber(const blink::StorageKey& storage_key, + int64_t GetNextBlobNumber(const storage::BucketLocator& bucket_locator, int64_t database_id) { int64_t number; base::RunLoop loop; auto control_test = GetControlTest(); control_test->GetNextBlobNumberForTesting( - storage_key, database_id, + bucket_locator, database_id, base::BindLambdaForTesting([&](int64_t next_blob_number) { number = next_blob_number; loop.Quit(); @@ -1208,14 +1216,14 @@ return number; } - base::FilePath PathForBlob(const blink::StorageKey& storage_key, + base::FilePath PathForBlob(const storage::BucketLocator& bucket_locator, int64_t database_id, int64_t blob_number) { base::FilePath path; base::RunLoop loop; auto control_test = GetControlTest(); control_test->GetPathForBlobForTesting( - storage_key, database_id, blob_number, + bucket_locator, database_id, blob_number, base::BindLambdaForTesting([&](const base::FilePath& blob_path) { path = blob_path; loop.Quit(); @@ -1234,6 +1242,9 @@ embedded_test_server()->InitializeAndListen()); const blink::StorageKey kTestStorageKey = blink::StorageKey( url::Origin::Create(embedded_test_server()->base_url())); + auto bucket_locator = storage::BucketLocator(); + bucket_locator.id = storage::BucketId::FromUnsafeValue(1); + bucket_locator.storage_key = kTestStorageKey; embedded_test_server()->RegisterRequestHandler(base::BindRepeating( &StaticFileRequestHandler, s_indexeddb_test_prefix, this)); embedded_test_server()->StartAcceptingConnections(); @@ -1242,12 +1253,12 @@ std::string test_file = std::string(s_indexeddb_test_prefix) + "write_and_read_blob.html"; SimpleTest(embedded_test_server()->GetURL(test_file)); - int64_t next_blob_number = GetNextBlobNumber(kTestStorageKey, 1); + int64_t next_blob_number = GetNextBlobNumber(bucket_locator, 1); base::FilePath first_blob = - PathForBlob(kTestStorageKey, 1, next_blob_number - 1); + PathForBlob(bucket_locator, 1, next_blob_number - 1); base::FilePath corrupt_blob = - PathForBlob(kTestStorageKey, 1, next_blob_number); + PathForBlob(bucket_locator, 1, next_blob_number); { base::ScopedAllowBlockingForTesting allow_blocking; EXPECT_TRUE(base::PathExists(first_blob));
diff --git a/content/browser/indexed_db/indexed_db_bucket_state.h b/content/browser/indexed_db/indexed_db_bucket_state.h index 145f83b..9dc4eb2 100644 --- a/content/browser/indexed_db/indexed_db_bucket_state.h +++ b/content/browser/indexed_db/indexed_db_bucket_state.h
@@ -94,7 +94,7 @@ // `earliest_global_sweep_time` and `earliest_global_compaction_time` are // expected to outlive this object. IndexedDBBucketState( - // TODO(crbug.com/1218100): This needs a BucketInfo + // TODO(crbug.com/1218100): This needs a BucketLocator blink::StorageKey storage_key, bool persist_for_incognito, base::Clock* clock,
diff --git a/content/browser/indexed_db/indexed_db_callbacks.cc b/content/browser/indexed_db/indexed_db_callbacks.cc index b02c4b7ac..0c3d478f 100644 --- a/content/browser/indexed_db/indexed_db_callbacks.cc +++ b/content/browser/indexed_db/indexed_db_callbacks.cc
@@ -86,12 +86,12 @@ IndexedDBCallbacks::IndexedDBCallbacks( base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host, - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, mojo::PendingAssociatedRemote<blink::mojom::IDBCallbacks> pending_callbacks, scoped_refptr<base::SequencedTaskRunner> idb_runner) : data_loss_(blink::mojom::IDBDataLoss::None), dispatcher_host_(std::move(dispatcher_host)), - storage_key_(storage_key), + bucket_locator_(bucket_locator), idb_runner_(std::move(idb_runner)) { DCHECK(idb_runner_->RunsTasksInCurrentSequence()); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -177,7 +177,7 @@ } auto database = std::make_unique<DatabaseImpl>( - std::move(wrapper.connection_), storage_key_, dispatcher_host_.get(), + std::move(wrapper.connection_), bucket_locator_, dispatcher_host_.get(), idb_runner_); mojo::PendingAssociatedRemote<blink::mojom::IDBDatabase> pending_remote; @@ -215,7 +215,7 @@ mojo::PendingAssociatedRemote<blink::mojom::IDBDatabase> pending_remote; if (wrapper.connection_) { auto database = std::make_unique<DatabaseImpl>( - std::move(wrapper.connection_), storage_key_, dispatcher_host_.get(), + std::move(wrapper.connection_), bucket_locator_, dispatcher_host_.get(), idb_runner_); dispatcher_host_->AddDatabaseBinding( std::move(database),
diff --git a/content/browser/indexed_db/indexed_db_callbacks.h b/content/browser/indexed_db/indexed_db_callbacks.h index 2dab7eb..4f30651 100644 --- a/content/browser/indexed_db/indexed_db_callbacks.h +++ b/content/browser/indexed_db/indexed_db_callbacks.h
@@ -13,6 +13,7 @@ #include "base/check.h" #include "base/memory/weak_ptr.h" #include "base/sequence_checker.h" +#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "content/browser/indexed_db/indexed_db_database_error.h" #include "content/browser/indexed_db/indexed_db_dispatcher_host.h" #include "content/common/content_export.h" @@ -20,7 +21,6 @@ #include "mojo/public/cpp/bindings/pending_associated_remote.h" #include "storage/browser/blob/blob_storage_context.h" #include "third_party/blink/public/common/indexeddb/indexeddb_key.h" -#include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h" namespace base { @@ -41,7 +41,7 @@ : public base::RefCounted<IndexedDBCallbacks> { public: IndexedDBCallbacks(base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host, - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, mojo::PendingAssociatedRemote<blink::mojom::IDBCallbacks> pending_callbacks, scoped_refptr<base::SequencedTaskRunner> idb_runner); @@ -100,7 +100,7 @@ bool sent_blocked_ = false; base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host_; - blink::StorageKey storage_key_; + storage::BucketLocator bucket_locator_; scoped_refptr<base::SequencedTaskRunner> idb_runner_; mojo::AssociatedRemote<blink::mojom::IDBCallbacks> callbacks_;
diff --git a/content/browser/indexed_db/indexed_db_cleanup_on_io_error_unittest.cc b/content/browser/indexed_db/indexed_db_cleanup_on_io_error_unittest.cc index 66fcf57..6836257 100644 --- a/content/browser/indexed_db/indexed_db_cleanup_on_io_error_unittest.cc +++ b/content/browser/indexed_db/indexed_db_cleanup_on_io_error_unittest.cc
@@ -16,6 +16,7 @@ #include "components/services/storage/indexed_db/scopes/leveldb_scopes.h" #include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_database.h" #include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_factory.h" +#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "content/browser/indexed_db/indexed_db_backing_store.h" #include "content/browser/indexed_db/indexed_db_class_factory.h" #include "content/browser/indexed_db/indexed_db_leveldb_env.h" @@ -36,6 +37,8 @@ base::test::TaskEnvironment task_env; const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); + auto bucket_locator = storage::BucketLocator(); + bucket_locator.storage_key = storage_key; base::ScopedTempDir temp_directory; ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); const base::FilePath path = temp_directory.GetPath(); @@ -45,7 +48,7 @@ std::unique_ptr<IndexedDBBackingStore> backing_store = std::make_unique< IndexedDBBackingStore>( IndexedDBBackingStore::Mode::kInMemory, &transactional_leveldb_factory, - storage_key, path, + bucket_locator, path, transactional_leveldb_factory.CreateLevelDBDatabase( FakeLevelDBFactory::GetBrokenLevelDB( leveldb::Status::IOError("It's broken!"), path), @@ -65,6 +68,8 @@ base::test::TaskEnvironment task_env; const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); + auto bucket_locator = storage::BucketLocator(); + bucket_locator.storage_key = storage_key; base::ScopedTempDir temp_directory; ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); const base::FilePath path = temp_directory.GetPath(); @@ -84,7 +89,7 @@ std::unique_ptr<IndexedDBBackingStore> backing_store = std::make_unique< IndexedDBBackingStore>( IndexedDBBackingStore::Mode::kInMemory, &transactional_leveldb_factory, - storage_key, path, + bucket_locator, path, transactional_leveldb_factory.CreateLevelDBDatabase( FakeLevelDBFactory::GetBrokenLevelDB(error_status, path), nullptr, task_runner.get(),
diff --git a/content/browser/indexed_db/indexed_db_context_impl.cc b/content/browser/indexed_db/indexed_db_context_impl.cc index 8340c86..08ad665 100644 --- a/content/browser/indexed_db/indexed_db_context_impl.cc +++ b/content/browser/indexed_db/indexed_db_context_impl.cc
@@ -30,6 +30,7 @@ #include "components/services/storage/indexed_db/scopes/varint_coding.h" #include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_database.h" #include "components/services/storage/public/cpp/buckets/bucket_info.h" +#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "components/services/storage/public/cpp/buckets/constants.h" #include "components/services/storage/public/cpp/quota_client_callback_wrapper.h" #include "components/services/storage/public/cpp/quota_error_or.h" @@ -208,14 +209,14 @@ void IndexedDBContextImpl::BindIndexedDB( const blink::StorageKey& storage_key, + // TODO(crbug.com/1315371): Allow custom bucket names. mojo::PendingReceiver<blink::mojom::IDBFactory> receiver) { // Ensure default bucket exists for storage key on storage access and add // bind receiver on retrieval. quota_manager_proxy()->GetOrCreateBucket( storage_key, storage::kDefaultBucketName, idb_task_runner_, base::BindOnce(&IndexedDBContextImpl::BindIndexedDBWithBucket, - weak_factory_.GetWeakPtr(), storage_key, - std::move(receiver))); + weak_factory_.GetWeakPtr(), std::move(receiver))); } void IndexedDBContextImpl::GetUsage(GetUsageCallback usage_callback) { @@ -579,14 +580,14 @@ } void IndexedDBContextImpl::WriteToIndexedDBForTesting( - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, const std::string& key, const std::string& value, base::OnceClosure callback) { IndexedDBBucketStateHandle handle; leveldb::Status s; std::tie(handle, s, std::ignore, std::ignore, std::ignore) = - GetIDBFactory()->GetOrOpenBucketFactory(storage_key, data_path(), + GetIDBFactory()->GetOrOpenBucketFactory(bucket_locator, data_path(), /*create_if_missing=*/true); CHECK(s.ok()) << s.ToString(); CHECK(handle.IsHeld()); @@ -597,7 +598,8 @@ s = db->Put(key, &value_copy); CHECK(s.ok()) << s.ToString(); handle.Release(); - GetIDBFactory()->ForceClose(storage_key, true); + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. + GetIDBFactory()->ForceClose(bucket_locator.storage_key, true); std::move(callback).Run(); } @@ -608,13 +610,13 @@ } void IndexedDBContextImpl::GetNextBlobNumberForTesting( - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, int64_t database_id, GetNextBlobNumberForTestingCallback callback) { IndexedDBBucketStateHandle handle; leveldb::Status s; std::tie(handle, s, std::ignore, std::ignore, std::ignore) = - GetIDBFactory()->GetOrOpenBucketFactory(storage_key, data_path(), + GetIDBFactory()->GetOrOpenBucketFactory(bucket_locator, data_path(), /*create_if_missing=*/true); CHECK(s.ok()) << s.ToString(); CHECK(handle.IsHeld()); @@ -638,14 +640,14 @@ } void IndexedDBContextImpl::GetPathForBlobForTesting( - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, int64_t database_id, int64_t blob_number, GetPathForBlobForTestingCallback callback) { IndexedDBBucketStateHandle handle; leveldb::Status s; std::tie(handle, s, std::ignore, std::ignore, std::ignore) = - GetIDBFactory()->GetOrOpenBucketFactory(storage_key, data_path(), + GetIDBFactory()->GetOrOpenBucketFactory(bucket_locator, data_path(), /*create_if_missing=*/true); CHECK(s.ok()) << s.ToString(); CHECK(handle.IsHeld()); @@ -864,13 +866,13 @@ } void IndexedDBContextImpl::BindIndexedDBWithBucket( - const blink::StorageKey& storage_key, mojo::PendingReceiver<blink::mojom::IDBFactory> receiver, storage::QuotaErrorOr<storage::BucketInfo> result) { - absl::optional<storage::BucketLocator> bucket = - result.ok() ? absl::make_optional(result->ToBucketLocator()) - : absl::nullopt; - dispatcher_host_.AddReceiver(storage_key, bucket, std::move(receiver)); + absl::optional<storage::BucketLocator> bucket = absl::nullopt; + if (result.ok()) { + bucket = absl::make_optional(result->ToBucketLocator()); + } + dispatcher_host_.AddReceiver(bucket, std::move(receiver)); } void IndexedDBContextImpl::ShutdownOnIDBSequence() {
diff --git a/content/browser/indexed_db/indexed_db_context_impl.h b/content/browser/indexed_db/indexed_db_context_impl.h index a01abe0..663da87a 100644 --- a/content/browser/indexed_db/indexed_db_context_impl.h +++ b/content/browser/indexed_db/indexed_db_context_impl.h
@@ -40,15 +40,16 @@ class FilePath; class SequencedTaskRunner; class Value; -} +} // namespace base namespace blink { class StorageKey; -} +} // namespace blink namespace storage { +struct BucketLocator; class QuotaClientCallbackWrapper; -} +} // namespace storage namespace content { class IndexedDBConnection; @@ -122,18 +123,18 @@ void HasV2SchemaCorruptionForTesting( const blink::StorageKey& storage_key, HasV2SchemaCorruptionForTestingCallback callback) override; - void WriteToIndexedDBForTesting(const blink::StorageKey& storage_key, + void WriteToIndexedDBForTesting(const storage::BucketLocator& bucket_locator, const std::string& key, const std::string& value, base::OnceClosure callback) override; void GetBlobCountForTesting(const blink::StorageKey& storage_key, GetBlobCountForTestingCallback callback) override; void GetNextBlobNumberForTesting( - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, int64_t database_id, GetNextBlobNumberForTestingCallback callback) override; void GetPathForBlobForTesting( - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, int64_t database_id, int64_t blob_number, GetPathForBlobForTestingCallback callback) override; @@ -226,7 +227,6 @@ // Binds receiver on bucket retrieval to ensure that a bucket always exists // for a storage key. void BindIndexedDBWithBucket( - const blink::StorageKey& storage_key, mojo::PendingReceiver<blink::mojom::IDBFactory> receiver, storage::QuotaErrorOr<storage::BucketInfo> result);
diff --git a/content/browser/indexed_db/indexed_db_context_unittest.cc b/content/browser/indexed_db/indexed_db_context_unittest.cc index eb606e18..d8bec47 100644 --- a/content/browser/indexed_db/indexed_db_context_unittest.cc +++ b/content/browser/indexed_db/indexed_db_context_unittest.cc
@@ -13,6 +13,7 @@ #include "base/threading/thread.h" #include "base/time/default_clock.h" #include "components/services/storage/public/cpp/buckets/bucket_info.h" +#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "components/services/storage/public/cpp/buckets/constants.h" #include "components/services/storage/public/cpp/quota_error_or.h" #include "content/browser/indexed_db/indexed_db_context_impl.h" @@ -91,10 +92,14 @@ auto callbacks = base::MakeRefCounted<MockIndexedDBCallbacks>( /*expect_connection=*/false); callbacks->CallOnInfoSuccess(base::BarrierClosure(2, loop.QuitClosure())); + auto example_bucket_locator = storage::BucketLocator(); + example_bucket_locator.storage_key = example_storage_key_; indexed_db_context_->GetIDBFactory()->GetDatabaseInfo( - callbacks, example_storage_key_, indexed_db_context_->data_path()); + callbacks, example_bucket_locator, indexed_db_context_->data_path()); + auto google_bucket_locator = storage::BucketLocator(); + google_bucket_locator.storage_key = google_storage_key_; indexed_db_context_->GetIDBFactory()->GetDatabaseInfo( - callbacks, google_storage_key_, indexed_db_context_->data_path()); + callbacks, google_bucket_locator, indexed_db_context_->data_path()); loop.Run(); // Check default bucket exists for https://example.com.
diff --git a/content/browser/indexed_db/indexed_db_cursor.cc b/content/browser/indexed_db/indexed_db_cursor.cc index aa395181..7af4a72 100644 --- a/content/browser/indexed_db/indexed_db_cursor.cc +++ b/content/browser/indexed_db/indexed_db_cursor.cc
@@ -12,6 +12,7 @@ #include "base/check_op.h" #include "base/notreached.h" #include "base/trace_event/base_tracing.h" +#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "content/browser/indexed_db/indexed_db_callback_helpers.h" #include "content/browser/indexed_db/indexed_db_callbacks.h" #include "content/browser/indexed_db/indexed_db_context_impl.h" @@ -51,9 +52,9 @@ indexed_db::CursorType cursor_type, blink::mojom::IDBTaskType task_type, base::WeakPtr<IndexedDBTransaction> transaction) - : storage_key_(transaction->BackingStoreTransaction() - ->backing_store() - ->storage_key()), + : bucket_locator_(transaction->BackingStoreTransaction() + ->backing_store() + ->bucket_locator()), task_type_(task_type), cursor_type_(cursor_type), transaction_(std::move(transaction)), @@ -128,7 +129,7 @@ if (value) { mojo_value = IndexedDBValue::ConvertAndEraseValue(value); external_objects.swap(value->external_objects); - dispatcher_host->CreateAllExternalObjects(storage_key_, external_objects, + dispatcher_host->CreateAllExternalObjects(bucket_locator_, external_objects, &mojo_value->external_objects); } else { mojo_value = blink::mojom::IDBValue::New(); @@ -209,7 +210,7 @@ if (value) { mojo_value = IndexedDBValue::ConvertAndEraseValue(value); external_objects.swap(value->external_objects); - dispatcher_host->CreateAllExternalObjects(storage_key_, external_objects, + dispatcher_host->CreateAllExternalObjects(bucket_locator_, external_objects, &mojo_value->external_objects); } else { mojo_value = blink::mojom::IDBValue::New(); @@ -337,7 +338,7 @@ mojo_values.push_back( IndexedDBValue::ConvertAndEraseValue(&found_values[i])); dispatcher_host->CreateAllExternalObjects( - storage_key_, found_values[i].external_objects, + bucket_locator_, found_values[i].external_objects, &mojo_values[i]->external_objects); }
diff --git a/content/browser/indexed_db/indexed_db_cursor.h b/content/browser/indexed_db/indexed_db_cursor.h index 2ec5598..08d5f30 100644 --- a/content/browser/indexed_db/indexed_db_cursor.h +++ b/content/browser/indexed_db/indexed_db_cursor.h
@@ -15,9 +15,12 @@ #include "content/browser/indexed_db/indexed_db_database.h" #include "content/browser/indexed_db/indexed_db_transaction.h" #include "third_party/blink/public/common/indexeddb/web_idb_types.h" -#include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-forward.h" +namespace storage { +struct BucketLocator; +} // namespace storage + namespace content { class IndexedDBCursor { @@ -78,7 +81,7 @@ IndexedDBTransaction* transaction); private: - const blink::StorageKey storage_key_; + const storage::BucketLocator bucket_locator_; blink::mojom::IDBTaskType task_type_; indexed_db::CursorType cursor_type_;
diff --git a/content/browser/indexed_db/indexed_db_database.cc b/content/browser/indexed_db/indexed_db_database.cc index 88979dc..912be1d 100644 --- a/content/browser/indexed_db/indexed_db_database.cc +++ b/content/browser/indexed_db/indexed_db_database.cc
@@ -70,14 +70,14 @@ std::vector<blink::mojom::IDBReturnValuePtr> CreateMojoValues( std::vector<IndexedDBReturnValue>& found_values, IndexedDBDispatcherHost* dispatcher_host, - const blink::StorageKey& storage_key) { + const storage::BucketLocator& bucket_locator) { std::vector<blink::mojom::IDBReturnValuePtr> mojo_values; mojo_values.reserve(found_values.size()); for (size_t i = 0; i < found_values.size(); ++i) { mojo_values.push_back( IndexedDBReturnValue::ConvertReturnValue(&found_values[i])); dispatcher_host->CreateAllExternalObjects( - storage_key, found_values[i].external_objects, + bucket_locator, found_values[i].external_objects, &mojo_values[i]->value->external_objects); } return mojo_values; @@ -843,7 +843,7 @@ blink::mojom::IDBReturnValuePtr mojo_value = IndexedDBReturnValue::ConvertReturnValue(&value); dispatcher_host->CreateAllExternalObjects( - storage_key(), value.external_objects, + bucket_locator(), value.external_objects, &mojo_value->value->external_objects); std::move(callback).Run( blink::mojom::IDBDatabaseGetResult::NewValue(std::move(mojo_value))); @@ -901,7 +901,7 @@ blink::mojom::IDBReturnValuePtr mojo_value = IndexedDBReturnValue::ConvertReturnValue(&value); dispatcher_host->CreateAllExternalObjects( - storage_key(), value.external_objects, + bucket_locator(), value.external_objects, &mojo_value->value->external_objects); std::move(callback).Run( blink::mojom::IDBDatabaseGetResult::NewValue(std::move(mojo_value))); @@ -1063,7 +1063,7 @@ } else { if (found_values.size() >= max_values_before_sending) { result_sink->ReceiveValues(CreateMojoValues( - found_values, dispatcher_host.get(), storage_key())); + found_values, dispatcher_host.get(), bucket_locator())); found_values.clear(); } } @@ -1075,8 +1075,8 @@ } } else { if (!found_values.empty()) { - result_sink->ReceiveValues( - CreateMojoValues(found_values, dispatcher_host.get(), storage_key())); + result_sink->ReceiveValues(CreateMojoValues( + found_values, dispatcher_host.get(), bucket_locator())); } } return s; @@ -1209,8 +1209,9 @@ std::move(params->callback) .Run(blink::mojom::IDBTransactionPutResult::NewKey(*key)); } + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. factory_->NotifyIndexedDBContentChanged( - storage_key(), metadata_.name, + bucket_locator().storage_key, metadata_.name, metadata_.object_stores[params->object_store_id].name); return s; } @@ -1401,7 +1402,7 @@ mojo_values.push_back( IndexedDBReturnValue::ConvertReturnValue(&found_values[j])); dispatcher_host->CreateAllExternalObjects( - storage_key(), found_values[j].external_objects, + bucket_locator(), found_values[j].external_objects, &mojo_values[j]->value->external_objects); } all_mojo_values.push_back(std::move(mojo_values)); @@ -1424,7 +1425,7 @@ Status IndexedDBDatabase::OpenCursorOperation( std::unique_ptr<OpenCursorOperationParams> params, - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host, IndexedDBTransaction* transaction) { TRACE_EVENT1("IndexedDB", "IndexedDBDatabase::OpenCursorOperation", "txn.id", @@ -1505,14 +1506,14 @@ } if (mojo_value) { - dispatcher_host->CreateAllExternalObjects(storage_key, external_objects, + dispatcher_host->CreateAllExternalObjects(bucket_locator, external_objects, &mojo_value->external_objects); } std::move(params->callback) .Run(blink::mojom::IDBDatabaseOpenCursorResult::NewValue( blink::mojom::IDBDatabaseOpenCursorValue::New( - dispatcher_host->CreateCursorBinding(storage_key, + dispatcher_host->CreateCursorBinding(bucket_locator, std::move(cursor)), cursor_ptr->key(), cursor_ptr->primary_key(), std::move(mojo_value)))); @@ -1580,8 +1581,9 @@ if (!s.ok()) return s; callbacks->OnSuccess(); + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. factory_->NotifyIndexedDBContentChanged( - storage_key(), metadata_.name, + bucket_locator().storage_key, metadata_.name, metadata_.object_stores[object_store_id].name); return s; } @@ -1626,8 +1628,9 @@ return s; callbacks->OnSuccess(); + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. factory_->NotifyIndexedDBContentChanged( - storage_key(), metadata_.name, + bucket_locator().storage_key, metadata_.name, metadata_.object_stores[object_store_id].name); return s; }
diff --git a/content/browser/indexed_db/indexed_db_database.h b/content/browser/indexed_db/indexed_db_database.h index fa70417..00e81bf0 100644 --- a/content/browser/indexed_db/indexed_db_database.h +++ b/content/browser/indexed_db/indexed_db_database.h
@@ -22,6 +22,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "components/services/storage/indexed_db/locks/leveled_lock_manager.h" +#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "content/browser/indexed_db/indexed_db.h" #include "content/browser/indexed_db/indexed_db_backing_store.h" #include "content/browser/indexed_db/indexed_db_callbacks.h" @@ -33,7 +34,6 @@ #include "content/common/content_export.h" #include "third_party/blink/public/common/indexeddb/indexeddb_key.h" #include "third_party/blink/public/common/indexeddb/web_idb_types.h" -#include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-forward.h" namespace blink { @@ -56,8 +56,8 @@ class CONTENT_EXPORT IndexedDBDatabase { public: - // Identifier is pair of (storage_key, database name). - using Identifier = std::pair<blink::StorageKey, std::u16string>; + // Identifier is pair of (bucket_locator, database name). + using Identifier = std::pair<storage::BucketLocator, std::u16string>; // Used to report irrecoverable backend errors. The second argument can be // null. using ErrorCallback = @@ -76,7 +76,9 @@ int64_t id() const { return metadata_.id; } const std::u16string& name() const { return metadata_.name; } - const blink::StorageKey& storage_key() const { return identifier_.first; } + const storage::BucketLocator& bucket_locator() const { + return identifier_.first; + } const blink::IndexedDBDatabaseMetadata& metadata() const { return metadata_; } LeveledLockManager* transaction_lock_manager() { return lock_manager_; } @@ -266,7 +268,7 @@ }; leveldb::Status OpenCursorOperation( std::unique_ptr<OpenCursorOperationParams> params, - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host, IndexedDBTransaction* transaction);
diff --git a/content/browser/indexed_db/indexed_db_database_callbacks.cc b/content/browser/indexed_db/indexed_db_database_callbacks.cc index 79df6b3..beaa2c8 100644 --- a/content/browser/indexed_db/indexed_db_database_callbacks.cc +++ b/content/browser/indexed_db/indexed_db_database_callbacks.cc
@@ -79,8 +79,9 @@ if (complete_) return; + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. indexed_db_context_->TransactionComplete( - transaction.database()->storage_key()); + transaction.database()->bucket_locator().storage_key); if (callbacks_) callbacks_->Complete(transaction.id()); }
diff --git a/content/browser/indexed_db/indexed_db_database_unittest.cc b/content/browser/indexed_db/indexed_db_database_unittest.cc index ca97145d..f438811 100644 --- a/content/browser/indexed_db/indexed_db_database_unittest.cc +++ b/content/browser/indexed_db/indexed_db_database_unittest.cc
@@ -19,6 +19,7 @@ #include "base/test/task_environment.h" #include "base/threading/thread_task_runner_handle.h" #include "components/services/storage/indexed_db/locks/disjoint_range_lock_manager.h" +#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "content/browser/indexed_db/fake_indexed_db_metadata_coding.h" #include "content/browser/indexed_db/indexed_db.h" #include "content/browser/indexed_db/indexed_db_backing_store.h" @@ -188,7 +189,7 @@ public: MockCallbacks() : IndexedDBCallbacks(nullptr, - blink::StorageKey(), + storage::BucketLocator(), mojo::NullAssociatedRemote(), base::ThreadTaskRunnerHandle::Get()) {}
diff --git a/content/browser/indexed_db/indexed_db_dispatcher_host.cc b/content/browser/indexed_db/indexed_db_dispatcher_host.cc index 741cb88a..f020c385 100644 --- a/content/browser/indexed_db/indexed_db_dispatcher_host.cc +++ b/content/browser/indexed_db/indexed_db_dispatcher_host.cc
@@ -213,13 +213,10 @@ } void IndexedDBDispatcherHost::AddReceiver( - const blink::StorageKey& storage_key, absl::optional<storage::BucketLocator> bucket, mojo::PendingReceiver<blink::mojom::IDBFactory> pending_receiver) { DCHECK(IDBTaskRunner()->RunsTasksInCurrentSequence()); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (bucket.has_value()) - DCHECK_EQ(bucket->storage_key, storage_key); receivers_.Add(this, std::move(pending_receiver), bucket); } @@ -233,11 +230,11 @@ mojo::PendingAssociatedRemote<blink::mojom::IDBCursor> IndexedDBDispatcherHost::CreateCursorBinding( - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, std::unique_ptr<IndexedDBCursor> cursor) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); auto cursor_impl = std::make_unique<CursorImpl>( - std::move(cursor), storage_key, this, IDBTaskRunner()); + std::move(cursor), bucket_locator, this, IDBTaskRunner()); auto* cursor_impl_ptr = cursor_impl.get(); mojo::PendingAssociatedRemote<blink::mojom::IDBCursor> remote; mojo::ReceiverId receiver_id = cursor_receivers_.Add( @@ -280,22 +277,22 @@ // Return error if failed to retrieve bucket from the QuotaManager. if (!receivers_.current_context().has_value()) { auto callbacks = base::MakeRefCounted<IndexedDBCallbacks>( - this->AsWeakPtr(), blink::StorageKey(), std::move(pending_callbacks), - IDBTaskRunner()); + this->AsWeakPtr(), storage::BucketLocator(), + std::move(pending_callbacks), IDBTaskRunner()); IndexedDBDatabaseError error = IndexedDBDatabaseError( blink::mojom::IDBException::kUnknownError, u"Internal error."); callbacks->OnError(error); return; } - const auto storage_key = receivers_.current_context()->storage_key; + const auto& bucket_locator = *receivers_.current_context(); auto callbacks = base::MakeRefCounted<IndexedDBCallbacks>( - this->AsWeakPtr(), storage_key, std::move(pending_callbacks), + this->AsWeakPtr(), bucket_locator, std::move(pending_callbacks), IDBTaskRunner()); base::FilePath indexed_db_path = indexed_db_context_->data_path(); indexed_db_context_->GetIDBFactory()->GetDatabaseInfo( - std::move(callbacks), storage_key, indexed_db_path); + std::move(callbacks), bucket_locator, indexed_db_path); } void IndexedDBDispatcherHost::Open( @@ -312,26 +309,26 @@ // Return error if failed to retrieve bucket from the QuotaManager. if (!receivers_.current_context().has_value()) { auto callbacks = base::MakeRefCounted<IndexedDBCallbacks>( - this->AsWeakPtr(), blink::StorageKey(), std::move(pending_callbacks), - IDBTaskRunner()); + this->AsWeakPtr(), storage::BucketLocator(), + std::move(pending_callbacks), IDBTaskRunner()); IndexedDBDatabaseError error = IndexedDBDatabaseError( blink::mojom::IDBException::kUnknownError, u"Internal error."); callbacks->OnError(error); return; } - const auto storage_key = receivers_.current_context()->storage_key; + const auto& bucket_locator = *receivers_.current_context(); auto callbacks = base::MakeRefCounted<IndexedDBCallbacks>( - this->AsWeakPtr(), storage_key, std::move(pending_callbacks), + this->AsWeakPtr(), bucket_locator, std::move(pending_callbacks), IDBTaskRunner()); auto database_callbacks = base::MakeRefCounted<IndexedDBDatabaseCallbacks>( indexed_db_context_, std::move(database_callbacks_remote), IDBTaskRunner()); base::FilePath indexed_db_path = indexed_db_context_->data_path(); - auto create_transaction_callback = - base::BindOnce(&IndexedDBDispatcherHost::CreateAndBindTransactionImpl, - AsWeakPtr(), std::move(transaction_receiver), storage_key); + auto create_transaction_callback = base::BindOnce( + &IndexedDBDispatcherHost::CreateAndBindTransactionImpl, AsWeakPtr(), + std::move(transaction_receiver), bucket_locator); std::unique_ptr<IndexedDBPendingConnection> connection = std::make_unique<IndexedDBPendingConnection>( std::move(callbacks), std::move(database_callbacks), transaction_id, @@ -340,7 +337,7 @@ // TODO(dgrogan): Don't let a non-existing database be opened (and therefore // created) if this origin is already over quota. indexed_db_context_->GetIDBFactory()->Open(name, std::move(connection), - storage_key, indexed_db_path); + bucket_locator, indexed_db_path); } void IndexedDBDispatcherHost::DeleteDatabase( @@ -352,22 +349,22 @@ // Return error if failed to retrieve bucket from the QuotaManager. if (!receivers_.current_context().has_value()) { auto callbacks = base::MakeRefCounted<IndexedDBCallbacks>( - this->AsWeakPtr(), blink::StorageKey(), std::move(pending_callbacks), - IDBTaskRunner()); + this->AsWeakPtr(), storage::BucketLocator(), + std::move(pending_callbacks), IDBTaskRunner()); IndexedDBDatabaseError error = IndexedDBDatabaseError( blink::mojom::IDBException::kUnknownError, u"Internal error."); callbacks->OnError(error); return; } - const auto storage_key = receivers_.current_context()->storage_key; + const auto& bucket_locator = *receivers_.current_context(); auto callbacks = base::MakeRefCounted<IndexedDBCallbacks>( - this->AsWeakPtr(), storage_key, std::move(pending_callbacks), + this->AsWeakPtr(), bucket_locator, std::move(pending_callbacks), IDBTaskRunner()); base::FilePath indexed_db_path = indexed_db_context_->data_path(); indexed_db_context_->GetIDBFactory()->DeleteDatabase( - name, std::move(callbacks), storage_key, indexed_db_path, force_close); + name, std::move(callbacks), bucket_locator, indexed_db_path, force_close); } void IndexedDBDispatcherHost::AbortTransactionsAndCompactDatabase( @@ -380,12 +377,13 @@ return; } - const auto storage_key = receivers_.current_context()->storage_key; + const auto& bucket_locator = *receivers_.current_context(); base::OnceCallback<void(leveldb::Status)> callback_on_io = base::BindOnce( &CallCompactionStatusCallbackOnIDBThread, std::move(mojo_callback)); + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. indexed_db_context_->GetIDBFactory()->AbortTransactionsAndCompactDatabase( - std::move(callback_on_io), storage_key); + std::move(callback_on_io), bucket_locator.storage_key); } void IndexedDBDispatcherHost::AbortTransactionsForDatabase( @@ -398,22 +396,23 @@ return; } - const auto storage_key = receivers_.current_context()->storage_key; + const auto& bucket_locator = *receivers_.current_context(); base::OnceCallback<void(leveldb::Status)> callback_on_io = base::BindOnce( &CallAbortStatusCallbackOnIDBThread, std::move(mojo_callback)); + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. indexed_db_context_->GetIDBFactory()->AbortTransactionsForDatabase( - std::move(callback_on_io), storage_key); + std::move(callback_on_io), bucket_locator.storage_key); } void IndexedDBDispatcherHost::CreateAndBindTransactionImpl( mojo::PendingAssociatedReceiver<blink::mojom::IDBTransaction> transaction_receiver, - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, base::WeakPtr<IndexedDBTransaction> transaction) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); auto transaction_impl = std::make_unique<TransactionImpl>( - transaction, storage_key, this->AsWeakPtr(), IDBTaskRunner()); + transaction, bucket_locator, this->AsWeakPtr(), IDBTaskRunner()); AddTransactionBinding(std::move(transaction_impl), std::move(transaction_receiver)); } @@ -445,7 +444,7 @@ } void IndexedDBDispatcherHost::CreateAllExternalObjects( - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, const std::vector<IndexedDBExternalObject>& objects, std::vector<blink::mojom::IDBExternalObjectPtr>* mojo_objects) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -510,7 +509,7 @@ } else { DCHECK(!blob_info.file_system_access_token().empty()); file_system_access_context()->DeserializeHandle( - storage_key, blob_info.file_system_access_token(), + bucket_locator.storage_key, blob_info.file_system_access_token(), mojo_token.InitWithNewPipeAndPassReceiver()); } mojo_object->get_file_system_access_token() = std::move(mojo_token);
diff --git a/content/browser/indexed_db/indexed_db_dispatcher_host.h b/content/browser/indexed_db/indexed_db_dispatcher_host.h index c96115e..5a85a8c 100644 --- a/content/browser/indexed_db/indexed_db_dispatcher_host.h +++ b/content/browser/indexed_db/indexed_db_dispatcher_host.h
@@ -23,13 +23,12 @@ #include "mojo/public/cpp/bindings/pending_associated_remote.h" #include "mojo/public/cpp/bindings/receiver_set.h" #include "mojo/public/cpp/bindings/unique_associated_receiver_set.h" -#include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h" namespace base { class SequencedTaskRunner; class TaskRunner; -} +} // namespace base namespace content { class IndexedDBContextImpl; @@ -51,7 +50,6 @@ ~IndexedDBDispatcherHost() override; void AddReceiver( - const blink::StorageKey& storage_key, absl::optional<storage::BucketLocator> bucket, mojo::PendingReceiver<blink::mojom::IDBFactory> pending_receiver); @@ -61,7 +59,7 @@ pending_receiver); mojo::PendingAssociatedRemote<blink::mojom::IDBCursor> CreateCursorBinding( - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, std::unique_ptr<IndexedDBCursor> cursor); void RemoveCursorBinding(mojo::ReceiverId receiver_id); @@ -80,7 +78,7 @@ void CreateAndBindTransactionImpl( mojo::PendingAssociatedReceiver<blink::mojom::IDBTransaction> transaction_receiver, - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, base::WeakPtr<IndexedDBTransaction> transaction); // Bind this receiver to read from this given file. @@ -95,7 +93,7 @@ // Create external objects from |objects| and store the results in // |mojo_objects|. |mojo_objects| must be the same length as |objects|. void CreateAllExternalObjects( - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, const std::vector<IndexedDBExternalObject>& objects, std::vector<blink::mojom::IDBExternalObjectPtr>* mojo_objects);
diff --git a/content/browser/indexed_db/indexed_db_factory.h b/content/browser/indexed_db/indexed_db_factory.h index c325be9..a500bf5 100644 --- a/content/browser/indexed_db/indexed_db_factory.h +++ b/content/browser/indexed_db/indexed_db_factory.h
@@ -24,6 +24,10 @@ #include "third_party/blink/public/common/storage_key/storage_key.h" #include "url/gurl.h" +namespace storage { +struct BucketLocator; +} // namespace storage + namespace content { class IndexedDBBackingStore; @@ -38,16 +42,16 @@ virtual ~IndexedDBFactory() = default; virtual void GetDatabaseInfo(scoped_refptr<IndexedDBCallbacks> callbacks, - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, const base::FilePath& data_directory) = 0; virtual void Open(const std::u16string& name, std::unique_ptr<IndexedDBPendingConnection> connection, - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, const base::FilePath& data_directory) = 0; virtual void DeleteDatabase(const std::u16string& name, scoped_refptr<IndexedDBCallbacks> callbacks, - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, const base::FilePath& data_directory, bool force_close) = 0;
diff --git a/content/browser/indexed_db/indexed_db_factory_impl.cc b/content/browser/indexed_db/indexed_db_factory_impl.cc index fcd6f8f..231b6f93 100644 --- a/content/browser/indexed_db/indexed_db_factory_impl.cc +++ b/content/browser/indexed_db/indexed_db_factory_impl.cc
@@ -39,6 +39,7 @@ #include "components/services/storage/indexed_db/scopes/leveldb_scopes_factory.h" #include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_database.h" #include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_factory.h" +#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "components/services/storage/public/cpp/filesystem/filesystem_proxy.h" #include "components/services/storage/public/mojom/blob_storage_context.mojom.h" #include "components/services/storage/public/mojom/indexed_db_control.mojom.h" @@ -188,7 +189,7 @@ void IndexedDBFactoryImpl::GetDatabaseInfo( scoped_refptr<IndexedDBCallbacks> callbacks, - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, const base::FilePath& data_directory) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); TRACE_EVENT0("IndexedDB", "IndexedDBFactoryImpl::GetDatabaseInfo"); @@ -199,7 +200,7 @@ // Note: Any data loss information here is not piped up to the renderer, and // will be lost. std::tie(bucket_state_handle, s, error, std::ignore, std::ignore) = - GetOrOpenBucketFactory(storage_key, data_directory, + GetOrOpenBucketFactory(bucket_locator, data_directory, /*create_if_missing=*/false); if (!bucket_state_handle.IsHeld() || !bucket_state_handle.bucket_state()) { if (s.IsNotFound()) { @@ -207,8 +208,10 @@ } else { callbacks->OnError(error); } - if (s.IsCorruption()) - HandleBackingStoreCorruption(storage_key, error); + if (s.IsCorruption()) { + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. + HandleBackingStoreCorruption(bucket_locator.storage_key, error); + } return; } IndexedDBBucketState* factory = bucket_state_handle.bucket_state(); @@ -222,8 +225,10 @@ "Internal error opening backing store for " "indexedDB.databases()."); callbacks->OnError(error); - if (s.IsCorruption()) - HandleBackingStoreCorruption(storage_key, error); + if (s.IsCorruption()) { + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. + HandleBackingStoreCorruption(bucket_locator.storage_key, error); + } return; } callbacks->OnSuccess(std::move(names_and_versions)); @@ -232,22 +237,24 @@ void IndexedDBFactoryImpl::Open( const std::u16string& name, std::unique_ptr<IndexedDBPendingConnection> connection, - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, const base::FilePath& data_directory) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); TRACE_EVENT0("IndexedDB", "IndexedDBFactoryImpl::Open"); - IndexedDBDatabase::Identifier unique_identifier(storage_key, name); + IndexedDBDatabase::Identifier unique_identifier(bucket_locator, name); IndexedDBBucketStateHandle bucket_state_handle; leveldb::Status s; IndexedDBDatabaseError error; std::tie(bucket_state_handle, s, error, connection->data_loss_info, connection->was_cold_open) = - GetOrOpenBucketFactory(storage_key, data_directory, + GetOrOpenBucketFactory(bucket_locator, data_directory, /*create_if_missing=*/true); if (!bucket_state_handle.IsHeld() || !bucket_state_handle.bucket_state()) { connection->callbacks->OnError(error); - if (s.IsCorruption()) - HandleBackingStoreCorruption(storage_key, error); + if (s.IsCorruption()) { + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. + HandleBackingStoreCorruption(bucket_locator.storage_key, error); + } return; } IndexedDBBucketState* factory = bucket_state_handle.bucket_state(); @@ -258,11 +265,12 @@ return; } std::unique_ptr<IndexedDBDatabase> database; + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. std::tie(database, s) = class_factory_->CreateIndexedDBDatabase( name, factory->backing_store(), this, base::BindRepeating(&IndexedDBFactoryImpl::MaybeRunTasksForBucket, bucket_state_destruction_weak_factory_.GetWeakPtr(), - storage_key), + bucket_locator.storage_key), std::make_unique<IndexedDBMetadataCoding>(), std::move(unique_identifier), factory->lock_manager()); if (!database.get()) { @@ -270,8 +278,10 @@ blink::mojom::IDBException::kUnknownError, u"Internal error creating database backend for indexedDB.open."); connection->callbacks->OnError(error); - if (s.IsCorruption()) - HandleBackingStoreCorruption(storage_key, error); + if (s.IsCorruption()) { + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. + HandleBackingStoreCorruption(bucket_locator.storage_key, error); + } return; } @@ -286,24 +296,26 @@ void IndexedDBFactoryImpl::DeleteDatabase( const std::u16string& name, scoped_refptr<IndexedDBCallbacks> callbacks, - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, const base::FilePath& data_directory, bool force_close) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); TRACE_EVENT0("IndexedDB", "IndexedDBFactoryImpl::DeleteDatabase"); - IndexedDBDatabase::Identifier unique_identifier(storage_key, name); + IndexedDBDatabase::Identifier unique_identifier(bucket_locator, name); IndexedDBBucketStateHandle bucket_state_handle; leveldb::Status s; IndexedDBDatabaseError error; // Note: Any data loss information here is not piped up to the renderer, and // will be lost. std::tie(bucket_state_handle, s, error, std::ignore, std::ignore) = - GetOrOpenBucketFactory(storage_key, data_directory, + GetOrOpenBucketFactory(bucket_locator, data_directory, /*create_if_missing=*/true); if (!bucket_state_handle.IsHeld() || !bucket_state_handle.bucket_state()) { callbacks->OnError(error); - if (s.IsCorruption()) - HandleBackingStoreCorruption(storage_key, error); + if (s.IsCorruption()) { + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. + HandleBackingStoreCorruption(bucket_locator.storage_key, error); + } return; } IndexedDBBucketState* factory = bucket_state_handle.bucket_state(); @@ -311,14 +323,18 @@ auto it = factory->databases().find(name); if (it != factory->databases().end()) { base::WeakPtr<IndexedDBDatabase> database = it->second->AsWeakPtr(); + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. database->ScheduleDeleteDatabase( std::move(bucket_state_handle), callbacks, base::BindOnce(&IndexedDBFactoryImpl::OnDatabaseDeleted, - weak_factory_.GetWeakPtr(), storage_key)); + weak_factory_.GetWeakPtr(), bucket_locator.storage_key)); if (force_close) { leveldb::Status status = database->ForceCloseAndRunTasks(); - if (!status.ok()) - OnDatabaseError(storage_key, status, "Error aborting transactions."); + if (!status.ok()) { + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. + OnDatabaseError(bucket_locator.storage_key, status, + "Error aborting transactions."); + } } return; } @@ -335,8 +351,10 @@ "Internal error opening backing store for " "indexedDB.deleteDatabase."); callbacks->OnError(error); - if (s.IsCorruption()) - HandleBackingStoreCorruption(storage_key, error); + if (s.IsCorruption()) { + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. + HandleBackingStoreCorruption(bucket_locator.storage_key, error); + } return; } @@ -347,11 +365,12 @@ } std::unique_ptr<IndexedDBDatabase> database; + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. std::tie(database, s) = class_factory_->CreateIndexedDBDatabase( name, factory->backing_store(), this, base::BindRepeating(&IndexedDBFactoryImpl::MaybeRunTasksForBucket, bucket_state_destruction_weak_factory_.GetWeakPtr(), - storage_key), + bucket_locator.storage_key), std::make_unique<IndexedDBMetadataCoding>(), unique_identifier, factory->lock_manager()); if (!database.get()) { @@ -359,21 +378,27 @@ u"Internal error creating database backend " u"for indexedDB.deleteDatabase."); callbacks->OnError(error); - if (s.IsCorruption()) - HandleBackingStoreCorruption(storage_key, error); + if (s.IsCorruption()) { + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. + HandleBackingStoreCorruption(bucket_locator.storage_key, error); + } return; } base::WeakPtr<IndexedDBDatabase> database_ptr = factory->AddDatabase(name, std::move(database))->AsWeakPtr(); + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. database_ptr->ScheduleDeleteDatabase( std::move(bucket_state_handle), std::move(callbacks), base::BindOnce(&IndexedDBFactoryImpl::OnDatabaseDeleted, - weak_factory_.GetWeakPtr(), storage_key)); + weak_factory_.GetWeakPtr(), bucket_locator.storage_key)); if (force_close) { leveldb::Status status = database_ptr->ForceCloseAndRunTasks(); - if (!status.ok()) - OnDatabaseError(storage_key, status, "Error aborting transactions."); + if (!status.ok()) { + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. + OnDatabaseError(bucket_locator.storage_key, status, + "Error aborting transactions."); + } } } @@ -624,7 +649,7 @@ IndexedDBDataLossInfo, /*is_cold_open=*/bool> IndexedDBFactoryImpl::GetOrOpenBucketFactory( - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, const base::FilePath& data_directory, bool create_if_missing) { TRACE_EVENT0("IndexedDB", "indexed_db::GetOrOpenBucketFactory"); @@ -634,7 +659,8 @@ // where the flowchart should be seen as the 'master' logic template. Please // check the git history of both to make sure they are in sync. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - auto it = factories_per_bucket_.find(storage_key); + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. + auto it = factories_per_bucket_.find(bucket_locator.storage_key); if (it != factories_per_bucket_.end()) { return {it->second->CreateHandle(), leveldb::Status::OK(), IndexedDBDatabaseError(), IndexedDBDataLossInfo(), @@ -651,8 +677,9 @@ if (!is_incognito_and_in_memory) { // The database will be on-disk and not in-memory. auto filesystem_proxy = storage::CreateFilesystemProxy(); + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. std::tie(database_path, blob_path, s) = CreateDatabaseDirectories( - filesystem_proxy.get(), data_directory, storage_key); + filesystem_proxy.get(), data_directory, bucket_locator.storage_key); if (!s.ok()) return {IndexedDBBucketStateHandle(), s, CreateDefaultError(), IndexedDBDataLossInfo(), /*was_cold_open=*/true}; @@ -673,20 +700,21 @@ scopes_options.lock_manager = lock_manager.get(); scopes_options.metadata_key_prefix = ScopesPrefix::Encode(); scopes_options.failure_callback = base::BindRepeating( - [](const blink::StorageKey& storage_key, + [](const storage::BucketLocator& bucket_locator, base::WeakPtr<IndexedDBFactoryImpl> factory, leveldb::Status s) { if (!factory) return; - factory->OnDatabaseError(storage_key, s, nullptr); + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. + factory->OnDatabaseError(bucket_locator.storage_key, s, nullptr); }, - storage_key, weak_factory_.GetWeakPtr()); + bucket_locator, weak_factory_.GetWeakPtr()); const bool is_first_attempt = i == 0; auto filesystem_proxy = !is_incognito_and_in_memory ? storage::CreateFilesystemProxy() : nullptr; std::tie(backing_store, s, data_loss_info, disk_full) = OpenAndVerifyIndexedDBBackingStore( - storage_key, data_directory, database_path, blob_path, + bucket_locator, data_directory, database_path, blob_path, std::move(scopes_options), &scopes_factory, std::move(filesystem_proxy), is_first_attempt, create_if_missing); if (LIKELY(is_first_attempt)) @@ -701,10 +729,13 @@ std::string sanitized_message = leveldb_env::GetCorruptionMessage(s); base::ReplaceSubstringsAfterOffset(&sanitized_message, 0u, data_directory.AsUTF8Unsafe(), "..."); - LOG(ERROR) << "Got corruption for " << storage_key.GetDebugString() - << ", " << sanitized_message; - IndexedDBBackingStore::RecordCorruptionInfo(data_directory, storage_key, - sanitized_message); + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. + LOG(ERROR) << "Got corruption for " + << bucket_locator.storage_key.GetDebugString() << ", " + << sanitized_message; + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. + IndexedDBBackingStore::RecordCorruptionInfo( + data_directory, bucket_locator.storage_key, sanitized_message); } } @@ -720,11 +751,14 @@ } if (UNLIKELY(!s.ok())) { + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. ReportOpenStatus(indexed_db::INDEXED_DB_BACKING_STORE_OPEN_NO_RECOVERY, - storage_key); + bucket_locator.storage_key); if (disk_full) { - context_->quota_manager_proxy()->NotifyWriteFailed(storage_key); + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. + context_->quota_manager_proxy()->NotifyWriteFailed( + bucket_locator.storage_key); return {IndexedDBBucketStateHandle(), s, IndexedDBDatabaseError(blink::mojom::IDBException::kQuotaError, u"Encountered full disk while opening " @@ -743,8 +777,9 @@ LevelDBScopes::TaskRunnerMode::kNewCleanupAndRevertSequences); if (UNLIKELY(!s.ok())) { + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. ReportOpenStatus(indexed_db::INDEXED_DB_BACKING_STORE_OPEN_NO_RECOVERY, - storage_key); + bucket_locator.storage_key); return {IndexedDBBucketStateHandle(), s, CreateDefaultError(), data_loss_info, /*was_cold_open=*/true}; @@ -752,32 +787,39 @@ if (!is_incognito_and_in_memory) ReportOpenStatus(indexed_db::INDEXED_DB_BACKING_STORE_OPEN_SUCCESS, - storage_key); + bucket_locator.storage_key); - auto run_tasks_callback = base::BindRepeating( - &IndexedDBFactoryImpl::MaybeRunTasksForBucket, - bucket_state_destruction_weak_factory_.GetWeakPtr(), storage_key); + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. + auto run_tasks_callback = + base::BindRepeating(&IndexedDBFactoryImpl::MaybeRunTasksForBucket, + bucket_state_destruction_weak_factory_.GetWeakPtr(), + bucket_locator.storage_key); auto tear_down_callback = base::BindRepeating( - [](const blink::StorageKey& storage_key, + [](const storage::BucketLocator& bucket_locator, base::WeakPtr<IndexedDBFactoryImpl> factory, leveldb::Status s) { if (!factory) return; - factory->OnDatabaseError(storage_key, s, nullptr); + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. + factory->OnDatabaseError(bucket_locator.storage_key, s, nullptr); }, - storage_key, weak_factory_.GetWeakPtr()); + bucket_locator, weak_factory_.GetWeakPtr()); + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. auto bucket_state = std::make_unique<IndexedDBBucketState>( - storage_key, + bucket_locator.storage_key, /*persist_for_incognito=*/is_incognito_and_in_memory, clock_, &class_factory_->transactional_leveldb_factory(), &earliest_sweep_, &earliest_compaction_, std::move(lock_manager), std::move(run_tasks_callback), std::move(tear_down_callback), std::move(backing_store)); - it = - factories_per_bucket_.emplace(storage_key, std::move(bucket_state)).first; - context_->FactoryOpened(storage_key); + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. + it = factories_per_bucket_ + .emplace(bucket_locator.storage_key, std::move(bucket_state)) + .first; + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. + context_->FactoryOpened(bucket_locator.storage_key); return {it->second->CreateHandle(), s, IndexedDBDatabaseError(), data_loss_info, /*was_cold_open=*/true}; } @@ -785,7 +827,7 @@ std::unique_ptr<IndexedDBBackingStore> IndexedDBFactoryImpl::CreateBackingStore( IndexedDBBackingStore::Mode backing_store_mode, TransactionalLevelDBFactory* transactional_leveldb_factory, - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, const base::FilePath& blob_path, std::unique_ptr<TransactionalLevelDBDatabase> db, storage::mojom::BlobStorageContext* blob_storage_context, @@ -796,17 +838,18 @@ report_outstanding_blobs, scoped_refptr<base::SequencedTaskRunner> idb_task_runner) { return std::make_unique<IndexedDBBackingStore>( - backing_store_mode, transactional_leveldb_factory, storage_key, blob_path, - std::move(db), blob_storage_context, file_system_access_context, - std::move(filesystem_proxy), std::move(blob_files_cleaned), - std::move(report_outstanding_blobs), std::move(idb_task_runner)); + backing_store_mode, transactional_leveldb_factory, bucket_locator, + blob_path, std::move(db), blob_storage_context, + file_system_access_context, std::move(filesystem_proxy), + std::move(blob_files_cleaned), std::move(report_outstanding_blobs), + std::move(idb_task_runner)); } std::tuple<std::unique_ptr<IndexedDBBackingStore>, leveldb::Status, IndexedDBDataLossInfo, bool /* is_disk_full */> IndexedDBFactoryImpl::OpenAndVerifyIndexedDBBackingStore( - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, base::FilePath data_directory, base::FilePath database_path, base::FilePath blob_path, @@ -831,15 +874,17 @@ if (!is_incognito_and_in_memory) { // Check for previous corruption, and if found then try to delete the // database. + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. std::string corruption_message = indexed_db::ReadCorruptionInfo( - filesystem_proxy.get(), data_directory, storage_key); + filesystem_proxy.get(), data_directory, bucket_locator.storage_key); if (UNLIKELY(!corruption_message.empty())) { LOG(ERROR) << "IndexedDB recovering from a corrupted (and deleted) " "database."; if (is_first_attempt) { + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. ReportOpenStatus( indexed_db::INDEXED_DB_BACKING_STORE_OPEN_FAILED_PRIOR_CORRUPTION, - storage_key); + bucket_locator.storage_key); } data_loss_info.status = blink::mojom::IDBDataLoss::Total; data_loss_info.message = base::StrCat( @@ -905,35 +950,41 @@ LOG(ERROR) << "IndexedDB had an error checking schema, treating it as " "failure to open: " << status.ToString(); + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. ReportOpenStatus( indexed_db:: INDEXED_DB_BACKING_STORE_OPEN_FAILED_IO_ERROR_CHECKING_SCHEMA, - storage_key); + bucket_locator.storage_key); return {nullptr, status, std::move(data_loss_info), /*is_disk_full=*/false}; } else if (UNLIKELY(!are_schemas_known)) { LOG(ERROR) << "IndexedDB backing store had unknown schema, treating it as " "failure to open."; + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. ReportOpenStatus( indexed_db::INDEXED_DB_BACKING_STORE_OPEN_FAILED_UNKNOWN_SCHEMA, - storage_key); + bucket_locator.storage_key); return {nullptr, leveldb::Status::Corruption("Unknown IndexedDB schema"), std::move(data_loss_info), /*is_disk_full=*/false}; } + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. bool first_open_since_startup = - backends_opened_since_startup_.insert(storage_key).second; + backends_opened_since_startup_.insert(bucket_locator.storage_key).second; IndexedDBBackingStore::Mode backing_store_mode = is_incognito_and_in_memory ? IndexedDBBackingStore::Mode::kInMemory : IndexedDBBackingStore::Mode::kOnDisk; + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. std::unique_ptr<IndexedDBBackingStore> backing_store = CreateBackingStore( backing_store_mode, &class_factory_->transactional_leveldb_factory(), - storage_key, blob_path, std::move(database), + bucket_locator, blob_path, std::move(database), context_->blob_storage_context(), context_->file_system_access_context(), std::move(filesystem_proxy), base::BindRepeating(&IndexedDBFactoryImpl::BlobFilesCleaned, - weak_factory_.GetWeakPtr(), storage_key), + weak_factory_.GetWeakPtr(), + bucket_locator.storage_key), base::BindRepeating(&IndexedDBFactoryImpl::ReportOutstandingBlobs, - weak_factory_.GetWeakPtr(), storage_key), + weak_factory_.GetWeakPtr(), + bucket_locator.storage_key), context_->IDBTaskRunner()); status = backing_store->Initialize( /*clean_active_blob_journal=*/(!is_incognito_and_in_memory &&
diff --git a/content/browser/indexed_db/indexed_db_factory_impl.h b/content/browser/indexed_db/indexed_db_factory_impl.h index 72d6f91..1c5857fe 100644 --- a/content/browser/indexed_db/indexed_db_factory_impl.h +++ b/content/browser/indexed_db/indexed_db_factory_impl.h
@@ -38,7 +38,11 @@ namespace base { class FilePath; class SequencedTaskRunner; -} +} // namespace base + +namespace storage { +struct BucketLocator; +} // namespace storage namespace content { class IndexedDBBucketState; @@ -64,16 +68,16 @@ // content::IndexedDBFactory overrides: void GetDatabaseInfo(scoped_refptr<IndexedDBCallbacks> callbacks, - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, const base::FilePath& data_directory) override; void Open(const std::u16string& name, std::unique_ptr<IndexedDBPendingConnection> connection, - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, const base::FilePath& data_directory) override; void DeleteDatabase(const std::u16string& name, scoped_refptr<IndexedDBCallbacks> callbacks, - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, const base::FilePath& data_directory, bool force_close) override; @@ -138,7 +142,7 @@ IndexedDBDatabaseError, IndexedDBDataLossInfo, /*was_cold_open=*/bool> - GetOrOpenBucketFactory(const blink::StorageKey& storage_key, + GetOrOpenBucketFactory(const storage::BucketLocator& bucket_locator, const base::FilePath& data_directory, bool create_if_missing); @@ -155,7 +159,7 @@ virtual std::unique_ptr<IndexedDBBackingStore> CreateBackingStore( IndexedDBBackingStore::Mode backing_store_mode, TransactionalLevelDBFactory* leveldb_factory, - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, const base::FilePath& blob_path, std::unique_ptr<TransactionalLevelDBDatabase> db, storage::mojom::BlobStorageContext* blob_storage_context, @@ -197,7 +201,7 @@ IndexedDBDataLossInfo, bool /* is_disk_full */> OpenAndVerifyIndexedDBBackingStore( - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, base::FilePath data_directory, base::FilePath database_path, base::FilePath blob_path,
diff --git a/content/browser/indexed_db/indexed_db_factory_unittest.cc b/content/browser/indexed_db/indexed_db_factory_unittest.cc index 5d9c3009..2728d490 100644 --- a/content/browser/indexed_db/indexed_db_factory_unittest.cc +++ b/content/browser/indexed_db/indexed_db_factory_unittest.cc
@@ -22,6 +22,7 @@ #include "base/time/default_clock.h" #include "components/services/storage/indexed_db/leveldb/fake_leveldb_factory.h" #include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_database.h" +#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "components/services/storage/public/mojom/indexed_db_control.mojom-test-utils.h" #include "components/services/storage/public/mojom/storage_usage_info.mojom.h" #include "content/browser/indexed_db/indexed_db_backing_store.h" @@ -143,7 +144,7 @@ // is no actual data in the database. std::tuple<std::unique_ptr<IndexedDBConnection>, scoped_refptr<MockIndexedDBDatabaseCallbacks>> - CreateConnectionForDatatabase(const blink::StorageKey& storage_key, + CreateConnectionForDatatabase(const storage::BucketLocator& bucket_locator, const std::u16string& name) { auto callbacks = base::MakeRefCounted<MockIndexedDBCallbacks>(); auto db_callbacks = base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>(); @@ -160,7 +161,7 @@ base::RunLoop loop; callbacks->CallOnUpgradeNeeded( base::BindLambdaForTesting([&]() { loop.Quit(); })); - factory()->Open(name, std::move(connection), storage_key, + factory()->Open(name, std::move(connection), bucket_locator, context()->data_path()); loop.Run(); } @@ -235,21 +236,27 @@ const blink::StorageKey storage_key_1 = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); + auto bucket_locator_1 = storage::BucketLocator(); + bucket_locator_1.storage_key = storage_key_1; const blink::StorageKey storage_key_2 = blink::StorageKey::CreateFromStringForTesting("http://localhost:82"); + auto bucket_locator_2 = storage::BucketLocator(); + bucket_locator_2.storage_key = storage_key_2; IndexedDBBucketStateHandle bucket_state1_handle; IndexedDBBucketStateHandle bucket_state2_handle; leveldb::Status s; std::tie(bucket_state1_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(storage_key_1, context()->data_path(), + factory()->GetOrOpenBucketFactory(bucket_locator_1, + context()->data_path(), /*create_if_missing=*/true); EXPECT_TRUE(bucket_state1_handle.IsHeld()) << s.ToString(); EXPECT_TRUE(s.ok()) << s.ToString(); std::tie(bucket_state2_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(storage_key_2, context()->data_path(), + factory()->GetOrOpenBucketFactory(bucket_locator_2, + context()->data_path(), /*create_if_missing=*/true); EXPECT_TRUE(bucket_state2_handle.IsHeld()) << s.ToString(); EXPECT_TRUE(s.ok()) << s.ToString(); @@ -267,12 +274,13 @@ const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - + auto bucket_locator = storage::BucketLocator(); + bucket_locator.storage_key = storage_key; IndexedDBBucketStateHandle bucket_state_handle; leveldb::Status s; std::tie(bucket_state_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(storage_key, context()->data_path(), + factory()->GetOrOpenBucketFactory(bucket_locator, context()->data_path(), /*create_if_missing=*/true); EXPECT_TRUE(bucket_state_handle.IsHeld()) << s.ToString(); bucket_state_handle.Release(); @@ -292,12 +300,13 @@ const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - + auto bucket_locator = storage::BucketLocator(); + bucket_locator.storage_key = storage_key; IndexedDBBucketStateHandle bucket_state_handle; leveldb::Status s; std::tie(bucket_state_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(storage_key, context()->data_path(), + factory()->GetOrOpenBucketFactory(bucket_locator, context()->data_path(), /*create_if_missing=*/true); EXPECT_TRUE(bucket_state_handle.IsHeld()) << s.ToString(); bucket_state_handle.Release(); @@ -315,14 +324,15 @@ const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - + auto bucket_locator = storage::BucketLocator(); + bucket_locator.storage_key = storage_key; IndexedDBBucketStateHandle bucket_state_handle; leveldb::Status s; // Open a connection & immediately release it to cause the closing sequence to // start. std::tie(bucket_state_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(storage_key, context()->data_path(), + factory()->GetOrOpenBucketFactory(bucket_locator, context()->data_path(), /*create_if_missing=*/true); EXPECT_TRUE(bucket_state_handle.IsHeld()) << s.ToString(); bucket_state_handle.Release(); @@ -346,7 +356,7 @@ // Open a connection & immediately release it to cause the closing sequence to // start again. std::tie(bucket_state_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(storage_key, context()->data_path(), + factory()->GetOrOpenBucketFactory(bucket_locator, context()->data_path(), /*create_if_missing=*/true); EXPECT_TRUE(bucket_state_handle.IsHeld()) << s.ToString(); bucket_state_handle.Release(); @@ -367,7 +377,7 @@ // Stop sweep by opening a connection. std::tie(bucket_state_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(storage_key, context()->data_path(), + factory()->GetOrOpenBucketFactory(bucket_locator, context()->data_path(), /*create_if_missing=*/true); EXPECT_TRUE(bucket_state_handle.IsHeld()) << s.ToString(); EXPECT_FALSE( @@ -393,7 +403,7 @@ // Finally, move the clock forward so the storage key should allow a sweep. clock.Advance(IndexedDBBucketState::kMaxEarliestBucketSweepFromNow); std::tie(bucket_state_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(storage_key, context()->data_path(), + factory()->GetOrOpenBucketFactory(bucket_locator, context()->data_path(), /*create_if_missing=*/true); bucket_state_handle.Release(); factory()->GetBucketFactory(storage_key)->close_timer()->FireNow(); @@ -415,14 +425,15 @@ const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - + auto bucket_locator = storage::BucketLocator(); + bucket_locator.storage_key = storage_key; IndexedDBBucketStateHandle bucket_state_handle; leveldb::Status s; // Open a connection & immediately release it to cause the closing sequence to // start. std::tie(bucket_state_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(storage_key, context()->data_path(), + factory()->GetOrOpenBucketFactory(bucket_locator, context()->data_path(), /*create_if_missing=*/true); EXPECT_TRUE(bucket_state_handle.IsHeld()) << s.ToString(); @@ -453,14 +464,15 @@ const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - + auto bucket_locator = storage::BucketLocator(); + bucket_locator.storage_key = storage_key; IndexedDBBucketStateHandle bucket_state_handle; leveldb::Status s; // Open a connection & immediately release it to cause the closing sequence to // start. std::tie(bucket_state_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(storage_key, context()->data_path(), + factory()->GetOrOpenBucketFactory(bucket_locator, context()->data_path(), /*create_if_missing=*/true); EXPECT_TRUE(bucket_state_handle.IsHeld()) << s.ToString(); @@ -494,13 +506,15 @@ const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); + auto bucket_locator = storage::BucketLocator(); + bucket_locator.storage_key = storage_key; IndexedDBBucketStateHandle bucket_state_handle; leveldb::Status s; // Open a connection & immediately release it to cause the closing sequence to // start. std::tie(bucket_state_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(storage_key, context()->data_path(), + factory()->GetOrOpenBucketFactory(bucket_locator, context()->data_path(), /*create_if_missing=*/true); EXPECT_TRUE(bucket_state_handle.IsHeld()) << s.ToString(); @@ -513,12 +527,13 @@ const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - + auto bucket_locator = storage::BucketLocator(); + bucket_locator.storage_key = storage_key; IndexedDBBucketStateHandle bucket_state_handle; leveldb::Status s; std::tie(bucket_state_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(storage_key, context()->data_path(), + factory()->GetOrOpenBucketFactory(bucket_locator, context()->data_path(), /*create_if_missing=*/true); EXPECT_TRUE(bucket_state_handle.IsHeld()) << s.ToString(); EXPECT_TRUE(StorageBucketFromHandle(bucket_state_handle) @@ -547,12 +562,13 @@ const blink::StorageKey too_long_storage_key = blink::StorageKey::CreateFromStringForTesting("http://" + origin + ":81/"); - + auto too_long_bucket_locator = storage::BucketLocator(); + too_long_bucket_locator.storage_key = too_long_storage_key; IndexedDBBucketStateHandle bucket_state_handle; leveldb::Status s; std::tie(bucket_state_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(too_long_storage_key, + factory()->GetOrOpenBucketFactory(too_long_bucket_locator, context()->data_path(), /*create_if_missing=*/true); EXPECT_FALSE(bucket_state_handle.IsHeld()); @@ -563,6 +579,8 @@ SetupContext(); const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); + auto bucket_locator = storage::BucketLocator(); + bucket_locator.storage_key = storage_key; auto callbacks = base::MakeRefCounted<MockIndexedDBCallbacks>(); auto db_callbacks = base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>(); @@ -574,7 +592,7 @@ callbacks, db_callbacks, transaction_id, IndexedDBDatabaseMetadata::DEFAULT_VERSION, std::move(create_transaction_callback)); - factory()->Open(u"db", std::move(connection), storage_key, + factory()->Open(u"db", std::move(connection), bucket_locator, context()->data_path()); RunPostedTasks(); @@ -587,12 +605,13 @@ SetupContext(); const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - + auto bucket_locator = storage::BucketLocator(); + bucket_locator.storage_key = storage_key; IndexedDBBucketStateHandle bucket_state_handle; leveldb::Status s; std::tie(bucket_state_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(storage_key, context()->data_path(), + factory()->GetOrOpenBucketFactory(bucket_locator, context()->data_path(), /*create_if_missing=*/true); EXPECT_TRUE(bucket_state_handle.IsHeld()) << s.ToString(); @@ -606,12 +625,13 @@ SetupContext(); const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - + auto bucket_locator = storage::BucketLocator(); + bucket_locator.storage_key = storage_key; IndexedDBBucketStateHandle bucket_state_handle; leveldb::Status s; std::tie(bucket_state_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(storage_key, context()->data_path(), + factory()->GetOrOpenBucketFactory(bucket_locator, context()->data_path(), /*create_if_missing=*/true); EXPECT_TRUE(bucket_state_handle.IsHeld()) << s.ToString(); @@ -627,6 +647,8 @@ SetupContext(); const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); + auto bucket_locator = storage::BucketLocator(); + bucket_locator.storage_key = storage_key; auto callbacks = base::MakeRefCounted<MockIndexedDBCallbacks>(); auto db_callbacks = base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>(); @@ -638,7 +660,7 @@ callbacks, db_callbacks, transaction_id, IndexedDBDatabaseMetadata::DEFAULT_VERSION, std::move(create_transaction_callback)); - factory()->Open(u"db", std::move(connection), storage_key, + factory()->Open(u"db", std::move(connection), bucket_locator, context()->data_path()); EXPECT_FALSE(callbacks->connection()); RunPostedTasks(); @@ -659,6 +681,8 @@ SetupContext(); const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); + auto bucket_locator = storage::BucketLocator(); + bucket_locator.storage_key = storage_key; auto callbacks = base::MakeRefCounted<MockIndexedDBCallbacks>(); auto db_callbacks = base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>(); @@ -676,7 +700,7 @@ base::RunLoop loop; callbacks->CallOnUpgradeNeeded( base::BindLambdaForTesting([&]() { loop.Quit(); })); - factory()->Open(u"db", std::move(connection), storage_key, + factory()->Open(u"db", std::move(connection), bucket_locator, context()->data_path()); loop.Run(); } @@ -697,6 +721,8 @@ SetupContext(); const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); + auto bucket_locator = storage::BucketLocator(); + bucket_locator.storage_key = storage_key; auto callbacks = base::MakeRefCounted<MockIndexedDBCallbacks>(); auto db_callbacks = base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>(); @@ -714,7 +740,7 @@ base::RunLoop loop; callbacks->CallOnUpgradeNeeded( base::BindLambdaForTesting([&]() { loop.Quit(); })); - factory()->Open(u"db", std::move(connection), storage_key, + factory()->Open(u"db", std::move(connection), bucket_locator, context()->data_path()); loop.Run(); } @@ -735,11 +761,13 @@ SetupContext(); const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); + auto bucket_locator = storage::BucketLocator(); + bucket_locator.storage_key = storage_key; std::unique_ptr<IndexedDBConnection> connection; scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks; std::tie(connection, db_callbacks) = - CreateConnectionForDatatabase(storage_key, u"db"); + CreateConnectionForDatatabase(bucket_locator, u"db"); // Force close the database. connection->database()->ForceCloseAndRunTasks(); @@ -758,8 +786,10 @@ const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); + auto bucket_locator = storage::BucketLocator(); + bucket_locator.storage_key = storage_key; - factory()->DeleteDatabase(u"db", callbacks, storage_key, + factory()->DeleteDatabase(u"db", callbacks, bucket_locator, context()->data_path(), /*force_close=*/false); @@ -773,12 +803,14 @@ const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); + auto bucket_locator = storage::BucketLocator(); + bucket_locator.storage_key = storage_key; const std::u16string name = u"db"; std::unique_ptr<IndexedDBConnection> connection; scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks; std::tie(connection, db_callbacks) = - CreateConnectionForDatatabase(storage_key, name); + CreateConnectionForDatatabase(bucket_locator, name); base::RunLoop run_loop; factory()->CallOnDatabaseDeletedForTesting(base::BindLambdaForTesting( @@ -790,7 +822,7 @@ auto callbacks = base::MakeRefCounted<MockIndexedDBCallbacks>( /*expect_connection=*/false); - factory()->DeleteDatabase(name, callbacks, storage_key, + factory()->DeleteDatabase(name, callbacks, bucket_locator, context()->data_path(), /*force_close=*/true); @@ -814,8 +846,10 @@ const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); + auto bucket_locator = storage::BucketLocator(); + bucket_locator.storage_key = storage_key; - factory()->GetDatabaseInfo(callbacks, storage_key, context()->data_path()); + factory()->GetDatabaseInfo(callbacks, bucket_locator, context()->data_path()); EXPECT_TRUE(callbacks->info_called()); // Don't create a factory if one doesn't exist. @@ -830,16 +864,17 @@ const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - + auto bucket_locator = storage::BucketLocator(); + bucket_locator.storage_key = storage_key; IndexedDBBucketStateHandle bucket_state_handle; leveldb::Status s; std::tie(bucket_state_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(storage_key, context()->data_path(), + factory()->GetOrOpenBucketFactory(bucket_locator, context()->data_path(), /*create_if_missing=*/true); EXPECT_TRUE(bucket_state_handle.IsHeld()) << s.ToString(); - factory()->GetDatabaseInfo(callbacks, storage_key, context()->data_path()); + factory()->GetDatabaseInfo(callbacks, bucket_locator, context()->data_path()); EXPECT_TRUE(callbacks->info_called()); EXPECT_TRUE(factory()->GetBucketFactory(storage_key)); @@ -851,7 +886,7 @@ public: LookingForQuotaErrorMockCallbacks() : IndexedDBCallbacks(nullptr, - blink::StorageKey(), + storage::BucketLocator(), mojo::NullAssociatedRemote(), base::SequencedTaskRunnerHandle::Get()) {} @@ -885,6 +920,8 @@ nullptr, mojo::NullAssociatedRemote(), context()->IDBTaskRunner()); const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); + auto bucket_locator = storage::BucketLocator(); + bucket_locator.storage_key = storage_key; const std::u16string name(u"name"); auto create_transaction_callback = base::BindOnce(&CreateAndBindTransactionPlaceholder); @@ -892,7 +929,7 @@ callbacks, dummy_database_callbacks, /*transaction_id=*/1, /*version=*/1, std::move(create_transaction_callback)); - factory()->Open(name, std::move(connection), storage_key, + factory()->Open(name, std::move(connection), bucket_locator, context()->data_path()); EXPECT_TRUE(callbacks->error_called()); base::RunLoop().RunUntilIdle(); @@ -942,6 +979,8 @@ SetupContext(); const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); + auto bucket_locator = storage::BucketLocator(); + bucket_locator.storage_key = storage_key; const std::u16string db_name(u"db"); const int64_t transaction_id = 1; @@ -963,7 +1002,7 @@ base::RunLoop loop; callbacks->CallOnUpgradeNeeded( base::BindLambdaForTesting([&]() { loop.Quit(); })); - factory()->Open(db_name, std::move(connection), storage_key, + factory()->Open(db_name, std::move(connection), bucket_locator, context()->data_path()); loop.Run(); } @@ -994,7 +1033,7 @@ auto connection = std::make_unique<IndexedDBPendingConnection>( failed_open_callbacks, db_callbacks2, transaction_id, db_version, std::move(create_transaction_callback)); - factory()->Open(db_name, std::move(connection), storage_key, + factory()->Open(db_name, std::move(connection), bucket_locator, context()->data_path()); EXPECT_TRUE(factory()->IsDatabaseOpen(storage_key, db_name)); RunPostedTasks(); @@ -1028,7 +1067,7 @@ TEST_F(IndexedDBFactoryTest, DataFormatVersion) { SetupContext(); - auto try_open = [this](const blink::StorageKey& storage_key, + auto try_open = [this](const storage::BucketLocator& bucket_locator, const IndexedDBDataFormatVersion& version) { base::AutoReset<IndexedDBDataFormatVersion> override_version( &IndexedDBDataFormatVersion::GetMutableCurrentForTesting(), version); @@ -1056,7 +1095,7 @@ base::BindLambdaForTesting([&]() { loop.Quit(); })); this->factory()->Open(u"test_db", std::move(pending_connection), - storage_key, context()->data_path()); + bucket_locator, context()->data_path()); loop.Run(); // If an upgrade was requested, then commit the upgrade transaction. @@ -1077,7 +1116,7 @@ } } RunPostedTasks(); - factory()->ForceClose(storage_key, false); + factory()->ForceClose(bucket_locator.storage_key, false); RunPostedTasks(); return callbacks->data_loss(); }; @@ -1095,10 +1134,12 @@ SCOPED_TRACE(test.origin); const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting(test.origin); + auto bucket_locator = storage::BucketLocator(); + bucket_locator.storage_key = storage_key; ASSERT_EQ(blink::mojom::IDBDataLoss::None, - try_open(storage_key, test.open_version_1)); + try_open(bucket_locator, test.open_version_1)); EXPECT_EQ(test.expected_data_loss, - try_open(storage_key, test.open_version_2)); + try_open(bucket_locator, test.open_version_2)); } }
diff --git a/content/browser/indexed_db/indexed_db_fake_backing_store.cc b/content/browser/indexed_db/indexed_db_fake_backing_store.cc index 3a53cb1..18a72cfe 100644 --- a/content/browser/indexed_db/indexed_db_fake_backing_store.cc +++ b/content/browser/indexed_db/indexed_db_fake_backing_store.cc
@@ -11,6 +11,7 @@ #include "base/threading/sequenced_task_runner_handle.h" #include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_database.h" #include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_factory.h" +#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "content/browser/indexed_db/indexed_db_leveldb_env.h" #include "third_party/blink/public/common/storage_key/storage_key.h" @@ -25,41 +26,49 @@ return factory.get(); } +const storage::BucketLocator GetBucketLocator(blink::StorageKey storage_key) { + auto bucket_locator = storage::BucketLocator(); + bucket_locator.storage_key = storage_key; + return bucket_locator; +} + } // namespace IndexedDBFakeBackingStore::IndexedDBFakeBackingStore() - : IndexedDBBackingStore( - IndexedDBBackingStore::Mode::kInMemory, - GetTransactionalLevelDBFactory(), - blink::StorageKey::CreateFromStringForTesting("http://localhost:81"), - base::FilePath(), - std::unique_ptr<TransactionalLevelDBDatabase>(), - /*blob_storage_context=*/nullptr, - /*file_system_access_context=*/nullptr, - std::make_unique<storage::FilesystemProxy>( - storage::FilesystemProxy::UNRESTRICTED, - base::FilePath()), - BlobFilesCleanedCallback(), - ReportOutstandingBlobsCallback(), - base::SequencedTaskRunnerHandle::Get()) {} + : IndexedDBBackingStore(IndexedDBBackingStore::Mode::kInMemory, + GetTransactionalLevelDBFactory(), + storage::BucketLocator(GetBucketLocator( + blink::StorageKey::CreateFromStringForTesting( + "http://localhost:81"))), + base::FilePath(), + std::unique_ptr<TransactionalLevelDBDatabase>(), + /*blob_storage_context=*/nullptr, + /*file_system_access_context=*/nullptr, + std::make_unique<storage::FilesystemProxy>( + storage::FilesystemProxy::UNRESTRICTED, + base::FilePath()), + BlobFilesCleanedCallback(), + ReportOutstandingBlobsCallback(), + base::SequencedTaskRunnerHandle::Get()) {} IndexedDBFakeBackingStore::IndexedDBFakeBackingStore( BlobFilesCleanedCallback blob_files_cleaned, ReportOutstandingBlobsCallback report_outstanding_blobs, scoped_refptr<base::SequencedTaskRunner> task_runner) - : IndexedDBBackingStore( - IndexedDBBackingStore::Mode::kOnDisk, - GetTransactionalLevelDBFactory(), - blink::StorageKey::CreateFromStringForTesting("http://localhost:81"), - base::FilePath(), - std::unique_ptr<TransactionalLevelDBDatabase>(), - /*blob_storage_context=*/nullptr, - /*file_system_access_context=*/nullptr, - std::make_unique<storage::FilesystemProxy>( - storage::FilesystemProxy::UNRESTRICTED, - base::FilePath()), - std::move(blob_files_cleaned), - std::move(report_outstanding_blobs), - task_runner) {} + : IndexedDBBackingStore(IndexedDBBackingStore::Mode::kOnDisk, + GetTransactionalLevelDBFactory(), + storage::BucketLocator(GetBucketLocator( + blink::StorageKey::CreateFromStringForTesting( + "http://localhost:81"))), + base::FilePath(), + std::unique_ptr<TransactionalLevelDBDatabase>(), + /*blob_storage_context=*/nullptr, + /*file_system_access_context=*/nullptr, + std::make_unique<storage::FilesystemProxy>( + storage::FilesystemProxy::UNRESTRICTED, + base::FilePath()), + std::move(blob_files_cleaned), + std::move(report_outstanding_blobs), + task_runner) {} IndexedDBFakeBackingStore::~IndexedDBFakeBackingStore() = default; leveldb::Status IndexedDBFakeBackingStore::DeleteDatabase(
diff --git a/content/browser/indexed_db/indexed_db_unittest.cc b/content/browser/indexed_db/indexed_db_unittest.cc index b14edec..ff0129e 100644 --- a/content/browser/indexed_db/indexed_db_unittest.cc +++ b/content/browser/indexed_db/indexed_db_unittest.cc
@@ -16,6 +16,7 @@ #include "base/time/default_clock.h" #include "components/services/storage/indexed_db/locks/leveled_lock_manager.h" #include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_database.h" +#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "components/services/storage/public/mojom/indexed_db_control.mojom-test-utils.h" #include "content/browser/indexed_db/indexed_db_bucket_state.h" #include "content/browser/indexed_db/indexed_db_connection.h" @@ -208,13 +209,13 @@ class ForceCloseDBCallbacks : public IndexedDBCallbacks { public: ForceCloseDBCallbacks(scoped_refptr<IndexedDBContextImpl> idb_context, - const blink::StorageKey& storage_key) + const storage::BucketLocator& bucket_locator) : IndexedDBCallbacks(nullptr, - storage_key, + bucket_locator, mojo::NullAssociatedRemote(), idb_context->IDBTaskRunner()), idb_context_(idb_context), - storage_key_(storage_key) {} + bucket_locator_(bucket_locator) {} ForceCloseDBCallbacks(const ForceCloseDBCallbacks&) = delete; ForceCloseDBCallbacks& operator=(const ForceCloseDBCallbacks&) = delete; @@ -223,7 +224,8 @@ void OnSuccess(std::unique_ptr<IndexedDBConnection> connection, const IndexedDBDatabaseMetadata& metadata) override { connection_ = std::move(connection); - idb_context_->ConnectionOpened(storage_key_, connection_.get()); + idb_context_->ConnectionOpened(bucket_locator_.storage_key, + connection_.get()); } IndexedDBConnection* connection() { return connection_.get(); } @@ -233,22 +235,24 @@ private: scoped_refptr<IndexedDBContextImpl> idb_context_; - blink::StorageKey storage_key_; + storage::BucketLocator bucket_locator_; std::unique_ptr<IndexedDBConnection> connection_; }; TEST_F(IndexedDBTest, ForceCloseOpenDatabasesOnDelete) { const blink::StorageKey kTestStorageKey = blink::StorageKey::CreateFromStringForTesting("http://test/"); + auto bucket_locator = storage::BucketLocator(); + bucket_locator.storage_key = kTestStorageKey; auto open_db_callbacks = base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>(); auto closed_db_callbacks = base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>(); auto open_callbacks = - base::MakeRefCounted<ForceCloseDBCallbacks>(context(), kTestStorageKey); + base::MakeRefCounted<ForceCloseDBCallbacks>(context(), bucket_locator); auto closed_callbacks = - base::MakeRefCounted<ForceCloseDBCallbacks>(context(), kTestStorageKey); + base::MakeRefCounted<ForceCloseDBCallbacks>(context(), bucket_locator); base::FilePath test_path = GetFilePathForTesting(kTestStorageKey); const int64_t host_transaction_id = 0; @@ -262,7 +266,7 @@ std::make_unique<IndexedDBPendingConnection>( open_callbacks, open_db_callbacks, host_transaction_id, version, std::move(create_transaction_callback1)), - kTestStorageKey, context()->data_path()); + bucket_locator, context()->data_path()); EXPECT_TRUE(base::DirectoryExists(test_path)); auto create_transaction_callback2 = @@ -271,7 +275,7 @@ std::make_unique<IndexedDBPendingConnection>( closed_callbacks, closed_db_callbacks, host_transaction_id, version, std::move(create_transaction_callback2)), - kTestStorageKey, context()->data_path()); + bucket_locator, context()->data_path()); RunPostedTasks(); ASSERT_TRUE(closed_callbacks->connection()); closed_callbacks->connection()->AbortTransactionsAndClose( @@ -321,6 +325,8 @@ TEST_F(IndexedDBTest, ForceCloseOpenDatabasesOnCommitFailure) { const blink::StorageKey kTestStorageKey = blink::StorageKey::CreateFromStringForTesting("http://test/"); + auto bucket_locator = storage::BucketLocator(); + bucket_locator.storage_key = kTestStorageKey; auto* factory = static_cast<IndexedDBFactoryImpl*>(context()->GetIDBFactory()); @@ -335,7 +341,7 @@ callbacks, db_callbacks, transaction_id, IndexedDBDatabaseMetadata::DEFAULT_VERSION, std::move(create_transaction_callback1)); - factory->Open(u"db", std::move(connection), kTestStorageKey, + factory->Open(u"db", std::move(connection), bucket_locator, context()->data_path()); RunPostedTasks();
diff --git a/content/browser/indexed_db/mock_indexed_db_callbacks.cc b/content/browser/indexed_db/mock_indexed_db_callbacks.cc index 73eb838..242b6d35 100644 --- a/content/browser/indexed_db/mock_indexed_db_callbacks.cc +++ b/content/browser/indexed_db/mock_indexed_db_callbacks.cc
@@ -7,8 +7,8 @@ #include <memory> #include <utility> +#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/common/storage_key/storage_key.h" using blink::IndexedDBDatabaseMetadata; using blink::IndexedDBKey; @@ -17,12 +17,12 @@ MockIndexedDBCallbacks::MockIndexedDBCallbacks() : IndexedDBCallbacks(nullptr, - blink::StorageKey(), + storage::BucketLocator(), mojo::NullAssociatedRemote(), base::SequencedTaskRunnerHandle::Get()) {} MockIndexedDBCallbacks::MockIndexedDBCallbacks(bool expect_connection) : IndexedDBCallbacks(nullptr, - blink::StorageKey(), + storage::BucketLocator(), mojo::NullAssociatedRemote(), base::SequencedTaskRunnerHandle::Get()), expect_connection_(expect_connection) {}
diff --git a/content/browser/indexed_db/mock_indexed_db_factory.h b/content/browser/indexed_db/mock_indexed_db_factory.h index 0f0b3699..f744c893 100644 --- a/content/browser/indexed_db/mock_indexed_db_factory.h +++ b/content/browser/indexed_db/mock_indexed_db_factory.h
@@ -29,7 +29,7 @@ const base::FilePath& data_directory)); MOCK_METHOD3(GetDatabaseInfo, void(scoped_refptr<IndexedDBCallbacks> callbacks, - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, const base::FilePath& data_directory)); MOCK_METHOD4(OpenProxy, void(const std::u16string& name, @@ -39,14 +39,15 @@ // Googlemock can't deal with move-only types, so *Proxy() is a workaround. void Open(const std::u16string& name, std::unique_ptr<IndexedDBPendingConnection> connection, - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, const base::FilePath& data_directory) override { - OpenProxy(name, connection.get(), storage_key, data_directory); + OpenProxy(name, connection.get(), bucket_locator.storage_key, + data_directory); } MOCK_METHOD5(DeleteDatabase, void(const std::u16string& name, scoped_refptr<IndexedDBCallbacks> callbacks, - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, const base::FilePath& data_directory, bool force_close)); MOCK_METHOD2(AbortTransactionsAndCompactDatabaseProxy,
diff --git a/content/browser/indexed_db/transaction_impl.cc b/content/browser/indexed_db/transaction_impl.cc index 34a2d84e7..1677fee 100644 --- a/content/browser/indexed_db/transaction_impl.cc +++ b/content/browser/indexed_db/transaction_impl.cc
@@ -23,13 +23,13 @@ TransactionImpl::TransactionImpl( base::WeakPtr<IndexedDBTransaction> transaction, - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host, scoped_refptr<base::SequencedTaskRunner> idb_runner) : dispatcher_host_(dispatcher_host), indexed_db_context_(dispatcher_host->context()), transaction_(std::move(transaction)), - storage_key_(storage_key), + bucket_locator_(bucket_locator), idb_runner_(std::move(idb_runner)) { DCHECK(idb_runner_->RunsTasksInCurrentSequence()); DCHECK(dispatcher_host_); @@ -242,8 +242,9 @@ return; } + // TODO(crbug.com/1319644): Propagate BucketLocator to GetBucketUsageAndQuota. indexed_db_context_->quota_manager_proxy()->GetUsageAndQuota( - storage_key_, blink::mojom::StorageType::kTemporary, + bucket_locator_.storage_key, blink::mojom::StorageType::kTemporary, indexed_db_context_->IDBTaskRunner(), base::BindOnce(&TransactionImpl::OnGotUsageAndQuotaForCommit, weak_factory_.GetWeakPtr()));
diff --git a/content/browser/indexed_db/transaction_impl.h b/content/browser/indexed_db/transaction_impl.h index 5495543..d9f4d77 100644 --- a/content/browser/indexed_db/transaction_impl.h +++ b/content/browser/indexed_db/transaction_impl.h
@@ -11,8 +11,8 @@ #include "base/memory/ref_counted.h" #include "base/sequence_checker.h" +#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "content/browser/indexed_db/indexed_db_external_object.h" -#include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h" #include "third_party/blink/public/mojom/quota/quota_types.mojom.h" @@ -29,7 +29,7 @@ public: explicit TransactionImpl( base::WeakPtr<IndexedDBTransaction> transaction, - const blink::StorageKey& storage_key, + const storage::BucketLocator& bucket_locator, base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host, scoped_refptr<base::SequencedTaskRunner> idb_runner); @@ -66,7 +66,7 @@ base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host_; scoped_refptr<IndexedDBContextImpl> indexed_db_context_; base::WeakPtr<IndexedDBTransaction> transaction_; - const blink::StorageKey storage_key_; + const storage::BucketLocator bucket_locator_; scoped_refptr<base::SequencedTaskRunner> idb_runner_; SEQUENCE_CHECKER(sequence_checker_);
diff --git a/content/browser/interest_group/ad_auction_service_impl.cc b/content/browser/interest_group/ad_auction_service_impl.cc index 2d2dcf78..ff954c7 100644 --- a/content/browser/interest_group/ad_auction_service_impl.cc +++ b/content/browser/interest_group/ad_auction_service_impl.cc
@@ -463,11 +463,11 @@ render_frame_host()->GetSiteInstance()->GetBrowserContext(), render_frame_host(), render_frame_host()->GetProcess()->GetID(), ContentBrowserClient::URLLoaderFactoryType::kDocumentSubResource, - url::Origin(), absl::nullopt /* navigation_id */, + url::Origin(), /*navigation_id=*/absl::nullopt, ukm::SourceIdObj::FromInt64(render_frame_host()->GetPageUkmSourceId()), - &factory_receiver, nullptr /* header_client */, - nullptr /* bypass_redirect_checks */, nullptr /* disable_secure_dns */, - nullptr /* factory_override */); + &factory_receiver, /*header_client=*/nullptr, + /*bypass_redirect_checks=*/nullptr, /*disable_secure_dns=*/nullptr, + /*factory_override=*/nullptr); render_frame_host() ->GetStoragePartition()
diff --git a/content/browser/interest_group/auction_process_manager_unittest.cc b/content/browser/interest_group/auction_process_manager_unittest.cc index 2c1ff6b..3112d6f9 100644 --- a/content/browser/interest_group/auction_process_manager_unittest.cc +++ b/content/browser/interest_group/auction_process_manager_unittest.cc
@@ -266,64 +266,64 @@ }; const Operation kOperationList[] = { - {Operation::Op::kRequestHandles, GetMaxProcesses() /* num_handles*/, - absl::nullopt /* index */, - GetMaxProcesses() /* expected_total_handles */}, + {Operation::Op::kRequestHandles, /*num_handles=*/GetMaxProcesses(), + /*index=*/absl::nullopt, + /*expected_total_handles=*/GetMaxProcesses()}, // Check destroying intermediate, last, and first handle when there are no // queued requests. Keep exactly GetMaxProcesses() requests, to ensure // there are in fact first, last, and intermediate requests (as long as // GetMaxProcesses() is at least 3). - {Operation::Op::kDestroyHandle, absl::nullopt /* num_handles*/, - 1u /* index */, GetMaxProcesses() - 1 /* expected_total_handles */}, - {Operation::Op::kRequestHandles, 1 /* num_handles*/, - absl::nullopt /* index */, - GetMaxProcesses() /* expected_total_handles */}, - {Operation::Op::kDestroyHandle, absl::nullopt /* num_handles*/, - 0u /* index */, GetMaxProcesses() - 1 /* expected_total_handles */}, - {Operation::Op::kRequestHandles, 1 /* num_handles*/, - absl::nullopt /* index */, - GetMaxProcesses() /* expected_total_handles */}, - {Operation::Op::kDestroyHandle, absl::nullopt /* num_handles*/, - GetMaxProcesses() - 1 /* index */, - GetMaxProcesses() - 1 /* expected_total_handles */}, - {Operation::Op::kRequestHandles, 1 /* num_handles*/, - absl::nullopt /* index */, - GetMaxProcesses() /* expected_total_handles */}, + {Operation::Op::kDestroyHandle, /*num_handles=*/absl::nullopt, + /*index=*/1u, /*expected_total_handles=*/GetMaxProcesses() - 1}, + {Operation::Op::kRequestHandles, /*num_handles=*/1, + /*index=*/absl::nullopt, + /*expected_total_handles=*/GetMaxProcesses()}, + {Operation::Op::kDestroyHandle, /*num_handles=*/absl::nullopt, + /*index=*/0u, /*expected_total_handles=*/GetMaxProcesses() - 1}, + {Operation::Op::kRequestHandles, /*num_handles=*/1, + /*index=*/absl::nullopt, + /*expected_total_handles=*/GetMaxProcesses()}, + {Operation::Op::kDestroyHandle, /*num_handles=*/absl::nullopt, + /*index=*/GetMaxProcesses() - 1, + /*expected_total_handles=*/GetMaxProcesses() - 1}, + {Operation::Op::kRequestHandles, /*num_handles=*/1, + /*index=*/absl::nullopt, + /*expected_total_handles=*/GetMaxProcesses()}, // Queue 3 more requests, but delete the last and first of them, to test // deleting queued requests. - {Operation::Op::kRequestHandles, 3 /* num_handles*/, - absl::nullopt /* index */, - GetMaxProcesses() + 3 /* expected_total_handles */}, - {Operation::Op::kDestroyHandle, absl::nullopt /* num_handles*/, - GetMaxProcesses() /* index */, - GetMaxProcesses() + 2 /* expected_total_handles */}, - {Operation::Op::kDestroyHandle, absl::nullopt /* num_handles*/, - GetMaxProcesses() + 1 /* index */, - GetMaxProcesses() + 1 /* expected_total_handles */}, + {Operation::Op::kRequestHandles, /*num_handles=*/3, + /*index=*/absl::nullopt, + /*expected_total_handles=*/GetMaxProcesses() + 3}, + {Operation::Op::kDestroyHandle, /*num_handles=*/absl::nullopt, + /*index=*/GetMaxProcesses(), + /*expected_total_handles=*/GetMaxProcesses() + 2}, + {Operation::Op::kDestroyHandle, /*num_handles=*/absl::nullopt, + /*index=*/GetMaxProcesses() + 1, + /*expected_total_handles=*/GetMaxProcesses() + 1}, // Request 4 more processes. - {Operation::Op::kRequestHandles, 4 /* num_handles*/, - absl::nullopt /* index */, - GetMaxProcesses() + 5 /* expected_total_handles */}, + {Operation::Op::kRequestHandles, /*num_handles=*/4, + /*index=*/absl::nullopt, + /*expected_total_handles=*/GetMaxProcesses() + 5}, // Destroy the first handle and the first pending in the queue immediately // afterwards. The next pending request should get a process. {Operation::Op::kDestroyHandleAndNextInQueue, - absl::nullopt /* num_handles*/, 0u /* index */, - GetMaxProcesses() + 3 /* expected_total_handles */}, + /*num_handles=*/absl::nullopt, /*index=*/0u, + /*expected_total_handles=*/GetMaxProcesses() + 3}, // Destroy three more requests that have been asssigned processes, being // sure to destroy the first, last, and some request request with nether, // amongst requests with assigned processes. - {Operation::Op::kDestroyHandle, absl::nullopt /* num_handles*/, - GetMaxProcesses() - 1 /* index */, - GetMaxProcesses() + 2 /* expected_total_handles */}, - {Operation::Op::kDestroyHandle, absl::nullopt /* num_handles*/, - 0u /* index */, GetMaxProcesses() + 1 /* expected_total_handles */}, - {Operation::Op::kDestroyHandle, absl::nullopt /* num_handles*/, - 1u /* index */, GetMaxProcesses() /* expected_total_handles */}, + {Operation::Op::kDestroyHandle, /*num_handles=*/absl::nullopt, + /*index=*/GetMaxProcesses() - 1, + /*expected_total_handles=*/GetMaxProcesses() + 2}, + {Operation::Op::kDestroyHandle, /*num_handles=*/absl::nullopt, + /*index=*/0u, /*expected_total_handles=*/GetMaxProcesses() + 1}, + {Operation::Op::kDestroyHandle, /*num_handles=*/absl::nullopt, + /*index=*/1u, /*expected_total_handles=*/GetMaxProcesses()}, }; struct ProcessHandleData {
diff --git a/content/browser/interest_group/auction_url_loader_factory_proxy_unittest.cc b/content/browser/interest_group/auction_url_loader_factory_proxy_unittest.cc index 257344a..a495a72 100644 --- a/content/browser/interest_group/auction_url_loader_factory_proxy_unittest.cc +++ b/content/browser/interest_group/auction_url_loader_factory_proxy_unittest.cc
@@ -109,7 +109,7 @@ int options = network::mojom::kURLLoadOptionSendSSLInfoWithResponse | network::mojom::kURLLoadOptionSniffMimeType; remote_url_loader_factory_->CreateLoaderAndStart( - receiver.InitWithNewPipeAndPassReceiver(), 0 /* request_id_ */, options, + receiver.InitWithNewPipeAndPassReceiver(), /*request_id=*/0, options, request, client.InitWithNewPipeAndPassRemote(), net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
diff --git a/content/browser/interest_group/auction_worklet_manager_unittest.cc b/content/browser/interest_group/auction_worklet_manager_unittest.cc index ff959dc0..450d29a 100644 --- a/content/browser/interest_group/auction_worklet_manager_unittest.cc +++ b/content/browser/interest_group/auction_worklet_manager_unittest.cc
@@ -1489,7 +1489,7 @@ mojo::PendingRemote<network::mojom::URLLoader> receiver; mojo::PendingReceiver<network::mojom::URLLoaderClient> client; bidder_worklet->url_loader_factory()->CreateLoaderAndStart( - receiver.InitWithNewPipeAndPassReceiver(), 0 /*request_id=*/, + receiver.InitWithNewPipeAndPassReceiver(), /*request_id=*/0, /*options=*/0, request, client.InitWithNewPipeAndPassRemote(), net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); bidder_worklet->url_loader_factory().FlushForTesting(); @@ -1550,7 +1550,7 @@ mojo::PendingRemote<network::mojom::URLLoader> receiver; mojo::PendingReceiver<network::mojom::URLLoaderClient> client; seller_worklet->url_loader_factory()->CreateLoaderAndStart( - receiver.InitWithNewPipeAndPassReceiver(), 0 /*request_id=*/, + receiver.InitWithNewPipeAndPassReceiver(), /*request_id=*/0, /*options=*/0, request, client.InitWithNewPipeAndPassRemote(), net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); seller_worklet->url_loader_factory().FlushForTesting();
diff --git a/content/browser/renderer_host/cookie_utils.cc b/content/browser/renderer_host/cookie_utils.cc index 437c0d2..21d05ae 100644 --- a/content/browser/renderer_host/cookie_utils.cc +++ b/content/browser/renderer_host/cookie_utils.cc
@@ -120,6 +120,10 @@ bool partitioned_cookies_exist = false; + bool cookie_has_not_been_refreshed_in_201_to_300_days = false; + bool cookie_has_not_been_refreshed_in_301_to_350_days = false; + bool cookie_has_not_been_refreshed_in_351_to_400_days = false; + for (const network::mojom::CookieOrLineWithAccessResultPtr& cookie : cookie_details->cookie_list) { if (ShouldReportDevToolsIssueForStatus(cookie->access_result.status)) { @@ -217,6 +221,27 @@ cookie->access_result.status, cookie_details->url); } + + // In order to anticipate the potential effects of the expiry limit in + // rfc6265bis, we need to check how long it's been since the cookie was + // refreshed (if LastUpdateDate is populated). These three buckets were + // picked so we could engage sites with some granularity around urgency. + // We ignore the space under 200 days as these cookies are not at risk + // of expiring and we ignore the space over 400 days as these cookies + // have already expired. Metrics will take 200 days from M103 to populate. + base::Time last_update_date = + cookie->cookie_or_line->is_cookie() + ? cookie->cookie_or_line->get_cookie().LastUpdateDate() + : base::Time(); + if (!last_update_date.is_null()) { + int days_since_refresh = (base::Time::Now() - last_update_date).InDays(); + cookie_has_not_been_refreshed_in_201_to_300_days |= + days_since_refresh > 200 && days_since_refresh <= 300; + cookie_has_not_been_refreshed_in_301_to_350_days |= + days_since_refresh > 300 && days_since_refresh <= 350; + cookie_has_not_been_refreshed_in_351_to_400_days |= + days_since_refresh > 350 && days_since_refresh <= 400; + } } if (samesite_treated_as_lax_cookies) { @@ -289,6 +314,24 @@ GetContentClient()->browser()->LogWebFeatureForCurrentPage( rfh, blink::mojom::WebFeature::kPartitionedCookies); } + + if (cookie_has_not_been_refreshed_in_201_to_300_days) { + GetContentClient()->browser()->LogWebFeatureForCurrentPage( + rfh, + blink::mojom::WebFeature::kCookieHasNotBeenRefreshedIn201To300Days); + } + + if (cookie_has_not_been_refreshed_in_301_to_350_days) { + GetContentClient()->browser()->LogWebFeatureForCurrentPage( + rfh, + blink::mojom::WebFeature::kCookieHasNotBeenRefreshedIn301To350Days); + } + + if (cookie_has_not_been_refreshed_in_351_to_400_days) { + GetContentClient()->browser()->LogWebFeatureForCurrentPage( + rfh, + blink::mojom::WebFeature::kCookieHasNotBeenRefreshedIn351To400Days); + } } } // namespace content
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index 3337abe..158a585 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -12126,8 +12126,20 @@ // Ensure that when a process is about to be destroyed after the last active // frame in it goes away, an attempt to reuse a proxy in that process doesn't // result in a crash. See https://crbug.com/794625. -IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, - RenderFrameProxyNotRecreatedDuringProcessShutdown) { +// TODO(https://crbug.com/754084): This is flaky on Fuchsia because the +// MessagePort is not cleared on the other side, resulting in Zircon killing the +// process. See the comment referencing the same bug in +// //mojo/core/channel_fuchsia.cc +#if BUILDFLAG(IS_FUCHSIA) +#define MAYBE_RenderFrameProxyNotRecreatedDuringProcessShutdown \ + RenderFrameProxyNotRecreatedDuringProcessShutdown +#else +#define MAYBE_RenderFrameProxyNotRecreatedDuringProcessShutdown \ + RenderFrameProxyNotRecreatedDuringProcessShutdown +#endif +IN_PROC_BROWSER_TEST_P( + SitePerProcessBrowserTest, + MAYBE_RenderFrameProxyNotRecreatedDuringProcessShutdown) { GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html")); EXPECT_TRUE(NavigateToURL(shell(), main_url)); FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
diff --git a/content/public/browser/render_frame_host.h b/content/public/browser/render_frame_host.h index fd48ddc9..2d336a5 100644 --- a/content/public/browser/render_frame_host.h +++ b/content/public/browser/render_frame_host.h
@@ -167,7 +167,7 @@ const base::android::JavaRef<jobject>& jrender_frame_host_android); #endif - ~RenderFrameHost() override {} + ~RenderFrameHost() override = default; // Returns the route id for this frame. virtual int GetRoutingID() const = 0;
diff --git a/content/services/auction_worklet/auction_downloader.cc b/content/services/auction_worklet/auction_downloader.cc index f020d80..ad51152 100644 --- a/content/services/auction_worklet/auction_downloader.cc +++ b/content/services/auction_worklet/auction_downloader.cc
@@ -160,20 +160,20 @@ net::ErrorToString(simple_url_loader->NetError()).c_str()); } std::move(auction_downloader_callback_) - .Run(nullptr /* body */, nullptr /* headers */, error_msg); + .Run(/*body=*/nullptr, /*headers=*/nullptr, error_msg); } else if (!simple_url_loader->ResponseInfo()->headers || !simple_url_loader->ResponseInfo()->headers->GetNormalizedHeader( "X-Allow-FLEDGE", &allow_fledge) || !base::EqualsCaseInsensitiveASCII(allow_fledge, "true")) { std::move(auction_downloader_callback_) - .Run(nullptr /* body */, nullptr /* headers */, + .Run(/*body=*/nullptr, /*headers=*/nullptr, base::StringPrintf( "Rejecting load of %s due to lack of X-Allow-FLEDGE: true.", source_url_.spec().c_str())); } else if (!MimeTypeIsConsistent(mime_type_, simple_url_loader->ResponseInfo())) { std::move(auction_downloader_callback_) - .Run(nullptr /* body */, nullptr /* headers */, + .Run(/*body=*/nullptr, /*headers=*/nullptr, base::StringPrintf( "Rejecting load of %s due to unexpected MIME type.", source_url_.spec().c_str())); @@ -181,7 +181,7 @@ !IsAllowedCharset(simple_url_loader->ResponseInfo()->charset, *body)) { std::move(auction_downloader_callback_) - .Run(nullptr /* body */, nullptr /* headers */, + .Run(/*body=*/nullptr, /*headers=*/nullptr, base::StringPrintf( "Rejecting load of %s due to unexpected charset.", source_url_.spec().c_str())); @@ -190,7 +190,7 @@ std::move(auction_downloader_callback_) .Run(std::move(body), std::move(simple_url_loader->ResponseInfo()->headers), - absl::nullopt /* error_msg */); + /*error_msg=*/absl::nullopt); } } @@ -204,7 +204,7 @@ simple_url_loader_.reset(); std::move(auction_downloader_callback_) - .Run(nullptr /* body */, nullptr /* headers */, + .Run(/*body=*/nullptr, /*headers=*/nullptr, base::StringPrintf("Unexpected redirect on %s.", source_url_.spec().c_str())); }
diff --git a/content/services/auction_worklet/auction_downloader_unittest.cc b/content/services/auction_worklet/auction_downloader_unittest.cc index abf38f9..ae6e26e4 100644 --- a/content/services/auction_worklet/auction_downloader_unittest.cc +++ b/content/services/auction_worklet/auction_downloader_unittest.cc
@@ -88,7 +88,7 @@ TEST_F(AuctionDownloaderTest, NetworkError) { network::URLLoaderCompletionStatus status; status.error_code = net::ERR_FAILED; - url_loader_factory_.AddResponse(url_, nullptr /* head */, kAsciiResponseBody, + url_loader_factory_.AddResponse(url_, /*head=*/nullptr, kAsciiResponseBody, status); EXPECT_FALSE(RunRequest()); EXPECT_EQ(
diff --git a/content/services/auction_worklet/auction_v8_helper.cc b/content/services/auction_worklet/auction_v8_helper.cc index 634248e8..2a22c44 100644 --- a/content/services/auction_worklet/auction_v8_helper.cc +++ b/content/services/auction_worklet/auction_v8_helper.cc
@@ -297,7 +297,7 @@ v8::Handle<v8::ObjectTemplate> global_template) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); v8::Local<v8::Context> context = - v8::Context::New(isolate(), nullptr /* extensions */, global_template); + v8::Context::New(isolate(), /*extensions=*/nullptr, global_template); auto result = context->Global()->Delete(context, CreateStringFromLiteral("Date")); DCHECK(!result.IsNothing());
diff --git a/content/services/auction_worklet/bidder_worklet.cc b/content/services/auction_worklet/bidder_worklet.cc index 03a75b9e..722fdf1 100644 --- a/content/services/auction_worklet/bidder_worklet.cc +++ b/content/services/auction_worklet/bidder_worklet.cc
@@ -352,8 +352,8 @@ &args) || !v8_helper_->AppendJsonValue(context, seller_signals_json, &args)) { PostReportWinCallbackToUserThread( - std::move(callback), absl::nullopt /* report_url */, - /*ad_beacon_map=*/{}, std::vector<std::string>() /* errors */); + std::move(callback), /*report_url=*/absl::nullopt, + /*ad_beacon_map=*/{}, /*errors=*/std::vector<std::string>()); return; } @@ -383,8 +383,8 @@ !browser_signals_dict.Set("dataVersion", bidding_signals_data_version.value()))) { PostReportWinCallbackToUserThread( - std::move(callback), absl::nullopt /* report_url */, - /*ad_beacon_map=*/{}, std::vector<std::string>() /* errors */); + std::move(callback), /*report_url=*/absl::nullopt, + /*ad_beacon_map=*/{}, /*errors=*/std::vector<std::string>()); return; } args.push_back(browser_signals); @@ -400,7 +400,7 @@ errors_out) .IsEmpty()) { PostReportWinCallbackToUserThread( - std::move(callback), absl::nullopt /* report_url */, + std::move(callback), /*report_url=*/absl::nullopt, /*ad_beacon_map=*/{}, std::move(errors_out)); return; }
diff --git a/content/services/auction_worklet/bidder_worklet_unittest.cc b/content/services/auction_worklet/bidder_worklet_unittest.cc index 5643687..69a188254 100644 --- a/content/services/auction_worklet/bidder_worklet_unittest.cc +++ b/content/services/auction_worklet/bidder_worklet_unittest.cc
@@ -140,12 +140,12 @@ interest_group_ads_.clear(); interest_group_ads_.emplace_back(blink::InterestGroup::Ad( - GURL("https://response.test/"), absl::nullopt /* metadata */)); + GURL("https://response.test/"), /*metadata=*/absl::nullopt)); interest_group_ad_components_.reset(); interest_group_ad_components_.emplace(); interest_group_ad_components_->emplace_back(blink::InterestGroup::Ad( - GURL("https://ad_component.test/"), absl::nullopt /* metadata */)); + GURL("https://ad_component.test/"), /*metadata=*/absl::nullopt)); daily_update_url_.reset(); @@ -683,7 +683,7 @@ // Bids <= 0. RunGenerateBidWithReturnValueExpectingResult( R"({ad: ["ad"], bid:0, render:"https://response.test/"})", - mojom::BidderWorkletBidPtr() /* expected_bid */); + /*expected_bid=*/mojom::BidderWorkletBidPtr()); RunGenerateBidWithReturnValueExpectingResult( R"({ad: ["ad"], bid:-10, render:"https://response.test/"})", /*expected_bid=*/mojom::BidderWorkletBidPtr(), @@ -2115,7 +2115,7 @@ // Adding an ad with a corresponding `renderUrl` should result in success. // Also check the `interestGroup.ads` field passed to Javascript. interest_group_ads_.emplace_back(blink::InterestGroup::Ad( - GURL("https://response2.test/"), R"(["metadata"])" /* metadata */)); + GURL("https://response2.test/"), /*metadata=*/R"(["metadata"])")); RunGenerateBidWithReturnValueExpectingResult( R"({ad: interestGroup.ads, bid:1, render:"https://response2.test/"})", mojom::BidderWorkletBid::New( @@ -3307,10 +3307,10 @@ AddJavascriptResponse(&url_loader_factory_, GURL(kUrl2), bid_script); auto worklet1 = - CreateWorklet(GURL(kUrl1), true /* pause_for_debugger_on_start */); + CreateWorklet(GURL(kUrl1), /*pause_for_debugger_on_start=*/true); GenerateBid(worklet1.get()); auto worklet2 = - CreateWorklet(GURL(kUrl2), true /* pause_for_debugger_on_start */); + CreateWorklet(GURL(kUrl2), /*pause_for_debugger_on_start=*/true); GenerateBid(worklet2.get()); mojo::AssociatedRemote<blink::mojom::DevToolsAgent> agent1, agent2; @@ -3318,9 +3318,9 @@ worklet2->ConnectDevToolsAgent(agent2.BindNewEndpointAndPassReceiver()); TestDevToolsAgentClient debug1(std::move(agent1), "123", - true /* use_binary_protocol */); + /*use_binary_protocol=*/true); TestDevToolsAgentClient debug2(std::move(agent2), "456", - true /* use_binary_protocol */); + /*use_binary_protocol=*/true); debug1.RunCommandAndWaitForResult( TestDevToolsAgentClient::Channel::kMain, 1, "Runtime.enable", @@ -3445,14 +3445,14 @@ CreateReportWinScript(R"(sendReportTo("https://foo.test"))")); auto worklet = - CreateWorklet(GURL(kUrl), true /* pause_for_debugger_on_start */); + CreateWorklet(GURL(kUrl), /*pause_for_debugger_on_start=*/true); GenerateBid(worklet.get()); mojo::AssociatedRemote<blink::mojom::DevToolsAgent> agent; worklet->ConnectDevToolsAgent(agent.BindNewEndpointAndPassReceiver()); TestDevToolsAgentClient debug(std::move(agent), "123", - true /* use_binary_protocol */); + /*use_binary_protocol=*/true); debug.RunCommandAndWaitForResult( TestDevToolsAgentClient::Channel::kMain, 1, "Runtime.enable",
diff --git a/content/services/auction_worklet/seller_worklet_unittest.cc b/content/services/auction_worklet/seller_worklet_unittest.cc index deaeb53..14b1834a 100644 --- a/content/services/auction_worklet/seller_worklet_unittest.cc +++ b/content/services/auction_worklet/seller_worklet_unittest.cc
@@ -1599,27 +1599,27 @@ // Tests parsing of return values. TEST_F(SellerWorkletTest, ReportResult) { RunReportResultCreatedScriptExpectingResult( - "1", std::string() /* extra_code */, - "1" /* expected_signals_for_winner */, - absl::nullopt /* expected_report_url */); + "1", /*extra_code=*/std::string(), + /*expected_signals_for_winner=*/"1", + /*expected_report_url=*/absl::nullopt); RunReportResultCreatedScriptExpectingResult( - R"(" 1 ")", std::string() /* extra_code */, - R"(" 1 ")" /* expected_signals_for_winner */, - absl::nullopt /* expected_report_url */); + R"(" 1 ")", /*extra_code=*/std::string(), + /*expected_signals_for_winner=*/R"(" 1 ")", + /*expected_report_url=*/absl::nullopt); RunReportResultCreatedScriptExpectingResult( - "[ null ]", std::string() /* extra_code */, "[null]", - absl::nullopt /* expected_report_url */); + "[ null ]", /*extra_code=*/std::string(), "[null]", + /*expected_report_url=*/absl::nullopt); // No return value. RunReportResultCreatedScriptExpectingResult( - "", std::string() /* extra_code */, "null", - absl::nullopt /* expected_report_url */); + "", /*extra_code=*/std::string(), "null", + /*expected_report_url=*/absl::nullopt); // Throw exception. RunReportResultCreatedScriptExpectingResult( - "shrimp", std::string() /* extra_code */, - absl::nullopt /* expected_signals_for_winner */, - absl::nullopt /* expected_render_url */, + "shrimp", /*extra_code=*/std::string(), + /*expected_signals_for_winner=*/absl::nullopt, + /*expected_report_url=*/absl::nullopt, /*expected_ad_beacon_map=*/{}, {"https://url.test/:10 Uncaught ReferenceError: " "shrimp is not defined."}); @@ -1629,23 +1629,23 @@ TEST_F(SellerWorkletTest, ReportResultSendReportTo) { RunReportResultCreatedScriptExpectingResult( "1", R"(sendReportTo("https://foo.test"))", - "1" /* expected_signals_for_winner */, GURL("https://foo.test/")); + /*expected_signals_for_winner=*/"1", GURL("https://foo.test/")); RunReportResultCreatedScriptExpectingResult( "1", R"(sendReportTo("https://foo.test/bar"))", - "1" /* expected_signals_for_winner */, GURL("https://foo.test/bar")); + /*expected_signals_for_winner=*/"1", GURL("https://foo.test/bar")); // Disallowed schemes. RunReportResultCreatedScriptExpectingResult( "1", R"(sendReportTo("http://foo.test/"))", - absl::nullopt /* expected_signals_for_winner */, - absl::nullopt /* expected_render_url */, + /*expected_signals_for_winner=*/absl::nullopt, + /*expected_report_url=*/absl::nullopt, /*expected_ad_beacon_map=*/{}, {"https://url.test/:9 Uncaught TypeError: " "sendReportTo must be passed a valid HTTPS url."}); RunReportResultCreatedScriptExpectingResult( "1", R"(sendReportTo("file:///foo/"))", - absl::nullopt /* expected_signals_for_winner */, - absl::nullopt /* expected_render_url */, + /*expected_signals_for_winner=*/absl::nullopt, + /*expected_report_url=*/absl::nullopt, /*expected_ad_beacon_map=*/{}, {"https://url.test/:9 Uncaught TypeError: " "sendReportTo must be passed a valid HTTPS url."}); @@ -1654,8 +1654,8 @@ RunReportResultCreatedScriptExpectingResult( "1", R"(sendReportTo("https://foo.test/"); sendReportTo("https://foo.test/"))", - absl::nullopt /* expected_signals_for_winner */, - absl::nullopt /* expected_render_url */, + /*expected_signals_for_winner=*/absl::nullopt, + /*expected_report_url=*/absl::nullopt, /*expected_ad_beacon_map=*/{}, {"https://url.test/:9 Uncaught TypeError: " "sendReportTo may be called at most once."}); @@ -1666,27 +1666,28 @@ R"(try { sendReportTo("https://foo.test/"); sendReportTo("https://foo.test/")} catch(e) {})", - "1" /* expected_render_url */, absl::nullopt /* expected_report_url */); + /*expected_signals_for_winner=*/"1", + /*expected_report_url=*/absl::nullopt); // Not a URL. RunReportResultCreatedScriptExpectingResult( "1", R"(sendReportTo("France"))", - absl::nullopt /* expected_signals_for_winner */, - absl::nullopt /* expected_render_url */, + /*expected_signals_for_winner=*/absl::nullopt, + /*expected_report_url=*/absl::nullopt, /*expected_ad_beacon_map=*/{}, {"https://url.test/:9 Uncaught TypeError: " "sendReportTo must be passed a valid HTTPS url."}); RunReportResultCreatedScriptExpectingResult( "1", R"(sendReportTo(null))", - absl::nullopt /* expected_signals_for_winner */, - absl::nullopt /* expected_render_url */, + /*expected_signals_for_winner=*/absl::nullopt, + /*expected_report_url=*/absl::nullopt, /*expected_ad_beacon_map=*/{}, {"https://url.test/:9 Uncaught TypeError: " "sendReportTo requires 1 string parameter."}); RunReportResultCreatedScriptExpectingResult( "1", R"(sendReportTo([5]))", - absl::nullopt /* expected_signals_for_winner */, - absl::nullopt /* expected_render_url */, + /*expected_signals_for_winner=*/absl::nullopt, + /*expected_report_url=*/absl::nullopt, /*expected_ad_beacon_map=*/{}, {"https://url.test/:9 Uncaught TypeError: " "sendReportTo requires 1 string parameter."}); @@ -1695,8 +1696,8 @@ TEST_F(SellerWorkletTest, ReportResultDateNotAvailable) { RunReportResultCreatedScriptExpectingResult( "1", R"(sendReportTo("https://foo.test/" + Date().toString()))", - absl::nullopt /* expected_signals_for_winner */, - absl::nullopt /* expected_render_url */, + /*expected_signals_for_winner=*/absl::nullopt, + /*expected_report_url=*/absl::nullopt, /*expected_ad_beacon_map=*/{}, {"https://url.test/:9 Uncaught ReferenceError: Date is not defined."}); } @@ -1705,14 +1706,14 @@ top_window_origin_ = url::Origin::Create(GURL("https://foo.test/")); RunReportResultCreatedScriptExpectingResult( R"(browserSignals.topWindowHostname == "foo.test" ? 2 : 1)", - std::string() /* extra_code */, "2", - absl::nullopt /* expected_report_url */); + /*extra_code=*/std::string(), "2", + /*expected_report_url=*/absl::nullopt); top_window_origin_ = url::Origin::Create(GURL("https://[::1]:40000/")); RunReportResultCreatedScriptExpectingResult( R"(browserSignals.topWindowHostname == "[::1]" ? 3 : 1)", - std::string() /* extra_code */, "3", - absl::nullopt /* expected_report_url */); + /*extra_code=*/std::string(), "3", + /*expected_report_url=*/absl::nullopt); } TEST_F(SellerWorkletTest, ReportResultTopLevelSeller) { @@ -1863,15 +1864,15 @@ url::Origin::Create(GURL("https://foo.test/")); RunReportResultCreatedScriptExpectingResult( R"(browserSignals.interestGroupOwner == "https://foo.test" ? 2 : 1)", - std::string() /* extra_code */, "2", - absl::nullopt /* expected_report_url */); + /*extra_code=*/std::string(), "2", + /*expected_report_url=*/absl::nullopt); browser_signal_interest_group_owner_ = url::Origin::Create(GURL("https://[::1]:40000/")); RunReportResultCreatedScriptExpectingResult( R"(browserSignals.interestGroupOwner == "https://[::1]:40000" ? 3 : 1)", - std::string() /* extra_code */, "3", - absl::nullopt /* expected_report_url */); + /*extra_code=*/std::string(), "3", + /*expected_report_url=*/absl::nullopt); } TEST_F(SellerWorkletTest, ReportResultRenderUrl) { @@ -2028,16 +2029,16 @@ bid_ = 5; RunReportResultCreatedScriptExpectingResult( "browserSignals.bid + typeof browserSignals.bid", - std::string() /* extra_code */, R"("5number")", - absl::nullopt /* expected_report_url */); + /*extra_code=*/std::string(), R"("5number")", + /*expected_report_url=*/absl::nullopt); } TEST_F(SellerWorkletTest, ReportResultDesireability) { browser_signal_desireability_ = 10; RunReportResultCreatedScriptExpectingResult( "browserSignals.desirability + typeof browserSignals.desirability", - std::string() /* extra_code */, R"("10number")", - absl::nullopt /* expected_report_url */); + /*extra_code=*/std::string(), R"("10number")", + /*expected_report_url=*/absl::nullopt); } TEST_F(SellerWorkletTest, ReportResultHighestScoringOtherBid) { @@ -2045,8 +2046,8 @@ RunReportResultCreatedScriptExpectingResult( "browserSignals.highestScoringOtherBid + typeof " "browserSignals.highestScoringOtherBid", - std::string() /* extra_code */, R"("5number")", - absl::nullopt /* expected_report_url */); + /*extra_code=*/std::string(), R"("5number")", + /*expected_report_url=*/absl::nullopt); } TEST_F(SellerWorkletTest, ReportResultAuctionConfigParam) { @@ -2143,30 +2144,30 @@ // decision logic URL. decision_logic_url_ = GURL("https://example.com/auction.js"); RunReportResultCreatedScriptExpectingResult( - "auctionConfig", std::string() /* extra_code */, + "auctionConfig", /*extra_code=*/std::string(), R"({"seller":"https://example.com",)" R"("decisionLogicUrl":"https://example.com/auction.js"})", - absl::nullopt /* expected_report_url */); + /*expected_report_url=*/absl::nullopt); base::flat_map<url::Origin, base::TimeDelta> per_buyer_timeouts; auction_ad_config_non_shared_params_->per_buyer_timeouts = std::move(per_buyer_timeouts); RunReportResultCreatedScriptExpectingResult( - "auctionConfig", std::string() /* extra_code */, + "auctionConfig", /*extra_code=*/std::string(), R"({"seller":"https://example.com",)" R"("decisionLogicUrl":"https://example.com/auction.js",)" R"("perBuyerTimeouts":{}})", - absl::nullopt /* expected_report_url */); + /*expected_report_url=*/absl::nullopt); auction_ad_config_non_shared_params_->all_buyers_timeout = base::Milliseconds(150); RunReportResultCreatedScriptExpectingResult( - "auctionConfig", std::string() /* extra_code */, + "auctionConfig", /*extra_code=*/std::string(), R"({"seller":"https://example.com",)" R"("decisionLogicUrl":"https://example.com/auction.js",)" R"("perBuyerTimeouts":{"*":150}})", - absl::nullopt /* expected_report_url */); + /*expected_report_url=*/absl::nullopt); } TEST_F(SellerWorkletTest, ReportResultExperimentGroupIdParam) { @@ -2185,9 +2186,9 @@ TEST_F(SellerWorkletTest, ReportResultDataVersion) { browser_signal_data_version_ = 20; RunReportResultCreatedScriptExpectingResult( - "browserSignals.dataVersion", std::string() /* extra_code */, - "20" /* expected_signals_for_winner */, - absl::nullopt /* expected_report_url */); + "browserSignals.dataVersion", /*extra_code=*/std::string(), + /*expected_signals_for_winner=*/"20", + /*expected_report_url=*/absl::nullopt); } // Subsequent runs of the same script should not affect each other. Same is true @@ -2548,7 +2549,7 @@ CreateScoreAdScript(kScriptResult)); decision_logic_url_ = GURL(kUrl1); - auto worklet1 = CreateWorklet(true /* pause_for_debugger_on_start */); + auto worklet1 = CreateWorklet(/*pause_for_debugger_on_start=*/true); base::RunLoop run_loop1; RunScoreAdOnWorkletAsync( worklet1.get(), 100.5, {}, mojom::ComponentAuctionModifiedBidParamsPtr(), @@ -2557,7 +2558,7 @@ /*expected_debug_win_report_url=*/absl::nullopt, run_loop1.QuitClosure()); decision_logic_url_ = GURL(kUrl2); - auto worklet2 = CreateWorklet(true /* pause_for_debugger_on_start */); + auto worklet2 = CreateWorklet(/*pause_for_debugger_on_start=*/true); base::RunLoop run_loop2; RunScoreAdOnWorkletAsync(worklet2.get(), 0, {"http://example.org/second.js scoreAd() did not " @@ -2573,9 +2574,9 @@ worklet2->ConnectDevToolsAgent(agent2.BindNewEndpointAndPassReceiver()); TestDevToolsAgentClient debug1(std::move(agent1), "123", - true /* use_binary_protocol */); + /*use_binary_protocol=*/true); TestDevToolsAgentClient debug2(std::move(agent2), "456", - true /* use_binary_protocol */); + /*use_binary_protocol=*/true); debug1.RunCommandAndWaitForResult( TestDevToolsAgentClient::Channel::kMain, 1, "Runtime.enable", @@ -2699,7 +2700,7 @@ AddJavascriptResponse(&url_loader_factory_, GURL(kUrl), script_body); decision_logic_url_ = GURL(kUrl); - auto worklet = CreateWorklet(true /* pause_for_debugger_on_start */); + auto worklet = CreateWorklet(/*pause_for_debugger_on_start=*/true); base::RunLoop run_loop; RunScoreAdOnWorkletAsync( worklet.get(), 1.0, {}, mojom::ComponentAuctionModifiedBidParamsPtr(), @@ -2711,7 +2712,7 @@ worklet->ConnectDevToolsAgent(agent.BindNewEndpointAndPassReceiver()); TestDevToolsAgentClient debug(std::move(agent), "123", - true /* use_binary_protocol */); + /*use_binary_protocol=*/true); debug.RunCommandAndWaitForResult( TestDevToolsAgentClient::Channel::kMain, 1, "Runtime.enable",
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index e659c45d..6b6dd34 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -47,6 +47,8 @@ "../browser/aggregation_service/aggregation_service_test_utils.h", "../browser/attribution_reporting/attribution_insecure_random_generator.cc", "../browser/attribution_reporting/attribution_insecure_random_generator.h", + "../browser/attribution_reporting/attribution_parser_test_utils.cc", + "../browser/attribution_reporting/attribution_parser_test_utils.h", "../browser/attribution_reporting/attribution_test_utils.cc", "../browser/attribution_reporting/attribution_test_utils.h", "../browser/background_fetch/background_fetch_test_base.cc",
diff --git a/content/test/attribution_simulator_input_parser.cc b/content/test/attribution_simulator_input_parser.cc index 6cb142e..14074c1 100644 --- a/content/test/attribution_simulator_input_parser.cc +++ b/content/test/attribution_simulator_input_parser.cc
@@ -23,6 +23,7 @@ #include "content/browser/attribution_reporting/attribution_aggregatable_source.h" #include "content/browser/attribution_reporting/attribution_aggregatable_trigger.h" #include "content/browser/attribution_reporting/attribution_filter_data.h" +#include "content/browser/attribution_reporting/attribution_parser_test_utils.h" #include "content/browser/attribution_reporting/attribution_source_type.h" #include "content/browser/attribution_reporting/attribution_trigger.h" #include "content/browser/attribution_reporting/common_source_info.h" @@ -40,9 +41,6 @@ namespace { -using Context = absl::variant<base::StringPiece, size_t>; -using ContextPath = std::vector<Context>; - constexpr char kTimestampKey[] = "timestamp"; constexpr char kAggregatableTriggerDataKey[] = @@ -50,52 +48,11 @@ constexpr char kAggregatableValuesKey[] = "Attribution-Reporting-Register-Aggregatable-Values"; -class ScopedContext { - public: - ScopedContext(ContextPath& path, Context context) : path_(path) { - path_.push_back(context); - } - - ~ScopedContext() { path_.pop_back(); } - - ScopedContext(const ScopedContext&) = delete; - ScopedContext(ScopedContext&&) = delete; - - ScopedContext& operator=(const ScopedContext&) = delete; - ScopedContext& operator=(ScopedContext&&) = delete; - - private: - ContextPath& path_; -}; - -// Writes a newline on destruction. -class ErrorWriter { - public: - explicit ErrorWriter(std::ostream& stream) : stream_(stream) {} - - ~ErrorWriter() { stream_ << std::endl; } - - ErrorWriter(const ErrorWriter&) = delete; - ErrorWriter(ErrorWriter&&) = default; - - ErrorWriter& operator=(const ErrorWriter&) = delete; - ErrorWriter& operator=(ErrorWriter&&) = delete; - - std::ostream& operator*() { return stream_; } - - void operator()(base::StringPiece key) { stream_ << "[\"" << key << "\"]"; } - - void operator()(size_t index) { stream_ << '[' << index << ']'; } - - private: - std::ostream& stream_; -}; - class AttributionSimulatorInputParser { public: AttributionSimulatorInputParser(base::Time offset_time, std::ostream& error_stream) - : offset_time_(offset_time), error_stream_(error_stream) {} + : offset_time_(offset_time), error_manager_(error_stream) {} ~AttributionSimulatorInputParser() = default; @@ -140,7 +97,7 @@ base::Unretained(this))); } - if (has_error_) + if (has_error()) return absl::nullopt; return std::move(events_); @@ -148,31 +105,21 @@ private: const base::Time offset_time_; - std::ostream& error_stream_; + AttributionParserErrorManager error_manager_; - ContextPath context_path_; - bool has_error_ = false; std::vector<AttributionSimulationEventAndValue> events_; - ScopedContext PushContext(Context context) { - return ScopedContext(context_path_, context); + [[nodiscard]] AttributionParserErrorManager::ScopedContext PushContext( + AttributionParserErrorManager::Context context) { + return error_manager_.PushContext(context); } - ErrorWriter Error() { - has_error_ = true; - - if (context_path_.empty()) - error_stream_ << "input root"; - - ErrorWriter writer(error_stream_); - for (Context context : context_path_) { - absl::visit(writer, context); - } - - error_stream_ << ": "; - return writer; + AttributionParserErrorManager::ErrorWriter Error() { + return error_manager_.Error(); } + bool has_error() const { return error_manager_.has_error(); } + template <typename T> void ParseList(T&& values, base::RepeatingCallback<void(decltype(values))> callback) { @@ -219,7 +166,7 @@ if (!canonical_cookie) *Error() << "invalid cookie"; - if (has_error_) + if (has_error()) return; events_.emplace_back( @@ -267,7 +214,7 @@ AttributionAggregatableSource aggregatable_source = ParseAggregatableSource(source_dict); - if (has_error_) + if (has_error()) return; events_.emplace_back( @@ -302,7 +249,7 @@ AttributionAggregatableTrigger aggregatable_trigger = ParseAggregatableTrigger(dict); - if (has_error_) + if (has_error()) return; events_.emplace_back( @@ -351,7 +298,7 @@ ParseFilterData(dict, "not_filters", &AttributionFilterData::FromTriggerFilterValues); - if (has_error_) + if (has_error()) return; event_triggers.emplace_back(trigger_data, priority, dedup_key, @@ -601,7 +548,7 @@ std::string id = ParseAggregatableKeyId(dict); absl::uint128 key = ParseAggregatableKey(dict); - if (has_error_) + if (has_error()) return; keys.emplace_back(std::move(id), key); @@ -678,7 +625,7 @@ trigger_dict, "not_filters", &AttributionFilterData::FromTriggerFilterValues); - if (has_error_) + if (has_error()) return; aggregatable_triggers.push_back(
diff --git a/content/test/data/attribution_reporting/register_source_headers_2.html b/content/test/data/attribution_reporting/register_source_headers_2.html deleted file mode 100644 index 6c9de327..0000000 --- a/content/test/data/attribution_reporting/register_source_headers_2.html +++ /dev/null
@@ -1 +0,0 @@ -Registers a source by providing headers.
diff --git a/content/test/data/attribution_reporting/register_source_headers_2.html.mock-http-headers b/content/test/data/attribution_reporting/register_source_headers_2.html.mock-http-headers deleted file mode 100644 index d0f8ace0..0000000 --- a/content/test/data/attribution_reporting/register_source_headers_2.html.mock-http-headers +++ /dev/null
@@ -1,2 +0,0 @@ -HTTP/1.1 200 OK -Attribution-Reporting-Register-Source:{"source_event_id":"2","destination":"https://d.test"}
diff --git a/content/test/data/attribution_reporting/register_source_headers_high_priority.html b/content/test/data/attribution_reporting/register_source_headers_high_priority.html deleted file mode 100644 index 85d016d..0000000 --- a/content/test/data/attribution_reporting/register_source_headers_high_priority.html +++ /dev/null
@@ -1 +0,0 @@ -Registers a source with high priority.
diff --git a/content/test/data/attribution_reporting/register_source_headers_high_priority.html.mock-http-headers b/content/test/data/attribution_reporting/register_source_headers_high_priority.html.mock-http-headers deleted file mode 100644 index 72b96412..0000000 --- a/content/test/data/attribution_reporting/register_source_headers_high_priority.html.mock-http-headers +++ /dev/null
@@ -1,2 +0,0 @@ -HTTP/1.1 200 OK -Attribution-Reporting-Register-Source:{"source_event_id":"3","destination":"https://d.test","priority":"10"}
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt index 946cd0409..4becb4a 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -284,6 +284,8 @@ crbug.com/1297265 [ win7 passthrough amd-0x6613 angle-d3d11 ] conformance2/renderbuffers/multisampled-stencil-renderbuffer-initialization.html [ RetryOnFailure ] crbug.com/1298096 [ win7 passthrough amd-0x6613 angle-d3d11 ] conformance2/textures/canvas_sub_rectangle/tex-3d-r16f-red-half_float.html [ RetryOnFailure ] +# Test regression and potential driver bug on AMD RX 5500 XT with recent BlendState refactoring +crbug.com/angleproject/7200 [ win amd-0x7340 angle-d3d11 ] conformance2/textures/misc/angle-stuck-depth-textures.html [ Failure ] # Recent AMD drivers seem to have a regression with 3D textures. # (Some of these tests seem to occasionally pass unexpectedly.)
diff --git a/docs/updater/functional_spec.md b/docs/updater/functional_spec.md index d9fc651..63ae153 100644 --- a/docs/updater/functional_spec.md +++ b/docs/updater/functional_spec.md
@@ -14,7 +14,13 @@ updater / an app. The metainstaller is downloaded by the user and can be run from any directory. -TODO(crbug.com/1035895): Document tagging. +The metainstaller may have a tag attached to it. The tag is a piece of unsigned +data from which the metainstaller extracts the ID of the application to be +installed, along with the application's brand code, usage-stats opt-in status, +and any additional parameters to be associated with the application. + +On Windows, the tag is embedded in one of the certificates in the metainstaller +PE. ### Elevation (Windows) The metainstaller parses its tag and re-launches itself at high integrity if @@ -30,7 +36,10 @@ TODO(crbug.com/1035895): Document bundled installers. -TODO(crbug.com/1035895): Document bundling the updater on macOS. +Applications on macOS frequently install via "drag-install", and then install +the updater using a standalone installer on the application's first-run. The +updater app can be embedded in a macOS application bundle as a helper and then +invoked with appropriate command line arguments to install itself. ## Updater The updater is installed at: @@ -54,7 +63,8 @@ * --handoff=... * As --tag. * --install-from-out-dir - * TODO(crbug.com/1035895): Document + * If specified, the program searches for an updater.runtime_deps file + * and copies all such files to the install directory. * --uninstall * Uninstall all versions of the updater. * --uninstall-self @@ -121,13 +131,104 @@ ### Installation TODO(crbug.com/1035895): Document UI/UX -TODO(crbug.com/1035895): Document installer APIs +#### Installer APIs +As part of installing or updating an application, the updater will execute the +application's installer. The API for the application installer is platform- +specific. -TODO(crbug.com/1035895): Document shim installation +The macOS API is [defined here](installer_api_mac.md). -TODO(crbug.com/1035895): Document handoff +TODO(crbug.com/1035895): Document Windows installer APIs -TODO(crbug.com/1035895): Document relevant enterprise policies. +#### Backward-Compatible Updater Shims +To maintain backwards compatibility with +[Omaha](https://github.com/google/omaha) and +[Keystone](https://code.google.com/archive/p/update-engine/), the updater +installs small versions of those programs that implement a subset of their APIs. + +##### Keystone Shims +The updater installs a Keystone-like application that contains these shims: + +1. The Keystone app executable. +1. The ksadmin helper executable. +2. The ksinstall helper executable. +3. The Keystone Agent helper app executable. + +Both the Keystone and Keystone Agent executables simply exit immediately when +run. + +The ksinstall executable expects to be called with `--uninstall` and possibly +`--system`. If so, it deletes the Keystone shim (but not the overall updater) +from the file system. Otherwise, it exits with a non-zero exit code. + +The ksadmin shim is frequently called by applications and handles a variety of +command lines: + +* --delete, -d + * Delete a ticket. + * Accepts -P. +* --install, -i + * Check for and apply updates. +* --ksadmin-version, -k + * Print the version of ksadmin. +* --print + * An alias for --print-tickets. +* --print-tag, -G + * Print a ticket's tag. + * Accepts -P. +* --print-tickets, -p + * Print all tickets. + * Accepts -P. +* --register, -r + * Register a new ticket or update an existing one. + * Accepts -P, -v, -x, -e, -a, -K, -H, -g. + +Some of these actions accept parameters: + +* --brand-key, -b plistKeyName + * Set the brand code key. Use with -P and -B. Value must be empty or + KSBrandID. +* --brand-path, -B pathToPlist + * Set the brand code path. Use with -P and -b. +* --productid, -P id + * Specifies the application ID. +* --system-store, -S + * Use the system-scope updater, even if not running as root. + * Not all operations can be performed with -S if not running as root. +* --tag, -g ap + * Set the application's additional parameters. Use with -P. +* --tag-key, -K plistKeyName + * Set the additional parameters path key. Use with -P and -H. +* --tag-path, -H pathToPlist + * Set the tag path. Use with -P and -K. +* --user-initiated, -F + * Set foreground priority for this operation. +* --user-store, -U + * Use a per-user ticket store, even if running as root. +* --version, -v version + * Set the application's version. Use with -P. +* --version-key, -e plistKeyName + * Set the version path key. Use with -P and -a. +* --version-path, -a pathToPlist + * Set the version path. Use with -P and -e. +* --xcpath, -x PATH + * Set a path to use as an existence checker. + +##### Omaha Shims +On Windows, the updater replaces Omaha's files with a copy of the updater, and +keeps the Omaha registry entry +(`CLIENTS/{430FD4D0-B729-4F61-AA34-91526481799D}`) up-to-date with the latest +`pv` value. Additionally, the updater replaces the Omaha uninstall command line +with its own. + +#### Enterprise Policies +Enterprise policies can prevent the installation of applications: +* A per-application setting may specify whether an application is installable. +* If no per-application setting specifies otherwise, the default install + policy is used. +* If the default install policy is unset, the application may be installed. + +Refer to chrome/updater/protos/omaha\_settings.proto for more details. #### Dynamic Install Parameters @@ -303,24 +404,83 @@ part of pings to the update server. ## Updates -TODO(crbug.com/1035895): Document server API (Omaha Protocol). +The updater communicates with update servers using the +[Omaha Protocol](protocol_3_1.md). -TODO(crbug.com/1035895): Document supported update formats. +### Update Formats +The updater accepts updates packaged as CRX₃ files. All files must be signed +with a publisher key. The corresponding public key is hardcoded into the +updater. +### Differential Updates TODO(crbug.com/1035895): Document differential updates. -TODO(crbug.com/1035895): Document update timing. +### Update Timing +The updater runs periodic tasks every hour, checking its own status, detecting +application uninstalls, and potential checking for updates (if it has been at +least 5 hours since the last update check). -TODO(crbug.com/1035895): Document on-demand APIs. +TODO(crbug.com/1035895): Does the updater run at user login on Windows? -TODO(crbug.com/1035895): Document registration APIs. +### On-Demand Updates +The updater exposes an RPC interface for any user to trigger an update check. +The update can be triggered by any user on the system, even in the system scope. -TODO(crbug.com/1035895): Document activity API. +The caller provides the ID of the item to update, the install data index to +request, the priority, whether a same-version update (repair) is permitted, and +callbacks to monitor the progress and completion of the operation. +Regardless of the normal update check timing, the update check will be attempted +immediately. + +### App Registration +The updater exposes an RPC interface for users to register an application with +the updater. Unlike on-demand updates, cross-user application registration is +not permitted. + +If the application is already installed, it should be registered with the +version present on disk. If it has not yet been installed, a version of 0 +should be used. + +### App Activity Reporting +Applications can report whether they are actively used or not through the +updater. Update servers can then aggregate this information to produce user +counts. + +Windows: +* When active, the application sets + HKCU\SOFTWARE\{Company}\Update\ClientState\{AppID} → dr (REG_SZ): 1. + * Note: both user-scoped and system-scoped updaters use HKCU. +* When reporting active use, the updater will reset the value to 0. + +macOS: +* The application touches + ~/Library/{Company}/{Company}SoftwareUpdate/Actives/{APPID}. +* The updater deletes the file when reporting active use. + +### EULA/ToS Acceptance TODO(crbug.com/1035895): Document EULA signals. -TODO(crbug.com/1035895): Document usage-stats opt-in signals. +### Usage Stats Acceptance +The updater may upload its crash reports and send usage stats if and only if +any piece of software it manages is permitted to send usage stats. +Windows: +* Applications enable usage stats by writing: + `HKCU\SOFTWARE\{Company}\Update\ClientState\{APPID}` → usagestats (DWORD): 1 + or + `HKLM\SOFTWARE\{Company}\Update\ClientStateMedium\{APPID}` → usagestats + (DWORD): 1 +* Applications rescind this permission by writing a value of 0. + +macOS: +* Application enable usage stats by setting `IsUploadEnabled` to true for a + crashpad database maintained in a "Crashpad" subdirectory of their + application data directory. +* The updater will search the file system for Crashpad directories belonging + to {Company}. + +### Enterprise Policies TODO(crbug.com/1035895): Document relevant enterprise policies. ### Telemetry @@ -331,29 +491,27 @@ When the updater updates an application (including itself) it will send an event with `"eventtype": 3` indicating the outcome of update operation. -## Services -TODO(crbug.com/1035895): Document app commands. +When the updater detects the uninstallation of an application, it will send an +event with `"eventtype": 4` to notify the server of the uninstallation. +When the updater attempts to download a file, it will send an event with +`"eventtype": 14` describing the parameters and outcome of the download. + +Multiple events associated with an update session are bundled together into a +single request. + +## Services + +### Crash Reporting TODO(crbug.com/1035895): Document updater crash reporting. -## Uninstallation -TODO(crbug.com/1035895): Document uninstallation APIs. - -TODO(crbug.com/1035895): Document updater self-uninstallation. - -## Associated Tools -TODO(crbug.com/1035895): Document external constant overrides (test build only). - -TODO(crbug.com/1035895): Document tagging tools. - -## Application Commands - +### Application Commands The Application Command feature allows installed Updater-managed products to pre-register and later run command lines in the format `c:\path-to-exe\exe.exe {params}` (elevated for system applications). `{params}` is optional and can also include replaceable parameters substituted at runtime. -### Registration +#### Registration App commands are registered in the registry with the following formats: * New command layout format: @@ -372,7 +530,7 @@ As shown above, `{command format}` needs to be the complete path to an executable followed by optional parameters. -### Usage +#### Usage Once registered, commands may be invoked using the `execute` method in the `IAppCommandWeb` interface. @@ -414,10 +572,7 @@ `COMMAND_STATUS_COMPLETE`, the `exitCode` method can be used to get the process exit code. -### Command-Line Format - -Some rules to follow for the command line: - +#### Command-Line Format * for system applications, the executable path must be in a secure location such as `%ProgramFiles%` for security, since it will be run elevated. * placeholders are not permitted in the executable path. @@ -430,3 +585,48 @@ becomes the command line `echo.exe AA %2 %BB` +## Uninstallation +On Mac and Linux, if the application was registered with an existence path +checker and no file at that path exists (or if the file at that path is owned +by another user), the updater will consider the application uninstalled, send +the ping, and cease trying to keep it up to date. + +On Windows, if the ClientState entry for for the application is deleted, the +app is considered uninstalled. + +On Windows, the updater registers a "UninstallCmdLine" under the +`Software\{Company}\Updater` key. This command line can be invoked by +application uninstallers to cause the updater to immediately update its +registrations. The updater will also check for uninstallations in every periodic +task execution. + +When the last registered application is uninstalled, the updater will uninstall +itself. The updater will also uninstall itself if it has started 24 times but +never had a product (besides itself) registered for updates. + +The updater uninstaller removes all updater files, registry keys, RPC hooks, +scheduled tasks, and so forth from the file system, except that it leaves a +small log file in its data directory. + +## Associated Tools + +### External Constants Overrides +Building the updater produces both a production-ready updater executable and a +version of the executable used for the purposes of testing. The test executable +is identical to the production one except that it allows cetain constants to be +overridden by the execution environment: + +* `url`: Update check & ping-back URL. +* `use_cup`: Whether CUP is used at all. +* `cup_public_key`: An unarmored PEM-encoded ASN.1 SubjectPublicKeyInfo with + the ecPublicKey algorithm and containing a named elliptic curve. + +Windows: these overrides exist in registry, under +`HKLM\Software\{Company}\Update\Clients\ClientState\UpdateDev`. + +macOS: these overrides exist in user defaults, in the `{MAC_BUNDLE_IDENTIFIER}` +suite. For system installs, the defaults are those of the root user. + +### Tagging Tools +TODO(crbug.com/1035895): Document tagging tools. +
diff --git a/docs/updater/installer_api_mac.md b/docs/updater/installer_api_mac.md index 0e41ed516..bb2d330 100644 --- a/docs/updater/installer_api_mac.md +++ b/docs/updater/installer_api_mac.md
@@ -7,49 +7,54 @@ an `.install` executable at the root of the archive. (Typically the archives also contain an app bundle, i.e. the new version of the app.) -The updater will execute `.install`, passing data as positional command-line -arguments and environment variables. +The updater will execute all of the following executables in the archive, if +they exist, in order: -The archive may also contain `.preinstall` and `.postinstall`, which are -executed before and after `.install` respectively. If any fail (exit with a -non-zero status), the remaining executables are not run. Collectively, these -three executables are called the "install executables". +1. `.preinstall` +2. `.keystone_preinstall` +3. `.install` +4. `.keystone_install` +5. `.postinstall` +6. `.keystone_postinstall` -## .install Execution Environment +If any fail (exit with a non-zero status), the remaining executables are not +run and the installation fails. -### Command-Line Arguments -For backward compatibility, install executables are passed the following -arguments, in this order: +If none exist, the installation fails. -1. The absolute path to the unpacked update archive (i.e. the parent directory -of the install executable.) - -2. The absolute path to the installation of the app, based on its -existence-checker value. - -3. The version of the app before this update. - -New install executables should instead depend on the environment variables below -rather than the above positional arguments. +## Execution Environment ### Environment Variables -The install executables are executed in an environment with the following -environment variables defined: +Installer executables are executed in an environment with the following +environment variables: -- `PATH`: '/bin:/usr/bin:/Path/To/ksadmin'. -- `PREVIOUS_VERSION`: The version of the app before this update. -- `KS_TICKET_XC_PATH`: The absolute path to the installation of the app, based - on its existence-checker value. - `KS_TICKET_AP`: The ap value of the currently-installed version of the app. (Note: "ap" was called "tag" in Keystone.) +- `KS_TICKET_XC_PATH`: The absolute path to the installation of the app, based + on its existence-checker value. +- `PATH`: '/bin:/usr/bin:/Path/To/ksadmin'. +- `PREVIOUS_VERSION`: The version of the app before this update. +- `SERVER_ARGS`: The arguments sent from the server, if any. Refer to + the [Omaha protocol](protocol_3_1.md)'s description of `manifest` response + objects. - `UPDATE_IS_MACHINE`: An indicator of the updater's scope. - 0 if the updater is per-user. - 1 if the updater is cross-user. -- `SERVER_ARGS`: The arguments sent from the server, if any. Refer to - protocol\_3\_1.md's description of `manifest` response objects. - `UNPACK_DIR`: The absolute path to the unpacked update archive (i.e. the parent directory of the install executable.) +### Command-Line Arguments +Installer executables are passed the following arguments, in this order: + +1. The absolute path to the unpacked update archive (i.e. the parent directory +of the install executable.) +2. The absolute path to the installation of the app, based on its +existence-checker value. +3. The version of the app before this update. + +New install executables should instead depend on environment variables rather +than positional arguments. + ## Updating Product Metadata If the install executables succeed, the updater will automatically record the new version of the application without any special action from the installers.
diff --git a/docs/updater/protocol_3_1.md b/docs/updater/protocol_3_1.md index 4dee64f3..27c9cb14 100644 --- a/docs/updater/protocol_3_1.md +++ b/docs/updater/protocol_3_1.md
@@ -1,5 +1,3 @@ -# Omaha Protocol (V3.1) -This document describes version 3.1 of the Omaha Client-Server Protocol. Previous versions are described at: * [Version 3](https://github.com/google/omaha/blob/master/doc/ServerProtocolV3.md) * [Version 2](https://github.com/google/omaha/blob/master/doc/ServerProtocolV2.md) @@ -426,6 +424,8 @@ contents, and can supply them if requested. This is used during installation to transmit alternate branding or seeded configurations to the application. `data` objects have the following members: + * `name`: The type of data lookup to perform. The only known supported value + is "install". Default: "". * `index`: The key to look up on the server. Default: "". #### `disabled` Objects (Update Check Request) @@ -570,8 +570,10 @@ #### `data` Objects (Update Check Response) Each data object in the response represents an answer to a data request from the client. It has the following members: + * `name`: The requested data name from `request.app.data.name`, echoed back + to the client. * `index`: The requested data index from `request.app.data.index`, echoed - back to the client. + back to the client, if valid. * `status`: The outcome of the data lookup. Default: "ok". Known values: * "ok": This tag contains the appropriate data response, even if such a response is the empty string. @@ -580,7 +582,7 @@ * "error-nodata": The data request was understood, but the server does not have a value for the requested entry. (This is distinct from having a zero-length value.) - * `value`: The value of the requested data index. + * `#text`: The value of the requested data index. #### `updatecheck` Objects (Update Check Response) An updatecheck response object contains whether or not there is an update
diff --git a/extensions/browser/api/alarms/alarms_api.cc b/extensions/browser/api/alarms/alarms_api.cc index 8e7ba2e..d643e2f 100644 --- a/extensions/browser/api/alarms/alarms_api.cc +++ b/extensions/browser/api/alarms/alarms_api.cc
@@ -157,13 +157,13 @@ } void AlarmsGetAllFunction::Callback(const AlarmList* alarms) { - auto alarms_value = std::make_unique<base::ListValue>(); + base::Value::List alarms_value; if (alarms) { for (const std::unique_ptr<Alarm>& alarm : *alarms) - alarms_value->Append(alarm->js_alarm->ToValue()); + alarms_value.Append( + base::Value::FromUniquePtrValue(alarm->js_alarm->ToValue())); } - Respond( - OneArgument(base::Value::FromUniquePtrValue(std::move(alarms_value)))); + Respond(OneArgument(base::Value(std::move(alarms_value)))); } ExtensionFunction::ResponseAction AlarmsClearFunction::Run() {
diff --git a/extensions/browser/api/app_runtime/app_runtime_api.cc b/extensions/browser/api/app_runtime/app_runtime_api.cc index e95c186..5a56593 100644 --- a/extensions/browser/api/app_runtime/app_runtime_api.cc +++ b/extensions/browser/api/app_runtime/app_runtime_api.cc
@@ -71,7 +71,7 @@ ExtensionsBrowserClient::Get()->IsLoggedInAsPublicAccount()); std::unique_ptr<base::ListValue> args(new base::ListValue()); - args->Append(std::move(launch_data)); + args->Append(base::Value::FromUniquePtrValue(std::move(launch_data))); auto event = std::make_unique<Event>( events::APP_RUNTIME_ON_LAUNCHED, app_runtime::OnLaunched::kEventName, std::move(*args).TakeListDeprecated(), context);
diff --git a/extensions/browser/api/async_api_function.cc b/extensions/browser/api/async_api_function.cc index e3a41c1c..3855f45 100644 --- a/extensions/browser/api/async_api_function.cc +++ b/extensions/browser/api/async_api_function.cc
@@ -68,7 +68,7 @@ void AsyncApiFunction::SetResult(std::unique_ptr<base::Value> result) { results_ = std::make_unique<base::ListValue>(); - results_->Append(std::move(result)); + results_->Append(base::Value::FromUniquePtrValue(std::move(result))); } void AsyncApiFunction::SetResultList(std::unique_ptr<base::ListValue> results) {
diff --git a/extensions/browser/api/bluetooth/bluetooth_api.cc b/extensions/browser/api/bluetooth/bluetooth_api.cc index 2620668e..0466b1e 100644 --- a/extensions/browser/api/bluetooth/bluetooth_api.cc +++ b/extensions/browser/api/bluetooth/bluetooth_api.cc
@@ -175,7 +175,8 @@ bluetooth_api::Device extension_device; bluetooth_api::BluetoothDeviceToApiDevice(*device, &extension_device); - device_list->Append(extension_device.ToValue()); + device_list->Append( + base::Value::FromUniquePtrValue(extension_device.ToValue())); } Respond(OneArgument(base::Value::FromUniquePtrValue(std::move(device_list))));
diff --git a/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_api.cc b/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_api.cc index 142d22e7..61ac4a1 100644 --- a/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_api.cc +++ b/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_api.cc
@@ -737,11 +737,12 @@ // Manually construct the result instead of using // apibtle::GetDescriptors::Result::Create as it doesn't convert lists of // enums correctly. - std::unique_ptr<base::ListValue> result(new base::ListValue()); + base::Value::List result; for (apibtle::Descriptor& descriptor : descriptor_list) - result->Append(apibtle::DescriptorToValue(&descriptor)); + result.Append(base::Value::FromUniquePtrValue( + apibtle::DescriptorToValue(&descriptor))); - Respond(OneArgument(base::Value::FromUniquePtrValue(std::move(result)))); + Respond(OneArgument(base::Value(std::move(result)))); } BluetoothLowEnergyReadCharacteristicValueFunction::
diff --git a/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc b/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc index 9bee8c5..a41708a2 100644 --- a/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc +++ b/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc
@@ -243,28 +243,28 @@ } } -// Builds a DictionaryValue from an array of the form {name1, value1, name2, +// Builds a base::Value::Dict from an array of the form {name1, value1, name2, // value2, ...}. Values for the same key are grouped in a ListValue. -std::unique_ptr<base::DictionaryValue> GetDictionaryFromArray( +base::Value::Dict GetDictionaryFromArray( const std::vector<const std::string*>& array) { const size_t length = array.size(); CHECK(length % 2 == 0); - std::unique_ptr<base::DictionaryValue> dictionary(new base::DictionaryValue); + base::Value::Dict dictionary; for (size_t i = 0; i < length; i += 2) { const std::string* name = array[i]; const std::string* value = array[i+1]; - if (base::Value* entry = dictionary->FindKey(*name)) { + if (base::Value* entry = dictionary.Find(*name)) { absl::optional<base::Value> entry_owned; switch (entry->type()) { case base::Value::Type::STRING: { // Replace the present string with a list. base::Value list(base::Value::Type::LIST); // No need to check again, we already verified the entry is there. - entry_owned = dictionary->ExtractKey(*name); + entry_owned = dictionary.Extract(*name); list.Append(std::move(*entry_owned)); list.Append(*value); - dictionary->SetKey(*name, std::move(list)); + dictionary.Set(*name, std::move(list)); break; } case base::Value::Type::LIST: // Just append to the list. @@ -272,10 +272,10 @@ break; default: NOTREACHED(); // We never put other Values here. - return nullptr; + return base::Value::Dict(); } } else { - dictionary->SetStringPath(*name, *value); + dictionary.Set(*name, *value); } } return dictionary; @@ -290,11 +290,9 @@ const WebRequestInfo& request_info, bool* result) { base::ListValue contains_headers; - for (size_t i = 0; i < tests.size(); ++i) { - std::unique_ptr<base::DictionaryValue> temp( - GetDictionaryFromArray(tests[i])); - ASSERT_TRUE(temp.get()); - contains_headers.Append(std::move(temp)); + for (const auto& test : tests) { + base::Value::Dict temp = GetDictionaryFromArray(test); + contains_headers.Append(base::Value(std::move(temp))); } std::string error;
diff --git a/extensions/browser/api/feedback_private/feedback_private_api_chromeos_unittest.cc b/extensions/browser/api/feedback_private/feedback_private_api_chromeos_unittest.cc index 4381298..f2b1341f 100644 --- a/extensions/browser/api/feedback_private/feedback_private_api_chromeos_unittest.cc +++ b/extensions/browser/api/feedback_private/feedback_private_api_chromeos_unittest.cc
@@ -34,7 +34,7 @@ template <typename T> std::string ParamsToJSON(const T& params) { base::ListValue params_value; - params_value.Append(params.ToValue()); + params_value.Append(base::Value::FromUniquePtrValue(params.ToValue())); std::string params_json_string; EXPECT_TRUE(base::JSONWriter::Write(params_value, ¶ms_json_string));
diff --git a/extensions/browser/api/file_system/file_system_api.cc b/extensions/browser/api/file_system/file_system_api.cc index 033dbc3b..e27a7ae8 100644 --- a/extensions/browser/api/file_system/file_system_api.cc +++ b/extensions/browser/api/file_system/file_system_api.cc
@@ -359,15 +359,16 @@ bool success = result->GetList("entries", &entries); DCHECK(success); - std::unique_ptr<base::DictionaryValue> entry(new base::DictionaryValue()); - entry->SetStringKey("fileSystemId", file_entry.filesystem_id); - entry->SetStringKey("baseName", file_entry.registered_name); - if (id_override.empty()) - entry->SetStringKey("id", file_entry.id); - else - entry->SetStringKey("id", id_override); - entry->SetBoolKey("isDirectory", is_directory_); - entries->Append(std::move(entry)); + base::Value::Dict entry; + entry.Set("fileSystemId", file_entry.filesystem_id); + entry.Set("baseName", file_entry.registered_name); + if (id_override.empty()) { + entry.Set("id", file_entry.id); + } else { + entry.Set("id", id_override); + } + entry.Set("isDirectory", is_directory_); + entries->Append(base::Value(std::move(entry))); } void FileSystemEntryFunction::HandleWritableFileError(
diff --git a/extensions/browser/api/idle/idle_api.cc b/extensions/browser/api/idle/idle_api.cc index 3f9cab1..d44504f 100644 --- a/extensions/browser/api/idle/idle_api.cc +++ b/extensions/browser/api/idle/idle_api.cc
@@ -43,8 +43,7 @@ IdleManagerFactory::GetForBrowserContext(browser_context()) ->QueryState(threshold); - return RespondNow(OneArgument( - base::Value::FromUniquePtrValue(IdleManager::CreateIdleValue(state)))); + return RespondNow(OneArgument(IdleManager::CreateIdleValue(state))); } void IdleQueryStateFunction::IdleStateCallback(ui::IdleState state) {
diff --git a/extensions/browser/api/idle/idle_manager.cc b/extensions/browser/api/idle/idle_manager.cc index dcacc0e..fe57cf9 100644 --- a/extensions/browser/api/idle/idle_manager.cc +++ b/extensions/browser/api/idle/idle_manager.cc
@@ -201,8 +201,7 @@ } // static -std::unique_ptr<base::Value> IdleManager::CreateIdleValue( - ui::IdleState idle_state) { +base::Value IdleManager::CreateIdleValue(ui::IdleState idle_state) { const char* description; if (idle_state == ui::IDLE_STATE_ACTIVE) { @@ -213,7 +212,7 @@ description = keys::kStateLocked; } - return std::make_unique<base::Value>(description); + return base::Value(description); } void IdleManager::SetEventDelegateForTest(
diff --git a/extensions/browser/api/idle/idle_manager.h b/extensions/browser/api/idle/idle_manager.h index be38183..42553b87 100644 --- a/extensions/browser/api/idle/idle_manager.h +++ b/extensions/browser/api/idle/idle_manager.h
@@ -100,7 +100,7 @@ // other operating systems. base::TimeDelta GetAutoLockDelay() const; - static std::unique_ptr<base::Value> CreateIdleValue(ui::IdleState idle_state); + static base::Value CreateIdleValue(ui::IdleState idle_state); // Override default event class. Callee assumes ownership. Used for testing. void SetEventDelegateForTest(std::unique_ptr<EventDelegate> event_delegate);
diff --git a/extensions/browser/extension_protocols.cc b/extensions/browser/extension_protocols.cc index c1ca84b..ab57cb7 100644 --- a/extensions/browser/extension_protocols.cc +++ b/extensions/browser/extension_protocols.cc
@@ -616,10 +616,14 @@ // encountering an error and communicating the error to the the `client_`). void DeleteThis() { delete this; } + void CompleteRequestAndDeleteThis(int status) { + client_->OnComplete(network::URLLoaderCompletionStatus(status)); + DeleteThis(); + } + void Start() { if (browser_context_->ShutdownStarted()) { - client_->OnComplete(network::URLLoaderCompletionStatus(net::ERR_FAILED)); - DeleteThis(); + CompleteRequestAndDeleteThis(net::ERR_FAILED); return; } @@ -638,9 +642,7 @@ render_process_id_, browser_context_->IsOffTheRecord(), extension.get(), incognito_enabled, enabled_extensions, *process_map)) { - client_->OnComplete( - network::URLLoaderCompletionStatus(net::ERR_BLOCKED_BY_CLIENT)); - DeleteThis(); + CompleteRequestAndDeleteThis(net::ERR_BLOCKED_BY_CLIENT); return; } @@ -648,8 +650,7 @@ if (!GetDirectoryForExtensionURL( request_.url, extension_id, extension.get(), registry->disabled_extensions(), &directory_path)) { - client_->OnComplete(network::URLLoaderCompletionStatus(net::ERR_FAILED)); - DeleteThis(); + CompleteRequestAndDeleteThis(net::ERR_FAILED); return; } @@ -704,8 +705,7 @@ base::as_bytes( base::make_span(bitmap_data->data(), bitmap_data->size()))); } else { - client_->OnComplete(network::URLLoaderCompletionStatus(net::ERR_FAILED)); - DeleteThis(); + CompleteRequestAndDeleteThis(net::ERR_FAILED); } } @@ -717,15 +717,13 @@ mojo::ScopedDataPipeConsumerHandle consumer_handle; if (mojo::CreateDataPipe(size, producer_handle, consumer_handle) != MOJO_RESULT_OK) { - client_->OnComplete(network::URLLoaderCompletionStatus(net::ERR_FAILED)); - DeleteThis(); + CompleteRequestAndDeleteThis(net::ERR_FAILED); return; } MojoResult result = producer_handle->WriteData(contents.data(), &size, MOJO_WRITE_DATA_FLAG_NONE); if (result != MOJO_RESULT_OK || size < contents.size()) { - client_->OnComplete(network::URLLoaderCompletionStatus(net::ERR_FAILED)); - DeleteThis(); + CompleteRequestAndDeleteThis(net::ERR_FAILED); return; } @@ -737,8 +735,7 @@ client_->OnStartLoadingResponseBody(std::move(consumer_handle)); } - client_->OnComplete(network::URLLoaderCompletionStatus(net::OK)); - DeleteThis(); + CompleteRequestAndDeleteThis(net::OK); } void LoadExtension(scoped_refptr<const Extension> extension, @@ -837,9 +834,7 @@ // files there are internal implementation details that should not be // considered part of the extension. if (base::FilePath(kMetadataFolder).IsParent(relative_path)) { - client_->OnComplete( - network::URLLoaderCompletionStatus(net::ERR_FILE_NOT_FOUND)); - DeleteThis(); + CompleteRequestAndDeleteThis(net::ERR_FILE_NOT_FOUND); return; } @@ -862,9 +857,7 @@ extension_id = new_extension_id; relative_path = base::FilePath::FromUTF8Unsafe(new_relative_path); } else { - client_->OnComplete( - network::URLLoaderCompletionStatus(net::ERR_BLOCKED_BY_CLIENT)); - DeleteThis(); + CompleteRequestAndDeleteThis(net::ERR_BLOCKED_BY_CLIENT); return; } }
diff --git a/gpu/command_buffer/service/native_image_buffer.cc b/gpu/command_buffer/service/native_image_buffer.cc index bcb0feb..e112c463 100644 --- a/gpu/command_buffer/service/native_image_buffer.cc +++ b/gpu/command_buffer/service/native_image_buffer.cc
@@ -56,7 +56,8 @@ scoped_refptr<NativeImageBufferEGL> NativeImageBufferEGL::Create( GLuint texture_id) { - EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); + EGLDisplay egl_display = + gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(); EGLContext egl_context = eglGetCurrentContext(); DCHECK_NE(EGL_NO_CONTEXT, egl_context);
diff --git a/gpu/command_buffer/service/passthrough_program_cache.cc b/gpu/command_buffer/service/passthrough_program_cache.cc index 02b318a..672f43e 100644 --- a/gpu/command_buffer/service/passthrough_program_cache.cc +++ b/gpu/command_buffer/service/passthrough_program_cache.cc
@@ -44,7 +44,8 @@ curr_size_bytes_(0), store_(ProgramLRUCache::NO_AUTO_EVICT) { #if defined(USE_EGL) - EGLDisplay display = gl::GLSurfaceEGL::GetHardwareDisplay(); + EGLDisplay display = + gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(); DCHECK(!g_program_cache); g_program_cache = this;
diff --git a/gpu/command_buffer/service/raster_decoder.cc b/gpu/command_buffer/service/raster_decoder.cc index 09ffd123..193f739b 100644 --- a/gpu/command_buffer/service/raster_decoder.cc +++ b/gpu/command_buffer/service/raster_decoder.cc
@@ -2228,20 +2228,21 @@ canvas->drawImageRect(source_image, gfx::RectToSkRect(source_rect), gfx::RectToSkRect(dest_rect), SkSamplingOptions(), &paint, SkCanvas::kStrict_SrcRectConstraint); - } - if (auto end_state = source_scoped_access->TakeEndState()) { - gr_context()->setBackendTextureState( - source_scoped_access->promise_image_texture()->backendTexture(), - *end_state); + if (auto end_state = source_scoped_access->TakeEndState()) { + gr_context()->setBackendTextureState( + source_scoped_access->promise_image_texture()->backendTexture(), + *end_state); + } + + if (!dest_shared_image->IsCleared()) { + dest_shared_image->SetClearedRect(new_cleared_rect); + } } FlushAndSubmitIfNecessary(dest_scoped_access->surface(), dest_scoped_access->TakeEndState(), std::move(end_semaphores)); - if (!dest_shared_image->IsCleared()) { - dest_shared_image->SetClearedRect(new_cleared_rect); - } } bool RasterDecoderImpl::TryCopySubTextureINTERNALMemory( @@ -2476,10 +2477,10 @@ dest_scoped_access->promise_image_texture()->backendTexture(), &pixmap, /*levels=*/1, dest_shared_image->surface_origin(), nullptr, nullptr); - if (dest_scoped_access->TakeEndState()) + if (auto end_state = dest_scoped_access->TakeEndState()) gr_context()->setBackendTextureState( dest_scoped_access->promise_image_texture()->backendTexture(), - *dest_scoped_access->TakeEndState()); + *end_state); FlushAndSubmitIfNecessary(nullptr, nullptr, std::move(end_semaphores)); if (written && !dest_shared_image->IsCleared()) {
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_angle_vulkan.cc b/gpu/command_buffer/service/shared_image_backing_factory_angle_vulkan.cc index c4ac92cc..dbd5771 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory_angle_vulkan.cc +++ b/gpu/command_buffer/service/shared_image_backing_factory_angle_vulkan.cc
@@ -471,7 +471,7 @@ context_state->progress_reporter()), context_state_(context_state) { DCHECK(context_state_->GrContextIsVulkan()); - DCHECK(gl::GLSurfaceEGL::IsANGLEVulkanImageSupported()); + DCHECK(gl::GLSurfaceEGL::GetGLDisplayEGL()->IsANGLEVulkanImageSupported()); } SharedImageBackingFactoryAngleVulkan::~SharedImageBackingFactoryAngleVulkan() =
diff --git a/gpu/command_buffer/service/shared_image_factory.cc b/gpu/command_buffer/service/shared_image_factory.cc index 47fe989..3fedc1fb 100644 --- a/gpu/command_buffer/service/shared_image_factory.cc +++ b/gpu/command_buffer/service/shared_image_factory.cc
@@ -256,7 +256,8 @@ } #endif // BUILDFLAG(ENABLE_VULKAN) - bool egl_ext_supported = gl::GLSurfaceEGL::HasEGLExtension("EGL_KHR_image"); + bool egl_ext_supported = + gl::GLSurfaceEGL::GetGLDisplayEGL()->HasEGLExtension("EGL_KHR_image"); bool glx_ext_supported = false; #if defined(USE_OZONE) #if BUILDFLAG(OZONE_PLATFORM_X11)
diff --git a/gpu/config/gpu_control_list.cc b/gpu/config/gpu_control_list.cc index 156c6e53..f1d165a 100644 --- a/gpu/config/gpu_control_list.cc +++ b/gpu/config/gpu_control_list.cc
@@ -17,6 +17,7 @@ #include "base/system/sys_info.h" #include "base/values.h" #include "build/build_config.h" +#include "components/crash/core/common/crash_key.h" #include "gpu/config/gpu_util.h" #include "third_party/re2/src/re2/re2.h" @@ -102,6 +103,9 @@ bool StringMismatch(const std::string& input, const std::string& pattern) { if (input.empty() || pattern.empty()) return false; + static crash_reporter::CrashKeyString<128> crash_key( + "StringMismatch::pattern"); + crash_reporter::ScopedCrashKeyString scoped_crash_key(&crash_key, pattern); return !RE2::FullMatch(input, pattern); } @@ -571,6 +575,10 @@ bool GpuControlList::Entry::Contains(OsType target_os_type, const std::string& target_os_version, const GPUInfo& gpu_info) const { + static crash_reporter::CrashKeyString<8> crash_key( + "GpuControlList::Entry::id"); + crash_reporter::ScopedCrashKeyString scoped_crash_key( + &crash_key, base::StringPrintf("%d", id)); if (!conditions.Contains(target_os_type, target_os_version, gpu_info)) { return false; }
diff --git a/gpu/config/gpu_info_collector.cc b/gpu/config/gpu_info_collector.cc index 4d1a80e..b0c51a1 100644 --- a/gpu/config/gpu_info_collector.cc +++ b/gpu/config/gpu_info_collector.cc
@@ -381,9 +381,12 @@ #if BUILDFLAG(IS_ANDROID) gpu_info->can_support_threaded_texture_mailbox = - gl::GLSurfaceEGL::HasEGLExtension("EGL_KHR_fence_sync") && - gl::GLSurfaceEGL::HasEGLExtension("EGL_KHR_image_base") && - gl::GLSurfaceEGL::HasEGLExtension("EGL_KHR_gl_texture_2D_image") && + gl::GLSurfaceEGL::GetGLDisplayEGL()->HasEGLExtension( + "EGL_KHR_fence_sync") && + gl::GLSurfaceEGL::GetGLDisplayEGL()->HasEGLExtension( + "EGL_KHR_image_base") && + gl::GLSurfaceEGL::GetGLDisplayEGL()->HasEGLExtension( + "EGL_KHR_gl_texture_2D_image") && gfx::HasExtension(extension_set, "GL_OES_EGL_image"); #else gl::GLWindowSystemBindingInfo window_system_binding_info; @@ -557,8 +560,9 @@ const GpuPreferences& prefs) { // Populate the list of ANGLE features by querying the functions exposed by // EGL_ANGLE_feature_control if it's available. - if (gl::GLSurfaceEGL::IsANGLEFeatureControlSupported()) { - EGLDisplay display = gl::GLSurfaceEGL::GetHardwareDisplay(); + if (gl::GLSurfaceEGL::GetGLDisplayEGL()->IsANGLEFeatureControlSupported()) { + EGLDisplay display = + gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(); EGLAttrib feature_count = 0; eglQueryDisplayAttribANGLE(display, EGL_FEATURE_COUNT_ANGLE, &feature_count);
diff --git a/gpu/config/gpu_util.cc b/gpu/config/gpu_util.cc index 972db1c..33b5b58 100644 --- a/gpu/config/gpu_util.cc +++ b/gpu/config/gpu_util.cc
@@ -127,7 +127,7 @@ // synchronization, this is based on Android native fence sync // support. If that is unavailable, i.e. on emulator or SwiftShader, // don't claim SurfaceControl support. - if (!gl::GLSurfaceEGL::IsAndroidNativeFenceSyncSupported()) + if (!gl::GLSurfaceEGL::GetGLDisplayEGL()->IsAndroidNativeFenceSyncSupported()) return kGpuFeatureStatusDisabled; DCHECK(gfx::SurfaceControl::IsSupported());
diff --git a/gpu/ipc/service/gpu_channel_manager.cc b/gpu/ipc/service/gpu_channel_manager.cc index e5f21ca6..04618c0 100644 --- a/gpu/ipc/service/gpu_channel_manager.cc +++ b/gpu/ipc/service/gpu_channel_manager.cc
@@ -815,7 +815,8 @@ // Disable robust resource initialization for raster decoder and compositor. // TODO(crbug.com/1192632): disable robust_resource_initialization for // SwANGLE. - if (gl::GLSurfaceEGL::GetDisplayType() != gl::ANGLE_SWIFTSHADER && + if (gl::GLSurfaceEGL::GetGLDisplayEGL()->GetDisplayType() != + gl::ANGLE_SWIFTSHADER && features::IsUsingSkiaRenderer()) { attribs.robust_resource_initialization = false; }
diff --git a/infra/config/generated/builders/ci/fuchsia-fyi-arm64-emu-arg/properties.json b/infra/config/generated/builders/ci/fuchsia-fyi-arm64-emu-arg/properties.json new file mode 100644 index 0000000..fc3bce3 --- /dev/null +++ b/infra/config/generated/builders/ci/fuchsia-fyi-arm64-emu-arg/properties.json
@@ -0,0 +1,17 @@ +{ + "$build/goma": { + "enable_ats": true, + "rpc_extra_params": "?prod", + "server_host": "goma.chromium.org", + "use_luci_auth": true + }, + "$recipe_engine/resultdb/test_presentation": { + "column_keys": [], + "grouping_keys": [ + "status", + "v.test_suite" + ] + }, + "builder_group": "chromium.fyi", + "recipe": "chromium" +} \ No newline at end of file
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg index cfedff1f..7c8bdd8 100644 --- a/infra/config/generated/luci/cr-buildbucket.cfg +++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -29116,6 +29116,85 @@ } } builders { + name: "fuchsia-fyi-arm64-emu-arg" + swarming_host: "chromium-swarm.appspot.com" + dimensions: "builderless:1" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-18.04" + dimensions: "pool:luci.chromium.ci" + dimensions: "ssd:0" + exe { + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" + } + properties: + '{' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/ci/fuchsia-fyi-arm64-emu-arg/properties.json",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' + ' },' + ' "builder_group": "chromium.fyi",' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium"' + '}' + execution_timeout_secs: 36000 + build_numbers: YES + service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" + experiments { + key: "luci.recipes.use_python3" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "ci_test_results" + test_results {} + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "gpu_ci_test_results" + test_results { + predicate { + test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+" + } + } + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "blink_web_tests_ci_test_results" + test_results { + predicate { + test_id_regexp: "ninja://[^/]*blink_web_tests/.+" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + } + builders { name: "fuchsia-fyi-arm64-femu" swarming_host: "chromium-swarm.appspot.com" dimensions: "builderless:1"
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg index 313f101..bd794cf1 100644 --- a/infra/config/generated/luci/luci-milo.cfg +++ b/infra/config/generated/luci/luci-milo.cfg
@@ -6522,6 +6522,11 @@ short_name: "dbg" } builders { + name: "buildbucket/luci.chromium.ci/fuchsia-fyi-arm64-emu-arg" + category: "fuchsia|a64" + short_name: "emu-arg" + } + builders { name: "buildbucket/luci.chromium.ci/fuchsia-fyi-arm64-femu" category: "fuchsia|a64" short_name: "femu"
diff --git a/infra/config/generated/luci/luci-notify.cfg b/infra/config/generated/luci/luci-notify.cfg index e5aa7999..90b00df 100644 --- a/infra/config/generated/luci/luci-notify.cfg +++ b/infra/config/generated/luci/luci-notify.cfg
@@ -2794,6 +2794,19 @@ notifications { on_change: true email { + recipients: "chrome-fuchsia-engprod+builder-notification@google.com" + } + } + builders { + bucket: "ci" + name: "fuchsia-fyi-arm64-emu-arg" + repository: "https://chromium.googlesource.com/chromium/src" + } +} +notifiers { + notifications { + on_change: true + email { recipients: "chrome-fuchsia-gardener@grotations.appspotmail.com" } }
diff --git a/infra/config/generated/luci/luci-scheduler.cfg b/infra/config/generated/luci/luci-scheduler.cfg index 25b16b68..0906c6e 100644 --- a/infra/config/generated/luci/luci-scheduler.cfg +++ b/infra/config/generated/luci/luci-scheduler.cfg
@@ -4484,6 +4484,17 @@ } } job { + id: "android-marshmallow-x86-fyi-rel-reviver" + realm: "ci" + schedule: "0 5,7 * * *" + acl_sets: "ci" + buildbucket { + server: "cr-buildbucket.appspot.com" + bucket: "ci" + builder: "android-marshmallow-x86-fyi-rel-reviver" + } +} +job { id: "android-marshmallow-x86-rel" realm: "ci" acl_sets: "ci" @@ -5015,6 +5026,16 @@ } } job { + id: "fuchsia-fyi-arm64-emu-arg" + realm: "ci" + acl_sets: "ci" + buildbucket { + server: "cr-buildbucket.appspot.com" + bucket: "ci" + builder: "fuchsia-fyi-arm64-emu-arg" + } +} +job { id: "fuchsia-fyi-arm64-femu" realm: "ci" acl_sets: "ci" @@ -7341,6 +7362,7 @@ triggers: "fuchsia-angle-builder" triggers: "fuchsia-arm64-cast" triggers: "fuchsia-fyi-arm64-dbg" + triggers: "fuchsia-fyi-arm64-emu-arg" triggers: "fuchsia-fyi-arm64-femu" triggers: "fuchsia-fyi-arm64-rel" triggers: "fuchsia-fyi-x64-asan"
diff --git a/infra/config/generated/luci/project.cfg b/infra/config/generated/luci/project.cfg index 5d4b8b8..5682f3ad 100644 --- a/infra/config/generated/luci/project.cfg +++ b/infra/config/generated/luci/project.cfg
@@ -7,7 +7,7 @@ name: "chromium" access: "group:all" lucicfg { - version: "1.30.11" + version: "1.30.10" package_dir: "../.." config_dir: "generated/luci" entry_point: "main.star"
diff --git a/infra/config/notifiers.star b/infra/config/notifiers.star index a602bce..7b542bc 100644 --- a/infra/config/notifiers.star +++ b/infra/config/notifiers.star
@@ -71,6 +71,14 @@ ) luci.notifier( + name = "cr-fuchsia-engprod", + on_status_change = True, + notify_emails = [ + "chrome-fuchsia-engprod+builder-notification@google.com", + ], +) + +luci.notifier( name = "cronet", on_occurrence = ["FAILURE", "INFRA_FAILURE"], notify_emails = [
diff --git a/infra/config/subprojects/chromium/ci/chromium.android.fyi.star b/infra/config/subprojects/chromium/ci/chromium.android.fyi.star index ce996b9..42e61d2 100644 --- a/infra/config/subprojects/chromium/ci/chromium.android.fyi.star +++ b/infra/config/subprojects/chromium/ci/chromium.android.fyi.star
@@ -103,6 +103,9 @@ category = "reviver", short_name = "M", ), + # To avoid peak hours, we run it at 5 AM UTC, 7 AM UTC. + # TODO(zhiyuans): Increase the frequency based on previous run results. + schedule = "0 5,7 * * *", # Set to an empty list to avoid chromium-gitiles-trigger triggering new # builds. Also we don't set any `schedule` since this builder is for # reference only and should not run any new builds.
diff --git a/infra/config/subprojects/chromium/ci/chromium.fyi.star b/infra/config/subprojects/chromium/ci/chromium.fyi.star index dc4bd38f..edd0a21 100644 --- a/infra/config/subprojects/chromium/ci/chromium.fyi.star +++ b/infra/config/subprojects/chromium/ci/chromium.fyi.star
@@ -165,6 +165,18 @@ ) ci.builder( + name = "fuchsia-fyi-arm64-emu-arg", + console_view_entry = [ + consoles.console_view_entry( + category = "fuchsia|a64", + short_name = "emu-arg", + ), + ], + notifies = ["cr-fuchsia-engprod"], + os = os.LINUX_BIONIC_SWITCH_TO_DEFAULT, +) + +ci.builder( name = "fuchsia-fyi-arm64-femu", console_view_entry = [ consoles.console_view_entry(
diff --git a/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm b/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm index 4497752c..c03aea1c 100644 --- a/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm +++ b/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm
@@ -46,6 +46,7 @@ #include "ios/chrome/browser/reading_list/reading_list_model_factory.h" #import "ios/chrome/browser/safe_browsing/chrome_password_protection_service_factory.h" #import "ios/chrome/browser/safe_browsing/real_time_url_lookup_service_factory.h" +#import "ios/chrome/browser/safe_browsing/safe_browsing_client_factory.h" #import "ios/chrome/browser/safe_browsing/safe_browsing_metrics_collector_factory.h" #import "ios/chrome/browser/safe_browsing/verdict_cache_manager_factory.h" #include "ios/chrome/browser/screen_time/screen_time_buildflags.h" @@ -71,7 +72,6 @@ #include "ios/chrome/browser/undo/bookmark_undo_service_factory.h" #include "ios/chrome/browser/unified_consent/unified_consent_service_factory.h" #include "ios/chrome/browser/webdata_services/web_data_service_factory.h" -#import "ios/components/security_interstitials/safe_browsing/safe_browsing_client_factory.h" #if BUILDFLAG(IOS_CREDENTIAL_PROVIDER_ENABLED) #include "ios/chrome/browser/credential_provider/credential_provider_service_factory.h"
diff --git a/ios/chrome/browser/flags/BUILD.gn b/ios/chrome/browser/flags/BUILD.gn index 2a5d909..d04b659 100644 --- a/ios/chrome/browser/flags/BUILD.gn +++ b/ios/chrome/browser/flags/BUILD.gn
@@ -52,6 +52,7 @@ "//ios/chrome/browser/browsing_data:feature_flags", "//ios/chrome/browser/crash_report", "//ios/chrome/browser/drag_and_drop", + "//ios/chrome/browser/ntp:features", "//ios/chrome/browser/policy", "//ios/chrome/browser/policy:feature_flags", "//ios/chrome/browser/policy:policy_util",
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index aa0425f..9d96897 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -62,6 +62,7 @@ #include "ios/chrome/browser/chrome_switches.h" #include "ios/chrome/browser/crash_report/features.h" #include "ios/chrome/browser/flags/ios_chrome_flag_descriptions.h" +#import "ios/chrome/browser/ntp/features.h" #include "ios/chrome/browser/policy/cloud/user_policy_switch.h" #include "ios/chrome/browser/policy/policy_features.h" #include "ios/chrome/browser/policy/policy_util.h"
diff --git a/ios/chrome/browser/ntp/features.cc b/ios/chrome/browser/ntp/features.cc index 480d865..11760e7b 100644 --- a/ios/chrome/browser/ntp/features.cc +++ b/ios/chrome/browser/ntp/features.cc
@@ -6,3 +6,10 @@ const base::Feature kBlockNewTabPagePendingLoad{ "BlockNewTabPagePendingLoad", base::FEATURE_DISABLED_BY_DEFAULT}; + +const base::Feature kEnableWebChannels{"EnableWebChannels", + base::FEATURE_DISABLED_BY_DEFAULT}; + +bool IsWebChannelsEnabled() { + return base::FeatureList::IsEnabled(kEnableWebChannels); +} \ No newline at end of file
diff --git a/ios/chrome/browser/ntp/features.h b/ios/chrome/browser/ntp/features.h index 0fbb1d3..4c274f3 100644 --- a/ios/chrome/browser/ntp/features.h +++ b/ios/chrome/browser/ntp/features.h
@@ -10,4 +10,11 @@ // Feature flag to enable NTP UI pending loader blocker. extern const base::Feature kBlockNewTabPagePendingLoad; +// Feature flag to enable the Following feed in the NTP. +// Use IsWebChannelsEnabled() instead of this constant directly. +extern const base::Feature kEnableWebChannels; + +// Whether the Following Feed is enabled on NTP. +bool IsWebChannelsEnabled(); + #endif // IOS_CHROME_BROWSER_NTP_FEATURES_H_
diff --git a/ios/chrome/browser/safe_browsing/BUILD.gn b/ios/chrome/browser/safe_browsing/BUILD.gn index b545e08..373b66f6 100644 --- a/ios/chrome/browser/safe_browsing/BUILD.gn +++ b/ios/chrome/browser/safe_browsing/BUILD.gn
@@ -19,6 +19,7 @@ "real_time_url_lookup_service_factory.mm", "safe_browsing_blocking_page.h", "safe_browsing_blocking_page.mm", + "safe_browsing_client_factory.h", "safe_browsing_client_factory.mm", "safe_browsing_client_impl.h", "safe_browsing_client_impl.mm",
diff --git a/ios/chrome/browser/safe_browsing/fake_safe_browsing_client.h b/ios/chrome/browser/safe_browsing/fake_safe_browsing_client.h index 28ab1c36..3f50086 100644 --- a/ios/chrome/browser/safe_browsing/fake_safe_browsing_client.h +++ b/ios/chrome/browser/safe_browsing/fake_safe_browsing_client.h
@@ -16,6 +16,9 @@ FakeSafeBrowsingClient(); ~FakeSafeBrowsingClient() override; + // SafeBrowsingClient implementation. + base::WeakPtr<SafeBrowsingClient> AsWeakPtr() override; + // Controls the return value of |ShouldBlockUnsafeResource|. void set_should_block_unsafe_resource(bool should_block_unsafe_resource) { should_block_unsafe_resource_ = should_block_unsafe_resource; @@ -54,6 +57,9 @@ safe_browsing::RealTimeUrlLookupService* lookup_service_ = nullptr; bool main_frame_cancellation_decided_called_ = false; bool sub_frame_cancellation_decided_called_ = false; + + // Must be last. + base::WeakPtrFactory<FakeSafeBrowsingClient> weak_factory_{this}; }; #endif // IOS_CHROME_BROWSER_SAFE_BROWSING_FAKE_SAFE_BROWSING_CLIENT_H_
diff --git a/ios/chrome/browser/safe_browsing/fake_safe_browsing_client.mm b/ios/chrome/browser/safe_browsing/fake_safe_browsing_client.mm index 51ff903..b552c74 100644 --- a/ios/chrome/browser/safe_browsing/fake_safe_browsing_client.mm +++ b/ios/chrome/browser/safe_browsing/fake_safe_browsing_client.mm
@@ -16,6 +16,10 @@ FakeSafeBrowsingClient::~FakeSafeBrowsingClient() = default; +base::WeakPtr<SafeBrowsingClient> FakeSafeBrowsingClient::AsWeakPtr() { + return weak_factory_.GetWeakPtr(); +} + SafeBrowsingService* FakeSafeBrowsingClient::GetSafeBrowsingService() { return safe_browsing_service_.get(); }
diff --git a/ios/chrome/browser/safe_browsing/fake_safe_browsing_service.h b/ios/chrome/browser/safe_browsing/fake_safe_browsing_service.h index f46113b..376468e 100644 --- a/ios/chrome/browser/safe_browsing/fake_safe_browsing_service.h +++ b/ios/chrome/browser/safe_browsing/fake_safe_browsing_service.h
@@ -32,7 +32,8 @@ void ShutDown() override; std::unique_ptr<safe_browsing::SafeBrowsingUrlCheckerImpl> CreateUrlChecker( network::mojom::RequestDestination request_destination, - web::WebState* web_state) override; + web::WebState* web_state, + SafeBrowsingClient* client) override; bool CanCheckUrl(const GURL& url) const override; scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override; scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> GetDatabaseManager()
diff --git a/ios/chrome/browser/safe_browsing/fake_safe_browsing_service.mm b/ios/chrome/browser/safe_browsing/fake_safe_browsing_service.mm index deb8fc1..44d864e 100644 --- a/ios/chrome/browser/safe_browsing/fake_safe_browsing_service.mm +++ b/ios/chrome/browser/safe_browsing/fake_safe_browsing_service.mm
@@ -26,7 +26,8 @@ network::mojom::RequestDestination request_destination) : SafeBrowsingUrlCheckerImpl(request_destination, base::MakeRefCounted<UrlCheckerDelegateImpl>( - /*database_manager=*/nullptr), + /*database_manager=*/nullptr, + /*client=*/nullptr), base::WeakPtr<web::WebState>(), /*real_time_lookup_enabled=*/false, /*can_rt_check_subresource_url=*/false, @@ -75,7 +76,8 @@ std::unique_ptr<safe_browsing::SafeBrowsingUrlCheckerImpl> FakeSafeBrowsingService::CreateUrlChecker( network::mojom::RequestDestination request_destination, - web::WebState* web_state) { + web::WebState* web_state, + SafeBrowsingClient* client) { return std::make_unique<FakeSafeBrowsingUrlCheckerImpl>(request_destination); }
diff --git a/ios/components/security_interstitials/safe_browsing/safe_browsing_client_factory.h b/ios/chrome/browser/safe_browsing/safe_browsing_client_factory.h similarity index 81% rename from ios/components/security_interstitials/safe_browsing/safe_browsing_client_factory.h rename to ios/chrome/browser/safe_browsing/safe_browsing_client_factory.h index c5a748d..d07299c 100644 --- a/ios/components/security_interstitials/safe_browsing/safe_browsing_client_factory.h +++ b/ios/chrome/browser/safe_browsing/safe_browsing_client_factory.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_COMPONENTS_SECURITY_INTERSTITIALS_SAFE_BROWSING_SAFE_BROWSING_CLIENT_FACTORY_H_ -#define IOS_COMPONENTS_SECURITY_INTERSTITIALS_SAFE_BROWSING_SAFE_BROWSING_CLIENT_FACTORY_H_ +#ifndef IOS_CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_CLIENT_FACTORY_H_ +#define IOS_CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_CLIENT_FACTORY_H_ #include <memory> @@ -41,4 +41,4 @@ web::BrowserState* context) const override; }; -#endif // IOS_COMPONENTS_SECURITY_INTERSTITIALS_SAFE_BROWSING_SAFE_BROWSING_CLIENT_FACTORY_H_ +#endif // IOS_CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_CLIENT_FACTORY_H_
diff --git a/ios/chrome/browser/safe_browsing/safe_browsing_client_factory.mm b/ios/chrome/browser/safe_browsing/safe_browsing_client_factory.mm index f369fb1d..8c1f3fc 100644 --- a/ios/chrome/browser/safe_browsing/safe_browsing_client_factory.mm +++ b/ios/chrome/browser/safe_browsing/safe_browsing_client_factory.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/components/security_interstitials/safe_browsing/safe_browsing_client_factory.h" +#import "ios/chrome/browser/safe_browsing/safe_browsing_client_factory.h" #import <memory>
diff --git a/ios/chrome/browser/safe_browsing/safe_browsing_client_factory_unittest.mm b/ios/chrome/browser/safe_browsing/safe_browsing_client_factory_unittest.mm index 74e7ddfd..e34c82e7 100644 --- a/ios/chrome/browser/safe_browsing/safe_browsing_client_factory_unittest.mm +++ b/ios/chrome/browser/safe_browsing/safe_browsing_client_factory_unittest.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/components/security_interstitials/safe_browsing/safe_browsing_client_factory.h" +#import "ios/chrome/browser/safe_browsing/safe_browsing_client_factory.h" #import "ios/chrome/browser/browser_state/test_chrome_browser_state.h" #import "ios/web/public/test/web_task_environment.h"
diff --git a/ios/chrome/browser/safe_browsing/safe_browsing_client_impl.h b/ios/chrome/browser/safe_browsing/safe_browsing_client_impl.h index a1c79225..a10e38a 100644 --- a/ios/chrome/browser/safe_browsing/safe_browsing_client_impl.h +++ b/ios/chrome/browser/safe_browsing/safe_browsing_client_impl.h
@@ -16,7 +16,10 @@ safe_browsing::RealTimeUrlLookupService* lookup_service, PrerenderService* prerender_service); + ~SafeBrowsingClientImpl() override; + // SafeBrowsingClient implementation. + base::WeakPtr<SafeBrowsingClient> AsWeakPtr() override; SafeBrowsingService* GetSafeBrowsingService() override; safe_browsing::RealTimeUrlLookupService* GetRealTimeUrlLookupService() override; @@ -30,6 +33,9 @@ private: safe_browsing::RealTimeUrlLookupService* lookup_service_; PrerenderService* prerender_service_; + + // Must be last. + base::WeakPtrFactory<SafeBrowsingClientImpl> weak_factory_{this}; }; #endif // IOS_CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_CLIENT_IMPL_H_
diff --git a/ios/chrome/browser/safe_browsing/safe_browsing_client_impl.mm b/ios/chrome/browser/safe_browsing/safe_browsing_client_impl.mm index b7e8934..dc901aac 100644 --- a/ios/chrome/browser/safe_browsing/safe_browsing_client_impl.mm +++ b/ios/chrome/browser/safe_browsing/safe_browsing_client_impl.mm
@@ -5,6 +5,7 @@ #import "ios/chrome/browser/safe_browsing/safe_browsing_client_impl.h" #import "base/check.h" +#import "base/memory/weak_ptr.h" #import "components/safe_browsing/core/browser/realtime/url_lookup_service.h" #import "components/security_interstitials/core/unsafe_resource.h" #import "ios/chrome/browser/application_context.h" @@ -20,6 +21,12 @@ PrerenderService* prerender_service) : lookup_service_(lookup_service), prerender_service_(prerender_service) {} +SafeBrowsingClientImpl::~SafeBrowsingClientImpl() = default; + +base::WeakPtr<SafeBrowsingClient> SafeBrowsingClientImpl::AsWeakPtr() { + return weak_factory_.GetWeakPtr(); +} + SafeBrowsingService* SafeBrowsingClientImpl::GetSafeBrowsingService() { return GetApplicationContext()->GetSafeBrowsingService(); }
diff --git a/ios/chrome/browser/safe_browsing/safe_browsing_query_manager.h b/ios/chrome/browser/safe_browsing/safe_browsing_query_manager.h index 014b9d40..7565479 100644 --- a/ios/chrome/browser/safe_browsing/safe_browsing_query_manager.h +++ b/ios/chrome/browser/safe_browsing/safe_browsing_query_manager.h
@@ -25,6 +25,8 @@ class NavigationItem; } +class SafeBrowsingClient; + // A helper object that manages the Safe Browsing URL queries for a single // WebState. class SafeBrowsingQueryManager @@ -84,6 +86,12 @@ SafeBrowsingQueryManager* manager) {} }; + static void CreateForWebState(web::WebState* web_state, + SafeBrowsingClient* client); + + SafeBrowsingQueryManager(web::WebState* web_state, + SafeBrowsingClient* client); + ~SafeBrowsingQueryManager() override; SafeBrowsingQueryManager(const SafeBrowsingQueryManager&) = delete; @@ -154,14 +162,14 @@ active_url_checkers_; }; - explicit SafeBrowsingQueryManager(web::WebState* web_state); - // Used as the completion callback for URL queries executed by // |url_checker_client_|. void UrlCheckFinished(const Query query, bool proceed, bool show_error_page); // The WebState whose URL queries are being managed. web::WebState* web_state_ = nullptr; + // The safe browsing client. + SafeBrowsingClient* client_ = nullptr; // The checker client. Used to communicate with the database on the IO // thread. std::unique_ptr<UrlCheckerClient> url_checker_client_;
diff --git a/ios/chrome/browser/safe_browsing/safe_browsing_query_manager.mm b/ios/chrome/browser/safe_browsing/safe_browsing_query_manager.mm index 0cb51b4..371c221 100644 --- a/ios/chrome/browser/safe_browsing/safe_browsing_query_manager.mm +++ b/ios/chrome/browser/safe_browsing/safe_browsing_query_manager.mm
@@ -8,7 +8,6 @@ #include "base/check_op.h" #include "ios/chrome/browser/safe_browsing/safe_browsing_service.h" #include "ios/components/security_interstitials/safe_browsing/safe_browsing_client.h" -#include "ios/components/security_interstitials/safe_browsing/safe_browsing_client_factory.h" #include "ios/web/public/thread/web_task_traits.h" #include "ios/web/public/thread/web_thread.h" #include "services/network/public/mojom/fetch_api.mojom.h" @@ -31,8 +30,21 @@ #pragma mark - SafeBrowsingQueryManager -SafeBrowsingQueryManager::SafeBrowsingQueryManager(web::WebState* web_state) +// static +void SafeBrowsingQueryManager::CreateForWebState(web::WebState* web_state, + SafeBrowsingClient* client) { + if (FromWebState(web_state)) + return; + + web_state->SetUserData( + UserDataKey(), + std::make_unique<SafeBrowsingQueryManager>(web_state, client)); +} + +SafeBrowsingQueryManager::SafeBrowsingQueryManager(web::WebState* web_state, + SafeBrowsingClient* client) : web_state_(web_state), + client_(client), url_checker_client_(std::make_unique<UrlCheckerClient>()) { DCHECK(web_state_); } @@ -62,13 +74,11 @@ network::mojom::RequestDestination request_destination = query.IsMainFrame() ? network::mojom::RequestDestination::kDocument : network::mojom::RequestDestination::kIframe; - SafeBrowsingClient* safe_browsing_client = - SafeBrowsingClientFactory::GetForBrowserState( - web_state_->GetBrowserState()); SafeBrowsingService* safe_browsing_service = - safe_browsing_client->GetSafeBrowsingService(); + client_->GetSafeBrowsingService(); std::unique_ptr<safe_browsing::SafeBrowsingUrlCheckerImpl> url_checker = - safe_browsing_service->CreateUrlChecker(request_destination, web_state_); + safe_browsing_service->CreateUrlChecker(request_destination, web_state_, + client_); base::OnceCallback<void(bool proceed, bool show_error_page)> callback = base::BindOnce(&SafeBrowsingQueryManager::UrlCheckFinished, weak_factory_.GetWeakPtr(), query);
diff --git a/ios/chrome/browser/safe_browsing/safe_browsing_query_manager_unittest.mm b/ios/chrome/browser/safe_browsing/safe_browsing_query_manager_unittest.mm index c224670e..7336e0a1 100644 --- a/ios/chrome/browser/safe_browsing/safe_browsing_query_manager_unittest.mm +++ b/ios/chrome/browser/safe_browsing/safe_browsing_query_manager_unittest.mm
@@ -9,7 +9,6 @@ #include "components/security_interstitials/core/unsafe_resource.h" #import "ios/chrome/browser/safe_browsing/fake_safe_browsing_client.h" #import "ios/chrome/browser/safe_browsing/fake_safe_browsing_service.h" -#import "ios/components/security_interstitials/safe_browsing/safe_browsing_client_factory.h" #import "ios/web/public/test/fakes/fake_browser_state.h" #import "ios/web/public/test/fakes/fake_web_state.h" #include "ios/web/public/test/web_task_environment.h" @@ -86,17 +85,9 @@ navigation_item_id_( GetParam() == network::mojom::RequestDestination::kDocument ? -1 : 0) { - SafeBrowsingQueryManager::CreateForWebState(web_state_.get()); + SafeBrowsingQueryManager::CreateForWebState(web_state_.get(), &client_); manager()->AddObserver(&observer_); web_state_->SetBrowserState(browser_state_.get()); - - // Set up the test safe browsing client factory. - SafeBrowsingClientFactory::GetInstance()->SetTestingFactory( - browser_state_.get(), - base::BindRepeating( - [](web::BrowserState*) -> std::unique_ptr<KeyedService> { - return std::make_unique<FakeSafeBrowsingClient>(); - })); } SafeBrowsingQueryManager* manager() { @@ -109,6 +100,7 @@ std::unique_ptr<web::FakeWebState> web_state_; std::string http_method_; int navigation_item_id_ = 0; + FakeSafeBrowsingClient client_; }; // Tests a query for a safe URL. @@ -220,14 +212,6 @@ : browser_state_(new web::FakeBrowserState()), web_state_(std::make_unique<web::FakeWebState>()) { web_state_->SetBrowserState(browser_state_.get()); - - // Set up the test safe browsing client factory. - SafeBrowsingClientFactory::GetInstance()->SetTestingFactory( - browser_state_.get(), - base::BindRepeating( - [](web::BrowserState*) -> std::unique_ptr<KeyedService> { - return std::make_unique<FakeSafeBrowsingClient>(); - })); } ~WebStateDestroyingQueryManagerObserver() override {} @@ -262,7 +246,8 @@ navigation_item_id_( GetParam() == network::mojom::RequestDestination::kDocument ? -1 : 0) { - SafeBrowsingQueryManager::CreateForWebState(observer_.web_state()); + SafeBrowsingQueryManager::CreateForWebState(observer_.web_state(), + &client_); manager()->AddObserver(&observer_); } @@ -274,6 +259,7 @@ WebStateDestroyingQueryManagerObserver observer_; std::string http_method_; int navigation_item_id_ = 0; + FakeSafeBrowsingClient client_; }; // Tests that a query for a safe URL doesn't cause a crash.
diff --git a/ios/chrome/browser/safe_browsing/safe_browsing_service.h b/ios/chrome/browser/safe_browsing/safe_browsing_service.h index a14e52b..c0e004c 100644 --- a/ios/chrome/browser/safe_browsing/safe_browsing_service.h +++ b/ios/chrome/browser/safe_browsing/safe_browsing_service.h
@@ -14,6 +14,7 @@ #include "url/gurl.h" class PrefService; +class SafeBrowsingClient; namespace base { class FilePath; @@ -57,7 +58,8 @@ // SafeBrowsingDatabaseManager owned by this service. virtual std::unique_ptr<safe_browsing::SafeBrowsingUrlCheckerImpl> CreateUrlChecker(network::mojom::RequestDestination request_destination, - web::WebState* web_state) = 0; + web::WebState* web_state, + SafeBrowsingClient* client) = 0; // Returns true if |url| has a scheme that is handled by Safe Browsing. virtual bool CanCheckUrl(const GURL& url) const = 0;
diff --git a/ios/chrome/browser/safe_browsing/safe_browsing_service_impl.h b/ios/chrome/browser/safe_browsing/safe_browsing_service_impl.h index c843609..18c4c1c8 100644 --- a/ios/chrome/browser/safe_browsing/safe_browsing_service_impl.h +++ b/ios/chrome/browser/safe_browsing/safe_browsing_service_impl.h
@@ -25,7 +25,6 @@ namespace safe_browsing { class SafeBrowsingDatabaseManager; -class UrlCheckerDelegate; } // namespace safe_browsing // This class must be created on the UI thread. @@ -44,7 +43,8 @@ void ShutDown() override; std::unique_ptr<safe_browsing::SafeBrowsingUrlCheckerImpl> CreateUrlChecker( network::mojom::RequestDestination request_destination, - web::WebState* web_state) override; + web::WebState* web_state, + SafeBrowsingClient* client) override; bool CanCheckUrl(const GURL& url) const override; scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override; scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> GetDatabaseManager() @@ -149,9 +149,6 @@ scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> safe_browsing_db_manager_; - // Delegate for SafeBrowsingUrlCheckerImpl instances. - scoped_refptr<safe_browsing::UrlCheckerDelegate> url_checker_delegate_; - // This watches for changes to the Safe Browsing opt-out preference. std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_;
diff --git a/ios/chrome/browser/safe_browsing/safe_browsing_service_impl.mm b/ios/chrome/browser/safe_browsing/safe_browsing_service_impl.mm index 100fcba..1cd20cd 100644 --- a/ios/chrome/browser/safe_browsing/safe_browsing_service_impl.mm +++ b/ios/chrome/browser/safe_browsing/safe_browsing_service_impl.mm
@@ -19,7 +19,6 @@ #import "ios/chrome/browser/safe_browsing/url_checker_delegate_impl.h" #import "ios/components/cookie_util/cookie_util.h" #include "ios/components/security_interstitials/safe_browsing/safe_browsing_client.h" -#include "ios/components/security_interstitials/safe_browsing/safe_browsing_client_factory.h" #import "ios/net/cookies/system_cookie_store.h" #import "ios/web/common/user_agent.h" #include "ios/web/public/thread/web_task_traits.h" @@ -60,9 +59,6 @@ web::GetIOThreadTaskRunner({}), safe_browsing::ExtendedReportingLevelCallback()); - url_checker_delegate_ = - base::MakeRefCounted<UrlCheckerDelegateImpl>(safe_browsing_db_manager_); - io_thread_enabler_ = base::MakeRefCounted<IOThreadEnabler>(safe_browsing_db_manager_); @@ -113,19 +109,19 @@ std::unique_ptr<safe_browsing::SafeBrowsingUrlCheckerImpl> SafeBrowsingServiceImpl::CreateUrlChecker( network::mojom::RequestDestination request_destination, - web::WebState* web_state) { - SafeBrowsingClient* safe_browsing_client = - SafeBrowsingClientFactory::GetForBrowserState( - web_state->GetBrowserState()); + web::WebState* web_state, + SafeBrowsingClient* client) { safe_browsing::RealTimeUrlLookupService* url_lookup_service = - safe_browsing_client->GetRealTimeUrlLookupService(); - + client->GetRealTimeUrlLookupService(); bool can_perform_full_url_lookup = url_lookup_service && url_lookup_service->CanPerformFullURLLookup(); bool can_realtime_check_subresource_url = url_lookup_service && url_lookup_service->CanCheckSubresourceURL(); + scoped_refptr<safe_browsing::UrlCheckerDelegate> url_checker_delegate = + base::MakeRefCounted<UrlCheckerDelegateImpl>(safe_browsing_db_manager_, + client->AsWeakPtr()); return std::make_unique<safe_browsing::SafeBrowsingUrlCheckerImpl>( - request_destination, url_checker_delegate_, web_state->GetWeakPtr(), + request_destination, url_checker_delegate, web_state->GetWeakPtr(), can_perform_full_url_lookup, can_realtime_check_subresource_url, web::GetUIThreadTaskRunner({}), url_lookup_service ? url_lookup_service->GetWeakPtr() : nullptr);
diff --git a/ios/chrome/browser/safe_browsing/safe_browsing_service_unittest.mm b/ios/chrome/browser/safe_browsing/safe_browsing_service_unittest.mm index aea6a47f..dca0a00 100644 --- a/ios/chrome/browser/safe_browsing/safe_browsing_service_unittest.mm +++ b/ios/chrome/browser/safe_browsing/safe_browsing_service_unittest.mm
@@ -34,7 +34,6 @@ #include "components/unified_consent/unified_consent_service.h" #import "ios/chrome/browser/safe_browsing/fake_safe_browsing_client.h" #import "ios/chrome/browser/safe_browsing/safe_browsing_query_manager.h" -#import "ios/components/security_interstitials/safe_browsing/safe_browsing_client_factory.h" #import "ios/components/security_interstitials/safe_browsing/safe_browsing_unsafe_resource_container.h" #import "ios/web/public/test/fakes/fake_browser_state.h" #import "ios/web/public/test/fakes/fake_web_state.h" @@ -60,9 +59,12 @@ class TestUrlCheckerClient { public: TestUrlCheckerClient(SafeBrowsingService* safe_browsing_service, - web::BrowserState* browser_state) - : safe_browsing_service_(safe_browsing_service) { - SafeBrowsingQueryManager::CreateForWebState(&web_state_); + web::BrowserState* browser_state, + SafeBrowsingClient* safe_browsing_client) + : safe_browsing_service_(safe_browsing_service), + safe_browsing_client_(safe_browsing_client) { + SafeBrowsingQueryManager::CreateForWebState(&web_state_, + safe_browsing_client_); SafeBrowsingUrlAllowList::CreateForWebState(&web_state_); SafeBrowsingUnsafeResourceContainer::CreateForWebState(&web_state_); web_state_.SetBrowserState(browser_state); @@ -78,7 +80,8 @@ void CheckUrl(const GURL& url) { result_pending_ = true; url_checker_ = safe_browsing_service_->CreateUrlChecker( - network::mojom::RequestDestination::kDocument, &web_state_); + network::mojom::RequestDestination::kDocument, &web_state_, + safe_browsing_client_); web::GetIOThreadTaskRunner({})->PostTask( FROM_HERE, base::BindOnce(&TestUrlCheckerClient::CheckUrlOnIOThread, base::Unretained(this), url)); @@ -87,7 +90,8 @@ void CheckSubFrameUrl(const GURL& url) { result_pending_ = true; url_checker_ = safe_browsing_service_->CreateUrlChecker( - network::mojom::RequestDestination::kIframe, &web_state_); + network::mojom::RequestDestination::kIframe, &web_state_, + safe_browsing_client_); web::GetIOThreadTaskRunner({})->PostTask( FROM_HERE, base::BindOnce(&TestUrlCheckerClient::CheckUrlOnIOThread, base::Unretained(this), url)); @@ -132,6 +136,7 @@ SafeBrowsingService* safe_browsing_service_; web::FakeWebState web_state_; std::unique_ptr<safe_browsing::SafeBrowsingUrlCheckerImpl> url_checker_; + SafeBrowsingClient* safe_browsing_client_; }; } // namespace @@ -169,12 +174,7 @@ /*safe_browsing_metrics_collector=*/nullptr); base::RunLoop().RunUntilIdle(); - // Set up the test safe browsing client factory. - SafeBrowsingClientFactory::GetInstance()->SetTestingFactory( - browser_state_.get(), - base::BindRepeating( - &SafeBrowsingServiceTest::CreateFakeSafeBrowsingClient, - base::Unretained(this))); + SetupUrlLookupService(); } SafeBrowsingServiceTest(const SafeBrowsingServiceTest&) = delete; @@ -229,6 +229,7 @@ scoped_refptr<SafeBrowsingService> safe_browsing_service_; std::unique_ptr<web::FakeBrowserState> browser_state_; std::unique_ptr<sync_preferences::TestingPrefServiceSyncable> pref_service_; + FakeSafeBrowsingClient safe_browsing_client_; private: void MarkUrlAsMalwareOnIOThread(const GURL& bad_url) { @@ -252,12 +253,7 @@ v4_get_hash_factory_->AddToFullHashCache(full_hash_info); } - // Creates a fake safe browsing client and injects other fakes needed to - // control lookup service. - std::unique_ptr<KeyedService> CreateFakeSafeBrowsingClient( - web::BrowserState* context) { - std::unique_ptr<FakeSafeBrowsingClient> client = - std::make_unique<FakeSafeBrowsingClient>(); + void SetupUrlLookupService() { host_content_settings_map_ = base::MakeRefCounted<HostContentSettingsMap>( pref_service_.get(), /*is_off_the_record=*/false, /*store_last_modified=*/false, /*restore_session=*/false); @@ -277,8 +273,8 @@ /*is_off_the_record=*/false, /*variations_service=*/nullptr, /*referrer_chain_provider=*/nullptr); - client->set_real_time_url_lookup_service(lookup_service_.get()); - return client; + safe_browsing_client_.set_real_time_url_lookup_service( + lookup_service_.get()); } base::ScopedTempDir temp_dir_; @@ -298,7 +294,7 @@ // Verify that queries to the Safe Browsing database owned by // SafeBrowsingService receive responses. TestUrlCheckerClient client(safe_browsing_service_.get(), - browser_state_.get()); + browser_state_.get(), &safe_browsing_client_); GURL safe_url = GURL(kSafePage); client.CheckUrl(safe_url); EXPECT_TRUE(client.result_pending()); @@ -328,7 +324,7 @@ // expected. TEST_F(SafeBrowsingServiceTest, RealTimeSafeAndUnsafePages) { TestUrlCheckerClient client(safe_browsing_service_.get(), - browser_state_.get()); + browser_state_.get(), &safe_browsing_client_); // Wait for an initial result to make sure the Safe Browsing database has // been initialized, before calling into functions that mark URLs as safe @@ -373,7 +369,7 @@ feature_list.InitAndEnableFeature(safe_browsing::kEnhancedProtection); TestUrlCheckerClient client(safe_browsing_service_.get(), - browser_state_.get()); + browser_state_.get(), &safe_browsing_client_); // Wait for an initial result to make sure the Safe Browsing database has // been initialized, before calling into functions that mark URLs as safe
diff --git a/ios/chrome/browser/safe_browsing/safe_browsing_tab_helper.h b/ios/chrome/browser/safe_browsing/safe_browsing_tab_helper.h index 6702c56..bbf94bc 100644 --- a/ios/chrome/browser/safe_browsing/safe_browsing_tab_helper.h +++ b/ios/chrome/browser/safe_browsing/safe_browsing_tab_helper.h
@@ -25,11 +25,18 @@ class NavigationItem; } +class SafeBrowsingClient; + // A tab helper that uses Safe Browsing to check whether URLs that are being // navigated to are unsafe. class SafeBrowsingTabHelper : public web::WebStateUserData<SafeBrowsingTabHelper> { public: + static void CreateForWebState(web::WebState* web_state, + SafeBrowsingClient* client); + + SafeBrowsingTabHelper(web::WebState* web_state, SafeBrowsingClient* client); + ~SafeBrowsingTabHelper() override; SafeBrowsingTabHelper(const SafeBrowsingTabHelper&) = delete; @@ -45,7 +52,7 @@ class PolicyDecider : public web::WebStatePolicyDecider, public base::SupportsWeakPtr<PolicyDecider> { public: - PolicyDecider(web::WebState* web_state); + PolicyDecider(web::WebState* web_state, SafeBrowsingClient* client); ~PolicyDecider() override; // Returns whether |query| is still relevant. May return false if @@ -145,6 +152,8 @@ // The URL check query manager. SafeBrowsingQueryManager* query_manager_; + // The safe browsing client. + SafeBrowsingClient* client_ = nullptr; // The pending query for the main frame navigation, if any. absl::optional<MainFrameUrlQuery> pending_main_frame_query_; // The previous query for main frame, navigation, if any. This is tracked @@ -206,8 +215,6 @@ scoped_observation_{this}; }; - explicit SafeBrowsingTabHelper(web::WebState* web_state); - PolicyDecider policy_decider_; QueryObserver query_observer_; NavigationObserver navigation_observer_;
diff --git a/ios/chrome/browser/safe_browsing/safe_browsing_tab_helper.mm b/ios/chrome/browser/safe_browsing/safe_browsing_tab_helper.mm index 8d458de..c827bba 100644 --- a/ios/chrome/browser/safe_browsing/safe_browsing_tab_helper.mm +++ b/ios/chrome/browser/safe_browsing/safe_browsing_tab_helper.mm
@@ -16,7 +16,6 @@ #import "components/safe_browsing/ios/browser/safe_browsing_url_allow_list.h" #include "ios/chrome/browser/safe_browsing/safe_browsing_service.h" #include "ios/components/security_interstitials/safe_browsing/safe_browsing_client.h" -#include "ios/components/security_interstitials/safe_browsing/safe_browsing_client_factory.h" #import "ios/components/security_interstitials/safe_browsing/safe_browsing_error.h" #import "ios/components/security_interstitials/safe_browsing/safe_browsing_unsafe_resource_container.h" #import "ios/web/public/navigation/navigation_context.h" @@ -64,8 +63,19 @@ #pragma mark - SafeBrowsingTabHelper -SafeBrowsingTabHelper::SafeBrowsingTabHelper(web::WebState* web_state) - : policy_decider_(web_state), +// static +void SafeBrowsingTabHelper::CreateForWebState(web::WebState* web_state, + SafeBrowsingClient* client) { + if (FromWebState(web_state)) + return; + + web_state->SetUserData(UserDataKey(), std::make_unique<SafeBrowsingTabHelper>( + web_state, client)); +} + +SafeBrowsingTabHelper::SafeBrowsingTabHelper(web::WebState* web_state, + SafeBrowsingClient* client) + : policy_decider_(web_state, client), query_observer_(web_state, &policy_decider_), navigation_observer_(web_state, &policy_decider_) {} @@ -75,9 +85,11 @@ #pragma mark - SafeBrowsingTabHelper::PolicyDecider -SafeBrowsingTabHelper::PolicyDecider::PolicyDecider(web::WebState* web_state) +SafeBrowsingTabHelper::PolicyDecider::PolicyDecider(web::WebState* web_state, + SafeBrowsingClient* client) : web::WebStatePolicyDecider(web_state), - query_manager_(SafeBrowsingQueryManager::FromWebState(web_state)) {} + query_manager_(SafeBrowsingQueryManager::FromWebState(web_state)), + client_(client) {} SafeBrowsingTabHelper::PolicyDecider::~PolicyDecider() = default; @@ -135,11 +147,8 @@ web::WebStatePolicyDecider::PolicyDecisionCallback callback) { // Allow navigations for URLs that cannot be checked by the service. GURL request_url = GetCanonicalizedUrl(net::GURLWithNSURL(request.URL)); - SafeBrowsingClient* safe_browsing_client = - SafeBrowsingClientFactory::GetForBrowserState( - web_state()->GetBrowserState()); SafeBrowsingService* safe_browsing_service = - safe_browsing_client->GetSafeBrowsingService(); + client_->GetSafeBrowsingService(); if (!safe_browsing_service->CanCheckUrl(request_url)) { return std::move(callback).Run( web::WebStatePolicyDecider::PolicyDecision::Allow()); @@ -224,11 +233,8 @@ web::WebStatePolicyDecider::ResponseInfo response_info, web::WebStatePolicyDecider::PolicyDecisionCallback callback) { // Allow navigations for URLs that cannot be checked by the service. - SafeBrowsingClient* safe_browsing_client = - SafeBrowsingClientFactory::GetForBrowserState( - web_state()->GetBrowserState()); SafeBrowsingService* safe_browsing_service = - safe_browsing_client->GetSafeBrowsingService(); + client_->GetSafeBrowsingService(); GURL response_url = GetCanonicalizedUrl(net::GURLWithNSURL(response.URL)); if (!safe_browsing_service->CanCheckUrl(response_url)) { return std::move(callback).Run( @@ -348,12 +354,8 @@ } } - SafeBrowsingClient* safe_browsing_client = - SafeBrowsingClientFactory::GetForBrowserState( - web_state()->GetBrowserState()); if (decision.ShouldCancelNavigation()) { - safe_browsing_client->OnMainFrameUrlQueryCancellationDecided(web_state(), - url); + client_->OnMainFrameUrlQueryCancellationDecided(web_state(), url); } } @@ -378,14 +380,10 @@ } sub_frame_query.response_callbacks.clear(); - SafeBrowsingClient* safe_browsing_client = - SafeBrowsingClientFactory::GetForBrowserState( - web_state()->GetBrowserState()); bool should_display_error = false; if (decision.ShouldCancelNavigation()) { should_display_error = - safe_browsing_client->OnSubFrameUrlQueryCancellationDecided(web_state(), - url); + client_->OnSubFrameUrlQueryCancellationDecided(web_state(), url); } // Error pages are only shown for cancelled main frame navigations, so
diff --git a/ios/chrome/browser/safe_browsing/safe_browsing_tab_helper_unittest.mm b/ios/chrome/browser/safe_browsing/safe_browsing_tab_helper_unittest.mm index 376edcb..d732cff3 100644 --- a/ios/chrome/browser/safe_browsing/safe_browsing_tab_helper_unittest.mm +++ b/ios/chrome/browser/safe_browsing/safe_browsing_tab_helper_unittest.mm
@@ -12,7 +12,6 @@ #import "ios/chrome/browser/safe_browsing/fake_safe_browsing_client.h" #import "ios/chrome/browser/safe_browsing/fake_safe_browsing_service.h" #import "ios/chrome/browser/safe_browsing/safe_browsing_query_manager.h" -#import "ios/components/security_interstitials/safe_browsing/safe_browsing_client_factory.h" #import "ios/components/security_interstitials/safe_browsing/safe_browsing_error.h" #import "ios/components/security_interstitials/safe_browsing/safe_browsing_unsafe_resource_container.h" #import "ios/web/public/navigation/navigation_item.h" @@ -41,19 +40,14 @@ SafeBrowsingTabHelperTest() : task_environment_(web::WebTaskEnvironment::IO_MAINLOOP), browser_state_(std::make_unique<web::FakeBrowserState>()) { - SafeBrowsingQueryManager::CreateForWebState(&web_state_); - SafeBrowsingTabHelper::CreateForWebState(&web_state_); + SafeBrowsingQueryManager::CreateForWebState(&web_state_, &client_); + SafeBrowsingTabHelper::CreateForWebState(&web_state_, &client_); SafeBrowsingUrlAllowList::CreateForWebState(&web_state_); SafeBrowsingUnsafeResourceContainer::CreateForWebState(&web_state_); auto navigation_manager = std::make_unique<web::FakeNavigationManager>(); navigation_manager_ = navigation_manager.get(); web_state_.SetNavigationManager(std::move(navigation_manager)); web_state_.SetBrowserState(browser_state_.get()); - SafeBrowsingClientFactory::GetInstance()->SetTestingFactory( - browser_state_.get(), - base::BindRepeating( - &SafeBrowsingTabHelperTest::CreateFakeSafeBrowsingClient, - base::Unretained(this))); } // Whether Safe Browsing decisions arrive before calls to @@ -136,15 +130,6 @@ web_state_.OnNavigationRedirected(&context); } - // Returns a FakeSafeBrowsingClient. - std::unique_ptr<KeyedService> CreateFakeSafeBrowsingClient( - web::BrowserState* context) { - std::unique_ptr<FakeSafeBrowsingClient> service = - std::make_unique<FakeSafeBrowsingClient>(); - client_ = service.get(); - return service; - } - // Stores an UnsafeResource for |url| in the query manager. It is expected // that an UnsafeResource is stored before check completion for unsafe URLs // that show an error page. @@ -163,7 +148,7 @@ std::unique_ptr<web::FakeBrowserState> browser_state_; web::FakeWebState web_state_; web::FakeNavigationManager* navigation_manager_ = nullptr; - FakeSafeBrowsingClient* client_ = nullptr; + FakeSafeBrowsingClient client_; }; // Tests the case of a single navigation request and response, for a URL that is @@ -948,15 +933,15 @@ // When |unsafe_url| is determined to be unsafe, the client should be // notified. - EXPECT_FALSE(client_->main_frame_cancellation_decided_called()); + EXPECT_FALSE(client_.main_frame_cancellation_decided_called()); if (SafeBrowsingDecisionArrivesBeforeResponse()) { base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(client_->main_frame_cancellation_decided_called()); + EXPECT_TRUE(client_.main_frame_cancellation_decided_called()); } else { web::WebStatePolicyDecider::PolicyDecision response_decision = ShouldAllowResponseUrl(unsafe_url); EXPECT_TRUE(response_decision.ShouldCancelNavigation()); - EXPECT_TRUE(client_->main_frame_cancellation_decided_called()); + EXPECT_TRUE(client_.main_frame_cancellation_decided_called()); } } @@ -972,15 +957,15 @@ // When |unsafe_url| is determined to be unsafe, the client should be // notified. - EXPECT_FALSE(client_->sub_frame_cancellation_decided_called()); + EXPECT_FALSE(client_.sub_frame_cancellation_decided_called()); if (SafeBrowsingDecisionArrivesBeforeResponse()) { base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(client_->sub_frame_cancellation_decided_called()); + EXPECT_TRUE(client_.sub_frame_cancellation_decided_called()); } else { web::WebStatePolicyDecider::PolicyDecision response_decision = ShouldAllowResponseUrl(unsafe_url, /*for_main_frame=*/false); EXPECT_TRUE(response_decision.ShouldCancelNavigation()); - EXPECT_TRUE(client_->sub_frame_cancellation_decided_called()); + EXPECT_TRUE(client_.sub_frame_cancellation_decided_called()); } } @@ -990,14 +975,14 @@ EXPECT_TRUE(ShouldAllowRequestUrl(safe_url).ShouldAllowNavigation()); - EXPECT_FALSE(client_->main_frame_cancellation_decided_called()); + EXPECT_FALSE(client_.main_frame_cancellation_decided_called()); if (SafeBrowsingDecisionArrivesBeforeResponse()) base::RunLoop().RunUntilIdle(); web::WebStatePolicyDecider::PolicyDecision response_decision = ShouldAllowResponseUrl(safe_url); EXPECT_TRUE(response_decision.ShouldAllowNavigation()); - EXPECT_FALSE(client_->main_frame_cancellation_decided_called()); + EXPECT_FALSE(client_.main_frame_cancellation_decided_called()); } // Tests that client is not notified when a sub frame URL is safe. @@ -1008,14 +993,14 @@ EXPECT_TRUE(ShouldAllowRequestUrl(safe_url, /*for_main_frame=*/false) .ShouldAllowNavigation()); - EXPECT_FALSE(client_->sub_frame_cancellation_decided_called()); + EXPECT_FALSE(client_.sub_frame_cancellation_decided_called()); if (SafeBrowsingDecisionArrivesBeforeResponse()) base::RunLoop().RunUntilIdle(); web::WebStatePolicyDecider::PolicyDecision response_decision = ShouldAllowResponseUrl(safe_url, /*for_main_frame=*/false); EXPECT_TRUE(response_decision.ShouldAllowNavigation()); - EXPECT_FALSE(client_->sub_frame_cancellation_decided_called()); + EXPECT_FALSE(client_.sub_frame_cancellation_decided_called()); } INSTANTIATE_TEST_SUITE_P(
diff --git a/ios/chrome/browser/safe_browsing/url_checker_delegate_impl.h b/ios/chrome/browser/safe_browsing/url_checker_delegate_impl.h index 51c0cb0e..bdcc6cc 100644 --- a/ios/chrome/browser/safe_browsing/url_checker_delegate_impl.h +++ b/ios/chrome/browser/safe_browsing/url_checker_delegate_impl.h
@@ -6,8 +6,11 @@ #define IOS_CHROME_BROWSER_SAFE_BROWSING_URL_CHECKER_DELEGATE_IMPL_H_ #include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" #include "components/safe_browsing/core/browser/url_checker_delegate.h" +class SafeBrowsingClient; + namespace safe_browsing { class SafeBrowsingDatabaseManager; } // namespace safe_browsing @@ -18,7 +21,8 @@ public: UrlCheckerDelegateImpl( scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> - database_manager); + database_manager, + base::WeakPtr<SafeBrowsingClient> client); UrlCheckerDelegateImpl(const UrlCheckerDelegateImpl&) = delete; UrlCheckerDelegateImpl& operator=(const UrlCheckerDelegateImpl&) = delete; @@ -60,6 +64,7 @@ safe_browsing::BaseUIManager* GetUIManager() override; scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager_; + base::WeakPtr<SafeBrowsingClient> client_; safe_browsing::SBThreatTypeSet threat_types_; };
diff --git a/ios/chrome/browser/safe_browsing/url_checker_delegate_impl.mm b/ios/chrome/browser/safe_browsing/url_checker_delegate_impl.mm index 199844e3..29f9859 100644 --- a/ios/chrome/browser/safe_browsing/url_checker_delegate_impl.mm +++ b/ios/chrome/browser/safe_browsing/url_checker_delegate_impl.mm
@@ -10,7 +10,6 @@ #include "components/security_interstitials/core/unsafe_resource.h" #import "ios/chrome/browser/safe_browsing/safe_browsing_query_manager.h" #include "ios/components/security_interstitials/safe_browsing/safe_browsing_client.h" -#include "ios/components/security_interstitials/safe_browsing/safe_browsing_client_factory.h" #import "ios/components/security_interstitials/safe_browsing/unsafe_resource_util.h" #include "ios/web/public/thread/web_task_traits.h" #import "ios/web/public/thread/web_thread.h" @@ -27,7 +26,8 @@ // displayed later when the do-not-proceed signal triggers an error page. Must // be called on the UI thread. void HandleBlockingPageRequestOnUIThread( - const security_interstitials::UnsafeResource resource) { + const security_interstitials::UnsafeResource resource, + base::WeakPtr<SafeBrowsingClient> client) { DCHECK_CURRENTLY_ON(web::WebThread::UI); // Send do-not-proceed signal if the WebState has been destroyed. @@ -38,10 +38,7 @@ return; } - SafeBrowsingClient* safe_browsing_client = - SafeBrowsingClientFactory::GetForBrowserState( - web_state->GetBrowserState()); - if (safe_browsing_client->ShouldBlockUnsafeResource(resource)) { + if (client && client->ShouldBlockUnsafeResource(resource)) { RunUnsafeResourceCallback(resource, /*proceed=*/false, /*showed_interstitial=*/false); return; @@ -76,8 +73,10 @@ #pragma mark - UrlCheckerDelegateImpl UrlCheckerDelegateImpl::UrlCheckerDelegateImpl( - scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager) + scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager, + base::WeakPtr<SafeBrowsingClient> client) : database_manager_(std::move(database_manager)), + client_(client), threat_types_(safe_browsing::CreateSBThreatTypeSet( {safe_browsing::SB_THREAT_TYPE_URL_MALWARE, safe_browsing::SB_THREAT_TYPE_URL_PHISHING, @@ -99,7 +98,7 @@ // can proceed. web::GetUIThreadTaskRunner({})->PostTask( FROM_HERE, - base::BindOnce(&HandleBlockingPageRequestOnUIThread, resource)); + base::BindOnce(&HandleBlockingPageRequestOnUIThread, resource, client_)); } void UrlCheckerDelegateImpl::
diff --git a/ios/chrome/browser/safe_browsing/url_checker_delegate_impl_unittest.mm b/ios/chrome/browser/safe_browsing/url_checker_delegate_impl_unittest.mm index de3a08b..69dc870b 100644 --- a/ios/chrome/browser/safe_browsing/url_checker_delegate_impl_unittest.mm +++ b/ios/chrome/browser/safe_browsing/url_checker_delegate_impl_unittest.mm
@@ -13,7 +13,6 @@ #import "components/safe_browsing/ios/browser/safe_browsing_url_allow_list.h" #import "ios/chrome/browser/safe_browsing/fake_safe_browsing_client.h" #import "ios/chrome/browser/safe_browsing/safe_browsing_query_manager.h" -#import "ios/components/security_interstitials/safe_browsing/safe_browsing_client_factory.h" #import "ios/components/security_interstitials/safe_browsing/safe_browsing_unsafe_resource_container.h" #import "ios/web/public/navigation/navigation_item.h" #include "ios/web/public/test/fakes/fake_browser_state.h" @@ -53,7 +52,9 @@ public: UrlCheckerDelegateImplTest() : browser_state_(std::make_unique<web::FakeBrowserState>()), - delegate_(base::MakeRefCounted<UrlCheckerDelegateImpl>(nullptr)), + delegate_( + base::MakeRefCounted<UrlCheckerDelegateImpl>(nullptr, + client_.AsWeakPtr())), item_(web::NavigationItem::Create()), web_state_(std::make_unique<web::FakeWebState>()) { // Set up the WebState. @@ -64,13 +65,7 @@ // Construct the allow list and unsafe resource container. SafeBrowsingUnsafeResourceContainer::CreateForWebState(web_state_.get()); SafeBrowsingUrlAllowList::CreateForWebState(web_state_.get()); - SafeBrowsingQueryManager::CreateForWebState(web_state_.get()); - // Set up the test safe browsing client factory. - SafeBrowsingClientFactory::GetInstance()->SetTestingFactory( - browser_state_.get(), - base::BindRepeating( - &UrlCheckerDelegateImplTest::CreateFakeSafeBrowsingClient, - base::Unretained(this))); + SafeBrowsingQueryManager::CreateForWebState(web_state_.get(), &client_); } ~UrlCheckerDelegateImplTest() override = default; @@ -107,24 +102,14 @@ : nullptr; } - // Creates a fake SafeBrowsingClient and configures whether or not it should - // block an unsafe resource. - std::unique_ptr<KeyedService> CreateFakeSafeBrowsingClient( - web::BrowserState* context) { - std::unique_ptr<FakeSafeBrowsingClient> service = - std::make_unique<FakeSafeBrowsingClient>(); - service->set_should_block_unsafe_resource(should_block_unsafe_resource_); - return service; - } - protected: web::WebTaskEnvironment task_environment_{ web::WebTaskEnvironment::IO_MAINLOOP}; std::unique_ptr<web::FakeBrowserState> browser_state_; + FakeSafeBrowsingClient client_; scoped_refptr<safe_browsing::UrlCheckerDelegate> delegate_; std::unique_ptr<web::NavigationItem> item_; std::unique_ptr<web::FakeWebState> web_state_; - bool should_block_unsafe_resource_ = false; }; // Tests that the delegate does not allow unsafe resources to proceed and does @@ -157,7 +142,7 @@ UnsafeResource resource = CreateUnsafeResource(&callback_state); // Make client block unsafe resource. - should_block_unsafe_resource_ = true; + client_.set_should_block_unsafe_resource(true); // Instruct the delegate to display the blocking page. delegate_->StartDisplayingBlockingPageHelper(resource, /*method=*/"",
diff --git a/ios/chrome/browser/tabs/tab_helper_util.mm b/ios/chrome/browser/tabs/tab_helper_util.mm index ccb8af7..4dacb3fa 100644 --- a/ios/chrome/browser/tabs/tab_helper_util.mm +++ b/ios/chrome/browser/tabs/tab_helper_util.mm
@@ -60,6 +60,7 @@ #import "ios/chrome/browser/reading_list/offline_page_tab_helper.h" #include "ios/chrome/browser/reading_list/reading_list_model_factory.h" #import "ios/chrome/browser/reading_list/reading_list_web_state_observer.h" +#import "ios/chrome/browser/safe_browsing/safe_browsing_client_factory.h" #import "ios/chrome/browser/safe_browsing/safe_browsing_query_manager.h" #import "ios/chrome/browser/safe_browsing/safe_browsing_tab_helper.h" #import "ios/chrome/browser/search_engines/search_engine_tab_helper.h" @@ -92,6 +93,7 @@ #import "ios/components/security_interstitials/lookalikes/lookalike_url_container.h" #import "ios/components/security_interstitials/lookalikes/lookalike_url_tab_allow_list.h" #import "ios/components/security_interstitials/lookalikes/lookalike_url_tab_helper.h" +#import "ios/components/security_interstitials/safe_browsing/safe_browsing_client.h" #import "ios/components/security_interstitials/safe_browsing/safe_browsing_unsafe_resource_container.h" #import "ios/public/provider/chrome/browser/text_zoom/text_zoom_api.h" #include "ios/web/common/features.h" @@ -141,8 +143,10 @@ BreadcrumbManagerTabHelper::CreateForWebState(web_state); } - SafeBrowsingQueryManager::CreateForWebState(web_state); - SafeBrowsingTabHelper::CreateForWebState(web_state); + SafeBrowsingClient* client = + SafeBrowsingClientFactory::GetForBrowserState(browser_state); + SafeBrowsingQueryManager::CreateForWebState(web_state, client); + SafeBrowsingTabHelper::CreateForWebState(web_state, client); SafeBrowsingUrlAllowList::CreateForWebState(web_state); SafeBrowsingUnsafeResourceContainer::CreateForWebState(web_state);
diff --git a/ios/chrome/browser/ui/follow/BUILD.gn b/ios/chrome/browser/ui/follow/BUILD.gn index 28acf6f..2cc14942 100644 --- a/ios/chrome/browser/ui/follow/BUILD.gn +++ b/ios/chrome/browser/ui/follow/BUILD.gn
@@ -63,8 +63,8 @@ deps = [ ":enums", "//ios/chrome/browser/browser_state", + "//ios/chrome/browser/ntp:features", "//ios/chrome/browser/signin", - "//ios/chrome/browser/ui/ntp:feature_flags", "//ios/web/public", "//url", ]
diff --git a/ios/chrome/browser/ui/follow/follow_util.mm b/ios/chrome/browser/ui/follow/follow_util.mm index aa17e7b0..7a58e1e 100644 --- a/ios/chrome/browser/ui/follow/follow_util.mm +++ b/ios/chrome/browser/ui/follow/follow_util.mm
@@ -5,9 +5,9 @@ #import "ios/chrome/browser/ui/follow/follow_util.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" +#import "ios/chrome/browser/ntp/features.h" #import "ios/chrome/browser/signin/authentication_service.h" #import "ios/chrome/browser/signin/authentication_service_factory.h" -#import "ios/chrome/browser/ui/ntp/new_tab_page_feature.h" #include "ios/web/public/web_client.h" #import "ios/web/public/web_state.h" #include "url/gurl.h"
diff --git a/ios/chrome/browser/ui/ntp/BUILD.gn b/ios/chrome/browser/ui/ntp/BUILD.gn index 9a26a06a..7d0aee4 100644 --- a/ios/chrome/browser/ui/ntp/BUILD.gn +++ b/ios/chrome/browser/ui/ntp/BUILD.gn
@@ -66,6 +66,7 @@ "//ios/chrome/browser/discover_feed", "//ios/chrome/browser/discover_feed:discover_feed_factory", "//ios/chrome/browser/main:public", + "//ios/chrome/browser/ntp:features", "//ios/chrome/browser/reading_list", "//ios/chrome/browser/search_engines", "//ios/chrome/browser/signin", @@ -170,6 +171,7 @@ "//ios/chrome/browser/favicon", "//ios/chrome/browser/history", "//ios/chrome/browser/metrics:metrics_internal", + "//ios/chrome/browser/ntp:features", "//ios/chrome/browser/ntp_tiles", "//ios/chrome/browser/reading_list", "//ios/chrome/browser/search_engines",
diff --git a/ios/chrome/browser/ui/ntp/feed_header_view_controller.mm b/ios/chrome/browser/ui/ntp/feed_header_view_controller.mm index a570fe6..40d871f 100644 --- a/ios/chrome/browser/ui/ntp/feed_header_view_controller.mm +++ b/ios/chrome/browser/ui/ntp/feed_header_view_controller.mm
@@ -4,10 +4,10 @@ #import "ios/chrome/browser/ui/ntp/feed_header_view_controller.h" +#import "ios/chrome/browser/ntp/features.h" #import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h" #import "ios/chrome/browser/ui/ntp/feed_control_delegate.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_constants.h" -#import "ios/chrome/browser/ui/ntp/new_tab_page_feature.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/constraints_ui_util.h"
diff --git a/ios/chrome/browser/ui/ntp/feed_management/BUILD.gn b/ios/chrome/browser/ui/ntp/feed_management/BUILD.gn index c245a84..91922583 100644 --- a/ios/chrome/browser/ui/ntp/feed_management/BUILD.gn +++ b/ios/chrome/browser/ui/ntp/feed_management/BUILD.gn
@@ -93,8 +93,8 @@ sources = [ "feed_management_egtest.mm" ] deps = [ "//ios/chrome/app/strings", + "//ios/chrome/browser/ntp:features", "//ios/chrome/browser/ui/authentication:eg_test_support+eg2", - "//ios/chrome/browser/ui/ntp:feature_flags", "//ios/chrome/test/earl_grey:eg_test_support+eg2", "//ios/public/provider/chrome/browser/signin:fake_chrome_identity", "//ios/testing/earl_grey:eg_test_support+eg2",
diff --git a/ios/chrome/browser/ui/ntp/feed_management/feed_management_egtest.mm b/ios/chrome/browser/ui/ntp/feed_management/feed_management_egtest.mm index 00e1bf4..17263fba 100644 --- a/ios/chrome/browser/ui/ntp/feed_management/feed_management_egtest.mm +++ b/ios/chrome/browser/ui/ntp/feed_management/feed_management_egtest.mm
@@ -5,9 +5,9 @@ #import <UIKit/UIKit.h> #import <XCTest/XCTest.h> +#import "ios/chrome/browser/ntp/features.h" #import "ios/chrome/browser/ui/authentication/signin_earl_grey.h" #import "ios/chrome/browser/ui/authentication/signin_earl_grey_ui_test_util.h" -#import "ios/chrome/browser/ui/ntp/new_tab_page_feature.h" #include "ios/chrome/grit/ios_strings.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h"
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm index c4db324..e63d537 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm +++ b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
@@ -26,6 +26,7 @@ #import "ios/chrome/browser/discover_feed/feed_constants.h" #import "ios/chrome/browser/discover_feed/feed_model_configuration.h" #import "ios/chrome/browser/main/browser.h" +#import "ios/chrome/browser/ntp/features.h" #import "ios/chrome/browser/pref_names.h" #include "ios/chrome/browser/reading_list/reading_list_model_factory.h" #import "ios/chrome/browser/search_engines/template_url_service_factory.h"
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_feature.h b/ios/chrome/browser/ui/ntp/new_tab_page_feature.h index 4a33a2e..287dfe2 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_feature.h +++ b/ios/chrome/browser/ui/ntp/new_tab_page_feature.h
@@ -31,12 +31,6 @@ // resource serving. extern const char kDiscoverFeedSRSPreloadTemplatesEnabled[]; -// Feature flag to enable the Following feed in the NTP. -// Use IsWebChannelsEnabled() instead of this constant directly. -// TODO(crbug.com/1264872): move it to web_channels feature directory when there -// has one since this feature will be used outside of NTP. -extern const base::Feature kEnableWebChannels; - // Feature flag to fix the NTP view hierarchy if it is broken before applying // constraints. // TODO(crbug.com/1262536): Remove this when it is fixed. @@ -51,8 +45,11 @@ // Whether the Discover feed shorter cache is enabled. bool IsDiscoverFeedShorterCacheEnabled(); +// TODO(crbug.com/1264872): Cleanup deprecated API. // Whether the Following Feed is enabled on NTP. -bool IsWebChannelsEnabled(); +inline bool IsWebChannelsEnabled() { + return false; +} // Whether the NTP view hierarchy repair is enabled. bool IsNTPViewHierarchyRepairEnabled();
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_feature.mm b/ios/chrome/browser/ui/ntp/new_tab_page_feature.mm index 791a705a..cc27b86 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_feature.mm +++ b/ios/chrome/browser/ui/ntp/new_tab_page_feature.mm
@@ -32,9 +32,6 @@ const char kDiscoverFeedSRSPreloadTemplatesEnabled[] = "DiscoverFeedSRSPreloadTemplatesEnabled"; -const base::Feature kEnableWebChannels{"EnableWebChannels", - base::FEATURE_DISABLED_BY_DEFAULT}; - const base::Feature kNTPViewHierarchyRepair{"NTPViewHierarchyRepair", base::FEATURE_ENABLED_BY_DEFAULT}; @@ -50,10 +47,6 @@ return base::FeatureList::IsEnabled(kEnableDiscoverFeedShorterCache); } -bool IsWebChannelsEnabled() { - return base::FeatureList::IsEnabled(kEnableWebChannels); -} - bool IsNTPViewHierarchyRepairEnabled() { return base::FeatureList::IsEnabled(kNTPViewHierarchyRepair); }
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm b/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm index 6bfe68f..f92f40144 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm +++ b/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm
@@ -7,6 +7,7 @@ #import "ios/chrome/browser/ui/ntp/new_tab_page_view_controller.h" #import "base/check.h" +#import "ios/chrome/browser/ntp/features.h" #import "ios/chrome/browser/ui/bubble/bubble_presenter.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_feature.h"
diff --git a/ios/chrome/browser/ui/popup_menu/BUILD.gn b/ios/chrome/browser/ui/popup_menu/BUILD.gn index 9eedd38..e83db72 100644 --- a/ios/chrome/browser/ui/popup_menu/BUILD.gn +++ b/ios/chrome/browser/ui/popup_menu/BUILD.gn
@@ -61,6 +61,7 @@ "//ios/chrome/browser/feature_engagement", "//ios/chrome/browser/find_in_page", "//ios/chrome/browser/main:public", + "//ios/chrome/browser/ntp:features", "//ios/chrome/browser/overlays", "//ios/chrome/browser/overlays/public/web_content_area", "//ios/chrome/browser/policy", @@ -82,7 +83,6 @@ "//ios/chrome/browser/ui/follow:enums", "//ios/chrome/browser/ui/follow:utils", "//ios/chrome/browser/ui/list_model", - "//ios/chrome/browser/ui/ntp:feature_flags", "//ios/chrome/browser/ui/popup_menu/cells", "//ios/chrome/browser/ui/popup_menu/overflow_menu", "//ios/chrome/browser/ui/popup_menu/overflow_menu:feature_flags",
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/BUILD.gn b/ios/chrome/browser/ui/popup_menu/overflow_menu/BUILD.gn index 56ad240..176adcf 100644 --- a/ios/chrome/browser/ui/popup_menu/overflow_menu/BUILD.gn +++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/BUILD.gn
@@ -52,6 +52,7 @@ "//ios/chrome/browser:chrome_url_constants", "//ios/chrome/browser/find_in_page", "//ios/chrome/browser/follow", + "//ios/chrome/browser/ntp:features", "//ios/chrome/browser/overlays", "//ios/chrome/browser/policy", "//ios/chrome/browser/policy:policy_util", @@ -64,7 +65,6 @@ "//ios/chrome/browser/ui/default_promo:utils", "//ios/chrome/browser/ui/follow", "//ios/chrome/browser/ui/follow:enums", - "//ios/chrome/browser/ui/ntp:feature_flags", "//ios/chrome/browser/ui/popup_menu:constants", "//ios/chrome/browser/ui/util", "//ios/chrome/browser/web",
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm index 9c8e56c..750423b 100644 --- a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm +++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm
@@ -25,6 +25,7 @@ #include "ios/chrome/browser/chrome_url_constants.h" #import "ios/chrome/browser/find_in_page/find_tab_helper.h" #import "ios/chrome/browser/follow/follow_java_script_feature.h" +#import "ios/chrome/browser/ntp/features.h" #import "ios/chrome/browser/overlays/public/overlay_presenter.h" #import "ios/chrome/browser/overlays/public/overlay_presenter_observer_bridge.h" #import "ios/chrome/browser/overlays/public/overlay_request.h" @@ -42,7 +43,6 @@ #import "ios/chrome/browser/ui/commands/text_zoom_commands.h" #import "ios/chrome/browser/ui/default_promo/default_browser_utils.h" #import "ios/chrome/browser/ui/follow/follow_web_page_urls.h" -#import "ios/chrome/browser/ui/ntp/new_tab_page_feature.h" #import "ios/chrome/browser/ui/popup_menu/overflow_menu/feature_flags.h" #import "ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_swift.h" #import "ios/chrome/browser/ui/popup_menu/popup_menu_constants.h"
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm index f389ac4d..1ce7aacf 100644 --- a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm +++ b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm
@@ -13,6 +13,7 @@ #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/feature_engagement/tracker_factory.h" #import "ios/chrome/browser/main/browser.h" +#import "ios/chrome/browser/ntp/features.h" #import "ios/chrome/browser/overlays/public/overlay_presenter.h" #include "ios/chrome/browser/reading_list/reading_list_model_factory.h" #import "ios/chrome/browser/search_engines/template_url_service_factory.h" @@ -25,7 +26,6 @@ #import "ios/chrome/browser/ui/commands/popup_menu_commands.h" #import "ios/chrome/browser/ui/follow/follow_action_state.h" #import "ios/chrome/browser/ui/follow/follow_util.h" -#import "ios/chrome/browser/ui/ntp/new_tab_page_feature.h" #import "ios/chrome/browser/ui/popup_menu/overflow_menu/feature_flags.h" #import "ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.h" #import "ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_swift.h"
diff --git a/ios/chrome/test/swift_interop/classes/polymorphism.h b/ios/chrome/test/swift_interop/classes/polymorphism.h index 75f7cde..333ef09 100644 --- a/ios/chrome/test/swift_interop/classes/polymorphism.h +++ b/ios/chrome/test/swift_interop/classes/polymorphism.h
@@ -8,9 +8,9 @@ class Shape { public: Shape(int width, int height) : width_(width), height_(height) {} - ~Shape() {} + virtual ~Shape() {} - virtual int Area() { return 0; } + virtual int Area() = 0; virtual int NumberOfSides() { return 0; } // Virtual or not, this cannot be called on inherited classes unless it @@ -25,7 +25,7 @@ class Rectangle : public Shape { public: Rectangle(int width, int height) : Shape(width, height) {} - ~Rectangle() {} + virtual ~Rectangle() {} virtual int Area() { return width_ * height_; } virtual int NumberOfSides() { return 4; } @@ -34,7 +34,7 @@ class Square : public Rectangle { public: Square(int size) : Rectangle(size, size) {} - ~Square() {} + virtual ~Square() {} // Even though these should not be necessary, they are. Without them, calling // these methods on a Square object results in a compiler error. @@ -45,7 +45,7 @@ class Triangle : public Shape { public: Triangle(int width, int height) : Shape(width, height) {} - ~Triangle() {} + virtual ~Triangle() {} virtual int Area() { return (width_ * height_) / 2; } virtual int NumberOfSides() { return 3; }
diff --git a/ios/chrome/test/swift_interop/classes/polymorphism_xctest.swift b/ios/chrome/test/swift_interop/classes/polymorphism_xctest.swift index d7ddda3..c194450f 100644 --- a/ios/chrome/test/swift_interop/classes/polymorphism_xctest.swift +++ b/ios/chrome/test/swift_interop/classes/polymorphism_xctest.swift
@@ -31,10 +31,16 @@ // MakeShape() creates a Triangle and returns the object as a Shape*. // let shape = MakeShape(10, 10) - // DOES NOT WORK: executes the Shape implementations of these methods, not - // the Triangle versions, so both return 0 and thus fail the comparision. - // XCTAssertEqual(shape!.pointee.Area(), 50) + // DOES NOT WORK: executes the Shape implementation, not the Triangle + // version, and thus fails the comparision (0 != 3) // XCTAssertEqual(shape!.pointee.NumberOfSides(), 3) } + func testPureVirtualMethods_noCompile() throws { + // MakeShape() creates a Triangle and returns the object as a Shape*. + // let shape = MakeShape(10, 10) + + // DOES NOT COMPILE: undefined symbol Shape::Area() for lld. + // XCTAssertEqual(shape!.pointee.Area(), 50) + } }
diff --git a/ios/components/security_interstitials/safe_browsing/BUILD.gn b/ios/components/security_interstitials/safe_browsing/BUILD.gn index 3fd08ade..c872408 100644 --- a/ios/components/security_interstitials/safe_browsing/BUILD.gn +++ b/ios/components/security_interstitials/safe_browsing/BUILD.gn
@@ -9,7 +9,6 @@ "pending_unsafe_resource_storage.h", "pending_unsafe_resource_storage.mm", "safe_browsing_client.h", - "safe_browsing_client_factory.h", "safe_browsing_error.h", "safe_browsing_error.mm", "safe_browsing_unsafe_resource_container.h",
diff --git a/ios/components/security_interstitials/safe_browsing/safe_browsing_client.h b/ios/components/security_interstitials/safe_browsing/safe_browsing_client.h index dfb40e8..c8cdfe3 100644 --- a/ios/components/security_interstitials/safe_browsing/safe_browsing_client.h +++ b/ios/components/security_interstitials/safe_browsing/safe_browsing_client.h
@@ -5,6 +5,7 @@ #ifndef IOS_COMPONENTS_SECURITY_INTERSTITIALS_SAFE_BROWSING_SAFE_BROWSING_CLIENT_H_ #define IOS_COMPONENTS_SECURITY_INTERSTITIALS_SAFE_BROWSING_SAFE_BROWSING_CLIENT_H_ +#include "base/memory/weak_ptr.h" #include "components/keyed_service/core/keyed_service.h" namespace safe_browsing { @@ -25,6 +26,8 @@ // Abstract interface to be implemented by clients of ios safe browsing. class SafeBrowsingClient : public KeyedService { public: + // Returns this as a weak pointer. + virtual base::WeakPtr<SafeBrowsingClient> AsWeakPtr() = 0; // Gets the safe browsing service for this client. Must not be nullptr. virtual SafeBrowsingService* GetSafeBrowsingService() = 0; // Gets the real time url look up service. Clients may return nullptr.
diff --git a/media/base/android/media_player_bridge.cc b/media/base/android/media_player_bridge.cc index 6a7eacd..9ed5a3f 100644 --- a/media/base/android/media_player_bridge.cc +++ b/media/base/android/media_player_bridge.cc
@@ -169,6 +169,11 @@ } void MediaPlayerBridge::SetPlaybackRate(double playback_rate) { + if (!prepared_) { + pending_playback_rate_ = playback_rate; + return; + } + if (j_media_player_bridge_.is_null()) return; @@ -481,6 +486,11 @@ StartInternal(); pending_play_ = false; } + + if (pending_playback_rate_) { + SetPlaybackRate(pending_playback_rate_.value()); + pending_playback_rate_.reset(); + } } ScopedJavaLocalRef<jobject> MediaPlayerBridge::GetAllowedOperations() {
diff --git a/media/base/android/media_player_bridge.h b/media/base/android/media_player_bridge.h index 862921c..98b88b97 100644 --- a/media/base/android/media_player_bridge.h +++ b/media/base/android/media_player_bridge.h
@@ -282,6 +282,9 @@ // Listener object that listens to all the media player events. std::unique_ptr<MediaPlayerListener> listener_; + // Pending playback rate while player is preparing. + absl::optional<double> pending_playback_rate_; + // Weak pointer passed to `listener_` for callbacks. // NOTE: Weak pointers must be invalidated before all other member variables. base::WeakPtrFactory<MediaPlayerBridge> weak_factory_{this};
diff --git a/media/formats/hls/parse_status.cc b/media/formats/hls/parse_status.cc index c507477..266a29b 100644 --- a/media/formats/hls/parse_status.cc +++ b/media/formats/hls/parse_status.cc
@@ -21,6 +21,7 @@ PARSE_STATUS_CODE_CASE(kFailedToParseDecimalInteger); PARSE_STATUS_CODE_CASE(kFailedToParseDecimalFloatingPoint); PARSE_STATUS_CODE_CASE(kFailedToParseSignedDecimalFloatingPoint); + PARSE_STATUS_CODE_CASE(kFailedToParseDecimalResolution); PARSE_STATUS_CODE_CASE(kFailedToParseQuotedString); PARSE_STATUS_CODE_CASE(kInvalidPlaylistVersion); PARSE_STATUS_CODE_CASE(kUnknownPlaylistType);
diff --git a/media/formats/hls/parse_status.h b/media/formats/hls/parse_status.h index 959e578..8d7dd88 100644 --- a/media/formats/hls/parse_status.h +++ b/media/formats/hls/parse_status.h
@@ -18,6 +18,7 @@ kFailedToParseDecimalInteger, kFailedToParseDecimalFloatingPoint, kFailedToParseSignedDecimalFloatingPoint, + kFailedToParseDecimalResolution, kFailedToParseQuotedString, kInvalidPlaylistVersion, kUnknownPlaylistType,
diff --git a/media/formats/hls/types.cc b/media/formats/hls/types.cc index f49af77..de78664 100644 --- a/media/formats/hls/types.cc +++ b/media/formats/hls/types.cc
@@ -9,6 +9,7 @@ #include "base/no_destructor.h" #include "base/strings/string_number_conversions.h" +#include "media/formats/hls/parse_status.h" #include "media/formats/hls/source_string.h" #include "third_party/re2/src/re2/re2.h" @@ -199,6 +200,33 @@ return result; } +ParseStatus::Or<DecimalResolution> DecimalResolution::Parse( + SourceString source_str) { + // decimal-resolution values are in the format: DecimalInteger 'x' + // DecimalInteger + const auto x_index = source_str.Str().find_first_of('x'); + if (x_index == base::StringPiece::npos) { + return ParseStatusCode::kFailedToParseDecimalResolution; + } + + // Extract width and height strings + const auto width_str = source_str.Consume(x_index); + source_str.Consume(1); + const auto height_str = source_str; + + auto width = ParseDecimalInteger(width_str); + auto height = ParseDecimalInteger(height_str); + for (auto* x : {&width, &height}) { + if (x->has_error()) { + return ParseStatus(ParseStatusCode::kFailedToParseDecimalResolution) + .AddCause(std::move(*x).error()); + } + } + + return DecimalResolution{.width = std::move(width).value(), + .height = std::move(height).value()}; +} + ParseStatus::Or<base::StringPiece> ParseQuotedString( SourceString source_str, const VariableDictionary& variable_dict,
diff --git a/media/formats/hls/types.h b/media/formats/hls/types.h index 927e9eca..caab6f7 100644 --- a/media/formats/hls/types.h +++ b/media/formats/hls/types.h
@@ -14,22 +14,38 @@ namespace media::hls::types { -// Data-types used in HLS, as described by the spec +// A `DecimalInteger` is an unsigned integer value. +// https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis#:~:text=of%20the%20following%3A%0A%0A%20%20%20o-,decimal%2Dinteger,-%3A%20an%20unquoted%20string using DecimalInteger = uint64_t; ParseStatus::Or<DecimalInteger> MEDIA_EXPORT ParseDecimalInteger(SourceString source_str); +// A `DecimalFloatingPoint` is an unsigned floating-point value. +// https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis#:~:text=on%20its%20AttributeNames.%0A%0A%20%20%20o-,decimal%2Dfloating%2Dpoint,-%3A%20an%20unquoted%20string using DecimalFloatingPoint = double; ParseStatus::Or<DecimalFloatingPoint> MEDIA_EXPORT ParseDecimalFloatingPoint(SourceString source_str); +// A `SignedDecimalFloatingPoint` is a signed floating-point value. +// https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis#:~:text=decimal%20positional%20notation.%0A%0A%20%20%20o-,signed%2Ddecimal%2Dfloating%2Dpoint,-%3A%20an%20unquoted%20string using SignedDecimalFloatingPoint = double; ParseStatus::Or<SignedDecimalFloatingPoint> MEDIA_EXPORT ParseSignedDecimalFloatingPoint(SourceString source_str); +// A `DecimalResolution` is a set of two `DecimalInteger`s describing width and +// height. +// https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis#:~:text=enumerated%2Dstring%2Dlist.%0A%0A%20%20%20o-,decimal%2Dresolution,-%3A%20two%20decimal%2Dintegers +struct DecimalResolution { + types::DecimalInteger width; + types::DecimalInteger height; + + static MEDIA_EXPORT ParseStatus::Or<DecimalResolution> Parse( + SourceString source_str); +}; + // Parses a string surrounded by double-quotes ("), returning the inner string. // These appear in the context of attribute-lists, and are subject to variable // substitution. `sub_buffer` must outlive the returned string.
diff --git a/media/formats/hls/types_unittest.cc b/media/formats/hls/types_unittest.cc index 9d55a0b..4b19468 100644 --- a/media/formats/hls/types_unittest.cc +++ b/media/formats/hls/types_unittest.cc
@@ -17,7 +17,7 @@ namespace media::hls { TEST(HlsTypesTest, ParseDecimalInteger) { - auto const error_test = [](base::StringPiece input, + const auto error_test = [](base::StringPiece input, const base::Location& from = base::Location::Current()) { auto result = @@ -28,7 +28,7 @@ << from.ToString(); }; - auto const ok_test = [](base::StringPiece input, + const auto ok_test = [](base::StringPiece input, types::DecimalInteger expected, const base::Location& from = base::Location::Current()) { @@ -72,7 +72,7 @@ } TEST(HlsTypesTest, ParseDecimalFloatingPoint) { - auto const error_test = [](base::StringPiece input, + const auto error_test = [](base::StringPiece input, const base::Location& from = base::Location::Current()) { auto result = types::ParseDecimalFloatingPoint( @@ -83,7 +83,7 @@ << from.ToString(); }; - auto const ok_test = [](base::StringPiece input, + const auto ok_test = [](base::StringPiece input, types::DecimalFloatingPoint expected, const base::Location& from = base::Location::Current()) { @@ -124,7 +124,7 @@ } TEST(HlsTypesTest, ParseSignedDecimalFloatingPoint) { - auto const error_test = [](base::StringPiece input, + const auto error_test = [](base::StringPiece input, const base::Location& from = base::Location::Current()) { auto result = types::ParseSignedDecimalFloatingPoint( @@ -136,7 +136,7 @@ << from.ToString(); }; - auto const ok_test = [](base::StringPiece input, + const auto ok_test = [](base::StringPiece input, types::SignedDecimalFloatingPoint expected, const base::Location& from = base::Location::Current()) { @@ -417,7 +417,7 @@ } TEST(HlsTypesTest, ParseVariableName) { - auto const ok_test = [](base::StringPiece input, + const auto ok_test = [](base::StringPiece input, const base::Location& from = base::Location::Current()) { auto result = @@ -426,7 +426,7 @@ EXPECT_EQ(std::move(result).value().GetName(), input) << from.ToString(); }; - auto const error_test = [](base::StringPiece input, + const auto error_test = [](base::StringPiece input, const base::Location& from = base::Location::Current()) { auto result = @@ -563,4 +563,79 @@ error_test("", ParseStatusCode::kFailedToParseQuotedString); } +TEST(HlsTypesTest, ParseDecimalResolution) { + const auto error_test = [](base::StringPiece input, + const base::Location& from = + base::Location::Current()) { + auto result = types::DecimalResolution::Parse( + SourceString::CreateForTesting(1, 1, input)); + ASSERT_TRUE(result.has_error()) << from.ToString(); + auto error = std::move(result).error(); + EXPECT_EQ(error.code(), ParseStatusCode::kFailedToParseDecimalResolution) + << from.ToString(); + }; + + const auto ok_test = + [](base::StringPiece input, types::DecimalResolution expected, + const base::Location& from = base::Location::Current()) { + auto result = types::DecimalResolution::Parse( + SourceString::CreateForTesting(1, 1, input)); + ASSERT_TRUE(result.has_value()) << from.ToString(); + auto value = std::move(result).value(); + EXPECT_EQ(value.width, expected.width) << from.ToString(); + EXPECT_EQ(value.height, expected.height) << from.ToString(); + }; + + // Empty string is not allowed + error_test(""); + + // Decimal-resolution must have a single lower-case 'x' between two + // DecimalIntegers + error_test("123"); + error_test("123X456"); + error_test("123*456"); + error_test("123x"); + error_test("x456"); + error_test("123x456x"); + error_test("x123x456"); + error_test("x123x456x"); + error_test("0X123"); + + // Decimal-resolutions may not be quoted + error_test("'123x456'"); + error_test("\"123x456\""); + + // Decimal-resolutions may not be negative + error_test("-123x456"); + error_test("123x-456"); + error_test("-123x-456"); + error_test("-0x456"); + + // Decimal-integers may not contain junk or leading/trailing spaces + error_test("12.3x456"); + error_test(" 123x456"); + error_test("123 x456"); + error_test("123x456 "); + error_test("123x 456"); + + // Decimal-integers may not exceed 20 characters + error_test("000000000000000000001x456"); + error_test("123x000000000000000000001"); + + // Test some valid inputs + ok_test("00000000000000000001x456", + types::DecimalResolution{.width = 1, .height = 456}); + ok_test("0x0", types::DecimalResolution{.width = 0, .height = 0}); + ok_test("1x1", types::DecimalResolution{.width = 1, .height = 1}); + ok_test("123x456", types::DecimalResolution{.width = 123, .height = 456}); + ok_test("123x0", types::DecimalResolution{.width = 123, .height = 0}); + ok_test("0x123", types::DecimalResolution{.width = 0, .height = 123}); + + // Test max supported value + ok_test("18446744073709551615x18446744073709551615", + types::DecimalResolution{.width = 18446744073709551615u, + .height = 18446744073709551615u}); + error_test("18446744073709551616x18446744073709551616"); +} + } // namespace media::hls
diff --git a/media/gpu/android/ndk_video_encode_accelerator.cc b/media/gpu/android/ndk_video_encode_accelerator.cc index af192771..c717cfc 100644 --- a/media/gpu/android/ndk_video_encode_accelerator.cc +++ b/media/gpu/android/ndk_video_encode_accelerator.cc
@@ -93,7 +93,7 @@ } const base::Feature kAndroidNdkVideoEncoder{"AndroidNdkVideoEncoder", - base::FEATURE_ENABLED_BY_DEFAULT}; + base::FEATURE_DISABLED_BY_DEFAULT}; static bool InitMediaCodec() { if (base::android::BuildInfo::GetInstance()->sdk_int() <
diff --git a/media/gpu/android/ndk_video_encode_accelerator_tests.cc b/media/gpu/android/ndk_video_encode_accelerator_tests.cc index 191ef101..adc1992 100644 --- a/media/gpu/android/ndk_video_encode_accelerator_tests.cc +++ b/media/gpu/android/ndk_video_encode_accelerator_tests.cc
@@ -266,10 +266,7 @@ Run(); EXPECT_FALSE(error_.has_value()); EXPECT_GE(outputs_.size(), total_frames_count); - // Here we'd like to test that an output with at `key_frame_index` - // has a keyframe flag set to true, but because MediaCodec - // is unreliable in inserting keyframes at our request we can't test - // for it. In practice it usually works, just not always. + EXPECT_TRUE(outputs_[key_frame_index].md.key_frame); for (auto& output : outputs_) { auto& mapping = id_to_buffer_[output.id]->GetMapping();
diff --git a/media/gpu/gpu_video_decode_accelerator_factory.cc b/media/gpu/gpu_video_decode_accelerator_factory.cc index 6687b11..98f1e2e 100644 --- a/media/gpu/gpu_video_decode_accelerator_factory.cc +++ b/media/gpu/gpu_video_decode_accelerator_factory.cc
@@ -201,8 +201,8 @@ scoped_refptr<V4L2Device> device = V4L2Device::Create(); if (device.get()) { decoder.reset(new V4L2VideoDecodeAccelerator( - gl::GLSurfaceEGL::GetHardwareDisplay(), gl_client_.get_context, - gl_client_.make_context_current, device)); + gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(), + gl_client_.get_context, gl_client_.make_context_current, device)); } return decoder; } @@ -216,8 +216,8 @@ scoped_refptr<V4L2Device> device = V4L2Device::Create(); if (device.get()) { decoder.reset(new V4L2SliceVideoDecodeAccelerator( - device, gl::GLSurfaceEGL::GetHardwareDisplay(), gl_client_.bind_image, - gl_client_.make_context_current)); + device, gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(), + gl_client_.bind_image, gl_client_.make_context_current)); } return decoder; }
diff --git a/media/gpu/v4l2/v4l2_image_processor_backend.cc b/media/gpu/v4l2/v4l2_image_processor_backend.cc index 8c05729..3dbd184 100644 --- a/media/gpu/v4l2/v4l2_image_processor_backend.cc +++ b/media/gpu/v4l2/v4l2_image_processor_backend.cc
@@ -30,17 +30,6 @@ #include "media/gpu/macros.h" #include "media/gpu/v4l2/v4l2_utils.h" -#define IOCTL_OR_ERROR_RETURN_VALUE(type, arg, value, type_str) \ - do { \ - if (device_->Ioctl(type, arg) != 0) { \ - VPLOGF(1) << "ioctl() failed: " << type_str; \ - return value; \ - } \ - } while (0) - -#define IOCTL_OR_ERROR_RETURN_FALSE(type, arg) \ - IOCTL_OR_ERROR_RETURN_VALUE(type, arg, false, #type) - namespace media { namespace { @@ -376,6 +365,42 @@ output_planes[i].size = pix_mp.plane_fmt[i].sizeimage; } + // Capabilities check. + struct v4l2_capability caps {}; + const __u32 kCapsRequired = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; + if (device->Ioctl(VIDIOC_QUERYCAP, &caps) != 0) { + VPLOGF(1) << "VIDIOC_QUERYCAP failed"; + return nullptr; + } + if ((caps.capabilities & kCapsRequired) != kCapsRequired) { + VLOGF(1) << "VIDIOC_QUERYCAP failed: " + << "caps check failed: 0x" << std::hex << caps.capabilities; + return nullptr; + } + + // Set a few standard controls to default values. + struct v4l2_control rotation = {.id = V4L2_CID_ROTATE, .value = 0}; + if (device->Ioctl(VIDIOC_S_CTRL, &rotation) != 0) { + VPLOGF(1) << "V4L2_CID_ROTATE failed"; + return nullptr; + } + + struct v4l2_control hflip = {.id = V4L2_CID_HFLIP, .value = 0}; + if (device->Ioctl(VIDIOC_S_CTRL, &hflip) != 0) { + VPLOGF(1) << "V4L2_CID_HFLIP failed"; + return nullptr; + } + + struct v4l2_control vflip = {.id = V4L2_CID_VFLIP, .value = 0}; + if (device->Ioctl(VIDIOC_S_CTRL, &vflip) != 0) { + VPLOGF(1) << "V4L2_CID_VFLIP failed"; + return nullptr; + } + + struct v4l2_control alpha = {.id = V4L2_CID_ALPHA_COMPONENT, .value = 255}; + if (device->Ioctl(VIDIOC_S_CTRL, &alpha) != 0) + VPLOGF(1) << "V4L2_CID_ALPHA_COMPONENT failed"; + const v4l2_memory output_memory_type = output_mode == OutputMode::ALLOCATE ? V4L2_MEMORY_MMAP @@ -391,7 +416,7 @@ input_memory_type, output_memory_type, output_mode, relative_rotation, num_buffers, std::move(error_cb))); - // Initialize at |backend_task_runner_|. + // Initialize at |backend_task_runner|. bool success = false; base::WaitableEvent done; auto init_cb = base::BindOnce( @@ -419,22 +444,6 @@ DVLOGF(2); DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_); - // Capabilities check. - struct v4l2_capability caps; - memset(&caps, 0, sizeof(caps)); - const __u32 kCapsRequired = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; - if (device_->Ioctl(VIDIOC_QUERYCAP, &caps) != 0) { - VPLOGF(1) << "ioctl() failed: VIDIOC_QUERYCAP"; - std::move(init_cb).Run(false); - return; - } - if ((caps.capabilities & kCapsRequired) != kCapsRequired) { - VLOGF(1) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP: " - << "caps check failed: 0x" << std::hex << caps.capabilities; - std::move(init_cb).Run(false); - return; - } - if (!CreateInputBuffers() || !CreateOutputBuffers()) { std::move(init_cb).Run(false); return; @@ -668,28 +677,6 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_); DCHECK_EQ(input_queue_, nullptr); - struct v4l2_control control; - memset(&control, 0, sizeof(control)); - control.id = V4L2_CID_ROTATE; - control.value = 0; - IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_CTRL, &control); - - memset(&control, 0, sizeof(control)); - control.id = V4L2_CID_HFLIP; - control.value = 0; - IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_CTRL, &control); - - memset(&control, 0, sizeof(control)); - control.id = V4L2_CID_VFLIP; - control.value = 0; - IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_CTRL, &control); - - memset(&control, 0, sizeof(control)); - control.id = V4L2_CID_ALPHA_COMPONENT; - control.value = 255; - if (device_->Ioctl(VIDIOC_S_CTRL, &control) != 0) - DVLOGF(4) << "V4L2_CID_ALPHA_COMPONENT is not supported"; - input_queue_ = device_->GetQueue(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); return input_queue_ && AllocateV4L2Buffers(input_queue_.get(), num_buffers_, input_memory_type_);
diff --git a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc index 34c8840..29994b9 100644 --- a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc +++ b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
@@ -1491,6 +1491,14 @@ if (bitrate.mode() != Bitrate::Mode::kConstant) return; + // Set bitrate control to CBR + // Not all devices support multiple bitrate control algorithms, + // so this control can't be mandatory and therefore the return + // value is not checked. + device_->SetExtCtrls(V4L2_CID_MPEG_CLASS, + {V4L2ExtCtrl(V4L2_CID_MPEG_VIDEO_BITRATE_MODE, + V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)}); + if (current_bitrate_ == bitrate.target_bps() && current_framerate_ == framerate) { return;
diff --git a/media/gpu/windows/dxva_picture_buffer_win.cc b/media/gpu/windows/dxva_picture_buffer_win.cc index 51299c6..d2a422431 100644 --- a/media/gpu/windows/dxva_picture_buffer_win.cc +++ b/media/gpu/windows/dxva_picture_buffer_win.cc
@@ -65,7 +65,8 @@ private: ~GLImagePbuffer() override { - EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); + EGLDisplay egl_display = + gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(); eglReleaseTexImage(egl_display, surface_, EGL_BACK_BUFFER); @@ -171,7 +172,8 @@ RETURN_ON_FAILURE(!picture_buffer_.service_texture_ids().empty(), "No service texture ids provided", false); - EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); + EGLDisplay egl_display = + gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(); EGLint use_rgb = 1; eglGetConfigAttrib(egl_display, egl_config, EGL_BIND_TO_TEXTURE_RGB, &use_rgb); @@ -368,7 +370,8 @@ RETURN_ON_FAILURE(result == S_OK, "Could not acquire sync mutex", false); } - EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); + EGLDisplay egl_display = + gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(); eglBindTexImage(egl_display, decoding_surface_, EGL_BACK_BUFFER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -398,7 +401,8 @@ bool PbufferPictureBuffer::ReusePictureBuffer() { DCHECK_NE(UNUSED, state_); DCHECK(decoding_surface_); - EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); + EGLDisplay egl_display = + gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(); eglReleaseTexImage(egl_display, decoding_surface_, EGL_BACK_BUFFER); decoder_surface_.Reset(); @@ -423,7 +427,8 @@ RETURN_ON_FAILURE(picture_buffer_.service_texture_ids().size() >= 2, "Not enough texture ids provided", false); - EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); + EGLDisplay egl_display = + gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(); const EGLint stream_attributes[] = { EGL_CONSUMER_LATENCY_USEC_KHR, 0, @@ -468,7 +473,8 @@ bool EGLStreamPictureBuffer::ReusePictureBuffer() { DCHECK_NE(UNUSED, state_); - EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); + EGLDisplay egl_display = + gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(); if (stream_) { EGLBoolean result = eglStreamConsumerReleaseKHR(egl_display, stream_); @@ -491,7 +497,8 @@ shared_images_.resize(picture_buffer_.service_texture_ids().size()); current_d3d_sample_ = sample; - EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); + EGLDisplay egl_display = + gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(); Microsoft::WRL::ComPtr<IMFMediaBuffer> output_buffer; HRESULT hr = current_d3d_sample_->GetBufferByIndex(0, &output_buffer); @@ -547,7 +554,8 @@ RETURN_ON_FAILURE(picture_buffer_.service_texture_ids().size() >= 2, "Not enough texture ids provided", false); - EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); + EGLDisplay egl_display = + gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(); const EGLint stream_attributes[] = { EGL_CONSUMER_LATENCY_USEC_KHR, 0, @@ -662,7 +670,8 @@ RETURN_ON_FAILURE(picture_buffer_.service_texture_ids().size() >= 2, "Not enough texture ids provided", false); - EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); + EGLDisplay egl_display = + gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(); const EGLint stream_attributes[] = { EGL_CONSUMER_LATENCY_USEC_KHR, 0, @@ -784,7 +793,8 @@ EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE, 0, EGL_NONE, }; - EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); + EGLDisplay egl_display = + gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(); EGLBoolean result = eglStreamPostD3DTextureANGLE( egl_display, stream_, static_cast<void*>(angle_copy_texture_.Get()), @@ -803,7 +813,8 @@ bool EGLStreamCopyPictureBuffer::ReusePictureBuffer() { DCHECK_NE(UNUSED, state_); - EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); + EGLDisplay egl_display = + gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(); if (state_ == IN_CLIENT) { HRESULT hr = egl_keyed_mutex_->ReleaseSync(++keyed_mutex_value_);
diff --git a/media/gpu/windows/dxva_video_decode_accelerator_win.cc b/media/gpu/windows/dxva_video_decode_accelerator_win.cc index fcf5954f..7d690078 100644 --- a/media/gpu/windows/dxva_video_decode_accelerator_win.cc +++ b/media/gpu/windows/dxva_video_decode_accelerator_win.cc
@@ -1552,10 +1552,11 @@ RETURN_ON_HR_FAILURE(hr, "Failed to pass D3D manager to decoder", false); } - if (!gl::GLSurfaceEGL::IsPixelFormatFloatSupported()) + if (!gl::GLSurfaceEGL::GetGLDisplayEGL()->IsPixelFormatFloatSupported()) use_fp16_ = false; - EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); + EGLDisplay egl_display = + gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(); while (true) { std::vector<EGLint> config_attribs = {EGL_BUFFER_SIZE, 32, @@ -1661,7 +1662,8 @@ } use_keyed_mutex_ = - use_dx11_ && gl::GLSurfaceEGL::HasEGLExtension("EGL_ANGLE_keyed_mutex"); + use_dx11_ && gl::GLSurfaceEGL::GetGLDisplayEGL()->HasEGLExtension( + "EGL_ANGLE_keyed_mutex"); if (!use_dx11_ || !gl::g_driver_egl.ext.b_EGL_ANGLE_stream_producer_d3d_texture ||
diff --git a/media/mojo/services/gpu_mojo_media_client_cros.cc b/media/mojo/services/gpu_mojo_media_client_cros.cc index f34b6108..d9c7a20 100644 --- a/media/mojo/services/gpu_mojo_media_client_cros.cc +++ b/media/mojo/services/gpu_mojo_media_client_cros.cc
@@ -108,8 +108,7 @@ traits.gpu_info)) { case VideoDecoderType::kVaapi: case VideoDecoderType::kV4L2: { - auto frame_pool = std::make_unique<PlatformVideoFramePool>( - traits.gpu_memory_buffer_factory); + auto frame_pool = std::make_unique<PlatformVideoFramePool>(nullptr); auto frame_converter = MailboxVideoFrameConverter::Create( base::BindRepeating(&PlatformVideoFramePool::UnwrapFrame, base::Unretained(frame_pool.get())),
diff --git a/net/extras/sqlite/sqlite_persistent_cookie_store.cc b/net/extras/sqlite/sqlite_persistent_cookie_store.cc index f7ef5fa..80b3391 100644 --- a/net/extras/sqlite/sqlite_persistent_cookie_store.cc +++ b/net/extras/sqlite/sqlite_persistent_cookie_store.cc
@@ -1099,6 +1099,14 @@ if (!cc->LastUpdateDate().is_null()) { DLOG_IF(WARNING, cc->LastUpdateDate() > Time::Now()) << L"LastUpdateDate too recent"; + // In order to anticipate the potential effects of the expiry limit in + // rfc6265bis, we need to check how long it's been since the cookie was + // refreshed (if LastUpdateDate is populated). We use 100 buckets for + // the highest reasonable granularity, set 1 day as the minimum and + // don't track over a 400 max (since these cookies will expire anyway). + UMA_HISTOGRAM_CUSTOM_COUNTS( + "Cookie.DaysSinceRefreshForRetrieval", + (base::Time::Now() - cc->LastUpdateDate()).InDays(), 1, 400, 100); } cookies.push_back(std::move(cc)); } else {
diff --git a/printing/page_range.h b/printing/page_range.h index 07414b3..218e758 100644 --- a/printing/page_range.h +++ b/printing/page_range.h
@@ -7,6 +7,7 @@ #include <stdint.h> +#include <limits> #include <vector> #include "base/component_export.h"
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index b54d780..3f64ad8 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -5876,21 +5876,21 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5026.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5027.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5026.0", + "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5027.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v103.0.5026.0", - "revision": "version:103.0.5026.0" + "location": "lacros_version_skew_tests_v103.0.5027.0", + "revision": "version:103.0.5027.0" } ], "dimension_sets": [ @@ -6018,21 +6018,21 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5026.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5027.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5026.0", + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5027.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v103.0.5026.0", - "revision": "version:103.0.5026.0" + "location": "lacros_version_skew_tests_v103.0.5027.0", + "revision": "version:103.0.5027.0" } ], "dimension_sets": [
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 2b15e8e..c13fc3d 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -24925,6 +24925,1392 @@ } ] }, + "fuchsia-fyi-arm64-emu-arg": { + "additional_compile_targets": [ + "all" + ], + "gtest_tests": [ + { + "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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "absl_hardening_tests", + "test_id_prefix": "ninja://third_party/abseil-cpp:absl_hardening_tests/" + }, + { + "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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "accessibility_unittests", + "test_id_prefix": "ninja://ui/accessibility:accessibility_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "aura_unittests", + "test_id_prefix": "ninja://ui/aura:aura_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "base_unittests", + "test_id_prefix": "ninja://base:base_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "blink_common_unittests", + "test_id_prefix": "ninja://third_party/blink/common:blink_common_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "blink_heap_unittests", + "test_id_prefix": "ninja://third_party/blink/renderer/platform/heap:blink_heap_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "blink_platform_unittests", + "test_id_prefix": "ninja://third_party/blink/renderer/platform:blink_platform_unittests/" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.blink_unittests.filter" + ], + "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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "blink_unittests", + "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "boringssl_crypto_tests", + "test_id_prefix": "ninja://third_party/boringssl:boringssl_crypto_tests/" + }, + { + "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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "boringssl_ssl_tests", + "test_id_prefix": "ninja://third_party/boringssl:boringssl_ssl_tests/" + }, + { + "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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "capture_unittests", + "test_id_prefix": "ninja://media/capture:capture_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "cast_runner_browsertests", + "test_id_prefix": "ninja://fuchsia/runners:cast_runner_browsertests/" + }, + { + "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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "cast_runner_integration_tests", + "test_id_prefix": "ninja://fuchsia/runners:cast_runner_integration_tests/" + }, + { + "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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "cast_runner_unittests", + "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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 2 + }, + "test": "cc_unittests", + "test_id_prefix": "ninja://cc:cc_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "color_unittests", + "test_id_prefix": "ninja://ui/color:color_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "components_browsertests", + "test_id_prefix": "ninja://components:components_browsertests/" + }, + { + "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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 2 + }, + "test": "components_unittests", + "test_id_prefix": "ninja://components:components_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "compositor_unittests", + "test_id_prefix": "ninja://ui/compositor:compositor_unittests/" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.content_unittests.filter" + ], + "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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "content_unittests", + "test_id_prefix": "ninja://content/test:content_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "courgette_unittests", + "test_id_prefix": "ninja://courgette:courgette_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "cr_fuchsia_base_unittests", + "test_id_prefix": "ninja://fuchsia/base:cr_fuchsia_base_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "crypto_unittests", + "test_id_prefix": "ninja://crypto:crypto_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "display_unittests", + "test_id_prefix": "ninja://ui/display:display_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "events_unittests", + "test_id_prefix": "ninja://ui/events:events_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "extensions_unittests", + "test_id_prefix": "ninja://extensions:extensions_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "fuchsia_mojo_unittests", + "test_id_prefix": "ninja://fuchsia/mojom:fuchsia_mojo_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "gcm_unit_tests", + "test_id_prefix": "ninja://google_apis/gcm:gcm_unit_tests/" + }, + { + "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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "gfx_unittests", + "test_id_prefix": "ninja://ui/gfx:gfx_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "gin_unittests", + "test_id_prefix": "ninja://gin:gin_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "google_apis_unittests", + "test_id_prefix": "ninja://google_apis:google_apis_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "gpu_unittests", + "test_id_prefix": "ninja://gpu:gpu_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "gwp_asan_unittests", + "test_id_prefix": "ninja://components/gwp_asan:gwp_asan_unittests/" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.headless_browsertests.filter" + ], + "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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "headless_browsertests", + "test_id_prefix": "ninja://headless:headless_browsertests/" + }, + { + "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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "headless_unittests", + "test_id_prefix": "ninja://headless:headless_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "ipc_tests", + "test_id_prefix": "ninja://ipc:ipc_tests/" + }, + { + "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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "latency_unittests", + "test_id_prefix": "ninja://ui/latency:latency_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "media_unittests", + "test_id_prefix": "ninja://media:media_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "message_center_unittests", + "test_id_prefix": "ninja://ui/message_center:message_center_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "midi_unittests", + "test_id_prefix": "ninja://media/midi:midi_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "mojo_core_unittests", + "test_id_prefix": "ninja://mojo/core:mojo_core_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "mojo_unittests", + "test_id_prefix": "ninja://mojo:mojo_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "native_theme_unittests", + "test_id_prefix": "ninja://ui/native_theme:native_theme_unittests/" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.net_unittests.filter" + ], + "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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 4 + }, + "test": "net_unittests", + "test_id_prefix": "ninja://net:net_unittests/" + }, + { + "args": [ + "--child-arg=--ozone-platform=headless" + ], + "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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "ozone_gl_unittests", + "test_id_prefix": "ninja://ui/ozone/gl:ozone_gl_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "ozone_unittests", + "test_id_prefix": "ninja://ui/ozone:ozone_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "perfetto_unittests", + "test_id_prefix": "ninja://third_party/perfetto:perfetto_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "service_manager_unittests", + "test_id_prefix": "ninja://services/service_manager/tests:service_manager_unittests/" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.services_unittests.filter" + ], + "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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "services_unittests", + "test_id_prefix": "ninja://services:services_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "shell_dialogs_unittests", + "test_id_prefix": "ninja://ui/shell_dialogs:shell_dialogs_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "skia_unittests", + "test_id_prefix": "ninja://skia:skia_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "snapshot_unittests", + "test_id_prefix": "ninja://ui/snapshot:snapshot_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "sql_unittests", + "test_id_prefix": "ninja://sql:sql_unittests/" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.storage_unittests.filter" + ], + "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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "storage_unittests", + "test_id_prefix": "ninja://storage:storage_unittests/" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.ui_base_unittests.filter" + ], + "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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "ui_base_unittests", + "test_id_prefix": "ninja://ui/base:ui_base_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "ui_touch_selection_unittests", + "test_id_prefix": "ninja://ui/touch_selection:ui_touch_selection_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "url_unittests", + "test_id_prefix": "ninja://url:url_unittests/" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.views_examples_unittests.filter" + ], + "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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "views_examples_unittests", + "test_id_prefix": "ninja://ui/views/examples:views_examples_unittests/" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.views_unittests.filter" + ], + "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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "views_unittests", + "test_id_prefix": "ninja://ui/views:views_unittests/" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.viz_unittests.filter" + ], + "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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "viz_unittests", + "test_id_prefix": "ninja://components/viz:viz_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "web_engine_browsertests", + "test_id_prefix": "ninja://fuchsia/engine:web_engine_browsertests/" + }, + { + "args": [ + "--child-arg=--vmodule=test_navigation_listener=1" + ], + "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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "web_engine_integration_tests", + "test_id_prefix": "ninja://fuchsia/engine:web_engine_integration_tests/" + }, + { + "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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "web_engine_unittests", + "test_id_prefix": "ninja://fuchsia/engine:web_engine_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "web_runner_integration_tests", + "test_id_prefix": "ninja://fuchsia/runners:web_runner_integration_tests/" + }, + { + "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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "wm_unittests", + "test_id_prefix": "ninja://ui/wm:wm_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "wtf_unittests", + "test_id_prefix": "ninja://third_party/blink/renderer/platform/wtf:wtf_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-20.04", + "pool": "chromium.tests.fuchsia" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "zlib_unittests", + "test_id_prefix": "ninja://third_party/zlib:zlib_unittests/" + } + ] + }, "fuchsia-fyi-arm64-femu": { "additional_compile_targets": [ "all" @@ -26293,7 +27679,6 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.content_browsertests.filter", "--", "--disable-gpu", "--headless", @@ -28946,7 +30331,6 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.content_browsertests.filter", "--", "--disable-gpu", "--headless", @@ -30332,7 +31716,6 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.content_browsertests.filter", "--", "--disable-gpu", "--headless", @@ -90617,21 +92000,21 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5026.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5027.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5026.0", + "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5027.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v103.0.5026.0", - "revision": "version:103.0.5026.0" + "location": "lacros_version_skew_tests_v103.0.5027.0", + "revision": "version:103.0.5027.0" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -90734,21 +92117,21 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5026.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5027.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5026.0", + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5027.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v103.0.5026.0", - "revision": "version:103.0.5026.0" + "location": "lacros_version_skew_tests_v103.0.5027.0", + "revision": "version:103.0.5027.0" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -92126,20 +93509,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5026.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5027.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5026.0", + "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5027.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v103.0.5026.0", - "revision": "version:103.0.5026.0" + "location": "lacros_version_skew_tests_v103.0.5027.0", + "revision": "version:103.0.5027.0" } ], "dimension_sets": [ @@ -92268,20 +93651,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5026.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5027.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5026.0", + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5027.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v103.0.5026.0", - "revision": "version:103.0.5026.0" + "location": "lacros_version_skew_tests_v103.0.5027.0", + "revision": "version:103.0.5027.0" } ], "dimension_sets": [ @@ -93823,20 +95206,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5026.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5027.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5026.0", + "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5027.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v103.0.5026.0", - "revision": "version:103.0.5026.0" + "location": "lacros_version_skew_tests_v103.0.5027.0", + "revision": "version:103.0.5027.0" } ], "dimension_sets": [ @@ -93965,20 +95348,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5026.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5027.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5026.0", + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5027.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v103.0.5026.0", - "revision": "version:103.0.5026.0" + "location": "lacros_version_skew_tests_v103.0.5027.0", + "revision": "version:103.0.5027.0" } ], "dimension_sets": [ @@ -94722,20 +96105,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5026.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5027.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "interactive_ui_tests Lacros version skew testing ash 103.0.5026.0", + "name": "interactive_ui_tests Lacros version skew testing ash 103.0.5027.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v103.0.5026.0", - "revision": "version:103.0.5026.0" + "location": "lacros_version_skew_tests_v103.0.5027.0", + "revision": "version:103.0.5027.0" } ], "dimension_sets": [
diff --git a/testing/buildbot/filters/BUILD.gn b/testing/buildbot/filters/BUILD.gn index c8d493fb..25a91f5f 100644 --- a/testing/buildbot/filters/BUILD.gn +++ b/testing/buildbot/filters/BUILD.gn
@@ -127,7 +127,6 @@ "//testing/buildbot/filters/android.marshmallow_tablet_tester.content_browsertests.filter", "//testing/buildbot/filters/cast-linux.content_browsertests.filter", "//testing/buildbot/filters/chromium.webrtc.fyi.android.tests.dbg.content_browsertests.filter", - "//testing/buildbot/filters/fuchsia.content_browsertests.filter", "//testing/buildbot/filters/linux-lacros.content_browsertests.filter", "//testing/buildbot/filters/site_isolation_android.content_browsertests.filter", "//testing/buildbot/filters/vulkan.content_browsertests.filter",
diff --git a/testing/buildbot/filters/fuchsia.content_browsertests.filter b/testing/buildbot/filters/fuchsia.content_browsertests.filter deleted file mode 100644 index fe319a9..0000000 --- a/testing/buildbot/filters/fuchsia.content_browsertests.filter +++ /dev/null
@@ -1,24 +0,0 @@ -# Being ported, https://crbug.com/1071095. - --All/WorkerFromAnonymousIframeNikBrowserTest.SharedWorkerRequestIsDoneWithPartitionedNetworkState/0 --All/WorkerFromAnonymousIframeNikBrowserTest.SharedWorkerRequestIsDoneWithPartitionedNetworkState/1 --All/WorkerFromAnonymousIframeNikBrowserTest.SharedWorkerRequestIsDoneWithPartitionedNetworkState/2 --ContentBrowserTest.BrowserCrashCallStack --ContentBrowserTest.RendererCrashCallStack --CrossPlatformAccessibilityBrowserTest.ControlsIdsForDateTimePopup --DirectSocketsTcpBrowserTest.OpenTcp_MDNS --MojoSandboxTest.NotIsProcessSandboxed --PrerenderBrowserTest.AbandonIfRendererProcessCrashes --SitePerProcessDelegatedInkBrowserTest.MetadataAndPointGoThroughOOPIF --SnapshotBrowserTest.AsyncMultiWindowTest --SnapshotBrowserTest.SyncMultiWindowTest --StorageServiceSandboxBrowserTest.CompactDatabase --UserMedia/WebRtcConstraintsBrowserTest.GetUserMediaConstraints/4 --WebContentsViewAuraTest.OverscrollNavigation --WebContentsViewAuraTest.OverscrollNavigationWithTouchHandler --WebContentsViewAuraTest.RepeatedQuickOverscrollGestures --WebRtcVideoCaptureServiceBrowserTest.FramesSentThroughTextureVirtualDeviceGetDisplayedOnPage - -# crbug.com/1280308: Tests are passing on a NUC but failing on the ARM64 bots. --MSE_ClearKey/EncryptedMediaTest.Playback_VideoOnly_WebM_VP9Profile2/0 --MSE_ClearKey/EncryptedMediaTest.Playback_VideoOnly_MP4_VP9Profile2/0
diff --git a/testing/buildbot/mixins.pyl b/testing/buildbot/mixins.pyl index 4fc75d4..0ddc91e 100644 --- a/testing/buildbot/mixins.pyl +++ b/testing/buildbot/mixins.pyl
@@ -457,6 +457,14 @@ ], }, }, + 'fuchsia-test-pool': { + # This pool is dedicated to test the test infra of fuchsia in chromium. + 'swarming': { + 'dimensions': { + 'pool': 'chromium.tests.fuchsia', + }, + }, + }, 'fuchsia_logs': { '$mixin_append': { 'args': [
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 0ee31d8b..a0bd72c 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -1898,7 +1898,6 @@ }, 'content_browsertests': { 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.content_browsertests.filter', '--', '--disable-gpu', '--headless',
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index 2c690ab..4592b93 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -22,15 +22,15 @@ }, 'LACROS_VERSION_SKEW_CANARY': { 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5026.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5027.0/test_ash_chrome', ], - 'identifier': 'Lacros version skew testing ash 103.0.5026.0', + 'identifier': 'Lacros version skew testing ash 103.0.5027.0', 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v103.0.5026.0', - 'revision': 'version:103.0.5026.0', + 'location': 'lacros_version_skew_tests_v103.0.5027.0', + 'revision': 'version:103.0.5027.0', }, ], },
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 5ec1957..2705fe5 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -3067,6 +3067,22 @@ 'linux-focal', ], }, + # A temporary builder to test the changes to the emulator arguments on + # arm64. + 'fuchsia-fyi-arm64-emu-arg': { + 'additional_compile_targets': [ + 'all', + ], + 'test_suites': { + 'gtest_tests': 'fuchsia_gtests', + }, + 'mixins': [ + 'arm64', + 'docker', + 'fuchsia-test-pool', + 'linux-focal', + ], + }, 'fuchsia-fyi-arm64-femu': { 'additional_compile_targets': [ 'all',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 558f598d..f253e92 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -3483,35 +3483,6 @@ ] } ], - "GoogleLensDesktopContextMenuSearch": [ - { - "platforms": [ - "chromeos", - "chromeos_lacros", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "Enabled", - "params": { - "availability": "any", - "enable-ukm-logging": "true", - "event_trigger": "name:side_panel_trigger;comparator:==0;window:360;storage:360", - "event_used": "name:side_panel_shown;comparator:==0;window:360;storage:360", - "session_rate": "any" - }, - "enable_features": [ - "IPH_ReadingListInSidePanel", - "LensRegionSearch", - "LensStandalone", - "SidePanel" - ] - } - ] - } - ], "GoogleLensIOS": [ { "platforms": [ @@ -4082,6 +4053,21 @@ ] } ], + "IOSThumbstrip": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ExpandedTabStrip" + ] + } + ] + } + ], "IOSUseUserDefaultsForExitedCleanlyBeacon": [ { "platforms": [ @@ -5242,6 +5228,32 @@ ] } ], + "OptimizeViewportConstrainedPaintInvalidation": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "OptimizeViewportConstrainedPaintInvalidation" + ] + }, + { + "name": "Control", + "disable_features": [ + "OptimizeViewportConstrainedPaintInvalidation" + ] + } + ] + } + ], "OptionalToolbarButton": [ { "platforms": [ @@ -6671,6 +6683,21 @@ ] } ], + "SharedHighlightingAmp": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SharedHighlightingAmp" + ] + } + ] + } + ], "SharedHighlightingIOS": [ { "platforms": [ @@ -7332,7 +7359,7 @@ ] } ], - "TouchToFillPasswordSubmissionAndroid": [ + "TouchToFillPasswordSubmissionStudy": [ { "platforms": [ "android"
diff --git a/third_party/blink/public/common/storage_key/storage_key.h b/third_party/blink/public/common/storage_key/storage_key.h index 11d1883..1684d19 100644 --- a/third_party/blink/public/common/storage_key/storage_key.h +++ b/third_party/blink/public/common/storage_key/storage_key.h
@@ -8,14 +8,13 @@ #include <iosfwd> #include <string> -#include "base/strings/string_piece.h" +#include "base/strings/string_piece_forward.h" #include "base/unguessable_token.h" #include "net/base/schemeful_site.h" #include "net/cookies/site_for_cookies.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/common/common_export.h" #include "third_party/blink/public/mojom/storage_key/ancestor_chain_bit.mojom.h" -#include "url/gurl.h" #include "url/origin.h" namespace blink {
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl index f731277..9c30a37 100644 --- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl +++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -744,36 +744,67 @@ type DeprecationIssueType extends string enum AuthorizationCoveredByWildcard + BatteryStatusInsecureOrigin + CanRequestURLHTTPContainingNewline + ChromeLoadTimesConnectionInfo + ChromeLoadTimesFirstPaintAfterLoadTime + ChromeLoadTimesWasAlternateProtocolAvailable CookieWithTruncatingChar CrossOriginAccessBasedOnDocumentDomain CrossOriginWindowAlert CrossOriginWindowConfirm + CSSSelectorInternalMediaControlsOverlayCastButton + CustomCursorIntersectsViewport DeprecationExample DocumentDomainSettingWithoutOriginAgentClusterHeader + EventPath GeolocationInsecureOrigin GeolocationInsecureOriginDeprecatedNotRemoved GetUserMediaInsecureOrigin + HostCandidateAttributeGetter + InsecurePrivateNetworkSubresourceRequest LegacyConstraintGoogCpuOveruseDetection LegacyConstraintGoogIPv6 LegacyConstraintGoogScreencastMinBitrate LegacyConstraintGoogSuspendBelowMinBitrate LocalCSSFileExtensionRejected + MediaElementAudioSourceNode + MediaSourceAbortRemove + MediaSourceDurationTruncatingBuffered + NoSysexWebMIDIWithoutPermission NotificationInsecureOrigin + NotificationPermissionRequestedIframe ObsoleteWebRtcCipherSuite + PaymentRequestBasicCard + PaymentRequestShowWithoutGesture PictureSourceSrc PrefixedCancelAnimationFrame PrefixedRequestAnimationFrame + PrefixedStorageInfo + PrefixedVideoDisplayingFullscreen + PrefixedVideoEnterFullscreen + PrefixedVideoEnterFullScreen + PrefixedVideoExitFullscreen + PrefixedVideoExitFullScreen + PrefixedVideoSupportsFullscreen + RangeExpand + RequestedSubresourceWithEmbeddedCredentials RTCConstraintEnableDtlsSrtpFalse RTCConstraintEnableDtlsSrtpTrue RTCPeerConnectionComplexPlanBSdpUsingDefaultSdpSemantics RTCPeerConnectionLegacyCreateWithMediaConstraints + RTCPeerConnectionSdpSemanticsPlanB + RtcpMuxPolicyNegotiate RTPDataChannel + SelectionAddRangeIntersect SharedArrayBufferConstructedWithoutIsolation + TextToSpeech_DisallowedByAutoplay Untranslated V8SharedArrayBufferConstructedInExtensionWithoutIsolation WebCodecsVideoFrameDefaultTimestamp XHRJSONEncodingDetection XMLHttpRequestSynchronousInNonWorkerOutsideBeforeUnload + XRSupportsSession # This issue tracks information needed to print a deprecation message. # The formatting is inherited from the old console.log version, see more at:
diff --git a/third_party/blink/public/mojom/payments/payment_request.mojom b/third_party/blink/public/mojom/payments/payment_request.mojom index fe7791d0..e09d2fd 100644 --- a/third_party/blink/public/mojom/payments/payment_request.mojom +++ b/third_party/blink/public/mojom/payments/payment_request.mojom
@@ -250,6 +250,17 @@ PaymentOptions options); // Shows the user interface with the payment details. + // |wait_for_updated_details|: It's true when merchant passed in a promise + // into PaymentRequest.show(), so Chrome should disregard the initial payment + // details and show a spinner until the promise resolves with the correct + // payment details. The payment details will be updated with UpdateWith(). + ShowNew(bool wait_for_updated_details); + + // Shows the user interface with the payment details. + // + // DEPRECATED: Use ShowNew(bool wait_for_updated_details), which will replace + // this method very shortly. + // // |is_user_gesture|: Whether the show is triggered from a user gesture. // |wait_for_updated_details|: It's true when merchant passed in a promise // into PaymentRequest.show(), so Chrome should disregard the initial payment
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 293ba81..224cdcd 100644 --- a/third_party/blink/public/mojom/web_feature/web_feature.mojom +++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -3534,6 +3534,9 @@ kDeferredShapingDisabledByPositioned = 4213, kCapabilityDelegationOfFullscreenRequest = 4214, kSerialPortForget = 4215, + kCookieHasNotBeenRefreshedIn201To300Days = 4216, + kCookieHasNotBeenRefreshedIn301To350Days = 4217, + kCookieHasNotBeenRefreshedIn351To400Days = 4218, // 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/renderer/core/execution_context/execution_context.cc b/third_party/blink/renderer/core/execution_context/execution_context.cc index ab29132a..a38cecd 100644 --- a/third_party/blink/renderer/core/execution_context/execution_context.cc +++ b/third_party/blink/renderer/core/execution_context/execution_context.cc
@@ -530,11 +530,6 @@ policy_container_->UpdateReferrerPolicy(referrer_policy); } -void ExecutionContext::SetAddressSpace( - network::mojom::blink::IPAddressSpace ip_address_space) { - GetPolicyContainer()->SetIPAddressSpace(ip_address_space); -} - void ExecutionContext::SetPolicyContainer( std::unique_ptr<PolicyContainer> container) { policy_container_ = std::move(container);
diff --git a/third_party/blink/renderer/core/execution_context/execution_context.h b/third_party/blink/renderer/core/execution_context/execution_context.h index 9a16869a..02b5758 100644 --- a/third_party/blink/renderer/core/execution_context/execution_context.h +++ b/third_party/blink/renderer/core/execution_context/execution_context.h
@@ -32,7 +32,6 @@ #include "base/notreached.h" #include "services/metrics/public/cpp/ukm_source_id.h" -#include "services/network/public/mojom/ip_address_space.mojom-blink-forward.h" #include "services/network/public/mojom/referrer_policy.mojom-blink-forward.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/common/tokens/tokens.h" @@ -374,9 +373,6 @@ const String& message = g_empty_string, const String& source_file = g_empty_string) const {} - // TODO(https://crbug.com/1204028): Remove this, it is useless. - void SetAddressSpace(network::mojom::blink::IPAddressSpace ip_address_space); - HeapObserverSet<ContextLifecycleObserver>& ContextLifecycleObserverSet(); unsigned ContextLifecycleStateObserverCountForTesting() const;
diff --git a/third_party/blink/renderer/core/frame/deprecation/deprecation.cc b/third_party/blink/renderer/core/frame/deprecation/deprecation.cc index 727fa69..2f2a4ef 100644 --- a/third_party/blink/renderer/core/frame/deprecation/deprecation.cc +++ b/third_party/blink/renderer/core/frame/deprecation/deprecation.cc
@@ -26,231 +26,9 @@ namespace { -enum Milestone { - kUnknown, - kM61 = 61, - kM62 = 62, - kM64 = 64, - kM65 = 65, - kM70 = 70, - kM71 = 71, - kM72 = 72, - kM75 = 75, - kM76 = 76, - kM77 = 77, - kM78 = 78, - kM79 = 79, - kM80 = 80, - kM81 = 81, - kM82 = 82, - kM83 = 83, - kM84 = 84, - kM85 = 85, - kM86 = 86, - kM87 = 87, - kM88 = 88, - kM89 = 89, - kM90 = 90, - kM91 = 91, - kM92 = 92, - kM93 = 93, - kM94 = 94, - kM95 = 95, - kM96 = 96, - kM97 = 97, - kM98 = 98, - kM99 = 99, - kM100 = 100, - kM101 = 101, - kM102 = 102, - kM103 = 103, - kM104 = 104, - kM105 = 105, - kM106 = 106, - kM107 = 107, - kM108 = 108, - kM109 = 109, -}; - -// Returns estimated milestone dates as milliseconds since January 1, 1970. -base::Time::Exploded MilestoneDate(Milestone milestone) { - // These are the Estimated Stable Dates: - // https://chromiumdash.appspot.com/schedule - // All dates except for kUnknown are at 04:00:00 GMT. - switch (milestone) { - case kUnknown: - break; - case kM61: - return {2017, 9, 0, 5, 4}; - case kM62: - return {2017, 10, 0, 17, 4}; - case kM64: - return {2018, 1, 0, 23, 4}; - case kM65: - return {2018, 3, 0, 6, 4}; - case kM70: - return {2018, 10, 0, 16, 4}; - case kM71: - return {2018, 12, 0, 4, 4}; - case kM72: - return {2019, 1, 0, 29, 4}; - case kM75: - return {2019, 6, 0, 4, 4}; - case kM76: - return {2019, 7, 0, 30, 4}; - case kM77: - return {2019, 9, 0, 10, 4}; - case kM78: - return {2019, 10, 0, 22, 4}; - case kM79: - return {2019, 12, 0, 10, 4}; - case kM80: - return {2020, 2, 0, 4, 4}; - case kM81: - return {2020, 4, 0, 7, 4}; - case kM82: - // This release was cancelled, so this is the (new) M83 date. - // https://groups.google.com/a/chromium.org/d/msg/chromium-dev/N1NxbSVOZas/ySlEKDKkBgAJ - return {2020, 5, 0, 18, 4}; - case kM83: - return {2020, 5, 0, 18, 4}; - case kM84: - return {2020, 7, 0, 14, 4}; - case kM85: - return {2020, 8, 0, 25, 4}; - case kM86: - return {2020, 10, 0, 6, 4}; - case kM87: - return {2020, 11, 0, 17, 4}; - case kM88: - return {2021, 1, 0, 19, 4}; - case kM89: - return {2021, 3, 0, 2, 4}; - case kM90: - return {2021, 4, 0, 13, 4}; - case kM91: - return {2021, 5, 0, 25, 4}; - case kM92: - return {2021, 7, 0, 20, 4}; - case kM93: - return {2021, 8, 0, 31, 4}; - case kM94: - return {2021, 9, 0, 21, 4}; - case kM95: - return {2021, 10, 0, 19, 4}; - case kM96: - return {2022, 11, 0, 16, 4}; - case kM97: - return {2022, 1, 0, 4, 4}; - case kM98: - return {2022, 2, 0, 1, 4}; - case kM99: - return {2022, 3, 0, 1, 4}; - case kM100: - return {2022, 3, 0, 29, 4}; - case kM101: - return {2022, 4, 0, 26, 4}; - case kM102: - return {2022, 5, 0, 24, 4}; - case kM103: - return {2022, 6, 0, 21, 4}; - case kM104: - return {2022, 7, 0, 26, 4}; - case kM105: - return {2022, 8, 0, 30, 4}; - case kM106: - return {2022, 9, 0, 27, 4}; - case kM107: - return {2022, 10, 0, 25, 4}; - case kM108: - return {2022, 11, 0, 29, 4}; - case kM109: - return {2023, 1, 0, 10, 4}; - } - - NOTREACHED(); - return {1970, 1, 0, 1, 0}; -} - -// Returns estimated milestone dates as human-readable strings. -String MilestoneString(Milestone milestone) { - if (milestone == kUnknown) - return String(); - base::Time::Exploded date = MilestoneDate(milestone); - return String::Format("M%d, around %s %d", milestone, - WTF::kMonthFullName[date.month - 1], date.year); -} - +// TODO(crbug/1264960): Cleanup or remove this class. class DeprecationInfo final { public: - // Use this to inform developers of any `details` for the deprecation with - // info at `chrome_status_id`. Use this format only if none of the ones below - // make sense. - static const DeprecationInfo WithDetailsAndChromeStatusID( - WebFeature feature, - const String& id, - Milestone milestone, - const String& details, - const String& chrome_status_id) { - return DeprecationInfo( - feature, DeprecationIssueType::kUntranslated, id, - String::Format( - "%s See https://www.chromestatus.com/feature/%s for more details.", - details.Ascii().c_str(), chrome_status_id.Ascii().c_str())); - } - - // Use this to inform developers a deprecated `feature` has a `replacement`. - static const DeprecationInfo WithFeatureAndReplacement( - WebFeature feature, - const String& id, - Milestone milestone, - const String& feature_name, - const String& replacement) { - return DeprecationInfo( - feature, DeprecationIssueType::kUntranslated, id, - String::Format("%s is deprecated. Please use %s instead.", - feature_name.Ascii().c_str(), - replacement.Ascii().c_str())); - } - - // Use this to inform developers a deprecated `feature` has info at - // `chrome_status_id`. - static const DeprecationInfo WithFeatureAndChromeStatusID( - WebFeature feature, - const String& id, - Milestone milestone, - const String& feature_name, - const String& chrome_status_id) { - return DeprecationInfo( - feature, DeprecationIssueType::kUntranslated, id, - String::Format( - "%s is deprecated and will be removed in %s. See " - "https://www.chromestatus.com/feature/%s for more details.", - feature_name.Ascii().c_str(), - MilestoneString(milestone).Ascii().c_str(), - chrome_status_id.Ascii().c_str())); - } - - // Use this to inform developers a deprecated `feature` has a `replacement` - // and info at `chrome_status_id`. - static const DeprecationInfo WithFeatureAndReplacementAndChromeStatusID( - WebFeature feature, - const String& id, - Milestone milestone, - const String& feature_name, - const String& replacement, - const String& chrome_status_id) { - return DeprecationInfo( - feature, DeprecationIssueType::kUntranslated, id, - String::Format( - "%s is deprecated and will be removed in %s. Please use %s " - "instead. See https://www.chromestatus.com/feature/%s for more " - "details.", - feature_name.Ascii().c_str(), - MilestoneString(milestone).Ascii().c_str(), - replacement.Ascii().c_str(), chrome_status_id.Ascii().c_str())); - } - static const DeprecationInfo WithTranslation( WebFeature feature, const DeprecationIssueType& type) { @@ -278,52 +56,37 @@ // TODO(crbug/1264960): Consider migrating this switch statement to // third_party/blink/renderer/core/inspector/inspector_audits_issue.h to stop // passing around protocol::Audits::DeprecationIssueType once all deprecations -// are translated. +// are translated. Alternatively, alphabetize this list. const DeprecationInfo GetDeprecationInfo(WebFeature feature) { switch (feature) { // Quota case WebFeature::kPrefixedStorageInfo: - return DeprecationInfo::WithFeatureAndReplacement( - feature, "PrefixedStorageInfo", kUnknown, - "'window.webkitStorageInfo'", - "'navigator.webkitTemporaryStorage' or " - "'navigator.webkitPersistentStorage'"); + return DeprecationInfo::WithTranslation( + feature, DeprecationIssueType::kPrefixedStorageInfo); case WebFeature::kPrefixedVideoSupportsFullscreen: - return DeprecationInfo::WithFeatureAndReplacement( - feature, "PrefixedVideoSupportsFullscreen", kUnknown, - "'HTMLVideoElement.webkitSupportsFullscreen'", - "'Document.fullscreenEnabled'"); + return DeprecationInfo::WithTranslation( + feature, DeprecationIssueType::kPrefixedVideoSupportsFullscreen); case WebFeature::kPrefixedVideoDisplayingFullscreen: - return DeprecationInfo::WithFeatureAndReplacement( - feature, "PrefixedVideoDisplayingFullscreen", kUnknown, - "'HTMLVideoElement.webkitDisplayingFullscreen'", - "'Document.fullscreenElement'"); + return DeprecationInfo::WithTranslation( + feature, DeprecationIssueType::kPrefixedVideoDisplayingFullscreen); case WebFeature::kPrefixedVideoEnterFullscreen: - return DeprecationInfo::WithFeatureAndReplacement( - feature, "PrefixedVideoEnterFullscreen", kUnknown, - "'HTMLVideoElement.webkitEnterFullscreen()'", - "'Element.requestFullscreen()'"); + return DeprecationInfo::WithTranslation( + feature, DeprecationIssueType::kPrefixedVideoEnterFullscreen); case WebFeature::kPrefixedVideoExitFullscreen: - return DeprecationInfo::WithFeatureAndReplacement( - feature, "PrefixedVideoExitFullscreen", kUnknown, - "'HTMLVideoElement.webkitExitFullscreen()'", - "'Document.exitFullscreen()'"); + return DeprecationInfo::WithTranslation( + feature, DeprecationIssueType::kPrefixedVideoExitFullscreen); case WebFeature::kPrefixedVideoEnterFullScreen: - return DeprecationInfo::WithFeatureAndReplacement( - feature, "PrefixedVideoEnterFullScreen", kUnknown, - "'HTMLVideoElement.webkitEnterFullScreen()'", - "'Element.requestFullscreen()'"); + return DeprecationInfo::WithTranslation( + feature, DeprecationIssueType::kPrefixedVideoEnterFullScreen); case WebFeature::kPrefixedVideoExitFullScreen: - return DeprecationInfo::WithFeatureAndReplacement( - feature, "PrefixedVideoExitFullScreen", kUnknown, - "'HTMLVideoElement.webkitExitFullScreen()'", - "'Document.exitFullscreen()'"); + return DeprecationInfo::WithTranslation( + feature, DeprecationIssueType::kPrefixedVideoExitFullScreen); case WebFeature::kPrefixedRequestAnimationFrame: return DeprecationInfo::WithTranslation( @@ -344,17 +107,14 @@ kXMLHttpRequestSynchronousInNonWorkerOutsideBeforeUnload); case WebFeature::kRangeExpand: - return DeprecationInfo::WithFeatureAndReplacement( - feature, "RangeExpand", kUnknown, "'Range.expand()'", - "'Selection.modify()'"); + return DeprecationInfo::WithTranslation( + feature, DeprecationIssueType::kRangeExpand); // Blocked subresource requests: case WebFeature::kRequestedSubresourceWithEmbeddedCredentials: - return DeprecationInfo::WithDetailsAndChromeStatusID( - feature, "RequestedSubresourceWithEmbeddedCredentials", kUnknown, - "Subresource requests whose URLs contain embedded credentials (e.g. " - "`https://user:pass@host/`) are blocked.", - "5669008342777856"); + return DeprecationInfo::WithTranslation( + feature, + DeprecationIssueType::kRequestedSubresourceWithEmbeddedCredentials); // Powerful features on insecure origins (https://goo.gl/rStTGz) case WebFeature::kGeolocationInsecureOrigin: @@ -374,25 +134,13 @@ feature, DeprecationIssueType::kGetUserMediaInsecureOrigin); case WebFeature::kMediaSourceAbortRemove: - return DeprecationInfo::WithDetailsAndChromeStatusID( - feature, "MediaSourceAbortRemove", kUnknown, - "Using SourceBuffer.abort() to abort remove()'s asynchronous range " - "removal is deprecated due to specification change. Support will be " - "removed in the future. You should instead await 'updateend'. " - "abort() is intended to only abort an asynchronous media append or " - "reset parser state.", - "6107495151960064"); + return DeprecationInfo::WithTranslation( + feature, DeprecationIssueType::kMediaSourceAbortRemove); case WebFeature::kMediaSourceDurationTruncatingBuffered: - return DeprecationInfo::WithDetailsAndChromeStatusID( - feature, "MediaSourceDurationTruncatingBuffered", kUnknown, - "Setting MediaSource.duration below the highest presentation " - "timestamp of any buffered coded frames is deprecated due to " - "specification change. Support for implicit removal of truncated " - "buffered media will be removed in the future. You should instead " - "perform explicit remove(newDuration, oldDuration) on all " - "sourceBuffers, where newDuration < oldDuration.", - "6107495151960064"); + return DeprecationInfo::WithTranslation( + feature, + DeprecationIssueType::kMediaSourceDurationTruncatingBuffered); case WebFeature::kNotificationInsecureOrigin: case WebFeature::kNotificationAPIInsecureOriginIframe: @@ -401,50 +149,30 @@ feature, DeprecationIssueType::kNotificationInsecureOrigin); case WebFeature::kNotificationPermissionRequestedIframe: - return DeprecationInfo::WithDetailsAndChromeStatusID( - feature, "NotificationPermissionRequestedIframe", kUnknown, - "Permission for the Notification API may no longer be requested from " - "a cross-origin iframe. You should consider requesting permission " - "from a top-level frame or opening a new window instead.", - "6451284559265792"); + return DeprecationInfo::WithTranslation( + feature, + DeprecationIssueType::kNotificationPermissionRequestedIframe); case WebFeature::kBatteryStatusInsecureOrigin: - return DeprecationInfo::WithFeatureAndChromeStatusID( - feature, "BatteryStatusInsecureOrigin", Milestone::kM103, - "Using the Battery Status API (e.g. navigator.getBattery()) in " - "insecure origins like HTTP", - "4878376799043584"); + return DeprecationInfo::WithTranslation( + feature, DeprecationIssueType::kBatteryStatusInsecureOrigin); case WebFeature::kCSSSelectorInternalMediaControlsOverlayCastButton: - return DeprecationInfo::WithDetailsAndChromeStatusID( - feature, "CSSSelectorInternalMediaControlsOverlayCastButton", - kUnknown, - "The disableRemotePlayback attribute should be used in order to " - "disable the default Cast integration instead of using " - "-internal-media-controls-overlay-cast-button selector.", - "5714245488476160"); + return DeprecationInfo::WithTranslation( + feature, DeprecationIssueType:: + kCSSSelectorInternalMediaControlsOverlayCastButton); case WebFeature::kSelectionAddRangeIntersect: - return DeprecationInfo::WithDetailsAndChromeStatusID( - feature, "SelectionAddRangeIntersect", kUnknown, - "The behavior that Selection.addRange() merges existing Range and " - "the specified Range was removed.", - "6680566019653632"); + return DeprecationInfo::WithTranslation( + feature, DeprecationIssueType::kSelectionAddRangeIntersect); case WebFeature::kRtcpMuxPolicyNegotiate: - return DeprecationInfo::WithFeatureAndChromeStatusID( - feature, "RtcpMuxPolicyNegotiate", kM62, "The rtcpMuxPolicy option", - "5654810086866944"); + return DeprecationInfo::WithTranslation( + feature, DeprecationIssueType::kRtcpMuxPolicyNegotiate); case WebFeature::kCanRequestURLHTTPContainingNewline: - return DeprecationInfo::WithDetailsAndChromeStatusID( - feature, "CanRequestURLHTTPContainingNewline", kUnknown, - "Resource requests whose URLs contained both removed whitespace " - "(`\\n`, `\\r`, `\\t`) characters and less-than characters (`<`) are " - "blocked. Please remove newlines and encode less-than characters " - "from places like element attribute values in order to load these " - "resources.", - "5735596811091968"); + return DeprecationInfo::WithTranslation( + feature, DeprecationIssueType::kCanRequestURLHTTPContainingNewline); case WebFeature::kLocalCSSFileExtensionRejected: return DeprecationInfo::WithTranslation( @@ -457,41 +185,30 @@ case WebFeature::kChromeLoadTimesFinishLoadTime: case WebFeature::kChromeLoadTimesNavigationType: case WebFeature::kChromeLoadTimesConnectionInfo: - return DeprecationInfo::WithDetailsAndChromeStatusID( - feature, "ChromeLoadTimesConnectionInfo", kUnknown, - "chrome.loadTimes() is deprecated, instead use standardized API: " - "Navigation Timing 2.", - "5637885046816768"); + return DeprecationInfo::WithTranslation( + feature, DeprecationIssueType::kChromeLoadTimesConnectionInfo); case WebFeature::kChromeLoadTimesFirstPaintTime: case WebFeature::kChromeLoadTimesFirstPaintAfterLoadTime: - return DeprecationInfo::WithDetailsAndChromeStatusID( - feature, "ChromeLoadTimesFirstPaintAfterLoadTime", kUnknown, - "chrome.loadTimes() is deprecated, instead use standardized API: " - "Paint Timing.", - "5637885046816768"); + return DeprecationInfo::WithTranslation( + feature, + DeprecationIssueType::kChromeLoadTimesFirstPaintAfterLoadTime); case WebFeature::kChromeLoadTimesWasFetchedViaSpdy: case WebFeature::kChromeLoadTimesWasNpnNegotiated: case WebFeature::kChromeLoadTimesNpnNegotiatedProtocol: case WebFeature::kChromeLoadTimesWasAlternateProtocolAvailable: - return DeprecationInfo::WithDetailsAndChromeStatusID( - feature, "ChromeLoadTimesWasAlternateProtocolAvailable", kUnknown, - "chrome.loadTimes() is deprecated, instead use standardized API: " - "nextHopProtocol in Navigation Timing 2.", - "5637885046816768"); + return DeprecationInfo::WithTranslation( + feature, + DeprecationIssueType::kChromeLoadTimesWasAlternateProtocolAvailable); case WebFeature::kMediaElementSourceOnOfflineContext: - return DeprecationInfo::WithFeatureAndChromeStatusID( - feature, "MediaElementAudioSourceNode", kM71, - "Creating a MediaElementAudioSourceNode on an OfflineAudioContext", - "5258622686724096"); + return DeprecationInfo::WithTranslation( + feature, DeprecationIssueType::kMediaElementAudioSourceNode); case WebFeature::kTextToSpeech_SpeakDisallowedByAutoplay: - return DeprecationInfo::WithFeatureAndChromeStatusID( - feature, "TextToSpeech_DisallowedByAutoplay", kM71, - "speechSynthesis.speak() without user activation", - "5687444770914304"); + return DeprecationInfo::WithTranslation( + feature, DeprecationIssueType::kTextToSpeech_DisallowedByAutoplay); case WebFeature::kRTCPeerConnectionComplexPlanBSdpUsingDefaultSdpSemantics: return DeprecationInfo::WithTranslation( @@ -500,25 +217,16 @@ kRTCPeerConnectionComplexPlanBSdpUsingDefaultSdpSemantics); case WebFeature::kNoSysexWebMIDIWithoutPermission: - return DeprecationInfo::WithDetailsAndChromeStatusID( - feature, "NoSysexWebMIDIWithoutPermission", kM82, - String::Format( - "Web MIDI will ask a permission to use even if the sysex is not " - "specified in the MIDIOptions since around %s.", - MilestoneString(kM82).Ascii().c_str()), - "5138066234671104"); + return DeprecationInfo::WithTranslation( + feature, DeprecationIssueType::kNoSysexWebMIDIWithoutPermission); case WebFeature::kCustomCursorIntersectsViewport: - return DeprecationInfo::WithFeatureAndChromeStatusID( - feature, "CustomCursorIntersectsViewport", kM75, - "Custom cursors with size greater than 32x32 DIP intersecting native " - "UI", - "5825971391299584"); + return DeprecationInfo::WithTranslation( + feature, DeprecationIssueType::kCustomCursorIntersectsViewport); case WebFeature::kXRSupportsSession: - return DeprecationInfo::WithFeatureAndReplacement( - feature, "XRSupportsSession", kM80, "supportsSession()", - "isSessionSupported() and check the resolved boolean value"); + return DeprecationInfo::WithTranslation( + feature, DeprecationIssueType::kXRSupportsSession); case WebFeature::kObsoleteWebrtcTlsVersion: return DeprecationInfo::WithTranslation( @@ -535,31 +243,15 @@ feature, DeprecationIssueType::kRTPDataChannel); case WebFeature::kRTCPeerConnectionSdpSemanticsPlanB: - return DeprecationInfo::WithDetailsAndChromeStatusID( - feature, "RTCPeerConnectionSdpSemanticsPlanB", kM93, - "Plan B SDP semantics, which is used when constructing an " - "RTCPeerConnection with {sdpSemantics:\"plan-b\"}, is a legacy " - "non-standard version of the Session Description Protocol that has " - "been permanently deleted from the Web Platform. It is still " - "available when building with IS_FUCHSIA, but we intend to delete it " - "as soon as possible. Stop depending on it. See " - "https://crbug.com/1302249 for status.", - "5823036655665152"); + return DeprecationInfo::WithTranslation( + feature, DeprecationIssueType::kRTCPeerConnectionSdpSemanticsPlanB); case WebFeature::kAddressSpacePublicNonSecureContextEmbeddedPrivate: case WebFeature::kAddressSpacePublicNonSecureContextEmbeddedLocal: case WebFeature::kAddressSpacePrivateNonSecureContextEmbeddedLocal: - return DeprecationInfo::WithDetailsAndChromeStatusID( - feature, "InsecurePrivateNetworkSubresourceRequest", kM92, - "The website requested a subresource from a network that it could " - "only access because of its users' privileged network position. " - "These requests expose non-public devices and servers to the " - "internet, increasing the risk of a cross-site request forgery " - "(CSRF) attack, and/or information leakage. To mitigate these risks, " - "Chrome deprecates requests to non-public subresources when " - "initiated from non-secure contexts, and will start blocking them in " - "Chrome 92 (July 2021).", - "5436853517811712"); + return DeprecationInfo::WithTranslation( + feature, + DeprecationIssueType::kInsecurePrivateNetworkSubresourceRequest); case WebFeature::kXHRJSONEncodingDetection: return DeprecationInfo::WithTranslation( feature, DeprecationIssueType::kXHRJSONEncodingDetection); @@ -589,22 +281,16 @@ feature, DeprecationIssueType::kCrossOriginWindowConfirm); case WebFeature::kPaymentRequestBasicCard: - return DeprecationInfo::WithFeatureAndChromeStatusID( - feature, "PaymentRequestBasicCard", kM100, - "The 'basic-card' payment method", "5730051011117056"); + return DeprecationInfo::WithTranslation( + feature, DeprecationIssueType::kPaymentRequestBasicCard); case WebFeature::kPaymentRequestShowWithoutGesture: - return DeprecationInfo::WithFeatureAndChromeStatusID( - feature, "PaymentRequestShowWithoutGesture", kM102, - "Calling PaymentRequest.show() without user activation", - "5948593429020672"); + return DeprecationInfo::WithTranslation( + feature, DeprecationIssueType::kPaymentRequestShowWithoutGesture); case WebFeature::kHostCandidateAttributeGetter: - return DeprecationInfo::WithFeatureAndReplacement( - feature, "HostCandidateAttributeGetter", kUnknown, - "'RTCPeerConnectionIceErrorEvent.hostCandidate'", - "'RTCPeerConnectionIceErrorEvent.address', " - "'RTCPeerConnectionIceErrorEvent.port'"); + return DeprecationInfo::WithTranslation( + feature, DeprecationIssueType::kHostCandidateAttributeGetter); case WebFeature::kWebCodecsVideoFrameDefaultTimestamp: return DeprecationInfo::WithTranslation( @@ -625,9 +311,8 @@ feature, DeprecationIssueType::kCookieWithTruncatingChar); case WebFeature::kEventPath: - return DeprecationInfo::WithFeatureAndReplacementAndChromeStatusID( - feature, "WebFeature::kEventPath", kM109, "'Event.path'", - "'Event.composedPath()'", "5726124632965120"); + return DeprecationInfo::WithTranslation(feature, + DeprecationIssueType::kEventPath); case WebFeature::kDeprecationExample: return DeprecationInfo::WithTranslation(
diff --git a/third_party/blink/renderer/core/frame/local_frame_view_test.cc b/third_party/blink/renderer/core/frame/local_frame_view_test.cc index a222e012..0dcbf143 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view_test.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view_test.cc
@@ -6,7 +6,9 @@ #include <memory> +#include "base/test/scoped_feature_list.h" #include "testing/gmock/include/gmock/gmock.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/public/mojom/scroll/scrollbar_mode.mojom-blink.h" #include "third_party/blink/renderer/core/css/css_style_declaration.h" #include "third_party/blink/renderer/core/html/html_anchor_element.h" @@ -679,5 +681,39 @@ EXPECT_EQ(frame_view->DocumentBackgroundColor(), Color(18, 18, 18)); } +class NoOptimizeViewportConstrainedPaintInvalidationTest + : public LocalFrameViewTest { + public: + void SetUp() override { + scoped_feature_list_.InitAndDisableFeature( + features::kOptimizeViewportConstrainedPaintInvalidation); + LocalFrameViewTest::SetUp(); + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +// This tests the codepath where |kOptimizeViewportConstrainedPaintInvalidation| +// is disabled. +TEST_F(NoOptimizeViewportConstrainedPaintInvalidationTest, + StickyScrollInvalidatesPaint) { + SetBodyInnerHTML(R"HTML( + <style> + #sticky { position: sticky; top: 0; width: 50px; height: 50px; } + </style> + <div id='sticky'>sticky</div> + <div id='forcescroll' style='height: 5000px;'></div> + )HTML"); + + auto* sticky = To<LayoutBoxModelObject>(GetLayoutObjectByElementId("sticky")); + EXPECT_FALSE(sticky->SubtreeShouldCheckForPaintInvalidation()); + + GetDocument().View()->LayoutViewport()->SetScrollOffset( + ScrollOffset(0, 100), mojom::blink::ScrollType::kProgrammatic); + + EXPECT_TRUE(sticky->SubtreeShouldCheckForPaintInvalidation()); +} + } // namespace } // namespace blink
diff --git a/third_party/blink/renderer/core/frame/policy_container.cc b/third_party/blink/renderer/core/frame/policy_container.cc index e70464d5..648fb5dd 100644 --- a/third_party/blink/renderer/core/frame/policy_container.cc +++ b/third_party/blink/renderer/core/frame/policy_container.cc
@@ -58,11 +58,6 @@ policy_container_host_remote_->SetReferrerPolicy(policy); } -void PolicyContainer::SetIPAddressSpace( - network::mojom::blink::IPAddressSpace ip_address_space) { - policies_->ip_address_space = ip_address_space; -} - const mojom::blink::PolicyContainerPolicies& PolicyContainer::GetPolicies() const { return *policies_;
diff --git a/third_party/blink/renderer/core/frame/policy_container.h b/third_party/blink/renderer/core/frame/policy_container.h index a3a05ed..027e25e 100644 --- a/third_party/blink/renderer/core/frame/policy_container.h +++ b/third_party/blink/renderer/core/frame/policy_container.h
@@ -46,14 +46,6 @@ network::mojom::blink::IPAddressSpace GetIPAddressSpace() const; - // This setter is used only by worklets and workers, which do not sync the - // PolicyContainer with the browser. - // - // TODO(https://crbug.com/1177199): Remove this when we implement policy - // inheritance for workers/worklets using the PolicyContainer. - void SetIPAddressSpace( - network::mojom::blink::IPAddressSpace ip_address_space); - // Append |policies| to the list of Content Security Policy and sync them with // the PolicyContainerHost. void AddContentSecurityPolicies(
diff --git a/third_party/blink/renderer/core/inspector/inspector_audits_issue.cc b/third_party/blink/renderer/core/inspector/inspector_audits_issue.cc index d707a17..4529b58 100644 --- a/third_party/blink/renderer/core/inspector/inspector_audits_issue.cc +++ b/third_party/blink/renderer/core/inspector/inspector_audits_issue.cc
@@ -436,6 +436,26 @@ type = protocol::Audits::DeprecationIssueTypeEnum:: AuthorizationCoveredByWildcard; break; + case DeprecationIssueType::kBatteryStatusInsecureOrigin: + type = protocol::Audits::DeprecationIssueTypeEnum:: + BatteryStatusInsecureOrigin; + break; + case DeprecationIssueType::kCanRequestURLHTTPContainingNewline: + type = protocol::Audits::DeprecationIssueTypeEnum:: + CanRequestURLHTTPContainingNewline; + break; + case DeprecationIssueType::kChromeLoadTimesConnectionInfo: + type = protocol::Audits::DeprecationIssueTypeEnum:: + ChromeLoadTimesConnectionInfo; + break; + case DeprecationIssueType::kChromeLoadTimesFirstPaintAfterLoadTime: + type = protocol::Audits::DeprecationIssueTypeEnum:: + ChromeLoadTimesFirstPaintAfterLoadTime; + break; + case DeprecationIssueType::kChromeLoadTimesWasAlternateProtocolAvailable: + type = protocol::Audits::DeprecationIssueTypeEnum:: + ChromeLoadTimesWasAlternateProtocolAvailable; + break; case DeprecationIssueType::kCookieWithTruncatingChar: type = protocol::Audits::DeprecationIssueTypeEnum:: CookieWithTruncatingChar; @@ -452,6 +472,15 @@ type = protocol::Audits::DeprecationIssueTypeEnum:: CrossOriginWindowConfirm; break; + case DeprecationIssueType:: + kCSSSelectorInternalMediaControlsOverlayCastButton: + type = protocol::Audits::DeprecationIssueTypeEnum:: + CSSSelectorInternalMediaControlsOverlayCastButton; + break; + case DeprecationIssueType::kCustomCursorIntersectsViewport: + type = protocol::Audits::DeprecationIssueTypeEnum:: + CustomCursorIntersectsViewport; + break; case DeprecationIssueType::kDeprecationExample: type = protocol::Audits::DeprecationIssueTypeEnum::DeprecationExample; break; @@ -460,6 +489,9 @@ type = protocol::Audits::DeprecationIssueTypeEnum:: DocumentDomainSettingWithoutOriginAgentClusterHeader; break; + case DeprecationIssueType::kEventPath: + type = protocol::Audits::DeprecationIssueTypeEnum::EventPath; + break; case DeprecationIssueType::kGeolocationInsecureOrigin: type = protocol::Audits::DeprecationIssueTypeEnum:: GeolocationInsecureOrigin; @@ -472,6 +504,14 @@ type = protocol::Audits::DeprecationIssueTypeEnum:: GetUserMediaInsecureOrigin; break; + case DeprecationIssueType::kHostCandidateAttributeGetter: + type = protocol::Audits::DeprecationIssueTypeEnum:: + HostCandidateAttributeGetter; + break; + case DeprecationIssueType::kInsecurePrivateNetworkSubresourceRequest: + type = protocol::Audits::DeprecationIssueTypeEnum:: + InsecurePrivateNetworkSubresourceRequest; + break; case DeprecationIssueType::kLegacyConstraintGoogCpuOveruseDetection: type = protocol::Audits::DeprecationIssueTypeEnum:: LegacyConstraintGoogCpuOveruseDetection; @@ -492,14 +532,42 @@ type = protocol::Audits::DeprecationIssueTypeEnum:: LocalCSSFileExtensionRejected; break; + case DeprecationIssueType::kMediaElementAudioSourceNode: + type = protocol::Audits::DeprecationIssueTypeEnum:: + MediaElementAudioSourceNode; + break; + case DeprecationIssueType::kMediaSourceAbortRemove: + type = + protocol::Audits::DeprecationIssueTypeEnum::MediaSourceAbortRemove; + break; + case DeprecationIssueType::kMediaSourceDurationTruncatingBuffered: + type = protocol::Audits::DeprecationIssueTypeEnum:: + MediaSourceDurationTruncatingBuffered; + break; + case DeprecationIssueType::kNoSysexWebMIDIWithoutPermission: + type = protocol::Audits::DeprecationIssueTypeEnum:: + NoSysexWebMIDIWithoutPermission; + break; case DeprecationIssueType::kNotificationInsecureOrigin: type = protocol::Audits::DeprecationIssueTypeEnum:: NotificationInsecureOrigin; break; + case DeprecationIssueType::kNotificationPermissionRequestedIframe: + type = protocol::Audits::DeprecationIssueTypeEnum:: + NotificationPermissionRequestedIframe; + break; case DeprecationIssueType::kObsoleteWebRtcCipherSuite: type = protocol::Audits::DeprecationIssueTypeEnum:: ObsoleteWebRtcCipherSuite; break; + case DeprecationIssueType::kPaymentRequestBasicCard: + type = + protocol::Audits::DeprecationIssueTypeEnum::PaymentRequestBasicCard; + break; + case DeprecationIssueType::kPaymentRequestShowWithoutGesture: + type = protocol::Audits::DeprecationIssueTypeEnum:: + PaymentRequestShowWithoutGesture; + break; case DeprecationIssueType::kPictureSourceSrc: type = protocol::Audits::DeprecationIssueTypeEnum::PictureSourceSrc; break; @@ -511,6 +579,40 @@ type = protocol::Audits::DeprecationIssueTypeEnum:: PrefixedRequestAnimationFrame; break; + case DeprecationIssueType::kPrefixedStorageInfo: + type = protocol::Audits::DeprecationIssueTypeEnum::PrefixedStorageInfo; + break; + case DeprecationIssueType::kPrefixedVideoDisplayingFullscreen: + type = protocol::Audits::DeprecationIssueTypeEnum:: + PrefixedVideoDisplayingFullscreen; + break; + case DeprecationIssueType::kPrefixedVideoEnterFullScreen: + type = protocol::Audits::DeprecationIssueTypeEnum:: + PrefixedVideoEnterFullScreen; + break; + case DeprecationIssueType::kPrefixedVideoEnterFullscreen: + type = protocol::Audits::DeprecationIssueTypeEnum:: + PrefixedVideoEnterFullscreen; + break; + case DeprecationIssueType::kPrefixedVideoExitFullScreen: + type = protocol::Audits::DeprecationIssueTypeEnum:: + PrefixedVideoExitFullScreen; + break; + case DeprecationIssueType::kPrefixedVideoExitFullscreen: + type = protocol::Audits::DeprecationIssueTypeEnum:: + PrefixedVideoExitFullscreen; + break; + case DeprecationIssueType::kPrefixedVideoSupportsFullscreen: + type = protocol::Audits::DeprecationIssueTypeEnum:: + PrefixedVideoSupportsFullscreen; + break; + case DeprecationIssueType::kRangeExpand: + type = protocol::Audits::DeprecationIssueTypeEnum::RangeExpand; + break; + case DeprecationIssueType::kRequestedSubresourceWithEmbeddedCredentials: + type = protocol::Audits::DeprecationIssueTypeEnum:: + RequestedSubresourceWithEmbeddedCredentials; + break; case DeprecationIssueType::kRTCConstraintEnableDtlsSrtpFalse: type = protocol::Audits::DeprecationIssueTypeEnum:: RTCConstraintEnableDtlsSrtpFalse; @@ -529,13 +631,29 @@ type = protocol::Audits::DeprecationIssueTypeEnum:: RTCPeerConnectionLegacyCreateWithMediaConstraints; break; + case DeprecationIssueType::kRTCPeerConnectionSdpSemanticsPlanB: + type = protocol::Audits::DeprecationIssueTypeEnum:: + RTCPeerConnectionSdpSemanticsPlanB; + break; + case DeprecationIssueType::kRtcpMuxPolicyNegotiate: + type = + protocol::Audits::DeprecationIssueTypeEnum::RtcpMuxPolicyNegotiate; + break; case DeprecationIssueType::kRTPDataChannel: type = protocol::Audits::DeprecationIssueTypeEnum::RTPDataChannel; break; + case DeprecationIssueType::kSelectionAddRangeIntersect: + type = protocol::Audits::DeprecationIssueTypeEnum:: + SelectionAddRangeIntersect; + break; case DeprecationIssueType::kSharedArrayBufferConstructedWithoutIsolation: type = protocol::Audits::DeprecationIssueTypeEnum:: SharedArrayBufferConstructedWithoutIsolation; break; + case DeprecationIssueType::kTextToSpeech_DisallowedByAutoplay: + type = protocol::Audits::DeprecationIssueTypeEnum:: + TextToSpeech_DisallowedByAutoplay; + break; case DeprecationIssueType::kUntranslated: LOG(FATAL) << "Feature " << legacy_type << " is not translated."; break; @@ -557,6 +675,9 @@ type = protocol::Audits::DeprecationIssueTypeEnum:: XMLHttpRequestSynchronousInNonWorkerOutsideBeforeUnload; break; + case DeprecationIssueType::kXRSupportsSession: + type = protocol::Audits::DeprecationIssueTypeEnum::XRSupportsSession; + break; } }
diff --git a/third_party/blink/renderer/core/inspector/inspector_audits_issue.h b/third_party/blink/renderer/core/inspector/inspector_audits_issue.h index 0ca1cef..1705038d 100644 --- a/third_party/blink/renderer/core/inspector/inspector_audits_issue.h +++ b/third_party/blink/renderer/core/inspector/inspector_audits_issue.h
@@ -39,36 +39,67 @@ // Please keep this alphabetized. enum class DeprecationIssueType { kAuthorizationCoveredByWildcard, + kBatteryStatusInsecureOrigin, + kCanRequestURLHTTPContainingNewline, + kChromeLoadTimesConnectionInfo, + kChromeLoadTimesFirstPaintAfterLoadTime, + kChromeLoadTimesWasAlternateProtocolAvailable, kCookieWithTruncatingChar, kCrossOriginAccessBasedOnDocumentDomain, kCrossOriginWindowAlert, kCrossOriginWindowConfirm, + kCSSSelectorInternalMediaControlsOverlayCastButton, + kCustomCursorIntersectsViewport, kDeprecationExample, kDocumentDomainSettingWithoutOriginAgentClusterHeader, + kEventPath, kGeolocationInsecureOrigin, kGeolocationInsecureOriginDeprecatedNotRemoved, kGetUserMediaInsecureOrigin, + kHostCandidateAttributeGetter, + kInsecurePrivateNetworkSubresourceRequest, kLegacyConstraintGoogCpuOveruseDetection, kLegacyConstraintGoogIPv6, kLegacyConstraintGoogScreencastMinBitrate, kLegacyConstraintGoogSuspendBelowMinBitrate, kLocalCSSFileExtensionRejected, + kMediaElementAudioSourceNode, + kMediaSourceAbortRemove, + kMediaSourceDurationTruncatingBuffered, + kNoSysexWebMIDIWithoutPermission, kNotificationInsecureOrigin, + kNotificationPermissionRequestedIframe, kObsoleteWebRtcCipherSuite, + kPaymentRequestBasicCard, + kPaymentRequestShowWithoutGesture, kPictureSourceSrc, kPrefixedCancelAnimationFrame, kPrefixedRequestAnimationFrame, + kPrefixedStorageInfo, + kPrefixedVideoDisplayingFullscreen, + kPrefixedVideoEnterFullScreen, + kPrefixedVideoEnterFullscreen, + kPrefixedVideoExitFullScreen, + kPrefixedVideoExitFullscreen, + kPrefixedVideoSupportsFullscreen, + kRangeExpand, + kRequestedSubresourceWithEmbeddedCredentials, kRTCConstraintEnableDtlsSrtpFalse, kRTCConstraintEnableDtlsSrtpTrue, kRTCPeerConnectionComplexPlanBSdpUsingDefaultSdpSemantics, kRTCPeerConnectionLegacyCreateWithMediaConstraints, + kRTCPeerConnectionSdpSemanticsPlanB, + kRtcpMuxPolicyNegotiate, kRTPDataChannel, + kSelectionAddRangeIntersect, kSharedArrayBufferConstructedWithoutIsolation, + kTextToSpeech_DisallowedByAutoplay, kUntranslated, kV8SharedArrayBufferConstructedInExtensionWithoutIsolation, kWebCodecsVideoFrameDefaultTimestamp, kXHRJSONEncodingDetection, kXMLHttpRequestSynchronousInNonWorkerOutsideBeforeUnload, + kXRSupportsSession, }; enum class RendererCorsIssueCode {
diff --git a/third_party/blink/renderer/core/loader/modulescript/installed_service_worker_module_script_fetcher.cc b/third_party/blink/renderer/core/loader/modulescript/installed_service_worker_module_script_fetcher.cc index e77a196..80875d2 100644 --- a/third_party/blink/renderer/core/loader/modulescript/installed_service_worker_module_script_fetcher.cc +++ b/third_party/blink/renderer/core/loader/modulescript/installed_service_worker_module_script_fetcher.cc
@@ -67,7 +67,6 @@ global_scope_->Initialize( response_url, response_referrer_policy, - script_data->GetResponseAddressSpace(), ParseContentSecurityPolicyHeaders( script_data->GetContentSecurityPolicyResponseHeaders()), script_data->CreateOriginTrialTokens().get());
diff --git a/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.cc b/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.cc index 5766ab5..62ac8a5 100644 --- a/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.cc +++ b/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.cc
@@ -6,7 +6,6 @@ #include <memory> -#include "services/network/public/mojom/ip_address_space.mojom-blink.h" #include "services/network/public/mojom/referrer_policy.mojom-blink.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/loader/network_utils.h" @@ -171,7 +170,7 @@ // Step 12.3-12.6 are implemented in Initialize(). global_scope_->Initialize( - response_url, response_referrer_policy, response.AddressSpace(), + response_url, response_referrer_policy, ParseContentSecurityPolicyHeaders( ContentSecurityPolicyResponseHeaders(response)), response_origin_trial_tokens.get());
diff --git a/third_party/blink/renderer/core/paint/highlight_painting_utils.cc b/third_party/blink/renderer/core/paint/highlight_painting_utils.cc index 1c0c1f0..a352e105 100644 --- a/third_party/blink/renderer/core/paint/highlight_painting_utils.cc +++ b/third_party/blink/renderer/core/paint/highlight_painting_utils.cc
@@ -98,11 +98,10 @@ if (RuntimeEnabledFeatures::HighlightOverlayPaintingEnabled()) { return previous_layer_color; } else { - // TODO(crbug.com/1295264): unstyled custom highlights should not change - // the foreground color, but for now the best we can do is defaulting to - // transparent (pre-HighlightOverlayPainting with double painting). The - // correct behaviour is to use the ‘color’ of the next topmost active - // highlight (equivalent to 'currentColor'). + // TODO(crbug.com/1147859): Unstyled custom highlights should not be + // painted, so here we make the color default to transparent. When the + // highlight painting code is updated to match the spec, this should + // instead return the equivalent of 'currentColor'. return Color::kTransparent; } default:
diff --git a/third_party/blink/renderer/core/paint/ng/ng_highlight_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_highlight_painter.cc index ca889ed5..d805ae9 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_highlight_painter.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_highlight_painter.cc
@@ -27,7 +27,6 @@ #include "third_party/blink/renderer/core/paint/ng/ng_text_painter.h" #include "third_party/blink/renderer/core/paint/paint_auto_dark_mode.h" #include "third_party/blink/renderer/core/paint/paint_info.h" -#include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" namespace blink { @@ -339,11 +338,8 @@ const PaintInfo& paint_info, const NGInlineCursor& cursor, const NGFragmentItem& fragment_item, - const absl::optional<AffineTransform> writing_mode_rotation, - const PhysicalRect& decoration_rect, const PhysicalOffset& box_origin, const ComputedStyle& style, - const TextPaintStyle& text_style, SelectionPaintState* selection, bool is_printing) : fragment_paint_info_(fragment_paint_info), @@ -352,11 +348,8 @@ paint_info_(paint_info), cursor_(cursor), fragment_item_(fragment_item), - writing_mode_rotation_(writing_mode_rotation), - decoration_rect_(decoration_rect), box_origin_(box_origin), style_(style), - originating_text_style_(text_style), selection_(selection), layout_object_(fragment_item_.GetLayoutObject()), node_(layout_object_->GetNode()), @@ -370,40 +363,13 @@ spelling_ = MarkersFor(node_, is_ellipsis, DocumentMarker::kSpelling); grammar_ = MarkersFor(node_, is_ellipsis, DocumentMarker::kGrammar); custom_ = MarkersFor(node_, is_ellipsis, DocumentMarker::kCustomHighlight); - Vector<HighlightLayer> layers = NGHighlightOverlay::ComputeLayers( + layers_ = NGHighlightOverlay::ComputeLayers( GetHighlightRegistry(node_), fragment_paint_info_, GetSelectionStatus(selection_), custom_, grammar_, spelling_, target_); Vector<HighlightEdge> edges = NGHighlightOverlay::ComputeEdges( node_, GetHighlightRegistry(node_), fragment_paint_info_, GetSelectionStatus(selection_), custom_, grammar_, spelling_, target_); - parts_ = NGHighlightOverlay::ComputeParts(layers, edges); - - const Document& document = layout_object_->GetDocument(); - for (wtf_size_t i = 0; i < layers.size(); i++) { - if (layers[i].type == HighlightLayerType::kOriginating) { - layers_.push_back(LayerPaintState{ - layers[i], - WrapRefCounted(&style_), - originating_text_style_, - }); - } else { - layers_.push_back(LayerPaintState{ - layers[i], - HighlightPaintingUtils::HighlightPseudoStyle( - node_, style_, layers[i].PseudoId(), - layers[i].PseudoArgument()), - HighlightPaintingUtils::HighlightPaintingStyle( - document, style_, node_, layers[i].PseudoId(), - layers_[i - 1].text_style, paint_info_, - layers[i].PseudoArgument()), - }); - } - if (layers_[i].style) { - decoration_painter_.UpdateDecorationInfo(layers_[i].decoration_info, - *layers_[i].style, - layers_[i].text_style); - } - } + parts_ = NGHighlightOverlay::ComputeParts(layers_, edges); } } @@ -606,16 +572,13 @@ // Then paint the text proper for any unhighlighted parts in storage order, // so that they’re always on top of the shadows. - for (const HighlightPart& part : parts_) { + for (const HighlightPart& part : Parts()) { if (part.layer.type != HighlightLayerType::kOriginating) continue; - PaintDecorationsExceptLineThrough(part); text_painter_.Paint(part.from, part.to, part.to - part.from, text_style, node_id, auto_dark_mode, NGTextPainter::kTextProperOnly); - PaintDecorationsOnlyLineThrough(part); - PaintSpellingGrammarDecorations(part); } } @@ -637,19 +600,24 @@ // For each overlay, paint its backgrounds and shadows over every highlighted // range in full. - for (const LayerPaintState& layer : layers_) { - if (layer.id.type == HighlightLayerType::kOriginating || - layer.id.type == HighlightLayerType::kSelection) + TextPaintStyle previous_layer_text_style = originating_text_style; + for (const HighlightLayer& layer : layers_) { + if (layer.type == HighlightLayerType::kOriginating || + layer.type == HighlightLayerType::kSelection) continue; const DocumentMarkerVector* markers = - SelectMarkers(layer.id, custom_, grammar_, spelling_, target_); + SelectMarkers(layer, custom_, grammar_, spelling_, target_); + TextPaintStyle text_style = HighlightPaintingUtils::HighlightPaintingStyle( + document, style_, node_, layer.PseudoId(), previous_layer_text_style, + paint_info_, layer.PseudoArgument()); + previous_layer_text_style = text_style; for (const auto& marker : *markers) { - if (layer.id.type == HighlightLayerType::kCustom) { + if (layer.type == HighlightLayerType::kCustom) { // Filter custom highlight markers to one highlight at a time. auto* custom = To<CustomHighlightMarker>(marker.Get()); - if (custom->GetHighlightName() != layer.id.PseudoArgument()) + if (custom->GetHighlightName() != layer.PseudoArgument()) continue; } @@ -665,8 +633,8 @@ const StringView text = cursor_.CurrentText(); Color background_color = HighlightPaintingUtils::HighlightBackgroundColor( - document, style_, node_, layer.text_style.fill_color, - layer.id.PseudoId(), layer.id.PseudoArgument()); + document, style_, node_, text_style.fill_color, layer.PseudoId(), + layer.PseudoArgument()); // TODO(dazabani@igalia.com) paint rects pixel-snapped in physical space, // not writing-mode space (SelectionPaintState::PaintSelectionBackground) @@ -674,7 +642,7 @@ fragment_item_.LocalRect(text, clamped_start, clamped_end), background_color, auto_dark_mode); - text_painter_.Paint(clamped_start, clamped_end, length, layer.text_style, + text_painter_.Paint(clamped_start, clamped_end, length, text_style, node_id, auto_dark_mode, TextPainterBase::kShadowsOnly); } @@ -692,28 +660,31 @@ // For each overlay, paint the text proper over every highlighted range, // except any parts for which we’re not the topmost active highlight. - for (const LayerPaintState& layer : layers_) { - if (layer.id.type == HighlightLayerType::kOriginating || - layer.id.type == HighlightLayerType::kSelection) + previous_layer_text_style = originating_text_style; + for (const HighlightLayer& layer : layers_) { + if (layer.type == HighlightLayerType::kOriginating || + layer.type == HighlightLayerType::kSelection) continue; - for (const HighlightPart& part : parts_) { - if (part.layer != layer.id) + TextPaintStyle text_style = HighlightPaintingUtils::HighlightPaintingStyle( + document, style_, node_, layer.PseudoId(), previous_layer_text_style, + paint_info_, layer.PseudoArgument()); + previous_layer_text_style = text_style; + + for (const HighlightPart& part : Parts()) { + if (part.layer != layer) continue; const unsigned clamped_start = ClampOffset(part.from, fragment_item_); const unsigned clamped_end = ClampOffset(part.to, fragment_item_); + // TODO(crbug.com/1147859) paint originating decorations, as well as + // decorations added by each highlight // TODO(dazabani@igalia.com) expand range to include partial glyphs, then // paint with clipping (NGTextPainter::PaintSelectedText) - - PaintDecorationsExceptLineThrough(part); text_painter_.Paint(clamped_start, clamped_end, - clamped_end - clamped_start, layer.text_style, - node_id, auto_dark_mode, - TextPainterBase::kTextProperOnly); - PaintDecorationsOnlyLineThrough(part); - PaintSpellingGrammarDecorations(part); + clamped_end - clamped_start, text_style, node_id, + auto_dark_mode, TextPainterBase::kTextProperOnly); } } @@ -721,160 +692,13 @@ // TODO(dazabani@igalia.com) generalise ::selection painting logic to support // all highlights, then merge this branch into the loop above if (UNLIKELY(selection_)) { - for (const HighlightPart& part : parts_) { - if (part.layer.type == HighlightLayerType::kSelection) - PaintDecorationsExceptLineThrough(part); - } - - selection_->PaintSelectedText( - text_painter_, fragment_paint_info_.to - fragment_paint_info_.from, - originating_text_style, node_id, auto_dark_mode); - - for (const HighlightPart& part : parts_) { - if (part.layer.type == HighlightLayerType::kSelection) { - PaintDecorationsOnlyLineThrough(part); - PaintSpellingGrammarDecorations(part); - } - } + unsigned length = fragment_paint_info_.to - fragment_paint_info_.from; + decoration_painter_.Begin(NGTextDecorationPainter::kSelection); + decoration_painter_.PaintExceptLineThrough(); + selection_->PaintSelectedText(text_painter_, length, originating_text_style, + node_id, auto_dark_mode); + decoration_painter_.PaintOnlyLineThrough(); } } -void NGHighlightPainter::ClipToPartDecorations(const HighlightPart& part) { - const StringView text = cursor_.CurrentText(); - const unsigned clamped_start = ClampOffset(part.from, fragment_item_); - const unsigned clamped_end = ClampOffset(part.to, fragment_item_); - PhysicalRect local_rect = - fragment_item_.LocalRect(text, clamped_start, clamped_end); - PhysicalRect part_rect{box_origin_ + local_rect.offset, local_rect.size}; - gfx::RectF clip_rect{part_rect}; - - if (writing_mode_rotation_) - clip_rect = writing_mode_rotation_->Inverse().MapRect(clip_rect); - - // Whether it’s best to clip to selection rect on both axes or only inline - // depends on the situation, but the latter can improve the appearance of - // decorations. For example, we often paint overlines entirely past the - // top edge of selection rect, and wavy underlines have similar problems. - // - // Sadly there’s no way to clip to a rect of infinite height, so for now, - // let’s clip to selection rect plus its height both above and below. This - // should be enough to avoid clipping most decorations in the wild. - // - // TODO(dazabani@igalia.com): take text-underline-offset and other - // text-decoration properties into account? - clip_rect.set_y(clip_rect.y() - clip_rect.height()); - clip_rect.set_height(3.0 * clip_rect.height()); - paint_info_.context.Clip(clip_rect); -} - -void NGHighlightPainter::PaintDecorationsExceptLineThrough( - const HighlightPart& part) { - GraphicsContextStateSaver state_saver(paint_info_.context); - ClipToPartDecorations(part); - - for (const HighlightLayer& decoration_layer_id : part.decorations) { - wtf_size_t decoration_layer_index = layers_.Find(decoration_layer_id); - DCHECK_NE(decoration_layer_index, kNotFound); - - LayerPaintState& decoration_layer = layers_[decoration_layer_index]; - if (!decoration_layer.decoration_info) - continue; - - if (decoration_layer_id.type == HighlightLayerType::kOriginating && - part.layer.type != HighlightLayerType::kOriginating) { - wtf_size_t part_layer_index = layers_.Find(part.layer); - decoration_layer.decoration_info->SetHighlightOverrideColor( - layers_[part_layer_index].text_style.fill_color); - } - - // TODO(crbug.com/1147859) order by underline-then-overline first, then by - // highlight layer, not grouping underline and overline within each layer - // https://github.com/w3c/csswg-drafts/issues/6022 - text_painter_.PaintDecorationsExceptLineThrough( - fragment_item_, paint_info_, *decoration_layer.style, - decoration_layer.text_style, *decoration_layer.decoration_info, - decoration_rect_, &decoration_layer.has_line_through_decorations); - } -} - -void NGHighlightPainter::PaintDecorationsOnlyLineThrough( - const HighlightPart& part) { - GraphicsContextStateSaver state_saver(paint_info_.context); - ClipToPartDecorations(part); - - for (const HighlightLayer& decoration_layer_id : part.decorations) { - wtf_size_t decoration_layer_index = layers_.Find(decoration_layer_id); - DCHECK_NE(decoration_layer_index, kNotFound); - - LayerPaintState& decoration_layer = layers_[decoration_layer_index]; - if (!decoration_layer.decoration_info || - !decoration_layer.has_line_through_decorations) - continue; - - if (decoration_layer_id.type == HighlightLayerType::kOriginating && - part.layer.type != HighlightLayerType::kOriginating) { - wtf_size_t part_layer_index = layers_.Find(part.layer); - decoration_layer.decoration_info->SetHighlightOverrideColor( - layers_[part_layer_index].text_style.fill_color); - } - - text_painter_.PaintDecorationsOnlyLineThrough( - fragment_item_, paint_info_, *decoration_layer.style, - decoration_layer.text_style, *decoration_layer.decoration_info, - decoration_rect_); - } -} - -void NGHighlightPainter::PaintSpellingGrammarDecorations( - const HighlightPart& part) { - const StringView text = cursor_.CurrentText(); - const unsigned clamped_start = ClampOffset(part.from, fragment_item_); - const unsigned clamped_end = ClampOffset(part.to, fragment_item_); - const PhysicalRect marker_rect = - MarkerRectForForeground(fragment_item_, text, clamped_start, clamped_end); - - for (const HighlightLayer& decoration_layer_id : part.decorations) { - switch (decoration_layer_id.type) { - case HighlightLayerType::kSpelling: - case HighlightLayerType::kGrammar: { - wtf_size_t i = layers_.Find(decoration_layer_id); - DCHECK_NE(i, kNotFound); - const LayerPaintState& decoration_layer = layers_[i]; - - // TODO(crbug.com/1163436): remove once UA stylesheet sets ::spelling - // and ::grammar to text-decoration-line:{spelling,grammar}-error - if (decoration_layer.style && - decoration_layer.style->TextDecorationsInEffect() != - TextDecorationLine::kNone) - break; - - DocumentMarkerPainter::PaintDocumentMarker( - paint_info_, box_origin_, style_, - decoration_layer_id.type == HighlightLayerType::kSpelling - ? DocumentMarker::kSpelling - : DocumentMarker::kGrammar, - marker_rect, - HighlightPaintingUtils::HighlightTextDecorationColor( - style_, node_, - decoration_layer_id.type == HighlightLayerType::kSpelling - ? kPseudoIdSpellingError - : kPseudoIdGrammarError)); - } break; - - default: - break; - } - } -} - -bool NGHighlightPainter::LayerPaintState::operator==( - const HighlightLayer& other) const { - return id == other; -} - -bool NGHighlightPainter::LayerPaintState::operator!=( - const HighlightLayer& other) const { - return !operator==(other); -} - } // namespace blink
diff --git a/third_party/blink/renderer/core/paint/ng/ng_highlight_painter.h b/third_party/blink/renderer/core/paint/ng/ng_highlight_painter.h index 20aa3c5..5d02934 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_highlight_painter.h +++ b/third_party/blink/renderer/core/paint/ng/ng_highlight_painter.h
@@ -12,7 +12,6 @@ #include "third_party/blink/renderer/core/layout/api/selection_state.h" #include "third_party/blink/renderer/core/layout/geometry/physical_rect.h" #include "third_party/blink/renderer/core/paint/ng/ng_highlight_overlay.h" -#include "third_party/blink/renderer/core/paint/text_decoration_info.h" #include "third_party/blink/renderer/core/paint/text_paint_style.h" #include "third_party/blink/renderer/platform/graphics/dom_node_id.h" #include "third_party/blink/renderer/platform/transforms/affine_transform.h" @@ -120,20 +119,16 @@ bool paint_selected_text_only_; }; - NGHighlightPainter( - const NGTextFragmentPaintInfo& fragment_paint_info, - NGTextPainter& text_painter, - NGTextDecorationPainter& decoration_painter, - const PaintInfo& paint_info, - const NGInlineCursor& cursor, - const NGFragmentItem& fragment_item, - const absl::optional<AffineTransform> writing_mode_rotation, - const PhysicalRect& decoration_rect, - const PhysicalOffset& box_origin, - const ComputedStyle& style, - const TextPaintStyle& text_style, - SelectionPaintState*, - bool is_printing); + NGHighlightPainter(const NGTextFragmentPaintInfo& fragment_paint_info, + NGTextPainter& text_painter, + NGTextDecorationPainter& decoration_painter, + const PaintInfo& paint_info, + const NGInlineCursor& cursor, + const NGFragmentItem& fragment_item, + const PhysicalOffset& box_origin, + const ComputedStyle& style, + SelectionPaintState*, + bool is_printing); enum Phase { kBackground, kForeground }; void Paint(Phase phase); @@ -147,48 +142,20 @@ const AutoDarkMode&, bool paint_marker_backgrounds, absl::optional<AffineTransform> rotation); - void ClipToPartDecorations(const NGHighlightOverlay::HighlightPart&); - void PaintDecorationsExceptLineThrough( - const NGHighlightOverlay::HighlightPart&); - void PaintDecorationsOnlyLineThrough( - const NGHighlightOverlay::HighlightPart&); - void PaintSpellingGrammarDecorations( - const NGHighlightOverlay::HighlightPart&); - wtf_size_t LayerCount() { return layers_.size(); } + const Vector<NGHighlightOverlay::HighlightLayer>& Layers() { return layers_; } + const Vector<NGHighlightOverlay::HighlightPart>& Parts() { return parts_; } SelectionPaintState* Selection() { return selection_; } private: - struct LayerPaintState { - LayerPaintState(NGHighlightOverlay::HighlightLayer id, - scoped_refptr<const ComputedStyle> style, - TextPaintStyle text_style) - : id(id), style(std::move(style)), text_style(text_style) {} - - // Equality on HighlightLayer id only, for Vector::Find. - bool operator==(const LayerPaintState&) const = delete; - bool operator!=(const LayerPaintState&) const = delete; - bool operator==(const NGHighlightOverlay::HighlightLayer&) const; - bool operator!=(const NGHighlightOverlay::HighlightLayer&) const; - - const NGHighlightOverlay::HighlightLayer id; - const scoped_refptr<const ComputedStyle> style; - const TextPaintStyle text_style; - absl::optional<TextDecorationInfo> decoration_info{}; - bool has_line_through_decorations{false}; - }; - const NGTextFragmentPaintInfo& fragment_paint_info_; NGTextPainter& text_painter_; NGTextDecorationPainter& decoration_painter_; const PaintInfo& paint_info_; const NGInlineCursor& cursor_; const NGFragmentItem& fragment_item_; - const absl::optional<AffineTransform> writing_mode_rotation_; - const PhysicalRect& decoration_rect_; const PhysicalOffset& box_origin_; const ComputedStyle& style_; - const TextPaintStyle& originating_text_style_; SelectionPaintState* selection_; const LayoutObject* layout_object_; Node* node_; @@ -197,7 +164,7 @@ DocumentMarkerVector spelling_; DocumentMarkerVector grammar_; DocumentMarkerVector custom_; - Vector<LayerPaintState> layers_; + Vector<NGHighlightOverlay::HighlightLayer> layers_; Vector<NGHighlightOverlay::HighlightPart> parts_; const bool skip_backgrounds_; };
diff --git a/third_party/blink/renderer/core/paint/ng/ng_text_decoration_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_text_decoration_painter.cc index 473f7a9..58c1d23b 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_text_decoration_painter.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_text_decoration_painter.cc
@@ -35,80 +35,73 @@ DCHECK(step_ == kBegin); } -void NGTextDecorationPainter::UpdateDecorationInfo( - absl::optional<TextDecorationInfo>& result, - const ComputedStyle& style, - const TextPaintStyle& text_style) { - result.reset(); - - if (style.TextDecorationsInEffect() == TextDecorationLine::kNone || - // Ellipsis should not have text decorations. This is not defined, but - // 4 impls do this: <https://github.com/w3c/csswg-drafts/issues/6531> - text_item_.IsEllipsis()) - return; - - absl::optional<AppliedTextDecoration> effective_selection_decoration = - UNLIKELY(phase_ == kSelection) - ? selection_->GetSelectionStyle().selection_text_decoration - : absl::nullopt; - - if (text_item_.Type() == NGFragmentItem::kSvgText && - paint_info_.IsRenderingResourceSubtree()) { - // Need to recompute a scaled font and a scaling factor because they - // depend on the scaling factor of an element referring to the text. - float scaling_factor = 1; - Font scaled_font; - LayoutSVGInlineText::ComputeNewScaledFontForStyle( - *text_item_.GetLayoutObject(), scaling_factor, scaled_font); - DCHECK(scaling_factor); - // Adjust the origin of the decoration because - // NGTextPainter::PaintDecorationsExceptLineThrough() will change the - // scaling of the GraphicsContext. - LayoutUnit top = decoration_rect_.offset.top; - // In svg/text/text-decorations-in-scaled-pattern.svg, the size of - // ScaledFont() is zero, and the top position is unreliable. So we - // adjust the baseline position, then shift it for scaled_font. - top += - text_item_.ScaledFont().PrimaryFont()->GetFontMetrics().FixedAscent(); - top *= scaling_factor / text_item_.SvgScalingFactor(); - top -= scaled_font.PrimaryFont()->GetFontMetrics().FixedAscent(); - result.emplace(PhysicalOffset(decoration_rect_.offset.left, top), - decoration_rect_.Width(), style.GetFontBaseline(), style, - scaled_font, effective_selection_decoration, nullptr, - MinimumThickness1(false), scaling_factor); - } else { - result.emplace( - decoration_rect_.offset, decoration_rect_.Width(), - style.GetFontBaseline(), style, text_item_.ScaledFont(), - effective_selection_decoration, nullptr, - MinimumThickness1(text_item_.Type() != NGFragmentItem::kSvgText)); - } -} - void NGTextDecorationPainter::Begin(Phase phase) { DCHECK(step_ == kBegin); phase_ = phase; has_line_through_decoration_ = false; - UpdateDecorationInfo(decoration_info_, style_, text_style_); + decoration_info_.reset(); clip_rect_.reset(); - if (decoration_info_ && UNLIKELY(selection_)) { - clip_rect_.emplace(selection_->RectInWritingModeSpace()); + if (style_.TextDecorationsInEffect() != TextDecorationLine::kNone && + // Ellipsis should not have text decorations. This is not defined, but + // 4 impls do this: <https://github.com/w3c/csswg-drafts/issues/6531> + !text_item_.IsEllipsis()) { + absl::optional<AppliedTextDecoration> effective_selection_decoration = + UNLIKELY(phase_ == kSelection) + ? selection_->GetSelectionStyle().selection_text_decoration + : absl::nullopt; - // Whether it’s best to clip to selection rect on both axes or only inline - // depends on the situation, but the latter can improve the appearance of - // decorations. For example, we often paint overlines entirely past the - // top edge of selection rect, and wavy underlines have similar problems. - // - // Sadly there’s no way to clip to a rect of infinite height, so for now, - // let’s clip to selection rect plus its height both above and below. This - // should be enough to avoid clipping most decorations in the wild. - // - // TODO(dazabani@igalia.com): take text-underline-offset and other - // text-decoration properties into account? - clip_rect_->set_y(clip_rect_->y() - clip_rect_->height()); - clip_rect_->set_height(3.0 * clip_rect_->height()); + if (text_item_.Type() == NGFragmentItem::kSvgText && + paint_info_.IsRenderingResourceSubtree()) { + // Need to recompute a scaled font and a scaling factor because they + // depend on the scaling factor of an element referring to the text. + float scaling_factor = 1; + Font scaled_font; + LayoutSVGInlineText::ComputeNewScaledFontForStyle( + *text_item_.GetLayoutObject(), scaling_factor, scaled_font); + DCHECK(scaling_factor); + // Adjust the origin of the decoration because + // NGTextPainter::PaintDecorationsExceptLineThrough() will change the + // scaling of the GraphicsContext. + LayoutUnit top = decoration_rect_.offset.top; + // In svg/text/text-decorations-in-scaled-pattern.svg, the size of + // ScaledFont() is zero, and the top position is unreliable. So we + // adjust the baseline position, then shift it for scaled_font. + top += + text_item_.ScaledFont().PrimaryFont()->GetFontMetrics().FixedAscent(); + top *= scaling_factor / text_item_.SvgScalingFactor(); + top -= scaled_font.PrimaryFont()->GetFontMetrics().FixedAscent(); + decoration_info_.emplace( + PhysicalOffset(decoration_rect_.offset.left, top), + decoration_rect_.Width(), style_.GetFontBaseline(), style_, + scaled_font, effective_selection_decoration, nullptr, + MinimumThickness1(false), scaling_factor); + } else { + decoration_info_.emplace( + decoration_rect_.offset, decoration_rect_.Width(), + style_.GetFontBaseline(), style_, text_item_.ScaledFont(), + effective_selection_decoration, nullptr, + MinimumThickness1(text_item_.Type() != NGFragmentItem::kSvgText)); + } + + if (UNLIKELY(selection_)) { + clip_rect_.emplace(selection_->RectInWritingModeSpace()); + + // Whether it’s best to clip to selection rect on both axes or only inline + // depends on the situation, but the latter can improve the appearance of + // decorations. For example, we often paint overlines entirely past the + // top edge of selection rect, and wavy underlines have similar problems. + // + // Sadly there’s no way to clip to a rect of infinite height, so for now, + // let’s clip to selection rect plus its height both above and below. This + // should be enough to avoid clipping most decorations in the wild. + // + // TODO(dazabani@igalia.com): take text-underline-offset and other + // text-decoration properties into account? + clip_rect_->set_y(clip_rect_->y() - clip_rect_->height()); + clip_rect_->set_height(3.0 * clip_rect_->height()); + } } step_ = kExcept;
diff --git a/third_party/blink/renderer/core/paint/ng/ng_text_decoration_painter.h b/third_party/blink/renderer/core/paint/ng/ng_text_decoration_painter.h index 5f7801a2..88e48c7 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_text_decoration_painter.h +++ b/third_party/blink/renderer/core/paint/ng/ng_text_decoration_painter.h
@@ -45,12 +45,6 @@ NGHighlightPainter::SelectionPaintState* selection); ~NGTextDecorationPainter(); - // Sets the given optional to a new TextDecorationInfo with the decorations - // that need to be painted, or nullopt if decorations should not be painted. - void UpdateDecorationInfo(absl::optional<TextDecorationInfo>&, - const ComputedStyle&, - const TextPaintStyle&); - enum Phase { kOriginating, kSelection }; void Begin(Phase phase); void PaintExceptLineThrough();
diff --git a/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.cc index 1f823ff2..9e213b5 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.cc
@@ -323,8 +323,8 @@ rotated_box, selection); NGHighlightPainter highlight_painter( fragment_paint_info, text_painter, decoration_painter, paint_info, - cursor_, *cursor_.CurrentItem(), rotation, rotated_box, - physical_box.offset, style, text_style, selection, is_printing); + cursor_, *cursor_.CurrentItem(), physical_box.offset, style, selection, + is_printing); if (svg_inline_text) { NGTextPainter::SvgTextPaintState& svg_state = text_painter.SetSvgState( @@ -397,7 +397,7 @@ if (LIKELY(!highlight_painter.Selection() && (!RuntimeEnabledFeatures::HighlightOverlayPaintingEnabled() || - highlight_painter.LayerCount() == 1))) { + highlight_painter.Layers().size() == 1))) { // Fast path: just paint the text, including its shadows. decoration_painter.Begin(NGTextDecorationPainter::kOriginating); decoration_painter.PaintExceptLineThrough(); @@ -418,7 +418,11 @@ DCHECK(RuntimeEnabledFeatures::HighlightOverlayPaintingEnabled()); // New slow path: paint suppressing text proper where highlighted, then // paint each highlight overlay, suppressing unless topmost highlight. + // TODO(crbug.com/1147859) suppress for ::selection too (regression) + decoration_painter.Begin(NGTextDecorationPainter::kOriginating); + decoration_painter.PaintExceptLineThrough(); highlight_painter.PaintOriginatingText(text_style, node_id, auto_dark_mode); + decoration_painter.PaintOnlyLineThrough(); highlight_painter.PaintHighlightOverlays( text_style, node_id, auto_dark_mode, paint_marker_backgrounds,
diff --git a/third_party/blink/renderer/core/paint/text_decoration_info.cc b/third_party/blink/renderer/core/paint/text_decoration_info.cc index c3e58d9..7960a9a5 100644 --- a/third_party/blink/renderer/core/paint/text_decoration_info.cc +++ b/third_party/blink/renderer/core/paint/text_decoration_info.cc
@@ -233,8 +233,6 @@ return LayoutTheme::GetTheme().PlatformSpellingMarkerUnderlineColor(); if (line_data_.line == TextDecorationLine::kGrammarError) return LayoutTheme::GetTheme().PlatformGrammarMarkerUnderlineColor(); - if (highlight_override_) - return *highlight_override_; // Find the matched normal and selection |AppliedTextDecoration| // and use the text-decoration-color from selection when it is. @@ -335,11 +333,6 @@ return line_data_.stroke_path; } -void TextDecorationInfo::SetHighlightOverrideColor( - const absl::optional<Color>& color) { - highlight_override_ = color; -} - float TextDecorationInfo::WavyDecorationSizing() const { // Minimum unit we use to compute control point distance and step to define // the path of the Bezier curve.
diff --git a/third_party/blink/renderer/core/paint/text_decoration_info.h b/third_party/blink/renderer/core/paint/text_decoration_info.h index add088c4..b8ab7045 100644 --- a/third_party/blink/renderer/core/paint/text_decoration_info.h +++ b/third_party/blink/renderer/core/paint/text_decoration_info.h
@@ -102,9 +102,6 @@ // Return a path for current decoration. absl::optional<Path> StrokePath() const; - // Overrides the line color with the given topmost active highlight ‘color’. - void SetHighlightOverrideColor(const absl::optional<Color>&); - private: float ComputeUnderlineThickness( const TextDecorationThickness& applied_decoration_thickness, @@ -145,7 +142,6 @@ absl::optional<Path> stroke_path; }; LineData line_data_; - absl::optional<Color> highlight_override_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/paint/text_paint_style.h b/third_party/blink/renderer/core/paint/text_paint_style.h index 01718ae..33fb74c 100644 --- a/third_party/blink/renderer/core/paint/text_paint_style.h +++ b/third_party/blink/renderer/core/paint/text_paint_style.h
@@ -17,6 +17,8 @@ class ShadowList; struct CORE_EXPORT TextPaintStyle { + STACK_ALLOCATED(); + public: Color current_color; Color fill_color;
diff --git a/third_party/blink/renderer/core/script/document_write_intervention.cc b/third_party/blink/renderer/core/script/document_write_intervention.cc index 3e2cd04..48c0bb9 100644 --- a/third_party/blink/renderer/core/script/document_write_intervention.cc +++ b/third_party/blink/renderer/core/script/document_write_intervention.cc
@@ -119,7 +119,7 @@ if (!settings) return false; - if (!document.GetFrame() || !document.GetFrame()->IsMainFrame()) + if (!document.IsInOutermostMainFrame()) return false; // Only block synchronously loaded (parser blocking) scripts.
diff --git a/third_party/blink/renderer/core/svg/svg_fe_image_element.cc b/third_party/blink/renderer/core/svg/svg_fe_image_element.cc index 23aa88b6..5159e7e 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_image_element.cc +++ b/third_party/blink/renderer/core/svg/svg_fe_image_element.cc
@@ -49,10 +49,6 @@ SVGFEImageElement::~SVGFEImageElement() = default; -void SVGFEImageElement::Dispose() { - ClearImageResource(); -} - void SVGFEImageElement::Trace(Visitor* visitor) const { visitor->Trace(preserve_aspect_ratio_); visitor->Trace(cached_image_); @@ -96,6 +92,13 @@ cached_image_ = nullptr; } +void SVGFEImageElement::Dispose() { + if (!cached_image_) + return; + cached_image_->DidRemoveObserver(); + cached_image_ = nullptr; +} + void SVGFEImageElement::BuildPendingResource() { ClearResourceReferences(); if (!isConnected())
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc index 7ffcd82..6646673 100644 --- a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc +++ b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc
@@ -79,8 +79,6 @@ KURL response_script_url = creation_params->script_url; network::mojom::ReferrerPolicy response_referrer_policy = creation_params->referrer_policy; - absl::optional<network::mojom::IPAddressSpace> response_address_space = - creation_params->response_address_space; const bool parent_cross_origin_isolated_capability = creation_params->parent_cross_origin_isolated_capability; const bool parent_direct_socket_capability = @@ -100,7 +98,7 @@ // Pass dummy origin trial tokens here as it is already set to outside's // origin trial tokens in DedicatedWorkerGlobalScope's constructor. global_scope->Initialize(response_script_url, response_referrer_policy, - *response_address_space, std::move(response_csp), + std::move(response_csp), nullptr /* response_origin_trial_tokens */); return global_scope; } else { @@ -230,7 +228,6 @@ void DedicatedWorkerGlobalScope::Initialize( const KURL& response_url, network::mojom::ReferrerPolicy response_referrer_policy, - network::mojom::IPAddressSpace response_address_space, Vector<network::mojom::blink::ContentSecurityPolicyPtr> response_csp, const Vector<String>* /* response_origin_trial_tokens */) { // Step 14.3. "Set worker global scope's url to response's url." @@ -244,9 +241,6 @@ // parsing the `Referrer-Policy` header of response." SetReferrerPolicy(response_referrer_policy); - // https://wicg.github.io/cors-rfc1918/#integration-html - SetAddressSpace(response_address_space); - // The following is the Content-Security-Policy part of "Initialize worker // global scope's policy container" // https://html.spec.whatwg.org/#initialize-worker-policy-container @@ -451,7 +445,6 @@ // Pass dummy origin trial tokens here as it is already set to outside's // origin trial tokens in DedicatedWorkerGlobalScope's constructor. Initialize(classic_script_loader->ResponseURL(), response_referrer_policy, - classic_script_loader->ResponseAddressSpace(), classic_script_loader->GetContentSecurityPolicy() ? mojo::Clone(classic_script_loader->GetContentSecurityPolicy() ->GetParsedPolicies())
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h index ef9e396..fd72266 100644 --- a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h +++ b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h
@@ -105,7 +105,6 @@ void Initialize( const KURL& response_url, network::mojom::ReferrerPolicy response_referrer_policy, - network::mojom::IPAddressSpace response_address_space, Vector<network::mojom::blink::ContentSecurityPolicyPtr> response_csp, const Vector<String>* response_origin_trial_tokens) override; void FetchAndRunClassicScript(
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_test.cc b/third_party/blink/renderer/core/workers/dedicated_worker_test.cc index 5406a149a..78c578b 100644 --- a/third_party/blink/renderer/core/workers/dedicated_worker_test.cc +++ b/third_party/blink/renderer/core/workers/dedicated_worker_test.cc
@@ -95,7 +95,6 @@ EXPECT_TRUE(IsCurrentThread()); To<DedicatedWorkerGlobalScope>(GlobalScope()) ->Initialize(script_url, network::mojom::ReferrerPolicy::kDefault, - network::mojom::IPAddressSpace::kLocal, Vector<network::mojom::blink::ContentSecurityPolicyPtr>(), nullptr /* response_origin_trial_tokens */); }
diff --git a/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc b/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc index 162e2353..35d265d 100644 --- a/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc +++ b/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc
@@ -110,7 +110,6 @@ void SharedWorkerGlobalScope::Initialize( const KURL& response_url, network::mojom::ReferrerPolicy response_referrer_policy, - network::mojom::IPAddressSpace response_address_space, Vector<network::mojom::blink::ContentSecurityPolicyPtr> response_csp, const Vector<String>* response_origin_trial_tokens) { // Step 12.3. "Set worker global scope's url to response's url." @@ -124,9 +123,6 @@ // parsing the `Referrer-Policy` header of response." SetReferrerPolicy(response_referrer_policy); - // https://wicg.github.io/cors-rfc1918/#integration-html - SetAddressSpace(response_address_space); - // Step 12.6. "Execute the Initialize a global object's CSP list algorithm // on worker global scope and response. [CSP]" // SharedWorkerGlobalScope inherits the outside's CSP instead of the response @@ -136,8 +132,6 @@ // https://fetch.spec.whatwg.org/#local-scheme // // https://w3c.github.io/webappsec-csp/#initialize-global-object-csp - // These should be called after SetAddressSpace() to correctly override the - // address space by the "treat-as-public-address" CSP directive. Vector<network::mojom::blink::ContentSecurityPolicyPtr> csp_headers = response_url.ProtocolIsAbout() || response_url.ProtocolIsData() || response_url.ProtocolIs("blob") @@ -280,7 +274,6 @@ // Step 12.3-12.6 are implemented in Initialize(). Initialize(classic_script_loader->ResponseURL(), response_referrer_policy, - classic_script_loader->ResponseAddressSpace(), classic_script_loader->GetContentSecurityPolicy() ? mojo::Clone(classic_script_loader->GetContentSecurityPolicy() ->GetParsedPolicies())
diff --git a/third_party/blink/renderer/core/workers/shared_worker_global_scope.h b/third_party/blink/renderer/core/workers/shared_worker_global_scope.h index d92bb9d..b2ebed4 100644 --- a/third_party/blink/renderer/core/workers/shared_worker_global_scope.h +++ b/third_party/blink/renderer/core/workers/shared_worker_global_scope.h
@@ -66,7 +66,6 @@ void Initialize( const KURL& response_url, network::mojom::ReferrerPolicy response_referrer_policy, - network::mojom::IPAddressSpace response_address_space, Vector<network::mojom::blink::ContentSecurityPolicyPtr> response_csp, const Vector<String>* response_origin_trial_tokens) override; void FetchAndRunClassicScript(
diff --git a/third_party/blink/renderer/core/workers/worker_global_scope.h b/third_party/blink/renderer/core/workers/worker_global_scope.h index 256eee1..caa9288 100644 --- a/third_party/blink/renderer/core/workers/worker_global_scope.h +++ b/third_party/blink/renderer/core/workers/worker_global_scope.h
@@ -31,7 +31,6 @@ #include "base/time/time.h" #include "services/network/public/mojom/fetch_api.mojom-blink-forward.h" -#include "services/network/public/mojom/ip_address_space.mojom-blink-forward.h" #include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/common/loader/worker_main_script_load_parameters.h" #include "third_party/blink/public/common/tokens/tokens.h" @@ -156,7 +155,6 @@ virtual void Initialize( const KURL& response_url, network::mojom::ReferrerPolicy response_referrer_policy, - network::mojom::IPAddressSpace response_address_space, Vector<network::mojom::blink::ContentSecurityPolicyPtr> response_csp, const Vector<String>* response_origin_trial_tokens) = 0;
diff --git a/third_party/blink/renderer/core/workers/worker_thread_test_helper.h b/third_party/blink/renderer/core/workers/worker_thread_test_helper.h index ce1401c1..034dca8 100644 --- a/third_party/blink/renderer/core/workers/worker_thread_test_helper.h +++ b/third_party/blink/renderer/core/workers/worker_thread_test_helper.h
@@ -9,7 +9,6 @@ #include "base/synchronization/waitable_event.h" #include "services/metrics/public/cpp/ukm_source_id.h" -#include "services/network/public/mojom/ip_address_space.mojom-blink.h" #include "testing/gmock/include/gmock/gmock.h" #include "third_party/blink/public/mojom/v8_cache_options.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/source_location.h" @@ -66,15 +65,11 @@ void Initialize( const KURL& response_url, network::mojom::ReferrerPolicy response_referrer_policy, - network::mojom::IPAddressSpace response_address_space, Vector<network::mojom::blink::ContentSecurityPolicyPtr> response_csp, const Vector<String>* response_origin_trial_tokens) override { InitializeURL(response_url); SetReferrerPolicy(response_referrer_policy); - SetAddressSpace(response_address_space); - // These should be called after SetAddressSpace() to correctly override the - // address space by the "treat-as-public-address" CSP directive. InitContentSecurityPolicyFromVector(std::move(response_csp)); BindContentSecurityPolicyToExecutionContext();
diff --git a/third_party/blink/renderer/modules/font_access/font_data.idl b/third_party/blink/renderer/modules/font_access/font_data.idl index 7c1ea73..8d2a4a5 100644 --- a/third_party/blink/renderer/modules/font_access/font_data.idl +++ b/third_party/blink/renderer/modules/font_access/font_data.idl
@@ -5,7 +5,7 @@ // Returned by the async iterator FontIterator as the entry value. // https://wicg.github.io/local-font-access/ [ - Exposed=(Window,Worker), + Exposed=(Window), SecureContext, RuntimeEnabled=FontAccess, ImplementedAs=FontMetadata
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream.cc b/third_party/blink/renderer/modules/mediastream/media_stream.cc index 10ee73dd..2dcc557 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream.cc +++ b/third_party/blink/renderer/modules/mediastream/media_stream.cc
@@ -142,7 +142,7 @@ audio_tracks_.push_back(new_track); if (transferred_track) { DCHECK(!transferred_track->HasImplementation()); - transferred_track->setImplementation(new_track); + transferred_track->SetImplementation(new_track); } } @@ -158,7 +158,7 @@ video_tracks_.push_back(new_track); if (transferred_track) { DCHECK(!transferred_track->HasImplementation()); - transferred_track->setImplementation(new_track); + transferred_track->SetImplementation(new_track); } }
diff --git a/third_party/blink/renderer/modules/mediastream/transferred_media_stream_track.cc b/third_party/blink/renderer/modules/mediastream/transferred_media_stream_track.cc index 9164cb1..f4846250 100644 --- a/third_party/blink/renderer/modules/mediastream/transferred_media_stream_track.cc +++ b/third_party/blink/renderer/modules/mediastream/transferred_media_stream_track.cc
@@ -182,7 +182,7 @@ return ScriptPromise(); } -void TransferredMediaStreamTrack::setImplementation(MediaStreamTrack* track) { +void TransferredMediaStreamTrack::SetImplementation(MediaStreamTrack* track) { track_ = track; // TODO(https://crbug.com/1288839): Replay mutations which have happened // before this point. Also set up plumbing so that events fired by the
diff --git a/third_party/blink/renderer/modules/mediastream/transferred_media_stream_track.h b/third_party/blink/renderer/modules/mediastream/transferred_media_stream_track.h index 10f7a26..a037d542 100644 --- a/third_party/blink/renderer/modules/mediastream/transferred_media_stream_track.h +++ b/third_party/blink/renderer/modules/mediastream/transferred_media_stream_track.h
@@ -53,8 +53,8 @@ ScriptPromise applyConstraints(ScriptState*, const MediaTrackConstraints*) override; - bool HasImplementation() { return !!track_; } - void setImplementation(MediaStreamTrack* track); + bool HasImplementation() const { return !!track_; } + void SetImplementation(MediaStreamTrack* track); void SetConstraints(const MediaConstraints&) override;
diff --git a/third_party/blink/renderer/modules/mediastream/transferred_media_stream_track_test.cc b/third_party/blink/renderer/modules/mediastream/transferred_media_stream_track_test.cc index 32c9a851..7822d769 100644 --- a/third_party/blink/renderer/modules/mediastream/transferred_media_stream_track_test.cc +++ b/third_party/blink/renderer/modules/mediastream/transferred_media_stream_track_test.cc
@@ -85,7 +85,7 @@ .muted = false, .content_hint = WebMediaStreamTrack::ContentHintType::kNone, .ready_state = MediaStreamSource::kReadyStateLive}); - transferred_track.setImplementation(&mock_impl); + transferred_track.SetImplementation(&mock_impl); EXPECT_EQ(transferred_track.kind(), kKind); EXPECT_EQ(transferred_track.id(), kId);
diff --git a/third_party/blink/renderer/modules/payments/payment_request.cc b/third_party/blink/renderer/modules/payments/payment_request.cc index 99850e24..36ca96047 100644 --- a/third_party/blink/renderer/modules/payments/payment_request.cc +++ b/third_party/blink/renderer/modules/payments/payment_request.cc
@@ -850,8 +850,7 @@ UseCounter::Count(GetExecutionContext(), WebFeature::kPaymentRequestShow); is_waiting_for_show_promise_to_resolve_ = !details_promise.IsEmpty(); - payment_provider_->Show(payment_request_allowed, - is_waiting_for_show_promise_to_resolve_); + payment_provider_->ShowNew(is_waiting_for_show_promise_to_resolve_); if (is_waiting_for_show_promise_to_resolve_) { // If the website does not calculate the final shopping cart contents within // 10 seconds, abort payment.
diff --git a/third_party/blink/renderer/modules/payments/payment_request_for_invalid_origin_or_ssl_test.cc b/third_party/blink/renderer/modules/payments/payment_request_for_invalid_origin_or_ssl_test.cc index cd517ff..748411a 100644 --- a/third_party/blink/renderer/modules/payments/payment_request_for_invalid_origin_or_ssl_test.cc +++ b/third_party/blink/renderer/modules/payments/payment_request_for_invalid_origin_or_ssl_test.cc
@@ -33,6 +33,7 @@ } void Show(bool is_user_gesture, bool wait_for_updated_details) override {} + void ShowNew(bool wait_for_updated_details) override {} void Retry( payments::mojom::blink::PaymentValidationErrorsPtr errors) override { NOTREACHED();
diff --git a/third_party/blink/renderer/modules/payments/payment_request_optional_total_test.cc b/third_party/blink/renderer/modules/payments/payment_request_optional_total_test.cc index 55fc27c7..c38818bc 100644 --- a/third_party/blink/renderer/modules/payments/payment_request_optional_total_test.cc +++ b/third_party/blink/renderer/modules/payments/payment_request_optional_total_test.cc
@@ -32,6 +32,7 @@ void Show(bool is_user_gesture, bool wait_for_updated_details) override { NOTREACHED(); } + void ShowNew(bool wait_for_updated_details) override { NOTREACHED(); } void Retry( payments::mojom::blink::PaymentValidationErrorsPtr errors) override { NOTREACHED();
diff --git a/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc b/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc index 5ec6c005..b898375 100644 --- a/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc +++ b/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc
@@ -9,7 +9,6 @@ #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_remote_playback_availability_callback.h" #include "third_party/blink/renderer/core/dom/document.h" @@ -115,25 +114,23 @@ ScriptPromise RemotePlayback::watchAvailability( ScriptState* script_state, - V8RemotePlaybackAvailabilityCallback* callback) { - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); - ScriptPromise promise = resolver->Promise(); - + V8RemotePlaybackAvailabilityCallback* callback, + ExceptionState& exception_state) { if (media_element_->FastHasAttribute( html_names::kDisableremoteplaybackAttr)) { - resolver->Reject(V8ThrowDOMException::CreateOrDie( - script_state->GetIsolate(), DOMExceptionCode::kInvalidStateError, - "disableRemotePlayback attribute is present.")); - return promise; + exception_state.ThrowDOMException( + DOMExceptionCode::kInvalidStateError, + "disableRemotePlayback attribute is present."); + return ScriptPromise(); } int id = WatchAvailabilityInternal( MakeGarbageCollected<AvailabilityCallbackWrapper>(callback)); if (id == kWatchAvailabilityNotSupported) { - resolver->Reject(V8ThrowDOMException::CreateOrDie( - script_state->GetIsolate(), DOMExceptionCode::kNotSupportedError, - "Availability monitoring is not supported on this device.")); - return promise; + exception_state.ThrowDOMException( + DOMExceptionCode::kNotSupportedError, + "Availability monitoring is not supported on this device."); + return ScriptPromise(); } // TODO(avayvod): Currently the availability is tracked for each media element @@ -142,110 +139,111 @@ // controls. If there are no default controls, we should also start tracking // availability on demand meaning the Promise returned by watchAvailability() // will be resolved asynchronously. + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = resolver->Promise(); resolver->Resolve(id); return promise; } -ScriptPromise RemotePlayback::cancelWatchAvailability(ScriptState* script_state, - int id) { - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); - ScriptPromise promise = resolver->Promise(); - +ScriptPromise RemotePlayback::cancelWatchAvailability( + ScriptState* script_state, + int id, + ExceptionState& exception_state) { if (media_element_->FastHasAttribute( html_names::kDisableremoteplaybackAttr)) { - resolver->Reject(V8ThrowDOMException::CreateOrDie( - script_state->GetIsolate(), DOMExceptionCode::kInvalidStateError, - "disableRemotePlayback attribute is present.")); - return promise; + exception_state.ThrowDOMException( + DOMExceptionCode::kInvalidStateError, + "disableRemotePlayback attribute is present."); + return ScriptPromise(); } if (!CancelWatchAvailabilityInternal(id)) { - resolver->Reject(V8ThrowDOMException::CreateOrDie( - script_state->GetIsolate(), DOMExceptionCode::kNotFoundError, - "A callback with the given id is not found.")); - return promise; + exception_state.ThrowDOMException( + DOMExceptionCode::kNotFoundError, + "A callback with the given id is not found."); + return ScriptPromise(); } + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = resolver->Promise(); resolver->Resolve(); return promise; } ScriptPromise RemotePlayback::cancelWatchAvailability( - ScriptState* script_state) { - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); - ScriptPromise promise = resolver->Promise(); - + ScriptState* script_state, + ExceptionState& exception_state) { if (media_element_->FastHasAttribute( html_names::kDisableremoteplaybackAttr)) { - resolver->Reject(V8ThrowDOMException::CreateOrDie( - script_state->GetIsolate(), DOMExceptionCode::kInvalidStateError, - "disableRemotePlayback attribute is present.")); - return promise; + exception_state.ThrowDOMException( + DOMExceptionCode::kInvalidStateError, + "disableRemotePlayback attribute is present."); + return ScriptPromise(); } availability_callbacks_.clear(); StopListeningForAvailability(); + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = resolver->Promise(); resolver->Resolve(); return promise; } -ScriptPromise RemotePlayback::prompt(ScriptState* script_state) { - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); - ScriptPromise promise = resolver->Promise(); - v8::Isolate* isolate = script_state->GetIsolate(); - +ScriptPromise RemotePlayback::prompt(ScriptState* script_state, + ExceptionState& exception_state) { if (media_element_->FastHasAttribute( html_names::kDisableremoteplaybackAttr)) { - resolver->Reject(V8ThrowDOMException::CreateOrDie( - isolate, DOMExceptionCode::kInvalidStateError, - "disableRemotePlayback attribute is present.")); - return promise; + exception_state.ThrowDOMException( + DOMExceptionCode::kInvalidStateError, + "disableRemotePlayback attribute is present."); + return ScriptPromise(); } if (prompt_promise_resolver_) { - resolver->Reject(V8ThrowDOMException::CreateOrDie( - isolate, DOMExceptionCode::kOperationError, - "A prompt is already being shown for this media element.")); - return promise; + exception_state.ThrowDOMException( + DOMExceptionCode::kOperationError, + "A prompt is already being shown for this media element."); + return ScriptPromise(); } if (!media_element_->DomWindow()) { - resolver->Reject(V8ThrowDOMException::CreateOrDie( - isolate, DOMExceptionCode::kInvalidAccessError, - "RemotePlayback::prompt() does not work in a detached window.")); - return promise; + exception_state.ThrowDOMException( + DOMExceptionCode::kInvalidAccessError, + "RemotePlayback::prompt() does not work in a detached window."); + return ScriptPromise(); } if (!LocalFrame::HasTransientUserActivation( media_element_->DomWindow()->GetFrame())) { - resolver->Reject(V8ThrowDOMException::CreateOrDie( - isolate, DOMExceptionCode::kInvalidAccessError, - "RemotePlayback::prompt() requires user gesture.")); - return promise; + exception_state.ThrowDOMException( + DOMExceptionCode::kInvalidAccessError, + "RemotePlayback::prompt() requires user gesture."); + return ScriptPromise(); } if (!RuntimeEnabledFeatures::RemotePlaybackBackendEnabled()) { - resolver->Reject(V8ThrowDOMException::CreateOrDie( - isolate, DOMExceptionCode::kNotSupportedError, - "The RemotePlayback API is disabled on this platform.")); - return promise; + exception_state.ThrowDOMException( + DOMExceptionCode::kNotSupportedError, + "The RemotePlayback API is disabled on this platform."); + return ScriptPromise(); } if (availability_ == mojom::ScreenAvailability::UNAVAILABLE) { - resolver->Reject(V8ThrowDOMException::CreateOrDie( - isolate, DOMExceptionCode::kNotFoundError, - "No remote playback devices found.")); - return promise; + exception_state.ThrowDOMException(DOMExceptionCode::kNotFoundError, + "No remote playback devices found."); + return ScriptPromise(); } if (availability_ == mojom::ScreenAvailability::SOURCE_NOT_SUPPORTED) { - resolver->Reject(V8ThrowDOMException::CreateOrDie( - isolate, DOMExceptionCode::kNotSupportedError, - "The currentSrc is not compatible with remote playback")); - return promise; + exception_state.ThrowDOMException( + DOMExceptionCode::kNotSupportedError, + "The currentSrc is not compatible with remote playback"); + return ScriptPromise(); } + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = resolver->Promise(); prompt_promise_resolver_ = resolver; PromptInternal(); RemotePlaybackMetrics::RecordRemotePlaybackLocation(
diff --git a/third_party/blink/renderer/modules/remoteplayback/remote_playback.h b/third_party/blink/renderer/modules/remoteplayback/remote_playback.h index 53607be5..a492a559 100644 --- a/third_party/blink/renderer/modules/remoteplayback/remote_playback.h +++ b/third_party/blink/renderer/modules/remoteplayback/remote_playback.h
@@ -74,18 +74,19 @@ // availability via the provided callback. May start the monitoring of remote // playback devices if it isn't running yet. ScriptPromise watchAvailability(ScriptState*, - V8RemotePlaybackAvailabilityCallback*); + V8RemotePlaybackAvailabilityCallback*, + ExceptionState&); // Cancels updating the page via the callback specified by its id. - ScriptPromise cancelWatchAvailability(ScriptState*, int id); + ScriptPromise cancelWatchAvailability(ScriptState*, int id, ExceptionState&); // Cancels all the callbacks watching remote playback availability changes // registered with this element. - ScriptPromise cancelWatchAvailability(ScriptState*); + ScriptPromise cancelWatchAvailability(ScriptState*, ExceptionState&); // Shows the UI allowing user to change the remote playback state of the media // element (by picking a remote playback device from the list, for example). - ScriptPromise prompt(ScriptState*); + ScriptPromise prompt(ScriptState*, ExceptionState&); String state() const;
diff --git a/third_party/blink/renderer/modules/remoteplayback/remote_playback.idl b/third_party/blink/renderer/modules/remoteplayback/remote_playback.idl index 0f400e46..93ee76e3 100644 --- a/third_party/blink/renderer/modules/remoteplayback/remote_playback.idl +++ b/third_party/blink/renderer/modules/remoteplayback/remote_playback.idl
@@ -22,7 +22,7 @@ attribute EventHandler onconnect; attribute EventHandler ondisconnect; - [Measure, CallWith=ScriptState] Promise<long> watchAvailability(RemotePlaybackAvailabilityCallback callback); - [CallWith=ScriptState] Promise<void> cancelWatchAvailability(optional long id); - [Measure, CallWith=ScriptState] Promise<void> prompt(); + [Measure, CallWith=ScriptState,RaisesException] Promise<long> watchAvailability(RemotePlaybackAvailabilityCallback callback); + [CallWith=ScriptState,RaisesException] Promise<void> cancelWatchAvailability(optional long id); + [Measure, CallWith=ScriptState,RaisesException] Promise<void> prompt(); };
diff --git a/third_party/blink/renderer/modules/remoteplayback/remote_playback_test.cc b/third_party/blink/renderer/modules/remoteplayback/remote_playback_test.cc index f0a2388..41ea9fce 100644 --- a/third_party/blink/renderer/modules/remoteplayback/remote_playback_test.cc +++ b/third_party/blink/renderer/modules/remoteplayback/remote_playback_test.cc
@@ -85,7 +85,7 @@ LocalFrame::NotifyUserActivation( &page_holder->GetFrame(), mojom::UserActivationNotificationType::kTest); - remote_playback.prompt(scope.GetScriptState()) + remote_playback.prompt(scope.GetScriptState(), scope.GetExceptionState()) .Then(funcs.ExpectNoCall(), funcs.ExpectCall()); CancelPrompt(remote_playback); @@ -109,7 +109,7 @@ LocalFrame::NotifyUserActivation( &page_holder->GetFrame(), mojom::UserActivationNotificationType::kTest); - remote_playback.prompt(scope.GetScriptState()) + remote_playback.prompt(scope.GetScriptState(), scope.GetExceptionState()) .Then(funcs.ExpectNoCall(), funcs.ExpectCall()); CancelPrompt(remote_playback); @@ -133,7 +133,7 @@ LocalFrame::NotifyUserActivation( &page_holder->GetFrame(), mojom::UserActivationNotificationType::kTest); - remote_playback.prompt(scope.GetScriptState()) + remote_playback.prompt(scope.GetScriptState(), scope.GetExceptionState()) .Then(funcs.ExpectCall(), funcs.ExpectNoCall()); SetState(remote_playback, mojom::blink::PresentationConnectionState::CLOSED); @@ -225,7 +225,7 @@ LocalFrame::NotifyUserActivation( &page_holder->GetFrame(), mojom::UserActivationNotificationType::kTest); - remote_playback.prompt(scope.GetScriptState()) + remote_playback.prompt(scope.GetScriptState(), scope.GetExceptionState()) .Then(funcs.ExpectNoCall(), funcs.ExpectCall()); HTMLMediaElementRemotePlayback::SetBooleanAttribute( *element, html_names::kDisableremoteplaybackAttr, true); @@ -249,7 +249,8 @@ V8RemotePlaybackAvailabilityCallback::Create(funcs.ExpectNoCall()); remote_playback - .watchAvailability(scope.GetScriptState(), availability_callback) + .watchAvailability(scope.GetScriptState(), availability_callback, + scope.GetExceptionState()) .Then(funcs.ExpectCall(), funcs.ExpectNoCall()); HTMLMediaElementRemotePlayback::SetBooleanAttribute( @@ -278,12 +279,14 @@ const int kNumberCallbacks = 10; for (int i = 0; i < kNumberCallbacks; ++i) { remote_playback.watchAvailability(scope.GetScriptState(), - availability_callback); + availability_callback, + scope.GetExceptionState()); } auto add_callback_lambda = [&]() { remote_playback.watchAvailability(scope.GetScriptState(), - availability_callback); + availability_callback, + scope.GetExceptionState()); return blink::ScriptValue::CreateNull(scope.GetScriptState()->GetIsolate()); }; @@ -324,15 +327,10 @@ MakeGarbageCollected<HTMLVideoElement>(page_holder->GetDocument()); RemotePlayback& remote_playback = RemotePlayback::From(*element); - MockFunctionScope funcs(scope.GetScriptState()); - LocalFrame::NotifyUserActivation( &page_holder->GetFrame(), mojom::UserActivationNotificationType::kTest); - remote_playback.prompt(scope.GetScriptState()) - .Then(funcs.ExpectNoCall(), funcs.ExpectCall()); - - // Runs pending promises. - v8::MicrotasksScope::PerformCheckpoint(scope.GetIsolate()); + remote_playback.prompt(scope.GetScriptState(), scope.GetExceptionState()); + EXPECT_TRUE(scope.GetExceptionState().HadException()); } TEST_F(RemotePlaybackTest, WatchAvailabilityWorksWhenBackendDisabled) { @@ -351,7 +349,8 @@ V8RemotePlaybackAvailabilityCallback::Create(funcs.ExpectNoCall()); remote_playback - .watchAvailability(scope.GetScriptState(), availability_callback) + .watchAvailability(scope.GetScriptState(), availability_callback, + scope.GetExceptionState()) .Then(funcs.ExpectCall(), funcs.ExpectNoCall()); // Runs pending promises. @@ -391,8 +390,8 @@ // message loop. EXPECT_CALL(*callback_function, Call(testing::_, testing::_)).Times(2); - remote_playback.watchAvailability(scope.GetScriptState(), - availability_callback); + remote_playback.watchAvailability( + scope.GetScriptState(), availability_callback, scope.GetExceptionState()); ASSERT_TRUE(remote_playback.Urls().IsEmpty()); ASSERT_FALSE(IsListening(remote_playback)); @@ -402,12 +401,13 @@ ASSERT_TRUE(IsListening(remote_playback)); remote_playback.AvailabilityChanged(mojom::ScreenAvailability::AVAILABLE); - remote_playback.cancelWatchAvailability(scope.GetScriptState()); + remote_playback.cancelWatchAvailability(scope.GetScriptState(), + scope.GetExceptionState()); ASSERT_EQ((size_t)1, remote_playback.Urls().size()); ASSERT_FALSE(IsListening(remote_playback)); - remote_playback.watchAvailability(scope.GetScriptState(), - availability_callback); + remote_playback.watchAvailability( + scope.GetScriptState(), availability_callback, scope.GetExceptionState()); ASSERT_EQ((size_t)1, remote_playback.Urls().size()); ASSERT_TRUE(IsListening(remote_playback)); remote_playback.AvailabilityChanged(mojom::ScreenAvailability::AVAILABLE);
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc index cff752a..4b9e6c3 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc +++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
@@ -440,7 +440,6 @@ void ServiceWorkerGlobalScope::Initialize( const KURL& response_url, network::mojom::ReferrerPolicy response_referrer_policy, - network::mojom::IPAddressSpace response_address_space, Vector<network::mojom::blink::ContentSecurityPolicyPtr> response_csp, const Vector<String>* response_origin_trial_tokens) { // Step 4.5. "Set workerGlobalScope's url to serviceWorker's script url." @@ -454,9 +453,6 @@ // script resource's referrer policy." SetReferrerPolicy(response_referrer_policy); - // https://wicg.github.io/cors-rfc1918/#integration-html - SetAddressSpace(response_address_space); - // This is quoted from the "Content Security Policy" algorithm in the service // workers spec: // "Whenever a user agent invokes Run Service Worker algorithm with a service @@ -467,9 +463,6 @@ // - If serviceWorker's script resource was delivered with a // Content-Security-Policy-Report-Only HTTP header containing the value // policy, the user agent must monitor policy for serviceWorker." - // - // These should be called after SetAddressSpace() to correctly override the - // address space by the "treat-as-public-address" CSP directive. InitContentSecurityPolicyFromVector(std::move(response_csp)); BindContentSecurityPolicyToExecutionContext(); @@ -529,8 +522,8 @@ std::unique_ptr<Vector<uint8_t>> cached_meta_data, const v8_inspector::V8StackTraceId& stack_id) { // Step 4.5-4.11 are implemented in Initialize(). - Initialize(response_url, response_referrer_policy, response_address_space, - std::move(response_csp), response_origin_trial_tokens); + Initialize(response_url, response_referrer_policy, std::move(response_csp), + response_origin_trial_tokens); // Step 4.12. "Let evaluationStatus be the result of running the classic // script script if script is a classic script, otherwise, the result of
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h index fc58619..0444ef0 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h +++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h
@@ -112,7 +112,6 @@ void Initialize( const KURL& response_url, network::mojom::ReferrerPolicy response_referrer_policy, - network::mojom::IPAddressSpace response_address_space, Vector<network::mojom::blink::ContentSecurityPolicyPtr> response_csp, const Vector<String>* response_origin_trial_tokens) override; // Fetches and runs the top-level classic worker script. @@ -349,6 +348,7 @@ void RunClassicScript( const KURL& response_url, network::mojom::ReferrerPolicy response_referrer_policy, + // TODO(https://crbug.com/1204028): Remove this unused parameter. network::mojom::IPAddressSpace response_address_space, Vector<network::mojom::blink::ContentSecurityPolicyPtr> response_csp, const Vector<String>* response_origin_trial_tokens,
diff --git a/third_party/blink/renderer/modules/vibration/vibration_controller.cc b/third_party/blink/renderer/modules/vibration/vibration_controller.cc index 4b04949..dcf34f06 100644 --- a/third_party/blink/renderer/modules/vibration/vibration_controller.cc +++ b/third_party/blink/renderer/modules/vibration/vibration_controller.cc
@@ -72,14 +72,17 @@ kSameOriginSubFrameWithUserGesture = 3, kCrossOriginSubFrameNoUserGesture = 4, kCrossOriginSubFrameWithUserGesture = 5, - kMaxValue = kCrossOriginSubFrameWithUserGesture, + kInFencedFrameTree = 6, + kMaxValue = kInFencedFrameTree, }; void CollectHistogramMetrics(LocalDOMWindow* window) { NavigatorVibrationType type; bool user_gesture = window->GetFrame()->HasStickyUserActivation(); UseCounter::Count(window, WebFeature::kNavigatorVibrate); - if (!window->GetFrame()->IsMainFrame()) { + if (window->GetFrame()->IsInFencedFrameTree()) { + type = NavigatorVibrationType::kInFencedFrameTree; + } else if (!window->GetFrame()->IsMainFrame()) { UseCounter::Count(window, WebFeature::kNavigatorVibrateSubFrame); if (window->GetFrame()->IsCrossOriginToMainFrame()) { if (user_gesture)
diff --git a/third_party/blink/renderer/modules/webaudio/async_audio_decoder.cc b/third_party/blink/renderer/modules/webaudio/async_audio_decoder.cc index da515f95..b4b5a14b 100644 --- a/third_party/blink/renderer/modules/webaudio/async_audio_decoder.cc +++ b/third_party/blink/renderer/modules/webaudio/async_audio_decoder.cc
@@ -33,6 +33,9 @@ #include "third_party/blink/renderer/modules/webaudio/base_audio_context.h" #include "third_party/blink/renderer/platform/audio/audio_bus.h" #include "third_party/blink/renderer/platform/audio/audio_file_reader.h" +#include "third_party/blink/renderer/platform/bindings/cross_thread_copier.h" +#include "third_party/blink/renderer/platform/bindings/exception_context.h" +#include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h" #include "third_party/blink/renderer/platform/scheduler/public/thread.h" #include "third_party/blink/renderer/platform/scheduler/public/worker_pool.h" @@ -46,7 +49,8 @@ V8DecodeSuccessCallback* success_callback, V8DecodeErrorCallback* error_callback, ScriptPromiseResolver* resolver, - BaseAudioContext* context) { + BaseAudioContext* context, + ExceptionState& exception_state) { DCHECK(IsMainThread()); DCHECK(audio_data); @@ -55,14 +59,14 @@ blink::TaskType::kInternalMedia); worker_pool::PostTask( - FROM_HERE, - CrossThreadBindOnce(&AsyncAudioDecoder::DecodeOnBackgroundThread, - WrapCrossThreadPersistent(audio_data), sample_rate, - WrapCrossThreadPersistent(success_callback), - WrapCrossThreadPersistent(error_callback), - WrapCrossThreadPersistent(resolver), - WrapCrossThreadPersistent(context), - std::move(task_runner))); + FROM_HERE, CrossThreadBindOnce( + &AsyncAudioDecoder::DecodeOnBackgroundThread, + WrapCrossThreadPersistent(audio_data), sample_rate, + WrapCrossThreadPersistent(success_callback), + WrapCrossThreadPersistent(error_callback), + WrapCrossThreadPersistent(resolver), + WrapCrossThreadPersistent(context), std::move(task_runner), + exception_state.GetContext())); } void AsyncAudioDecoder::DecodeOnBackgroundThread( @@ -72,7 +76,8 @@ V8DecodeErrorCallback* error_callback, ScriptPromiseResolver* resolver, BaseAudioContext* context, - scoped_refptr<base::SingleThreadTaskRunner> task_runner) { + scoped_refptr<base::SingleThreadTaskRunner> task_runner, + const ExceptionContext& exception_context) { DCHECK(!IsMainThread()); scoped_refptr<AudioBus> bus = CreateBusFromInMemoryAudioFile( audio_data->Data(), audio_data->ByteLength(), false, sample_rate); @@ -92,7 +97,8 @@ WrapCrossThreadPersistent(error_callback), WTF::RetainedRef(std::move(bus)), WrapCrossThreadPersistent(resolver), - WrapCrossThreadPersistent(context))); + WrapCrossThreadPersistent(context), + exception_context)); } } @@ -102,7 +108,8 @@ V8DecodeErrorCallback* error_callback, AudioBus* audio_bus, ScriptPromiseResolver* resolver, - BaseAudioContext* context) { + BaseAudioContext* context, + const ExceptionContext& exception_context) { DCHECK(IsMainThread()); AudioBuffer* audio_buffer = AudioBuffer::CreateFromAudioBus(audio_bus); @@ -110,7 +117,7 @@ // If the context is available, let the context finish the notification. if (context) { context->HandleDecodeAudioData(audio_buffer, resolver, success_callback, - error_callback); + error_callback, exception_context); } }
diff --git a/third_party/blink/renderer/modules/webaudio/async_audio_decoder.h b/third_party/blink/renderer/modules/webaudio/async_audio_decoder.h index 20c16c5..711c9306 100644 --- a/third_party/blink/renderer/modules/webaudio/async_audio_decoder.h +++ b/third_party/blink/renderer/modules/webaudio/async_audio_decoder.h
@@ -40,6 +40,8 @@ class BaseAudioContext; class DOMArrayBuffer; class ScriptPromiseResolver; +class ExceptionContext; +class ExceptionState; // AsyncAudioDecoder asynchronously decodes audio file data from a // DOMArrayBuffer in the background thread. Upon successful decoding, a @@ -66,7 +68,8 @@ V8DecodeSuccessCallback*, V8DecodeErrorCallback*, ScriptPromiseResolver*, - BaseAudioContext*); + BaseAudioContext*, + ExceptionState&); private: AudioBuffer* CreateAudioBufferFromAudioBus(AudioBus*); @@ -77,13 +80,15 @@ V8DecodeErrorCallback*, ScriptPromiseResolver*, BaseAudioContext*, - scoped_refptr<base::SingleThreadTaskRunner>); + scoped_refptr<base::SingleThreadTaskRunner>, + const ExceptionContext&); static void NotifyComplete(DOMArrayBuffer* audio_data, V8DecodeSuccessCallback*, V8DecodeErrorCallback*, AudioBus*, ScriptPromiseResolver*, - BaseAudioContext*); + BaseAudioContext*, + const ExceptionContext&); }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/webaudio/audio_context.cc b/third_party/blink/renderer/modules/webaudio/audio_context.cc index 82d8d39..cab42ae 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_context.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_context.cc
@@ -295,9 +295,6 @@ return ScriptPromise(); } - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); - ScriptPromise promise = resolver->Promise(); - suspended_by_user_ = true; // Stop rendering now. @@ -305,14 +302,12 @@ SuspendRendering(); } - // Since we don't have any way of knowing when the hardware actually stops, - // we'll just resolve the promise now. - resolver->Resolve(); - // Probe reports the suspension only when the promise is resolved. probe::DidSuspendAudioContext(GetDocument()); - return promise; + // Since we don't have any way of knowing when the hardware actually stops, + // we'll just resolve the promise now. + return ScriptPromise::CastUndefined(script_state); } ScriptPromise AudioContext::resumeContext(ScriptState* script_state,
diff --git a/third_party/blink/renderer/modules/webaudio/base_audio_context.cc b/third_party/blink/renderer/modules/webaudio/base_audio_context.cc index 63fbe739..443c29ab 100644 --- a/third_party/blink/renderer/modules/webaudio/base_audio_context.cc +++ b/third_party/blink/renderer/modules/webaudio/base_audio_context.cc
@@ -327,9 +327,6 @@ return ScriptPromise(); } - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); - ScriptPromise promise = resolver->Promise(); - v8::Isolate* isolate = script_state->GetIsolate(); ArrayBufferContents buffer_contents; // Detach the audio array buffer from the main thread and start @@ -338,36 +335,44 @@ audio_data->Transfer(isolate, buffer_contents)) { DOMArrayBuffer* audio = DOMArrayBuffer::Create(buffer_contents); + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = resolver->Promise(); decode_audio_resolvers_.insert(resolver); audio_decoder_.DecodeAsync(audio, sampleRate(), success_callback, - error_callback, resolver, this); - } else { - // If audioData is already detached (neutered) we need to reject the - // promise with an error. - auto* error = MakeGarbageCollected<DOMException>( - DOMExceptionCode::kDataCloneError, - "Cannot decode detached ArrayBuffer"); - resolver->Reject(error); - if (error_callback) { - error_callback->InvokeAndReportException(this, error); - } + error_callback, resolver, this, exception_state); + return promise; } - return promise; + // If audioData is already detached (neutered) we need to reject the + // promise with an error. + exception_state.ThrowDOMException(DOMExceptionCode::kDataCloneError, + "Cannot decode detached ArrayBuffer"); + v8::Local<v8::Value> error = exception_state.GetException(); + if (error_callback) { + error_callback->InvokeAndReportException( + this, NativeValueTraits<DOMException>::NativeValue( + script_state->GetIsolate(), error, exception_state)); + } + + return ScriptPromise(); } void BaseAudioContext::HandleDecodeAudioData( AudioBuffer* audio_buffer, ScriptPromiseResolver* resolver, V8DecodeSuccessCallback* success_callback, - V8DecodeErrorCallback* error_callback) { + V8DecodeErrorCallback* error_callback, + ExceptionContext exception_context) { DCHECK(IsMainThread()); + DCHECK(resolver); - if (!GetExecutionContext()) { - // Nothing to do if the execution context is gone. + ScriptState* resolver_script_state = resolver->GetScriptState(); + if (!IsInParallelAlgorithmRunnable(resolver->GetExecutionContext(), + resolver_script_state)) { return; } + ScriptState::Scope script_state_scope(resolver_script_state); if (audio_buffer) { // Resolve promise successfully and run the success callback @@ -377,11 +382,20 @@ } } else { // Reject the promise and run the error callback - auto* error = MakeGarbageCollected<DOMException>( - DOMExceptionCode::kEncodingError, "Unable to decode audio data"); + ExceptionState exception_state(resolver_script_state->GetIsolate(), + exception_context); + // Create DOM exception from the exception state since it gives more info + // and return it using resolver as it's expected by interface specification. + exception_state.ThrowDOMException(DOMExceptionCode::kEncodingError, + "Unable to decode audio data"); + v8::Local<v8::Value> error = exception_state.GetException(); + exception_state.ClearException(); resolver->Reject(error); if (error_callback) { - error_callback->InvokeAndReportException(this, error); + error_callback->InvokeAndReportException( + this, + NativeValueTraits<DOMException>::NativeValue( + resolver_script_state->GetIsolate(), error, exception_state)); } }
diff --git a/third_party/blink/renderer/modules/webaudio/base_audio_context.h b/third_party/blink/renderer/modules/webaudio/base_audio_context.h index f6df421..158a79c8 100644 --- a/third_party/blink/renderer/modules/webaudio/base_audio_context.h +++ b/third_party/blink/renderer/modules/webaudio/base_audio_context.h
@@ -169,7 +169,8 @@ void HandleDecodeAudioData(AudioBuffer*, ScriptPromiseResolver*, V8DecodeSuccessCallback*, - V8DecodeErrorCallback*); + V8DecodeErrorCallback*, + ExceptionContext); AudioListener* listener() { return listener_; }
diff --git a/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc b/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc index a198f03f..5fae458 100644 --- a/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc +++ b/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc
@@ -217,27 +217,25 @@ return complete_resolver_->Promise(); } -ScriptPromise OfflineAudioContext::suspendContext(ScriptState* script_state, - double when) { +ScriptPromise OfflineAudioContext::suspendContext( + ScriptState* script_state, + double when, + ExceptionState& exception_state) { DCHECK(IsMainThread()); - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); - ScriptPromise promise = resolver->Promise(); - // If the rendering is finished, reject the promise. if (ContextState() == AudioContextState::kClosed) { - resolver->Reject(MakeGarbageCollected<DOMException>( - DOMExceptionCode::kInvalidStateError, - "the rendering is already finished")); - return promise; + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + "the rendering is already finished"); + return ScriptPromise(); } // The specified suspend time is negative; reject the promise. if (when < 0) { - resolver->Reject(MakeGarbageCollected<DOMException>( + exception_state.ThrowDOMException( DOMExceptionCode::kInvalidStateError, - "negative suspend time (" + String::Number(when) + ") is not allowed")); - return promise; + "negative suspend time (" + String::Number(when) + ") is not allowed"); + return ScriptPromise(); } // The suspend time should be earlier than the total render frame. If the @@ -245,7 +243,7 @@ // will be rejected. double total_render_duration = total_render_frames_ / sampleRate(); if (total_render_duration <= when) { - resolver->Reject(MakeGarbageCollected<DOMException>( + exception_state.ThrowDOMException( DOMExceptionCode::kInvalidStateError, "cannot schedule a suspend at " + String::NumberToStringECMAScript(when) + @@ -254,8 +252,8 @@ "render duration of " + String::Number(total_render_frames_) + " frames (" + String::NumberToStringECMAScript(total_render_duration) + - " seconds)")); - return promise; + " seconds)"); + return ScriptPromise(); } // Find the sample frame and round up to the nearest render quantum @@ -271,15 +269,17 @@ std::min(CurrentSampleFrame(), static_cast<size_t>(length())); double current_time_clamped = std::min(currentTime(), length() / static_cast<double>(sampleRate())); - resolver->Reject(MakeGarbageCollected<DOMException>( + exception_state.ThrowDOMException( DOMExceptionCode::kInvalidStateError, "suspend(" + String::Number(when) + ") failed to suspend at frame " + String::Number(frame) + " because it is earlier than the current " + "frame of " + String::Number(current_frame_clamped) + " (" + - String::Number(current_time_clamped) + " seconds)")); - return promise; + String::Number(current_time_clamped) + " seconds)"); + return ScriptPromise(); } + ScriptPromise promise; + { // Wait until the suspend map is available for the insertion. Here we should // use GraphAutoLocker because it locks the graph from the main thread. @@ -288,14 +288,17 @@ // If there is a duplicate suspension at the same quantized frame, // reject the promise. if (scheduled_suspends_.Contains(frame)) { - resolver->Reject(MakeGarbageCollected<DOMException>( + exception_state.ThrowDOMException( DOMExceptionCode::kInvalidStateError, "cannot schedule more than one suspend at frame " + String::Number(frame) + " (" + String::Number(when) + - " seconds)")); - return promise; + " seconds)"); + return ScriptPromise(); } + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); + promise = resolver->Promise(); + scheduled_suspends_.insert(frame, resolver); } @@ -307,34 +310,31 @@ return promise; } -ScriptPromise OfflineAudioContext::resumeContext(ScriptState* script_state) { +ScriptPromise OfflineAudioContext::resumeContext( + ScriptState* script_state, + ExceptionState& exception_state) { DCHECK(IsMainThread()); - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); - ScriptPromise promise = resolver->Promise(); - // If the rendering has not started, reject the promise. if (!is_rendering_started_) { - resolver->Reject(MakeGarbageCollected<DOMException>( + exception_state.ThrowDOMException( DOMExceptionCode::kInvalidStateError, - "cannot resume an offline context that has not started")); - return promise; + "cannot resume an offline context that has not started"); + return ScriptPromise(); } // If the context is in a closed state or it really is closed (cleared), // reject the promise. if (IsContextCleared() || ContextState() == AudioContextState::kClosed) { - resolver->Reject(MakeGarbageCollected<DOMException>( - DOMExceptionCode::kInvalidStateError, - "cannot resume a closed offline context")); - return promise; + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + "cannot resume a closed offline context"); + return ScriptPromise(); } // If the context is already running, resolve the promise without altering // the current state or starting the rendering loop. if (ContextState() == AudioContextState::kRunning) { - resolver->Resolve(); - return promise; + return ScriptPromise::CastUndefined(script_state); } DCHECK_EQ(ContextState(), AudioContextState::kSuspended); @@ -346,9 +346,7 @@ DestinationHandler().StartRendering(); // Resolve the promise immediately. - resolver->Resolve(); - - return promise; + return ScriptPromise::CastUndefined(script_state); } void OfflineAudioContext::FireCompletionEvent() {
diff --git a/third_party/blink/renderer/modules/webaudio/offline_audio_context.h b/third_party/blink/renderer/modules/webaudio/offline_audio_context.h index 45e9808..b2b138e1 100644 --- a/third_party/blink/renderer/modules/webaudio/offline_audio_context.h +++ b/third_party/blink/renderer/modules/webaudio/offline_audio_context.h
@@ -65,8 +65,8 @@ ScriptPromise startOfflineRendering(ScriptState*, ExceptionState&); - ScriptPromise suspendContext(ScriptState*, double); - ScriptPromise resumeContext(ScriptState*); + ScriptPromise suspendContext(ScriptState*, double, ExceptionState&); + ScriptPromise resumeContext(ScriptState*, ExceptionState&); void RejectPendingResolvers() override;
diff --git a/third_party/blink/renderer/modules/webaudio/offline_audio_context.idl b/third_party/blink/renderer/modules/webaudio/offline_audio_context.idl index d2b4c18..47075f51 100644 --- a/third_party/blink/renderer/modules/webaudio/offline_audio_context.idl +++ b/third_party/blink/renderer/modules/webaudio/offline_audio_context.idl
@@ -33,6 +33,6 @@ attribute EventHandler oncomplete; readonly attribute unsigned long length; [CallWith=ScriptState, RaisesException, ImplementedAs=startOfflineRendering, MeasureAs=OfflineAudioContextStartRendering] Promise<AudioBuffer> startRendering(); - [CallWith=ScriptState, ImplementedAs=suspendContext, MeasureAs=OfflineAudioContextSuspend] Promise<void> suspend(double suspendTime); - [MeasureAs=OfflineAudioContextResume, CallWith=ScriptState, ImplementedAs=resumeContext] Promise<void> resume(); + [RaisesException, CallWith=ScriptState, ImplementedAs=suspendContext, MeasureAs=OfflineAudioContextSuspend] Promise<void> suspend(double suspendTime); + [RaisesException, MeasureAs=OfflineAudioContextResume, CallWith=ScriptState, ImplementedAs=resumeContext] Promise<void> resume(); };
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn index 82e60b4..8e5cea6 100644 --- a/third_party/blink/renderer/platform/BUILD.gn +++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -378,6 +378,7 @@ "bindings/callback_interface_base.h", "bindings/callback_method_retriever.cc", "bindings/callback_method_retriever.h", + "bindings/cross_thread_copier.h", "bindings/custom_wrappable.h", "bindings/dictionary_base.cc", "bindings/dictionary_base.h",
diff --git a/third_party/blink/renderer/platform/bindings/cross_thread_copier.h b/third_party/blink/renderer/platform/bindings/cross_thread_copier.h new file mode 100644 index 0000000..c6f71384 --- /dev/null +++ b/third_party/blink/renderer/platform/bindings/cross_thread_copier.h
@@ -0,0 +1,23 @@ +// Copyright 2022 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_PLATFORM_BINDINGS_CROSS_THREAD_COPIER_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_CROSS_THREAD_COPIER_H_ + +#include "third_party/blink/renderer/platform/wtf/cross_thread_copier.h" + +namespace WTF { + +template <> +struct CrossThreadCopier<blink::ExceptionContext> { + STATIC_ONLY(CrossThreadCopier); + static blink::ExceptionContext Copy( + blink::ExceptionContext exception_context) { + return exception_context; + }; +}; + +} // namespace WTF + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_CROSS_THREAD_COPIER_H_
diff --git a/third_party/blink/renderer/platform/bindings/v8_binding.cc b/third_party/blink/renderer/platform/bindings/v8_binding.cc index 4d7fe950..e14f32cc 100644 --- a/third_party/blink/renderer/platform/bindings/v8_binding.cc +++ b/third_party/blink/renderer/platform/bindings/v8_binding.cc
@@ -81,7 +81,7 @@ int frame_count = stack_trace->GetFrameCount(); for (int i = 0; i < frame_count; ++i) { v8::Local<v8::StackFrame> frame = stack_trace->GetFrame(isolate, i); - v8::Local<v8::String> script_name = frame->GetScriptNameOrSourceURL(); + v8::Local<v8::String> script_name = frame->GetScriptName(); if (script_name.IsEmpty() || !script_name->Length()) continue; String url = ToCoreString(script_name);
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 4326c6b5..c9d2ace6 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -3221,14 +3221,17 @@ # virtual/css-highlight-overlay-painting/ crbug.com/1295264 virtual/css-highlight-overlay-painting/external/wpt/css/css-highlight-api/painting/custom-highlight-painting-overlapping-highlights-001.html [ Failure ] crbug.com/1295264 virtual/css-highlight-overlay-painting/external/wpt/css/css-highlight-api/painting/custom-highlight-painting-overlapping-highlights-002.html [ Failure ] -crbug.com/1147859 [ Mac11 ] virtual/css-highlight-overlay-painting/external/wpt/css/css-highlight-api/painting/custom-highlight-painting-text-decoration-001.html [ Failure ] -crbug.com/1147859 virtual/css-highlight-overlay-painting/wpt_internal/css/css-pseudo/grammar-error-color-001.html [ Pass ] +crbug.com/1147859 virtual/css-highlight-overlay-painting/external/wpt/css/css-highlight-api/painting/custom-highlight-painting-text-decoration-001.html [ Failure ] +crbug.com/1147859 virtual/css-highlight-overlay-painting/wpt_internal/css/css-pseudo/grammar-error-color-001.html [ Failure ] crbug.com/1147859 virtual/css-highlight-overlay-painting/wpt_internal/css/css-pseudo/grammar-error-color-002.html [ Pass ] -crbug.com/1147859 virtual/css-highlight-overlay-painting/wpt_internal/css/css-pseudo/spelling-error-color-001.html [ Pass ] +crbug.com/1147859 virtual/css-highlight-overlay-painting/wpt_internal/css/css-pseudo/grammar-error-color-003.html [ Failure ] +crbug.com/1147859 virtual/css-highlight-overlay-painting/wpt_internal/css/css-pseudo/grammar-error-color-dynamic-002.html [ Failure ] +crbug.com/1147859 virtual/css-highlight-overlay-painting/wpt_internal/css/css-pseudo/spelling-error-color-001.html [ Failure ] crbug.com/1147859 virtual/css-highlight-overlay-painting/wpt_internal/css/css-pseudo/spelling-error-color-002.html [ Pass ] +crbug.com/1147859 virtual/css-highlight-overlay-painting/wpt_internal/css/css-pseudo/spelling-error-color-003.html [ Failure ] +crbug.com/1147859 virtual/css-highlight-overlay-painting/wpt_internal/css/css-pseudo/spelling-error-color-dynamic-002.html [ Failure ] crbug.com/1147859 virtual/css-highlight-overlay-painting/external/wpt/css/css-highlight-api/painting/custom-highlight-painting-001.html [ Pass ] crbug.com/1147859 virtual/css-highlight-overlay-painting/external/wpt/css/css-highlight-api/painting/custom-highlight-painting-002.html [ Pass ] -crbug.com/1147859 virtual/css-highlight-overlay-painting/external/wpt/css/css-highlight-api/painting/custom-highlight-painting-003.html [ Pass ] crbug.com/1147859 virtual/css-highlight-overlay-painting/external/wpt/css/css-highlight-api/painting/custom-highlight-painting-005.html [ Pass ] crbug.com/1147859 virtual/css-highlight-overlay-painting/external/wpt/css/css-highlight-api/painting/custom-highlight-painting-006.html [ Pass ] crbug.com/1147859 virtual/css-highlight-overlay-painting/external/wpt/css/css-highlight-api/painting/custom-highlight-painting-007.html [ Pass ] @@ -3250,9 +3253,7 @@ crbug.com/1147859 virtual/css-highlight-overlay-painting/external/wpt/css/css-highlight-api/painting/custom-highlight-painting-iframe-004.html [ Pass ] crbug.com/1147859 virtual/css-highlight-overlay-painting/external/wpt/css/css-highlight-api/painting/custom-highlight-painting-iframe-005.html [ Pass ] crbug.com/1147859 virtual/css-highlight-overlay-painting/external/wpt/css/css-highlight-api/painting/custom-highlight-painting-iframe-006.html [ Pass ] -crbug.com/1147859 virtual/css-highlight-overlay-painting/external/wpt/css/css-highlight-api/painting/custom-highlight-painting-inheritance-001.html [ Pass ] -crbug.com/1147859 virtual/css-highlight-overlay-painting/external/wpt/css/css-highlight-api/painting/custom-highlight-painting-inheritance-002.html [ Pass ] -crbug.com/1147859 virtual/css-highlight-overlay-painting/external/wpt/css/css-highlight-api/painting/custom-highlight-painting-inheritance-003.html [ Pass ] +crbug.com/1147859 virtual/css-highlight-overlay-painting/external/wpt/css/css-highlight-api/painting/custom-highlight-painting-inheritance-003.html [ Failure ] crbug.com/1147859 virtual/css-highlight-overlay-painting/external/wpt/css/css-highlight-api/painting/custom-highlight-painting-invalidation-001.html [ Pass ] crbug.com/1147859 virtual/css-highlight-overlay-painting/external/wpt/css/css-highlight-api/painting/custom-highlight-painting-invalidation-002.html [ Pass ] crbug.com/1147859 virtual/css-highlight-overlay-painting/external/wpt/css/css-highlight-api/painting/custom-highlight-painting-invalidation-003.html [ Pass ] @@ -3270,20 +3271,13 @@ crbug.com/1147859 virtual/css-highlight-overlay-painting/external/wpt/css/css-highlight-api/painting/custom-highlight-painting-staticrange-006.html [ Pass ] crbug.com/1147859 virtual/css-highlight-overlay-painting/external/wpt/css/css-highlight-api/painting/custom-highlight-painting-staticrange-007.html [ Pass ] crbug.com/1147859 virtual/css-highlight-overlay-painting/external/wpt/css/css-highlight-api/painting/custom-highlight-painting-text-shadow.tentative.html [ Pass ] -crbug.com/1147859 [ Mac11 ] virtual/css-highlight-overlay-painting/external/wpt/css/css-pseudo/highlight-painting-003.html [ Failure ] -crbug.com/1147859 [ Win ] virtual/css-highlight-overlay-painting/external/wpt/css/css-pseudo/highlight-painting-003.html [ Pass ] -crbug.com/1147859 [ Linux ] virtual/css-highlight-overlay-painting/external/wpt/css/css-pseudo/highlight-painting-003.html [ Pass ] -crbug.com/1147859 [ Fuchsia ] virtual/css-highlight-overlay-painting/external/wpt/css/css-pseudo/highlight-painting-003.html [ Pass ] -crbug.com/1147859 virtual/css-highlight-overlay-painting/external/wpt/css/css-pseudo/highlight-painting-currentcolor-003.html [ Pass ] -crbug.com/1147859 virtual/css-highlight-overlay-painting/external/wpt/css/css-pseudo/highlight-painting-currentcolor-004.html [ Pass ] crbug.com/1147859 virtual/css-highlight-overlay-painting/external/wpt/css/css-pseudo/target-text-006.html [ Pass ] -crbug.com/1147859 virtual/css-highlight-overlay-painting/external/wpt/css/css-pseudo/target-text-text-decoration-001.html [ Pass ] -crbug.com/1251193 crbug.com/1024156 virtual/css-highlight-overlay-painting/wpt_internal/css/css-pseudo/grammar-error-color-dynamic-001.html [ Failure ] -crbug.com/1251193 crbug.com/1024156 virtual/css-highlight-overlay-painting/wpt_internal/css/css-pseudo/grammar-error-color-dynamic-003.html [ Failure ] -crbug.com/1251193 crbug.com/1024156 virtual/css-highlight-overlay-painting/wpt_internal/css/css-pseudo/grammar-error-color-dynamic-004.html [ Failure ] -crbug.com/1251193 crbug.com/1024156 virtual/css-highlight-overlay-painting/wpt_internal/css/css-pseudo/spelling-error-color-dynamic-001.html [ Failure ] -crbug.com/1251193 crbug.com/1024156 virtual/css-highlight-overlay-painting/wpt_internal/css/css-pseudo/spelling-error-color-dynamic-003.html [ Failure ] -crbug.com/1251193 crbug.com/1024156 virtual/css-highlight-overlay-painting/wpt_internal/css/css-pseudo/spelling-error-color-dynamic-004.html [ Failure ] +crbug.com/1147859 virtual/css-highlight-overlay-painting/wpt_internal/css/css-pseudo/grammar-error-color-dynamic-001.html [ Pass ] +crbug.com/1147859 virtual/css-highlight-overlay-painting/wpt_internal/css/css-pseudo/grammar-error-color-dynamic-003.html [ Pass ] +crbug.com/1147859 virtual/css-highlight-overlay-painting/wpt_internal/css/css-pseudo/grammar-error-color-dynamic-004.html [ Pass ] +crbug.com/1147859 virtual/css-highlight-overlay-painting/wpt_internal/css/css-pseudo/spelling-error-color-dynamic-001.html [ Pass ] +crbug.com/1147859 virtual/css-highlight-overlay-painting/wpt_internal/css/css-pseudo/spelling-error-color-dynamic-003.html [ Pass ] +crbug.com/1147859 virtual/css-highlight-overlay-painting/wpt_internal/css/css-pseudo/spelling-error-color-dynamic-004.html [ Pass ] crbug.com/825270 external/wpt/payment-request/delegate-request.https.sub.html [ Failure ] crbug.com/1105958 external/wpt/payment-request/payment-is-showing.https.html [ Failure Timeout ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 270fff6..f11bbb4 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -1182,10 +1182,7 @@ "bases": [ "external/wpt/css/css-pseudo", "wpt_internal/css/css-pseudo", - "external/wpt/css/css-highlight-api", - "paint/markers/inline_spelling_markers.html", - "paint/markers/inline-spelling-markers-hidpi.html", - "paint/markers/inline-spelling-markers-hidpi-composited.html" + "external/wpt/css/css-highlight-api" ], "args": ["--enable-blink-features=HighlightOverlayPainting"] },
diff --git a/third_party/blink/web_tests/external/PRESUBMIT.py b/third_party/blink/web_tests/external/PRESUBMIT.py index 473de608..eda75ea 100644 --- a/third_party/blink/web_tests/external/PRESUBMIT.py +++ b/third_party/blink/web_tests/external/PRESUBMIT.py
@@ -8,6 +8,8 @@ for more details about the presubmit API built into depot_tools. """ +import os +import tempfile USE_PYTHON3 = True @@ -56,42 +58,35 @@ if not paths_in_wpt: return [] - # When running git cl presubmit --all this presubmit may be asked to check - # ~65,000 files, leading to a command line that is over 7,000,000 characters. - # This goes past the Windows 8191 character cmd.exe limit and causes cryptic - # failures. To avoid these we break the command up into smaller pieces. The - # non-Windows limit is chosen so that the code that splits up commands will - # get some exercise on other platforms. - # Depending on how long the command is on Windows the error may be: - # The command line is too long. - # Or it may be: - # OSError: Execution failed with error: [WinError 206] The filename or - # extension is too long. - # I suspect that the latter error comes from CreateProcess hitting its 32768 - # character limit. - files_per_command = 25 if input_api.is_windows else 1000 - results = [] - for i in range(0, len(paths_in_wpt), files_per_command): - args = [ - python3_command(input_api), - linter_path, - 'lint', - '--repo-root=%s' % wpt_path, - '--ignore-glob=*-expected.txt', - '--ignore-glob=*DIR_METADATA', - '--ignore-glob=*OWNERS', - ] + paths_in_wpt[i:i + files_per_command] + # We have to set delete=False and then let the object go out of scope so + # that the file can be opened by name on Windows. + with tempfile.NamedTemporaryFile('w+', newline='', delete=False) as f: + for path in paths_in_wpt: + f.write('%s\n' % path) + paths_name = f.name + args = [ + python3_command(input_api), + linter_path, + 'lint', + '--repo-root=%s' % wpt_path, + '--ignore-glob=*-expected.txt', + '--ignore-glob=*DIR_METADATA', + '--ignore-glob=*OWNERS', + '--paths-file=%s' % paths_name, + ] - proc = input_api.subprocess.Popen(args, - stdout=input_api.subprocess.PIPE, - stderr=input_api.subprocess.PIPE) - stdout, stderr = proc.communicate() + proc = input_api.subprocess.Popen(args, + stdout=input_api.subprocess.PIPE, + stderr=input_api.subprocess.PIPE) + stdout, stderr = proc.communicate() + os.remove(paths_name) - if proc.returncode != 0: - results.append( - output_api.PresubmitError('wpt lint failed:', - long_text=stdout + stderr)) - return results + if proc.returncode != 0: + return [ + output_api.PresubmitError('wpt lint failed:', + long_text=stdout + stderr) + ] + return [] def _DontModifyIDLFiles(input_api, output_api):
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audiocontext-interface/audiocontext-suspend-resume-expected.txt b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audiocontext-interface/audiocontext-suspend-resume-expected.txt index 4b3708bc..962df08 100644 --- a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audiocontext-interface/audiocontext-suspend-resume-expected.txt +++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audiocontext-interface/audiocontext-suspend-resume-expected.txt
@@ -16,13 +16,13 @@ PASS p2 = offlineContext.resume() did not throw an exception. PASS p2 instanceof Promise is true. PASS After resume, offlineContext.state is equal to suspended. -PASS p2 rejected correctly with InvalidStateError: cannot resume an offline context that has not started. +PASS p2 rejected correctly with InvalidStateError: Failed to execute 'resume' on 'OfflineAudioContext': cannot resume an offline context that has not started. PASS < [test-resume] All assertions passed. (total 4 assertions) PASS > [test-after-close] Test state after context closed PASS p3 = offlineContext.startRendering() did not throw an exception. PASS After close, offlineContext.state is equal to closed. PASS offlineContext.suspend() rejected correctly with TypeError: Failed to execute 'suspend' on 'OfflineAudioContext': 1 argument required, but only 0 present.. -PASS offlineContext.resume() rejected correctly with InvalidStateError: cannot resume an offline context that has not started. +PASS offlineContext.resume() rejected correctly with InvalidStateError: Failed to execute 'resume' on 'OfflineAudioContext': cannot resume an offline context that has not started. PASS < [test-after-close] All assertions passed. (total 4 assertions) PASS > [resume-running-context] Test resuming a running context PASS Create online context did not throw an exception.
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/issues/deprecation-issue-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/deprecation-issue-expected.txt index bcfc4b1..026cb6f 100644 --- a/third_party/blink/web_tests/http/tests/inspector-protocol/issues/deprecation-issue-expected.txt +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/deprecation-issue-expected.txt
@@ -7,15 +7,15 @@ affectedFrame : { frameId : <string> } - deprecationType : RangeExpand - message : 'Range.expand()' is deprecated. Please use 'Selection.modify()' instead. + deprecationType : + message : sourceCodeLocation : { columnNumber : 24 lineNumber : 0 scriptId : <string> url : } - type : Untranslated + type : RangeExpand } } }
diff --git a/third_party/blink/web_tests/http/tests/origin_trials/resources/inject-third-party-token-sourcemapped.js b/third_party/blink/web_tests/http/tests/origin_trials/resources/inject-third-party-token-sourcemapped.js new file mode 100644 index 0000000..2da2492 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/origin_trials/resources/inject-third-party-token-sourcemapped.js
@@ -0,0 +1,12 @@ +// Generate this token with the given commands: +// generate_token.py http://localhost:8000 FrobulateThirdParty --version 3 --is-third-party --expire-timestamp=2000000000 +const third_party_token = "A2sI42GtBtrjupmY4DvSO3OlTDHgLuhXEy+To7Qm3s9WlW3wI+x/26MeVUQ4iczVMpM+IlbENy/1+BJkGtEzkAYAAABxeyJvcmlnaW4iOiAiaHR0cDovL2xvY2FsaG9zdDo4MDAwIiwgImlzVGhpcmRQYXJ0eSI6IHRydWUsICJmZWF0dXJlIjogIkZyb2J1bGF0ZVRoaXJkUGFydHkiLCAiZXhwaXJ5IjogMjAwMDAwMDAwMH0="; + +// This token is for "localhost", which is a different origin from the +// "127.0.0.1" origin used to run all http tests. +const tokenElement = document.createElement('meta'); +tokenElement.httpEquiv = 'origin-trial'; +tokenElement.content = third_party_token; +document.head.appendChild(tokenElement); + +//# sourceURL=debugging-url
diff --git a/third_party/blink/web_tests/http/tests/origin_trials/third-party-injected-sourcemapped-script.html b/third_party/blink/web_tests/http/tests/origin_trials/third-party-injected-sourcemapped-script.html new file mode 100644 index 0000000..a5f8aab4 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/origin_trials/third-party-injected-sourcemapped-script.html
@@ -0,0 +1,13 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test that trial is enabled by third-party token, injected by a source-mapped classic script</title> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<script src="resources/origintrials.js"></script> +<script src="http://localhost:8000/origin_trials/resources/inject-third-party-token-sourcemapped.js"></script> +<script> + // The trial is enabled, by the third party token added in + // inject-third-party-token-sourcemapped.js, which is an external classic script, served + // from a different origin. + expect_success_third_party(); +</script>
diff --git a/third_party/blink/web_tests/media/remoteplayback/prompt-twice-throws.html b/third_party/blink/web_tests/media/remoteplayback/prompt-twice-throws.html index 284c422..f0fdffd9 100644 --- a/third_party/blink/web_tests/media/remoteplayback/prompt-twice-throws.html +++ b/third_party/blink/web_tests/media/remoteplayback/prompt-twice-throws.html
@@ -43,7 +43,7 @@ test.unreached_func(), test.step_func_done(function(e) { assert_equals(e.name, 'OperationError'); - assert_equals(e.message, 'A prompt is already being shown for this media element.'); + assert_equals(e.message, 'Failed to execute \'prompt\' on \'RemotePlayback\': A prompt is already being shown for this media element.'); })); btn.onclick = null; }
diff --git a/third_party/blink/web_tests/media/remoteplayback/watch-availability-throws-low-end-device.html b/third_party/blink/web_tests/media/remoteplayback/watch-availability-throws-low-end-device.html index 56cbf25..9c1594ea 100644 --- a/third_party/blink/web_tests/media/remoteplayback/watch-availability-throws-low-end-device.html +++ b/third_party/blink/web_tests/media/remoteplayback/watch-availability-throws-low-end-device.html
@@ -22,7 +22,7 @@ t.step_func_done(function(e) { assert_equals(e.name, 'NotSupportedError'); assert_equals(e.message, - 'Availability monitoring is not supported on this device.'); + 'Failed to execute \'watchAvailability\' on \'RemotePlayback\': Availability monitoring is not supported on this device.'); internals.setIsLowEndDevice(false); })); }, 'Test that watchAvailability() throws on low-end devices.');
diff --git a/third_party/blink/web_tests/platform/mac/transforms/matrix-02-expected.png b/third_party/blink/web_tests/platform/mac/transforms/matrix-02-expected.png deleted file mode 100644 index de91d28c..0000000 --- a/third_party/blink/web_tests/platform/mac/transforms/matrix-02-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/transforms/matrix-02-expected.png b/third_party/blink/web_tests/platform/win/transforms/matrix-02-expected.png deleted file mode 100644 index db489a6..0000000 --- a/third_party/blink/web_tests/platform/win/transforms/matrix-02-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/transforms/matrix-02-expected.png b/third_party/blink/web_tests/platform/win7/transforms/matrix-02-expected.png deleted file mode 100644 index 6cda17ad..0000000 --- a/third_party/blink/web_tests/platform/win7/transforms/matrix-02-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/transforms/matrix-02-expected.png b/third_party/blink/web_tests/transforms/matrix-02-expected.png similarity index 100% rename from third_party/blink/web_tests/platform/linux/transforms/matrix-02-expected.png rename to third_party/blink/web_tests/transforms/matrix-02-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/wpt_internal/payments/resources/payment-request-mock.js b/third_party/blink/web_tests/wpt_internal/payments/resources/payment-request-mock.js index 1da6ce7..79bceb8c 100644 --- a/third_party/blink/web_tests/wpt_internal/payments/resources/payment-request-mock.js +++ b/third_party/blink/web_tests/wpt_internal/payments/resources/payment-request-mock.js
@@ -22,6 +22,7 @@ } show() {} + showNew() {} updateWith(details) {} onPaymentDetailsNotUpdated() {} abort() {}
diff --git a/third_party/node/README.chromium b/third_party/node/README.chromium index b823d6acf..78a0ad1 100644 --- a/third_party/node/README.chromium +++ b/third_party/node/README.chromium
@@ -38,7 +38,7 @@ Name: Typescript Compiler Short Name: typescript URL: https://www.npmjs.com/package/typescript -Version: 4.5.4 +Version: 4.6.3 License: Apache 2.0 Security Critical: No. The compiler is not shipped with Chrome but code compiled using it is.
diff --git a/third_party/node/node_modules.tar.gz.sha1 b/third_party/node/node_modules.tar.gz.sha1 index 9544316..984af9cc 100644 --- a/third_party/node/node_modules.tar.gz.sha1 +++ b/third_party/node/node_modules.tar.gz.sha1
@@ -1 +1 @@ -df473d4b1ab26ce6b669007521f2ffb8ff99f9d7 +080eea1a73a366746aa456925538e0068e307562
diff --git a/third_party/node/package-lock.json b/third_party/node/package-lock.json index 9aca5b1d..eb343cc 100644 --- a/third_party/node/package-lock.json +++ b/third_party/node/package-lock.json
@@ -30,7 +30,7 @@ "rollup": "2.58.0", "svgo": "1.2.0", "terser": "5.3.3", - "typescript": "4.5.5" + "typescript": "4.6.3" } }, "node_modules/@babel/code-frame": { @@ -3980,9 +3980,9 @@ } }, "node_modules/typescript": { - "version": "4.5.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", - "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==", + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", + "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -7159,9 +7159,9 @@ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" }, "typescript": { - "version": "4.5.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", - "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==" + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", + "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==" }, "typical": { "version": "2.6.1",
diff --git a/third_party/node/package.json b/third_party/node/package.json index 4f331004..01a41749 100644 --- a/third_party/node/package.json +++ b/third_party/node/package.json
@@ -25,6 +25,6 @@ "rollup": "2.58.0", "svgo": "1.2.0", "terser": "5.3.3", - "typescript": "4.5.5" + "typescript": "4.6.3" } }
diff --git a/third_party/wayland-protocols/unstable/text-input/text-input-extension-unstable-v1.xml b/third_party/wayland-protocols/unstable/text-input/text-input-extension-unstable-v1.xml index 5b777b4..be5958c 100644 --- a/third_party/wayland-protocols/unstable/text-input/text-input-extension-unstable-v1.xml +++ b/third_party/wayland-protocols/unstable/text-input/text-input-extension-unstable-v1.xml
@@ -24,7 +24,7 @@ DEALINGS IN THE SOFTWARE. </copyright> - <interface name="zcr_text_input_extension_v1" version="1"> + <interface name="zcr_text_input_extension_v1" version="2"> <description summary="extends text_input to support richer operations"> Allows a text_input to sends more variation of operations to support richer features, such as set_preedit_region. @@ -54,9 +54,10 @@ <arg name="id" type="new_id" interface="zcr_extended_text_input_v1"/> <arg name="text_input" type="object" interface="zwp_text_input_v1"/> </request> + </interface> - <interface name="zcr_extended_text_input_v1" version="1"> + <interface name="zcr_extended_text_input_v1" version="2"> <description summary="extension of text_input protocol"> The zcr_extended_text_input_v1 interface extends the text_input interface to support more rich operations on text_input. @@ -82,5 +83,91 @@ <arg name="length" type="uint" /> </event> + <!-- Version 2 --> + + <enum name="input_type" since="2"> + <description summary="Chrome's TextInputType"> + Wayland has its own input-type support, which is + zwp_text_input::content_purpose. However, it is not rich enough to + represent all Chrome's input types. This enum is introduced to keep + all entries so exo can understand it without any information loss. + See TextInputType's description for details about each entry. + </description> + <entry name="none" value="0" /> + <entry name="text" value="1" /> + <entry name="password" value="2" /> + <entry name="search" value="3" /> + <entry name="email" value="4" /> + <entry name="number" value="5" /> + <entry name="telephone" value="6" /> + <entry name="url" value="7" /> + <entry name="date" value="8" /> + <entry name="date_time" value="9" /> + <entry name="date_time_local" value="10" /> + <entry name="month" value="11" /> + <entry name="time" value="12" /> + <entry name="week" value="13" /> + <entry name="text_area" value="14" /> + <entry name="content_editable" value="15" /> + <entry name="date_time_field" value="16" /> + <entry name="null" value="17" /> + </enum> + + <enum name="input_mode" since="2"> + <description summary="Chrome's TextInputMode"> + Similar to input_type defined above, this keeps Chrome's TextInputMode. + See TextInputMode's description for details for each entry. + </description> + <entry name="default" value="0" /> + <entry name="none" value="1" /> + <entry name="text" value="2" /> + <entry name="tel" value="3" /> + <entry name="url" value="4" /> + <entry name="email" value="5" /> + <entry name="numeric" value="6" /> + <entry name="decimal" value="7" /> + <entry name="search" value="8" /> + </enum> + + <enum name="input_flags" since="2"> + <description summary="Chrome's TextInputFlags"> + Similar to input_type defined above, this keeps Chrome's TextInputFlags, + because content_hint is not enough power to represent what Chrome wants. + See TextInputFlags' description for details for each entry. + </description> + <entry name="none" value="0" /> + <entry name="autocomplete_on" value="1 << 0" /> + <entry name="autocomplete_off" value="1 << 1" /> + <entry name="autocorrect_on" value="1 << 2" /> + <entry name="autocorrect_off" value="1 << 3" /> + <entry name="spellcheck_on" value="1 << 4" /> + <entry name="spellcheck_off" value="1 << 5" /> + <entry name="autocapitalize_none" value="1 << 6" /> + <entry name="autocapitalize_characters" value="1 << 7" /> + <entry name="autocapitalize_words" value="1 << 8" /> + <entry name="autocapitalize_sentences" value="1 << 9" /> + <entry name="has_been_password" value="1 << 10" /> + </enum> + + <enum name="learning_mode" since="2"> + <description summary="Whether IME is allowed to learn" /> + <entry name="disabled" value="0" /> + <entry name="enabled" value="1" /> + </enum> + + <request name="set_input_type" since="2"> + <description summary="Sets input type, mode and flags together"> + In wayland, there's a concept that can be mapped to Chrome's + TextInputType, Mode and Flags. It can be set via + zwp_text_input::set_content_type. However, the variation is not rich + enough to represent Chrome's detailed behavior change. This API can be + used as a replacement of set_content_type. + </description> + <arg name="input_type" type="uint" enum="input_type" /> + <arg name="input_mode" type="uint" enum="input_mode" /> + <arg name="input_flags" type="uint" /> + <arg name="learning_mode" type="uint" enum="learning_mode" /> + </request> + </interface> </protocol>
diff --git a/tools/cast3p/OWNERS b/tools/cast3p/OWNERS index b886434..39eb6fde 100644 --- a/tools/cast3p/OWNERS +++ b/tools/cast3p/OWNERS
@@ -1,4 +1,7 @@ chonggu@google.com mfoltz@google.com riazantsevv@google.com -rwkeane@google.com \ No newline at end of file +rwkeane@google.com + +per-file cast_core.version=chromium-autoroll@skia-public.iam.gserviceaccount.com +per-file runtime.version=chromium-autoroll@skia-public.iam.gserviceaccount.com \ No newline at end of file
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index b3cac13c..43fecfed 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -31280,6 +31280,18 @@ </description> </action> +<action name="TabletTabStrip.UndoCloseTab"> + <owner>gauravjj@google.com</owner> + <owner>skavuluru@google.com</owner> + <owner>twellington@chromium.org</owner> + <owner>clank-large-form-factors@google.com</owner> + <description> + User clicked on the undo close tab snackbar to undo a tab closure on tablet + done from the tab strip. This does not include undo tab closures from the + grid tab switcher. + </description> +</action> + <action name="TabMediaIndicator_Clicked"> <obsolete>Replaced with "TabAlertIndicator_Clicked".</obsolete> <owner>miu@chromium.org</owner>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index a8500fa..5e64066 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -38032,6 +38032,9 @@ <int value="4213" label="DeferredShapingDisabledByPositioned"/> <int value="4214" label="CapabilityDelegationOfFullscreenRequest"/> <int value="4215" label="SerialPortForget"/> + <int value="4216" label="CookieHasNotBeenRefreshedIn201To300Days"/> + <int value="4217" label="CookieHasNotBeenRefreshedIn301To350Days"/> + <int value="4218" label="CookieHasNotBeenRefreshedIn351To400Days"/> </enum> <enum name="FeaturePolicyAllowlistType"> @@ -38196,6 +38199,11 @@ <int value="20" label="ThirdPartyCookiesBlocked"/> <int value="21" label="DisabledInSettings"/> <int value="22" label="DisabledInFlags"/> + <int value="23" label="ManifestListHttpNotFound"/> + <int value="24" label="ManifestListNoResponse"/> + <int value="25" label="ManifestListInvalidResponse"/> + <int value="26" label="ManifestNotInManifestList"/> + <int value="27" label="ManifestListTooBig"/> </enum> <enum name="FedCmRevokeStatus"> @@ -63375,6 +63383,7 @@ <int value="3" label="Same-origin subframe vibrate, with user gesture"/> <int value="4" label="Cross-origin subframe vibrate, no user gesture"/> <int value="5" label="Cross-origin subframe vibrate, with user gesture"/> + <int value="6" label="In a fenced frame tree"/> </enum> <enum name="NCNGetActiveNetworkInfoResult">
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml index 0bee1814..a9c2c64f 100644 --- a/tools/metrics/histograms/metadata/ash/histograms.xml +++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -2499,10 +2499,7 @@ <histogram name="Ash.NavigationWidget.AnimationSmoothness{HotseatTransitionType}" - units="%" expires_after="2022-06-02"> -<!-- Name completed by histogram suffixes - name="HotseatTransitionType" --> - + units="%" expires_after="2023-04-20"> <owner>anasalazar@chromium.org</owner> <owner>newcomer@chromium.org</owner> <summary> @@ -2518,7 +2515,7 @@ <histogram name="Ash.NavigationWidget.{NavigationWidgetElement}AnimationSmoothness" - units="%" expires_after="2022-06-02"> + units="%" expires_after="2023-04-20"> <owner>anasalazar@chromium.org</owner> <owner>newcomer@chromium.org</owner> <summary> @@ -4233,8 +4230,9 @@ </histogram> <histogram name="Ash.Wallpaper.CustomLayout" enum="WallpaperLayout" - expires_after="2022-04-24"> - <owner>xdai@chromium.org</owner> + expires_after="2023-04-24"> + <owner>xiaohuic@chromium.org</owner> + <owner>assistive-eng@chromium.org</owner> <summary> The custom wallpaper layout type. Recorded when the user sets a new custom wallpaper or changes the existing custom wallpaper's layout.
diff --git a/tools/metrics/histograms/metadata/commerce/histograms.xml b/tools/metrics/histograms/metadata/commerce/histograms.xml index ecfd079..fd622b3 100644 --- a/tools/metrics/histograms/metadata/commerce/histograms.xml +++ b/tools/metrics/histograms/metadata/commerce/histograms.xml
@@ -296,7 +296,7 @@ <histogram name="Commerce.PriceDrops.{TabUsageStatus}{LocationIdentifier}.ContainsPrice" - enum="BooleanContainsPrice" expires_after="2022-06-07"> + enum="BooleanContainsPrice" expires_after="2023-04-25"> <owner>davidjm@chromium.org</owner> <owner>ayman@chromium.org</owner> <owner>dtrainor@chromium.org</owner> @@ -312,7 +312,7 @@ <histogram name="Commerce.PriceDrops.{TabUsageStatus}{LocationIdentifier}.ContainsPriceDrop" - enum="BooleanContainsPriceDrop" expires_after="2022-06-07"> + enum="BooleanContainsPriceDrop" expires_after="2023-04-25"> <owner>davidjm@chromium.org</owner> <owner>ayman@chromium.org</owner> <owner>dtrainor@chromium.org</owner> @@ -329,7 +329,7 @@ <histogram name="Commerce.PriceDrops.{TabUsageStatus}{LocationIdentifier}.IsProductDetailPage" - enum="BooleanIsProductDetailPage" expires_after="2022-06-07"> + enum="BooleanIsProductDetailPage" expires_after="2023-04-25"> <owner>davidjm@chromium.org</owner> <owner>ayman@chromium.org</owner> <owner>dtrainor@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/cookie/histograms.xml b/tools/metrics/histograms/metadata/cookie/histograms.xml index 7e47225..01f9cd1 100644 --- a/tools/metrics/histograms/metadata/cookie/histograms.xml +++ b/tools/metrics/histograms/metadata/cookie/histograms.xml
@@ -176,6 +176,17 @@ </token> </histogram> +<histogram name="Cookie.DaysSinceRefreshForRetrieval" units="days" + expires_after="M114"> + <owner>arichiv@chromium.org</owner> + <owner>bingler@chromium.org</owner> + <summary> + Number of days since a cookie was updated, collected when cookies are loaded + into memory at browser start. This is used to track how many cookies are in + danger of expiring due to the proposed 400 day maximum expiration day limit. + </summary> +</histogram> + <histogram name="Cookie.DomainHasNonASCII" enum="Boolean" expires_after="2023-01-01"> <owner>johannhof@chromium.org</owner> @@ -201,7 +212,7 @@ </histogram> <histogram name="Cookie.ExpirationDuration400DaysGT" units="days" - expires_after="M104"> + expires_after="M114"> <owner>arichiv@chromium.org</owner> <owner>bingler@chromium.org</owner> <summary> @@ -211,7 +222,7 @@ </histogram> <histogram name="Cookie.ExpirationDuration400DaysLTE" units="days" - expires_after="2022-09-25"> + expires_after="M114"> <owner>arichiv@chromium.org</owner> <owner>bingler@chromium.org</owner> <summary> @@ -221,14 +232,14 @@ </histogram> <histogram name="Cookie.ExpirationDurationMinutesNonSecure" units="minutes" - expires_after="2022-09-18"> + expires_after="M114"> <owner>kaustubhag@chromium.org</owner> <owner>bingler@chromium.org</owner> <summary>Number of minutes until non-Secure cookie expires when set.</summary> </histogram> <histogram name="Cookie.ExpirationDurationMinutesSecure" units="minutes" - expires_after="2022-09-18"> + expires_after="M114"> <owner>kaustubhag@chromium.org</owner> <owner>bingler@chromium.org</owner> <summary>Number of minutes until Secure cookie expires when set.</summary>
diff --git a/tools/perf/benchmarks/system_health_load_tests_smoke_test.py b/tools/perf/benchmarks/system_health_load_tests_smoke_test.py index 3e32000..59e98fe7 100755 --- a/tools/perf/benchmarks/system_health_load_tests_smoke_test.py +++ b/tools/perf/benchmarks/system_health_load_tests_smoke_test.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # 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.
diff --git a/tools/perf/contrib/cluster_telemetry/analyze_metrics_ct.py b/tools/perf/contrib/cluster_telemetry/analyze_metrics_ct.py index c3a48e82..8343b3e 100755 --- a/tools/perf/contrib/cluster_telemetry/analyze_metrics_ct.py +++ b/tools/perf/contrib/cluster_telemetry/analyze_metrics_ct.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # 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.
diff --git a/tools/perf/contrib/cluster_telemetry/ct_benchmarks_util.py b/tools/perf/contrib/cluster_telemetry/ct_benchmarks_util.py index 1a71765..cb24cad 100755 --- a/tools/perf/contrib/cluster_telemetry/ct_benchmarks_util.py +++ b/tools/perf/contrib/cluster_telemetry/ct_benchmarks_util.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # Copyright 2015 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/tools/perf/contrib/orderfile/orderfile_unittest.py b/tools/perf/contrib/orderfile/orderfile_unittest.py index 2689c39..a0a0860f 100755 --- a/tools/perf/contrib/orderfile/orderfile_unittest.py +++ b/tools/perf/contrib/orderfile/orderfile_unittest.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # Copyright 2015 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/tools/perf/core/perf_data_generator.py b/tools/perf/core/perf_data_generator.py index 94d7b39d..36d48e5 100755 --- a/tools/perf/core/perf_data_generator.py +++ b/tools/perf/core/perf_data_generator.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # Copyright 2016 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.
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index aa8a5338a..af849025 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -13,8 +13,8 @@ "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux_arm/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell" }, "mac": { - "hash": "2c899375ec8adeba3c55112c50c9dcd1edc97bb4", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/bbe5831b282629a91661412ca529003223f00f6d/trace_processor_shell" + "hash": "c1fef49cb3394d3a226906dd82797cb84e8140c8", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/0b75597e27aff59a918baab6cc6bc0a3db00ce86/trace_processor_shell" }, "mac_arm64": { "hash": "e1ad4861384b06d911a65f035317914b8cc975c6",
diff --git a/tools/perf/core/perfetto_binary_roller/roll_trace_processor b/tools/perf/core/perfetto_binary_roller/roll_trace_processor index f3872fa..acf52e7 100755 --- a/tools/perf/core/perfetto_binary_roller/roll_trace_processor +++ b/tools/perf/core/perfetto_binary_roller/roll_trace_processor
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # 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.
diff --git a/tools/perf/core/perfetto_binary_roller/update_power_profile.py b/tools/perf/core/perfetto_binary_roller/update_power_profile.py index 3ae7bb72..e3b0125 100755 --- a/tools/perf/core/perfetto_binary_roller/update_power_profile.py +++ b/tools/perf/core/perfetto_binary_roller/update_power_profile.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # 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.
diff --git a/tools/perf/core/results_dashboard.py b/tools/perf/core/results_dashboard.py index 6a44ce48..04566ed 100755 --- a/tools/perf/core/results_dashboard.py +++ b/tools/perf/core/results_dashboard.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # Copyright (c) 2013 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.
diff --git a/tools/perf/core/retrieve_story_timing.py b/tools/perf/core/retrieve_story_timing.py index af9fbd14..80f11550 100755 --- a/tools/perf/core/retrieve_story_timing.py +++ b/tools/perf/core/retrieve_story_timing.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # Copyright 2018 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/tools/perf/core/story_expectation_validator.py b/tools/perf/core/story_expectation_validator.py index 9682d6b..35153f1 100755 --- a/tools/perf/core/story_expectation_validator.py +++ b/tools/perf/core/story_expectation_validator.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # 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. @@ -32,11 +32,11 @@ def is_desktop_tag(tag): - return any(tag.lower().startswith(t) for t in DESKTOP_PREFIXES) + return any(tag.lower().startswith(t) for t in DESKTOP_PREFIXES) def is_mobile_tag(tag): - return any(tag.lower().startswith(t) for t in MOBILE_PREFIXES) + return any(tag.lower().startswith(t) for t in MOBILE_PREFIXES) def validate_story_names(benchmarks, test_expectations):
diff --git a/tools/perf/core/tbmv3/run_tbmv3_metric.py b/tools/perf/core/tbmv3/run_tbmv3_metric.py index bee2672..d119360 100755 --- a/tools/perf/core/tbmv3/run_tbmv3_metric.py +++ b/tools/perf/core/tbmv3/run_tbmv3_metric.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # 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.
diff --git a/tools/perf/core/upload_results_to_perf_dashboard.py b/tools/perf/core/upload_results_to_perf_dashboard.py index f579752dc..9774d19 100755 --- a/tools/perf/core/upload_results_to_perf_dashboard.py +++ b/tools/perf/core/upload_results_to_perf_dashboard.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # Copyright 2016 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.
diff --git a/tools/perf/diagnose_test_failure b/tools/perf/diagnose_test_failure index 58aad53..50aea09 100755 --- a/tools/perf/diagnose_test_failure +++ b/tools/perf/diagnose_test_failure
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # Copyright 2016 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.
diff --git a/tools/perf/download_proto_trace.py b/tools/perf/download_proto_trace.py index 1e68758..c7b4079 100755 --- a/tools/perf/download_proto_trace.py +++ b/tools/perf/download_proto_trace.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # 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.
diff --git a/tools/perf/export_csv b/tools/perf/export_csv index bd87d348..9e9d586 100755 --- a/tools/perf/export_csv +++ b/tools/perf/export_csv
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # Copyright 2018 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/tools/perf/fetch_benchmark_deps.py b/tools/perf/fetch_benchmark_deps.py index 054ed72..aea2a07 100755 --- a/tools/perf/fetch_benchmark_deps.py +++ b/tools/perf/fetch_benchmark_deps.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # Copyright 2015 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/tools/perf/find_dependencies b/tools/perf/find_dependencies index 5a0ed47..65361de 100755 --- a/tools/perf/find_dependencies +++ b/tools/perf/find_dependencies
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # 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.
diff --git a/tools/perf/flakiness_cli b/tools/perf/flakiness_cli index 86f4483..2d1eb007 100755 --- a/tools/perf/flakiness_cli +++ b/tools/perf/flakiness_cli
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # Copyright 2018 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/tools/perf/generate_legacy_perf_dashboard_json.py b/tools/perf/generate_legacy_perf_dashboard_json.py index 82b13c4..b8c52f5 100755 --- a/tools/perf/generate_legacy_perf_dashboard_json.py +++ b/tools/perf/generate_legacy_perf_dashboard_json.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # Copyright 2016 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.
diff --git a/tools/perf/generate_legacy_perf_dashboard_json_unittest.py b/tools/perf/generate_legacy_perf_dashboard_json_unittest.py index 2e15c17a..d0674717 100755 --- a/tools/perf/generate_legacy_perf_dashboard_json_unittest.py +++ b/tools/perf/generate_legacy_perf_dashboard_json_unittest.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # Copyright 2016 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.
diff --git a/tools/perf/generate_perf_data b/tools/perf/generate_perf_data index 65e9171..ca1aa86 100755 --- a/tools/perf/generate_perf_data +++ b/tools/perf/generate_perf_data
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # 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.
diff --git a/tools/perf/generate_perf_sharding.py b/tools/perf/generate_perf_sharding.py index d20fa35..5cc4c0f9 100755 --- a/tools/perf/generate_perf_sharding.py +++ b/tools/perf/generate_perf_sharding.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # Copyright 2018 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/tools/perf/list_affected_benchmarks b/tools/perf/list_affected_benchmarks index 6d8d38a..dc297ae 100755 --- a/tools/perf/list_affected_benchmarks +++ b/tools/perf/list_affected_benchmarks
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # Copyright 2013 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.
diff --git a/tools/perf/list_benchmarks b/tools/perf/list_benchmarks index 6a6f7ace..87deb56 100755 --- a/tools/perf/list_benchmarks +++ b/tools/perf/list_benchmarks
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # 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.
diff --git a/tools/perf/page_sets/tough_scheduling_cases/_second_batch_js_generator.py b/tools/perf/page_sets/tough_scheduling_cases/_second_batch_js_generator.py index de6b62385..75e9864 100755 --- a/tools/perf/page_sets/tough_scheduling_cases/_second_batch_js_generator.py +++ b/tools/perf/page_sets/tough_scheduling_cases/_second_batch_js_generator.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # Copyright 2015 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/tools/perf/page_sets/update_webrtc_cases b/tools/perf/page_sets/update_webrtc_cases index 14ea7f3..da57a65 100755 --- a/tools/perf/page_sets/update_webrtc_cases +++ b/tools/perf/page_sets/update_webrtc_cases
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # 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.
diff --git a/tools/perf/pinboard b/tools/perf/pinboard index d9da7e86..97ec21e 100755 --- a/tools/perf/pinboard +++ b/tools/perf/pinboard
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # 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.
diff --git a/tools/perf/process_perf_results.py b/tools/perf/process_perf_results.py index c08a7d83..c5f2d2d 100755 --- a/tools/perf/process_perf_results.py +++ b/tools/perf/process_perf_results.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # Copyright 2018 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/tools/perf/process_perf_results_unittest.py b/tools/perf/process_perf_results_unittest.py index 95b3e993c..1f16652 100755 --- a/tools/perf/process_perf_results_unittest.py +++ b/tools/perf/process_perf_results_unittest.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # Copyright 2018 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/tools/perf/record_wpr b/tools/perf/record_wpr index 1050103..d510c17e 100755 --- a/tools/perf/record_wpr +++ b/tools/perf/record_wpr
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # Copyright 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.
diff --git a/tools/perf/results_processor b/tools/perf/results_processor index 0cc14995..d38d1fd 100755 --- a/tools/perf/results_processor +++ b/tools/perf/results_processor
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # 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.
diff --git a/tools/perf/run_telemetry_tests b/tools/perf/run_telemetry_tests index 0d970e4f..a4b8ed6 100755 --- a/tools/perf/run_telemetry_tests +++ b/tools/perf/run_telemetry_tests
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # Copyright 2016 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.
diff --git a/tools/perf/soundwave b/tools/perf/soundwave index 37224fa3..9e033d5 100755 --- a/tools/perf/soundwave +++ b/tools/perf/soundwave
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # Copyright 2018 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/tools/perf/testdata/dummy_gtest b/tools/perf/testdata/dummy_gtest index 6baa671..fe7039f5 100755 --- a/tools/perf/testdata/dummy_gtest +++ b/tools/perf/testdata/dummy_gtest
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # 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. @@ -13,7 +13,7 @@ import shutil # This is just a random line of output that can be converted into graph_json. -print r"*RESULT clockless_video_playback_vp8: bear_silent.webm= 53.406108056578425 runs/s" +print(r"*RESULT clockless_video_playback_vp8: bear_silent.webm= 53.406108056578425 runs/s") # Simulate trace file generation when "--trace-dir" switch is present. parser = argparse.ArgumentParser() @@ -40,7 +40,7 @@ os.path.join(options.trace_dir, 'dummy_luci_test_result.json'), 'w') as f: f.write(test_result) if options.argument_to_check_that_arguments_work: - print 'Arguments worked!' + print('Arguments worked!') else: - print '--argument-to-check-that-arguments-work was not passed. Failing.' + print('--argument-to-check-that-arguments-work was not passed. Failing.') sys.exit(1)
diff --git a/tools/perf/testdata/fail_and_do_nothing b/tools/perf/testdata/fail_and_do_nothing index 1d7b47b3..7bc9e04 100755 --- a/tools/perf/testdata/fail_and_do_nothing +++ b/tools/perf/testdata/fail_and_do_nothing
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # 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.
diff --git a/tools/perf/update_wpr b/tools/perf/update_wpr index 74d12e1..82c5ee49 100755 --- a/tools/perf/update_wpr +++ b/tools/perf/update_wpr
@@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright 2018 the V8 project authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/tools/perf/validate_perf_json_config b/tools/perf/validate_perf_json_config index 0490aa9..cf2b8fb 100755 --- a/tools/perf/validate_perf_json_config +++ b/tools/perf/validate_perf_json_config
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # Copyright 2018 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/tools/perf/validate_story_expectation_data b/tools/perf/validate_story_expectation_data index 0b218a3f..100bdd0 100755 --- a/tools/perf/validate_story_expectation_data +++ b/tools/perf/validate_story_expectation_data
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # 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.
diff --git a/tools/perf/validate_tbmv3_metric b/tools/perf/validate_tbmv3_metric index 4f919ac8..06440dd 100755 --- a/tools/perf/validate_tbmv3_metric +++ b/tools/perf/validate_tbmv3_metric
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # 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.
diff --git a/tools/perf/validate_wpr_archives b/tools/perf/validate_wpr_archives index d3871851..26edc53 100755 --- a/tools/perf/validate_wpr_archives +++ b/tools/perf/validate_wpr_archives
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # 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.
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn index 3c1aacc2..3b99e84 100644 --- a/ui/base/BUILD.gn +++ b/ui/base/BUILD.gn
@@ -1212,6 +1212,11 @@ "//ui/lottie", ] } + + # If the platform supports wayland, run wayland library unittests, too. + if (is_chromeos_ash || ozone_platform_wayland) { + deps += [ "//ui/base/wayland:unittests" ] + } } if (is_mac) {
diff --git a/ui/base/ime/linux/fake_input_method_context.cc b/ui/base/ime/linux/fake_input_method_context.cc index c2116234..1c8ed77 100644 --- a/ui/base/ime/linux/fake_input_method_context.cc +++ b/ui/base/ime/linux/fake_input_method_context.cc
@@ -35,8 +35,9 @@ const std::u16string& text, const gfx::Range& selection_range) {} -void FakeInputMethodContext::SetContentType(TextInputType input_type, - int input_flags, +void FakeInputMethodContext::SetContentType(TextInputType type, + TextInputMode mode, + uint32_t flags, bool should_do_learning) {} VirtualKeyboardController*
diff --git a/ui/base/ime/linux/fake_input_method_context.h b/ui/base/ime/linux/fake_input_method_context.h index f95f0ad8..c173682 100644 --- a/ui/base/ime/linux/fake_input_method_context.h +++ b/ui/base/ime/linux/fake_input_method_context.h
@@ -28,8 +28,9 @@ void SetCursorLocation(const gfx::Rect& rect) override; void SetSurroundingText(const std::u16string& text, const gfx::Range& selection_range) override; - void SetContentType(TextInputType input_type, - int input_flags, + void SetContentType(TextInputType type, + TextInputMode mode, + uint32_t flags, bool should_do_learning) override; VirtualKeyboardController* GetVirtualKeyboardController() override; };
diff --git a/ui/base/ime/linux/input_method_auralinux.cc b/ui/base/ime/linux/input_method_auralinux.cc index 46f8f37a..1c038741 100644 --- a/ui/base/ime/linux/input_method_auralinux.cc +++ b/ui/base/ime/linux/input_method_auralinux.cc
@@ -369,9 +369,15 @@ text_input_type_ != TEXT_INPUT_TYPE_PASSWORD ? context_.get() : context_simple_.get(); - int flags = client ? client->GetTextInputFlags() : TEXT_INPUT_FLAG_NONE; - context->SetContentType(text_input_type_, flags, - client && client->ShouldDoLearning()); + TextInputMode mode = TEXT_INPUT_MODE_DEFAULT; + int flags = TEXT_INPUT_FLAG_NONE; + bool should_do_learning = false; + if (client) { + mode = client->GetTextInputMode(); + flags = client->GetTextInputFlags(); + should_do_learning = client->ShouldDoLearning(); + } + context->SetContentType(text_input_type_, mode, flags, should_do_learning); } void InputMethodAuraLinux::OnTextInputTypeChanged(TextInputClient* client) {
diff --git a/ui/base/ime/linux/input_method_auralinux_unittest.cc b/ui/base/ime/linux/input_method_auralinux_unittest.cc index f7a8a87..02d80bd 100644 --- a/ui/base/ime/linux/input_method_auralinux_unittest.cc +++ b/ui/base/ime/linux/input_method_auralinux_unittest.cc
@@ -91,7 +91,8 @@ } TextInputType input_type() const { return input_type_; } - int input_flags() const { return input_flags_; } + TextInputMode input_mode() const { return input_mode_; } + uint32_t input_flags() const { return input_flags_; } bool should_do_learning() const { return should_do_learning_; } protected: @@ -161,11 +162,13 @@ TestResult::GetInstance()->RecordAction(base::ASCIIToUTF16(re.str())); } - void SetContentType(TextInputType input_type, - int input_flags, + void SetContentType(TextInputType type, + TextInputMode mode, + uint32_t flags, bool should_do_learning) override { - input_type_ = input_type; - input_flags_ = input_flags; + input_type_ = type; + input_mode_ = mode; + input_flags_ = flags; should_do_learning_ = should_do_learning; } @@ -178,7 +181,8 @@ bool focused_; gfx::Rect cursor_position_; TextInputType input_type_; - int input_flags_; + TextInputMode input_mode_; + uint32_t input_flags_; bool should_do_learning_; };
diff --git a/ui/base/ime/linux/linux_input_method_context.h b/ui/base/ime/linux/linux_input_method_context.h index 708d6c9..3073d32 100644 --- a/ui/base/ime/linux/linux_input_method_context.h +++ b/ui/base/ime/linux/linux_input_method_context.h
@@ -5,10 +5,13 @@ #ifndef UI_BASE_IME_LINUX_LINUX_INPUT_METHOD_CONTEXT_H_ #define UI_BASE_IME_LINUX_LINUX_INPUT_METHOD_CONTEXT_H_ +#include <stdint.h> + #include <string> #include <vector> #include "base/component_export.h" +#include "ui/base/ime/text_input_mode.h" #include "ui/base/ime/text_input_type.h" namespace gfx { @@ -46,8 +49,9 @@ const gfx::Range& selection_range) = 0; // Tells the system IME the content type of the text input client is changed. - virtual void SetContentType(TextInputType input_type, - int input_flags, + virtual void SetContentType(TextInputType type, + TextInputMode mode, + uint32_t flags, bool should_do_learning) = 0; // Resets the context. A client needs to call OnTextInputTypeChanged() again
diff --git a/ui/base/wayland/BUILD.gn b/ui/base/wayland/BUILD.gn new file mode 100644 index 0000000..b2d3f8c --- /dev/null +++ b/ui/base/wayland/BUILD.gn
@@ -0,0 +1,70 @@ +# Copyright 2022 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/chromeos/ui_mode.gni") +import("//build/config/ozone.gni") + +# ash-chrome depends on wayland, since components/exo is wayland compositor. +# If platform supports wayland (as a client), it also depends on wayland. +assert(is_chromeos_ash || ozone_platform_wayland) + +source_set("wayland_input_types_impl") { + sources = [ "wayland_input_types_impl.h" ] + + visibility = [ + ":wayland_client_input_types", + ":wayland_server_input_types", + ] +} + +source_set("wayland_client_input_types") { + sources = [ + "wayland_client_input_types.cc", + "wayland_client_input_types.h", + ] + + public_deps = [ + "//third_party/wayland-protocols:text_input_extension_protocol", + "//third_party/wayland-protocols:text_input_protocol", + "//third_party/wayland:wayland_client", + "//ui/base/ime:text_input_types", + ] + + deps = [ + ":wayland_input_types_impl", + "//base", + ] +} + +source_set("wayland_server_input_types") { + sources = [ + "wayland_server_input_types.cc", + "wayland_server_input_types.h", + ] + + public_deps = [ + "//third_party/abseil-cpp:absl", + "//third_party/wayland-protocols:text_input_extension_protocol", + "//third_party/wayland-protocols:text_input_protocol", + "//third_party/wayland:wayland_server", + "//ui/base/ime:text_input_types", + ] + + deps = [ + ":wayland_input_types_impl", + ] +} + +source_set("unittests") { + testonly = true + + sources = [ "wayland_input_types_unittest.cc" ] + + deps = [ + ":wayland_client_input_types", + ":wayland_server_input_types", + "//testing/gtest", + "//ui/base/ime:text_input_types", + ] +}
diff --git a/ui/base/wayland/OWNERS b/ui/base/wayland/OWNERS new file mode 100644 index 0000000..5bba4a4 --- /dev/null +++ b/ui/base/wayland/OWNERS
@@ -0,0 +1,4 @@ +hidehiko@chromium.org +oshima@chromium.org +rjkroege@chromium.org +yhanada@chromium.org
diff --git a/ui/base/wayland/wayland_client_input_types.cc b/ui/base/wayland/wayland_client_input_types.cc new file mode 100644 index 0000000..7f1f5e0 --- /dev/null +++ b/ui/base/wayland/wayland_client_input_types.cc
@@ -0,0 +1,50 @@ +// Copyright 2022 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 "ui/base/wayland/wayland_client_input_types.h" + +#include "base/check_op.h" +#include "ui/base/wayland/wayland_input_types_impl.h" + +namespace ui::wayland { + +zcr_extended_text_input_v1_input_type ConvertFromTextInputType( + TextInputType text_input_type) { + switch (text_input_type) { +#define MAP_ENTRY(name) \ + case ui::TEXT_INPUT_TYPE_##name: \ + return ZCR_EXTENDED_TEXT_INPUT_V1_INPUT_TYPE_##name; + + MAP_TYPES(MAP_ENTRY) +#undef MAP_ENTRY + } +} + +zcr_extended_text_input_v1_input_mode ConvertFromTextInputMode( + TextInputMode text_input_mode) { + switch (text_input_mode) { +#define MAP_ENTRY(name) \ + case ui::TEXT_INPUT_MODE_##name: \ + return ZCR_EXTENDED_TEXT_INPUT_V1_INPUT_MODE_##name; + + MAP_MODES(MAP_ENTRY) +#undef MAP_ENTRY + } +} + +uint32_t ConvertFromTextInputFlags(uint32_t text_input_flags) { + uint32_t result = 0; + for (auto ui_flag : kAllTextInputFlags) { + if (text_input_flags & ui_flag) { + result |= ConvertFromTextInputFlag(ui_flag); + text_input_flags &= ~ui_flag; + } + } + + // Making sure all the bits are converted. + DCHECK_EQ(text_input_flags, 0u); + return result; +} + +} // namespace ui::wayland
diff --git a/ui/base/wayland/wayland_client_input_types.h b/ui/base/wayland/wayland_client_input_types.h new file mode 100644 index 0000000..faa53931 --- /dev/null +++ b/ui/base/wayland/wayland_client_input_types.h
@@ -0,0 +1,26 @@ +// Copyright 2022 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_WAYLAND_WAYLAND_CLIENT_INPUT_TYPES_H_ +#define UI_BASE_WAYLAND_WAYLAND_CLIENT_INPUT_TYPES_H_ + +#include <text-input-extension-unstable-v1-client-protocol.h> + +#include "ui/base/ime/text_input_flags.h" +#include "ui/base/ime/text_input_mode.h" +#include "ui/base/ime/text_input_type.h" + +namespace ui::wayland { + +zcr_extended_text_input_v1_input_type ConvertFromTextInputType( + TextInputType text_input_type); + +zcr_extended_text_input_v1_input_mode ConvertFromTextInputMode( + TextInputMode text_input_mode); + +uint32_t ConvertFromTextInputFlags(uint32_t text_input_flags); + +} // namespace ui::wayland + +#endif // UI_BASE_WAYLAND_WAYLAND_CLIENT_INPUT_TYPES_H_
diff --git a/ui/base/wayland/wayland_input_types_impl.h b/ui/base/wayland/wayland_input_types_impl.h new file mode 100644 index 0000000..4eb0865 --- /dev/null +++ b/ui/base/wayland/wayland_input_types_impl.h
@@ -0,0 +1,58 @@ +// Copyright 2022 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. + +// This file is designed to be included from wayland_*_input_types.cc only, +// in order to share the mapping rules. +// So please do not use in other places. + +#ifndef UI_BASE_WAYLAND_WAYLAND_INPUT_TYPES_IMPL_H_ +#define UI_BASE_WAYLAND_WAYLAND_INPUT_TYPES_IMPL_H_ + +// List all TextInputType here. +// This is used to create a mapping between TextInputType and Wayland's +// zcr_extended_text_input_v1_input_type. +// If a new entry is added to TextInputType, then corresponding code +// needs to be added to the wayland's extension, ozone/wayland (wayland client), +// and components/exo (wayland compositor). +#define MAP_TYPES(macro) \ + macro(NONE) macro(TEXT) macro(PASSWORD) macro(SEARCH) macro(EMAIL) \ + macro(NUMBER) macro(TELEPHONE) macro(URL) macro(DATE) macro(DATE_TIME) \ + macro(DATE_TIME_LOCAL) macro(MONTH) macro(TIME) macro(WEEK) \ + macro(TEXT_AREA) macro(CONTENT_EDITABLE) macro(DATE_TIME_FIELD) \ + macro(NULL) + +// Similar to MAP_TYPES, list all TextInputMode. See above how to update. +#define MAP_MODES(macro) \ + macro(DEFAULT) macro(NONE) macro(TEXT) macro(TEL) macro(URL) macro(EMAIL) \ + macro(NUMERIC) macro(DECIMAL) macro(SEARCH) + +// Similar to MAP_TYPES, list all TextInputFlags. See above how to update. +#define MAP_FLAGS(macro) \ + macro(NONE) macro(AUTOCOMPLETE_ON) macro(AUTOCOMPLETE_OFF) \ + macro(AUTOCORRECT_ON) macro(AUTOCORRECT_OFF) macro(SPELLCHECK_ON) \ + macro(SPELLCHECK_OFF) macro(AUTOCAPITALIZE_NONE) \ + macro(AUTOCAPITALIZE_CHARACTERS) macro(AUTOCAPITALIZE_WORDS) \ + macro(AUTOCAPITALIZE_SENTENCES) macro(HAS_BEEN_PASSWORD) + +// Note: we assume that the source file including this header implementation +// already includes either text-input-extension-unstable-v1-server-protocol.h +// or text-input-extension-unstable-v1-client-protocol.h. +static inline uint32_t ConvertFromTextInputFlag(ui::TextInputFlags flag) { + switch (flag) { +#define MAP_ENTRY(name) \ + case ui::TEXT_INPUT_FLAG_##name: \ + return ZCR_EXTENDED_TEXT_INPUT_V1_INPUT_FLAGS_##name; + + MAP_FLAGS(MAP_ENTRY) +#undef MAP_ENTRY + } +} + +static inline constexpr ui::TextInputFlags kAllTextInputFlags[] = { +#define MAP_ENTRY(name) ui::TEXT_INPUT_FLAG_##name, + MAP_FLAGS(MAP_ENTRY) +#undef MAP_ENTRY +}; + +#endif // UI_BASE_WAYLAND_WAYLAND_INPUT_TYPES_IMPL_H_
diff --git a/ui/base/wayland/wayland_input_types_unittest.cc b/ui/base/wayland/wayland_input_types_unittest.cc new file mode 100644 index 0000000..c967320 --- /dev/null +++ b/ui/base/wayland/wayland_input_types_unittest.cc
@@ -0,0 +1,39 @@ +// Copyright 2022 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 "testing/gtest/include/gtest/gtest.h" +#include "ui/base/wayland/wayland_client_input_types.h" +#include "ui/base/wayland/wayland_server_input_types.h" + +namespace ui::wayland { + +TEST(WaylandInputTypesTest, TextInputType) { + // Checking that roundtrip does not change the value. + for (int i = 0; i <= TEXT_INPUT_TYPE_MAX; ++i) { + const auto input_type = static_cast<ui::TextInputType>(i); + EXPECT_EQ(input_type, + ConvertToTextInputType(ConvertFromTextInputType(input_type))); + } + + // Passing the invalid value returns nullopt. + constexpr auto kInvalidValue = + static_cast<zcr_extended_text_input_v1_input_type>(0xFFFFFFFF); + EXPECT_FALSE(ConvertToTextInputType(kInvalidValue).has_value()); +} + +TEST(WaylandInputTypesTest, TextInputMode) { + // Checking that roundtrip does not change the value. + for (int i = 0; i <= TEXT_INPUT_MODE_MAX; ++i) { + const auto input_mode = static_cast<ui::TextInputMode>(i); + EXPECT_EQ(input_mode, + ConvertToTextInputMode(ConvertFromTextInputMode(input_mode))); + } + + // Passing the invalid value returns nullopt. + constexpr auto kInvalidValue = + static_cast<zcr_extended_text_input_v1_input_mode>(0xFFFFFFFF); + EXPECT_FALSE(ConvertToTextInputMode(kInvalidValue).has_value()); +} + +} // namespace ui::wayland
diff --git a/ui/base/wayland/wayland_server_input_types.cc b/ui/base/wayland/wayland_server_input_types.cc new file mode 100644 index 0000000..f22f3dc --- /dev/null +++ b/ui/base/wayland/wayland_server_input_types.cc
@@ -0,0 +1,52 @@ +// Copyright 2022 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 "ui/base/wayland/wayland_server_input_types.h" + +#include "ui/base/wayland/wayland_input_types_impl.h" + +namespace ui::wayland { + +absl::optional<TextInputType> ConvertToTextInputType( + zcr_extended_text_input_v1_input_type wayland_input_type) { + switch (wayland_input_type) { +#define MAP_ENTRY(name) \ + case ZCR_EXTENDED_TEXT_INPUT_V1_INPUT_TYPE_##name: \ + return ui::TEXT_INPUT_TYPE_##name; + + MAP_TYPES(MAP_ENTRY) +#undef MAP_ENTRY + } + + return absl::nullopt; +} + +absl::optional<TextInputMode> ConvertToTextInputMode( + zcr_extended_text_input_v1_input_mode wayland_input_mode) { + switch (wayland_input_mode) { +#define MAP_ENTRY(name) \ + case ZCR_EXTENDED_TEXT_INPUT_V1_INPUT_MODE_##name: \ + return ui::TEXT_INPUT_MODE_##name; + + MAP_MODES(MAP_ENTRY) +#undef MAP_ENTRY + } + + return absl::nullopt; +} + +std::pair<uint32_t, uint32_t> ConvertToTextInputFlags( + uint32_t wayland_input_flags) { + uint32_t result = 0; + for (const auto ui_flag : kAllTextInputFlags) { + const uint32_t wayland_flag = ConvertFromTextInputFlag(ui_flag); + if (wayland_input_flags & wayland_flag) { + result |= ui_flag; + wayland_input_flags &= ~wayland_flag; + } + } + return {result, wayland_input_flags}; +} + +} // namespace ui::wayland
diff --git a/ui/base/wayland/wayland_server_input_types.h b/ui/base/wayland/wayland_server_input_types.h new file mode 100644 index 0000000..a64004c9 --- /dev/null +++ b/ui/base/wayland/wayland_server_input_types.h
@@ -0,0 +1,37 @@ +// Copyright 2022 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_WAYLAND_WAYLAND_SERVER_INPUT_TYPES_H_ +#define UI_BASE_WAYLAND_WAYLAND_SERVER_INPUT_TYPES_H_ + +#include <text-input-extension-unstable-v1-server-protocol.h> + +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "ui/base/ime/text_input_flags.h" +#include "ui/base/ime/text_input_mode.h" +#include "ui/base/ime/text_input_type.h" + +namespace ui::wayland { + +// Coverts zcr_extended_text_input::input_type into ui::TextInputType. +// Returns nullopt if unknown type is given. +// This can happen if wayland client (e.g. Lacros) and wayland compositor +// (e.g. exo) have version skew, so that the wayland client sends a new +// type that the wayland compositor cannot understand. +absl::optional<TextInputType> ConvertToTextInputType( + zcr_extended_text_input_v1_input_type wayland_input_type); + +// Converts zcr_extended_text_input::input_mode into ui::TextInputMode. +absl::optional<TextInputMode> ConvertToTextInputMode( + zcr_extended_text_input_v1_input_mode wayland_input_mode); + +// Converts a bit set of ui::TextInputFlags into a bit set of +// zcr_extended_text_input::input_flags. +// Returns a pair of (converted result, unrecognized flags). +std::pair<uint32_t, uint32_t> ConvertToTextInputFlags( + uint32_t wayland_input_flags); + +} // namespace ui::wayland + +#endif // UI_BASE_WAYLAND_WAYLAND_SERVER_INPUT_TYPES_H_
diff --git a/ui/base/x/x11_gl_egl_utility.cc b/ui/base/x/x11_gl_egl_utility.cc index 8464e44..e625e27 100644 --- a/ui/base/x/x11_gl_egl_utility.cc +++ b/ui/base/x/x11_gl_egl_utility.cc
@@ -59,7 +59,8 @@ EGLint* buffer_size) { // If we're using ANGLE_NULL, we may not have a display, in which case we // can't use XVisualManager. - if (gl::GLSurfaceEGL::GetNativeDisplay() != EGL_DEFAULT_DISPLAY) { + if (gl::GLSurfaceEGL::GetGLDisplayEGL()->GetNativeDisplay() != + EGL_DEFAULT_DISPLAY) { uint8_t depth; XVisualManager::GetInstance()->ChooseVisualForWindow(true, nullptr, &depth, nullptr, nullptr);
diff --git a/ui/color/ui_color_mixer.cc b/ui/color/ui_color_mixer.cc index 3e44d34..8b5b8c6 100644 --- a/ui/color/ui_color_mixer.cc +++ b/ui/color/ui_color_mixer.cc
@@ -86,8 +86,9 @@ kColorLiveCaptionBubbleButtonIcon, gfx::kDisabledControlAlpha); mixer[kColorLiveCaptionBubbleForegroundDefault] = GetColorWithMaxContrast(kColorLiveCaptionBubbleBackgroundDefault); - mixer[kColorLiveCaptionBubbleCheckbox] = {gfx::kGoogleBlue300}; - mixer[kColorLiveCaptionBubbleLink] = {gfx::kGoogleBlue300}; + mixer[kColorLiveCaptionBubbleCheckbox] = PickGoogleColor( + kColorAccent, kColorLiveCaptionBubbleBackgroundDefault, 6.0f); + mixer[kColorLiveCaptionBubbleLink] = {kColorLiveCaptionBubbleCheckbox}; mixer[kColorMenuBackground] = {kColorPrimaryBackground}; mixer[kColorMenuBorder] = {kColorMidground}; mixer[kColorMenuDropmarker] = {kColorPrimaryForeground}; @@ -167,9 +168,13 @@ SetAlpha(kColorAlertHighSeverity, gfx::kGoogleGreyAlpha100); mixer[kColorSyncInfoBackgroundPaused] = SetAlpha(kColorAccent, gfx::kGoogleGreyAlpha100); - mixer[kColorTabBackgroundHighlighted] = SetAlpha(gfx::kGoogleBlue300, 0x2B); - mixer[kColorTabBackgroundHighlightedFocused] = - SetAlpha(gfx::kGoogleBlue300, 0x53); + { + auto tab_background_base = + PickGoogleColor(kColorAccent, kColorPrimaryBackground, 6.0f); + mixer[kColorTabBackgroundHighlighted] = SetAlpha(tab_background_base, 0x2B); + mixer[kColorTabBackgroundHighlightedFocused] = + SetAlpha(std::move(tab_background_base), 0x53); + } mixer[kColorTabBorderSelected] = {kColorAccent}; mixer[kColorTabContentSeparator] = {kColorMidground}; mixer[kColorTabForeground] = {kColorSecondaryForeground}; @@ -210,8 +215,8 @@ } mixer[kColorToggleButtonTrackOff] = { dark_mode ? ColorTransform(gfx::kGoogleGrey700) : kColorMidground}; - mixer[kColorToggleButtonTrackOn] = {dark_mode ? gfx::kGoogleBlue600 - : gfx::kGoogleBlue300}; + mixer[kColorToggleButtonTrackOn] = + PickGoogleColor(kColorAccent, kColorToggleButtonThumbOn, 2.13f); mixer[kColorTooltipBackground] = SetAlpha(kColorPrimaryBackground, 0xCC); mixer[kColorTooltipForeground] = SetAlpha(kColorPrimaryForeground, 0xDE); mixer[kColorTreeBackground] = {kColorPrimaryBackground};
diff --git a/ui/gl/direct_composition_surface_win.cc b/ui/gl/direct_composition_surface_win.cc index e027993..897073e 100644 --- a/ui/gl/direct_composition_surface_win.cc +++ b/ui/gl/direct_composition_surface_win.cc
@@ -427,7 +427,7 @@ // EGL_KHR_no_config_context surface compatibility is required to be able to // MakeCurrent with the default pbuffer surface. - if (!GLSurfaceEGL::IsEGLNoConfigContextSupported()) { + if (!GLSurfaceEGL::GetGLDisplayEGL()->IsEGLNoConfigContextSupported()) { DLOG(ERROR) << "EGL_KHR_no_config_context not supported"; return; }
diff --git a/ui/gl/gl_angle_util_vulkan.cc b/ui/gl/gl_angle_util_vulkan.cc index 91bac2a..c0099aa 100644 --- a/ui/gl/gl_angle_util_vulkan.cc +++ b/ui/gl/gl_angle_util_vulkan.cc
@@ -12,13 +12,14 @@ namespace gl { namespace { EGLDeviceEXT GetEGLDeviceFromANGLE() { - EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); + EGLDisplay egl_display = + gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(); if (egl_display == EGL_NO_DISPLAY) { LOG(ERROR) << "Failed to retrieve EGLDisplay"; return nullptr; } - if (!gl::GLSurfaceEGL::IsEGLQueryDeviceSupported()) { + if (!gl::GLSurfaceEGL::GetGLDisplayEGL()->IsEGLQueryDeviceSupported()) { LOG(ERROR) << "EGL_EXT_device_query not supported"; return nullptr; }
diff --git a/ui/gl/gl_angle_util_win.cc b/ui/gl/gl_angle_util_win.cc index 345e8dd..3427df23 100644 --- a/ui/gl/gl_angle_util_win.cc +++ b/ui/gl/gl_angle_util_win.cc
@@ -17,13 +17,14 @@ void* QueryDeviceObjectFromANGLE(int object_type) { TRACE_EVENT0("gpu", "QueryDeviceObjectFromANGLE"); - EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); + EGLDisplay egl_display = + gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(); if (egl_display == EGL_NO_DISPLAY) { DVLOG(1) << "Failed to retrieve EGLDisplay"; return nullptr; } - if (!gl::GLSurfaceEGL::IsEGLQueryDeviceSupported()) { + if (!gl::GLSurfaceEGL::GetGLDisplayEGL()->IsEGLQueryDeviceSupported()) { DVLOG(1) << "EGL_EXT_device_query not supported"; return nullptr; }
diff --git a/ui/gl/gl_bindings.cc b/ui/gl/gl_bindings.cc index a5061544..13786d5 100644 --- a/ui/gl/gl_bindings.cc +++ b/ui/gl/gl_bindings.cc
@@ -23,7 +23,7 @@ #if defined(USE_EGL) std::string DriverEGL::GetPlatformExtensions() { - EGLDisplay display = GLSurfaceEGL::GetHardwareDisplay(); + EGLDisplay display = GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(); if (display == EGL_NO_DISPLAY) return ""; const char* str = eglQueryString(display, EGL_EXTENSIONS);
diff --git a/ui/gl/gl_context_egl.cc b/ui/gl/gl_context_egl.cc index 2216b9ff..5ed98c826 100644 --- a/ui/gl/gl_context_egl.cc +++ b/ui/gl/gl_context_egl.cc
@@ -128,7 +128,7 @@ // Always prefer to use EGL_KHR_no_config_context so that all surfaces and // contexts are compatible - if (!GLSurfaceEGL::IsEGLNoConfigContextSupported()) { + if (!GLSurfaceEGL::GetGLDisplayEGL()->IsEGLNoConfigContextSupported()) { config_ = compatible_surface->GetConfig(); EGLint config_renderable_type = 0; if (!eglGetConfigAttrib(display_, config_, EGL_RENDERABLE_TYPE, @@ -156,7 +156,8 @@ // EGL_KHR_create_context allows requesting both a major and minor context // version - if (GLSurfaceEGL::HasEGLExtension("EGL_KHR_create_context")) { + if (GLSurfaceEGL::GetGLDisplayEGL()->HasEGLExtension( + "EGL_KHR_create_context")) { context_attributes.push_back(EGL_CONTEXT_MAJOR_VERSION); context_attributes.push_back(context_client_major_version); @@ -174,7 +175,8 @@ bool is_swangle = IsSoftwareGLImplementation(GetGLImplementationParts()); - if (GLSurfaceEGL::IsCreateContextRobustnessSupported() || is_swangle) { + if (GLSurfaceEGL::GetGLDisplayEGL()->IsCreateContextRobustnessSupported() || + is_swangle) { DVLOG(1) << "EGL_EXT_create_context_robustness supported."; context_attributes.push_back(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT); context_attributes.push_back( @@ -184,7 +186,8 @@ EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT); context_attributes.push_back(EGL_LOSE_CONTEXT_ON_RESET_EXT); - if (GLSurfaceEGL::IsRobustnessVideoMemoryPurgeSupported()) { + if (GLSurfaceEGL::GetGLDisplayEGL() + ->IsRobustnessVideoMemoryPurgeSupported()) { context_attributes.push_back( EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV); context_attributes.push_back(EGL_TRUE); @@ -202,7 +205,8 @@ return false; } - if (GLSurfaceEGL::IsCreateContextBindGeneratesResourceSupported()) { + if (GLSurfaceEGL::GetGLDisplayEGL() + ->IsCreateContextBindGeneratesResourceSupported()) { context_attributes.push_back(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM); context_attributes.push_back(attribs.bind_generates_resource ? EGL_TRUE : EGL_FALSE); @@ -210,7 +214,8 @@ DCHECK(attribs.bind_generates_resource); } - if (GLSurfaceEGL::IsCreateContextWebGLCompatabilitySupported()) { + if (GLSurfaceEGL::GetGLDisplayEGL() + ->IsCreateContextWebGLCompatabilitySupported()) { context_attributes.push_back(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE); context_attributes.push_back( attribs.webgl_compatibility_context ? EGL_TRUE : EGL_FALSE); @@ -218,7 +223,7 @@ DCHECK(!attribs.webgl_compatibility_context); } - if (GLSurfaceEGL::IsEGLContextPrioritySupported()) { + if (GLSurfaceEGL::GetGLDisplayEGL()->IsEGLContextPrioritySupported()) { // Medium priority is the default, only set the attribute if // a different priority is requested. if (attribs.context_priority == ContextPriorityLow) { @@ -232,7 +237,7 @@ } } - if (GLSurfaceEGL::IsDisplayTextureShareGroupSupported()) { + if (GLSurfaceEGL::GetGLDisplayEGL()->IsDisplayTextureShareGroupSupported()) { context_attributes.push_back(EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE); context_attributes.push_back( attribs.global_texture_share_group ? EGL_TRUE : EGL_FALSE); @@ -240,7 +245,8 @@ DCHECK(!attribs.global_texture_share_group); } - if (GLSurfaceEGL::IsDisplaySemaphoreShareGroupSupported()) { + if (GLSurfaceEGL::GetGLDisplayEGL() + ->IsDisplaySemaphoreShareGroupSupported()) { context_attributes.push_back(EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE); context_attributes.push_back( attribs.global_semaphore_share_group ? EGL_TRUE : EGL_FALSE); @@ -248,13 +254,14 @@ DCHECK(!attribs.global_semaphore_share_group); } - if (GLSurfaceEGL::IsCreateContextClientArraysSupported()) { + if (GLSurfaceEGL::GetGLDisplayEGL()->IsCreateContextClientArraysSupported()) { // Disable client arrays if the context supports it context_attributes.push_back(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE); context_attributes.push_back(EGL_FALSE); } - if (GLSurfaceEGL::IsRobustResourceInitSupported() || is_swangle) { + if (GLSurfaceEGL::GetGLDisplayEGL()->IsRobustResourceInitSupported() || + is_swangle) { context_attributes.push_back(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE); context_attributes.push_back( (attribs.robust_resource_initialization || is_swangle) ? EGL_TRUE @@ -263,7 +270,7 @@ DCHECK(!attribs.robust_resource_initialization); } - if (GLSurfaceEGL::HasEGLExtension( + if (GLSurfaceEGL::GetGLDisplayEGL()->HasEGLExtension( "EGL_ANGLE_create_context_backwards_compatible")) { // Request a specific context version. The Passthrough command decoder // relies on the returned context being the exact version it requested. @@ -271,7 +278,7 @@ context_attributes.push_back(EGL_FALSE); } - if (GLSurfaceEGL::IsANGLEPowerPreferenceSupported()) { + if (GLSurfaceEGL::GetGLDisplayEGL()->IsANGLEPowerPreferenceSupported()) { GpuPreference pref = attribs.gpu_preference; pref = GLSurface::AdjustGpuPreference(pref); switch (pref) { @@ -291,7 +298,8 @@ } } - if (GLSurfaceEGL::IsANGLEExternalContextAndSurfaceSupported()) { + if (GLSurfaceEGL::GetGLDisplayEGL() + ->IsANGLEExternalContextAndSurfaceSupported()) { if (attribs.angle_create_from_external_context) { context_attributes.push_back(EGL_EXTERNAL_CONTEXT_ANGLE); context_attributes.push_back(EGL_TRUE); @@ -302,7 +310,8 @@ } } - if (GLSurfaceEGL::IsANGLEContextVirtualizationSupported()) { + if (GLSurfaceEGL::GetGLDisplayEGL() + ->IsANGLEContextVirtualizationSupported()) { context_attributes.push_back(EGL_CONTEXT_VIRTUALIZATION_GROUP_ANGLE); context_attributes.push_back( static_cast<EGLint>(attribs.angle_context_virtualization_group_number)); @@ -319,7 +328,8 @@ // If EGL_KHR_no_config_context is in use and context creation failed, // it might indicate that an unsupported ES version was requested. Try // falling back to a lower version. - if (!context_ && GLSurfaceEGL::IsEGLNoConfigContextSupported() && + if (!context_ && + GLSurfaceEGL::GetGLDisplayEGL()->IsEGLNoConfigContextSupported() && eglGetError() == EGL_BAD_MATCH) { // Set up the list of versions to try: 3.1 -> 3.0 -> 2.0 std::vector<std::pair<EGLint, EGLint>> candidate_versions; @@ -378,7 +388,7 @@ // contexts aren't supported since support for surfaceless EGL contexts is // required in order to properly release YUVToRGBConverter objects (see // GLContextEGL::ReleaseYUVToRGBConvertersAndBackpressureFences()) - if (!GLSurfaceEGL::IsEGLSurfacelessContextSupported()) { + if (!GLSurfaceEGL::GetGLDisplayEGL()->IsEGLSurfacelessContextSupported()) { return nullptr; } @@ -392,7 +402,7 @@ } void GLContextEGL::SetVisibility(bool visibility) { - if (GLSurfaceEGL::IsANGLEPowerPreferenceSupported()) { + if (GLSurfaceEGL::GetGLDisplayEGL()->IsANGLEPowerPreferenceSupported()) { // It doesn't matter whether this context was explicitly allocated // with a power preference - ANGLE will take care of any default behavior. if (visibility) { @@ -549,7 +559,7 @@ DCHECK(g_current_gl_driver); const ExtensionsGL& ext = g_current_gl_driver->ext; if ((graphics_reset_status_ == GL_NO_ERROR) && - GLSurfaceEGL::IsCreateContextRobustnessSupported() && + GLSurfaceEGL::GetGLDisplayEGL()->IsCreateContextRobustnessSupported() && (ext.b_GL_KHR_robustness || ext.b_GL_EXT_robustness || ext.b_GL_ARB_robustness)) { graphics_reset_status_ = glGetGraphicsResetStatusARB();
diff --git a/ui/gl/gl_display.cc b/ui/gl/gl_display.cc index 59de624..4f862ff7 100644 --- a/ui/gl/gl_display.cc +++ b/ui/gl/gl_display.cc
@@ -4,15 +4,12 @@ #include "ui/gl/gl_display.h" #include "base/notreached.h" +#include "ui/gl/gl_surface.h" #if defined(USE_GLX) #include "ui/gl/glx_util.h" #endif // defined(USE_GLX) -#if defined(USE_EGL) -#define EGL_NO_DISPLAY 0 -#endif - namespace gl { GLDisplay::GLDisplay() = default; @@ -38,6 +35,112 @@ display_ = display; } +EGLDisplay GLDisplayEGL::GetHardwareDisplay() { + return GetDisplay(); +} + +EGLNativeDisplayType GLDisplayEGL::GetNativeDisplay() { + return native_display.GetDisplay(); +} + +DisplayType GLDisplayEGL::GetDisplayType() { + return display_type; +} + +bool GLDisplayEGL::HasEGLClientExtension(const char* name) { + if (!egl_client_extensions) + return false; + return GLSurface::ExtensionsContain(egl_client_extensions, name); +} + +bool GLDisplayEGL::HasEGLExtension(const char* name) { + return GLSurface::ExtensionsContain(egl_extensions, name); +} + +bool GLDisplayEGL::IsCreateContextRobustnessSupported() { + return egl_create_context_robustness_supported; +} + +bool GLDisplayEGL::IsRobustnessVideoMemoryPurgeSupported() { + return egl_robustness_video_memory_purge_supported; +} + +bool GLDisplayEGL::IsCreateContextBindGeneratesResourceSupported() { + return egl_create_context_bind_generates_resource_supported; +} + +bool GLDisplayEGL::IsCreateContextWebGLCompatabilitySupported() { + return egl_create_context_webgl_compatability_supported; +} + +bool GLDisplayEGL::IsEGLSurfacelessContextSupported() { + return egl_surfaceless_context_supported; +} + +bool GLDisplayEGL::IsEGLContextPrioritySupported() { + return egl_context_priority_supported; +} + +bool GLDisplayEGL::IsEGLNoConfigContextSupported() { + return egl_no_config_context_supported; +} + +bool GLDisplayEGL::IsRobustResourceInitSupported() { + return egl_robust_resource_init_supported; +} + +bool GLDisplayEGL::IsDisplayTextureShareGroupSupported() { + return egl_display_texture_share_group_supported; +} + +bool GLDisplayEGL::IsDisplaySemaphoreShareGroupSupported() { + return egl_display_semaphore_share_group_supported; +} + +bool GLDisplayEGL::IsCreateContextClientArraysSupported() { + return egl_create_context_client_arrays_supported; +} + +bool GLDisplayEGL::IsAndroidNativeFenceSyncSupported() { + return egl_android_native_fence_sync_supported; +} + +bool GLDisplayEGL::IsPixelFormatFloatSupported() { + return egl_ext_pixel_format_float_supported; +} + +bool GLDisplayEGL::IsANGLEFeatureControlSupported() { + return egl_angle_feature_control_supported; +} + +bool GLDisplayEGL::IsANGLEPowerPreferenceSupported() { + return egl_angle_power_preference_supported; +} + +bool GLDisplayEGL::IsANGLEDisplayPowerPreferenceSupported() { + return egl_angle_display_power_preference_supported; +} + +bool GLDisplayEGL::IsANGLEPlatformANGLEDeviceIdSupported() { + return egl_angle_platform_angle_device_id_supported; +} + +bool GLDisplayEGL::IsANGLEExternalContextAndSurfaceSupported() { + return egl_angle_external_context_and_surface_supported; +} + +bool GLDisplayEGL::IsANGLEContextVirtualizationSupported() { + return egl_angle_context_virtualization_supported; +} + +bool GLDisplayEGL::IsANGLEVulkanImageSupported() { + return egl_angle_vulkan_image_supported; +} + +bool GLDisplayEGL::IsEGLQueryDeviceSupported() { + return egl_ext_query_device_supported; +} + #endif // defined(USE_EGL) #if defined(USE_GLX)
diff --git a/ui/gl/gl_display.h b/ui/gl/gl_display.h index 0e9bdd5..552f3f7 100644 --- a/ui/gl/gl_display.h +++ b/ui/gl/gl_display.h
@@ -8,11 +8,55 @@ #include "ui/gl/gl_export.h" #if defined(USE_EGL) -typedef void* EGLDisplay; +#include <EGL/egl.h> #endif // defined(USE_EGL) namespace gl { +class EGLDisplayPlatform { + public: + constexpr EGLDisplayPlatform() + : display_(EGL_DEFAULT_DISPLAY), platform_(0), valid_(false) {} + explicit constexpr EGLDisplayPlatform(EGLNativeDisplayType display, + int platform = 0) + : display_(display), platform_(platform), valid_(true) {} + + bool Valid() const { return valid_; } + int GetPlatform() const { return platform_; } + EGLNativeDisplayType GetDisplay() const { return display_; } + + private: + EGLNativeDisplayType display_; + // 0 for default, or EGL_PLATFORM_* enum. + int platform_; + bool valid_; +}; + +// If adding a new type, also add it to EGLDisplayType in +// tools/metrics/histograms/enums.xml. Don't remove or reorder entries. +enum DisplayType { + DEFAULT = 0, + SWIFT_SHADER = 1, + ANGLE_WARP = 2, + ANGLE_D3D9 = 3, + ANGLE_D3D11 = 4, + ANGLE_OPENGL = 5, + ANGLE_OPENGLES = 6, + ANGLE_NULL = 7, + ANGLE_D3D11_NULL = 8, + ANGLE_OPENGL_NULL = 9, + ANGLE_OPENGLES_NULL = 10, + ANGLE_VULKAN = 11, + ANGLE_VULKAN_NULL = 12, + ANGLE_D3D11on12 = 13, + ANGLE_SWIFTSHADER = 14, + ANGLE_OPENGL_EGL = 15, + ANGLE_OPENGLES_EGL = 16, + ANGLE_METAL = 17, + ANGLE_METAL_NULL = 18, + DISPLAY_TYPE_MAX = 19, +}; + class GL_EXPORT GLDisplay { public: GLDisplay(); @@ -39,6 +83,70 @@ EGLDisplay GetDisplay() override; void SetDisplay(EGLDisplay display); + EGLDisplay GetHardwareDisplay(); + + EGLNativeDisplayType GetNativeDisplay(); + DisplayType GetDisplayType(); + + bool HasEGLClientExtension(const char* name); + bool HasEGLExtension(const char* name); + bool IsCreateContextRobustnessSupported(); + bool IsRobustnessVideoMemoryPurgeSupported(); + bool IsCreateContextBindGeneratesResourceSupported(); + bool IsCreateContextWebGLCompatabilitySupported(); + bool IsEGLSurfacelessContextSupported(); + bool IsEGLContextPrioritySupported(); + bool IsEGLNoConfigContextSupported(); + bool IsRobustResourceInitSupported(); + bool IsDisplayTextureShareGroupSupported(); + bool IsDisplaySemaphoreShareGroupSupported(); + bool IsCreateContextClientArraysSupported(); + bool IsAndroidNativeFenceSyncSupported(); + bool IsPixelFormatFloatSupported(); + bool IsANGLEFeatureControlSupported(); + bool IsANGLEPowerPreferenceSupported(); + bool IsANGLEDisplayPowerPreferenceSupported(); + bool IsANGLEPlatformANGLEDeviceIdSupported(); + bool IsANGLEExternalContextAndSurfaceSupported(); + bool IsANGLEContextVirtualizationSupported(); + bool IsANGLEVulkanImageSupported(); + bool IsEGLQueryDeviceSupported(); + + EGLDisplayPlatform native_display = EGLDisplayPlatform(EGL_DEFAULT_DISPLAY); + + DisplayType display_type = DisplayType::DEFAULT; + + const char* egl_client_extensions = nullptr; + const char* egl_extensions = nullptr; + bool egl_create_context_robustness_supported = false; + bool egl_robustness_video_memory_purge_supported = false; + bool egl_create_context_bind_generates_resource_supported = false; + bool egl_create_context_webgl_compatability_supported = false; + bool egl_sync_control_supported = false; + bool egl_sync_control_rate_supported = false; + bool egl_window_fixed_size_supported = false; + bool egl_surfaceless_context_supported = false; + bool egl_surface_orientation_supported = false; + bool egl_context_priority_supported = false; + bool egl_khr_colorspace = false; + bool egl_ext_colorspace_display_p3 = false; + bool egl_ext_colorspace_display_p3_passthrough = false; + bool egl_no_config_context_supported = false; + bool egl_robust_resource_init_supported = false; + bool egl_display_texture_share_group_supported = false; + bool egl_display_semaphore_share_group_supported = false; + bool egl_create_context_client_arrays_supported = false; + bool egl_android_native_fence_sync_supported = false; + bool egl_ext_pixel_format_float_supported = false; + bool egl_angle_feature_control_supported = false; + bool egl_angle_power_preference_supported = false; + bool egl_angle_display_power_preference_supported = false; + bool egl_angle_platform_angle_device_id_supported = false; + bool egl_angle_external_context_and_surface_supported = false; + bool egl_ext_query_device_supported = false; + bool egl_angle_context_virtualization_supported = false; + bool egl_angle_vulkan_image_supported = false; + private: EGLDisplay display_; };
diff --git a/ui/gl/gl_fence.cc b/ui/gl/gl_fence.cc index 28cbcb12..e4dc6595f 100644 --- a/ui/gl/gl_fence.cc +++ b/ui/gl/gl_fence.cc
@@ -98,7 +98,8 @@ bool GLFence::IsGpuFenceSupported() { #if defined(USE_GL_FENCE_ANDROID_NATIVE_FENCE_SYNC) - return gl::GLSurfaceEGL::IsAndroidNativeFenceSyncSupported(); + return gl::GLSurfaceEGL::GetGLDisplayEGL() + ->IsAndroidNativeFenceSyncSupported(); #elif BUILDFLAG(IS_WIN) return gl::GLFenceWin::IsSupported(); #else
diff --git a/ui/gl/gl_fence_android_native_fence_sync.cc b/ui/gl/gl_fence_android_native_fence_sync.cc index 5f09e6b..c5368ed71 100644 --- a/ui/gl/gl_fence_android_native_fence_sync.cc +++ b/ui/gl/gl_fence_android_native_fence_sync.cc
@@ -30,7 +30,7 @@ // static std::unique_ptr<GLFenceAndroidNativeFenceSync> GLFenceAndroidNativeFenceSync::CreateInternal(EGLenum type, EGLint* attribs) { - DCHECK(GLSurfaceEGL::IsAndroidNativeFenceSyncSupported()); + DCHECK(GLSurfaceEGL::GetGLDisplayEGL()->IsAndroidNativeFenceSyncSupported()); // Can't use MakeUnique, the no-args constructor is private. auto fence = base::WrapUnique(new GLFenceAndroidNativeFenceSync()); @@ -58,7 +58,7 @@ } std::unique_ptr<gfx::GpuFence> GLFenceAndroidNativeFenceSync::GetGpuFence() { - DCHECK(GLSurfaceEGL::IsAndroidNativeFenceSyncSupported()); + DCHECK(GLSurfaceEGL::GetGLDisplayEGL()->IsAndroidNativeFenceSyncSupported()); const EGLint sync_fd = eglDupNativeFenceFDANDROID(display_, sync_); if (sync_fd < 0)
diff --git a/ui/gl/gl_image_d3d.cc b/ui/gl/gl_image_d3d.cc index 5c83568d..00cce39 100644 --- a/ui/gl/gl_image_d3d.cc +++ b/ui/gl/gl_image_d3d.cc
@@ -39,8 +39,9 @@ GLImageD3D::~GLImageD3D() { if (egl_image_ != EGL_NO_IMAGE_KHR) { - if (eglDestroyImageKHR(GLSurfaceEGL::GetHardwareDisplay(), egl_image_) == - EGL_FALSE) { + if (eglDestroyImageKHR( + GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(), + egl_image_) == EGL_FALSE) { DLOG(ERROR) << "Error destroying EGLImage: " << ui::GetLastEGLErrorString(); } @@ -57,8 +58,8 @@ static_cast<EGLint>(plane_index_), EGL_NONE}; egl_image_ = - eglCreateImageKHR(GLSurfaceEGL::GetHardwareDisplay(), EGL_NO_CONTEXT, - EGL_D3D11_TEXTURE_ANGLE, + eglCreateImageKHR(GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(), + EGL_NO_CONTEXT, EGL_D3D11_TEXTURE_ANGLE, static_cast<EGLClientBuffer>(texture_.Get()), attribs); if (egl_image_ == EGL_NO_IMAGE_KHR) { LOG(ERROR) << "Error creating EGLImage: " << ui::GetLastEGLErrorString();
diff --git a/ui/gl/gl_image_dxgi.cc b/ui/gl/gl_image_dxgi.cc index 8b5c796..15c1166b 100644 --- a/ui/gl/gl_image_dxgi.cc +++ b/ui/gl/gl_image_dxgi.cc
@@ -64,14 +64,16 @@ EGL_NONE}; EGLint num_config; - EGLDisplay display = gl::GLSurfaceEGL::GetHardwareDisplay(); + EGLDisplay display = + gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(); EGLBoolean result = eglChooseConfig(display, attrib_list, nullptr, 0, &num_config); if (result != EGL_TRUE) return nullptr; std::vector<EGLConfig> all_configs(num_config); - result = eglChooseConfig(gl::GLSurfaceEGL::GetHardwareDisplay(), attrib_list, - all_configs.data(), num_config, &num_config); + result = + eglChooseConfig(gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(), + attrib_list, all_configs.data(), num_config, &num_config); if (result != EGL_TRUE) return nullptr; for (EGLConfig config : all_configs) { @@ -125,8 +127,8 @@ EGL_NONE}; return eglCreatePbufferFromClientBuffer( - gl::GLSurfaceEGL::GetHardwareDisplay(), EGL_D3D_TEXTURE_ANGLE, - texture.Get(), config, pBufferAttributes); + gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(), + EGL_D3D_TEXTURE_ANGLE, texture.Get(), config, pBufferAttributes); } } // namespace @@ -172,8 +174,9 @@ return false; } - return eglBindTexImage(gl::GLSurfaceEGL::GetHardwareDisplay(), surface_, - EGL_BACK_BUFFER) == EGL_TRUE; + return eglBindTexImage( + gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(), + surface_, EGL_BACK_BUFFER) == EGL_TRUE; } bool GLImageDXGI::CopyTexImage(unsigned target) { @@ -221,8 +224,8 @@ keyed_mutex_->ReleaseSync(KEY_RELEASE); - eglReleaseTexImage(gl::GLSurfaceEGL::GetHardwareDisplay(), surface_, - EGL_BACK_BUFFER); + eglReleaseTexImage(gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(), + surface_, EGL_BACK_BUFFER); } bool GLImageDXGI::InitializeHandle(base::win::ScopedHandle handle, @@ -264,10 +267,12 @@ GLImageDXGI::~GLImageDXGI() { if (handle_.Get()) { if (surface_ != EGL_NO_SURFACE) { - eglDestroySurface(gl::GLSurfaceEGL::GetHardwareDisplay(), surface_); + eglDestroySurface( + gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(), surface_); } } else if (stream_) { - EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); + EGLDisplay egl_display = + gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(); eglDestroyStreamKHR(egl_display, stream_); } } @@ -298,7 +303,8 @@ DLOG(ERROR) << "CreateTexture2D failed: " << std::hex << hr; return false; } - EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); + EGLDisplay egl_display = + gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(); EGLAttrib frame_attributes[] = { EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE, 0, EGL_NONE,
diff --git a/ui/gl/gl_image_egl.cc b/ui/gl/gl_image_egl.cc index 22dd965..13fd21b1 100644 --- a/ui/gl/gl_image_egl.cc +++ b/ui/gl/gl_image_egl.cc
@@ -19,8 +19,8 @@ if (egl_image_ == EGL_NO_IMAGE_KHR) return; - const EGLBoolean result = - eglDestroyImageKHR(GLSurfaceEGL::GetHardwareDisplay(), egl_image_); + const EGLBoolean result = eglDestroyImageKHR( + GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(), egl_image_); if (result == EGL_FALSE) DLOG(ERROR) << "Error destroying EGLImage: " << ui::GetLastEGLErrorString(); } @@ -31,8 +31,9 @@ const EGLint* attrs) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK_EQ(EGL_NO_IMAGE_KHR, egl_image_); - egl_image_ = eglCreateImageKHR(GLSurfaceEGL::GetHardwareDisplay(), context, - target, buffer, attrs); + egl_image_ = + eglCreateImageKHR(GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(), + context, target, buffer, attrs); const bool success = egl_image_ != EGL_NO_IMAGE_KHR; if (!success) LOG(ERROR) << "Error creating EGLImage: " << ui::GetLastEGLErrorString();
diff --git a/ui/gl/gl_image_io_surface_egl.mm b/ui/gl/gl_image_io_surface_egl.mm index 6e2117e..c03ad34 100644 --- a/ui/gl/gl_image_io_surface_egl.mm +++ b/ui/gl/gl_image_io_surface_egl.mm
@@ -113,7 +113,7 @@ GLImageIOSurfaceEGL::GLImageIOSurfaceEGL(const gfx::Size& size, unsigned internalformat) : GLImageIOSurface(size, internalformat), - display_(GLSurfaceEGL::GetHardwareDisplay()), + display_(GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay()), pbuffer_(EGL_NO_SURFACE), dummy_config_(nullptr), texture_target_(EGL_TEXTURE_RECTANGLE_ANGLE),
diff --git a/ui/gl/gl_image_native_pixmap.cc b/ui/gl/gl_image_native_pixmap.cc index 073508f..effe6136 100644 --- a/ui/gl/gl_image_native_pixmap.cc +++ b/ui/gl/gl_image_native_pixmap.cc
@@ -132,9 +132,11 @@ format_(format), plane_(plane), has_image_flush_external_( - gl::GLSurfaceEGL::HasEGLExtension("EGL_EXT_image_flush_external")), + gl::GLSurfaceEGL::GetGLDisplayEGL()->HasEGLExtension( + "EGL_EXT_image_flush_external")), has_image_dma_buf_export_( - gl::GLSurfaceEGL::HasEGLExtension("EGL_MESA_image_dma_buf_export")) {} + gl::GLSurfaceEGL::GetGLDisplayEGL()->HasEGLExtension( + "EGL_MESA_image_dma_buf_export")) {} GLImageNativePixmap::~GLImageNativePixmap() {} @@ -171,8 +173,9 @@ const EGLint kLinuxDrmModifiers[] = {EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT, EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT, EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT}; - bool has_dma_buf_import_modifier = gl::GLSurfaceEGL::HasEGLExtension( - "EGL_EXT_image_dma_buf_import_modifiers"); + bool has_dma_buf_import_modifier = + gl::GLSurfaceEGL::GetGLDisplayEGL()->HasEGLExtension( + "EGL_EXT_image_dma_buf_import_modifiers"); for (size_t attrs_plane = 0; attrs_plane < pixmap->GetNumberOfPlanes(); ++attrs_plane) { @@ -267,9 +270,9 @@ int num_planes = 0; EGLuint64KHR modifiers = 0; - if (!eglExportDMABUFImageQueryMESA(GLSurfaceEGL::GetHardwareDisplay(), - egl_image_, &fourcc, &num_planes, - &modifiers)) { + if (!eglExportDMABUFImageQueryMESA( + GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(), egl_image_, + &fourcc, &num_planes, &modifiers)) { LOG(ERROR) << "Error querying EGLImage: " << ui::GetLastEGLErrorString(); return gfx::NativePixmapHandle(); } @@ -305,8 +308,9 @@ // It is specified for eglExportDMABUFImageMESA that the app is responsible // for closing any fds retrieved. - if (!eglExportDMABUFImageMESA(GLSurfaceEGL::GetHardwareDisplay(), egl_image_, - &fds[0], &strides[0], &offsets[0])) { + if (!eglExportDMABUFImageMESA( + GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(), egl_image_, + &fds[0], &strides[0], &offsets[0])) { LOG(ERROR) << "Error exporting EGLImage: " << ui::GetLastEGLErrorString(); return gfx::NativePixmapHandle(); } @@ -366,7 +370,8 @@ if (!has_image_flush_external_) return; - EGLDisplay display = gl::GLSurfaceEGL::GetHardwareDisplay(); + EGLDisplay display = + gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(); const EGLAttrib attribs[] = { EGL_NONE, };
diff --git a/ui/gl/gl_surface_egl.cc b/ui/gl/gl_surface_egl.cc index de2a4b3..f73d405 100644 --- a/ui/gl/gl_surface_egl.cc +++ b/ui/gl/gl_surface_egl.cc
@@ -195,40 +195,6 @@ // GLDisplay reference, passed in on init. GLDisplayEGL* g_gl_display = nullptr; -EGLDisplayPlatform g_native_display(EGL_DEFAULT_DISPLAY); - -DisplayType g_display_type = DisplayType::DEFAULT; - -const char* g_egl_client_extensions = nullptr; -const char* g_egl_extensions = nullptr; -bool g_egl_create_context_robustness_supported = false; -bool g_egl_robustness_video_memory_purge_supported = false; -bool g_egl_create_context_bind_generates_resource_supported = false; -bool g_egl_create_context_webgl_compatability_supported = false; -bool g_egl_sync_control_supported = false; -bool g_egl_sync_control_rate_supported = false; -bool g_egl_window_fixed_size_supported = false; -bool g_egl_surfaceless_context_supported = false; -bool g_egl_surface_orientation_supported = false; -bool g_egl_context_priority_supported = false; -bool g_egl_khr_colorspace = false; -bool g_egl_ext_colorspace_display_p3 = false; -bool g_egl_ext_colorspace_display_p3_passthrough = false; -bool g_egl_no_config_context_supported = false; -bool g_egl_robust_resource_init_supported = false; -bool g_egl_display_texture_share_group_supported = false; -bool g_egl_display_semaphore_share_group_supported = false; -bool g_egl_create_context_client_arrays_supported = false; -bool g_egl_android_native_fence_sync_supported = false; -bool g_egl_ext_pixel_format_float_supported = false; -bool g_egl_angle_feature_control_supported = false; -bool g_egl_angle_power_preference_supported = false; -bool g_egl_angle_display_power_preference_supported = false; -bool g_egl_angle_platform_angle_device_id_supported = false; -bool g_egl_angle_external_context_and_surface_supported = false; -bool g_egl_ext_query_device_supported = false; -bool g_egl_angle_context_virtualization_supported = false; -bool g_egl_angle_vulkan_image_supported = false; EGLGpuSwitchingObserver* g_egl_gpu_switching_observer = nullptr; constexpr const char kSwapEventTraceCategories[] = "gpu"; @@ -245,13 +211,6 @@ static base::LazyInstance<TraceSwapEventsInitializer>::Leaky g_trace_swap_enabled = LAZY_INSTANCE_INITIALIZER; -GLDisplayEGL* GetOrInitializeGLDisplay() { - if (g_gl_display == nullptr) { - g_gl_display = new GLDisplayEGL(EGL_NO_DISPLAY); - } - return g_gl_display; -} - class EGLSyncControlVSyncProvider : public SyncControlVSyncProvider { public: EGLSyncControlVSyncProvider(EGLSurface surface, GLDisplay* display) @@ -265,7 +224,7 @@ static bool IsSupported() { return SyncControlVSyncProvider::IsSupported() && - g_egl_sync_control_supported; + GLSurfaceEGL::GetGLDisplayEGL()->egl_sync_control_supported; } protected: @@ -286,7 +245,7 @@ } bool GetMscRate(int32_t* numerator, int32_t* denominator) override { - if (!g_egl_sync_control_rate_supported) { + if (!GLSurfaceEGL::GetGLDisplayEGL()->egl_sync_control_rate_supported) { return false; } @@ -305,8 +264,8 @@ class EGLGpuSwitchingObserver final : public ui::GpuSwitchingObserver { public: void OnGpuSwitched(gl::GpuPreference active_gpu_heuristic) override { - DCHECK(GLSurfaceEGL::IsANGLEPowerPreferenceSupported()); - eglHandleGPUSwitchANGLE(GetOrInitializeGLDisplay()->GetDisplay()); + DCHECK(GLSurfaceEGL::GetGLDisplayEGL()->IsANGLEPowerPreferenceSupported()); + eglHandleGPUSwitchANGLE(GLSurfaceEGL::GetGLDisplayEGL()->GetDisplay()); } }; @@ -370,7 +329,7 @@ GetAttribArrayFromStringVector(enabled_features); std::vector<const char*> disabled_features_attribs = GetAttribArrayFromStringVector(disabled_features); - if (g_egl_angle_feature_control_supported) { + if (GLSurfaceEGL::GetGLDisplayEGL()->egl_angle_feature_control_supported) { if (!enabled_features_attribs.empty()) { display_attribs.push_back(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE); display_attribs.push_back( @@ -384,7 +343,8 @@ } // TODO(dbehr) Add an attrib to Angle to pass EGL platform. - if (GLSurfaceEGL::IsANGLEDisplayPowerPreferenceSupported()) { + if (GLSurfaceEGL::GetGLDisplayEGL() + ->IsANGLEDisplayPowerPreferenceSupported()) { GpuPreference pref = GLSurface::AdjustGpuPreference(GpuPreference::kDefault); switch (pref) { @@ -426,8 +386,8 @@ extra_display_attribs.push_back(EGL_FEATURE_ALL_DISABLED_ANGLE); extra_display_attribs.push_back(EGL_TRUE); } - if (system_device_id != 0 && - GLSurfaceEGL::IsANGLEPlatformANGLEDeviceIdSupported()) { + if (system_device_id != 0 && GLSurfaceEGL::GetGLDisplayEGL() + ->IsANGLEPlatformANGLEDeviceIdSupported()) { uint32_t low_part = system_device_id & 0xffffffff; extra_display_attribs.push_back(EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE); extra_display_attribs.push_back(low_part); @@ -998,7 +958,7 @@ } GLDisplay* GLSurfaceEGL::GetGLDisplay() { - return GetOrInitializeGLDisplay(); + return GetGLDisplayEGL(); } EGLConfig GLSurfaceEGL::GetConfig() { @@ -1019,6 +979,14 @@ } // static +GLDisplayEGL* GLSurfaceEGL::GetGLDisplayEGL() { + if (g_gl_display == nullptr) { + g_gl_display = new GLDisplayEGL(EGL_NO_DISPLAY); + } + return g_gl_display; +} + +// static bool GLSurfaceEGL::InitializeOneOff(EGLDisplayPlatform native_display, uint64_t system_device_id) { if (initialized_) @@ -1040,7 +1008,7 @@ // static bool GLSurfaceEGL::InitializeOneOffForTesting() { g_driver_egl.InitializeClientExtensionBindings(); - GLDisplayEGL* display = GetOrInitializeGLDisplay(); + GLDisplayEGL* display = GetGLDisplayEGL(); display->SetDisplay(eglGetCurrentDisplay()); g_driver_egl.InitializeExtensionBindings(); return InitializeOneOffCommon(display); @@ -1048,29 +1016,34 @@ // static bool GLSurfaceEGL::InitializeOneOffCommon(GLDisplayEGL* display) { - g_egl_client_extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); - g_egl_extensions = eglQueryString(display->GetDisplay(), EGL_EXTENSIONS); + display->egl_client_extensions = + eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); + display->egl_extensions = + eglQueryString(display->GetDisplay(), EGL_EXTENSIONS); - g_egl_create_context_robustness_supported = - HasEGLExtension("EGL_EXT_create_context_robustness"); - g_egl_robustness_video_memory_purge_supported = - HasEGLExtension("EGL_NV_robustness_video_memory_purge"); - g_egl_create_context_bind_generates_resource_supported = - HasEGLExtension("EGL_CHROMIUM_create_context_bind_generates_resource"); - g_egl_create_context_webgl_compatability_supported = - HasEGLExtension("EGL_ANGLE_create_context_webgl_compatibility"); - g_egl_sync_control_supported = HasEGLExtension("EGL_CHROMIUM_sync_control"); - g_egl_sync_control_rate_supported = - HasEGLExtension("EGL_ANGLE_sync_control_rate"); - g_egl_window_fixed_size_supported = - HasEGLExtension("EGL_ANGLE_window_fixed_size"); - g_egl_surface_orientation_supported = - HasEGLExtension("EGL_ANGLE_surface_orientation"); - g_egl_khr_colorspace = HasEGLExtension("EGL_KHR_gl_colorspace"); - g_egl_ext_colorspace_display_p3 = - HasEGLExtension("EGL_EXT_gl_colorspace_display_p3"); - g_egl_ext_colorspace_display_p3_passthrough = - HasEGLExtension("EGL_EXT_gl_colorspace_display_p3_passthrough"); + display->egl_create_context_robustness_supported = + display->HasEGLExtension("EGL_EXT_create_context_robustness"); + display->egl_robustness_video_memory_purge_supported = + display->HasEGLExtension("EGL_NV_robustness_video_memory_purge"); + display->egl_create_context_bind_generates_resource_supported = + display->HasEGLExtension( + "EGL_CHROMIUM_create_context_bind_generates_resource"); + display->egl_create_context_webgl_compatability_supported = + display->HasEGLExtension("EGL_ANGLE_create_context_webgl_compatibility"); + display->egl_sync_control_supported = + display->HasEGLExtension("EGL_CHROMIUM_sync_control"); + display->egl_sync_control_rate_supported = + display->HasEGLExtension("EGL_ANGLE_sync_control_rate"); + display->egl_window_fixed_size_supported = + display->HasEGLExtension("EGL_ANGLE_window_fixed_size"); + display->egl_surface_orientation_supported = + display->HasEGLExtension("EGL_ANGLE_surface_orientation"); + display->egl_khr_colorspace = + display->HasEGLExtension("EGL_KHR_gl_colorspace"); + display->egl_ext_colorspace_display_p3 = + display->HasEGLExtension("EGL_EXT_gl_colorspace_display_p3"); + display->egl_ext_colorspace_display_p3_passthrough = + display->HasEGLExtension("EGL_EXT_gl_colorspace_display_p3_passthrough"); // According to https://source.android.com/compatibility/android-cdd.html the // EGL_IMG_context_priority extension is mandatory for Virtual Reality High // Performance support, but due to a bug in Android Nougat the extension @@ -1078,28 +1051,28 @@ // related extensions that were added for VR support are present, and assume // that this implies context priority is also supported. See also: // https://github.com/googlevr/gvr-android-sdk/issues/330 - g_egl_context_priority_supported = - HasEGLExtension("EGL_IMG_context_priority") || - (HasEGLExtension("EGL_ANDROID_front_buffer_auto_refresh") && - HasEGLExtension("EGL_ANDROID_create_native_client_buffer")); + display->egl_context_priority_supported = + display->HasEGLExtension("EGL_IMG_context_priority") || + (display->HasEGLExtension("EGL_ANDROID_front_buffer_auto_refresh") && + display->HasEGLExtension("EGL_ANDROID_create_native_client_buffer")); // Need EGL_KHR_no_config_context to allow surfaces with and without alpha to // be bound to the same context. - g_egl_no_config_context_supported = - HasEGLExtension("EGL_KHR_no_config_context"); + display->egl_no_config_context_supported = + display->HasEGLExtension("EGL_KHR_no_config_context"); - g_egl_display_texture_share_group_supported = - HasEGLExtension("EGL_ANGLE_display_texture_share_group"); - g_egl_display_semaphore_share_group_supported = - HasEGLExtension("EGL_ANGLE_display_semaphore_share_group"); - g_egl_create_context_client_arrays_supported = - HasEGLExtension("EGL_ANGLE_create_context_client_arrays"); - g_egl_robust_resource_init_supported = - HasEGLExtension("EGL_ANGLE_robust_resource_initialization"); + display->egl_display_texture_share_group_supported = + display->HasEGLExtension("EGL_ANGLE_display_texture_share_group"); + display->egl_display_semaphore_share_group_supported = + display->HasEGLExtension("EGL_ANGLE_display_semaphore_share_group"); + display->egl_create_context_client_arrays_supported = + display->HasEGLExtension("EGL_ANGLE_create_context_client_arrays"); + display->egl_robust_resource_init_supported = + display->HasEGLExtension("EGL_ANGLE_robust_resource_initialization"); // Check if SurfacelessEGL is supported. - g_egl_surfaceless_context_supported = - HasEGLExtension("EGL_KHR_surfaceless_context"); + display->egl_surfaceless_context_supported = + display->HasEGLExtension("EGL_KHR_surfaceless_context"); // TODO(oetuaho@nvidia.com): Surfaceless is disabled on Android as a temporary // workaround, since code written for Android WebView takes different paths @@ -1111,13 +1084,13 @@ #if BUILDFLAG(IS_ANDROID) // Use the WebGL compatibility extension for detecting ANGLE. ANGLE always // exposes it. - bool is_angle = g_egl_create_context_webgl_compatability_supported; + bool is_angle = display->egl_create_context_webgl_compatability_supported; if (!is_angle) { - g_egl_surfaceless_context_supported = false; + display->egl_surfaceless_context_supported = false; } #endif - if (g_egl_surfaceless_context_supported) { + if (display->egl_surfaceless_context_supported) { // EGL_KHR_surfaceless_context is supported but ensure // GL_OES_surfaceless_context is also supported. We need a current context // to query for supported GL extensions. @@ -1125,11 +1098,11 @@ scoped_refptr<GLContext> context = InitializeGLContext( new GLContextEGL(nullptr), surface.get(), GLContextAttribs()); if (!context || !context->MakeCurrent(surface.get())) - g_egl_surfaceless_context_supported = false; + display->egl_surfaceless_context_supported = false; // Ensure context supports GL_OES_surfaceless_context. - if (g_egl_surfaceless_context_supported) { - g_egl_surfaceless_context_supported = + if (display->egl_surfaceless_context_supported) { + display->egl_surfaceless_context_supported = context->HasExtension("GL_OES_surfaceless_context"); context->ReleaseCurrent(surface.get()); } @@ -1144,38 +1117,38 @@ // reported. TODO(https://crbug.com/1086781): Once this is fixed at the // Android level, update the heuristic to trust the reported extension from // that version onward. - g_egl_android_native_fence_sync_supported = - HasEGLExtension("EGL_ANDROID_native_fence_sync"); + display->egl_android_native_fence_sync_supported = + display->HasEGLExtension("EGL_ANDROID_native_fence_sync"); #if BUILDFLAG(IS_ANDROID) - if (!g_egl_android_native_fence_sync_supported && + if (!display->egl_android_native_fence_sync_supported && base::android::BuildInfo::GetInstance()->sdk_int() >= base::android::SDK_VERSION_NOUGAT && g_driver_egl.fn.eglDupNativeFenceFDANDROIDFn && base::SysInfo::GetAndroidHardwareEGL() != "swiftshader" && base::SysInfo::GetAndroidHardwareEGL() != "emulation") { - g_egl_android_native_fence_sync_supported = true; + display->egl_android_native_fence_sync_supported = true; } #endif - g_egl_ext_pixel_format_float_supported = - HasEGLExtension("EGL_EXT_pixel_format_float"); + display->egl_ext_pixel_format_float_supported = + display->HasEGLExtension("EGL_EXT_pixel_format_float"); - g_egl_angle_power_preference_supported = - HasEGLExtension("EGL_ANGLE_power_preference"); + display->egl_angle_power_preference_supported = + display->HasEGLExtension("EGL_ANGLE_power_preference"); - g_egl_angle_external_context_and_surface_supported = - HasEGLExtension("EGL_ANGLE_external_context_and_surface"); + display->egl_angle_external_context_and_surface_supported = + display->HasEGLExtension("EGL_ANGLE_external_context_and_surface"); - g_egl_ext_query_device_supported = - HasEGLClientExtension("EGL_EXT_device_query"); + display->egl_ext_query_device_supported = + display->HasEGLClientExtension("EGL_EXT_device_query"); - g_egl_angle_context_virtualization_supported = - HasEGLExtension("EGL_ANGLE_context_virtualization"); + display->egl_angle_context_virtualization_supported = + display->HasEGLExtension("EGL_ANGLE_context_virtualization"); - g_egl_angle_vulkan_image_supported = - HasEGLExtension("EGL_ANGLE_vulkan_image"); + display->egl_angle_vulkan_image_supported = + display->HasEGLExtension("EGL_ANGLE_vulkan_image"); - if (g_egl_angle_power_preference_supported) { + if (display->egl_angle_power_preference_supported) { g_egl_gpu_switching_observer = new EGLGpuSwitchingObserver(); ui::GpuSwitchingManager::GetInstance()->AddObserver( g_egl_gpu_switching_observer); @@ -1190,9 +1163,10 @@ if (!initialized_) return false; g_driver_egl.UpdateConditionalExtensionBindings(); - g_egl_client_extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); - g_egl_extensions = - eglQueryString(GetOrInitializeGLDisplay()->GetDisplay(), EGL_EXTENSIONS); + GetGLDisplayEGL()->egl_client_extensions = + eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); + GetGLDisplayEGL()->egl_extensions = + eglQueryString(GetGLDisplayEGL()->GetDisplay(), EGL_EXTENSIONS); return true; } @@ -1209,162 +1183,37 @@ delete g_egl_gpu_switching_observer; g_egl_gpu_switching_observer = nullptr; } - angle::ResetPlatform(GetOrInitializeGLDisplay()->GetDisplay()); - if (GetOrInitializeGLDisplay()->GetDisplay() != EGL_NO_DISPLAY) { + GLDisplayEGL* display = GetGLDisplayEGL(); + angle::ResetPlatform(display->GetDisplay()); + if (display->GetDisplay() != EGL_NO_DISPLAY) { DCHECK(g_driver_egl.fn.eglTerminateFn); - eglTerminate(GetOrInitializeGLDisplay()->GetDisplay()); + eglTerminate(display->GetDisplay()); } + display->egl_client_extensions = nullptr; + display->egl_extensions = nullptr; + display->egl_create_context_robustness_supported = false; + display->egl_robustness_video_memory_purge_supported = false; + display->egl_create_context_bind_generates_resource_supported = false; + display->egl_create_context_webgl_compatability_supported = false; + display->egl_sync_control_supported = false; + display->egl_sync_control_rate_supported = false; + display->egl_window_fixed_size_supported = false; + display->egl_surface_orientation_supported = false; + display->egl_surfaceless_context_supported = false; + display->egl_robust_resource_init_supported = false; + display->egl_display_texture_share_group_supported = false; + display->egl_create_context_client_arrays_supported = false; + display->egl_angle_feature_control_supported = false; + if (g_gl_display) { delete g_gl_display; g_gl_display = nullptr; } - g_egl_client_extensions = nullptr; - g_egl_extensions = nullptr; - g_egl_create_context_robustness_supported = false; - g_egl_robustness_video_memory_purge_supported = false; - g_egl_create_context_bind_generates_resource_supported = false; - g_egl_create_context_webgl_compatability_supported = false; - g_egl_sync_control_supported = false; - g_egl_sync_control_rate_supported = false; - g_egl_window_fixed_size_supported = false; - g_egl_surface_orientation_supported = false; - g_egl_surfaceless_context_supported = false; - g_egl_robust_resource_init_supported = false; - g_egl_display_texture_share_group_supported = false; - g_egl_create_context_client_arrays_supported = false; - g_egl_angle_feature_control_supported = false; - initialized_ = false; } -// static -EGLDisplay GLSurfaceEGL::GetHardwareDisplay() { - return GetOrInitializeGLDisplay()->GetDisplay(); -} - -// static -EGLNativeDisplayType GLSurfaceEGL::GetNativeDisplay() { - return g_native_display.GetDisplay(); -} - -// static -DisplayType GLSurfaceEGL::GetDisplayType() { - return g_display_type; -} - -// static -const char* GLSurfaceEGL::GetEGLClientExtensions() { - return g_egl_client_extensions ? g_egl_client_extensions : ""; -} - -// static -const char* GLSurfaceEGL::GetEGLExtensions() { - return g_egl_extensions; -} - -// static -bool GLSurfaceEGL::HasEGLClientExtension(const char* name) { - return ExtensionsContain(GetEGLClientExtensions(), name); -} - -// static -bool GLSurfaceEGL::HasEGLExtension(const char* name) { - return ExtensionsContain(GetEGLExtensions(), name); -} - -// static -bool GLSurfaceEGL::IsCreateContextRobustnessSupported() { - return g_egl_create_context_robustness_supported; -} - -// static -bool GLSurfaceEGL::IsRobustnessVideoMemoryPurgeSupported() { - return g_egl_robustness_video_memory_purge_supported; -} - -bool GLSurfaceEGL::IsCreateContextBindGeneratesResourceSupported() { - return g_egl_create_context_bind_generates_resource_supported; -} - -bool GLSurfaceEGL::IsCreateContextWebGLCompatabilitySupported() { - return g_egl_create_context_webgl_compatability_supported; -} - -// static -bool GLSurfaceEGL::IsEGLSurfacelessContextSupported() { - return g_egl_surfaceless_context_supported; -} - -// static -bool GLSurfaceEGL::IsEGLContextPrioritySupported() { - return g_egl_context_priority_supported; -} - -// static -bool GLSurfaceEGL::IsEGLNoConfigContextSupported() { - return g_egl_no_config_context_supported; -} - -bool GLSurfaceEGL::IsRobustResourceInitSupported() { - return g_egl_robust_resource_init_supported; -} - -bool GLSurfaceEGL::IsDisplayTextureShareGroupSupported() { - return g_egl_display_texture_share_group_supported; -} - -bool GLSurfaceEGL::IsDisplaySemaphoreShareGroupSupported() { - return g_egl_display_semaphore_share_group_supported; -} - -bool GLSurfaceEGL::IsCreateContextClientArraysSupported() { - return g_egl_create_context_client_arrays_supported; -} - -bool GLSurfaceEGL::IsAndroidNativeFenceSyncSupported() { - return g_egl_android_native_fence_sync_supported; -} - -bool GLSurfaceEGL::IsPixelFormatFloatSupported() { - return g_egl_ext_pixel_format_float_supported; -} - -bool GLSurfaceEGL::IsANGLEFeatureControlSupported() { - return g_egl_angle_feature_control_supported; -} - -bool GLSurfaceEGL::IsANGLEPowerPreferenceSupported() { - return g_egl_angle_power_preference_supported; -} - -bool GLSurfaceEGL::IsANGLEDisplayPowerPreferenceSupported() { - return g_egl_angle_display_power_preference_supported; -} - -bool GLSurfaceEGL::IsANGLEPlatformANGLEDeviceIdSupported() { - return g_egl_angle_platform_angle_device_id_supported; -} - -bool GLSurfaceEGL::IsANGLEExternalContextAndSurfaceSupported() { - return g_egl_angle_external_context_and_surface_supported; -} - -// static -bool GLSurfaceEGL::IsANGLEContextVirtualizationSupported() { - return g_egl_angle_context_virtualization_supported; -} - -// static -bool GLSurfaceEGL::IsANGLEVulkanImageSupported() { - return g_egl_angle_vulkan_image_supported; -} - -bool GLSurfaceEGL::IsEGLQueryDeviceSupported() { - return g_egl_ext_query_device_supported; -} - GLSurfaceEGL::~GLSurfaceEGL() = default; // InitializeDisplay is necessary because the static binding code @@ -1372,18 +1221,19 @@ // static GLDisplayEGL* GLSurfaceEGL::InitializeDisplay(EGLDisplayPlatform native_display, uint64_t system_device_id) { - GLDisplayEGL* gl_display = GetOrInitializeGLDisplay(); + GLDisplayEGL* gl_display = GetGLDisplayEGL(); if (gl_display->GetDisplay() != EGL_NO_DISPLAY) { return gl_display; } - g_native_display = native_display; + gl_display->native_display = native_display; // If EGL_EXT_client_extensions not supported this call to eglQueryString // will return nullptr. - g_egl_client_extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); + gl_display->egl_client_extensions = + eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); - bool supports_egl_debug = HasEGLClientExtension("EGL_KHR_debug"); + bool supports_egl_debug = gl_display->HasEGLClientExtension("EGL_KHR_debug"); if (supports_egl_debug) { EGLAttrib controls[] = { EGL_DEBUG_MSG_CRITICAL_KHR, @@ -1409,34 +1259,35 @@ bool supports_angle_egl = false; bool supports_angle_metal = false; // Check for availability of ANGLE extensions. - if (HasEGLClientExtension("EGL_ANGLE_platform_angle")) { - supports_angle_d3d = HasEGLClientExtension("EGL_ANGLE_platform_angle_d3d"); + if (gl_display->HasEGLClientExtension("EGL_ANGLE_platform_angle")) { + supports_angle_d3d = + gl_display->HasEGLClientExtension("EGL_ANGLE_platform_angle_d3d"); supports_angle_opengl = - HasEGLClientExtension("EGL_ANGLE_platform_angle_opengl"); + gl_display->HasEGLClientExtension("EGL_ANGLE_platform_angle_opengl"); supports_angle_null = - HasEGLClientExtension("EGL_ANGLE_platform_angle_null"); + gl_display->HasEGLClientExtension("EGL_ANGLE_platform_angle_null"); supports_angle_vulkan = - HasEGLClientExtension("EGL_ANGLE_platform_angle_vulkan"); - supports_angle_swiftshader = HasEGLClientExtension( + gl_display->HasEGLClientExtension("EGL_ANGLE_platform_angle_vulkan"); + supports_angle_swiftshader = gl_display->HasEGLClientExtension( "EGL_ANGLE_platform_angle_device_type_swiftshader"); - supports_angle_egl = - HasEGLClientExtension("EGL_ANGLE_platform_angle_device_type_egl_angle"); + supports_angle_egl = gl_display->HasEGLClientExtension( + "EGL_ANGLE_platform_angle_device_type_egl_angle"); supports_angle_metal = - HasEGLClientExtension("EGL_ANGLE_platform_angle_metal"); + gl_display->HasEGLClientExtension("EGL_ANGLE_platform_angle_metal"); } bool supports_angle = supports_angle_d3d || supports_angle_opengl || supports_angle_null || supports_angle_vulkan || supports_angle_swiftshader || supports_angle_metal; - g_egl_angle_feature_control_supported = - HasEGLClientExtension("EGL_ANGLE_feature_control"); + gl_display->egl_angle_feature_control_supported = + gl_display->HasEGLClientExtension("EGL_ANGLE_feature_control"); - g_egl_angle_display_power_preference_supported = - HasEGLClientExtension("EGL_ANGLE_display_power_preference"); + gl_display->egl_angle_display_power_preference_supported = + gl_display->HasEGLClientExtension("EGL_ANGLE_display_power_preference"); - g_egl_angle_platform_angle_device_id_supported = - HasEGLClientExtension("EGL_ANGLE_platform_angle_device_id"); + gl_display->egl_angle_platform_angle_device_id_supported = + gl_display->HasEGLClientExtension("EGL_ANGLE_platform_angle_device_id"); std::vector<DisplayType> init_displays; base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); @@ -1458,7 +1309,7 @@ for (size_t disp_index = 0; disp_index < init_displays.size(); ++disp_index) { DisplayType display_type = init_displays[disp_index]; EGLDisplay display = GetDisplayFromType( - display_type, g_native_display, enabled_angle_features, + display_type, gl_display->native_display, enabled_angle_features, disabled_angle_features, disable_all_angle_features, system_device_id); if (display == EGL_NO_DISPLAY) { LOG(ERROR) << "EGL display query failed with error " @@ -1507,7 +1358,7 @@ UMA_HISTOGRAM_ENUMERATION("GPU.EGLDisplayType", display_type, DISPLAY_TYPE_MAX); gl_display->SetDisplay(display); - g_display_type = display_type; + gl_display->display_type = display_type; break; } @@ -1534,7 +1385,8 @@ DCHECK(!surface_); format_ = format; - if (!GetEGLDisplay()) { + GLDisplayEGL* display = GetGLDisplayEGL(); + if (!display->GetDisplay()) { LOG(ERROR) << "Trying to create surface with invalid display."; return false; } @@ -1548,7 +1400,7 @@ std::vector<EGLint> egl_window_attributes; - if (g_egl_window_fixed_size_supported && enable_fixed_size_angle_) { + if (display->egl_window_fixed_size_supported && enable_fixed_size_angle_) { egl_window_attributes.push_back(EGL_FIXED_SIZE_ANGLE); egl_window_attributes.push_back(EGL_TRUE); egl_window_attributes.push_back(EGL_WIDTH); @@ -1562,9 +1414,9 @@ egl_window_attributes.push_back(EGL_TRUE); } - if (g_egl_surface_orientation_supported) { + if (display->egl_surface_orientation_supported) { EGLint attrib; - eglGetConfigAttrib(GetEGLDisplay(), GetConfig(), + eglGetConfigAttrib(display->GetDisplay(), GetConfig(), EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE, &attrib); surface_origin_ = (attrib == EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE) ? gfx::SurfaceOrigin::kTopLeft @@ -1583,7 +1435,7 @@ // Note that COLORSPACE_LINEAR refers to the sRGB color space, but // without opting into sRGB blending. It is equivalent to // COLORSPACE_SRGB with Disable(FRAMEBUFFER_SRGB). - if (g_egl_khr_colorspace) { + if (display->egl_khr_colorspace) { egl_window_attributes.push_back(EGL_GL_COLORSPACE_KHR); egl_window_attributes.push_back(EGL_GL_COLORSPACE_LINEAR_KHR); } @@ -1597,15 +1449,15 @@ // with the P3 gamut instead of the the sRGB gamut. // COLORSPACE_DISPLAY_P3_LINEAR has a linear transfer function, and is // intended for use with 16-bit formats. - bool p3_supported = g_egl_ext_colorspace_display_p3 || - g_egl_ext_colorspace_display_p3_passthrough; - if (g_egl_khr_colorspace && p3_supported) { + bool p3_supported = display->egl_ext_colorspace_display_p3 || + display->egl_ext_colorspace_display_p3_passthrough; + if (display->egl_khr_colorspace && p3_supported) { egl_window_attributes.push_back(EGL_GL_COLORSPACE_KHR); // Chrome relied on incorrect Android behavior when dealing with P3 / // framebuffer_srgb interactions. This behavior was fixed in Q, which // causes invalid Chrome rendering. To achieve Android-P behavior in Q+, // use EGL_GL_COLORSPACE_P3_PASSTHROUGH_EXT where possible. - if (g_egl_ext_colorspace_display_p3_passthrough) { + if (display->egl_ext_colorspace_display_p3_passthrough) { egl_window_attributes.push_back( EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT); } else { @@ -1617,7 +1469,7 @@ egl_window_attributes.push_back(EGL_NONE); // Create a surface for the native window. - surface_ = eglCreateWindowSurface(GetEGLDisplay(), GetConfig(), window_, + surface_ = eglCreateWindowSurface(display->GetDisplay(), GetConfig(), window_, &egl_window_attributes[0]); if (!surface_) { @@ -1630,7 +1482,7 @@ if (g_driver_egl.ext.b_EGL_NV_post_sub_buffer) { EGLint surfaceVal; EGLBoolean retVal = - eglQuerySurface(GetEGLDisplay(), surface_, + eglQuerySurface(display->GetDisplay(), surface_, EGL_POST_SUB_BUFFER_SUPPORTED_NV, &surfaceVal); supports_post_sub_buffer_ = (surfaceVal && retVal) == EGL_TRUE; } @@ -2235,7 +2087,7 @@ // Enable robust resource init when using SwANGLE if (IsSoftwareGLImplementation(GetGLImplementationParts()) && - GLSurfaceEGL::IsRobustResourceInitSupported()) { + GLSurfaceEGL::GetGLDisplayEGL()->IsRobustResourceInitSupported()) { pbuffer_attribs.push_back(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE); pbuffer_attribs.push_back(EGL_TRUE); }
diff --git a/ui/gl/gl_surface_egl.h b/ui/gl/gl_surface_egl.h index 96cf88ec..12f3da9 100644 --- a/ui/gl/gl_surface_egl.h +++ b/ui/gl/gl_surface_egl.h
@@ -30,52 +30,8 @@ namespace gl { -class EGLDisplayPlatform { - public: - constexpr EGLDisplayPlatform() - : display_(EGL_DEFAULT_DISPLAY), platform_(0), valid_(false) {} - explicit constexpr EGLDisplayPlatform(EGLNativeDisplayType display, - int platform = 0) - : display_(display), platform_(platform), valid_(true) {} - - bool Valid() const { return valid_; } - int GetPlatform() const { return platform_; } - EGLNativeDisplayType GetDisplay() const { return display_; } - - private: - EGLNativeDisplayType display_; - // 0 for default, or EGL_PLATFORM_* enum. - int platform_; - bool valid_; -}; - class GLSurfacePresentationHelper; -// If adding a new type, also add it to EGLDisplayType in -// tools/metrics/histograms/enums.xml. Don't remove or reorder entries. -enum DisplayType { - DEFAULT = 0, - SWIFT_SHADER = 1, - ANGLE_WARP = 2, - ANGLE_D3D9 = 3, - ANGLE_D3D11 = 4, - ANGLE_OPENGL = 5, - ANGLE_OPENGLES = 6, - ANGLE_NULL = 7, - ANGLE_D3D11_NULL = 8, - ANGLE_OPENGL_NULL = 9, - ANGLE_OPENGLES_NULL = 10, - ANGLE_VULKAN = 11, - ANGLE_VULKAN_NULL = 12, - ANGLE_D3D11on12 = 13, - ANGLE_SWIFTSHADER = 14, - ANGLE_OPENGL_EGL = 15, - ANGLE_OPENGLES_EGL = 16, - ANGLE_METAL = 17, - ANGLE_METAL_NULL = 18, - DISPLAY_TYPE_MAX = 19, -}; - GL_EXPORT void GetEGLInitDisplays(bool supports_angle_d3d, bool supports_angle_opengl, bool supports_angle_null, @@ -102,6 +58,8 @@ EGLDisplay GetEGLDisplay(); + static GLDisplayEGL* GetGLDisplayEGL(); + // |system_device_id| specifies which GPU to use on a multi-GPU system. // If its value is 0, use the default GPU of the system. static bool InitializeOneOff(EGLDisplayPlatform native_display, @@ -109,42 +67,10 @@ static bool InitializeOneOffForTesting(); static bool InitializeExtensionSettingsOneOff(); static void ShutdownOneOff(); - static EGLDisplay GetHardwareDisplay(); // |system_device_id| specifies which GPU to use on a multi-GPU system. // If its value is 0, use the default GPU of the system. static GLDisplayEGL* InitializeDisplay(EGLDisplayPlatform native_display, uint64_t system_device_id); - static EGLNativeDisplayType GetNativeDisplay(); - static DisplayType GetDisplayType(); - - // These aren't particularly tied to surfaces, but since we already - // have the static InitializeOneOff here, it's easiest to reuse its - // initialization guards. - static const char* GetEGLClientExtensions(); - static const char* GetEGLExtensions(); - static bool HasEGLClientExtension(const char* name); - static bool HasEGLExtension(const char* name); - static bool IsCreateContextRobustnessSupported(); - static bool IsRobustnessVideoMemoryPurgeSupported(); - static bool IsCreateContextBindGeneratesResourceSupported(); - static bool IsCreateContextWebGLCompatabilitySupported(); - static bool IsEGLSurfacelessContextSupported(); - static bool IsEGLContextPrioritySupported(); - static bool IsEGLNoConfigContextSupported(); - static bool IsRobustResourceInitSupported(); - static bool IsDisplayTextureShareGroupSupported(); - static bool IsDisplaySemaphoreShareGroupSupported(); - static bool IsCreateContextClientArraysSupported(); - static bool IsAndroidNativeFenceSyncSupported(); - static bool IsPixelFormatFloatSupported(); - static bool IsANGLEFeatureControlSupported(); - static bool IsANGLEPowerPreferenceSupported(); - static bool IsANGLEDisplayPowerPreferenceSupported(); - static bool IsANGLEPlatformANGLEDeviceIdSupported(); - static bool IsANGLEExternalContextAndSurfaceSupported(); - static bool IsANGLEContextVirtualizationSupported(); - static bool IsANGLEVulkanImageSupported(); - static bool IsEGLQueryDeviceSupported(); protected: ~GLSurfaceEGL() override;
diff --git a/ui/gl/gl_surface_egl_x11_gles2.cc b/ui/gl/gl_surface_egl_x11_gles2.cc index 223f9e8..23b76ef 100644 --- a/ui/gl/gl_surface_egl_x11_gles2.cc +++ b/ui/gl/gl_surface_egl_x11_gles2.cc
@@ -92,7 +92,7 @@ EGL_NONE}; config_attribs[kBufferSizeOffset] = geometry->depth; - EGLDisplay display = GetHardwareDisplay(); + EGLDisplay display = GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(); x11::VisualId visual_id; ui::XVisualManager::GetInstance()->ChooseVisualForWindow( true, &visual_id, nullptr, nullptr, nullptr);
diff --git a/ui/gl/gl_utils.cc b/ui/gl/gl_utils.cc index ba56ce4..2ff24c8 100644 --- a/ui/gl/gl_utils.cc +++ b/ui/gl/gl_utils.cc
@@ -100,13 +100,14 @@ bool PassthroughCommandDecoderSupported() { #if defined(USE_EGL) + GLDisplayEGL* display = gl::GLSurfaceEGL::GetGLDisplayEGL(); // Using the passthrough command buffer requires that specific ANGLE // extensions are exposed - return gl::GLSurfaceEGL::IsCreateContextBindGeneratesResourceSupported() && - gl::GLSurfaceEGL::IsCreateContextWebGLCompatabilitySupported() && - gl::GLSurfaceEGL::IsRobustResourceInitSupported() && - gl::GLSurfaceEGL::IsDisplayTextureShareGroupSupported() && - gl::GLSurfaceEGL::IsCreateContextClientArraysSupported(); + return display->IsCreateContextBindGeneratesResourceSupported() && + display->IsCreateContextWebGLCompatabilitySupported() && + display->IsRobustResourceInitSupported() && + display->IsDisplayTextureShareGroupSupported() && + display->IsCreateContextClientArraysSupported(); #else // The passthrough command buffer is only supported on top of ANGLE/EGL return false;
diff --git a/ui/gl/init/gl_factory_android.cc b/ui/gl/init/gl_factory_android.cc index 73fd52a..039e13b 100644 --- a/ui/gl/init/gl_factory_android.cc +++ b/ui/gl/init/gl_factory_android.cc
@@ -140,7 +140,7 @@ switch (GetGLImplementation()) { case kGLImplementationEGLGLES2: case kGLImplementationEGLANGLE: { - if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() && + if (GLSurfaceEGL::GetGLDisplayEGL()->IsEGLSurfacelessContextSupported() && (size.width() == 0 && size.height() == 0)) { return InitializeGLSurfaceWithFormat(new SurfacelessEGL(size), format); } else {
diff --git a/ui/gl/init/gl_factory_mac.cc b/ui/gl/init/gl_factory_mac.cc index 9cf7edf..7cae0d3 100644 --- a/ui/gl/init/gl_factory_mac.cc +++ b/ui/gl/init/gl_factory_mac.cc
@@ -141,7 +141,7 @@ #if defined(USE_EGL) case kGLImplementationEGLGLES2: case kGLImplementationEGLANGLE: - if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() && + if (GLSurfaceEGL::GetGLDisplayEGL()->IsEGLSurfacelessContextSupported() && size.width() == 0 && size.height() == 0) { return InitializeGLSurfaceWithFormat(new SurfacelessEGL(size), format); } else {
diff --git a/ui/gl/init/gl_factory_win.cc b/ui/gl/init/gl_factory_win.cc index a938498f..9356c32 100644 --- a/ui/gl/init/gl_factory_win.cc +++ b/ui/gl/init/gl_factory_win.cc
@@ -81,7 +81,7 @@ TRACE_EVENT0("gpu", "gl::init::CreateOffscreenGLSurface"); switch (GetGLImplementation()) { case kGLImplementationEGLANGLE: - if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() && + if (GLSurfaceEGL::GetGLDisplayEGL()->IsEGLSurfacelessContextSupported() && size.width() == 0 && size.height() == 0) { return InitializeGLSurfaceWithFormat(new SurfacelessEGL(size), format); } else {
diff --git a/ui/gtk/input_method_context_impl_gtk.cc b/ui/gtk/input_method_context_impl_gtk.cc index d0f6840..6d6e2e9 100644 --- a/ui/gtk/input_method_context_impl_gtk.cc +++ b/ui/gtk/input_method_context_impl_gtk.cc
@@ -251,8 +251,9 @@ gdk_last_set_client_window_ = window; } -void InputMethodContextImplGtk::SetContentType(ui::TextInputType input_type, - int input_flags, +void InputMethodContextImplGtk::SetContentType(ui::TextInputType type, + ui::TextInputMode mode, + uint32_t flags, bool should_do_learning) { // Do nothing. }
diff --git a/ui/gtk/input_method_context_impl_gtk.h b/ui/gtk/input_method_context_impl_gtk.h index 1d485bb..e501519 100644 --- a/ui/gtk/input_method_context_impl_gtk.h +++ b/ui/gtk/input_method_context_impl_gtk.h
@@ -39,8 +39,9 @@ void Blur() override; void SetSurroundingText(const std::u16string& text, const gfx::Range& selection_range) override; - void SetContentType(ui::TextInputType input_type, - int input_flags, + void SetContentType(ui::TextInputType type, + ui::TextInputMode mode, + uint32_t flags, bool should_do_learning) override; ui::VirtualKeyboardController* GetVirtualKeyboardController() override;
diff --git a/ui/message_center/popup_timers_controller.cc b/ui/message_center/popup_timers_controller.cc index 501d70d..0c3004f 100644 --- a/ui/message_center/popup_timers_controller.cc +++ b/ui/message_center/popup_timers_controller.cc
@@ -119,29 +119,37 @@ return; } + // Group child notifications are contained in a parent popup, we must reset + // the parent popup's timer when they are displayed or updated. + auto* notification = message_center_->FindNotificationById(id); + const std::string& popup_id = + notification->group_child() + ? message_center_->FindParentNotification(notification)->id() + : id; + auto iter = popup_notifications.begin(); for (; iter != popup_notifications.end(); ++iter) { - if ((*iter)->id() == id) + if ((*iter)->id() == popup_id) break; } if (iter == popup_notifications.end() || (*iter)->never_timeout()) { - CancelTimer(id); + CancelTimer(popup_id); return; } - auto timer = popup_timers_.find(id); + auto timer = popup_timers_.find(popup_id); // The timer must already have been started and not be running. Relies on // the invariant that |popup_timers_| only contains timers that have been // started. bool was_paused = timer != popup_timers_.end() && !timer->second->IsRunning(); - CancelTimer(id); - StartTimer(id, GetTimeoutForNotification(*iter)); + CancelTimer(popup_id); + StartTimer(popup_id, GetTimeoutForNotification(*iter)); // If a timer was paused before, pause it afterwards as well. // See crbug.com/710298 if (was_paused) { - popup_timers_.find(id)->second->Pause(); + popup_timers_.find(popup_id)->second->Pause(); } }
diff --git a/ui/message_center/views/notification_view.cc b/ui/message_center/views/notification_view.cc index 70b3209..a438d82 100644 --- a/ui/message_center/views/notification_view.cc +++ b/ui/message_center/views/notification_view.cc
@@ -271,6 +271,8 @@ header_row->ConfigureLabelsStyle(font_list, text_view_padding, false); header_row->SetPreferredSize(header_row->GetPreferredSize() - gfx::Size(GetInsets().width(), 0)); + header_row->SetCallback(base::BindRepeating( + &NotificationView::HeaderRowPressed, base::Unretained(this))); header_row->AddChildView(CreateControlButtonsBuilder().Build()); auto content_row = CreateContentRowBuilder() @@ -652,4 +654,21 @@ settings_done_button_}; } +void NotificationView::HeaderRowPressed() { + if (!IsExpandable() || !content_row()->GetVisible()) + return; + + // Tapping anywhere on |header_row_| can expand the notification, though only + // |expand_button| can be focused by TAB. + SetManuallyExpandedOrCollapsed(true); + auto weak_ptr = weak_ptr_factory_.GetWeakPtr(); + SetExpanded(!IsExpanded()); + // Check |this| is valid before continuing, because ToggleExpanded() might + // cause |this| to be deleted. + if (!weak_ptr) + return; + Layout(); + SchedulePaint(); +} + } // namespace message_center
diff --git a/ui/message_center/views/notification_view.h b/ui/message_center/views/notification_view.h index a638885..c914753 100644 --- a/ui/message_center/views/notification_view.h +++ b/ui/message_center/views/notification_view.h
@@ -71,6 +71,8 @@ // destroyed when the ink drop is visible. std::vector<views::View*> GetChildrenForLayerAdjustment(); + void HeaderRowPressed(); + // Notification title, which is dynamically created inside view hierarchy. raw_ptr<views::Label> title_view_ = nullptr; @@ -85,6 +87,8 @@ // Owned by views properties. Guaranteed to be not null for the lifetime of // |this| because views properties are the last thing cleaned up. raw_ptr<NotificationViewPathGenerator> highlight_path_generator_ = nullptr; + + base::WeakPtrFactory<NotificationView> weak_ptr_factory_{this}; }; } // namespace message_center
diff --git a/ui/message_center/views/notification_view_base.cc b/ui/message_center/views/notification_view_base.cc index 9afd4301..a806e188 100644 --- a/ui/message_center/views/notification_view_base.cc +++ b/ui/message_center/views/notification_view_base.cc
@@ -453,10 +453,6 @@ auto header_row_builder = views::Builder<NotificationHeaderView>() .SetID(kHeaderRow) .CopyAddressTo(&header_row_); - if (!for_ash_notification_) { - header_row_builder.SetCallback(base::BindRepeating( - &NotificationViewBase::HeaderRowPressed, base::Unretained(this))); - } return header_row_builder; } @@ -818,23 +814,6 @@ left_content_->ReorderChildView(view, left_content_count_++); } -void NotificationViewBase::HeaderRowPressed() { - if (!IsExpandable() || !content_row_->GetVisible()) - return; - - // Tapping anywhere on |header_row_| can expand the notification, though only - // |expand_button| can be focused by TAB. - SetManuallyExpandedOrCollapsed(true); - auto weak_ptr = weak_ptr_factory_.GetWeakPtr(); - ToggleExpanded(); - // Check |this| is valid before continuing, because ToggleExpanded() might - // cause |this| to be deleted. - if (!weak_ptr) - return; - Layout(); - SchedulePaint(); -} - void NotificationViewBase::ActionButtonPressed(size_t index, const ui::Event& event) { const absl::optional<std::u16string>& placeholder = @@ -869,10 +848,6 @@ header_row_->SetExpandButtonEnabled(enabled); } -void NotificationViewBase::ToggleExpanded() { - SetExpanded(!expanded_); -} - void NotificationViewBase::UpdateViewForExpandedState(bool expanded) { if (!for_ash_notification_) header_row_->SetExpanded(expanded);
diff --git a/ui/message_center/views/notification_view_base.h b/ui/message_center/views/notification_view_base.h index b2574e3..4108c0e 100644 --- a/ui/message_center/views/notification_view_base.h +++ b/ui/message_center/views/notification_view_base.h
@@ -291,8 +291,6 @@ FRIEND_TEST_ALL_PREFIXES(NotificationViewBaseTest, AppNameWebNotification); FRIEND_TEST_ALL_PREFIXES(NotificationViewBaseTest, AppNameWebAppNotification); FRIEND_TEST_ALL_PREFIXES(NotificationViewBaseTest, CreateOrUpdateTest); - FRIEND_TEST_ALL_PREFIXES(NotificationViewBaseTest, - ManuallyExpandedOrCollapsed); FRIEND_TEST_ALL_PREFIXES(NotificationViewBaseTest, InlineSettings); FRIEND_TEST_ALL_PREFIXES(NotificationViewBaseTest, InlineSettingsInkDropAnimation); @@ -321,6 +319,7 @@ FRIEND_TEST_ALL_PREFIXES(NotificationViewBaseTest, UseImageAsIcon); FRIEND_TEST_ALL_PREFIXES(NotificationViewTest, TestIconSizing); FRIEND_TEST_ALL_PREFIXES(NotificationViewTest, LeftContentResizeForIcon); + FRIEND_TEST_ALL_PREFIXES(NotificationViewTest, ManuallyExpandedOrCollapsed); FRIEND_TEST_ALL_PREFIXES(NotificationViewTest, InlineSettingsNotBlock); FRIEND_TEST_ALL_PREFIXES(NotificationViewTest, InlineSettingsBlockAll); FRIEND_TEST_ALL_PREFIXES(NotificationViewTest, TestAccentColor); @@ -337,10 +336,6 @@ void CreateOrUpdateImageView(const Notification& notification); void CreateOrUpdateActionButtonViews(const Notification& notification); - void HeaderRowPressed(); - - void ToggleExpanded(); - // View containing close and settings buttons NotificationControlButtonsView* control_buttons_view_ = nullptr;
diff --git a/ui/message_center/views/notification_view_base_unittest.cc b/ui/message_center/views/notification_view_base_unittest.cc index 4889ea43..b9f821d 100644 --- a/ui/message_center/views/notification_view_base_unittest.cc +++ b/ui/message_center/views/notification_view_base_unittest.cc
@@ -180,6 +180,10 @@ delete_on_preferred_size_changed_ = delete_on_preferred_size_changed; } + void ToggleExpanded() { + notification_view_->SetExpanded(!notification_view_->IsExpanded()); + } + protected: const gfx::Image CreateTestImage(int width, int height) const; const SkBitmap CreateBitmap(int width, int height) const; @@ -389,7 +393,7 @@ notification->set_buttons(CreateButtons(0)); notification_view()->CreateOrUpdateViews(*notification); // Expand, and add buttons. - notification_view()->ToggleExpanded(); + ToggleExpanded(); EXPECT_TRUE(notification_view()->expanded_); notification->set_buttons(CreateButtons(2)); notification_view()->CreateOrUpdateViews(*notification); @@ -433,7 +437,7 @@ // Action buttons are hidden by collapsed state. if (!notification_view()->expanded_) - notification_view()->ToggleExpanded(); + ToggleExpanded(); EXPECT_TRUE(notification_view()->actions_row_->GetVisible()); EXPECT_EQ(views::Button::STATE_NORMAL, @@ -485,7 +489,7 @@ // Action buttons are hidden by collapsed state. if (!notification_view()->expanded_) - notification_view()->ToggleExpanded(); + ToggleExpanded(); EXPECT_TRUE(notification_view()->actions_row_->GetVisible()); // Now construct a mouse click event inside the boundary of the action button. @@ -520,7 +524,7 @@ // Action buttons are hidden by collapsed state. if (!notification_view()->expanded_) - notification_view()->ToggleExpanded(); + ToggleExpanded(); EXPECT_TRUE(notification_view()->actions_row_->GetVisible()); // Now construct a mouse click event inside the boundary of the action button. @@ -536,8 +540,8 @@ // Toggling should hide the inline textfield. EXPECT_TRUE(notification_view()->inline_reply_->GetVisible()); - notification_view()->ToggleExpanded(); - notification_view()->ToggleExpanded(); + ToggleExpanded(); + ToggleExpanded(); EXPECT_FALSE(notification_view()->inline_reply_->GetVisible()); // Click the button again and the inline textfield should be focused. @@ -609,7 +613,7 @@ // Action buttons are hidden by collapsed state. if (!notification_view()->expanded_) - notification_view()->ToggleExpanded(); + ToggleExpanded(); EXPECT_TRUE(notification_view()->actions_row_->GetVisible()); // Now construct a mouse click event inside the boundary of the action button. @@ -656,7 +660,7 @@ // Action buttons are hidden by collapsed state. if (!notification_view()->expanded_) - notification_view()->ToggleExpanded(); + ToggleExpanded(); ui::test::EventGenerator generator( GetRootWindow(notification_view()->GetWidget())); @@ -839,22 +843,6 @@ #endif // BUILDFLAG(IS_CHROMEOS_ASH) -TEST_F(NotificationViewBaseTest, ManuallyExpandedOrCollapsed) { - // Test |manually_expanded_or_collapsed| being set when the toggle is done by - // user interaction. - EXPECT_FALSE(notification_view()->IsManuallyExpandedOrCollapsed()); - - // Construct a mouse click event inside the header. - gfx::Point done_cursor_location = - notification_view()->header_row_->GetBoundsInScreen().CenterPoint(); - ui::test::EventGenerator generator( - GetRootWindow(notification_view()->GetWidget())); - generator.MoveMouseTo(done_cursor_location); - generator.ClickLeftButton(); - - EXPECT_TRUE(notification_view()->IsManuallyExpandedOrCollapsed()); -} - TEST_F(NotificationViewBaseTest, UseImageAsIcon) { // TODO(tetsui): Remove duplicated integer literal in CreateOrUpdateIconView. const int kIconSize = 30; @@ -871,12 +859,12 @@ EXPECT_TRUE(notification_view()->right_content_->GetVisible()); // Icon on the right side is still visible when expanded. - notification_view()->ToggleExpanded(); + ToggleExpanded(); EXPECT_TRUE(notification_view()->expanded_); EXPECT_TRUE(notification_view()->icon_view_->GetVisible()); EXPECT_TRUE(notification_view()->right_content_->GetVisible()); - notification_view()->ToggleExpanded(); + ToggleExpanded(); EXPECT_FALSE(notification_view()->expanded_); // Test notification with |use_image_for_icon| e.g. screenshot preview. @@ -886,7 +874,7 @@ EXPECT_TRUE(notification_view()->right_content_->GetVisible()); // Icon on the right side is not visible when expanded. - notification_view()->ToggleExpanded(); + ToggleExpanded(); EXPECT_TRUE(notification_view()->expanded_); EXPECT_TRUE(notification_view()->icon_view_->GetVisible()); EXPECT_FALSE(notification_view()->right_content_->GetVisible()); @@ -903,7 +891,7 @@ EXPECT_FALSE(notification_view()->right_content_->GetVisible()); // Toggling should not affect the icon. - notification_view()->ToggleExpanded(); + ToggleExpanded(); EXPECT_FALSE(notification_view()->icon_view_); EXPECT_FALSE(notification_view()->right_content_->GetVisible()); } @@ -999,7 +987,7 @@ // Collapse the notification if it's expanded. if (notification_view()->expanded_) - notification_view()->ToggleExpanded(); + ToggleExpanded(); EXPECT_FALSE(notification_view()->actions_row_->GetVisible()); // Now construct a mouse click event 2 pixel inside from the bottom. @@ -1023,7 +1011,7 @@ // Expand the notification if it's collapsed. if (!notification_view()->expanded_) - notification_view()->ToggleExpanded(); + ToggleExpanded(); EXPECT_FALSE(notification_view()->actions_row_->GetVisible()); // Now construct a mouse click event 2 pixel inside from the bottom. @@ -1061,7 +1049,7 @@ u"labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud " u"exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."); UpdateNotificationViews(*notification); - notification_view()->ToggleExpanded(); + ToggleExpanded(); // Get the height of the message view with a short title. const int message_height = notification_view()->message_label_->height();
diff --git a/ui/message_center/views/notification_view_unittest.cc b/ui/message_center/views/notification_view_unittest.cc index 522bd4c5..09a16ec 100644 --- a/ui/message_center/views/notification_view_unittest.cc +++ b/ui/message_center/views/notification_view_unittest.cc
@@ -225,6 +225,10 @@ return rect.size(); } + void ToggleExpanded() { + notification_view_->SetExpanded(!notification_view_->IsExpanded()); + } + // Toggle inline settings with a dummy event. void ToggleInlineSettings() { notification_view_->ToggleInlineSettings(DummyEvent()); @@ -391,6 +395,22 @@ EXPECT_LT(notification_view()->left_content_->width(), left_content_width); } +TEST_F(NotificationViewTest, ManuallyExpandedOrCollapsed) { + // Test |manually_expanded_or_collapsed| being set when the toggle is done by + // user interaction. + EXPECT_FALSE(notification_view()->IsManuallyExpandedOrCollapsed()); + + // Construct a mouse click event inside the header. + gfx::Point done_cursor_location = + notification_view()->header_row_->GetBoundsInScreen().CenterPoint(); + ui::test::EventGenerator generator( + GetRootWindow(notification_view()->GetWidget())); + generator.MoveMouseTo(done_cursor_location); + generator.ClickLeftButton(); + + EXPECT_TRUE(notification_view()->IsManuallyExpandedOrCollapsed()); +} + TEST_F(NotificationViewTest, InlineSettingsNotBlock) { std::unique_ptr<Notification> notification = CreateSimpleNotification(); notification->set_type(NOTIFICATION_TYPE_SIMPLE); @@ -461,7 +481,7 @@ // Action buttons are hidden by collapsed state. if (!notification_view()->expanded_) - notification_view()->ToggleExpanded(); + ToggleExpanded(); EXPECT_TRUE(notification_view()->actions_row_->GetVisible()); const auto* color_provider = notification_view()->GetColorProvider(); @@ -647,13 +667,13 @@ EXPECT_LT(0, collapsed_height); EXPECT_LT(0, collapsed_preferred_height); - notification_view()->ToggleExpanded(); + ToggleExpanded(); EXPECT_TRUE(notification_view()->expanded_); EXPECT_LT(collapsed_height, message_label()->height()); EXPECT_LT(collapsed_preferred_height, notification_view()->GetPreferredSize().height()); - notification_view()->ToggleExpanded(); + ToggleExpanded(); EXPECT_FALSE(notification_view()->expanded_); EXPECT_EQ(collapsed_height, message_label()->height()); EXPECT_EQ(collapsed_preferred_height,
diff --git a/ui/ozone/platform/drm/gpu/gbm_surfaceless.cc b/ui/ozone/platform/drm/gpu/gbm_surfaceless.cc index 7cee75377b..9037b6b 100644 --- a/ui/ozone/platform/drm/gpu/gbm_surfaceless.cc +++ b/ui/ozone/platform/drm/gpu/gbm_surfaceless.cc
@@ -45,9 +45,9 @@ window_(std::move(window)), widget_(widget), has_implicit_external_sync_( - HasEGLExtension("EGL_ARM_implicit_external_sync")), + GetGLDisplayEGL()->HasEGLExtension("EGL_ARM_implicit_external_sync")), has_image_flush_external_( - HasEGLExtension("EGL_EXT_image_flush_external")) { + GetGLDisplayEGL()->HasEGLExtension("EGL_EXT_image_flush_external")) { surface_factory_->RegisterSurface(window_->widget(), this); supports_plane_gpu_fences_ = window_->SupportsGpuFences(); unsubmitted_frames_.push_back(std::make_unique<PendingFrame>());
diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn index c97137d..bb12f7f 100644 --- a/ui/ozone/platform/wayland/BUILD.gn +++ b/ui/ozone/platform/wayland/BUILD.gn
@@ -252,6 +252,7 @@ "//ui/base/dragdrop:types", "//ui/base/dragdrop/mojom", "//ui/base/ime/linux", + "//ui/base/wayland:wayland_client_input_types", "//ui/display/util:gpu_info_util", "//ui/events", "//ui/events:dom_keycode_converter",
diff --git a/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc b/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc index 380c31fb..f68e444 100644 --- a/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc +++ b/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc
@@ -117,7 +117,7 @@ buffer_manager_(buffer_manager), widget_(widget), has_implicit_external_sync_( - HasEGLExtension("EGL_ARM_implicit_external_sync")), + GetGLDisplayEGL()->HasEGLExtension("EGL_ARM_implicit_external_sync")), solid_color_buffers_holder_(std::make_unique<SolidColorBufferHolder>()), weak_factory_(this) { buffer_manager_->RegisterSurface(widget_, this);
diff --git a/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc b/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc index 32ceabf3..f6b09a9 100644 --- a/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc +++ b/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc
@@ -317,7 +317,8 @@ GbmDevice* WaylandBufferManagerGpu::GetGbmDevice() { // Wayland won't support wl_drm or zwp_linux_dmabuf without this extension. if (!supports_dmabuf_ || - (!gl::GLSurfaceEGL::HasEGLExtension("EGL_EXT_image_dma_buf_import") && + (!gl::GLSurfaceEGL::GetGLDisplayEGL()->HasEGLExtension( + "EGL_EXT_image_dma_buf_import") && !use_fake_gbm_device_for_test_)) { supports_dmabuf_ = false; return nullptr;
diff --git a/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc b/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc index 872b011..8f9757ff 100644 --- a/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc +++ b/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc
@@ -104,7 +104,7 @@ scoped_refptr<gl::GLSurface> GLOzoneEGLWayland::CreateOffscreenGLSurface( const gfx::Size& size) { - if (gl::GLSurfaceEGL::IsEGLSurfacelessContextSupported() && + if (gl::GLSurfaceEGL::GetGLDisplayEGL()->IsEGLSurfacelessContextSupported() && size.width() == 0 && size.height() == 0) { return gl::InitializeGLSurface(new gl::SurfacelessEGL(size)); } else {
diff --git a/ui/ozone/platform/wayland/host/wayland_connection.cc b/ui/ozone/platform/wayland/host/wayland_connection.cc index 9246a6d..fbb261d5 100644 --- a/ui/ozone/platform/wayland/host/wayland_connection.cc +++ b/ui/ozone/platform/wayland/host/wayland_connection.cc
@@ -80,7 +80,7 @@ constexpr uint32_t kMaxWpPresentationVersion = 1; constexpr uint32_t kMaxWpViewporterVersion = 1; constexpr uint32_t kMaxTextInputManagerVersion = 1; -constexpr uint32_t kMaxTextInputExtensionVersion = 1; +constexpr uint32_t kMaxTextInputExtensionVersion = 2; constexpr uint32_t kMaxExplicitSyncVersion = 2; constexpr uint32_t kMaxAlphaCompositingVersion = 1; constexpr uint32_t kMaxXdgDecorationVersion = 1;
diff --git a/ui/ozone/platform/wayland/host/wayland_input_method_context.cc b/ui/ozone/platform/wayland/host/wayland_input_method_context.cc index ab716d20a..f15df62d 100644 --- a/ui/ozone/platform/wayland/host/wayland_input_method_context.cc +++ b/ui/ozone/platform/wayland/host/wayland_input_method_context.cc
@@ -122,71 +122,6 @@ return absl::nullopt; } -// Converts Chrome's TextInputType into wayland's content_purpose. -// Some of TextInputType values do not have clearly corresponding wayland value, -// and they fallback to closer type. -uint32_t InputTypeToContentPurpose(TextInputType input_type) { - switch (input_type) { - case TEXT_INPUT_TYPE_NONE: - return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_NORMAL; - case TEXT_INPUT_TYPE_TEXT: - return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_NORMAL; - case TEXT_INPUT_TYPE_PASSWORD: - return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_PASSWORD; - case TEXT_INPUT_TYPE_SEARCH: - return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_NORMAL; - case TEXT_INPUT_TYPE_EMAIL: - return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_EMAIL; - case TEXT_INPUT_TYPE_NUMBER: - return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_NUMBER; - case TEXT_INPUT_TYPE_TELEPHONE: - return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_PHONE; - case TEXT_INPUT_TYPE_URL: - return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_URL; - case TEXT_INPUT_TYPE_DATE: - return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_DATE; - case TEXT_INPUT_TYPE_DATE_TIME: - return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_DATETIME; - case TEXT_INPUT_TYPE_DATE_TIME_LOCAL: - return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_DATETIME; - case TEXT_INPUT_TYPE_MONTH: - return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_DATE; - case TEXT_INPUT_TYPE_TIME: - return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_TIME; - case TEXT_INPUT_TYPE_WEEK: - return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_DATE; - case TEXT_INPUT_TYPE_TEXT_AREA: - return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_NORMAL; - case TEXT_INPUT_TYPE_CONTENT_EDITABLE: - return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_NORMAL; - case TEXT_INPUT_TYPE_DATE_TIME_FIELD: - return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_DATETIME; - case TEXT_INPUT_TYPE_NULL: - return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_NORMAL; - } -} - -// Converts Chrome's TextInputType into wayland's content_hint. -uint32_t InputFlagsToContentHint(int input_flags) { - uint32_t hint = 0; - if (input_flags & TEXT_INPUT_FLAG_AUTOCOMPLETE_ON) - hint |= ZWP_TEXT_INPUT_V1_CONTENT_HINT_AUTO_COMPLETION; - if (input_flags & TEXT_INPUT_FLAG_AUTOCORRECT_ON) - hint |= ZWP_TEXT_INPUT_V1_CONTENT_HINT_AUTO_CORRECTION; - // No good match. Fallback to AUTO_CORRECTION. - if (input_flags & TEXT_INPUT_FLAG_SPELLCHECK_ON) - hint |= ZWP_TEXT_INPUT_V1_CONTENT_HINT_AUTO_CORRECTION; - if (input_flags & TEXT_INPUT_FLAG_AUTOCAPITALIZE_CHARACTERS) - hint |= ZWP_TEXT_INPUT_V1_CONTENT_HINT_UPPERCASE; - if (input_flags & TEXT_INPUT_FLAG_AUTOCAPITALIZE_WORDS) - hint |= ZWP_TEXT_INPUT_V1_CONTENT_HINT_TITLECASE; - if (input_flags & TEXT_INPUT_FLAG_AUTOCAPITALIZE_SENTENCES) - hint |= ZWP_TEXT_INPUT_V1_CONTENT_HINT_AUTO_CAPITALIZATION; - if (input_flags & TEXT_INPUT_FLAG_HAS_BEEN_PASSWORD) - hint |= ZWP_TEXT_INPUT_V1_CONTENT_HINT_PASSWORD; - return hint; -} - } // namespace WaylandInputMethodContext::WaylandInputMethodContext( @@ -387,17 +322,13 @@ text_input_->SetSurroundingText(truncated_text, relocated_selection_range); } -void WaylandInputMethodContext::SetContentType(TextInputType input_type, - int input_flags, +void WaylandInputMethodContext::SetContentType(TextInputType type, + TextInputMode mode, + uint32_t flags, bool should_do_learning) { if (!text_input_) return; - - uint32_t content_purpose = InputTypeToContentPurpose(input_type); - uint32_t content_hint = InputFlagsToContentHint(input_flags); - if (!should_do_learning) - content_hint |= ZWP_TEXT_INPUT_V1_CONTENT_HINT_SENSITIVE_DATA; - text_input_->SetContentType(content_hint, content_purpose); + text_input_->SetContentType(type, mode, flags, should_do_learning); } VirtualKeyboardController*
diff --git a/ui/ozone/platform/wayland/host/wayland_input_method_context.h b/ui/ozone/platform/wayland/host/wayland_input_method_context.h index 4d11108..c3d3171f 100644 --- a/ui/ozone/platform/wayland/host/wayland_input_method_context.h +++ b/ui/ozone/platform/wayland/host/wayland_input_method_context.h
@@ -48,8 +48,9 @@ void SetCursorLocation(const gfx::Rect& rect) override; void SetSurroundingText(const std::u16string& text, const gfx::Range& selection_range) override; - void SetContentType(TextInputType input_type, - int input_flags, + void SetContentType(TextInputType type, + TextInputMode mode, + uint32_t flags, bool should_do_learning) override; void Reset() override; void Focus() override;
diff --git a/ui/ozone/platform/wayland/host/wayland_input_method_context_unittest.cc b/ui/ozone/platform/wayland/host/wayland_input_method_context_unittest.cc index e9e09d70..435cf71a 100644 --- a/ui/ozone/platform/wayland/host/wayland_input_method_context_unittest.cc +++ b/ui/ozone/platform/wayland/host/wayland_input_method_context_unittest.cc
@@ -388,6 +388,7 @@ ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_URL)) .Times(1); input_method_context_->SetContentType(TEXT_INPUT_TYPE_URL, + TEXT_INPUT_MODE_DEFAULT, TEXT_INPUT_FLAG_AUTOCOMPLETE_ON, /*should_do_learning=*/true); connection_->ScheduleFlush(); @@ -401,6 +402,7 @@ ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_URL)) .Times(1); input_method_context_->SetContentType(TEXT_INPUT_TYPE_URL, + TEXT_INPUT_MODE_DEFAULT, TEXT_INPUT_FLAG_AUTOCOMPLETE_ON, /*should_do_learning=*/false); connection_->ScheduleFlush();
diff --git a/ui/ozone/platform/wayland/host/zwp_text_input_wrapper.h b/ui/ozone/platform/wayland/host/zwp_text_input_wrapper.h index 18ad5e6..0d245fe5 100644 --- a/ui/ozone/platform/wayland/host/zwp_text_input_wrapper.h +++ b/ui/ozone/platform/wayland/host/zwp_text_input_wrapper.h
@@ -11,6 +11,8 @@ #include <vector> #include "base/strings/string_piece.h" +#include "ui/base/ime/text_input_mode.h" +#include "ui/base/ime/text_input_type.h" namespace gfx { class Rect; @@ -101,8 +103,10 @@ virtual void SetCursorRect(const gfx::Rect& rect) = 0; virtual void SetSurroundingText(const std::string& text, const gfx::Range& selection_range) = 0; - virtual void SetContentType(uint32_t content_hint, - uint32_t content_purpose) = 0; + virtual void SetContentType(ui::TextInputType type, + ui::TextInputMode mode, + uint32_t flags, + bool should_do_learning) = 0; }; } // namespace ui
diff --git a/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v1.cc b/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v1.cc index 834e43d..da1971c 100644 --- a/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v1.cc +++ b/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v1.cc
@@ -9,6 +9,7 @@ #include "base/strings/string_piece.h" #include "base/strings/string_split.h" +#include "ui/base/wayland/wayland_client_input_types.h" #include "ui/gfx/range/range.h" #include "ui/ozone/platform/wayland/host/wayland_connection.h" #include "ui/ozone/platform/wayland/host/wayland_seat.h" @@ -17,6 +18,71 @@ namespace ui { namespace { +// Converts Chrome's TextInputType into wayland's content_purpose. +// Some of TextInputType values do not have clearly corresponding wayland value, +// and they fallback to closer type. +uint32_t InputTypeToContentPurpose(TextInputType input_type) { + switch (input_type) { + case TEXT_INPUT_TYPE_NONE: + return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_NORMAL; + case TEXT_INPUT_TYPE_TEXT: + return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_NORMAL; + case TEXT_INPUT_TYPE_PASSWORD: + return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_PASSWORD; + case TEXT_INPUT_TYPE_SEARCH: + return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_NORMAL; + case TEXT_INPUT_TYPE_EMAIL: + return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_EMAIL; + case TEXT_INPUT_TYPE_NUMBER: + return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_NUMBER; + case TEXT_INPUT_TYPE_TELEPHONE: + return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_PHONE; + case TEXT_INPUT_TYPE_URL: + return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_URL; + case TEXT_INPUT_TYPE_DATE: + return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_DATE; + case TEXT_INPUT_TYPE_DATE_TIME: + return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_DATETIME; + case TEXT_INPUT_TYPE_DATE_TIME_LOCAL: + return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_DATETIME; + case TEXT_INPUT_TYPE_MONTH: + return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_DATE; + case TEXT_INPUT_TYPE_TIME: + return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_TIME; + case TEXT_INPUT_TYPE_WEEK: + return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_DATE; + case TEXT_INPUT_TYPE_TEXT_AREA: + return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_NORMAL; + case TEXT_INPUT_TYPE_CONTENT_EDITABLE: + return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_NORMAL; + case TEXT_INPUT_TYPE_DATE_TIME_FIELD: + return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_DATETIME; + case TEXT_INPUT_TYPE_NULL: + return ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_NORMAL; + } +} + +// Converts Chrome's TextInputType into wayland's content_hint. +uint32_t InputFlagsToContentHint(int input_flags) { + uint32_t hint = 0; + if (input_flags & TEXT_INPUT_FLAG_AUTOCOMPLETE_ON) + hint |= ZWP_TEXT_INPUT_V1_CONTENT_HINT_AUTO_COMPLETION; + if (input_flags & TEXT_INPUT_FLAG_AUTOCORRECT_ON) + hint |= ZWP_TEXT_INPUT_V1_CONTENT_HINT_AUTO_CORRECTION; + // No good match. Fallback to AUTO_CORRECTION. + if (input_flags & TEXT_INPUT_FLAG_SPELLCHECK_ON) + hint |= ZWP_TEXT_INPUT_V1_CONTENT_HINT_AUTO_CORRECTION; + if (input_flags & TEXT_INPUT_FLAG_AUTOCAPITALIZE_CHARACTERS) + hint |= ZWP_TEXT_INPUT_V1_CONTENT_HINT_UPPERCASE; + if (input_flags & TEXT_INPUT_FLAG_AUTOCAPITALIZE_WORDS) + hint |= ZWP_TEXT_INPUT_V1_CONTENT_HINT_TITLECASE; + if (input_flags & TEXT_INPUT_FLAG_AUTOCAPITALIZE_SENTENCES) + hint |= ZWP_TEXT_INPUT_V1_CONTENT_HINT_AUTO_CAPITALIZATION; + if (input_flags & TEXT_INPUT_FLAG_HAS_BEEN_PASSWORD) + hint |= ZWP_TEXT_INPUT_V1_CONTENT_HINT_PASSWORD; + return hint; +} + // Parses the content of |array|, and creates a map of modifiers. // The content of array is just a concat of modifier names in c-style string // (i.e., '\0' terminated string), thus this splits the whole byte array by @@ -116,8 +182,29 @@ obj_.get(), text.c_str(), selection_range.start(), selection_range.end()); } -void ZWPTextInputWrapperV1::SetContentType(uint32_t content_hint, - uint32_t content_purpose) { +void ZWPTextInputWrapperV1::SetContentType(ui::TextInputType type, + ui::TextInputMode mode, + uint32_t flags, + bool should_do_learning) { + // If wayland compositor supports the extended version of set input type, + // use it to avoid loosing the info. + if (extended_obj_.get() && + wl::get_version_of_object(extended_obj_.get()) >= + ZCR_EXTENDED_TEXT_INPUT_V1_SET_INPUT_TYPE_SINCE_VERSION) { + zcr_extended_text_input_v1_set_input_type( + extended_obj_.get(), ui::wayland::ConvertFromTextInputType(type), + ui::wayland::ConvertFromTextInputMode(mode), + ui::wayland::ConvertFromTextInputFlags(flags), + should_do_learning ? ZCR_EXTENDED_TEXT_INPUT_V1_LEARNING_MODE_ENABLED + : ZCR_EXTENDED_TEXT_INPUT_V1_LEARNING_MODE_DISABLED); + return; + } + + // Otherwise, fallback to the standard set_content_type. + uint32_t content_purpose = InputTypeToContentPurpose(type); + uint32_t content_hint = InputFlagsToContentHint(flags); + if (!should_do_learning) + content_hint |= ZWP_TEXT_INPUT_V1_CONTENT_HINT_SENSITIVE_DATA; zwp_text_input_v1_set_content_type(obj_.get(), content_hint, content_purpose); }
diff --git a/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v1.h b/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v1.h index c1440d4..7daa3f90 100644 --- a/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v1.h +++ b/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v1.h
@@ -46,7 +46,10 @@ void SetCursorRect(const gfx::Rect& rect) override; void SetSurroundingText(const std::string& text, const gfx::Range& selection_range) override; - void SetContentType(uint32_t content_hint, uint32_t content_purpose) override; + void SetContentType(TextInputType type, + TextInputMode mode, + uint32_t flags, + bool should_do_learning) override; private: void ResetInputEventState();
diff --git a/ui/ozone/platform/x11/x11_surface_factory.cc b/ui/ozone/platform/x11/x11_surface_factory.cc index 67c8073..9d797ca6 100644 --- a/ui/ozone/platform/x11/x11_surface_factory.cc +++ b/ui/ozone/platform/x11/x11_surface_factory.cc
@@ -67,7 +67,8 @@ scoped_refptr<gl::GLSurface> CreateOffscreenGLSurface( const gfx::Size& size) override { - if (gl::GLSurfaceEGL::IsEGLSurfacelessContextSupported() && + if (gl::GLSurfaceEGL::GetGLDisplayEGL() + ->IsEGLSurfacelessContextSupported() && size.width() == 0 && size.height() == 0) { return InitializeGLSurface(new gl::SurfacelessEGL(size)); } else {
diff --git a/ui/views/bubble/bubble_border.h b/ui/views/bubble/bubble_border.h index 25f7ce3..e29d52a 100644 --- a/ui/views/bubble/bubble_border.h +++ b/ui/views/bubble/bubble_border.h
@@ -82,6 +82,8 @@ // On Mac, the native window server should provide its own shadow for // windows that could overlap the browser window. DIALOG_SHADOW = NO_SHADOW, +#elif BUILDFLAG(IS_CHROMEOS_ASH) + DIALOG_SHADOW = CHROMEOS_SYSTEM_UI_SHADOW, #else DIALOG_SHADOW = STANDARD_SHADOW, #endif
diff --git a/ui/views/controls/styled_label.cc b/ui/views/controls/styled_label.cc index 065b2329..c9d72a3a 100644 --- a/ui/views/controls/styled_label.cc +++ b/ui/views/controls/styled_label.cc
@@ -48,7 +48,6 @@ Link::ClickedCallback callback) { RangeStyleInfo result; result.callback = std::move(callback); - result.disable_line_wrapping = true; result.text_style = style::STYLE_LINK; return result; } @@ -460,11 +459,9 @@ chunk = substrings[0]; } - if (((custom_view && - line_size.width() + custom_view->GetPreferredSize().width() > - content_width) || - (style_info.disable_line_wrapping && - chunk.size() < range.length())) && + if ((custom_view && + line_size.width() + custom_view->GetPreferredSize().width() > + content_width) && position == range.start() && line_size.width() != 0) { // If the chunk should not be wrapped, try to fit it entirely on the // next line.
diff --git a/ui/views/controls/styled_label.h b/ui/views/controls/styled_label.h index a867863b..30b36de 100644 --- a/ui/views/controls/styled_label.h +++ b/ui/views/controls/styled_label.h
@@ -69,9 +69,6 @@ // Tooltip for the range. std::u16string tooltip; - // If set, the whole range will be put on a single line. - bool disable_line_wrapping = false; - // A custom view shown instead of the underlying text. Ownership of custom // views must be passed to StyledLabel via AddCustomView(). raw_ptr<View> custom_view = nullptr;
diff --git a/ui/views/controls/styled_label_unittest.cc b/ui/views/controls/styled_label_unittest.cc index 454598a..2c4bdb0 100644 --- a/ui/views/controls/styled_label_unittest.cc +++ b/ui/views/controls/styled_label_unittest.cc
@@ -270,54 +270,6 @@ EXPECT_EQ(7u, styled()->children().size()); } -TEST_F(StyledLabelTest, DontBreakLinks) { - const std::string text("This is a test block of text, "); - const std::string link_text("and this should be a link"); - InitStyledLabel(text + link_text); - styled()->AddStyleRange( - gfx::Range(text.size(), text.size() + link_text.size()), - StyledLabel::RangeStyleInfo::CreateForLink(base::RepeatingClosure())); - - Label label(ASCIIToUTF16(text + link_text.substr(0, link_text.size() / 2))); - gfx::Size label_preferred_size = label.GetPreferredSize(); - int pref_height = styled()->GetHeightForWidth(label_preferred_size.width()); - EXPECT_EQ(label_preferred_size.height() * 2, - pref_height - styled()->GetInsets().height()); - - styled()->SetBounds(0, 0, label_preferred_size.width(), pref_height); - styled()->Layout(); - ASSERT_EQ(2u, styled()->children().size()); - - // No additional insets should be added. - EXPECT_EQ(0, styled()->children()[0]->x()); - // The Link shouldn't be offset. - EXPECT_EQ(0, styled()->children()[1]->x()); -} - -TEST_F(StyledLabelTest, StyledRangeWithDisabledLineWrapping) { - const std::string text("This is a test block of text, "); - const std::string unbreakable_text("and this should not be broken"); - InitStyledLabel(text + unbreakable_text); - StyledLabel::RangeStyleInfo style_info; - style_info.disable_line_wrapping = true; - styled()->AddStyleRange( - gfx::Range(text.size(), text.size() + unbreakable_text.size()), - style_info); - - Label label(ASCIIToUTF16( - text + unbreakable_text.substr(0, unbreakable_text.size() / 2))); - gfx::Size label_preferred_size = label.GetPreferredSize(); - int pref_height = styled()->GetHeightForWidth(label_preferred_size.width()); - EXPECT_EQ(label_preferred_size.height() * 2, - pref_height - styled()->GetInsets().height()); - - styled()->SetBounds(0, 0, label_preferred_size.width(), pref_height); - styled()->Layout(); - ASSERT_EQ(2u, styled()->children().size()); - EXPECT_EQ(0, styled()->children()[0]->x()); - EXPECT_EQ(0, styled()->children()[1]->x()); -} - TEST_F(StyledLabelTest, StyledRangeCustomFontUnderlined) { const std::string text("This is a test block of text, "); const std::string underlined_text("and this should be undelined"); @@ -480,7 +432,7 @@ EXPECT_EQ(label_preferred_size.width(), styled()->width()); - ASSERT_EQ(5u, styled()->children().size()); + ASSERT_EQ(6u, styled()->children().size()); // The labels shouldn't be offset to cater for focus rings. EXPECT_EQ(0, styled()->children()[0]->x()); @@ -490,7 +442,6 @@ styled()->children()[1]->x()); EXPECT_EQ(styled()->children()[2]->bounds().right(), styled()->children()[3]->x()); - EXPECT_EQ(0, styled()->children()[4]->x()); std::u16string tooltip = styled()->children()[1]->GetTooltipText(gfx::Point(1, 1));
diff --git a/ui/webui/resources/js/cr/ui/store.js b/ui/webui/resources/js/cr/ui/store.js index 125bfeb..f9805a5e 100644 --- a/ui/webui/resources/js/cr/ui/store.js +++ b/ui/webui/resources/js/cr/ui/store.js
@@ -125,14 +125,14 @@ * @param {DeferredAction} action */ dispatchInternal_(action) { - action(this.reduce_.bind(this)); + action(this.reduce.bind(this)); } /** * @param {?Action} action - * @private + * @protected */ - reduce_(action) { + reduce(action) { if (!action) { return; }
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestService.java b/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestService.java index 082c675..23f8f61 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestService.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestService.java
@@ -129,7 +129,7 @@ // Implements BrowserPaymentRequest: @Override @Nullable - public String onShowCalledAndAppsQueriedAndDetailsFinalized(boolean isUserGestureShow) { + public String onShowCalledAndAppsQueriedAndDetailsFinalized() { assert !mAvailableApps.isEmpty() : "triggerPaymentAppUiSkipIfApplicable() should be called only when there is any " + "available app.";