diff --git a/DEPS b/DEPS index 3820d963..295542ff 100644 --- a/DEPS +++ b/DEPS
@@ -245,7 +245,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '112f9f1273ef9505673c4a5154a2f9d8cc929d23', + 'skia_revision': '87ced29082dba285f3c5f7f763bda906191cf354', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # 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 devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': 'eba1a96f6793a1360b99f86597632af9e565b953', + 'devtools_frontend_revision': '85c29e982d6574fcf9bd48875a70e720d195fea4', # 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. @@ -722,7 +722,7 @@ 'packages': [ { 'package': 'chromium/rts/model/linux-amd64', - 'version': '6Tedy7sNUuGxQonFLNS-cNqwCuei42vo8V4kHVA1VEYC', + 'version': 'vYgH0GbTQNVjRMtt15gEkKoqlY0FhG33N87v_dmmbncC', }, ], 'dep_type': 'cipd', @@ -733,7 +733,7 @@ 'packages': [ { 'package': 'chromium/rts/model/mac-amd64', - 'version': 'YeHsBYNVPaSD3APzBkAWSm87R40cALe68s52fVUvlTkC', + 'version': '8U89GphSBwmWWUP7Cd_rd0X0S0E5QwXwyAZ6Qfhx3usC', }, ], 'dep_type': 'cipd', @@ -744,7 +744,7 @@ 'packages': [ { 'package': 'chromium/rts/model/windows-amd64', - 'version': 'cxcXx7pnzR_s9RsYCFVuHp7syDOa5VOx4lQvokSjk3IC', + 'version': 'JbHSIdHFMOq3WzVVAqvQ9ECPOFSDUHkquSqY4jJbUscC', }, ], 'dep_type': 'cipd', @@ -805,7 +805,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'ZFybfM9WA_ZDTzPoqqNyWkYnKhc-eKP-qu_wHennQ34C', + 'version': 'HODW6m8VayryUJucacS9PY8PR4FM7dBYoYjG6f3eKukC', }, ], 'condition': 'checkout_android', @@ -1044,7 +1044,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'db41eed6b7442273b54bac9695567d97b60718de', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '54c265ea2b2fc90ae29fc87366cffc0a5e57f7c4', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1583,7 +1583,7 @@ Var('swiftshader_git') + '/SwiftShader.git' + '@' + Var('swiftshader_revision'), 'src/third_party/text-fragments-polyfill/src': { - 'url': Var('chromium_git') + '/external/github.com/GoogleChromeLabs/text-fragments-polyfill.git' + '@' + '04c058c92fc5be41f91db654b9e903ade4fca27e', + 'url': Var('chromium_git') + '/external/github.com/GoogleChromeLabs/text-fragments-polyfill.git' + '@' + 'ea30795d4a95a1850aff9f52f37ea3146260403e', 'condition': 'checkout_ios', }, @@ -1648,7 +1648,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'c843f8d63c8c17acfbb7d48e09059a581ba779b9', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'ce702dbbe4e86d5248a6ad4b13475cc166dd02a8', + Var('webrtc_git') + '/src.git' + '@' + '8d6cd55b60176da8f975da9f4ee1143e01a09db1', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1730,7 +1730,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@0b962ed90d3d4a7a9b8561dd52e0910ed8a7ed2b', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@3c3863829f5177f88561647211b56cae27ee6030', 'condition': 'checkout_src_internal', }, @@ -1760,7 +1760,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/help_app/app', - 'version': 'huP5FRrbgw-tHl9bdM4-qlL3hrfYHTOXmzc2xcJQQYMC', + 'version': 'RzDWpfmi2CqSz2ZX8kwgQTvcycW3-Co8uCieXmHyzSgC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -1771,7 +1771,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/media_app/app', - 'version': '4RiezqEg5sHwAct7NoR1oxnGBRbhs8iTOjB3hI6uLdAC', + 'version': '4pOvBAmmlVc7FirmYud1YCAv1qqLeMCxmwXh2bCNXjMC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index ff2447d..623876d 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -659,6 +659,8 @@ '^chrome/services/sharing/nearby/', # gRPC provides some C++ libraries that use std::shared_ptr<>. '^chromeos/services/libassistant/grpc/', + '^chromecast/cast_core/grpc', + '^chromecast/cast_core/runtime/browser', # Fuchsia provides C++ libraries that use std::shared_ptr<>. '.*fuchsia.*test\.(cc|h)', _THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders.
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc index d0ad3195..f908042 100644 --- a/android_webview/browser/aw_content_browser_client.cc +++ b/android_webview/browser/aw_content_browser_client.cc
@@ -825,6 +825,7 @@ ui::PageTransition page_transition, bool has_user_gesture, const absl::optional<url::Origin>& initiating_origin, + content::RenderFrameHost* initiator_document, mojo::PendingRemote<network::mojom::URLLoaderFactory>* out_factory) { // Sandbox flags // =============
diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h index b11001f3..d0b57377 100644 --- a/android_webview/browser/aw_content_browser_client.h +++ b/android_webview/browser/aw_content_browser_client.h
@@ -188,6 +188,7 @@ ui::PageTransition page_transition, bool has_user_gesture, const absl::optional<url::Origin>& initiating_origin, + content::RenderFrameHost* initiator_document, mojo::PendingRemote<network::mojom::URLLoaderFactory>* out_factory) override; void RegisterNonNetworkSubresourceURLLoaderFactories(
diff --git a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java index 8ef2bc3..5525049 100644 --- a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java +++ b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
@@ -205,6 +205,9 @@ "Force the Chrome major version number to 100 in the User-Agent string."), Flag.baseFeature(BlinkFeatures.FORCE_MINOR_VERSION100_IN_USER_AGENT, "Force the Chrome minor version number to 100 in the User-Agent string."), + Flag.baseFeature(BlinkFeatures.FORCE_MAJOR_VERSION_IN_MINOR_POSITION_IN_USER_AGENT, + "Force the Chrome major version number to 99 and put the major version" + + " number in the minor version position in the User-Agent string."), Flag.baseFeature(NetworkServiceFeatures.URL_LOADER_SYNC_CLIENT, "Optimizes communication between URLLoader and CorsURLLoader."), Flag.baseFeature(BlinkFeatures.SET_TIMEOUT_WITHOUT_CLAMP,
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwAutofillTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwAutofillTest.java index 47f339c..ae561c9 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwAutofillTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwAutofillTest.java
@@ -50,7 +50,6 @@ import org.chromium.base.task.PostTask; import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.DisableIf; -import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.FlakyTest; import org.chromium.base.test.util.MetricsUtils; @@ -918,7 +917,6 @@ @Test @SmallTest @Feature({"AndroidWebView"}) - @DisabledTest(message = "https://crbug.com/1279813") public void testTouchingFormWithAdjustResize() throws Throwable { PostTask.runOrPostTask(UiThreadTaskTraits.DEFAULT, () -> { mRule.getActivity().getWindow().setSoftInputMode( @@ -1116,7 +1114,6 @@ @Test @SmallTest @Feature({"AndroidWebView"}) - @DisabledTest(message = "https://crbug.com/1153875") public void testAutofillTriggersAfterReload() throws Throwable { final String data = "<html><head></head><body><form action='a.html' name='formname'>" + "<input type='text' id='text1' name='username'" @@ -1147,7 +1144,6 @@ @Test @SmallTest @Feature({"AndroidWebView"}) - @DisabledTest(message = "https://crbug.com/1279813") public void testNotifyVirtualValueChanged() throws Throwable { final String data = "<html><head></head><body><form action='a.html' name='formname'>" + "<input type='text' id='text1' name='username'" @@ -1182,7 +1178,6 @@ @Test @SmallTest @Feature({"AndroidWebView"}) - @DisabledTest(message = "https://crbug.com/1279813") public void testJavascriptNotTriggerNotifyVirtualValueChanged() throws Throwable { final String data = "<html><head></head><body><form action='a.html' name='formname'>" + "<input type='text' id='text1' name='username'" @@ -1307,7 +1302,6 @@ @Test @SmallTest @Feature({"AndroidWebView"}) - @DisabledTest(message = "https://crbug.com/1279813") public void testSwitchFromIFrame() throws Throwable { // we intentionally load main frame and iframe from the same URL and make both have the // similar form, so the new session is triggered by frame change @@ -1522,7 +1516,6 @@ @Feature({"AndroidWebView"}) @DisableIf.Build(sdk_is_less_than = Build.VERSION_CODES.P, message = "This test is disabled on Android O because of https://crbug.com/997362") - @DisabledTest(message = "https://crbug.com/1279813") public void testSelectControlChangeNotification() throws Throwable { int cnt = 0; @@ -2058,7 +2051,6 @@ @Test @SmallTest @Feature({"AndroidWebView"}) - @DisabledTest(message = "https://crbug.com/1279813") public void testPageScrollTriggerViewExitAndEnter() throws Throwable { final String data = "<html><head></head><body><form action='a.html' name='formname'>" + "<input type='text' id='text1' name='username'" @@ -2678,7 +2670,6 @@ @Test @SmallTest @Feature({"AndroidWebView"}) - @DisabledTest(message = "https://crbug.com/1279813") public void testFirstFieldRemovedBeforeSuggestionSelected() throws Throwable { // This test verifies that form filling works even if an element of the form that was // supposed to be filled has been deleted between the time of decision to fill the form and
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/devui/util/ComponentsInfoLoaderTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/devui/util/ComponentsInfoLoaderTest.java index 3316abc..94373d3 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/devui/util/ComponentsInfoLoaderTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/devui/util/ComponentsInfoLoaderTest.java
@@ -6,20 +6,19 @@ import androidx.test.filters.SmallTest; -import org.junit.After; import org.junit.Assert; -import org.junit.BeforeClass; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.chromium.android_webview.devui.util.ComponentInfo; import org.chromium.android_webview.devui.util.ComponentsInfoLoader; -import org.chromium.android_webview.services.ComponentsProviderPathUtil; import org.chromium.android_webview.test.AwJUnit4ClassRunner; -import org.chromium.base.FileUtils; import org.chromium.base.test.util.Batch; import java.io.File; +import java.io.IOException; import java.util.ArrayList; /** @@ -28,37 +27,22 @@ @RunWith(AwJUnit4ClassRunner.class) @Batch(Batch.UNIT_TESTS) public class ComponentsInfoLoaderTest { - private static File sComponentsDownloadDir = - new File(ComponentsProviderPathUtil.getComponentUpdateServiceDirectoryPath()); - - @BeforeClass - public static void deleteOriginalComponentsDownloadDir() { - if (sComponentsDownloadDir.exists()) { - Assert.assertTrue(FileUtils.recursivelyDeleteFile(sComponentsDownloadDir, null)); - } - } - - @After - public void tearDown() { - if (sComponentsDownloadDir.exists()) { - Assert.assertTrue(FileUtils.recursivelyDeleteFile(sComponentsDownloadDir, null)); - } - } + @Rule + public TemporaryFolder mTempDir = new TemporaryFolder(); @Test @SmallTest - public void testMultipleComponents_withOneVersionSubDirectory() { + public void testMultipleComponents_withOneVersionSubDirectory() throws IOException { ComponentInfo[] expectedList = new ComponentInfo[] {new ComponentInfo("MockComponent A", "1.0.2.1"), new ComponentInfo("MockComponent B", "2021.1.2.1")}; for (ComponentInfo mockComponent : expectedList) { - new File(sComponentsDownloadDir, - mockComponent.getComponentName() + "/" + mockComponent.getComponentVersion()) - .mkdirs(); + mTempDir.newFolder( + mockComponent.getComponentName(), mockComponent.getComponentVersion()); } - ComponentsInfoLoader componentsInfoLoader = new ComponentsInfoLoader(); + ComponentsInfoLoader componentsInfoLoader = new ComponentsInfoLoader(mTempDir.getRoot()); ArrayList<ComponentInfo> retrievedComponentsInfoList = componentsInfoLoader.getComponentsInfo(); @@ -67,10 +51,8 @@ @Test @SmallTest - public void testComponentsDownloadDirectory_isEmpty() { - sComponentsDownloadDir.mkdirs(); - - ComponentsInfoLoader componentsInfoLoader = new ComponentsInfoLoader(); + public void testComponentsDownloadDirectory_isEmpty() throws IOException { + ComponentsInfoLoader componentsInfoLoader = new ComponentsInfoLoader(mTempDir.getRoot()); ArrayList<ComponentInfo> retrievedComponentsInfoList = componentsInfoLoader.getComponentsInfo(); @@ -80,8 +62,9 @@ @Test @SmallTest - public void testComponentsDownloadDirectory_doesNotExist() { - ComponentsInfoLoader componentsInfoLoader = new ComponentsInfoLoader(); + public void testComponentsDownloadDirectory_doesNotExist() throws IOException { + ComponentsInfoLoader componentsInfoLoader = + new ComponentsInfoLoader(new File(mTempDir.getRoot(), "nonexistent")); ArrayList<ComponentInfo> retrievedComponentsInfoList = componentsInfoLoader.getComponentsInfo(); @@ -91,10 +74,10 @@ @Test @SmallTest - public void testVersionSubDirectory_doesNotExist() { - new File(sComponentsDownloadDir, "MockComponent A").mkdirs(); + public void testVersionSubDirectory_doesNotExist() throws IOException { + mTempDir.newFolder("MockComponent A"); - ComponentsInfoLoader componentsInfoLoader = new ComponentsInfoLoader(); + ComponentsInfoLoader componentsInfoLoader = new ComponentsInfoLoader(mTempDir.getRoot()); ArrayList<ComponentInfo> retrievedComponentsInfoList = componentsInfoLoader.getComponentsInfo();
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/ComponentsListFragment.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/ComponentsListFragment.java index a7e60ee0..f28406f 100644 --- a/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/ComponentsListFragment.java +++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/ComponentsListFragment.java
@@ -28,10 +28,12 @@ import org.chromium.android_webview.common.services.ServiceNames; import org.chromium.android_webview.devui.util.ComponentInfo; import org.chromium.android_webview.devui.util.ComponentsInfoLoader; +import org.chromium.android_webview.services.ComponentsProviderPathUtil; import org.chromium.base.ThreadUtils; import org.chromium.base.task.AsyncTask; import org.chromium.ui.widget.Toast; +import java.io.File; import java.util.ArrayList; import java.util.Locale; @@ -134,7 +136,8 @@ @Override @WorkerThread protected ArrayList<ComponentInfo> doInBackground() { - ComponentsInfoLoader componentInfoLoader = new ComponentsInfoLoader(); + ComponentsInfoLoader componentInfoLoader = new ComponentsInfoLoader(new File( + ComponentsProviderPathUtil.getComponentUpdateServiceDirectoryPath())); ArrayList<ComponentInfo> retrievedComponentInfoList = componentInfoLoader.getComponentsInfo();
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/util/ComponentsInfoLoader.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/util/ComponentsInfoLoader.java index 46229db..f999ea2 100644 --- a/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/util/ComponentsInfoLoader.java +++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/util/ComponentsInfoLoader.java
@@ -4,27 +4,32 @@ package org.chromium.android_webview.devui.util; -import org.chromium.android_webview.services.ComponentsProviderPathUtil; - import java.io.File; import java.util.ArrayList; import java.util.Arrays; /** - * A Controller class which iterates over AwComponentUpdateService's download directory {@link - * ComponentsProviderPathUtil#getComponentUpdateServiceDirectoryPath} to retrieve component name and - * version for each component. + * A Controller class which iterates over the directory where components are downloaded to retrieve + * component name and version for each component. */ public class ComponentsInfoLoader { + private final File mComponentsDir; + + /** + * @param componentsDir the top directory where components are downloaded {@link + * ComponentsProviderPathUtil#getComponentUpdateServiceDirectoryPath}. + */ + public ComponentsInfoLoader(File componentsDir) { + mComponentsDir = componentsDir; + } + /** * @return list of {@link ComponentInfo} for downloaded components sorted in lexicographical * order. */ public ArrayList<ComponentInfo> getComponentsInfo() { ArrayList<ComponentInfo> componentInfoList = new ArrayList<>(); - File[] componentDirectories = - new File(ComponentsProviderPathUtil.getComponentUpdateServiceDirectoryPath()) - .listFiles(); + File[] componentDirectories = mComponentsDir.listFiles(); if (componentDirectories == null || componentDirectories.length == 0) { return componentInfoList;
diff --git a/android_webview/tools/system_webview_shell/layout_tests/src/org/chromium/webview_shell/test/WebPlatformTestsActivityTest.java b/android_webview/tools/system_webview_shell/layout_tests/src/org/chromium/webview_shell/test/WebPlatformTestsActivityTest.java index f2a2d07..d7f7f72 100644 --- a/android_webview/tools/system_webview_shell/layout_tests/src/org/chromium/webview_shell/test/WebPlatformTestsActivityTest.java +++ b/android_webview/tools/system_webview_shell/layout_tests/src/org/chromium/webview_shell/test/WebPlatformTestsActivityTest.java
@@ -101,6 +101,7 @@ @Test @MediumTest + @FlakyTest(message = "https://crbug.com/1282164") public void testNestedOpensAndCloses() throws Exception { final BlockingQueue<Integer> queue = new LinkedBlockingQueue<>(); final int depthToTest = 3;
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index ad8767b..ff7d8bc 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -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("//ash/ambient/resources/resources.gni") import("//build/config/chromeos/ui_mode.gni") import("//build/config/features.gni") import("//build/config/ui.gni") @@ -163,6 +164,7 @@ "ambient/model/ambient_photo_config.h", "ambient/model/ambient_slideshow_photo_config.cc", "ambient/model/ambient_slideshow_photo_config.h", + "ambient/resources/ambient_animation_static_resources.h", "ambient/ui/ambient_background_image_view.cc", "ambient/ui/ambient_background_image_view.h", "ambient/ui/ambient_container_view.cc", @@ -1415,6 +1417,8 @@ "system/privacy_screen/privacy_screen_toast_view.h", "system/rotation/rotation_lock_feature_pod_controller.cc", "system/rotation/rotation_lock_feature_pod_controller.h", + "system/scheduled_feature/scheduled_feature.cc", + "system/scheduled_feature/scheduled_feature.h", "system/screen_layout_observer.cc", "system/screen_layout_observer.h", "system/screen_security/screen_capture_observer.h", @@ -2204,6 +2208,15 @@ deps += [ "//chromeos/assistant/internal/ambient" ] } + + if (include_ash_ambient_animation_resources) { + sources += + [ "ambient/resources/ambient_animation_static_resources_impl.cc" ] + deps += [ "//ash/ambient/resources:lottie_resources" ] + } else { + sources += + [ "ambient/resources/ambient_animation_static_resources_stub.cc" ] + } } action("dbus_service_files") { @@ -2529,6 +2542,7 @@ "system/network/sms_observer_unittest.cc", "system/network/vpn_list_unittest.cc", "system/network/wifi_toggle_notification_controller_unittest.cc", + "system/night_light/night_light_controller_unittest.cc", "system/overview/overview_button_tray_unittest.cc", "system/palette/mock_palette_tool_delegate.cc", "system/palette/mock_palette_tool_delegate.h", @@ -2560,6 +2574,7 @@ "system/power/power_status_unittest.cc", "system/power/video_activity_notifier_unittest.cc", "system/rotation/rotation_lock_feature_pod_controller_unittest.cc", + "system/scheduled_feature/scheduled_feature_unittest.cc", "system/screen_layout_observer_unittest.cc", "system/screen_security/screen_security_notification_controller_unittest.cc", "system/session/logout_button_tray_unittest.cc", @@ -2873,6 +2888,12 @@ "//content/public/browser", "//content/public/common", ] + + if (include_ash_ambient_animation_resources) { + sources += [ + "ambient/resources/ambient_animation_static_resources_impl_unittest.cc", + ] + } } # TODO(oshima): Remove or migrate to new ash_ui_perftests
diff --git a/ash/ambient/resources/BUILD.gn b/ash/ambient/resources/BUILD.gn index 33d14b6..dfc8a38 100644 --- a/ash/ambient/resources/BUILD.gn +++ b/ash/ambient/resources/BUILD.gn
@@ -3,11 +3,14 @@ # found in the LICENSE file. import("//build/cipd/cipd.gni") +import("//build/config/chrome_build.gni") import("//build/config/chromeos/ui_mode.gni") import("//tools/grit/grit_rule.gni") import("//ui/webui/resources/tools/generate_grd.gni") -assert(is_chromeos_ash) +# See DEPS file. Both of these are prerequisites for downloading Lottie +# ambient mode resources from CIPD. +assert(is_chromeos_ash && is_chrome_branded) lottie_resources_grd_file = "$target_gen_dir/lottie_resources.grd"
diff --git a/ash/ambient/resources/ambient_animation_static_resources.h b/ash/ambient/resources/ambient_animation_static_resources.h new file mode 100644 index 0000000..3532d383 --- /dev/null +++ b/ash/ambient/resources/ambient_animation_static_resources.h
@@ -0,0 +1,58 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_AMBIENT_RESOURCES_AMBIENT_ANIMATION_STATIC_RESOURCES_H_ +#define ASH_AMBIENT_RESOURCES_AMBIENT_ANIMATION_STATIC_RESOURCES_H_ + +#include <memory> + +#include "ash/ash_export.h" +#include "ash/public/cpp/ambient/ambient_animation_theme.h" +#include "base/containers/flat_map.h" +#include "base/strings/string_piece.h" + +namespace gfx { +class ImageSkia; +} // namespace gfx + +namespace ash { + +// Loads static resources for a given AmbientAnimationTheme. "Static" resources +// are those that are fixed for the lifetime of the animation, as opposed to +// dynamic ones that can change between animation cycles (photos from IMAX). +// All resources are only loaded one time internally, so callers are free to +// invoke these methods as many times as desired without having to worry about +// caching the output themselves. +// +// This class is not thread-safe, but it may be bound to any sequence (including +// the UI sequence). It does not do expensive blocking I/O. +class ASH_EXPORT AmbientAnimationStaticResources { + public: + // Creates an AmbientAnimationStaticResources instance that loads resources + // for the given |theme|. Returns nullptr if |theme| is not supported. + static std::unique_ptr<AmbientAnimationStaticResources> Create( + AmbientAnimationTheme theme); + + virtual ~AmbientAnimationStaticResources() = default; + + // Returns the Lottie animation json data for this theme. The returned + // StringPiece points to data owned by the AmbientAnimationStaticResources + // instance. This method can never fail. + // TODO(esum): Add an argument where the caller specifies whether to load the + // "portrait" or "landscape" version of this animation theme. + virtual base::StringPiece GetLottieData() const = 0; + + // Returns the image to use for a static asset in the animation, identified by + // the |asset_id|. The |asset_id| is a string identifier specified when the + // animation is built offline by UX and is embedded in the Lottie json file. + // Asset ids are unique within each Lottie file, but not across Lottie files. + // + // Returns an empty ImageSkia instance if the |asset_id| is unknown. + virtual gfx::ImageSkia GetStaticImageAsset( + base::StringPiece asset_id) const = 0; +}; + +} // namespace ash + +#endif // ASH_AMBIENT_RESOURCES_AMBIENT_ANIMATION_STATIC_RESOURCES_H_
diff --git a/ash/ambient/resources/ambient_animation_static_resources_impl.cc b/ash/ambient/resources/ambient_animation_static_resources_impl.cc new file mode 100644 index 0000000..b283cd20 --- /dev/null +++ b/ash/ambient/resources/ambient_animation_static_resources_impl.cc
@@ -0,0 +1,129 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/ambient/resources/ambient_animation_static_resources.h" + +#include <utility> + +#include "ash/ambient/resources/grit/ash_ambient_lottie_resources.h" +#include "base/check.h" +#include "base/logging.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/image/image_skia.h" + +namespace ash { +namespace { + +using AnimationThemeToResourceIdMap = + base::flat_map<AmbientAnimationTheme, int>; +using AssetIdToResourceIdMap = base::flat_map<base::StringPiece, int>; + +const AnimationThemeToResourceIdMap& GetAnimationThemeToLottieResourceIdMap() { + static const AnimationThemeToResourceIdMap* m = + new AnimationThemeToResourceIdMap( + {{AmbientAnimationTheme::kFeelTheBreeze, + IDR_ASH_AMBIENT_LOTTIE_LOTTIE_FEEL_THE_BREEZE_ANIMATION_JSON}}); + return *m; +} + +// TODO(esum): Look into auto-generating this map and the one above via a +// build-time script. +AssetIdToResourceIdMap GetAssetIdToResourceIdMapForTheme( + AmbientAnimationTheme theme) { + base::flat_map<AmbientAnimationTheme, AssetIdToResourceIdMap> m = { + // Themes + { + // Theme: Feel the Breeze + AmbientAnimationTheme::kFeelTheBreeze, + { + // Assets + {"bg.png", IDR_ASH_AMBIENT_LOTTIE_LOTTIE_FEEL_THE_BREEZE_BG_PNG}, + {"clips_bottom.png", + IDR_ASH_AMBIENT_LOTTIE_LOTTIE_FEEL_THE_BREEZE_CLIPS_BOTTOM_PNG}, + {"clips_top.png", + IDR_ASH_AMBIENT_LOTTIE_LOTTIE_FEEL_THE_BREEZE_CLIPS_TOP_PNG}, + {"shadow_1.png", + IDR_ASH_AMBIENT_LOTTIE_LOTTIE_FEEL_THE_BREEZE_SHADOW_1_PNG}, + {"shadow_2.png", + IDR_ASH_AMBIENT_LOTTIE_LOTTIE_FEEL_THE_BREEZE_SHADOW_2_PNG}, + {"shadow_3.png", + IDR_ASH_AMBIENT_LOTTIE_LOTTIE_FEEL_THE_BREEZE_SHADOW_3_PNG}, + {"shadow_4.png", + IDR_ASH_AMBIENT_LOTTIE_LOTTIE_FEEL_THE_BREEZE_SHADOW_4_PNG}, + {"shadow_5.png", + IDR_ASH_AMBIENT_LOTTIE_LOTTIE_FEEL_THE_BREEZE_SHADOW_5_PNG}, + {"shadow_6.png", + IDR_ASH_AMBIENT_LOTTIE_LOTTIE_FEEL_THE_BREEZE_SHADOW_6_PNG}, + {"time_weather.png", + IDR_ASH_AMBIENT_LOTTIE_LOTTIE_FEEL_THE_BREEZE_TIME_WEATHER_PNG}, + {"tree_shadow.png", + IDR_ASH_AMBIENT_LOTTIE_LOTTIE_FEEL_THE_BREEZE_TREE_SHADOW_PNG} + // End Assets + } + // End Theme: Feel the Breeze + } + // End Themes + }; + DCHECK(m.contains(theme)) << "Asset/resource ids missing for " << theme; + return m.at(theme); +} + +class AmbientAnimationStaticResourcesImpl + : public AmbientAnimationStaticResources { + public: + AmbientAnimationStaticResourcesImpl( + int lottie_json_resource_id, + base::flat_map<base::StringPiece, int> asset_id_to_resource_id) + : lottie_json_resource_id_(lottie_json_resource_id), + asset_id_to_resource_id_(std::move(asset_id_to_resource_id)) {} + + AmbientAnimationStaticResourcesImpl( + const AmbientAnimationStaticResourcesImpl&) = delete; + AmbientAnimationStaticResourcesImpl& operator=( + const AmbientAnimationStaticResourcesImpl&) = delete; + + ~AmbientAnimationStaticResourcesImpl() override = default; + + base::StringPiece GetLottieData() const override { + base::StringPiece animation_json = + ui::ResourceBundle::GetSharedInstance().GetRawDataResource( + lottie_json_resource_id_); + DCHECK(!animation_json.empty()); + return animation_json; + } + + gfx::ImageSkia GetStaticImageAsset( + base::StringPiece asset_id) const override { + if (!asset_id_to_resource_id_.contains(asset_id)) + return gfx::ImageSkia(); + + const gfx::ImageSkia* image = + ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( + asset_id_to_resource_id_.at(asset_id)); + DCHECK(image) << asset_id; + return *image; + } + + private: + // Resource id for this animation theme's Lottie json data. + const int lottie_json_resource_id_; + // Map of all static image assets in this animation to their corresponding + // resource ids. Points to global memory with static duration. + const base::flat_map<base::StringPiece, int> asset_id_to_resource_id_; +}; + +} // namespace + +// static +std::unique_ptr<AmbientAnimationStaticResources> +AmbientAnimationStaticResources::Create(AmbientAnimationTheme theme) { + if (!GetAnimationThemeToLottieResourceIdMap().contains(theme)) + return nullptr; + + return std::make_unique<AmbientAnimationStaticResourcesImpl>( + GetAnimationThemeToLottieResourceIdMap().at(theme), + GetAssetIdToResourceIdMapForTheme(theme)); +} + +} // namespace ash
diff --git a/ash/ambient/resources/ambient_animation_static_resources_impl_unittest.cc b/ash/ambient/resources/ambient_animation_static_resources_impl_unittest.cc new file mode 100644 index 0000000..f9545e6 --- /dev/null +++ b/ash/ambient/resources/ambient_animation_static_resources_impl_unittest.cc
@@ -0,0 +1,64 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/ambient/resources/ambient_animation_static_resources.h" + +#include "ash/public/cpp/ambient/ambient_animation_theme.h" +#include "base/json/json_reader.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/image/image_skia.h" + +namespace ash { + +using ::testing::IsEmpty; +using ::testing::IsNull; +using ::testing::Not; +using ::testing::NotNull; + +// AmbientAnimationStaticResources actually has very little application logic +// and is more a class to house static data. Thus, an animation theme is picked +// as an example and the basics are tested with it. A test case does not need to +// exist for every possible animation theme. + +TEST(AmbientAnimationStaticResourcesTest, LoadsLottieData) { + auto resources = AmbientAnimationStaticResources::Create( + AmbientAnimationTheme::kFeelTheBreeze); + ASSERT_THAT(resources, NotNull()); + ASSERT_THAT(resources->GetLottieData(), Not(IsEmpty())); + EXPECT_TRUE(base::JSONReader::Read(resources->GetLottieData())); +} + +TEST(AmbientAnimationStaticResourcesTest, LoadsStaticAssets) { + auto resources = AmbientAnimationStaticResources::Create( + AmbientAnimationTheme::kFeelTheBreeze); + ASSERT_THAT(resources, NotNull()); + gfx::ImageSkia clips_bottom_original = + resources->GetStaticImageAsset("clips_bottom.png"); + ASSERT_FALSE(clips_bottom_original.isNull()); + gfx::ImageSkia clips_bottom_reloaded = + resources->GetStaticImageAsset("clips_bottom.png"); + ASSERT_FALSE(clips_bottom_reloaded.isNull()); + EXPECT_TRUE( + clips_bottom_reloaded.BackedBySameObjectAs(clips_bottom_original)); + + gfx::ImageSkia clips_top = resources->GetStaticImageAsset("clips_top.png"); + EXPECT_FALSE(clips_top.isNull()); +} + +TEST(AmbientAnimationStaticResourcesTest, FailsForSlideshowTheme) { + EXPECT_THAT(AmbientAnimationStaticResources::Create( + AmbientAnimationTheme::kSlideshow), + IsNull()); +} + +TEST(AmbientAnimationStaticResourcesTest, FailsForUnknownAssetId) { + auto resources = AmbientAnimationStaticResources::Create( + AmbientAnimationTheme::kFeelTheBreeze); + ASSERT_THAT(resources, NotNull()); + gfx::ImageSkia image = resources->GetStaticImageAsset("unknown_asset_id"); + EXPECT_TRUE(image.isNull()); +} + +} // namespace ash
diff --git a/ash/ambient/resources/ambient_animation_static_resources_stub.cc b/ash/ambient/resources/ambient_animation_static_resources_stub.cc new file mode 100644 index 0000000..6b6694d --- /dev/null +++ b/ash/ambient/resources/ambient_animation_static_resources_stub.cc
@@ -0,0 +1,29 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/ambient/resources/ambient_animation_static_resources.h" + +#include "base/logging.h" + +namespace ash { + +// This stub source file is only built on platforms that don't support the +// ambient animation resources. 2 things are required currently for support: +// 1) An internal chrome-branded checkout. +// 2) The include_ash_ambient_animation_resources GN flag must be true. +// Without these, the ambient animation code will still compile due to the +// dummy definitions in this stub, but any resource loading will immediately +// fail with a FATAL error. + +// static +std::unique_ptr<AmbientAnimationStaticResources> +AmbientAnimationStaticResources::Create(AmbientAnimationTheme theme) { + LOG(FATAL) << "Ambient animation resources are not available on this build. " + "To enable, an internal chrome-branded checkout is required, " + "and the include_ash_ambient_animation_resources GN flag must " + "be true."; + return nullptr; +} + +} // namespace ash
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 6e70c9e..7c6ef100 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -2914,6 +2914,12 @@ <message name="IDS_ASH_LOGIN_PUBLIC_ACCOUNT_SIGNOUT_REMINDER" desc="Text shown in the public account user pod, reminding the user to log out."> Your internet session will be cleared when you sign out. <ph name="LEARN_MORE">$1<ex>Learn more</ex></ph> </message> + <message name="IDS_ASH_LOGIN_PUBLIC_ACCOUNT_KEYBOARD_MENU_ACCESSIBLE_NAME" desc="Text to be spoken when the focus is set to the button that opens the keyboard menu for the given public account."> + Enter keyboard menu + </message> + <message name="IDS_ASH_LOGIN_PUBLIC_ACCOUNT_LANGUAGE_MENU_ACCESSIBLE_NAME" desc="Text to be spoken when the focus is set to the button that opens the language menu for the given public account."> + Enter language menu + </message> <message name="IDS_ASH_LOGIN_PUBLIC_SESSION_LANGUAGE_AND_INPUT" desc="Link in managed session pod that shows a section which allows the user to change the UI language and keyboard layout."> Choose language and keyboard </message>
diff --git a/ash/ash_strings_grd/IDS_ASH_LOGIN_PUBLIC_ACCOUNT_KEYBOARD_MENU_ACCESSIBLE_NAME.png.sha1 b/ash/ash_strings_grd/IDS_ASH_LOGIN_PUBLIC_ACCOUNT_KEYBOARD_MENU_ACCESSIBLE_NAME.png.sha1 new file mode 100644 index 0000000..64879a0b --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_LOGIN_PUBLIC_ACCOUNT_KEYBOARD_MENU_ACCESSIBLE_NAME.png.sha1
@@ -0,0 +1 @@ +0c765e9ca952f1ef90d361ed1621d4c36ea877a8 \ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_LOGIN_PUBLIC_ACCOUNT_LANGUAGE_MENU_ACCESSIBLE_NAME.png.sha1 b/ash/ash_strings_grd/IDS_ASH_LOGIN_PUBLIC_ACCOUNT_LANGUAGE_MENU_ACCESSIBLE_NAME.png.sha1 new file mode 100644 index 0000000..f36eda78 --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_LOGIN_PUBLIC_ACCOUNT_LANGUAGE_MENU_ACCESSIBLE_NAME.png.sha1
@@ -0,0 +1 @@ +79334e470869b8793b6db55d2ac2672f8eb6653f \ No newline at end of file
diff --git a/ash/capture_mode/capture_mode_advanced_settings_view.cc b/ash/capture_mode/capture_mode_advanced_settings_view.cc index cfb3a54..699fb7c2 100644 --- a/ash/capture_mode/capture_mode_advanced_settings_view.cc +++ b/ash/capture_mode/capture_mode_advanced_settings_view.cc
@@ -65,9 +65,11 @@ this, kCaptureModeMicIcon, l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_AUDIO_INPUT)))) { - audio_input_menu_group_->AddOption( - l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_AUDIO_INPUT_OFF), - kAudioOff); + if (!is_in_projector_mode) { + audio_input_menu_group_->AddOption( + l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_AUDIO_INPUT_OFF), + kAudioOff); + } audio_input_menu_group_->AddOption( l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_AUDIO_INPUT_MICROPHONE), kAudioMicrophone);
diff --git a/ash/capture_mode/capture_mode_bar_view.cc b/ash/capture_mode/capture_mode_bar_view.cc index be1194b..17941009 100644 --- a/ash/capture_mode/capture_mode_bar_view.cc +++ b/ash/capture_mode/capture_mode_bar_view.cc
@@ -25,6 +25,7 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/compositor/layer.h" +#include "ui/gfx/geometry/size.h" #include "ui/gfx/paint_vector_icon.h" #include "ui/strings/grit/ui_strings.h" #include "ui/views/background.h" @@ -36,7 +37,9 @@ namespace { -constexpr gfx::Size kBarSize{376, 64}; +// Full size of capture mode bar view, the width of which will be +// adjusted in projector mode. +constexpr gfx::Size kFullBarSize{376, 64}; constexpr gfx::Insets kBarPadding{/*vertical=*/14, /*horizontal=*/16}; @@ -110,7 +113,8 @@ CaptureModeBarView::~CaptureModeBarView() = default; // static -gfx::Rect CaptureModeBarView::GetBounds(aura::Window* root) { +gfx::Rect CaptureModeBarView::GetBounds(aura::Window* root, + bool is_in_projector_mode) { DCHECK(root); auto bounds = root->GetBoundsInScreen(); @@ -128,8 +132,14 @@ bar_y = shelf_widget->GetWindowBoundsInScreen().y(); } - bar_y -= (kDistanceFromShelfOrHotseatTopDp + kBarSize.height()); - bounds.ClampToCenteredSize(kBarSize); + gfx::Size bar_size = kFullBarSize; + if (is_in_projector_mode) { + bar_size.set_width(kFullBarSize.width() - + capture_mode::kButtonSize.width() - + capture_mode::kSpaceBetweenCaptureModeTypeButtons); + } + bar_y -= (kDistanceFromShelfOrHotseatTopDp + bar_size.height()); + bounds.ClampToCenteredSize(bar_size); bounds.set_y(bar_y); return bounds; }
diff --git a/ash/capture_mode/capture_mode_bar_view.h b/ash/capture_mode/capture_mode_bar_view.h index e98feb0..f18d4c26 100644 --- a/ash/capture_mode/capture_mode_bar_view.h +++ b/ash/capture_mode/capture_mode_bar_view.h
@@ -62,8 +62,10 @@ CaptureModeButton* close_button() const { return close_button_; } // Gets the ideal bounds in screen coordinates of the bar of widget on the - // given |root| window. - static gfx::Rect GetBounds(aura::Window* root); + // given `root` window. The `image_toggle_button` will not be shown in the bar + // if `is_in_projector_mode` is true, which means the width of the bar will be + // different. + static gfx::Rect GetBounds(aura::Window* root, bool is_in_projector_mode); // Called when either the capture mode source or type changes. void OnCaptureSourceChanged(CaptureModeSource new_source);
diff --git a/ash/capture_mode/capture_mode_constants.h b/ash/capture_mode/capture_mode_constants.h index c750632..adf05a68 100644 --- a/ash/capture_mode/capture_mode_constants.h +++ b/ash/capture_mode/capture_mode_constants.h
@@ -32,6 +32,9 @@ constexpr int kCaptureRegionBorderStrokePx = 1; constexpr SkColor kRegionBorderColor = SK_ColorWHITE; +// The space between the `image_toggle_button_` and `video_toggle_button_`. +constexpr int kSpaceBetweenCaptureModeTypeButtons = 2; + } // namespace capture_mode } // namespace ash
diff --git a/ash/capture_mode/capture_mode_session.cc b/ash/capture_mode/capture_mode_session.cc index b72e9ea..ee4d7af8 100644 --- a/ash/capture_mode/capture_mode_session.cc +++ b/ash/capture_mode/capture_mode_session.cc
@@ -540,9 +540,10 @@ // the region is not larger than the current display. ClampCaptureRegionToRootWindowSize(); - capture_mode_bar_widget_->Init( - CreateWidgetParams(parent, CaptureModeBarView::GetBounds(current_root_), - "CaptureModeBarWidget")); + capture_mode_bar_widget_->Init(CreateWidgetParams( + parent, + CaptureModeBarView::GetBounds(current_root_, is_in_projector_mode_), + "CaptureModeBarWidget")); capture_mode_bar_view_ = capture_mode_bar_widget_->SetContentsView( std::make_unique<CaptureModeBarView>(is_in_projector_mode_)); capture_mode_bar_widget_->GetNativeWindow()->SetTitle( @@ -1163,7 +1164,7 @@ void CaptureModeSession::RefreshBarWidgetBounds() { DCHECK(capture_mode_bar_widget_); capture_mode_bar_widget_->SetBounds( - CaptureModeBarView::GetBounds(current_root_)); + CaptureModeBarView::GetBounds(current_root_, is_in_projector_mode_)); auto* parent = GetParentContainer(current_root_); parent->StackChildAtTop(capture_mode_bar_widget_->GetNativeWindow()); if (user_nudge_controller_)
diff --git a/ash/capture_mode/capture_mode_session_focus_cycler.cc b/ash/capture_mode/capture_mode_session_focus_cycler.cc index 2ea7e2b..35792d35 100644 --- a/ash/capture_mode/capture_mode_session_focus_cycler.cc +++ b/ash/capture_mode/capture_mode_session_focus_cycler.cc
@@ -448,9 +448,10 @@ source_view->fullscreen_toggle_button(), source_view->region_toggle_button(), source_view->window_toggle_button()}; + base::EraseIf(items, [](CaptureModeSessionFocusCycler::HighlightableView* item) { - return !item->GetView()->GetEnabled(); + return !item || !item->GetView()->GetEnabled(); }); break; }
diff --git a/ash/capture_mode/capture_mode_type_view.cc b/ash/capture_mode/capture_mode_type_view.cc index a7260c65..bacbd68 100644 --- a/ash/capture_mode/capture_mode_type_view.cc +++ b/ash/capture_mode/capture_mode_type_view.cc
@@ -6,6 +6,7 @@ #include <memory> +#include "ash/capture_mode/capture_mode_constants.h" #include "ash/capture_mode/capture_mode_controller.h" #include "ash/capture_mode/capture_mode_metrics.h" #include "ash/capture_mode/capture_mode_toggle_button.h" @@ -27,21 +28,23 @@ constexpr gfx::Insets kViewInsets{2}; -constexpr int kButtonSpacing = 2; - } // namespace CaptureModeTypeView::CaptureModeTypeView(bool projector_mode) - : image_toggle_button_( - AddChildView(std::make_unique<CaptureModeToggleButton>( - base::BindRepeating(&CaptureModeTypeView::OnImageToggle, - base::Unretained(this)), - kCaptureModeImageIcon))), - video_toggle_button_( + : video_toggle_button_( AddChildView(std::make_unique<CaptureModeToggleButton>( base::BindRepeating(&CaptureModeTypeView::OnVideoToggle, base::Unretained(this)), kCaptureModeVideoIcon))) { + if (!projector_mode) { + image_toggle_button_ = + AddChildView(std::make_unique<CaptureModeToggleButton>( + base::BindRepeating(&CaptureModeTypeView::OnImageToggle, + base::Unretained(this)), + kCaptureModeImageIcon)); + image_toggle_button_->SetTooltipText( + l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_TOOLTIP_SCREENSHOT)); + } auto* color_provider = AshColorProvider::Get(); const SkColor bg_color = color_provider->GetControlsLayerColor( AshColorProvider::ControlsLayerType::kControlBackgroundColorInactive); @@ -50,22 +53,18 @@ SetBorder(views::CreateEmptyBorder(kViewInsets)); auto* box_layout = SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kHorizontal, gfx::Insets(0), - kButtonSpacing)); + capture_mode::kSpaceBetweenCaptureModeTypeButtons)); box_layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kCenter); auto* controller = CaptureModeController::Get(); + if (controller->is_recording_in_progress()) { // We can't have more than one recording at the same time. video_toggle_button_->SetEnabled(false); - } else if (projector_mode) { - // Projector mode can only do video recording. - image_toggle_button_->SetEnabled(false); } OnCaptureTypeChanged(controller->type()); - image_toggle_button_->SetTooltipText( - l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_TOOLTIP_SCREENSHOT)); video_toggle_button_->SetTooltipText( l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_TOOLTIP_SCREENRECORD)); } @@ -75,10 +74,13 @@ void CaptureModeTypeView::OnCaptureTypeChanged(CaptureModeType new_type) { DCHECK(!CaptureModeController::Get()->is_recording_in_progress() || new_type == CaptureModeType::kImage); - image_toggle_button_->SetToggled(new_type == CaptureModeType::kImage); + video_toggle_button_->SetToggled(new_type == CaptureModeType::kVideo); - DCHECK_NE(image_toggle_button_->GetToggled(), - video_toggle_button_->GetToggled()); + if (image_toggle_button_) { + image_toggle_button_->SetToggled(new_type == CaptureModeType::kImage); + DCHECK_NE(image_toggle_button_->GetToggled(), + video_toggle_button_->GetToggled()); + } } void CaptureModeTypeView::OnImageToggle() {
diff --git a/ash/capture_mode/capture_mode_type_view.h b/ash/capture_mode/capture_mode_type_view.h index 91a4fc2..46678e42 100644 --- a/ash/capture_mode/capture_mode_type_view.h +++ b/ash/capture_mode/capture_mode_type_view.h
@@ -42,8 +42,9 @@ void OnImageToggle(); void OnVideoToggle(); - // Owned by the views hierarchy. - CaptureModeToggleButton* image_toggle_button_; + // Owned by the views hierarchy. Initialize `image_toggle_button_` to nullptr + // as it is never created in projector mode. + CaptureModeToggleButton* image_toggle_button_ = nullptr; CaptureModeToggleButton* video_toggle_button_; };
diff --git a/ash/capture_mode/capture_mode_unittests.cc b/ash/capture_mode/capture_mode_unittests.cc index 95b6257..66acb9e2 100644 --- a/ash/capture_mode/capture_mode_unittests.cc +++ b/ash/capture_mode/capture_mode_unittests.cc
@@ -4932,24 +4932,19 @@ CaptureModeMenuGroup* save_to_menu_group = test_api.GetSaveToMenuGroup(); EXPECT_FALSE(save_to_menu_group); - // The audio-off option should be disabled, unchecked and not interactable - // (even when clicked). - views::View* audio_off_option = test_api.GetAudioOffOption(); - EXPECT_FALSE(audio_off_option->GetEnabled()); + // The audio-off option should never be added. + EXPECT_FALSE(test_api.GetAudioOffOption()); + CaptureModeMenuGroup* audio_input_menu_group = test_api.GetAudioInputMenuGroup(); EXPECT_TRUE(audio_input_menu_group->IsOptionChecked(kAudioMicrophone)); - EXPECT_FALSE(audio_input_menu_group->IsOptionChecked(kAudioOff)); - ClickOnView(audio_off_option, event_generator); - EXPECT_TRUE(audio_input_menu_group->IsOptionChecked(kAudioMicrophone)); - EXPECT_FALSE(audio_input_menu_group->IsOptionChecked(kAudioOff)); EXPECT_TRUE(controller->enable_audio_recording()); } // Tests the keyboard navigation for projector mode with advanced capture mode // settings enabled. The `image_toggle_button_` in `CaptureModeTypeView` and the -// `Off` audio input option in `CaptureModeAdvancedSettingsView` are disabled in -// projector mode, thus they should be skipped while tabbing though. +// `Off` audio input option in `CaptureModeAdvancedSettingsView` are not +// available in projector mode. TEST_F(ProjectorCaptureModeIntegrationTests, KeyboardNavigationWithAdvancedSettings) { base::test::ScopedFeatureList scoped_feature_list{ @@ -4964,9 +4959,8 @@ using FocusGroup = CaptureModeSessionFocusCycler::FocusGroup; CaptureModeSessionTestApi test_api(controller->capture_mode_session()); - EXPECT_FALSE(GetImageToggleButton()->GetEnabled()); - // Tab once, check the image toggle button is skipped and the current focused - // view is the video toggle button. + EXPECT_FALSE(GetImageToggleButton()); + // Tab once, check the current focused view is the video toggle button. auto* event_generator = GetEventGenerator(); SendKey(ui::VKEY_TAB, event_generator); EXPECT_EQ(test_api.GetCurrentFocusedView()->GetView(), @@ -4982,10 +4976,10 @@ ASSERT_TRUE(settings_menu); CaptureModeAdvancedSettingsTestApi advanced_settings_test_api; - // Tab twice, check the `Off` option is skipped and remains disabled. The - // current focused view is the `Microphone` option. + // The `Off` option should not be visible. + EXPECT_FALSE(advanced_settings_test_api.GetAudioOffOption()); + // Tab twice, the current focused view is the `Microphone` option. SendKey(ui::VKEY_TAB, event_generator, /*shift_down=*/false, /*count=*/2); - EXPECT_FALSE(advanced_settings_test_api.GetAudioOffOption()->GetEnabled()); EXPECT_EQ(test_api.GetCurrentFocusedView()->GetView(), advanced_settings_test_api.GetMicrophoneOption()); } @@ -4995,10 +4989,9 @@ StartProjectorModeSession(); EXPECT_TRUE(controller->IsActive()); - // The image toggle button should be disabled, whereas the video toggle button - // should be enabled and active. - EXPECT_FALSE(GetImageToggleButton()->GetEnabled()); - EXPECT_FALSE(GetImageToggleButton()->GetToggled()); + // The image toggle button shouldn't be available, whereas the video toggle + // button should be enabled and active. + EXPECT_FALSE(GetImageToggleButton()); EXPECT_TRUE(GetVideoToggleButton()->GetEnabled()); EXPECT_TRUE(GetVideoToggleButton()->GetToggled()); }
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index 1a122f84..86ee1593 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -703,14 +703,14 @@ // transfer or access it later. const base::Feature kHoldingSpaceInProgressDownloadsIntegration{ "HoldingSpaceInProgressDownloadsIntegration", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; // Enables in-progress downloads notification suppression with the productivity // feature that aims to reduce context switching by enabling users to collect // content and transfer or access it later. const base::Feature kHoldingSpaceInProgressDownloadsNotificationSuppression{ "HoldingSpaceInProgressNotificationSuppression", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; // Enables incognito profile integration with the productivity feature that // aims to reduce context switching by enabling users to collect content and
diff --git a/ash/login/login_screen_test_api.cc b/ash/login/login_screen_test_api.cc index 63886ace..c3342fa 100644 --- a/ash/login/login_screen_test_api.cc +++ b/ash/login/login_screen_test_api.cc
@@ -662,7 +662,7 @@ lock_screen_test.contents_view()); LoginExpandedPublicAccountView::TestApi expanded_test( lock_contents_test.expanded_view()); - return expanded_test.selected_language_item().value; + return expanded_test.selected_language_item_value(); } // static @@ -672,7 +672,7 @@ lock_screen_test.contents_view()); LoginExpandedPublicAccountView::TestApi expanded_test( lock_contents_test.expanded_view()); - return expanded_test.selected_keyboard_item().value; + return expanded_test.selected_keyboard_item_value(); } // static
diff --git a/ash/login/ui/login_expanded_public_account_view.cc b/ash/login/ui/login_expanded_public_account_view.cc index df8f780..3a2779b 100644 --- a/ash/login/ui/login_expanded_public_account_view.cc +++ b/ash/login/ui/login_expanded_public_account_view.cc
@@ -37,6 +37,7 @@ #include "ui/views/controls/label.h" #include "ui/views/layout/box_layout.h" #include "ui/views/layout/fill_layout.h" +#include "ui/views/mouse_constants.h" namespace ash { @@ -52,19 +53,15 @@ constexpr int kBorderThicknessDp = 1; constexpr int kHorizontalMarginPaneDp = 28; constexpr int kLabelMarginDp = 20; -constexpr int kLeftMarginForSelectionButton = 8; -constexpr int kRightMarginForSelectionButton = 3; constexpr int kDropDownIconSizeDp = 16; constexpr int kArrowButtonSizeDp = 48; constexpr int kAdvancedViewButtonWidthDp = 190; constexpr int kAdvancedViewButtonHeightDp = 16; -constexpr int kSelectionBoxWidthDp = 192; -constexpr int kSelectionBoxHeightDp = 28; constexpr int kTopSpacingForLabelInAdvancedViewDp = 7; constexpr int kTopSpacingForLabelInRegularViewDp = 65; constexpr int kSpacingBetweenLabelsDp = 17; -constexpr int kSpacingBetweenSelectionMenusDp = 15; +constexpr int kSpacingBetweenSelectionMenusDp = 7; constexpr int kSpacingBetweenSelectionTitleAndButtonDp = 3; constexpr int kSpacingBetweenLanguageMenuAndAdvancedViewButtonDp = 4; constexpr int kSpacingBetweenAdvancedViewButtonAndLabelDp = 32; @@ -77,6 +74,10 @@ constexpr int kSpacingBetweenMonitoringWarningIconAndLabelDp = 8; constexpr int kMonitoringWarningIconSizeDp = 20; +constexpr char kRightPaneViewClassName[] = "RightPaneView"; +constexpr char kRightPaneLabelsViewClassName[] = "RightPaneLabelsView"; +constexpr char kRightPaneAdvancedViewClassName[] = "RightPaneAdvancedView"; + views::Label* CreateLabel(const std::u16string& text, SkColor color) { auto* label = new views::Label(text); label->SetSubpixelRenderingEnabled(false); @@ -300,13 +301,14 @@ // Implements the right part of the expanded public session view. class RightPaneView : public NonAccessibleView { public: - explicit RightPaneView(const base::RepeatingClosure& on_learn_more_tapped) { + explicit RightPaneView(const base::RepeatingClosure& on_learn_more_tapped) + : NonAccessibleView(kRightPaneViewClassName) { SetPreferredSize( gfx::Size(kExpandedViewWidthDp / 2, kExpandedViewHeightDp)); SetBorder(views::CreateEmptyBorder(gfx::Insets(kHorizontalMarginPaneDp))); // Create labels view. - labels_view_ = new NonAccessibleView(); + labels_view_ = new NonAccessibleView(kRightPaneLabelsViewClassName); labels_view_->SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kVertical, gfx::Insets(), kSpacingBetweenLabelsDp)); @@ -356,7 +358,7 @@ AddChildView(advanced_view_button_); // Create advanced view. - advanced_view_ = new NonAccessibleView(); + advanced_view_ = new NonAccessibleView(kRightPaneAdvancedViewClassName); advanced_view_->SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kVertical)); AddChildView(advanced_view_); @@ -365,55 +367,28 @@ AshColorProvider::Get()->GetContentLayerColor( AshColorProvider::ContentLayerType::kTextColorSecondary); - // Creates button to open the menu. - auto create_menu_button = - [&](views::Button::PressedCallback callback, - const std::u16string& text) -> SelectionButtonView* { - auto* button = new SelectionButtonView(std::move(callback), text); - button->SetPreferredSize( - gfx::Size(kSelectionBoxWidthDp, kSelectionBoxHeightDp)); - button->SetMargins(kLeftMarginForSelectionButton, - kRightMarginForSelectionButton); - button->SetBorder(views::CreateRoundedRectBorder( - kBorderThicknessDp, kRoundRectCornerRadiusDp, - AshColorProvider::Get()->GetContentLayerColor( - AshColorProvider::ContentLayerType::kSeparatorColor))); - button->SetIcon(kLoginScreenMenuDropdownIcon, selection_menu_title_color); - return button; - }; - auto create_padding = [](int amount) -> views::View* { auto* padding = new NonAccessibleView(); padding->SetPreferredSize(gfx::Size(kNonEmptyWidth, amount)); return padding; }; - views::Label* language_title = CreateLabel( + language_title_ = CreateLabel( l10n_util::GetStringUTF16(IDS_ASH_LOGIN_LANGUAGE_SELECTION_SELECT), selection_menu_title_color); - language_selection_ = create_menu_button( - base::BindRepeating(&RightPaneView::LanguageSelectionButtonPressed, - base::Unretained(this)), - std::u16string()); - views::Label* keyboard_title = CreateLabel( + keyboard_title_ = CreateLabel( l10n_util::GetStringUTF16(IDS_ASH_LOGIN_KEYBOARD_SELECTION_SELECT), selection_menu_title_color); - keyboard_selection_ = create_menu_button( - base::BindRepeating(&RightPaneView::KeyboardSelectionButtonPressed, - base::Unretained(this)), - std::u16string()); - advanced_view_->AddChildView(language_title); + advanced_view_->AddChildView(language_title_); advanced_view_->AddChildView( create_padding(kSpacingBetweenSelectionTitleAndButtonDp)); - advanced_view_->AddChildView(language_selection_); advanced_view_->AddChildView( create_padding(kSpacingBetweenSelectionMenusDp)); - advanced_view_->AddChildView(keyboard_title); + advanced_view_->AddChildView(keyboard_title_); advanced_view_->AddChildView( create_padding(kSpacingBetweenSelectionTitleAndButtonDp)); - advanced_view_->AddChildView(keyboard_selection_); submit_button_ = new ArrowButtonView( base::BindRepeating(&RightPaneView::SubmitButtonPressed, @@ -471,19 +446,13 @@ monitoring_warning_view_->UpdateForUser(user); current_user_ = user; if (!language_changed_by_user_) - selected_language_item_.value = user.public_account_info->default_locale; + selected_language_item_value_ = user.public_account_info->default_locale; PopulateLanguageItems(user.public_account_info->available_locales); if (user.public_account_info->default_locale == - selected_language_item_.value) { + selected_language_item_value_) PopulateKeyboardItems(user.public_account_info->keyboard_layouts); - } - - language_selection_->SetText( - base::UTF8ToUTF16(selected_language_item_.title)); - keyboard_selection_->SetText( - base::UTF8ToUTF16(selected_keyboard_item_.title)); if (!show_advanced_changed_by_user_) show_advanced_view_ = user.public_account_info->show_advanced_view; @@ -499,27 +468,26 @@ : MonitoringWarningView::WarningType::kSoftWarning); } - void OnLanguageSelected(PublicAccountMenuView::Item item) { + void OnLanguageSelected(const std::string& value) { language_changed_by_user_ = true; - selected_language_item_ = item; - language_selection_->SetText(base::UTF8ToUTF16(item.title)); - current_user_.public_account_info->default_locale = item.value; + selected_language_item_value_ = value; + current_user_.public_account_info->default_locale = value; // User changed the preferred locale, request to get corresponding keyboard // layouts. Shell::Get() ->login_screen_controller() ->RequestPublicSessionKeyboardLayouts( - current_user_.basic_user_info.account_id, item.value); + current_user_.basic_user_info.account_id, value); } - void OnKeyboardSelected(PublicAccountMenuView::Item item) { - selected_keyboard_item_ = item; - keyboard_selection_->SetText(base::UTF8ToUTF16(item.title)); + void OnKeyboardSelected(const std::string& value) { + selected_keyboard_item_value_ = value; } void PopulateLanguageItems(const std::vector<LocaleItem>& locales) { language_items_.clear(); + int selected_language_index = 0; for (const auto& locale : locales) { PublicAccountMenuView::Item item; if (locale.group_name) { @@ -529,69 +497,74 @@ item.title = locale.title; item.value = locale.language_code; item.is_group = false; - item.selected = selected_language_item_.value == locale.language_code; + item.selected = selected_language_item_value_ == locale.language_code; } + if (selected_language_item_value_ == locale.language_code) + selected_language_index = language_items_.size(); language_items_.push_back(item); - - if (selected_language_item_.value == locale.language_code) - selected_language_item_ = item; } - PublicAccountMenuView* old_language_menu_view = language_menu_view_; - + if (language_menu_view_) { + advanced_view_->RemoveChildView(language_menu_view_); + delete language_menu_view_; + } language_menu_view_ = new PublicAccountMenuView( - language_items_, language_selection_ /*anchor_view*/, - language_selection_ /*bubble_opener*/, + language_items_, selected_language_index, base::BindRepeating(&RightPaneView::OnLanguageSelected, weak_factory_.GetWeakPtr())); - login_views_utils::GetBubbleContainer(this)->AddChildView( - language_menu_view_); + language_menu_view_->SetTooltipTextAndAccessibleName( + l10n_util::GetStringUTF16( + IDS_ASH_LOGIN_PUBLIC_ACCOUNT_LANGUAGE_MENU_ACCESSIBLE_NAME)); - if (old_language_menu_view) - delete old_language_menu_view; + int after_title_after_padding_index = + advanced_view_->GetIndexOf(language_title_) + 2; + advanced_view_->AddChildViewAt(language_menu_view_, + after_title_after_padding_index); } void PopulateKeyboardItems( const std::vector<InputMethodItem>& keyboard_layouts) { keyboard_items_.clear(); + int selected_keyboard_index = 0; for (const auto& keyboard : keyboard_layouts) { PublicAccountMenuView::Item item; item.title = keyboard.title; item.value = keyboard.ime_id; item.is_group = false; item.selected = keyboard.selected; + if (keyboard.selected) { + selected_keyboard_index = keyboard_items_.size(); + selected_keyboard_item_value_ = item.value; + } keyboard_items_.push_back(item); - - if (keyboard.selected) - selected_keyboard_item_ = item; } - PublicAccountMenuView* old_keyboard_menu_view = keyboard_menu_view_; - + if (keyboard_menu_view_) { + advanced_view_->RemoveChildView(keyboard_menu_view_); + delete keyboard_menu_view_; + } keyboard_menu_view_ = new PublicAccountMenuView( - keyboard_items_, keyboard_selection_ /*anchor_view*/, - keyboard_selection_ /*bubble_opener*/, + keyboard_items_, selected_keyboard_index, base::BindRepeating(&RightPaneView::OnKeyboardSelected, weak_factory_.GetWeakPtr())); - login_views_utils::GetBubbleContainer(this)->AddChildView( - keyboard_menu_view_); + keyboard_menu_view_->SetTooltipTextAndAccessibleName( + l10n_util::GetStringUTF16( + IDS_ASH_LOGIN_PUBLIC_ACCOUNT_KEYBOARD_MENU_ACCESSIBLE_NAME)); - if (old_keyboard_menu_view) - delete old_keyboard_menu_view; + int after_title_after_padding_index = + advanced_view_->GetIndexOf(keyboard_title_) + 2; + advanced_view_->AddChildViewAt(keyboard_menu_view_, + after_title_after_padding_index); } - LoginBaseBubbleView* GetLanguageMenuView() { return language_menu_view_; } + PublicAccountMenuView* GetLanguageMenuView() { return language_menu_view_; } - LoginBaseBubbleView* GetKeyboardMenuView() { return keyboard_menu_view_; } + PublicAccountMenuView* GetKeyboardMenuView() { return keyboard_menu_view_; } - // Close language and keyboard menus and reset local states. + // Reset local states. void Reset() { show_advanced_changed_by_user_ = false; language_changed_by_user_ = false; - if (language_menu_view_ && language_menu_view_->GetVisible()) - language_menu_view_->Hide(); - if (keyboard_menu_view_ && keyboard_menu_view_->GetVisible()) - keyboard_menu_view_->Hide(); } private: @@ -605,42 +578,15 @@ void SubmitButtonPressed() { // TODO(crbug.com/984021) change to LaunchSamlPublicSession which would - // take selected_language_item_.value, selected_keyboard_item_.value too. + // take |selected_language_item_value_| and |selected_keyboard_item_value_| + // too. if (current_user_.public_account_info->using_saml) { Shell::Get()->login_screen_controller()->ShowGaiaSignin( current_user_.basic_user_info.account_id); } else { Shell::Get()->login_screen_controller()->LaunchPublicSession( current_user_.basic_user_info.account_id, - selected_language_item_.value, selected_keyboard_item_.value); - } - } - - void LanguageSelectionButtonPressed() { - DCHECK(language_menu_view_); - if (language_menu_view_->GetVisible()) { - language_menu_view_->Hide(); - } else { - bool opener_had_focus = language_selection_->HasFocus(); - - language_menu_view_->Show(); - - if (opener_had_focus) - language_menu_view_->RequestFocus(); - } - } - - void KeyboardSelectionButtonPressed() { - DCHECK(keyboard_menu_view_); - if (keyboard_menu_view_->GetVisible()) { - keyboard_menu_view_->Hide(); - } else { - bool opener_had_focus = keyboard_selection_->HasFocus(); - - keyboard_menu_view_->Show(); - - if (opener_had_focus) - keyboard_menu_view_->RequestFocus(); + selected_language_item_value_, selected_keyboard_item_value_); } } @@ -650,20 +596,17 @@ views::View* labels_view_ = nullptr; SelectionButtonView* advanced_view_button_ = nullptr; views::View* advanced_view_ = nullptr; - SelectionButtonView* language_selection_ = nullptr; - SelectionButtonView* keyboard_selection_ = nullptr; + views::View* language_title_ = nullptr; + views::View* keyboard_title_ = nullptr; ArrowButtonView* submit_button_ = nullptr; views::StyledLabel* learn_more_label_ = nullptr; MonitoringWarningView* monitoring_warning_view_ = nullptr; - // |language_menu_view_| and |keyboard_menu_view_| are parented by the top - // level view, either LockContentsView or LockDebugView. This allows the menu - // items to be clicked outside the bounds of the right pane view. PublicAccountMenuView* language_menu_view_ = nullptr; PublicAccountMenuView* keyboard_menu_view_ = nullptr; - PublicAccountMenuView::Item selected_language_item_; - PublicAccountMenuView::Item selected_keyboard_item_; + std::string selected_language_item_value_; + std::string selected_keyboard_item_value_; std::vector<PublicAccountMenuView::Item> language_items_; std::vector<PublicAccountMenuView::Item> keyboard_items_; @@ -711,16 +654,6 @@ return view_->right_pane_->learn_more_label_; } -views::View* -LoginExpandedPublicAccountView::TestApi::language_selection_button() { - return view_->right_pane_->language_selection_; -} - -views::View* -LoginExpandedPublicAccountView::TestApi::keyboard_selection_button() { - return view_->right_pane_->keyboard_selection_; -} - PublicAccountMenuView* LoginExpandedPublicAccountView::TestApi::language_menu_view() { return view_->right_pane_->language_menu_view_; @@ -731,14 +664,14 @@ return view_->right_pane_->keyboard_menu_view_; } -PublicAccountMenuView::Item -LoginExpandedPublicAccountView::TestApi::selected_language_item() { - return view_->right_pane_->selected_language_item_; +std::string +LoginExpandedPublicAccountView::TestApi::selected_language_item_value() { + return view_->right_pane_->selected_language_item_value_; } -PublicAccountMenuView::Item -LoginExpandedPublicAccountView::TestApi::selected_keyboard_item() { - return view_->right_pane_->selected_keyboard_item_; +std::string +LoginExpandedPublicAccountView::TestApi::selected_keyboard_item_value() { + return view_->right_pane_->selected_keyboard_item_value_; } views::ImageView* @@ -764,7 +697,7 @@ const std::string& language_code) { for (PublicAccountMenuView::Item item : view_->right_pane_->language_items_) { if (item.value == language_code) { - view_->right_pane_->OnLanguageSelected(item); + view_->right_pane_->OnLanguageSelected(item.value); return true; } } @@ -775,7 +708,7 @@ const std::string& ime_id) { for (PublicAccountMenuView::Item item : view_->right_pane_->keyboard_items_) { if (item.value == ime_id) { - view_->right_pane_->OnKeyboardSelected(item); + view_->right_pane_->OnKeyboardSelected(item.value); return true; } } @@ -853,16 +786,27 @@ if (GetBoundsInScreen().Contains(event->root_location())) return; - // Ignore press event inside the language and keyboard menu. - LoginBaseBubbleView* language_menu_view = right_pane_->GetLanguageMenuView(); + // Ignore press event if the language or keyboard menu is still running, + // or if it had just been closed. Note that when we checked closed time, + // if the menu has never been closed, closed time will be set to time 0 and + // the time delta between now and then will be more than 100 ms. + PublicAccountMenuView* language_menu_view = + right_pane_->GetLanguageMenuView(); if (language_menu_view && - language_menu_view->GetBoundsInScreen().Contains(event->root_location())) + (language_menu_view->IsMenuRunning() || + (base::TimeTicks::Now() - language_menu_view->GetClosedTime()) < + views::kMinimumTimeBetweenButtonClicks)) { return; + } - LoginBaseBubbleView* keyboard_menu_view = right_pane_->GetKeyboardMenuView(); + PublicAccountMenuView* keyboard_menu_view = + right_pane_->GetKeyboardMenuView(); if (keyboard_menu_view && - keyboard_menu_view->GetBoundsInScreen().Contains(event->root_location())) + (keyboard_menu_view->IsMenuRunning() || + (base::TimeTicks::Now() - language_menu_view->GetClosedTime()) < + views::kMinimumTimeBetweenButtonClicks)) { return; + } Hide(); }
diff --git a/ash/login/ui/login_expanded_public_account_view.h b/ash/login/ui/login_expanded_public_account_view.h index f905b98..9e04875e 100644 --- a/ash/login/ui/login_expanded_public_account_view.h +++ b/ash/login/ui/login_expanded_public_account_view.h
@@ -43,12 +43,10 @@ views::View* advanced_view(); PublicAccountMonitoringInfoDialog* learn_more_dialog(); views::StyledLabel* learn_more_label(); - views::View* language_selection_button(); - views::View* keyboard_selection_button(); PublicAccountMenuView* language_menu_view(); PublicAccountMenuView* keyboard_menu_view(); - PublicAccountMenuView::Item selected_language_item(); - PublicAccountMenuView::Item selected_keyboard_item(); + std::string selected_language_item_value(); + std::string selected_keyboard_item_value(); views::ImageView* monitoring_warning_icon(); views::Label* monitoring_warning_label(); void ResetUserForTest();
diff --git a/ash/login/ui/login_expanded_public_account_view_unittest.cc b/ash/login/ui/login_expanded_public_account_view_unittest.cc index 5c52c56a..db7dd56 100644 --- a/ash/login/ui/login_expanded_public_account_view_unittest.cc +++ b/ash/login/ui/login_expanded_public_account_view_unittest.cc
@@ -20,6 +20,7 @@ #include "ui/events/test/event_generator.h" #include "ui/views/controls/link.h" #include "ui/views/layout/box_layout.h" +#include "ui/views/test/combobox_test_api.h" #include "ui/views/widget/widget.h" namespace ash { @@ -203,16 +204,18 @@ LoginExpandedPublicAccountView::TestApi test_api(public_account_); // Verify the language and keyboard information is populated correctly. - std::string selected_language = test_api.selected_language_item().value; - std::string selected_keyboard = test_api.selected_keyboard_item().value; - EXPECT_EQ(selected_language, kEnglishLanguageCode); - EXPECT_EQ(selected_keyboard, kKeyboardIdForItem2); + std::string selected_language_item_value = + test_api.selected_language_item_value(); + EXPECT_EQ(selected_language_item_value, kEnglishLanguageCode); + std::string selected_keyboard_item_value = + test_api.selected_keyboard_item_value(); + EXPECT_EQ(selected_keyboard_item_value, kKeyboardIdForItem2); // Expect LaunchPublicSession mojo call when the submit button is clicked. auto client = std::make_unique<MockLoginScreenClient>(); - EXPECT_CALL(*client, - LaunchPublicSession(user_.basic_user_info.account_id, - selected_language, selected_keyboard)); + EXPECT_CALL(*client, LaunchPublicSession(user_.basic_user_info.account_id, + selected_language_item_value, + selected_keyboard_item_value)); // Click on the submit button. TapOnView(test_api.submit_button()); @@ -230,35 +233,41 @@ public_account_->UpdateForUser(user_); EXPECT_TRUE(test_api.advanced_view()->GetVisible()); - // Tap on language selection button should bring up the language menu. - TapOnView(test_api.language_selection_button()); - EXPECT_TRUE(test_api.language_menu_view()->GetVisible()); + // Open language menu. + PublicAccountMenuView* language_menu_view = test_api.language_menu_view(); + EXPECT_FALSE(language_menu_view->IsMenuRunning()); + TapOnView(language_menu_view); + EXPECT_TRUE(language_menu_view->IsMenuRunning()); - // First language item is selected, and selected item should have focus. - EXPECT_EQ(test_api.selected_language_item().value, kEnglishLanguageCode); - PublicAccountMenuView::TestApi language_test_api( - test_api.language_menu_view()); - ASSERT_EQ(2u, language_test_api.contents()->children().size()); - EXPECT_TRUE(language_test_api.contents()->children()[0]->HasFocus()); + // First language item is selected. + EXPECT_EQ(test_api.selected_language_item_value(), kEnglishLanguageCode); + ASSERT_EQ(2, language_menu_view->GetRowCount()); + EXPECT_EQ(0, language_menu_view->GetSelectedRow()); - // Select language item should close the language menu. + // Once the menu is open, the focus is set on the entire view. + // The first key press will set the focus on the language item, the second + // press will select it and should close the language menu. GetEventGenerator()->PressKey(ui::KeyboardCode::VKEY_RETURN, 0); - EXPECT_FALSE(test_api.language_menu_view()->GetVisible()); - - // Tap on keyboard selection button should bring up the keyboard menu. - TapOnView(test_api.keyboard_selection_button()); - EXPECT_TRUE(test_api.keyboard_menu_view()->GetVisible()); - - // Second keyboard item is selected, and selected item should have focus. - EXPECT_EQ(test_api.selected_keyboard_item().value, kKeyboardIdForItem2); - PublicAccountMenuView::TestApi keyboard_test_api( - test_api.keyboard_menu_view()); - ASSERT_EQ(2u, keyboard_test_api.contents()->children().size()); - EXPECT_TRUE(keyboard_test_api.contents()->children()[1]->HasFocus()); - - // Select keyboard item should close the keyboard menu. GetEventGenerator()->PressKey(ui::KeyboardCode::VKEY_RETURN, 0); - EXPECT_FALSE(test_api.keyboard_menu_view()->GetVisible()); + EXPECT_FALSE(language_menu_view->IsMenuRunning()); + + // Open keyboard menu. + PublicAccountMenuView* keyboard_menu_view = test_api.keyboard_menu_view(); + EXPECT_FALSE(keyboard_menu_view->IsMenuRunning()); + TapOnView(keyboard_menu_view); + EXPECT_TRUE(keyboard_menu_view->IsMenuRunning()); + + // Second keyboard item is selected. + EXPECT_EQ(test_api.selected_keyboard_item_value(), kKeyboardIdForItem2); + ASSERT_EQ(2, keyboard_menu_view->GetRowCount()); + EXPECT_EQ(1, keyboard_menu_view->GetSelectedRow()); + + // Once the menu is open, the focus is set on the entire view. + // The first key press will set the focus on the keyboard item, the second + // press will select it and should close the keyboard menu. + GetEventGenerator()->PressKey(ui::KeyboardCode::VKEY_RETURN, 0); + GetEventGenerator()->PressKey(ui::KeyboardCode::VKEY_RETURN, 0); + EXPECT_FALSE(keyboard_menu_view->IsMenuRunning()); } TEST_P(LoginExpandedPublicAccountViewTest, ChangeMenuSelection) { @@ -267,43 +276,48 @@ public_account_->UpdateForUser(user_); EXPECT_TRUE(test_api.advanced_view()->GetVisible()); - // Try to change language selection. // Open language menu. - TapOnView(test_api.language_selection_button()); - EXPECT_TRUE(test_api.language_menu_view()->GetVisible()); + PublicAccountMenuView* language_menu_view = test_api.language_menu_view(); + EXPECT_FALSE(language_menu_view->IsMenuRunning()); + TapOnView(language_menu_view); + EXPECT_TRUE(language_menu_view->IsMenuRunning()); // Select second language item: - // 1. Language menu will be closed automatically. - // 2. Selected language item will change. - // 3. Expect RequestPublicSessionKeyboardLayouts mojo call with the selected + // 1. Selected language will change. + // 2. Expect RequestPublicSessionKeyboardLayouts mojo call with the selected // language item. auto client = std::make_unique<MockLoginScreenClient>(); EXPECT_CALL(*client, RequestPublicSessionKeyboardLayouts( user_.basic_user_info.account_id, kFrenchLanguageCode)); - EXPECT_EQ(test_api.selected_language_item().value, kEnglishLanguageCode); - PublicAccountMenuView::TestApi language_test_api( - test_api.language_menu_view()); - TapOnView(language_test_api.contents()->children()[1]); - EXPECT_FALSE(test_api.language_menu_view()->GetVisible()); - EXPECT_EQ(test_api.selected_language_item().value, kFrenchLanguageCode); + EXPECT_EQ(test_api.selected_language_item_value(), kEnglishLanguageCode); + std::unique_ptr<views::test::ComboboxTestApi> language_test_api = + std::make_unique<views::test::ComboboxTestApi>(language_menu_view); + // Note that we do not need to open the menu to make this test API call. + language_test_api->PerformActionAt(1); + EXPECT_EQ(test_api.selected_language_item_value(), kFrenchLanguageCode); base::RunLoop().RunUntilIdle(); - // Try to change keyboard selection. + PublicAccountMenuView* keyboard_menu_view = test_api.keyboard_menu_view(); + // Close language menu. + // `PerformActionAt` does not close the menu automatically, make a click + // outside of language menu boundaries to close the menu. + EXPECT_TRUE(language_menu_view->IsMenuRunning()); + TapOnView(keyboard_menu_view); + EXPECT_FALSE(language_menu_view->IsMenuRunning()); // Open keyboard menu. - TapOnView(test_api.keyboard_selection_button()); - EXPECT_TRUE(test_api.keyboard_menu_view()->GetVisible()); + EXPECT_FALSE(keyboard_menu_view->IsMenuRunning()); + TapOnView(keyboard_menu_view); + EXPECT_TRUE(keyboard_menu_view->IsMenuRunning()); - // Select first keyboard item: - // 1. Keyboard menu will be closed automatically. - // 2. Selected keyboard item will change. - EXPECT_EQ(test_api.selected_keyboard_item().value, kKeyboardIdForItem2); - PublicAccountMenuView::TestApi keyboard_test_api( - test_api.keyboard_menu_view()); - TapOnView(keyboard_test_api.contents()->children()[0]); - EXPECT_FALSE(test_api.keyboard_menu_view()->GetVisible()); - EXPECT_EQ(test_api.selected_keyboard_item().value, kKeyboardIdForItem1); + // Select first keyboard item, selected keyboard will change. + EXPECT_EQ(test_api.selected_keyboard_item_value(), kKeyboardIdForItem2); + std::unique_ptr<views::test::ComboboxTestApi> keyboard_test_api = + std::make_unique<views::test::ComboboxTestApi>( + test_api.keyboard_menu_view()); + keyboard_test_api->PerformActionAt(0); + EXPECT_EQ(test_api.selected_keyboard_item_value(), kKeyboardIdForItem1); } TEST_P(LoginExpandedPublicAccountViewTest, ChangeWarningLabel) {
diff --git a/ash/login/ui/public_account_menu_view.cc b/ash/login/ui/public_account_menu_view.cc index 74875815..11b51c53 100644 --- a/ash/login/ui/public_account_menu_view.cc +++ b/ash/login/ui/public_account_menu_view.cc
@@ -4,227 +4,79 @@ #include "ash/login/ui/public_account_menu_view.h" -#include <algorithm> -#include <iterator> -#include <memory> -#include <utility> - #include "ash/login/ui/hover_notifier.h" #include "ash/login/ui/non_accessible_view.h" #include "ash/style/ash_color_provider.h" #include "base/bind.h" #include "base/strings/utf_string_conversions.h" -#include "ui/views/controls/button/button.h" -#include "ui/views/controls/label.h" -#include "ui/views/controls/scroll_view.h" -#include "ui/views/controls/scrollbar/overlay_scroll_bar.h" -#include "ui/views/layout/box_layout.h" +#include "ui/base/models/combobox_model.h" namespace ash { constexpr int kMenuItemWidthDp = 192; -constexpr int kMenuItemHeightDp = 28; -constexpr int kRegularMenuItemLeftPaddingDp = 2; -constexpr int kGroupMenuItemLeftPaddingDp = 10; -constexpr int kNonEmptyHeight = 1; namespace { -class MenuItemView : public views::Button { +class PublicAccountComboboxModel : public ui::ComboboxModel { public: - MenuItemView(const PublicAccountMenuView::Item& item, - const PublicAccountMenuView::OnHighlight& on_highlight) - : views::Button(base::BindRepeating(&MenuItemView::ButtonPressed, - base::Unretained(this))), - item_(item), - on_highlight_(on_highlight) { - SetFocusBehavior(FocusBehavior::ALWAYS); - set_suppress_default_focus_handling(); - SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::Orientation::kHorizontal)); - SetPreferredSize(gfx::Size(kMenuItemWidthDp, kMenuItemHeightDp)); + PublicAccountComboboxModel( + const std::vector<PublicAccountMenuView::Item>& items, + const size_t default_index) + : items_(items), default_index_(default_index) {} - auto spacing = std::make_unique<NonAccessibleView>(); - spacing->SetPreferredSize(gfx::Size(item.is_group - ? kRegularMenuItemLeftPaddingDp - : kGroupMenuItemLeftPaddingDp, - kNonEmptyHeight)); - AddChildView(std::move(spacing)); + PublicAccountComboboxModel(const PublicAccountComboboxModel&) = delete; + PublicAccountComboboxModel& operator=(const PublicAccountComboboxModel&) = + delete; - auto label = std::make_unique<views::Label>(base::UTF8ToUTF16(item.title)); - label->SetEnabledColor(AshColorProvider::Get()->GetContentLayerColor( - AshColorProvider::ContentLayerType::kTextColorPrimary)); - label->SetSubpixelRenderingEnabled(false); - label->SetAutoColorReadabilityEnabled(false); - label->SetHorizontalAlignment(gfx::ALIGN_LEFT); - AddChildView(std::move(label)); + ~PublicAccountComboboxModel() override = default; - if (item.selected) - SetBackground(views::CreateSolidBackground(SK_ColorGRAY)); + // ui::ComboboxModel: + int GetItemCount() const override { return items_.size(); } - hover_notifier_ = std::make_unique<HoverNotifier>( - this, - base::BindRepeating(&MenuItemView::OnHover, base::Unretained(this))); - } - MenuItemView(const MenuItemView&) = delete; - MenuItemView& operator=(const MenuItemView&) = delete; - ~MenuItemView() override = default; - - // views::View: - int GetHeightForWidth(int w) const override { - // Make row height fixed avoiding layout manager adjustments. - return GetPreferredSize().height(); + // ui::ComboboxModel: + std::u16string GetItemAt(int index) const override { + return base::UTF8ToUTF16(items_[index].title); } - void OnHover(bool has_hover) { - if (has_hover && !item_.is_group) - RequestFocus(); + // ui::ComboboxModel: + // Alternatively, we could override `IsItemSeparatorAt`, especially since + // group items are considered as some sort of separators. We choose to + // represent them as disabled items because they were presented in a similar + // fashion before (i.e. the group name was visible but unclickable). + bool IsItemEnabledAt(int index) const override { + return !items_[index].is_group; } - void OnFocus() override { - ScrollViewToVisible(); - on_highlight_.Run(false /*by_selection*/); - } - - const PublicAccountMenuView::Item& item() const { return item_; } + // ui::ComboboxModel: + int GetDefaultIndex() const override { return default_index_; } private: - void ButtonPressed() { - if (!item_.is_group) - on_highlight_.Run(true /*by_selection*/); - } - - const PublicAccountMenuView::Item item_; - const PublicAccountMenuView::OnHighlight on_highlight_; - std::unique_ptr<HoverNotifier> hover_notifier_; -}; - -class LoginScrollBar : public views::OverlayScrollBar { - public: - LoginScrollBar() : OverlayScrollBar(false) {} - LoginScrollBar(const LoginScrollBar&) = delete; - LoginScrollBar& operator=(const LoginScrollBar&) = delete; - ~LoginScrollBar() override = default; - - // OverlayScrollBar: - bool OnKeyPressed(const ui::KeyEvent& event) override { - // Let LoginMenuView to handle up/down keypress. - return false; - } + const std::vector<PublicAccountMenuView::Item>& items_; + const int default_index_; }; } // namespace -PublicAccountMenuView::TestApi::TestApi(PublicAccountMenuView* view) - : view_(view) {} - -PublicAccountMenuView::TestApi::~TestApi() = default; - -views::View* PublicAccountMenuView::TestApi::contents() const { - return view_->contents_; -} - PublicAccountMenuView::Item::Item() = default; PublicAccountMenuView::PublicAccountMenuView(const std::vector<Item>& items, - views::View* anchor_view, - LoginButton* opener, + const size_t selected_index, const OnSelect& on_select) - : LoginBaseBubbleView(anchor_view), opener_(opener), on_select_(on_select) { - SetFocusBehavior(views::View::FocusBehavior::ALWAYS); - set_suppress_default_focus_handling(); + : views::Combobox(new PublicAccountComboboxModel(items, selected_index)), + items_(items), + on_select_(on_select) { + SetPreferredSize( + gfx::Size(kMenuItemWidthDp, GetHeightForWidth(kMenuItemWidthDp))); - scroller_ = new views::ScrollView(); - scroller_->SetBackgroundColor(absl::nullopt); - scroller_->SetDrawOverflowIndicator(false); - scroller_->ClipHeightTo(kMenuItemHeightDp, kMenuItemHeightDp * 5); - AddChildView(scroller_); - - views::BoxLayout* box_layout = - SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::Orientation::kVertical)); - box_layout->SetFlexForView(scroller_, 1); - - auto contents = std::make_unique<NonAccessibleView>(); - views::BoxLayout* layout = - contents->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::Orientation::kVertical)); - layout->SetDefaultFlex(1); - layout->set_minimum_cross_axis_size(kMenuItemWidthDp); - layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kCenter); - - for (size_t i = 0; i < items.size(); i++) { - const Item& item = items[i]; - contents->AddChildView(new MenuItemView( - item, base::BindRepeating(&PublicAccountMenuView::OnHighlightChange, - base::Unretained(this), i))); - - if (item.selected) - selected_index_ = i; - } - contents_ = scroller_->SetContents(std::move(contents)); - scroller_->SetVerticalScrollBar(std::make_unique<LoginScrollBar>()); + property_changed_subscription_ = AddSelectedIndexChangedCallback( + base::BindRepeating(&PublicAccountMenuView::OnSelectedIndexChanged, + weak_factory_.GetWeakPtr())); } PublicAccountMenuView::~PublicAccountMenuView() = default; -void PublicAccountMenuView::OnHighlightChange(size_t item_index, - bool by_selection) { - selected_index_ = item_index; - views::View* highlight_item = contents_->children()[item_index]; - for (views::View* child : contents_->GetChildrenInZOrder()) { - child->SetBackground(views::CreateSolidBackground( - child == highlight_item ? SK_ColorGRAY : SK_ColorTRANSPARENT)); - } - - if (by_selection) { - SetVisible(false); - MenuItemView* menu_view = static_cast<MenuItemView*>(highlight_item); - on_select_.Run(menu_view->item()); - } - contents_->SchedulePaint(); -} - -LoginButton* PublicAccountMenuView::GetBubbleOpener() const { - return opener_; -} - -void PublicAccountMenuView::OnFocus() { - // Forward the focus to the selected child view. - contents_->children()[selected_index_]->RequestFocus(); -} - -bool PublicAccountMenuView::OnKeyPressed(const ui::KeyEvent& event) { - const ui::KeyboardCode key = event.key_code(); - if (key == ui::VKEY_UP || key == ui::VKEY_DOWN) { - FindNextItem(key == ui::VKEY_UP)->RequestFocus(); - return true; - } - - return false; -} - -void PublicAccountMenuView::VisibilityChanged(View* starting_from, - bool is_visible) { - if (is_visible) - contents_->children()[selected_index_]->RequestFocus(); -} - -views::View* PublicAccountMenuView::FindNextItem(bool reverse) { - const auto& children = contents_->children(); - const auto is_item = [](views::View* v) { - return !static_cast<MenuItemView*>(v)->item().is_group; - }; - const auto begin = std::next(children.begin(), selected_index_); - if (reverse) { - // Subtle: make_reverse_iterator() will result in an iterator that refers to - // the element before its argument, which is what we want. - const auto i = std::find_if(std::make_reverse_iterator(begin), - children.rend(), is_item); - return (i == children.rend()) ? *begin : *i; - } - const auto i = std::find_if(std::next(begin), children.end(), is_item); - return (i == children.end()) ? *begin : *i; +void PublicAccountMenuView::OnSelectedIndexChanged() { + on_select_.Run(items_[GetSelectedIndex()].value); } } // namespace ash
diff --git a/ash/login/ui/public_account_menu_view.h b/ash/login/ui/public_account_menu_view.h index db9885fe..adf94ad 100644 --- a/ash/login/ui/public_account_menu_view.h +++ b/ash/login/ui/public_account_menu_view.h
@@ -6,33 +6,14 @@ #define ASH_LOGIN_UI_PUBLIC_ACCOUNT_MENU_VIEW_H_ #include "ash/ash_export.h" -#include "ash/login/ui/login_base_bubble_view.h" -#include "ash/login/ui/login_button.h" -#include "base/callback.h" -#include "ui/views/view.h" +#include "base/memory/weak_ptr.h" +#include "ui/views/controls/combobox/combobox.h" namespace ash { // Implements a menu view for the login screen's expanded public account view. -// This is used instead of views::Combobox because we want a more customisable -// view for the menu items to support some sepcific styles like nested menu -// entries which have different left margin (less than regular items) and are -// not selectable. views::Combobox uses views::MenuItemView which is not very -// straightforward to customize. -class ASH_EXPORT PublicAccountMenuView : public LoginBaseBubbleView { +class ASH_EXPORT PublicAccountMenuView : public views::Combobox { public: - // TestApi is used for tests to get internal implementation details. - class ASH_EXPORT TestApi { - public: - explicit TestApi(PublicAccountMenuView* view); - ~TestApi(); - - views::View* contents() const; - - private: - PublicAccountMenuView* const view_; - }; - struct Item { Item(); @@ -42,40 +23,24 @@ bool selected = false; }; - using OnSelect = base::RepeatingCallback<void(Item item)>; - using OnHighlight = base::RepeatingCallback<void(bool by_selection)>; + using OnSelect = base::RepeatingCallback<void(const std::string& value)>; PublicAccountMenuView(const std::vector<Item>& items, - views::View* anchor_view, - LoginButton* opener_, + const size_t selected_index, const OnSelect& on_select); PublicAccountMenuView(const PublicAccountMenuView&) = delete; PublicAccountMenuView& operator=(const PublicAccountMenuView&) = delete; ~PublicAccountMenuView() override; - void OnHighlightChange(size_t item_index, bool by_selection); - - // LoginBaseBubbleView: - LoginButton* GetBubbleOpener() const override; - - // views::View: - void OnFocus() override; - bool OnKeyPressed(const ui::KeyEvent& event) override; - void VisibilityChanged(View* starting_from, bool is_visible) override; + void OnSelectedIndexChanged(); private: - views::View* FindNextItem(bool reverse); - - // Owned by this class. - views::ScrollView* scroller_ = nullptr; - - // Owned by ScrollView. - views::View* contents_ = nullptr; - - LoginButton* opener_ = nullptr; - + const std::vector<Item>& items_; const OnSelect on_select_; - size_t selected_index_ = 0; + + base::CallbackListSubscription property_changed_subscription_; + + base::WeakPtrFactory<PublicAccountMenuView> weak_factory_{this}; }; } // namespace ash
diff --git a/ash/public/cpp/BUILD.gn b/ash/public/cpp/BUILD.gn index 6267301..d637941 100644 --- a/ash/public/cpp/BUILD.gn +++ b/ash/public/cpp/BUILD.gn
@@ -23,6 +23,8 @@ "accessibility_focus_ring_controller.h", "accessibility_focus_ring_info.cc", "accessibility_focus_ring_info.h", + "ambient/ambient_animation_theme.cc", + "ambient/ambient_animation_theme.h", "ambient/ambient_backend_controller.cc", "ambient/ambient_backend_controller.h", "ambient/ambient_client.cc",
diff --git a/ash/public/cpp/ambient/ambient_animation_theme.cc b/ash/public/cpp/ambient/ambient_animation_theme.cc new file mode 100644 index 0000000..558c2b1 --- /dev/null +++ b/ash/public/cpp/ambient/ambient_animation_theme.cc
@@ -0,0 +1,18 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/public/cpp/ambient/ambient_animation_theme.h" + +namespace ash { + +std::ostream& operator<<(std::ostream& os, AmbientAnimationTheme theme) { + switch (theme) { + case AmbientAnimationTheme::kSlideshow: + return os << "SLIDESHOW"; + case AmbientAnimationTheme::kFeelTheBreeze: + return os << "FEEL_THE_BREZE"; + } +} + +} // namespace ash
diff --git a/ash/public/cpp/ambient/ambient_animation_theme.h b/ash/public/cpp/ambient/ambient_animation_theme.h new file mode 100644 index 0000000..80ad8de3 --- /dev/null +++ b/ash/public/cpp/ambient/ambient_animation_theme.h
@@ -0,0 +1,33 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_PUBLIC_CPP_AMBIENT_AMBIENT_ANIMATION_THEME_H_ +#define ASH_PUBLIC_CPP_AMBIENT_AMBIENT_ANIMATION_THEME_H_ + +#include <ostream> + +#include "ash/public/cpp/ash_public_export.h" + +namespace ash { + +// Each corresponds to an animation design for ambient mode that UX created and +// has its own Lottie file. +// +// These values are persisted in user pref storage, so they should never be +// renumbered or reused. +enum class ASH_PUBLIC_EXPORT AmbientAnimationTheme { + // This is the one exception in the list, and it describes the mode where + // IMAX photos are displayed at full screen in a slideshow fashion. This is + // not currently implemented as an "animation" and doesn't have a Lottie file. + // It is currently implemented entirely as a native UI view. + kSlideshow = 0, + kFeelTheBreeze = 1, +}; + +ASH_PUBLIC_EXPORT std::ostream& operator<<(std::ostream& os, + AmbientAnimationTheme theme); + +} // namespace ash + +#endif // ASH_PUBLIC_CPP_AMBIENT_AMBIENT_ANIMATION_THEME_H_
diff --git a/ash/resources/BUILD.gn b/ash/resources/BUILD.gn index 4f4dc66..2cc4f721 100644 --- a/ash/resources/BUILD.gn +++ b/ash/resources/BUILD.gn
@@ -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("//ash/ambient/resources/resources.gni") import("//build/config/chromeos/ui_mode.gni") import("//tools/grit/grit_rule.gni") import("//tools/grit/repack.gni") @@ -16,6 +17,13 @@ "$root_gen_dir/ash/public/cpp/resources/ash_public_unscaled_resources.pak", ] deps = [ "//ash/public/cpp/resources:ash_public_unscaled_resources" ] + + if (include_ash_ambient_animation_resources) { + sources += [ + "$root_gen_dir/ash/ambient/resources/ash_ambient_lottie_resources.pak", + ] + deps += [ "//ash/ambient/resources:lottie_resources" ] + } } # Repacks resources needed for ash_unittests, etc. at a given scale.
diff --git a/ash/system/geolocation/geolocation_controller.cc b/ash/system/geolocation/geolocation_controller.cc index a3f0e28..12c941e 100644 --- a/ash/system/geolocation/geolocation_controller.cc +++ b/ash/system/geolocation/geolocation_controller.cc
@@ -17,6 +17,8 @@ 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); @@ -44,10 +46,19 @@ 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; } void GeolocationController::AddObserver(Observer* observer) { @@ -110,12 +121,30 @@ return; } - last_successful_geo_request_time_ = GetNow(); + absl::optional<base::Time> previous_sunset; + absl::optional<base::Time> previous_sunrise; + bool possible_change_in_timezone = !geoposition_; + if (geoposition_) { + previous_sunset = GetSunsetTime(); + previous_sunrise = GetSunriseTime(); + } geoposition_ = std::make_unique<SimpleGeoposition>(); geoposition_->latitude = position.latitude; geoposition_->longitude = position.longitude; - NotifyWithCurrentGeoposition(*geoposition_); + + if (previous_sunset && previous_sunrise) { + // If the change in geoposition results in an hour or more in either sunset + // or sunrise times indicates of a possible timezone change. + constexpr base::TimeDelta kOneHourDuration = base::Hours(1); + possible_change_in_timezone = + (GetSunsetTime() - previous_sunset.value()).magnitude() > + kOneHourDuration || + (GetSunriseTime() - previous_sunrise.value()).magnitude() > + kOneHourDuration; + } + + NotifyGeopositionChange(possible_change_in_timezone); // On success, reset the backoff delay to its minimum value, and schedule // another request. @@ -132,10 +161,10 @@ &GeolocationController::RequestGeoposition); } -void GeolocationController::NotifyWithCurrentGeoposition( - SimpleGeoposition position) { +void GeolocationController::NotifyGeopositionChange( + bool possible_change_in_timezone) { for (Observer& observer : observers_) - observer.OnGeopositionChanged(position); + observer.OnGeopositionChanged(possible_change_in_timezone); } void GeolocationController::RequestGeoposition() {
diff --git a/ash/system/geolocation/geolocation_controller.h b/ash/system/geolocation/geolocation_controller.h index 055504c..499b476 100644 --- a/ash/system/geolocation/geolocation_controller.h +++ b/ash/system/geolocation/geolocation_controller.h
@@ -47,8 +47,10 @@ public: class Observer : public base::CheckedObserver { public: - // Emitted when the Geoposition is updated. - virtual void OnGeopositionChanged(SimpleGeoposition position) {} + // Emitted when the Geoposition is updated with + // |possible_change_in_timezone| to indicate whether timezone might have + // changed as a result of the geoposition change. + virtual void OnGeopositionChanged(bool possible_change_in_timezone) {} protected: ~Observer() override = default; @@ -60,6 +62,8 @@ GeolocationController& operator=(const GeolocationController&) = delete; ~GeolocationController() override; + static GeolocationController* Get(); + const base::OneShotTimer& timer() const { return *timer_; } base::Time last_successful_geo_request_time() const { @@ -107,8 +111,10 @@ // Calls `RequestGeoposition()` after `delay`. void ScheduleNextRequest(base::TimeDelta delay); - // Broadcasts the new position obtained from the request to all observers. - void NotifyWithCurrentGeoposition(SimpleGeoposition position); + // Broadcasts the change in geoposition to all observers with + // |possible_change_in_timezone| to indicate whether timezone might have + // changed as a result of the geoposition change. + void NotifyGeopositionChange(bool possible_change_in_timezone); // Virtual so that it can be overridden by a fake implementation in unit tests // that doesn't request actual geopositions.
diff --git a/ash/system/geolocation/geolocation_controller_unittest.cc b/ash/system/geolocation/geolocation_controller_unittest.cc index a5a3d37..b6cb8c52 100644 --- a/ash/system/geolocation/geolocation_controller_unittest.cc +++ b/ash/system/geolocation/geolocation_controller_unittest.cc
@@ -41,7 +41,7 @@ // TODO(crbug.com/1269915): Add `sunset_` and `sunrise_` and update their // values when receiving the new position. - void OnGeopositionChanged(SimpleGeoposition position) override { + void OnGeopositionChanged(bool possible_change_in_timezone) override { position_received_num_++; }
diff --git a/ash/system/message_center/notification_grouping_controller.cc b/ash/system/message_center/notification_grouping_controller.cc index 56bbe59..b49cce3a 100644 --- a/ash/system/message_center/notification_grouping_controller.cc +++ b/ash/system/message_center/notification_grouping_controller.cc
@@ -142,6 +142,10 @@ << notification_id; return; } + + if (!parent_view->IsManuallyExpandedOrCollapsed()) + parent_view->SetExpanded(false); + std::vector<const Notification*> notifications; for (const auto* notification : MessageCenter::Get()->GetNotifications()) { if (notification->notifier_id() == parent_view->notifier_id() &&
diff --git a/ash/system/message_center/stacked_notification_bar.cc b/ash/system/message_center/stacked_notification_bar.cc index 9371f5c4..dde6eb06 100644 --- a/ash/system/message_center/stacked_notification_bar.cc +++ b/ash/system/message_center/stacked_notification_bar.cc
@@ -110,7 +110,10 @@ return; SkColor accent_color = - color_provider->GetColor(ui::kColorNotificationHeaderForeground); + features::IsNotificationsRefreshEnabled() + ? AshColorProvider::Get()->GetContentLayerColor( + AshColorProvider::ContentLayerType::kIconColorPrimary) + : color_provider->GetColor(ui::kColorNotificationHeaderForeground); gfx::Image masked_small_icon = notification->GenerateMaskedSmallIcon( kStackedNotificationIconSize, accent_color, color_provider->GetColor(ui::kColorNotificationIconBackground), @@ -265,7 +268,12 @@ message_center::MessageCenter::Get()->AddObserver(this); - count_label_->SetEnabledColor(message_center_style::kCountLabelColor); + SkColor label_color = + features::IsNotificationsRefreshEnabled() + ? AshColorProvider::Get()->GetContentLayerColor( + AshColorProvider::ContentLayerType::kIconColorPrimary) + : message_center_style::kCountLabelColor; + count_label_->SetEnabledColor(label_color); count_label_->SetFontList(views::Label::GetDefaultFontList().Derive( 1, gfx::Font::NORMAL, gfx::Font::Weight::MEDIUM));
diff --git a/ash/system/scheduled_feature/scheduled_feature.cc b/ash/system/scheduled_feature/scheduled_feature.cc new file mode 100644 index 0000000..0ff37e4 --- /dev/null +++ b/ash/system/scheduled_feature/scheduled_feature.cc
@@ -0,0 +1,407 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/system/scheduled_feature/scheduled_feature.h" + +#include <cmath> +#include <memory> + +#include "ash/constants/ash_features.h" +#include "ash/constants/ash_pref_names.h" +#include "ash/public/cpp/notification_utils.h" +#include "ash/session/session_controller_impl.h" +#include "ash/shell.h" +#include "ash/strings/grit/ash_strings.h" +#include "ash/system/geolocation/geolocation_controller.h" +#include "ash/system/model/system_tray_model.h" +#include "base/bind.h" +#include "base/cxx17_backports.h" +#include "base/i18n/time_formatting.h" +#include "base/logging.h" +#include "base/time/time.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/pref_service.h" +#include "third_party/icu/source/i18n/astro.h" +#include "ui/aura/env.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/gfx/geometry/vector3d_f.h" + +namespace ash { + +namespace { + +// Default start time at 6:00 PM as an offset from 00:00. +constexpr int kDefaultStartTimeOffsetMinutes = 18 * 60; + +// Default end time at 6:00 AM as an offset from 00:00. +constexpr int kDefaultEndTimeOffsetMinutes = 6 * 60; + +} // namespace + +ScheduledFeature::ScheduledFeature( + const std::string prefs_path_enabled, + const std::string prefs_path_schedule_type, + const std::string prefs_path_custom_start_time, + const std::string prefs_path_custom_end_time) + : prefs_path_enabled_(prefs_path_enabled), + prefs_path_schedule_type_(prefs_path_schedule_type), + prefs_path_custom_start_time_(prefs_path_custom_start_time), + prefs_path_custom_end_time_(prefs_path_custom_end_time), + geolocation_controller_(ash::GeolocationController::Get()) { + Shell::Get()->session_controller()->AddObserver(this); + aura::Env::GetInstance()->AddObserver(this); + chromeos::PowerManagerClient::Get()->AddObserver(this); +} + +ScheduledFeature::~ScheduledFeature() { + chromeos::PowerManagerClient::Get()->RemoveObserver(this); + aura::Env::GetInstance()->RemoveObserver(this); + Shell::Get()->session_controller()->RemoveObserver(this); +} + +// static +bool ScheduledFeature::GetEnabled() const { + return active_user_pref_service_ && + active_user_pref_service_->GetBoolean(prefs_path_enabled_); +} + +ScheduledFeature::ScheduleType ScheduledFeature::GetScheduleType() const { + if (active_user_pref_service_) { + return static_cast<ScheduleType>( + active_user_pref_service_->GetInteger(prefs_path_schedule_type_)); + } + + return ScheduleType::kNone; +} + +TimeOfDay ScheduledFeature::GetCustomStartTime() const { + if (active_user_pref_service_) { + return TimeOfDay( + active_user_pref_service_->GetInteger(prefs_path_custom_start_time_)); + } + + return TimeOfDay(kDefaultStartTimeOffsetMinutes); +} + +TimeOfDay ScheduledFeature::GetCustomEndTime() const { + if (active_user_pref_service_) { + return TimeOfDay( + active_user_pref_service_->GetInteger(prefs_path_custom_end_time_)); + } + + return TimeOfDay(kDefaultEndTimeOffsetMinutes); +} + +bool ScheduledFeature::IsNowWithinSunsetSunrise() const { + // The times below are all on the same calendar day. + const base::Time now = GetNow(); + return now < geolocation_controller_->GetSunriseTime() || + now > geolocation_controller_->GetSunsetTime(); +} + +void ScheduledFeature::SetEnabled(bool enabled) { + if (active_user_pref_service_) + active_user_pref_service_->SetBoolean(prefs_path_enabled_, enabled); +} + +void ScheduledFeature::SetScheduleType(ScheduleType type) { + if (active_user_pref_service_) { + active_user_pref_service_->SetInteger(prefs_path_schedule_type_, + static_cast<int>(type)); + } +} + +void ScheduledFeature::SetCustomStartTime(TimeOfDay start_time) { + if (active_user_pref_service_) { + active_user_pref_service_->SetInteger( + prefs_path_custom_start_time_, + start_time.offset_minutes_from_zero_hour()); + } +} + +void ScheduledFeature::SetCustomEndTime(TimeOfDay end_time) { + if (active_user_pref_service_) { + active_user_pref_service_->SetInteger( + prefs_path_custom_end_time_, end_time.offset_minutes_from_zero_hour()); + } +} + +void ScheduledFeature::OnActiveUserPrefServiceChanged( + PrefService* pref_service) { + if (pref_service == active_user_pref_service_) + return; + + // Initial login and user switching in multi profiles. + active_user_pref_service_ = pref_service; + InitFromUserPrefs(); +} + +void ScheduledFeature::OnGeopositionChanged(bool possible_change_in_timezone) { + DCHECK(GetScheduleType() != ScheduleType::kNone); + + VLOG(1) << "Received new geoposition."; + + // We only keep manual toggles if there's no change in timezone. + const bool keep_manual_toggles_during_schedules = + !possible_change_in_timezone; + + Refresh(/*did_schedule_change=*/true, keep_manual_toggles_during_schedules); +} + +void ScheduledFeature::SuspendDone(base::TimeDelta sleep_duration) { + // Time changes while the device is suspended. We need to refresh the schedule + // upon device resume to know what the status should be now. + Refresh(/*did_schedule_change=*/true, + /*keep_manual_toggles_during_schedules=*/true); +} + +void ScheduledFeature::SetClockForTesting(base::Clock* clock) { + clock_ = clock; +} + +base::Time ScheduledFeature::GetNow() const { + return clock_ ? clock_->Now() : base::Time::Now(); +} + +bool ScheduledFeature::MaybeRestoreSchedule() { + DCHECK(active_user_pref_service_); + DCHECK_NE(GetScheduleType(), ScheduleType::kNone); + + auto iter = per_user_schedule_target_state_.find(active_user_pref_service_); + if (iter == per_user_schedule_target_state_.end()) + return false; + + ScheduleTargetState& target_state = iter->second; + const base::Time now = GetNow(); + // It may be that the device was suspended for a very long time that the + // target time is no longer valid. + if (target_state.target_time <= now) + return false; + + VLOG(1) << "Restoring a previous schedule."; + DCHECK_NE(GetEnabled(), target_state.target_status); + ScheduleNextToggle(target_state.target_time - now); + return true; +} + +void ScheduledFeature::StartWatchingPrefsChanges() { + DCHECK(active_user_pref_service_); + + pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>(); + pref_change_registrar_->Init(active_user_pref_service_); + pref_change_registrar_->Add( + prefs_path_enabled_, + base::BindRepeating(&ScheduledFeature::OnEnabledPrefChanged, + base::Unretained(this))); + pref_change_registrar_->Add( + prefs_path_schedule_type_, + base::BindRepeating(&ScheduledFeature::OnScheduleTypePrefChanged, + base::Unretained(this))); + pref_change_registrar_->Add( + prefs_path_custom_start_time_, + base::BindRepeating(&ScheduledFeature::OnCustomSchedulePrefsChanged, + base::Unretained(this))); + pref_change_registrar_->Add( + prefs_path_custom_end_time_, + base::BindRepeating(&ScheduledFeature::OnCustomSchedulePrefsChanged, + base::Unretained(this))); +} + +void ScheduledFeature::InitFromUserPrefs() { + StartWatchingPrefsChanges(); + Refresh(/*did_schedule_change=*/true, + /*keep_manual_toggles_during_schedules=*/true); + is_first_user_init_ = false; +} + +void ScheduledFeature::OnEnabledPrefChanged() { + const bool enabled = GetEnabled(); + VLOG(1) << "Enable state changed. New state: " << enabled << "."; + DCHECK(active_user_pref_service_); + Refresh(/*did_schedule_change=*/false, + /*keep_manual_toggles_during_schedules=*/false); +} + +void ScheduledFeature::OnScheduleTypePrefChanged() { + const ScheduledFeature::ScheduleType schedule_type = GetScheduleType(); + // To prevent adding (or removing) an observer twice in a row when switching + // between different users, we need to check `is_observing_geolocation_`. + if (schedule_type == ScheduledFeature::ScheduleType::kNone && + is_observing_geolocation_) { + geolocation_controller_->RemoveObserver(this); + is_observing_geolocation_ = false; + } else if (schedule_type != ScheduledFeature::ScheduleType::kNone && + !is_observing_geolocation_) { + geolocation_controller_->AddObserver(this); + is_observing_geolocation_ = true; + } + Refresh(/*did_schedule_change=*/true, + /*keep_manual_toggles_during_schedules=*/false); +} + +void ScheduledFeature::OnCustomSchedulePrefsChanged() { + DCHECK(active_user_pref_service_); + Refresh(/*did_schedule_change=*/true, + /*keep_manual_toggles_during_schedules=*/false); +} + +void ScheduledFeature::Refresh(bool did_schedule_change, + bool keep_manual_toggles_during_schedules) { + switch (GetScheduleType()) { + case ScheduleType::kNone: + timer_.Stop(); + RefreshFeatureState(); + return; + case ScheduleType::kSunsetToSunrise: + RefreshScheduleTimer(geolocation_controller_->GetSunsetTime(), + geolocation_controller_->GetSunriseTime(), + did_schedule_change, + keep_manual_toggles_during_schedules); + return; + case ScheduleType::kCustom: + RefreshScheduleTimer( + GetCustomStartTime().ToTimeToday(), GetCustomEndTime().ToTimeToday(), + did_schedule_change, keep_manual_toggles_during_schedules); + return; + } +} + +void ScheduledFeature::RefreshScheduleTimer( + base::Time start_time, + base::Time end_time, + bool did_schedule_change, + bool keep_manual_toggles_during_schedules) { + DCHECK(GetScheduleType() != ScheduleType::kNone); + + if (keep_manual_toggles_during_schedules && MaybeRestoreSchedule()) { + RefreshFeatureState(); + return; + } + + // NOTE: Users can set any weird combinations. + const base::Time now = GetNow(); + if (end_time <= start_time) { + // Example: + // Start: 9:00 PM, End: 6:00 AM. + // + // 6:00 21:00 + // <----- + ------------------ + -----> + // | | + // end start + // + // Note that the above times are times of day (today). It is important to + // know where "now" is with respect to these times to decide how to adjust + // them. + if (end_time >= now) { + // If the end time (today) is greater than the time now, this means "now" + // is within the feature schedule, and the start time is actually + // yesterday. The above timeline is interpreted as: + // + // 21:00 (-1day) 6:00 + // <----- + ----------- + ------ + -----> + // | | | + // start now end + // + start_time -= base::Days(1); + } else { + // Two possibilities here: + // - Either "now" is greater than the end time, but less than start time. + // This means the feature is outside the schedule, waiting for the next + // start time. The end time is actually a day later. + // - Or "now" is greater than both the start and end times. This means + // the feature is within the schedule, waiting to turn off at the next + // end time, which is also a day later. + end_time += base::Days(1); + } + } + + DCHECK_GE(end_time, start_time); + + // The target status that we need to set the feature to now if a change of + // status is needed immediately. + bool enable_now = false; + + // Where are we now with respect to the start and end times? + if (now < start_time) { + // Example: + // Start: 6:00 PM today, End: 6:00 AM tomorrow, Now: 4:00 PM. + // + // <----- + ----------- + ----------- + -----> + // | | | + // now start end + // + // In this case, we need to disable the feature immediately if it's enabled. + enable_now = false; + } else if (now >= start_time && now < end_time) { + // Example: + // Start: 6:00 PM today, End: 6:00 AM tomorrow, Now: 11:00 PM. + // + // <----- + ----------- + ----------- + -----> + // | | | + // start now end + // + // Turn the feature on right away. Our future start time is a day later than + // its current value. + enable_now = true; + start_time += base::Days(1); + } else { // now >= end_time. + // Example: + // Start: 6:00 PM today, End: 10:00 PM today, Now: 11:00 PM. + // + // <----- + ----------- + ----------- + -----> + // | | | + // start end now + // + // In this case, our future start and end times are a day later from their + // current values. The feature needs to be off immediately if it's already + // enabled. + enable_now = false; + start_time += base::Days(1); + end_time += base::Days(1); + } + + // After the above processing, the start and end time are all in the future. + DCHECK_GE(start_time, now); + DCHECK_GE(end_time, now); + + if (did_schedule_change && enable_now != GetEnabled()) { + // If the change in the schedule introduces a change in the status, then + // calling SetEnabled() is all we need, since it will trigger a change in + // the user prefs to which we will respond by calling Refresh(). This will + // end up in this function again, adjusting all the needed schedules. + SetEnabled(enable_now); + return; + } + + // We reach here in one of the following conditions: + // 1) If schedule changes don't result in changes in the status, we need to + // explicitly update the timer to re-schedule the next toggle to account for + // any changes. + // 2) The user has just manually toggled the status of the feature either from + // the System Menu or System Settings. In this case, we respect the user + // wish and maintain the current status that they desire, but we schedule the + // status to be toggled according to the time that corresponds with the + // opposite status of the current one. + ScheduleNextToggle(GetEnabled() ? end_time - now : start_time - now); + RefreshFeatureState(); +} + +void ScheduledFeature::ScheduleNextToggle(base::TimeDelta delay) { + DCHECK(active_user_pref_service_); + + const bool new_status = !GetEnabled(); + const base::Time target_time = GetNow() + delay; + + per_user_schedule_target_state_[active_user_pref_service_] = + ScheduleTargetState{target_time, new_status}; + + VLOG(1) << "Setting " << GetFeatureName() << " to toggle to " + << (new_status ? "enabled" : "disabled") << " at " + << base::TimeFormatTimeOfDay(target_time); + timer_.Start(FROM_HERE, delay, + base::BindOnce(&ScheduledFeature::SetEnabled, + base::Unretained(this), new_status)); +} + +} // namespace ash
diff --git a/ash/system/scheduled_feature/scheduled_feature.h b/ash/system/scheduled_feature/scheduled_feature.h new file mode 100644 index 0000000..8bed5c24 --- /dev/null +++ b/ash/system/scheduled_feature/scheduled_feature.h
@@ -0,0 +1,193 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_SYSTEM_SCHEDULED_FEATURE_SCHEDULED_FEATURE_H_ +#define ASH_SYSTEM_SCHEDULED_FEATURE_SCHEDULED_FEATURE_H_ + +#include <memory> + +#include "ash/ash_export.h" +#include "ash/public/cpp/session/session_observer.h" +#include "ash/system/geolocation/geolocation_controller.h" +#include "ash/system/time/time_of_day.h" +#include "base/containers/flat_map.h" +#include "base/memory/weak_ptr.h" +#include "base/time/clock.h" +#include "base/time/time.h" +#include "base/timer/timer.h" +#include "chromeos/dbus/power/power_manager_client.h" +#include "components/prefs/pref_change_registrar.h" +#include "ui/aura/env_observer.h" + +class PrefService; + +namespace ash { + +class ASH_EXPORT ScheduledFeature + : public GeolocationController::Observer, + public aura::EnvObserver, + public SessionObserver, + public chromeos::PowerManagerClient::Observer { + public: + // These values are written to logs. New enum values can be added, but + // existing enums must never be renumbered or deleted and reused. + enum ScheduleType { + // Automatic toggling of ScheduledFeature is turned off. + kNone = 0, + + // Turned automatically on at the user's local sunset time, and off at the + // user's local sunrise time. + kSunsetToSunrise = 1, + + // Toggled automatically based on the custom set start and end times + // selected by the user from the system settings. + kCustom = 2, + + // kMaxValue is required for UMA_HISTOGRAM_ENUMERATION. + kMaxValue = kCustom, + }; + + ScheduledFeature(const std::string prefs_path_enabled, + const std::string prefs_path_schedule_type, + const std::string prefs_path_custom_start_time, + const std::string prefs_path_custom_end_time); + + ScheduledFeature(const ScheduledFeature&) = delete; + ScheduledFeature& operator=(const ScheduledFeature&) = delete; + ~ScheduledFeature() override; + + base::OneShotTimer* timer() { return &timer_; } + + bool GetEnabled() const; + ScheduleType GetScheduleType() const; + TimeOfDay GetCustomStartTime() const; + TimeOfDay GetCustomEndTime() const; + + // Get whether the current time is after sunset and before sunrise. + bool IsNowWithinSunsetSunrise() const; + + // Set the desired ScheduledFeature settings in the current active user + // prefs. + void SetEnabled(bool enabled); + void SetScheduleType(ScheduleType type); + void SetCustomStartTime(TimeOfDay start_time); + void SetCustomEndTime(TimeOfDay end_time); + + // SessionObserver: + void OnActiveUserPrefServiceChanged(PrefService* pref_service) override; + + // GeolocationController::Observer: + void OnGeopositionChanged(bool possible_change_in_timezone) override; + + // chromeos::PowerManagerClient::Observer: + void SuspendDone(base::TimeDelta sleep_duration) override; + + void SetClockForTesting(base::Clock* clock); + + protected: + // Called by `Refresh()` and `RefreshScheduleTimer()` to refresh the feature + // state such as display temperature in Night Light. + virtual void RefreshFeatureState() {} + + private: + virtual const char* GetFeatureName() const = 0; + + // Gets now time from the `clock_`, used for testing, or `base::Time::Now()` + // if `clock_` does not exist. + base::Time GetNow() const; + + // Attempts restoring a previously stored schedule for the current user if + // possible and returns true if so, false otherwise. + bool MaybeRestoreSchedule(); + + void StartWatchingPrefsChanges(); + + void InitFromUserPrefs(); + + // Called when the user pref for the enabled status of ScheduledFeature is + // changed. + void OnEnabledPrefChanged(); + + // Called when the user pref for the schedule type is changed. + void OnScheduleTypePrefChanged(); + + // Called when either of the custom schedule prefs (custom start or end times) + // are changed. + void OnCustomSchedulePrefsChanged(); + + // Refreshes the state of ScheduledFeature according to the currently set + // parameters. `did_schedule_change` is true when Refresh() is called as a + // result of a change in one of the schedule related prefs, and false + // otherwise. + // If `keep_manual_toggles_during_schedules` is true, refreshing the schedule + // will not override a previous user's decision to toggle the + // ScheduledFeature status while the schedule is being used. + void Refresh(bool did_schedule_change, + bool keep_manual_toggles_during_schedules); + + // Given the desired start and end times that determine the time interval + // during which the feature will be ON, depending on the time of "now", it + // refreshes the `timer_` to either schedule the future start or end of + // the feature, as well as update the current status if needed. + // For `did_schedule_change` and `keep_manual_toggles_during_schedules`, see + // Refresh() above. + // This function should never be called if the schedule type is `kNone`. + void RefreshScheduleTimer(base::Time start_time, + base::Time end_time, + bool did_schedule_change, + bool keep_manual_toggles_during_schedules); + + // Schedule the upcoming next toggle of the feature status. + void ScheduleNextToggle(base::TimeDelta delay); + + // The pref service of the currently active user. Can be null in + // ash_unittests. + PrefService* active_user_pref_service_ = nullptr; + + // Tracks the upcoming feature state changes per each user due to automatic + // schedules. This can be used to restore a manually toggled status while the + // schedule is being used. See MaybeRestoreSchedule(). + struct ScheduleTargetState { + // The time at which the feature will switch to `target_status` defined + // below. + base::Time target_time; + bool target_status; + }; + base::flat_map<PrefService*, ScheduleTargetState> + per_user_schedule_target_state_; + + // The timer that schedules the start and end of this feature when the + // schedule type is either kSunsetToSunrise or kCustom. + base::OneShotTimer timer_; + + // True only until this feature is initialized from the very first user + // session. After that, it is set to false. + bool is_first_user_init_ = true; + + // The registrar used to watch prefs changes in the above + // `active_user_pref_service_` from outside ash. + // NOTE: Prefs are how Chrome communicates changes to the ScheduledFeature + // settings controlled by this class from the WebUI settings. + std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_; + + const std::string prefs_path_enabled_; + const std::string prefs_path_schedule_type_; + const std::string prefs_path_custom_start_time_; + const std::string prefs_path_custom_end_time_; + const std::string prefs_path_latitude_; + const std::string prefs_path_longitude_; + + GeolocationController* geolocation_controller_; + + // Track if this is `GeolocationController::Observer` to make sure it is not + // added twice if it is already an observer. + bool is_observing_geolocation_ = false; + + // Optional Used in tests to override the time of "Now". + base::Clock* clock_ = nullptr; // Not owned. +}; + +} // namespace ash + +#endif // ASH_SYSTEM_SCHEDULED_FEATURE_SCHEDULED_FEATURE_H_
diff --git a/ash/system/scheduled_feature/scheduled_feature_unittest.cc b/ash/system/scheduled_feature/scheduled_feature_unittest.cc new file mode 100644 index 0000000..0c23ebf --- /dev/null +++ b/ash/system/scheduled_feature/scheduled_feature_unittest.cc
@@ -0,0 +1,408 @@ +// Copyright 2021 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 <cmath> +#include <limits> +#include <memory> +#include <sstream> +#include <string> + +#include "ash/constants/ash_features.h" +#include "ash/constants/ash_pref_names.h" +#include "ash/public/cpp/session/session_types.h" +#include "ash/session/session_controller_impl.h" +#include "ash/session/test_session_controller_client.h" +#include "ash/shell.h" +#include "ash/system/geolocation/geolocation_controller.h" +#include "ash/system/scheduled_feature/scheduled_feature.h" +#include "ash/system/time/time_of_day.h" +#include "ash/test/ash_test_base.h" +#include "ash/test/ash_test_helper.h" +#include "ash/test_shell_delegate.h" +#include "base/bind.h" +#include "base/command_line.h" +#include "base/memory/ptr_util.h" +#include "base/strings/pattern.h" +#include "base/test/scoped_feature_list.h" +#include "base/test/simple_test_clock.h" +#include "base/time/time.h" +#include "components/prefs/pref_service.h" +#include "ui/compositor/layer.h" +#include "ui/gfx/geometry/vector3d_f.h" + +namespace ash { + +namespace { + +constexpr char kUser1Email[] = "user1@featuredschedule"; +constexpr char kUser2Email[] = "user2@featuredschedule"; + +class TestScheduledFeature : public ScheduledFeature { + public: + TestScheduledFeature(const std::string prefs_path_enabled, + const std::string prefs_path_schedule_type, + const std::string prefs_path_custom_start_time, + const std::string prefs_path_custom_end_time) + : ScheduledFeature(prefs_path_enabled, + prefs_path_schedule_type, + prefs_path_custom_start_time, + prefs_path_custom_end_time) {} + TestScheduledFeature(const TestScheduledFeature& other) = delete; + TestScheduledFeature& operator=(const TestScheduledFeature& rhs) = delete; + ~TestScheduledFeature() override {} + + const char* GetFeatureName() const override { return "TestFeature"; } +}; + +class ScheduledFeatureTest : public NoSessionAshTestBase { + public: + ScheduledFeatureTest() = default; + ScheduledFeatureTest(const ScheduledFeatureTest& other) = delete; + ScheduledFeatureTest& operator=(const ScheduledFeatureTest& rhs) = delete; + ~ScheduledFeatureTest() override = default; + + PrefService* user1_pref_service() { + return Shell::Get()->session_controller()->GetUserPrefServiceForUser( + AccountId::FromUserEmail(kUser1Email)); + } + + PrefService* user2_pref_service() { + return Shell::Get()->session_controller()->GetUserPrefServiceForUser( + AccountId::FromUserEmail(kUser2Email)); + } + + ScheduledFeature* feature() { return feature_.get(); } + + // AshTestBase: + void SetUp() override { + NoSessionAshTestBase::SetUp(); + + CreateTestUserSessions(); + + // Simulate user 1 login. + SimulateNewUserFirstLogin(kUser1Email); + + geolocation_controller_ = std::make_unique<GeolocationController>( + /*url_context_getter=*/nullptr); + + // Use user prefs of NightLight, which is an example of ScheduledFeature. + feature_ = std::make_unique<TestScheduledFeature>( + prefs::kNightLightEnabled, prefs::kNightLightScheduleType, + prefs::kNightLightCustomStartTime, prefs::kNightLightCustomEndTime); + + feature_->SetClockForTesting(&test_clock_); + feature_->OnActiveUserPrefServiceChanged( + Shell::Get()->session_controller()->GetActivePrefService()); + } + + void TearDown() override { + geolocation_controller_.reset(); + feature_.reset(); + NoSessionAshTestBase::TearDown(); + } + + void CreateTestUserSessions() { + auto* session_controller_client = GetSessionControllerClient(); + session_controller_client->Reset(); + session_controller_client->AddUserSession(kUser1Email); + session_controller_client->AddUserSession(kUser2Email); + } + + void SwitchActiveUser(const std::string& email) { + GetSessionControllerClient()->SwitchActiveUser( + AccountId::FromUserEmail(email)); + } + + bool GetEnabled() { return feature_->GetEnabled(); } + ScheduledFeature::ScheduleType GetScheduleType() { + return feature_->GetScheduleType(); + } + + void SetFeatureEnabled(bool enabled) { feature_->SetEnabled(enabled); } + void SetScheduleType(ScheduledFeature::ScheduleType type) { + feature_->SetScheduleType(type); + } + + protected: + std::unique_ptr<TestScheduledFeature> feature_; + std::unique_ptr<GeolocationController> geolocation_controller_; + base::SimpleTestClock test_clock_; +}; + +// Tests that switching users retrieves the feature settings for the active +// user's prefs. +TEST_F(ScheduledFeatureTest, UserSwitchAndSettingsPersistence) { + // Start with user1 logged in and update to sunset-to-sunrise schedule type. + const std::string kScheduleTypePrefString = prefs::kNightLightScheduleType; + ScheduledFeature::ScheduleType user1_schedule_type = + ScheduledFeature::ScheduleType::kSunsetToSunrise; + feature()->SetScheduleType(user1_schedule_type); + EXPECT_EQ(user1_schedule_type, GetScheduleType()); + EXPECT_EQ(user1_schedule_type, + user1_pref_service()->GetInteger(kScheduleTypePrefString)); + + // Switch to user 2, and set to custom schedule type. + SwitchActiveUser(kUser2Email); + + ScheduledFeature::ScheduleType user2_schedule_type = + ScheduledFeature::ScheduleType::kCustom; + user2_pref_service()->SetInteger(kScheduleTypePrefString, + user2_schedule_type); + EXPECT_EQ(user2_schedule_type, GetScheduleType()); + EXPECT_EQ(user1_schedule_type, + user1_pref_service()->GetInteger(kScheduleTypePrefString)); + + // Switch back to user 1, to find feature schedule type is restored to + // sunset-to-sunrise. + SwitchActiveUser(kUser1Email); + EXPECT_EQ(user1_schedule_type, GetScheduleType()); +} + +// Tests transitioning from kNone to kCustom and back to kNone schedule +// types. +TEST_F(ScheduledFeatureTest, ScheduleNoneToCustomTransition) { + // Now is 6:00 PM. + test_clock_.SetNow(TimeOfDay(18 * 60).ToTimeToday()); + SetFeatureEnabled(false); + feature()->SetScheduleType(ScheduledFeature::ScheduleType::kNone); + // Start time is at 3:00 PM and end time is at 8:00 PM. + feature()->SetCustomStartTime(TimeOfDay(15 * 60)); + feature()->SetCustomEndTime(TimeOfDay(20 * 60)); + + // 15:00 18:00 20:00 + // <----- + ----------- + ----------- + -----> + // | | | + // start now end + // + // Even though "Now" is inside the feature interval, nothing should + // change, since the schedule type is "none". + EXPECT_FALSE(GetEnabled()); + + // Now change the schedule type to custom, the feature should turn on + // immediately, and the timer should be running with a delay of exactly 2 + // hours scheduling the end. + feature()->SetScheduleType(ScheduledFeature::ScheduleType::kCustom); + EXPECT_TRUE(GetEnabled()); + EXPECT_TRUE(feature()->timer()->IsRunning()); + EXPECT_EQ(base::Hours(2), feature()->timer()->GetCurrentDelay()); + + // If the user changes the schedule type to "none", the feature status + // should not change, but the timer should not be running. + feature()->SetScheduleType(ScheduledFeature::ScheduleType::kNone); + EXPECT_TRUE(GetEnabled()); + EXPECT_FALSE(feature()->timer()->IsRunning()); +} + +// Tests what happens when the time now reaches the end of the feature +// interval when the feature mode is on. +TEST_F(ScheduledFeatureTest, TestCustomScheduleReachingEndTime) { + test_clock_.SetNow(TimeOfDay(18 * 60).ToTimeToday()); + feature()->SetCustomStartTime(TimeOfDay(15 * 60)); + feature()->SetCustomEndTime(TimeOfDay(20 * 60)); + feature()->SetScheduleType(ScheduledFeature::ScheduleType::kCustom); + EXPECT_TRUE(GetEnabled()); + + // Simulate reaching the end time by triggering the timer's user task. Make + // sure that the feature ended. + // + // 15:00 20:00 + // <----- + ------------------------ + -----> + // | | + // start end & now + // + // Now is 8:00 PM. + test_clock_.SetNow(TimeOfDay(20 * 60).ToTimeToday()); + feature()->timer()->FireNow(); + EXPECT_FALSE(GetEnabled()); + // The timer should still be running, but now scheduling the start at 3:00 PM + // tomorrow which is 19 hours from "now" (8:00 PM). + EXPECT_TRUE(feature()->timer()->IsRunning()); + EXPECT_EQ(base::Hours(19), feature()->timer()->GetCurrentDelay()); +} + +// Tests that user toggles from the system menu or system settings override any +// status set by an automatic schedule. +TEST_F(ScheduledFeatureTest, ExplicitUserTogglesWhileScheduleIsActive) { + // Start with the below custom schedule, where the feature is off. + // + // 15:00 20:00 23:00 + // <----- + ----------------- + ------------ + ----> + // | | | + // start end now + // + test_clock_.SetNow(TimeOfDay(23 * 60).ToTimeToday()); + feature()->SetCustomStartTime(TimeOfDay(15 * 60)); + feature()->SetCustomEndTime(TimeOfDay(20 * 60)); + feature()->SetScheduleType(ScheduledFeature::ScheduleType::kCustom); + EXPECT_FALSE(GetEnabled()); + + // What happens if the user manually turns the feature on while the schedule + // type says it should be off? + // User toggles either from the system menu or the System Settings toggle + // button must override any automatic schedule. + SetFeatureEnabled(true); + EXPECT_TRUE(GetEnabled()); + // The timer should still be running, but the feature should automatically + // turn off at 8:00 PM tomorrow, which is 21 hours from now (11:00 PM). + EXPECT_TRUE(feature()->timer()->IsRunning()); + EXPECT_EQ(base::Hours(21), feature()->timer()->GetCurrentDelay()); + + // Manually turning it back off should also be respected, and this time the + // start is scheduled at 3:00 PM tomorrow after 19 hours from "now" (8:00 + // PM). + SetFeatureEnabled(false); + EXPECT_FALSE(GetEnabled()); + EXPECT_TRUE(feature()->timer()->IsRunning()); + EXPECT_EQ(base::Hours(16), feature()->timer()->GetCurrentDelay()); +} + +// Tests that changing the custom start and end times, in such a way that +// shouldn't change the current status, only updates the timer but doesn't +// change the status. +TEST_F(ScheduledFeatureTest, ChangingStartTimesThatDontChangeTheStatus) { + // 16:00 18:00 22:00 + // <----- + ----------- + ----------- + -----> + // | | | + // now start end + // + test_clock_.SetNow(TimeOfDay(16 * 60).ToTimeToday()); // 4:00 PM. + SetFeatureEnabled(false); + feature()->SetScheduleType(ScheduledFeature::ScheduleType::kNone); + feature()->SetCustomStartTime(TimeOfDay(18 * 60)); // 6:00 PM. + feature()->SetCustomEndTime(TimeOfDay(22 * 60)); // 10:00 PM. + + // Since now is outside the feature interval, changing the schedule type + // to kCustom, shouldn't affect the status. Validate the timer is running + // with a 2-hour delay. + feature()->SetScheduleType(ScheduledFeature::ScheduleType::kCustom); + EXPECT_FALSE(GetEnabled()); + EXPECT_TRUE(feature()->timer()->IsRunning()); + EXPECT_EQ(base::Hours(2), feature()->timer()->GetCurrentDelay()); + + // Change the start time in such a way that doesn't change the status, but + // despite that, confirm that schedule has been updated. + feature()->SetCustomStartTime(TimeOfDay(19 * 60)); // 7:00 PM. + EXPECT_FALSE(GetEnabled()); + EXPECT_TRUE(feature()->timer()->IsRunning()); + EXPECT_EQ(base::Hours(3), feature()->timer()->GetCurrentDelay()); + + // Changing the end time in a similar fashion to the above and expect no + // change. + feature()->SetCustomEndTime(TimeOfDay(23 * 60)); // 11:00 PM. + EXPECT_FALSE(GetEnabled()); + EXPECT_TRUE(feature()->timer()->IsRunning()); + EXPECT_EQ(base::Hours(3), feature()->timer()->GetCurrentDelay()); +} + +// Tests that the feature should turn on at sunset time and turn off at sunrise +// time. +TEST_F(ScheduledFeatureTest, SunsetSunrise) { + EXPECT_FALSE(GetEnabled()); + + // Set time now to 10:00 AM. + base::Time current_time = TimeOfDay(10 * 60).ToTimeToday(); + test_clock_.SetNow(current_time); + EXPECT_FALSE(feature()->timer()->IsRunning()); + feature()->SetScheduleType(ScheduledFeature::ScheduleType::kSunsetToSunrise); + EXPECT_FALSE(GetEnabled()); + EXPECT_TRUE(feature()->timer()->IsRunning()); + EXPECT_EQ(geolocation_controller_->GetSunsetTime() - current_time, + feature()->timer()->GetCurrentDelay()); + + // Firing a timer should to advance the time to sunset and automatically turn + // on the feature. + current_time = geolocation_controller_->GetSunsetTime(); + test_clock_.SetNow(current_time); + feature()->timer()->FireNow(); + EXPECT_TRUE(feature()->timer()->IsRunning()); + EXPECT_TRUE(GetEnabled()); + EXPECT_EQ(geolocation_controller_->GetSunriseTime() + base::Hours(24) - + current_time, + feature()->timer()->GetCurrentDelay()); + + // Firing a timer should advance the time to sunrise and automatically turn + // off the feature. + current_time = geolocation_controller_->GetSunriseTime(); + test_clock_.SetNow(current_time); + feature()->timer()->FireNow(); + EXPECT_FALSE(GetEnabled()); + EXPECT_TRUE(feature()->timer()->IsRunning()); + EXPECT_EQ(geolocation_controller_->GetSunsetTime() - current_time, + feature()->timer()->GetCurrentDelay()); +} + +// The following tests ensure that the feature schedule is correctly +// refreshed when the start and end times are inverted (i.e. the "start time" as +// a time of day today is in the future with respect to the "end time" also as a +// time of day today). +// +// Case 1: "Now" is less than both "end" and "start". +TEST_F(ScheduledFeatureTest, CustomScheduleInvertedStartAndEndTimesCase1) { + // Now is 4:00 AM. + test_clock_.SetNow(TimeOfDay(4 * 60).ToTimeToday()); + SetFeatureEnabled(false); + // Start time is at 9:00 PM and end time is at 6:00 AM. "Now" is less than + // both. The feature should be on. + // 4:00 6:00 21:00 + // <----- + ----------- + ----------- + -----> + // | | | + // now end start + // + feature()->SetCustomStartTime(TimeOfDay(21 * 60)); + feature()->SetCustomEndTime(TimeOfDay(6 * 60)); + feature()->SetScheduleType(ScheduledFeature::ScheduleType::kCustom); + + EXPECT_TRUE(GetEnabled()); + EXPECT_TRUE(feature()->timer()->IsRunning()); + // The feature should end in two hours. + EXPECT_EQ(base::Hours(2), feature()->timer()->GetCurrentDelay()); +} + +// Case 2: "Now" is between "end" and "start". +TEST_F(ScheduledFeatureTest, CustomScheduleInvertedStartAndEndTimesCase2) { + // Now is 6:00 AM. + test_clock_.SetNow(TimeOfDay(6 * 60).ToTimeToday()); + SetFeatureEnabled(false); + // Start time is at 9:00 PM and end time is at 4:00 AM. "Now" is between both. + // The feature should be off. + // 4:00 6:00 21:00 + // <----- + ----------- + ----------- + -----> + // | | | + // end now start + // + feature()->SetCustomStartTime(TimeOfDay(21 * 60)); + feature()->SetCustomEndTime(TimeOfDay(4 * 60)); + feature()->SetScheduleType(ScheduledFeature::ScheduleType::kCustom); + + EXPECT_FALSE(GetEnabled()); + EXPECT_TRUE(feature()->timer()->IsRunning()); + // The feature should start in 15 hours. + EXPECT_EQ(base::Hours(15), feature()->timer()->GetCurrentDelay()); +} + +// Case 3: "Now" is greater than both "start" and "end". +TEST_F(ScheduledFeatureTest, CustomScheduleInvertedStartAndEndTimesCase3) { + // Now is 11:00 PM. + test_clock_.SetNow(TimeOfDay(23 * 60).ToTimeToday()); + SetFeatureEnabled(false); + // Start time is at 9:00 PM and end time is at 4:00 AM. "Now" is greater than + // both. NightLight should be on. + // 4:00 21:00 23:00 + // <----- + ----------- + ----------- + -----> + // | | | + // end start now + // + feature()->SetCustomStartTime(TimeOfDay(21 * 60)); + feature()->SetCustomEndTime(TimeOfDay(4 * 60)); + feature()->SetScheduleType(ScheduledFeature::ScheduleType::kCustom); + + EXPECT_TRUE(GetEnabled()); + EXPECT_TRUE(feature()->timer()->IsRunning()); + // The feature should end in 5 hours. + EXPECT_EQ(base::Hours(5), feature()->timer()->GetCurrentDelay()); +} + +} // namespace + +} // namespace ash \ No newline at end of file
diff --git a/ash/system/unified/notification_icons_controller.cc b/ash/system/unified/notification_icons_controller.cc index 0ae81af0..6558f83 100644 --- a/ash/system/unified/notification_icons_controller.cc +++ b/ash/system/unified/notification_icons_controller.cc
@@ -240,23 +240,28 @@ const bool should_show_icons = icons_view_visible_ && ShouldShowNotificationItemsInTray(); - auto it = tray_items_.begin(); - for (message_center::Notification* notification : - message_center_utils::GetSortedNotificationsWithOwnView()) { - if (it == tray_items_.end()) + // Iterates `tray_items_` and notifications in reverse order so new pinned + // notifications get shown on the left side. + auto notifications = + message_center_utils::GetSortedNotificationsWithOwnView(); + + auto tray_it = tray_items_.rbegin(); + for (auto notification_it = notifications.rbegin(); + notification_it != notifications.rend(); ++notification_it) { + if (tray_it == tray_items_.rend()) break; - if (ShouldShowNotification(notification)) { - (*it)->SetNotification(notification); - (*it)->SetVisible(should_show_icons); - ++it; + if (ShouldShowNotification(*notification_it)) { + (*tray_it)->SetNotification(*notification_it); + (*tray_it)->SetVisible(should_show_icons); + ++tray_it; } } - first_unused_item_index_ = std::distance(tray_items_.begin(), it); + first_unused_item_index_ = std::distance(tray_items_.rbegin(), tray_it); - for (; it != tray_items_.end(); ++it) { - (*it)->Reset(); - (*it)->SetVisible(false); + for (; tray_it != tray_items_.rend(); ++tray_it) { + (*tray_it)->Reset(); + (*tray_it)->SetVisible(false); } separator_->SetVisible(should_show_icons && TrayItemHasNotification()); }
diff --git a/ash/system/unified/notification_icons_controller_unittest.cc b/ash/system/unified/notification_icons_controller_unittest.cc index cd90c5d..10160d4 100644 --- a/ash/system/unified/notification_icons_controller_unittest.cc +++ b/ash/system/unified/notification_icons_controller_unittest.cc
@@ -94,37 +94,47 @@ AddNotification(true /* is_pinned */, false /* is_critical_warning */); AddNotification(false /* is_pinned */, false /* is_critical_warning */); + // Icons get added from RTL, so we check the end of the vector first. + // Notification icons should be shown in medium screen size. UpdateDisplay("800x700"); EXPECT_EQ(IsScalableStatusAreaEnabled(), - notification_icons_controller_->tray_items().front()->GetVisible()); + notification_icons_controller_->tray_items().back()->GetVisible()); EXPECT_EQ(IsScalableStatusAreaEnabled(), separator()->GetVisible()); // Notification icons should not be shown in small screen size. UpdateDisplay("600x500"); EXPECT_FALSE( - notification_icons_controller_->tray_items().front()->GetVisible()); + notification_icons_controller_->tray_items().back()->GetVisible()); EXPECT_FALSE(separator()->GetVisible()); // Notification icons should be shown in large screen size. UpdateDisplay("1680x800"); EXPECT_EQ(IsScalableStatusAreaEnabled(), - notification_icons_controller_->tray_items().front()->GetVisible()); + notification_icons_controller_->tray_items().back()->GetVisible()); EXPECT_EQ(IsScalableStatusAreaEnabled(), separator()->GetVisible()); } TEST_P(NotificationIconsControllerTest, ShowNotificationIcons) { UpdateDisplay("800x700"); + // Icons get added from RTL, so we check the end of the vector first. + const int end = notification_icons_controller_->tray_items().size() - 1; + + // Ensure that the indexes that will be accessed exist. + ASSERT_TRUE(notification_icons_controller_->tray_items().size() >= 2); + // If there's no notification, no notification icons should be shown. - EXPECT_FALSE(notification_icons_controller_->tray_items()[0]->GetVisible()); - EXPECT_FALSE(notification_icons_controller_->tray_items()[1]->GetVisible()); + EXPECT_FALSE(notification_icons_controller_->tray_items()[end]->GetVisible()); + EXPECT_FALSE( + notification_icons_controller_->tray_items()[end - 1]->GetVisible()); EXPECT_FALSE(separator()->GetVisible()); // Same case for non pinned or non critical warning notification. AddNotification(false /* is_pinned */, false /* is_critical_warning */); - EXPECT_FALSE(notification_icons_controller_->tray_items()[0]->GetVisible()); - EXPECT_FALSE(notification_icons_controller_->tray_items()[1]->GetVisible()); + EXPECT_FALSE(notification_icons_controller_->tray_items()[end]->GetVisible()); + EXPECT_FALSE( + notification_icons_controller_->tray_items()[end - 1]->GetVisible()); EXPECT_FALSE(separator()->GetVisible()); // Notification icons should be shown when pinned or critical warning @@ -132,16 +142,18 @@ std::string id0 = AddNotification(true /* is_pinned */, false /* is_critical_warning */); EXPECT_EQ(IsScalableStatusAreaEnabled(), - notification_icons_controller_->tray_items()[0]->GetVisible()); - EXPECT_FALSE(notification_icons_controller_->tray_items()[1]->GetVisible()); + notification_icons_controller_->tray_items()[end]->GetVisible()); + EXPECT_FALSE( + notification_icons_controller_->tray_items()[end - 1]->GetVisible()); EXPECT_EQ(IsScalableStatusAreaEnabled(), separator()->GetVisible()); std::string id1 = AddNotification(false /* is_pinned */, true /* is_critical_warning */); EXPECT_EQ(IsScalableStatusAreaEnabled(), - notification_icons_controller_->tray_items()[0]->GetVisible()); - EXPECT_EQ(IsScalableStatusAreaEnabled(), - notification_icons_controller_->tray_items()[1]->GetVisible()); + notification_icons_controller_->tray_items()[end]->GetVisible()); + EXPECT_EQ( + IsScalableStatusAreaEnabled(), + notification_icons_controller_->tray_items()[end - 1]->GetVisible()); EXPECT_EQ(IsScalableStatusAreaEnabled(), separator()->GetVisible()); // Remove the critical warning notification should make the tray show only one @@ -149,27 +161,33 @@ message_center::MessageCenter::Get()->RemoveNotification(id1, false /* by_user */); EXPECT_EQ(IsScalableStatusAreaEnabled(), - notification_icons_controller_->tray_items()[0]->GetVisible()); - EXPECT_FALSE(notification_icons_controller_->tray_items()[1]->GetVisible()); + notification_icons_controller_->tray_items()[end]->GetVisible()); + EXPECT_FALSE( + notification_icons_controller_->tray_items()[end - 1]->GetVisible()); EXPECT_EQ(IsScalableStatusAreaEnabled(), separator()->GetVisible()); // Remove the pinned notification, no icon is shown. message_center::MessageCenter::Get()->RemoveNotification(id0, false /* by_user */); - EXPECT_FALSE(notification_icons_controller_->tray_items()[0]->GetVisible()); - EXPECT_FALSE(notification_icons_controller_->tray_items()[1]->GetVisible()); + EXPECT_FALSE(notification_icons_controller_->tray_items()[end]->GetVisible()); + EXPECT_FALSE( + notification_icons_controller_->tray_items()[end - 1]->GetVisible()); EXPECT_FALSE(separator()->GetVisible()); } TEST_P(NotificationIconsControllerTest, NotShowNotificationIcons) { UpdateDisplay("800x700"); - EXPECT_FALSE(notification_icons_controller_->tray_items()[0]->GetVisible()); + // Icons get added from RTL, so we check the end of the vector first. + + EXPECT_FALSE( + notification_icons_controller_->tray_items().back()->GetVisible()); AddNotification(true /* is_pinned */, false /* is_critical_warning */, kBatteryNotificationNotifierId); // Battery notification should not be shown. - EXPECT_FALSE(notification_icons_controller_->tray_items()[0]->GetVisible()); + EXPECT_FALSE( + notification_icons_controller_->tray_items().back()->GetVisible()); EXPECT_FALSE(separator()->GetVisible()); // Notification count does update for this notification. notification_icons_controller_->notification_counter_view()->Update(); @@ -179,7 +197,8 @@ AddNotification(true /* is_pinned */, false /* is_critical_warning */, kUsbNotificationNotifierId); // Usb charging notification should not be shown. - EXPECT_FALSE(notification_icons_controller_->tray_items()[0]->GetVisible()); + EXPECT_FALSE( + notification_icons_controller_->tray_items().back()->GetVisible()); EXPECT_FALSE(separator()->GetVisible()); // Notification count does update for this notification. notification_icons_controller_->notification_counter_view()->Update(); @@ -189,7 +208,8 @@ AddNotification(true /* is_pinned */, false /* is_critical_warning */, kVmCameraMicNotifierId); // VM camera/mic notification should not be shown. - EXPECT_FALSE(notification_icons_controller_->tray_items()[0]->GetVisible()); + EXPECT_FALSE( + notification_icons_controller_->tray_items().back()->GetVisible()); EXPECT_FALSE(separator()->GetVisible()); // Notification count does not update for this notification (since there's // another tray item for this).
diff --git a/ash/wm/desks/templates/desks_templates_presenter.cc b/ash/wm/desks/templates/desks_templates_presenter.cc index daffefeb..2fddd6c 100644 --- a/ash/wm/desks/templates/desks_templates_presenter.cc +++ b/ash/wm/desks/templates/desks_templates_presenter.cc
@@ -25,6 +25,7 @@ namespace ash { namespace { + DesksTemplatesPresenter* g_instance = nullptr; // The amount of time for which the launch template toasts will remain @@ -37,7 +38,6 @@ // Helper to get the desk model from the shell delegate. Should always return a // usable desk model, either from chrome sync, or a local storage. -// TODO(sammiequon): Investigate if we can cache this. desks_storage::DeskModel* GetDeskModel() { auto* desk_model = Shell::Get()->desks_templates_delegate()->GetDeskModel(); DCHECK(desk_model); @@ -181,12 +181,22 @@ weak_ptr_factory_.GetWeakPtr(), is_update)); } -void DesksTemplatesPresenter::DeskModelLoaded() {} - void DesksTemplatesPresenter::OnDeskModelDestroying() { desk_model_observation_.Reset(); } +void DesksTemplatesPresenter::EntriesAddedOrUpdatedRemotely( + const std::vector<const DeskTemplate*>& new_entries) { + if (overview_session_->IsShowingDesksTemplatesGrid()) + GetAllEntries(); +} + +void DesksTemplatesPresenter::EntriesRemovedRemotely( + const std::vector<std::string>& uuids) { + if (overview_session_->IsShowingDesksTemplatesGrid()) + GetAllEntries(); +} + void DesksTemplatesPresenter::OnGetAllEntries( desks_storage::DeskModel::GetAllEntriesStatus status, const std::vector<DeskTemplate*>& entries) { @@ -218,8 +228,6 @@ RecordDeleteTemplateHistogram(); GetAllEntries(); - - UpdateDesksTemplatesUI(); } void DesksTemplatesPresenter::OnGetTemplateForDeskLaunch( @@ -250,18 +258,17 @@ if (status != desks_storage::DeskModel::AddOrUpdateEntryStatus::kOk) return; - const auto& grid_list = overview_session_->grid_list(); - DCHECK(!grid_list.empty()); - // If the templates grid is already shown, just update the entries. - if (grid_list[0]->IsShowingDesksTemplatesGrid()) { + if (overview_session_->IsShowingDesksTemplatesGrid()) { GetAllEntries(); return; } // Update the button here in case it has been disabled. + const auto& grid_list = overview_session_->grid_list(); + DCHECK(!grid_list.empty()); overview_session_->ShowDesksTemplatesGrids( - grid_list[0]->desks_bar_view()->IsZeroState()); + grid_list.front()->desks_bar_view()->IsZeroState()); for (auto& overview_grid : grid_list) overview_grid->UpdateSaveDeskAsTemplateButton();
diff --git a/ash/wm/desks/templates/desks_templates_presenter.h b/ash/wm/desks/templates/desks_templates_presenter.h index 2592b77..9fc3bd2 100644 --- a/ash/wm/desks/templates/desks_templates_presenter.h +++ b/ash/wm/desks/templates/desks_templates_presenter.h
@@ -66,13 +66,11 @@ std::unique_ptr<DeskTemplate> desk_template); // desks_storage::DeskModelObserver: - // TODO(sammiequon): Implement these once the model starts sending these - // messages. - void DeskModelLoaded() override; + void DeskModelLoaded() override {} void OnDeskModelDestroying() override; void EntriesAddedOrUpdatedRemotely( - const std::vector<const DeskTemplate*>& new_entries) override {} - void EntriesRemovedRemotely(const std::vector<std::string>& uuids) override {} + const std::vector<const DeskTemplate*>& new_entries) override; + void EntriesRemovedRemotely(const std::vector<std::string>& uuids) override; void EntriesAddedOrUpdatedLocally( const std::vector<const DeskTemplate*>& new_entries) override {} void EntriesRemovedLocally(const std::vector<std::string>& uuids) override {}
diff --git a/ash/wm/overview/overview_session.cc b/ash/wm/overview/overview_session.cc index 7452172d..82e163b 100644 --- a/ash/wm/overview/overview_session.cc +++ b/ash/wm/overview/overview_session.cc
@@ -1005,6 +1005,13 @@ grid->HideDesksTemplatesGrid(/*exit_overview=*/false); } +bool OverviewSession::IsShowingDesksTemplatesGrid() const { + // All the grids should show the templates grid at the same time so just check + // if the first grid is showing. + return grid_list_.empty() ? false + : grid_list_.front()->IsShowingDesksTemplatesGrid(); +} + void OverviewSession::OnDeskAdded(const Desk* desk) {} void OverviewSession::OnDeskRemoved(const Desk* desk) {} void OverviewSession::OnDeskReordered(int old_index, int new_index) {}
diff --git a/ash/wm/overview/overview_session.h b/ash/wm/overview/overview_session.h index 30512b7c..464b61d6 100644 --- a/ash/wm/overview/overview_session.h +++ b/ash/wm/overview/overview_session.h
@@ -282,6 +282,7 @@ // true then we will expand the desks bars. void ShowDesksTemplatesGrids(bool was_zero_state); void HideDesksTemplatesGrids(); + bool IsShowingDesksTemplatesGrid() const; // DesksController::Observer: void OnDeskAdded(const Desk* desk) override;
diff --git a/base/BUILD.gn b/base/BUILD.gn index e393c80c..554604d 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -3830,6 +3830,7 @@ "containers/buffer_iterator_unittest.nc", "containers/checked_iterators_unittest.nc", "containers/contains_unittest.nc", + "containers/enum_set_unittest.nc", "containers/span_unittest.nc", "debug/crash_logging_unittest.nc", "memory/raw_ptr_unittest.nc",
diff --git a/base/containers/enum_set.h b/base/containers/enum_set.h index 30fbb36..28f79dd 100644 --- a/base/containers/enum_set.h +++ b/base/containers/enum_set.h
@@ -296,7 +296,7 @@ // some minor optimizations. explicit constexpr EnumSet(EnumBitSet enums) : enums_(enums) { static_assert(kValueCount <= 64, - "Max number of enum values is 64 for constexpr "); + "Max number of enum values is 64 for constexpr constructor"); } // Converts a value to/from an index into |enums_|.
diff --git a/base/containers/enum_set_unittest.cc b/base/containers/enum_set_unittest.cc index 4ecbe7d..489e1f4 100644 --- a/base/containers/enum_set_unittest.cc +++ b/base/containers/enum_set_unittest.cc
@@ -420,6 +420,57 @@ TestEnumSet::single_val_bitstring(TestEnum::TEST_7_OUT_OF_BOUNDS)); } +TEST_F(EnumSetTest, SparseEnum) { + enum class TestEnumSparse { + TEST_1 = 1, + TEST_MIN = 1, + TEST_50 = 50, + TEST_100 = 100, + TEST_MAX = TEST_100, + }; + using TestEnumSparseSet = EnumSet<TestEnumSparse, TestEnumSparse::TEST_MIN, + TestEnumSparse::TEST_MAX>; + TestEnumSparseSet sparse; + sparse.Put(TestEnumSparse::TEST_MIN); + sparse.Put(TestEnumSparse::TEST_MAX); + EXPECT_EQ(sparse.Size(), 2u); + + // TestEnumSparseSet::All() does not compile because there are more than 64 + // possible values. See NCTEST_ALL_METHOD_DISALLOWED_ON_LARGE_SPARSE_ENUM in + // enum_set_unittest.nc. +} + +TEST_F(EnumSetTest, SparseEnumSmall) { + enum class TestEnumSparse { + TEST_1 = 1, + TEST_MIN = 1, + TEST_50 = 50, + TEST_60 = 60, + TEST_MAX = TEST_60, + }; + using TestEnumSparseSet = EnumSet<TestEnumSparse, TestEnumSparse::TEST_MIN, + TestEnumSparse::TEST_MAX>; + TestEnumSparseSet sparse; + sparse.Put(TestEnumSparse::TEST_MIN); + sparse.Put(TestEnumSparse::TEST_MAX); + EXPECT_EQ(sparse.Size(), 2u); + + // This may seem a little surprising! There are only 3 distinct values in + // TestEnumSparse, so why does TestEnumSparseSet think it has 60 of them? This + // is an artifact of EnumSet's design, as it has no way of knowing which + // values between the min and max are actually named in the enum's definition. + EXPECT_EQ(TestEnumSparseSet::All().Size(), 60u); +} + +TEST_F(EnumSetTest, SingleValBitstringCrashesOnOutOfRange) { + EXPECT_CHECK_DEATH( + TestEnumSet::single_val_bitstring(TestEnum::TEST_BELOW_MIN)); + EXPECT_CHECK_DEATH( + TestEnumSet::single_val_bitstring(TestEnum::TEST_6_OUT_OF_BOUNDS)); + EXPECT_CHECK_DEATH( + TestEnumSet::single_val_bitstring(TestEnum::TEST_7_OUT_OF_BOUNDS)); +} + TEST_F(EnumSetDeathTest, SingleValBitstringEnumWithNegatives) { enum class TestEnumNeg { TEST_BELOW_MIN = -3,
diff --git a/base/containers/enum_set_unittest.nc b/base/containers/enum_set_unittest.nc new file mode 100644 index 0000000..c3d7347 --- /dev/null +++ b/base/containers/enum_set_unittest.nc
@@ -0,0 +1,34 @@ +// Copyright (c) 2021 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 is a "No Compile Test" suite. +// https://dev.chromium.org/developers/testing/no-compile-tests + +#include "base/containers/enum_set.h" + +namespace base { +namespace { + +#if defined(NCTEST_ALL_METHOD_DISALLOWED_ON_LARGE_SPARSE_ENUM) // [r"fatal error: static_assert failed due to requirement 'kValueCount <= 64' \"Max number of enum values is 64 for constexpr constructor\""] + +void WontCompile() { + enum class TestEnumSparse { + TEST_1 = 1, + TEST_MIN = 1, + TEST_50 = 50, + TEST_100 = 100, + TEST_MAX = TEST_100, + }; + using TestEnumSparseSet = EnumSet<TestEnumSparse, TestEnumSparse::TEST_MIN, + TestEnumSparse::TEST_MAX>; + + // TestEnumSparseSet::All() does not compile because there are more than 64 + // possible values. + TestEnumSparseSet::All(); +} + +#endif + +} // namespace +} // namespace base
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 7fa20e5..a170f0e5 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -7.20211222.1.1 +7.20211222.2.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 7fa20e5..a170f0e5 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -7.20211222.1.1 +7.20211222.2.1
diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc index 2b8ad609..e8a6155a 100644 --- a/cc/trees/draw_property_utils.cc +++ b/cc/trees/draw_property_utils.cc
@@ -769,8 +769,10 @@ auto result = std::make_pair(node->mask_filter_info, node->is_fast_rounded_corner); - if (!result.first.Transform(to_target)) + if (!result.first.Transform(to_target)) { + DCHECK(result.first.IsEmpty()); return kEmptyMaskFilterInfoPair; + } return result; }
diff --git a/chrome/VERSION b/chrome/VERSION index 88bf9e5..8abb8d7 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=99 MINOR=0 -BUILD=4782 +BUILD=4783 PATCH=0
diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_java_resources.gni index 1824e362..220effc 100644 --- a/chrome/android/chrome_java_resources.gni +++ b/chrome/android/chrome_java_resources.gni
@@ -531,7 +531,6 @@ "java/res/drawable/material_tooltip_background.xml", "java/res/drawable/mir_card.xml", "java/res/drawable/outline_chevron_right_24dp.xml", - "java/res/drawable/pill_background.xml", "java/res/drawable/price_tracking_disabled.xml", "java/res/drawable/price_tracking_enabled_filled.xml", "java/res/drawable/price_tracking_enabled_outline.xml", @@ -651,7 +650,6 @@ "java/res/layout/fre_data_reduction_proxy_lite_mode.xml", "java/res/layout/fre_tos_privacy_disclaimer.xml", "java/res/layout/fre_tosanduma.xml", - "java/res/layout/fullscreen_notification.xml", "java/res/layout/history_clear_browsing_data_header.xml", "java/res/layout/history_item_view.xml", "java/res/layout/history_main.xml",
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantCoordinator.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantCoordinator.java index 6617051..af885369 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantCoordinator.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantCoordinator.java
@@ -23,8 +23,6 @@ * sub-components and shutting down the Autofill Assistant. */ public class AssistantCoordinator { - private final Activity mActivity; - private final AssistantModel mModel; private AssistantBottomBarCoordinator mBottomBarCoordinator; private final AssistantKeyboardCoordinator mKeyboardCoordinator; @@ -38,8 +36,6 @@ @NonNull BrowserControlsManager browserControlsManager, @NonNull ApplicationViewportInsetSupplier applicationBottomInsetProvider, AccessibilityUtil accessibilityUtil, AssistantInfoPageUtil infoPageUtil) { - mActivity = activity; - if (overlayCoordinator != null) { mModel = new AssistantModel(overlayCoordinator.getModel()); mOverlayCoordinator = overlayCoordinator;
diff --git a/chrome/android/java/res/drawable/pill_background.xml b/chrome/android/java/res/drawable/pill_background.xml deleted file mode 100644 index b9ed6ad..0000000 --- a/chrome/android/java/res/drawable/pill_background.xml +++ /dev/null
@@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright 2021 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. --> - -<shape xmlns:android="http://schemas.android.com/apk/res/android" - android:dither="true" - android:shape="rectangle"> - <corners android:radius="40dp" /> - <solid android:color="@color/default_bg_color_dark"/> - <size - android:width="60dp" - android:height="20dp" /> -</shape>
diff --git a/chrome/android/java/res/layout/fullscreen_notification.xml b/chrome/android/java/res/layout/fullscreen_notification.xml deleted file mode 100644 index 5687b66a..0000000 --- a/chrome/android/java/res/layout/fullscreen_notification.xml +++ /dev/null
@@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright 2021 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. --> - -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical" - android:paddingTop="24dp"> - <TextView - android:id="@+id/text" - android:layout_height="wrap_content" - android:layout_width="wrap_content" - android:maxWidth="@dimen/fullscreen_notification_max_width" - android:layout_gravity="center" - android:background="@drawable/pill_background" - android:textAppearance="@style/TextAppearance.Toast" - android:paddingStart="20dp" - android:paddingEnd="20dp" - android:paddingTop="8dp" - android:paddingBottom="8dp" - android:textAlignment="center" - android:text="@string/immersive_fullscreen_api_notification"/> -</LinearLayout>
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index b2547931..6cbd92c 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -157,7 +157,6 @@ <!-- Should match toolbar_height_no_shadow --> <dimen name="control_container_height">56dp</dimen> <dimen name="custom_tabs_control_container_height">56dp</dimen> - <dimen name="fullscreen_notification_max_width">320dp</dimen> <!-- The combined height of the tab strip and toolbar. --> <dimen name="tab_strip_and_toolbar_height">56dp</dimen>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRow.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRow.java index dfbc97f5..10e936d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRow.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRow.java
@@ -157,8 +157,8 @@ ApiCompatibilityUtils.setTextAppearance( primaryText, R.styleable.ChipView_primaryTextAppearance); primaryText.setText(formattedCurrentPrice); - primaryText.setTextColor( - ApiCompatibilityUtils.getColor(getResources(), R.color.default_green)); + primaryText.setTextColor(ApiCompatibilityUtils.getColor( + getResources(), R.color.price_drop_annotation_text_green)); // Secondary text displays the original price with a strikethrough. TextView secondaryText = cv.getSecondaryTextView();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandler.java index 73e3b4f7..a31dfe9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandler.java
@@ -11,10 +11,9 @@ import android.app.Activity; import android.os.Handler; import android.os.Message; -import android.view.LayoutInflater; +import android.view.Gravity; import android.view.View; import android.view.View.OnLayoutChangeListener; -import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; @@ -47,6 +46,7 @@ import org.chromium.content_public.browser.NavigationHandle; import org.chromium.content_public.browser.SelectionPopupController; import org.chromium.content_public.browser.WebContents; +import org.chromium.ui.widget.Toast; import java.lang.ref.WeakReference; @@ -66,8 +66,6 @@ // Delay to allow a frame to render between getting the fullscreen layout update and clearing // the SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN flag. private static final long CLEAR_LAYOUT_FULLSCREEN_DELAY_MS = 20; - // Fade in/out animation duration for fullscreen notification toast. - private static final int TOAST_FADE_MS = 500; private final Activity mActivity; private final Handler mHandler; @@ -88,7 +86,7 @@ // Toast at the top of the screen that is shown when user enters fullscreen for the // first time. - private View mNotificationToast; + private Toast mNotificationToast; private OnLayoutChangeListener mFullscreenOnLayoutChangeListener; @@ -357,10 +355,13 @@ * @param controlsHidden {@code true} if the controls are now hidden. */ private void maybeEnterFullscreenFromPendingState(boolean controlsHidden) { - if (!controlsHidden) return; - if (mTab != null && mPendingFullscreenOptions != null) { + if (!controlsHidden || mTab == null) return; + if (mPendingFullscreenOptions != null) { enterFullscreen(mTab, mPendingFullscreenOptions); mPendingFullscreenOptions = null; + } else { + // Restore browser controls if the fullscreen process got canceled. + TabBrowserControlsConstraintsHelper.update(mTab, BrowserControlsState.SHOWN, true); } } @@ -511,27 +512,23 @@ * Create and show the fullscreen notification toast. */ private void showNotificationToast() { - assert mTab != null && mTab.getContentView() != null; - ViewGroup parent = mTab.getContentView(); - if (mNotificationToast != null) parent.removeView(mNotificationToast); - mNotificationToast = - LayoutInflater.from(mActivity).inflate(R.layout.fullscreen_notification, null); - mNotificationToast.setAlpha(0); - parent.addView(mNotificationToast); - mNotificationToast.animate().alpha(1).setDuration(TOAST_FADE_MS).start(); - mHandler.postDelayed(this::hideNotificationToast, 5000); + if (mNotificationToast != null) { + mNotificationToast.cancel(); + } + int resId = R.string.immersive_fullscreen_api_notification; + mNotificationToast = Toast.makeText(mActivity, resId, Toast.LENGTH_LONG); + mNotificationToast.setGravity(Gravity.TOP | Gravity.CENTER, 0, 0); + mNotificationToast.show(); } /** * Hides the notification toast. */ private void hideNotificationToast() { - if (mNotificationToast == null) return; - mNotificationToast.animate().alpha(0).setDuration(TOAST_FADE_MS).withEndAction(() -> { - assert mTab != null && mTab.getContentView() != null; - mTab.getContentView().removeView(mNotificationToast); + if (mNotificationToast != null) { + mNotificationToast.cancel(); mNotificationToast = null; - }); + } } // ActivityStateListener
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkTest.java index 4be9638e..c71e2d5 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkTest.java
@@ -14,7 +14,6 @@ import android.widget.LinearLayout; import android.widget.TextView; -import androidx.annotation.ColorInt; import androidx.test.filters.MediumTest; import org.junit.Rule; @@ -39,6 +38,7 @@ import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate; import org.chromium.chrome.test.util.ChromeRenderTestRule; +import org.chromium.components.browser_ui.styles.SemanticColorUtils; import org.chromium.components.image_fetcher.ImageFetcher; import org.chromium.components.payments.CurrencyFormatter; import org.chromium.content_public.browser.test.util.TestThreadUtils; @@ -59,7 +59,6 @@ private static List<ParameterSet> sClassParams = new NightModeParams().getParameters(); private static final long CURRENCY_MUTLIPLIER = 1000000; - private final @ColorInt int mFakeBgColor; @Rule public ChromeRenderTestRule mRenderTestRule = @@ -85,7 +84,6 @@ public PowerBookmarkTest(boolean nightModeEnabled) { // Sets a fake background color to make the screenshots easier to compare with bare eyes. - mFakeBgColor = nightModeEnabled ? Color.BLACK : Color.WHITE; NightModeTestUtils.setUpNightModeForDummyUiActivity(nightModeEnabled); mRenderTestRule.setNightModeEnabled(nightModeEnabled); } @@ -135,7 +133,8 @@ .getLayoutInflater() .inflate(R.layout.power_bookmark_shopping_item_row, mContentView, true) .findViewById(R.id.power_bookmark_shopping_row); - mPowerBookmarkShoppingItemRow.setBackgroundColor(mFakeBgColor); + mPowerBookmarkShoppingItemRow.setBackgroundColor( + SemanticColorUtils.getDefaultBgColor(getActivity())); ((TextView) mPowerBookmarkShoppingItemRow.findViewById(R.id.title)) .setText("Test Bookmark"); ((TextView) mPowerBookmarkShoppingItemRow.findViewById(R.id.description))
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTest.java index aa6d6052..00acf05b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTest.java
@@ -184,7 +184,6 @@ @Test @MediumTest @Feature({"Fullscreen"}) - @DisabledTest(message = "crbug.com/1282137") public void testDelayedPersistentFullscreen() { mActivityTestRule.startMainActivityWithURL(LONG_HTML_TEST_PAGE); @@ -216,7 +215,6 @@ @Test @LargeTest @Feature({"Fullscreen"}) - @DisabledTest(message = "crbug.com/1282137") public void testPersistentFullscreenChangingUiFlags() throws InterruptedException { // Exiting fullscreen via UI Flags is not supported in versions prior to MR2. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) return; @@ -542,7 +540,6 @@ @Test @LargeTest @Feature({"Fullscreen"}) - @DisabledTest(message = "crbug.com/1282137") public void testEnterPendingPersistentFullscreen() { FullscreenManagerTestUtils.disableBrowserOverrides(); mActivityTestRule.startMainActivityWithURL(LONG_FULLSCREEN_API_HTML_TEST_PAGE);
diff --git a/chrome/app/extensions_strings.grdp b/chrome/app/extensions_strings.grdp index eeffbea5..5a4a804 100644 --- a/chrome/app/extensions_strings.grdp +++ b/chrome/app/extensions_strings.grdp
@@ -277,18 +277,12 @@ <message name="IDS_EXTENSIONS_ITEM_SITE_ACCESS" desc="The label above the list of the websites that the extension can access."> Site access </message> - <message name="IDS_EXTENSIONS_ITEM_SITE_ACCESS_NEW" desc="The label of the button to click to view the list of websites that the extension can access."> - Site permissions - </message> <message name="IDS_EXTENSIONS_ITEM_SITE_ACCESS_ADD_HOST" desc="The label of the option to add a new site that the extension should be allowed to access."> Add a new page </message> <message name="IDS_EXTENSIONS_ITEM_SITE_ACCESS_EMPTY" desc="The text to indicate that an extension does not have any site access."> This extension has no additional site access. </message> - <message name="IDS_EXTENSIONS_ITEM_SITE_ACCESS_SUBLABEL" desc="The sublabel of the button to click to view the list of websites that the extension can access."> - Choose when this extension can read and change your site data - </message> <message name="IDS_EXTENSIONS_ITEM_SOURCE" desc="The label above an extension's source, which indicates where the extension came from (webstore, third-party, local disk, etc)."> Source </message>
diff --git a/chrome/app/extensions_strings_grdp/IDS_EXTENSIONS_ITEM_SITE_ACCESS_NEW.png.sha1 b/chrome/app/extensions_strings_grdp/IDS_EXTENSIONS_ITEM_SITE_ACCESS_NEW.png.sha1 deleted file mode 100644 index 203f3cb..0000000 --- a/chrome/app/extensions_strings_grdp/IDS_EXTENSIONS_ITEM_SITE_ACCESS_NEW.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -9d4f527dbd30b304e5468c804dde1f5d51911fc3 \ No newline at end of file
diff --git a/chrome/app/extensions_strings_grdp/IDS_EXTENSIONS_ITEM_SITE_ACCESS_SUBLABEL.png.sha1 b/chrome/app/extensions_strings_grdp/IDS_EXTENSIONS_ITEM_SITE_ACCESS_SUBLABEL.png.sha1 deleted file mode 100644 index 203f3cb..0000000 --- a/chrome/app/extensions_strings_grdp/IDS_EXTENSIONS_ITEM_SITE_ACCESS_SUBLABEL.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -9d4f527dbd30b304e5468c804dde1f5d51911fc3 \ No newline at end of file
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index ccdf7bee..b47217f 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -5107,8 +5107,7 @@ {"enable-web-authentication-cable-v2-support", flag_descriptions::kEnableWebAuthenticationCableV2SupportName, flag_descriptions::kEnableWebAuthenticationCableV2SupportDescription, - kOsDesktop | kOsAndroid, - FEATURE_VALUE_TYPE(device::kWebAuthCableSecondFactor)}, + kOsDesktop, FEATURE_VALUE_TYPE(device::kWebAuthPhoneSupport)}, #if BUILDFLAG(IS_CHROMEOS_ASH) {"enable-web-authentication-chromeos-authenticator", @@ -7502,7 +7501,12 @@ flag_descriptions::kU2FSecurityKeyAPIDescription, kOsAll, FEATURE_VALUE_TYPE(extensions_features::kU2FSecurityKeyAPI)}, #endif // ENABLE_EXTENSIONS - + {"force-major-version-to-minor", + flag_descriptions::kForceMajorVersionInMinorPositionInUserAgentName, + flag_descriptions::kForceMajorVersionInMinorPositionInUserAgentDescription, + kOsAll, + FEATURE_VALUE_TYPE( + blink::features::kForceMajorVersionInMinorPositionInUserAgent)}, {"force-major-version-to-100", flag_descriptions::kForceMajorVersion100InUserAgentName, flag_descriptions::kForceMajorVersion100InUserAgentDescription, kOsAll,
diff --git a/chrome/browser/android/autofill_assistant/assistant_collect_user_data_delegate.cc b/chrome/browser/android/autofill_assistant/assistant_collect_user_data_delegate.cc index 50fd175..8b1ea1faf 100644 --- a/chrome/browser/android/autofill_assistant/assistant_collect_user_data_delegate.cc +++ b/chrome/browser/android/autofill_assistant/assistant_collect_user_data_delegate.cc
@@ -13,8 +13,6 @@ #include "chrome/browser/android/autofill_assistant/ui_controller_android.h" #include "chrome/browser/android/autofill_assistant/ui_controller_android_utils.h" #include "chrome/browser/autofill/android/personal_data_manager_android.h" -#include "chrome/browser/autofill/personal_data_manager_factory.h" -#include "chrome/browser/profiles/profile_manager.h" #include "components/autofill/core/browser/autofill_data_util.h" using base::android::AttachCurrentThread;
diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.cc b/chrome/browser/android/autofill_assistant/ui_controller_android.cc index a63e256..e7b092ea 100644 --- a/chrome/browser/android/autofill_assistant/ui_controller_android.cc +++ b/chrome/browser/android/autofill_assistant/ui_controller_android.cc
@@ -34,10 +34,6 @@ #include "chrome/browser/android/autofill_assistant/generic_ui_root_controller_android.h" #include "chrome/browser/android/autofill_assistant/ui_controller_android_utils.h" #include "chrome/browser/autofill/android/personal_data_manager_android.h" -#include "chrome/browser/autofill/personal_data_manager_factory.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/signin/identity_manager_factory.h" #include "components/autofill/core/browser/data_model/autofill_profile.h" #include "components/autofill/core/browser/data_model/credit_card.h" #include "components/autofill_assistant/browser/bottom_sheet_state.h" @@ -51,8 +47,6 @@ #include "components/autofill_assistant/browser/user_data.h" #include "components/autofill_assistant/browser/user_data_util.h" #include "components/autofill_assistant/browser/user_model.h" -#include "components/signin/public/identity_manager/account_info.h" -#include "components/signin/public/identity_manager/identity_manager.h" #include "components/strings/grit/components_strings.h" #include "components/version_info/channel.h" #include "content/public/browser/browser_task_traits.h"
diff --git a/chrome/browser/ash/crostini/crostini_shelf_utils.cc b/chrome/browser/ash/crostini/crostini_shelf_utils.cc index c1dea43..8ba5b26 100644 --- a/chrome/browser/ash/crostini/crostini_shelf_utils.cc +++ b/chrome/browser/ash/crostini/crostini_shelf_utils.cc
@@ -61,7 +61,7 @@ enum class FindAppIdResult { NoMatch, UniqueMatch, NonUniqueMatch }; // Looks for an app where prefs_key is set to search_value. Returns the apps id // if there was only one app matching, otherwise returns an empty string. -FindAppIdResult FindAppId(const base::DictionaryValue* prefs, +FindAppIdResult FindAppId(const base::Value* prefs, base::StringPiece prefs_key, base::StringPiece search_value, std::string* result, @@ -142,8 +142,8 @@ std::string GetCrostiniShelfAppId(const Profile* profile, const std::string* window_app_id, const std::string* window_startup_id) { - const base::DictionaryValue* apps = &base::Value::AsDictionaryValue( - *profile->GetPrefs()->GetDictionary(guest_os::prefs::kGuestOsRegistry)); + const base::Value* apps = + profile->GetPrefs()->GetDictionary(guest_os::prefs::kGuestOsRegistry); std::string app_id; if (window_startup_id) {
diff --git a/chrome/browser/ash/external_protocol_dialog.cc b/chrome/browser/ash/external_protocol_dialog.cc index a023ff0..0f33ea95 100644 --- a/chrome/browser/ash/external_protocol_dialog.cc +++ b/chrome/browser/ash/external_protocol_dialog.cc
@@ -15,6 +15,7 @@ #include "chrome/grit/generated_resources.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" +#include "content/public/browser/weak_document_ptr.h" #include "content/public/browser/web_contents.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/text_elider.h" @@ -31,6 +32,7 @@ void OnArcHandled(const GURL& url, const absl::optional<url::Origin>& initiating_origin, + content::WeakDocumentPtr initiator_document, int render_process_host_id, int routing_id, bool handled) { @@ -50,7 +52,7 @@ if (registration) { new ExternalProtocolDialog(web_contents, url, base::UTF8ToUTF16(registration->Name()), - initiating_origin); + initiating_origin, initiator_document); } else { new ash::ExternalProtocolNoHandlersDialog(web_contents, url); } @@ -67,7 +69,8 @@ WebContents* web_contents, ui::PageTransition page_transition, bool has_user_gesture, - const absl::optional<url::Origin>& initiating_origin) { + const absl::optional<url::Origin>& initiating_origin, + content::WeakDocumentPtr initiator_document) { // First, check if ARC version of the dialog is available and run ARC version // when possible. // TODO(ellyjones): Refactor arc::RunArcExternalProtocolDialog() to take a @@ -80,7 +83,8 @@ url, initiating_origin, render_process_host_id, routing_id, page_transition, has_user_gesture, base::BindOnce(&OnArcHandled, url, initiating_origin, - render_process_host_id, routing_id)); + std::move(initiator_document), render_process_host_id, + routing_id)); } namespace ash {
diff --git a/chrome/browser/ash/login/quick_unlock/fingerprint_storage.cc b/chrome/browser/ash/login/quick_unlock/fingerprint_storage.cc index 934bac01..0cec6d7 100644 --- a/chrome/browser/ash/login/quick_unlock/fingerprint_storage.cc +++ b/chrome/browser/ash/login/quick_unlock/fingerprint_storage.cc
@@ -125,8 +125,7 @@ msg->get_scan_result()); return; case device::mojom::FingerprintMessage::Tag::kFingerprintError: - base::UmaHistogramEnumeration("Fingerprint.Auth.Error", - msg->get_fingerprint_error()); + // TODO(issuetracker.google.com/184843581): Add metrics for errors. return; } NOTREACHED();
diff --git a/chrome/browser/ash/login/quick_unlock/fingerprint_storage_unittest.cc b/chrome/browser/ash/login/quick_unlock/fingerprint_storage_unittest.cc index 7972296e..0c5fef8 100644 --- a/chrome/browser/ash/login/quick_unlock/fingerprint_storage_unittest.cc +++ b/chrome/browser/ash/login/quick_unlock/fingerprint_storage_unittest.cc
@@ -24,7 +24,6 @@ namespace { const char* kUmaAuthScanResult = "Fingerprint.Auth.ScanResult"; -const char* kUmaAuthError = "Fingerprint.Auth.Error"; class FingerprintStorageUnitTest : public testing::Test { public: @@ -137,29 +136,6 @@ histogram_tester.GetAllSamples(kUmaAuthScanResult), ElementsAre(base::Bucket( static_cast<int>(device::mojom::ScanResult::SUCCESS), /*count=*/1))); - - EXPECT_TRUE(histogram_tester.GetAllSamples(kUmaAuthError).empty()); -} - -TEST_F(FingerprintStorageUnitTest, TestFingerprintErrorIsSentToUma) { - FingerprintStorage* fingerprint_storage = - QuickUnlockFactory::GetForProfile(profile_.get())->fingerprint_storage(); - base::HistogramTester histogram_tester; - base::flat_map<std::string, std::vector<std::string>> empty_matches; - device::mojom::FingerprintMessagePtr msg = - device::mojom::FingerprintMessage::New(); - - msg->set_fingerprint_error( - device::mojom::FingerprintError::UNABLE_TO_PROCESS); - fingerprint_storage->OnAuthScanDone(std::move(msg), empty_matches); - - EXPECT_TRUE(histogram_tester.GetAllSamples(kUmaAuthScanResult).empty()); - - EXPECT_THAT( - histogram_tester.GetAllSamples(kUmaAuthError), - ElementsAre(base::Bucket( - static_cast<int>(device::mojom::FingerprintError::UNABLE_TO_PROCESS), - /*count=*/1))); } } // namespace quick_unlock
diff --git a/chrome/browser/ash/policy/dlp/dlp_content_manager_ash.h b/chrome/browser/ash/policy/dlp/dlp_content_manager_ash.h index 0f4b8824..85e462da 100644 --- a/chrome/browser/ash/policy/dlp/dlp_content_manager_ash.h +++ b/chrome/browser/ash/policy/dlp/dlp_content_manager_ash.h
@@ -308,9 +308,6 @@ // List of the currently running screen shares. std::vector<ScreenShareInfo> running_screen_shares_; - - // TODO(https://crbug.com/1278733): Remove this flag - const bool is_screen_share_warning_mode_enabled_ = false; }; // Helper class to call SetDlpContentManagerAshForTesting and
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/metric_reporting_manager_unittest.cc b/chrome/browser/ash/policy/reporting/metrics_reporting/metric_reporting_manager_unittest.cc index 9c48203..560c459 100644 --- a/chrome/browser/ash/policy/reporting/metrics_reporting/metric_reporting_manager_unittest.cc +++ b/chrome/browser/ash/policy/reporting/metrics_reporting/metric_reporting_manager_unittest.cc
@@ -16,6 +16,7 @@ #include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "base/time/time.h" +#include "base/values.h" #include "chrome/browser/ash/settings/device_settings_service.h" #include "chrome/browser/ash/settings/scoped_testing_cros_settings.h" #include "chrome/browser/ash/settings/stub_cros_settings_provider.h" @@ -158,9 +159,22 @@ ::ash::kReportDeviceNetworkTelemetryEventCheckingRateMs, kNetworkHealthRateMs); - network_handler_test_helper_.device_test()->ClearDevices(); - network_handler_test_helper_.device_test()->AddDevice( - "ethernet/path", shill::kTypeEthernet, "ethernet"); + const std::string kEthernetPath = "ethernet/path"; + const std::string kProfilePath = "/profile/path"; + network_handler_test_helper_.profile_test()->AddProfile(kProfilePath, + "user_hash"); + auto* const device_client = network_handler_test_helper_.device_test(); + auto* const service_client = network_handler_test_helper_.service_test(); + base::RunLoop().RunUntilIdle(); + + device_client->ClearDevices(); + service_client->ClearServices(); + device_client->AddDevice(kEthernetPath, shill::kTypeEthernet, "ethernet"); + service_client->AddService(kEthernetPath, "guid", "name", + shill::kTypeEthernet, shill::kStateOnline, + /*is_visible=*/true); + service_client->SetServiceProperty(kEthernetPath, shill::kProfileProperty, + base::Value(kProfilePath)); base::RunLoop().RunUntilIdle(); } @@ -223,6 +237,11 @@ ->set_verdict(test_case.latency_verdict); https_latency_sampler->SetMetricData(std::move(https_latency_data)); fake_delegate->SetHttpsLatencySampler(std::move(https_latency_sampler)); + + int info_report_count = 0; + int telemetry_report_count = 0; + int telemetry_flush_count = 0; + int event_report_count = 0; auto info_queue = std::unique_ptr<MockReportQueue, base::OnTaskRunnerDeleter>( new ::testing::NiceMock<MockReportQueue>(), base::OnTaskRunnerDeleter(task_runner_)); @@ -234,45 +253,57 @@ std::unique_ptr<MockReportQueue, base::OnTaskRunnerDeleter>( new ::testing::NiceMock<MockReportQueue>(), base::OnTaskRunnerDeleter(task_runner_)); - auto* const info_queue_ptr = info_queue.get(); - auto* const telemetry_queue_ptr = telemetry_queue.get(); - auto* const event_queue_ptr = event_queue.get(); + ON_CALL(*info_queue, AddRecord).WillByDefault([&]() { ++info_report_count; }); + ON_CALL(*telemetry_queue, AddRecord).WillByDefault([&]() { + ++telemetry_report_count; + }); + ON_CALL(*telemetry_queue, Flush).WillByDefault([&]() { + ++telemetry_flush_count; + }); + ON_CALL(*event_queue, AddRecord).WillByDefault([&]() { + ++event_report_count; + }); fake_delegate->SetInfoQueue(std::move(info_queue)); fake_delegate->SetTelemetryQueue(std::move(telemetry_queue)); fake_delegate->SetEventQueue(std::move(event_queue)); - EXPECT_CALL(*info_queue_ptr, AddRecord).Times(test_case.expected_info_count); auto metric_reporting_manager = MetricReportingManager::CreateForTesting( std::move(fake_delegate), nullptr); + base::RunLoop run_loop; + base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, + run_loop.QuitClosure()); + run_loop.Run(); + EXPECT_EQ(info_report_count, test_case.expected_info_count); - EXPECT_CALL(*telemetry_queue_ptr, AddRecord).Times(0); - EXPECT_CALL(*telemetry_queue_ptr, Flush) - .Times(test_case.expected_flush_per_period); - EXPECT_CALL(*event_queue_ptr, AddRecord).Times(0); task_environment_.FastForwardBy(base::Milliseconds(kNetworkHealthRateMs)); + EXPECT_EQ(telemetry_report_count, 0); + EXPECT_EQ(telemetry_flush_count, test_case.expected_flush_per_period); + EXPECT_EQ(event_report_count, 0); metric_reporting_manager->OnLogin(nullptr); - EXPECT_CALL(*telemetry_queue_ptr, AddRecord) - .Times(test_case.expected_telemetry_count); - EXPECT_CALL(*telemetry_queue_ptr, Flush) - .Times(test_case.expected_flush_per_period); - EXPECT_CALL(*event_queue_ptr, AddRecord) - .Times(test_case.expected_event_count); + // Reset flush count. + telemetry_flush_count = 0; task_environment_.FastForwardBy(base::Milliseconds(kNetworkHealthRateMs)); + EXPECT_EQ(telemetry_report_count, test_case.expected_telemetry_count); + EXPECT_EQ(telemetry_flush_count, test_case.expected_flush_per_period); + EXPECT_EQ(event_report_count, test_case.expected_event_count); fake_delegate_ptr->SetIsDeprovisioned(true); metric_reporting_manager->DeviceSettingsUpdated(); - // Device is deprovisioned, so no reporting. - EXPECT_CALL(*telemetry_queue_ptr, AddRecord).Times(0); - EXPECT_CALL(*telemetry_queue_ptr, Flush).Times(0); - EXPECT_CALL(*event_queue_ptr, AddRecord).Times(0); + // Device is deprovisioned, so no reporting, reset all counts. + telemetry_report_count = 0; + telemetry_flush_count = 0; + event_report_count = 0; task_environment_.FastForwardBy(base::Milliseconds(kNetworkHealthRateMs)); + EXPECT_EQ(telemetry_report_count, 0); + EXPECT_EQ(telemetry_flush_count, 0); + EXPECT_EQ(event_report_count, 0); } -TEST_F(NetworkHealthReportingTest, NetworkEventsOvserver) { +TEST_F(NetworkHealthReportingTest, NetworkEventsObserver) { scoped_testing_cros_settings_.device_settings()->SetBoolean( ::ash::kReportDeviceNetworkStatus, true); @@ -282,23 +313,28 @@ auto fake_delegate = std::make_unique<FakeDelegate>(); fake_delegate->SetIsAffiliated(true); + + int event_reported_count = 0; auto event_queue = std::unique_ptr<MockReportQueue, base::OnTaskRunnerDeleter>( new ::testing::NiceMock<MockReportQueue>(), base::OnTaskRunnerDeleter(task_runner_)); - auto* const event_queue_ptr = event_queue.get(); + ON_CALL(*event_queue, AddRecord).WillByDefault([&]() { + ++event_reported_count; + }); fake_delegate->SetEventQueue(std::move(event_queue)); auto metric_reporting_manager = MetricReportingManager::CreateForTesting( std::move(fake_delegate), nullptr); metric_reporting_manager->OnLogin(nullptr); - EXPECT_CALL(*event_queue_ptr, AddRecord).Times(1); base::RunLoop run_loop; EmitSignalStrengthEvent(); base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, run_loop.QuitClosure()); run_loop.Run(); + + EXPECT_EQ(event_reported_count, 1); } INSTANTIATE_TEST_SUITE_P(
diff --git a/chrome/browser/ash/printing/calculators_policies_binder.cc b/chrome/browser/ash/printing/calculators_policies_binder.cc index 486b6158..e7732c9 100644 --- a/chrome/browser/ash/printing/calculators_policies_binder.cc +++ b/chrome/browser/ash/printing/calculators_policies_binder.cc
@@ -35,9 +35,9 @@ return BulkPrintersCalculator::ALL_ACCESS; } -std::vector<std::string> ConvertToVector(const base::ListValue* list) { +std::vector<std::string> ConvertToVector(const base::Value* list) { std::vector<std::string> string_list; - if (!list) { + if (!list || !list->is_list()) { return string_list; } @@ -72,7 +72,7 @@ } std::vector<std::string> GetStringList(const char* name) const override { - return ConvertToVector(&base::Value::AsListValue(*prefs_->GetList(name))); + return ConvertToVector(prefs_->GetList(name)); } private:
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 76de414..bc79850 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -269,6 +269,7 @@ #include "content/public/browser/tts_platform.h" #include "content/public/browser/url_loader_request_interceptor.h" #include "content/public/browser/vpn_service_proxy.h" +#include "content/public/browser/weak_document_ptr.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_delegate.h" #include "content/public/browser/web_ui_url_loader_factory.h" @@ -1067,7 +1068,8 @@ bool is_main_frame, network::mojom::WebSandboxFlags sandbox_flags, bool has_user_gesture, - const absl::optional<url::Origin>& initiating_origin) { + const absl::optional<url::Origin>& initiating_origin, + content::WeakDocumentPtr initiator_document) { // If there is no longer a WebContents, the request may have raced with tab // closing. Don't fire the external request. (It may have been a prerender.) content::WebContents* web_contents = web_contents_getter.Run(); @@ -1153,11 +1155,12 @@ // without any additional security checks. Since the URL is allowlisted, // we assume it can be executed. if (is_allowlisted) { - ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck(url, web_contents); + ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck( + url, web_contents, std::move(initiator_document)); } else { - ExternalProtocolHandler::LaunchUrl(url, std::move(web_contents_getter), - page_transition, has_user_gesture, - initiating_origin); + ExternalProtocolHandler::LaunchUrl( + url, std::move(web_contents_getter), page_transition, has_user_gesture, + initiating_origin, std::move(initiator_document)); } } @@ -5507,6 +5510,7 @@ ui::PageTransition page_transition, bool has_user_gesture, const absl::optional<url::Origin>& initiating_origin, + content::RenderFrameHost* initiator_document, mojo::PendingRemote<network::mojom::URLLoaderFactory>* out_factory) { #if BUILDFLAG(ENABLE_EXTENSIONS) // External protocols are disabled for guests. An exception is made for the @@ -5529,11 +5533,16 @@ return false; #endif // defined(ANDROID) + auto weak_initiator_document = initiator_document + ? initiator_document->GetWeakDocumentPtr() + : content::WeakDocumentPtr(); + content::GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(&LaunchURL, weak_factory_.GetWeakPtr(), url, - std::move(web_contents_getter), page_transition, - is_main_frame, sandbox_flags, has_user_gesture, - initiating_origin)); + FROM_HERE, + base::BindOnce(&LaunchURL, weak_factory_.GetWeakPtr(), url, + std::move(web_contents_getter), page_transition, + is_main_frame, sandbox_flags, has_user_gesture, + initiating_origin, std::move(weak_initiator_document))); return true; }
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index b5b7ba4f3..3a8f7cf2 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -614,6 +614,7 @@ ui::PageTransition page_transition, bool has_user_gesture, const absl::optional<url::Origin>& initiating_origin, + content::RenderFrameHost* initiator_document, mojo::PendingRemote<network::mojom::URLLoaderFactory>* out_factory) override; std::unique_ptr<content::OverlayWindow> CreateWindowForPictureInPicture(
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_content_manager.cc b/chrome/browser/chromeos/policy/dlp/dlp_content_manager.cc index e9961c7..8086d85 100644 --- a/chrome/browser/chromeos/policy/dlp/dlp_content_manager.cc +++ b/chrome/browser/chromeos/policy/dlp/dlp_content_manager.cc
@@ -227,7 +227,7 @@ std::move(callback).Run(false); return; } - if (IsWarn(info.restriction_info)) { + if (is_screen_share_warning_mode_enabled_ && IsWarn(info.restriction_info)) { // Check which of the contents were already allowed and don't warn for // those. RemoveAllowedContents(info.confidential_contents,
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_content_manager.h b/chrome/browser/chromeos/policy/dlp/dlp_content_manager.h index 55797b95e..2921239 100644 --- a/chrome/browser/chromeos/policy/dlp/dlp_content_manager.h +++ b/chrome/browser/chromeos/policy/dlp/dlp_content_manager.h
@@ -154,6 +154,9 @@ DlpReportingManager* reporting_manager_; std::unique_ptr<DlpWarnNotifier> warn_notifier_; + + // TODO(https://crbug.com/1278733): Remove this flag + const bool is_screen_share_warning_mode_enabled_ = false; }; } // namespace policy
diff --git a/chrome/browser/devtools/devtools_browsertest.cc b/chrome/browser/devtools/devtools_browsertest.cc index 36cfae0..5616953 100644 --- a/chrome/browser/devtools/devtools_browsertest.cc +++ b/chrome/browser/devtools/devtools_browsertest.cc
@@ -1891,9 +1891,9 @@ std::string("window.location = \"") + url.spec() + "\"")); observer.Wait(); - ASSERT_TRUE(main_web_contents()->GetURL(). - SchemeIs(content::kChromeDevToolsScheme)); - ASSERT_EQ(url, GetInspectedTab()->GetURL()); + ASSERT_TRUE(main_web_contents()->GetLastCommittedURL().SchemeIs( + content::kChromeDevToolsScheme)); + ASSERT_EQ(url, GetInspectedTab()->GetLastCommittedURL()); CloseDevToolsWindow(); }
diff --git a/chrome/browser/devtools/devtools_file_helper.cc b/chrome/browser/devtools/devtools_file_helper.cc index 1ec973e9..8ffee4fb 100644 --- a/chrome/browser/devtools/devtools_file_helper.cc +++ b/chrome/browser/devtools/devtools_file_helper.cc
@@ -154,7 +154,8 @@ std::string RegisterFileSystem(WebContents* web_contents, const base::FilePath& path) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - CHECK(web_contents->GetURL().SchemeIs(content::kChromeDevToolsScheme)); + CHECK(web_contents->GetLastCommittedURL().SchemeIs( + content::kChromeDevToolsScheme)); std::string root_name(kRootName); storage::IsolatedContext::ScopedFSHandle file_system = isolated_context()->RegisterFileSystemForPath( @@ -183,7 +184,8 @@ const std::string& type, const std::string& file_system_id, const std::string& file_system_path) { - const GURL origin = web_contents->GetURL().DeprecatedGetOriginAsURL(); + const GURL origin = + web_contents->GetLastCommittedURL().DeprecatedGetOriginAsURL(); std::string file_system_name = storage::GetIsolatedFileSystemName(origin, file_system_id); std::string root_url = storage::GetIsolatedFileSystemRootURIString(
diff --git a/chrome/browser/devtools/devtools_ui_bindings.cc b/chrome/browser/devtools/devtools_ui_bindings.cc index 7c61157..c6cce2f8 100644 --- a/chrome/browser/devtools/devtools_ui_bindings.cc +++ b/chrome/browser/devtools/devtools_ui_bindings.cc
@@ -898,14 +898,14 @@ // committed URL of that frame, and use the loader associated with that // frame to allow nested frames with different schemes to load files. if (allow_web_ui_scheme && target_tab && - target_tab->GetURL().scheme() == gurl.scheme()) { + target_tab->GetLastCommittedURL().scheme() == gurl.scheme()) { std::vector<std::string> allowed_webui_hosts; content::RenderFrameHost* frame_host = web_contents()->GetMainFrame(); mojo::PendingRemote<network::mojom::URLLoaderFactory> pending_remote = - content::CreateWebUIURLLoaderFactory(frame_host, - target_tab->GetURL().scheme(), - std::move(allowed_webui_hosts)); + content::CreateWebUIURLLoaderFactory( + frame_host, target_tab->GetLastCommittedURL().scheme(), + std::move(allowed_webui_hosts)); url_loader_factory = network::SharedURLLoaderFactory::Create( std::make_unique<network::WrapperPendingSharedURLLoaderFactory>( std::move(pending_remote))); @@ -941,7 +941,8 @@ } void DevToolsUIBindings::ShowItemInFolder(const std::string& file_system_path) { - CHECK(IsValidFrontendURL(web_contents_->GetURL()) && frontend_host_); + CHECK(IsValidFrontendURL(web_contents_->GetLastCommittedURL()) && + frontend_host_); file_helper_->ShowItemInFolder(file_system_path); } @@ -963,7 +964,8 @@ } void DevToolsUIBindings::RequestFileSystems() { - CHECK(IsValidFrontendURL(web_contents_->GetURL()) && frontend_host_); + CHECK(IsValidFrontendURL(web_contents_->GetLastCommittedURL()) && + frontend_host_); base::ListValue file_systems_value; for (auto const& file_system : file_helper_->GetFileSystems()) file_systems_value.Append(CreateFileSystemValue(file_system)); @@ -972,20 +974,23 @@ } void DevToolsUIBindings::AddFileSystem(const std::string& type) { - CHECK(IsValidFrontendURL(web_contents_->GetURL()) && frontend_host_); + CHECK(IsValidFrontendURL(web_contents_->GetLastCommittedURL()) && + frontend_host_); file_helper_->AddFileSystem( type, base::BindRepeating(&DevToolsUIBindings::ShowDevToolsInfoBar, weak_factory_.GetWeakPtr())); } void DevToolsUIBindings::RemoveFileSystem(const std::string& file_system_path) { - CHECK(IsValidFrontendURL(web_contents_->GetURL()) && frontend_host_); + CHECK(IsValidFrontendURL(web_contents_->GetLastCommittedURL()) && + frontend_host_); file_helper_->RemoveFileSystem(file_system_path); } void DevToolsUIBindings::UpgradeDraggedFileSystemPermissions( const std::string& file_system_url) { - CHECK(IsValidFrontendURL(web_contents_->GetURL()) && frontend_host_); + CHECK(IsValidFrontendURL(web_contents_->GetLastCommittedURL()) && + frontend_host_); file_helper_->UpgradeDraggedFileSystemPermissions( file_system_url, base::BindRepeating(&DevToolsUIBindings::ShowDevToolsInfoBar, @@ -997,7 +1002,8 @@ const std::string& file_system_path, const std::string& excluded_folders_message) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - CHECK(IsValidFrontendURL(web_contents_->GetURL()) && frontend_host_); + CHECK(IsValidFrontendURL(web_contents_->GetLastCommittedURL()) && + frontend_host_); if (!file_helper_->IsFileSystemAdded(file_system_path)) { IndexingDone(index_request_id, file_system_path); return; @@ -1042,7 +1048,8 @@ const std::string& file_system_path, const std::string& query) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - CHECK(IsValidFrontendURL(web_contents_->GetURL()) && frontend_host_); + CHECK(IsValidFrontendURL(web_contents_->GetLastCommittedURL()) && + frontend_host_); if (!file_helper_->IsFileSystemAdded(file_system_path)) { SearchCompleted(search_request_id, file_system_path,
diff --git a/chrome/browser/extensions/api/browsing_data/browsing_data_api.cc b/chrome/browser/extensions/api/browsing_data/browsing_data_api.cc index 36c6966..c2e39e7 100644 --- a/chrome/browser/extensions/api/browsing_data/browsing_data_api.cc +++ b/chrome/browser/extensions/api/browsing_data/browsing_data_api.cc
@@ -161,16 +161,15 @@ // REMOVE_SITE_DATA in browsing_data_remover.h, the former for the unprotected // web, the latter for protected web data. There is no UI control for // extension data. - std::unique_ptr<base::DictionaryValue> origin_types( - new base::DictionaryValue); - origin_types->SetBoolean( + base::Value origin_types(base::Value::Type::DICTIONARY); + origin_types.SetBoolKey( extension_browsing_data_api_constants::kUnprotectedWebKey, isDataTypeSelected(BrowsingDataType::COOKIES, tab)); - origin_types->SetBoolean( + origin_types.SetBoolKey( extension_browsing_data_api_constants::kProtectedWebKey, isDataTypeSelected(BrowsingDataType::HOSTED_APPS_DATA, tab)); - origin_types->SetBoolean( - extension_browsing_data_api_constants::kExtensionsKey, false); + origin_types.SetBoolKey(extension_browsing_data_api_constants::kExtensionsKey, + false); // Fill deletion time period. int period_pref = @@ -184,80 +183,77 @@ since = time.ToJsTime(); } - std::unique_ptr<base::DictionaryValue> options(new base::DictionaryValue); - options->Set(extension_browsing_data_api_constants::kOriginTypesKey, - std::move(origin_types)); - options->SetDoubleKey(extension_browsing_data_api_constants::kSinceKey, - since); + base::Value options(base::Value::Type::DICTIONARY); + options.SetKey(extension_browsing_data_api_constants::kOriginTypesKey, + std::move(origin_types)); + options.SetDoubleKey(extension_browsing_data_api_constants::kSinceKey, since); // Fill dataToRemove and dataRemovalPermitted. - std::unique_ptr<base::DictionaryValue> selected(new base::DictionaryValue); - std::unique_ptr<base::DictionaryValue> permitted(new base::DictionaryValue); + base::Value selected(base::Value::Type::DICTIONARY); + base::Value permitted(base::Value::Type::DICTIONARY); bool delete_site_data = isDataTypeSelected(BrowsingDataType::COOKIES, tab) || isDataTypeSelected(BrowsingDataType::HOSTED_APPS_DATA, tab); - SetDetails(selected.get(), permitted.get(), + SetDetails(&selected, &permitted, extension_browsing_data_api_constants::kCookiesKey, delete_site_data); - SetDetails(selected.get(), permitted.get(), + SetDetails(&selected, &permitted, extension_browsing_data_api_constants::kFileSystemsKey, delete_site_data); - SetDetails(selected.get(), permitted.get(), + SetDetails(&selected, &permitted, extension_browsing_data_api_constants::kIndexedDBKey, delete_site_data); - SetDetails(selected.get(), permitted.get(), - extension_browsing_data_api_constants::kLocalStorageKey, - delete_site_data); - SetDetails(selected.get(), permitted.get(), + SetDetails(&selected, &permitted, + extension_browsing_data_api_constants::kLocalStorageKey, + delete_site_data); + SetDetails(&selected, &permitted, extension_browsing_data_api_constants::kWebSQLKey, delete_site_data); - SetDetails(selected.get(), permitted.get(), + SetDetails(&selected, &permitted, extension_browsing_data_api_constants::kServiceWorkersKey, delete_site_data); - SetDetails(selected.get(), permitted.get(), + SetDetails(&selected, &permitted, extension_browsing_data_api_constants::kCacheStorageKey, delete_site_data); // PluginData is not supported anymore. (crbug.com/1135791) - SetDetails(selected.get(), permitted.get(), + SetDetails(&selected, &permitted, extension_browsing_data_api_constants::kPluginDataKeyDeprecated, false); - SetDetails(selected.get(), permitted.get(), + SetDetails(&selected, &permitted, extension_browsing_data_api_constants::kHistoryKey, isDataTypeSelected(BrowsingDataType::HISTORY, tab)); - SetDetails(selected.get(), permitted.get(), + SetDetails(&selected, &permitted, extension_browsing_data_api_constants::kDownloadsKey, isDataTypeSelected(BrowsingDataType::DOWNLOADS, tab)); - SetDetails(selected.get(), permitted.get(), + SetDetails(&selected, &permitted, extension_browsing_data_api_constants::kCacheKey, isDataTypeSelected(BrowsingDataType::CACHE, tab)); - SetDetails(selected.get(), permitted.get(), + SetDetails(&selected, &permitted, extension_browsing_data_api_constants::kFormDataKey, isDataTypeSelected(BrowsingDataType::FORM_DATA, tab)); - SetDetails(selected.get(), permitted.get(), + SetDetails(&selected, &permitted, extension_browsing_data_api_constants::kPasswordsKey, isDataTypeSelected(BrowsingDataType::PASSWORDS, tab)); - std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue); - result->Set(extension_browsing_data_api_constants::kOptionsKey, - std::move(options)); - result->Set(extension_browsing_data_api_constants::kDataToRemoveKey, - std::move(selected)); - result->Set(extension_browsing_data_api_constants::kDataRemovalPermittedKey, - std::move(permitted)); - return RespondNow( - OneArgument(base::Value::FromUniquePtrValue(std::move(result)))); + base::Value result(base::Value::Type::DICTIONARY); + result.SetKey(extension_browsing_data_api_constants::kOptionsKey, + std::move(options)); + result.SetKey(extension_browsing_data_api_constants::kDataToRemoveKey, + std::move(selected)); + result.SetKey(extension_browsing_data_api_constants::kDataRemovalPermittedKey, + std::move(permitted)); + return RespondNow(OneArgument(std::move(result))); } -void BrowsingDataSettingsFunction::SetDetails( - base::DictionaryValue* selected_dict, - base::DictionaryValue* permitted_dict, - const char* data_type, - bool is_selected) { +void BrowsingDataSettingsFunction::SetDetails(base::Value* selected_dict, + base::Value* permitted_dict, + const char* data_type, + bool is_selected) { bool is_permitted = IsRemovalPermitted(MaskForKey(data_type), prefs_); - selected_dict->SetBoolean(data_type, is_selected && is_permitted); - permitted_dict->SetBoolean(data_type, is_permitted); + selected_dict->SetBoolKey(data_type, is_selected && is_permitted); + permitted_dict->SetBoolKey(data_type, is_permitted); } BrowsingDataRemoverFunction::BrowsingDataRemoverFunction() = default; @@ -303,11 +299,9 @@ EXTENSION_FUNCTION_VALIDATE(GetRemovalMask(&removal_mask_)); const base::Value* origins = - options.FindKeyOfType(extension_browsing_data_api_constants::kOriginsKey, - base::Value::Type::LIST); - const base::Value* exclude_origins = options.FindKeyOfType( - extension_browsing_data_api_constants::kExcludeOriginsKey, - base::Value::Type::LIST); + options.FindListKey(extension_browsing_data_api_constants::kOriginsKey); + const base::Value* exclude_origins = options.FindListKey( + extension_browsing_data_api_constants::kExcludeOriginsKey); // Check that only |origins| or |excludeOrigins| can be set. if (origins && exclude_origins) {
diff --git a/chrome/browser/extensions/api/browsing_data/browsing_data_api.h b/chrome/browser/extensions/api/browsing_data/browsing_data_api.h index 8f7bfc6e..241d641 100644 --- a/chrome/browser/extensions/api/browsing_data/browsing_data_api.h +++ b/chrome/browser/extensions/api/browsing_data/browsing_data_api.h
@@ -75,8 +75,8 @@ // indicating whether the data type is both selected and permitted to be // removed; and a value in the |permitted_dict| with the |data_type| as a // key, indicating only whether the data type is permitted to be removed. - void SetDetails(base::DictionaryValue* selected_dict, - base::DictionaryValue* permitted_dict, + void SetDetails(base::Value* selected_dict, + base::Value* permitted_dict, const char* data_type, bool is_selected);
diff --git a/chrome/browser/extensions/api/browsing_data/browsing_data_unittest.cc b/chrome/browser/extensions/api/browsing_data/browsing_data_unittest.cc index d4c4494..c282cf47 100644 --- a/chrome/browser/extensions/api/browsing_data/browsing_data_unittest.cc +++ b/chrome/browser/extensions/api/browsing_data/browsing_data_unittest.cc
@@ -82,12 +82,11 @@ return remover_->GetLastUsedOriginTypeMaskForTesting(); } - uint64_t GetAsMask(const base::DictionaryValue* dict, + uint64_t GetAsMask(const base::Value* dict, std::string path, uint64_t mask_value) { - absl::optional<bool> result = dict->FindBoolPath(path); - EXPECT_TRUE(result.has_value()) << "for " << path; - return result.value() ? mask_value : 0; + EXPECT_TRUE(dict->FindBoolKey(path)); + return *dict->FindBoolKey(path) ? mask_value : 0; } void RunBrowsingDataRemoveFunctionAndCompareRemovalMask( @@ -142,15 +141,12 @@ scoped_refptr<BrowsingDataSettingsFunction> function = new BrowsingDataSettingsFunction(); SCOPED_TRACE("settings"); - std::unique_ptr<base::Value> result_value(RunFunctionAndReturnSingleResult( - function.get(), std::string("[]"), browser())); + std::unique_ptr<base::Value> result = RunFunctionAndReturnSingleResult( + function.get(), std::string("[]"), browser()); - base::DictionaryValue* result; - EXPECT_TRUE(result_value->GetAsDictionary(&result)); - base::DictionaryValue* options; - EXPECT_TRUE(result->GetDictionary("options", &options)); - absl::optional<double> since = options->FindDoubleKey("since"); - ASSERT_TRUE(since); + EXPECT_TRUE(result->is_dict()); + EXPECT_TRUE(result->FindDoublePath("options.since")); + double since = *result->FindDoublePath("options.since"); double expected_since = 0; if (since_pref != browsing_data::TimePeriod::ALL_TIME) { @@ -162,7 +158,7 @@ // second, so we'll make sure the requested start time is within 10 seconds. // Since the smallest selectable period is an hour, that should be // sufficient. - EXPECT_LE(expected_since, *since + 10.0 * 1000.0); + EXPECT_LE(expected_since, since + 10.0 * 1000.0); } void SetPrefsAndVerifySettings(int data_type_flags, @@ -229,24 +225,21 @@ scoped_refptr<BrowsingDataSettingsFunction> function = new BrowsingDataSettingsFunction(); SCOPED_TRACE("settings"); - std::unique_ptr<base::Value> result_value(RunFunctionAndReturnSingleResult( + std::unique_ptr<base::Value> result(RunFunctionAndReturnSingleResult( function.get(), std::string("[]"), browser())); - base::DictionaryValue* result; - EXPECT_TRUE(result_value->GetAsDictionary(&result)); + EXPECT_TRUE(result->is_dict()); - base::DictionaryValue* options; - EXPECT_TRUE(result->GetDictionary("options", &options)); - base::DictionaryValue* origin_types; - EXPECT_TRUE(options->GetDictionary("originTypes", &origin_types)); + base::Value* origin_types = result->FindDictPath("options.originTypes"); + EXPECT_TRUE(origin_types); uint64_t origin_type_mask = GetAsMask(origin_types, "unprotectedWeb", UNPROTECTED_WEB) | GetAsMask(origin_types, "protectedWeb", PROTECTED_WEB) | GetAsMask(origin_types, "extension", EXTENSION); EXPECT_EQ(expected_origin_type_mask, origin_type_mask); - base::DictionaryValue* data_to_remove; - EXPECT_TRUE(result->GetDictionary("dataToRemove", &data_to_remove)); + base::Value* data_to_remove = result->FindDictKey("dataToRemove"); + EXPECT_TRUE(data_to_remove); uint64_t removal_mask = GetAsMask(data_to_remove, "cache", content::BrowsingDataRemover::DATA_TYPE_CACHE) | @@ -471,13 +464,12 @@ scoped_refptr<BrowsingDataSettingsFunction> settings_function = new BrowsingDataSettingsFunction(); SCOPED_TRACE("settings_json"); - std::unique_ptr<base::Value> result_value(RunFunctionAndReturnSingleResult( + std::unique_ptr<base::Value> result(RunFunctionAndReturnSingleResult( settings_function.get(), std::string("[]"), browser())); - base::DictionaryValue* result; - EXPECT_TRUE(result_value->GetAsDictionary(&result)); - base::DictionaryValue* data_to_remove; - EXPECT_TRUE(result->GetDictionary("dataToRemove", &data_to_remove)); + EXPECT_TRUE(result->is_dict()); + base::Value* data_to_remove = result->FindDictKey("dataToRemove"); + EXPECT_TRUE(data_to_remove); JSONStringValueSerializer serializer(&json); EXPECT_TRUE(serializer.Serialize(*data_to_remove));
diff --git a/chrome/browser/external_protocol/external_protocol_handler.cc b/chrome/browser/external_protocol/external_protocol_handler.cc index 16e07067..1681c8e 100644 --- a/chrome/browser/external_protocol/external_protocol_handler.cc +++ b/chrome/browser/external_protocol/external_protocol_handler.cc
@@ -25,7 +25,7 @@ #include "components/prefs/scoped_user_pref_update.h" #include "components/url_matcher/url_matcher.h" #include "content/public/browser/browser_thread.h" -#include "content/public/browser/web_contents.h" +#include "content/public/browser/weak_document_ptr.h" #include "net/base/escape.h" #include "services/network/public/cpp/is_potentially_trustworthy.h" #include "third_party/blink/public/mojom/devtools/console_message.mojom.h" @@ -85,6 +85,13 @@ "mailto", "news", "snews", }; +void AddMessageToConsole(const content::WeakDocumentPtr& document, + blink::mojom::ConsoleMessageLevel level, + const std::string& message) { + if (content::RenderFrameHost* rfh = document.AsRenderFrameHostIfValid()) + rfh->AddMessageToConsole(level, message); +} + // Functions enabling unit testing. Using a NULL delegate will use the default // behavior; if a delegate is provided it will be used instead. scoped_refptr<shell_integration::DefaultProtocolClientWorker> CreateShellWorker( @@ -113,6 +120,7 @@ ui::PageTransition page_transition, bool has_user_gesture, const absl::optional<url::Origin>& initiating_origin, + content::WeakDocumentPtr initiator_document, ExternalProtocolHandler::Delegate* delegate) { DCHECK(web_contents); if (delegate) { @@ -125,8 +133,8 @@ // If the Shell does not have a registered name for the protocol, // attempting to invoke the protocol will fail. if (shell_integration::GetApplicationNameForProtocol(url).empty()) { - web_contents->GetMainFrame()->AddMessageToConsole( - blink::mojom::ConsoleMessageLevel::kError, + AddMessageToConsole( + initiator_document, blink::mojom::ConsoleMessageLevel::kError, "Failed to launch '" + url.possibly_invalid_spec() + "' because the scheme does not have a registered handler."); return; @@ -134,12 +142,14 @@ #endif ExternalProtocolHandler::RunExternalProtocolDialog( - url, web_contents, page_transition, has_user_gesture, initiating_origin); + url, web_contents, page_transition, has_user_gesture, initiating_origin, + std::move(initiator_document)); } void LaunchUrlWithoutSecurityCheckWithDelegate( const GURL& url, content::WebContents* web_contents, + content::WeakDocumentPtr initiator_document, ExternalProtocolHandler::Delegate* delegate) { if (delegate) { delegate->LaunchUrlWithoutSecurityCheck(url, web_contents); @@ -151,8 +161,8 @@ if (!web_contents) return; - web_contents->GetMainFrame()->AddMessageToConsole( - blink::mojom::ConsoleMessageLevel::kInfo, + AddMessageToConsole( + initiator_document, blink::mojom::ConsoleMessageLevel::kInfo, "Launched external handler for '" + url.possibly_invalid_spec() + "'."); platform_util::OpenExternal( @@ -183,6 +193,7 @@ ui::PageTransition page_transition, bool has_user_gesture, const absl::optional<url::Origin>& initiating_origin, + content::WeakDocumentPtr initiator_document, ExternalProtocolHandler::Delegate* delegate, shell_integration::DefaultWebClientState state) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -204,6 +215,7 @@ // Handle tel links by opening the Click to Call dialog. This will call back // into LaunchUrlWithoutSecurityCheck if the user selects a system handler. ClickToCallUiController::ShowDialog(web_contents, initiating_origin, + std::move(initiator_document), escaped_url, chrome_is_default_handler); return; } @@ -225,14 +237,14 @@ // Ask the user if they want to allow the protocol. This will call // LaunchUrlWithoutSecurityCheck if the user decides to accept the // protocol. - RunExternalProtocolDialogWithDelegate(escaped_url, web_contents, - page_transition, has_user_gesture, - initiating_origin, delegate); + RunExternalProtocolDialogWithDelegate( + escaped_url, web_contents, page_transition, has_user_gesture, + initiating_origin, std::move(initiator_document), delegate); return; } - LaunchUrlWithoutSecurityCheckWithDelegate(escaped_url, web_contents, - delegate); + LaunchUrlWithoutSecurityCheckWithDelegate( + escaped_url, web_contents, std::move(initiator_document), delegate); } bool IsSchemeOriginPairAllowedByPolicy(const std::string& scheme, @@ -395,7 +407,8 @@ content::WebContents::Getter web_contents_getter, ui::PageTransition page_transition, bool has_user_gesture, - const absl::optional<url::Origin>& initiating_origin) { + const absl::optional<url::Origin>& initiating_origin, + content::WeakDocumentPtr initiator_document) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); // Disable anti-flood protection if the user is invoking a bookmark or @@ -424,8 +437,8 @@ escaped_url.scheme(), base::OptionalOrNullptr(initiating_origin), g_external_protocol_handler_delegate, profile); if (block_state == BLOCK) { - web_contents->GetMainFrame()->AddMessageToConsole( - blink::mojom::ConsoleMessageLevel::kError, + AddMessageToConsole( + initiator_document, blink::mojom::ConsoleMessageLevel::kError, "Not allowed to launch '" + url.possibly_invalid_spec() + "'" + (g_accept_requests ? "." : " because a user gesture is required.")); @@ -456,7 +469,7 @@ &OnDefaultProtocolClientWorkerFinished, escaped_url, std::move(web_contents_getter), block_state == UNKNOWN, page_transition, has_user_gesture, initiating_origin_or_precursor, - g_external_protocol_handler_delegate); + std::move(initiator_document), g_external_protocol_handler_delegate); // Start the check process running. This will send tasks to a worker task // runner and when the answer is known will send the result back to @@ -468,7 +481,8 @@ // static void ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck( const GURL& url, - content::WebContents* web_contents) { + content::WebContents* web_contents, + content::WeakDocumentPtr initiator_document) { // Escape the input scheme to be sure that the command does not // have parameters unexpected by the external program. The url passed in the // |url| parameter might already be escaped but the EscapeExternalHandlerValue @@ -480,7 +494,8 @@ GURL escaped_url(escaped_url_string); LaunchUrlWithoutSecurityCheckWithDelegate( - escaped_url, web_contents, g_external_protocol_handler_delegate); + escaped_url, web_contents, std::move(initiator_document), + g_external_protocol_handler_delegate); } // static
diff --git a/chrome/browser/external_protocol/external_protocol_handler.h b/chrome/browser/external_protocol/external_protocol_handler.h index 102b2f27..8818262 100644 --- a/chrome/browser/external_protocol/external_protocol_handler.h +++ b/chrome/browser/external_protocol/external_protocol_handler.h
@@ -13,7 +13,7 @@ #include "ui/base/page_transition_types.h" namespace content { -class WebContents; +class WeakDocumentPtr; } namespace url { @@ -105,12 +105,15 @@ // ExternalProtocolDialog is created asking the user. If the user accepts, // LaunchUrlWithoutSecurityCheck is called on the io thread and the // application is launched. + // If possible, |initiator_document| identifies the document that requested + // the external protocol launch. // Must run on the UI thread. static void LaunchUrl(const GURL& url, content::WebContents::Getter web_contents_getter, ui::PageTransition page_transition, bool has_user_gesture, - const absl::optional<url::Origin>& initiating_origin); + const absl::optional<url::Origin>& initiating_origin, + content::WeakDocumentPtr initiator_document); // Starts a url using the external protocol handler with the help // of shellexecute. Should only be called if the protocol is allowlisted @@ -121,8 +124,10 @@ // NOTE: You should NOT call this function directly unless you are sure the // url you have has been checked against the denylist. // All calls to this function should originate in some way from LaunchUrl. - static void LaunchUrlWithoutSecurityCheck(const GURL& url, - content::WebContents* web_contents); + static void LaunchUrlWithoutSecurityCheck( + const GURL& url, + content::WebContents* web_contents, + content::WeakDocumentPtr initiator_document); // Allows LaunchUrl to proceed with launching an external protocol handler. // This is typically triggered by a user gesture, but is also called for @@ -161,7 +166,8 @@ content::WebContents* web_contents, ui::PageTransition page_transition, bool has_user_gesture, - const absl::optional<url::Origin>& initiating_origin); + const absl::optional<url::Origin>& initiating_origin, + content::WeakDocumentPtr initiator_document); // Clears the external protocol handling data. static void ClearData(Profile* profile);
diff --git a/chrome/browser/external_protocol/external_protocol_handler_browsertest.cc b/chrome/browser/external_protocol/external_protocol_handler_browsertest.cc index 0260e45..add515e2 100644 --- a/chrome/browser/external_protocol/external_protocol_handler_browsertest.cc +++ b/chrome/browser/external_protocol/external_protocol_handler_browsertest.cc
@@ -5,10 +5,13 @@ #include "base/test/bind.h" #include "build/build_config.h" #include "chrome/browser/browser_features.h" +#include "chrome/browser/external_protocol/external_protocol_handler.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/shell_integration.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" #include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" #include "components/policy/core/common/policy_pref_names.h" #include "components/prefs/pref_service.h" #include "content/public/browser/browser_context.h" @@ -246,3 +249,71 @@ "allow-top-navigation-by-user-activation';", /*user-gesture=*/true)); } + +namespace { + +class AlwaysBlockedExternalProtocolHandlerDelegate + : public ExternalProtocolHandler::Delegate { + public: + AlwaysBlockedExternalProtocolHandlerDelegate() { + ExternalProtocolHandler::SetDelegateForTesting(this); + } + ~AlwaysBlockedExternalProtocolHandlerDelegate() override { + ExternalProtocolHandler::SetDelegateForTesting(nullptr); + } + + scoped_refptr<shell_integration::DefaultProtocolClientWorker> + CreateShellWorker(const std::string& protocol) override { + NOTREACHED(); + return nullptr; + } + ExternalProtocolHandler::BlockState GetBlockState(const std::string& scheme, + Profile* profile) override { + return ExternalProtocolHandler::BLOCK; + } + void BlockRequest() override {} + void RunExternalProtocolDialog( + const GURL& url, + content::WebContents* web_contents, + ui::PageTransition page_transition, + bool has_user_gesture, + const absl::optional<url::Origin>& initiating_origin) override { + NOTREACHED(); + } + void LaunchUrlWithoutSecurityCheck( + const GURL& url, + content::WebContents* web_contents) override { + NOTREACHED(); + } + void FinishedProcessingCheck() override {} +}; + +} // namespace + +// Tests (by forcing a particular scheme to be blocked, regardless of platform) +// that the console message is attributed to a subframe if one was responsible. +IN_PROC_BROWSER_TEST_F(ExternalProtocolHandlerBrowserTest, + ProtocolLaunchEmitsConsoleLogInCorrectFrame) { + AlwaysBlockedExternalProtocolHandlerDelegate always_blocked; + content::RenderFrameHost* main_rfh = ui_test_utils::NavigateToURL( + browser(), GURL("data:text/html,<iframe srcdoc=\"Hello!\"></iframe>")); + ASSERT_TRUE(main_rfh); + content::RenderFrameHost* originating_rfh = ChildFrameAt(main_rfh, 0); + + content::WebContentsConsoleObserver observer( + content::WebContents::FromRenderFrameHost(originating_rfh)); + observer.SetPattern("*aunch*'willfailtolaunch://foo'*"); + observer.SetFilter(base::BindRepeating( + [](content::RenderFrameHost* expected_rfh, + const content::WebContentsConsoleObserver::Message& message) { + return message.source_frame == expected_rfh; + }, + originating_rfh)); + + ASSERT_TRUE( + ExecJs(originating_rfh, "location.href = 'willfailtolaunch://foo';")); + observer.Wait(); + ASSERT_EQ(1u, observer.messages().size()); + EXPECT_EQ("Not allowed to launch 'willfailtolaunch://foo'.", + observer.GetMessageAt(0u)); +}
diff --git a/chrome/browser/external_protocol/external_protocol_handler_unittest.cc b/chrome/browser/external_protocol/external_protocol_handler_unittest.cc index 15a57690..d7e0d158 100644 --- a/chrome/browser/external_protocol/external_protocol_handler_unittest.cc +++ b/chrome/browser/external_protocol/external_protocol_handler_unittest.cc
@@ -16,6 +16,7 @@ #include "components/prefs/testing_pref_service.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" +#include "content/public/browser/weak_document_ptr.h" #include "content/public/test/browser_task_environment.h" #include "content/public/test/test_renderer_host.h" #include "content/public/test/test_utils.h" @@ -193,7 +194,8 @@ url, base::BindRepeating(&ExternalProtocolHandlerTest::GetWebContents, base::Unretained(this)), - ui::PAGE_TRANSITION_LINK, true, initiating_origin); + ui::PAGE_TRANSITION_LINK, true, initiating_origin, + content::WeakDocumentPtr()); run_loop_.Run(); ExternalProtocolHandler::SetDelegateForTesting(nullptr); @@ -309,8 +311,8 @@ delegate_.set_block_state(ExternalProtocolHandler::DONT_BLOCK); delegate_.set_os_state(shell_integration::NOT_DEFAULT); delegate_.set_complete_on_launch(true); - ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck(url, - web_contents_.get()); + ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck( + url, web_contents_.get(), content::WeakDocumentPtr()); run_loop_.Run(); ExternalProtocolHandler::SetDelegateForTesting(nullptr);
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 12550e9b..e7fc120f 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -2865,7 +2865,7 @@ { "name": "enable-web-authentication-cable-v2-support", "owners": [ "webauthn-team@google.com" ], - "expiry_milestone": 95 + "expiry_milestone": 103 }, { "name": "enable-web-authentication-chromeos-authenticator", @@ -3262,6 +3262,11 @@ "expiry_milestone": 100 }, { + "name": "force-major-version-to-minor", + "owners": [ "brgoldstein", "potassium-katabolism@google.com" ], + "expiry_milestone": 110 + }, + { "name": "force-minor-version-to-100", "owners": [ "abeyad", "potassium-katabolism@google.com" ], "expiry_milestone": 100 @@ -5586,6 +5591,11 @@ "expiry_milestone": 95 }, { + "name": "use-sf-symbols-samples", + "owners": [ "gambard", "bling-flags@google.com" ], + "expiry_milestone": 110 + }, + { "name": "use-stork-smds-server-address", "owners": [ "cros-connectivity@google.com", "hsuregan"], // This flag is required for dev testing via Stork profiles which can be quickly
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index f009c57..dde9322 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -1231,10 +1231,9 @@ "Allow subresource compression for data savings"; const char kEnableWebAuthenticationCableV2SupportName[] = - "Web Authentication caBLE v2 support"; + "Web Authentication caBLE v2 QR codes"; const char kEnableWebAuthenticationCableV2SupportDescription[] = - "Enable use of phones that are signed into the same account, with Sync " - "enabled, to be used as 2nd-factor security keys."; + "Enable display of QR codes for using Android phones as security keys."; const char kEnableWebAuthenticationChromeOSAuthenticatorName[] = "ChromeOS platform Web Authentication support"; @@ -2809,12 +2808,22 @@ "a common submenu."; #endif +const char kForceMajorVersionInMinorPositionInUserAgentName[] = + "Put major version in minor version position in User-Agent"; +const char kForceMajorVersionInMinorPositionInUserAgentDescription[] = + "Lock the Chrome major version in the User-Agent string to 99, and " + "force the major version number to the minor version position. This " + "flag is a backup plan for unexpected site-compatibility breakage with " + "a three digit major version."; + const char kForceMajorVersion100InUserAgentName[] = "Force major version to 100 in User-Agent"; const char kForceMajorVersion100InUserAgentDescription[] = "Force the Chrome major version in the User-Agent string to 100, which " "allows testing the 3-digit major version number before the actual M100 " - "release. This flag is only available from M96-M99."; + "release. This flag is only available from M96-M99. " + "If force-major-version-in-minor is enabled this flag will " + "have no effect."; const char kForceMinorVersion100InUserAgentName[] = "Force the minor version to 100 in the User-Agent string"; @@ -2825,7 +2834,9 @@ "upcoming major version 100, this flag allows us to test whether setting " "the major version in the minor version part of the User-Agent string " "would be an acceptable alternative. If force-major-version-to-100 is set, " - "then this flag has no effect. See crbug.com/1278459 for details."; + "then this flag has no effect. See crbug.com/1278459 for details." + "If force-major-version-in-minor is enabled this flag will " + "have no effect."; // Android ---------------------------------------------------------------------
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 8c0fa89..1d7ead0 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1623,6 +1623,9 @@ extern const char kShareContextMenuDescription[]; #endif +extern const char kForceMajorVersionInMinorPositionInUserAgentName[]; +extern const char kForceMajorVersionInMinorPositionInUserAgentDescription[]; + extern const char kForceMajorVersion100InUserAgentName[]; extern const char kForceMajorVersion100InUserAgentDescription[];
diff --git a/chrome/browser/metrics/power/power_metrics_reporter.cc b/chrome/browser/metrics/power/power_metrics_reporter.cc index cc7497f64..aa3c341d 100644 --- a/chrome/browser/metrics/power/power_metrics_reporter.cc +++ b/chrome/browser/metrics/power/power_metrics_reporter.cc
@@ -11,7 +11,6 @@ #include "base/strings/strcat.h" #include "base/strings/string_util.h" #include "base/time/time.h" -#include "build/build_config.h" #include "chrome/browser/lifetime/browser_shutdown.h" #include "chrome/browser/metrics/power/power_details_provider.h" #include "chrome/browser/performance_monitor/process_metrics_recorder_util.h" @@ -105,6 +104,9 @@ #if defined(OS_MAC) power_details_provider_ = PowerDetailsProvider::Create(); + iopm_power_source_sampling_event_source_.Start( + base::BindRepeating(&PowerMetricsReporter::OnIOPMPowerSourceSamplingEvent, + base::Unretained(this))); #endif } @@ -405,3 +407,24 @@ return {BatteryDischargeMode::kBatteryLevelIncreased, absl::nullopt}; return {BatteryDischargeMode::kDischarging, discharge_rate}; } + +#if defined(OS_MAC) +void PowerMetricsReporter::OnIOPMPowerSourceSamplingEvent() { + base::TimeTicks now_ticks = base::TimeTicks::Now(); + + if (!last_event_time_ticks_) { + last_event_time_ticks_ = now_ticks; + return; + } + + // The delta is expected to be almost always 60 seconds. Split the buckets for + // 0.2s granularity (10s interval with 50 buckets + 1 underflow bucket + 1 + // overflow bucket) around that value. + base::HistogramBase* histogram = base::LinearHistogram::FactoryTimeGet( + "Power.IOPMPowerSource.SamplingEventDelta", + /*min=*/base::Seconds(55), /*max=*/base::Seconds(65), /*buckets=*/52, + base::HistogramBase::kUmaTargetedHistogramFlag); + histogram->AddTime(now_ticks - *last_event_time_ticks_); + *last_event_time_ticks_ = now_ticks; +} +#endif // defined(OS_MAC)
diff --git a/chrome/browser/metrics/power/power_metrics_reporter.h b/chrome/browser/metrics/power/power_metrics_reporter.h index 4adee4d..ebc5adb2 100644 --- a/chrome/browser/metrics/power/power_metrics_reporter.h +++ b/chrome/browser/metrics/power/power_metrics_reporter.h
@@ -10,12 +10,17 @@ #include "base/memory/weak_ptr.h" #include "base/time/time.h" +#include "build/build_config.h" #include "chrome/browser/metrics/power/battery_level_provider.h" #include "chrome/browser/metrics/power/power_details_provider.h" #include "chrome/browser/metrics/usage_scenario/usage_scenario_data_store.h" #include "chrome/browser/performance_monitor/process_monitor.h" #include "third_party/abseil-cpp/absl/types/optional.h" +#if defined(OS_MAC) +#include "components/power_metrics/iopm_power_source_sampling_event_source.h" +#endif // defined(OS_MAC) + // Reports metrics related to power (battery discharge, cpu time, etc.) to // understand what impacts Chrome's power consumption over an interval of time. // @@ -126,6 +131,10 @@ const BatteryLevelProvider::BatteryState& new_battery_state, base::TimeDelta interval_duration); +#if defined(OS_MAC) + void OnIOPMPowerSourceSamplingEvent(); +#endif // defined(OS_MAC) + // The data store used to get the usage scenario data, it needs to outlive // this class. base::WeakPtr<UsageScenarioDataStore> data_store_; @@ -144,6 +153,14 @@ base::OnceClosure on_battery_sampled_for_testing_; +#if defined(OS_MAC) + power_metrics::IOPMPowerSourceSamplingEventSource + iopm_power_source_sampling_event_source_; + + // The time ticks from when the last IOPMPowerSource event was received. + absl::optional<base::TimeTicks> last_event_time_ticks_; +#endif // defined(OS_MAC) + SEQUENCE_CHECKER(sequence_checker_); base::WeakPtrFactory<PowerMetricsReporter> weak_factory_{this};
diff --git a/chrome/browser/optimization_guide/hints_fetcher_browsertest.cc b/chrome/browser/optimization_guide/hints_fetcher_browsertest.cc index ce280e1..d8fd60d 100644 --- a/chrome/browser/optimization_guide/hints_fetcher_browsertest.cc +++ b/chrome/browser/optimization_guide/hints_fetcher_browsertest.cc
@@ -381,7 +381,9 @@ optimization_guide::proto::Hint* hint = get_hints_response.add_hints(); hint->set_key_representation(optimization_guide::proto::HOST); - hint->set_key(https_url_.host()); + hint->set_key(search_results_page_url_.host()); + hint->add_allowlisted_optimizations()->set_optimization_type( + optimization_guide::proto::OptimizationType::NOSCRIPT); optimization_guide::proto::PageHint* page_hint = hint->add_page_hints(); page_hint->set_page_pattern("page pattern"); @@ -477,6 +479,15 @@ std::unique_ptr<ukm::TestAutoSetUkmRecorder> ukm_recorder_; }; +IN_PROC_BROWSER_TEST_F(HintsFetcherDisabledBrowserTest, HintsFetcherDisabled) { + const base::HistogramTester* histogram_tester = GetHistogramTester(); + + // Expect that the histogram for HintsFetcher to be 0 because the OnePlatform + // is not enabled. + histogram_tester->ExpectTotalCount( + "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount", 0); +} + // This test class enables OnePlatform Hints. class HintsFetcherBrowserTest : public HintsFetcherDisabledBrowserTest { public: @@ -506,11 +517,7 @@ void SetUpOnMainThread() override { // Register an optimization type, so hints will be fetched at page // navigation. - OptimizationGuideKeyedServiceFactory::GetForProfile( - Profile::FromBrowserContext(browser() - ->tab_strip_model() - ->GetActiveWebContents() - ->GetBrowserContext())) + OptimizationGuideKeyedServiceFactory::GetForProfile(browser()->profile()) ->RegisterOptimizationTypes({optimization_guide::proto::NOSCRIPT}); HintsFetcherDisabledBrowserTest::SetUpOnMainThread(); @@ -522,6 +529,18 @@ browser()->profile()); return keyed_service->GetTopHostProvider(); } + + void CanApplyOptimizationOnDemand( + const std::vector<GURL>& urls, + const std::vector<optimization_guide::proto::OptimizationType>& + optimization_types, + optimization_guide::OnDemandOptimizationGuideDecisionRepeatingCallback + callback) { + OptimizationGuideKeyedServiceFactory::GetForProfile(browser()->profile()) + ->CanApplyOptimizationOnDemand( + urls, optimization_types, + optimization_guide::proto::CONTEXT_BOOKMARKS, callback); + } }; // This test creates new browser with no profile and loads a random page with @@ -557,15 +576,6 @@ "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 1, 1); } -IN_PROC_BROWSER_TEST_F(HintsFetcherDisabledBrowserTest, HintsFetcherDisabled) { - const base::HistogramTester* histogram_tester = GetHistogramTester(); - - // Expect that the histogram for HintsFetcher to be 0 because the OnePlatform - // is not enabled. - histogram_tester->ExpectTotalCount( - "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount", 0); -} - IN_PROC_BROWSER_TEST_F(HintsFetcherBrowserTest, HintsFetcherFetchedHintsLoaded) { const base::HistogramTester* histogram_tester = GetHistogramTester(); @@ -859,6 +869,156 @@ "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 1, 1); } +IN_PROC_BROWSER_TEST_F(HintsFetcherBrowserTest, + OnDemandFetchRepeatedlyWithCache) { + SetNetworkConnectionOnline(); + + SetResponseType( + optimization_guide::HintsFetcherRemoteResponseType::kSuccessful); + + OptimizationGuideKeyedService* ogks = + OptimizationGuideKeyedServiceFactory::GetForProfile(browser()->profile()); + ogks->RegisterOptimizationTypes( + {optimization_guide::proto::OptimizationType::NOSCRIPT}); + + { + base::HistogramTester histogram_tester; + std::unique_ptr<base::RunLoop> run_loop = std::make_unique<base::RunLoop>(); + CanApplyOptimizationOnDemand( + {search_results_page_url()}, + {optimization_guide::proto::OptimizationType::NOSCRIPT}, + base::BindRepeating( + [](base::RunLoop* run_loop, const GURL& url, + const base::flat_map< + optimization_guide::proto::OptimizationType, + optimization_guide::OptimizationGuideDecisionWithMetadata>& + decisions) { + // Expect one decision per requested type. + EXPECT_EQ(decisions.size(), 1u); + auto it = decisions.find( + optimization_guide::proto::OptimizationType::NOSCRIPT); + EXPECT_NE(it, decisions.end()); + EXPECT_EQ(it->second.decision, + optimization_guide::OptimizationGuideDecision::kTrue); + + run_loop->Quit(); + }, + run_loop.get())); + run_loop->Run(); + + histogram_tester.ExpectUniqueSample( + "OptimizationGuide.HintsFetcher.RequestStatus.Bookmarks", + optimization_guide::HintsFetcherRequestStatus::kSuccess, 1); + } + + { + base::HistogramTester histogram_tester; + std::unique_ptr<base::RunLoop> run_loop = std::make_unique<base::RunLoop>(); + CanApplyOptimizationOnDemand( + {search_results_page_url()}, + {optimization_guide::proto::OptimizationType::NOSCRIPT}, + base::BindRepeating( + [](base::RunLoop* run_loop, const GURL& url, + const base::flat_map< + optimization_guide::proto::OptimizationType, + optimization_guide::OptimizationGuideDecisionWithMetadata>& + decisions) { + // Expect one decision per requested type. + EXPECT_EQ(decisions.size(), 1u); + auto it = decisions.find( + optimization_guide::proto::OptimizationType::NOSCRIPT); + EXPECT_NE(it, decisions.end()); + EXPECT_EQ(it->second.decision, + optimization_guide::OptimizationGuideDecision::kTrue); + + run_loop->Quit(); + }, + run_loop.get())); + run_loop->Run(); + + // Second time should not refetch since have all the right info already. + histogram_tester.ExpectTotalCount( + "OptimizationGuide.HintsFetcher.RequestStatus.Bookmarks", 0); + } +} + +IN_PROC_BROWSER_TEST_F(HintsFetcherBrowserTest, + OnDemandFetchRepeatedlyNoCache) { + SetNetworkConnectionOnline(); + + SetResponseType( + optimization_guide::HintsFetcherRemoteResponseType::kSuccessful); + + OptimizationGuideKeyedService* ogks = + OptimizationGuideKeyedServiceFactory::GetForProfile(browser()->profile()); + ogks->RegisterOptimizationTypes( + {optimization_guide::proto::OptimizationType::NOSCRIPT}); + + GURL url_with_no_hints("https://urlwithnohints.com/notcached"); + + { + base::HistogramTester histogram_tester; + std::unique_ptr<base::RunLoop> run_loop = std::make_unique<base::RunLoop>(); + CanApplyOptimizationOnDemand( + {url_with_no_hints}, + {optimization_guide::proto::OptimizationType::NOSCRIPT}, + base::BindRepeating( + [](base::RunLoop* run_loop, const GURL& url, + const base::flat_map< + optimization_guide::proto::OptimizationType, + optimization_guide::OptimizationGuideDecisionWithMetadata>& + decisions) { + // Expect one decision per requested type. + EXPECT_EQ(decisions.size(), 1u); + auto it = decisions.find( + optimization_guide::proto::OptimizationType::NOSCRIPT); + EXPECT_NE(it, decisions.end()); + EXPECT_EQ(it->second.decision, + optimization_guide::OptimizationGuideDecision::kFalse); + + run_loop->Quit(); + }, + run_loop.get())); + run_loop->Run(); + + histogram_tester.ExpectUniqueSample( + "OptimizationGuide.HintsFetcher.RequestStatus.Bookmarks", + optimization_guide::HintsFetcherRequestStatus::kSuccess, 1); + } + + { + base::HistogramTester histogram_tester; + std::unique_ptr<base::RunLoop> run_loop = std::make_unique<base::RunLoop>(); + CanApplyOptimizationOnDemand( + {url_with_no_hints}, + {optimization_guide::proto::OptimizationType::NOSCRIPT}, + base::BindRepeating( + [](base::RunLoop* run_loop, const GURL& url, + const base::flat_map< + optimization_guide::proto::OptimizationType, + optimization_guide::OptimizationGuideDecisionWithMetadata>& + decisions) { + // Expect one decision per requested type. + EXPECT_EQ(decisions.size(), 1u); + auto it = decisions.find( + optimization_guide::proto::OptimizationType::NOSCRIPT); + EXPECT_NE(it, decisions.end()); + EXPECT_EQ(it->second.decision, + optimization_guide::OptimizationGuideDecision::kFalse); + + run_loop->Quit(); + }, + run_loop.get())); + run_loop->Run(); + + // Second time should not refetch since no hosts or urls match. + histogram_tester.ExpectUniqueSample( + "OptimizationGuide.HintsFetcher.RequestStatus.Bookmarks", + optimization_guide::HintsFetcherRequestStatus::kNoHostsOrURLsToFetch, + 1); + } +} + // Test that the hints are fetched at the time of the navigation. IN_PROC_BROWSER_TEST_F(HintsFetcherBrowserTest, HintsFetcher_NavigationFetch_URLKeyedNotRefetched) {
diff --git a/chrome/browser/optimization_guide/page_content_annotations_service_browsertest.cc b/chrome/browser/optimization_guide/page_content_annotations_service_browsertest.cc index 4371d31d..0fdba194 100644 --- a/chrome/browser/optimization_guide/page_content_annotations_service_browsertest.cc +++ b/chrome/browser/optimization_guide/page_content_annotations_service_browsertest.cc
@@ -459,12 +459,11 @@ base::test::ScopedFeatureList scoped_feature_list_; }; -// TODO(https://crbug.com/1225946): Test is flaky. IN_PROC_BROWSER_TEST_F(PageContentAnnotationsServiceNoHistoryTest, - DISABLED_ModelExecutesButDoesntWriteToHistory) { + ModelExecutesButDoesntWriteToHistory) { base::HistogramTester histogram_tester; - GURL url(embedded_test_server()->GetURL("a.com", "/hello-no-history.html")); + GURL url(embedded_test_server()->GetURL("a.com", "/hello.html")); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); RetryForHistogramUntilCountReached(
diff --git a/chrome/browser/optimization_guide/prediction/prediction_manager_browsertest.cc b/chrome/browser/optimization_guide/prediction/prediction_manager_browsertest.cc index bfa5f38..881555e8 100644 --- a/chrome/browser/optimization_guide/prediction/prediction_manager_browsertest.cc +++ b/chrome/browser/optimization_guide/prediction/prediction_manager_browsertest.cc
@@ -513,6 +513,10 @@ /*model_metadata=*/absl::nullopt, model_file_observer_.get()); } + base::HistogramTester* test_harness_histogram_tester() { + return &histogram_tester_; + } + private: void InitializeFeatureList() override { scoped_feature_list_.InitWithFeaturesAndParameters( @@ -536,11 +540,11 @@ } std::unique_ptr<ModelFileObserver> model_file_observer_; + base::HistogramTester histogram_tester_; }; -// Flaky on various bots. See https://crbug.com/1266318 IN_PROC_BROWSER_TEST_F(PredictionManagerModelDownloadingBrowserTest, - DISABLED_TestIncognitoUsesModelFromRegularProfile) { + TestIncognitoUsesModelFromRegularProfile) { SetResponseType( PredictionModelsFetcherRemoteResponseType::kSuccessfulWithValidModelFile); @@ -599,44 +603,51 @@ run_loop->Run(); + // Should have same model loaded as original profile. + otr_histogram_tester.ExpectUniqueSample( + "OptimizationGuide.PredictionModelLoadedVersion.PainfulPageLoad", 123, + 1); + // Should not have fetched. otr_histogram_tester.ExpectTotalCount( - "OptimizationGuide.PredictionModelDownloadManager.DownloadStatus", 0); - otr_histogram_tester.ExpectTotalCount( - "OptimizationGuide.PredictionModelUpdateVersion.PainfulPageLoad", 0); + "OptimizationGuide.PredictionModelFetcher.GetModelsResponse.Status", 0); } } -// Flaky on multiple ASAN bots. See https://crbug.com/1266318 -#if defined(ADDRESS_SANITIZER) -#define MAYBE_TestIncognitoDoesntFetchModels \ - DISABLED_TestIncognitoDoesntFetchModels -#else -#define MAYBE_TestIncognitoDoesntFetchModels TestIncognitoDoesntFetchModels -#endif -IN_PROC_BROWSER_TEST_F(PredictionManagerModelDownloadingBrowserTest, - MAYBE_TestIncognitoDoesntFetchModels) { - base::HistogramTester histogram_tester; +IN_PROC_BROWSER_TEST_F(PredictionManagerModelDownloadingBrowserTest, + TestIncognitoDoesntFetchModels) { SetResponseType(PredictionModelsFetcherRemoteResponseType:: kSuccessfulWithInvalidModelFile); + // Wait until regular profile has finished its model initialization routine. + { + RetryForHistogramUntilCountReached( + test_harness_histogram_tester(), + "OptimizationGuide.PredictionManager.StoreInitialized", 1); + base::RunLoop().RunUntilIdle(); + } - Browser* otr_browser = CreateIncognitoBrowser(browser()->profile()); + { + base::HistogramTester otr_histogram_tester; - // Registering should not initiate the fetch and the model updated callback - // should not be triggered too. - RegisterModelFileObserverWithKeyedService(otr_browser->profile()); + Browser* otr_browser = CreateIncognitoBrowser(browser()->profile()); - model_file_observer()->set_model_file_received_callback(base::BindOnce( - [](proto::OptimizationTarget optimization_target, - const ModelInfo& model_info) { FAIL() << "Should not be called"; })); + // Registering should not initiate the fetch and the model updated callback + // should not be triggered either. + RegisterModelFileObserverWithKeyedService(otr_browser->profile()); - RetryForHistogramUntilCountReached( - &histogram_tester, - "OptimizationGuide.PredictionManager.HostModelFeaturesMapSize", 1); + model_file_observer()->set_model_file_received_callback(base::BindOnce( + [](proto::OptimizationTarget optimization_target, + const ModelInfo& model_info) { FAIL() << "Should not be called"; })); - histogram_tester.ExpectTotalCount( - "OptimizationGuide.PredictionModelDownloadManager.DownloadStatus", 0); - histogram_tester.ExpectTotalCount( - "OptimizationGuide.PredictionModelUpdateVersion.PainfulPageLoad", 0); + RetryForHistogramUntilCountReached( + &otr_histogram_tester, + "OptimizationGuide.PredictionManager.StoreInitialized", 1); + // Wait until everything has stabilized before ensuring no fetches went out. + base::RunLoop().RunUntilIdle(); + + // Should not have fetched. + otr_histogram_tester.ExpectTotalCount( + "OptimizationGuide.PredictionModelFetcher.GetModelsResponse.Status", 0); + } } IN_PROC_BROWSER_TEST_F(PredictionManagerModelDownloadingBrowserTest,
diff --git a/chrome/browser/password_manager/android/password_store_android_backend.cc b/chrome/browser/password_manager/android/password_store_android_backend.cc index 55a5e19..ed19b9a6 100644 --- a/chrome/browser/password_manager/android/password_store_android_backend.cc +++ b/chrome/browser/password_manager/android/password_store_android_backend.cc
@@ -317,10 +317,8 @@ void PasswordStoreAndroidBackend::GetAllLoginsAsync( LoginsOrErrorReply callback) { - JobId job_id = bridge_->GetAllLogins(PasswordStoreOperationTarget::kDefault); - QueueNewJob(job_id, JobReturnHandler( - std::move(callback), - MetricsRecorder(MetricInfix("GetAllLoginsAsync")))); + GetAllLoginsForTarget(PasswordStoreOperationTarget::kDefault, + std::move(callback)); } void PasswordStoreAndroidBackend::GetAutofillableLoginsAsync( @@ -385,11 +383,8 @@ void PasswordStoreAndroidBackend::RemoveLoginAsync( const PasswordForm& form, PasswordStoreChangeListReply callback) { - JobId job_id = - bridge_->RemoveLogin(form, PasswordStoreOperationTarget::kDefault); - QueueNewJob(job_id, JobReturnHandler( - std::move(callback), - MetricsRecorder(MetricInfix("RemoveLoginAsync")))); + RemoveLoginForTarget(form, PasswordStoreOperationTarget::kDefault, + std::move(callback)); } void PasswordStoreAndroidBackend::FilterAndRemoveLogins( @@ -523,6 +518,33 @@ base::Unretained(this))); } +void PasswordStoreAndroidBackend::ClearAllLocalPasswords() { + LoginsOrErrorReply cleaning_callback = base::BindOnce( + [](base::WeakPtr<PasswordStoreAndroidBackend> weak_self, + LoginsResultOrError logins_or_error) { + if (!weak_self || + absl::holds_alternative<PasswordStoreBackendError>(logins_or_error)) + return; + + base::OnceClosure callbacks_chain = base::DoNothing(); + + for (const auto& login : absl::get<LoginsResult>(logins_or_error)) { + callbacks_chain = base::BindOnce( + &PasswordStoreAndroidBackend::RemoveLoginForTarget, weak_self, + std::move(*login), PasswordStoreOperationTarget::kLocalStorage, + IgnoreChangeListAndRunCallback(std::move(callbacks_chain))); + } + + std::move(callbacks_chain).Run(); + }, + weak_ptr_factory_.GetWeakPtr()); + + // TODO(https://crbug.com/1278748) Record whether the operation was + // successful. + GetAllLoginsForTarget(PasswordStoreOperationTarget::kLocalStorage, + std::move(cleaning_callback)); +} + void PasswordStoreAndroidBackend::OnCompleteWithLogins( JobId job_id, std::vector<PasswordForm> passwords) { @@ -676,4 +698,23 @@ MetricsRecorder(metric_infix), std::move(callback)); } +void PasswordStoreAndroidBackend::GetAllLoginsForTarget( + PasswordStoreOperationTarget target, + LoginsOrErrorReply callback) { + JobId job_id = bridge_->GetAllLogins(target); + QueueNewJob(job_id, JobReturnHandler( + std::move(callback), + MetricsRecorder(MetricInfix("GetAllLoginsAsync")))); +} + +void PasswordStoreAndroidBackend::RemoveLoginForTarget( + const PasswordForm& form, + PasswordStoreOperationTarget target, + PasswordStoreChangeListReply callback) { + JobId job_id = bridge_->RemoveLogin(form, target); + QueueNewJob(job_id, JobReturnHandler( + std::move(callback), + MetricsRecorder(MetricInfix("RemoveLoginAsync")))); +} + } // namespace password_manager
diff --git a/chrome/browser/password_manager/android/password_store_android_backend.h b/chrome/browser/password_manager/android/password_store_android_backend.h index bff952d..f9b242a 100644 --- a/chrome/browser/password_manager/android/password_store_android_backend.h +++ b/chrome/browser/password_manager/android/password_store_android_backend.h
@@ -189,6 +189,7 @@ FieldInfoStore* GetFieldInfoStore() override; std::unique_ptr<syncer::ProxyModelTypeControllerDelegate> CreateSyncControllerDelegate() override; + void ClearAllLocalPasswords() override; // Implements PasswordStoreAndroidBackendBridge::Consumer interface. void OnCompleteWithLogins(PasswordStoreAndroidBackendBridge::JobId job_id, @@ -241,6 +242,16 @@ const MetricInfix& metric_infix, PasswordStoreChangeListReply callback); + // Returns the complete list of PasswordForms (regardless of their blocklist + // status) from specified storage. + void GetAllLoginsForTarget(PasswordStoreOperationTarget target, + LoginsOrErrorReply callback); + + // Removes |form| from specified storage. + void RemoveLoginForTarget(const PasswordForm& form, + PasswordStoreOperationTarget target, + PasswordStoreChangeListReply callback); + // Observer to propagate remote form changes to. RemoteChangesReceived remote_form_changes_received_;
diff --git a/chrome/browser/password_manager/android/password_store_android_backend_unittest.cc b/chrome/browser/password_manager/android/password_store_android_backend_unittest.cc index 2f5d31e..0c01630 100644 --- a/chrome/browser/password_manager/android/password_store_android_backend_unittest.cc +++ b/chrome/browser/password_manager/android/password_store_android_backend_unittest.cc
@@ -555,6 +555,30 @@ 1); } +TEST_F(PasswordStoreAndroidBackendTest, RemoveAllLocalLogins) { + backend().InitBackend(PasswordStoreAndroidBackend::RemoteChangesReceived(), + base::RepeatingClosure(), base::DoNothing()); + + base::MockCallback<LoginsReply> mock_logins_reply; + const JobId kGetLoginsJobId{13387}; + EXPECT_CALL(*bridge(), + GetAllLogins(PasswordStoreOperationTarget::kLocalStorage)) + .WillOnce(Return(kGetLoginsJobId)); + backend().ClearAllLocalPasswords(); + + // Imitate login retrieval and check that it triggers the removal of forms. + const JobId kRemoveLoginJobId{13388}; + PasswordForm form_to_delete = CreateTestLogin( + kTestUsername, kTestPassword, kTestUrl, base::Time::FromTimeT(1500)); + EXPECT_CALL( + *bridge(), + RemoveLogin(form_to_delete, PasswordStoreOperationTarget::kLocalStorage)) + .WillOnce(Return(kRemoveLoginJobId)); + + consumer().OnCompleteWithLogins(kGetLoginsJobId, {form_to_delete}); + RunUntilIdle(); +} + class PasswordStoreAndroidBackendTestForMetrics : public PasswordStoreAndroidBackendTest, public testing::WithParamInterface<bool> {
diff --git a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_url_loader_interceptor.h b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_url_loader_interceptor.h index 209dd548..5423bb7 100644 --- a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_url_loader_interceptor.h +++ b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_url_loader_interceptor.h
@@ -37,7 +37,7 @@ ~PrefetchProxyURLLoaderInterceptor() override; - // content::URLLaoderRequestInterceptor: + // content::URLLoaderRequestInterceptor: void MaybeCreateLoader( const network::ResourceRequest& tentative_resource_request, content::BrowserContext* browser_context,
diff --git a/chrome/browser/prefetch/search_prefetch/search_prefetch_url_loader_interceptor.h b/chrome/browser/prefetch/search_prefetch/search_prefetch_url_loader_interceptor.h index d20220d6..62929e31e 100644 --- a/chrome/browser/prefetch/search_prefetch/search_prefetch_url_loader_interceptor.h +++ b/chrome/browser/prefetch/search_prefetch/search_prefetch_url_loader_interceptor.h
@@ -38,7 +38,7 @@ const network::ResourceRequest& tentative_resource_request, int frame_tree_node_id); - // content::URLLaoderRequestInterceptor: + // content::URLLoaderRequestInterceptor: void MaybeCreateLoader( const network::ResourceRequest& tentative_resource_request, content::BrowserContext* browser_context,
diff --git a/chrome/browser/profiles/host_zoom_map_browsertest.cc b/chrome/browser/profiles/host_zoom_map_browsertest.cc index 2e4bcac4..ca55c35 100644 --- a/chrome/browser/profiles/host_zoom_map_browsertest.cc +++ b/chrome/browser/profiles/host_zoom_map_browsertest.cc
@@ -121,17 +121,15 @@ std::vector<std::string> GetHostsWithZoomLevelsFromPrefs() { PrefService* prefs = browser()->profile()->GetPrefs(); - const base::DictionaryValue* dictionaries = &base::Value::AsDictionaryValue( - *prefs->GetDictionary(prefs::kPartitionPerHostZoomLevels)); - const base::DictionaryValue* values = NULL; + const base::Value* dictionaries = + prefs->GetDictionary(prefs::kPartitionPerHostZoomLevels); std::string partition_key = ChromeZoomLevelPrefs::GetPartitionKeyForTesting(base::FilePath()); - dictionaries->GetDictionary(partition_key, &values); + const base::Value* values = dictionaries->FindDictPath(partition_key); std::vector<std::string> results; if (values) { - for (base::DictionaryValue::Iterator it(*values); - !it.IsAtEnd(); it.Advance()) - results.push_back(it.key()); + for (const auto it : values->DictItems()) + results.push_back(it.first); } return results; }
diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc index dce671bb..e7d59e6 100644 --- a/chrome/browser/profiles/profile_manager.cc +++ b/chrome/browser/profiles/profile_manager.cc
@@ -518,7 +518,7 @@ const ProfileInfo* profile_info = path_and_profile_info.second.get(); Profile* profile = profile_info->GetRawProfile(); - if (profile && profile->IsSystemProfile()) + if (profile && !profile->IsRegularProfile()) continue; for (const auto& origin_and_count : profile_info->keep_alives) { @@ -2109,7 +2109,8 @@ ProfileInfo* info_raw = info.get(); profiles_info_.insert( std::make_pair(profile_ptr->GetPath(), std::move(info))); - ever_loaded_profiles_.insert(profile_ptr->GetPath()); + if (profile_ptr->IsRegularProfile()) + ever_loaded_profiles_.insert(profile_ptr->GetPath()); return info_raw; } @@ -2120,7 +2121,8 @@ auto info = ProfileInfo::FromUnownedProfile(profile); ProfileInfo* info_raw = info.get(); profiles_info_.insert(std::make_pair(path, std::move(info))); - ever_loaded_profiles_.insert(path); + if (profile->IsRegularProfile()) + ever_loaded_profiles_.insert(path); return info_raw; }
diff --git a/chrome/browser/profiles/profile_manager.h b/chrome/browser/profiles/profile_manager.h index 32096da..6b23be2 100644 --- a/chrome/browser/profiles/profile_manager.h +++ b/chrome/browser/profiles/profile_manager.h
@@ -589,6 +589,8 @@ // Set of profile dirs that were loaded during this browsing session at some // point (or are currently loaded). This is used to measure memory savings // from DestroyProfileOnBrowserClose. + // + // Doesn't include the System and Guest profile paths. std::set<base::FilePath> ever_loaded_profiles_; // Runs a task every 30 minutes to record the number of zombie & non-zombie
diff --git a/chrome/browser/resources/BUILD.gn b/chrome/browser/resources/BUILD.gn index aa466347..94dfd32f1 100644 --- a/chrome/browser/resources/BUILD.gn +++ b/chrome/browser/resources/BUILD.gn
@@ -163,9 +163,6 @@ if (enable_nacl) { deps += [ "about_nacl:closure_compile" ] } - if (enable_pdf) { - deps += [ "pdf:closure_compile" ] - } if (is_android) { deps += [ "explore_sites_internals:closure_compile",
diff --git a/chrome/browser/resources/chromeos/login/screens/common/user_creation.html b/chrome/browser/resources/chromeos/login/screens/common/user_creation.html index db766963..f8b2e09e 100644 --- a/chrome/browser/resources/chromeos/login/screens/common/user_creation.html +++ b/chrome/browser/resources/chromeos/login/screens/common/user_creation.html
@@ -32,8 +32,8 @@ margin-top: 16px; } </style> - <oobe-adaptive-dialog id="userCreationDialog" role="dialog" - aria-label$="[[i18nDynamic(locale, titleKey_)]]" for-step="create"> + <oobe-adaptive-dialog id="userCreationDialog" for-step="create" + role="presentation"> <iron-icon slot="icon" icon="oobe-32:googleg"></iron-icon> <h1 slot="title"> [[i18nDynamic(locale, titleKey_)]]
diff --git a/chrome/browser/resources/extensions/BUILD.gn b/chrome/browser/resources/extensions/BUILD.gn index 7762738f..81705a7 100644 --- a/chrome/browser/resources/extensions/BUILD.gn +++ b/chrome/browser/resources/extensions/BUILD.gn
@@ -100,7 +100,6 @@ "shared_vars.ts", "shortcut_input.ts", "sidebar.ts", - "site_access.ts", "toggle_row.ts", "toolbar.ts", ] @@ -140,7 +139,6 @@ "shared_vars.ts", "shortcut_input.ts", "sidebar.ts", - "site_access.ts", "toggle_row.ts", "toolbar.ts", ] @@ -206,7 +204,6 @@ "shortcut_input.ts", "shortcut_util.ts", "sidebar.ts", - "site_access.ts", "toggle_row.ts", "toolbar.ts", ]
diff --git a/chrome/browser/resources/extensions/detail_view.html b/chrome/browser/resources/extensions/detail_view.html index 967e53f..65f5b040 100644 --- a/chrome/browser/resources/extensions/detail_view.html +++ b/chrome/browser/resources/extensions/detail_view.html
@@ -314,46 +314,33 @@ </ul> </div> </div> - <!-- TODO(crbug.com/1253673): Add a "learn more" question mark with link at - the end of the sublabel. --> - <cr-link-row class="hr" - id="extensionsSiteAccessLink" - hidden$="[[!showSiteAccessLink_(data.*)]]" - label="$i18n{newItemSiteAccessTitle}" - sub-label="$i18n{itemSiteAccessSublabel}" - on-click="onSiteAccessTap_" - role-description="$i18n{subpageArrowRoleDescription}"> - </cr-link-row> - <template is="dom-if" if="[[!showSiteAccessLink_(data.*)]]"> - <div class="section hr"> - <div class="section-title" role="heading" aria-level="2"> - [[getSiteAccessTitle_(useNewSiteAccessPage)]] - </div> - <div class="section-content"> - <span id="no-site-access" - hidden$="[[showSiteAccessContent_(data.*)]]"> - $i18n{itemSiteAccessEmpty} - </span> - <template is="dom-if" - if="[[showFreeformRuntimeHostPermissions_(data.*)]]"> - <extensions-runtime-host-permissions - permissions="[[data.permissions.runtimeHostPermissions]]" - use-new-site-access-page="[[useNewSiteAccessPage]]" - delegate="[[delegate]]" - item-id="[[data.id]]"> - </extensions-runtime-host-permissions> - </template> - <template is="dom-if" - if="[[showHostPermissionsToggleList_(data.*)]]"> - <extensions-host-permissions-toggle-list - permissions="[[data.permissions.runtimeHostPermissions]]" - delegate="[[delegate]]" - item-id="[[data.id]]"> - </extensions-host-permissions-toggle-list> - </template> - </div> + <div class="section hr"> + <div class="section-title" role="heading" aria-level="2"> + $i18n{itemSiteAccess} </div> - </template> + <div class="section-content"> + <span id="no-site-access" + hidden$="[[showSiteAccessContent_(data.*)]]"> + $i18n{itemSiteAccessEmpty} + </span> + <template is="dom-if" + if="[[showFreeformRuntimeHostPermissions_(data.*)]]"> + <extensions-runtime-host-permissions + permissions="[[data.permissions.runtimeHostPermissions]]" + delegate="[[delegate]]" + item-id="[[data.id]]"> + </extensions-runtime-host-permissions> + </template> + <template is="dom-if" + if="[[showHostPermissionsToggleList_(data.*)]]"> + <extensions-host-permissions-toggle-list + permissions="[[data.permissions.runtimeHostPermissions]]" + delegate="[[delegate]]" + item-id="[[data.id]]"> + </extensions-host-permissions-toggle-list> + </template> + </div> + </div> <template is="dom-if" if="[[hasDependentExtensions_(data.dependentExtensions.splices)]]"> <div class="section hr">
diff --git a/chrome/browser/resources/extensions/detail_view.ts b/chrome/browser/resources/extensions/detail_view.ts index f8088d1..949349a 100644 --- a/chrome/browser/resources/extensions/detail_view.ts +++ b/chrome/browser/resources/extensions/detail_view.ts
@@ -78,9 +78,6 @@ /** Whether the user has enabled the UI's developer mode. */ inDevMode: Boolean, - /** Whether the extension's site access will be shown in a new page. */ - useNewSiteAccessPage: Boolean, - /** Whether "allow in incognito" option should be shown. */ incognitoAvailable: Boolean, @@ -99,7 +96,6 @@ data: chrome.developerPrivate.ExtensionInfo; delegate: ItemDelegate; inDevMode: boolean; - useNewSiteAccessPage: boolean; incognitoAvailable: boolean; showActivityLog: boolean; fromActivityLog: boolean; @@ -134,8 +130,6 @@ * Focuses the back button when page is loaded. */ private onViewEnterStart_() { - // TODO(crbug.com/1253673): Focus on the site access link if we returned to - // this view from that subpage. const elementToFocus = this.fromActivityLog ? this.$.extensionsActivityLogLink : this.$.closeButton; @@ -156,11 +150,6 @@ navigation.navigateTo({page: Page.ACTIVITY_LOG, extensionId: this.data.id}); } - private onSiteAccessTap_() { - navigation.navigateTo( - {page: Page.EXTENSION_SITE_ACCESS, extensionId: this.data.id}); - } - private getDescription_(description: string, fallback: string): string { return description || fallback; } @@ -301,12 +290,6 @@ getItemSourceString(getItemSource(this.data)); } - private getSiteAccessTitle_(): string { - return loadTimeData.getString( - this.useNewSiteAccessPage ? 'newItemSiteAccessTitle' : - 'itemSiteAccess'); - } - private hasPermissions_(): boolean { return this.data.permissions.simplePermissions.length > 0 || this.hasRuntimeHostPermissions_(); @@ -321,10 +304,6 @@ this.showHostPermissionsToggleList_(); } - private showSiteAccessLink_(): boolean { - return this.hasRuntimeHostPermissions_() && this.useNewSiteAccessPage; - } - private showFreeformRuntimeHostPermissions_(): boolean { return this.hasRuntimeHostPermissions_() && this.data.permissions.runtimeHostPermissions!.hasAllHosts;
diff --git a/chrome/browser/resources/extensions/manager.html b/chrome/browser/resources/extensions/manager.html index 123e305..d8f993e 100644 --- a/chrome/browser/resources/extensions/manager.html +++ b/chrome/browser/resources/extensions/manager.html
@@ -56,7 +56,6 @@ <template> <extensions-detail-view delegate="[[delegate]]" slot="view" in-dev-mode="[[inDevMode]]" - use-new-site-access-page="[[useNewSiteAccessPage]]" from-activity-log="[[fromActivityLog_]]" show-activity-log="[[showActivityLog]]" incognito-available="[[incognitoAvailable_]]" @@ -71,13 +70,6 @@ </extensions-activity-log> </template> </cr-lazy-render> - <cr-lazy-render id="extension-site-access"> - <template> - <extensions-site-access slot="view" - extension-info="[[extensionSiteAccessItem_]]"> - </extensions-site-access> - </template> - </cr-lazy-render> <cr-lazy-render id="keyboard-shortcuts"> <template> <extensions-keyboard-shortcuts delegate="[[delegate]]" slot="view"
diff --git a/chrome/browser/resources/extensions/manager.ts b/chrome/browser/resources/extensions/manager.ts index 5846b68..ed24e15 100644 --- a/chrome/browser/resources/extensions/manager.ts +++ b/chrome/browser/resources/extensions/manager.ts
@@ -20,16 +20,15 @@ import './load_error.js'; import './options_dialog.js'; import './sidebar.js'; -import './site_access.js'; import './toolbar.js'; // <if expr="chromeos"> import './kiosk_dialog.js'; // </if> -import {CrViewManagerElement} from 'chrome://resources/cr_elements/cr_view_manager/cr_view_manager.js'; import {assert, assertNotReached} from 'chrome://resources/js/assert.m.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {CrViewManagerElement} from 'chrome://resources/cr_elements/cr_view_manager/cr_view_manager.js'; import {ActivityLogExtensionPlaceholder} from './activity_log/activity_log.js'; import {ExtensionsDetailViewElement} from './detail_view.js'; @@ -108,11 +107,6 @@ value: () => loadTimeData.getBoolean('showActivityLog'), }, - useNewSiteAccessPage: { - type: Boolean, - value: () => loadTimeData.getBoolean('useNewSiteAccessPage'), - }, - devModeControlledByPolicy: { type: Boolean, value: false, @@ -154,12 +148,6 @@ */ activityLogItem_: Object, - /** - * The item that provides some information about the current extension - * for the extension site access view subpage. See also errorPageItem_. - */ - extensionSiteAccessItem_: Object, - extensions_: Array, apps_: Array, @@ -206,7 +194,6 @@ delegate: Service; inDevMode: boolean; showActivityLog: boolean; - useNewSiteAccessPage: boolean; devModeControlledByPolicy: boolean; private isChildAccount_: boolean; private incognitoAvailable_: boolean; @@ -215,7 +202,6 @@ private detailViewItem_?: chrome.developerPrivate.ExtensionInfo; private activityLogItem_?: chrome.developerPrivate.ExtensionInfo| ActivityLogExtensionPlaceholder; - private extensionSiteAccessItem_?: chrome.developerPrivate.ExtensionInfo; private extensions_: Array<chrome.developerPrivate.ExtensionInfo>; private apps_: Array<chrome.developerPrivate.ExtensionInfo>; private didInitPage_: boolean; @@ -479,11 +465,6 @@ this.activityLogItem_ && this.activityLogItem_.id === item.id && this.currentPage_!.page === Page.ACTIVITY_LOG) { this.activityLogItem_ = item; - } else if ( - this.extensionSiteAccessItem_ && - this.extensionSiteAccessItem_.id === item.id && - this.currentPage_!.page === Page.EXTENSION_SITE_ACCESS) { - this.extensionSiteAccessItem_ = item; } } @@ -503,8 +484,7 @@ // We should never try and remove a non-existent item. assert(index >= 0); this.splice(listId, index, 1); - if ((this.currentPage_!.page === Page.EXTENSION_SITE_ACCESS || - this.currentPage_!.page === Page.ACTIVITY_LOG || + if ((this.currentPage_!.page === Page.ACTIVITY_LOG || this.currentPage_!.page === Page.DETAILS || this.currentPage_!.page === Page.ERRORS) && this.currentPage_!.extensionId === itemId) { @@ -572,18 +552,6 @@ } this.activityLogItem_ = data ? assert(data) : activityLogPlaceholder; - } else if (toPage === Page.EXTENSION_SITE_ACCESS) { - // TODO(crbug.com/1253673): Redirect back to details page if the extension - // does not have any runtime host permissions. - if (!this.useNewSiteAccessPage) { - // Redirect back to the details page if we try to view the new extension - // site access page of an extension but the flag is not set. - navigation.replaceWith( - {page: Page.DETAILS, extensionId: newPage.extensionId}); - return; - } - - this.extensionSiteAccessItem_ = assert(data); } if (fromPage !== toPage) { @@ -647,8 +615,7 @@ const viewType = (e.composedPath()[0] as HTMLElement).tagName; if (viewType === 'EXTENSIONS-ITEM-LIST' || viewType === 'EXTENSIONS-KEYBOARD-SHORTCUTS' || - viewType === 'EXTENSIONS-ACTIVITY-LOG' || - viewType === 'EXTENSIONS-SITE-ACCESS') { + viewType === 'EXTENSIONS-ACTIVITY-LOG') { return; }
diff --git a/chrome/browser/resources/extensions/navigation_helper.ts b/chrome/browser/resources/extensions/navigation_helper.ts index 36606f4..9ed4800 100644 --- a/chrome/browser/resources/extensions/navigation_helper.ts +++ b/chrome/browser/resources/extensions/navigation_helper.ts
@@ -13,7 +13,6 @@ LIST = 'items-list', DETAILS = 'details-view', ACTIVITY_LOG = 'activity-log', - EXTENSION_SITE_ACCESS = 'extension-site-access', SHORTCUTS = 'keyboard-shortcuts', ERRORS = 'error-page', } @@ -92,10 +91,6 @@ if (id) { return {page: Page.ACTIVITY_LOG, extensionId: id}; } - id = search.get('siteAccess'); - if (id) { - return {page: Page.EXTENSION_SITE_ACCESS, extensionId: id}; - } id = search.get('options'); if (id) { return {page: Page.DETAILS, extensionId: id, subpage: Dialog.OPTIONS}; @@ -187,9 +182,6 @@ path = '/?id=' + entry.extensionId; } break; - case Page.EXTENSION_SITE_ACCESS: - path = '/?siteAccess=' + entry.extensionId; - break; case Page.SHORTCUTS: path = '/shortcuts'; break;
diff --git a/chrome/browser/resources/extensions/runtime_host_permissions.html b/chrome/browser/resources/extensions/runtime_host_permissions.html index ced1400..c972ce0 100644 --- a/chrome/browser/resources/extensions/runtime_host_permissions.html +++ b/chrome/browser/resources/extensions/runtime_host_permissions.html
@@ -64,7 +64,7 @@ <div id="section-heading"> <div id="section-heading-heading"> <span id="section-heading-text"> - [[getHostPermissionsHeading_(useNewSiteAccessPage)]] + [[getHostPermissionsHeading_(extensionsMenuAccessControlEnabled_)]] </span> <a class="link-icon-button" aria-label="$i18n{learnMore}" href="$i18n{hostPermissionsLearnMoreLink}" target="_blank" @@ -77,7 +77,7 @@ <select id="host-access" class="md-select" on-change="onHostAccessChange_" value="[[permissions.hostAccess]]" aria-labelledby="section-heading-text"> - <template is="dom-if" if="[[!useNewSiteAccessPage]]"> + <template is="dom-if" if="[[!extensionsMenuAccessControlEnabled_]]"> <option value="[[HostAccess_.ON_CLICK]]"> $i18n{hostAccessOnClick} </option> @@ -88,7 +88,7 @@ $i18n{hostAccessOnAllSites} </option> </template> - <template is="dom-if" if="[[useNewSiteAccessPage]]"> + <template is="dom-if" if="[[extensionsMenuAccessControlEnabled_]]"> <option value="[[HostAccess_.ON_CLICK]]"> $i18n{newHostAccessOnClick} </option>
diff --git a/chrome/browser/resources/extensions/runtime_host_permissions.ts b/chrome/browser/resources/extensions/runtime_host_permissions.ts index 315efb6f..4710acb1 100644 --- a/chrome/browser/resources/extensions/runtime_host_permissions.ts +++ b/chrome/browser/resources/extensions/runtime_host_permissions.ts
@@ -59,8 +59,6 @@ delegate: Object, - useNewSiteAccessText: Boolean, - /** * Whether the dialog to add a new host permission is shown. */ @@ -127,13 +125,21 @@ type: Object, value: chrome.developerPrivate.HostAccess, }, + + /** + * Whether the new site access menu should be shown. + */ + extensionsMenuAccessControlEnabled_: { + type: Boolean, + value: () => + loadTimeData.getBoolean('extensionsMenuAccessControlEnabled'), + }, }; } permissions: chrome.developerPrivate.RuntimeHostPermissions; itemId: string; delegate: ItemDelegate; - useNewSiteAccessText: boolean; private showHostDialog_: boolean; private hostDialogModel_: string|null; private hostDialogAnchorElement_: HTMLElement|null; @@ -141,6 +147,7 @@ private actionMenuAnchorElement_: HTMLElement|null; private oldHostAccess_: string|null; private revertingHostAccess_: boolean; + private extensionsMenuAccessControlEnabled_: boolean; private onHostAccessChange_() { const selectMenu = this.$['host-access']; @@ -185,14 +192,14 @@ private getHostPermissionsHeading_(): string { return loadTimeData.getString( - this.useNewSiteAccessText ? 'newHostPermissionsHeading' : - 'hostPermissionsHeading'); + this.extensionsMenuAccessControlEnabled_ ? 'newHostPermissionsHeading' : + 'hostPermissionsHeading'); } private showSpecificSites_(): boolean { // TODO(crbug.com/1253673): Show a different "customize for each site" menu // for the new site access menu. - return !this.useNewSiteAccessText && + return !this.extensionsMenuAccessControlEnabled_ && this.permissions.hostAccess === chrome.developerPrivate.HostAccess.ON_SPECIFIC_SITES; }
diff --git a/chrome/browser/resources/extensions/site_access.html b/chrome/browser/resources/extensions/site_access.html deleted file mode 100644 index e3e0f89a..0000000 --- a/chrome/browser/resources/extensions/site_access.html +++ /dev/null
@@ -1,20 +0,0 @@ -<style include="cr-icons cr-shared-style shared-style"> - #icon { - height: 24px; - margin-inline-end: 12px; - margin-inline-start: 16px; - width: 24px; - } -</style> -<div class="page-container" id="container"> - <div class="page-content"> - <div class="page-header"> - <cr-icon-button class="icon-arrow-back no-overlap" id="closeButton" - aria-label="$i18n{back}" on-click="onCloseButtonClick_"> - </cr-icon-button> - <img id="icon" src="[[extensionInfo.iconUrl]]" alt="" - hidden="[[extensionInfo.isPlaceholder]]"> - <div class="cr-title-text">[[extensionInfo.name]]</div> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/extensions/site_access.ts b/chrome/browser/resources/extensions/site_access.ts deleted file mode 100644 index 18b1c1e2..0000000 --- a/chrome/browser/resources/extensions/site_access.ts +++ /dev/null
@@ -1,70 +0,0 @@ -// Copyright 2021 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 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js'; -import 'chrome://resources/cr_elements/cr_icons_css.m.js'; -import 'chrome://resources/cr_elements/shared_style_css.m.js'; -import 'chrome://resources/cr_elements/shared_vars_css.m.js'; -import './strings.m.js'; -import './shared_style.js'; -import './shared_vars.js'; - -import {CrContainerShadowMixin} from 'chrome://resources/cr_elements/cr_container_shadow_mixin.js'; -import {focusWithoutInk} from 'chrome://resources/js/cr/ui/focus_without_ink.m.js'; -import {I18nMixin, I18nMixinInterface} from 'chrome://resources/js/i18n_mixin.js'; -import {afterNextRender, html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; - -import {navigation, Page} from './navigation_helper.js'; - -interface ExtensionsSiteAccessElement { - $: { - closeButton: HTMLElement, - }; -} - -const ExtensionsSiteAccessElementBase = - I18nMixin(CrContainerShadowMixin(PolymerElement)) as - {new (): PolymerElement & I18nMixinInterface}; - -class ExtensionsSiteAccessElement extends ExtensionsSiteAccessElementBase { - static get is() { - return 'extensions-site-access'; - } - - static get template() { - return html`{__html_template__}`; - } - - static get properties() { - return { - /** - * The underlying ExtensionInfo for the extension site access items being - * displayed. - */ - extensionInfo: Object, - }; - } - - extensionInfo: chrome.developerPrivate.ExtensionInfo; - - ready() { - super.ready(); - this.addEventListener('view-enter-start', this.onViewEnterStart_); - } - - /** - * Focuses the back button when page is loaded. - */ - private onViewEnterStart_() { - afterNextRender(this, () => focusWithoutInk(this.$.closeButton)); - } - - private onCloseButtonClick_() { - navigation.navigateTo( - {page: Page.DETAILS, extensionId: this.extensionInfo.id}); - } -} - -customElements.define( - ExtensionsSiteAccessElement.is, ExtensionsSiteAccessElement);
diff --git a/chrome/browser/resources/history/history_clusters/top_visit.html b/chrome/browser/resources/history/history_clusters/top_visit.html index 51d5d727..44aeffda 100644 --- a/chrome/browser/resources/history/history_clusters/top_visit.html +++ b/chrome/browser/resources/history/history_clusters/top_visit.html
@@ -73,7 +73,7 @@ } </style> <url-visit visit="[[visit]]" cluster-index="[[clusterIndex]]" index="0" - has-related-visits$="[[hasRelatedVisits_]]" is-top-visit> + is-top-visit> </url-visit> <template is="dom-repeat" items="[[visibleRelatedVisits_]]"> <url-visit visit="[[item]]" cluster-index="[[clusterIndex]]"
diff --git a/chrome/browser/resources/history/history_clusters/top_visit.ts b/chrome/browser/resources/history/history_clusters/top_visit.ts index cdbef03..d2aba93 100644 --- a/chrome/browser/resources/history/history_clusters/top_visit.ts +++ b/chrome/browser/resources/history/history_clusters/top_visit.ts
@@ -68,14 +68,6 @@ }, /** - * Whether there are related visits. - */ - hasRelatedVisits_: { - type: Boolean, - computed: 'computeHasRelatedVisits_(visit.relatedVisits.*)', - }, - - /** * The default-hidden related visits. */ hiddenRelatedVisits_: { @@ -100,7 +92,6 @@ visit: URLVisit; private expanded_: boolean; private hiddenRelatedVisits_: Array<URLVisit>; - private relatedVisits_: Array<URLVisit>; //============================================================================ // Event handlers @@ -143,10 +134,6 @@ return this.hiddenRelatedVisits_.length > 0; } - private computeHasRelatedVisits_(): boolean { - return this.visit.relatedVisits.length > 0; - } - private computeHiddenRelatedVisits_(): Array<URLVisit> { return this.visit.relatedVisits.filter((visit: URLVisit) => { return visit.belowTheFold;
diff --git a/chrome/browser/resources/history/history_clusters/url_visit.html b/chrome/browser/resources/history/history_clusters/url_visit.html index d5afe35..468dd82 100644 --- a/chrome/browser/resources/history/history_clusters/url_visit.html +++ b/chrome/browser/resources/history/history_clusters/url_visit.html
@@ -121,11 +121,6 @@ :host([is-top-visit]) #actionMenuButton { --cr-icon-button-icon-size: 24px; } - - :host(:not([has-related-visits])) #removeAllButton, - :host(:not([has-related-visits])) #openAllButton { - display: none; - } </style> <div id="header" on-click="onClick_" on-auxclick="onAuxClick_" on-keydown="onKeydown_"> @@ -160,14 +155,16 @@ <template> <cr-action-menu role-description="$i18n{actionMenuDescription}"> <button id="openAllButton" class="dropdown-item" - on-click="onOpenAllButtonClick_"> + on-click="onOpenAllButtonClick_" + hidden="[[!visit.relatedVisits.length]]"> $i18n{openAllInTabGroup} </button> <button class="dropdown-item" on-click="onRemoveSelfButtonClick_"> $i18n{removeFromHistory} </button> <button id="removeAllButton" class="dropdown-item" - on-click="onRemoveAllButtonClick_"> + on-click="onRemoveAllButtonClick_" + hidden="[[!visit.relatedVisits.length]]"> $i18n{removeAllFromHistory} </button> </cr-action-menu>
diff --git a/chrome/browser/resources/pdf/BUILD.gn b/chrome/browser/resources/pdf/BUILD.gn index 99aecf0e8..0d68ac5 100644 --- a/chrome/browser/resources/pdf/BUILD.gn +++ b/chrome/browser/resources/pdf/BUILD.gn
@@ -4,23 +4,21 @@ import("//chrome/common/features.gni") import("//pdf/features.gni") -import("//third_party/closure_compiler/compile_js.gni") import("//tools/grit/grit_rule.gni") import("//tools/grit/preprocess_if_expr.gni") import("//tools/polymer/html_to_js.gni") +import("//tools/typescript/ts_library.gni") import("//ui/webui/resources/tools/generate_grd.gni") import("../tools/optimize_webui.gni") -preprocess_folder = "preprocessed" -preprocess_manifest = "preprocessed_manifest.json" -preprocess_gen_manifest = "preprocessed_gen_manifest.json" - assert(enable_pdf, "enable_pdf check failed") +preprocess_folder = "preprocessed" +tsc_folder = "tsc" + preprocess_if_expr("preprocess") { in_folder = "./" out_folder = "$target_gen_dir/$preprocess_folder" - out_manifest = "$target_gen_dir/$preprocess_manifest" defines = [ "enable_ink=$enable_ink" ] in_files = [ "bookmark_type.js", @@ -50,7 +48,6 @@ deps = [ ":web_components" ] in_folder = target_gen_dir out_folder = "$target_gen_dir/$preprocess_folder" - out_manifest = "$target_gen_dir/$preprocess_gen_manifest" defines = [ "enable_ink=$enable_ink" ] in_files = [ "elements/icons.js", @@ -92,14 +89,13 @@ optimize_webui("build") { host = "chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai" - input = rebase_path("$target_gen_dir/$preprocess_folder", root_build_dir) + input = rebase_path("$target_gen_dir/$tsc_folder", root_build_dir) js_out_files = [ "pdf_viewer_wrapper.rollup.js" ] js_module_in_files = [ "pdf_viewer_wrapper.js" ] out_manifest = "$target_gen_dir/$build_manifest" deps = [ - ":preprocess", - ":preprocess_generated", + ":build_ts", "../../../../ui/webui/resources:preprocess", ] excludes = [ @@ -132,7 +128,6 @@ generate_grd("build_grd") { input_files = [ - "browser_api.js", "index.css", "index.html", "main.js", @@ -146,19 +141,14 @@ input_files_base_dir = rebase_path(".", "//") if (optimize_webui) { + input_files += [ "browser_api.js" ] deps = [ ":build" ] resource_path_rewrites = [ "pdf_viewer_wrapper.rollup.js|pdf_viewer_wrapper.js" ] manifest_files = [ "$target_gen_dir/$build_manifest" ] } else { - deps = [ - ":preprocess", - ":preprocess_generated", - ] - manifest_files = [ - "$target_gen_dir/$preprocess_manifest", - "$target_gen_dir/$preprocess_gen_manifest", - ] + deps = [ ":build_ts" ] + manifest_files = [ "$target_gen_dir/tsconfig.manifest" ] } deps += [ ":build_internal_plugin" ] @@ -202,234 +192,97 @@ ] } -group("closure_compile") { - deps = [ - ":closure_compile_local", - "elements:closure_compile", +copy("copy_files") { + sources = [ "browser_api.js" ] + outputs = [ "$target_gen_dir/$preprocess_folder/{{source_file_part}}" ] +} + +# Copies transpiled JS files that are used by Print Preview to the expected +# location used by Print Preview's build configuration. +# TODO(crbug.com/1260303): Print Preview is implemented in TS, so figure out a +# better way expose these files to Print Preview after the PDF viewer migrates +# to TS. +copy("copy_print_preview_files") { + sources = [ + "$target_gen_dir/tsc/constants.js", + "$target_gen_dir/tsc/controller.js", + "$target_gen_dir/tsc/gesture_detector.js", + "$target_gen_dir/tsc/metrics.js", + "$target_gen_dir/tsc/open_pdf_params_parser.js", + "$target_gen_dir/tsc/pdf_scripting_api.js", + "$target_gen_dir/tsc/pdf_viewer_base.js", + "$target_gen_dir/tsc/pdf_viewer_utils.js", + "$target_gen_dir/tsc/viewport.js", + "$target_gen_dir/tsc/viewport_scroller.js", + "$target_gen_dir/tsc/zoom_manager.js", ] + outputs = [ "$target_gen_dir//{{source_file_part}}" ] + deps = [ ":build_ts" ] +} + +ts_library("build_ts") { + root_dir = "$target_gen_dir/$preprocess_folder" + out_dir = "$target_gen_dir/$tsc_folder" + tsconfig_base = "tsconfig_base.json" + + # TODO(crbug.com/1260303): Factor out these source files to a .gni file to + # reduce redundancy. + in_files = [ + "bookmark_type.js", + "browser_api.js", + "constants.js", + "controller.js", + "elements/icons.js", + "elements/shared-css.js", + "elements/shared-vars.js", + "elements/viewer-bookmark.js", + "elements/viewer-document-outline.js", + "elements/viewer-download-controls.js", + "elements/viewer-error-dialog.js", + "elements/viewer-page-selector.js", + "elements/viewer-password-dialog.js", + "elements/viewer-pdf-sidenav.js", + "elements/viewer-properties-dialog.js", + "elements/viewer-thumbnail-bar.js", + "elements/viewer-thumbnail.js", + "elements/viewer-toolbar.js", + "gesture_detector.js", + "local_storage_proxy.js", + "metrics.js", + "navigator.js", + "open_pdf_params_parser.js", + "pdf_scripting_api.js", + "pdf_viewer_base.js", + "pdf_viewer.js", + "pdf_viewer_shared_style.js", + "pdf_viewer_utils.js", + "pdf_viewer_wrapper.js", + "viewport.js", + "viewport_scroller.js", + "zoom_manager.js", + ] + if (enable_ink) { - deps += [ "ink:closure_compile" ] + in_files += [ + "annotation_tool.js", + "ink_controller.js", + "ink/drawing_canvas_externs.js", + "ink/ink_api.js", + "elements/viewer-annotations-bar.js", + "elements/viewer-annotations-mode-dialog.js", + "elements/viewer-ink-host.js", + "elements/viewer-pen-options.js", + "elements/viewer-toolbar-dropdown.js", + ] } -} - -js_library("annotation_tool") { -} - -js_library("bookmark_type") { -} - -js_library("browser_api") { - deps = [ "//ui/webui/resources/js:assert.m" ] - externs_list = [ - "$externs_path/chrome_extensions.js", - "$externs_path/mime_handler_private.js", - ] -} - -js_library("constants") { -} - -js_library("gesture_detector") { + definitions = [ "//tools/typescript/definitions/metrics_private.d.ts" ] deps = [ - ":constants", - "//ui/webui/resources/js/cr:event_target.m", + "//third_party/polymer/v3_0:library", + "//ui/webui/resources:library", ] -} - -js_library("open_pdf_params_parser") { - deps = [ ":constants" ] - externs_list = [ "$externs_path/pending.js" ] -} - -js_library("pdf_scripting_api") { -} - -js_library("viewport_scroller") { -} - -js_library("viewport") { - deps = [ - ":constants", - ":gesture_detector", - ":internal_plugin", - ":zoom_manager", - "//ui/webui/resources/js:assert.m", - "//ui/webui/resources/js:event_tracker.m", - "//ui/webui/resources/js:util.m", - ] - externs_list = [ "$externs_path/pending.js" ] -} - -js_library("zoom_manager") { - deps = [ - ":browser_api", - "//ui/webui/resources/js/cr:event_target.m", - ] -} - -js_library("metrics") { - deps = [ ":constants" ] - externs_list = [ "$externs_path/metrics_private.js" ] -} - -js_library("navigator") { - deps = [ - ":browser_api", - ":open_pdf_params_parser", - ":viewport", - ] -} - -js_library("toolbar_manager") { - deps = [ - "elements:viewer-zoom-toolbar", - "//ui/webui/resources/js:util.m", - ] -} - -js_library("ink_controller") { - deps = [ - ":annotation_tool", - ":controller", - ":viewport", - "//ui/webui/resources/js/cr:event_target.m", - ] -} - -js_library("local_storage_proxy") { -} - -js_library("controller") { - deps = [ - ":gesture_detector", - ":internal_plugin", - ":viewport", - "//ui/webui/resources/js:assert.m", - "//ui/webui/resources/js:load_time_data.m", - "//ui/webui/resources/js:promise_resolver.m", - "//ui/webui/resources/js/cr:event_target.m", - ] -} - -js_library("internal_plugin") { -} - -js_library("pdf_internal_plugin_wrapper") { - deps = [ ":gesture_detector" ] -} - -js_library("pdf_viewer_base") { - deps = [ - ":browser_api", - ":constants", - ":controller", - ":metrics", - ":pdf_scripting_api", - ":pdf_viewer_utils", - ":viewport", - ":viewport_scroller", - "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - "//ui/webui/resources/js:assert.m", - "//ui/webui/resources/js:event_tracker.m", - "//ui/webui/resources/js:load_time_data.m", - "//ui/webui/resources/js:promise_resolver.m", - "//ui/webui/resources/js:util.m", - ] - externs_list = [ "$externs_path/resources_private.js" ] -} - -js_library("pdf_viewer") { - deps = [ - ":bookmark_type", - ":browser_api", - ":constants", - ":controller", - ":ink_controller", - ":local_storage_proxy", - ":metrics", - ":navigator", - ":pdf_scripting_api", - ":pdf_viewer_base", - ":pdf_viewer_utils", - "elements:viewer-bookmark", - "elements:viewer-error-dialog", - "elements:viewer-password-dialog", - "elements:viewer-pdf-sidenav", - "elements:viewer-properties-dialog", - "elements:viewer-toolbar", - "//ui/webui/resources/js:assert.m", - "//ui/webui/resources/js:event_tracker.m", - "//ui/webui/resources/js:load_time_data.m", - "//ui/webui/resources/js:promise_resolver.m", - "//ui/webui/resources/js:util.m", - ] - externs_list = [ "$externs_path/resources_private.js" ] -} - -js_library("pdf_viewer_wrapper") { - deps = [ ":pdf_viewer" ] -} - -js_library("pdf_viewer_utils") { - deps = [ - ":controller", - ":viewport", - "//ui/webui/resources/js:util.m", - ] -} - -js_library("pdf_viewer_pp") { - deps = [ - ":constants", - ":controller", - ":pdf_scripting_api", - ":pdf_viewer_base", - ":pdf_viewer_utils", - ":toolbar_manager", - ":viewport", - "elements:viewer-error-dialog", - "elements:viewer-page-indicator", - "elements:viewer-zoom-toolbar", - "//ui/webui/resources/js:assert.m", - "//ui/webui/resources/js:event_tracker.m", - "//ui/webui/resources/js:load_time_data.m", - "//ui/webui/resources/js:promise_resolver.m", - "//ui/webui/resources/js:util.m", - ] - externs_list = [ "$externs_path/resources_private.js" ] -} - -js_library("main") { - deps = [ - ":browser_api", - ":pdf_viewer", - ] -} - -js_type_check("closure_compile_local") { - is_polymer3 = true - deps = [ - ":annotation_tool", - ":browser_api", - ":constants", - ":controller", - ":gesture_detector", - ":ink_controller", - ":local_storage_proxy", - ":main", - ":metrics", - ":navigator", - ":open_pdf_params_parser", - ":pdf_internal_plugin_wrapper", - ":pdf_scripting_api", - ":pdf_viewer", - ":pdf_viewer_base", - ":pdf_viewer_pp", - ":pdf_viewer_utils", - ":pdf_viewer_wrapper", - ":toolbar_manager", - ":viewport", - ":viewport_scroller", - ":zoom_manager", + extra_deps = [ + ":copy_files", + ":preprocess", + ":preprocess_generated", ] }
diff --git a/chrome/browser/resources/pdf/elements/BUILD.gn b/chrome/browser/resources/pdf/elements/BUILD.gn index 8c63a4e..7ab835c 100644 --- a/chrome/browser/resources/pdf/elements/BUILD.gn +++ b/chrome/browser/resources/pdf/elements/BUILD.gn
@@ -3,177 +3,8 @@ # found in the LICENSE file. import("//pdf/features.gni") -import("//third_party/closure_compiler/compile_js.gni") import("//tools/polymer/html_to_js.gni") -js_type_check("closure_compile") { - is_polymer3 = true - deps = [ - ":viewer-bookmark", - ":viewer-document-outline", - ":viewer-download-controls", - ":viewer-error-dialog", - ":viewer-page-indicator", - ":viewer-page-selector", - ":viewer-password-dialog", - ":viewer-pdf-sidenav", - ":viewer-properties-dialog", - ":viewer-thumbnail", - ":viewer-thumbnail-bar", - ":viewer-toolbar", - ":viewer-zoom-button", - ":viewer-zoom-toolbar", - ] - if (enable_ink) { - deps += [ - ":viewer-annotations-bar", - ":viewer-annotations-mode-dialog", - ":viewer-ink-host", - ":viewer-pen-options", - ":viewer-toolbar-dropdown", - ] - } -} - -js_library("viewer-bookmark") { - deps = [ "..:bookmark_type" ] -} - -js_library("viewer-document-outline") { - deps = [ - ":viewer-bookmark", - "..:bookmark_type", - "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - ] -} - -js_library("viewer-download-controls") { - deps = [ - "..:constants", - "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - "//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu", - ] -} - -js_library("viewer-error-dialog") { - deps = [ "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog.m" ] -} - -js_library("viewer-annotations-bar") { - deps = [ - ":viewer-pen-options", - ":viewer-toolbar-dropdown", - "..:annotation_tool", - "..:ink_controller", - "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - "//ui/webui/resources/js:assert.m", - "//ui/webui/resources/js:event_tracker.m", - ] -} - -js_library("viewer-annotations-mode-dialog") { - deps = [ - "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog.m", - ] -} - -if (enable_ink) { - js_library("viewer-ink-host") { - deps = [ - "..:metrics", - "..:viewport", - "../ink:ink_api", - ] - } -} - -js_library("viewer-page-indicator") { - deps = [ - "//ui/webui/resources/js:assert.m", - "//ui/webui/resources/js:util.m", - ] -} - -js_library("viewer-page-selector") { -} - -js_library("viewer-password-dialog") { - deps = [ - "//ui/webui/resources/cr_elements/cr_button:cr_button.m", - "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog.m", - "//ui/webui/resources/cr_elements/cr_input:cr_input.m", - ] -} - -js_library("viewer-pdf-sidenav") { - deps = [ - ":viewer-document-outline", - ":viewer-thumbnail-bar", - "..:metrics", - "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m", - ] -} - -js_library("viewer-pen-options") { -} - -js_library("viewer-properties-dialog") { - deps = [ - "..:constants", - "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog.m", - ] -} - -js_library("viewer-thumbnail") { - deps = [ - "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - "//ui/webui/resources/js:assert.m", - ] -} - -js_library("viewer-thumbnail-bar") { - deps = [ - ":viewer-thumbnail", - "..:controller", - "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - "//ui/webui/resources/js:assert.m", - "//ui/webui/resources/js:event_tracker.m", - "//ui/webui/resources/js:load_time_data.m", - "//ui/webui/resources/js/cr/ui:focus_outline_manager.m", - ] -} - -js_library("viewer-toolbar") { - deps = [ - ":viewer-annotations-bar", - ":viewer-annotations-mode-dialog", - ":viewer-download-controls", - ":viewer-page-selector", - "..:metrics", - "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - ] -} - -js_library("viewer-toolbar-dropdown") { - deps = [] -} - -js_library("viewer-zoom-toolbar") { - deps = [ - ":viewer-zoom-button", - "..:constants", - "//ui/webui/resources/js:assert.m", - "//ui/webui/resources/js:util.m", - ] -} - -js_library("viewer-zoom-button") { - deps = [] -} - html_to_js("web_components") { js_files = [ "icons.js",
diff --git a/chrome/browser/resources/pdf/tsconfig_base.json b/chrome/browser/resources/pdf/tsconfig_base.json new file mode 100644 index 0000000..3e71f763 --- /dev/null +++ b/chrome/browser/resources/pdf/tsconfig_base.json
@@ -0,0 +1,9 @@ +{ + "extends": "../../../../tools/typescript/tsconfig_base.json", + "compilerOptions": { + "allowJs": true, + "noUncheckedIndexedAccess": false, + "noUnusedLocals": false, + "strictPropertyInitialization": false + } +}
diff --git a/chrome/browser/resources/print_preview/BUILD.gn b/chrome/browser/resources/print_preview/BUILD.gn index e13962e..1cfbc26 100644 --- a/chrome/browser/resources/print_preview/BUILD.gn +++ b/chrome/browser/resources/print_preview/BUILD.gn
@@ -93,39 +93,45 @@ out_manifest = "$target_gen_dir/$preprocess_pdf_manifest" in_files = [ "pdf/browser_api.js", - "pdf/constants.js", - "pdf/controller.js", - "pdf/gesture_detector.js", "pdf/index.css", "pdf/index_pp.html", "pdf/internal_plugin.js", "pdf/main.js", - "pdf/metrics.js", - "pdf/open_pdf_params_parser.js", - "pdf/pdf_scripting_api.js", - "pdf/pdf_viewer_utils.js", - "pdf/pdf_viewer_base.js", "pdf/toolbar_manager.js", - "pdf/viewport.js", - "pdf/viewport_scroller.js", - "pdf/zoom_manager.js", ] } preprocess_if_expr("preprocess_pdf_generated") { - deps = [ "../pdf:web_components" ] + deps = [ + "../pdf:copy_print_preview_files", + "../pdf:web_components", + ] in_folder = get_path_info("..", "gen_dir") out_folder = "$target_gen_dir/$preprocess_folder" out_manifest = "$target_gen_dir/$preprocess_pdf_gen_manifest" in_files = [ + # Files produced by :copy_print_preview_files. + "pdf/constants.js", + "pdf/controller.js", "pdf/elements/icons.js", "pdf/elements/shared-vars.js", "pdf/elements/viewer-error-dialog.js", + "pdf/gesture_detector.js", + "pdf/metrics.js", + "pdf/open_pdf_params_parser.js", + "pdf/pdf_scripting_api.js", + "pdf/pdf_viewer_pp.js", + "pdf/pdf_viewer_shared_style.js", + "pdf/pdf_viewer_utils.js", + "pdf/viewport.js", + "pdf/viewport_scroller.js", + "pdf/zoom_manager.js", + + # Other files (not part of PDF Viewer's ts_library). "pdf/elements/viewer-page-indicator.js", "pdf/elements/viewer-zoom-button.js", "pdf/elements/viewer-zoom-toolbar.js", - "pdf/pdf_viewer_pp.js", - "pdf/pdf_viewer_shared_style.js", + "pdf/pdf_viewer_base.js", ] }
diff --git a/chrome/browser/resources/settings/chromeos/BUILD.gn b/chrome/browser/resources/settings/chromeos/BUILD.gn index dc92c58..4a3838f 100644 --- a/chrome/browser/resources/settings/chromeos/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/BUILD.gn
@@ -347,6 +347,7 @@ "privacy_page/privacy_page_browser_proxy.js", "privacy_page/secure_dns_input.js", "privacy_page/secure_dns.js", + "relaunch_mixin.js", "setting_id_param_util.js", "settings_page_css.js", "settings_page/settings_animated_pages.js",
diff --git a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_change_device_name_dialog.html b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_change_device_name_dialog.html index 0635d58..434d63e 100644 --- a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_change_device_name_dialog.html +++ b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_change_device_name_dialog.html
@@ -6,7 +6,7 @@ [slot='button-container'] { display: flex; justify-content: flex-end; - margin: 18px 0 6px 0; + margin: 40px 0 20px 0; padding-top: 0; } @@ -14,6 +14,10 @@ color: var(--cros-text-color-alert); } + #inputContainer { + margin-top: 24px; + } + #inputInfo { background-color: var(--cros-bg-color); color: var(--cros-text-color-secondary); @@ -24,7 +28,7 @@ line-height: var(--cr-form-field-label-line-height); padding-top: 8px; position: absolute; - top: 100px; + top: 128px; width: 280px; }
diff --git a/chrome/browser/resources/settings/languages_page/languages_subpage.html b/chrome/browser/resources/settings/languages_page/languages_subpage.html index 85ffb30..92489b5 100644 --- a/chrome/browser/resources/settings/languages_page/languages_subpage.html +++ b/chrome/browser/resources/settings/languages_page/languages_subpage.html
@@ -227,3 +227,9 @@ body="[[i18n('languageManagedDialogBody')]]"> </managed-dialog> </template> +<if expr="not chromeos_ash"> + <template is="dom-if" if="[[shouldShowRelaunchDialog]]" restamp> + <relaunch-confirmation-dialog restart-type="[[restartTypeEnum.RESTART]]" + on-close="onRelaunchDialogClose"></relaunch-confirmation-dialog> + </template> +</if>
diff --git a/chrome/browser/resources/settings/languages_page/languages_subpage.ts b/chrome/browser/resources/settings/languages_page/languages_subpage.ts index 2c0718b..d7f21f5a7 100644 --- a/chrome/browser/resources/settings/languages_page/languages_subpage.ts +++ b/chrome/browser/resources/settings/languages_page/languages_subpage.ts
@@ -25,6 +25,9 @@ import './languages.js'; import '../controls/settings_toggle_button.js'; import '../icons.js'; +// <if expr="not chromeos_ash"> +import '../relaunch_confirmation_dialog.js'; +// </if> import '../settings_shared_css.js'; import '../settings_vars_css.js'; @@ -43,10 +46,8 @@ import {SettingsToggleButtonElement} from '../controls/settings_toggle_button.js'; import {loadTimeData} from '../i18n_setup.js'; -// <if expr="is_win"> -import {LifetimeBrowserProxyImpl} from '../lifetime_browser_proxy.js'; -// </if> import {PrefsMixin} from '../prefs/prefs_mixin.js'; +import {RelaunchMixin, RestartType} from '../relaunch_mixin.js'; import {LanguageSettingsActionType, LanguageSettingsMetricsProxy, LanguageSettingsMetricsProxyImpl, LanguageSettingsPageImpressionType} from './languages_settings_metrics_proxy.js'; import {LanguageHelper, LanguagesModel, LanguageState} from './languages_types.js'; @@ -72,7 +73,7 @@ } const SettingsLanguagesSubpageElementBase = - I18nMixin(PrefsMixin(PolymerElement)); + RelaunchMixin(I18nMixin(PrefsMixin(PolymerElement))); export class SettingsLanguagesSubpageElement extends SettingsLanguagesSubpageElementBase { @@ -437,7 +438,7 @@ * Handler for the restart button. */ private onRestartTap_() { - LifetimeBrowserProxyImpl.getInstance().restart(); + this.performRestart(RestartType.RESTART); } // </if>
diff --git a/chrome/browser/resources/settings/privacy_page/personalization_options.html b/chrome/browser/resources/settings/privacy_page/personalization_options.html index 4851699..66b09a6 100644 --- a/chrome/browser/resources/settings/privacy_page/personalization_options.html +++ b/chrome/browser/resources/settings/privacy_page/personalization_options.html
@@ -103,9 +103,14 @@ </settings-signout-dialog> </template> -<if expr="not chromeos"> +<if expr="not chromeos_ash"> <cr-toast id="toast"> <div>$i18n{restartToApplyChanges}</div> <cr-button on-click="onRestartTap_">$i18n{restart}</cr-button> </cr-toast> + + <template is="dom-if" if="[[shouldShowRelaunchDialog]]" restamp> + <relaunch-confirmation-dialog restart-type="[[restartTypeEnum.RESTART]]" + on-close="onRelaunchDialogClose"></relaunch-confirmation-dialog> + </template> </if>
diff --git a/chrome/browser/resources/settings/privacy_page/personalization_options.ts b/chrome/browser/resources/settings/privacy_page/personalization_options.ts index dba5556..06f3989 100644 --- a/chrome/browser/resources/settings/privacy_page/personalization_options.ts +++ b/chrome/browser/resources/settings/privacy_page/personalization_options.ts
@@ -12,8 +12,11 @@ import '../controls/settings_toggle_button.js'; import '../people_page/signout_dialog.js'; import '../prefs/prefs.js'; +// <if expr="not chromeos_ash"> +import '../relaunch_confirmation_dialog.js'; +// </if> import '../settings_shared_css.js'; -// <if expr="not chromeos"> +// <if expr="not chromeos_ash"> import '//resources/cr_elements/cr_toast/cr_toast.js'; // </if> @@ -23,11 +26,11 @@ import {SettingsToggleButtonElement} from '../controls/settings_toggle_button.js'; import {loadTimeData} from '../i18n_setup.js'; -import {LifetimeBrowserProxyImpl} from '../lifetime_browser_proxy.js'; import {PrivacyPageVisibility} from '../page_visibility.js'; import {SettingsSignoutDialogElement} from '../people_page/signout_dialog.js'; import {StatusAction, SyncStatus} from '../people_page/sync_browser_proxy.js'; import {PrefsMixin} from '../prefs/prefs_mixin.js'; +import {RelaunchMixin, RestartType} from '../relaunch_mixin.js'; import {MetricsReporting, PrivacyPageBrowserProxy, PrivacyPageBrowserProxyImpl} from './privacy_page_browser_proxy.js'; @@ -42,7 +45,7 @@ } const SettingsPersonalizationOptionsElementBase = - WebUIListenerMixin(PrefsMixin(PolymerElement)); + RelaunchMixin(WebUIListenerMixin(PrefsMixin(PolymerElement))); export class SettingsPersonalizationOptionsElement extends SettingsPersonalizationOptionsElementBase { @@ -287,7 +290,7 @@ private onRestartTap_(e: Event) { e.stopPropagation(); - LifetimeBrowserProxyImpl.getInstance().restart(); + this.performRestart(RestartType.RESTART); } }
diff --git a/chrome/browser/resources/settings/safety_check_page/safety_check_updates_child.html b/chrome/browser/resources/settings/safety_check_page/safety_check_updates_child.html index 8baba523..3154c78 100644 --- a/chrome/browser/resources/settings/safety_check_page/safety_check_updates_child.html +++ b/chrome/browser/resources/settings/safety_check_page/safety_check_updates_child.html
@@ -10,3 +10,9 @@ managed-icon="[[getManagedIcon_(status_)]]" role="presentation"> </settings-safety-check-child> +<if expr="not chromeos_ash"> + <template is="dom-if" if="[[shouldShowRelaunchDialog]]" restamp> + <relaunch-confirmation-dialog restart-type="[[restartTypeEnum.RELAUNCH]]" + on-close="onRelaunchDialogClose"></relaunch-confirmation-dialog> + </template> +</if>
diff --git a/chrome/browser/resources/settings/safety_check_page/safety_check_updates_child.ts b/chrome/browser/resources/settings/safety_check_page/safety_check_updates_child.ts index fcd3aa75..f7d1ee8 100644 --- a/chrome/browser/resources/settings/safety_check_page/safety_check_updates_child.ts +++ b/chrome/browser/resources/settings/safety_check_page/safety_check_updates_child.ts
@@ -7,14 +7,18 @@ * 'settings-safety-updates-child' is the settings page containing the safety * check child showing the browser's update status. */ + +// <if expr="not chromeos_ash"> +import '../relaunch_confirmation_dialog.js'; +// </if> + import {assertNotReached} from 'chrome://resources/js/assert.m.js'; import {I18nMixin} from 'chrome://resources/js/i18n_mixin.js'; import {WebUIListenerMixin} from 'chrome://resources/js/web_ui_listener_mixin.js'; import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {LifetimeBrowserProxyImpl} from '../lifetime_browser_proxy.js'; import {MetricsBrowserProxy, MetricsBrowserProxyImpl, SafetyCheckInteractions} from '../metrics_browser_proxy.js'; - +import {RelaunchMixin, RestartType} from '../relaunch_mixin.js'; import {SafetyCheckCallbackConstants, SafetyCheckUpdatesStatus} from './safety_check_browser_proxy.js'; import {SafetyCheckIconStatus} from './safety_check_child.js'; @@ -24,7 +28,7 @@ }; const SettingsSafetyCheckUpdatesChildElementBase = - WebUIListenerMixin(I18nMixin(PolymerElement)); + RelaunchMixin(WebUIListenerMixin(I18nMixin(PolymerElement))); export class SettingsSafetyCheckUpdatesChildElement extends SettingsSafetyCheckUpdatesChildElementBase { @@ -108,7 +112,7 @@ this.metricsBrowserProxy_.recordAction( 'Settings.SafetyCheck.RelaunchAfterUpdates'); - LifetimeBrowserProxyImpl.getInstance().relaunch(); + this.performRestart(RestartType.RELAUNCH); } private getManagedIcon_(): string|null {
diff --git a/chrome/browser/resources/settings/system_page/system_page.html b/chrome/browser/resources/settings/system_page/system_page.html index 6bc65d2e..f62f11cb 100644 --- a/chrome/browser/resources/settings/system_page/system_page.html +++ b/chrome/browser/resources/settings/system_page/system_page.html
@@ -49,3 +49,9 @@ </extension-controlled-indicator> </div> </template> + <if expr="not chromeos_ash"> + <template is="dom-if" if="[[shouldShowRelaunchDialog]]" restamp> + <relaunch-confirmation-dialog restart-type="[[restartTypeEnum.RESTART]]" + on-close="onRelaunchDialogClose"></relaunch-confirmation-dialog> + </template> + </if>
diff --git a/chrome/browser/resources/settings/system_page/system_page.ts b/chrome/browser/resources/settings/system_page/system_page.ts index 895f75e9..4e5c6aa 100644 --- a/chrome/browser/resources/settings/system_page/system_page.ts +++ b/chrome/browser/resources/settings/system_page/system_page.ts
@@ -14,12 +14,15 @@ import '../controls/extension_controlled_indicator.js'; import '../controls/settings_toggle_button.js'; import '../prefs/prefs.js'; +// <if expr="not chromeos_ash"> +import '../relaunch_confirmation_dialog.js'; +// </if> import '../settings_shared_css.js'; import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {SettingsToggleButtonElement} from '../controls/settings_toggle_button.js'; -import {LifetimeBrowserProxyImpl} from '../lifetime_browser_proxy.js'; +import {RelaunchMixin, RestartType} from '../relaunch_mixin.js'; import {SystemPageBrowserProxyImpl} from './system_page_browser_proxy.js'; @@ -31,7 +34,9 @@ }; } -export class SettingsSystemPageElement extends PolymerElement { +const SettingsSystemPageElementBase = RelaunchMixin(PolymerElement); + +export class SettingsSystemPageElement extends SettingsSystemPageElementBase { static get is() { return 'settings-system-page'; } @@ -90,8 +95,7 @@ private onRestartTap_(e: Event) { // Prevent event from bubbling up to the toggle button. e.stopPropagation(); - // TODO(dbeam): we should prompt before restarting the browser. - LifetimeBrowserProxyImpl.getInstance().restart(); + this.performRestart(RestartType.RESTART); } /**
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/LongScreenshotsTabServiceTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/LongScreenshotsTabServiceTest.java index 491acaea..01524ed 100644 --- a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/LongScreenshotsTabServiceTest.java +++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/LongScreenshotsTabServiceTest.java
@@ -18,6 +18,7 @@ import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Criteria; import org.chromium.base.test.util.CriteriaHelper; +import org.chromium.base.test.util.DisableIf; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.Matchers; import org.chromium.chrome.browser.flags.ChromeSwitches; @@ -87,7 +88,10 @@ @Test @MediumTest @Feature({"LongScreenshots"}) - public void testCapturedFilesystem() throws Exception { + @DisableIf.Build(message = "Flaky on emulators; see https://crbug.com/1282258", + supported_abis_includes = "x86") + public void + testCapturedFilesystem() throws Exception { EmbeddedTestServer testServer = mActivityTestRule.getTestServer(); final String url = testServer.getURL("/chrome/test/data/android/about.html");
diff --git a/chrome/browser/sharing/click_to_call/click_to_call_ui_controller.cc b/chrome/browser/sharing/click_to_call/click_to_call_ui_controller.cc index f472fa93..07031f52 100644 --- a/chrome/browser/sharing/click_to_call/click_to_call_ui_controller.cc +++ b/chrome/browser/sharing/click_to_call/click_to_call_ui_controller.cc
@@ -19,6 +19,7 @@ #include "chrome/grit/chromium_strings.h" #include "components/sync_device_info/device_info.h" #include "components/vector_icons/vector_icons.h" +#include "content/public/browser/weak_document_ptr.h" #include "content/public/browser/web_contents.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/paint_vector_icon.h" @@ -41,10 +42,12 @@ void ClickToCallUiController::ShowDialog( content::WebContents* web_contents, const absl::optional<url::Origin>& initiating_origin, + content::WeakDocumentPtr initiator_document, const GURL& url, bool hide_default_handler) { auto* controller = GetOrCreateFromWebContents(web_contents); controller->phone_url_ = url; + controller->initiator_document_ = std::move(initiator_document); controller->hide_default_handler_ = hide_default_handler; controller->UpdateAndShowDialog(initiating_origin); } @@ -140,8 +143,8 @@ if (ukm_recorder_) std::move(ukm_recorder_).Run(SharingClickToCallSelection::kApp); - ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck(phone_url_, - web_contents()); + ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck( + phone_url_, web_contents(), initiator_document_); } void ClickToCallUiController::OnDialogShown(bool has_devices, bool has_apps) {
diff --git a/chrome/browser/sharing/click_to_call/click_to_call_ui_controller.h b/chrome/browser/sharing/click_to_call/click_to_call_ui_controller.h index 4ae4a38f..d67af75c 100644 --- a/chrome/browser/sharing/click_to_call/click_to_call_ui_controller.h +++ b/chrome/browser/sharing/click_to_call/click_to_call_ui_controller.h
@@ -14,6 +14,7 @@ #include "chrome/browser/sharing/sharing_service.h" #include "chrome/browser/sharing/sharing_ui_controller.h" #include "chrome/browser/ui/page_action/page_action_icon_type.h" +#include "content/public/browser/weak_document_ptr.h" #include "content/public/browser/web_contents_user_data.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "url/gurl.h" @@ -31,6 +32,7 @@ content::WebContents* web_contents); static void ShowDialog(content::WebContents* web_contents, const absl::optional<url::Origin>& initiating_origin, + content::WeakDocumentPtr initiator_document, const GURL& url, bool hide_default_handler); @@ -76,6 +78,7 @@ UKMRecorderCallback ukm_recorder_; GURL phone_url_; + content::WeakDocumentPtr initiator_document_; bool hide_default_handler_ = false; base::WeakPtrFactory<ClickToCallUiController> weak_ptr_factory_{this};
diff --git a/chrome/browser/sharing/click_to_call/click_to_call_ui_controller_unittest.cc b/chrome/browser/sharing/click_to_call/click_to_call_ui_controller_unittest.cc index a88120b..7dd5d811 100644 --- a/chrome/browser/sharing/click_to_call/click_to_call_ui_controller_unittest.cc +++ b/chrome/browser/sharing/click_to_call/click_to_call_ui_controller_unittest.cc
@@ -22,6 +22,7 @@ #include "components/sync/protocol/device_info_specifics.pb.h" #include "components/sync_device_info/fake_device_info_tracker.h" #include "components/sync_preferences/testing_pref_service_syncable.h" +#include "content/public/browser/weak_document_ptr.h" #include "content/public/test/browser_task_environment.h" #include "content/public/test/test_renderer_host.h" #include "content/public/test/web_contents_tester.h" @@ -51,7 +52,9 @@ return std::make_unique<testing::NiceMock<MockSharingService>>(); })); ClickToCallUiController::ShowDialog( - web_contents_.get(), /*initiating_origin=*/absl::nullopt, + web_contents_.get(), + /*initiating_origin=*/absl::nullopt, + /*initiator_document=*/content::WeakDocumentPtr(), GURL(base::StrCat({"tel:", kPhoneNumber})), false); controller_ = ClickToCallUiController::GetOrCreateFromWebContents( web_contents_.get());
diff --git a/chrome/browser/themes/browser_theme_pack.cc b/chrome/browser/themes/browser_theme_pack.cc index b946c2d..62748c0 100644 --- a/chrome/browser/themes/browser_theme_pack.cc +++ b/chrome/browser/themes/browser_theme_pack.cc
@@ -96,7 +96,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 = 77; +const int kThemePackVersion = 78; // 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 @@ -207,12 +207,12 @@ // Strings used by themes to identify tints in the JSON. const StringToIntTable kTintTable[] = { + {"background_tab", TP::TINT_BACKGROUND_TAB}, {"buttons", TP::TINT_BUTTONS}, {"frame", TP::TINT_FRAME}, {"frame_inactive", TP::TINT_FRAME_INACTIVE}, {"frame_incognito", TP::TINT_FRAME_INCOGNITO}, {"frame_incognito_inactive", TP::TINT_FRAME_INCOGNITO_INACTIVE}, - {"background_tab", TP::TINT_BACKGROUND_TAB}, // /!\ If you make any changes here, you must also increment // kThemePackVersion above, or else themes will display incorrectly. @@ -221,10 +221,6 @@ // Strings used by themes to identify colors in the JSON. constexpr StringToIntTable kOverwritableColorTable[] = { - {"frame", TP::COLOR_FRAME_ACTIVE}, - {"frame_inactive", TP::COLOR_FRAME_INACTIVE}, - {"frame_incognito", TP::COLOR_FRAME_ACTIVE_INCOGNITO}, - {"frame_incognito_inactive", TP::COLOR_FRAME_INACTIVE_INCOGNITO}, {"background_tab", TP::COLOR_TAB_BACKGROUND_INACTIVE_FRAME_ACTIVE}, {"background_tab_inactive", TP::COLOR_TAB_BACKGROUND_INACTIVE_FRAME_INACTIVE}, @@ -234,6 +230,16 @@ TP::COLOR_TAB_BACKGROUND_INACTIVE_FRAME_INACTIVE_INCOGNITO}, {"bookmark_text", TP::COLOR_BOOKMARK_TEXT}, {"button_background", TP::COLOR_CONTROL_BUTTON_BACKGROUND}, + {"frame", TP::COLOR_FRAME_ACTIVE}, + {"frame_inactive", TP::COLOR_FRAME_INACTIVE}, + {"frame_incognito", TP::COLOR_FRAME_ACTIVE_INCOGNITO}, + {"frame_incognito_inactive", TP::COLOR_FRAME_INACTIVE_INCOGNITO}, + {"ntp_background", TP::COLOR_NTP_BACKGROUND}, + {"ntp_header", TP::COLOR_NTP_HEADER}, + {"ntp_link", TP::COLOR_NTP_LINK}, + {"ntp_text", TP::COLOR_NTP_TEXT}, + {"omnibox_background", TP::COLOR_OMNIBOX_BACKGROUND}, + {"omnibox_text", TP::COLOR_OMNIBOX_TEXT}, {"tab_background_text", TP::COLOR_TAB_FOREGROUND_INACTIVE_FRAME_ACTIVE}, {"tab_background_text_inactive", TP::COLOR_TAB_FOREGROUND_INACTIVE_FRAME_INACTIVE}, @@ -244,12 +250,7 @@ {"tab_text", TP::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_ACTIVE}, {"toolbar", TP::COLOR_TOOLBAR}, {"toolbar_button_icon", TP::COLOR_TOOLBAR_BUTTON_ICON}, - {"omnibox_text", TP::COLOR_OMNIBOX_TEXT}, - {"omnibox_background", TP::COLOR_OMNIBOX_BACKGROUND}, - {"ntp_background", TP::COLOR_NTP_BACKGROUND}, - {"ntp_header", TP::COLOR_NTP_HEADER}, - {"ntp_link", TP::COLOR_NTP_LINK}, - {"ntp_text", TP::COLOR_NTP_TEXT}, + {"toolbar_text", TP::COLOR_TOOLBAR_TEXT}, // /!\ If you make any changes here, you must also increment // kThemePackVersion above, or else themes will display incorrectly. @@ -844,10 +845,8 @@ // Toolbar and active tab (set in SetFrameAndToolbarRelatedColors) use active // tab color. pack->SetColor(TP::COLOR_TOOLBAR, colors.active_tab_color); - pack->SetColor(TP::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_ACTIVE, - colors.active_tab_text_color); + pack->SetColor(TP::COLOR_TOOLBAR_TEXT, colors.active_tab_text_color); pack->SetColor(TP::COLOR_TOOLBAR_BUTTON_ICON, colors.active_tab_text_color); - pack->SetColor(TP::COLOR_BOOKMARK_TEXT, colors.active_tab_text_color); // NTP. pack->SetColor(TP::COLOR_NTP_BACKGROUND, colors.ntp_color); @@ -1054,10 +1053,16 @@ int property_id; int color_id; } kThemePropertiesMap[] = { + {TP::COLOR_BOOKMARK_TEXT, kColorBookmarkText}, {TP::COLOR_DOWNLOAD_SHELF, kColorDownloadShelf}, - {TP::COLOR_TOOLBAR, kColorToolbar}, {TP::COLOR_OMNIBOX_TEXT, kColorOmniboxText}, {TP::COLOR_OMNIBOX_BACKGROUND, kColorOmniboxBackground}, + {TP::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_ACTIVE, + kColorTabForegroundActiveFrameActive}, + {TP::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_INACTIVE, + kColorTabForegroundActiveFrameInactive}, + {TP::COLOR_TOOLBAR, kColorToolbar}, + {TP::COLOR_TOOLBAR_TEXT, kColorToolbarText}, }; ui::ColorSet::ColorMap theme_colors; @@ -1507,6 +1512,12 @@ SetColor(TP::COLOR_TOOLBAR_BUTTON_ICON_HOVERED, toolbar_button_icon_color); SetColor(TP::COLOR_TOOLBAR_BUTTON_ICON_PRESSED, toolbar_button_icon_color); } + SkColor toolbar_text_color; + if (GetColor(TP::COLOR_TOOLBAR_TEXT, &toolbar_text_color)) { + SetColorIfUnspecified(TP::COLOR_BOOKMARK_TEXT, toolbar_text_color); + SetColorIfUnspecified(TP::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_ACTIVE, + toolbar_text_color); + } SkColor tab_foreground_color; if (GetColor(TP::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_ACTIVE, &tab_foreground_color)) {
diff --git a/chrome/browser/themes/browser_theme_pack_unittest.cc b/chrome/browser/themes/browser_theme_pack_unittest.cc index 8875a09..5b934300 100644 --- a/chrome/browser/themes/browser_theme_pack_unittest.cc +++ b/chrome/browser/themes/browser_theme_pack_unittest.cc
@@ -1085,20 +1085,16 @@ EXPECT_EQ(frame_color, background_tab); EXPECT_TRUE(has_readable_contrast(background_tab_text, background_tab)); - SkColor toolbar_color, ntp_background, tab_text, bookmark_text, - toolbar_button_icon; - EXPECT_TRUE(pack->GetColor(TP::COLOR_TOOLBAR, &toolbar_color)); + SkColor ntp_background, toolbar_color, toolbar_button_icon, toolbar_text; EXPECT_TRUE(pack->GetColor(TP::COLOR_NTP_BACKGROUND, &ntp_background)); - EXPECT_TRUE(pack->GetColor(TP::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_ACTIVE, - &tab_text)); + EXPECT_TRUE(pack->GetColor(TP::COLOR_TOOLBAR, &toolbar_color)); EXPECT_TRUE( pack->GetColor(TP::COLOR_TOOLBAR_BUTTON_ICON, &toolbar_button_icon)); - EXPECT_TRUE(pack->GetColor(TP::COLOR_BOOKMARK_TEXT, &bookmark_text)); + EXPECT_TRUE(pack->GetColor(TP::COLOR_TOOLBAR_TEXT, &toolbar_text)); EXPECT_EQ(toolbar_color, ntp_background); - EXPECT_EQ(tab_text, toolbar_button_icon); - EXPECT_EQ(tab_text, bookmark_text); - EXPECT_TRUE(has_readable_contrast(tab_text, toolbar_color)); + EXPECT_EQ(toolbar_text, toolbar_button_icon); + EXPECT_TRUE(has_readable_contrast(toolbar_text, toolbar_color)); EXPECT_NE(frame_color, toolbar_color); EXPECT_GE(color_utils::GetContrastRatio(frame_color, toolbar_color),
diff --git a/chrome/browser/themes/increased_contrast_theme_supplier.cc b/chrome/browser/themes/increased_contrast_theme_supplier.cc index 3f69dba..94d526e 100644 --- a/chrome/browser/themes/increased_contrast_theme_supplier.cc +++ b/chrome/browser/themes/increased_contrast_theme_supplier.cc
@@ -23,10 +23,6 @@ const SkColor foreground = is_dark_mode_ ? SK_ColorWHITE : SK_ColorBLACK; const SkColor background = is_dark_mode_ ? SK_ColorBLACK : SK_ColorWHITE; switch (id) { - case ThemeProperties::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_ACTIVE: - case ThemeProperties::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_INACTIVE: - *color = foreground; - return true; case ThemeProperties::COLOR_TAB_FOREGROUND_INACTIVE_FRAME_ACTIVE: case ThemeProperties::COLOR_TAB_FOREGROUND_INACTIVE_FRAME_ACTIVE_INCOGNITO: *color = SK_ColorWHITE; @@ -52,10 +48,9 @@ case ThemeProperties::COLOR_TOOLBAR_TOP_SEPARATOR: *color = is_dark_mode_ ? SK_ColorDKGRAY : SK_ColorLTGRAY; return true; - case ThemeProperties::COLOR_TOOLBAR_CONTENT_AREA_SEPARATOR: - *color = foreground; - return true; case ThemeProperties::COLOR_LOCATION_BAR_BORDER: + case ThemeProperties::COLOR_TOOLBAR_CONTENT_AREA_SEPARATOR: + case ThemeProperties::COLOR_TOOLBAR_TEXT: *color = foreground; return true; }
diff --git a/chrome/browser/themes/theme_helper.cc b/chrome/browser/themes/theme_helper.cc index 238ce8f3..ad332d6 100644 --- a/chrome/browser/themes/theme_helper.cc +++ b/chrome/browser/themes/theme_helper.cc
@@ -358,10 +358,14 @@ incognito, theme_supplier); }; switch (id) { - case TP::COLOR_DOWNLOAD_SHELF_BUTTON_BACKGROUND: { + case TP::COLOR_BOOKMARK_TEXT: + case TP::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_ACTIVE: + case TP::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_INACTIVE: + return GetColor(TP::COLOR_TOOLBAR_TEXT, incognito, theme_supplier, + nullptr); + case TP::COLOR_DOWNLOAD_SHELF_BUTTON_BACKGROUND: return GetColor(TP::COLOR_DOWNLOAD_SHELF, incognito, theme_supplier, nullptr); - } case TP::COLOR_DOWNLOAD_SHELF_BUTTON_TEXT: { const SkColor download_shelf_color = GetColor(TP::COLOR_DOWNLOAD_SHELF_BUTTON_BACKGROUND, incognito,
diff --git a/chrome/browser/themes/theme_helper_win.cc b/chrome/browser/themes/theme_helper_win.cc index 20caee0b..f90085d1 100644 --- a/chrome/browser/themes/theme_helper_win.cc +++ b/chrome/browser/themes/theme_helper_win.cc
@@ -64,7 +64,7 @@ // Button Text Foreground case ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON: - case ThemeProperties::COLOR_BOOKMARK_TEXT: + case ThemeProperties::COLOR_TOOLBAR_TEXT: case ThemeProperties::COLOR_TAB_FOREGROUND_INACTIVE_FRAME_ACTIVE: case ThemeProperties::COLOR_TAB_FOREGROUND_INACTIVE_FRAME_ACTIVE_INCOGNITO: case ThemeProperties::COLOR_TAB_FOREGROUND_INACTIVE_FRAME_INACTIVE:
diff --git a/chrome/browser/themes/theme_properties.cc b/chrome/browser/themes/theme_properties.cc index 3db36d09..62152f7 100644 --- a/chrome/browser/themes/theme_properties.cc +++ b/chrome/browser/themes/theme_properties.cc
@@ -75,9 +75,7 @@ return gfx::kGoogleGrey050; case ThemeProperties::COLOR_TAB_FOREGROUND_INACTIVE_FRAME_ACTIVE: case ThemeProperties::COLOR_TAB_FOREGROUND_INACTIVE_FRAME_INACTIVE: - case ThemeProperties::COLOR_BOOKMARK_TEXT: - case ThemeProperties::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_ACTIVE: - case ThemeProperties::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_INACTIVE: + case ThemeProperties::COLOR_TOOLBAR_TEXT: return gfx::kGoogleGrey800; case ThemeProperties::COLOR_NTP_BACKGROUND: return kDefaultColorNTPBackground; @@ -160,9 +158,7 @@ case ThemeProperties::COLOR_HOVER_CARD_NO_PREVIEW_BACKGROUND: case ThemeProperties::COLOR_NTP_SHORTCUT: return gfx::kGoogleGrey900; - case ThemeProperties::COLOR_BOOKMARK_TEXT: - case ThemeProperties::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_ACTIVE: - case ThemeProperties::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_INACTIVE: + case ThemeProperties::COLOR_TOOLBAR_TEXT: return SK_ColorWHITE; case ThemeProperties::COLOR_NTP_TEXT: return gfx::kGoogleGrey200;
diff --git a/chrome/browser/themes/theme_properties.h b/chrome/browser/themes/theme_properties.h index 8e45df1..a5f03ec 100644 --- a/chrome/browser/themes/theme_properties.h +++ b/chrome/browser/themes/theme_properties.h
@@ -26,40 +26,41 @@ // incorrectly. enum OverwritableByUserThemeProperty { - COLOR_FRAME_ACTIVE, - COLOR_FRAME_INACTIVE, // Instead of using the INCOGNITO variants directly, most code should // use the original color ID in an incognito-aware context (such as // GetDefaultColor). This comment applies to other properties tagged // INCOGNITO below as well. - COLOR_FRAME_ACTIVE_INCOGNITO, - COLOR_FRAME_INACTIVE_INCOGNITO, - COLOR_TAB_BACKGROUND_INACTIVE_FRAME_ACTIVE, - COLOR_TAB_BACKGROUND_INACTIVE_FRAME_INACTIVE, - COLOR_TAB_BACKGROUND_INACTIVE_FRAME_ACTIVE_INCOGNITO, - COLOR_TAB_BACKGROUND_INACTIVE_FRAME_INACTIVE_INCOGNITO, - COLOR_TOOLBAR, - COLOR_TAB_FOREGROUND_ACTIVE_FRAME_ACTIVE, - COLOR_TAB_FOREGROUND_INACTIVE_FRAME_ACTIVE, - COLOR_TAB_FOREGROUND_INACTIVE_FRAME_INACTIVE, - COLOR_TAB_FOREGROUND_INACTIVE_FRAME_ACTIVE_INCOGNITO, - COLOR_TAB_FOREGROUND_INACTIVE_FRAME_INACTIVE_INCOGNITO, COLOR_BOOKMARK_TEXT, + COLOR_CONTROL_BUTTON_BACKGROUND, + COLOR_FRAME_ACTIVE, + COLOR_FRAME_ACTIVE_INCOGNITO, + COLOR_FRAME_INACTIVE, + COLOR_FRAME_INACTIVE_INCOGNITO, COLOR_NTP_BACKGROUND, - COLOR_NTP_TEXT, COLOR_NTP_LINK, COLOR_NTP_HEADER, - COLOR_CONTROL_BUTTON_BACKGROUND, - COLOR_TOOLBAR_BUTTON_ICON, - COLOR_OMNIBOX_TEXT, + COLOR_NTP_TEXT, COLOR_OMNIBOX_BACKGROUND, + COLOR_OMNIBOX_TEXT, + COLOR_TAB_BACKGROUND_INACTIVE_FRAME_ACTIVE, + COLOR_TAB_BACKGROUND_INACTIVE_FRAME_ACTIVE_INCOGNITO, + COLOR_TAB_BACKGROUND_INACTIVE_FRAME_INACTIVE, + COLOR_TAB_BACKGROUND_INACTIVE_FRAME_INACTIVE_INCOGNITO, + COLOR_TAB_FOREGROUND_ACTIVE_FRAME_ACTIVE, + COLOR_TAB_FOREGROUND_INACTIVE_FRAME_ACTIVE, + COLOR_TAB_FOREGROUND_INACTIVE_FRAME_ACTIVE_INCOGNITO, + COLOR_TAB_FOREGROUND_INACTIVE_FRAME_INACTIVE, + COLOR_TAB_FOREGROUND_INACTIVE_FRAME_INACTIVE_INCOGNITO, + COLOR_TOOLBAR, + COLOR_TOOLBAR_BUTTON_ICON, + COLOR_TOOLBAR_TEXT, + TINT_BACKGROUND_TAB, TINT_BUTTONS, TINT_FRAME, TINT_FRAME_INACTIVE, TINT_FRAME_INCOGNITO, TINT_FRAME_INCOGNITO_INACTIVE, - TINT_BACKGROUND_TAB, NTP_BACKGROUND_ALIGNMENT, NTP_BACKGROUND_TILING,
diff --git a/chrome/browser/themes/theme_service.cc b/chrome/browser/themes/theme_service.cc index 68feae7..479ccaa 100644 --- a/chrome/browser/themes/theme_service.cc +++ b/chrome/browser/themes/theme_service.cc
@@ -84,6 +84,7 @@ absl::optional<ui::ColorId> ThemeProviderColorIdToColorId(int color_id) { static constexpr const auto kMap = base::MakeFixedFlatMap<int, ui::ColorId>({ + {TP::COLOR_BOOKMARK_TEXT, kColorBookmarkText}, {TP::COLOR_DOWNLOAD_SHELF, kColorDownloadShelf}, {TP::COLOR_DOWNLOAD_SHELF_BUTTON_BACKGROUND, kColorDownloadShelfButtonBackground}, @@ -116,7 +117,12 @@ {TP::COLOR_OMNIBOX_SECURITY_CHIP_SECURE, kColorOmniboxSecurityChipSecure}, {TP::COLOR_OMNIBOX_TEXT, kColorOmniboxText}, {TP::COLOR_OMNIBOX_TEXT_DIMMED, kColorOmniboxTextDimmed}, + {TP::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_ACTIVE, + kColorTabForegroundActiveFrameActive}, + {TP::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_INACTIVE, + kColorTabForegroundActiveFrameInactive}, {TP::COLOR_TOOLBAR, kColorToolbar}, + {TP::COLOR_TOOLBAR_TEXT, kColorToolbarText}, }); auto* color_it = kMap.find(color_id); if (color_it != kMap.cend()) {
diff --git a/chrome/browser/ui/android/external_protocol_dialog_android.cc b/chrome/browser/ui/android/external_protocol_dialog_android.cc index 25eab61b..aedb9ea 100644 --- a/chrome/browser/ui/android/external_protocol_dialog_android.cc +++ b/chrome/browser/ui/android/external_protocol_dialog_android.cc
@@ -8,6 +8,7 @@ #include "chrome/browser/tab_contents/tab_util.h" #include "components/navigation_interception/intercept_navigation_delegate.h" #include "components/navigation_interception/navigation_params.h" +#include "content/public/browser/weak_document_ptr.h" #include "content/public/browser/web_contents.h" #include "content/public/common/referrer.h" #include "ui/base/page_transition_types.h" @@ -20,7 +21,8 @@ WebContents* web_contents, ui::PageTransition page_transition, bool has_user_gesture, - const absl::optional<url::Origin>& initiating_origin) { + const absl::optional<url::Origin>& initiating_origin, + content::WeakDocumentPtr) { navigation_interception::InterceptNavigationDelegate* delegate = navigation_interception::InterceptNavigationDelegate::Get(web_contents); if (!delegate)
diff --git a/chrome/browser/ui/android/webid/account_selection_view_android.cc b/chrome/browser/ui/android/webid/account_selection_view_android.cc index b885bd72..9959bab 100644 --- a/chrome/browser/ui/android/webid/account_selection_view_android.cc +++ b/chrome/browser/ui/android/webid/account_selection_view_android.cc
@@ -19,6 +19,7 @@ #include "ui/android/color_utils_android.h" #include "ui/android/view_android.h" #include "ui/android/window_android.h" +#include "ui/gfx/android/java_bitmap.h" #include "url/android/gurl_android.h" #include "url/gurl.h" #include "url/origin.h" @@ -45,9 +46,13 @@ ScopedJavaLocalRef<jobject> ConvertToJavaIdentityProviderMetadata( JNIEnv* env, const content::IdentityProviderMetadata& metadata) { + base::android::ScopedJavaLocalRef<jobject> java_brand_icon; + if (!metadata.brand_icon.isNull()) + java_brand_icon = gfx::ConvertToJavaBitmap(metadata.brand_icon); return Java_IdentityProviderMetadata_Constructor( env, ui::OptionalSkColorToJavaColor(metadata.brand_text_color), - ui::OptionalSkColorToJavaColor(metadata.brand_background_color)); + ui::OptionalSkColorToJavaColor(metadata.brand_background_color), + java_brand_icon); } ScopedJavaLocalRef<jobject> ConvertToJavaClientIdMetadata( @@ -177,3 +182,15 @@ AccountSelectionView::Delegate* delegate) { return std::make_unique<AccountSelectionViewAndroid>(delegate); } + +// static +int AccountSelectionView::GetBrandIconMinimumSize() { + return Java_AccountSelectionBridge_getBrandIconMinimumSize( + base::android::AttachCurrentThread()); +} + +// static +int AccountSelectionView::GetBrandIconIdealSize() { + return Java_AccountSelectionBridge_getBrandIconIdealSize( + base::android::AttachCurrentThread()); +}
diff --git a/chrome/browser/ui/android/webid/internal/java/res/layout/account_selection_continue_button.xml b/chrome/browser/ui/android/webid/internal/java/res/layout/account_selection_continue_button.xml index 22c6bbc..91a911f 100644 --- a/chrome/browser/ui/android/webid/internal/java/res/layout/account_selection_continue_button.xml +++ b/chrome/browser/ui/android/webid/internal/java/res/layout/account_selection_continue_button.xml
@@ -11,7 +11,9 @@ android:layout_height="wrap_content" android:layout_marginTop="@dimen/account_selection_sheet_button_margin" android:layout_marginBottom="@dimen/account_selection_sheet_button_margin" - android:text="@string/account_selection_continue" + android:drawablePadding="5dp" + android:paddingStart="10dp" + android:paddingEnd="@dimen/account_selection_continue_padding_end" android:ellipsize="end" android:singleLine="true" style="@style/FilledButton.Flat"/>
diff --git a/chrome/browser/ui/android/webid/internal/java/res/values/dimens.xml b/chrome/browser/ui/android/webid/internal/java/res/values/dimens.xml index 60fe321..108f19e 100644 --- a/chrome/browser/ui/android/webid/internal/java/res/values/dimens.xml +++ b/chrome/browser/ui/android/webid/internal/java/res/values/dimens.xml
@@ -14,4 +14,11 @@ <dimen name="account_selection_favicon_border_size">1dp</dimen> <dimen name="account_selection_sheet_button_margin">2dp</dimen> + + <dimen name="account_selection_continue_icon_size">24dp</dimen> + <!-- Value chosen so that the text is centered in the button. + paddingStart (10dp) + + icon account_selection_continue_icon_size (24dp) + + drawablePadding (5dp) --> + <dimen name="account_selection_continue_padding_end">39dp</dimen> </resources>
diff --git a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionBridge.java b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionBridge.java index 6132254..97d5e81 100644 --- a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionBridge.java +++ b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionBridge.java
@@ -4,8 +4,11 @@ package org.chromium.chrome.browser.ui.android.webid; +import android.content.res.Resources; + import androidx.annotation.Nullable; +import org.chromium.base.ContextUtils; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.NativeMethods; import org.chromium.chrome.browser.ui.android.webid.data.Account; @@ -35,6 +38,19 @@ } @CalledByNative + private static int getBrandIconMinimumSize() { + // Icon needs to be big enough for the smallest screen density (1x). + Resources resources = ContextUtils.getApplicationContext().getResources(); + return Math.round(getBrandIconIdealSize() / resources.getDisplayMetrics().density); + } + + @CalledByNative + private static int getBrandIconIdealSize() { + Resources resources = ContextUtils.getApplicationContext().getResources(); + return Math.round(resources.getDimension(R.dimen.account_selection_continue_icon_size)); + } + + @CalledByNative private static @Nullable AccountSelectionBridge create( long nativeView, WindowAndroid windowAndroid) { BottomSheetController bottomSheetController =
diff --git a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionControllerTest.java b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionControllerTest.java index 89e33d9..4e03e14 100644 --- a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionControllerTest.java +++ b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionControllerTest.java
@@ -98,7 +98,7 @@ "Sam E. Goto", "Sam", TEST_PROFILE_PIC, /*isSignIn=*/false); private static final IdentityProviderMetadata IDP_METADATA = - new IdentityProviderMetadata(Color.BLACK, Color.BLACK); + new IdentityProviderMetadata(Color.BLACK, Color.BLACK, null); private static final ClientIdMetadata CLIENT_ID_METADATA = new ClientIdMetadata(TEST_URL_TERMS_OF_SERVICE, TEST_URL_PRIVACY_POLICY);
diff --git a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionIntegrationTest.java b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionIntegrationTest.java index ffc8476a..c1e2f4d 100644 --- a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionIntegrationTest.java +++ b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionIntegrationTest.java
@@ -98,7 +98,7 @@ private static final Account BOB = new Account("Bob", "", "Bob", "", TEST_PROFILE_PIC, false); private static final IdentityProviderMetadata IDP_METADATA = - new IdentityProviderMetadata(Color.BLACK, Color.BLACK); + new IdentityProviderMetadata(Color.BLACK, Color.BLACK, null); private static final ClientIdMetadata CLIENT_ID_METADATA = new ClientIdMetadata(TEST_URL_TERMS_OF_SERVICE, TEST_URL_PRIVACY_POLICY);
diff --git a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionViewBinder.java b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionViewBinder.java index 83021bd..6d40e5c 100644 --- a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionViewBinder.java +++ b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionViewBinder.java
@@ -237,6 +237,17 @@ } button.setTextColor(textColor); } + + Bitmap brandIcon = idpMetadata.getBrandIcon(); + if (brandIcon != null) { + Resources resources = context.getResources(); + int avatarSize = resources.getDimensionPixelSize( + R.dimen.account_selection_continue_icon_size); + Drawable croppedBrandIcon = + AvatarGenerator.makeRoundAvatar(resources, brandIcon, avatarSize); + button.setCompoundDrawablesWithIntrinsicBounds( + croppedBrandIcon, null, null, null); + } } } else if (key == ContinueButtonProperties.ACCOUNT) { Account account = model.get(ContinueButtonProperties.ACCOUNT);
diff --git a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionViewTest.java b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionViewTest.java index f069dfd..0fccfdf 100644 --- a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionViewTest.java +++ b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionViewTest.java
@@ -6,6 +6,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.verify; @@ -14,6 +16,10 @@ import static java.util.Arrays.asList; +import android.graphics.Bitmap; +import android.graphics.Color; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; import android.text.Spanned; import android.text.style.ClickableSpan; import android.view.View; @@ -42,6 +48,7 @@ import org.chromium.chrome.browser.ui.android.webid.AccountSelectionProperties.HeaderProperties; import org.chromium.chrome.browser.ui.android.webid.AccountSelectionProperties.HeaderProperties.HeaderType; import org.chromium.chrome.browser.ui.android.webid.data.Account; +import org.chromium.chrome.browser.ui.android.webid.data.IdentityProviderMetadata; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.content_public.browser.test.util.TouchCommon; @@ -175,7 +182,7 @@ .with(AccountProperties.ON_CLICK_LISTENER, null) .build()); - mSheetItems.addAll(asList(account_without_callback, buildContinueButton(ANA))); + mSheetItems.addAll(asList(account_without_callback, buildContinueButton(ANA, null))); }); pollUiThread(() -> mContentView.getVisibility() == View.VISIBLE); @@ -252,6 +259,46 @@ assertEquals("Expected two clickable links", 2, spans.length); } + /** + * Tests that the brand foreground and the brand icon are used in the "Continue" button. + */ + @Test + @MediumTest + public void testContinueButtonBranding() { + final int expectedTextColor = Color.BLUE; + final int expectedIconColor = Color.RED; + TestThreadUtils.runOnUiThreadBlocking(() -> { + Bitmap brandIcon = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); + brandIcon.eraseColor(expectedIconColor); + IdentityProviderMetadata idpMetadata = new IdentityProviderMetadata( + expectedTextColor, /*brandBackgroundColor*/ Color.GREEN, brandIcon); + + mSheetItems.addAll(Collections.singletonList(buildContinueButton(ANA, idpMetadata))); + }); + + pollUiThread(() -> mContentView.getVisibility() == View.VISIBLE); + + assertNotNull(getAccounts().getChildAt(0)); + TextView continueButton = mContentView.findViewById(R.id.account_selection_continue_btn); + + assertEquals(expectedTextColor, continueButton.getTextColors().getDefaultColor()); + + Drawable[] compoundDrawables = continueButton.getCompoundDrawables(); + assertEquals(4, compoundDrawables.length); + + assertTrue(compoundDrawables[0] instanceof BitmapDrawable); + Bitmap actualBrandIconBitmap = ((BitmapDrawable) compoundDrawables[0]).getBitmap(); + // AccountSelectionViewBinder crops the brand icon in a circle. Test a pixel in the middle + // of the icon which is unaffected by the cropping. + int centerX = actualBrandIconBitmap.getWidth() / 2; + int centerY = actualBrandIconBitmap.getHeight() / 2; + assertEquals(expectedIconColor, actualBrandIconBitmap.getColor(centerX, centerY).toArgb()); + + assertNull(compoundDrawables[1]); + assertNull(compoundDrawables[2]); + assertNull(compoundDrawables[3]); + } + private RecyclerView getAccounts() { return mContentView.findViewById(R.id.sheet_item_list); } @@ -277,12 +324,18 @@ .build()); } - private MVCListAdapter.ListItem buildContinueButton(Account account) { - return new MVCListAdapter.ListItem(AccountSelectionProperties.ItemType.CONTINUE_BUTTON, + private MVCListAdapter.ListItem buildContinueButton( + Account account, IdentityProviderMetadata idpMetadata) { + PropertyModel.Builder modelBuilder = new PropertyModel.Builder(ContinueButtonProperties.ALL_KEYS) .with(ContinueButtonProperties.ACCOUNT, account) - .with(ContinueButtonProperties.ON_CLICK_LISTENER, mAccountCallback) - .build()); + .with(ContinueButtonProperties.ON_CLICK_LISTENER, mAccountCallback); + if (idpMetadata != null) { + modelBuilder.with(ContinueButtonProperties.IDP_METADATA, idpMetadata); + } + + return new MVCListAdapter.ListItem( + AccountSelectionProperties.ItemType.CONTINUE_BUTTON, modelBuilder.build()); } private MVCListAdapter.ListItem buildCancelButton() {
diff --git a/chrome/browser/ui/android/webid/java/src/org/chromium/chrome/browser/ui/android/webid/data/IdentityProviderMetadata.java b/chrome/browser/ui/android/webid/java/src/org/chromium/chrome/browser/ui/android/webid/data/IdentityProviderMetadata.java index da5be5c..86ac1f8 100644 --- a/chrome/browser/ui/android/webid/java/src/org/chromium/chrome/browser/ui/android/webid/data/IdentityProviderMetadata.java +++ b/chrome/browser/ui/android/webid/java/src/org/chromium/chrome/browser/ui/android/webid/data/IdentityProviderMetadata.java
@@ -4,6 +4,8 @@ package org.chromium.chrome.browser.ui.android.webid.data; +import android.graphics.Bitmap; + import androidx.annotation.Nullable; import org.chromium.base.annotations.CalledByNative; @@ -15,15 +17,18 @@ public class IdentityProviderMetadata { private final Integer mBrandTextColor; private final Integer mBrandBackgroundColor; + private final Bitmap mBrandIcon; @CalledByNative - public IdentityProviderMetadata(long brandTextColor, long brandBackgroundColor) { + public IdentityProviderMetadata( + long brandTextColor, long brandBackgroundColor, Bitmap brandIcon) { // Parameters are longs because ColorUtils.INVALID_COLOR does not fit in an int. mBrandTextColor = (brandTextColor == ColorUtils.INVALID_COLOR) ? null : (int) brandTextColor; mBrandBackgroundColor = (brandBackgroundColor == ColorUtils.INVALID_COLOR) ? null : (int) brandBackgroundColor; + mBrandIcon = brandIcon; } public @Nullable Integer getBrandTextColor() { @@ -33,4 +38,8 @@ public @Nullable Integer getBrandBackgroundColor() { return mBrandBackgroundColor; } + + public Bitmap getBrandIcon() { + return mBrandIcon; + } }
diff --git a/chrome/browser/ui/app_list/search/ranking/ranker_delegate.h b/chrome/browser/ui/app_list/search/ranking/ranker_delegate.h index 6c6bfc77..d9851a5 100644 --- a/chrome/browser/ui/app_list/search/ranking/ranker_delegate.h +++ b/chrome/browser/ui/app_list/search/ranking/ranker_delegate.h
@@ -22,8 +22,7 @@ // behavior. class RankerDelegate : public Ranker { public: - RankerDelegate(Profile* profile, - SearchController* controller); + RankerDelegate(Profile* profile, SearchController* controller); ~RankerDelegate() override; RankerDelegate(const RankerDelegate&) = delete;
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 4957c457..2a67b7f 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
@@ -70,6 +70,9 @@ void SearchControllerImplNew::StartZeroState(base::OnceClosure on_done, base::TimeDelta timeout) { + // Categories currently are not used by zero-state, but may be required for + // sorting in SetResults. + categories_ = CreateAllCategories(); base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, std::move(on_done), timeout); } @@ -161,7 +164,15 @@ ranker_->UpdateResultRanks(results_, provider_type); ranker_->UpdateCategoryRanks(results_, categories_, provider_type); - // Compile a single list of results and sort by their relevance. + // Sort categories and create a vector of category enums in display order. + std::sort(categories_.begin(), categories_.end(), + [](const auto& a, const auto& b) { return a.score > b.score; }); + std::vector<Category> category_enums; + for (const auto& category : categories_) + category_enums.push_back(category.category); + + // Compile a single list of results and sort first by their category with best + // match first, and then by relevance. std::vector<ChromeSearchResult*> all_results; for (const auto& type_results : results_) { for (const auto& result : type_results.second) { @@ -186,17 +197,32 @@ all_results.push_back(result.get()); } } - std::sort(all_results.begin(), all_results.end(), - [](const ChromeSearchResult* a, const ChromeSearchResult* b) { - return a->display_score() > b->display_score(); - }); - // Create a vector of categories in display order. - std::sort(categories_.begin(), categories_.end(), - [](const auto& a, const auto& b) { return a.score > b.score; }); - std::vector<Category> category_enums; - for (const auto& category : categories_) - category_enums.push_back(category.category); + std::sort(all_results.begin(), all_results.end(), + [&](const ChromeSearchResult* a, const ChromeSearchResult* b) { + if (a->best_match() != b->best_match()) { + // First, sort best matches to the front of the list. + return a->best_match(); + } else if (!a->best_match() && a->category() != b->category()) { + // Next, sort by categories, except for within best match. + // |categories_| has been sorted above so the first category in + // |categories_| should be ranked more highly. + for (const auto& category : categories_) { + if (category.category == a->category()) { + return true; + } else if (category.category == b->category()) { + return false; + } + } + // Any category associated with a result should also be present + // in |categories_|. + NOTREACHED(); + return false; + } else { + // Lastly, sort by display score. + return a->display_score() > b->display_score(); + } + }); if (!observer_list_.empty()) { std::vector<const ChromeSearchResult*> observer_results;
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 7f6bb96c..b1206da 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
@@ -16,6 +16,7 @@ #include "base/observer_list.h" #include "chrome/browser/ui/app_list/search/mixer.h" #include "chrome/browser/ui/app_list/search/ranking/launch_data.h" +#include "chrome/browser/ui/app_list/search/ranking/ranker_delegate.h" #include "chrome/browser/ui/app_list/search/search_controller.h" class AppListControllerDelegate; @@ -32,7 +33,6 @@ class SearchMetricsObserver; class SearchProvider; -class RankerDelegate; enum class RankingItemType; // TODO(crbug.com/1199206): This is the new implementation of the search @@ -82,6 +82,11 @@ std::u16string get_query() override; base::Time session_start() override; + void set_ranker_delegate_for_test( + std::unique_ptr<RankerDelegate> ranker_delegate) { + ranker_ = std::move(ranker_delegate); + } + private: Profile* profile_;
diff --git a/chrome/browser/ui/app_list/search/search_controller_impl_new_unittest.cc b/chrome/browser/ui/app_list/search/search_controller_impl_new_unittest.cc new file mode 100644 index 0000000..5c6241f --- /dev/null +++ b/chrome/browser/ui/app_list/search/search_controller_impl_new_unittest.cc
@@ -0,0 +1,191 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/app_list/search/search_controller_impl_new.h" + +#include <memory> +#include <vector> + +#include "ash/public/cpp/app_list/app_list_features.h" +#include "ash/public/cpp/app_list/app_list_types.h" +#include "ash/public/cpp/test/shell_test_api.h" +#include "base/test/scoped_feature_list.h" +#include "chrome/browser/ui/app_list/search/chrome_search_result.h" +#include "chrome/browser/ui/app_list/search/ranking/ranker_delegate.h" +#include "chrome/browser/ui/app_list/search/search_controller.h" +#include "chrome/browser/ui/app_list/test/fake_app_list_model_updater.h" +#include "chrome/test/base/chrome_ash_test_base.h" +#include "chrome/test/base/testing_profile.h" +#include "content/public/test/browser_task_environment.h" + +namespace app_list { +namespace { + +using Category = ash::AppListSearchResultCategory; + +class TestSearchResult : public ChromeSearchResult { + public: + TestSearchResult(const std::string& id, + Category category, + bool best_match, + double relevance) { + set_id(id); + SetCategory(category); + SetBestMatch(best_match); + set_relevance(relevance); + scoring().normalized_relevance = relevance; + } + + TestSearchResult(const TestSearchResult&) = delete; + TestSearchResult& operator=(const TestSearchResult&) = delete; + ~TestSearchResult() override = default; + + private: + void Open(int event_flags) override { NOTIMPLEMENTED(); } +}; + +// A test ranker delegate that circumvents all result rankings, and hardcodes +// category ranking. +class TestRankerDelegate : public RankerDelegate { + public: + explicit TestRankerDelegate(Profile* profile) + : RankerDelegate(profile, nullptr) {} + ~TestRankerDelegate() override {} + + TestRankerDelegate(const TestRankerDelegate&) = delete; + TestRankerDelegate& operator=(const TestRankerDelegate&) = delete; + + void SetCategoryRanks(base::flat_map<Category, double> category_ranks) { + category_ranks_ = category_ranks; + } + + // Ranker: + void UpdateResultRanks(ResultsMap& results, ProviderType provider) override { + // Noop. + } + + // Ranker: + void UpdateCategoryRanks(const ResultsMap& results, + CategoriesList& categories, + ProviderType provider) override { + for (auto& category : categories) { + const auto it = category_ranks_.find(category.category); + if (it != category_ranks_.end()) + category.score = it->second; + } + } + + // Ranker: + void Start(const std::u16string& query, + ResultsMap& results, + CategoriesList& categories) override {} + void Train(const LaunchData& launch) override {} + void Remove(ChromeSearchResult* result) override {} + + private: + base::flat_map<Category, double> category_ranks_; +}; + +std::vector<std::unique_ptr<ChromeSearchResult>> MakeResults( + std::vector<std::string> ids, + std::vector<Category> categories, + std::vector<bool> best_matches, + std::vector<double> scores) { + std::vector<std::unique_ptr<ChromeSearchResult>> results; + for (size_t i = 0; i < ids.size(); ++i) { + results.emplace_back(std::make_unique<TestSearchResult>( + ids[i], categories[i], best_matches[i], scores[i])); + } + return results; +} + +} // namespace + +class SearchControllerImplNewTest : public testing::Test { + public: + SearchControllerImplNewTest() = default; + SearchControllerImplNewTest(const SearchControllerImplNewTest&) = delete; + SearchControllerImplNewTest& operator=(const SearchControllerImplNewTest&) = + delete; + ~SearchControllerImplNewTest() override = default; + + void SetUp() override { + // TODO(crbug.com/1258415): Feature list can be removed after launch. + scoped_feature_list_.InitWithFeatures( + {app_list_features::kCategoricalSearch}, {}); + + search_controller_ = std::make_unique<SearchControllerImplNew>( + /*model_updater=*/&model_updater_, /*list_controller=*/nullptr, + /*notifier=*/nullptr, &profile_); + + auto ranker_delegate = std::make_unique<TestRankerDelegate>(&profile_); + ranker_delegate_ = ranker_delegate.get(); + search_controller_->set_ranker_delegate_for_test( + std::move(ranker_delegate)); + } + + void ExpectIdOrder(std::vector<std::string> id_order) { + const auto& sorted_results = model_updater_.search_results(); + ASSERT_EQ(sorted_results.size(), id_order.size()); + for (size_t i = 0; i < sorted_results.size(); ++i) + EXPECT_EQ(sorted_results[i]->id(), id_order[i]); + } + + void Wait() { task_environment_.RunUntilIdle(); } + + protected: + content::BrowserTaskEnvironment task_environment_; + base::test::ScopedFeatureList scoped_feature_list_; + TestingProfile profile_; + FakeAppListModelUpdater model_updater_{&profile_, /*order_delegate=*/nullptr}; + std::unique_ptr<SearchControllerImplNew> search_controller_; + // Owned by |search_controller_|. + TestRankerDelegate* ranker_delegate_{nullptr}; +}; + +// Tests that categories are ordered correctly, and their results are grouped +// together and ordered by score. +TEST_F(SearchControllerImplNewTest, CategoriesOrderedCorrectly) { + ranker_delegate_->SetCategoryRanks( + {{Category::kFiles, 0.3}, {Category::kWeb, 0.2}, {Category::kApps, 0.1}}); + auto file_results = MakeResults({"a"}, {Category::kFiles}, {false}, {0.9}); + auto web_results = MakeResults( + {"c", "d", "b"}, {Category::kWeb, Category::kWeb, Category::kWeb}, + {false, false, false}, {0.2, 0.1, 0.4}); + auto app_results = MakeResults({"e"}, {Category::kApps}, {false}, {0.1}); + + // Simulate starting a search. + search_controller_->StartSearch(u"abc"); + // Simulate several providers returning results. + search_controller_->SetResults(ash::AppListSearchResultType::kOmnibox, + std::move(web_results)); + search_controller_->SetResults(ash::AppListSearchResultType::kInstalledApp, + std::move(app_results)); + search_controller_->SetResults(ash::AppListSearchResultType::kFileSearch, + std::move(file_results)); + + ExpectIdOrder({"a", "b", "c", "d", "e"}); +} + +// Tests that best matches are ordered first, and categories are ignored when +// ranking within best match. +TEST_F(SearchControllerImplNewTest, BestMatchesOrderedAboveOtherResults) { + auto results = MakeResults( + {"a", "b", "c", "d"}, + {Category::kWeb, Category::kWeb, Category::kApps, Category::kWeb}, + {true, false, true, false}, {0.4, 0.8, 0.2, 0.9}); + ranker_delegate_->SetCategoryRanks( + {{Category::kApps, 0.4}, {Category::kWeb, 0.2}}); + + search_controller_->StartSearch(u"abc"); + // Simulate a provider returning and containing all of the above results. A + // single provider wouldn't return many results like this, but that's + // unimportant for the test. + search_controller_->SetResults(ash::AppListSearchResultType::kOmnibox, + std::move(results)); + + ExpectIdOrder({"a", "c", "d", "b"}); +} + +} // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/search_controller_unittest.cc b/chrome/browser/ui/app_list/search/search_controller_impl_unittest.cc similarity index 85% rename from chrome/browser/ui/app_list/search/search_controller_unittest.cc rename to chrome/browser/ui/app_list/search/search_controller_impl_unittest.cc index 8fd490c..97cd453f 100644 --- a/chrome/browser/ui/app_list/search/search_controller_unittest.cc +++ b/chrome/browser/ui/app_list/search/search_controller_impl_unittest.cc
@@ -31,14 +31,15 @@ void Open(int event_flags) override { NOTIMPLEMENTED(); } }; -// SearchControllerTest -------------------------------------------------------- +// SearchControllerImplTest +// -------------------------------------------------------- -class SearchControllerTest : public ChromeAshTestBase { +class SearchControllerImplTest : public ChromeAshTestBase { public: - SearchControllerTest() = default; - SearchControllerTest(const SearchControllerTest&) = delete; - SearchControllerTest& operator=(const SearchControllerTest&) = delete; - ~SearchControllerTest() override = default; + SearchControllerImplTest() = default; + SearchControllerImplTest(const SearchControllerImplTest&) = delete; + SearchControllerImplTest& operator=(const SearchControllerImplTest&) = delete; + ~SearchControllerImplTest() override = default; SearchController& search_controller() { return search_controller_; } TestAppListControllerDelegate& list_controller() { return list_controller_; } @@ -52,7 +53,8 @@ // Tests ----------------------------------------------------------------------- -TEST_F(SearchControllerTest, ShouldConditionallyDismissViewWhenOpeningResult) { +TEST_F(SearchControllerImplTest, + ShouldConditionallyDismissViewWhenOpeningResult) { struct TestCase { bool is_tablet_mode = false; bool request_to_dismiss_view = false;
diff --git a/chrome/browser/ui/bluetooth/chrome_bluetooth_chooser_controller.cc b/chrome/browser/ui/bluetooth/chrome_bluetooth_chooser_controller.cc index 9f08367..46718b7b 100644 --- a/chrome/browser/ui/bluetooth/chrome_bluetooth_chooser_controller.cc +++ b/chrome/browser/ui/bluetooth/chrome_bluetooth_chooser_controller.cc
@@ -19,6 +19,7 @@ #include "components/strings/grit/components_strings.h" #include "content/public/browser/page_navigator.h" #include "content/public/browser/render_frame_host.h" +#include "content/public/browser/weak_document_ptr.h" #include "content/public/browser/web_contents.h" #include "content/public/common/referrer.h" #include "ui/base/page_transition_types.h" @@ -87,7 +88,8 @@ #if defined(OS_MAC) if (web_contents_) { ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck( - GURL(kBluetoothSettingsUri), web_contents_.get()); + GURL(kBluetoothSettingsUri), web_contents_.get(), + content::WeakDocumentPtr()); } #else NOTREACHED();
diff --git a/chrome/browser/ui/cocoa/window_size_autosaver.mm b/chrome/browser/ui/cocoa/window_size_autosaver.mm index 536484f..6938a16c 100644 --- a/chrome/browser/ui/cocoa/window_size_autosaver.mm +++ b/chrome/browser/ui/cocoa/window_size_autosaver.mm
@@ -54,57 +54,62 @@ - (void)save:(NSNotification*)notification { DictionaryPrefUpdate update(_prefService, _path); - base::DictionaryValue* windowPrefs = update.Get(); + base::Value* windowPrefs = update.Get(); NSRect frame = [_window frame]; if ([_window styleMask] & NSResizableWindowMask) { // Save the origin of the window. - windowPrefs->SetInteger("left", NSMinX(frame)); - windowPrefs->SetInteger("right", NSMaxX(frame)); + windowPrefs->SetIntKey("left", NSMinX(frame)); + windowPrefs->SetIntKey("right", NSMaxX(frame)); // windows's and linux's profiles have top < bottom due to having their // screen origin in the upper left, while cocoa's is in the lower left. To // keep the top < bottom invariant, store top in bottom and vice versa. - windowPrefs->SetInteger("top", NSMinY(frame)); - windowPrefs->SetInteger("bottom", NSMaxY(frame)); + windowPrefs->SetIntKey("top", NSMinY(frame)); + windowPrefs->SetIntKey("bottom", NSMaxY(frame)); } else { // Save the origin of the window. - windowPrefs->SetInteger("x", frame.origin.x); - windowPrefs->SetInteger("y", frame.origin.y); + windowPrefs->SetIntKey("x", frame.origin.x); + windowPrefs->SetIntKey("y", frame.origin.y); } } - (void)restore { // Get the positioning information. - const base::DictionaryValue* windowPrefs = - &base::Value::AsDictionaryValue(*_prefService->GetDictionary(_path)); + const base::Value* windowPrefs = _prefService->GetDictionary(_path); if ([_window styleMask] & NSResizableWindowMask) { - int x1, x2, y1, y2; - if (!windowPrefs->GetInteger("left", &x1) || - !windowPrefs->GetInteger("right", &x2) || - !windowPrefs->GetInteger("top", &y1) || - !windowPrefs->GetInteger("bottom", &y2)) { + absl::optional<int> x1 = windowPrefs->FindIntKey("left"); + absl::optional<int> x2 = windowPrefs->FindIntKey("right"); + absl::optional<int> y1 = windowPrefs->FindIntKey("top"); + absl::optional<int> y2 = windowPrefs->FindIntKey("bottom"); + if (!x1.has_value() || !x2.has_value() || !y1.has_value() || + !y2.has_value()) { return; } - if (x2 - x1 < kMinWindowWidth || y2 - y1 < kMinWindowHeight) { + if (x2.value() - x1.value() < kMinWindowWidth || + y2.value() - y1.value() < kMinWindowHeight) { // Windows should never be very small. DictionaryPrefUpdate update(_prefService, _path); - base::DictionaryValue* mutableWindowPrefs = update.Get(); + base::Value* mutableWindowPrefs = update.Get(); mutableWindowPrefs->RemoveKey("left"); mutableWindowPrefs->RemoveKey("right"); mutableWindowPrefs->RemoveKey("top"); mutableWindowPrefs->RemoveKey("bottom"); } else { - [_window setFrame:NSMakeRect(x1, y1, x2 - x1, y2 - y1) display:YES]; + [_window + setFrame:NSMakeRect(x1.value(), y1.value(), x2.value() - x1.value(), + y2.value() - y1.value()) + display:YES]; // Make sure the window is on-screen. [_window cascadeTopLeftFromPoint:NSZeroPoint]; } } else { - int x, y; - if (!windowPrefs->GetInteger("x", &x) || - !windowPrefs->GetInteger("y", &y)) - return; // Nothing stored. + absl::optional<int> x = windowPrefs->FindIntKey("x"); + absl::optional<int> y = windowPrefs->FindIntKey("y"); + if (!x.has_value() || !y.has_value()) + return; // Nothing stored. // Turn the origin (lower-left) into an upper-left window point. - NSPoint upperLeft = NSMakePoint(x, y + NSHeight([_window frame])); + NSPoint upperLeft = + NSMakePoint(x.value(), y.value() + NSHeight([_window frame])); [_window cascadeTopLeftFromPoint:upperLeft]; } }
diff --git a/chrome/browser/ui/cocoa/window_size_autosaver_unittest.mm b/chrome/browser/ui/cocoa/window_size_autosaver_unittest.mm index c247d81..365ff61 100644 --- a/chrome/browser/ui/cocoa/window_size_autosaver_unittest.mm +++ b/chrome/browser/ui/cocoa/window_size_autosaver_unittest.mm
@@ -96,18 +96,18 @@ } // ...and it should be in the profile, too. - EXPECT_TRUE(pref->GetDictionary(path_)); - int x, y; - const base::DictionaryValue* windowPref = - &base::Value::AsDictionaryValue(*pref->GetDictionary(path_)); - EXPECT_FALSE(windowPref->GetInteger("left", &x)); - EXPECT_FALSE(windowPref->GetInteger("right", &x)); - EXPECT_FALSE(windowPref->GetInteger("top", &x)); - EXPECT_FALSE(windowPref->GetInteger("bottom", &x)); - ASSERT_TRUE(windowPref->GetInteger("x", &x)); - ASSERT_TRUE(windowPref->GetInteger("y", &y)); - EXPECT_EQ(300, x); - EXPECT_EQ(310, y); + const base::Value* windowPref = pref->GetDictionary(path_); + ASSERT_TRUE(windowPref); + EXPECT_FALSE(windowPref->FindIntKey("left").has_value()); + EXPECT_FALSE(windowPref->FindIntKey("right").has_value()); + EXPECT_FALSE(windowPref->FindIntKey("top").has_value()); + EXPECT_FALSE(windowPref->FindIntKey("bottom").has_value()); + absl::optional<int> x = windowPref->FindIntKey("x"); + absl::optional<int> y = windowPref->FindIntKey("y"); + ASSERT_TRUE(x.has_value()); + ASSERT_TRUE(y.has_value()); + EXPECT_EQ(300, x.value()); + EXPECT_EQ(310, y.value()); } TEST_F(WindowSizeAutosaverTest, RestoresAndSavesRect) { @@ -157,19 +157,22 @@ // ...and it should be in the profile, too. EXPECT_TRUE(pref->GetDictionary(path_)); - int x1, y1, x2, y2; - const base::DictionaryValue* windowPref = - &base::Value::AsDictionaryValue(*pref->GetDictionary(path_)); - EXPECT_FALSE(windowPref->GetInteger("x", &x1)); - EXPECT_FALSE(windowPref->GetInteger("y", &x1)); - ASSERT_TRUE(windowPref->GetInteger("left", &x1)); - ASSERT_TRUE(windowPref->GetInteger("right", &x2)); - ASSERT_TRUE(windowPref->GetInteger("top", &y1)); - ASSERT_TRUE(windowPref->GetInteger("bottom", &y2)); - EXPECT_EQ(300, x1); - EXPECT_EQ(310, y1); - EXPECT_EQ(300 + 250, x2); - EXPECT_EQ(310 + 252, y2); + const base::Value* windowPref = pref->GetDictionary(path_); + ASSERT_TRUE(windowPref); + EXPECT_FALSE(windowPref->FindIntKey("x").has_value()); + EXPECT_FALSE(windowPref->FindIntKey("y").has_value()); + absl::optional<int> x1 = windowPref->FindIntKey("left"); + absl::optional<int> x2 = windowPref->FindIntKey("right"); + absl::optional<int> y1 = windowPref->FindIntKey("top"); + absl::optional<int> y2 = windowPref->FindIntKey("bottom"); + ASSERT_TRUE(x1.has_value()); + ASSERT_TRUE(x2.has_value()); + ASSERT_TRUE(y1.has_value()); + ASSERT_TRUE(y2.has_value()); + EXPECT_EQ(300, x1.value()); + EXPECT_EQ(310, y1.value()); + EXPECT_EQ(300 + 250, x2.value()); + EXPECT_EQ(310 + 252, y2.value()); } // http://crbug.com/39625 @@ -178,11 +181,11 @@ ASSERT_TRUE(pref); DictionaryPrefUpdate update(pref, path_); - base::DictionaryValue* windowPref = update.Get(); - windowPref->SetInteger("left", 50); - windowPref->SetInteger("right", 50); - windowPref->SetInteger("top", 60); - windowPref->SetInteger("bottom", 60); + base::Value* windowPref = update.Get(); + windowPref->SetIntKey("left", 50); + windowPref->SetIntKey("right", 50); + windowPref->SetIntKey("top", 60); + windowPref->SetIntKey("bottom", 60); { // Window rect shouldn't change... @@ -199,13 +202,12 @@ // ...and it should be gone from the profile, too. EXPECT_TRUE(pref->GetDictionary(path_)); - int x1, y1, x2, y2; - EXPECT_FALSE(windowPref->GetInteger("x", &x1)); - EXPECT_FALSE(windowPref->GetInteger("y", &x1)); - ASSERT_FALSE(windowPref->GetInteger("left", &x1)); - ASSERT_FALSE(windowPref->GetInteger("right", &x2)); - ASSERT_FALSE(windowPref->GetInteger("top", &y1)); - ASSERT_FALSE(windowPref->GetInteger("bottom", &y2)); + EXPECT_FALSE(windowPref->FindIntKey("x").has_value()); + EXPECT_FALSE(windowPref->FindIntKey("y").has_value()); + ASSERT_FALSE(windowPref->FindIntKey("left").has_value()); + ASSERT_FALSE(windowPref->FindIntKey("right").has_value()); + ASSERT_FALSE(windowPref->FindIntKey("top").has_value()); + ASSERT_FALSE(windowPref->FindIntKey("bottom").has_value()); } } // namespace
diff --git a/chrome/browser/ui/color/BUILD.gn b/chrome/browser/ui/color/BUILD.gn index 0eccf93..08e8c46 100644 --- a/chrome/browser/ui/color/BUILD.gn +++ b/chrome/browser/ui/color/BUILD.gn
@@ -18,6 +18,8 @@ "chrome_color_mixers.h", "chrome_color_provider_utils.cc", "chrome_color_provider_utils.h", + "native_chrome_color_mixer.cc", + "native_chrome_color_mixer.h", "omnibox_color_mixer.cc", "omnibox_color_mixer.h", ] @@ -27,6 +29,10 @@ "//ui/color:color", "//ui/color:mixers", ] + + if (is_win) { + sources += [ "win/native_chrome_color_mixer_win.cc" ] + } } if (!is_ios && !is_android && !is_chromecast && !is_fuchsia) {
diff --git a/chrome/browser/ui/color/chrome_color_id.h b/chrome/browser/ui/color/chrome_color_id.h index 5d60ba16..2212fd6 100644 --- a/chrome/browser/ui/color/chrome_color_id.h +++ b/chrome/browser/ui/color/chrome_color_id.h
@@ -56,11 +56,17 @@ ThemeProperties::COLOR_OMNIBOX_SECURITY_CHIP_SECURE) \ E(kColorOmniboxText, ThemeProperties::COLOR_OMNIBOX_TEXT) \ E(kColorOmniboxTextDimmed, ThemeProperties::COLOR_OMNIBOX_TEXT_DIMMED) \ + /* Tab output colors. */ \ + E(kColorTabForegroundActiveFrameActive, \ + ThemeProperties::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_ACTIVE) \ + E(kColorTabForegroundActiveFrameInactive, \ + ThemeProperties::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_INACTIVE) \ /* Toolbar output colors. */ \ E(kColorToolbar, ThemeProperties::COLOR_TOOLBAR) \ E(kColorToolbarButtonIcon, ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON) \ E(kColorToolbarContentAreaSeparator, \ - ThemeProperties::COLOR_TOOLBAR_CONTENT_AREA_SEPARATOR) + ThemeProperties::COLOR_TOOLBAR_CONTENT_AREA_SEPARATOR) \ + E(kColorToolbarText, ThemeProperties::COLOR_TOOLBAR_TEXT) #include "ui/color/color_id_macros.inc"
diff --git a/chrome/browser/ui/color/chrome_color_mixer.cc b/chrome/browser/ui/color/chrome_color_mixer.cc index 7eea2018..0bf1481 100644 --- a/chrome/browser/ui/color/chrome_color_mixer.cc +++ b/chrome/browser/ui/color/chrome_color_mixer.cc
@@ -4,8 +4,6 @@ #include "chrome/browser/ui/color/chrome_color_mixer.h" -#include "base/bind.h" -#include "build/build_config.h" #include "chrome/browser/ui/color/chrome_color_id.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/color/color_id.h" @@ -22,13 +20,13 @@ if (dark_mode) { mixer[kColorOmniboxBackground] = {gfx::kGoogleGrey900}; mixer[kColorOmniboxText] = {SK_ColorWHITE}; - mixer[kColorToolbar] = {SkColorSetRGB(0x35, 0x36, 0x3A)}; + mixer[kColorToolbarText] = {SK_ColorWHITE}; } else { mixer[kColorOmniboxBackground] = {gfx::kGoogleGrey100}; mixer[kColorOmniboxText] = {gfx::kGoogleGrey900}; - mixer[kColorToolbar] = {SK_ColorWHITE}; + mixer[kColorToolbarText] = {gfx::kGoogleGrey800}; } } @@ -40,27 +38,16 @@ key.color_mode == ui::ColorProviderManager::ColorMode::kDark; ui::ColorMixer& mixer = provider->AddMixer(); -#if defined(OS_WIN) - const bool high_contrast_mode = - key.contrast_mode == ui::ColorProviderManager::ContrastMode::kHigh; - if (high_contrast_mode) { - // High contrast uses system colors. - mixer[kColorOmniboxBackground] = {ui::kColorNativeBtnFace}; - mixer[kColorOmniboxText] = {ui::kColorNativeBtnText}; - - mixer[kColorToolbar] = {ui::kColorNativeWindow}; - } else { - AddBaseColors(dark_mode, mixer); - } -#else AddBaseColors(dark_mode, mixer); -#endif - // Download shelf colors. + mixer[kColorBookmarkText] = {kColorToolbarText}; mixer[kColorDownloadShelf] = {kColorToolbar}; mixer[kColorDownloadShelfButtonBackground] = {kColorDownloadShelf}; mixer[kColorDownloadShelfButtonText] = ui::PickGoogleColor(ui::kColorAccent, kColorDownloadShelf, color_utils::kMinimumReadableContrastRatio); + mixer[kColorTabForegroundActiveFrameActive] = {kColorToolbarText}; + mixer[kColorTabForegroundActiveFrameInactive] = { + kColorTabForegroundActiveFrameActive}; mixer[kColorToolbarContentAreaSeparator] = {ui::kColorSeparator}; }
diff --git a/chrome/browser/ui/color/chrome_color_mixers.cc b/chrome/browser/ui/color/chrome_color_mixers.cc index 14d1ba6..f3549552 100644 --- a/chrome/browser/ui/color/chrome_color_mixers.cc +++ b/chrome/browser/ui/color/chrome_color_mixers.cc
@@ -5,11 +5,13 @@ #include "chrome/browser/ui/color/chrome_color_mixers.h" #include "chrome/browser/ui/color/chrome_color_mixer.h" +#include "chrome/browser/ui/color/native_chrome_color_mixer.h" #include "chrome/browser/ui/color/omnibox_color_mixer.h" void AddChromeColorMixers(ui::ColorProvider* provider, const ui::ColorProviderManager::Key& key) { AddChromeColorMixer(provider, key); + AddNativeChromeColorMixer(provider, key); AddOmniboxColorMixer(provider, key); if (key.custom_theme) {
diff --git a/chrome/browser/ui/color/native_chrome_color_mixer.cc b/chrome/browser/ui/color/native_chrome_color_mixer.cc new file mode 100644 index 0000000..4eb7302 --- /dev/null +++ b/chrome/browser/ui/color/native_chrome_color_mixer.cc
@@ -0,0 +1,12 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/color/native_chrome_color_mixer.h" + +#include "build/build_config.h" + +#if !defined(OS_WIN) +void AddNativeChromeColorMixer(ui::ColorProvider* provider, + const ui::ColorProviderManager::Key& key) {} +#endif
diff --git a/chrome/browser/ui/color/native_chrome_color_mixer.h b/chrome/browser/ui/color/native_chrome_color_mixer.h new file mode 100644 index 0000000..fef722b7 --- /dev/null +++ b/chrome/browser/ui/color/native_chrome_color_mixer.h
@@ -0,0 +1,20 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_COLOR_NATIVE_CHROME_COLOR_MIXER_H_ +#define CHROME_BROWSER_UI_COLOR_NATIVE_CHROME_COLOR_MIXER_H_ + +#include "ui/color/color_provider_manager.h" + +namespace ui { +class ColorProvider; +} + +// Adds a color mixer to |provider| that can override the default chrome colors. +// This function should be implemented on a per-platform basis in relevant +// subdirectories. +void AddNativeChromeColorMixer(ui::ColorProvider* provider, + const ui::ColorProviderManager::Key& key); + +#endif // CHROME_BROWSER_UI_COLOR_NATIVE_CHROME_COLOR_MIXER_H_
diff --git a/chrome/browser/ui/color/win/native_chrome_color_mixer_win.cc b/chrome/browser/ui/color/win/native_chrome_color_mixer_win.cc new file mode 100644 index 0000000..fbaca64 --- /dev/null +++ b/chrome/browser/ui/color/win/native_chrome_color_mixer_win.cc
@@ -0,0 +1,27 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/color/native_chrome_color_mixer.h" + +#include "chrome/browser/ui/color/chrome_color_id.h" +#include "ui/color/color_id.h" +#include "ui/color/color_mixer.h" +#include "ui/color/color_provider.h" +#include "ui/color/color_provider_manager.h" +#include "ui/color/color_recipe.h" + +void AddNativeChromeColorMixer(ui::ColorProvider* provider, + const ui::ColorProviderManager::Key& key) { + if (key.contrast_mode != ui::ColorProviderManager::ContrastMode::kHigh) + return; + + ui::ColorMixer& mixer = provider->AddMixer(); + + // High contrast uses system colors. + mixer[kColorOmniboxBackground] = {ui::kColorNativeBtnFace}; + mixer[kColorOmniboxText] = {ui::kColorNativeBtnText}; + mixer[kColorToolbar] = {ui::kColorNativeWindow}; + mixer[kColorToolbarText] = {ui::kColorNativeBtnText}; + mixer[kColorTabForegroundActiveFrameActive] = {ui::kColorNativeHighlightText}; +}
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc index df80cdd..6d47b2c 100644 --- a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc +++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
@@ -67,6 +67,7 @@ #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" +#include "content/public/browser/weak_document_ptr.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_delegate.h" #include "mojo/public/cpp/bindings/associated_remote.h" @@ -887,10 +888,10 @@ if (CameraAccessed()) { ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck( - GURL(kCameraSettingsURI), web_contents()); + GURL(kCameraSettingsURI), web_contents(), content::WeakDocumentPtr()); } else if (MicrophoneAccessed()) { ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck( - GURL(kMicSettingsURI), web_contents()); + GURL(kMicSettingsURI), web_contents(), content::WeakDocumentPtr()); } return; #endif // defined(OS_MAC) @@ -1268,7 +1269,7 @@ } ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck( - GURL(kLocationSettingsURI), web_contents()); + GURL(kLocationSettingsURI), web_contents(), content::WeakDocumentPtr()); return; #endif // defined(OS_MAC) }
diff --git a/chrome/browser/ui/profile_picker.h b/chrome/browser/ui/profile_picker.h index 6d48eb1e..0c11b39 100644 --- a/chrome/browser/ui/profile_picker.h +++ b/chrome/browser/ui/profile_picker.h
@@ -7,6 +7,7 @@ #include "base/callback_forward.h" #include "base/feature_list.h" +#include "base/files/file_path.h" #include "base/time/time.h" #include "chrome/browser/ui/webui/signin/enterprise_profile_welcome_ui.h" #include "components/signin/public/base/signin_buildflags.h" @@ -16,11 +17,6 @@ class GURL; class Profile; - -namespace base { -class FilePath; -} // namespace base - namespace content { class BrowserContext; }
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc index 50ce688..27300cb 100644 --- a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc +++ b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc
@@ -391,6 +391,9 @@ inner_labels_.push_back(label); } + // Returns the string to be set as the name of the ui::AXNodeData. + std::u16string GetVoiceOverString(); + private: // Returns a vector of optional labels to be displayed beneath value. virtual std::vector<std::unique_ptr<views::View>> CreateSubtextViews(); @@ -585,38 +588,8 @@ void AutofillPopupItemView::GetAccessibleNodeData(ui::AXNodeData* node_data) { base::WeakPtr<AutofillPopupController> controller = popup_view()->controller(); - std::vector<std::u16string> text; - auto suggestion = controller->GetSuggestionAt(GetLineNumber()); - std::u16string icon_name = GetIconAccessibleName(suggestion.icon); - if (!icon_name.empty()) - text.push_back(icon_name); - - auto main_text = controller->GetSuggestionMainTextAt(GetLineNumber()); - text.push_back(main_text); - - auto minor_text = controller->GetSuggestionMinorTextAt(GetLineNumber()); - if (!minor_text.empty()) - text.push_back(minor_text); - - auto label_text = controller->GetSuggestionLabelAt(GetLineNumber()); - if (!label_text.empty()) { - // |label| is not populated for footers or autocomplete entries. - text.push_back(label_text); - } - - // TODO(siyua): GetSuggestionLabelAt should return a vector of strings. - if (!suggestion.offer_label.empty()) { - // |offer_label| is only populated for credit card suggestions. - text.push_back(suggestion.offer_label); - } - - if (!suggestion.additional_label.empty()) { - // |additional_label| is only populated in a passwords context. - text.push_back(suggestion.additional_label); - } - - node_data->SetName(base::JoinString(text, u" ")); + node_data->SetName(GetVoiceOverString()); // Options are selectable. node_data->role = ax::mojom::Role::kListBoxOption; @@ -903,6 +876,47 @@ /*use_min_size=*/true); } +std::u16string AutofillPopupItemView::GetVoiceOverString() { + base::WeakPtr<AutofillPopupController> controller = + popup_view()->controller(); + + auto suggestion = controller->GetSuggestionAt(GetLineNumber()); + + if (suggestion.voice_over) + return *suggestion.voice_over; + + std::vector<std::u16string> text; + std::u16string icon_name = GetIconAccessibleName(suggestion.icon); + if (!icon_name.empty()) + text.push_back(icon_name); + + auto main_text = controller->GetSuggestionMainTextAt(GetLineNumber()); + text.push_back(main_text); + + auto minor_text = controller->GetSuggestionMinorTextAt(GetLineNumber()); + if (!minor_text.empty()) + text.push_back(minor_text); + + auto label_text = controller->GetSuggestionLabelAt(GetLineNumber()); + if (!label_text.empty()) { + // |label| is not populated for footers or autocomplete entries. + text.push_back(label_text); + } + + // TODO(siyua): GetSuggestionLabelAt should return a vector of strings. + if (!suggestion.offer_label.empty()) { + // |offer_label| is only populated for credit card suggestions. + text.push_back(suggestion.offer_label); + } + + if (!suggestion.additional_label.empty()) { + // |additional_label| is only populated in a passwords context. + text.push_back(suggestion.additional_label); + } + + return base::JoinString(text, u" "); +} + /************** AutofillPopupSuggestionView **************/ // static
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views_unittest.cc b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views_unittest.cc index d5c14405..34951245 100644 --- a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views_unittest.cc +++ b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views_unittest.cc
@@ -292,6 +292,33 @@ widget_->OnMouseEvent(&click_mouse_event); } +// Ensure that the voice_over value of suggestions is presented to the +// accessibility layer. +TEST_F(AutofillPopupViewNativeViewsTest, VoiceOverTest) { + const std::u16string voice_over_value = u"Password for user@gmail.com"; + // Create a realistic suggestion for a password. + autofill::Suggestion suggestion(u"user@gmail.com"); + suggestion.is_value_secondary = false; + suggestion.label = u"example.com"; + suggestion.voice_over = voice_over_value; + suggestion.additional_label = u"\u2022\u2022\u2022\u2022"; + suggestion.frontend_id = autofill::POPUP_ITEM_ID_USERNAME_ENTRY; + + // Create autofill menu. + autofill_popup_controller_.set_suggestions({suggestion}); + view_ = std::make_unique<autofill::AutofillPopupViewNativeViews>( + autofill_popup_controller_.GetWeakPtr(), widget_.get()); + widget_->SetContentsView(view_.get()); + widget_->Show(); + view_->Show(); + + // Verify that the accessibility layer gets the right string to read out. + ui::AXNodeData node_data; + view_->GetRowsForTesting()[0]->GetAccessibleNodeData(&node_data); + EXPECT_EQ(voice_over_value, + node_data.GetString16Attribute(ax::mojom::StringAttribute::kName)); +} + // Tests that (only) clickable items trigger an AcceptSuggestion event. TEST_P(AutofillPopupViewNativeViewsTestWithAnyPopupItemId, ShowClickTest) { CreateAndShowView({popup_item_id()});
diff --git a/chrome/browser/ui/views/chrome_typography_provider.cc b/chrome/browser/ui/views/chrome_typography_provider.cc index 1e07f94..c7121bc7 100644 --- a/chrome/browser/ui/views/chrome_typography_provider.cc +++ b/chrome/browser/ui/views/chrome_typography_provider.cc
@@ -129,13 +129,11 @@ if (context == CONTEXT_DOWNLOAD_SHELF || (context == CONTEXT_DOWNLOAD_SHELF_STATUS && style == views::style::STYLE_DISABLED)) { - // TODO(pkasting): Instead of reusing COLOR_BOOKMARK_TEXT, use dedicated - // values. const auto* theme_provider = view.GetThemeProvider(); if (!theme_provider) return gfx::kPlaceholderColor; const SkColor base_color = - theme_provider->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT); + theme_provider->GetColor(ThemeProperties::COLOR_TOOLBAR_TEXT); // TODO(pkasting): Should use some way of dimming text that's as analogous // as possible to e.g. enabled vs. disabled labels. const SkColor dimmed_color = SkColorSetA(base_color, 0xC7);
diff --git a/chrome/browser/ui/views/download/download_item_view.cc b/chrome/browser/ui/views/download/download_item_view.cc index 4394b52..88cf0de 100644 --- a/chrome/browser/ui/views/download/download_item_view.cc +++ b/chrome/browser/ui/views/download/download_item_view.cc
@@ -320,6 +320,7 @@ file_name_label_ = AddChildView(std::make_unique<views::Label>()); file_name_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); file_name_label_->SetTextContext(CONTEXT_DOWNLOAD_SHELF); + file_name_label_->SetAutoColorReadabilityEnabled(false); file_name_label_->GetViewAccessibility().OverrideIsIgnored(true); const std::u16string filename = ElidedFilename(*file_name_label_); file_name_label_->SetText(filename); @@ -329,13 +330,16 @@ status_label_ = AddChildView(std::make_unique<views::Label>( std::u16string(), CONTEXT_DOWNLOAD_SHELF_STATUS)); status_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); + status_label_->SetAutoColorReadabilityEnabled(false); warning_label_ = AddChildView(std::make_unique<views::StyledLabel>()); warning_label_->SetTextContext(CONTEXT_DOWNLOAD_SHELF); + warning_label_->SetAutoColorReadabilityEnabled(false); warning_label_->SetCanProcessEventsWithinSubtree(false); deep_scanning_label_ = AddChildView(std::make_unique<views::StyledLabel>()); deep_scanning_label_->SetTextContext(CONTEXT_DOWNLOAD_SHELF); + deep_scanning_label_->SetAutoColorReadabilityEnabled(false); deep_scanning_label_->SetCanProcessEventsWithinSubtree(false); open_now_button_ = AddChildView(std::make_unique<views::MdTextButton>( @@ -697,10 +701,6 @@ const SkColor background_color = GetThemeProvider()->GetColor(ThemeProperties::COLOR_DOWNLOAD_SHELF); SetBackground(views::CreateSolidBackground(background_color)); - file_name_label_->SetBackgroundColor(background_color); - status_label_->SetBackgroundColor(background_color); - warning_label_->SetDisplayedOnBackgroundColor(background_color); - deep_scanning_label_->SetDisplayedOnBackgroundColor(background_color); shelf_->ConfigureButtonForTheme(open_now_button_); shelf_->ConfigureButtonForTheme(save_button_); @@ -1282,7 +1282,7 @@ dropdown_button_, dropdown_pressed_ ? vector_icons::kCaretDownIcon : vector_icons::kCaretUpIcon, - GetThemeProvider()->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT)); + GetThemeProvider()->GetColor(ThemeProperties::COLOR_TOOLBAR_TEXT)); dropdown_button_->SizeToPreferredSize(); }
diff --git a/chrome/browser/ui/views/download/download_shelf_view.cc b/chrome/browser/ui/views/download/download_shelf_view.cc index 4b0c339a..76fdee3c 100644 --- a/chrome/browser/ui/views/download/download_shelf_view.cc +++ b/chrome/browser/ui/views/download/download_shelf_view.cc
@@ -368,7 +368,7 @@ views::SetImageFromVectorIcon( close_button_, vector_icons::kCloseRoundedIcon, - GetThemeProvider()->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT)); + GetThemeProvider()->GetColor(ThemeProperties::COLOR_TOOLBAR_TEXT)); } views::View* DownloadShelfView::GetDefaultFocusableChild() {
diff --git a/chrome/browser/ui/views/external_protocol_dialog.cc b/chrome/browser/ui/views/external_protocol_dialog.cc index cf4fc1b..80216b5 100644 --- a/chrome/browser/ui/views/external_protocol_dialog.cc +++ b/chrome/browser/ui/views/external_protocol_dialog.cc
@@ -23,6 +23,7 @@ #include "components/constrained_window/constrained_window_views.h" #include "components/prefs/pref_service.h" #include "components/url_formatter/elide_url.h" +#include "content/public/browser/weak_document_ptr.h" #include "content/public/browser/web_contents.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/metadata/metadata_impl_macros.h" @@ -54,7 +55,8 @@ WebContents* web_contents, ui::PageTransition ignored_page_transition, bool ignored_has_user_gesture, - const absl::optional<url::Origin>& initiating_origin) { + const absl::optional<url::Origin>& initiating_origin, + content::WeakDocumentPtr initiator_document) { DCHECK(web_contents); std::u16string program_name = @@ -65,8 +67,8 @@ } // Windowing system takes ownership. - new ExternalProtocolDialog(web_contents, url, program_name, - initiating_origin); + new ExternalProtocolDialog(web_contents, url, program_name, initiating_origin, + std::move(initiator_document)); } #endif // !BUILDFLAG(IS_CHROMEOS_ASH) @@ -74,11 +76,13 @@ WebContents* web_contents, const GURL& url, const std::u16string& program_name, - const absl::optional<url::Origin>& initiating_origin) + const absl::optional<url::Origin>& initiating_origin, + content::WeakDocumentPtr initiator_document) : web_contents_(web_contents->GetWeakPtr()), url_(url), program_name_(program_name), - initiating_origin_(initiating_origin) { + initiating_origin_(initiating_origin), + initiator_document_(std::move(initiator_document)) { SetDefaultButton(ui::DIALOG_BUTTON_CANCEL); SetButtonLabel(ui::DIALOG_BUTTON_OK, l10n_util::GetStringFUTF16( @@ -171,8 +175,8 @@ profile); } - ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck(url_, - web_contents_.get()); + ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck( + url_, web_contents_.get(), initiator_document_); } views::View* ExternalProtocolDialog::GetContentsView() {
diff --git a/chrome/browser/ui/views/external_protocol_dialog.h b/chrome/browser/ui/views/external_protocol_dialog.h index edc83dd7..1e21bd8d 100644 --- a/chrome/browser/ui/views/external_protocol_dialog.h +++ b/chrome/browser/ui/views/external_protocol_dialog.h
@@ -8,6 +8,7 @@ #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" #include "chrome/browser/profiles/profile.h" +#include "content/public/browser/weak_document_ptr.h" #include "ui/base/metadata/metadata_header_macros.h" #include "ui/views/window/dialog_delegate.h" #include "url/gurl.h" @@ -32,7 +33,8 @@ ExternalProtocolDialog(content::WebContents* web_contents, const GURL& url, const std::u16string& program_name, - const absl::optional<url::Origin>& initiating_origin); + const absl::optional<url::Origin>& initiating_origin, + content::WeakDocumentPtr initiator_document); ExternalProtocolDialog(const ExternalProtocolDialog&) = delete; ExternalProtocolDialog& operator=(const ExternalProtocolDialog&) = delete; ~ExternalProtocolDialog() override; @@ -51,11 +53,12 @@ void SetRememberSelectionCheckboxCheckedForTesting(bool checked); void OnDialogAccepted(); - base::WeakPtr<content::WebContents> web_contents_; + const base::WeakPtr<content::WebContents> web_contents_; const GURL url_; const std::u16string program_name_; const absl::optional<url::Origin> initiating_origin_; + const content::WeakDocumentPtr initiator_document_; // The message box whose commands we handle. raw_ptr<views::MessageBoxView> message_box_view_ = nullptr;
diff --git a/chrome/browser/ui/views/external_protocol_dialog_browsertest.cc b/chrome/browser/ui/views/external_protocol_dialog_browsertest.cc index 53b382a..dcec56c 100644 --- a/chrome/browser/ui/views/external_protocol_dialog_browsertest.cc +++ b/chrome/browser/ui/views/external_protocol_dialog_browsertest.cc
@@ -19,6 +19,7 @@ #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" +#include "content/public/browser/weak_document_ptr.h" #include "content/public/browser/web_contents.h" #include "content/public/test/browser_test.h" #include "net/dns/mock_host_resolver.h" @@ -100,7 +101,8 @@ browser()->tab_strip_model()->GetActiveWebContents(); dialog_ = new ExternalProtocolDialog( web_contents, GURL("telnet://12345"), u"/usr/bin/telnet", - url::Origin::Create(GURL(initiating_origin))); + url::Origin::Create(GURL(initiating_origin)), + web_contents->GetMainFrame()->GetWeakDocumentPtr()); } void SetChecked(bool checked) {
diff --git a/chrome/browser/ui/views/infobars/infobar_view.cc b/chrome/browser/ui/views/infobars/infobar_view.cc index 223ad75..cabd9ef 100644 --- a/chrome/browser/ui/views/infobars/infobar_view.cc +++ b/chrome/browser/ui/views/infobars/infobar_view.cc
@@ -62,7 +62,7 @@ // IDs of the colors to use for infobar elements. constexpr int kInfoBarLabelBackgroundColor = ThemeProperties::COLOR_INFOBAR; -constexpr int kInfoBarLabelTextColor = ThemeProperties::COLOR_BOOKMARK_TEXT; +constexpr int kInfoBarLabelTextColor = ThemeProperties::COLOR_TOOLBAR_TEXT; constexpr int kSeparatorHeightDip = 1; @@ -243,8 +243,10 @@ if (label_type != LabelType::kNone) { auto* label = static_cast<views::Label*>(child); label->SetBackgroundColor(background_color); - if (label_type == LabelType::kLabel) + if (label_type == LabelType::kLabel) { label->SetEnabledColor(text_color); + label->SetAutoColorReadabilityEnabled(false); + } } }
diff --git a/chrome/browser/ui/views/profiles/signin_view_controller_delegate_views.cc b/chrome/browser/ui/views/profiles/signin_view_controller_delegate_views.cc index 4d621da..8509b023 100644 --- a/chrome/browser/ui/views/profiles/signin_view_controller_delegate_views.cc +++ b/chrome/browser/ui/views/profiles/signin_view_controller_delegate_views.cc
@@ -61,14 +61,15 @@ return CreateDialogWebView( browser, GURL(chrome::kChromeUISyncConfirmationURL), GetSyncConfirmationDialogPreferredHeight(browser->profile()), - kSyncConfirmationDialogWidth); + kSyncConfirmationDialogWidth, InitializeSigninWebDialogUI(true)); } // static std::unique_ptr<views::WebView> SigninViewControllerDelegateViews::CreateSigninErrorWebView(Browser* browser) { return CreateDialogWebView(browser, GURL(chrome::kChromeUISigninErrorURL), - kSigninErrorDialogHeight, absl::nullopt); + kSigninErrorDialogHeight, absl::nullopt, + InitializeSigninWebDialogUI(true)); } // static @@ -78,7 +79,8 @@ signin_metrics::ReauthAccessPoint access_point) { return CreateDialogWebView(browser, signin::GetReauthConfirmationURL(access_point), - kReauthDialogHeight, kReauthDialogWidth); + kReauthDialogHeight, kReauthDialogWidth, + InitializeSigninWebDialogUI(false)); } #if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \ @@ -92,7 +94,8 @@ base::OnceCallback<void(bool)> callback) { std::unique_ptr<views::WebView> web_view = CreateDialogWebView( browser, GURL(chrome::kChromeUIEnterpriseProfileWelcomeURL), - kSyncConfirmationDialogHeight, kSyncConfirmationDialogWidth); + kSyncConfirmationDialogHeight, kSyncConfirmationDialogWidth, + InitializeSigninWebDialogUI(false)); EnterpriseProfileWelcomeUI* web_dialog_ui = web_view->GetWebContents() @@ -244,14 +247,17 @@ Browser* browser, const GURL& url, int dialog_height, - absl::optional<int> opt_width) { + absl::optional<int> opt_width, + InitializeSigninWebDialogUI initialize_signin_web_dialog_ui) { int dialog_width = opt_width.value_or(kModalDialogWidth); views::WebView* web_view = new views::WebView(browser->profile()); web_view->LoadInitialURL(url); - SigninWebDialogUI* web_dialog_ui = static_cast<SigninWebDialogUI*>( - web_view->GetWebContents()->GetWebUI()->GetController()); - web_dialog_ui->InitializeMessageHandlerWithBrowser(browser); + if (initialize_signin_web_dialog_ui) { + SigninWebDialogUI* web_dialog_ui = static_cast<SigninWebDialogUI*>( + web_view->GetWebContents()->GetWebUI()->GetController()); + web_dialog_ui->InitializeMessageHandlerWithBrowser(browser); + } int max_height = browser->window() ->GetWebContentsModalDialogHost()
diff --git a/chrome/browser/ui/views/profiles/signin_view_controller_delegate_views.h b/chrome/browser/ui/views/profiles/signin_view_controller_delegate_views.h index 7f5150f..9450218 100644 --- a/chrome/browser/ui/views/profiles/signin_view_controller_delegate_views.h +++ b/chrome/browser/ui/views/profiles/signin_view_controller_delegate_views.h
@@ -7,6 +7,7 @@ #include "base/callback.h" #include "base/memory/raw_ptr.h" +#include "base/types/strong_alias.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/ui/chrome_web_modal_dialog_manager_delegate.h" @@ -106,6 +107,9 @@ friend SigninViewControllerDelegate; friend class SigninViewControllerDelegateViewsBrowserTest; + using InitializeSigninWebDialogUI = + base::StrongAlias<class InitializeSigninWebDialogUITag, bool>; + // Creates and displays a constrained window containing |web_contents|. If // |wait_for_size| is true, the delegate will wait for ResizeNativeView() to // be called by the base class before displaying the constrained window. @@ -122,7 +126,8 @@ Browser* browser, const GURL& url, int dialog_height, - absl::optional<int> dialog_width); + absl::optional<int> dialog_width, + InitializeSigninWebDialogUI initialize_signin_web_dialog_ui); // Displays the modal dialog. void DisplayModal();
diff --git a/chrome/browser/ui/views/toolbar/reload_button_browsertest.cc b/chrome/browser/ui/views/toolbar/reload_button_browsertest.cc index abee95f..93fad30 100644 --- a/chrome/browser/ui/views/toolbar/reload_button_browsertest.cc +++ b/chrome/browser/ui/views/toolbar/reload_button_browsertest.cc
@@ -9,6 +9,7 @@ #include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/interactive_test_utils.h" +#include "content/public/browser/weak_document_ptr.h" #include "content/public/test/browser_test.h" class ReloadButtonBrowserTest : public InProcessBrowserTest { @@ -29,7 +30,8 @@ url, base::BindRepeating(&ReloadButtonBrowserTest::GetWebContents, base::Unretained(this)), - ui::PAGE_TRANSITION_LINK, true, url::Origin::Create(url)); + ui::PAGE_TRANSITION_LINK, true, url::Origin::Create(url), + content::WeakDocumentPtr()); ASSERT_EQ(ExternalProtocolHandler::BLOCK, ExternalProtocolHandler::GetBlockState(fake_protocol, nullptr, browser()->profile()));
diff --git a/chrome/browser/ui/views/webid/webid_account_selection_views.cc b/chrome/browser/ui/views/webid/webid_account_selection_views.cc index 93cb8904..7d3a7fad 100644 --- a/chrome/browser/ui/views/webid/webid_account_selection_views.cc +++ b/chrome/browser/ui/views/webid/webid_account_selection_views.cc
@@ -9,3 +9,12 @@ AccountSelectionView::Delegate* delegate) { return nullptr; } + +// static +int AccountSelectionView::GetBrandIconMinimumSize() { + return 0; +} + +int AccountSelectionView::GetBrandIconIdealSize() { + return 0; +}
diff --git a/chrome/browser/ui/webid/account_selection_view.h b/chrome/browser/ui/webid/account_selection_view.h index 14990fb..d8cfde8 100644 --- a/chrome/browser/ui/webid/account_selection_view.h +++ b/chrome/browser/ui/webid/account_selection_view.h
@@ -31,6 +31,8 @@ }; static std::unique_ptr<AccountSelectionView> Create(Delegate* delegate); + static int GetBrandIconMinimumSize(); + static int GetBrandIconIdealSize(); explicit AccountSelectionView(Delegate* delegate) : delegate_(delegate) {} AccountSelectionView(const AccountSelectionView&) = delete;
diff --git a/chrome/browser/ui/webid/identity_dialog_controller.cc b/chrome/browser/ui/webid/identity_dialog_controller.cc index 7840dc7..b91fa3f 100644 --- a/chrome/browser/ui/webid/identity_dialog_controller.cc +++ b/chrome/browser/ui/webid/identity_dialog_controller.cc
@@ -19,6 +19,14 @@ IdentityDialogController::~IdentityDialogController() = default; +int IdentityDialogController::GetBrandIconMinimumSize() { + return AccountSelectionView::GetBrandIconMinimumSize(); +} + +int IdentityDialogController::GetBrandIconIdealSize() { + return AccountSelectionView::GetBrandIconIdealSize(); +} + void IdentityDialogController::ShowInitialPermissionDialog( content::WebContents* rp_web_contents, const GURL& idp_url, @@ -125,7 +133,10 @@ } void IdentityDialogController::OnDismiss() { - std::move(on_account_selection_).Run(std::string()); + // |OnDismiss| can be called after |OnAccountSelected| which sets the callback + // to null. + if (on_account_selection_) + std::move(on_account_selection_).Run(std::string()); } gfx::NativeView IdentityDialogController::GetNativeView() {
diff --git a/chrome/browser/ui/webid/identity_dialog_controller.h b/chrome/browser/ui/webid/identity_dialog_controller.h index 403a9eb..bab4796 100644 --- a/chrome/browser/ui/webid/identity_dialog_controller.h +++ b/chrome/browser/ui/webid/identity_dialog_controller.h
@@ -43,6 +43,9 @@ ~IdentityDialogController() override; // content::IdentityRequestDelegate + int GetBrandIconMinimumSize() override; + int GetBrandIconIdealSize() override; + void ShowInitialPermissionDialog( content::WebContents* rp_web_contents, const GURL& idp_url,
diff --git a/chrome/browser/ui/webui/extensions/extensions_ui.cc b/chrome/browser/ui/webui/extensions/extensions_ui.cc index 19570ad..32f9805 100644 --- a/chrome/browser/ui/webui/extensions/extensions_ui.cc +++ b/chrome/browser/ui/webui/extensions/extensions_ui.cc
@@ -59,7 +59,8 @@ constexpr char kInDevModeKey[] = "inDevMode"; constexpr char kShowActivityLogKey[] = "showActivityLog"; constexpr char kLoadTimeClassesKey[] = "loadTimeClasses"; -constexpr char kUseNewSiteAccessPage[] = "useNewSiteAccessPage"; +constexpr char kExtensionsMenuAccessControlEnabled[] = + "extensionsMenuAccessControlEnabled"; std::string GetLoadTimeClasses(bool in_dev_mode) { return in_dev_mode ? "in-dev-mode" : std::string(); @@ -195,7 +196,6 @@ {"itemPermissionsEmpty", IDS_EXTENSIONS_ITEM_PERMISSIONS_EMPTY}, {"itemRemoveExtension", IDS_EXTENSIONS_ITEM_REMOVE_EXTENSION}, {"itemSiteAccess", IDS_EXTENSIONS_ITEM_SITE_ACCESS}, - {"itemSiteAccessSublabel", IDS_EXTENSIONS_ITEM_SITE_ACCESS_SUBLABEL}, {"itemSiteAccessAddHost", IDS_EXTENSIONS_ITEM_SITE_ACCESS_ADD_HOST}, {"itemSiteAccessEmpty", IDS_EXTENSIONS_ITEM_SITE_ACCESS_EMPTY}, {"itemSource", IDS_EXTENSIONS_ITEM_SOURCE}, @@ -225,7 +225,6 @@ {"loadErrorRetry", IDS_EXTENSIONS_LOAD_ERROR_RETRY}, {"loadingActivities", IDS_EXTENSIONS_LOADING_ACTIVITIES}, {"missingOrUninstalledExtension", IDS_MISSING_OR_UNINSTALLED_EXTENSION}, - {"newItemSiteAccessTitle", IDS_EXTENSIONS_ITEM_SITE_ACCESS_NEW}, {"noActivities", IDS_EXTENSIONS_NO_ACTIVITIES}, {"noErrorsToShow", IDS_EXTENSIONS_ERROR_NO_ERRORS_CODE_MESSAGE}, {"runtimeHostsDialogInputError", @@ -336,7 +335,7 @@ source->AddString(kLoadTimeClassesKey, GetLoadTimeClasses(in_dev_mode)); source->AddBoolean( - kUseNewSiteAccessPage, + kExtensionsMenuAccessControlEnabled, base::FeatureList::IsEnabled(features::kExtensionsMenuAccessControl)); return source;
diff --git a/chrome/browser/ui/webui/signin/enterprise_profile_welcome_ui.cc b/chrome/browser/ui/webui/signin/enterprise_profile_welcome_ui.cc index 47022bef..765807b 100644 --- a/chrome/browser/ui/webui/signin/enterprise_profile_welcome_ui.cc +++ b/chrome/browser/ui/webui/signin/enterprise_profile_welcome_ui.cc
@@ -21,7 +21,7 @@ #include "ui/resources/grit/webui_generated_resources.h" EnterpriseProfileWelcomeUI::EnterpriseProfileWelcomeUI(content::WebUI* web_ui) - : SigninWebDialogUI(web_ui) { + : content::WebUIController(web_ui) { content::WebUIDataSource* source = content::WebUIDataSource::Create( chrome::kChromeUIEnterpriseProfileWelcomeHost); webui::SetJSModuleDefaults(source); @@ -81,7 +81,4 @@ return handler_; } -void EnterpriseProfileWelcomeUI::InitializeMessageHandlerWithBrowser( - Browser* browser) {} - WEB_UI_CONTROLLER_TYPE_IMPL(EnterpriseProfileWelcomeUI)
diff --git a/chrome/browser/ui/webui/signin/enterprise_profile_welcome_ui.h b/chrome/browser/ui/webui/signin/enterprise_profile_welcome_ui.h index 493f2b9..3fa43da8 100644 --- a/chrome/browser/ui/webui/signin/enterprise_profile_welcome_ui.h +++ b/chrome/browser/ui/webui/signin/enterprise_profile_welcome_ui.h
@@ -7,7 +7,7 @@ #include "base/callback.h" #include "base/memory/raw_ptr.h" -#include "chrome/browser/ui/webui/signin/signin_web_dialog_ui.h" +#include "content/public/browser/web_ui_controller.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/skia/include/core/SkColor.h" @@ -19,7 +19,7 @@ class WebUI; } -class EnterpriseProfileWelcomeUI : public SigninWebDialogUI { +class EnterpriseProfileWelcomeUI : public content::WebUIController { public: // Type of a welcome screen for the enterprise flow. enum class ScreenType { @@ -46,9 +46,6 @@ // Allows tests to trigger page events. EnterpriseProfileWelcomeHandler* GetHandlerForTesting(); - // SigninWebDialogUI: - void InitializeMessageHandlerWithBrowser(Browser* browser) override; - private: // Stored for tests. raw_ptr<EnterpriseProfileWelcomeHandler> handler_ = nullptr;
diff --git a/chrome/browser/ui/webui/signin/signin_reauth_ui.cc b/chrome/browser/ui/webui/signin/signin_reauth_ui.cc index 6dcb530..60794d0 100644 --- a/chrome/browser/ui/webui/signin/signin_reauth_ui.cc +++ b/chrome/browser/ui/webui/signin/signin_reauth_ui.cc
@@ -23,6 +23,7 @@ #include "components/signin/public/base/signin_metrics.h" #include "components/signin/public/identity_manager/account_info.h" #include "components/signin/public/identity_manager/identity_manager.h" +#include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui_controller.h" #include "content/public/browser/web_ui_data_source.h" #include "google_apis/gaia/core_account_id.h" @@ -89,7 +90,7 @@ } // namespace SigninReauthUI::SigninReauthUI(content::WebUI* web_ui) - : SigninWebDialogUI(web_ui) { + : content::WebUIController(web_ui) { Profile* profile = Profile::FromWebUI(web_ui); content::WebUIDataSource* source = content::WebUIDataSource::Create(chrome::kChromeUISigninReauthHost); @@ -137,8 +138,6 @@ base::flat_map<std::string, int>(js_localized_string_to_ids_))); } -void SigninReauthUI::InitializeMessageHandlerWithBrowser(Browser* browser) {} - void SigninReauthUI::AddStringResource(content::WebUIDataSource* source, base::StringPiece name, int ids) {
diff --git a/chrome/browser/ui/webui/signin/signin_reauth_ui.h b/chrome/browser/ui/webui/signin/signin_reauth_ui.h index a4f2bfbc..12ae2da 100644 --- a/chrome/browser/ui/webui/signin/signin_reauth_ui.h +++ b/chrome/browser/ui/webui/signin/signin_reauth_ui.h
@@ -8,10 +8,8 @@ #include <string> #include <vector> -#include "chrome/browser/ui/webui/signin/signin_web_dialog_ui.h" #include "content/public/browser/web_ui_controller.h" -class Browser; class SigninReauthViewController; namespace content { @@ -32,7 +30,7 @@ // // Contact chrome-signin@chromium.org if you want to reuse this dialog for other // reauth use-cases. -class SigninReauthUI : public SigninWebDialogUI { +class SigninReauthUI : public content::WebUIController { public: explicit SigninReauthUI(content::WebUI* web_ui); ~SigninReauthUI() override; @@ -45,11 +43,6 @@ void InitializeMessageHandlerWithReauthController( SigninReauthViewController* controller); - // SigninWebDialogUI: - // This class relies on InitializeMessageHandlerWithReauthController() so this - // method does nothing. - void InitializeMessageHandlerWithBrowser(Browser* browser) override; - private: // Adds a string resource with the given GRD |ids| to the WebUI data |source| // named as |name|. Also stores a reverse mapping from the localized version
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index e072d18..8130e17 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1640152356-7110f7b9e061caa182e80e91922d963a27259c43.profdata +chrome-linux-main-1640195998-5f12738e91a40fba7c9211c94fa17b72687b2c7c.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index d1cae67..15c9fb83 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1640152356-8f297e453cce0188cadd2b4256a99a8b72186a5a.profdata +chrome-mac-main-1640195998-b46144647da22c393082a759c08824a0c2dd2e1e.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 4e81953..830e0d6 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1640162853-e127f09e7d28173b7f76e48ecb02c54042744ba6.profdata +chrome-win32-main-1640195998-914d5c9e0aa5241537ef3445167069f5128293f9.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 72066b2..aa7b377 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1640162853-3c4bf97ec3b654f6ce6b7df852105d11837a41cc.profdata +chrome-win64-main-1640184867-a096f2b75bb14eb11cd3987363ed828b310a80f5.profdata
diff --git a/chrome/installer/util/initial_preferences.cc b/chrome/installer/util/initial_preferences.cc index 1184098f..cd55f22d 100644 --- a/chrome/installer/util/initial_preferences.cc +++ b/chrome/installer/util/initial_preferences.cc
@@ -33,10 +33,6 @@ base::LazyInstance<installer::InitialPreferences>::DestructorAtExit g_initial_preferences = LAZY_INSTANCE_INITIALIZER; -bool GetURLFromValue(const base::Value* in_value, std::string* out_value) { - return in_value && out_value && in_value->GetAsString(out_value); -} - std::vector<std::string> GetNamedList(const char* name, const base::DictionaryValue* prefs) { std::vector<std::string> list; @@ -49,12 +45,11 @@ list.reserve(value_list->GetList().size()); for (const base::Value& entry : value_list->GetList()) { - std::string url_entry; - if (!GetURLFromValue(&entry, &url_entry)) { + if (!entry.is_string()) { NOTREACHED(); break; } - list.push_back(url_entry); + list.push_back(entry.GetString()); } return list; } @@ -325,7 +320,9 @@ absl::optional<base::Value> pref_value = initial_dictionary_->ExtractKey(name); if (pref_value.has_value()) { - if (!pref_value->GetAsString(&result)) + if (pref_value->is_string()) + result = pref_value->GetString(); + else NOTREACHED(); } return result;
diff --git a/chrome/renderer/resources/plugins/plugin_poster.html b/chrome/renderer/resources/plugins/plugin_poster.html deleted file mode 100644 index ec97d91..0000000 --- a/chrome/renderer/resources/plugins/plugin_poster.html +++ /dev/null
@@ -1,107 +0,0 @@ -<!doctype html> -<html> -<head> -<meta charset="utf-8"> -<meta name="viewport" content="width=device-width, user-scalable=no"> -<script> - window.onload = function() { - if (plugin.didFinishLoading) - plugin.didFinishLoading(); - }; - - window.onkeydown = function(e) { - if (e.key == 'Enter' || e.key == ' ') { - plugin.load(); - e.preventDefault(); - } - }; -</script> -<link rel="stylesheet" href="plugin_placeholders.css"></link> -<style> -#outer { - border: none; - flex-direction: row; - cursor: pointer; -} - -#shielding { - background-color: rgba(0, 0, 0, 0.5); - height: 100%; - left: 0px; - position: absolute; - top: 0px; - width: 100%; - z-index: 2; -} - -#plugin-icon { - opacity: 0.8; - max-height: 100%; - max-width: 100%; - min-width: 0; - min-height: 0; -} - -#plugin-icon:hover { - opacity: 0.95; -} - -#poster { - height: 100%; - object-fit: contain; - width: 100%; - z-index: 1; -} - -#inner-container { - align-items: center; - display: flex; - height: 100%; - justify-content: center; - left: 0px; - max-height: 100%; - max-width: 100%; - position: absolute; - top: 0px; - width: 100%; - z-index: 2; -} -</style> -<base href="$i18n{baseurl}"> -</head> - -<body> - <div title="$i18n{name}" id="outer"> - <img id="poster" srcset="$i18n{poster}"> - <div id="shielding"></div> - <div id="inner-container" - style="width:$i18n{visibleWidth};height:$i18n{visibleHeight}"> - <img id="plugin-icon" src="plugin_power_saver_play.png" /> - </div> - </div> - <script> - document.getElementById('poster').onerror = function() { - this.hidden = true; - }; - - document.getElementById('outer').onclick = function() { - plugin.load(); - }; - - window.resizePoster = function(marginLeft, marginTop, width, height) { - var container = document.getElementById('inner-container'); - container.style.marginLeft = marginLeft; - container.style.marginTop = marginTop; - container.style.width = width; - container.style.height = height; - - if (plugin.notifyPlaceholderReadyForTesting) { - // Defer until reflow complete. - window.setTimeout(function() { - plugin.notifyPlaceholderReadyForTesting(); - }); - } - }; - </script> -</body> -</html>
diff --git a/chrome/renderer/resources/plugins/plugin_power_saver_play.png b/chrome/renderer/resources/plugins/plugin_power_saver_play.png deleted file mode 100644 index f713caf4..0000000 --- a/chrome/renderer/resources/plugins/plugin_power_saver_play.png +++ /dev/null Binary files differ
diff --git a/chrome/renderer/resources/renderer_resources.grd b/chrome/renderer/resources/renderer_resources.grd index c75a7d2..9cc7c42 100644 --- a/chrome/renderer/resources/renderer_resources.grd +++ b/chrome/renderer/resources/renderer_resources.grd
@@ -13,7 +13,6 @@ <include name="IDR_BLOCKED_PLUGIN_HTML" file="plugins/blocked_plugin.html" flattenhtml="true" type="BINDATA" /> <include name="IDR_DISABLED_PLUGIN_HTML" file="plugins/disabled_plugin.html" flattenhtml="true" type="BINDATA" /> <include name="IDR_PDF_PLUGIN_HTML" file="plugins/pdf_plugin.html" flattenhtml="true" type="BINDATA" /> - <include name="IDR_PLUGIN_POSTER_HTML" file="plugins/plugin_poster.html" flattenhtml="true" type="BINDATA" /> <include name="IDR_CART_PRODUCT_EXTRACTION_JS" file="cart/cart-product-extraction.js" type="BINDATA"/> <include name="IDR_CART_DOMAIN_PRODUCT_ID_REGEX_JSON" file="cart/cart_domain_product_id_regex.json" type="BINDATA"/> <include name="IDR_CART_DOMAIN_CART_URL_REGEX_JSON" file="cart/cart_domain_cart_url_regex.json" type="BINDATA"/>
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index bd62f0b..0c936b98 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -3451,6 +3451,8 @@ "../browser/chromeos/policy/dlp/mock_dlp_content_observer.h", "../browser/chromeos/policy/dlp/mock_dlp_rules_manager.cc", "../browser/chromeos/policy/dlp/mock_dlp_rules_manager.h", + "../browser/chromeos/policy/dlp/mock_dlp_warn_notifier.cc", + "../browser/chromeos/policy/dlp/mock_dlp_warn_notifier.h", "../browser/device_api/device_attribute_api_browsertest.cc", "../browser/drive/drive_notification_manager_factory_browsertest.cc", "../browser/metrics/chromeos_metrics_provider_browsertest.cc", @@ -6630,7 +6632,8 @@ "../browser/ui/app_list/search/ranking/category_item_ranker_unittest.cc", "../browser/ui/app_list/search/ranking/category_usage_ranker_unittest.cc", "../browser/ui/app_list/search/ranking/removed_results_ranker_unittest.cc", - "../browser/ui/app_list/search/search_controller_unittest.cc", + "../browser/ui/app_list/search/search_controller_impl_new_unittest.cc", + "../browser/ui/app_list/search/search_controller_impl_unittest.cc", "../browser/ui/app_list/search/search_result_ranker/app_launch_event_logger_unittest.cc", "../browser/ui/app_list/search/search_result_ranker/app_launch_predictor_test_util.h", "../browser/ui/app_list/search/search_result_ranker/app_launch_predictor_unittest.cc",
diff --git a/chrome/test/chromedriver/element_commands.cc b/chrome/test/chromedriver/element_commands.cc index 366ef2c..62a52bd 100644 --- a/chrome/test/chromedriver/element_commands.cc +++ b/chrome/test/chromedriver/element_commands.cc
@@ -1148,10 +1148,12 @@ double device_pixel_ratio = browser_info->FindKey("device_pixel_ratio")->GetDouble(); - std::unique_ptr<base::DictionaryValue> clip_dict = - base::DictionaryValue::From(std::move(clip)); - if (!clip_dict) + if (!clip->is_dict()) return Status(kUnknownError, "Element Rect is not a dictionary"); + + base::DictionaryValue screenshot_params; + base::Value* clip_dict = screenshot_params.SetKey( + "clip", base::Value::FromUniquePtrValue(std::move(clip))); // |clip_dict| already contains the right width and height of the target // element, but its x and y are relative to containing frame. We replace them // with the x and y relative to top-level document origin, as expected by @@ -1166,8 +1168,6 @@ clip_dict->SetDoubleKey("width", std::min(viewport_width - location.x, clip_dict->FindKey("width")->GetDouble())); - base::DictionaryValue screenshot_params; - screenshot_params.SetDictionary("clip", std::move(clip_dict)); std::string screenshot; status = web_view->CaptureScreenshot(&screenshot, screenshot_params);
diff --git a/chrome/test/chromedriver/server/http_handler.cc b/chrome/test/chromedriver/server/http_handler.cc index b940f9f0..db0e4b3 100644 --- a/chrome/test/chromedriver/server/http_handler.cc +++ b/chrome/test/chromedriver/server/http_handler.cc
@@ -1329,11 +1329,11 @@ base::DictionaryValue body_params; if (status.IsError()){ - std::unique_ptr<base::DictionaryValue> inner_params( - new base::DictionaryValue()); - inner_params->SetString("error", StatusCodeToString(status.code())); - inner_params->SetString("message", status.message()); - inner_params->SetString("stacktrace", status.stack_trace()); + base::Value* inner_params = + body_params.SetKey("value", base::Value(base::Value::Type::DICTIONARY)); + inner_params->SetStringKey("error", StatusCodeToString(status.code())); + inner_params->SetStringKey("message", status.message()); + inner_params->SetStringKey("stacktrace", status.stack_trace()); // According to // https://www.w3.org/TR/2018/REC-webdriver1-20180605/#dfn-annotated-unexpected-alert-open-error // error UnexpectedAlertOpen should contain 'data.text' with alert text @@ -1342,18 +1342,18 @@ auto first = message.find("{"); auto last = message.find_last_of("}"); if (first == std::string::npos || last == std::string::npos) { - inner_params->SetString("data.text", ""); + inner_params->SetStringPath("data.text", ""); } else { std::string alertText = message.substr(first, last - first); auto colon = alertText.find(":"); if (colon != std::string::npos && alertText.size() > (colon + 2)) alertText = alertText.substr(colon + 2); - inner_params->SetString("data.text", alertText); + inner_params->SetStringPath("data.text", alertText); } } - body_params.SetDictionary("value", std::move(inner_params)); } else { - body_params.Set("value", std::move(value)); + body_params.SetKey("value", + base::Value::FromUniquePtrValue(std::move(value))); } std::string body;
diff --git a/chrome/test/chromedriver/session_commands_unittest.cc b/chrome/test/chromedriver/session_commands_unittest.cc index 28a1458d..3e2a245 100644 --- a/chrome/test/chromedriver/session_commands_unittest.cc +++ b/chrome/test/chromedriver/session_commands_unittest.cc
@@ -118,8 +118,7 @@ ASSERT_EQ(kInvalidArgument, status.code()); // Empty "capabilities" is OK - params.SetDictionary("capabilities", - std::make_unique<base::DictionaryValue>()); + params.SetKey("capabilities", base::Value(base::Value::Type::DICTIONARY)); status = ProcessCapabilities(params, &result); ASSERT_EQ(kOk, status.code()) << status.message(); ASSERT_TRUE(result.DictEmpty()); @@ -136,8 +135,8 @@ ASSERT_EQ(kInvalidArgument, status.code()); // Empty "alwaysMatch" is OK - params.SetDictionary("capabilities.alwaysMatch", - std::make_unique<base::DictionaryValue>()); + params.SetPath("capabilities.alwaysMatch", + base::Value(base::Value::Type::DICTIONARY)); status = ProcessCapabilities(params, &result); ASSERT_EQ(kOk, status.code()) << status.message(); ASSERT_TRUE(result.DictEmpty()); @@ -168,8 +167,8 @@ base::DictionaryValue result; // "firstMatch" must be a JSON list - params.SetDictionary("capabilities.firstMatch", - std::make_unique<base::DictionaryValue>()); + params.SetPath("capabilities.firstMatch", + base::Value(base::Value::Type::DICTIONARY)); Status status = ProcessCapabilities(params, &result); ASSERT_EQ(kInvalidArgument, status.code()); @@ -490,8 +489,8 @@ caps.SetPath({"goog:chromeOptions", "args"}, base::Value(args)); base::DictionaryValue prefs; - prefs.SetKey("download.default_directory", - base::Value("/examples/python/downloads")); + prefs.SetPath("download.default_directory", + base::Value("/examples/python/downloads")); caps.SetPath({"goog:chromeOptions", "prefs"}, prefs.Clone()); Status status = capabilities.Parse(caps); @@ -514,11 +513,11 @@ args.emplace_back("headless"); caps.SetPath({"goog:chromeOptions", "args"}, base::Value(args)); - base::DictionaryValue prefs; - std::unique_ptr<base::DictionaryValue> download(new base::DictionaryValue()); - download->SetStringPath("default_directory", "/examples/python/downloads"); - prefs.SetDictionary("download", std::move(download)); - caps.SetPath({"goog:chromeOptions", "prefs"}, prefs.Clone()); + base::Value* prefs = caps.SetPath({"goog:chromeOptions", "prefs"}, + base::Value(base::Value::Type::DICTIONARY)); + base::Value* download = + prefs->SetKey("download", base::Value(base::Value::Type::DICTIONARY)); + download->SetStringKey("default_directory", "/examples/python/downloads"); Status status = capabilities.Parse(caps); BrowserInfo binfo; @@ -555,11 +554,11 @@ TEST(SessionCommandsTest, ConfigureHeadlessSession_notHeadless) { Capabilities capabilities; base::DictionaryValue caps; - base::DictionaryValue prefs; - std::unique_ptr<base::DictionaryValue> download(new base::DictionaryValue()); - download->SetStringPath("default_directory", "/examples/python/downloads"); - prefs.SetDictionary("download", std::move(download)); - caps.SetPath({"goog:chromeOptions", "prefs"}, prefs.Clone()); + base::Value* prefs = caps.SetPath({"goog:chromeOptions", "prefs"}, + base::Value(base::Value::Type::DICTIONARY)); + base::Value* download = + prefs->SetKey("download", base::Value(base::Value::Type::DICTIONARY)); + download->SetStringKey("default_directory", "/examples/python/downloads"); Status status = capabilities.Parse(caps); BrowserInfo binfo;
diff --git a/chrome/test/chromedriver/util_unittest.cc b/chrome/test/chromedriver/util_unittest.cc index 6d08fa2..156fbddd8 100644 --- a/chrome/test/chromedriver/util_unittest.cc +++ b/chrome/test/chromedriver/util_unittest.cc
@@ -272,10 +272,8 @@ base::DictionaryValue dv2; dv2.SetString("dv", "2"); - std::unique_ptr<base::DictionaryValue> params(dv1.DeepCopy()); - base::DictionaryValue dict; - dict.SetDictionary(key, std::move(params)); + dict.SetKey(key, dv1.Clone()); const base::DictionaryValue* res = &dv2; bool has_value; bool has_dict = GetOptionalDictionary(&dict, key, &res, &has_value);
diff --git a/chrome/test/chromedriver/window_commands.cc b/chrome/test/chromedriver/window_commands.cc index 71e101d..d8592ada 100644 --- a/chrome/test/chromedriver/window_commands.cc +++ b/chrome/test/chromedriver/window_commands.cc
@@ -1315,30 +1315,28 @@ session->active_input_sources.Append(std::move(tmp_source)); - base::DictionaryValue tmp_state; - tmp_state.SetString("id", id); + base::Value* tmp_state = session->input_state_table.SetPath( + id, base::Value(base::Value::Type::DICTIONARY)); + tmp_state->SetStringKey("id", id); if (type == "key") { // Initialize a key input state object // (https://w3c.github.io/webdriver/#dfn-key-input-state). - tmp_state.SetDictionary("pressed", - std::make_unique<base::DictionaryValue>()); + tmp_state->SetKey("pressed", base::Value(base::Value::Type::DICTIONARY)); // For convenience, we use one integer property to encode four Boolean // properties (alt, shift, ctrl, meta) from the spec, using values from // enum KeyModifierMask. - tmp_state.SetInteger("modifiers", 0); + tmp_state->SetIntKey("modifiers", 0); } else if (type == "pointer") { int x = 0; int y = 0; // "pressed" is stored as a bitmask of pointer buttons. - tmp_state.SetInteger("pressed", 0); - tmp_state.SetString("subtype", pointer_type); + tmp_state->SetIntKey("pressed", 0); + tmp_state->SetStringKey("subtype", pointer_type); - tmp_state.SetInteger("x", x); - tmp_state.SetInteger("y", y); + tmp_state->SetIntKey("x", x); + tmp_state->SetIntKey("y", y); } - session->input_state_table.SetDictionary( - id, std::make_unique<base::DictionaryValue>(std::move(tmp_state))); } const base::ListValue* actions; @@ -1463,10 +1461,9 @@ std::string element_id; if (!origin_dict->GetString(GetElementKey(), &element_id)) return Status(kInvalidArgument, "'element' is missing"); - std::unique_ptr<base::DictionaryValue> origin_result = - std::make_unique<base::DictionaryValue>(); - origin_result->SetString(GetElementKey(), element_id); - action->SetDictionary("origin", std::move(origin_result)); + base::Value* origin_result = action->SetKey( + "origin", base::Value(base::Value::Type::DICTIONARY)); + origin_result->SetStringPath(GetElementKey(), element_id); } else { if (origin != "viewport" && origin != "pointer") return Status(kInvalidArgument,
diff --git a/chrome/test/chromedriver/window_commands_unittest.cc b/chrome/test/chromedriver/window_commands_unittest.cc index 5933b582..fe55ba8 100644 --- a/chrome/test/chromedriver/window_commands_unittest.cc +++ b/chrome/test/chromedriver/window_commands_unittest.cc
@@ -88,7 +88,7 @@ TEST(WindowCommandsTest, ExecuteSendCommandAndGetResult_NoCmd) { base::DictionaryValue params; - params.SetDictionary("params", std::make_unique<base::DictionaryValue>()); + params.SetKey("params", base::Value(base::Value::Type::DICTIONARY)); Status status = CallWindowCommand(ExecuteSendCommandAndGetResult, params); ASSERT_EQ(kInvalidArgument, status.code()); ASSERT_NE(status.message().find("command not passed"), std::string::npos); @@ -96,7 +96,7 @@ TEST(WindowCommandsTest, ExecuteSendCommandAndGetResult_NoParams) { base::DictionaryValue params; - params.SetString("cmd", "CSS.enable"); + params.SetStringKey("cmd", "CSS.enable"); Status status = CallWindowCommand(ExecuteSendCommandAndGetResult, params); ASSERT_EQ(kInvalidArgument, status.code()); ASSERT_NE(status.message().find("params not passed"), std::string::npos); @@ -108,27 +108,26 @@ std::unique_ptr<base::DictionaryValue> action_sequence( new base::DictionaryValue()); std::unique_ptr<base::ListValue> actions(new base::ListValue()); - std::unique_ptr<base::DictionaryValue> action(new base::DictionaryValue()); - std::unique_ptr<base::DictionaryValue> parameters( - new base::DictionaryValue()); - parameters->SetString("pointerType", "mouse"); - action->SetString("type", "pointerMove"); - action->SetInteger("x", 30); - action->SetInteger("y", 60); + base::Value action(base::Value::Type::DICTIONARY); + base::Value* parameters = action_sequence->SetKey( + "parameters", base::Value(base::Value::Type::DICTIONARY)); + parameters->SetStringKey("pointerType", "mouse"); + action.SetStringKey("type", "pointerMove"); + action.SetIntKey("x", 30); + action.SetIntKey("y", 60); actions->Append(std::move(action)); - action = std::make_unique<base::DictionaryValue>(); - action->SetString("type", "pointerDown"); - action->SetInteger("button", 0); + action = base::Value(base::Value::Type::DICTIONARY); + action.SetStringKey("type", "pointerDown"); + action.SetIntKey("button", 0); actions->Append(std::move(action)); - action = std::make_unique<base::DictionaryValue>(); - action->SetString("type", "pointerUp"); - action->SetInteger("button", 0); + action = base::Value(base::Value::Type::DICTIONARY); + action.SetStringKey("type", "pointerUp"); + action.SetIntKey("button", 0); actions->Append(std::move(action)); // pointer properties action_sequence->SetString("type", "pointer"); action_sequence->SetString("id", "pointer1"); - action_sequence->SetDictionary("parameters", std::move(parameters)); action_sequence->SetList("actions", std::move(actions)); const base::DictionaryValue* input_action_sequence = action_sequence.get(); Status status = @@ -189,25 +188,24 @@ std::unique_ptr<base::DictionaryValue> action_sequence( new base::DictionaryValue()); std::unique_ptr<base::ListValue> actions(new base::ListValue()); - std::unique_ptr<base::DictionaryValue> action(new base::DictionaryValue()); - std::unique_ptr<base::DictionaryValue> parameters( - new base::DictionaryValue()); - parameters->SetString("pointerType", "touch"); - action->SetString("type", "pointerMove"); - action->SetInteger("x", 30); - action->SetInteger("y", 60); + base::Value action(base::Value::Type::DICTIONARY); + base::Value* parameters = action_sequence->SetKey( + "parameters", base::Value(base::Value::Type::DICTIONARY)); + parameters->SetStringKey("pointerType", "touch"); + action.SetStringKey("type", "pointerMove"); + action.SetIntKey("x", 30); + action.SetIntKey("y", 60); actions->Append(std::move(action)); - action = std::make_unique<base::DictionaryValue>(); - action->SetString("type", "pointerDown"); + action = base::Value(base::Value::Type::DICTIONARY); + action.SetStringKey("type", "pointerDown"); actions->Append(std::move(action)); - action = std::make_unique<base::DictionaryValue>(); - action->SetString("type", "pointerUp"); + action = base::Value(base::Value::Type::DICTIONARY); + action.SetStringKey("type", "pointerUp"); actions->Append(std::move(action)); // pointer properties action_sequence->SetString("type", "pointer"); action_sequence->SetString("id", "pointer1"); - action_sequence->SetDictionary("parameters", std::move(parameters)); action_sequence->SetList("actions", std::move(actions)); const base::DictionaryValue* input_action_sequence = action_sequence.get(); Status status = @@ -284,12 +282,11 @@ TEST(WindowCommandsTest, ExecuteAddCookie_Valid) { AddCookieWebView webview = AddCookieWebView("http://chromium.org"); base::DictionaryValue params; - std::unique_ptr<base::DictionaryValue> cookie_params = - std::make_unique<base::DictionaryValue>(); - cookie_params->SetString("name", "testcookie"); - cookie_params->SetString("value", "cookievalue"); - cookie_params->SetString("sameSite", "Strict"); - params.SetDictionary("cookie", std::move(cookie_params)); + base::Value* cookie_params = + params.SetKey("cookie", base::Value(base::Value::Type::DICTIONARY)); + cookie_params->SetStringKey("name", "testcookie"); + cookie_params->SetStringKey("value", "cookievalue"); + cookie_params->SetStringKey("sameSite", "Strict"); std::unique_ptr<base::Value> result_value; Status status = CallWindowCommand(ExecuteAddCookie, &webview, params, &result_value); @@ -299,11 +296,10 @@ TEST(WindowCommandsTest, ExecuteAddCookie_NameMissing) { AddCookieWebView webview = AddCookieWebView("http://chromium.org"); base::DictionaryValue params; - std::unique_ptr<base::DictionaryValue> cookie_params = - std::make_unique<base::DictionaryValue>(); - cookie_params->SetString("value", "cookievalue"); - cookie_params->SetString("sameSite", "invalid"); - params.SetDictionary("cookie", std::move(cookie_params)); + base::Value* cookie_params = + params.SetKey("cookie", base::Value(base::Value::Type::DICTIONARY)); + cookie_params->SetStringKey("value", "cookievalue"); + cookie_params->SetStringKey("sameSite", "invalid"); std::unique_ptr<base::Value> result_value; Status status = CallWindowCommand(ExecuteAddCookie, &webview, params, &result_value); @@ -315,11 +311,10 @@ TEST(WindowCommandsTest, ExecuteAddCookie_MissingValue) { AddCookieWebView webview = AddCookieWebView("http://chromium.org"); base::DictionaryValue params; - std::unique_ptr<base::DictionaryValue> cookie_params = - std::make_unique<base::DictionaryValue>(); - cookie_params->SetString("name", "testcookie"); - cookie_params->SetString("sameSite", "Strict"); - params.SetDictionary("cookie", std::move(cookie_params)); + base::Value* cookie_params = + params.SetKey("cookie", base::Value(base::Value::Type::DICTIONARY)); + cookie_params->SetStringKey("name", "testcookie"); + cookie_params->SetStringKey("sameSite", "Strict"); std::unique_ptr<base::Value> result_value; Status status = CallWindowCommand(ExecuteAddCookie, &webview, params, &result_value); @@ -331,12 +326,11 @@ TEST(WindowCommandsTest, ExecuteAddCookie_DomainInvalid) { AddCookieWebView webview = AddCookieWebView("file://chromium.org"); base::DictionaryValue params; - std::unique_ptr<base::DictionaryValue> cookie_params = - std::make_unique<base::DictionaryValue>(); - cookie_params->SetString("name", "testcookie"); - cookie_params->SetString("value", "cookievalue"); - cookie_params->SetString("sameSite", "Strict"); - params.SetDictionary("cookie", std::move(cookie_params)); + base::Value* cookie_params = + params.SetKey("cookie", base::Value(base::Value::Type::DICTIONARY)); + cookie_params->SetStringKey("name", "testcookie"); + cookie_params->SetStringKey("value", "cookievalue"); + cookie_params->SetStringKey("sameSite", "Strict"); std::unique_ptr<base::Value> result_value; Status status = CallWindowCommand(ExecuteAddCookie, &webview, params, &result_value); @@ -346,12 +340,11 @@ TEST(WindowCommandsTest, ExecuteAddCookie_SameSiteEmpty) { AddCookieWebView webview = AddCookieWebView("https://chromium.org"); base::DictionaryValue params; - std::unique_ptr<base::DictionaryValue> cookie_params = - std::make_unique<base::DictionaryValue>(); - cookie_params->SetString("name", "testcookie"); - cookie_params->SetString("value", "cookievalue"); - cookie_params->SetString("sameSite", ""); - params.SetDictionary("cookie", std::move(cookie_params)); + base::Value* cookie_params = + params.SetKey("cookie", base::Value(base::Value::Type::DICTIONARY)); + cookie_params->SetStringKey("name", "testcookie"); + cookie_params->SetStringKey("value", "cookievalue"); + cookie_params->SetStringKey("sameSite", ""); std::unique_ptr<base::Value> result_value; Status status = CallWindowCommand(ExecuteAddCookie, &webview, params, &result_value); @@ -361,11 +354,10 @@ TEST(WindowCommandsTest, ExecuteAddCookie_SameSiteNotSet) { AddCookieWebView webview = AddCookieWebView("ftp://chromium.org"); base::DictionaryValue params; - std::unique_ptr<base::DictionaryValue> cookie_params = - std::make_unique<base::DictionaryValue>(); - cookie_params->SetString("name", "testcookie"); - cookie_params->SetString("value", "cookievalue"); - params.SetDictionary("cookie", std::move(cookie_params)); + base::Value* cookie_params = + params.SetKey("cookie", base::Value(base::Value::Type::DICTIONARY)); + cookie_params->SetStringKey("name", "testcookie"); + cookie_params->SetStringKey("value", "cookievalue"); std::unique_ptr<base::Value> result_value; Status status = CallWindowCommand(ExecuteAddCookie, &webview, params, &result_value); @@ -601,71 +593,63 @@ base::DictionaryValue params; std::unique_ptr<base::Value> result_value; - std::unique_ptr<base::DictionaryValue> dv(new base::DictionaryValue()); - params.SetDictionary("page", std::move(dv)); + base::Value* dv = + params.SetKey("page", base::Value(base::Value::Type::DICTIONARY)); Status status = CallWindowCommand(ExecutePrint, &webview, params, &result_value); ASSERT_EQ(kOk, status.code()) << status.message(); base::DictionaryValue printParams = getDefaultPrintParams(); ASSERT_EQ(static_cast<const base::Value&>(printParams), webview.getParams()); - dv = std::make_unique<base::DictionaryValue>(); + dv = params.SetKey("page", base::Value(base::Value::Type::DICTIONARY)); dv->SetDoubleKey("width", 21.59); - params.SetDictionary("page", std::move(dv)); status = CallWindowCommand(ExecutePrint, &webview, params, &result_value); ASSERT_EQ(kOk, status.code()) << status.message(); printParams = getDefaultPrintParams(); printParams.SetDoubleKey("paperWidth", ConvertCentimeterToInch(21.59)); ASSERT_EQ(static_cast<const base::Value&>(printParams), webview.getParams()); - dv = std::make_unique<base::DictionaryValue>(); + dv = params.SetKey("page", base::Value(base::Value::Type::DICTIONARY)); dv->SetDoubleKey("width", 33); - params.SetDictionary("page", std::move(dv)); status = CallWindowCommand(ExecutePrint, &webview, params, &result_value); ASSERT_EQ(kOk, status.code()) << status.message(); printParams = getDefaultPrintParams(); printParams.SetDoubleKey("paperWidth", ConvertCentimeterToInch(33)); ASSERT_EQ(static_cast<const base::Value&>(printParams), webview.getParams()); - dv = std::make_unique<base::DictionaryValue>(); - dv->SetString("width", "10"); - params.SetDictionary("page", std::move(dv)); + dv = params.SetKey("page", base::Value(base::Value::Type::DICTIONARY)); + dv->SetStringKey("width", "10"); status = CallWindowCommand(ExecutePrint, &webview, params, &result_value); ASSERT_EQ(kInvalidArgument, status.code()) << status.message(); - dv = std::make_unique<base::DictionaryValue>(); + dv = params.SetKey("page", base::Value(base::Value::Type::DICTIONARY)); dv->SetDoubleKey("width", -3.0); - params.SetDictionary("page", std::move(dv)); status = CallWindowCommand(ExecutePrint, &webview, params, &result_value); ASSERT_EQ(kInvalidArgument, status.code()) << status.message(); - dv = std::make_unique<base::DictionaryValue>(); + dv = params.SetKey("page", base::Value(base::Value::Type::DICTIONARY)); dv->SetDoubleKey("height", 20); - params.SetDictionary("page", std::move(dv)); status = CallWindowCommand(ExecutePrint, &webview, params, &result_value); ASSERT_EQ(kOk, status.code()) << status.message(); printParams = getDefaultPrintParams(); printParams.SetDoubleKey("paperHeight", ConvertCentimeterToInch(20)); ASSERT_EQ(static_cast<const base::Value&>(printParams), webview.getParams()); - dv = std::make_unique<base::DictionaryValue>(); + dv = params.SetKey("page", base::Value(base::Value::Type::DICTIONARY)); dv->SetDoubleKey("height", 27.94); - params.SetDictionary("page", std::move(dv)); status = CallWindowCommand(ExecutePrint, &webview, params, &result_value); ASSERT_EQ(kOk, status.code()) << status.message(); printParams = getDefaultPrintParams(); printParams.SetDoubleKey("paperHeight", ConvertCentimeterToInch(27.94)); ASSERT_EQ(static_cast<const base::Value&>(printParams), webview.getParams()); - dv = std::make_unique<base::DictionaryValue>(); - dv->SetString("height", "10"); - params.SetDictionary("page", std::move(dv)); + dv = params.SetKey("page", base::Value(base::Value::Type::DICTIONARY)); + dv->SetStringKey("height", "10"); status = CallWindowCommand(ExecutePrint, &webview, params, &result_value); ASSERT_EQ(kInvalidArgument, status.code()) << status.message(); - dv = std::make_unique<base::DictionaryValue>(); + dv = params.SetKey("page", base::Value(base::Value::Type::DICTIONARY)); dv->SetDoubleKey("height", -3.0); - params.SetDictionary("page", std::move(dv)); status = CallWindowCommand(ExecutePrint, &webview, params, &result_value); ASSERT_EQ(kInvalidArgument, status.code()) << status.message(); } @@ -675,131 +659,115 @@ base::DictionaryValue params; std::unique_ptr<base::Value> result_value; - std::unique_ptr<base::DictionaryValue> dv(new base::DictionaryValue()); - params.SetDictionary("margin", std::move(dv)); + base::Value* dv = + params.SetKey("margin", base::Value(base::Value::Type::DICTIONARY)); Status status = CallWindowCommand(ExecutePrint, &webview, params, &result_value); ASSERT_EQ(kOk, status.code()) << status.message(); base::DictionaryValue printParams = getDefaultPrintParams(); ASSERT_EQ(static_cast<const base::Value&>(printParams), webview.getParams()); - dv = std::make_unique<base::DictionaryValue>(); + dv = params.SetKey("margin", base::Value(base::Value::Type::DICTIONARY)); dv->SetDoubleKey("top", 1.0); - params.SetDictionary("margin", std::move(dv)); status = CallWindowCommand(ExecutePrint, &webview, params, &result_value); ASSERT_EQ(kOk, status.code()) << status.message(); printParams = getDefaultPrintParams(); printParams.SetDoubleKey("marginTop", ConvertCentimeterToInch(1.0)); ASSERT_EQ(static_cast<const base::Value&>(printParams), webview.getParams()); - dv = std::make_unique<base::DictionaryValue>(); + dv = params.SetKey("margin", base::Value(base::Value::Type::DICTIONARY)); dv->SetDoubleKey("top", 10.2); - params.SetDictionary("margin", std::move(dv)); status = CallWindowCommand(ExecutePrint, &webview, params, &result_value); ASSERT_EQ(kOk, status.code()) << status.message(); printParams = getDefaultPrintParams(); printParams.SetDoubleKey("marginTop", ConvertCentimeterToInch(10.2)); ASSERT_EQ(static_cast<const base::Value&>(printParams), webview.getParams()); - dv = std::make_unique<base::DictionaryValue>(); - dv->SetString("top", "10.2"); - params.SetDictionary("margin", std::move(dv)); + dv = params.SetKey("margin", base::Value(base::Value::Type::DICTIONARY)); + dv->SetStringKey("top", "10.2"); status = CallWindowCommand(ExecutePrint, &webview, params, &result_value); ASSERT_EQ(kInvalidArgument, status.code()) << status.message(); - dv = std::make_unique<base::DictionaryValue>(); + dv = params.SetKey("margin", base::Value(base::Value::Type::DICTIONARY)); dv->SetDoubleKey("top", -0.1); - params.SetDictionary("margin", std::move(dv)); status = CallWindowCommand(ExecutePrint, &webview, params, &result_value); ASSERT_EQ(kInvalidArgument, status.code()) << status.message(); - dv = std::make_unique<base::DictionaryValue>(); + dv = params.SetKey("margin", base::Value(base::Value::Type::DICTIONARY)); dv->SetDoubleKey("bottom", 1.0); - params.SetDictionary("margin", std::move(dv)); status = CallWindowCommand(ExecutePrint, &webview, params, &result_value); ASSERT_EQ(kOk, status.code()) << status.message(); printParams = getDefaultPrintParams(); printParams.SetDoubleKey("marginBottom", ConvertCentimeterToInch(1.0)); ASSERT_EQ(static_cast<const base::Value&>(printParams), webview.getParams()); - dv = std::make_unique<base::DictionaryValue>(); + dv = params.SetKey("margin", base::Value(base::Value::Type::DICTIONARY)); dv->SetDoubleKey("bottom", 5.3); - params.SetDictionary("margin", std::move(dv)); status = CallWindowCommand(ExecutePrint, &webview, params, &result_value); ASSERT_EQ(kOk, status.code()) << status.message(); printParams = getDefaultPrintParams(); printParams.SetDoubleKey("marginBottom", ConvertCentimeterToInch(5.3)); ASSERT_EQ(static_cast<const base::Value&>(printParams), webview.getParams()); - dv = std::make_unique<base::DictionaryValue>(); - dv->SetString("bottom", "10.2"); - params.SetDictionary("margin", std::move(dv)); + dv = params.SetKey("margin", base::Value(base::Value::Type::DICTIONARY)); + dv->SetStringKey("bottom", "10.2"); status = CallWindowCommand(ExecutePrint, &webview, params, &result_value); ASSERT_EQ(kInvalidArgument, status.code()) << status.message(); - dv = std::make_unique<base::DictionaryValue>(); + dv = params.SetKey("margin", base::Value(base::Value::Type::DICTIONARY)); dv->SetDoubleKey("bottom", -0.1); - params.SetDictionary("margin", std::move(dv)); status = CallWindowCommand(ExecutePrint, &webview, params, &result_value); ASSERT_EQ(kInvalidArgument, status.code()) << status.message(); - dv = std::make_unique<base::DictionaryValue>(); + dv = params.SetKey("margin", base::Value(base::Value::Type::DICTIONARY)); dv->SetDoubleKey("left", 1.0); - params.SetDictionary("margin", std::move(dv)); status = CallWindowCommand(ExecutePrint, &webview, params, &result_value); ASSERT_EQ(kOk, status.code()) << status.message(); printParams = getDefaultPrintParams(); printParams.SetDoubleKey("marginLeft", ConvertCentimeterToInch(1.0)); ASSERT_EQ(static_cast<const base::Value&>(printParams), webview.getParams()); - dv = std::make_unique<base::DictionaryValue>(); + dv = params.SetKey("margin", base::Value(base::Value::Type::DICTIONARY)); dv->SetDoubleKey("left", 9.1); - params.SetDictionary("margin", std::move(dv)); status = CallWindowCommand(ExecutePrint, &webview, params, &result_value); ASSERT_EQ(kOk, status.code()) << status.message(); printParams = getDefaultPrintParams(); printParams.SetDoubleKey("marginLeft", ConvertCentimeterToInch(9.1)); ASSERT_EQ(static_cast<const base::Value&>(printParams), webview.getParams()); - dv = std::make_unique<base::DictionaryValue>(); - dv->SetString("left", "10.2"); - params.SetDictionary("margin", std::move(dv)); + dv = params.SetKey("margin", base::Value(base::Value::Type::DICTIONARY)); + dv->SetStringKey("left", "10.2"); status = CallWindowCommand(ExecutePrint, &webview, params, &result_value); ASSERT_EQ(kInvalidArgument, status.code()) << status.message(); - dv = std::make_unique<base::DictionaryValue>(); + dv = params.SetKey("margin", base::Value(base::Value::Type::DICTIONARY)); dv->SetDoubleKey("left", -0.1); - params.SetDictionary("margin", std::move(dv)); status = CallWindowCommand(ExecutePrint, &webview, params, &result_value); ASSERT_EQ(kInvalidArgument, status.code()) << status.message(); - dv = std::make_unique<base::DictionaryValue>(); + dv = params.SetKey("margin", base::Value(base::Value::Type::DICTIONARY)); dv->SetDoubleKey("right", 1.0); - params.SetDictionary("margin", std::move(dv)); status = CallWindowCommand(ExecutePrint, &webview, params, &result_value); ASSERT_EQ(kOk, status.code()) << status.message(); printParams = getDefaultPrintParams(); printParams.SetDoubleKey("marginRight", ConvertCentimeterToInch(1.0)); ASSERT_EQ(static_cast<const base::Value&>(printParams), webview.getParams()); - dv = std::make_unique<base::DictionaryValue>(); + dv = params.SetKey("margin", base::Value(base::Value::Type::DICTIONARY)); dv->SetDoubleKey("right", 8.1); - params.SetDictionary("margin", std::move(dv)); status = CallWindowCommand(ExecutePrint, &webview, params, &result_value); ASSERT_EQ(kOk, status.code()) << status.message(); printParams = getDefaultPrintParams(); printParams.SetDoubleKey("marginRight", ConvertCentimeterToInch(8.1)); ASSERT_EQ(static_cast<const base::Value&>(printParams), webview.getParams()); - dv = std::make_unique<base::DictionaryValue>(); - dv->SetString("right", "10.2"); - params.SetDictionary("margin", std::move(dv)); + dv = params.SetKey("margin", base::Value(base::Value::Type::DICTIONARY)); + dv->SetStringKey("right", "10.2"); status = CallWindowCommand(ExecutePrint, &webview, params, &result_value); ASSERT_EQ(kInvalidArgument, status.code()) << status.message(); - dv = std::make_unique<base::DictionaryValue>(); + dv = params.SetKey("margin", base::Value(base::Value::Type::DICTIONARY)); dv->SetDoubleKey("right", -0.1); - params.SetDictionary("margin", std::move(dv)); status = CallWindowCommand(ExecutePrint, &webview, params, &result_value); ASSERT_EQ(kInvalidArgument, status.code()) << status.message(); } @@ -825,11 +793,10 @@ if (cmd == "Page.getLayoutMetrics") { std::unique_ptr<base::DictionaryValue> res = std::make_unique<base::DictionaryValue>(); - std::unique_ptr<base::DictionaryValue> d = - std::make_unique<base::DictionaryValue>(); + base::Value* d = res->SetKey("contentSize", + base::Value(base::Value::Type::DICTIONARY)); d->SetDoubleKey("width", wd); d->SetDoubleKey("height", hd); - res->SetDictionary("contentSize", std::move(d)); *value = std::move(res); } else if (cmd == "Emulation.setDeviceMetricsOverride") { base::DictionaryValue expect;
diff --git a/chrome/test/data/BUILD.gn b/chrome/test/data/BUILD.gn index b554785..435dded 100644 --- a/chrome/test/data/BUILD.gn +++ b/chrome/test/data/BUILD.gn
@@ -4,7 +4,6 @@ import("//chrome/common/features.gni") import("//mojo/public/tools/bindings/mojom.gni") -import("//pdf/features.gni") import("//third_party/closure_compiler/compile_js.gni") import("//tools/grit/grit_rule.gni") @@ -51,9 +50,6 @@ "cast:closure_compile", ] - if (enable_pdf) { - deps += [ "pdf:closure_compile" ] - } if (!is_android) { deps += [ "webui:closure_compile" ] }
diff --git a/chrome/test/data/pdf/BUILD.gn b/chrome/test/data/pdf/BUILD.gn deleted file mode 100644 index b0efa80..0000000 --- a/chrome/test/data/pdf/BUILD.gn +++ /dev/null
@@ -1,260 +0,0 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//pdf/features.gni") -import("//third_party/closure_compiler/compile_js.gni") - -js_type_check("closure_compile") { - is_polymer3 = true - closure_flags = default_closure_args + [ - "browser_resolver_prefix_replacements=\"chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/_test_resources/=../../chrome/test/data/\"", - "browser_resolver_prefix_replacements=\"chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/=../../chrome/browser/resources/pdf/\"", - "js_module_root=../../chrome/test/data/webui/", - "js_module_root=./gen/chrome/test/data/webui/", - ] - deps = [ - #":annotations_feature_enabled_test", - ":basic_plugin_test", - ":basic_test", - ":beep_test", - ":bookmarks_test", - ":download_controls_test", - ":fullscreen_test", - ":gesture_detector_test", - ":layout_test", - ":material_elements_test", - - #":metrics_test", - ":navigator_test", - ":nobeep_test", - ":page_change_test", - ":params_parser_test", - ":post_message_proxy_test", - ":printing_icon_test", - - #":redirects_fail_test", - ":scroll_with_form_field_focused_test", - ":test_util", - ":title_test", - - #":toolbar_manager_test", - #":touch_handling_test", - ":viewer_password_dialog_test", - ":viewer_pdf_sidenav_test", - ":viewer_properties_dialog_test", - ":viewer_thumbnail_bar_test", - ":viewer_thumbnail_test", - ":viewer_toolbar_test", - ":viewport_test", - ":whitespace_title_test", - - #":zoom_manager_test", - ] - - if (enable_ink) { - deps += [ ":viewer_toolbar_dropdown_test" ] - } -} - -js_library("basic_plugin_test") { - deps = [ "//chrome/browser/resources/pdf:pdf_viewer_wrapper" ] - externs_list = [ "$externs_path/test.js" ] -} - -js_library("basic_test") { - deps = [ "//chrome/browser/resources/pdf:pdf_viewer_wrapper" ] - externs_list = [ "$externs_path/test.js" ] -} - -js_library("beep_test") { - deps = [ "//chrome/browser/resources/pdf:pdf_viewer_wrapper" ] - externs_list = [ "$externs_path/test.js" ] -} - -js_library("bookmarks_test") { - deps = [ - ":test_util", - "//chrome/browser/resources/pdf:pdf_viewer_wrapper", - "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - ] - externs_list = [ "$externs_path/test.js" ] -} - -js_library("gesture_detector_test") { - deps = [ - ":test_util", - "//chrome/browser/resources/pdf:gesture_detector", - "//ui/webui/resources/js/cr:event_target.m", - ] - externs_list = [ "$externs_path/test.js" ] -} - -js_library("layout_test") { - deps = [ "//chrome/browser/resources/pdf:pdf_viewer_wrapper" ] - externs_list = [ "$externs_path/test.js" ] -} - -js_library("material_elements_test") { - deps = [ - ":test_util", - "//chrome/browser/resources/pdf:pdf_viewer_wrapper", - "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m", - "//ui/webui/resources/js:cr.m", - ] - externs_list = [ "$externs_path/test.js" ] -} - -if (enable_ink) { - js_library("viewer_toolbar_dropdown_test") { - deps = [ "//chrome/browser/resources/pdf:pdf_viewer_wrapper" ] - externs_list = [ "$externs_path/test.js" ] - } -} - -js_library("download_controls_test") { - deps = [ - "../webui:test_util", - "//chrome/browser/resources/pdf:pdf_viewer_wrapper", - "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - "//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu", - "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m", - "//ui/webui/resources/js:util.m", - ] - externs_list = [ "$externs_path/test.js" ] -} - -js_library("fullscreen_test") { - deps = [ - ":test_util", - "../webui:test_util", - "//chrome/browser/resources/pdf:pdf_viewer_wrapper", - "//third_party/polymer/v3_0/components-chromium/iron-test-helpers:mock-interactions", - "//ui/webui/resources/js:cr.m", - "//ui/webui/resources/js:util.m", - ] - externs_list = [ "$externs_path/test.js" ] -} - -js_library("navigator_test") { - deps = [ - ":test_util", - "../webui:test_browser_proxy", - "//chrome/browser/resources/pdf:pdf_viewer_wrapper", - ] - externs_list = [ "$externs_path/test.js" ] -} - -js_library("nobeep_test") { - deps = [ "//chrome/browser/resources/pdf:pdf_viewer_wrapper" ] - externs_list = [ "$externs_path/test.js" ] -} - -js_library("page_change_test") { - deps = [ - "//chrome/browser/resources/pdf:pdf_viewer_wrapper", - "//third_party/polymer/v3_0/components-chromium/iron-test-helpers:mock-interactions", - ] - externs_list = [ "$externs_path/test.js" ] -} - -js_library("post_message_proxy_test") { - deps = [ - "../webui:test_util", - "//chrome/browser/resources/pdf:pdf_viewer_wrapper", - ] - externs_list = [ "$externs_path/test.js" ] -} - -js_library("printing_icon_test") { - deps = [ "//chrome/browser/resources/pdf:pdf_viewer_wrapper" ] - externs_list = [ "$externs_path/test.js" ] -} - -js_library("params_parser_test") { - deps = [ "//chrome/browser/resources/pdf:pdf_viewer_wrapper" ] - externs_list = [ "$externs_path/test.js" ] -} - -js_library("scroll_with_form_field_focused_test") { - deps = [ - "../webui:test_util", - "//chrome/browser/resources/pdf:pdf_viewer_wrapper", - ] - externs_list = [ "$externs_path/test.js" ] -} - -js_library("test_util") { - deps = [ - "//chrome/browser/resources/pdf:pdf_viewer_wrapper", - "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - ] -} - -js_library("title_test") { - externs_list = [ "$externs_path/test.js" ] -} - -js_library("viewer_password_dialog_test") { - deps = [ - "../webui:test_util", - "//chrome/browser/resources/pdf:pdf_viewer_wrapper", - "//ui/webui/resources/cr_elements/cr_button:cr_button.m", - "//ui/webui/resources/cr_elements/cr_input:cr_input.m", - ] - externs_list = [ "$externs_path/test.js" ] -} - -js_library("viewer_pdf_sidenav_test") { - deps = [ "//chrome/browser/resources/pdf:pdf_viewer_wrapper" ] - externs_list = [ "$externs_path/test.js" ] -} - -js_library("viewer_properties_dialog_test") { - deps = [ - "../webui:test_util", - "//chrome/browser/resources/pdf:pdf_viewer_wrapper", - ] - externs_list = [ "$externs_path/test.js" ] -} - -js_library("viewer_thumbnail_bar_test") { - deps = [ - "../webui:test_util", - "//chrome/browser/resources/pdf:pdf_viewer_wrapper", - "//third_party/polymer/v3_0/components-chromium/iron-test-helpers:mock-interactions", - "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - "//ui/webui/resources/js/cr/ui:focus_outline_manager.m", - ] - externs_list = [ "$externs_path/test.js" ] -} - -js_library("viewer_thumbnail_test") { - deps = [ - "../webui:test_util", - "//chrome/browser/resources/pdf:pdf_viewer_wrapper", - "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - ] - externs_list = [ "$externs_path/test.js" ] -} - -js_library("viewer_toolbar_test") { - deps = [ - "../webui:test_util", - "//chrome/browser/resources/pdf:pdf_viewer_wrapper", - ] - externs_list = [ "$externs_path/test.js" ] -} - -js_library("viewport_test") { - deps = [ - ":test_util", - "//chrome/browser/resources/pdf:pdf_viewer_wrapper", - ] - externs_list = [ "$externs_path/test.js" ] -} - -js_library("whitespace_title_test") { - externs_list = [ "$externs_path/test.js" ] -}
diff --git a/chrome/test/data/pdf/download_controls_test.js b/chrome/test/data/pdf/download_controls_test.js index f7d1aa5..7aa0d63 100644 --- a/chrome/test/data/pdf/download_controls_test.js +++ b/chrome/test/data/pdf/download_controls_test.js
@@ -3,9 +3,8 @@ // found in the LICENSE file. import {eventToPromise} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/_test_resources/webui/test_util.js'; -import {CrActionMenuElement, SaveRequestType, ViewerDownloadControlsElement} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_viewer_wrapper.js'; +import {SaveRequestType, ViewerDownloadControlsElement} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_viewer_wrapper.js'; import {listenOnce} from 'chrome://resources/js/util.m.js'; -import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; const tests = [ /**
diff --git a/chrome/test/data/webui/extensions/cr_extensions_browsertest.js b/chrome/test/data/webui/extensions/cr_extensions_browsertest.js index 36d9d29..744236ea 100644 --- a/chrome/test/data/webui/extensions/cr_extensions_browsertest.js +++ b/chrome/test/data/webui/extensions/cr_extensions_browsertest.js
@@ -9,7 +9,6 @@ GEN('#include "chrome/browser/ui/webui/extensions/' + 'extension_settings_browsertest.h"'); -GEN('#include "chrome/browser/ui/ui_features.h"'); GEN('#include "content/public/test/browser_test.h"'); GEN('#include "build/chromeos_buildflags.h"'); @@ -291,20 +290,6 @@ }); //////////////////////////////////////////////////////////////////////////////// -// Extension Site Access Tests - -var CrExtensionsSiteAccessTest = class extends CrExtensionsBrowserTest { - /** @override */ - get browsePreload() { - return 'chrome://extensions/test_loader.html?module=extensions/site_access_test.js'; - } -}; - -TEST_F('CrExtensionsSiteAccessTest', 'All', () => { - mocha.run(); -}); - -//////////////////////////////////////////////////////////////////////////////// // Extension Item List Tests var CrExtensionsItemListTest = class extends CrExtensionsBrowserTest { @@ -521,13 +506,6 @@ extension_manager_tests.TestNames.UrlNavigationToActivityLogFail); }); -TEST_F( - 'CrExtensionsManagerTestWithIdQueryParam', 'UrlNavigationToSiteAccessFail', - function() { - this.runMochaTest( - extension_manager_tests.TestNames.UrlNavigationToSiteAccessFail); - }); - CrExtensionsManagerTestWithActivityLogFlag = class extends CrExtensionsManagerTestWithIdQueryParam { /** @override */ @@ -550,26 +528,6 @@ extension_manager_tests.TestNames.UrlNavigationToActivityLogSuccess); }); -CrExtensionsManagerTestWithNewSiteAccess = - class extends CrExtensionsManagerTestWithIdQueryParam { - /** @override */ - get browsePreload() { - return 'chrome://extensions/test_loader.html?module=extensions/manager_test_with_new_site_access.js'; - } - - /** @override */ - get featureList() { - return {enabled: ['features::kExtensionsMenuAccessControl']}; - } -}; - -TEST_F( - 'CrExtensionsManagerTestWithNewSiteAccess', - 'UrlNavigationToSiteAccessSuccess', function() { - this.runMochaTest( - extension_manager_tests.TestNames.UrlNavigationToSiteAccessSuccess); - }); - //////////////////////////////////////////////////////////////////////////////// // Extension Keyboard Shortcuts Tests
diff --git a/chrome/test/data/webui/extensions/detail_view_test.js b/chrome/test/data/webui/extensions/detail_view_test.js index 5f67cac..29227b92 100644 --- a/chrome/test/data/webui/extensions/detail_view_test.js +++ b/chrome/test/data/webui/extensions/detail_view_test.js
@@ -55,11 +55,9 @@ item.set('inDevMode', false); item.set('incognitoAvailable', true); item.set('showActivityLog', false); - item.set('useNewSiteAccessPage', false); document.body.appendChild(item); }); - // TODO(crbug.com/1253673): Break this test up into smaller subtests. test(assert(extension_detail_view_tests.TestNames.Layout), function() { flush(); @@ -127,36 +125,6 @@ item.set('data.permissions', {simplePermissions: []}); flush(); - expectFalse(testIsVisible('#extensionsSiteAccessLink')); - expectTrue(testIsVisible('#no-site-access')); - item.set('useNewSiteAccessPage', true); - flush(); - - // Since there are no site permissions, there shouldn't be a link to the - // site access page. - expectFalse(testIsVisible('#extensionsSiteAccessLink')); - expectTrue(testIsVisible('#no-site-access')); - - // Adding any runtime host permissions should result in the runtime host - // controls becoming visible. - const allSitesPermissions = { - simplePermissions: [], - runtimeHostPermissions: { - hosts: [{granted: false, host: '<all_urls>'}], - hasAllHosts: true, - hostAccess: chrome.developerPrivate.HostAccess.ON_CLICK, - }, - }; - item.set('data.permissions', allSitesPermissions); - flush(); - - expectTrue(testIsVisible('#extensionsSiteAccessLink')); - expectFalse(testIsVisible('#no-site-access')); - - item.set('useNewSiteAccessPage', false); - item.set('data.permissions', {simplePermissions: []}); - flush(); - const optionsUrl = 'chrome-extension://' + extensionData.id + '/options.html'; item.set('data.optionsPage', {openInTab: true, url: optionsUrl}); @@ -238,6 +206,14 @@ // Adding any runtime host permissions should result in the runtime host // controls becoming visible. + const allSitesPermissions = { + simplePermissions: [], + runtimeHostPermissions: { + hosts: [{granted: false, host: '<all_urls>'}], + hasAllHosts: true, + hostAccess: chrome.developerPrivate.HostAccess.ON_CLICK, + }, + }; item.set('data.permissions', allSitesPermissions); flush(); expectFalse(testIsVisible('#no-site-access')); @@ -351,13 +327,6 @@ currentPage, {page: Page.ACTIVITY_LOG, extensionId: extensionData.id}); - // Ditto for the site access page, which is hidden behind a feature - // flag. - item.shadowRoot.querySelector('#extensionsSiteAccessLink').click(); - expectDeepEquals( - currentPage, - {page: Page.EXTENSION_SITE_ACCESS, extensionId: extensionData.id}); - // Reset current page and test delegate calls. navigation.navigateTo( {page: Page.DETAILS, extensionId: extensionData.id});
diff --git a/chrome/test/data/webui/extensions/manager_test_with_id_query_param.js b/chrome/test/data/webui/extensions/manager_test_with_id_query_param.js index 27369888..98966a1 100644 --- a/chrome/test/data/webui/extensions/manager_test_with_id_query_param.js +++ b/chrome/test/data/webui/extensions/manager_test_with_id_query_param.js
@@ -15,8 +15,6 @@ UrlNavigationToDetails: 'url navigation to details', UrlNavigationToActivityLogFail: 'url navigation to activity log without flag set', - UrlNavigationToSiteAccessFail: - 'url navigation to site access page without flag set', }; function getDataByName(list, name) { @@ -99,31 +97,4 @@ // Should be re-routed to the main page. assertViewActive('extensions-item-list'); }); - - test( - assert(extension_manager_tests.TestNames.UrlNavigationToSiteAccessFail), - function() { - expectFalse(manager.useNewSiteAccessPage); - - // Try to open the extensions site access page with a valid ID. - navigation.navigateTo({ - page: Page.EXTENSION_SITE_ACCESS, - extensionId: 'ldnnhddmnhbkjipkidpdiheffobcpfmf' - }); - flush(); - - // Should be re-routed to details page with useNewSiteAccessPage set to - // false. - assertViewActive('extensions-detail-view'); - const detailsView = - manager.shadowRoot.querySelector('extensions-detail-view'); - expectFalse(detailsView.useNewSiteAccessPage); - - // Try to open the extensions site access page with an invalid ID. - navigation.navigateTo( - {page: Page.EXTENSION_SITE_ACCESS, extensionId: 'z'.repeat(32)}); - flush(); - // Should be re-routed to the main page. - assertViewActive('extensions-item-list'); - }); });
diff --git a/chrome/test/data/webui/extensions/manager_test_with_new_site_access.js b/chrome/test/data/webui/extensions/manager_test_with_new_site_access.js deleted file mode 100644 index 5a7c72346..0000000 --- a/chrome/test/data/webui/extensions/manager_test_with_new_site_access.js +++ /dev/null
@@ -1,64 +0,0 @@ -// Copyright 2021 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 {navigation, Page} from 'chrome://extensions/extensions.js'; - -import {assert} from 'chrome://resources/js/assert.m.js'; -import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {eventToPromise} from '../test_util.js'; - - -window.extension_manager_tests = {}; -extension_manager_tests.suiteName = 'ExtensionManagerTest'; -/** @enum {string} */ -extension_manager_tests.TestNames = { - UrlNavigationToSiteAccessSuccess: - 'url navigation to site access page with flag set', -}; - -suite(extension_manager_tests.suiteName, function() { - /** @type {ExtensionsManagerElement} */ - let manager; - - /** @param {string} tagName */ - function assertViewActive(tagName) { - assertTrue(!!manager.$.viewManager.querySelector(`${tagName}.active`)); - } - - setup(function() { - document.body.innerHTML = ''; - window.history.replaceState( - {}, '', '/?id=ldnnhddmnhbkjipkidpdiheffobcpfmf'); - - manager = document.createElement('extensions-manager'); - document.body.appendChild(manager); - - // Wait for the first view to be active before starting tests. - return eventToPromise('view-enter-start', manager); - }); - - - test( - assert( - extension_manager_tests.TestNames.UrlNavigationToSiteAccessSuccess), - function() { - expectTrue(manager.useNewSiteAccessPage); - - // Try to open the extensions site access page with a valid ID. - navigation.navigateTo({ - page: Page.EXTENSION_SITE_ACCESS, - extensionId: 'ldnnhddmnhbkjipkidpdiheffobcpfmf' - }); - - flush(); - assertViewActive('extensions-site-access'); - - // Try to open extensions site access page with an invalid ID. - navigation.navigateTo( - {page: Page.EXTENSION_SITE_ACCESS, extensionId: 'z'.repeat(32)}); - flush(); - // Should be redirected to the list page. - assertViewActive('extensions-item-list'); - }); -});
diff --git a/chrome/test/data/webui/extensions/runtime_host_permissions_test.js b/chrome/test/data/webui/extensions/runtime_host_permissions_test.js index 440efab..9dfbd64 100644 --- a/chrome/test/data/webui/extensions/runtime_host_permissions_test.js +++ b/chrome/test/data/webui/extensions/runtime_host_permissions_test.js
@@ -21,12 +21,12 @@ const ITEM_ID = 'a'.repeat(32); setup(function() { + loadTimeData.overrideValues({extensionsMenuAccessControlEnabled: false}); document.body.innerHTML = ''; element = document.createElement('extensions-runtime-host-permissions'); delegate = new TestService(); element.delegate = delegate; element.itemId = ITEM_ID; - element.useNewSiteAccessPage = false; document.body.appendChild(element); @@ -85,7 +85,7 @@ }); test('permissions display new site access menu', function() { - element.set('useNewSiteAccessPage', true); + loadTimeData.overrideValues({extensionsMenuAccessControlEnabled: true}); const permissions = { hostAccess: HostAccess.ON_CLICK, hasAllHosts: true,
diff --git a/chrome/test/data/webui/extensions/site_access_test.js b/chrome/test/data/webui/extensions/site_access_test.js deleted file mode 100644 index 11989deb..0000000 --- a/chrome/test/data/webui/extensions/site_access_test.js +++ /dev/null
@@ -1,70 +0,0 @@ -// Copyright 2021 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 {navigation, Page} from 'chrome://extensions/extensions.js'; - -import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {createExtensionInfo} from './test_util.js'; - -/** @fileoverview Suite of tests for extensions-site-access. */ -suite('ExtensionsSiteAccessTest', function() { - /** - * Backing extension id, same id as the one in - * createExtensionInfo - * @type {string} - */ - const EXTENSION_ID = 'a'.repeat(32); - - /** - * Extension site access element created before each test. - * @type {ExtensionsSiteAccess} - */ - let extensionsSiteAccess; - - /** - * Backing extension info for the site access page. - * @type {chrome.developerPrivate.ExtensionInfo} - */ - let extensionInfo; - - /** - * ID of a navigation listener. Cleared after every test. - * @type {Number} - */ - let listenerId = 0; - - // Initialize an extension site access element before each test. - setup(function() { - document.body.innerHTML = ''; - - extensionsSiteAccess = document.createElement('extensions-site-access'); - - extensionInfo = createExtensionInfo({ - id: EXTENSION_ID, - }); - extensionsSiteAccess.extensionInfo = extensionInfo; - - document.body.appendChild(extensionsSiteAccess); - - extensionsSiteAccess.dispatchEvent( - new CustomEvent('view-enter-start', {bubbles: true})); - }); - - teardown(function() { - navigation.removeListener(listenerId); - }); - - test('clicking on back button navigates to the details page', function() { - flush(); - - let currentPage = null; - listenerId = navigation.addListener(newPage => { - currentPage = newPage; - }); - - extensionsSiteAccess.shadowRoot.querySelector('#closeButton').click(); - expectDeepEquals( - currentPage, {page: Page.DETAILS, extensionId: EXTENSION_ID}); - }); -});
diff --git a/chromecast/browser/test/cast_navigation_browsertest.cc b/chromecast/browser/test/cast_navigation_browsertest.cc index 2f714ec..dbf95e1 100644 --- a/chromecast/browser/test/cast_navigation_browsertest.cc +++ b/chromecast/browser/test/cast_navigation_browsertest.cc
@@ -40,10 +40,9 @@ void LoadAboutBlank() { content::WebContents* web_contents = NavigateToURL(GURL(url::kAboutBlankURL)); - content::TitleWatcher title_watcher( - web_contents, base::ASCIIToUTF16(url::kAboutBlankURL)); + content::TitleWatcher title_watcher(web_contents, url::kAboutBlankURL16); std::u16string result = title_watcher.WaitAndGetTitle(); - EXPECT_EQ(url::kAboutBlankURL, base::UTF16ToASCII(result)); + EXPECT_EQ(url::kAboutBlankURL16, result); } void PlayAudio(const std::string& media_file) { PlayMedia("audio", media_file);
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index 57215768..5cd190e 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -14411.0.0 \ No newline at end of file +14412.0.0 \ No newline at end of file
diff --git a/chromeos/services/bluetooth_config/cros_bluetooth_config.cc b/chromeos/services/bluetooth_config/cros_bluetooth_config.cc index f8fd335..7ad73cf 100644 --- a/chromeos/services/bluetooth_config/cros_bluetooth_config.cc +++ b/chromeos/services/bluetooth_config/cros_bluetooth_config.cc
@@ -46,7 +46,8 @@ discovered_devices_provider_.get())), device_operation_handler_(initializer.CreateDeviceOperationHandler( adapter_state_controller_.get(), - bluetooth_adapter)), + bluetooth_adapter, + device_name_manager_.get())), fast_pair_delegate_(fast_pair_delegate) { if (fast_pair_delegate_) fast_pair_delegate_->SetDeviceNameManager(device_name_manager_.get());
diff --git a/chromeos/services/bluetooth_config/device_cache_impl.cc b/chromeos/services/bluetooth_config/device_cache_impl.cc index 7e689b1..2fc57b1 100644 --- a/chromeos/services/bluetooth_config/device_cache_impl.cc +++ b/chromeos/services/bluetooth_config/device_cache_impl.cc
@@ -142,15 +142,13 @@ DeviceChanged(adapter, device); } -void DeviceCacheImpl::OnDeviceNicknameChanged(const std::string& device_id, - const std::string&) { +void DeviceCacheImpl::OnDeviceNicknameChanged( + const std::string& device_id, + const absl::optional<std::string>&) { for (device::BluetoothDevice* device : bluetooth_adapter_->GetDevices()) { if (device->GetIdentifier() != device_id) continue; - // The device should be paired or its nickname shouldn't have been able to - // be changed. - DCHECK(device->IsPaired()); DeviceChanged(bluetooth_adapter_.get(), device); return; }
diff --git a/chromeos/services/bluetooth_config/device_cache_impl.h b/chromeos/services/bluetooth_config/device_cache_impl.h index 13e05ff8..9702511 100644 --- a/chromeos/services/bluetooth_config/device_cache_impl.h +++ b/chromeos/services/bluetooth_config/device_cache_impl.h
@@ -78,8 +78,9 @@ device::BluetoothDevice::BatteryType type) override; // DeviceNameManager::Observer: - void OnDeviceNicknameChanged(const std::string& device_id, - const std::string& nickname) override; + void OnDeviceNicknameChanged( + const std::string& device_id, + const absl::optional<std::string>& nickname) override; // Fetches all known devices from BluetoothAdapter and populates them into // |paired_devices_| and |unpaired_devices_|.
diff --git a/chromeos/services/bluetooth_config/device_name_manager.cc b/chromeos/services/bluetooth_config/device_name_manager.cc index 29ea3c6..f82509ae 100644 --- a/chromeos/services/bluetooth_config/device_name_manager.cc +++ b/chromeos/services/bluetooth_config/device_name_manager.cc
@@ -21,7 +21,7 @@ void DeviceNameManager::NotifyDeviceNicknameChanged( const std::string& device_id, - const std::string& nickname) { + const absl::optional<std::string>& nickname) { for (auto& observer : observers_) observer.OnDeviceNicknameChanged(device_id, nickname); }
diff --git a/chromeos/services/bluetooth_config/device_name_manager.h b/chromeos/services/bluetooth_config/device_name_manager.h index 8e3e1a3..b9917a8 100644 --- a/chromeos/services/bluetooth_config/device_name_manager.h +++ b/chromeos/services/bluetooth_config/device_name_manager.h
@@ -25,9 +25,11 @@ ~Observer() override = default; // Invoked when the nickname of device with id |device_id| has changed to - // |nickname|. - virtual void OnDeviceNicknameChanged(const std::string& device_id, - const std::string& nickname) = 0; + // |nickname|. If |nickname| is null, the nickname has been removed for + // |device_id|. + virtual void OnDeviceNicknameChanged( + const std::string& device_id, + const absl::optional<std::string>& nickname) = 0; }; virtual ~DeviceNameManager(); @@ -42,6 +44,10 @@ virtual void SetDeviceNickname(const std::string& device_id, const std::string& nickname) = 0; + // Removes the nickname of the Bluetooth device with ID |device_id| for all + // users of the current device. + virtual void RemoveDeviceNickname(const std::string& device_id) = 0; + // Sets the PrefService used to store nicknames. virtual void SetPrefs(PrefService* local_state) = 0; @@ -52,7 +58,7 @@ DeviceNameManager(); void NotifyDeviceNicknameChanged(const std::string& device_id, - const std::string& nickname); + const absl::optional<std::string>& nickname); base::ObserverList<Observer> observers_; };
diff --git a/chromeos/services/bluetooth_config/device_name_manager_impl.cc b/chromeos/services/bluetooth_config/device_name_manager_impl.cc index fa23efd4..8bf786aa 100644 --- a/chromeos/services/bluetooth_config/device_name_manager_impl.cc +++ b/chromeos/services/bluetooth_config/device_name_manager_impl.cc
@@ -75,7 +75,8 @@ if (!local_state_) { BLUETOOTH_LOG(ERROR) << "SetDeviceNickname for device failed because " - "no local_state_ was set."; + "no local_state_ was set, device_id: " + << device_id; device::RecordSetDeviceNickName( device::SetNicknameResult::kPrefsUnavailable); return; @@ -91,6 +92,29 @@ device::RecordSetDeviceNickName(device::SetNicknameResult::kSuccess); } +void DeviceNameManagerImpl::RemoveDeviceNickname(const std::string& device_id) { + if (!local_state_) { + BLUETOOTH_LOG(ERROR) << "RemoveDeviceNickname for device failed because " + << "no local_state_ was set, device_id: " << device_id; + return; + } + + base::DictionaryValue* device_id_to_nickname_map = + DictionaryPrefUpdate(local_state_, kDeviceIdToNicknameMapPrefName).Get(); + DCHECK(device_id_to_nickname_map) + << "Device ID to nickname map pref is unregistered."; + + // Do nothing if no nickname exists for |device_id|. + if (!device_id_to_nickname_map->FindStringKey(device_id)) { + BLUETOOTH_LOG(ERROR) << "RemoveDeviceNickname for device failed because no " + << "nickname exists for " << device_id; + return; + } + + device_id_to_nickname_map->RemoveKey(device_id); + NotifyDeviceNicknameChanged(device_id, /*nickname=*/absl::nullopt); +} + void DeviceNameManagerImpl::SetPrefs(PrefService* local_state) { local_state_ = local_state; }
diff --git a/chromeos/services/bluetooth_config/device_name_manager_impl.h b/chromeos/services/bluetooth_config/device_name_manager_impl.h index f94025d..6a2d1e2 100644 --- a/chromeos/services/bluetooth_config/device_name_manager_impl.h +++ b/chromeos/services/bluetooth_config/device_name_manager_impl.h
@@ -29,6 +29,7 @@ const std::string& device_id) override; void SetDeviceNickname(const std::string& device_id, const std::string& nickname) override; + void RemoveDeviceNickname(const std::string& device_id) override; void SetPrefs(PrefService* local_state) override; private:
diff --git a/chromeos/services/bluetooth_config/device_name_manager_impl_unittest.cc b/chromeos/services/bluetooth_config/device_name_manager_impl_unittest.cc index 332d0e3..13848b5a 100644 --- a/chromeos/services/bluetooth_config/device_name_manager_impl_unittest.cc +++ b/chromeos/services/bluetooth_config/device_name_manager_impl_unittest.cc
@@ -37,14 +37,15 @@ return last_device_id_nickname_changed_; } - const std::string& last_device_nickname_changed() const { + const absl::optional<std::string>& last_device_nickname_changed() const { return last_device_nickname_changed_; } private: // DeviceNameManager::Observer: - void OnDeviceNicknameChanged(const std::string& device_id, - const std::string& nickname) override { + void OnDeviceNicknameChanged( + const std::string& device_id, + const absl::optional<std::string>& nickname) override { ++num_device_nickname_changed_calls_; last_device_id_nickname_changed_ = device_id; last_device_nickname_changed_ = nickname; @@ -52,7 +53,7 @@ size_t num_device_nickname_changed_calls_ = 0u; std::string last_device_id_nickname_changed_; - std::string last_device_nickname_changed_; + absl::optional<std::string> last_device_nickname_changed_; }; } // namespace @@ -108,7 +109,7 @@ return fake_observer_.last_device_id_nickname_changed(); } - const std::string& GetLastDeviceNicknameChanged() const { + const absl::optional<std::string>& GetLastDeviceNicknameChanged() const { return fake_observer_.last_device_nickname_changed(); } @@ -212,5 +213,33 @@ device::SetNicknameResult::kSuccess, 0); } +TEST_F(DeviceNameManagerImplTest, RemoveThenSetThenRemove) { + std::string device_id; + AddDevice(&device_id); + std::unique_ptr<DeviceNameManagerImpl> manager = CreateDeviceNameManager(); + EXPECT_FALSE(manager->GetDeviceNickname(device_id)); + + // Nothing should happen when removing a nickname that doesn't exist. + manager->RemoveDeviceNickname(device_id); + EXPECT_EQ(GetNumDeviceNicknameObserverEvents(), 0u); + EXPECT_FALSE(manager->GetDeviceNickname(device_id)); + + manager->SetDeviceNickname(device_id, kTestNickname); + EXPECT_EQ(manager->GetDeviceNickname(device_id), kTestNickname); + EXPECT_EQ(GetNumDeviceNicknameObserverEvents(), 1u); + EXPECT_EQ(GetLastDeviceIdNicknameChanged(), device_id); + EXPECT_EQ(GetLastDeviceNicknameChanged(), kTestNickname); + + manager->RemoveDeviceNickname(device_id); + EXPECT_EQ(GetNumDeviceNicknameObserverEvents(), 2u); + EXPECT_FALSE(manager->GetDeviceNickname(device_id)); + EXPECT_EQ(GetLastDeviceIdNicknameChanged(), device_id); + EXPECT_EQ(GetLastDeviceNicknameChanged(), absl::nullopt); + + // Create a new manager and destroy the old one. + manager = CreateDeviceNameManager(); + EXPECT_FALSE(manager->GetDeviceNickname(device_id)); +} + } // namespace bluetooth_config } // namespace chromeos
diff --git a/chromeos/services/bluetooth_config/device_operation_handler_impl.cc b/chromeos/services/bluetooth_config/device_operation_handler_impl.cc index ababdd4f..9c082d7 100644 --- a/chromeos/services/bluetooth_config/device_operation_handler_impl.cc +++ b/chromeos/services/bluetooth_config/device_operation_handler_impl.cc
@@ -11,9 +11,11 @@ DeviceOperationHandlerImpl::DeviceOperationHandlerImpl( AdapterStateController* adapter_state_controller, - scoped_refptr<device::BluetoothAdapter> bluetooth_adapter) + scoped_refptr<device::BluetoothAdapter> bluetooth_adapter, + DeviceNameManager* device_name_manager) : DeviceOperationHandler(adapter_state_controller), - bluetooth_adapter_(std::move(bluetooth_adapter)) {} + bluetooth_adapter_(std::move(bluetooth_adapter)), + device_name_manager_(device_name_manager) {} DeviceOperationHandlerImpl::~DeviceOperationHandlerImpl() = default; @@ -71,6 +73,7 @@ }, device_id)); + device_name_manager_->RemoveDeviceNickname(device_id); HandleFinishedOperation(/*success=*/true); }
diff --git a/chromeos/services/bluetooth_config/device_operation_handler_impl.h b/chromeos/services/bluetooth_config/device_operation_handler_impl.h index 1ce067f6..8956bab 100644 --- a/chromeos/services/bluetooth_config/device_operation_handler_impl.h +++ b/chromeos/services/bluetooth_config/device_operation_handler_impl.h
@@ -7,6 +7,7 @@ #include "base/memory/weak_ptr.h" #include "chromeos/services/bluetooth_config/adapter_state_controller.h" +#include "chromeos/services/bluetooth_config/device_name_manager.h" #include "chromeos/services/bluetooth_config/device_operation_handler.h" #include "device/bluetooth/bluetooth_adapter.h" #include "device/bluetooth/bluetooth_device.h" @@ -20,7 +21,8 @@ public: DeviceOperationHandlerImpl( AdapterStateController* adapter_state_controller, - scoped_refptr<device::BluetoothAdapter> bluetooth_adapter); + scoped_refptr<device::BluetoothAdapter> bluetooth_adapter, + DeviceNameManager* device_name_manager); ~DeviceOperationHandlerImpl() override; private: @@ -39,6 +41,7 @@ device::BluetoothDevice* FindDevice(const std::string& device_id) const; scoped_refptr<device::BluetoothAdapter> bluetooth_adapter_; + DeviceNameManager* device_name_manager_; base::WeakPtrFactory<DeviceOperationHandlerImpl> weak_ptr_factory_{this}; };
diff --git a/chromeos/services/bluetooth_config/device_operation_handler_impl_unittest.cc b/chromeos/services/bluetooth_config/device_operation_handler_impl_unittest.cc index 4841d4ee..abf9d389 100644 --- a/chromeos/services/bluetooth_config/device_operation_handler_impl_unittest.cc +++ b/chromeos/services/bluetooth_config/device_operation_handler_impl_unittest.cc
@@ -8,6 +8,7 @@ #include "base/strings/string_number_conversions.h" #include "base/test/task_environment.h" #include "chromeos/services/bluetooth_config/fake_adapter_state_controller.h" +#include "chromeos/services/bluetooth_config/fake_device_name_manager.h" #include "device/bluetooth/test/mock_bluetooth_adapter.h" #include "device/bluetooth/test/mock_bluetooth_device.h" #include "testing/gmock/include/gmock/gmock.h" @@ -22,6 +23,7 @@ const uint32_t kTestBluetoothClass = 1337u; const char kTestBluetoothName[] = "testName"; +const char kTestBluetoothNickname[] = "testNickname"; } // namespace @@ -48,7 +50,8 @@ this, &DeviceOperationHandlerImplTest::GetMockDevices)); device_operation_handler_ = std::make_unique<DeviceOperationHandlerImpl>( - &fake_adapter_state_controller_, mock_adapter_); + &fake_adapter_state_controller_, mock_adapter_, + &fake_device_name_manager_); } void SetBluetoothSystemState(mojom::BluetoothSystemState system_state) { @@ -169,6 +172,15 @@ forget_callbacks_.reset(); } + void SetDeviceNickname(const std::string& device_id) { + fake_device_name_manager_.SetDeviceNickname(device_id, + kTestBluetoothNickname); + } + + absl::optional<std::string> GetDeviceNickname(const std::string& device_id) { + return fake_device_name_manager_.GetDeviceNickname(device_id); + } + private: std::vector<const device::BluetoothDevice*> GetMockDevices() { std::vector<const device::BluetoothDevice*> devices; @@ -196,6 +208,7 @@ FakeAdapterStateController fake_adapter_state_controller_; scoped_refptr<testing::NiceMock<device::MockBluetoothAdapter>> mock_adapter_; + FakeDeviceNameManager fake_device_name_manager_; std::unique_ptr<DeviceOperationHandlerImpl> device_operation_handler_; }; @@ -256,7 +269,7 @@ /*success=*/true)); } -TEST_F(DeviceOperationHandlerImplTest, ForgetNotFoundFailThenSucceed) { +TEST_F(DeviceOperationHandlerImplTest, ForgetNotFoundThenSucceed) { std::string device_id = "testid"; // Forget should fail due to device not being found. @@ -275,6 +288,21 @@ std::make_tuple(device_id, Operation::kForget, /*success=*/true)); } +TEST_F(DeviceOperationHandlerImplTest, ForgettingDeviceRemovesNickname) { + std::string device_id; + AddDevice(&device_id); + + SetDeviceNickname(device_id); + absl::optional<std::string> nickname = GetDeviceNickname(device_id); + EXPECT_TRUE(nickname.has_value()); + EXPECT_EQ(kTestBluetoothNickname, nickname.value()); + + ForgetDevice(device_id); + EXPECT_EQ(results()[0], + std::make_tuple(device_id, Operation::kForget, /*success=*/true)); + EXPECT_FALSE(GetDeviceNickname(device_id).has_value()); +} + TEST_F(DeviceOperationHandlerImplTest, SimultaneousOperationsAreQueued) { std::string device_id1 = "device_id1"; AddDevice(&device_id1);
diff --git a/chromeos/services/bluetooth_config/fake_device_name_manager.cc b/chromeos/services/bluetooth_config/fake_device_name_manager.cc index 3839267e..2d04de2 100644 --- a/chromeos/services/bluetooth_config/fake_device_name_manager.cc +++ b/chromeos/services/bluetooth_config/fake_device_name_manager.cc
@@ -27,5 +27,10 @@ NotifyDeviceNicknameChanged(device_id, nickname); } +void FakeDeviceNameManager::RemoveDeviceNickname(const std::string& device_id) { + device_id_to_nickname_map_.erase(device_id); + NotifyDeviceNicknameChanged(device_id, /*nickname=*/absl::nullopt); +} + } // namespace bluetooth_config } // namespace chromeos
diff --git a/chromeos/services/bluetooth_config/fake_device_name_manager.h b/chromeos/services/bluetooth_config/fake_device_name_manager.h index 3a2a348e..7dcfee5f 100644 --- a/chromeos/services/bluetooth_config/fake_device_name_manager.h +++ b/chromeos/services/bluetooth_config/fake_device_name_manager.h
@@ -24,6 +24,7 @@ const std::string& device_id) override; void SetDeviceNickname(const std::string& device_id, const std::string& nickname) override; + void RemoveDeviceNickname(const std::string& device_id) override; void SetPrefs(PrefService* local_state) override {} private:
diff --git a/chromeos/services/bluetooth_config/initializer.h b/chromeos/services/bluetooth_config/initializer.h index f546cc5f..ca7824dc1 100644 --- a/chromeos/services/bluetooth_config/initializer.h +++ b/chromeos/services/bluetooth_config/initializer.h
@@ -55,7 +55,8 @@ DiscoveredDevicesProvider* discovered_devices_provider) = 0; virtual std::unique_ptr<DeviceOperationHandler> CreateDeviceOperationHandler( AdapterStateController* adapter_state_controller, - scoped_refptr<device::BluetoothAdapter> bluetooth_adapter) = 0; + scoped_refptr<device::BluetoothAdapter> bluetooth_adapter, + DeviceNameManager* device_name_manager) = 0; protected: Initializer() = default;
diff --git a/chromeos/services/bluetooth_config/initializer_impl.cc b/chromeos/services/bluetooth_config/initializer_impl.cc index cfef9d8..9f7b5af 100644 --- a/chromeos/services/bluetooth_config/initializer_impl.cc +++ b/chromeos/services/bluetooth_config/initializer_impl.cc
@@ -72,9 +72,11 @@ std::unique_ptr<DeviceOperationHandler> InitializerImpl::CreateDeviceOperationHandler( AdapterStateController* adapter_state_controller, - scoped_refptr<device::BluetoothAdapter> bluetooth_adapter) { + scoped_refptr<device::BluetoothAdapter> bluetooth_adapter, + DeviceNameManager* device_name_manager) { return std::make_unique<DeviceOperationHandlerImpl>( - adapter_state_controller, std::move(bluetooth_adapter)); + adapter_state_controller, std::move(bluetooth_adapter), + device_name_manager); } } // namespace bluetooth_config
diff --git a/chromeos/services/bluetooth_config/initializer_impl.h b/chromeos/services/bluetooth_config/initializer_impl.h index 27ec50f..df24f574 100644 --- a/chromeos/services/bluetooth_config/initializer_impl.h +++ b/chromeos/services/bluetooth_config/initializer_impl.h
@@ -40,7 +40,8 @@ DiscoveredDevicesProvider* discovered_devices_provider) override; std::unique_ptr<DeviceOperationHandler> CreateDeviceOperationHandler( AdapterStateController* adapter_state_controller, - scoped_refptr<device::BluetoothAdapter> bluetooth_adapter) override; + scoped_refptr<device::BluetoothAdapter> bluetooth_adapter, + DeviceNameManager* device_name_manager) override; }; } // namespace bluetooth_config
diff --git a/chromeos/services/bluetooth_config/scoped_bluetooth_config_test_helper.cc b/chromeos/services/bluetooth_config/scoped_bluetooth_config_test_helper.cc index 8d1de5e..906e83ce 100644 --- a/chromeos/services/bluetooth_config/scoped_bluetooth_config_test_helper.cc +++ b/chromeos/services/bluetooth_config/scoped_bluetooth_config_test_helper.cc
@@ -96,7 +96,8 @@ std::unique_ptr<DeviceOperationHandler> ScopedBluetoothConfigTestHelper::CreateDeviceOperationHandler( AdapterStateController* adapter_state_controller, - scoped_refptr<device::BluetoothAdapter> bluetooth_adapter) { + scoped_refptr<device::BluetoothAdapter> bluetooth_adapter, + DeviceNameManager* device_name_manager) { auto fake_device_operation_handler = std::make_unique<FakeDeviceOperationHandler>(adapter_state_controller); fake_device_operation_handler_ = fake_device_operation_handler.get();
diff --git a/chromeos/services/bluetooth_config/scoped_bluetooth_config_test_helper.h b/chromeos/services/bluetooth_config/scoped_bluetooth_config_test_helper.h index a915632..f5edc59 100644 --- a/chromeos/services/bluetooth_config/scoped_bluetooth_config_test_helper.h +++ b/chromeos/services/bluetooth_config/scoped_bluetooth_config_test_helper.h
@@ -89,7 +89,8 @@ DiscoveredDevicesProvider* discovered_devices_provider) override; std::unique_ptr<DeviceOperationHandler> CreateDeviceOperationHandler( AdapterStateController* adapter_state_controller, - scoped_refptr<device::BluetoothAdapter> bluetooth_adapter) override; + scoped_refptr<device::BluetoothAdapter> bluetooth_adapter, + DeviceNameManager* device_name_manager) override; FakeAdapterStateController* fake_adapter_state_controller_; FakeBluetoothDeviceStatusNotifier* fake_bluetooth_device_status_notifier_;
diff --git a/components/BUILD.gn b/components/BUILD.gn index f4ac6f2..1f558c9 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn
@@ -848,6 +848,22 @@ "//build/config/fuchsia/test/present_view_capabilities.test-cmx", ] } + + # This test won't work as-is on POSIX platforms, where fork()+exec() is + # used to launch child processes, failure does not happen until exec(). + # See also ServiceProcessLauncherTest.FailToLaunchProcess and + # UtilityProcessHostBrowserTest.FailToLaunchProcess. + if (!is_posix || is_mac) { + sources += [ + "metrics/content/content_stability_metrics_provider_browsertest.cc", + ] + deps += [ + "//components/prefs:test_support", + "//components/variations", + "//content/test:content_test_mojo_bindings", + "//sandbox", + ] + } } test("components_perftests") {
diff --git a/components/autofill/core/browser/payments/payments_client.h b/components/autofill/core/browser/payments/payments_client.h index d69bfe5a..2202ea7 100644 --- a/components/autofill/core/browser/payments/payments_client.h +++ b/components/autofill/core/browser/payments/payments_client.h
@@ -277,6 +277,9 @@ LOCAL_CARD_MIGRATION_SETTINGS_PAGE, }; + // TODO(crbug.com/1281695): Add GetDetailsForEnrollRequest. + // A collection of information received in the response for a + // GetDetailsForEnrollRequest. struct GetDetailsForEnrollmentResponseDetails { GetDetailsForEnrollmentResponseDetails(); GetDetailsForEnrollmentResponseDetails( @@ -284,17 +287,17 @@ GetDetailsForEnrollmentResponseDetails& operator=( const GetDetailsForEnrollmentResponseDetails&) = delete; ~GetDetailsForEnrollmentResponseDetails(); - // |vcn_context_token_| is used in the sequential Enroll call, where it - // allows the server to get the instrument id for this |vcn_context_token_| + // |vcn_context_token| is used in the sequential Enroll call, where it + // allows the server to get the instrument id for this |vcn_context_token| // and link this specific GetDetailsForEnroll call with its corresponding // enroll call. - std::string vcn_context_token_; + std::string vcn_context_token; // Google's legal message lines in the virtual card enroll flow for this - // specific card based on |vcn_context_token_|. - LegalMessageLines google_legal_message_; + // specific card based on |vcn_context_token|. + LegalMessageLines google_legal_message; // The issuer's legal message lines in the virtual card enroll flow for this - // specific card based on |vcn_context_token_|. - LegalMessageLines issuer_legal_message_; + // specific card based on |vcn_context_token|. + LegalMessageLines issuer_legal_message; }; // |url_loader_factory| is reference counted so it has no lifetime or
diff --git a/components/autofill/core/browser/payments/virtual_card_enrollment_manager.cc b/components/autofill/core/browser/payments/virtual_card_enrollment_manager.cc index 4b8f074..56d1dc5 100644 --- a/components/autofill/core/browser/payments/virtual_card_enrollment_manager.cc +++ b/components/autofill/core/browser/payments/virtual_card_enrollment_manager.cc
@@ -46,7 +46,7 @@ raw_ptr<CreditCard> credit_card) {} void VirtualCardEnrollmentManager::OnDidGetUpdateVirtualCardEnrollmentResponse( - CreditCard::VirtualCardEnrollmentState virtual_card_enrollment_state) {} + AutofillClient::PaymentsRpcResult result) {} void VirtualCardEnrollmentManager::OnVirtualCardEnrollmentBubbleCancelled() {}
diff --git a/components/autofill/core/browser/payments/virtual_card_enrollment_manager.h b/components/autofill/core/browser/payments/virtual_card_enrollment_manager.h index 4817a42..9139271 100644 --- a/components/autofill/core/browser/payments/virtual_card_enrollment_manager.h +++ b/components/autofill/core/browser/payments/virtual_card_enrollment_manager.h
@@ -9,11 +9,14 @@ #include "base/memory/raw_ptr.h" #include "components/autofill/core/browser/autofill_client.h" -#include "components/autofill/core/browser/data_model/credit_card.h" #include "components/autofill/core/browser/payments/payments_client.h" namespace autofill { +class CreditCard; + +// This enum is used to denote the specific flow that the virtual card +// enrollment process is a part of. enum class VirtualCardEnrollmentFlow { // Default value, should never be used. kNone = 0, @@ -32,7 +35,7 @@ // This struct is passed into the controller when we show the // VirtualCardEnrollmentBubble, and it lets the controller customize the // bubble based on the fields in this struct. For example, we will show -// different last 4 digits of a credit card based on the |credit_card_| object +// different last 4 digits of a credit card based on the |credit_card| object // in this struct. struct VirtualCardEnrollmentFields { VirtualCardEnrollmentFields(); @@ -40,20 +43,23 @@ VirtualCardEnrollmentFields& operator=(const VirtualCardEnrollmentFields&) = delete; ~VirtualCardEnrollmentFields(); - // Pointer to the credit card to enroll. The |credit_card_| object is owned + // Pointer to the credit card to enroll. The |credit_card| object is owned // by PersonalDataManager. - raw_ptr<CreditCard> credit_card_ = nullptr; - // Raw pointer to the image for the card art. The |card_art_image_| object is + raw_ptr<CreditCard> credit_card = nullptr; + // Raw pointer to the image for the card art. The |card_art_image| object is // owned by PersonalDataManager. - raw_ptr<gfx::Image> card_art_image_ = nullptr; + raw_ptr<gfx::Image> card_art_image = nullptr; // The legal message lines for the footer of the // VirtualCardEnrollmentBubble. - LegalMessageLines legal_message_lines_; + LegalMessageLines legal_message_lines; // The flow for which the VirtualCardEnrollmentBubble will be shown. - VirtualCardEnrollmentFlow virtual_card_enroll_flow_ = + VirtualCardEnrollmentFlow virtual_card_enrollment_flow = VirtualCardEnrollmentFlow::kNone; }; +// This struct is used to track the state of the virtual card enrollment +// process, and its members are read from and written to throughout the process +// where needed. It is created and owned by VirtualCardEnrollmentManager. struct VirtualCardEnrollmentProcessState { VirtualCardEnrollmentProcessState(); VirtualCardEnrollmentProcessState(const VirtualCardEnrollmentProcessState&) = @@ -62,11 +68,18 @@ const VirtualCardEnrollmentProcessState&) = delete; ~VirtualCardEnrollmentProcessState(); // Only populated once the risk engine responded. - absl::optional<std::string> risk_data_; - // |credit_card_| and |virtual_card_enroll_flow_| are populated in the - // beginning of the virtual card enrollment flow, but the rest of the fields - // are only populated before showing the VirtualCardEnrollmentBubble. - VirtualCardEnrollmentFields virtual_card_enrollment_fields_; + absl::optional<std::string> risk_data; + // |virtual_card_enrollment_fields|'s |credit_card| and + // |virtual_card_enrollment_flow| are populated in the beginning of the + // virtual card enrollment flow, but the rest of the fields are only populated + // before showing the VirtualCardEnrollmentBubble. + VirtualCardEnrollmentFields virtual_card_enrollment_fields; + // Populated after the GetDetailsForEnrollResponseDetails are received. Based + // on the |vcn_context_token| the server is able to retrieve the instrument + // id, and using |vcn_context_token| for enroll allows the server to link a + // GetDetailsForEnrollRequest with the corresponding + // UpdateVirtualCardEnrollmentRequest for the enroll process. + absl::optional<std::string> vcn_context_token; }; // Owned by FormDataImporter. There is one instance of this class per tab. This @@ -81,7 +94,6 @@ VirtualCardEnrollmentManager& operator=(const VirtualCardEnrollmentManager&) = delete; ~VirtualCardEnrollmentManager(); - // Starting point for the VCN enroll flow. The fields in |credit_card| will // be used throughout the flow, such as for request fields as well as credit // card specific fields for the bubble to display. @@ -97,24 +109,29 @@ private: // Called once the risk data is loaded. The |risk_data| will be used with - // |credit_card|'s |instrument_id_| field to make a GetDetailsForEnroll - // request, and |virtual_card_enroll_flow| will be passed down to when we show - // the bubble so that we show the correct bubble version. + // |state|'s |virtual_card_enrollment_fields|'s |credit_card|'s + // |instrument_id_| field to make a GetDetailsForEnroll request, and + // |state|'s |virtual_card_enrollment_flow| will be passed down to when we + // show the bubble so that we show the correct bubble version. void OnRiskDataLoadedForVirtualCard( std::unique_ptr<VirtualCardEnrollmentProcessState> state, const std::string& risk_data); - // Sends the GetDetailsForEnrollRequest using AutofillClient's - // |payments_client_|. |state|'s |risk_data| and |credit_card|'s - // |instrument_id| are the fields the server requires for the - // GetDetailsForEnrollRequest, and will be used by |payments_client_|. - // |state|'s |virtual_card_enrollment_fields_|'s - // |virtual_card_enrollment_flow| is passed here so that it can be forwarded - // to ShowVirtualCardEnrollBubble. + // TODO(crbug.com/1281695): Add |client_| data member. + // Sends the GetDetailsForEnrollRequest using |client_|'s + // |payments_client_|. |state|'s |risk_data| and its + // |virtual_card_enrollment_fields|'s |credit_card|'s |instrument_id| are the + // fields the server requires for the GetDetailsForEnrollRequest, and will be + // used by |client_|'s |payments_client_|. |state|'s + // |virtual_card_enrollment_fields_|'s |virtual_card_enrollment_flow| is + // passed here so that it can be forwarded to ShowVirtualCardEnrollBubble. void GetDetailsForEnroll( std::unique_ptr<VirtualCardEnrollmentProcessState> state); - // Handles the response from the GetDetailsForEnrollRequest. + // Handles the response from the GetDetailsForEnrollRequest. |result| and + // |get_details_for_enrollment_response_fields| are received from the + // GetDetailsForEnroll server call response, while |state| is passed down from + // GetDetailsForEnroll() to track the current process' state. void OnDidGetDetailsForEnrollResponse( std::unique_ptr<VirtualCardEnrollmentProcessState> state, AutofillClient::PaymentsRpcResult result, @@ -127,17 +144,21 @@ void ShowVirtualCardEnrollmentBubble( std::unique_ptr<VirtualCardEnrollmentProcessState> state); - // Uses AutofillClient's |payments_client_| to send the enroll request when - // the user accepts the bubble. |vcn_context_token_|, which + // TODO(crbug.com/1281695): Add |client_| data member. + // Uses |client_|'s |payments_client_| to send the enroll request when + // the user accepts the bubble. |state|'s |vcn_context_token_|, which // should be set when we receive the GetDetailsForEnrollResponse, is used in - // the enroll request to enroll the correct card. + // the UpdateVirtualCardEnrollmentRequest to enroll the correct card. void OnVirtualCardEnrollmentBubbleAccepted(raw_ptr<CreditCard> credit_card); - // Handles the response from the Update Virtual Card Enrollment Request. + // Handles the response from the UpdateVirtualCardEnrollmentRequest. + // |result| represents the result from the server call to change the virtual + // card enrollment state for the credit card passed into + // OfferVirtualCardEnroll(). void OnDidGetUpdateVirtualCardEnrollmentResponse( - CreditCard::VirtualCardEnrollmentState virtual_card_enrollment_state); + AutofillClient::PaymentsRpcResult result); - // Cancels the entire Virtual Card Enrollment flow. + // Cancels the entire Virtual Card Enrollment process. void OnVirtualCardEnrollmentBubbleCancelled(); };
diff --git a/components/autofill/core/browser/ui/suggestion.h b/components/autofill/core/browser/ui/suggestion.h index 96a6338..00cfc654 100644 --- a/components/autofill/core/browser/ui/suggestion.h +++ b/components/autofill/core/browser/ui/suggestion.h
@@ -10,6 +10,7 @@ #include "base/strings/string_piece.h" #include "base/types/strong_alias.h" #include "build/build_config.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/gfx/image/image.h" #include "url/gurl.h" namespace autofill { @@ -85,6 +86,9 @@ IsLoading is_loading = IsLoading(false); // The In-Product-Help feature that should be shown for the suggestion. std::string feature_for_iph; + + // If specified, this text will be played back as voice over for a11y. + absl::optional<std::u16string> voice_over; }; } // namespace autofill
diff --git a/components/certificate_transparency/data/log_list.json b/components/certificate_transparency/data/log_list.json index 957d363..eb012ce 100644 --- a/components/certificate_transparency/data/log_list.json +++ b/components/certificate_transparency/data/log_list.json
@@ -1,6 +1,6 @@ { - "version": "4.64", - "log_list_timestamp": "2021-12-20T01:34:42Z", + "version": "4.66", + "log_list_timestamp": "2021-12-22T01:34:28Z", "operators": [ { "name": "Google",
diff --git a/components/content_settings/core/browser/content_settings_default_provider.cc b/components/content_settings/core/browser/content_settings_default_provider.cc index 8169e36..e7d8c4c 100644 --- a/components/content_settings/core/browser/content_settings_default_provider.cc +++ b/components/content_settings/core/browser/content_settings_default_provider.cc
@@ -221,10 +221,15 @@ ContentSettingsType::AUTO_DARK_WEB_CONTENT))), CONTENT_SETTING_NUM_SETTINGS); +#endif + +#if defined(OS_ANDROID) || defined(OS_IOS) + UMA_HISTOGRAM_ENUMERATION("ContentSettings.DefaultRequestDesktopSiteSetting", IntToContentSetting(prefs_->GetInteger(GetPrefName( ContentSettingsType::REQUEST_DESKTOP_SITE))), CONTENT_SETTING_NUM_SETTINGS); + #endif pref_change_registrar_.Init(prefs_);
diff --git a/components/content_settings/core/browser/content_settings_registry.cc b/components/content_settings/core/browser/content_settings_registry.cc index b8968af..2a48c11 100644 --- a/components/content_settings/core/browser/content_settings_registry.cc +++ b/components/content_settings/core/browser/content_settings_registry.cc
@@ -637,7 +637,8 @@ AllowlistedSchemes(), ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK), WebsiteSettingsInfo::SINGLE_ORIGIN_ONLY_SCOPE, - WebsiteSettingsRegistry::PLATFORM_ANDROID, + WebsiteSettingsRegistry::PLATFORM_ANDROID | + WebsiteSettingsRegistry::PLATFORM_IOS, ContentSettingsInfo::INHERIT_IN_INCOGNITO, ContentSettingsInfo::PERSISTENT, ContentSettingsInfo::EXCEPTIONS_ON_SECURE_AND_INSECURE_ORIGINS);
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc index 29117fd..1699ed7 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc
@@ -49,12 +49,13 @@ } // Returns the value at |index| of |list_value| as an int64_t. -int64_t GetInt64PrefValue(const base::ListValue& list_value, size_t index) { +int64_t GetInt64PrefValue(const base::Value& list_value, size_t index) { int64_t val = 0; base::Value::ConstListView list_value_view = list_value.GetList(); if (index < list_value_view.size() && list_value_view[index].is_string()) { - std::string pref_value = list_value_view[index].GetString(); - bool rv = base::StringToInt64(pref_value, &val); + const base::Value& pref_value = list_value_view[index]; + DCHECK(pref_value.is_string()); + bool rv = base::StringToInt64(pref_value.GetString(), &val); DCHECK(rv); } return val; @@ -62,7 +63,7 @@ // Ensure list has exactly |length| elements, either by truncating at the // front, or appending "0"'s to the back. -void MaintainContentLengthPrefsWindow(base::ListValue* list, size_t length) { +void MaintainContentLengthPrefsWindow(base::Value* list, size_t length) { // Remove data for old days from the front. base::Value::ListView list_view = list->GetList(); while (list_view.size() > length) @@ -79,7 +80,7 @@ // number. void AddInt64ToListPref(size_t index, int64_t length, - base::ListValue* list_update) { + base::Value* list_update) { int64_t value = GetInt64PrefValue(*list_update, index) + length; list_update->GetList()[index] = base::Value(base::NumberToString(value)); } @@ -111,7 +112,7 @@ int key, int value) { DictionaryPrefUpdate pref_update(pref_service, pref); - base::DictionaryValue* pref_dict = pref_update.Get(); + base::Value* pref_dict = pref_update.Get(); const std::string key_str = base::NumberToString(key); base::Value* dict_value = pref_dict->FindKey(key_str); if (dict_value) @@ -264,7 +265,7 @@ } // Non-owned. Lazily initialized, set to nullptr until initialized. - raw_ptr<base::ListValue> update_; + raw_ptr<base::Value> update_; // Non-owned pointer. raw_ptr<DataReductionProxyCompressionStats> compression_stats_; // The path of the content length pref for |this|. @@ -396,8 +397,7 @@ void DataReductionProxyCompressionStats::InitListPref(const char* pref) { base::Value pref_value = pref_service_->GetList(pref)->Clone(); - list_pref_map_[pref] = base::ListValue::From( - base::Value::ToUniquePtrValue(std::move(pref_value))); + list_pref_map_[pref] = std::move(pref_value); } int64_t DataReductionProxyCompressionStats::GetInt64(const char* pref_path) { @@ -425,7 +425,7 @@ SetInt64(pref_path, GetInt64(pref_path) + delta); } -base::ListValue* DataReductionProxyCompressionStats::GetList( +base::Value* DataReductionProxyCompressionStats::GetList( const char* pref_path) { if (delay_.is_zero()) return ListPrefUpdate(pref_service_, pref_path).Get(); @@ -434,7 +434,7 @@ auto it = list_pref_map_.find(pref_path); if (it == list_pref_map_.end()) return nullptr; - return it->second.get(); + return &it->second; } void DataReductionProxyCompressionStats::WritePrefs() { @@ -448,7 +448,7 @@ for (auto iter = list_pref_map_.begin(); iter != list_pref_map_.end(); ++iter) { - TransferList(*(iter->second.get()), + TransferList(iter->second, ListPrefUpdate(pref_service_, iter->first).Get()); } } @@ -461,9 +461,9 @@ } void DataReductionProxyCompressionStats::ResetStatistics() { - base::ListValue* original_update = + base::Value* original_update = GetList(prefs::kDailyHttpOriginalContentLength); - base::ListValue* received_update = + base::Value* received_update = GetList(prefs::kDailyHttpReceivedContentLength); original_update->ClearList(); received_update->ClearList(); @@ -484,7 +484,7 @@ ContentLengthList DataReductionProxyCompressionStats::GetDailyContentLengths( const char* pref_name) { ContentLengthList content_lengths; - const base::ListValue* list_value = GetList(pref_name); + const base::Value* list_value = GetList(pref_name); if (list_value->GetList().size() == kNumDaysInHistory) { for (size_t i = 0; i < kNumDaysInHistory; ++i) content_lengths.push_back(GetInt64PrefValue(*list_value, i)); @@ -499,9 +499,9 @@ int64_t* last_update_time) { DCHECK_LE(days, kNumDaysInHistory); - const base::ListValue* original_list = + const base::Value* original_list = GetList(prefs::kDailyHttpOriginalContentLength); - const base::ListValue* received_list = + const base::Value* received_list = GetList(prefs::kDailyHttpReceivedContentLength); if (original_list->GetList().size() != kNumDaysInHistory || @@ -611,7 +611,7 @@ for (auto iter = list_pref_map_.begin(); iter != list_pref_map_.end(); ++iter) { - iter->second->ClearList(); + iter->second.ClearList(); } RecordSavingsClearedMetric(reason);
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h index cc86976..4595582 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h
@@ -28,7 +28,6 @@ class PrefService; namespace base { -class ListValue; class Value; } @@ -169,7 +168,7 @@ friend class DataReductionProxyCompressionStatsTest; typedef std::map<const char*, int64_t> DataReductionProxyPrefMap; - typedef std::unordered_map<const char*, std::unique_ptr<base::ListValue>> + typedef std::unordered_map<const char*, base::Value> DataReductionProxyListPrefMap; class DailyContentLengthUpdate; @@ -201,7 +200,7 @@ void IncreaseInt64Pref(const char* pref_path, int64_t delta); // Gets the pref list at |pref_path| from the |DataReductionProxyPrefMap|. - base::ListValue* GetList(const char* pref_path); + base::Value* GetList(const char* pref_path); // Writes the prefs stored in |DataReductionProxyPrefMap| and // |DataReductionProxyListPrefMap| to |pref_service|.
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc index d45ccd464..932ff0e0 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc
@@ -38,8 +38,7 @@ // for 60 days. const int kNumExpectedBuckets = 60 * 24 * 60 / 15; -int64_t GetListPrefInt64Value(const base::ListValue& list_update, - size_t index) { +int64_t GetListPrefInt64Value(const base::Value& list_update, size_t index) { std::string string_value; base::Value::ConstListView list_view = list_update.GetList(); if (index < list_view.size() && list_view[index].is_string()) { @@ -157,9 +156,9 @@ compression_stats_->SetInt64( prefs::kHttpReceivedContentLength, kReceivedLength); - base::ListValue* original_daily_content_length_list = + base::Value* original_daily_content_length_list = compression_stats_->GetList(prefs::kDailyHttpOriginalContentLength); - base::ListValue* received_daily_content_length_list = + base::Value* received_daily_content_length_list = compression_stats_->GetList(prefs::kDailyHttpReceivedContentLength); for (size_t i = 0; i < kNumDaysInHistory; ++i) { @@ -185,9 +184,8 @@ // Verify the pref list values in |pref_service_| are equal to those in // |simple_pref_service| for |pref|. void VerifyPrefListWasWritten(const char* pref) { - const base::ListValue* delayed_list = compression_stats_->GetList(pref); - const base::ListValue* written_list = - &base::Value::AsListValue(*pref_service()->GetList(pref)); + const base::Value* delayed_list = compression_stats_->GetList(pref); + const base::Value* written_list = pref_service()->GetList(pref); ASSERT_EQ(delayed_list->GetList().size(), written_list->GetList().size()); size_t count = delayed_list->GetList().size(); @@ -205,25 +203,6 @@ EXPECT_EQ(delayed_pref, written_pref); } - // Verify the pref values in |dict| are equal to that in |compression_stats_|. - void VerifyPrefs(base::DictionaryValue* dict) { - std::u16string dict_pref_string; - int64_t dict_pref; - int64_t service_pref; - - dict->GetString("historic_original_content_length", &dict_pref_string); - base::StringToInt64(dict_pref_string, &dict_pref); - service_pref = - compression_stats_->GetInt64(prefs::kHttpOriginalContentLength); - EXPECT_EQ(service_pref, dict_pref); - - dict->GetString("historic_received_content_length", &dict_pref_string); - base::StringToInt64(dict_pref_string, &dict_pref); - service_pref = - compression_stats_->GetInt64(prefs::kHttpReceivedContentLength); - EXPECT_EQ(service_pref, dict_pref); - } - // Verify the pref list values are equal to the given values. // If the count of values is less than kNumDaysInHistory, zeros are assumed // at the beginning. @@ -232,7 +211,7 @@ size_t count, size_t num_days_in_history) { ASSERT_GE(num_days_in_history, count); - base::ListValue* update = compression_stats_->GetList(pref); + base::Value* update = compression_stats_->GetList(pref); ASSERT_EQ(num_days_in_history, update->GetList().size()) << "Pref: " << pref;
diff --git a/components/embedder_support/user_agent_utils.cc b/components/embedder_support/user_agent_utils.cc index 2c451bda..0c5532b 100644 --- a/components/embedder_support/user_agent_utils.cc +++ b/components/embedder_support/user_agent_utils.cc
@@ -39,6 +39,7 @@ namespace { constexpr char kVersion100[] = "100"; +constexpr char kVersion99[] = "99"; #if defined(OS_WIN) @@ -138,6 +139,31 @@ return *m100_version_number; } +const std::string& GetMajorInMinorVersionNumber() { + static const base::NoDestructor<std::string> version_number([] { + base::Version version(version_info::GetVersionNumber()); + std::string version_str; + const std::vector<uint32_t>& components = version.components(); + for (size_t i = 0; i < components.size(); ++i) { + if (i > 0) { + version_str.append("."); + } + if (i == 0) { + // Hardcode major version to 99 + version_str.append(kVersion99); + } else if (i == 1) { + // Force major into minor version + version_str.append(base::NumberToString(components[0])); + } else { + // build and patch stay the same + version_str.append(base::NumberToString(components[i])); + } + } + return version_str; + }()); + return *version_number; +} + const std::string& GetM100InMinorVersionNumber() { static const base::NoDestructor<std::string> m100_version_number([] { base::Version version(version_info::GetVersionNumber()); @@ -248,10 +274,20 @@ } std::string GetProduct(const bool allow_version_override) { + // FF Priority 1: force major version to 99 and minor version to major version + // number. + if (allow_version_override && + base::FeatureList::IsEnabled( + blink::features::kForceMajorVersionInMinorPositionInUserAgent)) + return "Chrome/" + GetMajorInMinorVersionNumber(); + + // FF Priority 2: Force major version to 100, leave the rest the same. if (allow_version_override && base::FeatureList::IsEnabled( blink::features::kForceMajorVersion100InUserAgent)) return "Chrome/" + GetM100VersionNumber(); + + // FF Priority 3: Force minor version to 100, leave the rest the same. if (allow_version_override && base::FeatureList::IsEnabled( blink::features::kForceMinorVersion100InUserAgent))
diff --git a/components/embedder_support/user_agent_utils_unittest.cc b/components/embedder_support/user_agent_utils_unittest.cc index 5129237..e8ef75e2 100644 --- a/components/embedder_support/user_agent_utils_unittest.cc +++ b/components/embedder_support/user_agent_utils_unittest.cc
@@ -49,7 +49,7 @@ // the User-Agent string, where the first capture is the {major_version} and the // second capture is the {minor_version}. static constexpr char kChromeProductVersionRegex[] = - "Chrome/([0-9]+)\\.([0-9]+\\.[0-9]+\\.[0-9]+)"; + "Chrome/([0-9]+).([0-9]+).([0-9]+).([0-9]+)"; void CheckUserAgentStringOrdering(bool mobile_device) { std::vector<std::string> pieces; @@ -762,7 +762,7 @@ EXPECT_TRUE( re2::RE2::FullMatch(product, kChromeProductVersionRegex, &major_version)); // Whether the force M100 experiment is on or not, the product value should - // contain the actual major version number. + // contain the actual major version number which is 0. EXPECT_EQ(major_version, version_info::GetMajorVersionNumber()); } @@ -776,7 +776,8 @@ EXPECT_EQ(major_version, "100"); else EXPECT_EQ(major_version, version_info::GetMajorVersionNumber()); - EXPECT_NE(minor_version, "0.0.0"); + // Minor version should contain the actual minor version number. + EXPECT_EQ(minor_version, "0"); } class UserAgentUtilsMinorVersionTest @@ -784,12 +785,12 @@ public testing::WithParamInterface<bool> { public: void SetUp() override { - if (ForceMinorVersionTo100()) + if (ForceMajorInMinorVersion()) scoped_feature_list_.InitAndEnableFeature( - blink::features::kForceMinorVersion100InUserAgent); + blink::features::kForceMajorVersionInMinorPositionInUserAgent); } - bool ForceMinorVersionTo100() { return GetParam(); } + bool ForceMajorInMinorVersion() { return GetParam(); } private: base::test::ScopedFeatureList scoped_feature_list_; @@ -797,7 +798,7 @@ INSTANTIATE_TEST_CASE_P(All, UserAgentUtilsMinorVersionTest, - /*force_minor_version_to_M100*/ testing::Bool()); + /*force_major_version_in_minor*/ testing::Bool()); TEST_P(UserAgentUtilsMinorVersionTest, GetUserAgent) { const std::string ua = GetUserAgent(); @@ -805,11 +806,54 @@ std::string minor_version; EXPECT_TRUE(re2::RE2::PartialMatch(ua, kChromeProductVersionRegex, &major_version, &minor_version)); - EXPECT_EQ(major_version, version_info::GetMajorVersionNumber()); - if (ForceMinorVersionTo100()) { - EXPECT_NE(minor_version, "100.0.0"); + if (ForceMajorInMinorVersion()) { + // When enabled major versions should be locked at 99 and minor version + // should hold the major version number. + EXPECT_EQ(major_version, "99"); + EXPECT_EQ(minor_version, version_info::GetMajorVersionNumber()); } else { - EXPECT_NE(minor_version, "0.0.0"); + // When disabled major version should hold major version number and minor + // version should be the minor version number which is 0. + EXPECT_EQ(major_version, version_info::GetMajorVersionNumber()); + EXPECT_EQ(minor_version, "0"); + } +} + +class UserAgentUtilsMinorVersionM100Test + : public testing::Test, + public testing::WithParamInterface<bool> { + public: + void SetUp() override { + if (ForceMinorVersion100InUserAgent()) + scoped_feature_list_.InitAndEnableFeature( + blink::features::kForceMinorVersion100InUserAgent); + } + + bool ForceMinorVersion100InUserAgent() { return GetParam(); } + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +INSTANTIATE_TEST_CASE_P(All, + UserAgentUtilsMinorVersionM100Test, + /*force_minor_version_to_M100*/ testing::Bool()); + +TEST_P(UserAgentUtilsMinorVersionM100Test, GetUserAgent) { + const std::string ua = GetUserAgent(); + std::string major_version; + std::string minor_version; + EXPECT_TRUE(re2::RE2::PartialMatch(ua, kChromeProductVersionRegex, + &major_version, &minor_version)); + if (ForceMinorVersion100InUserAgent()) { + // When enabled minor version should be hardcoded to 100. + EXPECT_EQ(major_version, version_info::GetMajorVersionNumber()); + EXPECT_EQ(minor_version, "100"); + } else { + // When disabled major version should hold major version number and minor + // version should be the minor version number which is 0. + EXPECT_EQ(major_version, version_info::GetMajorVersionNumber()); + EXPECT_EQ(minor_version, "0"); } }
diff --git a/components/image_fetcher/android/java/src/org/chromium/components/image_fetcher/ImageFetcher.java b/components/image_fetcher/android/java/src/org/chromium/components/image_fetcher/ImageFetcher.java index f99af4c1..cc4a22b 100644 --- a/components/image_fetcher/android/java/src/org/chromium/components/image_fetcher/ImageFetcher.java +++ b/components/image_fetcher/android/java/src/org/chromium/components/image_fetcher/ImageFetcher.java
@@ -51,6 +51,15 @@ * Creates image fetcher parameters. The image will not be resized. * @See {@link #Params(String, String, int, int, int)}. */ + public static Params create(final GURL url, String clientName) { + return create(url.getSpec(), clientName); + } + + /** + * Creates image fetcher parameters. The image will not be resized. + * @See {@link #Params(String, String, int, int, int)}. + */ + @Deprecated public static Params create(final String url, String clientName) { return new Params(url, clientName, DEFAULT_IMAGE_SIZE, DEFAULT_IMAGE_SIZE, INVALID_EXPIRATION_INTERVAL); @@ -60,6 +69,15 @@ * Creates image fetcher parameters with image size specified. * @See {@link #Params(String, String, int, int, int)}. */ + public static Params create(final GURL url, String clientName, int width, int height) { + return create(url.getSpec(), clientName, width, height); + } + + /** + * Creates image fetcher parameters with image size specified. + * @See {@link #Params(String, String, int, int, int)}. + */ + @Deprecated public static Params create(final String url, String clientName, int width, int height) { return new Params(url, clientName, width, height, INVALID_EXPIRATION_INTERVAL); }
diff --git a/components/image_fetcher/android/junit/src/org/chromium/components/image_fetcher/ImageFetcherTest.java b/components/image_fetcher/android/junit/src/org/chromium/components/image_fetcher/ImageFetcherTest.java index d535318..953f102 100644 --- a/components/image_fetcher/android/junit/src/org/chromium/components/image_fetcher/ImageFetcherTest.java +++ b/components/image_fetcher/android/junit/src/org/chromium/components/image_fetcher/ImageFetcherTest.java
@@ -36,6 +36,7 @@ @Config(manifest = Config.NONE) public class ImageFetcherTest { private static final GURL URL = JUnitTestGURLs.getGURL(JUnitTestGURLs.EXAMPLE_URL); + private static final GURL URL_2 = JUnitTestGURLs.getGURL(JUnitTestGURLs.URL_2); private static final String CLIENT_NAME = "client"; private static final int WIDTH_PX = 100; private static final int HEIGHT_PX = 200; @@ -110,19 +111,17 @@ @Test public void testFetchImageNoDimensionsAlias() { - mImageFetcher.fetchImage( - ImageFetcher.Params.create(URL.getSpec(), CLIENT_NAME), result -> {}); + mImageFetcher.fetchImage(ImageFetcher.Params.create(URL, CLIENT_NAME), result -> {}); // No arguments should alias to 0, 0. verify(mImageFetcher) - .fetchImage( - eq(ImageFetcher.Params.create(URL.getSpec(), CLIENT_NAME, 0, 0)), any()); + .fetchImage(eq(ImageFetcher.Params.create(URL, CLIENT_NAME, 0, 0)), any()); } @Test public void testCreateParams() { // Verifies params without size specified. - ImageFetcher.Params params = ImageFetcher.Params.create(URL.getSpec(), CLIENT_NAME); + ImageFetcher.Params params = ImageFetcher.Params.create(URL, CLIENT_NAME); assertEquals(URL.getSpec(), params.url); assertEquals(CLIENT_NAME, params.clientName); assertEquals(0, params.width); @@ -130,7 +129,7 @@ assertEquals(0, params.expirationIntervalMinutes); // Verifies params with size. - params = ImageFetcher.Params.create(URL.getSpec(), CLIENT_NAME, WIDTH_PX, HEIGHT_PX); + params = ImageFetcher.Params.create(URL, CLIENT_NAME, WIDTH_PX, HEIGHT_PX); assertEquals(URL.getSpec(), params.url); assertEquals(CLIENT_NAME, params.clientName); assertEquals(WIDTH_PX, params.width); @@ -153,14 +152,14 @@ @Test public void testParamsEqual() { // Different URLs. - ImageFetcher.Params params1 = ImageFetcher.Params.create(URL.getSpec(), CLIENT_NAME); - ImageFetcher.Params params2 = ImageFetcher.Params.create("Not the same URL", CLIENT_NAME); + ImageFetcher.Params params1 = ImageFetcher.Params.create(URL, CLIENT_NAME); + ImageFetcher.Params params2 = ImageFetcher.Params.create(URL_2, CLIENT_NAME); assertFalse(params1.equals(params2)); assertFalse(params2.equals(params1)); assertNotEquals(params1.hashCode(), params2.hashCode()); // Different width and height. - params2 = ImageFetcher.Params.create(URL.getSpec(), CLIENT_NAME, WIDTH_PX, HEIGHT_PX); + params2 = ImageFetcher.Params.create(URL, CLIENT_NAME, WIDTH_PX, HEIGHT_PX); assertFalse(params1.equals(params2)); assertFalse(params2.equals(params1)); assertNotEquals(params1.hashCode(), params2.hashCode());
diff --git a/components/language/core/browser/url_language_histogram.cc b/components/language/core/browser/url_language_histogram.cc index 42713037..7663776 100644 --- a/components/language/core/browser/url_language_histogram.cc +++ b/components/language/core/browser/url_language_histogram.cc
@@ -25,31 +25,29 @@ const float kDiscountFactor = 0.75f; // Gets the sum of the counter for all languages in the histogram. -int GetCountersSum(const base::DictionaryValue& dict) { +int GetCountersSum(const base::Value& dict) { int sum = 0; - for (base::DictionaryValue::Iterator itr(dict); !itr.IsAtEnd(); - itr.Advance()) { - if (itr.value().is_int()) - sum += itr.value().GetInt(); + for (const auto itr : dict.DictItems()) { + if (itr.second.is_int()) + sum += itr.second.GetInt(); } return sum; } // Removes languages with small counter values and discount remaining counters. -void DiscountAndCleanCounters(base::DictionaryValue* dict) { +void DiscountAndCleanCounters(base::Value* dict) { std::set<std::string> remove_keys; - for (base::DictionaryValue::Iterator itr(*dict); !itr.IsAtEnd(); - itr.Advance()) { + for (const auto itr : dict->DictItems()) { // Remove languages with invalid or small values. - if (!itr.value().is_int() || - itr.value().GetInt() < (kCutoffRatio * kMaxCountersSum)) { - remove_keys.insert(itr.key()); + if (!itr.second.is_int() || + itr.second.GetInt() < (kCutoffRatio * kMaxCountersSum)) { + remove_keys.insert(itr.first); continue; } // Discount the value. - dict->SetInteger(itr.key(), itr.value().GetInt() * kDiscountFactor); + dict->SetIntKey(itr.first, itr.second.GetInt() * kDiscountFactor); } for (const std::string& lang_to_remove : remove_keys) @@ -58,7 +56,7 @@ // Transforms the counters from prefs into a list of LanguageInfo structs. std::vector<UrlLanguageHistogram::LanguageInfo> GetAllLanguages( - const base::DictionaryValue& dict) { + const base::Value& dict) { int counters_sum = GetCountersSum(dict); // If the sample is not large enough yet, pretend there are no top languages. @@ -66,12 +64,11 @@ return std::vector<UrlLanguageHistogram::LanguageInfo>(); std::vector<UrlLanguageHistogram::LanguageInfo> top_languages; - for (base::DictionaryValue::Iterator itr(dict); !itr.IsAtEnd(); - itr.Advance()) { - if (!itr.value().is_int()) + for (const auto itr : dict.DictItems()) { + if (!itr.second.is_int()) continue; top_languages.emplace_back( - itr.key(), static_cast<float>(itr.value().GetInt()) / counters_sum); + itr.first, static_cast<float>(itr.second.GetInt()) / counters_sum); } return top_languages; } @@ -92,8 +89,8 @@ std::vector<UrlLanguageHistogram::LanguageInfo> UrlLanguageHistogram::GetTopLanguages() const { std::vector<UrlLanguageHistogram::LanguageInfo> top_languages = - GetAllLanguages(base::Value::AsDictionaryValue( - *pref_service_->GetDictionary(kUrlLanguageHistogramCounters))); + GetAllLanguages( + *pref_service_->GetDictionary(kUrlLanguageHistogramCounters)); std::sort(top_languages.begin(), top_languages.end(), [](UrlLanguageHistogram::LanguageInfo a, @@ -106,27 +103,25 @@ float UrlLanguageHistogram::GetLanguageFrequency( const std::string& language_code) const { - const base::DictionaryValue* dict = &base::Value::AsDictionaryValue( - *pref_service_->GetDictionary(kUrlLanguageHistogramCounters)); + const base::Value* dict = + pref_service_->GetDictionary(kUrlLanguageHistogramCounters); int counters_sum = GetCountersSum(*dict); // If the sample is not large enough yet, pretend there are no top languages. if (counters_sum < kMinCountersSum) return 0; - int counter_value = 0; // If the key |language_code| does not exist, |counter_value| stays 0. - dict->GetInteger(language_code, &counter_value); + int counter_value = dict->FindIntKey(language_code).value_or(0); return static_cast<float>(counter_value) / counters_sum; } void UrlLanguageHistogram::OnPageVisited(const std::string& language_code) { DictionaryPrefUpdate update(pref_service_, kUrlLanguageHistogramCounters); - base::DictionaryValue* dict = update.Get(); - int counter_value = 0; + base::Value* dict = update.Get(); // If the key |language_code| does not exist, |counter_value| stays 0. - dict->GetInteger(language_code, &counter_value); - dict->SetInteger(language_code, counter_value + 1); + int counter_value = dict->FindIntKey(language_code).value_or(0); + dict->SetIntKey(language_code, counter_value + 1); if (GetCountersSum(*dict) > kMaxCountersSum) DiscountAndCleanCounters(dict);
diff --git a/components/metrics/content/DEPS b/components/metrics/content/DEPS index c8b2783..01ec3c7 100644 --- a/components/metrics/content/DEPS +++ b/components/metrics/content/DEPS
@@ -10,5 +10,9 @@ "subprocess_metrics_provider_browsertest\.cc": [ "+content/shell/browser/shell.h", "+net/dns/mock_host_resolver.h", + ], + + "content_stability_metrics_provider_browsertest\.cc": [ + "+sandbox" ] }
diff --git a/components/metrics/content/content_stability_metrics_provider.cc b/components/metrics/content/content_stability_metrics_provider.cc index f2f4b51..083128c3 100644 --- a/components/metrics/content/content_stability_metrics_provider.cc +++ b/components/metrics/content/content_stability_metrics_provider.cc
@@ -128,6 +128,20 @@ helper_.BrowserUtilityProcessLaunched(data.metrics_name); } +void ContentStabilityMetricsProvider::BrowserChildProcessLaunchFailed( + const content::ChildProcessData& data, + const content::ChildProcessTerminationInfo& info) { + DCHECK(!data.metrics_name.empty()); + DCHECK_EQ(info.status, base::TERMINATION_STATUS_LAUNCH_FAILED); + if (data.process_type == content::PROCESS_TYPE_UTILITY) + helper_.BrowserUtilityProcessLaunchFailed(data.metrics_name, info.exit_code +#if defined(OS_WIN) + , + info.last_error +#endif + ); +} + #if defined(OS_ANDROID) void ContentStabilityMetricsProvider::OnCrashDumpProcessed( int rph_id,
diff --git a/components/metrics/content/content_stability_metrics_provider.h b/components/metrics/content/content_stability_metrics_provider.h index 3710e37..1d42ed9 100644 --- a/components/metrics/content/content_stability_metrics_provider.h +++ b/components/metrics/content/content_stability_metrics_provider.h
@@ -76,6 +76,9 @@ const content::ChildProcessTerminationInfo& info) override; void BrowserChildProcessLaunchedAndConnected( const content::ChildProcessData& data) override; + void BrowserChildProcessLaunchFailed( + const content::ChildProcessData& data, + const content::ChildProcessTerminationInfo& info) override; #if defined(OS_ANDROID) // crash_reporter::CrashMetricsReporter::Observer:
diff --git a/components/metrics/content/content_stability_metrics_provider_browsertest.cc b/components/metrics/content/content_stability_metrics_provider_browsertest.cc new file mode 100644 index 0000000..e668e6e --- /dev/null +++ b/components/metrics/content/content_stability_metrics_provider_browsertest.cc
@@ -0,0 +1,124 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/metrics/content/content_stability_metrics_provider.h" + +#include <string> + +#include "base/callback.h" +#include "base/command_line.h" +#include "base/files/file_path.h" +#include "base/metrics/histogram.h" +#include "base/test/metrics/histogram_tester.h" +#include "build/build_config.h" +#include "components/metrics/content/extensions_helper.h" +#include "components/prefs/testing_pref_service.h" +#include "components/variations/hashing.h" +#include "content/public/browser/browser_child_process_observer.h" +#include "content/public/browser/child_process_data.h" +#include "content/public/browser/service_process_host.h" +#include "content/public/common/content_switches.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_base.h" +#include "content/public/test/content_browser_test.h" +#include "content/public/test/content_browser_test_utils.h" +#include "content/public/test/test_service.mojom.h" +#include "sandbox/policy/mojom/sandbox.mojom.h" + +#if defined(OS_WIN) +#include <windows.h> + +#include "sandbox/win/src/sandbox_types.h" +#endif + +namespace content { + +template <> +sandbox::mojom::Sandbox GetServiceSandboxType<content::mojom::TestService>() { + // On Windows, the sandbox does not like having a different binary name + // 'non_existent_path' from the browser process, so set no sandbox here. +#if defined(OS_WIN) + return sandbox::mojom::Sandbox::kNoSandbox; +#else + return sandbox::mojom::Sandbox::kService; +#endif +} + +} // namespace content + +namespace metrics { + +class ContentStabilityProviderBrowserTest + : public content::ContentBrowserTest, + content::BrowserChildProcessObserver { + public: + // Either the process launched, or did not launch. Both cause the run_loop to + // terminate. + void BrowserChildProcessLaunchFailed( + const content::ChildProcessData& data, + const content::ChildProcessTerminationInfo& info) override { + if (data.metrics_name == content::mojom::TestService::Name_) + std::move(done_closure_).Run(); + } + + void BrowserChildProcessLaunchedAndConnected( + const content::ChildProcessData& data) override { + if (data.metrics_name == content::mojom::TestService::Name_) + std::move(done_closure_).Run(); + } + + protected: + void AddObserver() { content::BrowserChildProcessObserver::Add(this); } + + void RemoveObserver() { content::BrowserChildProcessObserver::Remove(this); } + + base::OnceClosure done_closure_; + TestingPrefServiceSimple prefs_; +}; + +IN_PROC_BROWSER_TEST_F(ContentStabilityProviderBrowserTest, + FailedUtilityProcessLaunches) { + base::RunLoop run_loop; + done_closure_ = run_loop.QuitClosure(); + AddObserver(); + + ContentStabilityMetricsProvider provider(&prefs_, nullptr); + base::HistogramTester histogram_tester; + + // Simulate a catastrophic utility process launch failure by specifying a bad + // path. + base::CommandLine::ForCurrentProcess()->AppendSwitchPath( + switches::kBrowserSubprocessPath, + base::FilePath(FILE_PATH_LITERAL("non_existent_path"))); + mojo::Remote<content::mojom::TestService> test_service; + content::ServiceProcessHost::Launch( + test_service.BindNewPipeAndPassReceiver()); + + // run_loop runs until either the process launches or fails to launch. + run_loop.Run(); + + RemoveObserver(); + + histogram_tester.ExpectUniqueSample( + "ChildProcess.LaunchFailed.UtilityProcessHash", + variations::HashName(content::mojom::TestService::Name_), 1); +#if defined(OS_WIN) + int expected_error_code = + sandbox::SBOX_ERROR_CANNOT_LAUNCH_UNSANDBOXED_PROCESS; +#else + int expected_error_code = + 1003; // content::LaunchResultCode::LAUNCH_RESULT_FAILURE. +#endif + histogram_tester.ExpectUniqueSample( + "ChildProcess.LaunchFailed.UtilityProcessErrorCode", expected_error_code, + 1); + +#if defined(OS_WIN) + // Last Error is only recorded on Windows. + histogram_tester.ExpectUniqueSample("ChildProcess.LaunchFailed.WinLastError", + DWORD{ERROR_FILE_NOT_FOUND}, 1); +#endif +} + +} // namespace metrics
diff --git a/components/metrics/stability_metrics_helper.cc b/components/metrics/stability_metrics_helper.cc index 38e5b30..7b8e4e5 100644 --- a/components/metrics/stability_metrics_helper.cc +++ b/components/metrics/stability_metrics_helper.cc
@@ -194,6 +194,27 @@ RecordStabilityEvent(StabilityEventType::kUtilityCrash); } +void StabilityMetricsHelper::BrowserUtilityProcessLaunchFailed( + const std::string& metrics_name, + int launch_error_code +#if defined(OS_WIN) + , + DWORD last_error +#endif +) { + uint32_t hash = variations::HashName(metrics_name); + base::UmaHistogramSparse("ChildProcess.LaunchFailed.UtilityProcessHash", + hash); + base::UmaHistogramSparse("ChildProcess.LaunchFailed.UtilityProcessErrorCode", + launch_error_code); +#if defined(OS_WIN) + base::UmaHistogramSparse("ChildProcess.LaunchFailed.WinLastError", + last_error); +#endif + // TODO(wfh): Decide if this utility process launch failure should also + // trigger a Stability Event. +} + void StabilityMetricsHelper::BrowserChildProcessCrashed() { IncrementPrefValue(prefs::kStabilityChildProcessCrashCount); RecordStabilityEvent(StabilityEventType::kChildProcessCrash);
diff --git a/components/metrics/stability_metrics_helper.h b/components/metrics/stability_metrics_helper.h index 94710cf..7758fde 100644 --- a/components/metrics/stability_metrics_helper.h +++ b/components/metrics/stability_metrics_helper.h
@@ -9,6 +9,11 @@ #include "base/memory/raw_ptr.h" #include "base/process/kill.h" +#include "build/build_config.h" + +#if defined(OS_WIN) +#include "base/win/windows_types.h" +#endif class PrefRegistrySimple; class PrefService; @@ -64,6 +69,17 @@ void BrowserUtilityProcessCrashed(const std::string& metrics_name, int exit_code); + // Records that a utility process with name |metrics_name| failed to launch. + // The |launch_error_code| is a platform-specific error code. On Windows, a + // |last_error| is also supplied to help diagnose the launch failure. + void BrowserUtilityProcessLaunchFailed(const std::string& metrics_name, + int launch_error_code +#if defined(OS_WIN) + , + DWORD last_error +#endif + ); + // Records a browser child process crash. void BrowserChildProcessCrashed();
diff --git a/components/optimization_guide/core/hints_manager.cc b/components/optimization_guide/core/hints_manager.cc index ce685a5..7ae4f3a 100644 --- a/components/optimization_guide/core/hints_manager.cc +++ b/components/optimization_guide/core/hints_manager.cc
@@ -861,7 +861,7 @@ &HintsManager::OnBatchUpdateHintsFetched, weak_ptr_factory_.GetWeakPtr(), request_id_and_fetcher.first, request_context, target_hosts.set(), target_urls.set(), - registered_optimization_types_, + target_urls.set(), registered_optimization_types_, base::DoNothingAs<void( const GURL&, const base::flat_map< proto::OptimizationType, @@ -990,18 +990,16 @@ // TODO(crbug/1275612): Check whether we have consent to fetch. + // This set contains URLs that require some information to be fetched, whether + // that be a URL-keyed hint or a host-keyed hint. + base::flat_set<GURL> urls_with_pending_callback; + InsertionOrderedSet<GURL> urls_to_fetch; InsertionOrderedSet<std::string> hosts_to_fetch; for (const auto& url : urls) { - base::flat_map<proto::OptimizationType, - OptimizationGuideDecisionWithMetadata> - decisions = GetDecisionsWithCachedInformationForURLAndOptimizationTypes( - url, optimization_types); - - bool has_something_to_fetch_for = false; if (!hint_cache_->HasURLKeyedEntryForURL(url)) { urls_to_fetch.insert(url); - has_something_to_fetch_for = true; + urls_with_pending_callback.insert(url); } // We check for the hint being loaded mostly for code simplicity. If we just // check for the presence in the cache and the hint wasn't loaded, we need @@ -1012,14 +1010,21 @@ if (!hint_cache_->HasHint(url.host()) || (hint_cache_->GetHostKeyedHintIfLoaded(url.host()) == nullptr)) { hosts_to_fetch.insert(url.host()); - has_something_to_fetch_for = true; + urls_with_pending_callback.insert(url); } - if (!has_something_to_fetch_for) { + + if (!urls_with_pending_callback.contains(url)) { + // Only get decisions if we know we do not need to fetch for anything. + base::flat_map<proto::OptimizationType, + OptimizationGuideDecisionWithMetadata> + decisions = + GetDecisionsWithCachedInformationForURLAndOptimizationTypes( + url, optimization_types); callback.Run(url, decisions); } } - if (urls_to_fetch.empty() && hosts_to_fetch.empty()) { + if (urls_with_pending_callback.empty()) { // Nothing to fetch for. return; } @@ -1037,7 +1042,7 @@ weak_ptr_factory_.GetWeakPtr(), request_id_and_fetcher.first, request_context, hosts_to_fetch.set(), urls_to_fetch.set(), - optimization_types, callback)); + urls_with_pending_callback, optimization_types, callback)); } void HintsManager::OnBatchUpdateHintsFetched( @@ -1045,6 +1050,7 @@ proto::RequestContext request_context, const base::flat_set<std::string>& hosts_requested, const base::flat_set<GURL>& urls_requested, + const base::flat_set<GURL>& urls_with_pending_callback, const base::flat_set<proto::OptimizationType>& optimization_types, OnDemandOptimizationGuideDecisionRepeatingCallback callback, absl::optional<std::unique_ptr<proto::GetHintsResponse>> @@ -1052,7 +1058,8 @@ CleanUpBatchUpdateHintsFetcher(request_id); if (!get_hints_response.has_value() || !get_hints_response.value()) { - OnBatchUpdateHintsStored(urls_requested, optimization_types, callback); + OnBatchUpdateHintsStored(urls_with_pending_callback, optimization_types, + callback); return; } @@ -1063,7 +1070,7 @@ clock_->Now() + features::GetActiveTabsFetchRefreshDuration(), hosts_requested, urls_requested, base::BindOnce(&HintsManager::OnBatchUpdateHintsStored, - weak_ptr_factory_.GetWeakPtr(), urls_requested, + weak_ptr_factory_.GetWeakPtr(), urls_with_pending_callback, optimization_types, callback)); if (switches::IsDebugLogsEnabled()) {
diff --git a/components/optimization_guide/core/hints_manager.h b/components/optimization_guide/core/hints_manager.h index b4b72b7c..59b0782d 100644 --- a/components/optimization_guide/core/hints_manager.h +++ b/components/optimization_guide/core/hints_manager.h
@@ -253,6 +253,7 @@ proto::RequestContext request_context, const base::flat_set<std::string>& hosts_fetched, const base::flat_set<GURL>& urls_fetched, + const base::flat_set<GURL>& urls_for_callback, const base::flat_set<proto::OptimizationType>& optimization_types, OnDemandOptimizationGuideDecisionRepeatingCallback callback, absl::optional<std::unique_ptr<proto::GetHintsResponse>>
diff --git a/components/password_manager/core/browser/built_in_backend_to_android_backend_migrator.cc b/components/password_manager/core/browser/built_in_backend_to_android_backend_migrator.cc index 32c4aeec..9d50e42 100644 --- a/components/password_manager/core/browser/built_in_backend_to_android_backend_migrator.cc +++ b/components/password_manager/core/browser/built_in_backend_to_android_backend_migrator.cc
@@ -11,6 +11,7 @@ #include "base/containers/flat_set.h" #include "base/memory/scoped_refptr.h" #include "base/ranges/algorithm.h" +#include "components/password_manager/core/browser/password_store_util.h" #include "components/password_manager/core/common/password_manager_features.h" #include "components/password_manager/core/common/password_manager_pref_names.h" #include "components/prefs/pref_service.h" @@ -27,15 +28,6 @@ } }; -base::OnceCallback<void(absl::optional<PasswordStoreChangeList>)> -IgnoreChangeListAndRunCallback(base::OnceClosure callback) { - return base::BindOnce( - [](base::OnceClosure callback, absl::optional<PasswordStoreChangeList>) { - std::move(callback).Run(); - }, - std::move(callback)); -} - bool IsInitialMigrationNeeded(PrefService* prefs) { return features::kMigrationVersion.Get() > prefs->GetInteger(
diff --git a/components/password_manager/core/browser/fake_password_store_backend.cc b/components/password_manager/core/browser/fake_password_store_backend.cc index b0f55816..5196785 100644 --- a/components/password_manager/core/browser/fake_password_store_backend.cc +++ b/components/password_manager/core/browser/fake_password_store_backend.cc
@@ -131,6 +131,10 @@ return nullptr; } +void FakePasswordStoreBackend::ClearAllLocalPasswords() { + NOTIMPLEMENTED(); +} + LoginsResult FakePasswordStoreBackend::GetAllLoginsInternal() { LoginsResult result; for (const auto& elements : stored_passwords_) {
diff --git a/components/password_manager/core/browser/fake_password_store_backend.h b/components/password_manager/core/browser/fake_password_store_backend.h index 5a54560..57fbad6 100644 --- a/components/password_manager/core/browser/fake_password_store_backend.h +++ b/components/password_manager/core/browser/fake_password_store_backend.h
@@ -63,6 +63,7 @@ FieldInfoStore* GetFieldInfoStore() override; std::unique_ptr<syncer::ProxyModelTypeControllerDelegate> CreateSyncControllerDelegate() override; + void ClearAllLocalPasswords() override; LoginsResult GetAllLoginsInternal(); LoginsResult GetAutofillableLoginsInternal();
diff --git a/components/password_manager/core/browser/mock_password_store_backend.h b/components/password_manager/core/browser/mock_password_store_backend.h index df756d8..8ab46f8 100644 --- a/components/password_manager/core/browser/mock_password_store_backend.h +++ b/components/password_manager/core/browser/mock_password_store_backend.h
@@ -87,6 +87,7 @@ CreateSyncControllerDelegate, (), (override)); + MOCK_METHOD(void, ClearAllLocalPasswords, (), (override)); private: base::WeakPtrFactory<MockPasswordStoreBackend> weak_ptr_factory_{this};
diff --git a/components/password_manager/core/browser/password_autofill_manager.cc b/components/password_manager/core/browser/password_autofill_manager.cc index c06b0fe..52fd554 100644 --- a/components/password_manager/core/browser/password_autofill_manager.cc +++ b/components/password_manager/core/browser/password_autofill_manager.cc
@@ -128,6 +128,8 @@ suggestion.label = GetHumanReadableRealm(signon_realm); suggestion.additional_label = std::u16string(password_length, kPasswordReplacementChar); + suggestion.voice_over = l10n_util::GetStringFUTF16( + IDS_PASSWORD_MANAGER_PASSWORD_FOR_ACCOUNT, suggestion.label); if (from_account_store) { suggestion.frontend_id = is_password_field
diff --git a/components/password_manager/core/browser/password_store_backend.h b/components/password_manager/core/browser/password_store_backend.h index 01a28ae..4654240 100644 --- a/components/password_manager/core/browser/password_store_backend.h +++ b/components/password_manager/core/browser/password_store_backend.h
@@ -128,6 +128,9 @@ virtual std::unique_ptr<syncer::ProxyModelTypeControllerDelegate> CreateSyncControllerDelegate() = 0; + // Clears all the passwords from the local storage. + virtual void ClearAllLocalPasswords() = 0; + // Factory function for creating the backend. The Local backend requires the // provided `login_db` for storage and Android backend for migration purposes. static std::unique_ptr<PasswordStoreBackend> Create(
diff --git a/components/password_manager/core/browser/password_store_backend_migration_decorator.cc b/components/password_manager/core/browser/password_store_backend_migration_decorator.cc index f95f8c3..61c4d29 100644 --- a/components/password_manager/core/browser/password_store_backend_migration_decorator.cc +++ b/components/password_manager/core/browser/password_store_backend_migration_decorator.cc
@@ -5,10 +5,12 @@ #include "components/password_manager/core/browser/password_store_backend_migration_decorator.h" #include "base/bind.h" +#include "base/task/sequenced_task_runner.h" #include "components/password_manager/core/browser/built_in_backend_to_android_backend_migrator.h" #include "components/password_manager/core/browser/field_info_table.h" #include "components/password_manager/core/browser/password_store_proxy_backend.h" #include "components/password_manager/core/common/password_manager_features.h" +#include "components/password_manager/core/common/password_manager_pref_names.h" #include "components/prefs/pref_service.h" #include "components/sync/model/proxy_model_type_controller_delegate.h" @@ -34,7 +36,7 @@ DCHECK(built_in_backend_); DCHECK(android_backend_); active_backend_ = std::make_unique<PasswordStoreProxyBackend>( - built_in_backend_.get(), android_backend_.get(), + built_in_backend_.get(), android_backend_.get(), prefs_, is_syncing_passwords_callback_); } @@ -50,6 +52,24 @@ RemoteChangesReceived remote_form_changes_received, base::RepeatingClosure sync_enabled_or_disabled_cb, base::OnceCallback<void(bool)> completion) { + base::RepeatingClosure handle_sync_status_change = base::BindRepeating( + &PasswordStoreBackendMigrationDecorator::SyncStatusChanged, + weak_ptr_factory_.GetWeakPtr()); + + // |sync_enabled_or_disabled_cb| is called on a background sequence so it + // should be posted to the main sequence before invoking + // PasswordStoreBackendMigrationDecorator::SyncStatusChanged(). + base::RepeatingClosure handle_sync_status_change_on_main_thread = + base::BindRepeating( + base::IgnoreResult(&base::SequencedTaskRunner::PostTask), + base::SequencedTaskRunnerHandle::Get(), FROM_HERE, + std::move(handle_sync_status_change)); + + // Inject nested callback to listen for sync status changes. + sync_enabled_or_disabled_cb = + std::move(handle_sync_status_change_on_main_thread) + .Then(std::move(sync_enabled_or_disabled_cb)); + active_backend_->InitBackend(std::move(remote_form_changes_received), std::move(sync_enabled_or_disabled_cb), std::move(completion)); @@ -168,6 +188,10 @@ return built_in_backend_->CreateSyncControllerDelegate(); } +void PasswordStoreBackendMigrationDecorator::ClearAllLocalPasswords() { + NOTIMPLEMENTED(); +} + void PasswordStoreBackendMigrationDecorator::StartMigration() { migrator_ = std::make_unique<BuiltInBackendToAndroidBackendMigrator>( built_in_backend_.get(), android_backend_.get(), prefs_, @@ -175,4 +199,16 @@ migrator_->StartMigrationIfNecessary(); } +void PasswordStoreBackendMigrationDecorator::SyncStatusChanged() { + if (is_syncing_passwords_callback_.Run()) { + // Sync was enabled. Delete all the passwords from GMS Core local storage. + // TODO(https://crbug.com/1278748) Implement. + } else { + // Clear migration pref to force rerun of initial migration of passwords + // from Chrome to GMS Core local storage. + prefs_->SetInteger(prefs::kCurrentMigrationVersionToGoogleMobileServices, + 0); + } +} + } // namespace password_manager
diff --git a/components/password_manager/core/browser/password_store_backend_migration_decorator.h b/components/password_manager/core/browser/password_store_backend_migration_decorator.h index 9353be1..8453e06 100644 --- a/components/password_manager/core/browser/password_store_backend_migration_decorator.h +++ b/components/password_manager/core/browser/password_store_backend_migration_decorator.h
@@ -77,10 +77,15 @@ FieldInfoStore* GetFieldInfoStore() override; std::unique_ptr<syncer::ProxyModelTypeControllerDelegate> CreateSyncControllerDelegate() override; + void ClearAllLocalPasswords() override; // Creates 'migrator_' and starts migration process. void StartMigration(); + // React on sync changes to keep GMS Core local storage up-to-date. + // TODO(https://crbug.com/) Remove this method when no longer needed. + void SyncStatusChanged(); + std::unique_ptr<PasswordStoreBackend> built_in_backend_; std::unique_ptr<PasswordStoreBackend> android_backend_;
diff --git a/components/password_manager/core/browser/password_store_backend_migration_decorator_unittest.cc b/components/password_manager/core/browser/password_store_backend_migration_decorator_unittest.cc index 3c0f0fe..1ce8b59 100644 --- a/components/password_manager/core/browser/password_store_backend_migration_decorator_unittest.cc +++ b/components/password_manager/core/browser/password_store_backend_migration_decorator_unittest.cc
@@ -4,47 +4,37 @@ #include "components/password_manager/core/browser/password_store_backend_migration_decorator.h" +#include "base/callback.h" +#include "base/callback_helpers.h" #include "base/memory/raw_ptr.h" #include "base/test/mock_callback.h" #include "base/test/task_environment.h" -#include "components/password_manager/core/browser/fake_password_store_backend.h" +#include "components/password_manager/core/browser/mock_password_store_backend.h" #include "components/password_manager/core/browser/password_manager_test_utils.h" +#include "components/password_manager/core/common/password_manager_pref_names.h" +#include "components/prefs/pref_registry.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/testing_pref_service.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" namespace password_manager { namespace { -using ::testing::_; -using ::testing::Invoke; using ::testing::WithArg; - -std::vector<std::unique_ptr<PasswordForm>> CreateTestLogins() { - std::vector<std::unique_ptr<PasswordForm>> forms; - forms.push_back(CreateEntry("Todd Tester", "S3cr3t", - GURL(u"https://example.com"), - /*is_psl_match=*/false, - /*is_affiliation_based_match=*/false)); - forms.push_back(CreateEntry("Marcus McSpartanGregor", "S0m3th1ngCr34t1v3", - GURL(u"https://m.example.com"), - /*is_psl_match=*/true, - /*is_affiliation_based_match=*/false)); - forms[0]->in_store = PasswordForm::Store::kProfileStore; - forms[1]->in_store = PasswordForm::Store::kProfileStore; - return forms; -} +using ::testing::WithArgs; } // namespace class PasswordStoreBackendMigrationDecoratorTest : public testing::Test { protected: - PasswordStoreBackendMigrationDecoratorTest() { + PasswordStoreBackendMigrationDecoratorTest() = default; + + void Init(base::RepeatingCallback<bool()> is_sync_enabled) { backend_migration_decorator_ = std::make_unique<PasswordStoreBackendMigrationDecorator>( - CreateBuiltInBackend(), CreateAndroidBackend(), /*prefs=*/nullptr, - /*is_syncing_passwords_callback=*/base::BindRepeating([]() { - return false; - })); + CreateBuiltInBackend(), CreateAndroidBackend(), &prefs_, + std::move(is_sync_enabled)); } ~PasswordStoreBackendMigrationDecoratorTest() override { @@ -54,49 +44,79 @@ PasswordStoreBackend* backend_migration_decorator() { return backend_migration_decorator_.get(); } - PasswordStoreBackend* built_in_backend() { return built_in_backend_; } - PasswordStoreBackend* android_backend() { return android_backend_; } + MockPasswordStoreBackend* built_in_backend() { return built_in_backend_; } + MockPasswordStoreBackend* android_backend() { return android_backend_; } - void AddTestLogins() { - for (const auto& login : CreateTestLogins()) { - built_in_backend()->AddLoginAsync(*login, base::DoNothing()); - android_backend()->AddLoginAsync(*login, base::DoNothing()); - } - RunUntilIdle(); - } + TestingPrefServiceSimple& prefs() { return prefs_; } void RunUntilIdle() { task_env_.RunUntilIdle(); } private: std::unique_ptr<PasswordStoreBackend> CreateBuiltInBackend() { - auto unique_backend = std::make_unique<FakePasswordStoreBackend>(); + auto unique_backend = std::make_unique<MockPasswordStoreBackend>(); built_in_backend_ = unique_backend.get(); return unique_backend; } std::unique_ptr<PasswordStoreBackend> CreateAndroidBackend() { - auto unique_backend = std::make_unique<FakePasswordStoreBackend>(); + auto unique_backend = std::make_unique<MockPasswordStoreBackend>(); android_backend_ = unique_backend.get(); return unique_backend; } base::test::SingleThreadTaskEnvironment task_env_; - raw_ptr<FakePasswordStoreBackend> built_in_backend_; - raw_ptr<FakePasswordStoreBackend> android_backend_; + TestingPrefServiceSimple prefs_; + raw_ptr<MockPasswordStoreBackend> built_in_backend_; + raw_ptr<MockPasswordStoreBackend> android_backend_; std::unique_ptr<PasswordStoreBackendMigrationDecorator> backend_migration_decorator_; }; TEST_F(PasswordStoreBackendMigrationDecoratorTest, - UseBuiltInBackendToGetAllLoginsAsync) { - base::MockCallback<LoginsOrErrorReply> mock_reply; - std::vector<std::unique_ptr<PasswordForm>> expected_logins = - CreateTestLogins(); - AddTestLogins(); - EXPECT_CALL(mock_reply, Run(LoginsResultsOrErrorAre(&expected_logins))); - backend_migration_decorator()->GetAllLoginsAsync(mock_reply.Get()); + MigrationPreferenceClearedWhenSyncDisabled) { + // Set up pref to indicate that initial migration is finished. + prefs().registry()->RegisterIntegerPref( + prefs::kCurrentMigrationVersionToGoogleMobileServices, 2); + + base::MockCallback<base::OnceCallback<void(bool)>> mock_completion_callback; + base::MockCallback<base::RepeatingCallback<bool()>> is_sync_enabled_callback_; + base::RepeatingClosure sync_status_changed_closure; + + Init(is_sync_enabled_callback_.Get()); + + EXPECT_CALL(mock_completion_callback, Run(/*success=*/true)); + + EXPECT_CALL(*built_in_backend(), InitBackend) + .WillOnce(WithArgs<1, 2>( + [&sync_status_changed_closure](auto sync_status_changed, + auto completion_callback) { + std::move(completion_callback).Run(/*success=*/true); + // Capture |sync_enabled_or_disabled_cb| passed to the + // build_in_backend. + sync_status_changed_closure = std::move(sync_status_changed); + })); + EXPECT_CALL(*android_backend(), InitBackend) + .WillOnce(WithArg<2>([](auto completion_callback) { + std::move(completion_callback).Run(/*success=*/true); + })); + + backend_migration_decorator()->InitBackend( + /*remote_form_changes_received=*/base::DoNothing(), + /*sync_enabled_or_disabled_cb=*/base::DoNothing(), + /*completion=*/mock_completion_callback.Get()); + + // Invoke sync callback to simulate a change in sync status. Set expectation + // for sync to be turned off. + EXPECT_CALL(is_sync_enabled_callback_, Run()) + .WillOnce(testing::Return(false)); + sync_status_changed_closure.Run(); + RunUntilIdle(); + + // Since sync was disabled pref value for migration version should be reset. + EXPECT_EQ(0, prefs().GetInteger( + prefs::kCurrentMigrationVersionToGoogleMobileServices)); } } // namespace password_manager
diff --git a/components/password_manager/core/browser/password_store_built_in_backend.cc b/components/password_manager/core/browser/password_store_built_in_backend.cc index a272280..eab741d 100644 --- a/components/password_manager/core/browser/password_store_built_in_backend.cc +++ b/components/password_manager/core/browser/password_store_built_in_backend.cc
@@ -439,6 +439,10 @@ weak_ptr_factory_.GetWeakPtr())); } +void PasswordStoreBuiltInBackend::ClearAllLocalPasswords() { + NOTREACHED(); +} + void PasswordStoreBuiltInBackend::AddSiteStats(const InteractionsStats& stats) { DCHECK(!was_shutdown_); DCHECK(main_task_runner_->RunsTasksInCurrentSequence());
diff --git a/components/password_manager/core/browser/password_store_built_in_backend.h b/components/password_manager/core/browser/password_store_built_in_backend.h index ba23748..2729462 100644 --- a/components/password_manager/core/browser/password_store_built_in_backend.h +++ b/components/password_manager/core/browser/password_store_built_in_backend.h
@@ -113,6 +113,7 @@ FieldInfoStore* GetFieldInfoStore() override; std::unique_ptr<syncer::ProxyModelTypeControllerDelegate> CreateSyncControllerDelegate() override; + void ClearAllLocalPasswords() override; // SmartBubbleStatsStore: void AddSiteStats(const InteractionsStats& stats) override;
diff --git a/components/password_manager/core/browser/password_store_proxy_backend.cc b/components/password_manager/core/browser/password_store_proxy_backend.cc index 7e964a5..177a630 100644 --- a/components/password_manager/core/browser/password_store_proxy_backend.cc +++ b/components/password_manager/core/browser/password_store_proxy_backend.cc
@@ -18,12 +18,32 @@ #include "base/strings/strcat.h" #include "components/password_manager/core/browser/field_info_table.h" #include "components/password_manager/core/common/password_manager_features.h" +#include "components/password_manager/core/common/password_manager_pref_names.h" +#include "components/prefs/pref_service.h" #include "components/sync/model/proxy_model_type_controller_delegate.h" namespace password_manager { namespace { +bool ShouldExecuteModifyOperationsOnShadowBackend(PrefService* prefs, + bool is_syncing) { + if (!base::FeatureList::IsEnabled( + features::kUnifiedPasswordManagerShadowWriteOperationsAndroid)) { + return false; + } + if (is_syncing) + return false; + if (features::kMigrationVersion.Get() > + prefs->GetInteger( + prefs::kCurrentMigrationVersionToGoogleMobileServices)) { + // If initial migration isn't completed yet, we shouldn't modify the shadow + // backend. + return false; + } + return true; +} + using MethodName = base::StrongAlias<struct MethodNameTag, std::string>; struct LoginsResultOrErrorImpl { @@ -53,6 +73,33 @@ } }; +struct PasswordStoreChangeListImpl { + using ResultType = absl::optional<PasswordStoreChangeList>; + using ElementsType = PasswordStoreChangeList; + + static PasswordStoreChangeList* GetElements( + absl::optional<PasswordStoreChangeList>& changelist) { + return changelist.has_value() ? &changelist.value() : nullptr; + } + + static PasswordStoreChange Clone(const PasswordStoreChange& change) { + return change; + } + + static bool IsLess(const PasswordStoreChange& lhs, + const PasswordStoreChange& rhs) { + return std::forward_as_tuple(PasswordFormUniqueKey(lhs.form()), + lhs.type()) < + std::forward_as_tuple(PasswordFormUniqueKey(rhs.form()), rhs.type()); + } + + static bool HaveInconsistentPasswords(const PasswordStoreChange& lhs, + const PasswordStoreChange& rhs) { + // We never consider PasswordStoreChange having inconsistent passwords. + return false; + } +}; + void InvokeCallbackWithCombinedStatus(base::OnceCallback<void(bool)> completion, std::vector<bool> statuses) { std::move(completion).Run(base::ranges::all_of(statuses, base::identity())); @@ -191,9 +238,11 @@ PasswordStoreProxyBackend::PasswordStoreProxyBackend( PasswordStoreBackend* main_backend, PasswordStoreBackend* shadow_backend, + PrefService* prefs, base::RepeatingCallback<bool()> is_syncing_passwords_callback) : main_backend_(main_backend), shadow_backend_(shadow_backend), + prefs_(prefs), is_syncing_passwords_callback_(std::move(is_syncing_passwords_callback)) { } @@ -227,10 +276,9 @@ } void PasswordStoreProxyBackend::GetAllLoginsAsync(LoginsOrErrorReply callback) { - scoped_refptr<ShadowTrafficMetricsRecorder<LoginsResultOrErrorImpl>> handler = - base::MakeRefCounted< - ShadowTrafficMetricsRecorder<LoginsResultOrErrorImpl>>( - MethodName("GetAllLoginsAsync")); + auto handler = base::MakeRefCounted< + ShadowTrafficMetricsRecorder<LoginsResultOrErrorImpl>>( + MethodName("GetAllLoginsAsync")); main_backend_->GetAllLoginsAsync( base::BindOnce(&ShadowTrafficMetricsRecorder< LoginsResultOrErrorImpl>::RecordMainResult, @@ -265,8 +313,23 @@ void PasswordStoreProxyBackend::AddLoginAsync( const PasswordForm& form, PasswordStoreChangeListReply callback) { - main_backend_->AddLoginAsync(form, std::move(callback)); - // TODO(crbug.com/1229655): Request shadow_backend_ and compare results. + auto handler = base::MakeRefCounted< + ShadowTrafficMetricsRecorder<PasswordStoreChangeListImpl>>( + MethodName("AddLoginAsync")); + + main_backend_->AddLoginAsync( + form, base::BindOnce(&ShadowTrafficMetricsRecorder< + PasswordStoreChangeListImpl>::RecordMainResult, + handler) + .Then(std::move(callback))); + if (ShouldExecuteModifyOperationsOnShadowBackend( + prefs_, is_syncing_passwords_callback_.Run())) { + shadow_backend_->AddLoginAsync( + form, + base::BindOnce(&ShadowTrafficMetricsRecorder< + PasswordStoreChangeListImpl>::RecordShadowResult, + handler)); + } } void PasswordStoreProxyBackend::UpdateLoginAsync( @@ -325,4 +388,8 @@ return main_backend_->CreateSyncControllerDelegate(); } +void PasswordStoreProxyBackend::ClearAllLocalPasswords() { + NOTIMPLEMENTED(); +} + } // namespace password_manager
diff --git a/components/password_manager/core/browser/password_store_proxy_backend.h b/components/password_manager/core/browser/password_store_proxy_backend.h index 0724074e..bc6e2fa5e 100644 --- a/components/password_manager/core/browser/password_store_proxy_backend.h +++ b/components/password_manager/core/browser/password_store_proxy_backend.h
@@ -12,6 +12,8 @@ #include "base/memory/weak_ptr.h" #include "components/password_manager/core/browser/password_store_backend.h" +class PrefService; + namespace password_manager { // This backend forwards requests to two backends in order to compare and record @@ -24,6 +26,7 @@ PasswordStoreProxyBackend( PasswordStoreBackend* main_backend, PasswordStoreBackend* shadow_backend, + PrefService* prefs, base::RepeatingCallback<bool()> is_syncing_passwords_callback); PasswordStoreProxyBackend(const PasswordStoreProxyBackend&) = delete; PasswordStoreProxyBackend(PasswordStoreProxyBackend&&) = delete; @@ -68,9 +71,11 @@ FieldInfoStore* GetFieldInfoStore() override; std::unique_ptr<syncer::ProxyModelTypeControllerDelegate> CreateSyncControllerDelegate() override; + void ClearAllLocalPasswords() override; const raw_ptr<PasswordStoreBackend> main_backend_; const raw_ptr<PasswordStoreBackend> shadow_backend_; + raw_ptr<PrefService> const prefs_ = nullptr; base::RepeatingCallback<bool()> is_syncing_passwords_callback_; base::WeakPtrFactory<PasswordStoreProxyBackend> weak_ptr_factory_{this}; };
diff --git a/components/password_manager/core/browser/password_store_proxy_backend_unittest.cc b/components/password_manager/core/browser/password_store_proxy_backend_unittest.cc index cd6e7fbb..213e3a8c 100644 --- a/components/password_manager/core/browser/password_store_proxy_backend_unittest.cc +++ b/components/password_manager/core/browser/password_store_proxy_backend_unittest.cc
@@ -18,6 +18,9 @@ #include "components/password_manager/core/browser/password_manager_test_utils.h" #include "components/password_manager/core/browser/password_store_change.h" #include "components/password_manager/core/common/password_manager_features.h" +#include "components/password_manager/core/common/password_manager_pref_names.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/testing_pref_service.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -68,10 +71,17 @@ protected: PasswordStoreProxyBackendTest() { proxy_backend_ = std::make_unique<PasswordStoreProxyBackend>( - &main_backend_, &shadow_backend_, is_syncing_passwords_callback_.Get()); + &main_backend_, &shadow_backend_, &prefs_, + is_syncing_passwords_callback_.Get()); - feature_list_.InitAndEnableFeature( - features::kUnifiedPasswordManagerShadowAndroid); + feature_list_.InitWithFeatures( + /*enabled_features=*/ + {features::kUnifiedPasswordManagerShadowAndroid, + features::kUnifiedPasswordManagerShadowWriteOperationsAndroid}, + /*disabled_features=*/{}); + + prefs_.registry()->RegisterIntegerPref( + prefs::kCurrentMigrationVersionToGoogleMobileServices, 0); } void TearDown() override { @@ -85,12 +95,14 @@ PasswordStoreBackend& proxy_backend() { return *proxy_backend_; } MockPasswordStoreBackend& main_backend() { return main_backend_; } MockPasswordStoreBackend& shadow_backend() { return shadow_backend_; } + TestingPrefServiceSimple* prefs() { return &prefs_; } base::MockCallback<base::RepeatingCallback<bool(void)>> is_syncing_passwords_callback_; private: base::test::ScopedFeatureList feature_list_; + TestingPrefServiceSimple prefs_; std::unique_ptr<PasswordStoreProxyBackend> proxy_backend_; StrictMock<MockPasswordStoreBackend> main_backend_; StrictMock<MockPasswordStoreBackend> shadow_backend_; @@ -186,6 +198,8 @@ PasswordStoreChangeList change_list; change_list.push_back(PasswordStoreChange(Type::ADD, form)); EXPECT_CALL(mock_reply, Run(Eq(change_list))); + // This test doesn't care about the shadow backend. + EXPECT_CALL(shadow_backend(), AddLoginAsync).Times(testing::AnyNumber()); EXPECT_CALL(main_backend(), AddLoginAsync(Eq(form), _)) .WillOnce(WithArg<1>( Invoke([&change_list](PasswordStoreChangeListReply reply) -> void { @@ -315,6 +329,97 @@ histogram_tester.ExpectTotalCount(prefix + "InconsistentPasswords.Rel", 0); } +TEST_F(PasswordStoreProxyBackendTest, NoShadowAddLoginsAsyncWhenSyncEnabled) { + EXPECT_CALL(is_syncing_passwords_callback_, Run).WillRepeatedly(Return(true)); + + EXPECT_CALL(main_backend(), AddLoginAsync); + EXPECT_CALL(shadow_backend(), AddLoginAsync).Times(0); + proxy_backend().AddLoginAsync(CreateTestForm(), + /*callback=*/base::DoNothing()); +} + +TEST_F(PasswordStoreProxyBackendTest, + NoShadowAddLoginsAsyncWhenSyncDisabledAndInitialMigrationIncomplete) { + base::test::ScopedFeatureList feature_list; + feature_list.InitWithFeaturesAndParameters( + /*enabled_features=*/{{features::kUnifiedPasswordManagerMigration, + {{"migration_version", "2"}}}}, + /*disabled_features=*/{}); + prefs()->SetInteger(prefs::kCurrentMigrationVersionToGoogleMobileServices, 1); + + EXPECT_CALL(is_syncing_passwords_callback_, Run) + .WillRepeatedly(Return(false)); + + EXPECT_CALL(main_backend(), AddLoginAsync); + EXPECT_CALL(shadow_backend(), AddLoginAsync).Times(0); + proxy_backend().AddLoginAsync(CreateTestForm(), + /*callback=*/base::DoNothing()); +} + +TEST_F(PasswordStoreProxyBackendTest, + ShadowAddLoginsAsyncWhenSyncDisabledAndInitialMigrationComplete) { + base::test::ScopedFeatureList feature_list; + feature_list.InitWithFeaturesAndParameters( + /*enabled_features=*/{{features::kUnifiedPasswordManagerMigration, + {{"migration_version", "2"}}}}, + /*disabled_features=*/{}); + prefs()->SetInteger(prefs::kCurrentMigrationVersionToGoogleMobileServices, 2); + + EXPECT_CALL(is_syncing_passwords_callback_, Run) + .WillRepeatedly(Return(false)); + + EXPECT_CALL(main_backend(), AddLoginAsync); + EXPECT_CALL(shadow_backend(), AddLoginAsync); + proxy_backend().AddLoginAsync(CreateTestForm(), + /*callback=*/base::DoNothing()); +} + +TEST_F(PasswordStoreProxyBackendTest, ShadowAddLoginsAsyncBasicMetricsTesting) { + base::HistogramTester histogram_tester; + // Set the prefs such that no initial migration is required to allow shadow + // write operations. + base::test::ScopedFeatureList feature_list; + feature_list.InitWithFeaturesAndParameters( + /*enabled_features=*/{{features::kUnifiedPasswordManagerMigration, + {{"migration_version", "2"}}}}, + /*disabled_features=*/{}); + prefs()->SetInteger(prefs::kCurrentMigrationVersionToGoogleMobileServices, 2); + // Shadow write operations run only for non-syncing users. + EXPECT_CALL(is_syncing_passwords_callback_, Run) + .WillRepeatedly(Return(false)); + + PasswordForm test_form = CreateTestForm(); + + PasswordStoreChangeList main_backend_changelist; + main_backend_changelist.emplace_back(PasswordStoreChange::ADD, test_form); + + PasswordStoreChangeList shadow_backend_changelist; + shadow_backend_changelist.emplace_back(PasswordStoreChange::UPDATE, + test_form); + + EXPECT_CALL(main_backend(), AddLoginAsync) + .WillOnce(WithArg<1>(Invoke( + [&main_backend_changelist](PasswordStoreChangeListReply reply) + -> void { std::move(reply).Run(main_backend_changelist); }))); + + EXPECT_CALL(shadow_backend(), AddLoginAsync) + .WillOnce(WithArg<1>(Invoke( + [&shadow_backend_changelist](PasswordStoreChangeListReply reply) + -> void { std::move(reply).Run(shadow_backend_changelist); }))); + + proxy_backend().AddLoginAsync(test_form, + /*callback=*/base::DoNothing()); + + std::string prefix = + "PasswordManager.PasswordStoreProxyBackend.AddLoginAsync."; + + histogram_tester.ExpectUniqueSample(prefix + "Diff.Abs", 2, 1); + histogram_tester.ExpectUniqueSample(prefix + "MainMinusShadow.Abs", 1, 1); + histogram_tester.ExpectUniqueSample(prefix + "ShadowMinusMain.Abs", 1, 1); + histogram_tester.ExpectUniqueSample(prefix + "InconsistentPasswords.Abs", 0, + 1); +} + // Holds the main and shadow backend's logins and the expected number of common // and different logins. struct LoginsMetricsParam {
diff --git a/components/password_manager/core/browser/password_store_util.cc b/components/password_manager/core/browser/password_store_util.cc index 2c8f99e..78a021b8 100644 --- a/components/password_manager/core/browser/password_store_util.cc +++ b/components/password_manager/core/browser/password_store_util.cc
@@ -25,4 +25,13 @@ return std::move(absl::get<LoginsResult>(result)); } +PasswordStoreChangeListReply IgnoreChangeListAndRunCallback( + base::OnceClosure callback) { + return base::BindOnce( + [](base::OnceClosure callback, absl::optional<PasswordStoreChangeList>) { + std::move(callback).Run(); + }, + std::move(callback)); +} + } // namespace password_manager
diff --git a/components/password_manager/core/browser/password_store_util.h b/components/password_manager/core/browser/password_store_util.h index c98fc94..346f089 100644 --- a/components/password_manager/core/browser/password_store_util.h +++ b/components/password_manager/core/browser/password_store_util.h
@@ -22,6 +22,11 @@ // holds an error. LoginsResult GetLoginsOrEmptyListOnFailure(LoginsResultOrError result); +// Helper function allowing to bind base::OnceClosure to +// PasswordStoreChangeListReply. +PasswordStoreChangeListReply IgnoreChangeListAndRunCallback( + base::OnceClosure callback); + } // namespace password_manager #endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_STORE_UTIL_H_
diff --git a/components/password_manager/core/browser/test_password_store.cc b/components/password_manager/core/browser/test_password_store.cc index 28a6675c..d0db0bc 100644 --- a/components/password_manager/core/browser/test_password_store.cc +++ b/components/password_manager/core/browser/test_password_store.cc
@@ -258,6 +258,10 @@ return nullptr; } +void TestPasswordStore::ClearAllLocalPasswords() { + NOTIMPLEMENTED(); +} + bool TestPasswordStore::IsAccountStore() const { return is_account_store_.value(); }
diff --git a/components/password_manager/core/browser/test_password_store.h b/components/password_manager/core/browser/test_password_store.h index da5b071..d44eec8 100644 --- a/components/password_manager/core/browser/test_password_store.h +++ b/components/password_manager/core/browser/test_password_store.h
@@ -99,6 +99,7 @@ FieldInfoStore* GetFieldInfoStore() override; std::unique_ptr<syncer::ProxyModelTypeControllerDelegate> CreateSyncControllerDelegate() override; + void ClearAllLocalPasswords() override; private: LoginsResult GetAllLoginsInternal();
diff --git a/components/password_manager/core/common/password_manager_features.cc b/components/password_manager/core/common/password_manager_features.cc index a30673a5..62dc10e7 100644 --- a/components/password_manager/core/common/password_manager_features.cc +++ b/components/password_manager/core/common/password_manager_features.cc
@@ -168,6 +168,12 @@ const base::Feature kUnifiedPasswordManagerShadowAndroid{ "UnifiedPasswordManagerShadowAndroid", base::FEATURE_DISABLED_BY_DEFAULT}; +// Similar to kUnifiedPasswordManagerShadowAndroid but send modify operations +// instead of read operations.Relevant only for non-sync'ing users. +const base::Feature kUnifiedPasswordManagerShadowWriteOperationsAndroid{ + "UnifiedPasswordManagerShadowWriteOperationsAndroid", + base::FEATURE_DISABLED_BY_DEFAULT}; + // If enabled, the built-in sync functionality in PasswordSyncBridge becomes // unused, meaning that SyncService/SyncEngine will no longer download or // upload changes to/from the Sync server. Instead, an external Android-specific
diff --git a/components/password_manager/core/common/password_manager_features.h b/components/password_manager/core/common/password_manager_features.h index 74618e62..d80920e 100644 --- a/components/password_manager/core/common/password_manager_features.h +++ b/components/password_manager/core/common/password_manager_features.h
@@ -50,6 +50,7 @@ extern const base::Feature kUnifiedPasswordManagerAndroid; extern const base::Feature kUnifiedPasswordManagerMigration; extern const base::Feature kUnifiedPasswordManagerShadowAndroid; +extern const base::Feature kUnifiedPasswordManagerShadowWriteOperationsAndroid; extern const base::Feature kUnifiedPasswordManagerSyncUsingAndroidBackendOnly; #endif
diff --git a/components/password_manager_strings.grdp b/components/password_manager_strings.grdp index 7cede914..c3c12aba 100644 --- a/components/password_manager_strings.grdp +++ b/components/password_manager_strings.grdp
@@ -100,4 +100,7 @@ <message name="IDS_PASSWORD_MANAGER_DEFAULT_EXPORT_FILENAME" desc="Chrome suggests this file name when user chooses to export their passwords saved with Chrome."> Chrome Passwords </message> + <message name="IDS_PASSWORD_MANAGER_PASSWORD_FOR_ACCOUNT" desc="Voice over text read if the user focuses a drop down entry to fill a password for a given account."> + Password for <ph name="username">$1<ex>chef@google.com</ex></ph> + </message> </grit-part>
diff --git a/components/password_manager_strings_grdp/IDS_PASSWORD_MANAGER_PASSWORD_FOR_ACCOUNT.png.sha1 b/components/password_manager_strings_grdp/IDS_PASSWORD_MANAGER_PASSWORD_FOR_ACCOUNT.png.sha1 new file mode 100644 index 0000000..661cafd --- /dev/null +++ b/components/password_manager_strings_grdp/IDS_PASSWORD_MANAGER_PASSWORD_FOR_ACCOUNT.png.sha1
@@ -0,0 +1 @@ +84e591dd00200eac4f46e43493a13039be622434 \ No newline at end of file
diff --git a/components/plugins/renderer/webview_plugin.cc b/components/plugins/renderer/webview_plugin.cc index b87c2b1..94d9fa4 100644 --- a/components/plugins/renderer/webview_plugin.cc +++ b/components/plugins/renderer/webview_plugin.cc
@@ -438,7 +438,6 @@ // The delegate may instantiate a new plugin. delegate_->OnUnobscuredRectUpdate(gfx::Rect(unobscured_rect)); // The delegate may have dirtied style and layout of the WebView. - // See for example the resizePoster function in plugin_poster.html. // Run the lifecycle now so that it is clean. DCHECK(web_view()->MainFrameWidget()); web_view()->MainFrameWidget()->UpdateAllLifecyclePhases(
diff --git a/components/policy/core/common/preg_parser.cc b/components/policy/core/common/preg_parser.cc index 8b8e1d188..bde1934 100644 --- a/components/policy/core/common/preg_parser.cc +++ b/components/policy/core/common/preg_parser.cc
@@ -159,14 +159,14 @@ // Decodes a value from a PReg file given as a uint8_t vector. bool DecodePRegValue(uint32_t type, const std::vector<uint8_t>& data, - std::unique_ptr<base::Value>* value) { + base::Value& value) { std::string data_utf8; switch (type) { case REG_SZ: case REG_EXPAND_SZ: if (!DecodePRegStringValue(data, &data_utf8)) return false; - *value = std::make_unique<base::Value>(data_utf8); + value = base::Value(data_utf8); return true; case REG_DWORD_LITTLE_ENDIAN: case REG_DWORD_BIG_ENDIAN: @@ -176,7 +176,7 @@ val = base::NetToHost32(val); else val = base::ByteSwapToLE32(val); - *value = std::make_unique<base::Value>(static_cast<int>(val)); + value = base::Value(static_cast<int>(val)); return true; } else { LOG(ERROR) << "Bad data size " << data.size(); @@ -250,9 +250,9 @@ std::string value_name(base::UTF16ToUTF8(value)); if (!base::StartsWith(value_name, kActionTriggerPrefix, base::CompareCase::SENSITIVE)) { - std::unique_ptr<base::Value> value_ptr; - if (DecodePRegValue(type, data, &value_ptr)) - dict->SetValue(value_name, std::move(value_ptr)); + base::Value value; + if (DecodePRegValue(type, data, value)) + dict->SetValue(value_name, std::move(value)); return; }
diff --git a/components/policy/core/common/preg_parser_unittest.cc b/components/policy/core/common/preg_parser_unittest.cc index f950a5f8..3e75265 100644 --- a/components/policy/core/common/preg_parser_unittest.cc +++ b/components/policy/core/common/preg_parser_unittest.cc
@@ -58,33 +58,33 @@ for (; iter_value_a != a.values().end() && iter_value_b != b.values().end(); ++iter_value_a, ++iter_value_b) { if (iter_value_a->first != iter_value_b->first || - *iter_value_a->second != *iter_value_b->second) { + iter_value_a->second != iter_value_b->second) { return testing::AssertionFailure() << "Value mismatch " << iter_value_a->first << "=" - << *iter_value_a->second << " vs. " << iter_value_b->first << "=" - << *iter_value_b->second; + << iter_value_a->second << " vs. " << iter_value_b->first << "=" + << iter_value_b->second; } } if (iter_value_a != a.values().end()) return testing::AssertionFailure() << "Value mismatch, a has extra value " << iter_value_a->first << "=" - << *iter_value_a->second; + << iter_value_a->second; if (iter_value_b != b.values().end()) return testing::AssertionFailure() << "Value mismatch, b has extra value " << iter_value_b->first << "=" - << *iter_value_b->second; + << iter_value_b->second; return testing::AssertionSuccess(); } void SetInteger(RegistryDict* dict, const std::string& name, int value) { - dict->SetValue(name, base::WrapUnique<base::Value>(new base::Value(value))); + dict->SetValue(name, base::Value(value)); } void SetString(RegistryDict* dict, const std::string& name, const std::string& value) { - dict->SetValue(name, base::WrapUnique<base::Value>(new base::Value(value))); + dict->SetValue(name, base::Value(value)); } class PRegParserTest : public testing::Test {
diff --git a/components/policy/core/common/registry_dict.cc b/components/policy/core/common/registry_dict.cc index 329e1ca9..5f56191 100644 --- a/components/policy/core/common/registry_dict.cc +++ b/components/policy/core/common/registry_dict.cc
@@ -15,6 +15,7 @@ #include "base/sys_byteorder.h" #include "base/values.h" #include "components/policy/core/common/schema.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #if defined(OS_WIN) #include "base/win/registry.h" @@ -188,27 +189,20 @@ base::Value* RegistryDict::GetValue(const std::string& name) { auto entry = values_.find(name); - return entry != values_.end() ? entry->second.get() : nullptr; + return entry != values_.end() ? &entry->second : nullptr; } const base::Value* RegistryDict::GetValue(const std::string& name) const { auto entry = values_.find(name); - return entry != values_.end() ? entry->second.get() : nullptr; + return entry != values_.end() ? &entry->second : nullptr; } -void RegistryDict::SetValue(const std::string& name, - std::unique_ptr<base::Value> dict) { - if (!dict) { - RemoveValue(name); - return; - } - +void RegistryDict::SetValue(const std::string& name, base::Value&& dict) { values_[name] = std::move(dict); } -std::unique_ptr<base::Value> RegistryDict::RemoveValue( - const std::string& name) { - std::unique_ptr<base::Value> result; +absl::optional<base::Value> RegistryDict::RemoveValue(const std::string& name) { + absl::optional<base::Value> result; auto entry = values_.find(name); if (entry != values_.end()) { result = std::move(entry->second); @@ -231,8 +225,7 @@ for (auto entry(other.values_.begin()); entry != other.values_.end(); ++entry) { - SetValue(entry->first, - base::Value::ToUniquePtrValue(entry->second->Clone())); + SetValue(entry->first, entry->second.Clone()); } } @@ -252,8 +245,7 @@ switch (it.Type()) { case REG_SZ: case REG_EXPAND_SZ: - SetValue(name, - std::make_unique<base::Value>(base::WideToUTF8(it.Value()))); + SetValue(name, base::Value(base::WideToUTF8(it.Value()))); continue; case REG_DWORD_LITTLE_ENDIAN: case REG_DWORD_BIG_ENDIAN: @@ -263,8 +255,7 @@ dword_value = base::NetToHost32(dword_value); else dword_value = base::ByteSwapToLE32(dword_value); - SetValue(name, std::make_unique<base::Value>( - static_cast<int>(dword_value))); + SetValue(name, base::Value(static_cast<int>(dword_value))); continue; } FALLTHROUGH; @@ -310,7 +301,7 @@ matching_schemas.push_back(Schema()); for (const Schema& subschema : matching_schemas) { absl::optional<base::Value> converted = - ConvertRegistryValue(*entry->second, subschema); + ConvertRegistryValue(entry->second, subschema); if (converted.has_value()) { result->SetKey(entry->first, std::move(converted.value())); break; @@ -353,7 +344,7 @@ if (!IsKeyNumerical(entry->first)) continue; absl::optional<base::Value> converted = - ConvertRegistryValue(*entry->second, item_schema); + ConvertRegistryValue(entry->second, item_schema); if (converted.has_value()) result->Append(std::move(converted.value())); }
diff --git a/components/policy/core/common/registry_dict.h b/components/policy/core/common/registry_dict.h index 7bbd392c..82742791 100644 --- a/components/policy/core/common/registry_dict.h +++ b/components/policy/core/common/registry_dict.h
@@ -44,9 +44,8 @@ using KeyMap = std::map<std::string, std::unique_ptr<RegistryDict>, CaseInsensitiveStringCompare>; - using ValueMap = std::map<std::string, - std::unique_ptr<base::Value>, - CaseInsensitiveStringCompare>; + using ValueMap = + std::map<std::string, base::Value, CaseInsensitiveStringCompare>; RegistryDict(); RegistryDict(const RegistryDict&) = delete; @@ -66,10 +65,10 @@ // Returns a pointer to a value, NULL if not present. base::Value* GetValue(const std::string& name); const base::Value* GetValue(const std::string& name) const; - // Sets a value. If |value| is NULL, removes the value. - void SetValue(const std::string& name, std::unique_ptr<base::Value> value); - // Removes a value. If the value doesn't exist, NULL is returned. - std::unique_ptr<base::Value> RemoveValue(const std::string& name); + // Sets a value. + void SetValue(const std::string& name, base::Value&& value); + // Removes a value. If the value doesn't exist, nullopt is returned. + absl::optional<base::Value> RemoveValue(const std::string& name); // Clears all values. void ClearValues();
diff --git a/components/policy/core/common/registry_dict_unittest.cc b/components/policy/core/common/registry_dict_unittest.cc index aa2ad40..bce87239 100644 --- a/components/policy/core/common/registry_dict_unittest.cc +++ b/components/policy/core/common/registry_dict_unittest.cc
@@ -9,6 +9,7 @@ #include <utility> #include "base/values.h" +#include "build/build_config.h" #include "components/policy/core/common/schema.h" #include "testing/gtest/include/gtest/gtest.h" @@ -21,19 +22,20 @@ base::Value int_value(42); base::Value string_value("fortytwo"); - test_dict.SetValue("one", int_value.CreateDeepCopy()); + test_dict.SetValue("one", int_value.Clone()); EXPECT_EQ(1u, test_dict.values().size()); EXPECT_EQ(int_value, *test_dict.GetValue("one")); EXPECT_FALSE(test_dict.GetValue("two")); - test_dict.SetValue("two", string_value.CreateDeepCopy()); + test_dict.SetValue("two", string_value.Clone()); EXPECT_EQ(2u, test_dict.values().size()); EXPECT_EQ(int_value, *test_dict.GetValue("one")); EXPECT_EQ(string_value, *test_dict.GetValue("two")); - std::unique_ptr<base::Value> one(test_dict.RemoveValue("one")); + absl::optional<base::Value> one(test_dict.RemoveValue("one")); + ASSERT_TRUE(one.has_value()); EXPECT_EQ(1u, test_dict.values().size()); - EXPECT_EQ(int_value, *one); + EXPECT_EQ(int_value, one.value()); EXPECT_FALSE(test_dict.GetValue("one")); EXPECT_EQ(string_value, *test_dict.GetValue("two")); @@ -49,7 +51,7 @@ base::Value int_value(42); base::Value string_value("fortytwo"); - test_dict.SetValue("One", int_value.CreateDeepCopy()); + test_dict.SetValue("One", int_value.Clone()); EXPECT_EQ(1u, test_dict.values().size()); EXPECT_EQ(int_value, *test_dict.GetValue("oNe")); @@ -57,12 +59,13 @@ ASSERT_NE(entry, test_dict.values().end()); EXPECT_EQ("One", entry->first); - test_dict.SetValue("ONE", string_value.CreateDeepCopy()); + test_dict.SetValue("ONE", string_value.Clone()); EXPECT_EQ(1u, test_dict.values().size()); EXPECT_EQ(string_value, *test_dict.GetValue("one")); - std::unique_ptr<base::Value> removed_value(test_dict.RemoveValue("onE")); - EXPECT_EQ(string_value, *removed_value); + absl::optional<base::Value> removed_value(test_dict.RemoveValue("onE")); + ASSERT_TRUE(removed_value.has_value()); + EXPECT_EQ(string_value, removed_value.value()); EXPECT_TRUE(test_dict.values().empty()); } @@ -73,7 +76,7 @@ base::Value string_value("fortytwo"); std::unique_ptr<RegistryDict> subdict(new RegistryDict()); - subdict->SetValue("one", int_value.CreateDeepCopy()); + subdict->SetValue("one", int_value.Clone()); test_dict.SetKey("two", std::move(subdict)); EXPECT_EQ(1u, test_dict.keys().size()); RegistryDict* actual_subdict = test_dict.GetKey("two"); @@ -81,7 +84,7 @@ EXPECT_EQ(int_value, *actual_subdict->GetValue("one")); subdict = std::make_unique<RegistryDict>(); - subdict->SetValue("three", string_value.CreateDeepCopy()); + subdict->SetValue("three", string_value.Clone()); test_dict.SetKey("four", std::move(subdict)); EXPECT_EQ(2u, test_dict.keys().size()); actual_subdict = test_dict.GetKey("two"); @@ -113,7 +116,7 @@ EXPECT_EQ("One", entry->first); std::unique_ptr<RegistryDict> subdict(new RegistryDict()); - subdict->SetValue("two", int_value.CreateDeepCopy()); + subdict->SetValue("two", int_value.Clone()); test_dict.SetKey("ONE", std::move(subdict)); EXPECT_EQ(1u, test_dict.keys().size()); actual_subdict = test_dict.GetKey("One"); @@ -133,17 +136,17 @@ base::Value int_value(42); base::Value string_value("fortytwo"); - dict_a.SetValue("one", int_value.CreateDeepCopy()); + dict_a.SetValue("one", int_value.Clone()); std::unique_ptr<RegistryDict> subdict(new RegistryDict()); - subdict->SetValue("two", string_value.CreateDeepCopy()); + subdict->SetValue("two", string_value.Clone()); dict_a.SetKey("three", std::move(subdict)); - dict_b.SetValue("four", string_value.CreateDeepCopy()); + dict_b.SetValue("four", string_value.Clone()); subdict = std::make_unique<RegistryDict>(); - subdict->SetValue("two", int_value.CreateDeepCopy()); + subdict->SetValue("two", int_value.Clone()); dict_b.SetKey("three", std::move(subdict)); subdict = std::make_unique<RegistryDict>(); - subdict->SetValue("five", int_value.CreateDeepCopy()); + subdict->SetValue("five", int_value.Clone()); dict_b.SetKey("six", std::move(subdict)); dict_a.Merge(dict_b); @@ -165,9 +168,9 @@ base::Value int_value(42); base::Value string_value("fortytwo"); - dict_a.SetValue("one", int_value.CreateDeepCopy()); + dict_a.SetValue("one", int_value.Clone()); dict_a.SetKey("two", std::make_unique<RegistryDict>()); - dict_b.SetValue("three", string_value.CreateDeepCopy()); + dict_b.SetValue("three", string_value.Clone()); dict_a.Swap(&dict_b); @@ -189,19 +192,19 @@ base::Value string_zero("0"); base::Value string_dict("{ \"key\": [ \"value\" ] }"); - test_dict.SetValue("one", int_value.CreateDeepCopy()); + test_dict.SetValue("one", int_value.Clone()); std::unique_ptr<RegistryDict> subdict(new RegistryDict()); - subdict->SetValue("two", string_value.CreateDeepCopy()); + subdict->SetValue("two", string_value.Clone()); test_dict.SetKey("three", std::move(subdict)); std::unique_ptr<RegistryDict> list(new RegistryDict()); - list->SetValue("1", string_value.CreateDeepCopy()); + list->SetValue("1", string_value.Clone()); test_dict.SetKey("dict-to-list", std::move(list)); - test_dict.SetValue("int-to-bool", int_value.CreateDeepCopy()); - test_dict.SetValue("int-to-double", int_value.CreateDeepCopy()); - test_dict.SetValue("string-to-bool", string_zero.CreateDeepCopy()); - test_dict.SetValue("string-to-double", string_zero.CreateDeepCopy()); - test_dict.SetValue("string-to-int", string_zero.CreateDeepCopy()); - test_dict.SetValue("string-to-dict", string_dict.CreateDeepCopy()); + test_dict.SetValue("int-to-bool", int_value.Clone()); + test_dict.SetValue("int-to-double", int_value.Clone()); + test_dict.SetValue("string-to-bool", string_zero.Clone()); + test_dict.SetValue("string-to-double", string_zero.Clone()); + test_dict.SetValue("string-to-int", string_zero.Clone()); + test_dict.SetValue("string-to-dict", string_dict.Clone()); std::string error; Schema schema = Schema::Parse( @@ -251,10 +254,10 @@ RegistryDict test_dict; std::unique_ptr<RegistryDict> list(new RegistryDict()); - list->SetValue("1", base::Value("1").CreateDeepCopy()); - list->SetValue("2", base::Value("2").CreateDeepCopy()); - list->SetValue("THREE", base::Value("3").CreateDeepCopy()); - list->SetValue("4", base::Value("4").CreateDeepCopy()); + list->SetValue("1", base::Value("1").Clone()); + list->SetValue("2", base::Value("2").Clone()); + list->SetValue("THREE", base::Value("3").Clone()); + list->SetValue("4", base::Value("4").Clone()); test_dict.SetKey("dict-to-list", std::move(list)); std::string error; @@ -275,9 +278,9 @@ base::DictionaryValue expected; std::unique_ptr<base::ListValue> expected_list(new base::ListValue()); - expected_list->Append(base::Value("1").CreateDeepCopy()); - expected_list->Append(base::Value("2").CreateDeepCopy()); - expected_list->Append(base::Value("4").CreateDeepCopy()); + expected_list->Append(base::Value("1").Clone()); + expected_list->Append(base::Value("2").Clone()); + expected_list->Append(base::Value("4").Clone()); expected.Set("dict-to-list", std::move(expected_list)); EXPECT_EQ(expected, *actual); @@ -292,15 +295,14 @@ std::unique_ptr<RegistryDict> policy_dict(new RegistryDict()); std::unique_ptr<RegistryDict> subdict_id(new RegistryDict()); // Values with schema are parsed even if the schema is a regexp property. - subdict_id->SetValue("runtime_blocked_hosts", string_dict.CreateDeepCopy()); - subdict_id->SetValue("runtime_allowed_hosts", string_dict.CreateDeepCopy()); + subdict_id->SetValue("runtime_blocked_hosts", string_dict.Clone()); + subdict_id->SetValue("runtime_allowed_hosts", string_dict.Clone()); // Regexp. validated properties are valid too. - subdict_id->SetValue("minimum_version_required", - version_string.CreateDeepCopy()); + subdict_id->SetValue("minimum_version_required", version_string.Clone()); policy_dict->SetKey("aaaabbbbaaaabbbbaaaabbbbaaaabbbb", std::move(subdict_id)); // Values that have no schema are left as strings regardless of structure. - policy_dict->SetValue("invalid_key", string_dict.CreateDeepCopy()); + policy_dict->SetValue("invalid_key", string_dict.Clone()); test_dict.SetKey("ExtensionSettings", std::move(policy_dict)); std::string error; @@ -346,12 +348,15 @@ list_value->Append("*://*.google.com"); std::unique_ptr<base::DictionaryValue> restrictions_properties( new base::DictionaryValue()); - restrictions_properties->Set("runtime_blocked_hosts", - list_value->CreateDeepCopy()); - restrictions_properties->Set("runtime_allowed_hosts", - list_value->CreateDeepCopy()); - restrictions_properties->Set("minimum_version_required", - version_string.CreateDeepCopy()); + restrictions_properties->Set( + "runtime_blocked_hosts", + base::Value::ToUniquePtrValue(list_value->Clone())); + restrictions_properties->Set( + "runtime_allowed_hosts", + base::Value::ToUniquePtrValue(list_value->Clone())); + restrictions_properties->Set( + "minimum_version_required", + base::Value::ToUniquePtrValue(version_string.Clone())); expected_extension_settings->Set("aaaabbbbaaaabbbbaaaabbbbaaaabbbb", std::move(restrictions_properties)); expected_extension_settings->Set( @@ -370,9 +375,9 @@ base::Value int_value(42); base::Value string_value("fortytwo"); - test_dict.SetValue("one", int_value.CreateDeepCopy()); + test_dict.SetValue("one", int_value.Clone()); std::unique_ptr<RegistryDict> subdict(new RegistryDict()); - subdict->SetValue("two", string_value.CreateDeepCopy()); + subdict->SetValue("two", string_value.Clone()); test_dict.SetKey("one", std::move(subdict)); EXPECT_EQ(int_value, *test_dict.GetValue("one"));
diff --git a/components/site_engagement/content/site_engagement_service.cc b/components/site_engagement/content/site_engagement_service.cc index bb19a13..0f62e5e 100644 --- a/components/site_engagement/content/site_engagement_service.cc +++ b/components/site_engagement/content/site_engagement_service.cc
@@ -14,6 +14,7 @@ #include "base/metrics/field_trial.h" #include "base/strings/string_util.h" #include "base/task/thread_pool.h" +#include "base/threading/thread_restrictions.h" #include "base/time/clock.h" #include "base/time/default_clock.h" #include "base/time/time.h" @@ -220,6 +221,7 @@ base::Time now, scoped_refptr<HostContentSettingsMap> map) { StoppedClock clock(now); + base::AssertLongCPUWorkAllowed(); return GetAllDetailsImpl(browsing_data::TimePeriod::ALL_TIME, &clock, map.get()); } @@ -255,7 +257,6 @@ const { if (IsLastEngagementStale()) CleanupEngagementScores(true); - return GetAllDetailsImpl( browsing_data::TimePeriod::ALL_TIME, clock_, permissions::PermissionsClient::Get()->GetSettingsMap(browser_context_));
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc index 4fbea6e..da0221a 100644 --- a/components/viz/service/display/skia_renderer.cc +++ b/components/viz/service/display/skia_renderer.cc
@@ -2173,7 +2173,7 @@ quad_alpha = 1.f; DCHECK(cf); } - paint.setColorFilter(std::move(cf)); + paint.setColorFilter(cf->makeComposed(paint.refColorFilter())); } if (needs_color_conversion_filter) {
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc index a95a948..da9b85e8 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc +++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
@@ -676,18 +676,18 @@ const FrameSinkId& root_frame_sink_id) { auto it = root_sink_map_.find(root_frame_sink_id); - DCHECK(it != root_sink_map_.end()); - DCHECK(cached_back_buffers_.find(cache_id) == cached_back_buffers_.end()); + // If creating RootCompositorFrameSinkImpl failed there might not be an entry + // in |root_sink_map_|. + if (it == root_sink_map_.end()) + return; + DCHECK(!base::Contains(cached_back_buffers_, cache_id)); cached_back_buffers_[cache_id] = it->second->GetCacheBackBufferCb(); } void FrameSinkManagerImpl::EvictBackBuffer(uint32_t cache_id, EvictBackBufferCallback callback) { - auto it = cached_back_buffers_.find(cache_id); - DCHECK(it != cached_back_buffers_.end()); - - cached_back_buffers_.erase(it); + cached_back_buffers_.erase(cache_id); std::move(callback).Run(); }
diff --git a/content/browser/attribution_reporting/attribution_storage_sql.cc b/content/browser/attribution_reporting/attribution_storage_sql.cc index 75f264cf..7ebd654 100644 --- a/content/browser/attribution_reporting/attribution_storage_sql.cc +++ b/content/browser/attribution_reporting/attribution_storage_sql.cc
@@ -1422,8 +1422,7 @@ } } - if (InitializeSchema(db_init_status_ == DbStatus::kDeferringCreation) == - false) { + if (!InitializeSchema(db_init_status_ == DbStatus::kDeferringCreation)) { HandleInitializationFailure(InitStatus::kFailedToInitializeSchema); return false; } @@ -1452,19 +1451,16 @@ if (current_version == kCurrentVersionNumber) return true; - if (current_version <= kDeprecatedVersionNumber) { + // Recreate the DB if the version is deprecated or too new. In the latter + // case, the DB will never work until Chrome is re-upgraded. Assume the user + // will continue using this Chrome version and raze the DB to get attribution + // reporting working. + if (current_version <= kDeprecatedVersionNumber || + meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) { // Note that this also razes the meta table, so it will need to be // initialized again. db_->Raze(); - return CreateSchema(); - } - - if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) { - // In this case the database version is too new to be used. The DB will - // never work until Chrome is re-upgraded. Assume the user will continue - // using this Chrome version and raze the DB to get attribution reporting - // working. - db_->Raze(); + meta_table_.Reset(); return CreateSchema(); } @@ -1474,6 +1470,11 @@ bool AttributionStorageSql::CreateSchema() { base::ThreadTicks start_timestamp = base::ThreadTicks::Now(); + + sql::Transaction transaction(db_.get()); + if (!transaction.Begin()) + return false; + // TODO(johnidel, csharrison): Many sources will share a target origin and // a reporting origin, so it makes sense to make a "shared string" table for // these to save disk / memory. However, this complicates the schema a lot, so @@ -1619,6 +1620,9 @@ return false; } + if (!transaction.Commit()) + return false; + base::UmaHistogramMediumTimes("Conversions.Storage.CreationTime", base::ThreadTicks::Now() - start_timestamp); return true;
diff --git a/content/browser/attribution_reporting/attribution_storage_sql_unittest.cc b/content/browser/attribution_reporting/attribution_storage_sql_unittest.cc index 8afb233..f5d4589 100644 --- a/content/browser/attribution_reporting/attribution_storage_sql_unittest.cc +++ b/content/browser/attribution_reporting/attribution_storage_sql_unittest.cc
@@ -20,6 +20,7 @@ #include "content/browser/attribution_reporting/storable_source.h" #include "content/browser/attribution_reporting/storable_trigger.h" #include "sql/database.h" +#include "sql/meta_table.h" #include "sql/test/scoped_error_expecter.h" #include "sql/test/test_helpers.h" #include "testing/gtest/include/gtest/gtest.h" @@ -187,6 +188,29 @@ EXPECT_TRUE(expecter.SawExpectedErrors()); } +TEST_F(AttributionStorageSqlTest, VersionTooNew_RazesDB) { + OpenDatabase(); + AddReportToStorage(); + ASSERT_THAT(storage()->GetAttributionsToReport(clock()->Now()), SizeIs(1)); + CloseDatabase(); + + { + sql::Database raw_db; + EXPECT_TRUE(raw_db.Open(db_path())); + + sql::MetaTable meta; + // The values here are irrelevant, as the meta table already exists. + ASSERT_TRUE(meta.Init(&raw_db, /*version=*/1, /*compatible_version=*/1)); + + meta.SetVersionNumber(meta.GetVersionNumber() + 1); + meta.SetCompatibleVersionNumber(meta.GetCompatibleVersionNumber() + 1); + } + + // The DB should be razed because the version is too new. + ASSERT_NO_FATAL_FAILURE(OpenDatabase()); + ASSERT_THAT(storage()->GetAttributionsToReport(clock()->Now()), IsEmpty()); +} + // Create an impression with two conversions (C1 and C2). Craft a query that // will target C2, which will in turn delete the impression. We should ensure // that C1 is properly deleted (conversions should not be stored unattributed).
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc index 6ed02d4..1ccb50d5 100644 --- a/content/browser/loader/navigation_url_loader_impl.cc +++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -670,7 +670,7 @@ request_info_->sandbox_flags, static_cast<ui::PageTransition>(resource_request_->transition_type), resource_request_->has_user_gesture, initiating_origin, - &loader_factory); + initiator_document_.AsRenderFrameHostIfValid(), &loader_factory); if (loader_factory) { factory = base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>( @@ -1194,6 +1194,7 @@ url_(request_info_->common_params->url), frame_tree_node_id_(request_info_->frame_tree_node_id), global_request_id_(GlobalRequestID::MakeBrowserInitiated()), + initiator_document_(request_info_->initiator_document), web_contents_getter_( base::BindRepeating(&WebContents::FromFrameTreeNodeId, frame_tree_node_id_)),
diff --git a/content/browser/loader/navigation_url_loader_impl.h b/content/browser/loader/navigation_url_loader_impl.h index 8334abb..3d75a59e 100644 --- a/content/browser/loader/navigation_url_loader_impl.h +++ b/content/browser/loader/navigation_url_loader_impl.h
@@ -15,6 +15,7 @@ #include "content/public/browser/content_browser_client.h" #include "content/public/browser/global_request_id.h" #include "content/public/browser/ssl_status.h" +#include "content/public/browser/weak_document_ptr.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "net/url_request/url_request.h" @@ -230,6 +231,7 @@ const int frame_tree_node_id_; const GlobalRequestID global_request_id_; + const WeakDocumentPtr initiator_document_; net::RedirectInfo redirect_info_; int redirect_limit_ = net::URLRequest::kMaxRedirects; base::RepeatingCallback<WebContents*()> web_contents_getter_;
diff --git a/content/browser/loader/navigation_url_loader_impl_unittest.cc b/content/browser/loader/navigation_url_loader_impl_unittest.cc index 6e859b1..46bbcdc 100644 --- a/content/browser/loader/navigation_url_loader_impl_unittest.cc +++ b/content/browser/loader/navigation_url_loader_impl_unittest.cc
@@ -228,7 +228,8 @@ net::HttpRequestHeaders() /* cors_exempt_headers */, nullptr /* client_security_state */, absl::nullopt /* devtools_accepted_stream_types */, - false /* is_pdf */)); + false /* is_pdf */, + content::WeakDocumentPtr() /* initiator_document */)); std::vector<std::unique_ptr<NavigationLoaderInterceptor>> interceptors; most_recent_resource_request_ = absl::nullopt; interceptors.push_back(std::make_unique<TestNavigationLoaderInterceptor>(
diff --git a/content/browser/loader/navigation_url_loader_unittest.cc b/content/browser/loader/navigation_url_loader_unittest.cc index bb9ca5fb..a971c73 100644 --- a/content/browser/loader/navigation_url_loader_unittest.cc +++ b/content/browser/loader/navigation_url_loader_unittest.cc
@@ -100,7 +100,8 @@ net::HttpRequestHeaders() /* cors_exempt_headers */, nullptr /* client_security_state */, absl::nullopt /* devtools_accepted_stream_types */, - false /* is_pdf */)); + false /* is_pdf */, + content::WeakDocumentPtr() /* initiator_document */)); return NavigationURLLoader::Create( browser_context_.get(), storage_partition, std::move(request_info), nullptr, nullptr, nullptr, delegate,
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc index 7efec132..5ba43e5 100644 --- a/content/browser/renderer_host/navigation_request.cc +++ b/content/browser/renderer_host/navigation_request.cc
@@ -97,6 +97,7 @@ #include "content/public/browser/render_view_host.h" #include "content/public/browser/site_isolation_policy.h" #include "content/public/browser/storage_partition.h" +#include "content/public/browser/weak_document_ptr.h" #include "content/public/common/child_process_host.h" #include "content/public/common/content_client.h" #include "content/public/common/content_features.h" @@ -1436,10 +1437,8 @@ if (GetInitiatorFrameToken().has_value()) { RenderFrameHostImpl* initiator_rfh = RenderFrameHostImpl::FromFrameToken( GetInitiatorProcessID(), GetInitiatorFrameToken().value()); - if (initiator_rfh) { - initiator_commit_navigation_sent_counter_ = - initiator_rfh->commit_navigation_sent_counter(); - } + if (initiator_rfh) + initiator_document_ = initiator_rfh->GetWeakDocumentPtr(); } policy_container_navigation_bundle_.emplace( @@ -3926,7 +3925,7 @@ devtools_navigation_token(), frame_tree_node_->devtools_frame_token(), OriginPolicyThrottle::ShouldRequestOriginPolicy(common_params_->url), std::move(cors_exempt_headers), std::move(client_security_state), - devtools_accepted_stream_types, is_pdf_), + devtools_accepted_stream_types, is_pdf_, initiator_document_), std::move(navigation_ui_data), service_worker_handle_.get(), std::move(prefetched_signed_exchange_cache_), this, loader_type, CreateCookieAccessObserver(), @@ -6859,24 +6858,8 @@ } RenderFrameHostImpl* NavigationRequest::GetInitiatorDocumentRenderFrameHost() { - if (!initiator_frame_token_.has_value()) { - return nullptr; - } - - RenderFrameHostImpl* initiator_render_frame_host = - RenderFrameHostImpl::FromFrameToken(initiator_process_id_, - *initiator_frame_token_); - - if (!initiator_render_frame_host || - initiator_render_frame_host->commit_navigation_sent_counter() != - initiator_commit_navigation_sent_counter_) { - // Either the initiator RFH has been destroyed, or the initiator document - // within that RFH has navigated away since the navigation started. In any - // case the initiator document is no longer available. - return nullptr; - } - - return initiator_render_frame_host; + return static_cast<RenderFrameHostImpl*>( + initiator_document_.AsRenderFrameHostIfValid()); } void NavigationRequest::RecordAddressSpaceFeature() { @@ -7261,6 +7244,14 @@ ->GetWebExposedIsolationInfo(); } + // This accommodates for web tests that use COOP. They expect an about:blank + // page to stay in process, and hang otherwise. In general, it is safe to + // allow about:blank pages to stay in process, since scriptability is limited + // to the BrowsingInstance and all pages with the same web-exposed isolation + // level are trusted. + if (common_params_->url.IsAboutBlank()) + return absl::nullopt; + // If we haven't yet received a definitive network response, it is too early // to guess the isolation state. if (state_ < WILL_PROCESS_RESPONSE)
diff --git a/content/browser/renderer_host/navigation_request.h b/content/browser/renderer_host/navigation_request.h index 042fb6d..266cfa4 100644 --- a/content/browser/renderer_host/navigation_request.h +++ b/content/browser/renderer_host/navigation_request.h
@@ -45,6 +45,7 @@ #include "content/public/browser/peak_gpu_memory_tracker.h" #include "content/public/browser/prerender_trigger_type.h" #include "content/public/browser/render_process_host_observer.h" +#include "content/public/browser/weak_document_ptr.h" #include "mojo/public/cpp/bindings/associated_remote.h" #include "mojo/public/cpp/bindings/pending_associated_remote.h" #include "mojo/public/cpp/bindings/pending_remote.h" @@ -1921,9 +1922,9 @@ // NavigationRequest. std::vector<ConsoleMessage> console_messages_; - // The `commit_navigation_sent_counter` of the initiator RenderFrameHost at - // the time when this NavigationRequest was created. - int initiator_commit_navigation_sent_counter_ = -1; + // The initiator RenderFrameHost, if the same document is present as when this + // NavigationRequest was created. + WeakDocumentPtr initiator_document_; // Indicates that this navigation is for PDF content in a renderer. bool is_pdf_ = false;
diff --git a/content/browser/renderer_host/navigation_request_info.cc b/content/browser/renderer_host/navigation_request_info.cc index 21cd58e..f096bd3 100644 --- a/content/browser/renderer_host/navigation_request_info.cc +++ b/content/browser/renderer_host/navigation_request_info.cc
@@ -4,6 +4,7 @@ #include "content/browser/renderer_host/navigation_request_info.h" +#include "content/public/browser/weak_document_ptr.h" #include "third_party/blink/public/mojom/navigation/navigation_params.mojom.h" namespace content { @@ -27,7 +28,8 @@ network::mojom::ClientSecurityStatePtr client_security_state, const absl::optional<std::vector<net::SourceStream::SourceType>>& devtools_accepted_stream_types, - bool is_pdf) + bool is_pdf, + WeakDocumentPtr initiator_document) : common_params(std::move(common_params)), begin_params(std::move(begin_params)), sandbox_flags(sandbox_flags), @@ -44,7 +46,8 @@ cors_exempt_headers(std::move(cors_exempt_headers)), client_security_state(std::move(client_security_state)), devtools_accepted_stream_types(devtools_accepted_stream_types), - is_pdf(is_pdf) {} + is_pdf(is_pdf), + initiator_document(std::move(initiator_document)) {} NavigationRequestInfo::~NavigationRequestInfo() {}
diff --git a/content/browser/renderer_host/navigation_request_info.h b/content/browser/renderer_host/navigation_request_info.h index e1a0e82..6635caa 100644 --- a/content/browser/renderer_host/navigation_request_info.h +++ b/content/browser/renderer_host/navigation_request_info.h
@@ -8,6 +8,7 @@ #include "base/memory/ref_counted.h" #include "base/unguessable_token.h" #include "content/common/content_export.h" +#include "content/public/browser/weak_document_ptr.h" #include "content/public/common/referrer.h" #include "net/base/isolation_info.h" #include "net/filter/source_stream.h" @@ -44,7 +45,8 @@ network::mojom::ClientSecurityStatePtr client_security_state, const absl::optional<std::vector<net::SourceStream::SourceType>>& devtools_accepted_stream_types, - bool is_pdf); + bool is_pdf, + WeakDocumentPtr initiator_document); NavigationRequestInfo(const NavigationRequestInfo& other) = delete; ~NavigationRequestInfo(); @@ -113,6 +115,9 @@ // Indicates that this navigation is for PDF content in a renderer. const bool is_pdf; + + // The initiator document, if still available. + const WeakDocumentPtr initiator_document; }; } // namespace content
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index 8d2e57caf..3b3a2ce 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -161,6 +161,7 @@ #include "content/public/browser/content_browser_client.h" #include "content/public/browser/context_menu_params.h" #include "content/public/browser/disallow_activation_reason.h" +#include "content/public/browser/document_ref.h" #include "content/public/browser/document_service_internal.h" #include "content/public/browser/download_manager.h" #include "content/public/browser/global_routing_id.h" @@ -171,6 +172,7 @@ #include "content/public/browser/site_isolation_policy.h" #include "content/public/browser/sms_fetcher.h" #include "content/public/browser/storage_partition.h" +#include "content/public/browser/weak_document_ptr.h" #include "content/public/browser/web_ui_url_loader_factory.h" #include "content/public/common/bindings_policy.h" #include "content/public/common/content_client.h" @@ -2150,6 +2152,15 @@ return is_error_page_; } +DocumentRef RenderFrameHostImpl::GetDocumentRef() { + return DocumentRef(document_associated_data_->weak_ptr_factory.GetSafeRef()); +} + +WeakDocumentPtr RenderFrameHostImpl::GetWeakDocumentPtr() { + return WeakDocumentPtr( + document_associated_data_->weak_ptr_factory.GetWeakPtr()); +} + void RenderFrameHostImpl::GetSerializedHtmlWithLocalLinks( const base::flat_map<GURL, base::FilePath>& url_map, const base::flat_map<blink::FrameToken, base::FilePath>& frame_token_map, @@ -12842,7 +12853,8 @@ } RenderFrameHostImpl::DocumentAssociatedData::DocumentAssociatedData( - RenderFrameHostImpl& document) { + RenderFrameHostImpl& document) + : weak_ptr_factory(&document) { // Only create page object for the main document as the PageImpl is 1:1 with // main document. if (!document.GetParent()) {
diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h index 0a2fe1a..caa81fe3 100644 --- a/content/browser/renderer_host/render_frame_host_impl.h +++ b/content/browser/renderer_host/render_frame_host_impl.h
@@ -448,6 +448,8 @@ void GetCanonicalUrl( base::OnceCallback<void(const absl::optional<GURL>&)> callback) override; bool IsErrorDocument() override; + DocumentRef GetDocumentRef() override; + WeakDocumentPtr GetWeakDocumentPtr() override; // Additional non-override const version of GetMainFrame. const RenderFrameHostImpl* GetMainFrame() const; @@ -3984,6 +3986,11 @@ // "Owned" but not with std::unique_ptr, as a DocumentServiceBase is // allowed to delete itself directly. std::vector<internal::DocumentServiceBase*> services; + + // Produces weak pointers to the hosting RenderFrameHostImpl. This is + // invalidated whenever DocumentAssociatedData is destroyed, due to + // RenderFrameHost deletion or cross-document navigation. + base::WeakPtrFactory<RenderFrameHostImpl> weak_ptr_factory; }; // Reset immediately before a RenderFrameHost is reused for hosting a new
diff --git a/content/browser/renderer_host/render_frame_host_manager.cc b/content/browser/renderer_host/render_frame_host_manager.cc index e3eaa7a..8f983a68 100644 --- a/content/browser/renderer_host/render_frame_host_manager.cc +++ b/content/browser/renderer_host/render_frame_host_manager.cc
@@ -176,14 +176,6 @@ bool IsSiteInstanceCompatibleWithWebExposedIsolation( SiteInstance* site_instance, const UrlInfo& url_info) { - // Note: The about blank case is to accommodate web tests that use COOP. They - // expect an about:blank page to stay in process, and hang otherwise. In - // general, it is safe to allow about:blank pages to stay in process, since - // scriptability is limited to the BrowsingInstance and all pages with the - // same web-exposed isolation level are trusted. - if (url_info.url.IsAboutBlank()) - return true; - SiteInstanceImpl* site_instance_impl = static_cast<SiteInstanceImpl*>(site_instance);
diff --git a/content/browser/web_package/web_bundle_element_browsertest.cc b/content/browser/web_package/web_bundle_element_browsertest.cc index 6799f684..df9493d 100644 --- a/content/browser/web_package/web_bundle_element_browsertest.cc +++ b/content/browser/web_package/web_bundle_element_browsertest.cc
@@ -54,6 +54,7 @@ ui::PageTransition page_transition, bool has_user_gesture, const absl::optional<url::Origin>& initiating_origin, + content::RenderFrameHost* initiator_document, mojo::PendingRemote<network::mojom::URLLoaderFactory>* out_factory) override { EXPECT_FALSE(observed_url_.has_value());
diff --git a/content/browser/webid/federated_auth_request_impl.cc b/content/browser/webid/federated_auth_request_impl.cc index 3bd9acf..17efaa66 100644 --- a/content/browser/webid/federated_auth_request_impl.cc +++ b/content/browser/webid/federated_auth_request_impl.cc
@@ -379,6 +379,10 @@ client_id_metadata_ = data; network_manager_->SendAccountsRequest( endpoints_.accounts, + request_dialog_controller_->GetBrandIconIdealSize(), + request_dialog_controller_->GetBrandIconMinimumSize(), + base::BindOnce(&FederatedAuthRequestImpl::DownloadBitmap, + weak_ptr_factory_.GetWeakPtr()), base::BindOnce(&FederatedAuthRequestImpl::OnAccountsResponseReceived, weak_ptr_factory_.GetWeakPtr())); } @@ -521,10 +525,21 @@ CompleteRequest(RequestIdTokenStatus::kSuccess, id_token_); } +void FederatedAuthRequestImpl::DownloadBitmap( + const GURL& icon_url, + int ideal_icon_size, + WebContents::ImageDownloadCallback callback) { + WebContents::FromRenderFrameHost(render_frame_host_) + ->DownloadImage(icon_url, /*is_favicon*/ false, + gfx::Size(ideal_icon_size, ideal_icon_size), + 0 /* max_bitmap_size */, false /* bypass_cache */, + std::move(callback)); +} + void FederatedAuthRequestImpl::OnAccountsResponseReceived( IdpNetworkRequestManager::FetchStatus status, IdpNetworkRequestManager::AccountList accounts, - content::IdentityProviderMetadata idp_metadata) { + IdentityProviderMetadata idp_metadata) { switch (status) { case IdpNetworkRequestManager::FetchStatus::kHttpNotFoundError: { CompleteRequest(RequestIdTokenStatus::kErrorFetchingAccountsHttpNotFound,
diff --git a/content/browser/webid/federated_auth_request_impl.h b/content/browser/webid/federated_auth_request_impl.h index 3d9790bc..36e7586 100644 --- a/content/browser/webid/federated_auth_request_impl.h +++ b/content/browser/webid/federated_auth_request_impl.h
@@ -15,6 +15,7 @@ #include "content/browser/webid/idp_network_request_manager.h" #include "content/common/content_export.h" #include "content/public/browser/identity_request_dialog_controller.h" +#include "content/public/browser/web_contents.h" #include "third_party/blink/public/mojom/webid/federated_auth_request.mojom.h" #include "url/gurl.h" @@ -81,10 +82,14 @@ void OnIdpPageClosed(); void OnTokenProvisionApproved( IdentityRequestDialogController::UserApproval approval); + + void DownloadBitmap(const GURL& icon_url, + int ideal_icon_size, + WebContents::ImageDownloadCallback callback); void OnAccountsResponseReceived( IdpNetworkRequestManager::FetchStatus status, IdpNetworkRequestManager::AccountList accounts, - content::IdentityProviderMetadata idp_metadata); + IdentityProviderMetadata idp_metadata); void OnAccountSelected(const std::string& account_id); void OnTokenResponseReceived(IdpNetworkRequestManager::FetchStatus status, const std::string& id_token);
diff --git a/content/browser/webid/federated_auth_request_impl_unittest.cc b/content/browser/webid/federated_auth_request_impl_unittest.cc index 0087516..c38042f4 100644 --- a/content/browser/webid/federated_auth_request_impl_unittest.cc +++ b/content/browser/webid/federated_auth_request_impl_unittest.cc
@@ -572,9 +572,10 @@ std::string token, bool prefer_auto_sign_in) { if (conf.accounts_response) { - EXPECT_CALL(*mock_request_manager_, SendAccountsRequest(_, _)) + EXPECT_CALL(*mock_request_manager_, SendAccountsRequest(_, _, _, _, _)) .WillOnce(Invoke( - [&](const GURL&, + [&](const GURL&, int, int, + IdpNetworkRequestManager::BrandIconDownloader, IdpNetworkRequestManager::AccountsRequestCallback callback) { std::move(callback).Run(*conf.accounts_response, conf.accounts, IdentityProviderMetadata());
diff --git a/content/browser/webid/idp_network_request_manager.cc b/content/browser/webid/idp_network_request_manager.cc index 03d6c43..b5ed43bb 100644 --- a/content/browser/webid/idp_network_request_manager.cc +++ b/content/browser/webid/idp_network_request_manager.cc
@@ -23,6 +23,8 @@ #include "services/network/public/cpp/simple_url_loader.h" #include "services/network/public/mojom/url_response_head.mojom.h" #include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/blink/public/common/manifest/manifest_icon_selector.h" +#include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/color_utils.h" #include "url/origin.h" @@ -66,6 +68,10 @@ // response size that is a part of this protocol. constexpr int maxResponseSizeInKiB = 1024; +// safe_zone_diameter/icon_size as defined in +// https://www.w3.org/TR/appmanifest/#icon-masks +constexpr float kMaskableWebIconSafeZoneRatio = 0.8f; + net::NetworkTrafficAnnotationTag CreateTrafficAnnotation() { return net::DefineNetworkTrafficAnnotation("fedcm", R"( semantics { @@ -177,7 +183,10 @@ // Parse IdentityProviderMetadata from given value. Overwrites |idp_metadata| // with the parsed value. void ParseIdentityProviderMetadata(const base::Value& idp_metadata_value, - IdentityProviderMetadata& idp_metadata) { + int brand_icon_ideal_size, + int brand_icon_minimum_size, + IdentityProviderMetadata& idp_metadata, + GURL* brand_icon_url) { if (!idp_metadata_value.is_dict()) return; @@ -193,6 +202,37 @@ idp_metadata.brand_text_color = absl::nullopt; } } + + const base::Value* icons_value = idp_metadata_value.FindKey("icons"); + if (icons_value != nullptr && icons_value->is_list()) { + std::vector<blink::Manifest::ImageResource> icons; + for (const base::Value& icon_value : icons_value->GetList()) { + if (!icon_value.is_dict()) + continue; + + const std::string* icon_src = icon_value.FindStringKey("url"); + if (icon_src == nullptr) + continue; + + blink::Manifest::ImageResource icon; + icon.src = GURL(*icon_src); + if (!icon.src.is_valid()) + continue; + + icon.purpose = {blink::mojom::ManifestImageResource_Purpose::MASKABLE}; + + absl::optional<int> icon_size = icon_value.FindIntKey("size"); + int icon_size_int = icon_size ? icon_size.value() : 0; + icon.sizes.emplace_back(icon_size_int, icon_size_int); + + icons.push_back(icon); + } + + *brand_icon_url = blink::ManifestIconSelector::FindBestMatchingSquareIcon( + icons, brand_icon_ideal_size / kMaskableWebIconSafeZoneRatio, + brand_icon_minimum_size / kMaskableWebIconSafeZoneRatio, + blink::mojom::ManifestImageResource_Purpose::MASKABLE); + } } using FetchStatus = content::IdpNetworkRequestManager::FetchStatus; @@ -255,7 +295,9 @@ scoped_refptr<network::SharedURLLoaderFactory> loader_factory) : provider_(provider), relying_party_origin_(relying_party_origin), - loader_factory_(loader_factory) {} + loader_factory_(loader_factory), + idp_brand_icon_ideal_size_(0), + idp_brand_icon_minimum_size_(0) {} IdpNetworkRequestManager::~IdpNetworkRequestManager() = default; @@ -303,10 +345,16 @@ void IdpNetworkRequestManager::SendAccountsRequest( const GURL& accounts_url, + int idp_brand_icon_ideal_size, + int idp_brand_icon_minimum_size, + BrandIconDownloader brand_icon_downloader, AccountsRequestCallback callback) { DCHECK(!url_loader_); DCHECK(!accounts_request_callback_); + idp_brand_icon_ideal_size_ = idp_brand_icon_ideal_size; + idp_brand_icon_minimum_size_ = idp_brand_icon_minimum_size; accounts_request_callback_ = std::move(callback); + brand_icon_downloader_ = std::move(brand_icon_downloader); // Use ReferrerPolicy::NO_REFERRER for this request so that relying party // identity is not exposed to the Identity provider via referrer. @@ -590,9 +638,40 @@ } IdentityProviderMetadata idp_metadata; + GURL idp_icon_url; const base::Value* idp_metadata_value = response.FindKey(kIdpBrandingKey); if (idp_metadata_value) - ParseIdentityProviderMetadata(*idp_metadata_value, idp_metadata); + ParseIdentityProviderMetadata( + *idp_metadata_value, idp_brand_icon_ideal_size_, + idp_brand_icon_minimum_size_, idp_metadata, &idp_icon_url); + + auto on_icon_fetched_callback = base::BindOnce( + &IdpNetworkRequestManager::OnIdentityProviderBrandIconFetched, + weak_ptr_factory_.GetWeakPtr(), std::move(account_list), + std::move(idp_metadata)); + + if (idp_icon_url.is_valid()) { + std::move(brand_icon_downloader_) + .Run(idp_icon_url, idp_brand_icon_ideal_size_, + std::move(on_icon_fetched_callback)); + return; + } + + std::move(on_icon_fetched_callback).Run(0, 404, GURL(), {}, {}); +} + +void IdpNetworkRequestManager::OnIdentityProviderBrandIconFetched( + AccountList account_list, + IdentityProviderMetadata idp_metadata, + int id, + int http_status_code, + const GURL& image_url, + const std::vector<SkBitmap>& bitmaps, + const std::vector<gfx::Size>& sizes) { + if (bitmaps.size() == 1 && bitmaps[0].width() == bitmaps[0].height() && + bitmaps[0].width() >= idp_brand_icon_minimum_size_) { + idp_metadata.brand_icon = bitmaps[0]; + } std::move(accounts_request_callback_) .Run(FetchStatus::kSuccess, std::move(account_list),
diff --git a/content/browser/webid/idp_network_request_manager.h b/content/browser/webid/idp_network_request_manager.h index 7ed622ca..e9a5c15 100644 --- a/content/browser/webid/idp_network_request_manager.h +++ b/content/browser/webid/idp_network_request_manager.h
@@ -12,11 +12,14 @@ #include "base/callback.h" #include "content/common/content_export.h" #include "content/public/browser/identity_request_dialog_controller.h" +#include "content/public/browser/web_contents.h" #include "services/data_decoder/public/cpp/data_decoder.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "url/gurl.h" #include "url/origin.h" +class SkBitmap; + namespace net { enum class ReferrerPolicy; } @@ -104,6 +107,10 @@ static constexpr char kWellKnownFilePath[] = ".well-known/fedcm"; using AccountList = std::vector<content::IdentityRequestAccount>; + using BrandIconDownloader = + base::OnceCallback<void(const GURL& /*icon_url*/, + int /*ideal_icon_size*/, + WebContents::ImageDownloadCallback)>; using FetchWellKnownCallback = base::OnceCallback<void(FetchStatus, Endpoints)>; using FetchClientIdMetadataCallback = @@ -145,7 +152,10 @@ // Fetch accounts list for this user from the IDP. virtual void SendAccountsRequest(const GURL& accounts_url, - AccountsRequestCallback); + int idp_brand_icon_ideal_size, + int idp_brand_icon_minimum_size, + BrandIconDownloader icon_downloader, + AccountsRequestCallback callback); // Request a new token for this user account and RP from the IDP. virtual void SendTokenRequest(const GURL& token_url, @@ -171,6 +181,13 @@ void OnSigninRequestParsed(data_decoder::DataDecoder::ValueOrError result); void OnAccountsRequestResponse(std::unique_ptr<std::string> response_body); void OnAccountsRequestParsed(data_decoder::DataDecoder::ValueOrError result); + void OnIdentityProviderBrandIconFetched(AccountList account_list, + IdentityProviderMetadata idp_metadata, + int id, + int http_status_code, + const GURL& image_url, + const std::vector<SkBitmap>& bitmaps, + const std::vector<gfx::Size>& sizes); void OnTokenRequestResponse(std::unique_ptr<std::string> response_body); void OnTokenRequestParsed(data_decoder::DataDecoder::ValueOrError result); void OnRevokeResponse(std::unique_ptr<std::string> response_body); @@ -198,7 +215,11 @@ RevokeCallback revoke_callback_; LogoutCallback logout_callback_; + int idp_brand_icon_ideal_size_; + int idp_brand_icon_minimum_size_; + std::unique_ptr<network::SimpleURLLoader> url_loader_; + BrandIconDownloader brand_icon_downloader_; base::WeakPtrFactory<IdpNetworkRequestManager> weak_ptr_factory_{this}; };
diff --git a/content/browser/webid/idp_network_request_manager_unittest.cc b/content/browser/webid/idp_network_request_manager_unittest.cc index e5c2639..7aa629c 100644 --- a/content/browser/webid/idp_network_request_manager_unittest.cc +++ b/content/browser/webid/idp_network_request_manager_unittest.cc
@@ -5,16 +5,21 @@ #include "content/browser/webid/idp_network_request_manager.h" #include <array> +#include <map> #include <string> #include <tuple> +#include <utility> #include "base/strings/stringprintf.h" #include "base/test/bind.h" #include "base/test/task_environment.h" #include "base/values.h" +#include "content/public/browser/manifest_icon_downloader.h" #include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #include "services/network/test/test_url_loader_factory.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "ui/gfx/geometry/size.h" #include "url/gurl.h" using AccountList = content::IdpNetworkRequestManager::AccountList; @@ -27,6 +32,10 @@ namespace { +// Values for testing. Real minimum and ideal sizes are different. +const int kTestIdpBrandIconMinimumSize = 16; +const int kTestIdpBrandIconIdealSize = 32; + const char kTestIdpUrl[] = "https://idp.test"; const char kTestRpUrl[] = "https://rp.test"; const char kTestAccountsEndpoint[] = "https://idp.test/accounts_endpoint"; @@ -43,6 +52,10 @@ void TearDown() override { manager_.reset(); } + void SetBitmapSpecsForUrl(const std::string& url, int size, int color) { + bitmap_specs_[GURL(url)] = std::make_pair(size, color); + } + std::tuple<FetchStatus, AccountList, IdentityProviderMetadata> SendAccountsRequestAndWaitForResponse(const char* test_accounts) { GURL accounts_endpoint(kTestAccountsEndpoint); @@ -61,7 +74,12 @@ parsed_idp_metadata = std::move(idp_metadata); run_loop.Quit(); }); - manager().SendAccountsRequest(accounts_endpoint, std::move(callback)); + manager().SendAccountsRequest( + accounts_endpoint, kTestIdpBrandIconIdealSize, + kTestIdpBrandIconMinimumSize, + base::BindOnce(&IdpNetworkRequestManagerTest::DownloadBitmap, + base::Unretained(this)), + std::move(callback)); run_loop.Run(); return {parsed_accounts_response, parsed_accounts, @@ -95,10 +113,31 @@ } private: + void DownloadBitmap(const GURL& url, + int ideal_icon_size, + WebContents::ImageDownloadCallback callback) { + auto bitmap_specs_it = bitmap_specs_.find(url); + CHECK(bitmap_specs_.empty() || bitmap_specs_it != bitmap_specs_.end()); + + SkBitmap bitmap; + if (bitmap_specs_it != bitmap_specs_.end()) { + int bitmap_edge_size = bitmap_specs_it->second.first; + int bitmap_color = bitmap_specs_it->second.second; + + bitmap.allocN32Pixels(bitmap_edge_size, bitmap_edge_size); + bitmap.eraseColor(bitmap_color); + } + + std::move(callback).Run(0, 200, url, {bitmap}, + {gfx::Size(bitmap.width(), bitmap.height())}); + } + base::test::SingleThreadTaskEnvironment task_environment_; network::TestURLLoaderFactory test_url_loader_factory_; std::unique_ptr<IdpNetworkRequestManager> manager_; data_decoder::test::InProcessDataDecoder in_process_data_decoder; + + std::map<GURL, std::pair<int, SkColor>> bitmap_specs_; }; TEST_F(IdpNetworkRequestManagerTest, ParseAccountEmpty) { @@ -456,6 +495,96 @@ EXPECT_EQ(absl::nullopt, idp_metadata.brand_text_color); } +TEST_F(IdpNetworkRequestManagerTest, ParseAccountBrandingSelectBestSize) { + const char test_accounts_json[] = R"({ + "accounts" : [ + { + "sub" : "1234", + "email": "ken@idp.test", + "name": "Ken R. Example" + } + ], + "branding" : { + "icons": [ + { + "url": "https://example.com/10.png", + "size": 10 + }, + { + "url": "https://example.com/16.png", + "size": 16 + }, + { + "url": "https://example.com/39.png", + "size": 39 + }, + { + "url": "https://example.com/40.png", + "size": 40 + }, + { + "url": "https://example.com/41.png", + "size": 41 + } + ] + } + })"; + + ASSERT_EQ(32, kTestIdpBrandIconIdealSize); + // 32 / kMaskableWebIconSafeZoneRatio = 40 + + SetBitmapSpecsForUrl("https://example.com/10.png", 10, SK_ColorBLACK); + SetBitmapSpecsForUrl("https://example.com/16.png", 16, SK_ColorBLACK); + SetBitmapSpecsForUrl("https://example.com/39.png", 39, SK_ColorBLACK); + SetBitmapSpecsForUrl("https://example.com/40.png", 40, SK_ColorBLUE); + SetBitmapSpecsForUrl("https://example.com/41.png", 41, SK_ColorBLACK); + + FetchStatus accounts_response; + AccountList accounts; + IdentityProviderMetadata idp_metadata; + std::tie(accounts_response, accounts, idp_metadata) = + SendAccountsRequestAndWaitForResponse(test_accounts_json); + + EXPECT_EQ(FetchStatus::kSuccess, accounts_response); + EXPECT_FALSE(idp_metadata.brand_icon.isNull()); + EXPECT_EQ(SK_ColorBLUE, idp_metadata.brand_icon.getColor(0, 0)); +} + +TEST_F(IdpNetworkRequestManagerTest, + ParseAccountBrandingIncorrectSizeInMetadata) { + const char test_accounts_json[] = R"({ + "accounts" : [ + { + "sub" : "1234", + "email": "ken@idp.test", + "name": "Ken R. Example" + } + ], + "branding" : { + "icons": [ + { + "url": "https://example.com/icon.png", + "size": 32 + } + ] + } + })"; + + SetBitmapSpecsForUrl("https://example.com/icon.png", 1, SK_ColorBLACK); + + FetchStatus accounts_response; + AccountList accounts; + IdentityProviderMetadata idp_metadata; + std::tie(accounts_response, accounts, idp_metadata) = + SendAccountsRequestAndWaitForResponse(test_accounts_json); + + // Downloaded brand icon should not be used because it is too small. + EXPECT_TRUE(idp_metadata.brand_icon.isNull()); + + // An invalid brand icon should not prevent sign in. + EXPECT_EQ(FetchStatus::kSuccess, accounts_response); +} + // Tests the revoke implementation. TEST_F(IdpNetworkRequestManagerTest, Revoke) { bool called = false;
diff --git a/content/browser/webid/test/mock_idp_network_request_manager.h b/content/browser/webid/test/mock_idp_network_request_manager.h index 80678333..4175d2b 100644 --- a/content/browser/webid/test/mock_idp_network_request_manager.h +++ b/content/browser/webid/test/mock_idp_network_request_manager.h
@@ -28,7 +28,12 @@ FetchClientIdMetadataCallback)); MOCK_METHOD3(SendSigninRequest, void(const GURL&, const std::string&, SigninRequestCallback)); - MOCK_METHOD2(SendAccountsRequest, void(const GURL&, AccountsRequestCallback)); + MOCK_METHOD5(SendAccountsRequest, + void(const GURL&, + int, + int, + BrandIconDownloader, + AccountsRequestCallback)); MOCK_METHOD4(SendTokenRequest, void(const GURL&, const std::string&,
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn index e3fd09e..ad9774a2 100644 --- a/content/public/browser/BUILD.gn +++ b/content/public/browser/BUILD.gn
@@ -139,6 +139,8 @@ "devtools_permission_overrides.h", "devtools_socket_factory.h", "disallow_activation_reason.h", + "document_ref.cc", + "document_ref.h", "document_service.h", "document_service_internal.cc", "document_service_internal.h", @@ -390,6 +392,8 @@ "video_capture_service.h", "visibility.h", "vpn_service_proxy.h", + "weak_document_ptr.cc", + "weak_document_ptr.h", "web_contents.cc", "web_contents.h", "web_contents_delegate.cc",
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index 2054b760..67026e9 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -1009,6 +1009,7 @@ ui::PageTransition page_transition, bool has_user_gesture, const absl::optional<url::Origin>& initiating_origin, + RenderFrameHost* initiator_document, mojo::PendingRemote<network::mojom::URLLoaderFactory>* out_factory) { return true; }
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 55b28433..6fbb03d 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -1803,6 +1803,10 @@ // browser-initiated navigations. The initiating origin is intended to help // users make security decisions about whether to allow an external // application to launch. + // + // |initiator_document| refers to the document that initiated the navigation, + // if it is still available. Use |initiating_origin| instead for security + // decisions. virtual bool HandleExternalProtocol( const GURL& url, base::RepeatingCallback<WebContents*()> web_contents_getter, @@ -1814,6 +1818,7 @@ ui::PageTransition page_transition, bool has_user_gesture, const absl::optional<url::Origin>& initiating_origin, + RenderFrameHost* initiator_document, mojo::PendingRemote<network::mojom::URLLoaderFactory>* out_factory); // Creates an OverlayWindow to be used for Picture-in-Picture. This window
diff --git a/content/public/browser/document_ref.cc b/content/public/browser/document_ref.cc new file mode 100644 index 0000000..03d1d6b8 --- /dev/null +++ b/content/public/browser/document_ref.cc
@@ -0,0 +1,12 @@ +// Copyright 2021 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/public/browser/document_ref.h" + +namespace content { + +DocumentRef::DocumentRef(base::SafeRef<RenderFrameHost> safe_document) + : safe_document_(std::move(safe_document)) {} + +} // namespace content
diff --git a/content/public/browser/document_ref.h b/content/public/browser/document_ref.h new file mode 100644 index 0000000..b55fa998 --- /dev/null +++ b/content/public/browser/document_ref.h
@@ -0,0 +1,62 @@ +// Copyright 2021 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_PUBLIC_BROWSER_DOCUMENT_REF_H_ +#define CONTENT_PUBLIC_BROWSER_DOCUMENT_REF_H_ + +#include "base/memory/safe_ref.h" +#include "base/memory/weak_ptr.h" +#include "content/common/content_export.h" + +namespace content { + +class RenderFrameHost; + +// A non-nullable, checked reference to a document. This will CHECK if it is +// accessed after the document is no longer valid, because the RenderFrameHost +// is deleted or navigatese to a different document. See also +// document_user_data.h. +// +// Note that though this is implemented as a base::SafeRef<RenderFrameHost>, +// it is different from an ordinary SafeRef to the RenderFrameHost. +// +// docs/render_document.md will make these equivalent in the future. +// +// If the document may become invalid, use a WeakDocumentPtr instead. +// +// Treat this like you would a base::SafeRef, because that's essentially what it +// is. +class DocumentRef { + public: + // Copyable and movable. + DocumentRef(DocumentRef&&); + DocumentRef& operator=(DocumentRef&&); + DocumentRef(const DocumentRef&); + DocumentRef& operator=(const DocumentRef&); + + ~DocumentRef(); + + RenderFrameHost& AsRenderFrameHost() const { return *safe_document_; } + + private: + explicit DocumentRef(base::SafeRef<RenderFrameHost> safe_document); + + friend class RenderFrameHostImpl; + + // Created from a factory scoped to document, rather than RenderFrameHost, + // lifetime. + base::SafeRef<RenderFrameHost> safe_document_; +}; + +// [chromium-style] requires these be out of line, but they are small enough to +// inline the defaults. +inline DocumentRef::DocumentRef(DocumentRef&&) = default; +inline DocumentRef& DocumentRef::operator=(DocumentRef&&) = default; +inline DocumentRef::DocumentRef(const DocumentRef&) = default; +inline DocumentRef& DocumentRef::operator=(const DocumentRef&) = default; +inline DocumentRef::~DocumentRef() = default; + +} // namespace content + +#endif // CONTENT_PUBLIC_BROWSER_DOCUMENT_REF_H_
diff --git a/content/public/browser/identity_request_dialog_controller.cc b/content/public/browser/identity_request_dialog_controller.cc index 4295436..86fe5694 100644 --- a/content/public/browser/identity_request_dialog_controller.cc +++ b/content/public/browser/identity_request_dialog_controller.cc
@@ -48,6 +48,14 @@ IdentityProviderMetadata::IdentityProviderMetadata( const IdentityProviderMetadata& other) = default; +int IdentityRequestDialogController::GetBrandIconIdealSize() { + return 0; +} + +int IdentityRequestDialogController::GetBrandIconMinimumSize() { + return 0; +} + void IdentityRequestDialogController::ShowInitialPermissionDialog( WebContents* rp_web_contents, const GURL& idp_url,
diff --git a/content/public/browser/identity_request_dialog_controller.h b/content/public/browser/identity_request_dialog_controller.h index 4b25a3d..8c21396f 100644 --- a/content/public/browser/identity_request_dialog_controller.h +++ b/content/public/browser/identity_request_dialog_controller.h
@@ -12,6 +12,7 @@ #include "base/containers/span.h" #include "content/common/content_export.h" #include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkColor.h" #include "url/gurl.h" @@ -80,6 +81,7 @@ absl::optional<SkColor> brand_text_color; absl::optional<SkColor> brand_background_color; + SkBitmap brand_icon; }; // IdentityRequestDialogController is in interface for control of the UI @@ -110,6 +112,14 @@ virtual ~IdentityRequestDialogController() = default; + // Returns the ideal size for the identity provider brand icon. The brand icon + // is displayed in the accounts dialog. + virtual int GetBrandIconIdealSize(); + + // Returns the minimum size for the identity provider brand icon. The brand + // icon is displayed in the accounts dialog. + virtual int GetBrandIconMinimumSize(); + // Permission-oriented flow methods. // Shows the initial permission dialog to the user.
diff --git a/content/public/browser/render_frame_host.h b/content/public/browser/render_frame_host.h index a3cae6b..3472819 100644 --- a/content/public/browser/render_frame_host.h +++ b/content/public/browser/render_frame_host.h
@@ -101,6 +101,7 @@ namespace content { class BrowserContext; +class DocumentRef; struct GlobalRenderFrameHostId; class RenderProcessHost; class RenderViewHost; @@ -108,6 +109,7 @@ class RenderWidgetHostView; class SiteInstance; class StoragePartition; +class WeakDocumentPtr; class WebUI; class Page; @@ -1018,6 +1020,12 @@ // during call to RenderFrameHostImpl::DidNavigate which happens after commit. virtual bool IsErrorDocument() = 0; + // Return checked and weak references, respectively, to the current document + // in this RenderFrameHost, which will be no longer valid once the + // RenderFrameHost is deleted or navigates to another document. + virtual DocumentRef GetDocumentRef() = 0; + virtual WeakDocumentPtr GetWeakDocumentPtr() = 0; + private: // This interface should only be implemented inside content. friend class RenderFrameHostImpl;
diff --git a/content/public/browser/weak_document_ptr.cc b/content/public/browser/weak_document_ptr.cc new file mode 100644 index 0000000..e017fb3 --- /dev/null +++ b/content/public/browser/weak_document_ptr.cc
@@ -0,0 +1,12 @@ +// Copyright 2021 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/public/browser/weak_document_ptr.h" + +namespace content { + +WeakDocumentPtr::WeakDocumentPtr(base::WeakPtr<RenderFrameHost> weak_rfh) + : weak_document_(std::move(weak_rfh)) {} + +} // namespace content
diff --git a/content/public/browser/weak_document_ptr.h b/content/public/browser/weak_document_ptr.h new file mode 100644 index 0000000..05f7ae50 --- /dev/null +++ b/content/public/browser/weak_document_ptr.h
@@ -0,0 +1,68 @@ +// Copyright 2021 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_PUBLIC_BROWSER_WEAK_DOCUMENT_PTR_H_ +#define CONTENT_PUBLIC_BROWSER_WEAK_DOCUMENT_PTR_H_ + +#include "base/memory/weak_ptr.h" +#include "content/common/content_export.h" + +namespace content { + +class RenderFrameHost; + +// Weakly refers to a document. +// +// This is invalidated at the same time as DocumentUserData. It +// becomes null whenever the RenderFrameHost is deleted or navigates to a +// different document. See also document_user_data.h. +// +// Note that though this is implemented as a base::WeakPtr<RenderFrameHost>, +// it is different from an ordinary weak pointer to the RenderFrameHost. +// +// docs/render_document.md will make these equivalent in the future. +// +// Treat this like you would a base::WeakPtr, because that's essentially what it +// is. +class WeakDocumentPtr { + public: + WeakDocumentPtr(); + + // Copyable and movable. + WeakDocumentPtr(WeakDocumentPtr&&); + WeakDocumentPtr& operator=(WeakDocumentPtr&&); + WeakDocumentPtr(const WeakDocumentPtr&); + WeakDocumentPtr& operator=(const WeakDocumentPtr&); + + ~WeakDocumentPtr(); + + // Callers must handle this returning null, in case the frame has been deleted + // or a cross-document navigation has committed in the same RenderFrameHost. + RenderFrameHost* AsRenderFrameHostIfValid() const { + return weak_document_.get(); + } + + private: + explicit WeakDocumentPtr(base::WeakPtr<RenderFrameHost> weak_rfh); + + friend class RenderFrameHostImpl; + + // Created from a factory scoped to document, rather than RenderFrameHost, + // lifetime. + base::WeakPtr<RenderFrameHost> weak_document_; +}; + +// [chromium-style] requires these be out of line, but they are small enough to +// inline the defaults. +inline WeakDocumentPtr::WeakDocumentPtr() = default; +inline WeakDocumentPtr::WeakDocumentPtr(WeakDocumentPtr&&) = default; +inline WeakDocumentPtr& WeakDocumentPtr::operator=(WeakDocumentPtr&&) = default; +inline WeakDocumentPtr::WeakDocumentPtr(const WeakDocumentPtr&) = default; +inline WeakDocumentPtr& WeakDocumentPtr::operator=(const WeakDocumentPtr&) = + default; +inline WeakDocumentPtr::~WeakDocumentPtr() = default; + +} // namespace content + +#endif // CONTENT_PUBLIC_BROWSER_WEAK_DOCUMENT_PTR_H_
diff --git a/content/public/common/content_switch_dependent_feature_overrides.cc b/content/public/common/content_switch_dependent_feature_overrides.cc index c9122563..df5a13e 100644 --- a/content/public/common/content_switch_dependent_feature_overrides.cc +++ b/content/public/common/content_switch_dependent_feature_overrides.cc
@@ -126,6 +126,11 @@ {::switches::kHeadless, std::cref(blink::features::kPaintHolding), base::FeatureList::OVERRIDE_DISABLE_FEATURE}, + // Override for --force-major-version-to-minor. + {switches::kForceMajorVersionToMinorPosition, + std::cref(blink::features::kForceMajorVersionInMinorPositionInUserAgent), + base::FeatureList::OVERRIDE_ENABLE_FEATURE}, + // Override for --force-major-version-to-100. {switches::kForceMajorVersionTo100, std::cref(blink::features::kForceMajorVersion100InUserAgent),
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index 7e79aca..6b9a2db 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc
@@ -496,6 +496,10 @@ // Forces the Chrome minor version to 100 in the User-Agent string. const char kForceMinorVersionTo100[] = "force-minor-version-to-100"; +// Forces the Chrome major version to the minor position in the User-Agent +// string. Locks major version to 99. +const char kForceMajorVersionToMinorPosition[] = "force-major-version-to-minor"; + // Forces use of hardware overlay for fullscreen video playback. Useful for // testing the Android overlay fullscreen functionality on other platforms. const char kForceOverlayFullscreenVideo[] = "force-overlay-fullscreen-video";
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index 9d1beef..d09b07e 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h
@@ -142,6 +142,7 @@ CONTENT_EXPORT extern const char kForceDisplayList2dCanvas[]; CONTENT_EXPORT extern const char kDisableOopRasterization[]; CONTENT_EXPORT extern const char kEnableOopRasterization[]; +CONTENT_EXPORT extern const char kForceMajorVersionToMinorPosition[]; CONTENT_EXPORT extern const char kForceMajorVersionTo100[]; CONTENT_EXPORT extern const char kForceMinorVersionTo100[]; CONTENT_EXPORT extern const char kForceOverlayFullscreenVideo[];
diff --git a/content/renderer/accessibility/blink_ax_tree_source.cc b/content/renderer/accessibility/blink_ax_tree_source.cc index 57f45c3..0c4a57a 100644 --- a/content/renderer/accessibility/blink_ax_tree_source.cc +++ b/content/renderer/accessibility/blink_ax_tree_source.cc
@@ -717,6 +717,14 @@ return; } + // Skip images that do not have an image_src url (e.g. SVGs), or are in + // documents that do not have a document_url. + // TODO(accessibility): Remove this check when support for SVGs is added. + if (!g_ignore_protocol_checks_for_testing && + (src.Url().GetString().Utf8().empty() || + document().Url().GetString().Utf8().empty())) + return; + if (!image_annotator_) { if (!first_unlabeled_image_id_.has_value() || first_unlabeled_image_id_.value() == src.AxID()) {
diff --git a/content/test/data/accessibility/aria/aria-img-expected-mac.txt b/content/test/data/accessibility/aria/aria-img-expected-mac.txt index 634a840..0fae38f 100644 --- a/content/test/data/accessibility/aria/aria-img-expected-mac.txt +++ b/content/test/data/accessibility/aria/aria-img-expected-mac.txt
@@ -1,2 +1,2 @@ AXWebArea -++AXImage AXDescription='To get missing image descriptions, open the context menu.' AXRoleDescription='Unlabeled image' +++AXImage \ No newline at end of file
diff --git a/content/test/data/accessibility/aria/aria-img-expected-win.txt b/content/test/data/accessibility/aria/aria-img-expected-win.txt index 418c075..3ce6eef 100644 --- a/content/test/data/accessibility/aria/aria-img-expected-win.txt +++ b/content/test/data/accessibility/aria/aria-img-expected-win.txt
@@ -1,2 +1,2 @@ ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE -++ROLE_SYSTEM_GRAPHIC name='To get missing image descriptions, open the context menu.' READONLY +++ROLE_SYSTEM_GRAPHIC READONLY \ No newline at end of file
diff --git a/content/test/data/accessibility/html/canvas-expected-mac.txt b/content/test/data/accessibility/html/canvas-expected-mac.txt index aab0489c..1e44372 100644 --- a/content/test/data/accessibility/html/canvas-expected-mac.txt +++ b/content/test/data/accessibility/html/canvas-expected-mac.txt
@@ -1,7 +1,7 @@ AXWebArea ++AXGroup -++++AXGroup AXDescription='To get missing image descriptions, open the context menu.' +++++AXGroup ++++++AXStaticText AXValue='Static fallback' ++++AXGroup ++++++AXLink AXDescription='Interactive fallback' -++++++++AXStaticText AXValue='Interactive fallback' +++++++++AXStaticText AXValue='Interactive fallback' \ No newline at end of file
diff --git a/content/test/data/accessibility/html/canvas-expected-uia-win.txt b/content/test/data/accessibility/html/canvas-expected-uia-win.txt index 5e09ab5..76b2d25 100644 --- a/content/test/data/accessibility/html/canvas-expected-uia-win.txt +++ b/content/test/data/accessibility/html/canvas-expected-uia-win.txt
@@ -1,7 +1,7 @@ Document ++Group IsControlElement=false -++++Image Name='To get missing image descriptions, open the context menu.' +++++Image ++++++Text Name='Static fallback' ++++Image ++++++Hyperlink Name='Interactive fallback' -++++++++Text Name='Interactive fallback' IsControlElement=false +++++++++Text Name='Interactive fallback' IsControlElement=false \ No newline at end of file
diff --git a/content/test/data/accessibility/html/canvas-fallback-expected-uia-win.txt b/content/test/data/accessibility/html/canvas-fallback-expected-uia-win.txt index 4ecbbde..75d6edd 100644 --- a/content/test/data/accessibility/html/canvas-fallback-expected-uia-win.txt +++ b/content/test/data/accessibility/html/canvas-fallback-expected-uia-win.txt
@@ -1,6 +1,6 @@ Document ++Group IsControlElement=false -++++Image Name='To get missing image descriptions, open the context menu.' +++++Image ++++++Text Name='Static fallback' ++++Image ++++++Text Name='<newline> ' @@ -18,4 +18,4 @@ ++++++Text Name='<newline> ' ++++++Text IsControlElement=false ++++++++Text Name='Visibility hidden paragraph in fallback content' IsControlElement=false -++++++Text Name='<newline> ' +++++++Text Name='<newline> ' \ No newline at end of file
diff --git a/content/test/data/accessibility/html/iframe-transform-expected-uia-win.txt b/content/test/data/accessibility/html/iframe-transform-expected-uia-win.txt index 07f2730..015293d2 100644 --- a/content/test/data/accessibility/html/iframe-transform-expected-uia-win.txt +++ b/content/test/data/accessibility/html/iframe-transform-expected-uia-win.txt
@@ -1,7 +1,7 @@ Document ++Document -++++Document Name='To get missing image descriptions, open the context menu.' -++++++Image Name='To get missing image descriptions, open the context menu.' +++++Document +++++++Image ++Document -++++Document Name='To get missing image descriptions, open the context menu.' -++++++Image Name='To get missing image descriptions, open the context menu.' +++++Document +++++++Image \ No newline at end of file
diff --git a/content/test/data/accessibility/html/iframe-transform-expected-win.txt b/content/test/data/accessibility/html/iframe-transform-expected-win.txt index ef94d77d8..1b5b2f2 100644 --- a/content/test/data/accessibility/html/iframe-transform-expected-win.txt +++ b/content/test/data/accessibility/html/iframe-transform-expected-win.txt
@@ -1,7 +1,7 @@ ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE location=(0, 0) ++IA2_ROLE_INTERNAL_FRAME location=(0, 0) -++++ROLE_SYSTEM_DOCUMENT name='To get missing image descriptions, open the context menu.' READONLY FOCUSABLE location=(0, 0) -++++++ROLE_SYSTEM_GRAPHIC name='To get missing image descriptions, open the context menu.' READONLY location=(10, 10) size=(100, 50) +++++ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE location=(0, 0) +++++++ROLE_SYSTEM_GRAPHIC READONLY location=(10, 10) size=(100, 50) ++IA2_ROLE_INTERNAL_FRAME location=(0, 250) -++++ROLE_SYSTEM_DOCUMENT name='To get missing image descriptions, open the context menu.' READONLY FOCUSABLE location=(0, 250) -++++++ROLE_SYSTEM_GRAPHIC name='To get missing image descriptions, open the context menu.' READONLY location=(15, 265) size=(150, 75) +++++ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE location=(0, 250) +++++++ROLE_SYSTEM_GRAPHIC READONLY location=(15, 265) size=(150, 75) \ No newline at end of file
diff --git a/content/test/data/accessibility/html/input-date-with-popup-open-expected-mac.txt b/content/test/data/accessibility/html/input-date-with-popup-open-expected-mac.txt index caa575b..73b47323 100644 --- a/content/test/data/accessibility/html/input-date-with-popup-open-expected-mac.txt +++ b/content/test/data/accessibility/html/input-date-with-popup-open-expected-mac.txt
@@ -18,9 +18,9 @@ ++++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='September 2008' ++++++++++++++++++AXImage AXRoleDescription='image' ++++++++++++++AXButton AXDescription='Show previous month' AXRoleDescription='button' -++++++++++++++++AXImage +++++++++++++++++AXImage AXRoleDescription='image' ++++++++++++++AXButton AXDescription='Show next month' AXRoleDescription='button' -++++++++++++++++AXImage +++++++++++++++++AXImage AXRoleDescription='image' ++++++++++++++AXTable AXRoleDescription='table' ++++++++++++++++AXGroup AXRoleDescription='group' ++++++++++++++++++AXGroup AXRoleDescription='group' @@ -222,4 +222,4 @@ ++++++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='4' ++++++++++++++++++AXCell AXDescription='Saturday, October 11, 2008' AXRoleDescription='cell' ++++++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='11' -++++++++++++++++AXGroup AXRoleDescription='group' \ No newline at end of file +++++++++++++++++AXGroup AXRoleDescription='group'
diff --git a/content/test/data/accessibility/html/input-date-with-popup-open-expected-uia-win.txt b/content/test/data/accessibility/html/input-date-with-popup-open-expected-uia-win.txt index 637b93c..efac9cd6 100644 --- a/content/test/data/accessibility/html/input-date-with-popup-open-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-date-with-popup-open-expected-uia-win.txt
@@ -19,7 +19,7 @@ ++++++++++++++++++++Text Name='September 2008' IsControlElement=false ++++++++++++++++++++Image ++++++++++++++++Button Name='Show previous month' -++++++++++++++++++Image Name='To get missing image descriptions, open the context menu.' +++++++++++++++++++Image ++++++++++++++++Button Name='Show next month' ++++++++++++++++++Image ++++++++++++++++DataGrid Grid.ColumnCount=7 Grid.RowCount=6 Selection.CanSelectMultiple=false Selection.IsSelectionRequired=false Table.RowOrColumnMajor='RowMajor' @@ -131,4 +131,4 @@ ++++++++++++++++++++++++DataItem Name='Saturday, October 11, 2008' GridItem.Column=6 GridItem.ColumnSpan=1 GridItem.Row=5 GridItem.RowSpan=1 SelectionItem.IsSelected=false ++++++++++++++++++++++++++Text Name='11' IsControlElement=false ++++++++++++++++++Button Name='Clear' -++++++++++++++++++Button Name='Today' +++++++++++++++++++Button Name='Today' \ No newline at end of file
diff --git a/content/test/data/accessibility/html/input-submit-expected-mac.txt b/content/test/data/accessibility/html/input-submit-expected-mac.txt index 3d1e2369..13b12910 100644 --- a/content/test/data/accessibility/html/input-submit-expected-mac.txt +++ b/content/test/data/accessibility/html/input-submit-expected-mac.txt
@@ -6,9 +6,9 @@ ++AXGroup AXRoleDescription='group' ++++AXTextField AXRoleDescription='text field' ++++AXButton AXDescription='First image button in a form is a valid default button' AXRoleDescription='button' -++++++AXImage AXDescription='To get missing image descriptions, open the context menu.' AXRoleDescription='Unlabeled image' +++++++AXImage AXRoleDescription='image' ++++++AXStaticText AXRoleDescription='text' AXValue='First image button in a form is a valid default button' ++++AXButton AXDescription='Second image button in a form not a valid default button' AXRoleDescription='button' -++++++AXImage AXRoleDescription='Unlabeled image' +++++++AXImage AXRoleDescription='image' ++++++AXStaticText AXRoleDescription='text' AXValue='Second image button in a form not a valid default button' -++AXButton AXRoleDescription='button' AXTitle='Submit outside of form not a valid default button' +++AXButton AXRoleDescription='button' AXTitle='Submit outside of form not a valid default button' \ No newline at end of file
diff --git a/content/test/data/accessibility/html/input-submit-expected-uia-win.txt b/content/test/data/accessibility/html/input-submit-expected-uia-win.txt index 64188db3..82ffe210 100644 --- a/content/test/data/accessibility/html/input-submit-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-submit-expected-uia-win.txt
@@ -6,7 +6,7 @@ ++Group ++++Edit ++++Button Name='First image button in a form is a valid default button' -++++++Image Name='To get missing image descriptions, open the context menu.' +++++++Image ++++++Text Name='First image button in a form is a valid default button' IsControlElement=false ++++Button Name='Second image button in a form not a valid default button' ++++++Image
diff --git a/content/test/data/accessibility/html/input-submit-expected-win.txt b/content/test/data/accessibility/html/input-submit-expected-win.txt index 8352e49..6a443840 100644 --- a/content/test/data/accessibility/html/input-submit-expected-win.txt +++ b/content/test/data/accessibility/html/input-submit-expected-win.txt
@@ -6,9 +6,9 @@ ++IA2_ROLE_SECTION ++++ROLE_SYSTEM_TEXT FOCUSABLE text-input-type:text ++++ROLE_SYSTEM_PUSHBUTTON name='First image button in a form is a valid default button' DEFAULT FOCUSABLE -++++++ROLE_SYSTEM_GRAPHIC name='To get missing image descriptions, open the context menu.' READONLY +++++++ROLE_SYSTEM_GRAPHIC READONLY ++++++ROLE_SYSTEM_STATICTEXT name='First image button in a form is a valid default button' ++++ROLE_SYSTEM_PUSHBUTTON name='Second image button in a form not a valid default button' FOCUSABLE ++++++ROLE_SYSTEM_GRAPHIC READONLY ++++++ROLE_SYSTEM_STATICTEXT name='Second image button in a form not a valid default button' -++ROLE_SYSTEM_PUSHBUTTON name='Submit outside of form not a valid default button' FOCUSABLE +++ROLE_SYSTEM_PUSHBUTTON name='Submit outside of form not a valid default button' FOCUSABLE \ No newline at end of file
diff --git a/content/test/data/accessibility/html/input-types-expected-mac.txt b/content/test/data/accessibility/html/input-types-expected-mac.txt index e5701d5..d4b2efc 100644 --- a/content/test/data/accessibility/html/input-types-expected-mac.txt +++ b/content/test/data/accessibility/html/input-types-expected-mac.txt
@@ -20,7 +20,7 @@ ++++AXGroup ++++++AXStaticText AXValue='Image: ' ++++++AXButton AXTitle='Image:' -++++++++AXImage AXDescription='To get missing image descriptions, open the context menu.' +++++++++AXImage ++++++++AXStaticText AXValue='Submit' ++++AXGroup ++++++AXStaticText AXValue='Number: ' @@ -49,4 +49,4 @@ ++++++AXTextField AXTitle='Text:' ++++AXGroup ++++++AXStaticText AXValue='Url: ' -++++++AXTextField AXTitle='Url:' +++++++AXTextField AXTitle='Url:' \ No newline at end of file
diff --git a/content/test/data/accessibility/html/input-types-expected-uia-win.txt b/content/test/data/accessibility/html/input-types-expected-uia-win.txt index 5fe5bfb..3b9aa09 100644 --- a/content/test/data/accessibility/html/input-types-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-types-expected-uia-win.txt
@@ -20,7 +20,7 @@ ++++Text ++++++Text Name='Image: ' ++++++Button Name='Image:' -++++++++Image Name='To get missing image descriptions, open the context menu.' +++++++++Image ++++++++Text Name='Submit' IsControlElement=false ++++Text ++++++Text Name='Number: ' @@ -49,4 +49,4 @@ ++++++Edit Name='Text:' ++++Text ++++++Text Name='Url: ' -++++++Edit Name='Url:' +++++++Edit Name='Url:' \ No newline at end of file
diff --git a/content/test/data/accessibility/html/input-types-expected-win.txt b/content/test/data/accessibility/html/input-types-expected-win.txt index e7b20c43..b459e064 100644 --- a/content/test/data/accessibility/html/input-types-expected-win.txt +++ b/content/test/data/accessibility/html/input-types-expected-win.txt
@@ -20,7 +20,7 @@ ++++IA2_ROLE_LABEL ++++++ROLE_SYSTEM_STATICTEXT name='Image: ' ++++++ROLE_SYSTEM_PUSHBUTTON name='Image:' FOCUSABLE -++++++++ROLE_SYSTEM_GRAPHIC name='To get missing image descriptions, open the context menu.' READONLY +++++++++ROLE_SYSTEM_GRAPHIC READONLY ++++++++ROLE_SYSTEM_STATICTEXT name='Submit' ++++IA2_ROLE_LABEL ++++++ROLE_SYSTEM_STATICTEXT name='Number: ' @@ -49,4 +49,4 @@ ++++++ROLE_SYSTEM_TEXT name='Text:' FOCUSABLE text-input-type:text ++++IA2_ROLE_LABEL ++++++ROLE_SYSTEM_STATICTEXT name='Url: ' -++++++ROLE_SYSTEM_TEXT name='Url:' FOCUSABLE text-input-type:url +++++++ROLE_SYSTEM_TEXT name='Url:' FOCUSABLE text-input-type:url \ No newline at end of file
diff --git a/content/test/data/accessibility/mac/methods/accessibility-role-description-expected.txt b/content/test/data/accessibility/mac/methods/accessibility-role-description-expected.txt index 041a936e..4ad1f85 100644 --- a/content/test/data/accessibility/mac/methods/accessibility-role-description-expected.txt +++ b/content/test/data/accessibility/mac/methods/accessibility-role-description-expected.txt
@@ -1,4 +1,4 @@ -unlabelled_img.accessibilityRoleDescription='Unlabeled image' +unlabelled_img.accessibilityRoleDescription='image' aria_roledescription.accessibilityRoleDescription='slidy slider button' document.accessibilityRoleDescription='HTML content' link.accessibilityRoleDescription='link' @@ -32,4 +32,4 @@ term.accessibilityRoleDescription='term' toggle_button.accessibilityRoleDescription='toggle button' fallback_role.accessibilityRoleDescription='text field' -fallback_subrole.accessibilityRoleDescription='secure text field' +fallback_subrole.accessibilityRoleDescription='secure text field' \ No newline at end of file
diff --git a/dbus/values_util.cc b/dbus/values_util.cc index e7405f9..2cd7b75 100644 --- a/dbus/values_util.cc +++ b/dbus/values_util.cc
@@ -267,11 +267,9 @@ break; } case base::Value::Type::LIST: { - const base::ListValue* list = nullptr; - value.GetAsList(&list); dbus::MessageWriter array_writer(nullptr); writer->OpenArray("v", &array_writer); - for (const auto& value_in_list : list->GetList()) { + for (const auto& value_in_list : value.GetList()) { AppendValueDataAsVariant(&array_writer, value_in_list); } writer->CloseContainer(&array_writer);
diff --git a/extensions/shell/browser/shell_content_browser_client.cc b/extensions/shell/browser/shell_content_browser_client.cc index 82708394..9faa2ece 100644 --- a/extensions/shell/browser/shell_content_browser_client.cc +++ b/extensions/shell/browser/shell_content_browser_client.cc
@@ -353,6 +353,7 @@ ui::PageTransition page_transition, bool has_user_gesture, const absl::optional<url::Origin>& initiating_origin, + content::RenderFrameHost* initiator_document, mojo::PendingRemote<network::mojom::URLLoaderFactory>* out_factory) { return false; }
diff --git a/extensions/shell/browser/shell_content_browser_client.h b/extensions/shell/browser/shell_content_browser_client.h index 078b2767..d95927795 100644 --- a/extensions/shell/browser/shell_content_browser_client.h +++ b/extensions/shell/browser/shell_content_browser_client.h
@@ -129,6 +129,7 @@ ui::PageTransition page_transition, bool has_user_gesture, const absl::optional<url::Origin>& initiating_origin, + content::RenderFrameHost* initiator_document, mojo::PendingRemote<network::mojom::URLLoaderFactory>* out_factory) override; void OverrideURLLoaderFactoryParams(
diff --git a/infra/config/subprojects/chromium/ci/chromium.linux.star b/infra/config/subprojects/chromium/ci/chromium.linux.star index 3970811..55efe99 100644 --- a/infra/config/subprojects/chromium/ci/chromium.linux.star +++ b/infra/config/subprojects/chromium/ci/chromium.linux.star
@@ -35,18 +35,6 @@ }, ) -def linux_builder( - *, - name, - notifies = ("chromium.linux",), - extra_notifies = None, - **kwargs): - return ci.builder( - name = name, - notifies = list(notifies) + (extra_notifies or []), - **kwargs - ) - ci.builder( name = "Cast Audio Linux", console_view_entry = consoles.console_view_entry(
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index 111b643..913f2d29 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -775,6 +775,9 @@ flag_descriptions::kSaveSessionTabsToSeparateFilesDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(sessions::kSaveSessionTabsToSeparateFiles)}, + {"use-sf-symbols-samples", flag_descriptions::kUseSFSymbolsSamplesName, + flag_descriptions::kUseSFSymbolsSamplesDescription, flags_ui::kOsIos, + FEATURE_VALUE_TYPE(kUseSFSymbolsSamples)}, }; bool SkipConditionalFeatureEntry(const flags_ui::FeatureEntry& entry) {
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc index 6d54880..4d923740 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -534,6 +534,10 @@ "When enabled, use Lens to search for images from the long press context " "menu when Google is the selected search engine."; +const char kUseSFSymbolsSamplesName[] = "Replace Image by SFSymbols"; +const char kUseSFSymbolsSamplesDescription[] = + "When enabled, some images (toolbar...) are replaced by SFSymbols"; + const char kWaitThresholdMillisecondsForCapabilitiesApiName[] = "Maximum wait time (in seconds) for a response from the Account " "Capabilities API";
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h index cc759a8..e276349 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -480,6 +480,11 @@ extern const char kUseLensToSearchForImageName[]; extern const char kUseLensToSearchForImageDescription[]; +// Title and description for the flag to enable the replacement of some images +// by SFSymbols. +extern const char kUseSFSymbolsSamplesName[]; +extern const char kUseSFSymbolsSamplesDescription[]; + // Title and description for the flag to control the maximum wait time (in // seconds) for a response from the Account Capabilities API. extern const char kWaitThresholdMillisecondsForCapabilitiesApiName[];
diff --git a/ios/chrome/browser/ui/authentication/signin_sync/signin_sync_coordinator.mm b/ios/chrome/browser/ui/authentication/signin_sync/signin_sync_coordinator.mm index ece6291f..5eb3d76 100644 --- a/ios/chrome/browser/ui/authentication/signin_sync/signin_sync_coordinator.mm +++ b/ios/chrome/browser/ui/authentication/signin_sync/signin_sync_coordinator.mm
@@ -92,6 +92,9 @@ SigninCoordinator* advancedSettingsSigninCoordinator; // Browser sign-in state to revert to in case sync is canceled. @property(nonatomic, assign) IdentitySigninState signinStateOnStart; +// Sign-in identity when the coordiantor starts. This is used as the identity to +// revert to in case sync is canceled. +@property(nonatomic, strong) ChromeIdentity* signinIdentityOnStart; @end @@ -129,6 +132,11 @@ - (void)start { ChromeBrowserState* browserState = self.browser->GetBrowserState(); + AuthenticationService* authenticationService = + AuthenticationServiceFactory::GetForBrowserState(browserState); + self.signinIdentityOnStart = + authenticationService->GetPrimaryIdentity(signin::ConsentLevel::kSignin); + if (!signin::IsSigninAllowedByPolicy() || IsSyncDisabledByPolicy(browserState)) { // Skip the screen if sync is disabled by policy. @@ -465,6 +473,12 @@ [self.advancedSettingsSigninCoordinator stop]; self.advancedSettingsSigninCoordinator = nil; + + // Should not stay signed in. Only sign-in the user when they selects the + // option to or when they are already signed in. + [self.mediator + cancelSigninWithIdentitySigninState:self.signinStateOnStart + signinIdentityOnStart:self.signinIdentityOnStart]; } @end
diff --git a/ios/chrome/browser/ui/authentication/signin_sync/signin_sync_mediator.h b/ios/chrome/browser/ui/authentication/signin_sync/signin_sync_mediator.h index 3165a99..16920e7 100644 --- a/ios/chrome/browser/ui/authentication/signin_sync/signin_sync_mediator.h +++ b/ios/chrome/browser/ui/authentication/signin_sync/signin_sync_mediator.h
@@ -8,6 +8,7 @@ #import <Foundation/Foundation.h> #import "base/ios/block_types.h" +#import "ios/chrome/browser/ui/authentication/signin/signin_constants.h" namespace consent_auditor { class ConsentAuditor; @@ -66,6 +67,13 @@ // Disconnect the mediator. - (void)disconnect; +// Reverts the sign-in operation if needed. +// @param signinStateOnStart: Browser sign-in state when the coordinator starts. +// @param signinIdentityOnStart: Sign-in identity when the coordinator starts. +- (void) + cancelSigninWithIdentitySigninState:(IdentitySigninState)signinStateOnStart + signinIdentityOnStart:(ChromeIdentity*)signinIdentityOnStart; + // Starts the sync engine. // @param confirmationID: The confirmation string ID of sync. // @param consentIDs: The consent string IDs of sync screen.
diff --git a/ios/chrome/browser/ui/authentication/signin_sync/signin_sync_mediator.mm b/ios/chrome/browser/ui/authentication/signin_sync/signin_sync_mediator.mm index 8d55040..aa3f3e8 100644 --- a/ios/chrome/browser/ui/authentication/signin_sync/signin_sync_mediator.mm +++ b/ios/chrome/browser/ui/authentication/signin_sync/signin_sync_mediator.mm
@@ -104,6 +104,54 @@ _accountManagerServiceObserver.reset(); } +- (void) + cancelSigninWithIdentitySigninState:(IdentitySigninState)signinStateOnStart + signinIdentityOnStart:(ChromeIdentity*)signinIdentityOnStart { + [self.authenticationFlow cancelAndDismissAnimated:NO]; + + self.syncService->GetUserSettings()->SetSyncRequested(false); + switch (signinStateOnStart) { + case IdentitySigninStateSignedOut: { + self.authenticationService->SignOut(signin_metrics::ABORT_SIGNIN, + /*force_clear_browsing_data=*/false, + nil); + break; + } + case IdentitySigninStateSignedInWithSyncDisabled: { + DCHECK(!self.authenticationService->GetPrimaryIdentity( + signin::ConsentLevel::kSync)); + if ([self.authenticationService->GetPrimaryIdentity( + signin::ConsentLevel::kSignin) isEqual:signinIdentityOnStart]) { + // Can't be synced in this option because sync has to be disabled. + _syncService->StopAndClear(); + } else { + __weak __typeof(self) weakSelf = self; + self.authenticationService->SignOut( + signin_metrics::ABORT_SIGNIN, + /*force_clear_browsing_data=*/false, ^() { + AuthenticationService* authenticationService = + weakSelf.authenticationService; + ChromeIdentity* identity = signinIdentityOnStart; + ChromeAccountManagerService* accountManagerService = + weakSelf.accountManagerService; + if (authenticationService && identity && + accountManagerService->IsValidIdentity(identity)) { + // Sign back in with a valid identity. + authenticationService->SignIn(identity); + } + }); + } + break; + } + case IdentitySigninStateSignedInWithSyncEnabled: { + // This view wouldn't be shown if sync is enabled, so this option + // shouldn't be reached. + NOTREACHED(); + break; + } + } +} + - (void)startSyncWithConfirmationID:(const int)confirmationID consentIDs:(NSArray<NSNumber*>*)consentIDs authenticationFlow:(AuthenticationFlow*)authenticationFlow {
diff --git a/ios/chrome/browser/ui/settings/content_settings/BUILD.gn b/ios/chrome/browser/ui/settings/content_settings/BUILD.gn index 06f2b87..3e6e6b61 100644 --- a/ios/chrome/browser/ui/settings/content_settings/BUILD.gn +++ b/ios/chrome/browser/ui/settings/content_settings/BUILD.gn
@@ -47,9 +47,11 @@ source_set("content_settings_ui") { configs += [ "//build/config/compiler:enable_arc" ] sources = [ + "default_page_mode.h", "default_page_mode_consumer.h", "default_page_mode_table_view_controller.h", "default_page_mode_table_view_controller.mm", + "default_page_mode_table_view_controller_delegate.h", ] deps = [ "//ios/chrome/browser/ui/settings:settings_root",
diff --git a/ios/chrome/browser/ui/settings/content_settings/default_page_mode.h b/ios/chrome/browser/ui/settings/content_settings/default_page_mode.h new file mode 100644 index 0000000..7cdec4f --- /dev/null +++ b/ios/chrome/browser/ui/settings/content_settings/default_page_mode.h
@@ -0,0 +1,16 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_CONTENT_SETTINGS_DEFAULT_PAGE_MODE_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_CONTENT_SETTINGS_DEFAULT_PAGE_MODE_H_ + +#import <Foundation/Foundation.h> + +// The mode in which pages should be loaded. +typedef NS_ENUM(NSUInteger, DefaultPageMode) { + DefaultPageModeMobile, + DefaultPageModeDesktop, +}; + +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_CONTENT_SETTINGS_DEFAULT_PAGE_MODE_H_
diff --git a/ios/chrome/browser/ui/settings/content_settings/default_page_mode_consumer.h b/ios/chrome/browser/ui/settings/content_settings/default_page_mode_consumer.h index 32861e0..aff912f 100644 --- a/ios/chrome/browser/ui/settings/content_settings/default_page_mode_consumer.h +++ b/ios/chrome/browser/ui/settings/content_settings/default_page_mode_consumer.h
@@ -7,11 +7,7 @@ #import <UIKit/UIKit.h> -// The mode in which pages should be loaded. -typedef NS_ENUM(NSUInteger, DefaultPageMode) { - DefaultPageModeMobile, - DefaultPageModeDesktop, -}; +#import "ios/chrome/browser/ui/settings/content_settings/default_page_mode.h" // Consumer protocol for the screen allowing the user to choose the default mode // (Desktop/Mobile) for loading pages.
diff --git a/ios/chrome/browser/ui/settings/content_settings/default_page_mode_coordinator.mm b/ios/chrome/browser/ui/settings/content_settings/default_page_mode_coordinator.mm index d76ec8c..79c0161 100644 --- a/ios/chrome/browser/ui/settings/content_settings/default_page_mode_coordinator.mm +++ b/ios/chrome/browser/ui/settings/content_settings/default_page_mode_coordinator.mm
@@ -4,15 +4,20 @@ #import "ios/chrome/browser/ui/settings/content_settings/default_page_mode_coordinator.h" +#include "components/content_settings/core/browser/host_content_settings_map.h" +#include "ios/chrome/browser/content_settings/host_content_settings_map_factory.h" +#import "ios/chrome/browser/main/browser.h" #import "ios/chrome/browser/ui/settings/content_settings/default_page_mode_mediator.h" #import "ios/chrome/browser/ui/settings/content_settings/default_page_mode_table_view_controller.h" +#import "ios/chrome/browser/ui/settings/content_settings/default_page_mode_table_view_controller_delegate.h" #import "ios/chrome/browser/ui/table_view/table_view_utils.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif -@interface DefaultPageModeCoordinator () +@interface DefaultPageModeCoordinator () < + DefaultPageModeTableViewControllerDelegate> @property(nonatomic, strong) DefaultPageModeTableViewController* viewController; @property(nonatomic, strong) DefaultPageModeMediator* mediator; @@ -35,12 +40,26 @@ } - (void)start { + HostContentSettingsMap* settingsMap = + ios::HostContentSettingsMapFactory::GetForBrowserState( + self.browser->GetBrowserState()); + self.mediator = + [[DefaultPageModeMediator alloc] initWithSettingsMap:settingsMap]; + self.viewController = [[DefaultPageModeTableViewController alloc] initWithStyle:ChromeTableViewStyle()]; - self.mediator = - [[DefaultPageModeMediator alloc] initWithConsumer:self.viewController]; + self.viewController.delegate = self; + + self.mediator.consumer = self.viewController; + [self.baseNavigationController pushViewController:self.viewController animated:YES]; } +#pragma mark - DefaultPageModeTableViewControllerDelegate + +- (void)didSelectMode:(DefaultPageMode)selectedMode { + [self.mediator setDefaultMode:selectedMode]; +} + @end
diff --git a/ios/chrome/browser/ui/settings/content_settings/default_page_mode_mediator.h b/ios/chrome/browser/ui/settings/content_settings/default_page_mode_mediator.h index a14653f..541e095 100644 --- a/ios/chrome/browser/ui/settings/content_settings/default_page_mode_mediator.h +++ b/ios/chrome/browser/ui/settings/content_settings/default_page_mode_mediator.h
@@ -7,17 +7,25 @@ #import <Foundation/Foundation.h> +#import "ios/chrome/browser/ui/settings/content_settings/default_page_mode.h" + @protocol DefaultPageModeConsumer; +class HostContentSettingsMap; // Mediator for the screen allowing the user to choose the default mode // (Desktop/Mobile) for loading pages. @interface DefaultPageModeMediator : NSObject -- (instancetype)initWithConsumer:(id<DefaultPageModeConsumer>)consumer +- (instancetype)initWithSettingsMap:(HostContentSettingsMap*)settingsMap NS_DESIGNATED_INITIALIZER; - (instancetype)init NS_UNAVAILABLE; +@property(nonatomic, weak) id<DefaultPageModeConsumer> consumer; + +// Sets the default mode for loading a page. +- (void)setDefaultMode:(DefaultPageMode)defaultMode; + @end #endif // IOS_CHROME_BROWSER_UI_SETTINGS_CONTENT_SETTINGS_DEFAULT_PAGE_MODE_MEDIATOR_H_
diff --git a/ios/chrome/browser/ui/settings/content_settings/default_page_mode_mediator.mm b/ios/chrome/browser/ui/settings/content_settings/default_page_mode_mediator.mm index 8c7cc3c..870ce80 100644 --- a/ios/chrome/browser/ui/settings/content_settings/default_page_mode_mediator.mm +++ b/ios/chrome/browser/ui/settings/content_settings/default_page_mode_mediator.mm
@@ -4,26 +4,69 @@ #import "ios/chrome/browser/ui/settings/content_settings/default_page_mode_mediator.h" +#include "components/content_settings/core/browser/host_content_settings_map.h" +#include "components/content_settings/core/common/content_settings.h" +#include "components/content_settings/core/common/content_settings_pattern.h" #import "ios/chrome/browser/ui/settings/content_settings/default_page_mode_consumer.h" +#import "ios/chrome/browser/ui/settings/utils/content_setting_backed_boolean.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif -@interface DefaultPageModeMediator () +@interface DefaultPageModeMediator () <BooleanObserver> -@property(nonatomic, weak) id<DefaultPageModeConsumer> consumer; +@property(nonatomic, strong) ContentSettingBackedBoolean* requestDesktopSetting; @end @implementation DefaultPageModeMediator -- (instancetype)initWithConsumer:(id<DefaultPageModeConsumer>)consumer { +- (instancetype)initWithSettingsMap:(HostContentSettingsMap*)settingsMap { self = [super init]; if (self) { - _consumer = consumer; + _requestDesktopSetting = [[ContentSettingBackedBoolean alloc] + initWithHostContentSettingsMap:settingsMap + settingID:ContentSettingsType::REQUEST_DESKTOP_SITE + inverted:NO]; + [_requestDesktopSetting setObserver:self]; } return self; } +- (void)setConsumer:(id<DefaultPageModeConsumer>)consumer { + if (_consumer == consumer) + return; + + _consumer = consumer; + [self updateConsumer]; +} + +- (void)setDefaultMode:(DefaultPageMode)defaultMode { + BOOL newValue = defaultMode == DefaultPageModeDesktop; + if (self.requestDesktopSetting.value == newValue) + return; + + self.requestDesktopSetting.value = newValue; + [self updateConsumer]; +} + +#pragma mark - BooleanObserver + +- (void)booleanDidChange:(id<ObservableBoolean>)observableBoolean { + DCHECK_EQ(observableBoolean, self.requestDesktopSetting); + [self updateConsumer]; +} + +#pragma mark - Private + +- (DefaultPageMode)defaultMode { + return self.requestDesktopSetting.value ? DefaultPageModeDesktop + : DefaultPageModeMobile; +} + +- (void)updateConsumer { + [self.consumer setDefaultPageMode:[self defaultMode]]; +} + @end
diff --git a/ios/chrome/browser/ui/settings/content_settings/default_page_mode_table_view_controller.h b/ios/chrome/browser/ui/settings/content_settings/default_page_mode_table_view_controller.h index 5670228..3f82019 100644 --- a/ios/chrome/browser/ui/settings/content_settings/default_page_mode_table_view_controller.h +++ b/ios/chrome/browser/ui/settings/content_settings/default_page_mode_table_view_controller.h
@@ -9,12 +9,17 @@ #import "ios/chrome/browser/ui/settings/settings_controller_protocol.h" #import "ios/chrome/browser/ui/settings/settings_root_table_view_controller.h" +@protocol DefaultPageModeTableViewControllerDelegate; + // ViewController for the screen allowing the user to choose the default mode // (Desktop/Mobile) for loading pages. @interface DefaultPageModeTableViewController : SettingsRootTableViewController <DefaultPageModeConsumer, SettingsControllerProtocol> +@property(nonatomic, weak) id<DefaultPageModeTableViewControllerDelegate> + delegate; + @end #endif // IOS_CHROME_BROWSER_UI_SETTINGS_CONTENT_SETTINGS_DEFAULT_PAGE_MODE_TABLE_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/settings/content_settings/default_page_mode_table_view_controller.mm b/ios/chrome/browser/ui/settings/content_settings/default_page_mode_table_view_controller.mm index e0949fa..5bf9bfa 100644 --- a/ios/chrome/browser/ui/settings/content_settings/default_page_mode_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/content_settings/default_page_mode_table_view_controller.mm
@@ -4,18 +4,99 @@ #import "ios/chrome/browser/ui/settings/content_settings/default_page_mode_table_view_controller.h" +#import "ios/chrome/browser/ui/settings/content_settings/default_page_mode_table_view_controller_delegate.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_detail_icon_item.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif +namespace { + +typedef NS_ENUM(NSInteger, SectionIdentifier) { + SectionIdentifierMode = kSectionIdentifierEnumZero, +}; + +typedef NS_ENUM(NSInteger, ItemType) { + ItemTypeMobile = kItemTypeEnumZero, + ItemTypeDesktop, +}; + +} // namespace + +@interface DefaultPageModeTableViewController () + +@property(nonatomic, assign) ItemType chosenItemType; + +@end + @implementation DefaultPageModeTableViewController +- (void)viewDidLoad { + [super viewDidLoad]; + [self loadModel]; +} + +#pragma mark - ChromeTableViewController + +- (void)loadModel { + [super loadModel]; + + TableViewModel* model = self.tableViewModel; + [model addSectionWithIdentifier:SectionIdentifierMode]; + + TableViewDetailIconItem* mobileItem = + [[TableViewDetailIconItem alloc] initWithType:ItemTypeMobile]; + mobileItem.text = @"TEST - Mobile"; + [model addItem:mobileItem toSectionWithIdentifier:SectionIdentifierMode]; + + TableViewDetailIconItem* desktopItem = + [[TableViewDetailIconItem alloc] initWithType:ItemTypeDesktop]; + desktopItem.text = @"TEST - Desktop"; + [model addItem:desktopItem toSectionWithIdentifier:SectionIdentifierMode]; + + for (TableViewItem* item in [self.tableViewModel + itemsInSectionWithIdentifier:SectionIdentifierMode]) { + if (item.type == self.chosenItemType) { + item.accessoryType = UITableViewCellAccessoryCheckmark; + } + } +} + +- (void)tableView:(UITableView*)tableView + didSelectRowAtIndexPath:(NSIndexPath*)indexPath { + TableViewModel* model = self.tableViewModel; + NSInteger itemType = [model itemTypeForIndexPath:indexPath]; + + DefaultPageMode chosenMode = itemType == ItemTypeMobile + ? DefaultPageModeMobile + : DefaultPageModeDesktop; + + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + + [self.delegate didSelectMode:chosenMode]; +} + #pragma mark - DefaultPageModeConsumer - (void)setDefaultPageMode:(DefaultPageMode)mode { - // TODO(crbug.com/1276922): change the selected cell based on the mode. + ItemType chosenType = + mode == DefaultPageModeMobile ? ItemTypeMobile : ItemTypeDesktop; + + self.chosenItemType = chosenType; + + for (TableViewItem* item in [self.tableViewModel + itemsInSectionWithIdentifier:SectionIdentifierMode]) { + if (item.type == chosenType) { + item.accessoryType = UITableViewCellAccessoryCheckmark; + } else { + item.accessoryType = UITableViewCellAccessoryNone; + } + } + + [self reloadCellsForItems:[self.tableViewModel itemsInSectionWithIdentifier: + SectionIdentifierMode] + withRowAnimation:UITableViewRowAnimationAutomatic]; } #pragma mark - SettingsControllerProtocol
diff --git a/ios/chrome/browser/ui/settings/content_settings/default_page_mode_table_view_controller_delegate.h b/ios/chrome/browser/ui/settings/content_settings/default_page_mode_table_view_controller_delegate.h new file mode 100644 index 0000000..12ed0c8 --- /dev/null +++ b/ios/chrome/browser/ui/settings/content_settings/default_page_mode_table_view_controller_delegate.h
@@ -0,0 +1,21 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_CONTENT_SETTINGS_DEFAULT_PAGE_MODE_TABLE_VIEW_CONTROLLER_DELEGATE_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_CONTENT_SETTINGS_DEFAULT_PAGE_MODE_TABLE_VIEW_CONTROLLER_DELEGATE_H_ + +#import <Foundation/Foundation.h> + +#import "ios/chrome/browser/ui/settings/content_settings/default_page_mode.h" + +// Delegate for the screen allowing the user to choose the default mode +// (Desktop/Mobile) for loading pages. +@protocol DefaultPageModeTableViewControllerDelegate + +// Called when the user chose a default page mode. +- (void)didSelectMode:(DefaultPageMode)selectedMode; + +@end + +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_CONTENT_SETTINGS_DEFAULT_PAGE_MODE_TABLE_VIEW_CONTROLLER_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.mm b/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.mm index 28d0ee3..84dbb7e 100644 --- a/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.mm +++ b/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.mm
@@ -13,6 +13,7 @@ #import "ios/chrome/browser/ui/toolbar/buttons/toolbar_tab_grid_button.h" #import "ios/chrome/browser/ui/toolbar/buttons/toolbar_tools_menu_button.h" #import "ios/chrome/browser/ui/toolbar/public/toolbar_constants.h" +#include "ios/chrome/browser/ui/ui_feature_flags.h" #import "ios/chrome/browser/ui/util/rtl_geometry.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" @@ -25,6 +26,17 @@ #error "This file requires ARC support." #endif +namespace { + +// Returns the default configuration for Symbols. +UIImageConfiguration* SymbolConfiguration() { + return [UIImageSymbolConfiguration + configurationWithPointSize:22 + weight:UIImageSymbolWeightMedium]; +} + +} // namespace + @implementation ToolbarButtonFactory - (instancetype)initWithStyle:(ToolbarStyle)style { @@ -39,8 +51,15 @@ #pragma mark - Buttons - (ToolbarButton*)backButton { + UIImage* backImage; + if (base::FeatureList::IsEnabled(kUseSFSymbolsSamples)) { + backImage = [UIImage systemImageNamed:@"arrow.left" + withConfiguration:SymbolConfiguration()]; + } else { + backImage = [UIImage imageNamed:@"toolbar_back"]; + } ToolbarButton* backButton = [ToolbarButton - toolbarButtonWithImage:[[UIImage imageNamed:@"toolbar_back"] + toolbarButtonWithImage:[backImage imageFlippedForRightToLeftLayoutDirection]]; [self configureButton:backButton width:kAdaptiveToolbarButtonWidth]; backButton.accessibilityLabel = l10n_util::GetNSString(IDS_ACCNAME_BACK); @@ -53,8 +72,15 @@ // Returns a forward button without visibility mask configured. - (ToolbarButton*)forwardButton { + UIImage* forwardImage; + if (base::FeatureList::IsEnabled(kUseSFSymbolsSamples)) { + forwardImage = [UIImage systemImageNamed:@"arrow.right" + withConfiguration:SymbolConfiguration()]; + } else { + forwardImage = [UIImage imageNamed:@"toolbar_forward"]; + } ToolbarButton* forwardButton = [ToolbarButton - toolbarButtonWithImage:[[UIImage imageNamed:@"toolbar_forward"] + toolbarButtonWithImage:[forwardImage imageFlippedForRightToLeftLayoutDirection]]; [self configureButton:forwardButton width:kAdaptiveToolbarButtonWidth]; forwardButton.visibilityMask = @@ -68,8 +94,16 @@ } - (ToolbarTabGridButton*)tabGridButton { - ToolbarTabGridButton* tabGridButton = [ToolbarTabGridButton - toolbarButtonWithImage:[UIImage imageNamed:@"toolbar_switcher"]]; + UIImage* tabGridImage; + if (base::FeatureList::IsEnabled(kUseSFSymbolsSamples)) { + tabGridImage = [UIImage systemImageNamed:@"square" + withConfiguration:SymbolConfiguration()]; + } else { + tabGridImage = [UIImage imageNamed:@"toolbar_switcher"]; + } + + ToolbarTabGridButton* tabGridButton = + [ToolbarTabGridButton toolbarButtonWithImage:tabGridImage]; [self configureButton:tabGridButton width:kAdaptiveToolbarButtonWidth]; SetA11yLabelAndUiAutomationName(tabGridButton, IDS_IOS_TOOLBAR_SHOW_TABS, kToolbarStackButtonIdentifier); @@ -103,8 +137,16 @@ } - (ToolbarButton*)shareButton { - ToolbarButton* shareButton = [ToolbarButton - toolbarButtonWithImage:[UIImage imageNamed:@"toolbar_share"]]; + UIImage* shareImage; + if (base::FeatureList::IsEnabled(kUseSFSymbolsSamples)) { + shareImage = [UIImage systemImageNamed:@"square.and.arrow.up" + withConfiguration:SymbolConfiguration()]; + } else { + shareImage = [UIImage imageNamed:@"toolbar_share"]; + } + + ToolbarButton* shareButton = + [ToolbarButton toolbarButtonWithImage:shareImage]; [self configureButton:shareButton width:kAdaptiveToolbarButtonWidth]; SetA11yLabelAndUiAutomationName(shareButton, IDS_IOS_TOOLS_MENU_SHARE, kToolbarShareButtonIdentifier); @@ -118,8 +160,16 @@ } - (ToolbarButton*)reloadButton { + UIImage* reloadImage; + if (base::FeatureList::IsEnabled(kUseSFSymbolsSamples)) { + reloadImage = [UIImage systemImageNamed:@"arrow.clockwise" + withConfiguration:SymbolConfiguration()]; + } else { + reloadImage = [UIImage imageNamed:@"toolbar_reload"]; + } + ToolbarButton* reloadButton = [ToolbarButton - toolbarButtonWithImage:[[UIImage imageNamed:@"toolbar_reload"] + toolbarButtonWithImage:[reloadImage imageFlippedForRightToLeftLayoutDirection]]; [self configureButton:reloadButton width:kAdaptiveToolbarButtonWidth]; reloadButton.accessibilityLabel = @@ -133,8 +183,15 @@ } - (ToolbarButton*)stopButton { - ToolbarButton* stopButton = [ToolbarButton - toolbarButtonWithImage:[UIImage imageNamed:@"toolbar_stop"]]; + UIImage* stopImage; + if (base::FeatureList::IsEnabled(kUseSFSymbolsSamples)) { + stopImage = [UIImage systemImageNamed:@"multiply" + withConfiguration:SymbolConfiguration()]; + } else { + stopImage = [UIImage imageNamed:@"toolbar_stop"]; + } + + ToolbarButton* stopButton = [ToolbarButton toolbarButtonWithImage:stopImage]; [self configureButton:stopButton width:kAdaptiveToolbarButtonWidth]; stopButton.accessibilityLabel = l10n_util::GetNSString(IDS_IOS_ACCNAME_STOP); [stopButton addTarget:self.actionHandler @@ -145,8 +202,15 @@ } - (ToolbarButton*)openNewTabButton { - ToolbarNewTabButton* newTabButton = [ToolbarNewTabButton - toolbarButtonWithImage:[UIImage imageNamed:@"toolbar_new_tab_page"]]; + UIImage* newTabImage; + if (base::FeatureList::IsEnabled(kUseSFSymbolsSamples)) { + newTabImage = [UIImage systemImageNamed:@"plus" + withConfiguration:SymbolConfiguration()]; + } else { + newTabImage = [UIImage imageNamed:@"toolbar_new_tab_page"]; + } + ToolbarNewTabButton* newTabButton = + [ToolbarNewTabButton toolbarButtonWithImage:newTabImage]; [newTabButton addTarget:self.actionHandler action:@selector(searchAction:)
diff --git a/ios/chrome/browser/ui/ui_feature_flags.cc b/ios/chrome/browser/ui/ui_feature_flags.cc index eb8e0c8..224494d 100644 --- a/ios/chrome/browser/ui/ui_feature_flags.cc +++ b/ios/chrome/browser/ui/ui_feature_flags.cc
@@ -74,6 +74,9 @@ const base::Feature kAddSettingForDefaultPageMode{ "DefaultRequestedMode", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kUseSFSymbolsSamples{"UseSFSymbolsSamples", + base::FEATURE_DISABLED_BY_DEFAULT}; + bool IsContextMenuActionsRefreshEnabled() { return base::FeatureList::IsEnabled(kContextMenuActionsRefresh); }
diff --git a/ios/chrome/browser/ui/ui_feature_flags.h b/ios/chrome/browser/ui/ui_feature_flags.h index b16954d..f4b69df 100644 --- a/ios/chrome/browser/ui/ui_feature_flags.h +++ b/ios/chrome/browser/ui/ui_feature_flags.h
@@ -87,6 +87,9 @@ // (Desktop/Mobile) in which the pages will be requested by default. extern const base::Feature kAddSettingForDefaultPageMode; +// Feature flag to switch some images to SFSymbols when enabled. +extern const base::Feature kUseSFSymbolsSamples; + // Whether the ContextMenuActionsRefresh flag is enabled. bool IsContextMenuActionsRefreshEnabled();
diff --git a/ios/web/js_messaging/web_frame_impl.h b/ios/web/js_messaging/web_frame_impl.h index 082b3c2..73c8edc 100644 --- a/ios/web/js_messaging/web_frame_impl.h +++ b/ios/web/js_messaging/web_frame_impl.h
@@ -67,6 +67,8 @@ base::OnceCallback<void(const base::Value*)> callback, base::TimeDelta timeout) override; + bool ExecuteJavaScript(const std::string& script) override; + // WebFrameContentWorldAPI: bool CallJavaScriptFunctionInContentWorld( const std::string& name,
diff --git a/ios/web/js_messaging/web_frame_impl.mm b/ios/web/js_messaging/web_frame_impl.mm index 5ca67a9..4d42c2d 100644 --- a/ios/web/js_messaging/web_frame_impl.mm +++ b/ios/web/js_messaging/web_frame_impl.mm
@@ -260,6 +260,33 @@ return called; } +bool WebFrameImpl::ExecuteJavaScript(const std::string& script) { + DCHECK(base::ios::IsRunningOnIOS14OrLater()); + DCHECK(frame_info_); + + if (!IsMainFrame()) { + return false; + } + + NSString* ns_script = base::SysUTF8ToNSString(script); + void (^completion_handler)(id, NSError*) = ^void(id value, NSError* error) { + if (error) { + DLOG(WARNING) << "Script execution of:" + << base::SysNSStringToUTF16(ns_script) + << "\nfailed with error: " + << base::SysNSStringToUTF16( + error.userInfo[NSLocalizedDescriptionKey]); + } + }; + + if (@available(iOS 14.0, *)) { + web::ExecuteJavaScript(frame_info_.webView, WKContentWorld.pageWorld, + frame_info_, ns_script, completion_handler); + return true; + } + return false; +} + bool WebFrameImpl::ExecuteJavaScriptFunction( JavaScriptContentWorld* content_world, const std::string& name,
diff --git a/ios/web/js_messaging/web_frame_impl_unittest.mm b/ios/web/js_messaging/web_frame_impl_unittest.mm index 3764b60..21f0f34 100644 --- a/ios/web/js_messaging/web_frame_impl_unittest.mm +++ b/ios/web/js_messaging/web_frame_impl_unittest.mm
@@ -8,6 +8,7 @@ #import "base/base64.h" #include "base/bind.h" +#include "base/ios/ios_util.h" #include "base/json/json_reader.h" #include "base/run_loop.h" #include "base/strings/string_number_conversions.h" @@ -446,4 +447,32 @@ EXPECT_EQ(last_script.length, 0ul); } +// Tests that the WebFrame can execute arbitrary JavaScript. +// if and only if it is a main frame. +TEST_F(WebFrameImplTest, ExecuteJavaScript) { + if (!base::ios::IsRunningOnIOS14OrLater()) { + return; + } + + FakeWebState fake_web_state; + GURL security_origin; + + NSString* script = @"__gCrWeb = {};" + @"__gCrWeb['fakeFunction'] = function() {" + @" return '10';" + @"}"; + + WebFrameImpl web_frame([[WKFrameInfo alloc] init], kFrameId, + /*is_main_frame=*/true, security_origin, + &fake_web_state); + + EXPECT_TRUE(web_frame.ExecuteJavaScript(base::SysNSStringToUTF8(script))); + + WebFrameImpl web_frame2([[WKFrameInfo alloc] init], kFrameId, + /*is_main_frame=*/false, security_origin, + &fake_web_state); + // Executing arbitrary code on an iframe should return false. + EXPECT_FALSE(web_frame2.ExecuteJavaScript(base::SysNSStringToUTF8(script))); +} + } // namespace web
diff --git a/ios/web/public/js_messaging/web_frame.h b/ios/web/public/js_messaging/web_frame.h index ebcf8cbb26b..31ddc73 100644 --- a/ios/web/public/js_messaging/web_frame.h +++ b/ios/web/public/js_messaging/web_frame.h
@@ -70,6 +70,9 @@ base::OnceCallback<void(const base::Value*)> callback, base::TimeDelta timeout) = 0; + // Executes the given |script| and returns whether the script was run. + virtual bool ExecuteJavaScript(const std::string& script) = 0; + // Returns the WebFrameInternal instance for this object. virtual WebFrameInternal* GetWebFrameInternal() = 0;
diff --git a/ios/web/test/fakes/fake_web_frame_impl.cc b/ios/web/test/fakes/fake_web_frame_impl.cc index 80d01da..2f9e320d 100644 --- a/ios/web/test/fakes/fake_web_frame_impl.cc +++ b/ios/web/test/fakes/fake_web_frame_impl.cc
@@ -145,6 +145,10 @@ return CallJavaScriptFunction(name, parameters, std::move(callback), timeout); } +bool FakeWebFrameImpl::ExecuteJavaScript(const std::string& script) { + return false; +} + void FakeWebFrameImpl::AddJsResultForFunctionCall( base::Value* js_result, const std::string& function_name) {
diff --git a/ios/web/test/fakes/fake_web_frame_impl.h b/ios/web/test/fakes/fake_web_frame_impl.h index c52ef31..0d028845 100644 --- a/ios/web/test/fakes/fake_web_frame_impl.h +++ b/ios/web/test/fakes/fake_web_frame_impl.h
@@ -41,6 +41,7 @@ const std::vector<base::Value>& parameters, base::OnceCallback<void(const base::Value*)> callback, base::TimeDelta timeout) override; + bool ExecuteJavaScript(const std::string& script) override; // FakeWebFrame: std::string GetLastJavaScriptCall() const override;
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index fb0b5b9..7994638 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -117,7 +117,7 @@ // The web::PageDisplayState recorded when the page starts loading. web::PageDisplayState _displayStateOnStartLoading; // Whether or not the page has zoomed since the current navigation has been - // committed, either by user interaction or via |-restoreStateFromHistory|. + // committed by user interaction. BOOL _pageHasZoomed; // Whether a PageDisplayState is currently being applied. BOOL _applyingPageState; @@ -230,9 +230,6 @@ // may be called multiple times and thus must be idempotent. - (void)loadCompleteWithSuccess:(BOOL)loadSuccess forContext:(web::NavigationContextImpl*)context; - -// Restores the state for this page from session history. -- (void)restoreStateFromHistory; // Extracts the current page's viewport tag information and calls |completion|. // If the page has changed before the viewport tag is successfully extracted, // |completion| is called with nullptr. @@ -1238,12 +1235,6 @@ #pragma mark - Page State -- (void)restoreStateFromHistory { - web::NavigationItem* item = self.currentNavItem; - if (item) - self.pageDisplayState = item->GetPageDisplayState(); -} - - (void)extractViewportTagWithCompletion:(ViewportStateCompletion)completion { DCHECK(completion); web::NavigationItem* currentItem = self.currentNavItem; @@ -1949,11 +1940,6 @@ self.webView.allowsBackForwardNavigationGestures = NO; } -- (void)webRequestControllerRestoreStateFromHistory: - (CRWWebRequestController*)requestController { - [self restoreStateFromHistory]; -} - - (CRWWKNavigationHandler*)webRequestControllerNavigationHandler: (CRWWebRequestController*)requestController { return self.navigationHandler;
diff --git a/ios/web/web_state/ui/crw_web_request_controller.h b/ios/web/web_state/ui/crw_web_request_controller.h index 41a1fa8b..df44272 100644 --- a/ios/web/web_state/ui/crw_web_request_controller.h +++ b/ios/web/web_state/ui/crw_web_request_controller.h
@@ -39,11 +39,6 @@ - (void)webRequestControllerDisableNavigationGesturesUntilFinishNavigation: (CRWWebRequestController*)requestController; -// Tells the delegate to restores the state for current page from session -// history. -- (void)webRequestControllerRestoreStateFromHistory: - (CRWWebRequestController*)requestController; - - (CRWWKNavigationHandler*)webRequestControllerNavigationHandler: (CRWWebRequestController*)requestController;
diff --git a/ios/web/web_state/ui/crw_web_request_controller.mm b/ios/web/web_state/ui/crw_web_request_controller.mm index 0673edb..8695e94 100644 --- a/ios/web/web_state/ui/crw_web_request_controller.mm +++ b/ios/web/web_state/ui/crw_web_request_controller.mm
@@ -362,9 +362,6 @@ context:(nullable const web::NavigationContextImpl*)context { DCHECK_EQ(web::WKNavigationState::FINISHED, self.navigationHandler.navigationState); - - [_delegate webRequestControllerRestoreStateFromHistory:self]; - // Placeholder and restore session URLs are implementation details so should // not notify WebStateObservers. If |context| is nullptr, don't skip // placeholder URLs because this may be the only opportunity to update
diff --git a/media/gpu/sandbox/hardware_video_decoding_sandbox_hook_linux.cc b/media/gpu/sandbox/hardware_video_decoding_sandbox_hook_linux.cc index 87f284c8..38ba788 100644 --- a/media/gpu/sandbox/hardware_video_decoding_sandbox_hook_linux.cc +++ b/media/gpu/sandbox/hardware_video_decoding_sandbox_hook_linux.cc
@@ -115,7 +115,11 @@ } } #elif BUILDFLAG(USE_LIBV4L2) +#if defined(__aarch64__) + dlopen("/usr/lib64/libv4l2.so", RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE); +#else dlopen("/usr/lib/libv4l2.so", RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE); +#endif // defined(__aarch64__) #endif // BUILDFLAG(USE_VAAPI) return true;
diff --git a/remoting/client/notification/notification_client.cc b/remoting/client/notification/notification_client.cc index 403d403..37a69cd 100644 --- a/remoting/client/notification/notification_client.cc +++ b/remoting/client/notification/notification_client.cc
@@ -116,7 +116,18 @@ int percent_int) { DCHECK_GE(percent_int, 0); DCHECK_LE(percent_int, 100); - return (base::FastHash(user_email) % 100) < + + // If the user is not logged in, we only want to show the notification if the + // rollout percentage is 100. `hash("") % 100` could be anything between + // [0, 99] and may therefore get selected for a lower percentage, so we add + // special-casing for percent_int != 100. + // For percent_int == 100, `hash(any_string) % 100` is always smaller than + // 100, so no special-casing is needed. + if (user_email.empty() && percent_int != 100) { + return false; + } + + return (base::PersistentHash(user_email) % 100) < static_cast<unsigned int>(percent_int); }
diff --git a/remoting/client/notification/notification_client.h b/remoting/client/notification/notification_client.h index 32dfcab..5d4c2e01 100644 --- a/remoting/client/notification/notification_client.h +++ b/remoting/client/notification/notification_client.h
@@ -41,6 +41,10 @@ // notification is found then absl::nullopt will be returned. |callback| will // be silently dropped if |this| is deleted before the notification is // fetched. + // |user_email| is used to determine if the notification is available to the + // user during percentage rollout. If |user_email| is empty (i.e. user not + // logged in), the notification percentage must be exactly 100 for the + // notification to become available. void GetNotification(const std::string& user_email, NotificationCallback callback);
diff --git a/remoting/client/notification/notification_client_unittest.cc b/remoting/client/notification/notification_client_unittest.cc index ec3706588..064aaf73 100644 --- a/remoting/client/notification/notification_client_unittest.cc +++ b/remoting/client/notification/notification_client_unittest.cc
@@ -362,4 +362,36 @@ client_->GetNotification(kTestEmail, callback.Get()); } +TEST_F(NotificationClientTest, + EmptyUserEmailAndNot100PercentRollout_NoNotification) { + base::Value rules(base::Value::Type::LIST); + base::Value rule = CreateDefaultRule(); + rule.SetIntKey("percent", 99); + rules.Append(std::move(rule)); + EXPECT_CALL(*fetcher_, FetchJsonFile("notification/rules.json")) + .WillOnce(ReturnByMove(std::move(rules))); + + base::MockCallback<NotificationClient::NotificationCallback> callback; + EXPECT_CALL(callback, Run(NoMessage())); + client_->GetNotification(/* user_email= */ "", callback.Get()); +} + +TEST_F(NotificationClientTest, + EmptyUserEmailAnd100PercentRollout_ReturnsNotification) { + base::Value rules(base::Value::Type::LIST); + base::Value rule = CreateDefaultRule(); + rule.SetIntKey("percent", 100); + rules.Append(std::move(rule)); + EXPECT_CALL(*fetcher_, FetchJsonFile("notification/rules.json")) + .WillOnce(ReturnByMove(std::move(rules))); + EXPECT_CALL(*fetcher_, FetchJsonFile("notification/message_text.json")) + .WillOnce(ReturnByMove(CreateDefaultTranslations("message"))); + EXPECT_CALL(*fetcher_, FetchJsonFile("notification/link_text.json")) + .WillOnce(ReturnByMove(CreateDefaultTranslations("link"))); + + base::MockCallback<NotificationClient::NotificationCallback> callback; + EXPECT_CALL(callback, Run(MessageMatches(CreateDefaultNotification()))); + client_->GetNotification(/* user_email= */ "", callback.Get()); +} + } // namespace remoting \ No newline at end of file
diff --git a/remoting/ios/app/notification_presenter.h b/remoting/ios/app/notification_presenter.h index a460b6d..ea34694 100644 --- a/remoting/ios/app/notification_presenter.h +++ b/remoting/ios/app/notification_presenter.h
@@ -41,7 +41,7 @@ NotificationPresenter(); ~NotificationPresenter() = delete; - void FetchNotificationIfNecessary(); + void FetchNotification(); void OnNotificationFetched(absl::optional<NotificationMessage> notification); NotificationClient notification_client_;
diff --git a/remoting/ios/app/notification_presenter.mm b/remoting/ios/app/notification_presenter.mm index ff3abb8c..6ddf6a7 100644 --- a/remoting/ios/app/notification_presenter.mm +++ b/remoting/ios/app/notification_presenter.mm
@@ -65,9 +65,7 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!user_update_observer_); - if ([RemotingService.instance.authentication.user isAuthenticated]) { - FetchNotificationIfNecessary(); - } + FetchNotification(); user_update_observer_ = [NSNotificationCenter.defaultCenter addObserverForName:kUserDidUpdate object:nil @@ -75,23 +73,24 @@ usingBlock:^(NSNotification*) { // This implicitly captures |this|, but should be fine since // |NotificationPresenter| is singleton. - FetchNotificationIfNecessary(); + FetchNotification(); }]; } -void NotificationPresenter::FetchNotificationIfNecessary() { +void NotificationPresenter::FetchNotification() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (state_ != State::NOT_FETCHED) { + if (state_ == State::FETCHED) { return; } UserInfo* user = RemotingService.instance.authentication.user; - if (![user isAuthenticated]) { - // Can't show notification since user email is unknown. - return; - } + std::string user_email = [user isAuthenticated] + ? base::SysNSStringToUTF8(user.userEmail) + : std::string(); state_ = State::FETCHING; + // If FetchNotification() is called when the timer is already running, this + // will restart the timer with the new user email. fetch_notification_timer_.Start( FROM_HERE, kFetchNotificationDelay, base::BindOnce( @@ -101,7 +100,7 @@ base::BindOnce(&NotificationPresenter::OnNotificationFetched, base::Unretained(that))); }, - base::Unretained(this), base::SysNSStringToUTF8(user.userEmail))); + base::Unretained(this), user_email)); } void NotificationPresenter::OnNotificationFetched(
diff --git a/services/preferences/public/cpp/dictionary_value_update.cc b/services/preferences/public/cpp/dictionary_value_update.cc index 65c70097..0ced2b5d 100644 --- a/services/preferences/public/cpp/dictionary_value_update.cc +++ b/services/preferences/public/cpp/dictionary_value_update.cc
@@ -92,8 +92,8 @@ base::StringPiece path, std::unique_ptr<base::DictionaryValue> in_value) { RecordPath(path); - base::DictionaryValue* dictionary_value = - value_->SetDictionary(path, std::move(in_value)); + auto* dictionary_value = static_cast<base::DictionaryValue*>(value_->SetPath( + path, base::Value::FromUniquePtrValue(std::move(in_value)))); return std::make_unique<DictionaryValueUpdate>( report_update_, dictionary_value, ConcatPath(path_, path));
diff --git a/services/preferences/tracked/dictionary_hash_store_contents.cc b/services/preferences/tracked/dictionary_hash_store_contents.cc index 74315fd..5df7bc2 100644 --- a/services/preferences/tracked/dictionary_hash_store_contents.cc +++ b/services/preferences/tracked/dictionary_hash_store_contents.cc
@@ -88,11 +88,10 @@ const std::string& split_path, const std::string& value) { base::DictionaryValue* macs_dict = GetMutableContents(true); - base::DictionaryValue* split_dict = nullptr; - macs_dict->GetDictionary(path, &split_dict); + base::Value* split_dict = macs_dict->FindDictPath(path); if (!split_dict) { - split_dict = macs_dict->SetDictionary( - path, std::make_unique<base::DictionaryValue>()); + split_dict = + macs_dict->SetPath(path, base::Value(base::Value::Type::DICTIONARY)); } split_dict->SetKey(split_path, base::Value(value)); } @@ -132,8 +131,8 @@ base::DictionaryValue* macs_dict = NULL; storage_->GetDictionary(kPreferenceMACs, &macs_dict); if (!macs_dict && create_if_null) { - macs_dict = storage_->SetDictionary( - kPreferenceMACs, std::make_unique<base::DictionaryValue>()); + macs_dict = static_cast<base::DictionaryValue*>(storage_->SetPath( + kPreferenceMACs, base::Value(base::Value::Type::DICTIONARY))); } return macs_dict; }
diff --git a/services/preferences/tracked/pref_hash_filter_unittest.cc b/services/preferences/tracked/pref_hash_filter_unittest.cc index 9f9bca3..8ffad5c 100644 --- a/services/preferences/tracked/pref_hash_filter_unittest.cc +++ b/services/preferences/tracked/pref_hash_filter_unittest.cc
@@ -735,10 +735,10 @@ TEST_P(PrefHashFilterTest, FilterSplitPrefUpdate) { base::DictionaryValue root_dict; - base::DictionaryValue* dict_value = root_dict.SetDictionary( - kSplitPref, std::make_unique<base::DictionaryValue>()); - dict_value->SetString("a", "foo"); - dict_value->SetInteger("b", 1234); + base::Value* dict_value = + root_dict.SetKey(kSplitPref, base::Value(base::Value::Type::DICTIONARY)); + dict_value->SetStringKey("a", "foo"); + dict_value->SetIntKey("b", 1234); // No path should be stored on FilterUpdate. pref_hash_filter_->FilterUpdate(kSplitPref); @@ -800,9 +800,9 @@ root_dict.SetInteger(kAtomicPref2, 2); root_dict.SetInteger(kAtomicPref3, 3); root_dict.SetInteger("untracked", 4); - base::DictionaryValue* dict_value = root_dict.SetDictionary( - kSplitPref, std::make_unique<base::DictionaryValue>()); - dict_value->SetBoolean("a", true); + base::Value* dict_value = + root_dict.SetKey(kSplitPref, base::Value(base::Value::Type::DICTIONARY)); + dict_value->SetBoolKey("a", true); // Only update kAtomicPref, kAtomicPref3, and kSplitPref. pref_hash_filter_->FilterUpdate(kAtomicPref); @@ -882,10 +882,10 @@ base::Value* string_value = pref_store_contents_->SetString(kAtomicPref, "string value"); - base::DictionaryValue* dict_value = pref_store_contents_->SetDictionary( - kSplitPref, std::make_unique<base::DictionaryValue>()); - dict_value->SetString("a", "foo"); - dict_value->SetInteger("b", 1234); + base::Value* dict_value = pref_store_contents_->SetKey( + kSplitPref, base::Value(base::Value::Type::DICTIONARY)); + dict_value->SetStringKey("a", "foo"); + dict_value->SetIntKey("b", 1234); ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref, NULL)); ASSERT_TRUE(pref_store_contents_->Get(kSplitPref, NULL)); @@ -947,10 +947,10 @@ base::Value* string_value = pref_store_contents_->SetString(kAtomicPref, "test"); - auto* dict_value = pref_store_contents_->SetDictionary( - kSplitPref, std::make_unique<base::DictionaryValue>()); - dict_value->SetString("a", "foo"); - dict_value->SetInteger("b", 1234); + auto* dict_value = pref_store_contents_->SetKey( + kSplitPref, base::Value(base::Value::Type::DICTIONARY)); + dict_value->SetStringKey("a", "foo"); + dict_value->SetIntKey("b", 1234); ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref, NULL)); ASSERT_TRUE(pref_store_contents_->Get(kSplitPref, NULL)); @@ -995,12 +995,12 @@ TEST_P(PrefHashFilterTest, InitialValueChanged) { base::Value* int_value = pref_store_contents_->SetInteger(kAtomicPref, 1234); - base::DictionaryValue* dict_value = pref_store_contents_->SetDictionary( - kSplitPref, std::make_unique<base::DictionaryValue>()); - dict_value->SetString("a", "foo"); - dict_value->SetInteger("b", 1234); - dict_value->SetInteger("c", 56); - dict_value->SetBoolean("d", false); + base::Value* dict_value = pref_store_contents_->SetKey( + kSplitPref, base::Value(base::Value::Type::DICTIONARY)); + dict_value->SetStringKey("a", "foo"); + dict_value->SetIntKey("b", 1234); + dict_value->SetIntKey("c", 56); + dict_value->SetBoolKey("d", false); ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref, NULL)); ASSERT_TRUE(pref_store_contents_->Get(kSplitPref, NULL)); @@ -1104,10 +1104,10 @@ base::Value* string_value = pref_store_contents_->SetString(kAtomicPref, "string value"); - base::DictionaryValue* dict_value = pref_store_contents_->SetDictionary( - kSplitPref, std::make_unique<base::DictionaryValue>()); - dict_value->SetString("a", "foo"); - dict_value->SetInteger("b", 1234); + base::Value* dict_value = pref_store_contents_->SetKey( + kSplitPref, base::Value(base::Value::Type::DICTIONARY)); + dict_value->SetStringKey("a", "foo"); + dict_value->SetIntKey("b", 1234); ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref, NULL)); ASSERT_TRUE(pref_store_contents_->Get(kSplitPref, NULL)); @@ -1158,10 +1158,9 @@ base::Value* int_value2 = pref_store_contents_->SetInteger(kAtomicPref2, 2); base::Value* report_only_val = pref_store_contents_->SetInteger(kReportOnlyPref, 3); - base::DictionaryValue* report_only_split_val = - pref_store_contents_->SetDictionary( - kReportOnlySplitPref, std::make_unique<base::DictionaryValue>()); - report_only_split_val->SetInteger("a", 1234); + base::Value* report_only_split_val = pref_store_contents_->SetKey( + kReportOnlySplitPref, base::Value(base::Value::Type::DICTIONARY)); + report_only_split_val->SetIntKey("a", 1234); ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref, NULL)); ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref2, NULL));
diff --git a/testing/scripts/test_traffic_annotation_auditor.py b/testing/scripts/test_traffic_annotation_auditor.py index 2d47de1..5400eb6 100755 --- a/testing/scripts/test_traffic_annotation_auditor.py +++ b/testing/scripts/test_traffic_annotation_auditor.py
@@ -63,7 +63,7 @@ if pattern.search(gn_args): return "chromeos" - except(valueError, OSError) as e: + except(ValueError, OSError) as e: logger.info(e) return None @@ -108,13 +108,13 @@ annotations_filename, ] rc = common.run_command(command_line) + cleanup_file(config_filename) else: print("Test failed without updating the annotations sheet.") - except (valueError, OSError) as e: + except (ValueError, OSError) as e: print("Error updating the annotations sheet", e) finally: cleanup_file(annotations_filename) - cleanup_file(config_filename) failures = ['Please refer to stdout for errors.'] if rc else [] common.record_local_script_results( 'test_traffic_annotation_auditor', args.output, failures, True)
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index 0fda834..4df552a 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -1074,6 +1074,10 @@ const base::Feature kForceMinorVersion100InUserAgent{ "ForceMinorVersion100InUserAgent", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kForceMajorVersionInMinorPositionInUserAgent{ + "ForceMajorVersionInMinorPositionInUserAgent", + base::FEATURE_DISABLED_BY_DEFAULT}; + // Enable `sec-ch-device-memory` client hint. const base::Feature kClientHintsDeviceMemory{"ClientHintsDeviceMemory", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h index 974d9a9..93e4c8ad0 100644 --- a/third_party/blink/public/common/features.h +++ b/third_party/blink/public/common/features.h
@@ -495,6 +495,14 @@ BLINK_COMMON_EXPORT extern const base::FeatureParam<double> kCostReductionOfMultiplexedRequests; +// If enabled, the major version number returned by Chrome will be locked at +// 99. The minor version number returned by Chrome will be forced to the +// value of the major version number. The purpose of this +// feature is a back up plan for if the major version moving from +// two to three digits breaks unexpected things. +BLINK_COMMON_EXPORT extern const base::Feature + kForceMajorVersionInMinorPositionInUserAgent; + // If enabled, the minor version number returned by Chrome will be forced to // 100. This feature is only applicable for M96-M99 and will be removed after // M99. The purpose of this feature is to allow testing of mitigation
diff --git a/third_party/blink/public/mojom/web_launch/web_launch.mojom b/third_party/blink/public/mojom/web_launch/web_launch.mojom index 1ce7aecf..e9e7b42 100644 --- a/third_party/blink/public/mojom/web_launch/web_launch.mojom +++ b/third_party/blink/public/mojom/web_launch/web_launch.mojom
@@ -9,7 +9,7 @@ // Interface for getting the cause of page loads to blink. This service lives // in blink and is used to implement the File Handling proposal: -// https://github.com/WICG/file-handling/blob/master/explainer.md +// https://github.com/WICG/file-handling/blob/main/explainer.md // TODO(crbug.com/829689): Replace link to explainer with link to spec, when // available. //
diff --git a/third_party/blink/renderer/core/content_capture/content_capture_task.cc b/third_party/blink/renderer/core/content_capture/content_capture_task.cc index dfb4281b..b1e1fe2 100644 --- a/third_party/blink/renderer/core/content_capture/content_capture_task.cc +++ b/third_party/blink/renderer/core/content_capture/content_capture_task.cc
@@ -17,7 +17,6 @@ #include "third_party/blink/renderer/core/frame/local_frame_client.h" #include "third_party/blink/renderer/core/layout/layout_text.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/wtf/functional.h"
diff --git a/third_party/blink/renderer/core/css/mock_css_paint_image_generator.h b/third_party/blink/renderer/core/css/mock_css_paint_image_generator.h index e126764e..2aa9aa1 100644 --- a/third_party/blink/renderer/core/css/mock_css_paint_image_generator.h +++ b/third_party/blink/renderer/core/css/mock_css_paint_image_generator.h
@@ -8,6 +8,7 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/core/css/css_paint_image_generator.h" +#include "third_party/blink/renderer/platform/graphics/image.h" using testing::ReturnRef;
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context.cc b/third_party/blink/renderer/core/display_lock/display_lock_context.cc index 5dd9647..803d7a06 100644 --- a/third_party/blink/renderer/core/display_lock/display_lock_context.cc +++ b/third_party/blink/renderer/core/display_lock/display_lock_context.cc
@@ -27,7 +27,6 @@ #include "third_party/blink/renderer/core/inspector/inspector_trace_events.h" #include "third_party/blink/renderer/core/layout/layout_object.h" #include "third_party/blink/renderer/core/page/page.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/pre_paint_tree_walk.h" #include "third_party/blink/renderer/platform/bindings/microtask.h"
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc b/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc index 9f20015..6d2ba7d 100644 --- a/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc +++ b/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc
@@ -30,7 +30,6 @@ #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" #include "third_party/blink/renderer/core/geometry/dom_rect.h" #include "third_party/blink/renderer/core/html/html_template_element.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
diff --git a/third_party/blink/renderer/core/document_transition/document_transition_test.cc b/third_party/blink/renderer/core/document_transition/document_transition_test.cc index d140b2f..d8b10bbf 100644 --- a/third_party/blink/renderer/core/document_transition/document_transition_test.cc +++ b/third_party/blink/renderer/core/document_transition/document_transition_test.cc
@@ -16,7 +16,6 @@ #include "third_party/blink/renderer/core/dom/abort_signal.h" #include "third_party/blink/renderer/core/frame/frame_test_helpers.h" #include "third_party/blink/renderer/core/html/html_element.h" -#include "third_party/blink/renderer/core/paint/compositing/compositing_state.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h" #include "third_party/blink/renderer/platform/testing/find_cc_layer.h"
diff --git a/third_party/blink/renderer/core/editing/finder/text_finder_test.cc b/third_party/blink/renderer/core/editing/finder/text_finder_test.cc index 7e390a372..298f043 100644 --- a/third_party/blink/renderer/core/editing/finder/text_finder_test.cc +++ b/third_party/blink/renderer/core/editing/finder/text_finder_test.cc
@@ -32,6 +32,7 @@ #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/testing/testing_platform_support.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" +#include "third_party/blink/renderer/platform/wtf/text/string_builder.h" namespace blink {
diff --git a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc index 87720e55..4f856cf5 100644 --- a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc +++ b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
@@ -68,7 +68,6 @@ #include "third_party/blink/renderer/core/page/page_popup_controller.h" #include "third_party/blink/renderer/platform/animation/compositor_animation_timeline.h" #include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
diff --git a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc index d677276..aadbc75 100644 --- a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc +++ b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
@@ -97,7 +97,6 @@ #include "third_party/blink/renderer/platform/exported/wrapped_resource_response.h" #include "third_party/blink/renderer/platform/geometry/layout_rect.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/graphics/paint/cull_rect.h" #include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h" #include "third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h"
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.h b/third_party/blink/renderer/core/exported/web_view_impl.h index cce6788b0..25f9a9f 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.h +++ b/third_party/blink/renderer/core/exported/web_view_impl.h
@@ -66,7 +66,6 @@ #include "third_party/blink/renderer/core/page/page_widget_delegate.h" #include "third_party/blink/renderer/core/page/scoped_page_pauser.h" #include "third_party/blink/renderer/platform/graphics/apply_viewport_changes.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/graphics/touch_action.h" #include "third_party/blink/renderer/platform/heap/member.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h"
diff --git a/third_party/blink/renderer/core/exported/web_view_test.cc b/third_party/blink/renderer/core/exported/web_view_test.cc index 57a0437..42089dc 100644 --- a/third_party/blink/renderer/core/exported/web_view_test.cc +++ b/third_party/blink/renderer/core/exported/web_view_test.cc
@@ -144,7 +144,6 @@ #include "third_party/blink/renderer/platform/cursors.h" #include "third_party/blink/renderer/platform/graphics/color.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h" #include "third_party/blink/renderer/platform/heap/thread_state.h" #include "third_party/blink/renderer/platform/keyboard_codes.h"
diff --git a/third_party/blink/renderer/core/frame/browser_controls_test.cc b/third_party/blink/renderer/core/frame/browser_controls_test.cc index 8ea1078..58b4cb0 100644 --- a/third_party/blink/renderer/core/frame/browser_controls_test.cc +++ b/third_party/blink/renderer/core/frame/browser_controls_test.cc
@@ -45,7 +45,6 @@ #include "third_party/blink/renderer/core/geometry/dom_rect.h" #include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/page/page.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
diff --git a/third_party/blink/renderer/core/frame/frame_overlay_test.cc b/third_party/blink/renderer/core/frame/frame_overlay_test.cc index 6036152a..a89f1b9 100644 --- a/third_party/blink/renderer/core/frame/frame_overlay_test.cc +++ b/third_party/blink/renderer/core/frame/frame_overlay_test.cc
@@ -18,7 +18,6 @@ #include "third_party/blink/renderer/platform/graphics/color.h" #include "third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
diff --git a/third_party/blink/renderer/core/frame/frame_serializer_test.cc b/third_party/blink/renderer/core/frame/frame_serializer_test.cc index 61dedc2f..343a75dc 100644 --- a/third_party/blink/renderer/core/frame/frame_serializer_test.cc +++ b/third_party/blink/renderer/core/frame/frame_serializer_test.cc
@@ -51,6 +51,7 @@ #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" #include "third_party/blink/renderer/platform/testing/url_test_helpers.h" #include "third_party/blink/renderer/platform/wtf/deque.h" +#include "third_party/blink/renderer/platform/wtf/text/string_builder.h" #include "third_party/blink/renderer/platform/wtf/vector.h" namespace blink {
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index 8816d71..69df0491 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -177,8 +177,6 @@ #include "third_party/blink/renderer/platform/bindings/v8_binding.h" #include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h" #include "third_party/blink/renderer/platform/blob/blob_data.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer_tree_as_text.h" #include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc index 2aa486d3..4676203 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -129,7 +129,6 @@ #include "third_party/blink/renderer/core/page/spatial_navigation_controller.h" #include "third_party/blink/renderer/core/page/validation_message_client.h" #include "third_party/blink/renderer/core/paint/block_paint_invalidator.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/cull_rect_updater.h" #include "third_party/blink/renderer/core/paint/frame_painter.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" @@ -155,7 +154,6 @@ #include "third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h" #include "third_party/blink/renderer/platform/graphics/dark_mode_settings_builder.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/graphics/paint/cull_rect.h" #include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_chunk_subset_recorder.h" @@ -1178,8 +1176,8 @@ background_attachment_fixed_objects_.begin()->Get()); // We should not add such object in the set. DCHECK(!object->BackgroundTransfersToView()); - // If the background is viewport background and it paints onto the main - // graphics layer only, then it doesn't need main thread scrolling. + // If the background is viewport background and it paints onto the border box + // space only, then it doesn't need main thread scrolling. if (IsA<LayoutView>(object) && object->GetBackgroundPaintLocation() == kBackgroundPaintInBorderBoxSpace) return false; @@ -2939,9 +2937,6 @@ } void LocalFrameView::CreatePaintTimelineEvents() { - // For pre-CAP, this is done in CompositedLayerMapping::PaintContents() - if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) - return; if (const cc::Layer* root_layer = paint_artifact_compositor_->RootLayer()) { for (const auto& layer : root_layer->children()) { if (!layer->update_rect().IsEmpty()) {
diff --git a/third_party/blink/renderer/core/frame/remote_frame.cc b/third_party/blink/renderer/core/frame/remote_frame.cc index f41715a1..b114ad27 100644 --- a/third_party/blink/renderer/core/frame/remote_frame.cc +++ b/third_party/blink/renderer/core/frame/remote_frame.cc
@@ -55,7 +55,6 @@ #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/core/timing/dom_window_performance.h" #include "third_party/blink/renderer/platform/exported/wrapped_resource_request.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object.h"
diff --git a/third_party/blink/renderer/core/frame/web_frame_test.cc b/third_party/blink/renderer/core/frame/web_frame_test.cc index 66cf13aa..e910a7b 100644 --- a/third_party/blink/renderer/core/frame/web_frame_test.cc +++ b/third_party/blink/renderer/core/frame/web_frame_test.cc
@@ -43,6 +43,7 @@ #include "cc/input/overscroll_behavior.h" #include "cc/layers/picture_layer.h" #include "cc/paint/paint_op_buffer.h" +#include "cc/paint/paint_recorder.h" #include "cc/trees/layer_tree_host.h" #include "cc/trees/scroll_node.h" #include "mojo/public/cpp/bindings/pending_remote.h" @@ -169,7 +170,6 @@ #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/page/scoped_page_pauser.h" #include "third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/core/scroll/scrollbar.h" @@ -188,7 +188,6 @@ #include "third_party/blink/renderer/platform/bindings/microtask.h" #include "third_party/blink/renderer/platform/blob/testing/fake_blob.h" #include "third_party/blink/renderer/platform/exported/wrapped_resource_request.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/keyboard_codes.h" #include "third_party/blink/renderer/platform/loader/fetch/fetch_context.h" #include "third_party/blink/renderer/platform/loader/fetch/raw_resource.h" @@ -13431,7 +13430,7 @@ gfx::Size page_size(500, 500); print_params.print_content_area.set_size(page_size); EXPECT_EQ(1u, frame->PrintBegin(print_params, WebNode())); - PaintRecorder recorder; + cc::PaintRecorder recorder; frame->PrintPagesForTesting(recorder.beginRecording(SkRect::MakeEmpty()), page_size, page_size); frame->PrintEnd(); @@ -13509,7 +13508,7 @@ print_params.print_content_area.set_size(page_size); WebLocalFrameImpl* frame = web_view_helper.LocalMainFrame(); EXPECT_EQ(1u, frame->PrintBegin(print_params, WebNode())); - PaintRecorder recorder; + cc::PaintRecorder recorder; frame->PrintPagesForTesting(recorder.beginRecording(SkRect::MakeEmpty()), page_size, page_size); frame->PrintEnd();
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc index 643e74f0..edb4d72 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -244,7 +244,6 @@ #include "third_party/blink/renderer/platform/fonts/font_cache.h" #include "third_party/blink/renderer/platform/graphics/color.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer_client.h" #include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h" #include "third_party/blink/renderer/platform/graphics/paint/scoped_paint_chunk_properties.h"
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc index bc6343ee..ad59358 100644 --- a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc +++ b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc
@@ -316,7 +316,8 @@ SkColorInfo CanvasRenderingContextHost::GetRenderingContextSkColorInfo() const { if (RenderingContext()) return RenderingContext()->CanvasRenderingContextSkColorInfo(); - return SkColorInfo(kN32_SkColorType, kPremul_SkAlphaType, nullptr); + return SkColorInfo(kN32_SkColorType, kPremul_SkAlphaType, + SkColorSpace::MakeSRGB()); } ScriptPromise CanvasRenderingContextHost::convertToBlob(
diff --git a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc index 98f1587..2e45c9dc 100644 --- a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc +++ b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
@@ -98,7 +98,6 @@ #include "third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.h" #include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h" #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/graphics/image_data_buffer.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h" #include "third_party/blink/renderer/platform/graphics/static_bitmap_image_to_video_frame_copier.h"
diff --git a/third_party/blink/renderer/core/html/media/html_media_element.cc b/third_party/blink/renderer/core/html/media/html_media_element.cc index f8933bf..50e9fb15 100644 --- a/third_party/blink/renderer/core/html/media/html_media_element.cc +++ b/third_party/blink/renderer/core/html/media/html_media_element.cc
@@ -36,6 +36,7 @@ #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/time/time.h" +#include "cc/layers/layer.h" #include "media/base/logging_override_if_enabled.h" #include "media/base/media_content_type.h" #include "media/base/media_switches.h" @@ -114,7 +115,6 @@ #include "third_party/blink/renderer/platform/bindings/exception_messages.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/microtask.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h" @@ -4290,7 +4290,6 @@ if (cc_layer == cc_layer_) return; - // We need to update the GraphicsLayer when the cc layer changes. SetNeedsCompositingUpdate(); cc_layer_ = cc_layer; }
diff --git a/third_party/blink/renderer/core/inspector/dev_tools_emulator.cc b/third_party/blink/renderer/core/inspector/dev_tools_emulator.cc index 2fc009e..d920bf2 100644 --- a/third_party/blink/renderer/core/inspector/dev_tools_emulator.cc +++ b/third_party/blink/renderer/core/inspector/dev_tools_emulator.cc
@@ -18,7 +18,6 @@ #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/scroll/scrollbar_theme.h" #include "third_party/blink/renderer/core/style/computed_style.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "ui/gfx/geometry/rect.h"
diff --git a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc index b970a55..5186c92e 100644 --- a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc
@@ -34,6 +34,7 @@ #include "base/auto_reset.h" #include "build/build_config.h" +#include "cc/layers/content_layer_client.h" #include "cc/layers/picture_layer.h" #include "third_party/blink/public/common/tokens/tokens.h" #include "third_party/blink/public/platform/platform.h"
diff --git a/third_party/blink/renderer/core/inspector/inspector_trace_events.cc b/third_party/blink/renderer/core/inspector/inspector_trace_events.cc index cf339cf..96cbd46 100644 --- a/third_party/blink/renderer/core/inspector/inspector_trace_events.cc +++ b/third_party/blink/renderer/core/inspector/inspector_trace_events.cc
@@ -35,7 +35,6 @@ #include "third_party/blink/renderer/core/workers/worker_global_scope.h" #include "third_party/blink/renderer/core/workers/worker_thread.h" #include "third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/instrumentation/instance_counters.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_load_priority.h"
diff --git a/third_party/blink/renderer/core/layout/layout_box_model_object.cc b/third_party/blink/renderer/core/layout/layout_box_model_object.cc index bce26b78..a722891 100644 --- a/third_party/blink/renderer/core/layout/layout_box_model_object.cc +++ b/third_party/blink/renderer/core/layout/layout_box_model_object.cc
@@ -41,7 +41,6 @@ #include "third_party/blink/renderer/core/layout/ng/legacy_layout_tree_walking.h" #include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h" #include "third_party/blink/renderer/core/layout/ng/ng_layout_result.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/object_paint_invalidator.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc index 917c0a0..db7c59b 100644 --- a/third_party/blink/renderer/core/layout/layout_object.cc +++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -111,7 +111,6 @@ #include "third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h" #include "third_party/blink/renderer/core/style/content_data.h" #include "third_party/blink/renderer/core/style/cursor_data.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h" #include "third_party/blink/renderer/platform/graphics/paint/property_tree_state.h" #include "third_party/blink/renderer/platform/graphics/touch_action.h" @@ -1850,13 +1849,6 @@ return GetNode() ? DOMNodeIds::IdForNode(GetNode()) : kInvalidDOMNodeId; } -bool LayoutObject::IsPaintInvalidationContainer() const { - NOT_DESTROYED(); - return HasLayer() && To<LayoutBoxModelObject>(this) - ->Layer() - ->IsPaintInvalidationContainer(); -} - void LayoutObject::InvalidateDisplayItemClients( PaintInvalidationReason reason) const { NOT_DESTROYED(); @@ -4035,13 +4027,6 @@ return CreatePositionWithAffinity(0); } -CompositingState LayoutObject::GetCompositingState() const { - NOT_DESTROYED(); - return HasLayer() - ? To<LayoutBoxModelObject>(this)->Layer()->GetCompositingState() - : kNotComposited; -} - bool LayoutObject::CanHaveAdditionalCompositingReasons() const { NOT_DESTROYED(); return false;
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h index 9ca6575..509f78eb 100644 --- a/third_party/blink/renderer/core/layout/layout_object.h +++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -52,7 +52,6 @@ #include "third_party/blink/renderer/core/layout/ng/ng_style_variant.h" #include "third_party/blink/renderer/core/layout/subtree_layout_scope.h" #include "third_party/blink/renderer/core/loader/resource/image_resource_observer.h" -#include "third_party/blink/renderer/core/paint/compositing/compositing_state.h" #include "third_party/blink/renderer/core/paint/fragment_data.h" #include "third_party/blink/renderer/core/paint/paint_phase.h" #include "third_party/blink/renderer/core/style/computed_style.h" @@ -2252,8 +2251,6 @@ virtual void AddAnnotatedRegions(Vector<AnnotatedRegionValue>&); - CompositingState GetCompositingState() const; - // True for object types which override |AdditionalCompositingReasons|. virtual bool CanHaveAdditionalCompositingReasons() const; virtual CompositingReasons AdditionalCompositingReasons() const; @@ -2606,8 +2603,6 @@ virtual CursorDirective GetCursor(const PhysicalOffset&, ui::Cursor&) const; - bool IsPaintInvalidationContainer() const; - // Returns the rect that should have raster invalidated whenever this object // changes. The rect is in the coordinate space of the document's scrolling // contents. This method deals with outlines and overflow.
diff --git a/third_party/blink/renderer/core/layout/layout_shift_tracker.cc b/third_party/blink/renderer/core/layout/layout_shift_tracker.cc index 7588d69..f04b1ce 100644 --- a/third_party/blink/renderer/core/layout/layout_shift_tracker.cc +++ b/third_party/blink/renderer/core/layout/layout_shift_tracker.cc
@@ -23,7 +23,6 @@ #include "third_party/blink/renderer/core/timing/dom_window_performance.h" #include "third_party/blink/renderer/core/timing/performance_entry.h" #include "third_party/blink/renderer/core/timing/window_performance.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h" #include "third_party/blink/renderer/platform/graphics/paint/property_tree_state.h" #include "ui/gfx/geometry/rect.h"
diff --git a/third_party/blink/renderer/core/layout/layout_tree_as_text.cc b/third_party/blink/renderer/core/layout/layout_tree_as_text.cc index 751d5d5..e9633a31 100644 --- a/third_party/blink/renderer/core/layout/layout_tree_as_text.cc +++ b/third_party/blink/renderer/core/layout/layout_tree_as_text.cc
@@ -59,7 +59,6 @@ #include "third_party/blink/renderer/core/layout/svg/layout_svg_text.h" #include "third_party/blink/renderer/core/layout/svg/svg_layout_tree_as_text.h" #include "third_party/blink/renderer/core/page/print_context.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer_paint_order_iterator.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h index a9b9300..8f5f005 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h +++ b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h
@@ -497,7 +497,7 @@ // Same as |base::span<const NGLink>|, except that: // * Each |NGLink| has the latest generation of post-layout. See - // |NGPhysicalFragment::UpdatedFragment()| for more details. + // |NGPhysicalFragment::PostLayout()| for more details. // * The iterator skips fragments for destroyed or moved |LayoutObject|. class PostLayoutChildLinkList { STACK_ALLOCATED();
diff --git a/third_party/blink/renderer/core/layout/scrollbars_test.cc b/third_party/blink/renderer/core/layout/scrollbars_test.cc index f134de38..314e788 100644 --- a/third_party/blink/renderer/core/layout/scrollbars_test.cc +++ b/third_party/blink/renderer/core/layout/scrollbars_test.cc
@@ -26,7 +26,6 @@ #include "third_party/blink/renderer/core/testing/color_scheme_helper.h" #include "third_party/blink/renderer/core/testing/sim/sim_request.h" #include "third_party/blink/renderer/core/testing/sim/sim_test.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/testing/paint_test_configurations.h" #include "third_party/blink/renderer/platform/testing/testing_platform_support.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" @@ -2179,7 +2178,7 @@ request.Complete(R"HTML( <!DOCTYPE html> <style> - /* transform keeps the graphics layer */ + /* transform keeps the composited layer */ #div { width: 100px; height: 100px; will-change: transform; } .scroller{ overflow: scroll; } .big{ height: 2000px; }
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc index d1b3d09..f110012 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc
@@ -613,11 +613,8 @@ NOT_DESTROYED(); auto layer_type_required = LayoutReplaced::LayerTypeRequired(); if (layer_type_required == kNoPaintLayer) { - // Force a paint layer so, - // 1) A GraphicsLayer can be created if there are directly-composited - // descendants. - // 2) The parent layer will know if there are non-isolated descendants with - // blend mode. + // Force a paint layer so the parent layer will know if there are + // non-isolated descendants with blend mode. layer_type_required = kForcedPaintLayer; } return layer_type_required;
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_root_test.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_root_test.cc index fb98878f..bb56a3b 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_root_test.cc +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_root_test.cc
@@ -9,7 +9,6 @@ #include "third_party/blink/renderer/core/layout/svg/svg_layout_support.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/testing/find_cc_layer.h" #include "third_party/blink/renderer/platform/testing/paint_test_configurations.h" @@ -123,10 +122,8 @@ EXPECT_EQ(2, count); } -// A PaintLayer is needed for the purposes of creating a GraphicsLayer to limit -// CompositeSVG to SVG subtrees. This PaintLayer will not be needed with -// CompositeAfterPaint. If compositing is needed for descendants, the paint -// layer should be self-painting. Otherwise, it should be non-self-painting. +// A PaintLayer is needed to ensure the parent layer knows about non-isolated +// descendants with blend mode. TEST_P(LayoutSVGRootTest, PaintLayerType) { SetBodyInnerHTML(R"HTML( <svg id="root" style="width: 200px; height: 200px;">
diff --git a/third_party/blink/renderer/core/layout/visual_rect_mapping_test.cc b/third_party/blink/renderer/core/layout/visual_rect_mapping_test.cc index aeec2be4..f641dfcb 100644 --- a/third_party/blink/renderer/core/layout/visual_rect_mapping_test.cc +++ b/third_party/blink/renderer/core/layout/visual_rect_mapping_test.cc
@@ -691,14 +691,6 @@ EXPECT_EQ(PhysicalRect(-2, 3, 140, 110), rect); } -static const LayoutBoxModelObject& EnclosingCompositedContainer( - const LayoutObject& layout_object) { - DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()); - return layout_object.PaintingLayer() - ->EnclosingLayerForPaintInvalidationCrossingFrameBoundaries() - ->GetLayoutObject(); -} - TEST_P(VisualRectMappingTest, DifferentPaintInvalidaitionContainerForAbsolutePosition) { GetDocument().GetFrame()->GetSettings()->SetPreferCompositingToLCDTextEnabled( @@ -724,9 +716,6 @@ auto* normal_flow = To<LayoutBlock>(GetLayoutObjectByElementId("normal-flow")); - if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) - EXPECT_EQ(scroller, &EnclosingCompositedContainer(*normal_flow)); - PhysicalRect normal_flow_visual_rect = normal_flow->LocalVisualRect(); EXPECT_EQ(PhysicalRect(0, 0, 2000, 2000), normal_flow_visual_rect); PhysicalRect rect = normal_flow_visual_rect; @@ -766,8 +755,6 @@ To<LayoutBlock>(GetLayoutObjectByElementId("stacking-context")); auto* absolute = To<LayoutBlock>(GetLayoutObjectByElementId("absolute")); auto* container = To<LayoutBlock>(GetLayoutObjectByElementId("container")); - if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) - EXPECT_EQ(absolute->View(), &EnclosingCompositedContainer(*absolute)); EXPECT_EQ(container, absolute->Container()); PhysicalRect absolute_visual_rect = absolute->LocalVisualRect();
diff --git a/third_party/blink/renderer/core/page/chrome_client_impl.cc b/third_party/blink/renderer/core/page/chrome_client_impl.cc index 24c6902..8c478e6 100644 --- a/third_party/blink/renderer/core/page/chrome_client_impl.cc +++ b/third_party/blink/renderer/core/page/chrome_client_impl.cc
@@ -96,7 +96,6 @@ #include "third_party/blink/renderer/platform/animation/compositor_animation_timeline.h" #include "third_party/blink/renderer/platform/exported/wrapped_resource_request.h" #include "third_party/blink/renderer/platform/graphics/compositor_element_id.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/graphics/touch_action.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/instrumentation/histogram.h"
diff --git a/third_party/blink/renderer/core/page/page.cc b/third_party/blink/renderer/core/page/page.cc index 5dd9992..e3f3a3c2 100644 --- a/third_party/blink/renderer/core/page/page.cc +++ b/third_party/blink/renderer/core/page/page.cc
@@ -83,7 +83,6 @@ #include "third_party/blink/renderer/core/scroll/scrollbar_theme_overlay_mobile.h" #include "third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h" #include "third_party/blink/renderer/core/svg/graphics/svg_image_chrome_client.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
diff --git a/third_party/blink/renderer/core/page/scrolling/main_thread_scrolling_reasons_test.cc b/third_party/blink/renderer/core/page/scrolling/main_thread_scrolling_reasons_test.cc index 34e68dc5..25915399 100644 --- a/third_party/blink/renderer/core/page/scrolling/main_thread_scrolling_reasons_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/main_thread_scrolling_reasons_test.cc
@@ -16,11 +16,9 @@ #include "third_party/blink/renderer/core/html/html_iframe_element.h" #include "third_party/blink/renderer/core/layout/layout_embedded_content.h" #include "third_party/blink/renderer/core/layout/layout_view.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/core/testing/sim/sim_request.h" #include "third_party/blink/renderer/core/testing/sim/sim_test.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/testing/find_cc_layer.h" #include "third_party/blink/renderer/platform/testing/paint_test_configurations.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" @@ -449,9 +447,8 @@ TEST_P(NonCompositedMainThreadScrollingReasonsTest, ForcedComositingWithLCDRelatedReasons) { // With "will-change:transform" we composite elements with - // LCDTextRelatedReasons only. For elements with other - // NonCompositedReasons, we don't create scrollingLayer for their - // CompositedLayerMapping therefore they don't get composited. + // LCDTextRelatedReasons only. For elements with other NonCompositedReasons, + // we don't composite them. GetWebView()->GetSettings()->SetPreferCompositingToLCDTextEnabled(false); Document* document = GetFrame()->GetDocument(); Element* container = document->getElementById("scroller1");
diff --git a/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.cc b/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.cc index 0759879a..067c491d 100644 --- a/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.cc +++ b/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.cc
@@ -22,7 +22,6 @@ #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/core/scroll/scrollable_area.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" #include "ui/gfx/geometry/size_conversions.h"
diff --git a/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc b/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc index 6a4581c..67df73a 100644 --- a/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc
@@ -31,7 +31,6 @@ #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/page/scrolling/root_scroller_controller.h" #include "third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/core/testing/sim/sim_request.h"
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc index 5e7b2802..1fe69e2 100644 --- a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc +++ b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
@@ -51,7 +51,6 @@ #include "third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.h" #include "third_party/blink/renderer/core/scroll/scrollbar_theme.h" #include "third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/instrumentation/histogram.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc index 78ea221..5cebb6d6 100644 --- a/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc
@@ -56,12 +56,10 @@ #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h" #include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_context.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/core/testing/sim/sim_request.h" #include "third_party/blink/renderer/core/testing/sim/sim_test.h" #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/graphics/test/fake_gles2_interface.h" #include "third_party/blink/renderer/platform/graphics/test/fake_web_graphics_context_3d_provider.h" #include "third_party/blink/renderer/platform/graphics/touch_action.h" @@ -1898,7 +1896,7 @@ )HTML"); ForceFullCompositingUpdate(); - // The non-scrolling graphics layer should have a non-scrolling region for the + // The non-scrolling layer should have a non-scrolling region for the // non-composited scroller. const auto* cc_layer = LayerByDOMElementId("composited_container"); auto region = cc_layer->non_fast_scrollable_region(); @@ -1929,9 +1927,9 @@ ForceFullCompositingUpdate(); auto* container_cc_layer = LayerByDOMElementId("container"); - // The non-fast scrollable region should be on the container's graphics layer - // and not one of the viewport scroll layers because the region should move - // when the container moves and not when the viewport scrolls. + // The non-fast scrollable region should be on the container's layer and not + // one of the viewport scroll layers because the region should move when the + // container moves and not when the viewport scrolls. auto region = container_cc_layer->non_fast_scrollable_region(); EXPECT_EQ(region.bounds(), gfx::Rect(86, 121, 14, 14)); }
diff --git a/third_party/blink/renderer/core/paint/background_image_geometry.cc b/third_party/blink/renderer/core/paint/background_image_geometry.cc index b3d49b9..f8ef6383 100644 --- a/third_party/blink/renderer/core/paint/background_image_geometry.cc +++ b/third_party/blink/renderer/core/paint/background_image_geometry.cc
@@ -13,7 +13,6 @@ #include "third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h" #include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h" #include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/core/paint/rounded_border_geometry.h"
diff --git a/third_party/blink/renderer/core/paint/block_painter_test.cc b/third_party/blink/renderer/core/paint/block_painter_test.cc index 289fe81b..f7df2f8 100644 --- a/third_party/blink/renderer/core/paint/block_painter_test.cc +++ b/third_party/blink/renderer/core/paint/block_painter_test.cc
@@ -11,7 +11,6 @@ #include "third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.h" #include "third_party/blink/renderer/core/dom/events/native_event_listener.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/paint_controller_paint_test.h" #include "third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_chunk.h"
diff --git a/third_party/blink/renderer/core/paint/box_paint_invalidator.cc b/third_party/blink/renderer/core/paint/box_paint_invalidator.cc index 18b98856..c53010ad 100644 --- a/third_party/blink/renderer/core/paint/box_paint_invalidator.cc +++ b/third_party/blink/renderer/core/paint/box_paint_invalidator.cc
@@ -7,7 +7,6 @@ #include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/layout/ng/ng_ink_overflow.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/object_paint_invalidator.h" #include "third_party/blink/renderer/core/paint/paint_invalidator.h" #include "third_party/blink/renderer/core/paint/paint_layer.h"
diff --git a/third_party/blink/renderer/core/paint/box_paint_invalidator_test.cc b/third_party/blink/renderer/core/paint/box_paint_invalidator_test.cc index efe3bc8..6b3690a 100644 --- a/third_party/blink/renderer/core/paint/box_paint_invalidator_test.cc +++ b/third_party/blink/renderer/core/paint/box_paint_invalidator_test.cc
@@ -13,7 +13,6 @@ #include "third_party/blink/renderer/core/paint/paint_invalidator.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.h" #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
diff --git a/third_party/blink/renderer/core/paint/box_painter.cc b/third_party/blink/renderer/core/paint/box_painter.cc index 2d9c92d..6a187ac 100644 --- a/third_party/blink/renderer/core/paint/box_painter.cc +++ b/third_party/blink/renderer/core/paint/box_painter.cc
@@ -16,7 +16,6 @@ #include "third_party/blink/renderer/core/paint/box_decoration_data.h" #include "third_party/blink/renderer/core/paint/box_model_object_painter.h" #include "third_party/blink/renderer/core/paint/box_painter_base.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/nine_piece_image_painter.h" #include "third_party/blink/renderer/core/paint/object_painter.h" #include "third_party/blink/renderer/core/paint/paint_info.h"
diff --git a/third_party/blink/renderer/core/paint/box_painter_test.cc b/third_party/blink/renderer/core/paint/box_painter_test.cc index 9907f29d..5cbfe2b 100644 --- a/third_party/blink/renderer/core/paint/box_painter_test.cc +++ b/third_party/blink/renderer/core/paint/box_painter_test.cc
@@ -5,7 +5,6 @@ #include "third_party/blink/renderer/core/paint/box_painter.h" #include "testing/gmock/include/gmock/gmock.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/paint_controller_paint_test.h" #include "third_party/blink/renderer/platform/testing/paint_property_test_helpers.h"
diff --git a/third_party/blink/renderer/core/paint/build.gni b/third_party/blink/renderer/core/paint/build.gni index 4de7fd1..3fe0c5b6 100644 --- a/third_party/blink/renderer/core/paint/build.gni +++ b/third_party/blink/renderer/core/paint/build.gni
@@ -34,19 +34,8 @@ "clip_rects.h", "collapsed_border_painter.cc", "collapsed_border_painter.h", - "compositing/composited_layer_mapping.cc", - "compositing/composited_layer_mapping.h", - "compositing/compositing_inputs_root.cc", - "compositing/compositing_inputs_root.h", - "compositing/compositing_layer_property_updater.cc", - "compositing/compositing_layer_property_updater.h", "compositing/compositing_reason_finder.cc", "compositing/compositing_reason_finder.h", - "compositing/compositing_state.h", - "compositing/graphics_layer_tree_builder.cc", - "compositing/graphics_layer_tree_builder.h", - "compositing/graphics_layer_updater.cc", - "compositing/graphics_layer_updater.h", "css_mask_painter.cc", "css_mask_painter.h", "cull_rect_updater.cc",
diff --git a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc deleted file mode 100644 index 3a6ae7b..0000000 --- a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc +++ /dev/null
@@ -1,1687 +0,0 @@ -/* - * Copyright (C) 2009, 2010, 2011 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" - -#include <memory> - -#include "cc/layers/picture_layer.h" -#include "third_party/blink/renderer/core/animation/element_animations.h" -#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h" -#include "third_party/blink/renderer/core/dom/dom_node_ids.h" -#include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h" -#include "third_party/blink/renderer/core/frame/local_frame_view.h" -#include "third_party/blink/renderer/core/frame/remote_frame.h" -#include "third_party/blink/renderer/core/frame/settings.h" -#include "third_party/blink/renderer/core/frame/visual_viewport.h" -#include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h" -#include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h" -#include "third_party/blink/renderer/core/html/html_body_element.h" -#include "third_party/blink/renderer/core/html/html_iframe_element.h" -#include "third_party/blink/renderer/core/html/media/html_media_element.h" -#include "third_party/blink/renderer/core/html/media/html_video_element.h" -#include "third_party/blink/renderer/core/html_names.h" -#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h" -#include "third_party/blink/renderer/core/layout/geometry/transform_state.h" -#include "third_party/blink/renderer/core/layout/layout_box_model_object.h" -#include "third_party/blink/renderer/core/layout/layout_embedded_content.h" -#include "third_party/blink/renderer/core/layout/layout_embedded_object.h" -#include "third_party/blink/renderer/core/layout/layout_html_canvas.h" -#include "third_party/blink/renderer/core/layout/layout_inline.h" -#include "third_party/blink/renderer/core/layout/layout_shift_tracker.h" -#include "third_party/blink/renderer/core/layout/layout_video.h" -#include "third_party/blink/renderer/core/layout/layout_view.h" -#include "third_party/blink/renderer/core/page/chrome_client.h" -#include "third_party/blink/renderer/core/page/page.h" -#include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h" -#include "third_party/blink/renderer/core/page/scrolling/snap_coordinator.h" -#include "third_party/blink/renderer/core/page/scrolling/sticky_position_scrolling_constraints.h" -#include "third_party/blink/renderer/core/paint/clip_path_clipper.h" -#include "third_party/blink/renderer/core/paint/css_mask_painter.h" -#include "third_party/blink/renderer/core/paint/frame_paint_timing.h" -#include "third_party/blink/renderer/core/paint/object_paint_invalidator.h" -#include "third_party/blink/renderer/core/paint/outline_painter.h" -#include "third_party/blink/renderer/core/paint/paint_info.h" -#include "third_party/blink/renderer/core/paint/paint_layer_paint_order_iterator.h" -#include "third_party/blink/renderer/core/paint/paint_layer_painter.h" -#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" -#include "third_party/blink/renderer/core/paint/scrollable_area_painter.h" -#include "third_party/blink/renderer/core/probe/core_probes.h" -#include "third_party/blink/renderer/platform/fonts/font_cache.h" -#include "third_party/blink/renderer/platform/geometry/length_functions.h" -#include "third_party/blink/renderer/platform/graphics/compositor_filter_operations.h" -#include "third_party/blink/renderer/platform/graphics/graphics_context.h" -#include "third_party/blink/renderer/platform/graphics/paint/cull_rect.h" -#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h" -#include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h" -#include "third_party/blink/renderer/platform/graphics/paint/ignore_paint_timing_scope.h" -#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h" -#include "third_party/blink/renderer/platform/runtime_enabled_features.h" -#include "third_party/blink/renderer/platform/wtf/text/string_builder.h" -#include "ui/gfx/geometry/point_conversions.h" -#include "ui/gfx/geometry/rect_conversions.h" - -namespace blink { - -static PhysicalRect ContentsRect(const LayoutObject& layout_object) { - if (!layout_object.IsBox()) - return PhysicalRect(); - if (auto* replaced = DynamicTo<LayoutReplaced>(layout_object)) - return replaced->ReplacedContentRect(); - return To<LayoutBox>(layout_object).PhysicalContentBoxRect(); -} - -static bool HasBoxDecorationsOrBackgroundImage(const ComputedStyle& style) { - return style.HasBoxDecorations() || style.HasBackgroundImage(); -} - -static WebPluginContainerImpl* GetPluginContainer(LayoutObject& layout_object) { - if (auto* embedded_object = DynamicTo<LayoutEmbeddedObject>(layout_object)) - return embedded_object->Plugin(); - return nullptr; -} - -// Returns true if the compositor will be responsible for applying the sticky -// position offset for this composited layer. -static bool UsesCompositedStickyPosition(PaintLayer& layer) { - return layer.GetLayoutObject().StyleRef().HasStickyConstrainedPosition() && - layer.AncestorScrollContainerLayer()->NeedsCompositedScrolling(); -} - -// Returns the sticky position offset that should be removed from a given -// layer for use in CompositedLayerMapping. -// -// If the layer is not using composited sticky position, this will return -// gfx::PointF(). -static gfx::PointF StickyPositionOffsetForLayer(PaintLayer& layer) { - if (!UsesCompositedStickyPosition(layer)) - return gfx::PointF(); - - const StickyConstraintsMap& constraints_map = - layer.AncestorScrollContainerLayer() - ->GetScrollableArea() - ->GetStickyConstraintsMap(); - const StickyPositionScrollingConstraints* constraints = - constraints_map.at(&layer); - - return gfx::PointF(constraints->GetOffsetForStickyPosition(constraints_map)); -} - -static bool NeedsDecorationOutlineLayer(const PaintLayer& paint_layer, - const LayoutObject& layout_object) { - const ComputedStyle& style = layout_object.StyleRef(); - const LayoutUnit min_border_width = - std::min(std::min(style.BorderLeftWidth(), style.BorderTopWidth()), - std::min(style.BorderRightWidth(), style.BorderBottomWidth())); - - bool could_obscure_decorations = - (paint_layer.GetScrollableArea() && - paint_layer.GetScrollableArea()->UsesCompositedScrolling()) || - layout_object.IsCanvas() || IsA<LayoutVideo>(layout_object); - - // Unlike normal outlines (whole width is outside of the offset), focus - // rings can be drawn with the center of the path aligned with the offset, - // so only 2/3 of the width is outside of the offset. - const int outline_drawn_inside = - style.OutlineStyleIsAuto() - ? OutlinePainter::FocusRingWidthInsideBorderBox(style) - : 0; - - return could_obscure_decorations && style.HasOutline() && - (style.OutlineOffset().ToInt() - outline_drawn_inside) < - -min_border_width.ToInt(); -} - -CompositedLayerMapping::CompositedLayerMapping(PaintLayer& layer) - : owning_layer_(&layer), pending_update_scope_(kGraphicsLayerUpdateNone) { - CreatePrimaryGraphicsLayer(); -} - -CompositedLayerMapping::~CompositedLayerMapping() { -#if DCHECK_IS_ON() - DCHECK(is_destroyed_); -#endif -} - -void CompositedLayerMapping::Destroy() { - UpdateForegroundLayer(false); - UpdateMaskLayer(false); - UpdateSquashingLayers(false); - if (graphics_layer_) - graphics_layer_.Release()->Destroy(); - if (scrolling_contents_layer_) - scrolling_contents_layer_.Release()->Destroy(); - if (mask_layer_) - mask_layer_.Release()->Destroy(); - if (foreground_layer_) - foreground_layer_.Release()->Destroy(); - if (layer_for_horizontal_scrollbar_) - layer_for_horizontal_scrollbar_.Release()->Destroy(); - if (layer_for_vertical_scrollbar_) - layer_for_vertical_scrollbar_.Release()->Destroy(); - if (layer_for_scroll_corner_) - layer_for_scroll_corner_.Release()->Destroy(); - if (decoration_outline_layer_) - decoration_outline_layer_.Release()->Destroy(); - if (non_scrolling_squashing_layer_) - non_scrolling_squashing_layer_.Release()->Destroy(); - -#if DCHECK_IS_ON() - is_destroyed_ = true; -#endif -} - -Member<GraphicsLayer> CompositedLayerMapping::CreateGraphicsLayer( - CompositingReasons reasons, - SquashingDisallowedReasons squashing_disallowed_reasons) { - auto* graphics_layer = MakeGarbageCollected<GraphicsLayer>(); - - graphics_layer->SetCompositingReasons(reasons); - graphics_layer->SetSquashingDisallowedReasons(squashing_disallowed_reasons); - if (Node* owning_node = owning_layer_->GetLayoutObject().GetNode()) { - graphics_layer->SetOwnerNodeId( - static_cast<int>(DOMNodeIds::IdForNode(owning_node))); - } - - return graphics_layer; -} - -void CompositedLayerMapping::CreatePrimaryGraphicsLayer() { - graphics_layer_ = - CreateGraphicsLayer(owning_layer_->GetCompositingReasons(), - owning_layer_->GetSquashingDisallowedReasons()); - - graphics_layer_->SetHitTestable(true); -} - -void CompositedLayerMapping::UpdateCompositedBounds() { - // FIXME: if this is really needed for performance, it would be better to - // store it on Layer. - composited_bounds_ = owning_layer_->BoundingBoxForCompositing(); -} - -bool CompositedLayerMapping::UpdateGraphicsLayerConfiguration( - const PaintLayer* compositing_container) { - // Note carefully: here we assume that the compositing state of all - // descendants have been updated already, so it is legitimate to compute and - // cache the composited bounds for this layer. - UpdateCompositedBounds(); - - LayoutObject& layout_object = GetLayoutObject(); - const ComputedStyle& style = layout_object.StyleRef(); - - bool layer_config_changed = false; - - // If the outline needs to draw over the composited scrolling contents layer - // or scrollbar layers (or video or webgl) it needs to be drawn into a - // separate layer. - bool needs_decoration_outline_layer = - NeedsDecorationOutlineLayer(*owning_layer_, layout_object); - - if (UpdateDecorationOutlineLayer(needs_decoration_outline_layer)) - layer_config_changed = true; - - if (UpdateSquashingLayers(!non_scrolling_squashed_layers_.IsEmpty())) - layer_config_changed = true; - - bool has_mask = - CSSMaskPainter::MaskBoundingBox(GetLayoutObject(), PhysicalOffset()) - .has_value(); - bool has_mask_based_clip_path = - ClipPathClipper::ShouldUseMaskBasedClip(GetLayoutObject()); - if (UpdateMaskLayer(has_mask || has_mask_based_clip_path)) - layer_config_changed = true; - - if (layer_config_changed) - UpdateInternalHierarchy(); - - if (layout_object.IsLayoutEmbeddedContent()) { - if (WebPluginContainerImpl* plugin = GetPluginContainer(layout_object)) { - graphics_layer_->SetContentsToCcLayer(plugin->CcLayer()); - } else if (auto* frame_owner = - DynamicTo<HTMLFrameOwnerElement>(layout_object.GetNode())) { - if (auto* remote = DynamicTo<RemoteFrame>(frame_owner->ContentFrame())) { - graphics_layer_->SetContentsToCcLayer(remote->GetCcLayer()); - } - } - } else if (IsA<LayoutVideo>(layout_object)) { - auto* media_element = To<HTMLMediaElement>(layout_object.GetNode()); - graphics_layer_->SetContentsToCcLayer(media_element->CcLayer()); - } else if (layout_object.IsCanvas()) { - graphics_layer_->SetContentsToCcLayer( - To<HTMLCanvasElement>(layout_object.GetNode())->ContentsCcLayer()); - layer_config_changed = true; - } - - if (layer_config_changed) { - // Changes to either the internal hierarchy or the mask layer have an - // impact on painting phases, so we need to update when either are - // updated. - UpdatePaintingPhases(); - } - - UpdateElementId(); - - if (style.Preserves3D() && style.HasOpacity() && - owning_layer_->Has3DTransformedDescendant()) { - UseCounter::Count(layout_object.GetDocument(), - WebFeature::kOpacityWithPreserve3DQuirk); - } - - return layer_config_changed; -} - -static PhysicalOffset ComputeOffsetFromCompositedAncestor( - const PaintLayer* layer, - const PaintLayer* composited_ancestor, - const PhysicalOffset& local_representative_point_for_fragmentation, - const gfx::PointF& offset_for_sticky_position) { - // Add in the offset of the composited bounds from the coordinate space of - // the PaintLayer, since visualOffsetFromAncestor() requires the pre-offset - // input to be in the space of the PaintLayer. We also need to add in this - // offset before computation of visualOffsetFromAncestor(), because it - // affects fragmentation offset if compositedAncestor crosses a pagination - // boundary. - // - // Currently, visual fragmentation for composited layers is not implemented. - // For fragmented contents, we paint in the logical coordinates of the flow - // thread, then split the result by fragment boundary and paste each part - // into each fragment's physical position. - // Since composited layers don't support visual fragmentation, we have to - // choose a "representative" fragment to position the painted contents. This - // is where localRepresentativePointForFragmentation comes into play. - // The fragment that the representative point resides in will be chosen as - // the representative fragment for layer position purpose. - // For layers that are not fragmented, the point doesn't affect behavior as - // there is one and only one fragment. - PhysicalOffset offset = layer->VisualOffsetFromAncestor( - composited_ancestor, local_representative_point_for_fragmentation); - if (composited_ancestor) - offset += composited_ancestor->SubpixelAccumulation(); - offset -= local_representative_point_for_fragmentation; - offset -= PhysicalOffset::FromPointFRound(offset_for_sticky_position); - return offset; -} - -PhysicalOffset ComputeSubpixelAccumulation( - const PhysicalOffset& offset_from_composited_ancestor, - const PaintLayer& layer, - gfx::Point& snapped_offset_from_composited_ancestor) { - snapped_offset_from_composited_ancestor = - ToRoundedPoint(offset_from_composited_ancestor); - PhysicalOffset subpixel_accumulation = - offset_from_composited_ancestor - - PhysicalOffset(snapped_offset_from_composited_ancestor); - if (subpixel_accumulation.IsZero()) { - return subpixel_accumulation; - } - if (layer.GetCompositingReasons() & - CompositingReason::kPreventingSubpixelAccumulationReasons) { - return PhysicalOffset(); - } - if (layer.GetCompositingReasons() & - CompositingReason::kActiveTransformAnimation) { - if (const Element* element = - To<Element>(layer.GetLayoutObject().GetNode())) { - DCHECK(element->GetElementAnimations()); - if (element->GetElementAnimations()->IsIdentityOrTranslation()) - return subpixel_accumulation; - } - return PhysicalOffset(); - } - if (!layer.Transform() || layer.Transform()->IsIdentityOrTranslation()) { - return subpixel_accumulation; - } - return PhysicalOffset(); -} - -void CompositedLayerMapping::ComputeBoundsOfOwningLayer( - const PaintLayer* composited_ancestor, - gfx::Rect& local_bounds, - gfx::Point& snapped_offset_from_composited_ancestor) { - // HACK(chrishtr): adjust for position of inlines. - PhysicalOffset local_representative_point_for_fragmentation; - if (owning_layer_->GetLayoutObject().IsLayoutInline()) { - local_representative_point_for_fragmentation = - To<LayoutInline>(owning_layer_->GetLayoutObject()) - .FirstLineBoxTopLeft(); - } - // Blink will already have applied any necessary offset for sticky - // positioned elements. If the compositor is handling sticky offsets for - // this layer, we need to remove the Blink-side offset to avoid - // double-counting. - gfx::PointF offset_for_sticky_position = - StickyPositionOffsetForLayer(*owning_layer_); - PhysicalOffset offset_from_composited_ancestor = - ComputeOffsetFromCompositedAncestor( - owning_layer_, composited_ancestor, - local_representative_point_for_fragmentation, - offset_for_sticky_position); - PhysicalOffset subpixel_accumulation = ComputeSubpixelAccumulation( - offset_from_composited_ancestor, *owning_layer_, - snapped_offset_from_composited_ancestor); - - // Invalidate the whole layer when subpixel accumulation changes, since - // the previous subpixel accumulation is baked into the display list. - // However, don't do so for directly composited layers, to avoid impacting - // performance. - if (subpixel_accumulation != owning_layer_->SubpixelAccumulation()) { - // Always invalidate if under-invalidation checking is on, to avoid - // false positives. - if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled() || - !(owning_layer_->GetCompositingReasons() & - CompositingReason::kComboAllDirectReasons)) - GetLayoutObject().SetShouldCheckForPaintInvalidation(); - } - - absl::optional<gfx::Rect> mask_bounding_box = - CSSMaskPainter::MaskBoundingBox(GetLayoutObject(), subpixel_accumulation); - absl::optional<gfx::RectF> clip_path_bounding_box = - ClipPathClipper::LocalClipPathBoundingBox(GetLayoutObject()); - if (clip_path_bounding_box) - clip_path_bounding_box->Offset(gfx::Vector2dF(subpixel_accumulation)); - - // Override graphics layer size to the bound of mask layer, this is because - // the compositor implementation requires mask layer bound to match its - // host layer. - if (mask_bounding_box) { - local_bounds = *mask_bounding_box; - if (clip_path_bounding_box) - local_bounds.Intersect(gfx::ToEnclosingRect(*clip_path_bounding_box)); - } else if (clip_path_bounding_box) { - local_bounds = gfx::ToEnclosingRect(*clip_path_bounding_box); - } else { - // Move the bounds by the subpixel accumulation so that it pixel-snaps - // relative to absolute pixels instead of local coordinates. - PhysicalRect local_raw_compositing_bounds = CompositedBounds(); - local_raw_compositing_bounds.Move(subpixel_accumulation); - local_bounds = ToPixelSnappedRect(local_raw_compositing_bounds); - } -} - -void CompositedLayerMapping::UpdateSquashingLayerGeometry( - const PaintLayer* compositing_container, - const gfx::Point& snapped_offset_from_composited_ancestor, - HeapVector<Member<GraphicsLayerPaintInfo>>& layers, - HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation) { - if (!non_scrolling_squashing_layer_) - return; - - gfx::Point graphics_layer_parent_location; - ComputeGraphicsLayerParentLocation(compositing_container, - graphics_layer_parent_location); - - PhysicalOffset compositing_container_offset_from_parent_graphics_layer = - -PhysicalOffset(graphics_layer_parent_location); - if (compositing_container) { - compositing_container_offset_from_parent_graphics_layer += - compositing_container->SubpixelAccumulation(); - } - - const PaintLayer* common_transform_ancestor = nullptr; - if (compositing_container && compositing_container->Transform()) { - common_transform_ancestor = compositing_container; - } else if (compositing_container) { - common_transform_ancestor = nullptr; - } else { - common_transform_ancestor = owning_layer_->Root(); - } - - // FIXME: Cache these offsets. - PhysicalOffset compositing_container_offset_from_transformed_ancestor; - if (compositing_container) { - compositing_container_offset_from_transformed_ancestor = - compositing_container->ComputeOffsetFromAncestor( - *common_transform_ancestor); - } - - PhysicalRect total_squash_bounds; - for (wtf_size_t i = 0; i < layers.size(); ++i) { - PhysicalRect squashed_bounds = - layers[i]->paint_layer->BoundingBoxForCompositing(); - - // Store the local bounds of the Layer subtree before applying the offset. - layers[i]->composited_bounds = squashed_bounds; - - PhysicalOffset squashed_layer_offset_from_transformed_ancestor = - layers[i]->paint_layer->ComputeOffsetFromAncestor( - *common_transform_ancestor); - PhysicalOffset squashed_layer_offset_from_compositing_container = - squashed_layer_offset_from_transformed_ancestor - - compositing_container_offset_from_transformed_ancestor; - - squashed_bounds.Move(squashed_layer_offset_from_compositing_container); - total_squash_bounds.Unite(squashed_bounds); - } - - // The totalSquashBounds is positioned with respect to compositingContainer. - // But the squashingLayer needs to be positioned with respect to the - // graphicsLayerParent. The conversion between compositingContainer and the - // graphicsLayerParent is already computed as - // compositingContainerOffsetFromParentGraphicsLayer. - total_squash_bounds.Move( - compositing_container_offset_from_parent_graphics_layer); - const gfx::Rect squash_layer_bounds = ToEnclosingRect(total_squash_bounds); - const gfx::Point squash_layer_origin = squash_layer_bounds.origin(); - const PhysicalOffset squash_layer_origin_in_compositing_container_space = - PhysicalOffset(squash_layer_origin) - - compositing_container_offset_from_parent_graphics_layer; - - // Now that the squashing bounds are known, we can convert the PaintLayer - // painting offsets from compositingContainer space to the squashing layer - // space. - // - // The painting offset we want to compute for each squashed PaintLayer is - // essentially the position of the squashed PaintLayer described w.r.t. - // compositingContainer's origin. So we just need to convert that point - // from compositingContainer space to the squashing layer's space. This is - // done by subtracting squashLayerOriginInCompositingContainerSpace, but - // then the offset overall needs to be negated because that's the direction - // that the painting code expects the offset to be. - for (auto& layer : layers) { - const PhysicalOffset squashed_layer_offset_from_transformed_ancestor = - layer->paint_layer->ComputeOffsetFromAncestor( - *common_transform_ancestor); - const PhysicalOffset offset_from_squash_layer_origin = - (squashed_layer_offset_from_transformed_ancestor - - compositing_container_offset_from_transformed_ancestor) - - squash_layer_origin_in_compositing_container_space; - - gfx::Vector2d new_offset_from_layout_object = - -ToRoundedVector2d(offset_from_squash_layer_origin); - if (layer->offset_from_layout_object_set && - layer->offset_from_layout_object != new_offset_from_layout_object) { - layers_needing_paint_invalidation.push_back(layer->paint_layer); - } - layer->offset_from_layout_object = new_offset_from_layout_object; - layer->offset_from_layout_object_set = true; - } - - non_scrolling_squashing_layer_->SetSize(squash_layer_bounds.size()); - // We can't non_scrolling_squashing_layer_->SetOffsetFromLayoutObject(). - // Squashing layer has special paint and invalidation logic that already - // compensated for compositing bounds, setting it here would end up - // double adjustment. - auto new_offset = squash_layer_bounds.origin() - - snapped_offset_from_composited_ancestor + - graphics_layer_parent_location.OffsetFromOrigin(); - if (new_offset != non_scrolling_squashing_layer_offset_from_layout_object_) { - non_scrolling_squashing_layer_offset_from_layout_object_ = new_offset; - // Need to update squashing LayerState according to the new offset. - // GraphicsLayerUpdater does this. - layers_needing_paint_invalidation.push_back(owning_layer_); - } - - for (auto& layer : layers) - UpdateLocalClipRectForSquashedLayer(*owning_layer_, layers, *layer); -} - -void CompositedLayerMapping::UpdateGraphicsLayerGeometry( - const PaintLayer* compositing_container, - HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation) { - gfx::Rect local_compositing_bounds; - gfx::Point snapped_offset_from_composited_ancestor; - ComputeBoundsOfOwningLayer(compositing_container, local_compositing_bounds, - snapped_offset_from_composited_ancestor); - - UpdateMainGraphicsLayerGeometry(local_compositing_bounds); - UpdateSquashingLayerGeometry( - compositing_container, snapped_offset_from_composited_ancestor, - non_scrolling_squashed_layers_, layers_needing_paint_invalidation); - - UpdateMaskLayerGeometry(); - UpdateDecorationOutlineLayerGeometry(local_compositing_bounds.size()); - UpdateScrollingContentsLayerGeometry(layers_needing_paint_invalidation); - UpdateForegroundLayerGeometry(); - - if (owning_layer_->GetScrollableArea() && - owning_layer_->GetScrollableArea()->ScrollsOverflow()) - owning_layer_->GetScrollableArea()->PositionOverflowControls(); - - UpdateContentsRect(); - UpdateDrawsContentAndPaintsHitTest(); - UpdateElementId(); -} - -void CompositedLayerMapping::UpdateMainGraphicsLayerGeometry( - const gfx::Rect& local_compositing_bounds) { - graphics_layer_->SetOffsetFromLayoutObject( - local_compositing_bounds.OffsetFromOrigin()); - graphics_layer_->SetSize(local_compositing_bounds.size()); - - // m_graphicsLayer is the corresponding GraphicsLayer for this PaintLayer - // and its non-compositing descendants. So, the visibility flag for - // m_graphicsLayer should be true if there are any non-compositing visible - // layers. - bool contents_visible = owning_layer_->HasVisibleContent() || - HasVisibleNonCompositingDescendant(owning_layer_); - // TODO(sunxd): Investigate and possibly implement computing hit test - // regions in PaintTouchActionRects code path, so that cc has correct - // pointer-events information. For now, there is no need to set - // graphics_layer_'s hit testable bit here, because it is always hit - // testable from cc's perspective. - graphics_layer_->SetContentsVisible(contents_visible); -} - -void CompositedLayerMapping::ComputeGraphicsLayerParentLocation( - const PaintLayer* compositing_container, - gfx::Point& graphics_layer_parent_location) { - if (compositing_container) { - graphics_layer_parent_location = gfx::PointAtOffsetFromOrigin( - compositing_container->GetCompositedLayerMapping() - ->ParentForSublayers() - ->OffsetFromLayoutObject()); - } else if (!GetLayoutObject().GetFrame()->IsLocalRoot()) { // TODO(oopif) - DCHECK(!compositing_container); - graphics_layer_parent_location = gfx::Point(); - } - - if (compositing_container && - compositing_container->NeedsCompositedScrolling()) { - auto& layout_box = To<LayoutBox>(compositing_container->GetLayoutObject()); - gfx::Vector2d scroll_offset = - layout_box.PixelSnappedScrolledContentOffset(); - gfx::Point scroll_origin = - compositing_container->GetScrollableArea()->ScrollOrigin(); - scroll_origin -= layout_box.OriginAdjustmentForScrollbars(); - scroll_origin.Offset(-layout_box.BorderLeft().ToInt(), - -layout_box.BorderTop().ToInt()); - graphics_layer_parent_location = gfx::PointAtOffsetFromOrigin( - -(scroll_origin.OffsetFromOrigin() + scroll_offset)); - } -} - -void CompositedLayerMapping::UpdateMaskLayerGeometry() { - if (!mask_layer_) - return; - - mask_layer_->SetSize(graphics_layer_->Size()); - mask_layer_->SetOffsetFromLayoutObject( - graphics_layer_->OffsetFromLayoutObject()); -} - -void CompositedLayerMapping::UpdateScrollingContentsLayerGeometry( - HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation) { - if (!scrolling_contents_layer_) { - DCHECK(squashed_layers_in_scrolling_contents_.IsEmpty()); - return; - } - - DCHECK(scrolling_contents_layer_); - auto& layout_box = To<LayoutBox>(GetLayoutObject()); - gfx::Rect overflow_clip_rect = ToPixelSnappedRect( - layout_box.OverflowClipRect(owning_layer_->SubpixelAccumulation())); - - bool scroll_container_size_changed = - previous_scroll_container_size_ != overflow_clip_rect.size(); - if (scroll_container_size_changed) - previous_scroll_container_size_ = overflow_clip_rect.size(); - - PaintLayerScrollableArea* scrollable_area = - owning_layer_->GetScrollableArea(); - gfx::Size scroll_size = scrollable_area->PixelSnappedContentsSize( - owning_layer_->SubpixelAccumulation()); - - // Ensure scrolling contents are at least as large as the scroll clip - scroll_size.SetToMin(overflow_clip_rect.size()); - - auto* scrolling_coordinator = owning_layer_->GetScrollingCoordinator(); - scrolling_coordinator->UpdateCompositorScrollOffset(*layout_box.GetFrame(), - *scrollable_area); - - scrolling_contents_layer_->SetSize(scroll_size); - - scrolling_contents_layer_->SetOffsetFromLayoutObject( - overflow_clip_rect.origin() - scrollable_area->ScrollOrigin()); - - for (auto& layer : squashed_layers_in_scrolling_contents_) { - layer->composited_bounds = layer->paint_layer->BoundingBoxForCompositing(); - PhysicalOffset offset_from_scrolling_contents_layer = - layer->paint_layer->ComputeOffsetFromAncestor(*owning_layer_) + - owning_layer_->SubpixelAccumulation() - - PhysicalOffset(scrolling_contents_layer_->OffsetFromLayoutObject()); - gfx::Vector2d new_offset_from_layout_object = - -ToRoundedVector2d(offset_from_scrolling_contents_layer); - - if (layer->offset_from_layout_object_set && - layer->offset_from_layout_object != new_offset_from_layout_object) { - layers_needing_paint_invalidation.push_back(layer->paint_layer); - } - layer->offset_from_layout_object = new_offset_from_layout_object; - layer->offset_from_layout_object_set = true; - } - for (auto& layer : squashed_layers_in_scrolling_contents_) { - UpdateLocalClipRectForSquashedLayer( - *owning_layer_, squashed_layers_in_scrolling_contents_, *layer); - } -} - -bool CompositedLayerMapping::RequiresHorizontalScrollbarLayer() const { - return owning_layer_->GetScrollableArea() && - owning_layer_->GetScrollableArea()->HorizontalScrollbar(); -} - -bool CompositedLayerMapping::RequiresVerticalScrollbarLayer() const { - return owning_layer_->GetScrollableArea() && - owning_layer_->GetScrollableArea()->VerticalScrollbar(); -} - -bool CompositedLayerMapping::RequiresScrollCornerLayer() const { - return owning_layer_->GetScrollableArea() && - !owning_layer_->GetScrollableArea() - ->ScrollCornerAndResizerRect() - .IsEmpty(); -} - -void CompositedLayerMapping::UpdateForegroundLayerGeometry() { - if (!foreground_layer_) - return; - - // Should be equivalent to local_compositing_bounds. - gfx::Rect compositing_bounds( - gfx::PointAtOffsetFromOrigin(graphics_layer_->OffsetFromLayoutObject()), - graphics_layer_->Size()); - if (scrolling_contents_layer_) { - // Override compositing bounds to include full overflow if composited - // scrolling is used. - compositing_bounds = - gfx::Rect(gfx::PointAtOffsetFromOrigin( - scrolling_contents_layer_->OffsetFromLayoutObject()), - scrolling_contents_layer_->Size()); - } - - foreground_layer_->SetOffsetFromLayoutObject( - compositing_bounds.OffsetFromOrigin()); - foreground_layer_->SetSize(compositing_bounds.size()); -} - -void CompositedLayerMapping::UpdateDecorationOutlineLayerGeometry( - const gfx::Size& relative_compositing_bounds_size) { - if (!decoration_outline_layer_) - return; - decoration_outline_layer_->SetSize(relative_compositing_bounds_size); - decoration_outline_layer_->SetOffsetFromLayoutObject( - graphics_layer_->OffsetFromLayoutObject()); -} - -void CompositedLayerMapping::UpdateInternalHierarchy() { - // foreground_layer_ has to be inserted in the correct order with child - // layers in SetSubLayers(), so it's not inserted here. - graphics_layer_->RemoveFromParent(); - - bool overflow_controls_after_scrolling_contents = - owning_layer_->IsRootLayer() || - (owning_layer_->GetScrollableArea() && - owning_layer_->GetScrollableArea()->HasOverlayOverflowControls()); - if (overflow_controls_after_scrolling_contents && scrolling_contents_layer_) - graphics_layer_->AddChild(scrolling_contents_layer_); - - if (layer_for_horizontal_scrollbar_) - graphics_layer_->AddChild(layer_for_horizontal_scrollbar_); - if (layer_for_vertical_scrollbar_) - graphics_layer_->AddChild(layer_for_vertical_scrollbar_); - if (layer_for_scroll_corner_) - graphics_layer_->AddChild(layer_for_scroll_corner_); - - if (!overflow_controls_after_scrolling_contents && scrolling_contents_layer_) - graphics_layer_->AddChild(scrolling_contents_layer_); - - if (decoration_outline_layer_) - graphics_layer_->AddChild(decoration_outline_layer_); - - if (mask_layer_) - graphics_layer_->AddChild(mask_layer_); - - if (non_scrolling_squashing_layer_) - graphics_layer_->AddChild(non_scrolling_squashing_layer_); -} - -void CompositedLayerMapping::UpdatePaintingPhases() { - graphics_layer_->SetPaintingPhase(PaintingPhaseForPrimaryLayer()); - if (scrolling_contents_layer_) { - GraphicsLayerPaintingPhase paint_phase = - kGraphicsLayerPaintOverflowContents | - kGraphicsLayerPaintCompositedScroll; - if (!foreground_layer_) - paint_phase |= kGraphicsLayerPaintForeground; - scrolling_contents_layer_->SetPaintingPhase(paint_phase); - } - if (foreground_layer_) { - GraphicsLayerPaintingPhase paint_phase = kGraphicsLayerPaintForeground; - if (scrolling_contents_layer_) - paint_phase |= kGraphicsLayerPaintOverflowContents; - foreground_layer_->SetPaintingPhase(paint_phase); - } -} - -void CompositedLayerMapping::UpdateContentsRect() { - graphics_layer_->SetContentsRect(ToPixelSnappedRect(ContentsBox())); -} - -void CompositedLayerMapping::UpdateDrawsContentAndPaintsHitTest() { - bool in_overlay_fullscreen_video = false; - if (IsA<LayoutVideo>(GetLayoutObject())) { - auto* video_element = To<HTMLVideoElement>(GetLayoutObject().GetNode()); - if (video_element->IsFullscreen() && - video_element->UsesOverlayFullscreenVideo()) - in_overlay_fullscreen_video = true; - } - bool has_painted_content = - in_overlay_fullscreen_video ? false : ContainsPaintedContent(); - graphics_layer_->SetDrawsContent(has_painted_content); - - // |has_painted_content| is conservative (e.g., will be true if any descendant - // paints content, regardless of whether the descendant content is a hit test) - // but an exhaustive check of descendants that paint hit tests would be too - // expensive. - bool paints_hit_test = has_painted_content || - GetLayoutObject().HasEffectiveAllowedTouchAction() || - GetLayoutObject().InsideBlockingWheelEventHandler(); - bool paints_scroll_hit_test = - ((owning_layer_->GetScrollableArea() && - owning_layer_->GetScrollableArea()->ScrollsOverflow()) || - (GetPluginContainer(GetLayoutObject()) && - GetPluginContainer(GetLayoutObject())->WantsWheelEvents())); - graphics_layer_->SetPaintsHitTest(paints_hit_test || paints_scroll_hit_test); - - if (scrolling_contents_layer_) { - // scrolling_contents_layer_ only needs backing store if the scrolled - // contents need to paint. - bool has_painted_scrolling_contents = - !squashed_layers_in_scrolling_contents_.IsEmpty() || - (owning_layer_->HasVisibleContent() && - (GetLayoutObject().StyleRef().HasBackground() || - GetLayoutObject().HasNonInitialBackdropFilter() || PaintsChildren())); - scrolling_contents_layer_->SetDrawsContent(has_painted_scrolling_contents); - scrolling_contents_layer_->SetPaintsHitTest(paints_hit_test); - } - - if (has_painted_content && GetLayoutObject().IsCanvas() && - To<LayoutHTMLCanvas>(GetLayoutObject()) - .DrawsBackgroundOntoContentLayer()) { - has_painted_content = false; - } - - // FIXME: we could refine this to only allocate backings for one of these - // layers if possible. - if (foreground_layer_) { - foreground_layer_->SetDrawsContent(has_painted_content); - foreground_layer_->SetPaintsHitTest(paints_hit_test); - } - - if (decoration_outline_layer_) - decoration_outline_layer_->SetDrawsContent(true); - - if (mask_layer_) - mask_layer_->SetDrawsContent(true); -} - -void CompositedLayerMapping::PositionOverflowControlsLayers() { - if (GraphicsLayer* layer = LayerForHorizontalScrollbar()) { - Scrollbar* h_bar = - owning_layer_->GetScrollableArea()->HorizontalScrollbar(); - if (h_bar) { - gfx::Rect frame_rect = h_bar->FrameRect(); - layer->SetOffsetFromLayoutObject(frame_rect.OffsetFromOrigin()); - layer->SetSize(frame_rect.size()); - if (layer->HasContentsLayer()) - layer->SetContentsRect(gfx::Rect(frame_rect.size())); - } - bool h_bar_visible = h_bar && !layer->HasContentsLayer(); - layer->SetDrawsContent(h_bar_visible); - layer->SetHitTestable(h_bar_visible); - } - - if (GraphicsLayer* layer = LayerForVerticalScrollbar()) { - Scrollbar* v_bar = owning_layer_->GetScrollableArea()->VerticalScrollbar(); - if (v_bar) { - gfx::Rect frame_rect = v_bar->FrameRect(); - layer->SetOffsetFromLayoutObject(frame_rect.OffsetFromOrigin()); - layer->SetSize(frame_rect.size()); - if (layer->HasContentsLayer()) - layer->SetContentsRect(gfx::Rect(frame_rect.size())); - } - bool v_bar_visible = v_bar && !layer->HasContentsLayer(); - layer->SetDrawsContent(v_bar_visible); - layer->SetHitTestable(v_bar_visible); - } - - if (GraphicsLayer* layer = LayerForScrollCorner()) { - const gfx::Rect& scroll_corner_and_resizer = - owning_layer_->GetScrollableArea()->ScrollCornerAndResizerRect(); - layer->SetOffsetFromLayoutObject( - scroll_corner_and_resizer.OffsetFromOrigin()); - layer->SetSize(scroll_corner_and_resizer.size()); - layer->SetDrawsContent(!scroll_corner_and_resizer.IsEmpty()); - layer->SetHitTestable(!scroll_corner_and_resizer.IsEmpty()); - } -} - -template <typename Function> -static void ApplyToGraphicsLayers(const CompositedLayerMapping* mapping, - const Function& function) { - auto null_checking_function = [&function](GraphicsLayer* layer) { - if (layer) - function(layer); - }; - - null_checking_function(mapping->MainGraphicsLayer()); - null_checking_function(mapping->ScrollingContentsLayer()); - null_checking_function(mapping->ForegroundLayer()); - null_checking_function(mapping->MaskLayer()); - null_checking_function(mapping->DecorationOutlineLayer()); - null_checking_function(mapping->NonScrollingSquashingLayer()); - null_checking_function(mapping->LayerForHorizontalScrollbar()); - null_checking_function(mapping->LayerForVerticalScrollbar()); - null_checking_function(mapping->LayerForScrollCorner()); -} - -// You receive an element id if you have an animation, or you're a scroller -// (and might impl animate). -// -// The element id for the scroll layers is assigned when they're constructed, -// since this is unconditional. However, the element id for the primary layer -// may change according to the rules above so we update those values here. -void CompositedLayerMapping::UpdateElementId() { - CompositorElementId element_id = CompositorElementIdFromUniqueObjectId( - owning_layer_->GetLayoutObject().UniqueId(), - CompositorElementIdNamespace::kPrimary); - - graphics_layer_->SetElementId(element_id); -} - -bool CompositedLayerMapping::UpdateForegroundLayer( - bool needs_foreground_layer) { - bool layer_changed = false; - if (needs_foreground_layer) { - if (!foreground_layer_) { - foreground_layer_ = - CreateGraphicsLayer(CompositingReason::kLayerForForeground); - foreground_layer_->SetHitTestable(true); - layer_changed = true; - } - } else if (foreground_layer_) { - foreground_layer_->RemoveFromParent(); - foreground_layer_.Release()->Destroy(); - layer_changed = true; - } - - return layer_changed; -} - -bool CompositedLayerMapping::UpdateDecorationOutlineLayer( - bool needs_decoration_outline_layer) { - bool layer_changed = false; - if (needs_decoration_outline_layer) { - if (!decoration_outline_layer_) { - decoration_outline_layer_ = - CreateGraphicsLayer(CompositingReason::kLayerForDecoration); - decoration_outline_layer_->SetPaintingPhase( - kGraphicsLayerPaintDecoration); - layer_changed = true; - } - } else if (decoration_outline_layer_) { - decoration_outline_layer_.Release()->Destroy(); - layer_changed = true; - } - - return layer_changed; -} - -bool CompositedLayerMapping::UpdateMaskLayer(bool needs_mask_layer) { - bool layer_changed = false; - if (needs_mask_layer) { - if (!mask_layer_) { - mask_layer_ = CreateGraphicsLayer(CompositingReason::kLayerForMask); - mask_layer_->SetPaintingPhase(kGraphicsLayerPaintMask); - CompositorElementId element_id = CompositorElementIdFromUniqueObjectId( - GetLayoutObject().UniqueId(), - CompositorElementIdNamespace::kEffectMask); - mask_layer_->SetElementId(element_id); - if (GetLayoutObject().HasNonInitialBackdropFilter()) - mask_layer_->CcLayer().SetIsBackdropFilterMask(true); - mask_layer_->SetHitTestable(true); - layer_changed = true; - } - } else if (mask_layer_) { - mask_layer_.Release()->Destroy(); - layer_changed = true; - } - - return layer_changed; -} - -bool CompositedLayerMapping::UpdateSquashingLayers( - bool needs_squashing_layers) { - bool layers_changed = false; - - if (needs_squashing_layers) { - if (!non_scrolling_squashing_layer_) { - non_scrolling_squashing_layer_ = - CreateGraphicsLayer(CompositingReason::kLayerForSquashingContents); - non_scrolling_squashing_layer_->SetDrawsContent(true); - non_scrolling_squashing_layer_->SetHitTestable(true); - layers_changed = true; - } - DCHECK(non_scrolling_squashing_layer_); - } else { - if (non_scrolling_squashing_layer_) { - non_scrolling_squashing_layer_->RemoveFromParent(); - non_scrolling_squashing_layer_.Release()->Destroy(); - layers_changed = true; - } - DCHECK(!non_scrolling_squashing_layer_); - } - - return layers_changed; -} - -GraphicsLayerPaintingPhase -CompositedLayerMapping::PaintingPhaseForPrimaryLayer() const { - unsigned phase = kGraphicsLayerPaintBackground; - if (!foreground_layer_) - phase |= kGraphicsLayerPaintForeground; - if (!mask_layer_) - phase |= kGraphicsLayerPaintMask; - if (!decoration_outline_layer_) - phase |= kGraphicsLayerPaintDecoration; - - if (scrolling_contents_layer_) { - phase &= ~kGraphicsLayerPaintForeground; - phase |= kGraphicsLayerPaintCompositedScroll; - } - - return static_cast<GraphicsLayerPaintingPhase>(phase); -} - -bool CompositedLayerMapping::PaintsChildren() const { - if (owning_layer_->HasVisibleContent() && - owning_layer_->HasNonEmptyChildLayoutObjects()) - return true; - - if (HasVisibleNonCompositingDescendant(owning_layer_)) - return true; - - return false; -} - -static bool IsCompositedPlugin(LayoutObject& layout_object) { - return layout_object.IsEmbeddedObject() && - layout_object.AdditionalCompositingReasons(); -} - -bool CompositedLayerMapping::HasVisibleNonCompositingDescendant( - PaintLayer* parent) { - if (!parent->HasVisibleDescendant()) - return false; - - PaintLayerPaintOrderIterator iterator(parent, kAllChildren); - while (PaintLayer* child_layer = iterator.Next()) { - if (child_layer->HasCompositedLayerMapping()) - continue; - if (child_layer->HasVisibleContent() || - HasVisibleNonCompositingDescendant(child_layer)) - return true; - } - - return false; -} - -bool CompositedLayerMapping::ContainsPaintedContent() const { - if (CompositedBounds().IsEmpty()) - return false; - - LayoutObject& layout_object = GetLayoutObject(); - // FIXME: we could optimize cases where the image, video or canvas is known - // to fill the border box entirely, and set background color on the layer in - // that case, instead of allocating backing store and painting. - auto* layout_video = DynamicTo<LayoutVideo>(layout_object); - if (layout_video && layout_video->GetDisplayMode() == LayoutVideo::kVideo) - return owning_layer_->HasBoxDecorationsOrBackground(); - - if (layout_object.GetNode() && layout_object.GetNode()->IsDocumentNode()) { - if (owning_layer_->NeedsCompositedScrolling()) - return BackgroundPaintsOntoGraphicsLayer(); - - // Look to see if the root object has a non-simple background - LayoutObject* root_object = - layout_object.GetDocument().documentElement() - ? layout_object.GetDocument().documentElement()->GetLayoutObject() - : nullptr; - // Reject anything that has a border, a border-radius or outline, - // or is not a simple background (no background, or solid color). - if (root_object && - HasBoxDecorationsOrBackgroundImage(root_object->StyleRef())) - return true; - - // Now look at the body's LayoutObject. - HTMLElement* body = layout_object.GetDocument().FirstBodyElement(); - LayoutObject* body_object = body ? body->GetLayoutObject() : nullptr; - if (body_object && - HasBoxDecorationsOrBackgroundImage(body_object->StyleRef())) - return true; - } - - if (owning_layer_->HasVisibleBoxDecorations()) - return true; - - if (layout_object.HasMask()) // masks require special treatment - return true; - - if (layout_object.IsAtomicInlineLevel() && !IsCompositedPlugin(layout_object)) - return true; - - if (layout_object.IsLayoutMultiColumnSet()) - return true; - - // FIXME: it's O(n^2). A better solution is needed. - return PaintsChildren(); -} - -// Return the offset from the top-left of this compositing layer at which the -// LayoutObject's contents are painted. -PhysicalOffset CompositedLayerMapping::ContentOffsetInCompositingLayer() const { - return owning_layer_->SubpixelAccumulation() - - PhysicalOffset(graphics_layer_->OffsetFromLayoutObject()); -} - -PhysicalRect CompositedLayerMapping::ContentsBox() const { - PhysicalRect contents_box = ContentsRect(GetLayoutObject()); - contents_box.Move(ContentOffsetInCompositingLayer()); - return contents_box; -} - -bool CompositedLayerMapping::NeedsToReparentOverflowControls() const { - return owning_layer_->NeedsReorderOverlayOverflowControls(); -} - -wtf_size_t CompositedLayerMapping::MoveOverflowControlLayersInto( - GraphicsLayerVector& vector, - wtf_size_t position) { - wtf_size_t count = 0; - auto move_layer = [&](GraphicsLayer* layer) { - if (!layer) - return; - layer->RemoveFromParent(); - vector.insert(position++, layer); - count++; - }; - move_layer(layer_for_horizontal_scrollbar_); - move_layer(layer_for_vertical_scrollbar_); - move_layer(layer_for_scroll_corner_); - return count; -} - -GraphicsLayer* CompositedLayerMapping::ParentForSublayers() const { - if (scrolling_contents_layer_) - return scrolling_contents_layer_; - - return graphics_layer_; -} - -void CompositedLayerMapping::SetSublayers(GraphicsLayerVector sublayers) { - GraphicsLayer* parent = ParentForSublayers(); - - // TODO(szager): Remove after diagnosing crash crbug.com/1092673 - CHECK(parent); - - // The caller should have inserted |foreground_layer_| into |sublayers|. - DCHECK(!foreground_layer_ || sublayers.Contains(foreground_layer_)); - - if (parent == graphics_layer_) { - // SetChildren() below will clobber all layers in |parent|, so we need to - // add layers that should stay in the children list into |sublayers|. - if (!NeedsToReparentOverflowControls()) { - if (layer_for_horizontal_scrollbar_) - sublayers.insert(0, layer_for_horizontal_scrollbar_); - if (layer_for_vertical_scrollbar_) - sublayers.insert(0, layer_for_vertical_scrollbar_); - if (layer_for_scroll_corner_) - sublayers.insert(0, layer_for_scroll_corner_); - } - - if (decoration_outline_layer_) - sublayers.push_back(decoration_outline_layer_); - if (mask_layer_) - sublayers.push_back(mask_layer_); - if (non_scrolling_squashing_layer_) - sublayers.push_back(non_scrolling_squashing_layer_); - } - - parent->SetChildren(sublayers); -} - -GraphicsLayerUpdater::UpdateType CompositedLayerMapping::UpdateTypeForChildren( - GraphicsLayerUpdater::UpdateType update_type) const { - if (pending_update_scope_ >= kGraphicsLayerUpdateSubtree) - return GraphicsLayerUpdater::kForceUpdate; - return update_type; -} - -GraphicsLayer* CompositedLayerMapping::SquashingLayer( - const PaintLayer& squashed_layer) const { - DCHECK(NonScrollingSquashingLayer()); - return NonScrollingSquashingLayer(); -} - -void CompositedLayerMapping::SetNeedsCheckRasterInvalidation() { - ApplyToGraphicsLayers(this, [](GraphicsLayer* graphics_layer) { - if (graphics_layer->DrawsContent()) - graphics_layer->SetNeedsCheckRasterInvalidation(); - }); -} - -const GraphicsLayerPaintInfo* CompositedLayerMapping::ContainingSquashedLayer( - const LayoutObject* layout_object, - const HeapVector<Member<GraphicsLayerPaintInfo>>& layers, - unsigned max_squashed_layer_index) { - if (!layout_object) - return nullptr; - for (wtf_size_t i = 0; i < layers.size() && i < max_squashed_layer_index; - ++i) { - if (layout_object->IsDescendantOf( - &layers[i]->paint_layer->GetLayoutObject())) - return layers[i]; - } - return nullptr; -} - -const GraphicsLayerPaintInfo* -CompositedLayerMapping::ContainingSquashedLayerInSquashingLayer( - const LayoutObject* layout_object, - unsigned max_squashed_layer_index) const { - return ContainingSquashedLayer(layout_object, non_scrolling_squashed_layers_, - max_squashed_layer_index); -} - -void CompositedLayerMapping::UpdateLocalClipRectForSquashedLayer( - const PaintLayer& reference_layer, - const HeapVector<Member<GraphicsLayerPaintInfo>>& layers, - GraphicsLayerPaintInfo& paint_info) { - const LayoutObject* clipping_container = - paint_info.paint_layer->ClippingContainer(); - if (clipping_container == reference_layer.ClippingContainer() || - // When squashing into scrolling contents without other clips. - clipping_container == &reference_layer.GetLayoutObject()) { - paint_info.local_clip_rect_for_squashed_layer = - ClipRect(PhysicalRect(LayoutRect::InfiniteIntRect())); - paint_info.offset_from_clip_rect_root = PhysicalOffset(); - paint_info.local_clip_rect_root = paint_info.paint_layer; - return; - } - - DCHECK(clipping_container); - - const GraphicsLayerPaintInfo* ancestor_paint_info = - ContainingSquashedLayer(clipping_container, layers, layers.size()); - // Must be there, otherwise - // CompositingLayerAssigner::GetReasonsPreventingSquashing() would have - // disallowed squashing. - DCHECK(ancestor_paint_info); - - const PaintLayer* ancestor_layer = ancestor_paint_info->paint_layer; - ClipRectsContext clip_rects_context( - ancestor_layer, - &ancestor_layer->GetLayoutObject().PrimaryStitchingFragment()); - ClipRect parent_clip_rect; - paint_info.paint_layer - ->Clipper(PaintLayer::GeometryMapperOption::kUseGeometryMapper) - .CalculateBackgroundClipRect(clip_rects_context, parent_clip_rect); - - // Convert from ancestor to local coordinates. - gfx::Vector2d ancestor_to_local_offset = - paint_info.offset_from_layout_object - - ancestor_paint_info->offset_from_layout_object; - parent_clip_rect.Move(PhysicalOffset(ancestor_to_local_offset)); - paint_info.local_clip_rect_for_squashed_layer = parent_clip_rect; - paint_info.offset_from_clip_rect_root = - PhysicalOffset(ancestor_to_local_offset); - paint_info.local_clip_rect_root = ancestor_paint_info->paint_layer; -} - -void CompositedLayerMapping::DoPaintTask( - const GraphicsLayerPaintInfo& paint_info, - const GraphicsLayer& graphics_layer, - PaintLayerFlags paint_layer_flags, - GraphicsContext& context, - const gfx::Rect& clip /* In the coords of rootLayer */) const { - FontCachePurgePreventer font_cache_purge_preventer; - - gfx::Vector2d offset = paint_info.offset_from_layout_object; - // The dirtyRect is in the coords of the painting root. - gfx::Rect dirty_rect(clip); - dirty_rect.Offset(offset); - - if (paint_layer_flags & (kPaintLayerPaintingOverflowContents)) { - dirty_rect.Offset( - ToRoundedVector2d(paint_info.paint_layer->SubpixelAccumulation())); - } else { - PhysicalRect bounds = paint_info.composited_bounds; - bounds.Move(paint_info.paint_layer->SubpixelAccumulation()); - dirty_rect.Intersect(ToPixelSnappedRect(bounds)); - } - -#if DCHECK_IS_ON() - if (!GetLayoutObject().View()->GetFrame() || - !GetLayoutObject().View()->GetFrame()->ShouldThrottleRendering()) - paint_info.paint_layer->GetLayoutObject().AssertSubtreeIsLaidOut(); -#endif - - float device_scale_factor = blink::DeviceScaleFactorDeprecated( - paint_info.paint_layer->GetLayoutObject().GetFrame()); - context.SetDeviceScaleFactor(device_scale_factor); - - // As a composited layer may be painted directly, we need to traverse the - // effect tree starting from the current node all the way up through the - // parents to determine which effects are opacity 0, for the purposes of - // correctly computing paint metrics such as First Contentful Paint and - // Largest Contentful Paint. For the latter we special-case the nodes where - // the opacity:0 depth is 1, so we need to only compute up to the first two - // opacity:0 effects in here and can ignore the rest. - absl::optional<IgnorePaintTimingScope> ignore_paint_timing_scope; - int num_ignores = 0; - DCHECK_EQ(IgnorePaintTimingScope::IgnoreDepth(), 0); - for (const auto* effect_node = &paint_info.paint_layer->GetLayoutObject() - .FirstFragment() - .PreEffect() - .Unalias(); - effect_node && num_ignores < 2; - effect_node = effect_node->UnaliasedParent()) { - if (effect_node->Opacity() == 0.0f) { - if (!ignore_paint_timing_scope) - ignore_paint_timing_scope.emplace(); - IgnorePaintTimingScope::IncrementIgnoreDepth(); - ++num_ignores; - } - } - - if (paint_info.paint_layer->GetCompositingState() != - kPaintsIntoGroupedBacking) { - // FIXME: GraphicsLayers need a way to split for multicol. - PaintLayerPaintingInfo painting_info( - paint_info.paint_layer, CullRect(dirty_rect), kGlobalPaintNormalPhase, - paint_info.paint_layer->SubpixelAccumulation()); - PaintLayerPainter(*paint_info.paint_layer) - .PaintLayerContents(context, painting_info, paint_layer_flags); - } else { - PaintLayerPaintingInfo painting_info( - paint_info.paint_layer, CullRect(dirty_rect), kGlobalPaintNormalPhase, - paint_info.paint_layer->SubpixelAccumulation()); - PaintLayerPainter(*paint_info.paint_layer) - .Paint(context, painting_info, paint_layer_flags); - } -} - -// TODO(eseckler): Make recording distance configurable, e.g. for use in -// headless, where we would like to record an exact area. -static const int kPixelDistanceToRecord = 4000; - -gfx::Rect CompositedLayerMapping::RecomputeInterestRect( - const GraphicsLayer* graphics_layer) const { - DCHECK(!RuntimeEnabledFeatures::CullRectUpdateEnabled()); - - gfx::Rect graphics_layer_bounds(graphics_layer->Size()); - - FloatClipRect mapping_rect((gfx::RectF(graphics_layer_bounds))); - - auto source_state = graphics_layer->GetPropertyTreeState(); - - LayoutView* root_view = owning_layer_->GetLayoutObject().View(); - while (root_view->GetFrame()->OwnerLayoutObject()) - root_view = root_view->GetFrame()->OwnerLayoutObject()->View(); - - auto root_view_state = root_view->FirstFragment().LocalBorderBoxProperties(); - - // 1. Move into local transform space. - mapping_rect.Move( - gfx::Vector2dF(graphics_layer->GetOffsetFromTransformNode())); - // 2. Map into visible space of the root LayoutView. - GeometryMapper::LocalToAncestorVisualRect(source_state, root_view_state, - mapping_rect); - - gfx::RectF visible_content_rect = - gfx::RectF(gfx::ToEnclosingRect(mapping_rect.Rect())); - - gfx::RectF local_interest_rect; - // If the visible content rect is empty, then it makes no sense to map it - // back since there is nothing to map. - if (!visible_content_rect.IsEmpty()) { - local_interest_rect = visible_content_rect; - // 3. Map the visible content rect from root view space to local graphics - // layer space. - GeometryMapper::SourceToDestinationRect(root_view_state.Transform(), - source_state.Transform(), - local_interest_rect); - local_interest_rect.Offset(-graphics_layer->GetOffsetFromTransformNode()); - - // TODO(chrishtr): the code below is a heuristic. Instead we should detect - // and return whether the mapping failed. In some cases, - // absoluteToLocalQuad can fail to map back to the local space, due to - // passing through non-invertible transforms or floating-point accuracy - // issues. Examples include rotation near 90 degrees or perspective. In - // such cases, fall back to painting the first kPixelDistanceToRecord - // pixels in each direction. - - // Note that since the interest rect mapping above can produce extremely - // large numbers in cases of perspective, try our best to "normalize" the - // result by ensuring that none of the rect dimensions exceed some large, - // but reasonable, limit. - const float reasonable_pixel_limit = std::numeric_limits<int>::max() / 2.f; - auto unpadded_intersection = local_interest_rect; - - // Note that by clamping X and Y, we are effectively moving the rect right - // / down. However, this will at most make us paint more content, which is - // better than erroneously deciding that the rect produced here is far - // offscreen. - if (unpadded_intersection.x() < -reasonable_pixel_limit) - unpadded_intersection.set_x(-reasonable_pixel_limit); - if (unpadded_intersection.y() < -reasonable_pixel_limit) - unpadded_intersection.set_y(-reasonable_pixel_limit); - if (unpadded_intersection.right() > reasonable_pixel_limit) { - unpadded_intersection.set_width(reasonable_pixel_limit - - unpadded_intersection.x()); - } - if (unpadded_intersection.bottom() > reasonable_pixel_limit) { - unpadded_intersection.set_height(reasonable_pixel_limit - - unpadded_intersection.y()); - } - - unpadded_intersection.Intersect(gfx::RectF(graphics_layer_bounds)); - // If our unpadded intersection is not empty, then use that before - // padding, since it can produce more stable results, and it would not - // produce any smaller area than if we used the original local interest - // rect. - if (!unpadded_intersection.IsEmpty()) - local_interest_rect = unpadded_intersection; - - // Expand by interest rect padding amount, scaled by the approximate scale - // of the GraphicsLayer relative to screen pixels. If width or height - // are zero or nearly zero, fall back to kPixelDistanceToRecord. - // This is the same as the else clause below. - float x_scale = - visible_content_rect.width() > std::numeric_limits<float>::epsilon() - ? local_interest_rect.width() / visible_content_rect.width() - : 1.0f; - float y_scale = - visible_content_rect.height() > std::numeric_limits<float>::epsilon() - ? local_interest_rect.height() / visible_content_rect.height() - : 1.0f; - // Take the max, to account for situations like rotation transforms, which - // swap x and y. - // Since at this point we can also have an extremely large scale due to - // perspective (see the comments above), cap it to something reasonable. - float scale = std::min(std::max(x_scale, y_scale), - reasonable_pixel_limit / kPixelDistanceToRecord); - local_interest_rect.Outset(kPixelDistanceToRecord * scale); - } else { - // Expand by interest rect padding amount. - local_interest_rect.Outset(kPixelDistanceToRecord); - } - return gfx::IntersectRects(gfx::ToEnclosingRect(local_interest_rect), - graphics_layer_bounds); -} - -static const int kMinimumDistanceBeforeRepaint = 512; - -bool CompositedLayerMapping::InterestRectChangedEnoughToRepaint( - const gfx::Rect& previous_interest_rect, - const gfx::Rect& new_interest_rect, - const gfx::Size& layer_size) { - DCHECK(!RuntimeEnabledFeatures::CullRectUpdateEnabled()); - - if (previous_interest_rect.IsEmpty() && new_interest_rect.IsEmpty()) - return false; - - // Repaint when going from empty to not-empty, to cover cases where the - // layer is painted for the first time, or otherwise becomes visible. - if (previous_interest_rect.IsEmpty()) - return true; - - // Repaint if the new interest rect includes area outside of a skirt around - // the existing interest rect. - gfx::Rect expanded_previous_interest_rect(previous_interest_rect); - expanded_previous_interest_rect.Outset(kMinimumDistanceBeforeRepaint); - if (!expanded_previous_interest_rect.Contains(new_interest_rect)) - return true; - - // Even if the new interest rect doesn't include enough new area to satisfy - // the condition above, repaint anyway if it touches a layer edge not - // touched by the existing interest rect. Because it's impossible to expose - // more area in the direction, repainting cannot be deferred until the - // exposed new area satisfies the condition above. - if (new_interest_rect.x() == 0 && previous_interest_rect.x() != 0) - return true; - if (new_interest_rect.y() == 0 && previous_interest_rect.y() != 0) - return true; - if (new_interest_rect.right() == layer_size.width() && - previous_interest_rect.right() != layer_size.width()) - return true; - if (new_interest_rect.bottom() == layer_size.height() && - previous_interest_rect.bottom() != layer_size.height()) - return true; - - return false; -} - -bool CompositedLayerMapping::AdjustForCompositedScrolling( - const GraphicsLayer* graphics_layer, - gfx::Vector2d& offset) const { - if (graphics_layer == scrolling_contents_layer_ || - graphics_layer == foreground_layer_) { - if (PaintLayerScrollableArea* scrollable_area = - owning_layer_->GetScrollableArea()) { - if (scrollable_area->UsesCompositedScrolling()) { - // Note: this is the offset from the beginning of flow of the block, - // not the offset from the top/left of the overflow rect. - // offsetFromLayoutObject adds the origin offset from top/left to the - // beginning of flow. - ScrollOffset scroll_offset = scrollable_area->GetScrollOffset(); - offset -= gfx::ToFlooredVector2d(scroll_offset); - return true; - } - } - } - return false; -} - -void CompositedLayerMapping::PaintScrollableArea( - const GraphicsLayer* graphics_layer, - GraphicsContext& context, - const gfx::Rect& interest_rect) const { - if (GetLayoutObject().StyleRef().Visibility() != EVisibility::kVisible) - return; - - // cull_rect is in the space of the containing scrollable area in which - // Scrollbar::Paint() will paint the scrollbar. - CullRect cull_rect(interest_rect); - cull_rect.Move(graphics_layer->OffsetFromLayoutObject()); - PaintLayerScrollableArea* scrollable_area = - owning_layer_->GetScrollableArea(); - ScrollableAreaPainter painter(*scrollable_area); - if (graphics_layer == LayerForHorizontalScrollbar()) { - if (Scrollbar* scrollbar = scrollable_area->HorizontalScrollbar()) - painter.PaintScrollbar(context, *scrollbar, gfx::Vector2d(), cull_rect); - } else if (graphics_layer == LayerForVerticalScrollbar()) { - if (Scrollbar* scrollbar = scrollable_area->VerticalScrollbar()) - painter.PaintScrollbar(context, *scrollbar, gfx::Vector2d(), cull_rect); - } else if (graphics_layer == LayerForScrollCorner()) { - painter.PaintScrollCorner(context, gfx::Vector2d(), cull_rect); - painter.PaintResizer(context, gfx::Vector2d(), cull_rect); - } -} - -bool CompositedLayerMapping::IsScrollableAreaLayer( - const GraphicsLayer* graphics_layer) const { - return graphics_layer == LayerForHorizontalScrollbar() || - graphics_layer == LayerForVerticalScrollbar() || - graphics_layer == LayerForScrollCorner(); -} - -bool CompositedLayerMapping::IsScrollableAreaLayerWhichNeedsRepaint( - const GraphicsLayer* graphics_layer) const { - if (PaintLayerScrollableArea* scrollable_area = - owning_layer_->GetScrollableArea()) { - if (graphics_layer == LayerForHorizontalScrollbar()) - return scrollable_area->HorizontalScrollbarNeedsPaintInvalidation(); - - if (graphics_layer == LayerForVerticalScrollbar()) - return scrollable_area->VerticalScrollbarNeedsPaintInvalidation(); - - if (graphics_layer == LayerForScrollCorner()) - return scrollable_area->ScrollCornerNeedsPaintInvalidation(); - } - - return false; -} - -void CompositedLayerMapping::Trace(Visitor* visitor) const { - visitor->Trace(owning_layer_); - visitor->Trace(graphics_layer_); - visitor->Trace(scrolling_contents_layer_); - visitor->Trace(mask_layer_); - visitor->Trace(foreground_layer_); - visitor->Trace(layer_for_horizontal_scrollbar_); - visitor->Trace(layer_for_vertical_scrollbar_); - visitor->Trace(layer_for_scroll_corner_); - visitor->Trace(decoration_outline_layer_); - visitor->Trace(non_scrolling_squashing_layer_); - visitor->Trace(non_scrolling_squashed_layers_); - visitor->Trace(squashed_layers_in_scrolling_contents_); -} - -bool CompositedLayerMapping::UpdateSquashingLayerAssignmentInternal( - HeapVector<Member<GraphicsLayerPaintInfo>>& squashed_layers, - PaintLayer& squashed_layer, - wtf_size_t next_squashed_layer_index) { - GraphicsLayerPaintInfo* paint_info = - MakeGarbageCollected<GraphicsLayerPaintInfo>(); - paint_info->paint_layer = &squashed_layer; - // NOTE: composited bounds are updated elsewhere - // NOTE: offsetFromLayoutObject is updated elsewhere - - // Change tracking on squashing layers: at the first sign of something - // changed, just invalidate the layer. - // FIXME: Perhaps we can find a tighter more clever mechanism later. - if (next_squashed_layer_index < squashed_layers.size()) { - if (paint_info->paint_layer == - squashed_layers[next_squashed_layer_index]->paint_layer) - return false; - squashed_layers.insert(next_squashed_layer_index, paint_info); - } else { - squashed_layers.push_back(paint_info); - } - return true; -} - -bool CompositedLayerMapping::UpdateSquashingLayerAssignment( - PaintLayer& squashed_layer, - wtf_size_t next_squashed_layer_in_non_scrolling_squashing_layer_index, - wtf_size_t next_squashed_layer_in_scrolling_contents_index) { - return UpdateSquashingLayerAssignmentInternal( - non_scrolling_squashed_layers_, squashed_layer, - next_squashed_layer_in_non_scrolling_squashing_layer_index); -} - -void CompositedLayerMapping::RemoveLayerFromSquashingGraphicsLayer( - const PaintLayer& layer) { - // We must try to remove the layer from both vectors because - // MayBeSquashedIntoScrollingContents() may not reflect the previous status. - for (wtf_size_t i = 0; i < non_scrolling_squashed_layers_.size(); ++i) { - if (non_scrolling_squashed_layers_[i]->paint_layer == &layer) { - non_scrolling_squashed_layers_.EraseAt(i); - return; - } - } - for (wtf_size_t i = 0; i < squashed_layers_in_scrolling_contents_.size(); - ++i) { - if (squashed_layers_in_scrolling_contents_[i]->paint_layer == &layer) { - squashed_layers_in_scrolling_contents_.EraseAt(i); - return; - } - } - - // Assert on incorrect mappings between layers and groups - NOTREACHED(); -} - -static void RemoveExtraSquashedLayers( - HeapVector<Member<GraphicsLayerPaintInfo>>& squashed_layers, - wtf_size_t new_count, - HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation) { - DCHECK_GE(squashed_layers.size(), new_count); - if (squashed_layers.size() == new_count) - return; - for (auto i = new_count; i < squashed_layers.size(); i++) { - layers_needing_paint_invalidation.push_back( - squashed_layers[i]->paint_layer); - } - squashed_layers.Shrink(new_count); -} - -void CompositedLayerMapping::FinishAccumulatingSquashingLayers( - wtf_size_t new_non_scrolling_squashed_layer_count, - wtf_size_t new_squashed_layer_in_scrolling_contents_count, - HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation) { - RemoveExtraSquashedLayers(non_scrolling_squashed_layers_, - new_non_scrolling_squashed_layer_count, - layers_needing_paint_invalidation); - RemoveExtraSquashedLayers(squashed_layers_in_scrolling_contents_, - new_squashed_layer_in_scrolling_contents_count, - layers_needing_paint_invalidation); -} - -String CompositedLayerMapping::DebugName( - const GraphicsLayer* graphics_layer) const { - String name; - if (graphics_layer == graphics_layer_) { - name = owning_layer_->DebugName(); - } else if (graphics_layer == non_scrolling_squashing_layer_) { - name = "Squashing Layer (first squashed layer: " + - (non_scrolling_squashed_layers_.size() > 0 - ? non_scrolling_squashed_layers_[0]->paint_layer->DebugName() - : "") + - ")"; - } else if (graphics_layer == foreground_layer_) { - name = owning_layer_->DebugName() + " (foreground) Layer"; - } else if (graphics_layer == mask_layer_) { - name = "Mask Layer"; - } else if (graphics_layer == layer_for_horizontal_scrollbar_) { - name = "Horizontal Scrollbar Layer"; - } else if (graphics_layer == layer_for_vertical_scrollbar_) { - name = "Vertical Scrollbar Layer"; - } else if (graphics_layer == layer_for_scroll_corner_) { - name = "Scroll Corner Layer"; - } else if (graphics_layer == scrolling_contents_layer_) { - name = "Scrolling Contents Layer"; - } else if (graphics_layer == decoration_outline_layer_) { - name = "Decoration Layer"; - } else { - NOTREACHED(); - } - - return name; -} - -} // namespace blink
diff --git a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h deleted file mode 100644 index 9b31925..0000000 --- a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h +++ /dev/null
@@ -1,436 +0,0 @@ -/* - * Copyright (C) 2009, 2010, 2011 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_COMPOSITED_LAYER_MAPPING_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_COMPOSITED_LAYER_MAPPING_H_ - -#include <memory> - -#include "base/dcheck_is_on.h" -#include "third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.h" -#include "third_party/blink/renderer/core/paint/paint_layer.h" -#include "third_party/blink/renderer/core/paint/paint_layer_painting_info.h" -#include "third_party/blink/renderer/platform/geometry/float_point_3d.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" -#include "third_party/blink/renderer/platform/graphics/graphics_types.h" -#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" -#include "ui/gfx/geometry/point_f.h" - -namespace blink { - -// A GraphicsLayerPaintInfo contains all the info needed to paint a partial -// subtree of Layers into a GraphicsLayer. -struct GraphicsLayerPaintInfo - : public GarbageCollected<GraphicsLayerPaintInfo> { - public: - Member<PaintLayer> paint_layer = nullptr; - - PhysicalRect composited_bounds; - - // The clip rect to apply, in the local coordinate space of the squashed - // layer, when painting it. - ClipRect local_clip_rect_for_squashed_layer; - - Member<PaintLayer> local_clip_rect_root = nullptr; - - PhysicalOffset offset_from_clip_rect_root; - - // Offset describing where this squashed Layer paints into the shared - // GraphicsLayer backing. - gfx::Vector2d offset_from_layout_object; - bool offset_from_layout_object_set = false; - - GraphicsLayerPaintInfo() = default; - - void Trace(Visitor* visitor) const { - visitor->Trace(paint_layer); - visitor->Trace(local_clip_rect_root); - } -}; - -enum GraphicsLayerUpdateScope { - kGraphicsLayerUpdateNone, - kGraphicsLayerUpdateLocal, - kGraphicsLayerUpdateSubtree, -}; - -// CompositedLayerMapping keeps track of how PaintLayers correspond to -// GraphicsLayers of the composited layer tree. Each instance of -// CompositedLayerMapping manages a small cluster of GraphicsLayers and the -// references to which Layers and paint phases contribute to each GraphicsLayer. -// -// - If a PaintLayer is composited, -// - if it paints into its own backings (GraphicsLayers), it owns a -// CompositedLayerMapping (PaintLayer::compositedLayerMapping()) to keep -// track the backings; -// - if it paints into grouped backing (i.e. it's squashed), it has a pointer -// (PaintLayer::groupedMapping()) to the CompositedLayerMapping into which -// the PaintLayer is squashed; -// - Otherwise the PaintLayer doesn't own or directly reference any -// CompositedLayerMapping. -class CORE_EXPORT CompositedLayerMapping final - : public GarbageCollected<CompositedLayerMapping> { - public: - // |Destroy()| should be called when the object is no longer used. - explicit CompositedLayerMapping(PaintLayer&); - CompositedLayerMapping(const CompositedLayerMapping&) = delete; - CompositedLayerMapping& operator=(const CompositedLayerMapping&) = delete; - virtual ~CompositedLayerMapping(); - void Destroy(); - - PaintLayer& OwningLayer() const { return *owning_layer_; } - - bool UpdateGraphicsLayerConfiguration( - const PaintLayer* compositing_container); - void UpdateGraphicsLayerGeometry( - const PaintLayer* compositing_container, - HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation); - - GraphicsLayer* MainGraphicsLayer() const { return graphics_layer_; } - - GraphicsLayer* ForegroundLayer() const { return foreground_layer_; } - - GraphicsLayer* DecorationOutlineLayer() const { - return decoration_outline_layer_; - } - - GraphicsLayer* ScrollingContentsLayer() const { - return scrolling_contents_layer_; - } - - GraphicsLayer* MaskLayer() const { return mask_layer_; } - - GraphicsLayer* ParentForSublayers() const; - void SetSublayers(GraphicsLayerVector); - - // Returns the GraphicsLayer that |layer| is squashed into, which may be - // NonScrollingSquashingLayer or ScrollingContentsLayer. - GraphicsLayer* SquashingLayer(const PaintLayer& squashed_layer) const; - - GraphicsLayer* NonScrollingSquashingLayer() const { - return non_scrolling_squashing_layer_; - } - const gfx::Vector2d& NonScrollingSquashingLayerOffsetFromLayoutObject() - const { - return non_scrolling_squashing_layer_offset_from_layout_object_; - } - - // Let all DrawsContent GraphicsLayers check raster invalidations after - // a no-change paint. - void SetNeedsCheckRasterInvalidation(); - - PhysicalRect CompositedBounds() const { return composited_bounds_; } - - void PositionOverflowControlsLayers(); - - // Returns true if the assignment actually changed the assigned squashing - // layer. - bool UpdateSquashingLayerAssignment( - PaintLayer& squashed_layer, - wtf_size_t next_non_scrolling_squashed_layer_index, - wtf_size_t next_squashed_layer_in_scrolling_contents_index); - void RemoveLayerFromSquashingGraphicsLayer(const PaintLayer&); -#if DCHECK_IS_ON() - void AssertInSquashedLayersVector(const PaintLayer&) const; -#endif - - void FinishAccumulatingSquashingLayers( - wtf_size_t new_non_scrolling_squashed_layer_count, - wtf_size_t new_squashed_layer_in_scrolling_contents_count, - HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation); - - void UpdateElementId(); - - virtual void Trace(Visitor*) const; - - PhysicalRect ContentsBox() const; - - GraphicsLayer* LayerForHorizontalScrollbar() const { - return layer_for_horizontal_scrollbar_; - } - GraphicsLayer* LayerForVerticalScrollbar() const { - return layer_for_vertical_scrollbar_; - } - GraphicsLayer* LayerForScrollCorner() const { - return layer_for_scroll_corner_; - } - - // Returns true if the overflow controls cannot be positioned within this - // CLM's internal hierarchy without incorrectly stacking under some - // scrolling content. If this returns true, these controls must be - // repositioned in the graphics layer tree to ensure that they stack above - // scrolling content. - bool NeedsToReparentOverflowControls() const; - - // Move overflow control layers from its parent into the vector. - // Returns the number of layers moved. - wtf_size_t MoveOverflowControlLayersInto(GraphicsLayerVector&, - wtf_size_t position); - - void SetBlendMode(BlendMode); - - bool NeedsGraphicsLayerUpdate() { - return pending_update_scope_ > kGraphicsLayerUpdateNone; - } - void SetNeedsGraphicsLayerUpdate(GraphicsLayerUpdateScope scope) { - pending_update_scope_ = std::max( - static_cast<GraphicsLayerUpdateScope>(pending_update_scope_), scope); - } - void ClearNeedsGraphicsLayerUpdate() { - pending_update_scope_ = kGraphicsLayerUpdateNone; - } - - GraphicsLayerUpdater::UpdateType UpdateTypeForChildren( - GraphicsLayerUpdater::UpdateType) const; - -#if DCHECK_IS_ON() - void AssertNeedsToUpdateGraphicsLayerBitsCleared() { - DCHECK_EQ(pending_update_scope_, - static_cast<unsigned>(kGraphicsLayerUpdateNone)); - } -#endif - - String DebugName(const GraphicsLayer*) const; - - PhysicalOffset ContentOffsetInCompositingLayer() const; - - // If there is a squashed layer painting into this CLM that is an ancestor of - // the given LayoutObject, return it. Otherwise return nullptr. - const GraphicsLayerPaintInfo* ContainingSquashedLayerInSquashingLayer( - const LayoutObject*, - unsigned max_squashed_layer_index) const; - - // Returns whether an adjustment happend. - bool AdjustForCompositedScrolling(const GraphicsLayer*, - gfx::Vector2d& offset) const; - - private: - // Returns true for layers with scrollable overflow which have a background - // that can be painted into the composited scrolling contents layer (i.e. - // the background can scroll with the content). When the background is also - // opaque this allows us to composite the scroller even on low DPI as we can - // draw with subpixel anti-aliasing. - bool BackgroundPaintsOntoScrollingContentsLayer() const { - return GetLayoutObject().GetBackgroundPaintLocation() & - kBackgroundPaintInContentsSpace; - } - - // Returns true if the background paints onto the main graphics layer. - // In some situations, we may paint background on both the main graphics layer - // and the scrolling contents layer. - bool BackgroundPaintsOntoGraphicsLayer() const { - return GetLayoutObject().GetBackgroundPaintLocation() & - kBackgroundPaintInBorderBoxSpace; - } - - gfx::Rect RecomputeInterestRect(const GraphicsLayer*) const; - static bool InterestRectChangedEnoughToRepaint( - const gfx::Rect& previous_interest_rect, - const gfx::Rect& new_interest_rect, - const gfx::Size& layer_size); - - static const GraphicsLayerPaintInfo* ContainingSquashedLayer( - const LayoutObject*, - const HeapVector<Member<GraphicsLayerPaintInfo>>& layers, - unsigned max_squashed_layer_index); - - // Paints the scrollbar part associated with the given graphics layer into the - // given context. - void PaintScrollableArea(const GraphicsLayer*, - GraphicsContext&, - const gfx::Rect& interest_rect) const; - // Returns whether the given layer is part of the scrollable area, if any, - // associated with this mapping. - bool IsScrollableAreaLayer(const GraphicsLayer*) const; - - // Returns whether the given layer is a repaint needed part of the scrollable - // area, if any, associated with this mapping. - bool IsScrollableAreaLayerWhichNeedsRepaint(const GraphicsLayer*) const; - - // Helper methods to updateGraphicsLayerGeometry: - void ComputeGraphicsLayerParentLocation( - const PaintLayer* compositing_container, - gfx::Point& graphics_layer_parent_location); - void UpdateSquashingLayerGeometry( - const PaintLayer* compositing_container, - const gfx::Point& snapped_offset_from_composited_ancestor, - HeapVector<Member<GraphicsLayerPaintInfo>>& layers, - HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation); - void UpdateMainGraphicsLayerGeometry( - const gfx::Rect& local_compositing_bounds); - void UpdateMaskLayerGeometry(); - void UpdateForegroundLayerGeometry(); - void UpdateDecorationOutlineLayerGeometry( - const gfx::Size& relative_compositing_bounds_size); - void UpdateScrollingContentsLayerGeometry( - HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation); - - void CreatePrimaryGraphicsLayer(); - - Member<GraphicsLayer> CreateGraphicsLayer( - CompositingReasons, - SquashingDisallowedReasons = SquashingDisallowedReason::kNone); - - LayoutBoxModelObject& GetLayoutObject() const { - return owning_layer_->GetLayoutObject(); - } - - void UpdateInternalHierarchy(); - void UpdatePaintingPhases(); - bool UpdateForegroundLayer(bool needs_foreground_layer); - bool UpdateDecorationOutlineLayer(bool needs_decoration_outline_layer); - bool UpdateMaskLayer(bool needs_mask_layer); - bool RequiresHorizontalScrollbarLayer() const; - bool RequiresVerticalScrollbarLayer() const; - bool RequiresScrollCornerLayer() const; - bool UpdateSquashingLayers(bool needs_squashing_layers); - void UpdateDrawsContentAndPaintsHitTest(); - void UpdateCompositedBounds(); - - // Also sets subpixelAccumulation on the layer. - void ComputeBoundsOfOwningLayer( - const PaintLayer* composited_ancestor, - gfx::Rect& local_compositing_bounds, - gfx::Point& snapped_offset_from_composited_ancestor); - - GraphicsLayerPaintingPhase PaintingPhaseForPrimaryLayer() const; - - bool PaintsChildren() const; - - // Returns true if this layer has content that needs to be displayed by - // painting into the backing store. - bool ContainsPaintedContent() const; - - void UpdateContentsRect(); - - static bool HasVisibleNonCompositingDescendant(PaintLayer* parent); - - void DoPaintTask(const GraphicsLayerPaintInfo&, - const GraphicsLayer&, - PaintLayerFlags, - GraphicsContext&, - const gfx::Rect& clip) const; - - // Computes the background clip rect for the given squashed layer, up to any - // containing layer that is squashed into the same squashing layer and - // contains this squashed layer's clipping ancestor. The clip rect is - // returned in the coordinate space of the given squashed layer. If there is - // no such containing layer, returns the infinite rect. - static void UpdateLocalClipRectForSquashedLayer( - const PaintLayer& reference_layer, - const HeapVector<Member<GraphicsLayerPaintInfo>>& layers, - GraphicsLayerPaintInfo&); - - bool UpdateSquashingLayerAssignmentInternal( - HeapVector<Member<GraphicsLayerPaintInfo>>& squashed_layers, - PaintLayer& squashed_layer, - wtf_size_t next_squashed_layer_index); - - Member<PaintLayer> owning_layer_; - - // The hierarchy of layers that is maintained by the CompositedLayerMapping - // looks like this: - // - // + graphics_layer_ - // + layer_for_vertical_scrollbar_ [OPTIONAL][*] - // + layer_for_horizontal_scrollbar_ [OPTIONAL][*] - // + layer_for_scroll_corner_ [OPTIONAL][*] - // + contents layers (or contents layers under scrolling_contents_layer_) - // + decoration_outline_layer_ [OPTIONAL] - // + mask_layer_ [ OPTIONAL ] - // + non_scrolling_squashing_layer_ [ OPTIONAL ] - // - // [*] Overlay overflow controls may be placed above - // scrolling_contents_layer_, or repositioned in the graphics layer tree - // to ensure that they stack above scrolling content. - // - // Contents layers are directly under |graphics_layer_|, or under - // |scrolling_contents_layer_| when the layer is using composited scrolling. - // If owning_layer_ is a stacking context, contents layers include: - // - negative z-index children - // - foreground_layer_ - // - normal flow and positive z-index children - // If owning_layer_ is not a stacking context, contents layers are normal - // flow children. - - Member<GraphicsLayer> graphics_layer_; - - // Only used if the layer is using composited scrolling. - Member<GraphicsLayer> scrolling_contents_layer_; - gfx::Size previous_scroll_container_size_; - - // Only used if we have a mask. - Member<GraphicsLayer> mask_layer_; - - // There is one other (optional) layer whose painting is managed by the - // CompositedLayerMapping, but whose position in the hierarchy is maintained - // by the PaintLayerCompositor. This is the foreground layer. The foreground - // layer exists if we have composited descendants with negative z-order. We - // need the extra layer in this case because the layer needs to draw both - // below (for the background, say) and above (for the normal flow content, - // say) the negative z-order descendants and this is impossible with a single - // layer. The RLC handles inserting foreground_layer_ in the correct position - // in our descendant list for us (right after the neg z-order dsecendants). - // Only used in cases where we need to draw the foreground separately. - Member<GraphicsLayer> foreground_layer_; - - Member<GraphicsLayer> layer_for_horizontal_scrollbar_; - Member<GraphicsLayer> layer_for_vertical_scrollbar_; - Member<GraphicsLayer> layer_for_scroll_corner_; - - // DecorationLayer which paints outline. - Member<GraphicsLayer> decoration_outline_layer_; - - // Only used when |non_scrolling_squashed_layers_| is not empty. This is - // the backing that |non_scrolling_squashed_layers_| paint into. - Member<GraphicsLayer> non_scrolling_squashing_layer_; - gfx::Vector2d non_scrolling_squashing_layer_offset_from_layout_object_; - - // Layers that are squashed into |non_scrolling_squashing_layer_|. - HeapVector<Member<GraphicsLayerPaintInfo>> non_scrolling_squashed_layers_; - - // Layers that are squashed into |scrolling_contents_layer_|. This is used - // when |owning_layer_| is scrollable but is not a stacking context, and - // there are scrolling stacked children that can be squashed into the - // scrolling contents without breaking stacking order. We don't need a special - // layer like |non_scrolling_squashing_layer_| because these squashed layers - // are always contained by |scrolling_contents_layer_|. - HeapVector<Member<GraphicsLayerPaintInfo>> - squashed_layers_in_scrolling_contents_; - - PhysicalRect composited_bounds_; - - unsigned pending_update_scope_ : 2; - -#if DCHECK_IS_ON() - bool is_destroyed_ = false; -#endif - - friend class CompositedLayerMappingTest; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_COMPOSITED_LAYER_MAPPING_H_
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_inputs_root.cc b/third_party/blink/renderer/core/paint/compositing/compositing_inputs_root.cc deleted file mode 100644 index fddd8d0..0000000 --- a/third_party/blink/renderer/core/paint/compositing/compositing_inputs_root.cc +++ /dev/null
@@ -1,35 +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 "third_party/blink/renderer/core/paint/compositing/compositing_inputs_root.h" - -#include "third_party/blink/renderer/core/paint/paint_layer.h" - -namespace blink { - -void CompositingInputsRoot::Update(PaintLayer* new_root_layer) { - DCHECK(new_root_layer); - - if (!root_layer_) { - // This is the first time we call Update() so just let set the root layer. - root_layer_ = new_root_layer; - return; - } - - if (root_layer_ == new_root_layer) - return; - - PaintLayer* common_ancestor = - const_cast<PaintLayer*>(root_layer_->CommonAncestor(new_root_layer)); - if (!common_ancestor) - common_ancestor = const_cast<PaintLayer*>(root_layer_->Root()); - - root_layer_ = common_ancestor; -} - -void CompositingInputsRoot::Trace(Visitor* visitor) const { - visitor->Trace(root_layer_); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_inputs_root.h b/third_party/blink/renderer/core/paint/compositing/compositing_inputs_root.h deleted file mode 100644 index 37ccb88c..0000000 --- a/third_party/blink/renderer/core/paint/compositing/compositing_inputs_root.h +++ /dev/null
@@ -1,32 +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 THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_COMPOSITING_INPUTS_ROOT_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_COMPOSITING_INPUTS_ROOT_H_ - -#include "third_party/blink/renderer/platform/heap/handle.h" -#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" - -namespace blink { - -class PaintLayer; - -class CompositingInputsRoot { - DISALLOW_NEW(); - - public: - PaintLayer* Get() const { return root_layer_; } - - void Update(PaintLayer* new_root_layer); - void Clear() { root_layer_ = nullptr; } - - void Trace(Visitor* visitor) const; - - private: - Member<PaintLayer> root_layer_ = nullptr; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_COMPOSITING_INPUTS_ROOT_H_
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc b/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc deleted file mode 100644 index 8099bfb..0000000 --- a/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc +++ /dev/null
@@ -1,209 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.h" - -#include "third_party/blink/renderer/core/frame/local_frame_view.h" -#include "third_party/blink/renderer/core/frame/visual_viewport.h" -#include "third_party/blink/renderer/core/layout/layout_box_model_object.h" -#include "third_party/blink/renderer/core/layout/svg/layout_svg_root.h" -#include "third_party/blink/renderer/core/page/page.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" -#include "third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.h" -#include "third_party/blink/renderer/core/paint/fragment_data.h" -#include "third_party/blink/renderer/platform/runtime_enabled_features.h" - -namespace { -enum class ScrollbarOrCorner { - kHorizontalScrollbar, - kVerticalScrollbar, - kScrollbarCorner, -}; -} - -namespace blink { - -void CompositingLayerPropertyUpdater::Update(const LayoutObject& object) { - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) - return; - - if (!object.HasLayer()) - return; - const auto* paint_layer = To<LayoutBoxModelObject>(object).Layer(); - const auto* mapping = paint_layer->GetCompositedLayerMapping(); - if (!mapping) - return; - - const FragmentData& fragment_data = object.PrimaryStitchingFragment(); - DCHECK(fragment_data.HasLocalBorderBoxProperties()); - // SPv1 compositing forces single fragment for directly composited elements. - DCHECK(object.IsLayoutNGObject() || !object.FirstFragment().NextFragment() || - // We create multiple fragments for composited repeating fixed-position - // during printing. - object.GetDocument().Printing()); - - PhysicalOffset layout_snapped_paint_offset = - fragment_data.PaintOffset() - paint_layer->SubpixelAccumulation(); - gfx::Vector2d snapped_paint_offset = - ToRoundedPoint(layout_snapped_paint_offset).OffsetFromOrigin(); - -#if DCHECK_IS_ON() - // A layer without visible contents can be composited due to animation. - // Since the layer itself has no visible subtree, there is no guarantee - // that all of its ancestors have a visible subtree. An ancestor with no - // visible subtree can be non-composited despite we expected it to, this - // resulted in the paint offset used by CompositedLayerMapping to mismatch. - bool subpixel_accumulation_may_be_bogus = paint_layer->SubtreeIsInvisible(); - if (!subpixel_accumulation_may_be_bogus && - layout_snapped_paint_offset != PhysicalOffset(snapped_paint_offset)) { - // TODO(crbug.com/925377): Fix the root cause. - DLOG(ERROR) << "Paint offset pixel snapping error for " << object - << " expected: " << snapped_paint_offset.ToString() - << " actual: " << layout_snapped_paint_offset; - } -#endif - - absl::optional<PropertyTreeStateOrAlias> container_layer_state; - auto SetContainerLayerState = - [&fragment_data, &snapped_paint_offset, - &container_layer_state](GraphicsLayer* graphics_layer) { - if (graphics_layer) { - if (!container_layer_state) - container_layer_state = fragment_data.LocalBorderBoxProperties(); - graphics_layer->SetLayerState( - *container_layer_state, - snapped_paint_offset + graphics_layer->OffsetFromLayoutObject()); - } - }; - SetContainerLayerState(mapping->MainGraphicsLayer()); - SetContainerLayerState(mapping->DecorationOutlineLayer()); - - bool is_root_scroller = - CompositingReasonFinder::RequiresCompositingForRootScroller(*paint_layer); - - auto SetContainerLayerStateForScrollbars = - [&object, &is_root_scroller, &fragment_data, &snapped_paint_offset, - &container_layer_state](GraphicsLayer* graphics_layer, - ScrollbarOrCorner scrollbar_or_corner) { - if (!graphics_layer) - return; - PropertyTreeStateOrAlias scrollbar_layer_state = - container_layer_state.value_or( - fragment_data.LocalBorderBoxProperties()); - // OverflowControlsClip should be applied within the scrollbar layers. - if (const auto* properties = fragment_data.PaintProperties()) { - if (const auto* clip = properties->OverflowControlsClip()) - scrollbar_layer_state.SetClip(*clip); - - if (scrollbar_or_corner == ScrollbarOrCorner::kHorizontalScrollbar) { - if (const auto* effect = properties->HorizontalScrollbarEffect()) { - scrollbar_layer_state.SetEffect(*effect); - } - } else if (scrollbar_or_corner == - ScrollbarOrCorner::kVerticalScrollbar) { - if (const auto* effect = properties->VerticalScrollbarEffect()) - scrollbar_layer_state.SetEffect(*effect); - } - } - - if (is_root_scroller) { - // The root scrollbar needs to use a transform node above the - // overscroll elasticity layer because the root scrollbar should not - // bounce with overscroll. - const auto* frame_view = object.GetFrameView(); - DCHECK(frame_view); - const auto* page = frame_view->GetPage(); - const auto& viewport = page->GetVisualViewport(); - if (const auto* transform = - viewport.GetOverscrollElasticityTransformNode()) { - DCHECK(transform->Parent()); - scrollbar_layer_state.SetTransform(*transform->Parent()); - } - } - - graphics_layer->SetLayerState( - scrollbar_layer_state, - snapped_paint_offset + graphics_layer->OffsetFromLayoutObject()); - }; - - SetContainerLayerStateForScrollbars(mapping->LayerForHorizontalScrollbar(), - ScrollbarOrCorner::kHorizontalScrollbar); - SetContainerLayerStateForScrollbars(mapping->LayerForVerticalScrollbar(), - ScrollbarOrCorner::kVerticalScrollbar); - SetContainerLayerStateForScrollbars(mapping->LayerForScrollCorner(), - ScrollbarOrCorner::kScrollbarCorner); - - if (mapping->ScrollingContentsLayer()) { - // See comments for ScrollTranslation in object_paint_properties.h for the - // reason of adding ScrollOrigin(). - auto contents_paint_offset = - snapped_paint_offset + - To<LayoutBox>(object).ScrollOrigin().OffsetFromOrigin(); - auto SetScrollingContentsLayerState = [&fragment_data, - &contents_paint_offset]( - GraphicsLayer* graphics_layer) { - if (graphics_layer) { - graphics_layer->SetLayerState( - fragment_data.ContentsProperties(), - contents_paint_offset + graphics_layer->OffsetFromLayoutObject()); - } - }; - SetScrollingContentsLayerState(mapping->ScrollingContentsLayer()); - SetScrollingContentsLayerState(mapping->ForegroundLayer()); - } else { - SetContainerLayerState(mapping->ForegroundLayer()); - } - - auto* main_graphics_layer = mapping->MainGraphicsLayer(); - if (main_graphics_layer->ContentsLayer()) { - gfx::Vector2d offset; - // The offset should be zero when the layer has ReplacedContentTransform, - // because the offset has been baked into ReplacedContentTransform. - if (!fragment_data.PaintProperties() || - !fragment_data.PaintProperties()->ReplacedContentTransform()) { - offset = main_graphics_layer->ContentsRect().OffsetFromOrigin() + - main_graphics_layer->GetOffsetFromTransformNode(); - } - main_graphics_layer->SetContentsLayerState( - fragment_data.ContentsProperties(), offset); - } - - if (auto* squashing_layer = mapping->NonScrollingSquashingLayer()) { - auto state = fragment_data.PreEffectProperties(); - // The squashing layer's ClippingContainer is the common ancestor of clip - // state of all squashed layers, so we should use its clip state. This skips - // any control clips on the squashing layer's object which should not apply - // on squashed layers. - const LayoutBoxModelObject* clipping_container = nullptr; - state.SetClip( - clipping_container - ? clipping_container->FirstFragment().ContentsProperties().Clip() - : ClipPaintPropertyNode::Root()); - squashing_layer->SetLayerState( - state, snapped_paint_offset + - mapping->NonScrollingSquashingLayerOffsetFromLayoutObject()); - } - - if (auto* mask_layer = mapping->MaskLayer()) { - auto state = fragment_data.LocalBorderBoxProperties(); - const auto* properties = fragment_data.PaintProperties(); - DCHECK(properties); - DCHECK(properties->Mask() || properties->ClipPathMask()); - DCHECK(properties->MaskClip()); - state.SetEffect(properties->Mask() ? *properties->Mask() - : *properties->ClipPathMask()); - state.SetClip(*properties->MaskClip()); - - mask_layer->SetLayerState( - state, snapped_paint_offset + mask_layer->OffsetFromLayoutObject()); - } - - if (object.IsSVGRoot()) { - main_graphics_layer->SetShouldCreateLayersAfterPaint( - To<LayoutSVGRoot>(object).HasDescendantCompositingReasons() && - main_graphics_layer->PaintsContentOrHitTest()); - } -} - -} // namespace blink
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.h b/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.h deleted file mode 100644 index ac313bab..0000000 --- a/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.h +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_COMPOSITING_LAYER_PROPERTY_UPDATER_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_COMPOSITING_LAYER_PROPERTY_UPDATER_H_ - -#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" - -namespace blink { - -class LayoutObject; - -class CompositingLayerPropertyUpdater { - STATIC_ONLY(CompositingLayerPropertyUpdater); - - public: - static void Update(const LayoutObject&); -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_COMPOSITING_LAYER_PROPERTY_UPDATER_H_
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc index bcaac55..2a7251e 100644 --- a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc +++ b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc
@@ -13,7 +13,6 @@ #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/scroll/scroll_types.h" #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/testing/paint_test_configurations.h" #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" #include "third_party/blink/renderer/platform/testing/testing_platform_support.h" @@ -69,10 +68,6 @@ style='width: 100px; height: 100px; transform: translateZ(0)'></div> )HTML"); - if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { - PaintLayer* paint_layer = GetPaintLayerByElementId("target"); - EXPECT_EQ(kPaintsIntoOwnBacking, paint_layer->GetCompositingState()); - } EXPECT_REASONS( CompositingReason::kTrivial3DTransform, DirectReasonsForPaintProperties(*GetLayoutObjectByElementId("target"))); @@ -84,10 +79,6 @@ style='width: 100px; height: 100px; transform: translateZ(1px)'></div> )HTML"); - if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { - PaintLayer* paint_layer = GetPaintLayerByElementId("target"); - EXPECT_EQ(kPaintsIntoOwnBacking, paint_layer->GetCompositingState()); - } EXPECT_REASONS( CompositingReason::k3DTransform, DirectReasonsForPaintProperties(*GetLayoutObjectByElementId("target"))); @@ -107,10 +98,6 @@ style='width: 100px; height: 100px; transform: translateZ(0)'></div> )HTML"); - if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { - PaintLayer* paint_layer = GetPaintLayerByElementId("target"); - EXPECT_EQ(kNotComposited, paint_layer->GetCompositingState()); - } EXPECT_REASONS( CompositingReason::kNone, DirectReasonsForPaintProperties(*GetLayoutObjectByElementId("target"))); @@ -129,13 +116,6 @@ </div> )HTML"); - if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { - EXPECT_EQ(kPaintsIntoOwnBacking, - GetPaintLayerByElementId("sticky-top")->GetCompositingState()); - EXPECT_EQ( - kNotComposited, - GetPaintLayerByElementId("sticky-no-anchor")->GetCompositingState()); - } EXPECT_REASONS(CompositingReason::kStickyPosition, DirectReasonsForPaintProperties( *GetLayoutObjectByElementId("sticky-top"))); @@ -209,17 +189,6 @@ CompositingReason::kNone, CompositingReasonFinder::CompositingReasonsForScrollDependentPosition( *overflow_hidden_no_scrolling.Layer())); - - if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { - EXPECT_EQ(kPaintsIntoOwnBacking, - sticky_scrolling.Layer()->GetCompositingState()); - EXPECT_EQ(kNotComposited, - sticky_no_scrolling.Layer()->GetCompositingState()); - EXPECT_EQ(kPaintsIntoOwnBacking, - overflow_hidden_scrolling.Layer()->GetCompositingState()); - EXPECT_EQ(kNotComposited, - overflow_hidden_no_scrolling.Layer()->GetCompositingState()); - } } void CompositingReasonFinderTest::CheckCompositingReasonsForAnimation( @@ -292,11 +261,6 @@ ASSERT_TRUE(child_frame); LocalFrameView* child_frame_view = child_frame->View(); ASSERT_TRUE(child_frame_view); - if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { - EXPECT_EQ( - kNotComposited, - child_frame_view->GetLayoutView()->Layer()->GetCompositingState()); - } EXPECT_TRUE(child_frame_view->CanThrottleRendering()); }
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_state.h b/third_party/blink/renderer/core/paint/compositing/compositing_state.h deleted file mode 100644 index 5646f9f..0000000 --- a/third_party/blink/renderer/core/paint/compositing/compositing_state.h +++ /dev/null
@@ -1,23 +0,0 @@ -// 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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_COMPOSITING_STATE_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_COMPOSITING_STATE_H_ - -namespace blink { - -enum CompositingState { - // The layer paints into its enclosing composited ancestor. - kNotComposited = 0, - - kPaintsIntoOwnBacking = 1, - - // In this state, the Layer subtree paints into a backing that is shared by - // several Layer subtrees. - kPaintsIntoGroupedBacking = 2 -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_COMPOSITING_STATE_H_
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_test.cc b/third_party/blink/renderer/core/paint/compositing/compositing_test.cc index 029ad0ab..c0c2f92 100644 --- a/third_party/blink/renderer/core/paint/compositing/compositing_test.cc +++ b/third_party/blink/renderer/core/paint/compositing/compositing_test.cc
@@ -23,7 +23,6 @@ #include "third_party/blink/renderer/core/html/html_iframe_element.h" #include "third_party/blink/renderer/core/layout/layout_box.h" #include "third_party/blink/renderer/core/layout/layout_view.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/core/svg_names.h"
diff --git a/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.cc b/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.cc deleted file mode 100644 index e3e797a..0000000 --- a/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.cc +++ /dev/null
@@ -1,175 +0,0 @@ -/* - * Copyright (C) 2009, 2010 Apple Inc. All rights reserved. - * Copyright (C) 2014 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.h" - -#include "third_party/blink/renderer/core/html/media/html_media_element.h" -#include "third_party/blink/renderer/core/html/media/html_video_element.h" -#include "third_party/blink/renderer/core/layout/layout_embedded_content.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" -#include "third_party/blink/renderer/core/paint/paint_layer.h" -#include "third_party/blink/renderer/core/paint/paint_layer_paint_order_iterator.h" -#include "third_party/blink/renderer/platform/heap/collection_support/clear_collection_scope.h" - -namespace blink { - -GraphicsLayerTreeBuilder::GraphicsLayerTreeBuilder() = default; - -static bool ShouldAppendLayer(const PaintLayer& layer) { - auto* video_element = - DynamicTo<HTMLVideoElement>(layer.GetLayoutObject().GetNode()); - if (video_element && video_element->IsFullscreen() && - video_element->UsesOverlayFullscreenVideo()) { - return false; - } - return true; -} - -void GraphicsLayerTreeBuilder::Rebuild(PaintLayer& layer, - GraphicsLayerVector& child_layers) { - PendingOverflowControlReparents ignored; - ClearCollectionScope<PendingOverflowControlReparents> scope(&ignored); - RebuildRecursive(layer, child_layers, ignored); -} - -using PendingPair = std::pair<const PaintLayer*, wtf_size_t>; - -void GraphicsLayerTreeBuilder::RebuildRecursive( - PaintLayer& layer, - GraphicsLayerVector& child_layers, - PendingOverflowControlReparents& pending_reparents) { - // Make the layer compositing if necessary, and set up clipping and content - // layers. Note that we can only do work here that is independent of whether - // the descendant layers have been processed. computeCompositingRequirements() - // will already have done the paint invalidation if necessary. - - const bool has_composited_layer_mapping = layer.HasCompositedLayerMapping(); - CompositedLayerMapping* current_composited_layer_mapping = - layer.GetCompositedLayerMapping(); - - // If this layer has a compositedLayerMapping, then that is where we place - // subsequent children GraphicsLayers. Otherwise children continue to append - // to the child list of the enclosing layer. - GraphicsLayerVector this_layer_children; - GraphicsLayerVector* layer_vector_for_children = - has_composited_layer_mapping ? &this_layer_children : &child_layers; - - PendingOverflowControlReparents this_pending_reparents_children; - ClearCollectionScope<PendingOverflowControlReparents> scope( - &this_pending_reparents_children); - - PendingOverflowControlReparents* pending_reparents_for_children = - has_composited_layer_mapping ? &this_pending_reparents_children - : &pending_reparents; - -#if DCHECK_IS_ON() - PaintLayerListMutationDetector mutation_checker(&layer); -#endif - - bool recursion_blocked_by_display_lock = - layer.GetLayoutObject().ChildPrePaintBlockedByDisplayLock(); - if (layer.IsStackingContextWithNegativeZOrderChildren()) { - if (!recursion_blocked_by_display_lock) { - PaintLayerPaintOrderIterator iterator(&layer, kNegativeZOrderChildren); - while (PaintLayer* child_layer = iterator.Next()) { - RebuildRecursive(*child_layer, *layer_vector_for_children, - *pending_reparents_for_children); - } - } - - // If a negative z-order child is compositing, we get a foreground layer - // which needs to get parented. - if (has_composited_layer_mapping && - current_composited_layer_mapping->ForegroundLayer()) { - layer_vector_for_children->push_back( - current_composited_layer_mapping->ForegroundLayer()); - } - } - - if (!recursion_blocked_by_display_lock) { - PaintLayerPaintOrderIterator iterator(&layer, - kNormalFlowAndPositiveZOrderChildren); - while (PaintLayer* child_layer = iterator.Next()) { - RebuildRecursive(*child_layer, *layer_vector_for_children, - *pending_reparents_for_children); - } - } - - if (has_composited_layer_mapping) { - // TODO(szager): Remove after diagnosing crash crbug.com/1092673 - CHECK(current_composited_layer_mapping); - - // Apply all pending reparents by inserting the overflow controls - // root layers into |this_layer_children|. To do this, first sort - // them by index. Then insert them one-by-one into the array, - // incrementing |offset| by one each time to account for previous - // insertions. - wtf_size_t offset = 0; - Vector<PendingPair> pending; - for (auto& item : *pending_reparents_for_children) - pending.push_back(std::make_pair(item.key, item.value)); - pending_reparents_for_children->clear(); - - std::sort(pending.begin(), pending.end(), - [](const PendingPair& a, const PendingPair& b) { - return a.second < b.second; - }); - for (auto& item : pending) { - offset += item.first->GetCompositedLayerMapping() - ->MoveOverflowControlLayersInto(this_layer_children, - item.second + offset); - } - - if (!this_layer_children.IsEmpty()) { - current_composited_layer_mapping->SetSublayers( - std::move(this_layer_children)); - } - - if (ShouldAppendLayer(layer)) { - child_layers.push_back( - current_composited_layer_mapping->MainGraphicsLayer()); - } - } - - // Also insert for self, to handle the case of scrollers with negative - // z-index children (the scrolbars should still paint on top of the - // scroller itself). - if (layer.GetLayoutObject().IsStacked() && has_composited_layer_mapping && - layer.GetCompositedLayerMapping()->NeedsToReparentOverflowControls()) - pending_reparents.Set(&layer, child_layers.size()); - - // Set or overwrite the entry in |pending_reparents| for this scroller. - // Overlay scrollbars need to paint on top of all content under the scroller, - // so keep overwriting if we find a PaintLayer that is later in paint order. - const PaintLayer* scroll_parent = layer.ScrollParent(); - if (layer.GetLayoutObject().IsStacked() && scroll_parent && - scroll_parent->HasCompositedLayerMapping() && - scroll_parent->GetCompositedLayerMapping() - ->NeedsToReparentOverflowControls()) - pending_reparents.Set(layer.ScrollParent(), child_layers.size()); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.h b/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.h deleted file mode 100644 index 8fbe89e6..0000000 --- a/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.h +++ /dev/null
@@ -1,60 +0,0 @@ -/* - * Copyright (C) 2009, 2010 Apple Inc. All rights reserved. - * Copyright (C) 2014 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_GRAPHICS_LAYER_TREE_BUILDER_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_GRAPHICS_LAYER_TREE_BUILDER_H_ - -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" -#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_map.h" -#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" - -namespace blink { - -class PaintLayer; - -class GraphicsLayerTreeBuilder { - STACK_ALLOCATED(); - - public: - GraphicsLayerTreeBuilder(); - - void Rebuild(PaintLayer&, GraphicsLayerVector&); - - private: - // Maps from PaintLayer::ScrollParent to index into |child_layers| (see below - // for child_layers parameter) at which to insert the overflow controls - // graphics layers for ScrollParent when reparenting them. - using PendingOverflowControlReparents = - HeapHashMap<Member<const PaintLayer>, size_t>; - - void RebuildRecursive(PaintLayer&, - GraphicsLayerVector& child_layers, - PendingOverflowControlReparents& pending_reparents); -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_GRAPHICS_LAYER_TREE_BUILDER_H_
diff --git a/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.cc b/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.cc deleted file mode 100644 index 09bb3119..0000000 --- a/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.cc +++ /dev/null
@@ -1,182 +0,0 @@ -/* - * Copyright (C) 2009, 2010 Apple Inc. All rights reserved. - * Copyright (C) 2014 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.h" - -#include "third_party/blink/renderer/core/html/media/html_media_element.h" -#include "third_party/blink/renderer/core/layout/layout_block.h" -#include "third_party/blink/renderer/core/layout/layout_embedded_content.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" -#include "third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.h" -#include "third_party/blink/renderer/core/paint/paint_layer.h" -#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" -#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" - -namespace blink { - -GraphicsLayerUpdater::UpdateContext::UpdateContext() - : compositing_stacking_context_(nullptr), - compositing_ancestor_(nullptr), - use_slow_path_(false) {} - -GraphicsLayerUpdater::UpdateContext::UpdateContext(const UpdateContext& other, - const PaintLayer& layer) - : compositing_stacking_context_(other.compositing_stacking_context_), - compositing_ancestor_(other.CompositingContainer(layer)), - use_slow_path_(other.use_slow_path_) { - CompositingState compositing_state = layer.GetCompositingState(); - if (compositing_state != kNotComposited && - compositing_state != kPaintsIntoGroupedBacking) { - compositing_ancestor_ = &layer; - if (layer.GetLayoutObject().IsStackingContext()) - compositing_stacking_context_ = &layer; - } - // Any composited content under SVG must be a descendant of (but not - // equal to, see PaintLayerCompositor::CanBeComposited) - // a <foreignObject> element. The rules for compositing ancestors are - // complicated for this situation, due to <foreignObject> being a replaced - // nornmal-flow stacking element - // (see PaintLayer::IsReplacedNormalFlowStacking). Use a slow path - // for these situations, to simplify the logic. - if (layer.GetLayoutObject().IsSVGRoot() || - layer.IsReplacedNormalFlowStacking()) - use_slow_path_ = true; - - parent_object_offset_delta = - compositing_ancestor_ == other.compositing_ancestor_ - ? other.parent_object_offset_delta - : other.object_offset_delta; -} - -const PaintLayer* GraphicsLayerUpdater::UpdateContext::CompositingContainer( - const PaintLayer& layer) const { - if (use_slow_path_) - return layer.EnclosingLayerWithCompositedLayerMapping(kExcludeSelf); - - const PaintLayer* compositing_container; - if (layer.GetLayoutObject().IsStacked() && - !layer.IsReplacedNormalFlowStacking()) { - compositing_container = compositing_stacking_context_; - } else if ((layer.Parent() && - !layer.Parent()->GetLayoutObject().IsLayoutBlock()) || - layer.GetLayoutObject().IsColumnSpanAll()) { - // In these cases, compositingContainer may escape the normal layer - // hierarchy. Use the slow path to ensure correct result. - // See PaintLayer::containingLayer() for details. - compositing_container = - layer.EnclosingLayerWithCompositedLayerMapping(kExcludeSelf); - } else { - compositing_container = compositing_ancestor_; - } - - // We should always get the same result as the slow path. - DCHECK_EQ(compositing_container, - layer.EnclosingLayerWithCompositedLayerMapping(kExcludeSelf)); - return compositing_container; -} - -const PaintLayer* -GraphicsLayerUpdater::UpdateContext::CompositingStackingContext() const { - return compositing_stacking_context_; -} - -GraphicsLayerUpdater::GraphicsLayerUpdater() : needs_rebuild_tree_(false) {} - -void GraphicsLayerUpdater::Update( - PaintLayer& layer, - HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation) { - TRACE_EVENT0("blink", "GraphicsLayerUpdater::update"); - UpdateContext update_context; - UpdateRecursive(layer, kDoNotForceUpdate, update_context, - layers_needing_paint_invalidation); -} - -void GraphicsLayerUpdater::UpdateRecursive( - PaintLayer& layer, - UpdateType update_type, - UpdateContext& context, - HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation) { - if (layer.HasCompositedLayerMapping()) { - CompositedLayerMapping* mapping = layer.GetCompositedLayerMapping(); - - if (update_type == kForceUpdate || mapping->NeedsGraphicsLayerUpdate()) { - bool had_scrolling_layer = mapping->ScrollingContentsLayer(); - const auto* compositing_container = context.CompositingContainer(layer); - if (mapping->UpdateGraphicsLayerConfiguration(compositing_container)) { - needs_rebuild_tree_ = true; - // Change of existence of scrolling layer affects visual rect offsets of - // descendants via LayoutObject::ScrollAdjustmentForPaintInvalidation(). - if (had_scrolling_layer != !!mapping->ScrollingContentsLayer()) - layers_needing_paint_invalidation.push_back(&layer); - } - mapping->UpdateGraphicsLayerGeometry(compositing_container, - layers_needing_paint_invalidation); - if (PaintLayerScrollableArea* scrollable_area = layer.GetScrollableArea()) - scrollable_area->PositionOverflowControls(); - update_type = mapping->UpdateTypeForChildren(update_type); - mapping->ClearNeedsGraphicsLayerUpdate(); - - // TODO(crbug.com/1058792): Allow multiple fragments for composited - // elements (passing |iterator| here is probably part of the solution). - CompositingLayerPropertyUpdater::Update(layer.GetLayoutObject()); - } - } - - PaintLayer* first_child = layer.FirstChild(); - // If we have children but the update is blocked, then we should clear the - // first child to block recursion. - if (first_child && - layer.GetLayoutObject().ChildPrePaintBlockedByDisplayLock()) { - first_child = nullptr; - } - - UpdateContext child_context(context, layer); - for (PaintLayer* child = first_child; child; child = child->NextSibling()) { - UpdateRecursive(*child, update_type, child_context, - layers_needing_paint_invalidation); - } -} - -#if DCHECK_IS_ON() - -void GraphicsLayerUpdater::AssertNeedsToUpdateGraphicsLayerBitsCleared( - PaintLayer& layer) { - if (layer.HasCompositedLayerMapping()) { - layer.GetCompositedLayerMapping() - ->AssertNeedsToUpdateGraphicsLayerBitsCleared(); - } - - PaintLayer* first_child = - layer.GetLayoutObject().ChildPrePaintBlockedByDisplayLock() - ? nullptr - : layer.FirstChild(); - for (PaintLayer* child = first_child; child; child = child->NextSibling()) - AssertNeedsToUpdateGraphicsLayerBitsCleared(*child); -} - -#endif - -} // namespace blink
diff --git a/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.h b/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.h deleted file mode 100644 index 830e025..0000000 --- a/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.h +++ /dev/null
@@ -1,93 +0,0 @@ -/* - * Copyright (C) 2009, 2010 Apple Inc. All rights reserved. - * Copyright (C) 2014 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_GRAPHICS_LAYER_UPDATER_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_GRAPHICS_LAYER_UPDATER_H_ - -#include "base/dcheck_is_on.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" -#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" - -namespace blink { - -class PaintLayer; - -class GraphicsLayerUpdater { - STACK_ALLOCATED(); - - public: - GraphicsLayerUpdater(); - - enum UpdateType { - kDoNotForceUpdate, - kForceUpdate, - }; - - void Update( - PaintLayer&, - HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation); - - bool NeedsRebuildTree() const { return needs_rebuild_tree_; } - -#if DCHECK_IS_ON() - static void AssertNeedsToUpdateGraphicsLayerBitsCleared(PaintLayer&); -#endif - - class UpdateContext { - STACK_ALLOCATED(); - - public: - UpdateContext(); - UpdateContext(const UpdateContext& other, const PaintLayer& layer); - const PaintLayer* CompositingContainer(const PaintLayer& layer) const; - const PaintLayer* CompositingStackingContext() const; - - // Offset of this PaintLayer's LayoutObject relative to the position of its - // main GraphicsLayer. - gfx::Vector2d object_offset_delta; - - // The object_offset_delta of the compositing ancestor. - gfx::Vector2d parent_object_offset_delta; - - private: - const PaintLayer* compositing_stacking_context_; - const PaintLayer* compositing_ancestor_; - bool use_slow_path_; - }; - - private: - void UpdateRecursive( - PaintLayer&, - UpdateType, - UpdateContext&, - HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation); - - bool needs_rebuild_tree_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_GRAPHICS_LAYER_UPDATER_H_
diff --git a/third_party/blink/renderer/core/paint/frame_painter.cc b/third_party/blink/renderer/core/paint/frame_painter.cc index 9c76d96..1af0d43 100644 --- a/third_party/blink/renderer/core/paint/frame_painter.cc +++ b/third_party/blink/renderer/core/paint/frame_painter.cc
@@ -14,7 +14,6 @@ #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer_painter.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/graphics/paint/cull_rect.h" #include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h" #include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h"
diff --git a/third_party/blink/renderer/core/paint/link_highlight_impl.cc b/third_party/blink/renderer/core/paint/link_highlight_impl.cc index 9396cc29f..572a327f 100644 --- a/third_party/blink/renderer/core/paint/link_highlight_impl.cc +++ b/third_party/blink/renderer/core/paint/link_highlight_impl.cc
@@ -47,7 +47,6 @@ #include "third_party/blink/renderer/core/layout/layout_object.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/fragment_data_iterator.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" @@ -56,7 +55,6 @@ #include "third_party/blink/renderer/platform/animation/compositor_keyframe_model.h" #include "third_party/blink/renderer/platform/animation/compositor_target_property.h" #include "third_party/blink/renderer/platform/animation/timing_function.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_recorder.h"
diff --git a/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc b/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc index 53971c2..a51c5b17 100644 --- a/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc +++ b/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc
@@ -48,7 +48,6 @@ #include "third_party/blink/renderer/platform/animation/compositor_animation_timeline.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/heap/thread_state.h" #include "third_party/blink/renderer/platform/testing/paint_test_configurations.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
diff --git a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc index c5f9bae..a039ee1 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
@@ -30,7 +30,6 @@ #include "third_party/blink/renderer/core/paint/box_border_painter.h" #include "third_party/blink/renderer/core/paint/box_decoration_data.h" #include "third_party/blink/renderer/core/paint/box_painter.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/ng/ng_fieldset_painter.h" #include "third_party/blink/renderer/core/paint/ng/ng_fragment_painter.h" #include "third_party/blink/renderer/core/paint/ng/ng_inline_box_fragment_painter.h"
diff --git a/third_party/blink/renderer/core/paint/object_paint_invalidator.cc b/third_party/blink/renderer/core/paint/object_paint_invalidator.cc index aa420b6..61d6ac8 100644 --- a/third_party/blink/renderer/core/paint/object_paint_invalidator.cc +++ b/third_party/blink/renderer/core/paint/object_paint_invalidator.cc
@@ -9,143 +9,11 @@ #include "third_party/blink/renderer/core/layout/layout_embedded_content.h" #include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/page/chrome_client.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/paint_invalidator.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" namespace blink { -template <typename Functor> -static void TraverseNonCompositingDescendantsInPaintOrder(const LayoutObject&, - const Functor&); - -static bool MayBeSkippedContainerForFloating(const LayoutObject& object) { - return !object.IsInLayoutNGInlineFormattingContext() && - !object.IsLayoutBlock(); -} - -template <typename Functor> -static void -TraverseNonCompositingDescendantsBelongingToAncestorPaintInvalidationContainer( - const LayoutObject& object, - const Functor& functor) { - // |object| is a paint invalidation container, but is not a stacking context - // (legacy layout only: or is a non-block), so the paint invalidation - // container of stacked descendants may not belong to |object| but belong to - // an ancestor. This function traverses all such descendants. See (legacy - // layout only: Case 1a and) Case 2 below for details. - DCHECK(object.IsPaintInvalidationContainer() && - (!object.IsStackingContext() || - MayBeSkippedContainerForFloating(object))); - - LayoutObject* descendant = object.NextInPreOrder(&object); - while (descendant) { - if (!descendant->HasLayer() || !descendant->IsStacked()) { - // Case 1: The descendant is not stacked (or is stacked but has not been - // allocated a layer yet during style change), so either it's a paint - // invalidation container in the same situation as |object|, or its paint - // invalidation container is in such situation. Keep searching until a - // stacked layer is found. - if (MayBeSkippedContainerForFloating(object) && - descendant->IsFloating()) { - // The following is for legacy layout only because LayoutNG allows an - // inline to contain floats. - // Case 1a (rare): However, if the descendant is a floating object below - // a composited non-block object, the subtree may belong to an ancestor - // in paint order, thus recur into the subtree. Note that for - // performance, we don't check whether the floating object's container - // is above or under |object|, so we may traverse more than expected. - // Example: - // <span id="object" class="position: relative; will-change: transform"> - // <div id="descendant" class="float: left"></div>" - // </span> - TraverseNonCompositingDescendantsInPaintOrder(*descendant, functor); - descendant = descendant->NextInPreOrderAfterChildren(&object); - } else { - descendant = descendant->NextInPreOrder(&object); - } - } else if (!descendant->IsPaintInvalidationContainer()) { - // Case 2: The descendant is stacked and is not composited. - // The invalidation container of its subtree is our ancestor, - // thus recur into the subtree. - TraverseNonCompositingDescendantsInPaintOrder(*descendant, functor); - descendant = descendant->NextInPreOrderAfterChildren(&object); - } else if (descendant->IsStackingContext() && - !MayBeSkippedContainerForFloating(*descendant)) { - // Case 3: The descendant is an invalidation container and is a stacking - // context. No objects in the subtree can have invalidation container - // outside of it, thus skip the whole subtree. - // Legacy layout only: This excludes non-block because there might be - // floating objects under the descendant belonging to some ancestor in - // paint order (Case 1a). - descendant = descendant->NextInPreOrderAfterChildren(&object); - } else { - // Case 4: The descendant is an invalidation container but not a stacking - // context, or the descendant is a non-block stacking context. - // This is the same situation as |object|, thus keep searching. - descendant = descendant->NextInPreOrder(&object); - } - } -} - -template <typename Functor> -static void TraverseNonCompositingDescendantsInPaintOrder( - const LayoutObject& object, - const Functor& functor) { - functor(object); - LayoutObject* descendant = object.NextInPreOrder(&object); - while (descendant) { - if (!descendant->IsPaintInvalidationContainer()) { - functor(*descendant); - descendant = descendant->NextInPreOrder(&object); - } else if (descendant->IsStackingContext() && - !MayBeSkippedContainerForFloating(*descendant)) { - // The descendant is an invalidation container and is a stacking context. - // No objects in the subtree can have invalidation container outside of - // it, thus skip the whole subtree. - // Legacy layout only: This excludes non-blocks because there might be - // floating objects under the descendant belonging to some ancestor in - // paint order (Case 1a). - descendant = descendant->NextInPreOrderAfterChildren(&object); - } else { - // If a paint invalidation container is not a stacking context, or the - // descendant is a non-block stacking context, some of its descendants may - // belong to the parent container. - TraverseNonCompositingDescendantsBelongingToAncestorPaintInvalidationContainer( - *descendant, functor); - descendant = descendant->NextInPreOrderAfterChildren(&object); - } - } -} - -static void SetPaintingLayerNeedsRepaintDuringTraverse( - const LayoutObject& object) { - if (object.HasLayer() && - To<LayoutBoxModelObject>(object).HasSelfPaintingLayer()) { - To<LayoutBoxModelObject>(object).Layer()->SetNeedsRepaint(); - } else if (object.IsFloating() && object.Parent() && - MayBeSkippedContainerForFloating(*object.Parent())) { - // The following is for legacy layout only because LayoutNG allows an - // inline to contain floats. - object.PaintingLayer()->SetNeedsRepaint(); - } -} - -void ObjectPaintInvalidator:: - InvalidatePaintIncludingNonCompositingDescendants() { - DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()); - SlowSetPaintingLayerNeedsRepaint(); - // This method may be used to invalidate paint of objects changing paint - // invalidation container. - // TODO(vmpstr): After paint containment isolation is in place, we might not - // have to recurse past the paint containment boundary. - TraverseNonCompositingDescendantsInPaintOrder( - object_, [](const LayoutObject& object) { - SetPaintingLayerNeedsRepaintDuringTraverse(object); - }); -} - #if DCHECK_IS_ON() void ObjectPaintInvalidator::CheckPaintLayerNeedsRepaint() { DCHECK(!object_.PaintingLayer() ||
diff --git a/third_party/blink/renderer/core/paint/object_paint_invalidator.h b/third_party/blink/renderer/core/paint/object_paint_invalidator.h index bc53051b..2065cb6 100644 --- a/third_party/blink/renderer/core/paint/object_paint_invalidator.h +++ b/third_party/blink/renderer/core/paint/object_paint_invalidator.h
@@ -55,8 +55,6 @@ client.Invalidate(reason); } - void InvalidatePaintIncludingNonCompositingDescendants(); - protected: #if DCHECK_IS_ON() void CheckPaintLayerNeedsRepaint();
diff --git a/third_party/blink/renderer/core/paint/object_paint_invalidator_test.cc b/third_party/blink/renderer/core/paint/object_paint_invalidator_test.cc index 6a34e8d..e6da083 100644 --- a/third_party/blink/renderer/core/paint/object_paint_invalidator_test.cc +++ b/third_party/blink/renderer/core/paint/object_paint_invalidator_test.cc
@@ -12,7 +12,6 @@ #include "third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/json/json_values.h" #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
diff --git a/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc b/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc index a9f8de0..71be1aa5 100644 --- a/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc +++ b/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc
@@ -6,7 +6,6 @@ #include "testing/gmock/include/gmock/gmock-matchers.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" @@ -398,14 +397,6 @@ GetDocument().View()->SetTracksRasterInvalidations(false); } -static const LayoutBoxModelObject& EnclosingCompositedContainer( - const LayoutObject& layout_object) { - DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()); - return layout_object.PaintingLayer() - ->EnclosingLayerForPaintInvalidationCrossingFrameBoundaries() - ->GetLayoutObject(); -} - TEST_P(PaintAndRasterInvalidationTest, NonCompositedLayoutViewResize) { ScopedPreferNonCompositedScrollingForTest non_composited_scrolling(true); @@ -426,10 +417,6 @@ UpdateAllLifecyclePhasesForTest(); Element* iframe = GetDocument().getElementById("iframe"); Element* content = ChildDocument().getElementById("content"); - if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { - EXPECT_EQ(GetLayoutView(), - EnclosingCompositedContainer(*content->GetLayoutObject())); - } EXPECT_EQ(kBackgroundPaintInContentsSpace, content->GetLayoutObject() ->View() @@ -510,10 +497,6 @@ UpdateAllLifecyclePhasesForTest(); Element* iframe = GetDocument().getElementById("iframe"); Element* content = ChildDocument().getElementById("content"); - if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { - EXPECT_EQ(GetLayoutView(), - EnclosingCompositedContainer(*content->GetLayoutObject())); - } // Resize the content. GetDocument().View()->SetTracksRasterInvalidations(true); @@ -663,8 +646,6 @@ ASSERT_NO_EXCEPTION); Element* child = GetDocument().getElementById("child"); UpdateAllLifecyclePhasesForTest(); - if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) - EXPECT_EQ(&GetLayoutView(), EnclosingCompositedContainer(*object)); EXPECT_EQ(kBackgroundPaintInContentsSpace, object->ComputeBackgroundPaintLocationIfComposited()); EXPECT_EQ(kBackgroundPaintInBorderBoxSpace,
diff --git a/third_party/blink/renderer/core/paint/paint_controller_paint_test.h b/third_party/blink/renderer/core/paint/paint_controller_paint_test.h index ce671821..19e2bd3 100644 --- a/third_party/blink/renderer/core/paint/paint_controller_paint_test.h +++ b/third_party/blink/renderer/core/paint/paint_controller_paint_test.h
@@ -13,8 +13,8 @@ #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/graphics/paint/cull_rect.h" +#include "third_party/blink/renderer/platform/graphics/paint/paint_chunk_subset.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_controller_test.h" #include "third_party/blink/renderer/platform/testing/paint_test_configurations.h"
diff --git a/third_party/blink/renderer/core/paint/paint_layer.cc b/third_party/blink/renderer/core/paint/paint_layer.cc index 28f7ddfa..1e12775 100644 --- a/third_party/blink/renderer/core/paint/paint_layer.cc +++ b/third_party/blink/renderer/core/paint/paint_layer.cc
@@ -75,7 +75,6 @@ #include "third_party/blink/renderer/core/page/scrolling/sticky_position_scrolling_constraints.h" #include "third_party/blink/renderer/core/paint/box_reflection_utils.h" #include "third_party/blink/renderer/core/paint/clip_path_clipper.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.h" #include "third_party/blink/renderer/core/paint/filter_effect_builder.h" #include "third_party/blink/renderer/core/paint/hit_testing_transform_state.h" @@ -362,17 +361,6 @@ return GetLayoutObject().Container() == GetLayoutObject().View(); } -bool PaintLayer::ScrollsWithRespectTo(const PaintLayer* other) const { - DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()); - if (FixedToViewport() != other->FixedToViewport()) - return true; - // If either element sticks we cannot trivially determine that the layers do - // not scroll with respect to each other. - if (SticksToScroller() || other->SticksToScroller()) - return true; - return AncestorScrollingLayer() != other->AncestorScrollingLayer(); -} - bool PaintLayer::IsAffectedByScrollOf(const PaintLayer* ancestor) const { if (this == ancestor) return false; @@ -868,19 +856,6 @@ return SlowContainingLayer(ancestor, skipped_ancestor, &layout_object); } -PhysicalOffset PaintLayer::ComputeOffsetFromAncestor( - const PaintLayer& ancestor_layer) const { - const LayoutBoxModelObject& ancestor_object = - ancestor_layer.GetLayoutObject(); - PhysicalOffset result = GetLayoutObject().LocalToAncestorPoint( - PhysicalOffset(), &ancestor_object, kIgnoreTransforms); - if (ancestor_object.UsesCompositedScrolling()) { - result += PhysicalOffset( - To<LayoutBox>(ancestor_object).PixelSnappedScrolledContentOffset()); - } - return result; -} - PaintLayer* PaintLayer::CompositingContainer() const { if (IsReplacedNormalFlowStacking()) return Parent(); @@ -901,73 +876,8 @@ return nullptr; } -bool PaintLayer::IsPaintInvalidationContainer() const { - return GetCompositingState() == kPaintsIntoOwnBacking || - GetCompositingState() == kPaintsIntoGroupedBacking; -} - -// Return the enclosingCompositedLayerForPaintInvalidation for the given Layer -// including crossing frame boundaries. -PaintLayer* -PaintLayer::EnclosingLayerForPaintInvalidationCrossingFrameBoundaries() const { - const PaintLayer* layer = this; - PaintLayer* composited_layer = nullptr; - while (!composited_layer) { - composited_layer = layer->EnclosingLayerForPaintInvalidation(); - if (!composited_layer) { - CHECK(layer->GetLayoutObject().GetFrame()); - auto* owner = layer->GetLayoutObject().GetFrame()->OwnerLayoutObject(); - if (!owner) - break; - layer = owner->EnclosingLayer(); - } - } - return composited_layer; -} - -PaintLayer* PaintLayer::EnclosingLayerForPaintInvalidation() const { - if (IsPaintInvalidationContainer()) - return const_cast<PaintLayer*>(this); - - for (PaintLayer* curr = CompositingContainer(); curr; - curr = curr->CompositingContainer()) { - if (curr->IsPaintInvalidationContainer()) - return curr; - } - - return nullptr; -} - -bool PaintLayer::CanBeComposited() const { - LocalFrameView* frame_view = GetLayoutObject().GetFrameView(); - // Elements within an invisible frame must not be composited because they are - // not drawn. - if (frame_view && !frame_view->IsVisible()) - return false; - - DCHECK(!frame_view->ShouldThrottleRendering()); - - const bool has_compositor_animation = - CompositingReasonFinder::CompositingReasonsForAnimation( - GetLayoutObject()) != CompositingReason::kNone; - - return frame_view->GetFrame() - .GetSettings() - ->GetAcceleratedCompositingEnabled() && - (has_compositor_animation || !SubtreeIsInvisible()) && - IsSelfPaintingLayer() && !GetLayoutObject().IsLayoutFlowThread() && - // Don't composite <foreignObject> for the moment, to reduce instances - // of the "fundamental compositing bug" breaking painting order. - // With CompositeSVG, foreignObjects will be correctly composited after - // paint in PaintArtifactCompositor without a GraphicsLayer. - // Composited descendants of foreignObject will still break painting - // order which will be fixed in CompositeAfterPaint. - !GetLayoutObject().IsSVGForeignObject(); -} - const PaintLayer* PaintLayer::EnclosingCompositedScrollingLayerUnderPagination( IncludeSelfOrNot include_self_or_not) const { - DCHECK(RuntimeEnabledFeatures::CompositeAfterPaintEnabled()); const auto* start_layer = include_self_or_not == kIncludeSelf ? this : CompositingContainer(); for (const auto* curr = start_layer; curr && curr->EnclosingPaginationLayer(); @@ -1138,8 +1048,7 @@ if (GetLayoutObject().IsStacked(*old_style)) DirtyStackingContextZOrderLists(); - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() && - PaintLayerPainter::PaintedOutputInvisible(*old_style)) { + if (PaintLayerPainter::PaintedOutputInvisible(*old_style)) { // PaintedOutputInvisible() was true because opacity was near zero, and // this layer is to be removed because opacity becomes 1. Do the same as // StyleDidChange() on change of PaintedOutputInvisible(). @@ -1359,12 +1268,6 @@ DirtyStackingContextZOrderLists(); } -bool PaintLayer::HasOverflowControls() const { - return scrollable_area_ && (scrollable_area_->HasScrollbar() || - scrollable_area_->ScrollCorner() || - GetLayoutObject().StyleRef().HasResize()); -} - void PaintLayer::AppendSingleFragmentIgnoringPaginationForHitTesting( PaintLayerFragments& fragments, ShouldRespectOverflowClipType respect_overflow_clip) const { @@ -2558,16 +2461,8 @@ PaintLayerPaintOrderIterator iterator(this, kAllChildren); while (PaintLayer* child_layer = iterator.Next()) { - // Here we exclude both directly composited layers and squashing layers - // because those Layers don't paint into the graphics layer - // for this Layer. For example, the bounds of squashed Layers - // will be included in the computation of the appropriate squashing - // GraphicsLayer. - if ((options & kIncludeCompositedChildLayers) || - child_layer->GetCompositingState() == kNotComposited) { - result.Unite(child_layer->BoundingBoxForCompositingInternal( - composited_layer, this, options)); - } + result.Unite(child_layer->BoundingBoxForCompositingInternal( + composited_layer, this, options)); } } @@ -2679,25 +2574,9 @@ return result; } -bool PaintLayer::NeedsCompositedScrolling() const { - return scrollable_area_ && scrollable_area_->NeedsCompositedScrolling(); -} - bool PaintLayer::PaintsWithTransform( GlobalPaintFlags global_paint_flags) const { - return Transform() && !PaintsIntoOwnBacking(global_paint_flags); -} - -bool PaintLayer::PaintsIntoOwnBacking( - GlobalPaintFlags global_paint_flags) const { - return !(global_paint_flags & kGlobalPaintFlattenCompositingLayers) && - GetCompositingState() == kPaintsIntoOwnBacking; -} - -bool PaintLayer::PaintsIntoOwnOrGroupedBacking( - GlobalPaintFlags global_paint_flags) const { - return !(global_paint_flags & kGlobalPaintFlattenCompositingLayers) && - GetCompositingState() != kNotComposited; + return Transform(); } bool PaintLayer::SupportsSubsequenceCaching() const { @@ -2725,11 +2604,6 @@ return GetLayoutObject().IsStacked(); } -ScrollingCoordinator* PaintLayer::GetScrollingCoordinator() { - Page* page = GetLayoutObject().GetFrame()->GetPage(); - return (!page) ? nullptr : page->GetScrollingCoordinator(); -} - bool PaintLayer::ShouldBeSelfPaintingLayer() const { return GetLayoutObject().LayerTypeRequired() == kNormalPaintLayer || (scrollable_area_ && scrollable_area_->HasOverlayOverflowControls()) || @@ -2775,38 +2649,6 @@ return layer; } -bool PaintLayer::HasNonEmptyChildLayoutObjects() const { - // Some HTML can cause whitespace text nodes to have layoutObjects, like: - // <div> - // <img src=...> - // </div> - // so test for 0x0 LayoutTexts here - for (const auto* child = GetLayoutObject().SlowFirstChild(); child; - child = child->NextSibling()) { - if (!child->HasLayer()) { - if (child->IsLayoutInline() || !child->IsBox()) - return true; - - const auto* box = To<LayoutBox>(child); - if (!box->Size().IsZero() || box->HasVisualOverflow()) - return true; - } - } - return false; -} - -bool PaintLayer::HasBoxDecorationsOrBackground() const { - return GetLayoutObject().StyleRef().HasBoxDecorations() || - GetLayoutObject().StyleRef().HasBackground(); -} - -bool PaintLayer::HasVisibleBoxDecorations() const { - if (!HasVisibleContent()) - return false; - - return HasBoxDecorationsOrBackground() || HasOverflowControls(); -} - void PaintLayer::UpdateFilters(const ComputedStyle* old_style, const ComputedStyle& new_style) { if (!filter_on_effect_node_dirty_) { @@ -2916,17 +2758,11 @@ PaintLayerPainter::PaintedOutputInvisible(new_style); if (PaintLayerPainter::PaintedOutputInvisible(*old_style) != new_painted_output_invisible) { - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { - // Force repaint of the subtree for two purposes: - // 1. To ensure FCP/LCP will be reported. See crbug.com/1184903. - // 2. To update effectively_invisible flags of PaintChunks. - // TODO(crbug.com/1104218): Optimize this. - GetLayoutObject().SetSubtreeShouldDoFullPaintInvalidation(); - } else { - // Change of PaintedOutputInvisible() will affect existence of paint - // chunks, so needs repaint. - SetNeedsRepaint(); - } + // Force repaint of the subtree for two purposes: + // 1. To ensure FCP/LCP will be reported. See crbug.com/1184903. + // 2. To update effectively_invisible flags of PaintChunks. + // TODO(crbug.com/1104218): Optimize this. + GetLayoutObject().SetSubtreeShouldDoFullPaintInvalidation(); } } }
diff --git a/third_party/blink/renderer/core/paint/paint_layer.h b/third_party/blink/renderer/core/paint/paint_layer.h index 2ac2d73..adb8f23 100644 --- a/third_party/blink/renderer/core/paint/paint_layer.h +++ b/third_party/blink/renderer/core/paint/paint_layer.h
@@ -58,15 +58,12 @@ #include "third_party/blink/renderer/core/paint/paint_layer_resource_info.h" #include "third_party/blink/renderer/core/paint/paint_layer_stacking_node.h" #include "third_party/blink/renderer/core/paint/paint_result.h" -#include "third_party/blink/renderer/platform/graphics/compositing_reasons.h" #include "third_party/blink/renderer/platform/graphics/overlay_scrollbar_clip_behavior.h" #include "third_party/blink/renderer/platform/graphics/paint/cull_rect.h" -#include "third_party/blink/renderer/platform/graphics/squashing_disallowed_reasons.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" namespace blink { -class CompositedLayerMapping; class CompositorFilterOperations; class ComputedStyle; class FilterEffect; @@ -74,7 +71,6 @@ class HitTestResult; class HitTestingTransformState; class PaintLayerScrollableArea; -class ScrollingCoordinator; class TransformationMatrix; enum IncludeSelfOrNot { kIncludeSelf, kExcludeSelf }; @@ -298,15 +294,6 @@ void UpdateTransformationMatrix(); - bool IsStackingContextWithNegativeZOrderChildren() const { - DCHECK(!stacking_node_ || GetLayoutObject().IsStackingContext()); - return stacking_node_ && !stacking_node_->NegZOrderList().IsEmpty(); - } - - bool SubtreeIsInvisible() const { - return !HasVisibleContent() && !HasVisibleDescendant(); - } - bool HasVisibleContent() const { DCHECK(!needs_descendant_dependent_flags_update_); return has_visible_content_; @@ -319,13 +306,6 @@ void DirtyVisibleContentStatus(); - // True if this layer paints box decorations or a background. Touch-action - // rects are painted as part of the background so these are included here. - bool HasBoxDecorationsOrBackground() const; - bool HasVisibleBoxDecorations() const; - // True if this layer container layoutObjects that paint. - bool HasNonEmptyChildLayoutObjects() const; - // Gets the ancestor layer that serves as the containing block (in the sense // of LayoutObject::container() instead of LayoutObject::containingBlock()) // of this layer. Normally the parent layer is the containing layer, except @@ -338,39 +318,12 @@ PaintLayer* ContainingLayer(const PaintLayer* ancestor = nullptr, bool* skipped_ancestor = nullptr) const; - bool IsPaintInvalidationContainer() const; - - // Do *not* call this method unless you know what you are dooing. You probably - // want to call enclosingCompositingLayerForPaintInvalidation() instead. - // If includeSelf is true, may return this. - PaintLayer* EnclosingLayerWithCompositedLayerMapping(IncludeSelfOrNot) const { - // TODO(pdr): Remove this. - return nullptr; - } - - // Returns the enclosing layer root into which this layer paints, inclusive of - // this one. Note that the enclosing layer may or may not have its own - // GraphicsLayer backing, but is nevertheless the root for a call to the - // Layer::paint*() methods. - PaintLayer* EnclosingLayerForPaintInvalidation() const; - - // For CompositeAfterPaint, but not for LayoutNGBlockFragmentation. + // Not for LayoutNGBlockFragmentation. const PaintLayer* EnclosingCompositedScrollingLayerUnderPagination( IncludeSelfOrNot) const; - // https://crbug.com/751768, this function can return nullptr sometimes. - // Always check the result before using it, don't just DCHECK. - PaintLayer* EnclosingLayerForPaintInvalidationCrossingFrameBoundaries() const; - bool HasAncestorWithFilterThatMovesPixels() const; - bool CanUseConvertToLayerCoords() const { - // These LayoutObjects have an impact on their layers without the - // layoutObjects knowing about it. - return !GetLayoutObject().HasTransformRelatedProperty() && - !GetLayoutObject().IsSVGRoot(); - } - void ConvertToLayerCoords(const PaintLayer* ancestor_layer, PhysicalOffset&) const; void ConvertToLayerCoords(const PaintLayer* ancestor_layer, @@ -467,14 +420,6 @@ return position; } - PhysicalOffset SubpixelAccumulation() const { - // TODO(pdr): Remove this. - return PhysicalOffset(); - } - - bool HasTransformRelatedProperty() const { - return GetLayoutObject().HasTransformRelatedProperty(); - } // Note that this transform has the transform-origin baked in. TransformationMatrix* Transform() const { return rare_data_ ? rare_data_->transform.get() : nullptr; @@ -495,47 +440,13 @@ !rare_data_->transform->IsAffine(); } - // FIXME: reflections should force transform-style to be flat in the style: - // https://bugs.webkit.org/show_bug.cgi?id=106959 - bool ShouldPreserve3D() const { - return !GetLayoutObject().HasReflection() && Preserves3D(); - } - // Returns |true| if any property that renders using filter operations is // used (including, but not limited to, 'filter' and 'box-reflect'). bool HasFilterInducingProperty() const { return GetLayoutObject().HasFilterInducingProperty(); } - CompositingState GetCompositingState() const { - // TODO(pdr): Remove this. - return kNotComposited; - } - - CompositedLayerMapping* GetCompositedLayerMapping() const { - // TODO(pdr): Remove this. - return nullptr; - } - - bool HasCompositedLayerMapping() const { - // TODO(pdr): Remove this. - return false; - } - - CompositedLayerMapping* GroupedMapping() const { - // TODO(pdr): Remove this. - return nullptr; - } - - bool NeedsCompositedScrolling() const; - - // Returns the ScrollingCoordinator associated with this layer, if - // any. Otherwise nullptr. - ScrollingCoordinator* GetScrollingCoordinator(); - bool PaintsWithTransform(GlobalPaintFlags) const; - bool PaintsIntoOwnBacking(GlobalPaintFlags) const; - bool PaintsIntoOwnOrGroupedBacking(GlobalPaintFlags) const; bool SupportsSubsequenceCaching() const; @@ -612,8 +523,6 @@ // Returns true if the layer is fixed position and will not move with // scrolling. bool FixedToViewport() const; - bool ScrollsWithRespectTo(const PaintLayer*) const; - bool IsAffectedByScrollOf(const PaintLayer* ancestor) const; // FIXME: This should probably return a ScrollableArea but a lot of internal @@ -631,9 +540,6 @@ bool ScrollsOverflow() const; - // Whether the layer could ever be composited. - bool CanBeComposited() const; - bool NeedsVisualOverflowRecalc() const { return needs_visual_overflow_recalc_; } @@ -650,14 +556,9 @@ const gfx::Rect ClippedAbsoluteBoundingBox() const; const gfx::Rect UnclippedAbsoluteBoundingBox() const; - // TODO(pdr): Remove this. - const LayoutBoxModelObject* ClippingContainer() const { return nullptr; } const PaintLayer* AncestorScrollContainerLayer() const { return ancestor_scroll_container_layer_; } - // TODO(pdr): Remove this. - const PaintLayer* AncestorScrollingLayer() const { return nullptr; } - const PaintLayer* ScrollParent() const { return nullptr; } bool HasFixedPositionDescendant() const { DCHECK(!needs_descendant_dependent_flags_update_); @@ -696,11 +597,6 @@ return CompositingReason::kNone; } - SquashingDisallowedReasons GetSquashingDisallowedReasons() const { - // TODO(pdr): Remove this. - return SquashingDisallowedReason::kNone; - } - void UpdateDescendantDependentFlags(); void UpdateSelfPaintingLayer(); @@ -708,11 +604,6 @@ // like those in PaintInvalidatorContext. PaintLayer* EnclosingSelfPaintingLayer(); - // Returned value does not include any composited scroll offset of - // the transform ancestor. - PhysicalOffset ComputeOffsetFromAncestor( - const PaintLayer& ancestor_layer) const; - void DidUpdateScrollsOverflow(); void CollectFragments( @@ -817,10 +708,6 @@ bool LayerListMutationAllowed() const { return layer_list_mutation_allowed_; } #endif - void SetNeedsCompositingLayerAssignment(); - void ClearNeedsCompositingLayerAssignment(); - void PropagateDescendantNeedsCompositingLayerAssignment(); - void DirtyStackingContextZOrderLists(); PhysicalOffset OffsetForInFlowRelPosition() const { @@ -840,8 +727,6 @@ PhysicalRect LocalBoundingBox() const; PhysicalRect ClippedLocalBoundingBox(const PaintLayer& ancestor_layer) const; - bool HasOverflowControls() const; - void UpdateLayerPositionRecursive(const PaintLayer* enclosing_scroller); void SetNextSibling(PaintLayer* next) { next_ = next; }
diff --git a/third_party/blink/renderer/core/paint/paint_layer_painter.cc b/third_party/blink/renderer/core/paint/paint_layer_painter.cc index 7929c06..bcc80e7 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_painter.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_painter.cc
@@ -11,7 +11,6 @@ #include "third_party/blink/renderer/core/layout/layout_video.h" #include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/paint/clip_path_clipper.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h" #include "third_party/blink/renderer/core/paint/object_paint_properties.h" #include "third_party/blink/renderer/core/paint/paint_info.h" @@ -21,7 +20,6 @@ #include "third_party/blink/renderer/core/paint/paint_timing_detector.h" #include "third_party/blink/renderer/core/paint/scrollable_area_painter.h" #include "third_party/blink/renderer/platform/geometry/float_point_3d.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h" #include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h" #include "third_party/blink/renderer/platform/graphics/paint/scoped_display_item_fragment.h" @@ -38,8 +36,7 @@ PaintLayerFlags paint_flags) { PaintLayerPaintingInfo painting_info(&paint_layer_, cull_rect, global_paint_flags, PhysicalOffset()); - if (!paint_layer_.PaintsIntoOwnOrGroupedBacking(global_paint_flags)) - Paint(context, painting_info, paint_flags); + Paint(context, painting_info, paint_flags); } static ShouldRespectOverflowClipType ShouldRespectOverflowClip( @@ -702,13 +699,6 @@ PaintLayerPaintOrderIterator iterator(&paint_layer_, children_to_visit); while (PaintLayer* child = iterator.Next()) { - // If this Layer should paint into its own backing or a grouped backing, - // that will be done via CompositedLayerMapping::PaintContents() and - // CompositedLayerMapping::DoPaintTask(). - if (child->PaintsIntoOwnOrGroupedBacking( - painting_info.GetGlobalPaintFlags())) - continue; - if (child->IsReplacedNormalFlowStacking()) continue;
diff --git a/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc b/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc index 5947d5b..201e74e3 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc
@@ -6,7 +6,6 @@ #include "testing/gmock/include/gmock/gmock.h" #include "third_party/blink/renderer/core/layout/layout_box_model_object.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/paint_controller_paint_test.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/blink/renderer/platform/testing/find_cc_layer.h"
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc index 6e324fb0..39fcd61 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
@@ -93,10 +93,10 @@ #include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h" #include "third_party/blink/renderer/core/page/scrolling/snap_coordinator.h" #include "third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.h" #include "third_party/blink/renderer/core/paint/object_paint_invalidator.h" #include "third_party/blink/renderer/core/paint/paint_invalidator.h" +#include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer_fragment.h" #include "third_party/blink/renderer/core/scroll/scroll_alignment.h" #include "third_party/blink/renderer/core/scroll/scroll_animator_base.h" @@ -1913,13 +1913,6 @@ resizer_->GetMutableForPainting().FirstFragment().SetPaintOffset( PhysicalOffset(rect.Location())); } - - // FIXME, this should eventually be removed, once we are certain that - // composited controls get correctly positioned on a compositor update. For - // now, conservatively leaving this unchanged. - if (Layer()->HasCompositedLayerMapping()) { - Layer()->GetCompositedLayerMapping()->PositionOverflowControlsLayers(); - } } void PaintLayerScrollableArea::UpdateScrollCornerStyle() {
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc index e4f7bcb..b235373 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc
@@ -19,7 +19,6 @@ #include "third_party/blink/renderer/core/scroll/scroll_types.h" #include "third_party/blink/renderer/core/scroll/scrollbar_theme.h" #include "third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" using testing::_;
diff --git a/third_party/blink/renderer/core/paint/paint_layer_stacking_node.cc b/third_party/blink/renderer/core/paint/paint_layer_stacking_node.cc index c066b2b..c1f21b17 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_stacking_node.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_stacking_node.cc
@@ -51,7 +51,6 @@ #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.h" #include "third_party/blink/renderer/core/layout/layout_view.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
diff --git a/third_party/blink/renderer/core/paint/paint_layer_test.cc b/third_party/blink/renderer/core/paint/paint_layer_test.cc index 52b424e..85051f6 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_test.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_test.cc
@@ -188,9 +188,6 @@ } TEST_P(PaintLayerTest, CompositedScrollingNoNeedsRepaint) { - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) - return; - SetBodyInnerHTML(R"HTML( <div id='scroll' style='width: 100px; height: 100px; overflow: scroll; will-change: transform'> @@ -200,10 +197,8 @@ )HTML"); PaintLayer* scroll_layer = GetPaintLayerByElementId("scroll"); - EXPECT_EQ(kPaintsIntoOwnBacking, scroll_layer->GetCompositingState()); PaintLayer* content_layer = GetPaintLayerByElementId("content"); - EXPECT_EQ(kNotComposited, content_layer->GetCompositingState()); EXPECT_EQ(PhysicalOffset(), content_layer->LocationWithoutPositionOffset()); scroll_layer->GetScrollableArea()->SetScrollOffset( @@ -237,10 +232,8 @@ .PaintProperties() ->ScrollTranslation() ->HasDirectCompositingReasons()); - EXPECT_EQ(kNotComposited, scroll_layer->GetCompositingState()); PaintLayer* content_layer = GetPaintLayerByElementId("content"); - EXPECT_EQ(kNotComposited, scroll_layer->GetCompositingState()); EXPECT_EQ(PhysicalOffset(), content_layer->LocationWithoutPositionOffset()); scroll_layer->GetScrollableArea()->SetScrollOffset( @@ -2560,19 +2553,6 @@ } } -TEST_P(PaintLayerTest, HasNonEmptyChildLayoutObjectsZeroSizeOverflowVisible) { - SetBodyInnerHTML(R"HTML( - <div id="layer" style="position: relative"> - <div style="overflow: visible; height: 0; width: 0">text</div> - </div> - )HTML"); - - auto* layer = GetPaintLayerByElementId("layer"); - EXPECT_TRUE(layer->HasVisibleContent()); - EXPECT_FALSE(layer->HasVisibleDescendant()); - EXPECT_TRUE(layer->HasNonEmptyChildLayoutObjects()); -} - TEST_P(PaintLayerTest, AddLayerNeedsRepaintAndCullRectUpdate) { SetBodyInnerHTML(R"HTML( <div id="parent" style="opacity: 0.9">
diff --git a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc index 907c9dda..b2af99f8 100644 --- a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc +++ b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc
@@ -26,7 +26,6 @@ #include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/link_highlight.h" #include "third_party/blink/renderer/core/page/page.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/cull_rect_updater.h" #include "third_party/blink/renderer/core/paint/object_paint_invalidator.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" @@ -360,65 +359,6 @@ } #endif -static LayoutBoxModelObject* ContainerForPaintInvalidation( - const PaintLayer* painting_layer) { - if (!painting_layer) - return nullptr; - if (auto* containing_paint_layer = - painting_layer - ->EnclosingLayerForPaintInvalidationCrossingFrameBoundaries()) - return &containing_paint_layer->GetLayoutObject(); - return nullptr; -} - -void PrePaintTreeWalk::UpdatePaintInvalidationContainer( - const LayoutObject& object, - const PaintLayer* painting_layer, - PrePaintTreeWalkContext& context, - bool is_ng_painting) { - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) - return; - - if (object.IsPaintInvalidationContainer()) { - context.paint_invalidation_container = To<LayoutBoxModelObject>(&object); - if (object.IsStackingContext() || object.IsSVGRoot()) { - context.paint_invalidation_container_for_stacked_contents = - To<LayoutBoxModelObject>(&object); - } - } else if (IsA<LayoutView>(object)) { - // paint_invalidation_container_for_stacked_contents is only for stacked - // descendants in its own frame, because it doesn't establish stacking - // context for stacked contents in sub-frames. - // Contents stacked in the root stacking context in this frame should use - // this frame's PaintInvalidationContainer. - context.paint_invalidation_container_for_stacked_contents = - ContainerForPaintInvalidation(painting_layer); - } else if (!is_ng_painting && - (object.IsColumnSpanAll() || - object.IsFloatingWithNonContainingBlockParent())) { - // In these cases, the object may belong to an ancestor of the current - // paint invalidation container, in paint order. - // Post LayoutNG the |LayoutObject::IsFloatingWithNonContainingBlockParent| - // check can be removed as floats will be painted by the correct layer. - context.paint_invalidation_container = - ContainerForPaintInvalidation(painting_layer); - } else if (object.IsStacked() && - // This is to exclude some objects (e.g. LayoutText) inheriting - // stacked style from parent but aren't actually stacked. - object.HasLayer() && - !To<LayoutBoxModelObject>(object) - .Layer() - ->IsReplacedNormalFlowStacking() && - context.paint_invalidation_container != - context.paint_invalidation_container_for_stacked_contents) { - // The current object is stacked, so we should use - // m_paintInvalidationContainerForStackedContents as its paint invalidation - // container on which the current object is painted. - context.paint_invalidation_container = - context.paint_invalidation_container_for_stacked_contents; - } -} - NGPrePaintInfo PrePaintTreeWalk::CreatePrePaintInfo( const NGLink& child, const PrePaintTreeWalkContext& context) { @@ -567,10 +507,6 @@ InvalidatePaintForHitTesting(object, context); - UpdatePaintInvalidationContainer(object, - paint_invalidator_context.painting_layer, - context, !!pre_paint_info); - if (context.tree_builder_context) { property_changed = std::max(property_changed, property_tree_builder->UpdateForChildren());
diff --git a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h index d31c28e..bab9dc7 100644 --- a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h +++ b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h
@@ -85,10 +85,6 @@ // fragmentainer even if the OOF / float is there. bool is_inside_orphaned_object = false; - const LayoutBoxModelObject* paint_invalidation_container = nullptr; - const LayoutBoxModelObject* - paint_invalidation_container_for_stacked_contents = nullptr; - ContainingFragment current_fragmentainer; ContainingFragment absolute_positioned_container; ContainingFragment fixed_positioned_container; @@ -221,11 +217,6 @@ void InvalidatePaintForHitTesting(const LayoutObject&, PrePaintTreeWalkContext&); - void UpdatePaintInvalidationContainer(const LayoutObject& object, - const PaintLayer* painting_layer, - PrePaintTreeWalkContext& context, - bool is_ng_painting); - PaintInvalidator paint_invalidator_; // List of fragments that may be missed during LayoutObject walking. See
diff --git a/third_party/blink/renderer/core/paint/replaced_painter.cc b/third_party/blink/renderer/core/paint/replaced_painter.cc index 2c038f66..69cb7404 100644 --- a/third_party/blink/renderer/core/paint/replaced_painter.cc +++ b/third_party/blink/renderer/core/paint/replaced_painter.cc
@@ -9,7 +9,6 @@ #include "third_party/blink/renderer/core/layout/layout_replaced.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_root.h" #include "third_party/blink/renderer/core/paint/box_painter.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/highlight_painting_utils.h" #include "third_party/blink/renderer/core/paint/object_painter.h" #include "third_party/blink/renderer/core/paint/paint_auto_dark_mode.h"
diff --git a/third_party/blink/renderer/core/paint/svg_container_painter_test.cc b/third_party/blink/renderer/core/paint/svg_container_painter_test.cc index 1cec2b68..c5d95c0f 100644 --- a/third_party/blink/renderer/core/paint/svg_container_painter_test.cc +++ b/third_party/blink/renderer/core/paint/svg_container_painter_test.cc
@@ -8,7 +8,6 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_root.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/paint_controller_paint_test.h" #include "third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_chunk.h"
diff --git a/third_party/blink/renderer/core/paint/view_painter.cc b/third_party/blink/renderer/core/paint/view_painter.cc index 976f6ed5..44bea3c 100644 --- a/third_party/blink/renderer/core/paint/view_painter.cc +++ b/third_party/blink/renderer/core/paint/view_painter.cc
@@ -15,7 +15,6 @@ #include "third_party/blink/renderer/core/paint/box_decoration_data.h" #include "third_party/blink/renderer/core/paint/box_model_object_painter.h" #include "third_party/blink/renderer/core/paint/box_painter.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.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/core/paint/paint_layer.h"
diff --git a/third_party/blink/renderer/core/paint/view_painter_test.cc b/third_party/blink/renderer/core/paint/view_painter_test.cc index 1590b7f..a0da795a 100644 --- a/third_party/blink/renderer/core/paint/view_painter_test.cc +++ b/third_party/blink/renderer/core/paint/view_painter_test.cc
@@ -6,7 +6,6 @@ #include <gtest/gtest.h> #include "third_party/blink/renderer/core/frame/local_dom_window.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/paint_controller_paint_test.h" #include "third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h" #include "third_party/blink/renderer/platform/testing/paint_property_test_helpers.h"
diff --git a/third_party/blink/renderer/core/scheduler_integration_tests/frame_throttling_test.cc b/third_party/blink/renderer/core/scheduler_integration_tests/frame_throttling_test.cc index f004a76..4a2e1f5 100644 --- a/third_party/blink/renderer/core/scheduler_integration_tests/frame_throttling_test.cc +++ b/third_party/blink/renderer/core/scheduler_integration_tests/frame_throttling_test.cc
@@ -25,7 +25,6 @@ #include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/page/focus_controller.h" #include "third_party/blink/renderer/core/page/page.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/core/resize_observer/resize_observer.h" @@ -520,8 +519,6 @@ To<HTMLIFrameElement>(GetDocument().getElementById("frame")); auto* frame_view = frame_element->contentDocument()->View(); EXPECT_FALSE(frame_view->CanThrottleRendering()); - auto* frame_layout_view = frame_view->GetLayoutView(); - EXPECT_TRUE(frame_layout_view->Layer()->CanBeComposited()); auto* root_layer = WebView().MainFrameImpl()->GetFrameView()->RootCcLayer(); EXPECT_EQ(0u, CcLayersByDOMElementId(root_layer, "container").size()); EXPECT_EQ(1u, CcLayersByDOMElementId(root_layer, "inner_frame").size()); @@ -542,7 +539,6 @@ ASSERT_TRUE(Compositor().NeedsBeginFrame()); CompositeFrame(); EXPECT_FALSE(frame_view->CanThrottleRendering()); - EXPECT_TRUE(frame_layout_view->Layer()->CanBeComposited()); EXPECT_EQ(0u, CcLayersByDOMElementId(root_layer, "container").size()); EXPECT_EQ(1u, CcLayersByDOMElementId(root_layer, "inner_frame").size()); }
diff --git a/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.cc b/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.cc index 1bddf18..90a8a8e 100644 --- a/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.cc +++ b/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.cc
@@ -10,7 +10,6 @@ #include "third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h" #include "third_party/blink/renderer/platform/animation/compositor_keyframe_model.h" #include "third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "ui/gfx/geometry/size.h" namespace blink {
diff --git a/third_party/blink/renderer/core/scroll/scroll_animator.cc b/third_party/blink/renderer/core/scroll/scroll_animator.cc index 540a69d..dc8730fb 100644 --- a/third_party/blink/renderer/core/scroll/scroll_animator.cc +++ b/third_party/blink/renderer/core/scroll/scroll_animator.cc
@@ -39,7 +39,6 @@ #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/core/scroll/scrollable_area.h" #include "third_party/blink/renderer/platform/animation/compositor_keyframe_model.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" // This should be after all other #includes.
diff --git a/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.cc b/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.cc index c0980e8..f4ff6cc 100644 --- a/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.cc +++ b/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.cc
@@ -14,8 +14,6 @@ #include "third_party/blink/renderer/platform/animation/compositor_animation.h" #include "third_party/blink/renderer/platform/animation/compositor_animation_timeline.h" #include "third_party/blink/renderer/platform/animation/compositor_keyframe_model.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" -#include "third_party/blink/renderer/platform/runtime_enabled_features.h" namespace blink {
diff --git a/third_party/blink/renderer/core/scroll/scrollable_area_test.cc b/third_party/blink/renderer/core/scroll/scrollable_area_test.cc index f23d62c..5dd13c8 100644 --- a/third_party/blink/renderer/core/scroll/scrollable_area_test.cc +++ b/third_party/blink/renderer/core/scroll/scrollable_area_test.cc
@@ -13,7 +13,6 @@ #include "third_party/blink/renderer/core/scroll/scrollbar_theme_overlay_mock.h" #include "third_party/blink/renderer/core/testing/scoped_mock_overlay_scrollbars.h" #include "third_party/blink/renderer/platform/graphics/color.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/heap/thread_state.h" #include "third_party/blink/renderer/platform/testing/paint_test_configurations.h" #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
diff --git a/third_party/blink/renderer/core/svg/graphics/svg_image_test.cc b/third_party/blink/renderer/core/svg/graphics/svg_image_test.cc index 63aff90..2b65de7 100644 --- a/third_party/blink/renderer/core/svg/graphics/svg_image_test.cc +++ b/third_party/blink/renderer/core/svg/graphics/svg_image_test.cc
@@ -21,6 +21,7 @@ #include "third_party/blink/renderer/core/svg/svg_svg_element.h" #include "third_party/blink/renderer/core/testing/sim/sim_request.h" #include "third_party/blink/renderer/core/testing/sim/sim_test.h" +#include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_flags.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc index acac2f0..b7cd594 100644 --- a/third_party/blink/renderer/core/testing/internals.cc +++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -132,7 +132,6 @@ #include "third_party/blink/renderer/core/page/spatial_navigation_controller.h" #include "third_party/blink/renderer/core/page/validation_message_client.h" #include "third_party/blink/renderer/core/page/viewport_description.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/core/probe/core_probes.h" @@ -175,7 +174,6 @@ #include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h" #include "third_party/blink/renderer/platform/geometry/layout_rect.h" #include "third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -2448,46 +2446,6 @@ return layerTreeAsText(document, 0, exception_state); } -bool Internals::scrollsWithRespectTo(Element* element1, - Element* element2, - ExceptionState& exception_state) { - DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()); - DCHECK(element1 && element2); - element1->GetDocument().View()->UpdateAllLifecyclePhasesForTest(); - - LayoutObject* layout_object1 = element1->GetLayoutObject(); - LayoutObject* layout_object2 = element2->GetLayoutObject(); - if (!layout_object1 || !layout_object1->IsBox()) { - exception_state.ThrowDOMException( - DOMExceptionCode::kInvalidAccessError, - layout_object1 - ? "The first provided element's layoutObject is not a box." - : "The first provided element has no layoutObject."); - return false; - } - if (!layout_object2 || !layout_object2->IsBox()) { - exception_state.ThrowDOMException( - DOMExceptionCode::kInvalidAccessError, - layout_object2 - ? "The second provided element's layoutObject is not a box." - : "The second provided element has no layoutObject."); - return false; - } - - PaintLayer* layer1 = To<LayoutBox>(layout_object1)->Layer(); - PaintLayer* layer2 = To<LayoutBox>(layout_object2)->Layer(); - if (!layer1 || !layer2) { - exception_state.ThrowDOMException( - DOMExceptionCode::kInvalidAccessError, - String::Format( - "No PaintLayer can be obtained from the %s provided element.", - layer1 ? "second" : "first")); - return false; - } - - return layer1->ScrollsWithRespectTo(layer2); -} - String Internals::layerTreeAsText(Document* document, unsigned flags, ExceptionState& exception_state) const {
diff --git a/third_party/blink/renderer/core/testing/internals.h b/third_party/blink/renderer/core/testing/internals.h index d6432695..5c6e222f 100644 --- a/third_party/blink/renderer/core/testing/internals.h +++ b/third_party/blink/renderer/core/testing/internals.h
@@ -354,8 +354,6 @@ String layerTreeAsText(Document*, unsigned flags, ExceptionState&) const; String layerTreeAsText(Document*, ExceptionState&) const; - bool scrollsWithRespectTo(Element*, Element*, ExceptionState&); - String scrollingStateTreeAsText(Document*) const; String mainThreadScrollingReasons(Document*, ExceptionState&) const; DOMRectList* nonFastScrollableRects(Document*, ExceptionState&) const;
diff --git a/third_party/blink/renderer/core/testing/internals.idl b/third_party/blink/renderer/core/testing/internals.idl index ff1c407a..7e83580 100644 --- a/third_party/blink/renderer/core/testing/internals.idl +++ b/third_party/blink/renderer/core/testing/internals.idl
@@ -195,8 +195,6 @@ [RaisesException] DOMString layerTreeAsText(Document document, optional unsigned short flags); - [RaisesException] boolean scrollsWithRespectTo(Element element1, Element element2); - DOMString scrollingStateTreeAsText(Document document); [RaisesException] DOMString mainThreadScrollingReasons(Document document); [RaisesException] DOMRectList nonFastScrollableRects(Document document);
diff --git a/third_party/blink/renderer/core/testing/sim/sim_compositor.cc b/third_party/blink/renderer/core/testing/sim/sim_compositor.cc index 7dcaab9d..c29169fe 100644 --- a/third_party/blink/renderer/core/testing/sim/sim_compositor.cc +++ b/third_party/blink/renderer/core/testing/sim/sim_compositor.cc
@@ -11,7 +11,6 @@ #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" #include "third_party/blink/renderer/core/layout/layout_view.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/blink/renderer/platform/graphics/paint/cull_rect.h"
diff --git a/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc b/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc index aed3b2a..12941713 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc
@@ -584,6 +584,8 @@ break; } } + if (AXObject* owned_child = ObjectFromAXID(obj_id)) + owned_child->DetachFromParent(); } }
diff --git a/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc b/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc index 5817068..27336dee 100644 --- a/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc +++ b/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc
@@ -129,12 +129,6 @@ return nullptr; } -bool CheckElementComposited(const Node& target) { - return target.GetLayoutObject() && - target.GetLayoutObject()->GetCompositingState() == - kPaintsIntoOwnBacking; -} - void StartEffectOnCompositor(CompositorAnimation* animation, KeyframeEffect* effect) { DCHECK(effect); @@ -619,9 +613,6 @@ if (failure_reasons != CompositorAnimations::kNoFailure) return false; - if (!CheckElementComposited(target)) - return false; - // If the scroll source is not composited, fall back to main thread. if (timeline_->IsScrollTimeline() && !CompositorAnimations::CheckUsesCompositedScrolling( @@ -629,7 +620,10 @@ return false; } - return true; + // TODO(crbug.com/1281413): This function has returned false since the launch + // of CompositeAfterPaint, but that may not be intended. Should this return + // true? + return false; } bool WorkletAnimation::StartOnCompositor() {
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc index a85e392..91ef0823 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
@@ -1899,7 +1899,7 @@ ExceptionState& exception_state) const { ImageData::ValidateAndCreateParams params; params.context_2d_error_mode = true; - params.default_color_space = GetCanvas2DColorParams().ColorSpace(); + params.default_color_space = GetDefaultImageDataColorSpace(); return ImageData::ValidateAndCreate(std::abs(sw), std::abs(sh), absl::nullopt, /*settings=*/nullptr, params, exception_state); @@ -1912,7 +1912,7 @@ ExceptionState& exception_state) const { ImageData::ValidateAndCreateParams params; params.context_2d_error_mode = true; - params.default_color_space = GetCanvas2DColorParams().ColorSpace(); + params.default_color_space = GetDefaultImageDataColorSpace(); return ImageData::ValidateAndCreate(std::abs(sw), std::abs(sh), absl::nullopt, image_data_settings, params, exception_state); @@ -1991,7 +1991,7 @@ ImageData::ValidateAndCreateParams validate_and_create_params; validate_and_create_params.context_2d_error_mode = true; validate_and_create_params.default_color_space = - GetCanvas2DColorParams().ColorSpace(); + GetDefaultImageDataColorSpace(); if (!CanCreateCanvas2dResourceProvider() || isContextLost()) { return ImageData::ValidateAndCreate( @@ -2129,46 +2129,33 @@ gfx::Rect source_rect = dest_rect; source_rect.Offset(-dest_offset); - // Color / format convert ImageData to context 2D settings if needed. Color / - // format conversion is not needed only if context 2D and ImageData are both - // in sRGB color space and use uint8 pixel storage format. We use RGBA pixel - // order for both ImageData and CanvasResourceProvider, therefore no - // additional swizzling is needed. SkPixmap data_pixmap = data->GetSkPixmap(); - CanvasColorParams data_color_params( - data->GetPredefinedColorSpace(), - data->GetImageDataStorageFormat() != ImageDataStorageFormat::kUint8 - ? CanvasPixelFormat::kF16 - : CanvasPixelFormat::kUint8, - kNonOpaque); - if (data_color_params.ColorSpace() != GetCanvas2DColorParams().ColorSpace() || - data_color_params.PixelFormat() != - GetCanvas2DColorParams().PixelFormat() || - GetCanvas2DColorParams().PixelFormat() == CanvasPixelFormat::kF16) { - SkImageInfo converted_info = data_pixmap.info(); - converted_info = - converted_info.makeColorType(GetCanvas2DColorParams().GetSkColorType()); - converted_info = converted_info.makeColorSpace( - GetCanvas2DColorParams().GetSkColorSpace()); - if (converted_info.colorType() == kN32_SkColorType) - converted_info = converted_info.makeColorType(kRGBA_8888_SkColorType); - const size_t converted_data_bytes = converted_info.computeMinByteSize(); - const size_t converted_row_bytes = converted_info.minRowBytes(); - if (SkImageInfo::ByteSizeOverflowed(converted_data_bytes)) + // WritePixels (called by PutByteArray) requires that the source and + // destination pixel formats have the same bytes per pixel. + if (auto* host = GetCanvasRenderingContextHost()) { + SkColorType dest_color_type = + host->GetRenderingContextSkColorInfo().colorType(); + if (SkColorTypeBytesPerPixel(dest_color_type) != + SkColorTypeBytesPerPixel(data_pixmap.colorType())) { + SkImageInfo converted_info = + data_pixmap.info().makeColorType(dest_color_type); + SkBitmap converted_bitmap; + if (!converted_bitmap.tryAllocPixels(converted_info)) { + exception_state.ThrowRangeError("Out of memory in putImageData"); + return; + } + if (!converted_bitmap.writePixels(data_pixmap, 0, 0)) + NOTREACHED() << "Failed to convert ImageData with writePixels."; + + PutByteArray(converted_bitmap.pixmap(), source_rect, dest_offset); + GetPaintCanvasForDraw(gfx::RectToSkIRect(dest_rect), + CanvasPerformanceMonitor::DrawType::kImageData); return; - std::unique_ptr<uint8_t[]> converted_pixels( - new uint8_t[converted_data_bytes]); - if (data_pixmap.readPixels(converted_info, converted_pixels.get(), - converted_row_bytes)) { - PutByteArray( - SkPixmap(converted_info, converted_pixels.get(), converted_row_bytes), - source_rect, dest_offset); } - } else { - PutByteArray(data_pixmap, source_rect, dest_offset); } + PutByteArray(data_pixmap, source_rect, dest_offset); GetPaintCanvasForDraw(gfx::RectToSkIRect(dest_rect), CanvasPerformanceMonitor::DrawType::kImageData); } @@ -2189,7 +2176,7 @@ SkImageInfo info = source.info().makeWH(source_rect.width(), source_rect.height()); - if (kOpaque == GetCanvas2DColorParams().GetOpacityMode()) { + if (!HasAlpha()) { // If the surface is opaque, tell it that we are writing opaque // pixels. Writing non-opaque pixels to opaque is undefined in // Skia. There is some discussion about whether it should be @@ -2199,8 +2186,6 @@ } else { info = info.makeAlphaType(kUnpremul_SkAlphaType); } - if (info.colorType() == kN32_SkColorType) - info = info.makeColorType(kRGBA_8888_SkColorType); WritePixels(info, source.addr(source_rect.x(), source_rect.y()), source.rowBytes(), dest_x, dest_y);
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h index 0fcad4d..467b2ad 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h +++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h
@@ -421,9 +421,9 @@ void UnwindStateStack(); - // The implementations of this will query the CanvasColorParams from the - // CanvasRenderingContext. - virtual CanvasColorParams GetCanvas2DColorParams() const = 0; + // Return the default color space to be used for calls to GetImageData or + // CreateImageData. + virtual PredefinedColorSpace GetDefaultImageDataColorSpace() const = 0; virtual bool WritePixels(const SkImageInfo& orig_info, const void* pixels,
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc index 03573e5..8ad03ad0 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
@@ -1098,9 +1098,9 @@ CanvasRenderingContext2DSettings::Create(); settings->setAlpha(CreationAttributes().alpha); if (RuntimeEnabledFeatures::CanvasColorManagementEnabled()) - settings->setColorSpace(GetCanvas2DColorParams().GetColorSpaceAsString()); + settings->setColorSpace(color_params_.GetColorSpaceAsString()); if (RuntimeEnabledFeatures::CanvasColorManagementV2Enabled()) - settings->setPixelFormat(GetCanvas2DColorParams().GetPixelFormatAsString()); + settings->setPixelFormat(color_params_.GetPixelFormatAsString()); settings->setDesynchronized(Host()->LowLatencyEnabled()); if (RuntimeEnabledFeatures::NewCanvas2DAPIEnabled( canvas()->GetTopExecutionContext()))
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h index 0130e61..c92354b0 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h
@@ -213,10 +213,6 @@ ImageDataSettings*, ExceptionState&) final; - CanvasColorParams ColorParamsForTest() const { - return GetCanvas2DColorParams(); - } - IdentifiableToken IdentifiableTextToken() const override { return identifiability_study_helper_.GetToken(); } @@ -236,13 +232,11 @@ } protected: - // This reports CanvasColorParams to the CanvasRenderingContext interface. CanvasColorParams CanvasRenderingContextColorParams() const override { return color_params_; } - // This reports CanvasColorParams to the BaseRenderingContext2D interface. - CanvasColorParams GetCanvas2DColorParams() const override { - return color_params_; + PredefinedColorSpace GetDefaultImageDataColorSpace() const final { + return color_params_.ColorSpace(); } bool WritePixels(const SkImageInfo& orig_info, const void* pixels,
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc index 441a452..06d6d6b3 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc
@@ -933,6 +933,7 @@ static void TestDrawSingleHighBitDepthPNGOnCanvas( String filepath, CanvasRenderingContext2D* context, + PredefinedColorSpace context_color_space, Document& document, ImageDataSettings* color_setting, ScriptState* script_state) { @@ -971,7 +972,7 @@ resource_content->GetImage()->PaintImageForCurrentFrame().GetSwSkImage(); ASSERT_EQ(kRGBA_F16_SkColorType, decoded_image->colorType()); sk_sp<SkImage> color_converted_image = decoded_image->makeColorSpace( - context->ColorParamsForTest().GetSkColorSpace()); + PredefinedColorSpaceToSkColorSpace(context_color_space)); float expected_pixels[16]; SkImageInfo expected_info_no_color_space = SkImageInfo::Make( 2, 2, kRGBA_F32_SkColorType, kUnpremul_SkAlphaType, nullptr); @@ -1019,8 +1020,8 @@ full_path.Append(alpha); full_path.Append(".png"); TestDrawSingleHighBitDepthPNGOnCanvas(full_path.ToString(), context, - document, color_setting, - script_state); + color_space, document, + color_setting, script_state); } } }
diff --git a/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h b/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h index 2e04d9d..a4d4f50 100644 --- a/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h +++ b/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h
@@ -164,13 +164,11 @@ void FlushCanvas() override; protected: - // This reports CanvasColorParams to the CanvasRenderingContext interface. CanvasColorParams CanvasRenderingContextColorParams() const override { return color_params_; } - // This reports CanvasColorParams to the BaseRenderingContext2D interface. - CanvasColorParams GetCanvas2DColorParams() const override { - return color_params_; + PredefinedColorSpace GetDefaultImageDataColorSpace() const final { + return color_params_.ColorSpace(); } bool WritePixels(const SkImageInfo& orig_info, const void* pixels,
diff --git a/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.cc b/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.cc index d74efc40..2d32a0d 100644 --- a/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.cc +++ b/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.cc
@@ -123,8 +123,11 @@ return GetState().GetFilterForOffscreenCanvas(container_size_, this); } -CanvasColorParams PaintRenderingContext2D::GetCanvas2DColorParams() const { - return CanvasColorParams(); +PredefinedColorSpace PaintRenderingContext2D::GetDefaultImageDataColorSpace() + const { + // PaintRenderingContext2D does not call getImageData or createImageData. + NOTREACHED(); + return PredefinedColorSpace::kSRGB; } void PaintRenderingContext2D::WillOverwriteCanvas() {
diff --git a/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.h b/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.h index aa167f80..69e9469 100644 --- a/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.h +++ b/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.h
@@ -106,7 +106,7 @@ } protected: - CanvasColorParams GetCanvas2DColorParams() const override; + PredefinedColorSpace GetDefaultImageDataColorSpace() const final; bool IsPaint2D() const override { return true; } void WillOverwriteCanvas() override;
diff --git a/third_party/blink/renderer/modules/launch/dom_window_launch_queue.idl b/third_party/blink/renderer/modules/launch/dom_window_launch_queue.idl index 90851e4..de85def 100644 --- a/third_party/blink/renderer/modules/launch/dom_window_launch_queue.idl +++ b/third_party/blink/renderer/modules/launch/dom_window_launch_queue.idl
@@ -3,7 +3,7 @@ // found in the LICENSE file. // TODO(crbug.com/829689): Add link to spec once complete. -// Explainer: https://github.com/WICG/file-handling/blob/master/explainer.md +// Explainer: https://github.com/WICG/file-handling/blob/main/explainer.md [ ImplementedAs=DOMWindowLaunchQueue,
diff --git a/third_party/blink/renderer/modules/launch/launch_params.idl b/third_party/blink/renderer/modules/launch/launch_params.idl index 751279794..7c9fe6c 100644 --- a/third_party/blink/renderer/modules/launch/launch_params.idl +++ b/third_party/blink/renderer/modules/launch/launch_params.idl
@@ -3,7 +3,7 @@ // found in the LICENSE file. // TODO(crbug.com/829689): Add link to spec once complete. -// Explainer: https://github.com/WICG/file-handling/blob/master/explainer.md +// Explainer: https://github.com/WICG/file-handling/blob/main/explainer.md [ Exposed=Window,
diff --git a/third_party/blink/renderer/modules/launch/launch_queue.idl b/third_party/blink/renderer/modules/launch/launch_queue.idl index 6bbe6aa..746d9ca 100644 --- a/third_party/blink/renderer/modules/launch/launch_queue.idl +++ b/third_party/blink/renderer/modules/launch/launch_queue.idl
@@ -3,7 +3,7 @@ // found in the LICENSE file. // TODO(crbug.com/829689): Add link to spec once complete. -// Explainer: https://github.com/WICG/file-handling/blob/master/explainer.md +// Explainer: https://github.com/WICG/file-handling/blob/main/explainer.md [ Exposed=Window,
diff --git a/third_party/blink/renderer/modules/manifest/manifest_parser.h b/third_party/blink/renderer/modules/manifest/manifest_parser.h index a84ae89..ff42b66 100644 --- a/third_party/blink/renderer/modules/manifest/manifest_parser.h +++ b/third_party/blink/renderer/modules/manifest/manifest_parser.h
@@ -315,7 +315,7 @@ const JSONObject* object); // Parses the 'file_handlers' field of a Manifest, as defined in: - // https://github.com/WICG/file-handling/blob/master/explainer.md + // https://github.com/WICG/file-handling/blob/main/explainer.md // Returns the parsed list of FileHandlers. The returned FileHandlers are // empty if the field didn't exist, parsing failed, or the input list was // empty. @@ -323,20 +323,20 @@ const JSONObject* object); // Parses a FileHandler from an entry in the 'file_handlers' list, as - // defined in: https://github.com/WICG/file-handling/blob/master/explainer.md. + // defined in: https://github.com/WICG/file-handling/blob/main/explainer.md. // Returns |absl::nullopt| if the FileHandler was invalid, or a // FileHandler, if parsing succeeded. absl::optional<mojom::blink::ManifestFileHandlerPtr> ParseFileHandler( const JSONObject* file_handler_entry); // Parses the 'accept' field of a FileHandler, as defined in: - // https://github.com/WICG/file-handling/blob/master/explainer.md. + // https://github.com/WICG/file-handling/blob/main/explainer.md. // Returns the parsed accept map. Invalid accept entries are ignored. HashMap<String, Vector<String>> ParseFileHandlerAccept( const JSONObject* accept); // Parses an extension in the 'accept' field of a FileHandler, as defined in: - // https://github.com/WICG/file-handling/blob/master/explainer.md. Returns + // https://github.com/WICG/file-handling/blob/main/explainer.md. Returns // whether the parsing was successful and, if so, populates |output| with the // parsed extension. bool ParseFileHandlerAcceptExtension(const JSONValue* extension,
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn index 88c18c5..fa9eb27 100644 --- a/third_party/blink/renderer/platform/BUILD.gn +++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -972,11 +972,6 @@ "graphics/graphics_context_state.cc", "graphics/graphics_context_state.h", "graphics/graphics_context_state_saver.h", - "graphics/graphics_layer.cc", - "graphics/graphics_layer.h", - "graphics/graphics_layer_client.h", - "graphics/graphics_layer_tree_as_text.cc", - "graphics/graphics_layer_tree_as_text.h", "graphics/graphics_types.cc", "graphics/graphics_types.h", "graphics/graphics_types_3d.h", @@ -1134,8 +1129,6 @@ "graphics/skia/sk_size_hash.h", "graphics/skia/skia_utils.cc", "graphics/skia/skia_utils.h", - "graphics/squashing_disallowed_reasons.cc", - "graphics/squashing_disallowed_reasons.h", "graphics/static_bitmap_image.cc", "graphics/static_bitmap_image.h", "graphics/static_bitmap_image_to_video_frame_copier.cc",
diff --git a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc index f1ee3fd..53fe9f8 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc
@@ -42,13 +42,13 @@ #include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h" #include "third_party/blink/renderer/platform/graphics/gpu/shared_context_rate_limiter.h" #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h" #include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h" #include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h" #include "third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_wrapper.h" #include "third_party/blink/renderer/platform/instrumentation/histogram.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/skia/include/core/SkData.h" #include "third_party/skia/include/core/SkSurface.h"
diff --git a/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.h b/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.h index 92a6907..e91eef7 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.h +++ b/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.h
@@ -9,7 +9,6 @@ #include "cc/layers/content_layer_client.h" #include "cc/layers/picture_layer.h" #include "third_party/blink/renderer/platform/graphics/compositing/layers_as_json.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer_client.h" #include "third_party/blink/renderer/platform/graphics/paint/raster_invalidator.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h"
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc index 7c3688ac..c1802ad 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
@@ -2084,8 +2084,7 @@ masking_state.local_transform_space = &t0(); masking_state.output_clip = &c0(); masking_state.blend_mode = SkBlendMode::kXor; - masking_state.direct_compositing_reasons = - CompositingReason::kSquashingDisallowed; + masking_state.direct_compositing_reasons = CompositingReason::kOverlap; auto masking = EffectPaintPropertyNode::Create(*masked, std::move(masking_state));
diff --git a/third_party/blink/renderer/platform/graphics/compositing_reasons.cc b/third_party/blink/renderer/platform/graphics/compositing_reasons.cc index 15dbc3b..545936a 100644 --- a/third_party/blink/renderer/platform/graphics/compositing_reasons.cc +++ b/third_party/blink/renderer/platform/graphics/compositing_reasons.cc
@@ -46,8 +46,6 @@ "Is sticky position"}, {CompositingReason::kOverflowScrolling, "overflowScrolling", "Is a scrollable overflow element"}, - {CompositingReason::kOverflowScrollingParent, "overflowScrollingParent", - "Scroll parent is not an ancestor"}, {CompositingReason::kOutOfFlowClipping, "outOfFlowClipping", "Has clipping ancestor"}, {CompositingReason::kVideoOverlay, "videoOverlay", @@ -74,8 +72,6 @@ "Overlaps other composited content"}, {CompositingReason::kNegativeZIndexChildren, "negativeZIndexChildren", "Parent with composited negative z-index content"}, - {CompositingReason::kSquashingDisallowed, "squashingDisallowed", - "Layer was separately composited because it could not be squashed."}, {CompositingReason::kOpacityWithCompositedDescendants, "opacityWithCompositedDescendants", "Has opacity that needs to be applied by compositor because of composited "
diff --git a/third_party/blink/renderer/platform/graphics/compositing_reasons.h b/third_party/blink/renderer/platform/graphics/compositing_reasons.h index e31810e..c28de64 100644 --- a/third_party/blink/renderer/platform/graphics/compositing_reasons.h +++ b/third_party/blink/renderer/platform/graphics/compositing_reasons.h
@@ -35,7 +35,6 @@ V(FixedPosition) \ V(StickyPosition) \ V(OverflowScrolling) \ - V(OverflowScrollingParent) \ V(OutOfFlowClipping) \ V(VideoOverlay) \ V(WillChangeTransform) \ @@ -63,7 +62,6 @@ V(AssumedOverlap) \ V(Overlap) \ V(NegativeZIndexChildren) \ - V(SquashingDisallowed) \ \ /* Subtree reasons that require knowing what the status of your subtree is \ before knowing the answer. */ \ @@ -141,11 +139,11 @@ kComboScrollDependentPosition = kFixedPosition | kStickyPosition, kComboAllDirectNonStyleDeterminedReasons = - kVideo | kCanvas | kPlugin | kIFrame | kSVGRoot | - kOverflowScrollingParent | kOutOfFlowClipping | kVideoOverlay | - kXrOverlay | kRoot | kRootScroller | kComboScrollDependentPosition | - kAffectedByOuterViewportBoundsDelta | kBackfaceInvisibility3DAncestor | - kTransform3DSceneLeaf | kDocumentTransitionSharedElement, + kVideo | kCanvas | kPlugin | kIFrame | kSVGRoot | kOutOfFlowClipping | + kVideoOverlay | kXrOverlay | kRoot | kRootScroller | + kComboScrollDependentPosition | kAffectedByOuterViewportBoundsDelta | + kBackfaceInvisibility3DAncestor | kTransform3DSceneLeaf | + kDocumentTransitionSharedElement, kComboAllDirectReasons = kComboAllDirectStyleDeterminedReasons | kComboAllDirectNonStyleDeterminedReasons, @@ -167,9 +165,6 @@ kComboCompositedDescendants | kCombo3DDescendants, - kComboSquashableReasons = - kOverlap | kAssumedOverlap | kOverflowScrollingParent, - kPreventingSubpixelAccumulationReasons = kWillChangeTransform, kDirectReasonsForPaintOffsetTranslationProperty = @@ -193,19 +188,6 @@ }; }; -// Any reasons other than overlap or assumed overlap will require the layer to -// be separately compositing. -inline bool RequiresCompositing(CompositingReasons reasons) { - return reasons & ~CompositingReason::kComboSquashableReasons; -} - -// If the layer has overlap or assumed overlap, but no other reasons, then it -// should be squashed. -inline bool RequiresSquashing(CompositingReasons reasons) { - return !RequiresCompositing(reasons) && - (reasons & CompositingReason::kComboSquashableReasons); -} - } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_COMPOSITING_REASONS_H_
diff --git a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc index cc345448..f672aae 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc
@@ -57,7 +57,7 @@ #include "third_party/blink/renderer/platform/graphics/canvas_resource.h" #include "third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.h" #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" +#include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h" #include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h" #include "third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_wrapper.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
diff --git a/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc b/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc index dfdfed70..a3c1153 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc
@@ -21,7 +21,6 @@ #include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h" #include "third_party/blink/renderer/platform/graphics/color_behavior.h" #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/graphics/image_orientation.h" #include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc b/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc index 4f1d914..0d50ab02 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc
@@ -9,7 +9,6 @@ #include "gpu/command_buffer/client/shared_image_interface.h" #include "gpu/command_buffer/client/webgpu_interface.h" #include "gpu/command_buffer/common/shared_image_usage.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/graphics/graphics_layer.cc b/third_party/blink/renderer/platform/graphics/graphics_layer.cc deleted file mode 100644 index ebba7fc9..0000000 --- a/third_party/blink/renderer/platform/graphics/graphics_layer.cc +++ /dev/null
@@ -1,565 +0,0 @@ -/* - * Copyright (C) 2009 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" - -#include <algorithm> -#include <cmath> -#include <memory> -#include <utility> - -#include "base/logging.h" -#include "base/memory/ptr_util.h" -#include "base/stl_util.h" -#include "base/trace_event/traced_value.h" -#include "cc/layers/layer.h" -#include "cc/layers/picture_layer.h" -#include "cc/paint/display_item_list.h" -#include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/renderer/platform/geometry/geometry_as_json.h" -#include "third_party/blink/renderer/platform/geometry/layout_rect.h" -#include "third_party/blink/renderer/platform/geometry/region.h" -#include "third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h" -#include "third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.h" -#include "third_party/blink/renderer/platform/graphics/compositor_filter_operations.h" -#include "third_party/blink/renderer/platform/graphics/graphics_context.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer_tree_as_text.h" -#include "third_party/blink/renderer/platform/graphics/image.h" -#include "third_party/blink/renderer/platform/graphics/logging_canvas.h" -#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h" -#include "third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h" -#include "third_party/blink/renderer/platform/graphics/paint/paint_chunk_subset_recorder.h" -#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h" -#include "third_party/blink/renderer/platform/graphics/paint/property_tree_state.h" -#include "third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.h" -#include "third_party/blink/renderer/platform/graphics/paint/raster_invalidator.h" -#include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h" -#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" -#include "third_party/blink/renderer/platform/wtf/hash_map.h" -#include "third_party/blink/renderer/platform/wtf/hash_set.h" -#include "third_party/blink/renderer/platform/wtf/math_extras.h" -#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" -#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" -#include "ui/gfx/geometry/rect_f.h" - -namespace blink { - -GraphicsLayer::GraphicsLayer() - : draws_content_(false), - paints_hit_test_(false), - contents_visible_(true), - hit_testable_(false), - needs_check_raster_invalidation_(false), - raster_invalidated_(false), - should_create_layers_after_paint_(false), - repainted_(false), - painting_phase_(kGraphicsLayerPaintAllWithOverflowClip), - parent_(nullptr), - raster_invalidation_function_( - base::BindRepeating(&GraphicsLayer::InvalidateRaster, - base::Unretained(this))) { - layer_ = cc::PictureLayer::Create(this); - layer_->SetIsDrawable(draws_content_ && contents_visible_); - layer_->SetHitTestable(hit_testable_); - - UpdateTrackingRasterInvalidations(); -} - -GraphicsLayer::~GraphicsLayer() { -#if DCHECK_IS_ON() - DCHECK(is_destroyed_); -#endif -} - -void GraphicsLayer::Destroy() { - CcLayer().ClearClient(); - contents_layer_ = nullptr; - - RemoveAllChildren(); - RemoveFromParent(); - DCHECK(!parent_); - - // This ensures we clean-up the ElementId to cc::Layer mapping in - // LayerTreeHost before a new layer with the same ElementId is added. See - // https://crbug.com/979002 for more information. - SetElementId(CompositorElementId()); - -#if DCHECK_IS_ON() - is_destroyed_ = true; -#endif -} - -void GraphicsLayer::AppendAdditionalInfoAsJSON(LayerTreeFlags flags, - const cc::Layer& layer, - JSONObject& json) const { - // Only the primary layer associated with GraphicsLayer adds additional - // information. Other layer state, such as raster invalidations, don't - // disambiguate between specific layers. - if (&layer != layer_.get()) - return; - - if ((flags & (kLayerTreeIncludesInvalidations | - kLayerTreeIncludesDetailedInvalidations)) && - IsTrackingRasterInvalidations() && GetRasterInvalidationTracking()) { - GetRasterInvalidationTracking()->AsJSON( - &json, flags & kLayerTreeIncludesDetailedInvalidations); - } - - GraphicsLayerPaintingPhase painting_phase = PaintingPhase(); - if ((flags & kLayerTreeIncludesPaintingPhases) && painting_phase) { - auto painting_phases_json = std::make_unique<JSONArray>(); - if (painting_phase & kGraphicsLayerPaintBackground) - painting_phases_json->PushString("GraphicsLayerPaintBackground"); - if (painting_phase & kGraphicsLayerPaintForeground) - painting_phases_json->PushString("GraphicsLayerPaintForeground"); - if (painting_phase & kGraphicsLayerPaintMask) - painting_phases_json->PushString("GraphicsLayerPaintMask"); - if (painting_phase & kGraphicsLayerPaintOverflowContents) - painting_phases_json->PushString("GraphicsLayerPaintOverflowContents"); - if (painting_phase & kGraphicsLayerPaintCompositedScroll) - painting_phases_json->PushString("GraphicsLayerPaintCompositedScroll"); - if (painting_phase & kGraphicsLayerPaintDecoration) - painting_phases_json->PushString("GraphicsLayerPaintDecoration"); - json.SetArray("paintingPhases", std::move(painting_phases_json)); - } - - if (flags & - (kLayerTreeIncludesDebugInfo | kLayerTreeIncludesCompositingReasons)) { - bool debug = flags & kLayerTreeIncludesDebugInfo; - { - auto squashing_disallowed_reasons_json = std::make_unique<JSONArray>(); - SquashingDisallowedReasons squashing_disallowed_reasons = - GetSquashingDisallowedReasons(); - auto names = debug ? SquashingDisallowedReason::Descriptions( - squashing_disallowed_reasons) - : SquashingDisallowedReason::ShortNames( - squashing_disallowed_reasons); - for (const char* name : names) - squashing_disallowed_reasons_json->PushString(name); - json.SetArray("squashingDisallowedReasons", - std::move(squashing_disallowed_reasons_json)); - } - } - - if (ShouldCreateLayersAfterPaint()) { - json.SetBoolean("shouldCreateLayersAfterPaint", true); - } else { -#if DCHECK_IS_ON() - if (HasLayerState() && cc_display_item_list_ && - (flags & kLayerTreeIncludesPaintRecords)) { - LoggingCanvas canvas; - cc_display_item_list_->Raster(&canvas); - json.SetValue("paintRecord", canvas.Log()); - } -#endif - } -} - -void GraphicsLayer::SetParent(GraphicsLayer* layer) { -#if DCHECK_IS_ON() - DCHECK(!layer || !layer->HasAncestor(this)); -#endif - parent_ = layer; -} - -#if DCHECK_IS_ON() - -bool GraphicsLayer::HasAncestor(GraphicsLayer* ancestor) const { - for (GraphicsLayer* curr = Parent(); curr; curr = curr->Parent()) { - if (curr == ancestor) - return true; - } - - return false; -} - -#endif - -bool GraphicsLayer::SetChildren(const GraphicsLayerVector& new_children) { - // If the contents of the arrays are the same, nothing to do. - if (new_children == children_) - return false; - - RemoveAllChildren(); - - for (GraphicsLayer* new_child : new_children) - AddChildInternal(new_child); - - NotifyChildListChange(); - - return true; -} - -void GraphicsLayer::AddChildInternal(GraphicsLayer* child_layer) { - // TODO(szager): Remove CHECK after diagnosing crbug.com/1092673 - CHECK(child_layer); - DCHECK_NE(child_layer, this); - - if (child_layer->Parent()) - child_layer->RemoveFromParent(); - - child_layer->SetParent(this); - children_.push_back(child_layer); - - // Don't call NotifyChildListChange here, this function is used in cases where - // it should not be called until all children are processed. -} - -void GraphicsLayer::AddChild(GraphicsLayer* child_layer) { - AddChildInternal(child_layer); - NotifyChildListChange(); -} - -void GraphicsLayer::RemoveAllChildren() { - while (!children_.IsEmpty()) { - GraphicsLayer* cur_layer = children_.back(); - DCHECK(cur_layer->Parent()); - cur_layer->RemoveFromParent(); - } -} - -void GraphicsLayer::RemoveFromParent() { - if (parent_) { - // We use reverseFind so that removeAllChildren() isn't n^2. - parent_->children_.EraseAt(parent_->children_.ReverseFind(this)); - SetParent(nullptr); - } -} - -void GraphicsLayer::SetOffsetFromLayoutObject(const gfx::Vector2d& offset) { - if (offset == offset_from_layout_object_) - return; - - offset_from_layout_object_ = offset; - Invalidate(PaintInvalidationReason::kFullLayer); // As DisplayItemClient. -} - -void GraphicsLayer::ClearPaintStateRecursively() { - ForAllGraphicsLayers( - *this, - [](GraphicsLayer& layer) -> bool { - layer.paint_controller_ = nullptr; - layer.raster_invalidator_ = nullptr; - return true; - }, - [](GraphicsLayer&, const cc::Layer&) {}); -} - -void GraphicsLayer::SetShouldCreateLayersAfterPaint( - bool should_create_layers_after_paint) { - if (should_create_layers_after_paint != should_create_layers_after_paint_) { - should_create_layers_after_paint_ = should_create_layers_after_paint; - // Depending on |should_create_layers_after_paint_|, raster invalidation - // will happen in via two different code paths. When it changes we need to - // fully invalidate because the incremental raster invalidations of these - // code paths will not work. - if (raster_invalidator_) - raster_invalidator_->ClearOldStates(); - } -} - -void GraphicsLayer::NotifyChildListChange() {} - -void GraphicsLayer::UpdateLayerIsDrawable() { - // For the rest of the accelerated compositor code, there is no reason to make - // a distinction between drawsContent and contentsVisible. So, for - // m_layer->layer(), these two flags are combined here. |m_contentsLayer| - // shouldn't receive the drawsContent flag, so it is only given - // contentsVisible. - - CcLayer().SetIsDrawable(draws_content_ && contents_visible_); - if (contents_layer_) - contents_layer_->SetIsDrawable(contents_visible_); - - if (draws_content_) - CcLayer().SetNeedsDisplay(); -} - -void GraphicsLayer::UpdateContentsLayerBounds() { - if (!contents_layer_) - return; - - contents_layer_->SetBounds(contents_rect_.size()); -} - -void GraphicsLayer::SetContentsToCcLayer( - scoped_refptr<cc::Layer> contents_layer) { - DCHECK_NE(contents_layer, layer_); - SetContentsTo(std::move(contents_layer)); -} - -void GraphicsLayer::SetContentsTo(scoped_refptr<cc::Layer> layer) { - if (layer) { - if (contents_layer_ != layer) { - contents_layer_ = std::move(layer); - // It is necessary to call SetDrawsContent() as soon as we receive the new - // contents_layer, for the correctness of early exit conditions in - // SetDrawsContent() and SetContentsVisible(). - contents_layer_->SetIsDrawable(contents_visible_); - contents_layer_->SetHitTestable(contents_visible_); - NotifyChildListChange(); - } - UpdateContentsLayerBounds(); - } else if (contents_layer_) { - contents_layer_ = nullptr; - NotifyChildListChange(); - } -} - -RasterInvalidator& GraphicsLayer::EnsureRasterInvalidator() { - if (!raster_invalidator_) { - raster_invalidator_ = std::make_unique<RasterInvalidator>(); - raster_invalidator_->SetTracksRasterInvalidations( - IsTrackingRasterInvalidations()); - } - return *raster_invalidator_; -} - -bool GraphicsLayer::IsTrackingRasterInvalidations() const { -#if DCHECK_IS_ON() - if (VLOG_IS_ON(3)) - return true; -#endif - return false; -} - -void GraphicsLayer::UpdateTrackingRasterInvalidations() { - if (IsTrackingRasterInvalidations()) - EnsureRasterInvalidator().SetTracksRasterInvalidations(true); - else if (raster_invalidator_) - raster_invalidator_->SetTracksRasterInvalidations(false); -} - -void GraphicsLayer::ResetTrackedRasterInvalidations() { - if (auto* tracking = GetRasterInvalidationTracking()) - tracking->ClearInvalidations(); -} - -bool GraphicsLayer::HasTrackedRasterInvalidations() const { - if (auto* tracking = GetRasterInvalidationTracking()) - return tracking->HasInvalidations(); - return false; -} - -RasterInvalidationTracking* GraphicsLayer::GetRasterInvalidationTracking() - const { - return raster_invalidator_ ? raster_invalidator_->GetTracking() : nullptr; -} - -void GraphicsLayer::TrackRasterInvalidation(const DisplayItemClient& client, - const gfx::Rect& rect, - PaintInvalidationReason reason) { - if (RasterInvalidationTracking::ShouldAlwaysTrack()) - EnsureRasterInvalidator().EnsureTracking(); - - // This only tracks invalidations that the cc::Layer is fully invalidated - // directly, e.g. from SetContentsNeedsDisplay(), etc. Other raster - // invalidations are tracked in RasterInvalidator. - if (auto* tracking = GetRasterInvalidationTracking()) { - tracking->AddInvalidation(client.Id(), client.DebugName(), rect, reason); - } -} - -String GraphicsLayer::DebugName(const cc::Layer* layer) const { - NOTREACHED(); - return ""; -} - -const gfx::Size& GraphicsLayer::Size() const { - return CcLayer().bounds(); -} - -void GraphicsLayer::SetSize(const gfx::Size& size) { - DCHECK(size.width() >= 0 && size.height() >= 0); - - if (size == CcLayer().bounds()) - return; - - Invalidate(PaintInvalidationReason::kIncremental); // as DisplayItemClient. - - CcLayer().SetBounds(size); - SetNeedsCheckRasterInvalidation(); - // Note that we don't resize contents_layer_. It's up the caller to do that. -} - -void GraphicsLayer::SetDrawsContent(bool draws_content) { - // NOTE: This early-exit is only correct because we also properly call - // cc::Layer::SetIsDrawable() whenever |contents_layer_| is set to a new - // layer in SetupContentsLayer(). - if (draws_content == draws_content_) - return; - - // This flag will be updated when the layer is repainted. - should_create_layers_after_paint_ = false; - - draws_content_ = draws_content; - UpdateLayerIsDrawable(); - - if (!draws_content) { - paint_controller_.reset(); - raster_invalidator_.reset(); - } -} - -void GraphicsLayer::SetContentsVisible(bool contents_visible) { - // NOTE: This early-exit is only correct because we also properly call - // cc::Layer::SetIsDrawable() whenever |contents_layer_| is set to a new - // layer in SetupContentsLayer(). - if (contents_visible == contents_visible_) - return; - - contents_visible_ = contents_visible; - UpdateLayerIsDrawable(); -} - -void GraphicsLayer::SetPaintsHitTest(bool paints_hit_test) { - if (paints_hit_test_ == paints_hit_test) - return; - // This flag will be updated when the layer is repainted. - should_create_layers_after_paint_ = false; - paints_hit_test_ = paints_hit_test; -} - -void GraphicsLayer::SetHitTestable(bool should_hit_test) { - if (hit_testable_ == should_hit_test) - return; - hit_testable_ = should_hit_test; - CcLayer().SetHitTestable(should_hit_test); -} - -void GraphicsLayer::InvalidateContents() { - if (contents_layer_) { - contents_layer_->SetNeedsDisplay(); - TrackRasterInvalidation(*this, contents_rect_, - PaintInvalidationReason::kFullLayer); - } -} - -void GraphicsLayer::InvalidateRaster(const gfx::Rect& rect) { - DCHECK(PaintsContentOrHitTest()); - raster_invalidated_ = true; - CcLayer().SetNeedsDisplayRect(rect); -} - -void GraphicsLayer::SetContentsRect(const gfx::Rect& rect) { - if (rect == contents_rect_) - return; - - contents_rect_ = rect; - UpdateContentsLayerBounds(); -} - -void GraphicsLayer::SetPaintingPhase(GraphicsLayerPaintingPhase phase) { - if (painting_phase_ == phase) - return; - painting_phase_ = phase; - Invalidate(PaintInvalidationReason::kFullLayer); // As DisplayItemClient. -} - -PaintController& GraphicsLayer::GetPaintController() const { - CHECK(PaintsContentOrHitTest()); - if (!paint_controller_) - paint_controller_ = std::make_unique<PaintController>(); - return *paint_controller_; -} - -void GraphicsLayer::SetElementId(const CompositorElementId& id) { - CcLayer().SetElementId(id); -} - -void GraphicsLayer::SetLayerState(const PropertyTreeStateOrAlias& layer_state, - const gfx::Vector2d& layer_offset) { - if (layer_state_) { - if (layer_state_->state == layer_state && - layer_state_->offset == layer_offset) - return; - layer_state_->state = layer_state; - layer_state_->offset = layer_offset; - } else { - layer_state_ = std::make_unique<LayerState>( - LayerState{RefCountedPropertyTreeState(layer_state), layer_offset}); - } - - CcLayer().SetSubtreePropertyChanged(); -} - -void GraphicsLayer::SetContentsLayerState( - const PropertyTreeStateOrAlias& layer_state, - const gfx::Vector2d& layer_offset) { - DCHECK(ContentsLayer()); - - if (contents_layer_state_) { - if (contents_layer_state_->state == layer_state && - contents_layer_state_->offset == layer_offset) - return; - contents_layer_state_->state = layer_state; - contents_layer_state_->offset = layer_offset; - } else { - contents_layer_state_ = std::make_unique<LayerState>( - LayerState{RefCountedPropertyTreeState(layer_state), layer_offset}); - } - - ContentsLayer()->SetSubtreePropertyChanged(); -} - -gfx::Rect GraphicsLayer::PaintableRegion() const { - return previous_interest_rect_; -} - -scoped_refptr<cc::DisplayItemList> GraphicsLayer::PaintContentsToDisplayList() { - DCHECK(!ShouldCreateLayersAfterPaint()); - return cc_display_item_list_; -} - -size_t GraphicsLayer::ApproximateUnsharedMemoryUsageRecursive() const { - size_t result = sizeof(*this); - if (paint_controller_) - result += paint_controller_->ApproximateUnsharedMemoryUsage(); - if (raster_invalidator_) - result += raster_invalidator_->ApproximateUnsharedMemoryUsage(); - for (GraphicsLayer* child : Children()) - result += child->ApproximateUnsharedMemoryUsageRecursive(); - return result; -} - -void GraphicsLayer::Trace(Visitor* visitor) const { - visitor->Trace(children_); - visitor->Trace(parent_); - DisplayItemClient::Trace(visitor); -} - -} // namespace blink - -#if DCHECK_IS_ON() -void showGraphicsLayerTree(const blink::GraphicsLayer* layer) { - if (!layer) { - LOG(ERROR) << "Cannot showGraphicsLayerTree for (nil)."; - return; - } - - String output = blink::GraphicsLayerTreeAsTextForTesting(layer, 0xffffffff); - LOG(INFO) << output.Utf8(); -} -#endif
diff --git a/third_party/blink/renderer/platform/graphics/graphics_layer.h b/third_party/blink/renderer/platform/graphics/graphics_layer.h deleted file mode 100644 index 0fa6a8b..0000000 --- a/third_party/blink/renderer/platform/graphics/graphics_layer.h +++ /dev/null
@@ -1,383 +0,0 @@ -/* - * Copyright (C) 2009 Apple Inc. All rights reserved. - * Copyright (C) 2013 Intel Corporation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GRAPHICS_LAYER_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GRAPHICS_LAYER_H_ - -#include <memory> - -#include "base/dcheck_is_on.h" -#include "cc/input/scroll_snap_data.h" -#include "cc/layers/content_layer_client.h" -#include "cc/layers/layer.h" -#include "third_party/blink/renderer/platform/geometry/float_point_3d.h" -#include "third_party/blink/renderer/platform/graphics/color.h" -#include "third_party/blink/renderer/platform/graphics/compositing/layers_as_json.h" -#include "third_party/blink/renderer/platform/graphics/compositing_reasons.h" -#include "third_party/blink/renderer/platform/graphics/compositor_element_id.h" -#include "third_party/blink/renderer/platform/graphics/graphics_context.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer_client.h" -#include "third_party/blink/renderer/platform/graphics/graphics_types.h" -#include "third_party/blink/renderer/platform/graphics/image_orientation.h" -#include "third_party/blink/renderer/platform/graphics/paint/display_item_client.h" -#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h" -#include "third_party/blink/renderer/platform/graphics/paint/raster_invalidator.h" -#include "third_party/blink/renderer/platform/graphics/paint_invalidation_reason.h" -#include "third_party/blink/renderer/platform/graphics/squashing_disallowed_reasons.h" -#include "third_party/blink/renderer/platform/heap/handle.h" -#include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/transforms/transformation_matrix.h" -#include "third_party/blink/renderer/platform/wtf/vector.h" -#include "third_party/skia/include/core/SkRefCnt.h" -#include "ui/gfx/geometry/point_f.h" -#include "ui/gfx/geometry/rect.h" -#include "ui/gfx/geometry/size_f.h" - -namespace cc { -class DisplayItemList; -class PictureLayer; -} // namespace cc - -namespace blink { - -class GraphicsLayer; -class PaintController; -class RasterInvalidationTracking; -class RasterInvalidator; - -typedef HeapVector<Member<GraphicsLayer>, 64> GraphicsLayerVector; - -// GraphicsLayer is an abstraction for a rendering surface with backing store, -// which may have associated transformation and animations. -class PLATFORM_EXPORT GraphicsLayer : public GarbageCollected<GraphicsLayer>, - public DisplayItemClient, - public LayerAsJSONClient, - private cc::ContentLayerClient { - public: - // |Destroy()| shouold be called when the object is no longer used. - explicit GraphicsLayer(); - GraphicsLayer(const GraphicsLayer&) = delete; - GraphicsLayer& operator=(const GraphicsLayer&) = delete; - ~GraphicsLayer() override; - void Destroy(); - - void SetCompositingReasons(CompositingReasons reasons) { - compositing_reasons_ = reasons; - } - CompositingReasons GetCompositingReasons() const { - return compositing_reasons_; - } - - SquashingDisallowedReasons GetSquashingDisallowedReasons() const { - return squashing_disallowed_reasons_; - } - void SetSquashingDisallowedReasons(SquashingDisallowedReasons reasons) { - squashing_disallowed_reasons_ = reasons; - } - - void SetOwnerNodeId(DOMNodeId id) { owner_node_id_ = id; } - - GraphicsLayer* Parent() const { return parent_; } - void SetParent(GraphicsLayer*); // Internal use only. - - const HeapVector<Member<GraphicsLayer>>& Children() const { - return children_; - } - // Returns true if the child list changed. - bool SetChildren(const GraphicsLayerVector&); - - // Add child layers. If the child is already parented, it will be removed from - // its old parent. - void AddChild(GraphicsLayer*); - - void RemoveAllChildren(); - void RemoveFromParent(); - - // The offset is the origin of the layoutObject minus the origin of the - // graphics layer (so either zero or negative). - gfx::Vector2d OffsetFromLayoutObject() const { - return offset_from_layout_object_; - } - void SetOffsetFromLayoutObject(const gfx::Vector2d&); - - // The size of the layer. - const gfx::Size& Size() const; - void SetSize(const gfx::Size&); - - bool DrawsContent() const { return draws_content_; } - void SetDrawsContent(bool); - - // False if no hit test data will be recorded onto this GraphicsLayer. - // This is different from |DrawsContent| because hit test data are internal - // to blink and are not copied to the cc::Layer's display list. - bool PaintsHitTest() const { return paints_hit_test_; } - void SetPaintsHitTest(bool); - - bool PaintsContentOrHitTest() const { - return draws_content_ || paints_hit_test_; - } - - bool ContentsAreVisible() const { return contents_visible_; } - void SetContentsVisible(bool); - - void SetHitTestable(bool); - bool IsHitTestable() const { return hit_testable_; } - - // Some GraphicsLayers paint only the foreground or the background content - GraphicsLayerPaintingPhase PaintingPhase() const { return painting_phase_; } - void SetPaintingPhase(GraphicsLayerPaintingPhase); - - void InvalidateContents(); - - // Set that the position/size of the contents (image or video). - void SetContentsRect(const gfx::Rect&); - - void SetContentsToCcLayer(scoped_refptr<cc::Layer> contents_layer); - bool HasContentsLayer() const { return ContentsLayer(); } - cc::Layer* ContentsLayer() const { return contents_layer_.get(); } - - const gfx::Rect& ContentsRect() const { return contents_rect_; } - - // For hosting this GraphicsLayer in a native layer hierarchy. - cc::PictureLayer& CcLayer() const { return *layer_; } - - bool IsTrackingRasterInvalidations() const; - void UpdateTrackingRasterInvalidations(); - void ResetTrackedRasterInvalidations(); - bool HasTrackedRasterInvalidations() const; - RasterInvalidationTracking* GetRasterInvalidationTracking() const; - void TrackRasterInvalidation(const DisplayItemClient&, - const gfx::Rect&, - PaintInvalidationReason); - - PaintController& GetPaintController() const; - - void SetElementId(const CompositorElementId&); - - // DisplayItemClient methods - String DebugName() const final { return ""; } - DOMNodeId OwnerNodeId() const final { return owner_node_id_; } - - // LayerAsJSONClient implementation. - void AppendAdditionalInfoAsJSON(LayerTreeFlags, - const cc::Layer&, - JSONObject&) const override; - - bool HasLayerState() const { return layer_state_.get(); } - void SetLayerState(const PropertyTreeStateOrAlias&, - const gfx::Vector2d& layer_offset); - PropertyTreeStateOrAlias GetPropertyTreeState() const { - return layer_state_->state.GetPropertyTreeState(); - } - gfx::Vector2d GetOffsetFromTransformNode() const { - return layer_state_->offset; - } - - void SetContentsLayerState(const PropertyTreeStateOrAlias&, - const gfx::Vector2d& layer_offset); - PropertyTreeStateOrAlias GetContentsPropertyTreeState() const { - return contents_layer_state_ - ? contents_layer_state_->state.GetPropertyTreeState() - : GetPropertyTreeState(); - } - gfx::Vector2d GetContentsOffsetFromTransformNode() const { - return contents_layer_state_ ? contents_layer_state_->offset - : GetOffsetFromTransformNode(); - } - - void SetNeedsCheckRasterInvalidation() { - needs_check_raster_invalidation_ = true; - } - - void SetShouldCreateLayersAfterPaint(bool); - bool ShouldCreateLayersAfterPaint() const { - return should_create_layers_after_paint_; - } - - // Whether this GraphicsLayer is repainted in the last Paint(). - bool Repainted() const { return repainted_; } - - size_t ApproximateUnsharedMemoryUsageRecursive() const; - - void Trace(Visitor* visitor) const override; - - protected: - String DebugName(const cc::Layer*) const; - - private: - friend class CompositedLayerMappingTest; - friend class GraphicsLayerTest; - - // cc::ContentLayerClient implementation. - gfx::Rect PaintableRegion() const final; - scoped_refptr<cc::DisplayItemList> PaintContentsToDisplayList() final; - bool FillsBoundsCompletely() const final { return false; } - - void ClearPaintStateRecursively(); - - // Adds a child without calling NotifyChildListChange(), so that adding - // children can be batched before updating. - void AddChildInternal(GraphicsLayer*); - -#if DCHECK_IS_ON() - bool HasAncestor(GraphicsLayer*) const; -#endif - - // Helper functions used by settors to keep layer's the state consistent. - void NotifyChildListChange(); - void UpdateLayerIsDrawable(); - void UpdateContentsLayerBounds(); - - void SetContentsTo(scoped_refptr<cc::Layer>); - - RasterInvalidator& EnsureRasterInvalidator(); - void InvalidateRaster(const gfx::Rect&); - - // Offset from the owning layoutObject - gfx::Vector2d offset_from_layout_object_; - - TransformationMatrix transform_; - - bool draws_content_ : 1; - bool paints_hit_test_ : 1; - bool contents_visible_ : 1; - bool hit_testable_ : 1; - bool needs_check_raster_invalidation_ : 1; - bool raster_invalidated_ : 1; - // True if the cc::Layers for this GraphicsLayer should be created after - // paint (in PaintArtifactCompositor). This depends on the display item list - // and is updated after CommitNewDisplayItems. - bool should_create_layers_after_paint_ : 1; - bool repainted_ : 1; - - GraphicsLayerPaintingPhase painting_phase_; - - HeapVector<Member<GraphicsLayer>> children_; - Member<GraphicsLayer> parent_; - - gfx::Rect contents_rect_; - - scoped_refptr<cc::PictureLayer> layer_; - scoped_refptr<cc::Layer> contents_layer_; - scoped_refptr<cc::DisplayItemList> cc_display_item_list_; - - SquashingDisallowedReasons squashing_disallowed_reasons_ = - SquashingDisallowedReason::kNone; - - mutable std::unique_ptr<PaintController> paint_controller_; - - // Used only when CullRectUpdate is not enabled. - gfx::Rect previous_interest_rect_; - - struct LayerState { - // In theory, it's unnecessary to use RefCountedPropertyTreeState because - // when it's used, the state should always reference current paint property - // nodes in ObjectPaintProperties. This is to workaround under-invalidation - // of layer state. - RefCountedPropertyTreeState state; - gfx::Vector2d offset; - }; - std::unique_ptr<LayerState> layer_state_; - std::unique_ptr<LayerState> contents_layer_state_; - - std::unique_ptr<RasterInvalidator> raster_invalidator_; - RasterInvalidator::RasterInvalidationFunction raster_invalidation_function_; - - DOMNodeId owner_node_id_ = kInvalidDOMNodeId; - CompositingReasons compositing_reasons_ = CompositingReason::kNone; - -#if DCHECK_IS_ON() - bool is_destroyed_ = false; -#endif -}; - -// Iterates all graphics layers that should be seen by the compositor in -// pre-order. |GraphicsLayerType&| matches |GraphicsLayer&| or -// |const GraphicsLayer&|. |GraphicsLayerFunction| accepts a GraphicsLayerType -// parameter, and returns a bool to indicate if the recursion should continue. -template <typename GraphicsLayerType, - typename GraphicsLayerFunction, - typename ContentsLayerFunction> -void ForAllGraphicsLayers( - GraphicsLayerType& layer, - const GraphicsLayerFunction& graphics_layer_function, - const ContentsLayerFunction& contents_layer_function) { - if (!graphics_layer_function(layer)) - return; - - if (auto* contents_layer = layer.ContentsLayer()) - contents_layer_function(layer, *contents_layer); - - for (GraphicsLayer* child : layer.Children()) { - ForAllGraphicsLayers(*child, graphics_layer_function, - contents_layer_function); - } -} - -// Unlike ForAllGraphicsLayers, here |GraphicsLayerFunction| should return void. -template <typename GraphicsLayerType, - typename GraphicsLayerFunction, - typename ContentsLayerFunction> -void ForAllActiveGraphicsLayers( - GraphicsLayerType& layer, - const GraphicsLayerFunction& graphics_layer_function, - const ContentsLayerFunction& contents_layer_function) { - ForAllGraphicsLayers( - layer, - [&graphics_layer_function](GraphicsLayerType& layer) -> bool { - if (layer.Client().ShouldSkipPaintingSubtree()) - return false; - if (layer.PaintsContentOrHitTest() || layer.IsHitTestable()) - graphics_layer_function(layer); - return true; - }, - contents_layer_function); -} - -template <typename GraphicsLayerType, typename Function> -void ForAllActiveGraphicsLayers(GraphicsLayerType& layer, - const Function& function) { - ForAllActiveGraphicsLayers(layer, function, - [](GraphicsLayerType&, const cc::Layer&) {}); -} - -template <typename GraphicsLayerType, typename Function> -void ForAllPaintingGraphicsLayers(GraphicsLayerType& layer, - const Function& function) { - ForAllActiveGraphicsLayers(layer, [&function](GraphicsLayerType& layer) { - if (layer.PaintsContentOrHitTest()) - function(layer); - }); -} - -} // namespace blink - -#if DCHECK_IS_ON() -// Outside the blink namespace for ease of invocation from gdb. -PLATFORM_EXPORT void showGraphicsLayerTree(const blink::GraphicsLayer*); -#endif - -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GRAPHICS_LAYER_H_
diff --git a/third_party/blink/renderer/platform/graphics/graphics_layer_client.h b/third_party/blink/renderer/platform/graphics/graphics_layer_client.h deleted file mode 100644 index 66126ab..0000000 --- a/third_party/blink/renderer/platform/graphics/graphics_layer_client.h +++ /dev/null
@@ -1,46 +0,0 @@ -/* - * Copyright (C) 2009 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GRAPHICS_LAYER_CLIENT_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GRAPHICS_LAYER_CLIENT_H_ - -namespace blink { - -enum GraphicsLayerPaintingPhaseFlags { - kGraphicsLayerPaintBackground = (1 << 0), - kGraphicsLayerPaintForeground = (1 << 1), - kGraphicsLayerPaintMask = (1 << 2), - kGraphicsLayerPaintOverflowContents = (1 << 3), - kGraphicsLayerPaintCompositedScroll = (1 << 4), - kGraphicsLayerPaintDecoration = (1 << 5), - kGraphicsLayerPaintAllWithOverflowClip = - (kGraphicsLayerPaintBackground | kGraphicsLayerPaintForeground | - kGraphicsLayerPaintMask | kGraphicsLayerPaintDecoration) -}; -typedef unsigned GraphicsLayerPaintingPhase; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GRAPHICS_LAYER_CLIENT_H_
diff --git a/third_party/blink/renderer/platform/graphics/graphics_layer_tree_as_text.cc b/third_party/blink/renderer/platform/graphics/graphics_layer_tree_as_text.cc deleted file mode 100644 index cc7f3372..0000000 --- a/third_party/blink/renderer/platform/graphics/graphics_layer_tree_as_text.cc +++ /dev/null
@@ -1,75 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/platform/graphics/graphics_layer_tree_as_text.h" - -#include "cc/layers/picture_layer.h" -#include "third_party/blink/renderer/platform/geometry/geometry_as_json.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" -#include "third_party/blink/renderer/platform/json/json_values.h" - -namespace blink { - -namespace { - -std::unique_ptr<JSONObject> GraphicsLayerAsJSON(const GraphicsLayer* layer, - LayerTreeFlags flags) { - auto json = CCLayerAsJSON(layer->CcLayer(), flags); - // CCLayerAsJSON() doesn't know the name before paint or if the layer is a - // legacy GraphicsLayer which doesn't contribute to the cc layer list. - json->SetString("name", layer->DebugName()); - - // Content dumped after this point, down to AppendAdditionalInfoAsJSON, is - // specific to GraphicsLayer tree dumping when called from one of the methods - // in this file. - - if (flags & kLayerTreeIncludesDebugInfo) { - if (layer->HasContentsLayer()) - json->SetInteger("ccContentsLayerId", layer->ContentsLayer()->id()); - } - - if (flags & kLayerTreeIncludesDebugInfo && - !layer->OffsetFromLayoutObject().IsZero()) { - json->SetArray("offsetFromLayoutObject", - VectorAsJSONArray(layer->OffsetFromLayoutObject())); - } - - if (!layer->ContentsAreVisible()) - json->SetBoolean("contentsVisible", false); - - if (layer->HasLayerState() && (flags & (kLayerTreeIncludesDebugInfo | - kLayerTreeIncludesPaintRecords))) { - json->SetString("layerState", layer->GetPropertyTreeState().ToString()); - json->SetValue("layerOffset", - VectorAsJSONArray(layer->GetOffsetFromTransformNode())); - } - - layer->AppendAdditionalInfoAsJSON(flags, layer->CcLayer(), *json.get()); - - return json; -} - -} // namespace - -std::unique_ptr<JSONObject> GraphicsLayerTreeAsJSON(const GraphicsLayer* layer, - LayerTreeFlags flags) { - DCHECK(flags & kOutputAsLayerTree); - std::unique_ptr<JSONObject> json = GraphicsLayerAsJSON(layer, flags); - if (layer->Children().size()) { - auto children_json = std::make_unique<JSONArray>(); - for (wtf_size_t i = 0; i < layer->Children().size(); i++) { - children_json->PushObject( - GraphicsLayerTreeAsJSON(layer->Children()[i], flags)); - } - json->SetArray("children", std::move(children_json)); - } - return json; -} - -String GraphicsLayerTreeAsTextForTesting(const GraphicsLayer* layer, - LayerTreeFlags flags) { - return GraphicsLayerTreeAsJSON(layer, flags)->ToPrettyJSONString(); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/graphics_layer_tree_as_text.h b/third_party/blink/renderer/platform/graphics/graphics_layer_tree_as_text.h deleted file mode 100644 index afabfcce..0000000 --- a/third_party/blink/renderer/platform/graphics/graphics_layer_tree_as_text.h +++ /dev/null
@@ -1,27 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GRAPHICS_LAYER_TREE_AS_TEXT_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GRAPHICS_LAYER_TREE_AS_TEXT_H_ - -#include <memory> - -#include "third_party/blink/renderer/platform/graphics/compositing/layers_as_json.h" -#include "third_party/blink/renderer/platform/platform_export.h" - -namespace blink { - -class GraphicsLayer; -class JSONObject; - -PLATFORM_EXPORT std::unique_ptr<JSONObject> GraphicsLayerTreeAsJSON( - const GraphicsLayer*, - LayerTreeFlags); - -PLATFORM_EXPORT String GraphicsLayerTreeAsTextForTesting(const GraphicsLayer*, - LayerTreeFlags); - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GRAPHICS_LAYER_TREE_AS_TEXT_H_
diff --git a/third_party/blink/renderer/platform/graphics/paint/drawing_recorder.cc b/third_party/blink/renderer/platform/graphics/paint/drawing_recorder.cc index 67b8b90..cfbbe01 100644 --- a/third_party/blink/renderer/platform/graphics/paint/drawing_recorder.cc +++ b/third_party/blink/renderer/platform/graphics/paint/drawing_recorder.cc
@@ -5,7 +5,6 @@ #include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_record.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
diff --git a/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.cc b/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.cc index 54f87768..0fef6f4 100644 --- a/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.cc +++ b/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.cc
@@ -10,7 +10,6 @@ #include "cc/layers/picture_layer.h" #include "third_party/blink/renderer/platform/graphics/compositing/layers_as_json.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/graphics/squashing_disallowed_reasons.cc b/third_party/blink/renderer/platform/graphics/squashing_disallowed_reasons.cc deleted file mode 100644 index ba96b66..0000000 --- a/third_party/blink/renderer/platform/graphics/squashing_disallowed_reasons.cc +++ /dev/null
@@ -1,122 +0,0 @@ -// 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. - -#include "third_party/blink/renderer/platform/graphics/squashing_disallowed_reasons.h" - -#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" - -namespace blink { - -namespace { - -struct SquashingDisallowedReasonStringMap { - SquashingDisallowedReasons reason; - const char* short_name; - const char* description; -}; - -constexpr SquashingDisallowedReasonStringMap - kSquashingDisallowedReasonsStringMap[] = { - {SquashingDisallowedReason::kScrollsWithRespectToSquashingLayer, - "scrollsWithRespectToSquashingLayer", - "Cannot be squashed since this layer scrolls with respect to the " - "squashing layer"}, - {SquashingDisallowedReason::kSquashingSparsityExceeded, - "squashingSparsityExceeded", - "Cannot be squashed as the squashing layer would become too sparse"}, - {SquashingDisallowedReason::kClippingContainerMismatch, - "squashingClippingContainerMismatch", - "Cannot be squashed because this layer has a different clipping " - "container than the squashing layer"}, - {SquashingDisallowedReason::kOpacityAncestorMismatch, - "squashingOpacityAncestorMismatch", - "Cannot be squashed because this layer has a different opacity " - "ancestor than the squashing layer"}, - {SquashingDisallowedReason::kTransformAncestorMismatch, - "squashingTransformAncestorMismatch", - "Cannot be squashed because this layer has a different transform " - "ancestor than the squashing layer"}, - {SquashingDisallowedReason::kPreserve3DSortingContextMismatch, - "squashingPreserve3DSortingContextMismatch", - "Cannot be squashed because this layer is part of a different 3-D" - "Rendering Context than the squashing layer"}, - {SquashingDisallowedReason::kFilterMismatch, - "squashingFilterAncestorMismatch", - "Cannot be squashed because this layer has a different filter " - "ancestor than the squashing layer, or this layer has a filter"}, - {SquashingDisallowedReason::kWouldBreakPaintOrder, - "squashingWouldBreakPaintOrder", - "Cannot be squashed without breaking paint order"}, - {SquashingDisallowedReason::kSquashingVideoIsDisallowed, - "squashingVideoIsDisallowed", "Squashing video is not supported"}, - {SquashingDisallowedReason::kSquashingLayoutEmbeddedContentIsDisallowed, - "squashingLayoutEmbeddedContentIsDisallowed", - "Squashing a frame, iframe or plugin is not supported."}, - {SquashingDisallowedReason::kSquashingBlendingIsDisallowed, - "squashingBlendingDisallowed", - "Squashing a layer with blending is not supported."}, - {SquashingDisallowedReason::kNearestFixedPositionMismatch, - "squashingNearestFixedPositionMismatch", - "Cannot be squashed because this layer has a different nearest fixed " - "position layer than the squashing layer"}, - {SquashingDisallowedReason::kSquashingLayerIsAnimating, - "squashingLayerIsAnimating", - "Cannot squash into a layer that is animating."}, - {SquashingDisallowedReason::kRenderingContextMismatch, - "squashingLayerRenderingContextMismatch", - "Cannot squash layers with different 3D contexts."}, - {SquashingDisallowedReason::kFragmentedContent, - "SquashingDisallowedReasonFragmentedContent", - "Cannot squash layers that are inside fragmentation contexts."}, - {SquashingDisallowedReason::kClipPathMismatch, - "SquashingDisallowedReasonClipPathMismatch", - "Cannot squash layers across clip-path boundaries."}, - {SquashingDisallowedReason::kMaskMismatch, - "SquashingDisallowedReasonMaskMismatch", - "Cannot squash layers across mask boundaries."}, - {SquashingDisallowedReason::kCrossesLayoutContainmentBoundary, - "SquashingDisallowedReasonCrossesLayoutContainmentBoundary", - "Cannot squash layer across layout containment boundary."}, - {SquashingDisallowedReason::kDisabled, - "SquashingDisallowedReasonDisabled", - "Squashing is disabled by runtime flag."}, -}; - -} // anonymous namespace - -Vector<const char*> SquashingDisallowedReason::ShortNames( - SquashingDisallowedReasons reasons) { -#define V(name) \ - static_assert(SquashingDisallowedReason::k##name == \ - kSquashingDisallowedReasonsStringMap \ - [SquashingDisallowedReason::kE##name] \ - .reason, \ - "kSquashingDisallowedReasonsStringMap needs update for " \ - "SquashingDisallowedReason::k" #name); \ - FOR_EACH_COMPOSITING_REASON(V) -#undef V - - Vector<const char*> result; - if (reasons == kNone) - return result; - for (auto& map : kSquashingDisallowedReasonsStringMap) { - if (reasons & map.reason) - result.push_back(map.short_name); - } - return result; -} - -Vector<const char*> SquashingDisallowedReason::Descriptions( - SquashingDisallowedReasons reasons) { - Vector<const char*> result; - if (reasons == kNone) - return result; - for (auto& map : kSquashingDisallowedReasonsStringMap) { - if (reasons & map.reason) - result.push_back(map.description); - } - return result; -} - -} // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/squashing_disallowed_reasons.h b/third_party/blink/renderer/platform/graphics/squashing_disallowed_reasons.h deleted file mode 100644 index c9fb8c6..0000000 --- a/third_party/blink/renderer/platform/graphics/squashing_disallowed_reasons.h +++ /dev/null
@@ -1,66 +0,0 @@ -// 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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_SQUASHING_DISALLOWED_REASONS_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_SQUASHING_DISALLOWED_REASONS_H_ - -#include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/wtf/vector.h" - -namespace blink { - -using SquashingDisallowedReasons = unsigned; - -#define FOR_EACH_SQUASHING_DISALLOWED_REASON(V) \ - V(ScrollsWithRespectToSquashingLayer) \ - V(SquashingSparsityExceeded) \ - V(ClippingContainerMismatch) \ - V(OpacityAncestorMismatch) \ - V(TransformAncestorMismatch) \ - V(Preserve3DSortingContextMismatch) \ - V(FilterMismatch) \ - V(WouldBreakPaintOrder) \ - V(SquashingVideoIsDisallowed) \ - V(SquashingLayoutEmbeddedContentIsDisallowed) \ - V(SquashingBlendingIsDisallowed) \ - V(NearestFixedPositionMismatch) \ - V(SquashingLayerIsAnimating) \ - V(RenderingContextMismatch) \ - V(FragmentedContent) \ - V(ClipPathMismatch) \ - V(MaskMismatch) \ - V(CrossesLayoutContainmentBoundary) \ - V(Disabled) - -class PLATFORM_EXPORT SquashingDisallowedReason { - DISALLOW_NEW(); - - private: - // This contains ordinal values for squashing disallowed reasons and will be - // used to generate the squashing disallowed reason bits. - enum { -#define V(name) kE##name, - FOR_EACH_SQUASHING_DISALLOWED_REASON(V) -#undef V - }; - -#define V(name) static_assert(kE##name < 32, "Should fit in 32 bits"); - FOR_EACH_SQUASHING_DISALLOWED_REASON(V) -#undef V - - public: - static Vector<const char*> ShortNames(SquashingDisallowedReasons); - static Vector<const char*> Descriptions(SquashingDisallowedReasons); - - enum : SquashingDisallowedReasons { - kNone = 0, -#define V(name) k##name = 1u << kE##name, - FOR_EACH_SQUASHING_DISALLOWED_REASON(V) -#undef V - }; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_SQUASHING_DISALLOWED_REASONS_H_
diff --git a/third_party/blink/tools/blinkpy/common/net/rpc.py b/third_party/blink/tools/blinkpy/common/net/rpc.py new file mode 100644 index 0000000..d28a4f3 --- /dev/null +++ b/third_party/blink/tools/blinkpy/common/net/rpc.py
@@ -0,0 +1,75 @@ +# Copyright (C) 2021 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import json +import six + +from blinkpy.common.net.luci_auth import LuciAuth + +# These characters always appear at the beginning of the RPC response. +SEARCHBUILDS_RESPONSE_PREFIX = b")]}'" + + +class Rpc(object): + def __init__(self, host): + self._host = host + + def luci_rpc(self, url, data): + """Fetches json data through Luci RPCs + + Args: + url: url for the rpc call + data: the request body in json format + + Returns: + On success: Returns the json representation of the response. + Otherwise: None + """ + luci_token = LuciAuth(self._host).get_access_token() + headers = { + 'Authorization': 'Bearer ' + luci_token, + 'Accept': 'application/json', + 'Content-Type': 'application/json', + } + if six.PY3: + body = json.dumps(data).encode("utf-8") + else: + body = json.dumps(data) + response = self._host.web.request('POST', url, data=body, headers=headers) + if response.getcode() == 200: + response_body = response.read() + if response_body.startswith(SEARCHBUILDS_RESPONSE_PREFIX): + response_body = response_body[len(SEARCHBUILDS_RESPONSE_PREFIX + ):] + return json.loads(response_body) + + _log.error( + "RPC request failed. Status=%s, url=%s" % + (response.status, url)) + _log.debug("Full RPC response: %s" % str(response)) + return None
diff --git a/third_party/blink/tools/blinkpy/common/net/rpc_mock.py b/third_party/blink/tools/blinkpy/common/net/rpc_mock.py new file mode 100644 index 0000000..4c578de --- /dev/null +++ b/third_party/blink/tools/blinkpy/common/net/rpc_mock.py
@@ -0,0 +1,38 @@ +# Copyright (C) 2011 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +class MockRpc(object): + def __init__(self, host): # pylint: disable=unused-argument + self._response = None + + def luci_rpc(self, url, data): # pylint: disable=unused-argument + return self._response + + def set_response(self, data): + self._response = data
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_uploader.py b/third_party/blink/tools/blinkpy/w3c/wpt_uploader.py new file mode 100644 index 0000000..a43c7f6 --- /dev/null +++ b/third_party/blink/tools/blinkpy/w3c/wpt_uploader.py
@@ -0,0 +1,206 @@ +# Copyright 2021 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. +"""Uploads Wpt test results from Chromium to wpt.fyi.""" + +import argparse +import gzip +import json +import logging +import os +import requests +import tempfile + +from blinkpy.common.net.rpc import Rpc +from blinkpy.common.system.log_utils import configure_logging + +_log = logging.getLogger(__name__) + + +class WptReportUploader(object): + def __init__(self, host): + self._host = host + self._rpc = Rpc(host) + self._dry_run = False + configure_logging(logging_level=logging.INFO, include_time=True) + + def main(self, argv=None): + """Pull wpt_report.json from latest CI runs, merge the reports and + upload that to wpt.fyi. + + Returns: + A boolean: True if success, False if there were any failures. + """ + options = self.parse_args(argv) + if options.verbose: + configure_logging(logging_level=logging.DEBUG, include_time=True) + self._dry_run = options.dry_run + + rv = 0 + + builders = [("chromium", "ci", "android-webview-pie-x86-wpt-fyi-rel")] + for builder in builders: + reports = [] + _log.info("Uploading report for %s" % builder[2]) + build = self.fetch_latest_complete_build(*builder) + if build: + _log.info("Find latest completed build %d" % build.get("number")) + urls = self.fetch_wpt_report_urls(build.get("id")) + for url in urls: + _log.info("Fetching wpt report from %s" % url) + res = self._host.web.request("GET", url) + if res.getcode() == 200: + body = res.read() + reports.append(json.loads(body)) + else: + _log.error("Failed to fetch wpt report.") + + merged_report = self.merge_reports(reports) + + with tempfile.TemporaryDirectory() as tmpdir: + path = os.path.join(tmpdir, "reports.json.gz") + with gzip.open(path, 'wt', encoding="utf-8") as zipfile: + json.dump(merged_report, zipfile) + rv = rv | self.upload_report(path) + _log.info(" ") + + return rv + + def fetch_wpt_report_urls(self, build_id): + """Get a list of fetchUrl for wpt-report from given build. + + This uses the QueryArtifacts rpc format specified in + https://source.chromium.org/chromium/infra/infra/+/main:go/src/go.chromium.org/luci/resultdb/proto/v1/resultdb.proto + + The response is a list of dicts of the following form: + + { + 'artifacts': [ + { + 'name': 'some name', + 'artifactId': 'wpt_reports_dada.json', + 'fetchUrl': 'https://something...', + 'fetchUrlExpiration': 'some future time', + 'sizeBytes': '8472164' + }, + ... more artifacts + ] + } + Returns a list of URLs for wpt report + """ + + invocation = "invocations/build-%s" % build_id + data = { + "invocations": [invocation], + "predicate": { + "followEdges": {"includedInvocations": True} + } + } + url = 'https://results.api.cr.dev/prpc/luci.resultdb.v1.ResultDB/QueryArtifacts' + res = self._rpc.luci_rpc(url, data) + artifacts = res.get("artifacts") if res else None + if not artifacts: + return [] + + rv = [] + for artifact in artifacts: + if artifact.get("artifactId").startswith("wpt_reports"): + rv.append(artifact.get("fetchUrl")) + return rv + + def fetch_latest_complete_build(self, project, bucket, builder_name): + """Gets latest successful build from a CI builder. + + This uses the SearchBuilds rpc format specified in + https://cs.chromium.org/chromium/infra/go/src/go.chromium.org/luci/buildbucket/proto/rpc.proto + + The response is a list of dicts of the following form: + { + "builds": [ + { + "id": "8828280326907235505", + "builder": { + "builder": "android-webview-pie-x86-wpt-fyi-rel" + }, + "status": "SUCCESS" + }, + ... more builds + } + + This method returns the latest finished build. + """ + data = { + "predicate": { + "builder": { + "project": project, + "bucket": bucket, + "builder": builder_name + }, + "status": "SUCCESS" + }, + "fields": "builds.*.builder.builder,builds.*.number,builds.*.status,builds.*.id", + "pageSize": 10 + } + url = 'https://cr-buildbucket.appspot.com/prpc/buildbucket.v2.Builds/SearchBuilds' + raw_results_json = self._rpc.luci_rpc(url, data) + if 'builds' not in raw_results_json: + return None + builds = raw_results_json['builds'] + return builds[0] if builds else None + + def upload_report(self, path_to_report): + """Upload the wpt report to wpt.fyi + + The Api is defined at: + https://github.com/web-platform-tests/wpt.fyi/tree/main/api#results-creation + """ + username = "chromium-ci-results-uploader" + password = "/!Lu:ahR%wrjb6B8x6cz" + url = "https://staging.wpt.fyi/api/results/upload" + + session = requests.Session() + session.auth = (username, password) + with open(path_to_report, 'rb') as fp: + files = {'result_file': fp} + if self._dry_run: + _log.info("Dry run, no report uploaded.") + return 0 + res = session.post(url=url, files=files) + if res.status_code == 200: + _log.info("Successfully uploaded wpt report with response: " + res.text) + report_id = res.text.split()[1] + _log.info("Report uploaded to https://staging.wpt.fyi/api/runs?run_id=%s" % report_id) + return 0 + else: + _log.error("Upload wpt report failed with status code: %d", res.status_code) + return 1 + + def merge_reports(self, reports): + if not reports: + return {} + + merged_report = {} + merged_report['run_info'] = reports[0]['run_info'] + merged_report['time_start'] = reports[0]['time_start'] + merged_report['results'] = [] + merged_report['time_end'] = reports[0]['time_end'] + for report in reports: + merged_report['time_start'] = min(merged_report['time_start'], + report['time_start']) + merged_report['results'].extend(report['results']) + merged_report['time_end'] = max(merged_report['time_end'], + report['time_end']) + return merged_report + + def parse_args(self, argv): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + '-v', + '--verbose', + action='store_true', + help='log extra details that may be helpful when debugging') + parser.add_argument( + '--dry-run', + action='store_true', + help='See what would be done without actually uploading any report.') + return parser.parse_args(argv)
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_uploader_unittest.py b/third_party/blink/tools/blinkpy/w3c/wpt_uploader_unittest.py new file mode 100644 index 0000000..576201a1 --- /dev/null +++ b/third_party/blink/tools/blinkpy/w3c/wpt_uploader_unittest.py
@@ -0,0 +1,128 @@ +# Copyright 2021 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. + +from blinkpy.common.host_mock import MockHost +from blinkpy.common.net.rpc_mock import MockRpc +from blinkpy.common.system.log_testing import LoggingTestCase +from blinkpy.w3c.wpt_uploader import WptReportUploader + + +class WptReportUploaderTest(LoggingTestCase): + def setUp(self): + super(WptReportUploaderTest, self).setUp() + self.host = MockHost() + + def test_fetch_wpt_report_urls(self): + uploader = WptReportUploader(self.host) + uploader._rpc = MockRpc(self.host) + res = {'artifacts': [{'name': 'report1', + 'artifactId': 'wpt_reports_dada.json', + 'fetchUrl': 'https://a.b.c/report1.json', + 'sizeBytes': '8472164'}, + {'name': 'report2', + 'artifactId': 'wpt_reports_dada.json', + 'fetchUrl': 'https://a.b.c/report2.json', + 'sizeBytes': '8455564'}, + {'name': 'other', + 'artifactId': 'other_dada.json', + 'fetchUrl': 'https://a.b.c/other.json', + 'sizeBytes': '9845'}]} + uploader._rpc.set_response(res) + self.assertEqual(uploader.fetch_wpt_report_urls("31415926535"), + ['https://a.b.c/report1.json', + 'https://a.b.c/report2.json']) + + res = {'artifacts': [{'name': 'other', + 'artifactId': 'other_dada.json', + 'fetchUrl': 'https://a.b.c/other.json', + 'sizeBytes': '9845'}]} + uploader._rpc.set_response(res) + self.assertEqual(uploader.fetch_wpt_report_urls("31415926535"), []) + + res = {} + uploader._rpc.set_response(res) + self.assertEqual(uploader.fetch_wpt_report_urls("31415926535"), []) + + def test_fetch_latest_complete_build(self): + uploader = WptReportUploader(self.host) + uploader._rpc = MockRpc(self.host) + builder = ("chromium", "ci", "test_builder") + expected = {"id": "31415926535", + "builder": {"builder": "test_builder"}, + "status": "SUCCESS", + "number": "100"} + res = {"builds": [expected, + {"id": "89793238462", + "builder": {"builder": "test_builder"}, + "status": "SUCCESS", + "number": "99"}, + {"id": "64338327950", + "builder": {"builder": "test_builder"}, + "status": "SUCCESS", + "number": "98"}]} + uploader._rpc.set_response(res) + build = uploader.fetch_latest_complete_build(*builder) + self.assertEqual(build, expected) + + res = {"builds": []} + uploader._rpc.set_response(res) + build = uploader.fetch_latest_complete_build(*builder) + self.assertIsNone(build) + + def test_merge_reports(self): + uploader = WptReportUploader(self.host) + report0 = {"run_info": {"os": "linux", + "processor": "x86_64", + "product": "android_webview", + "revision": "1408b119ac563b427a3e00a5514eef697c8da268"}, + "time_start": 4248, + "results": [{"test": "foo1.html", + "status": "PASS", + "duration": 2100}, + {"test": "foo2.html", + "status": "FAIL", + "duration": 300}], + "time_end": 7293} + self.assertEqual(uploader.merge_reports([report0]), report0) + + report1 = {"run_info": {"os": "linux", + "processor": "x86_64", + "product": "android_webview", + "revision": "1408b119ac563b427a3e00a5514eef697c8da268"}, + "time_start": 4200, + "results": [{"test": "bar.html", + "status": "PASS", + "duration": 990}], + "time_end": 7200} + + report2 = {"run_info": {"os": "linux", + "processor": "x86_64", + "product": "android_webview", + "revision": "1408b119ac563b427a3e00a5514eef697c8da268"}, + "time_start": 5200, + "results": [{"test": "test.html", + "status": "PASS", + "duration": 990}], + "time_end": 7999} + + _expect = {"run_info": {"os": "linux", + "processor": "x86_64", + "product": "android_webview", + "revision": "1408b119ac563b427a3e00a5514eef697c8da268"}, + "time_start": 4200, + "results": [{"test": "foo1.html", + "status": "PASS", + "duration": 2100}, + {"test": "foo2.html", + "status": "FAIL", + "duration": 300}, + {"test": "bar.html", + "status": "PASS", + "duration": 990}, + {"test": "test.html", + "status": "PASS", + "duration": 990}], + "time_end": 7999} + self.assertEqual(uploader.merge_reports([report0, report1, report2]), + _expect)
diff --git a/third_party/blink/tools/wpt_upload.py b/third_party/blink/tools/wpt_upload.py new file mode 100755 index 0000000..39259d4 --- /dev/null +++ b/third_party/blink/tools/wpt_upload.py
@@ -0,0 +1,25 @@ +#!/usr/bin/env vpython3 +# Copyright 2021 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. +"""Pulls the test results from CI builders and upload that to wpt.fyi.""" + +from blinkpy.common import exit_codes +from blinkpy.common.host import Host +from blinkpy.common.path_finder import add_depot_tools_dir_to_os_path +from blinkpy.w3c.wpt_uploader import WptReportUploader + + +def main(): + add_depot_tools_dir_to_os_path() + host = Host() + uploader = WptReportUploader(host) + try: + host.exit(uploader.main()) + except KeyboardInterrupt: + host.print_("Interrupted, exiting") + host.exit(exit_codes.INTERRUPTED_EXIT_STATUS) + + +if __name__ == '__main__': + main()
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng index 5cbf3bf..318c28ab 100644 --- a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng +++ b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
@@ -795,6 +795,7 @@ crbug.com/591099 fast/writing-mode/flipped-blocks-inline-map-local-to-container.html [ Failure ] ### external/wpt/html/rendering +crbug.com/591099 external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-block-size.html [ Failure ] crbug.com/591099 external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-containing-block.html [ Failure ] crbug.com/880062 external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-content-before-legend.html [ Failure ] crbug.com/880062 external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-generated-content.html [ Failure ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 7d42846..bb3a721 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -1728,6 +1728,28 @@ crbug.com/490511 external/wpt/html/rendering/non-replaced-elements/the-hr-element-0/width.html [ Failure ] crbug.com/692560 external/wpt/html/semantics/document-metadata/styling/LinkStyle.html [ Failure Pass ] +crbug.com/895846 external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-margins.html [ Failure ] +crbug.com/895846 external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-margins-2.html [ Failure ] +crbug.com/1223214 external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-painting-order.html [ Failure ] +crbug.com/1223214 external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-rendering.html [ Failure ] +crbug.com/1223214 external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-tall.html [ Failure ] +crbug.com/1172023 external/wpt/html/rendering/non-replaced-elements/tables/table-border-3s.html [ Failure ] +crbug.com/1172023 external/wpt/html/rendering/non-replaced-elements/tables/table-border-3q.html [ Failure ] +crbug.com/962936 external/wpt/html/rendering/widgets/button-layout/anonymous-button-content-box.html [ Failure ] +crbug.com/962936 external/wpt/html/rendering/widgets/button-layout/inline-level.html [ Failure ] +crbug.com/707210 external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-1i.html [ Failure ] +crbug.com/707210 external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-1j.html [ Failure ] +crbug.com/707210 external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-1k.html [ Failure ] +crbug.com/707210 external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-1l.html [ Failure ] +crbug.com/707210 external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-2i.html [ Failure ] +crbug.com/707210 external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-2j.html [ Failure ] +crbug.com/707210 external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-2k.html [ Failure ] +crbug.com/707210 external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-2l.html [ Failure ] + +# These were crashing only on DCHECK-enabled release builds, but maybe don't now. +# crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/margin-collapsing-quirks/multicol-quirks-mode.html [ Crash Pass ] +# crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/margin-collapsing-quirks/multicol-standards-mode.html [ Crash Failure Pass ] + crbug.com/860211 [ Mac ] external/wpt/editing/run/delete.html [ Failure ] crbug.com/821455 editing/pasteboard/drag-files-to-editable-element.html [ Failure ] @@ -4664,8 +4686,6 @@ crbug.com/626703 [ Mac10.12 ] external/wpt/preload/download-resources.html [ Failure Timeout ] crbug.com/626703 [ Mac10.13 ] external/wpt/preload/download-resources.html [ Failure Timeout ] crbug.com/626703 [ Mac10.13 ] external/wpt/preload/onload-event.html [ Failure Skip Timeout ] -crbug.com/626703 external/wpt/html/rendering/widgets/button-layout/anonymous-button-content-box.html [ Failure ] -crbug.com/626703 external/wpt/html/rendering/widgets/button-layout/inline-level.html [ Failure ] crbug.com/626703 external/wpt/xhr/abort-after-stop.any.worker.html [ Timeout ] crbug.com/626703 external/wpt/speech-api/SpeechSynthesisUtterance-volume-manual.html [ Skip ] crbug.com/626703 crbug.com/606367 external/wpt/pointerevents/pointerevent_touch-action-pan-x-pan-y-pan-y_touch.html [ Failure Pass Timeout ] @@ -4676,8 +4696,6 @@ crbug.com/626703 external/wpt/media-source/mediasource-correct-frames.html [ Failure Pass Skip Timeout ] crbug.com/626703 external/wpt/payment-method-basic-card/steps_for_selecting_the_payment_handler.html [ Timeout ] crbug.com/626703 external/wpt/payment-method-basic-card/apply_the_modifiers.html [ Timeout ] -crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/tables/table-border-3s.html [ Failure ] -crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/tables/table-border-3q.html [ Failure ] crbug.com/626703 external/wpt/screen-orientation/onchange-event.html [ Timeout ] crbug.com/626703 external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https.html [ Skip Timeout ] crbug.com/626703 external/wpt/webrtc/RTCPeerConnection-remote-track-mute.https.html [ Skip Timeout ] @@ -4734,7 +4752,6 @@ ### See crbug.com/891427 comment near the top of this file: -crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-margins-2.html [ Failure ] crbug.com/367760 external/wpt/svg/pservers/reftests/meshgradient-basic-004.svg [ Failure ] crbug.com/367760 external/wpt/svg/pservers/reftests/meshgradient-basic-001.svg [ Failure ] @@ -4758,9 +4775,6 @@ crbug.com/367760 external/wpt/svg/pservers/reftests/meshgradient-basic-005.svg [ Failure ] crbug.com/367760 external/wpt/svg/pservers/reftests/meshgradient-basic-002.svg [ Failure ] crbug.com/367760 external/wpt/svg/pservers/reftests/meshgradient-basic-003.svg [ Failure ] -crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-margins.html [ Failure ] -crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-rendering.html [ Failure ] -crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-tall.html [ Failure ] crbug.com/626703 external/wpt/speech-api/SpeechSynthesis-pause-resume.tentative.html [ Timeout ] crbug.com/626703 external/wpt/css/CSS2/floats/float-nowrap-9.html [ Failure ] crbug.com/626703 external/wpt/css/CSS2/floats/float-nowrap-8.html [ Failure ] @@ -4786,7 +4800,6 @@ crbug.com/626703 external/wpt/css/selectors/old-tests/css3-modsel-159.xml [ Skip ] crbug.com/626703 external/wpt/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/reload.window.html [ Timeout ] crbug.com/626703 external/wpt/quirks/text-decoration-doesnt-propagate-into-tables/quirks.html [ Failure ] -crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-painting-order.html [ Failure ] crbug.com/626703 external/wpt/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/tasks.window.html [ Timeout ] crbug.com/875411 external/wpt/svg/text/reftests/text-complex-002.svg [ Failure ] crbug.com/875411 external/wpt/svg/text/reftests/text-shape-inside-001.svg [ Failure ] @@ -4862,14 +4875,6 @@ crbug.com/626703 [ Linux ] external/wpt/css/css-color/t425-hsla-onscreen-multiple-boxes-c.xht [ Failure ] crbug.com/626703 [ Linux ] external/wpt/css/css-color/t425-hsla-onscreen-b.xht [ Failure ] crbug.com/626703 [ Win ] external/wpt/css/css-color/t425-hsla-onscreen-b.xht [ Failure ] -crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-1i.html [ Failure ] -crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-1j.html [ Failure ] -crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-1k.html [ Failure ] -crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-1l.html [ Failure ] -crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-2i.html [ Failure ] -crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-2j.html [ Failure ] -crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-2k.html [ Failure ] -crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-2l.html [ Failure ] crbug.com/626703 external/wpt/acid/acid2/reftest.html [ Failure Pass ] crbug.com/626703 external/wpt/acid/acid3/test.html [ Failure ] crbug.com/626703 external/wpt/css/css-ui/cursor-auto-006.html [ Skip ] @@ -5014,8 +5019,6 @@ # Crashes with DCHECK enabled, but not on normal Release builds. crbug.com/809935 external/wpt/css/css-fonts/variations/font-style-interpolation.html [ Skip Timeout ] crbug.com/626703 external/wpt/css/css-ui/text-overflow-011.html [ Crash Failure Pass ] -crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/margin-collapsing-quirks/multicol-quirks-mode.html [ Crash Pass ] -crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/margin-collapsing-quirks/multicol-standards-mode.html [ Crash Failure Pass ] # Other untriaged test failures, timeouts and crashes from newly-imported WPT tests. crbug.com/626703 external/wpt/html/browsers/history/the-location-interface/location-protocol-setter-non-broken.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 29b04f6..259b263 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -959,6 +959,7 @@ "accessibility/virtual-node-repair-document.html", "external/wpt/accessibility/crashtests/aria-hidden-with-select.html", "external/wpt/accessibility/crashtests/aria-owns-destroyed-by-content-replacement.html", + "external/wpt/accessibility/crashtests/aria-owns-reparent.html", "external/wpt/accessibility/crashtests/content-visibility-generated-content-removal.html", "external/wpt/accessibility/crashtests/included-descendant-dom-removal.html", "external/wpt/accessibility/crashtests/included-descendant-layout-removal.html",
diff --git a/third_party/blink/web_tests/external/wpt/accessibility/crashtests/aria-owns-reparent.html b/third_party/blink/web_tests/external/wpt/accessibility/crashtests/aria-owns-reparent.html new file mode 100644 index 0000000..2eaceb66 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/accessibility/crashtests/aria-owns-reparent.html
@@ -0,0 +1,21 @@ +<html class="test-wait"> +<script> +document.addEventListener("DOMContentLoaded", () => { + requestAnimationFrame(() => { + requestAnimationFrame(() => { + document.getElementById('owner').setAttribute('aria-owns','x'); + document.body.setAttribute('aria-hidden', 'true'); + document.documentElement.className = ''; + }); + }); +}); +</script> +</head> +<body> +<p id='owner'></p> + +<div> + <fieldset id='x'></fieldset> +</div> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-radius-clipping-with-transform-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-radius-clipping-with-transform-001-ref.html new file mode 100644 index 0000000..db3ae40 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-radius-clipping-with-transform-001-ref.html
@@ -0,0 +1,47 @@ +<!DOCTYPE html> +<title>CSS Test (Backgrounds): border-radius clipping on overflow:hidden with transforms</title> +<link rel="author" title="L. David Baron" href="https://dbaron.org/"> +<link rel="author" title="Google" href="http://www.google.com/"> +<style> + +#outer { + border: 10px solid #000; + border-radius: 60px; + width: 200px; + height: 200px; + background: blue; + position: absolute; + top: 10px; + left: 10px; +} + +#coverinner, #coverouter { + position: absolute; + border: 4px solid fuchsia; + filter: grayscale(30%); +} + +#coverinner { + width: 196px; + height: 196px; + top: 18px; + left: 18px; + border-radius: 52px; +} + +#coverouter { + width: 216px; + height: 216px; + top: 8px; + left: 8px; + border-radius: 62px; +} + +</style> + +<div id="outer"> +</div> +<div id="coverinner"> +</div> +<div id="coverouter"> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-radius-clipping-with-transform-001.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-radius-clipping-with-transform-001.html new file mode 100644 index 0000000..e7d173b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-radius-clipping-with-transform-001.html
@@ -0,0 +1,60 @@ +<!DOCTYPE html> +<title>CSS Test (Backgrounds): border-radius clipping on overflow:hidden with transforms</title> +<link rel="author" title="L. David Baron" href="https://dbaron.org/"> +<link rel="author" title="Google" href="http://www.google.com/"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1207151"> +<link rel="help" href="https://drafts.csswg.org/css-backgrounds-3/#corner-clipping"> +<link rel="match" href="border-radius-clipping-with-transform-001-ref.html"> +<meta name="assert" content="The content should be clipped correctly, despite the interesting transforms."> +<style> + +#outer { + border: 10px solid #000; + border-radius: 60px; + width: 200px; + height: 200px; + overflow: hidden; + transform: rotate(90deg); + position: absolute; + top: 10px; + left: 10px; +} +#inner { + width: 100%; + height: 100%; + background: blue; + transform: translateZ(0); +} + +#coverinner, #coverouter { + position: absolute; + border: 4px solid fuchsia; + filter: grayscale(30%); +} + +#coverinner { + width: 196px; + height: 196px; + top: 18px; + left: 18px; + border-radius: 52px; +} + +#coverouter { + width: 216px; + height: 216px; + top: 8px; + left: 8px; + border-radius: 62px; +} + +</style> + +<div id="outer"> + <div id="inner"> + </div> +</div> +<div id="coverinner"> +</div> +<div id="coverouter"> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-block-size.html b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-block-size.html new file mode 100644 index 0000000..e124763 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-block-size.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<link rel="help" href="https://html.spec.whatwg.org/C/#the-fieldset-and-legend-elements"> +<!-- A test for the following paragraph: +For the purpose of calculating the used 'block-size', if the computed +'block-size' is not 'auto', the space allocated for the rendered legend's +margin box that spills out past the border, if any, is expected to be +subtracted from the 'block-size'. If the content box's block-size would be +negative, then let the content box's block-size be zero instead. +--> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +fieldset { + margin: 0; + padding: 0; + border: 2px solid black; +} +legend { + height: 102px; + background-color: yellow; +} +.content { + background-color: lime; +} +</style> +<fieldset style="block-size: 200px;"> +<legend>Legend</legend> +<div class="content" style="height:100%"></div> +</fieldset> + +<fieldset style="block-size: 40px;"> +<legend>Legend</legend> +<div class="content" style="height:100%"></div> +</fieldset> + +<script> +test(() => { + let cs = document.querySelectorAll('.content'); + assert_equals(cs[0].offsetHeight, Math.max(202 - 102, 0)); + assert_equals(cs[1].offsetHeight, Math.max(42 - 102, 0)); +}, 'Test content\'s block-size'); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-position-centering.html b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-position-centering.html new file mode 100644 index 0000000..a4eda6e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-position-centering.html
@@ -0,0 +1,58 @@ +<!DOCTYPE html> +<link rel="help" href="https://html.spec.whatwg.org/C/#the-fieldset-and-legend-elements"> +<!-- A test for the following paragraph: +The element is expected to be positioned in the block-flow direction such that +its border box is centered over the border on the block-start side of the +fieldset element. +--> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +fieldset { + margin: 0; + padding: 0; + border: 100px solid black; +} +legend { + height: 0px; + border-color: yellow; + border-style: solid; +} +</style> +<fieldset> +<legend style="border-width:50px"></legend> +<br> +</fieldset> +<br> + +<fieldset> +<legend style="border-width:25px 50px"></legend> +<br> +</fieldset> +<br> + +<fieldset> +<legend style="border-width:10px 50px 40px 50px"></legend> +<br> +</fieldset> +<br> + +<fieldset> +<legend style="border-width:40px 50px 10px 50px"></legend> +<br> +</fieldset> + +<script> +function legendBlockOffset(fieldset) { + let legend = fieldset.querySelector('legend'); + return legend.getBoundingClientRect().y - fieldset.getBoundingClientRect().y; +} + +test(() => { + let fieldsets = document.querySelectorAll('fieldset'); + assert_equals(legendBlockOffset(fieldsets[0]), 0); + assert_equals(legendBlockOffset(fieldsets[1]), 25); + assert_equals(legendBlockOffset(fieldsets[2]), 25); + assert_equals(legendBlockOffset(fieldsets[3]), 25); +}, 'Legend\'s border-box should be centere on the fieldset border'); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-inline-position-with-fieldset-padding.html b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-inline-position-with-fieldset-padding.html new file mode 100644 index 0000000..0b26248 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-inline-position-with-fieldset-padding.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<link rel="help" href="https://html.spec.whatwg.org/C/#the-fieldset-and-legend-elements"> +<!-- A test for the following paragraphs: +The element's box is expected to be constrained in the inline direction by +the inline content size of the fieldset as if it had used its computed +inline padding. +Example: +For example, if the fieldset has a specified padding of 50px, then the +rendered legend will be positioned 50px in from the fieldset's border. The +padding will further apply to the anonymous fieldset content box instead +of the fieldset element itself. +--> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +fieldset { + width: 400px; + margin: 0; + padding: 0 50px; + border: 2px solid black; +} +legend { + width: 100%; + padding: 0; + background-color: yellow; +} +.content { + background-color: lime; +} +</style> +<fieldset> +<legend>Legend</legend> +</fieldset> + +<script> +test(() => { + let fieldset = document.querySelector('fieldset'); + let legend = document.querySelector('legend'); + assert_equals(legend.offsetLeft - fieldset.offsetLeft, 52); + assert_equals(legend.offsetWidth, 400); +}, 'Test legend\'s inline-size in a fieldset with inline paddings'); +</script>
diff --git a/third_party/blink/web_tests/virtual/file-handling/README.md b/third_party/blink/web_tests/virtual/file-handling/README.md index 8b2dac5..0de4f12 100644 --- a/third_party/blink/web_tests/virtual/file-handling/README.md +++ b/third_party/blink/web_tests/virtual/file-handling/README.md
@@ -1,5 +1,5 @@ # File Handling -This directory contains (tentative) tests for the [File Handling](https://github.com/WICG/file-handling/blob/master/explainer.md) proposal. +This directory contains (tentative) tests for the [File Handling](https://github.com/WICG/file-handling/blob/main/explainer.md) proposal. **This suite runs the tests with** `--enable-features=NativeFilesystemAPI,FileHandlingAPI`
diff --git a/third_party/blink/web_tests/virtual/file-handling/file-handling/launchQueue-exists.tentative.window.html b/third_party/blink/web_tests/virtual/file-handling/file-handling/launchQueue-exists.tentative.window.html index 2542dc39..94d543f 100644 --- a/third_party/blink/web_tests/virtual/file-handling/file-handling/launchQueue-exists.tentative.window.html +++ b/third_party/blink/web_tests/virtual/file-handling/file-handling/launchQueue-exists.tentative.window.html
@@ -1,6 +1,6 @@ <!doctype html> <title>Launch Params are available from JavaScript.</title> -<link rel="help" href="https://github.com/WICG/file-handling/blob/master/explainer.md"> +<link rel="help" href="https://github.com/WICG/file-handling/blob/main/explainer.md"> <script src="../../../resources/testharness.js"></script> <script src="../../../resources/testharnessreport.js"></script> <script>
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/csp.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/csp.html new file mode 100644 index 0000000..39d0d9e --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/csp.html
@@ -0,0 +1,35 @@ +<!DOCTYPE html> + <title>Test Content Security Policy</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="resources/utils.js"></script> + + <body> + + <script> + promise_test(async () => { + const csp_key = KEYS["csp"]; + + // The 'csp' property does not appear in the IDL definition for + // fenced frames, so ensure that the 'csp' property didn't + // leak over from the IFrame prototype. + assert_equals(HTMLFencedFrameElement.prototype.hasOwnProperty('csp'), + false); + + const new_frame = document.createElement('fencedframe'); + new_frame.src = "resources/csp-inner.html"; + + // This attribute will be ignored since the IDL for + // fenced frames do not support the 'csp' attribute. + new_frame.setAttribute("csp", "style-src 'none';"); + document.body.append(new_frame); + + // Get the result for the top-level fenced frame. + const fenced_frame_result = await nextValueFromServer(csp_key); + assert_equals(fenced_frame_result, "pass"); + + }, "Fenced Frames should not honor the csp attribute from parent page"); + </script> + + </body> +</html> \ No newline at end of file
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/csp-inner.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/csp-inner.html new file mode 100644 index 0000000..0f34450 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/csp-inner.html
@@ -0,0 +1,37 @@ +<!DOCTYPE html> + <script src="utils.js"></script> + + <style> + body {background-color: red;} + </style> + + <title>Fenced frame content to test Content Security Policies</title> + + <body> + <script> + const csp_key = KEYS["csp"]; + + function fail() { + writeValueToServer(csp_key, + "FAIL: img-src policy was not honored in fenced frame"); + } + + function pass() { + // The parent page is going to attempt to pass a + // style-src: 'none' CSP to the fenced frame. Make sure that + // the header is not honored. + const bgcolor = window.getComputedStyle(document.body, null) + .getPropertyValue('background-color'); + + if (bgcolor != "rgb(255, 0, 0)") { + writeValueToServer(csp_key, + "FAIL: style-src policy was passed to fenced frame"); + return; + } + + writeValueToServer(csp_key, "pass"); + } + </script> + <img src="csp.png" id="my_img" onload="fail();" onerror="pass();"> + </body> +</html> \ No newline at end of file
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/csp-inner.html.headers b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/csp-inner.html.headers new file mode 100644 index 0000000..e89be70 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/csp-inner.html.headers
@@ -0,0 +1,2 @@ +Supports-Loading-Mode: fenced-frame +Content-Security-Policy: img-src 'none' \ No newline at end of file
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/csp.png b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/csp.png new file mode 100644 index 0000000..53a9748 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/csp.png Binary files differ
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/utils.js b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/utils.js index a0b28f58..58acdc4 100644 --- a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/utils.js +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/utils.js
@@ -107,6 +107,8 @@ "resize_lock_inner_page_is_ready" : "00000000-0000-0000-0000-000000000038", "resize_lock_resize_is_done" : "00000000-0000-0000-0000-000000000039", "resize_lock_report_inner_dimensions" : "00000000-0000-0000-0000-00000000004A", + + "csp" : "00000000-0000-0000-0000-00000000004B", // Add keys above this list, incrementing the key UUID in hexadecimal }
diff --git a/third_party/googletest/README.chromium b/third_party/googletest/README.chromium index e80a50c..2875768 100644 --- a/third_party/googletest/README.chromium +++ b/third_party/googletest/README.chromium
@@ -150,5 +150,5 @@ ### Other Resources * [AutoRoller](https://autoroll.skia.org/r/googletest-chromium-autoroll) and - accompanying [configuration file](https://skia.googlesource.com/buildbot/+/master/autoroll/config/googletest-chromium.cfg) + accompanying [configuration file](https://skia.googlesource.com/skia-autoroll-internal-config.git/+/main/skia-public/googletest-chromium.cfg) * [Bug tracking substantial roll](https://crbug.com/1163396)
diff --git a/tools/json_schema_compiler/cc_generator.py b/tools/json_schema_compiler/cc_generator.py index 26a093ab..736d362 100644 --- a/tools/json_schema_compiler/cc_generator.py +++ b/tools/json_schema_compiler/cc_generator.py
@@ -972,8 +972,7 @@ c.Append('%(dst_var)s = temp.value();') elif underlying_type.property_type == PropertyType.OBJECT: if is_ptr: - (c.Append('const base::DictionaryValue* dictionary = nullptr;') - .Sblock('if (!%(src_var)s.GetAsDictionary(&dictionary)) {') + (c.Sblock('if (!%(src_var)s.is_dict()) {') .Concat(self._AppendError16( 'u"\'%%(key)s\': expected dictionary, got " + ' + self._util_cc_helper.GetValueTypeString('%%(src_var)s'))) @@ -983,7 +982,7 @@ .Sblock('else {') .Append('auto temp = std::make_unique<%(cpp_type)s>();') .Append('if (!%%(cpp_type)s::Populate(%s)) {' % self._GenerateArgs( - ('*dictionary', 'temp.get()'))) + ('%(src_var)s', 'temp.get()'))) .Append(' return %(failure_value)s;') ) (c.Append('}') @@ -992,15 +991,14 @@ .Eblock('}') ) else: - (c.Append('const base::DictionaryValue* dictionary = nullptr;') - .Sblock('if (!%(src_var)s.GetAsDictionary(&dictionary)) {') + (c.Sblock('if (!%(src_var)s.is_dict()) {') .Concat(self._AppendError16( 'u"\'%%(key)s\': expected dictionary, got " + ' + self._util_cc_helper.GetValueTypeString('%%(src_var)s'))) .Append('return %(failure_value)s;') .Eblock('}') .Append('if (!%%(cpp_type)s::Populate(%s)) {' % self._GenerateArgs( - ('*dictionary', '&%(dst_var)s'))) + ('%(src_var)s', '&%(dst_var)s'))) .Append(' return %(failure_value)s;') .Append('}') )
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 6ada213f..f9d53c8a 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -37780,18 +37780,6 @@ <int value="2" label="Not found"/> </enum> -<enum name="FingerprintError"> - <int value="0" label="Unknown error"/> - <int value="1" label="Hardware unavailable"/> - <int value="2" label="Unable to process"/> - <int value="3" label="Timeout"/> - <int value="4" label="No space available for a template"/> - <int value="5" label="Canceled"/> - <int value="6" label="Unable to remove record"/> - <int value="7" label="Hardware is locked"/> - <int value="8" label="No templates"/> -</enum> - <enum name="FingerprintRecordFormatVersion"> <int value="0" label="None"/> <int value="1" label="Record format version without validation value"/> @@ -51697,6 +51685,8 @@ <int value="-843496368" label="AutofillRejectCompanyBirthyear:disabled"/> <int value="-842438090" label="enable-md-feedback"/> <int value="-839664591" label="enable-web-authentication-testing-api"/> + <int value="-838719204" + label="ForceMajorVersionInMinorPositionInUserAgent:disabled"/> <int value="-837650216" label="DisableCryptAuthV1DeviceSync:disabled"/> <int value="-837473047" label="AutofillEnableStickyPaymentsBubble:disabled"/> <int value="-836123854" label="wallet-service-use-sandbox"/> @@ -53992,6 +53982,8 @@ <int value="877432034" label="DisableQuickAnswersV2Translation:enabled"/> <int value="877907263" label="StrictExtensionIsolation:disabled"/> <int value="878773995" label="ChromeHomeBottomNavLabels:disabled"/> + <int value="879538323" + label="ForceMajorVersionInMinorPositionInUserAgent:enabled"/> <int value="879699575" label="disable-gesture-tap-highlight"/> <int value="879992337" label="disable-pull-to-refresh-effect"/> <int value="880510010" label="enable-permissions-bubbles"/>
diff --git a/tools/metrics/histograms/metadata/event/histograms.xml b/tools/metrics/histograms/metadata/event/histograms.xml index 86e5be6..fa258d0 100644 --- a/tools/metrics/histograms/metadata/event/histograms.xml +++ b/tools/metrics/histograms/metadata/event/histograms.xml
@@ -374,6 +374,9 @@ <histogram name="Event.FractionOfTimeWithoutUserInput" units="%" expires_after="2021-06-16"> + <obsolete> + Removed December 2021. + </obsolete> <owner>sullivan@chromium.org</owner> <owner>speed-metrics-dev@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/fingerprint/histograms.xml b/tools/metrics/histograms/metadata/fingerprint/histograms.xml index 3253643..80612ec8 100644 --- a/tools/metrics/histograms/metadata/fingerprint/histograms.xml +++ b/tools/metrics/histograms/metadata/fingerprint/histograms.xml
@@ -22,19 +22,6 @@ <histograms> -<histogram name="Fingerprint.Auth.Error" enum="FingerprintError" - expires_after="2022-04-10"> - <owner>patrykd@google.com</owner> - <owner>tomhughes@chromium.org</owner> - <owner>cros-oac@google.com</owner> - <owner>chromeos-fingerprint@google.com</owner> - <summary> - Tracks the error during fingerprint authentication session. It is recorded - every time authentication session (unlock screen, web auth, etc.) ends with - error. - </summary> -</histogram> - <histogram name="Fingerprint.Auth.ScanResult" enum="FingerprintScanResult" expires_after="2022-04-10"> <owner>rsorokin@chromium.org</owner> @@ -44,7 +31,7 @@ <summary> Tracks the scan result during fingerprint authentication session. It is recorded every time user touches the fingerprint sensor while authenticating - (unlock screen, web auth, etc.) and session is not finished with error. + (unlock screen, web auth, etc.). </summary> </histogram> @@ -88,7 +75,7 @@ </histogram> <histogram name="Fingerprint.SetContext.Success" enum="BooleanSuccess" - expires_after="2022-01-02"> + expires_after="2023-01-02"> <owner>hesling@chromium.org</owner> <owner>chromeos-fingerprint@google.com</owner> <summary>Whether setting FPMCU mode succeeded.</summary> @@ -156,7 +143,7 @@ </histogram> <histogram name="Fingerprint.Unlock.Match.PositiveMatchSecretCorrect" - enum="BooleanCorrect" expires_after="2022-01-02"> + enum="BooleanCorrect" expires_after="2023-01-02"> <owner>hesling@chromium.org</owner> <owner>chromeos-fingerprint@google.com</owner> <summary> @@ -250,9 +237,8 @@ <histogram name="Fingerprint.UnlockEnabled" enum="BooleanEnabled" expires_after="2022-04-03"> - <owner>rsorokin@chromium.org</owner> - <owner>jessejames@chromium.org</owner> - <owner>cros-oac@google.com</owner> + <owner>tomhughes@chromium.org</owner> + <owner>chromeos-fingerprint@google.com</owner> <summary> Track whether fingerprint is enabled to unlock the screen, when the user logs in.
diff --git a/tools/metrics/histograms/metadata/network/histograms.xml b/tools/metrics/histograms/metadata/network/histograms.xml index 8941175..8cf9b2f5 100644 --- a/tools/metrics/histograms/metadata/network/histograms.xml +++ b/tools/metrics/histograms/metadata/network/histograms.xml
@@ -3007,6 +3007,18 @@ </summary> </histogram> +<histogram name="Network.Shill.Wifi.TimeFromRekeyToFailureSeconds" + units="seconds" expires_after="2022-12-01"> + <owner>billyzhao@chromium.org</owner> + <owner>cros-network-metrics@google.com</owner> + <summary> + Time spent between network rekey attempt to connection failure. The metric + timer starts when a rekey is initiated and stops once a connection failure + is reported or another rekey is initiated. The metric is only reported if + the timer is stopped by a connection failure within 180 seconds. + </summary> +</histogram> + <histogram name="Network.Shill.Wifi.TimeOnline" units="seconds" expires_after="2022-04-24"> <owner>norvez@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/omnibox/histograms.xml b/tools/metrics/histograms/metadata/omnibox/histograms.xml index cf7ef551..d78d9b4d 100644 --- a/tools/metrics/histograms/metadata/omnibox/histograms.xml +++ b/tools/metrics/histograms/metadata/omnibox/histograms.xml
@@ -745,8 +745,8 @@ </histogram> <histogram name="Omnibox.Search.OffTheRecord" enum="BooleanOffTheRecord" - expires_after="2022-02-02"> - <owner>rhalavati@chromium.org</owner> + expires_after="2022-08-02"> + <owner>sideyilmaz@chromium.org</owner> <owner>chrome-incognito@google.com</owner> <summary> This histogram records the number of searches done from omnibox using
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml index 87022dd..28570ab 100644 --- a/tools/metrics/histograms/metadata/others/histograms.xml +++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -2650,13 +2650,15 @@ </histogram> <histogram name="ChildProcess.Crashed.UtilityProcessHash" - enum="UtilityProcessNameHash" expires_after="2022-06-12"> + enum="UtilityProcessNameHash" expires_after="never"> +<!-- expires-never: Critical stability metrics. go/chrome-stability-metrics --> + <owner>wfh@chromium.org</owner> <owner>chrome-stability-core@google.com</owner> <summary> Count of child utility process crashes, bucketed by the hash of their process name. The process name is typically the service name of the mojo - service. + service. Recorded when a Utility process crashes. </summary> </histogram> @@ -2763,6 +2765,44 @@ </summary> </histogram> +<histogram name="ChildProcess.LaunchFailed.UtilityProcessErrorCode" + enum="LaunchErrorCodes" expires_after="never"> +<!-- expires-never: Critical stability metrics. go/chrome-stability-metrics --> + + <owner>wfh@chromium.org</owner> + <owner>chrome-stability-core@google.com</owner> + <summary> + A platform-specific error code returned from the attempt to launch a Utility + process. Recorded when a Utility process fails to launch. + </summary> +</histogram> + +<histogram name="ChildProcess.LaunchFailed.UtilityProcessHash" + enum="UtilityProcessNameHash" expires_after="never"> +<!-- expires-never: Critical stability metrics. go/chrome-stability-metrics --> + + <owner>wfh@chromium.org</owner> + <owner>chrome-stability-core@google.com</owner> + <summary> + Count of child utility process launch failures, bucketed by the hash of + their process name. The process name is typically the service name of the + mojo service. Recorded when a Utility process fails to launch. + </summary> +</histogram> + +<histogram name="ChildProcess.LaunchFailed.WinLastError" enum="WinGetLastError" + expires_after="never"> +<!-- expires-never: Critical stability metrics. go/chrome-stability-metrics --> + + <owner>wfh@chromium.org</owner> + <owner>chrome-stability-core@google.com</owner> + <summary> + An extended Windows error code returned from GetLastError when failing to + launch a utility process. Recorded when a Utility process fails to launch on + Windows. + </summary> +</histogram> + <histogram name="ChromiumAndroidLinker.BrowserLoadTime" units="ms" expires_after="2022-10-01"> <obsolete>
diff --git a/tools/metrics/histograms/metadata/password/histograms.xml b/tools/metrics/histograms/metadata/password/histograms.xml index ead501ec..66719062 100644 --- a/tools/metrics/histograms/metadata/password/histograms.xml +++ b/tools/metrics/histograms/metadata/password/histograms.xml
@@ -1473,9 +1473,9 @@ </histogram> <histogram name="PasswordManager.FormSubmission.PerProfileType" - enum="BrowserProfileType" expires_after="2022-02-02"> - <owner>rhalavati@chromium.org</owner> - <owner>chrome-privacy-core@google.com</owner> + enum="BrowserProfileType" expires_after="2022-08-02"> + <owner>sideyilmaz@chromium.org</owner> + <owner>chrome-incognito@google.com</owner> <summary> This histogram records the browser profile type when a password form is submitted. @@ -2393,6 +2393,40 @@ </token> </histogram> +<histogram + name="PasswordManager.PasswordStoreProxyBackend.{ModifyingFunction}.{Metric}.{Measurement}" + units="count" expires_after="2022-06-30"> + <owner>fhorschig@chromium.org</owner> + <owner>vasilii@chromium.org</owner> + <summary> + Records the number of password store changes {Metric}{Measurement} Recorded + when the asynchronous job for {ModifyingFunction} has returned. Recorded + only for non-syncing users and only after initial migration is finished. + </summary> + <token key="ModifyingFunction"> + <variant name="AddLoginAsync" summary="AddLoginAsync()"/> + </token> + <token key="Metric"> + <variant name="Diff" + summary="in either the main or the shadow backend but not in both of + them"/> + <variant name="InconsistentPasswords" + summary="that occur in both the main and the shadow backend but + differ in their stored passwords"/> + <variant name="MainMinusShadow" + summary="in the main backend that are not in the shadow backend"/> + <variant name="ShadowMinusMain" + summary="in the shadow backend that are not the main backend"/> + </token> + <token key="Measurement"> + <variant name="Abs" summary="."/> + <variant name="Rel" + summary=", divided by the total number of password store changes, as + a percentage rounded up to the next integer. If the + denominator is zero, no value is emitted."/> + </token> +</histogram> + <histogram name="PasswordManager.PasswordSyncState" enum="PasswordSyncState" expires_after="2022-06-12"> <owner>kazinova@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/power/histograms.xml b/tools/metrics/histograms/metadata/power/histograms.xml index 93e2cd1..f23fa904 100644 --- a/tools/metrics/histograms/metadata/power/histograms.xml +++ b/tools/metrics/histograms/metadata/power/histograms.xml
@@ -972,6 +972,15 @@ </summary> </histogram> +<histogram name="Power.IOPMPowerSource.SamplingEventDelta" units="ms" + expires_after="2022-03-01"> + <owner>pmonette@chromium.org</owner> + <owner>catan-team@chromium.org</owner> + <summary> + Records the time between each IOPMPowerSource event. Only recorded on MacOS. + </summary> +</histogram> + <histogram name="Power.KernelResumeTimeOnAC" units="ms" expires_after="2021-10-17"> <owner>puthik@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/profile/histograms.xml b/tools/metrics/histograms/metadata/profile/histograms.xml index abc8aeb..28f4398 100644 --- a/tools/metrics/histograms/metadata/profile/histograms.xml +++ b/tools/metrics/histograms/metadata/profile/histograms.xml
@@ -359,6 +359,9 @@ Recorded during BrowserProcess teardown. Indicates that a Profile still has ScopedProfileKeepAlive objects referencing it, of the given origin. This is a sign of a bug, or incorrect usage of the ScopedProfileKeepAlive API. + + Only regular Profiles are considered for this metric (no Incognito, Guest, + or System Profiles). </summary> </histogram> @@ -369,7 +372,8 @@ <summary> Number of Profiles that are currently loaded in memory, with a non-zero refcount. Recorded 30 minutes after startup, and every 30 minutes - afterwards. + afterwards. Only regular Profiles are considered for this metric (no + Incognito, Guest, or System Profiles). See also Profile.ZombieProfileCount, the number of Profiles with a refcount of 0. @@ -835,9 +839,10 @@ <owner>cbe-eng@google.com</owner> <summary> Number of Profiles that are in a "zombie" state. Recorded 30 - minutes after startup, and every 30 minutes afterwards. A "zombie" - profile is one of 2 things, depending on the DestroyProfileOnBrowserClose - (DPoBC) variation: + minutes after startup, and every 30 minutes afterwards. Only regular + Profiles are considered for this metric (no Incognito, Guest, or System + Profiles). A "zombie" profile is one of 2 things, depending on the + DestroyProfileOnBrowserClose (DPoBC) variation: If DPoBC is false: the Profile has a refcount of 0, but is still loaded in memory.
diff --git a/tools/metrics/histograms/metadata/settings/histograms.xml b/tools/metrics/histograms/metadata/settings/histograms.xml index 08a6ee7e..f7a7f1ef 100644 --- a/tools/metrics/histograms/metadata/settings/histograms.xml +++ b/tools/metrics/histograms/metadata/settings/histograms.xml
@@ -166,7 +166,7 @@ </histogram> <histogram name="Settings.OpenSettingsFromMenu.PerProfileType" - enum="BrowserProfileType" expires_after="2021-12-31"> + enum="BrowserProfileType" expires_after="2022-08-02"> <owner>sideyilmaz@chromium.org</owner> <owner>chrome-incognito@google.com</owner> <summary>
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml index 556bc46..5a646828 100644 --- a/tools/traffic_annotation/summary/annotations.xml +++ b/tools/traffic_annotation/summary/annotations.xml
@@ -316,7 +316,6 @@ <item id="app_suggestion_get_favicon" added_in_milestone="98" content_hash_code="07fca800" os_list="chromeos" file_path="chrome/browser/ui/app_list/search/app_service_app_result.cc" /> <item id="url_icon_source_fetch" added_in_milestone="98" content_hash_code="0297f30b" os_list="chromeos" file_path="chrome/browser/ui/app_list/search/common/url_icon_source.cc" /> <item id="launcher_item_suggest" added_in_milestone="98" content_hash_code="04a4041e" os_list="chromeos" file_path="chrome/browser/ui/app_list/search/files/item_suggest_cache.cc" /> - <item id="cros_launcher_omnibox" added_in_milestone="98" content_hash_code="04c3a59e" os_list="chromeos" file_path="chrome/browser/ui/app_list/search/omnibox_result.cc" /> <item id="ambient_client" added_in_milestone="98" content_hash_code="062d821f" os_list="chromeos" file_path="chrome/browser/ui/ash/ambient/ambient_client_impl.cc" /> <item id="calendar_get_events" added_in_milestone="98" content_hash_code="0108842a" os_list="chromeos" file_path="chrome/browser/ui/ash/calendar/calendar_keyed_service.cc" /> <item id="side_search_availability_test" added_in_milestone="98" content_hash_code="04410970" os_list="chromeos" file_path="chrome/browser/ui/side_search/side_search_tab_contents_helper.cc" />
diff --git a/tools/traffic_annotation/summary/grouping.xml b/tools/traffic_annotation/summary/grouping.xml index f5a07e5b..308838f 100644 --- a/tools/traffic_annotation/summary/grouping.xml +++ b/tools/traffic_annotation/summary/grouping.xml
@@ -60,7 +60,6 @@ <traffic_annotation unique_id="calendar_get_events"/> <traffic_annotation unique_id="chrome_plugin_vm_api"/> <traffic_annotation unique_id="chromebook_mail_api"/> - <traffic_annotation unique_id="cros_launcher_omnibox"/> <traffic_annotation unique_id="customization_wallpaper_downloader"/> <traffic_annotation unique_id="edu_account_login_profile_image_fetcher"/> <traffic_annotation unique_id="fast_pair_footprints_request"/>
diff --git a/ui/android/java/res/values-night/colors.xml b/ui/android/java/res/values-night/colors.xml index 40c73952..835cb50 100644 --- a/ui/android/java/res/values-night/colors.xml +++ b/ui/android/java/res/values-night/colors.xml
@@ -102,5 +102,6 @@ <color name="menu_chip_background_color_disabled">@color/menu_chip_background_color_disabled_light</color> <color name="iph_highlight_blue">@color/iph_highlight_blue_light</color> <color name="rating_star_yellow">@color/rating_star_yellow_light</color> - <color name="price_drop_annotation_bg_color">@color/google_green_800</color> + <color name="price_drop_annotation_bg_color">@color/price_drop_annotation_bg_color_dark</color> + <color name="price_drop_annotation_text_green">@color/price_drop_annotation_text_green_dark</color> </resources>
diff --git a/ui/android/java/res/values-v17/styles.xml b/ui/android/java/res/values-v17/styles.xml index 51df0a0..46440fa 100644 --- a/ui/android/java/res/values-v17/styles.xml +++ b/ui/android/java/res/values-v17/styles.xml
@@ -343,11 +343,6 @@ <item name="android:textColor">@color/chip_text_color_secondary</item> </style> - <!-- Toast UI --> - <style name="TextAppearance.Toast" parent="TextAppearance.TextSmall"> - <item name="android:textColor">@color/default_text_color_light</item> - </style> - <!-- Dividers --> <style name="HorizontalDivider" tools:ignore="UnusedResources">
diff --git a/ui/android/java/res/values/color_palette.xml b/ui/android/java/res/values/color_palette.xml index b1093a60..5e21334 100644 --- a/ui/android/java/res/values/color_palette.xml +++ b/ui/android/java/res/values/color_palette.xml
@@ -69,10 +69,10 @@ <color name="baseline_secondary_300_with_neutral_100_alpha_8">#53A7E1</color> <color name="baseline_secondary_300_with_neutral_100_alpha_24">#448FC4</color> <color name="baseline_secondary_900">#001D35</color> - <color name="baseline_tertiary_50">#E7F8ED</color> + <color name="baseline_tertiary_100">#C4EED0</color> <color name="baseline_tertiary_200">#6DD58C</color> <color name="baseline_tertiary_600">#146C2E</color> - <color name="baseline_tertiary_800">#0A3818</color> + <color name="baseline_tertiary_700">#0F5223</color> <!-- Remapped to 2021 color palette. Do not add new references to these. --> <color name="modern_white">@color/baseline_neutral_0</color> @@ -88,10 +88,8 @@ <color name="modern_blue_700">@color/baseline_primary_700</color> <color name="modern_blue_800" tools:ignore="UnusedResources">@color/baseline_primary_800</color> - <color name="google_green_50">@color/baseline_tertiary_50</color> <color name="google_green_300">@color/baseline_tertiary_200</color> <color name="google_green_600">@color/baseline_tertiary_600</color> - <color name="google_green_800">@color/baseline_tertiary_800</color> <color name="modern_grey_50" tools:ignore="UnusedResources">@color/baseline_neutral_50</color> <color name="modern_grey_100">@color/baseline_neutral_100</color> <color name="modern_grey_100_alpha_38">@color/baseline_neutral_100_alpha_38</color>
diff --git a/ui/android/java/res/values/semantic_colors_adaptive.xml b/ui/android/java/res/values/semantic_colors_adaptive.xml index 32abfcb..91864bd 100644 --- a/ui/android/java/res/values/semantic_colors_adaptive.xml +++ b/ui/android/java/res/values/semantic_colors_adaptive.xml
@@ -134,5 +134,6 @@ <color name="menu_chip_background_color_disabled">@color/menu_chip_background_color_disabled_dark</color> <color name="iph_highlight_blue">@color/iph_highlight_blue_dark</color> <color name="rating_star_yellow">@color/rating_star_yellow_dark</color> - <color name="price_drop_annotation_bg_color">@color/google_green_50</color> + <color name="price_drop_annotation_bg_color">@color/price_drop_annotation_bg_color_light</color> + <color name="price_drop_annotation_text_green">@color/price_drop_annotation_text_green_light</color> </resources>
diff --git a/ui/android/java/res/values/semantic_colors_non_adaptive.xml b/ui/android/java/res/values/semantic_colors_non_adaptive.xml index bd216f2..efda394d 100644 --- a/ui/android/java/res/values/semantic_colors_non_adaptive.xml +++ b/ui/android/java/res/values/semantic_colors_non_adaptive.xml
@@ -189,4 +189,10 @@ <!-- Toast colors --> <color name="toast_bg_color">@color/baseline_neutral_900_with_neutral_200_alpha_11_with_primary_200_alpha_2</color> + + <!-- Price-tracking colors --> + <color name="price_drop_annotation_bg_color_light">@color/baseline_tertiary_100</color> + <color name="price_drop_annotation_bg_color_dark">@color/baseline_tertiary_700</color> + <color name="price_drop_annotation_text_green_light">@color/baseline_tertiary_600</color> + <color name="price_drop_annotation_text_green_dark">@color/baseline_tertiary_200</color> </resources>
diff --git a/ui/aura/window_event_dispatcher.cc b/ui/aura/window_event_dispatcher.cc index 8e7624e..52c3578 100644 --- a/ui/aura/window_event_dispatcher.cc +++ b/ui/aura/window_event_dispatcher.cc
@@ -516,11 +516,6 @@ Window* target_window = static_cast<Window*>(target); CHECK(window()->Contains(target_window)); - if (!(event->flags() & ui::EF_IS_SYNTHESIZED)) { - fraction_of_time_without_user_input_recorder_.RecordEventAtTime( - event->time_stamp()); - } - WindowTracker target_window_tracker; target_window_tracker.Add(target_window); if (!dispatching_held_event_) {
diff --git a/ui/aura/window_event_dispatcher.h b/ui/aura/window_event_dispatcher.h index e64765a3..1c3b3676 100644 --- a/ui/aura/window_event_dispatcher.h +++ b/ui/aura/window_event_dispatcher.h
@@ -25,7 +25,6 @@ #include "ui/events/event_constants.h" #include "ui/events/event_processor.h" #include "ui/events/event_targeter.h" -#include "ui/events/fraction_of_time_without_user_input_recorder.h" #include "ui/events/gestures/gesture_recognizer.h" #include "ui/events/gestures/gesture_types.h" #include "ui/events/types/event_type.h" @@ -299,9 +298,6 @@ raw_ptr<Window> event_dispatch_target_ = nullptr; raw_ptr<Window> old_dispatch_target_ = nullptr; - ui::FractionOfTimeWithoutUserInputRecorder - fraction_of_time_without_user_input_recorder_; - bool synthesize_mouse_move_ = false; // Whether a OnWindowTargetTransformChanging() call didn't have its
diff --git a/ui/aura/window_event_dispatcher_unittest.cc b/ui/aura/window_event_dispatcher_unittest.cc index 336344c9..6fd75c2 100644 --- a/ui/aura/window_event_dispatcher_unittest.cc +++ b/ui/aura/window_event_dispatcher_unittest.cc
@@ -3106,37 +3106,6 @@ w->RemovePreTargetHandler(&recorder); } -// Tests that we correctly report the fraction of time without user input via -// UMA. -TEST_F(WindowEventDispatcherTest, FractionOfTimeWithoutUserInputRecorded) { - const char* kHistogram = "Event.FractionOfTimeWithoutUserInput"; - base::HistogramTester tester; - - std::unique_ptr<aura::Window> window( - test::CreateTestWindowWithId(1234, root_window())); - - ui::MouseEvent mouse1(ui::ET_MOUSE_MOVED, gfx::Point(10, 10), - gfx::Point(10, 10), ui::EventTimeStampFromSeconds(4), 0, - 0); - - // To flush the idle fraction reporter, we need to dispatch two events. The - // first event causes us to record the previous active period, and the second - // flushes the previous active period. - ui::MouseEvent mouse2(ui::ET_MOUSE_MOVED, gfx::Point(10, 10), - gfx::Point(10, 10), ui::EventTimeStampFromSeconds(16), - 0, 0); - - ui::MouseEvent mouse3(ui::ET_MOUSE_MOVED, gfx::Point(10, 10), - gfx::Point(10, 10), ui::EventTimeStampFromSeconds(30), - 0, 0); - - DispatchEventUsingWindowDispatcher(&mouse1); - DispatchEventUsingWindowDispatcher(&mouse2); - DispatchEventUsingWindowDispatcher(&mouse3); - - tester.ExpectTotalCount(kHistogram, 1); -} - TEST_F(WindowEventDispatcherTest, TouchEventWithScaledWindow) { WindowEventDispatcher* dispatcher = host()->dispatcher();
diff --git a/ui/events/BUILD.gn b/ui/events/BUILD.gn index c571db8..bdc40a6b 100644 --- a/ui/events/BUILD.gn +++ b/ui/events/BUILD.gn
@@ -101,8 +101,6 @@ "event_switches.cc", "event_switches.h", "events_base_export.h", - "fraction_of_time_without_user_input_recorder.cc", - "fraction_of_time_without_user_input_recorder.h", "gesture_curve.h", "gesture_event_details.cc", "gesture_event_details.h", @@ -621,7 +619,6 @@ "event_rewriter_unittest.cc", "event_target_unittest.cc", "event_unittest.cc", - "fraction_of_time_without_user_input_recorder_unittest.cc", "gesture_detection/bitset_32_unittest.cc", "gesture_detection/filtered_gesture_provider_unittest.cc", "gesture_detection/gesture_event_data_packet_unittest.cc",
diff --git a/ui/events/fraction_of_time_without_user_input_recorder.cc b/ui/events/fraction_of_time_without_user_input_recorder.cc deleted file mode 100644 index 8733301d..0000000 --- a/ui/events/fraction_of_time_without_user_input_recorder.cc +++ /dev/null
@@ -1,77 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/events/fraction_of_time_without_user_input_recorder.h" - -#include <algorithm> - -#include "base/metrics/histogram_macros.h" - -namespace { - -constexpr base::TimeDelta DEFAULT_WINDOW_SIZE = base::Seconds(10); -constexpr base::TimeDelta DEFAULT_IDLE_TIMEOUT = base::Seconds(0.05); - -} // namespace - -namespace ui { - -FractionOfTimeWithoutUserInputRecorder::FractionOfTimeWithoutUserInputRecorder() - : window_size_(DEFAULT_WINDOW_SIZE), idle_timeout_(DEFAULT_IDLE_TIMEOUT) {} - -void FractionOfTimeWithoutUserInputRecorder::RecordEventAtTime( - base::TimeTicks start_time) { - base::TimeTicks event_end_time = start_time + idle_timeout_; - - if (active_duration_start_time_.is_null()) - active_duration_start_time_ = start_time; - if (previous_event_end_time_.is_null()) - previous_event_end_time_ = start_time; - - // The user is no longer interacting with the browser. Report the previous - // active duration. - if (previous_event_end_time_ < start_time) { - RecordActiveInterval(active_duration_start_time_, previous_event_end_time_); - active_duration_start_time_ = start_time; - } - - previous_event_end_time_ = event_end_time; -} - -void FractionOfTimeWithoutUserInputRecorder::RecordActiveInterval( - base::TimeTicks start_time, - base::TimeTicks end_time) { - if (window_start_time_.is_null()) - window_start_time_ = start_time; - - base::TimeTicks window_end_time; - - while (true) { - window_end_time = window_start_time_ + window_size_; - base::TimeDelta interval_in_window_duration = - std::min(end_time, window_end_time) - - std::max(start_time, window_start_time_); - interval_in_window_duration = - std::max(interval_in_window_duration, base::TimeDelta()); - - current_window_active_time_ += interval_in_window_duration; - - // If we haven't exceeded the window bounds, we're done. - if (end_time < window_end_time) - break; - - RecordToUma(current_window_active_time_ / window_size_); - - current_window_active_time_ = base::TimeDelta(); - window_start_time_ = window_end_time; - } -} - -void FractionOfTimeWithoutUserInputRecorder::RecordToUma( - float fraction_active) const { - UMA_HISTOGRAM_PERCENTAGE("Event.FractionOfTimeWithoutUserInput", - std::round((1 - fraction_active) * 100)); -} - -} // namespace ui
diff --git a/ui/events/fraction_of_time_without_user_input_recorder.h b/ui/events/fraction_of_time_without_user_input_recorder.h deleted file mode 100644 index 82b7688..0000000 --- a/ui/events/fraction_of_time_without_user_input_recorder.h +++ /dev/null
@@ -1,51 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_EVENTS_FRACTION_OF_TIME_WITHOUT_USER_INPUT_RECORDER_H_ -#define UI_EVENTS_FRACTION_OF_TIME_WITHOUT_USER_INPUT_RECORDER_H_ - -#include "base/time/time.h" -#include "ui/events/events_base_export.h" - -namespace ui { - -// Receives as input a set of timestamps indicating when events were -// received. Reports via UMA the fraction of the time per |window_size_| that -// the user was interacting. -class EVENTS_BASE_EXPORT FractionOfTimeWithoutUserInputRecorder { - public: - FractionOfTimeWithoutUserInputRecorder(); - void RecordEventAtTime(base::TimeTicks start_time); - - protected: - virtual void RecordActiveInterval(base::TimeTicks start_time, - base::TimeTicks end_time); - void RecordToUma(float idle_fraction) const; - void set_window_size(base::TimeDelta window_size) { - window_size_ = window_size; - } - void set_idle_timeout(base::TimeDelta idle_timeout) { - idle_timeout_ = idle_timeout; - } - - private: - // Within the current period of length |window_size_|, how long has the user - // been active? - base::TimeDelta current_window_active_time_; - // If the user is currently active, when did they start being active? - base::TimeTicks active_duration_start_time_; - base::TimeTicks window_start_time_; - base::TimeTicks previous_event_end_time_; - - // We report the fraction of the time we were idle once per |window_size_|. - base::TimeDelta window_size_; - - // Two events within |idle_timeout_| of one another are considered to be in - // the same period of user activity. - base::TimeDelta idle_timeout_; -}; - -} // namespace ui - -#endif // UI_EVENTS_FRACTION_OF_TIME_WITHOUT_USER_INPUT_RECORDER_H_
diff --git a/ui/events/fraction_of_time_without_user_input_recorder_unittest.cc b/ui/events/fraction_of_time_without_user_input_recorder_unittest.cc deleted file mode 100644 index fb4efbc..0000000 --- a/ui/events/fraction_of_time_without_user_input_recorder_unittest.cc +++ /dev/null
@@ -1,171 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/events/fraction_of_time_without_user_input_recorder.h" - -#include "base/test/metrics/histogram_tester.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/events/base_event_utils.h" - -namespace ui { - -namespace { - -using base::Bucket; -using testing::ElementsAre; -using testing::Pair; - -const char* kHistogram = "Event.FractionOfTimeWithoutUserInput"; - -class TestFractionOfTimeWithoutUserInputRecorder - : public FractionOfTimeWithoutUserInputRecorder { - public: - void RecordActiveInterval(base::TimeTicks start_time, - base::TimeTicks end_time) override { - active_intervals_.push_back(std::make_pair(start_time, end_time)); - FractionOfTimeWithoutUserInputRecorder::RecordActiveInterval(start_time, - end_time); - } - - void set_window_size_for_test(base::TimeDelta window_size) { - set_window_size(window_size); - } - - void set_idle_timeout_for_test(base::TimeDelta idle_timeout) { - set_idle_timeout(idle_timeout); - } - - const std::vector<std::pair<base::TimeTicks, base::TimeTicks>>& - active_intervals() { - return active_intervals_; - } - - private: - std::vector<std::pair<base::TimeTicks, base::TimeTicks>> active_intervals_; -}; - -TEST(FractionOfTimeWithoutUserInputRecorderTest, IntervalIncludesIdleTimeout) { - TestFractionOfTimeWithoutUserInputRecorder idle_fraction_recorder; - idle_fraction_recorder.set_idle_timeout_for_test(base::Seconds(0.1)); - - idle_fraction_recorder.RecordEventAtTime(EventTimeStampFromSeconds(0.5)); - - // Flush the previous event. - idle_fraction_recorder.RecordEventAtTime(EventTimeStampFromSeconds(100)); - - // We observed a single event, so the we consider it to have lasted a duration - // of one idle timeout. - EXPECT_THAT(idle_fraction_recorder.active_intervals(), - ElementsAre(Pair(EventTimeStampFromSeconds(0.5), - EventTimeStampFromSeconds(0.6)))); -} - -TEST(FractionOfTimeWithoutUserInputRecorderTest, TwoLongIntervals) { - TestFractionOfTimeWithoutUserInputRecorder idle_fraction_recorder; - idle_fraction_recorder.set_idle_timeout_for_test(base::Seconds(0.1)); - - // Send events regularly between 0.1 seconds and 0.1 + 20 * 0.05 = 1.10 - // seconds. - base::TimeTicks time = base::TimeTicks() + base::Seconds(0.1); - idle_fraction_recorder.RecordEventAtTime(time); - - for (int i = 0; i < 20; ++i) { - time += base::Seconds(0.05); - idle_fraction_recorder.RecordEventAtTime(time); - } - - // Send events regularly between 2.2 seconds and 2.2 + 20 * 0.05 = 3.20 - // seconds. - time = base::TimeTicks() + base::Seconds(2.2); - idle_fraction_recorder.RecordEventAtTime(time); - - for (int i = 0; i < 20; ++i) { - time += base::Seconds(0.05); - idle_fraction_recorder.RecordEventAtTime(time); - } - - // Flush the previous event. - idle_fraction_recorder.RecordEventAtTime(EventTimeStampFromSeconds(100)); - - // Interval end times include idle timeout. - EXPECT_THAT(idle_fraction_recorder.active_intervals(), - ElementsAre(Pair(EventTimeStampFromSeconds(0.1), - EventTimeStampFromSeconds(1.2)), - Pair(EventTimeStampFromSeconds(2.2), - EventTimeStampFromSeconds(3.3)))); -} - -TEST(FractionOfTimeWithoutUserInputRecorderTest, SingleShortRange) { - TestFractionOfTimeWithoutUserInputRecorder idle_fraction_recorder; - idle_fraction_recorder.set_window_size_for_test(base::Seconds(1)); - - base::HistogramTester tester; - // Start window at 1 second. - idle_fraction_recorder.RecordActiveInterval(EventTimeStampFromSeconds(1), - EventTimeStampFromSeconds(1)); - - idle_fraction_recorder.RecordActiveInterval(EventTimeStampFromSeconds(1.1), - EventTimeStampFromSeconds(1.6)); - - // Flush the previous interval. - idle_fraction_recorder.RecordActiveInterval(EventTimeStampFromSeconds(2), - EventTimeStampFromSeconds(2)); - - EXPECT_THAT(tester.GetAllSamples(kHistogram), ElementsAre(Bucket(50, 1))); -} - -TEST(FractionOfTimeWithoutUserInputRecorderTest, SingleLongRange) { - TestFractionOfTimeWithoutUserInputRecorder idle_fraction_recorder; - idle_fraction_recorder.set_window_size_for_test(base::Seconds(1)); - - base::HistogramTester tester; - - // Start window at 1 second. - idle_fraction_recorder.RecordActiveInterval(EventTimeStampFromSeconds(1), - EventTimeStampFromSeconds(1)); - - idle_fraction_recorder.RecordActiveInterval(EventTimeStampFromSeconds(1.1), - EventTimeStampFromSeconds(4.2)); - - // Flush the previous interval. - idle_fraction_recorder.RecordActiveInterval(EventTimeStampFromSeconds(5), - EventTimeStampFromSeconds(5)); - - // The windows contain: [1.1, 2], [2, 3], [3, 4], [4, 4.2]. - EXPECT_THAT(tester.GetAllSamples(kHistogram), - ElementsAre(Bucket(0, 2), Bucket(10, 1), Bucket(80, 1))); -} - -TEST(FractionOfTimeWithoutUserInputRecorderTest, TwoLongRanges) { - TestFractionOfTimeWithoutUserInputRecorder idle_fraction_recorder; - idle_fraction_recorder.set_window_size_for_test(base::Seconds(1)); - - base::HistogramTester tester; - - // Start window at 1 second. - idle_fraction_recorder.RecordActiveInterval(EventTimeStampFromSeconds(1), - EventTimeStampFromSeconds(1)); - - idle_fraction_recorder.RecordActiveInterval(EventTimeStampFromSeconds(1.1), - EventTimeStampFromSeconds(2.2)); - - idle_fraction_recorder.RecordActiveInterval(EventTimeStampFromSeconds(2.6), - EventTimeStampFromSeconds(3.2)); - - // Flush the previous interval. - idle_fraction_recorder.RecordActiveInterval(EventTimeStampFromSeconds(4), - EventTimeStampFromSeconds(4)); - - // The windows contain: - // 1: 1.1 - 2.0 - // 2: 2.0 - 2.2, 2.6 - 3.0 - // 3: 3.0 - 3.2 - EXPECT_THAT(tester.GetAllSamples(kHistogram), - ElementsAre(Bucket(10, 1), Bucket(40, 1), Bucket(80, 1))); -} - -} // namespace - -} // namespace ui
diff --git a/ui/gfx/geometry/transform.cc b/ui/gfx/geometry/transform.cc index eee5af7..ef9e268 100644 --- a/ui/gfx/geometry/transform.cc +++ b/ui/gfx/geometry/transform.cc
@@ -485,8 +485,23 @@ } bool Transform::TransformRRectF(RRectF* rrect) const { + // We want this to fail only in cases where our + // Transform::Preserves2dAxisAlignment returns false. However, + // SkMatrix::preservesAxisAlignment is stricter (it lacks the kEpsilon + // test). So after converting our skia::Matrix44 to SkMatrix, round + // relevant values less than kEpsilon to zero. + SkMatrix rounded_matrix(matrix_); + if (std::abs(rounded_matrix.get(SkMatrix::kMScaleX)) < kEpsilon) + rounded_matrix.set(SkMatrix::kMScaleX, 0.0f); + if (std::abs(rounded_matrix.get(SkMatrix::kMSkewX)) < kEpsilon) + rounded_matrix.set(SkMatrix::kMSkewX, 0.0f); + if (std::abs(rounded_matrix.get(SkMatrix::kMSkewY)) < kEpsilon) + rounded_matrix.set(SkMatrix::kMSkewY, 0.0f); + if (std::abs(rounded_matrix.get(SkMatrix::kMScaleY)) < kEpsilon) + rounded_matrix.set(SkMatrix::kMScaleY, 0.0f); + SkRRect result; - if (!SkRRect(*rrect).transform(SkMatrix(matrix_), &result)) + if (!SkRRect(*rrect).transform(rounded_matrix, &result)) return false; *rrect = gfx::RRectF(result); return true;
diff --git a/ui/gfx/geometry/transform_unittest.cc b/ui/gfx/geometry/transform_unittest.cc index 127c203..fb57d8a 100644 --- a/ui/gfx/geometry/transform_unittest.cc +++ b/ui/gfx/geometry/transform_unittest.cc
@@ -2645,6 +2645,14 @@ EXPECT_TRUE(rotation_90_Clock.TransformRRectF(&rrect)); EXPECT_EQ(expected.ToString(), rrect.ToString()); + Transform rotation_90_unrounded; + rotation_90_unrounded.Rotate(90.0); + rrect = RRectF(gfx::RectF(0, 0, 20.f, 25.f), + gfx::RoundedCornersF(1.f, 2.f, 3.f, 4.f)); + EXPECT_TRUE(rotation_90_unrounded.Preserves2dAxisAlignment()); + EXPECT_TRUE(rotation_90_unrounded.TransformRRectF(&rrect)); + EXPECT_EQ(expected.ToString(), rrect.ToString()); + Transform scale; scale.Scale(2.f, 2.f); rrect = RRectF(gfx::RectF(0, 0, 20.f, 25.f),
diff --git a/ui/gtk/gtk_ui.cc b/ui/gtk/gtk_ui.cc index 62b05ec..c8eb5c7 100644 --- a/ui/gtk/gtk_ui.cc +++ b/ui/gtk/gtk_ui.cc
@@ -933,11 +933,7 @@ colors_[ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON] = tab_text_color; colors_[ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON_HOVERED] = tab_text_color; colors_[ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON_PRESSED] = tab_text_color; - colors_[ThemeProperties::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_ACTIVE] = - tab_text_color; - colors_[ThemeProperties::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_INACTIVE] = - tab_text_color; - colors_[ThemeProperties::COLOR_BOOKMARK_TEXT] = tab_text_color; + colors_[ThemeProperties::COLOR_TOOLBAR_TEXT] = tab_text_color; colors_[ThemeProperties::COLOR_NTP_LINK] = color_provider->GetColor(ui::kColorTextfieldSelectionBackground);
diff --git a/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc b/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc index 13b89bda..b94fff1 100644 --- a/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc +++ b/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc
@@ -54,6 +54,10 @@ constexpr uint32_t kDndActionWindowDrag = WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE; +// Value intentionally high to exit the horizontal rail threshold in +// SnapScrollController, in case of an upwards tab dragging detach with touch. +constexpr int kHorizontalRailExitThreshold = -1000; + } // namespace class WaylandWindowDragController::ExtendedDragSource { @@ -292,8 +296,28 @@ // ideally be reworked in the future, at higher level layers such that they // properly handle platforms that do not support global screen coordinates, // like Wayland. - if (state_ == State::kAttached) + // + // TODO(https://crbug.com/1282186): Find a better solution for upwards tab + // detaching. + if (state_ != State::kAttached) + return; + + if (*drag_source_ == DragSource::kMouse) { pointer_delegate_->OnPointerMotionEvent({pointer_location_.x(), -1}); + } else { + base::TimeTicks timestamp = base::TimeTicks::Now(); + auto touch_pointer_ids = touch_delegate_->GetActiveTouchPointIds(); + DCHECK_EQ(touch_pointer_ids.size(), 1u); + + // If an user starts dragging a tab horizontally with touch, Chrome enters + // in "horizontal snapping" mode (see ScrollSnapController for details). + // Hence, in case of touch driven dragging, use a higher negative dy + // to work around the threshold in ScrollSnapController otherwise, + // the drag event is discarded. + touch_delegate_->OnTouchMotionEvent( + {pointer_location_.x(), kHorizontalRailExitThreshold}, timestamp, + touch_pointer_ids[0]); + } } void WaylandWindowDragController::OnDragDrop() {
diff --git a/ui/ozone/platform/wayland/host/wayland_window_drag_controller_unittest.cc b/ui/ozone/platform/wayland/host/wayland_window_drag_controller_unittest.cc index 0663a84..ecd049c 100644 --- a/ui/ozone/platform/wayland/host/wayland_window_drag_controller_unittest.cc +++ b/ui/ozone/platform/wayland/host/wayland_window_drag_controller_unittest.cc
@@ -751,6 +751,48 @@ screen_->GetLocalProcessWidgetAtPoint({20, 20}, {})); } +// Verifies wl_data_device::leave events are properly handled and propagated +// while in window dragging "attached" mode. +TEST_P(WaylandWindowDragControllerTest, DragExitAttached_TOUCH) { + // Ensure there is no window currently focused + EXPECT_FALSE(window_manager()->GetCurrentPointerOrTouchFocusedWindow()); + EXPECT_EQ(gfx::kNullAcceleratedWidget, + screen_->GetLocalProcessWidgetAtPoint({10, 10}, {})); + + // SendPointerEnter(window_.get(), &delegate_); + // SendPointerPress(window_.get(), &delegate_, BTN_LEFT); + // SendPointerMotion(window_.get(), &delegate_, {10, 10}); + SendTouchDown(window_.get(), &delegate_, 0 /*point id*/, {0, 0} /*location*/); + SendTouchMotion(window_.get(), &delegate_, 0 /*point id*/, + {10, 10} /*location*/); + Sync(); + EXPECT_EQ(window_->GetWidget(), + screen_->GetLocalProcessWidgetAtPoint({10, 10}, {})); + + auto* wayland_extension = GetWaylandExtension(*window_); + wayland_extension->StartWindowDraggingSessionIfNeeded(); + Sync(); + EXPECT_EQ(State::kAttached, drag_controller()->state()); + + // Emulate a [motion => leave] event sequence and make sure the correct + // ui::Events are dispatched in response. + SendDndMotion({50, 50}); + EXPECT_CALL(delegate_, DispatchEvent(_)).Times(1); + Sync(); + + SendDndLeave(); + EXPECT_CALL(delegate_, DispatchEvent(_)).WillOnce([&](Event* event) { + EXPECT_EQ(ET_TOUCH_MOVED, event->type()); + EXPECT_EQ(gfx::Point(50, -1000).ToString(), + event->AsTouchEvent()->location().ToString()); + }); + Sync(); + + SendDndDrop(); + EXPECT_CALL(delegate_, DispatchEvent(_)).Times(1); + Sync(); +} + TEST_P(WaylandWindowDragControllerTest, RestoreDuringWindowDragSession) { const gfx::Rect original_bounds = window_->GetBounds(); wl::ScopedWlArray states({XDG_TOPLEVEL_STATE_ACTIVATED});
diff --git a/ui/ozone/platform/wayland/test/scoped_wl_array.cc b/ui/ozone/platform/wayland/test/scoped_wl_array.cc index 9977ca1..64aea2c 100644 --- a/ui/ozone/platform/wayland/test/scoped_wl_array.cc +++ b/ui/ozone/platform/wayland/test/scoped_wl_array.cc
@@ -35,7 +35,7 @@ } void ScopedWlArray::AddStateToWlArray(uint32_t state) { - *static_cast<uint32_t*>(wl_array_add(&array_, sizeof array_)) = state; + *static_cast<uint32_t*>(wl_array_add(&array_, sizeof(uint32_t))) = state; } } // namespace wl
diff --git a/ui/views/controls/combobox/combobox.cc b/ui/views/controls/combobox/combobox.cc index 906a983..2780d3f 100644 --- a/ui/views/controls/combobox/combobox.cc +++ b/ui/views/controls/combobox/combobox.cc
@@ -363,6 +363,10 @@ OnPropertyChanged(&selected_index_, kPropertyEffectsPreferredSizeChanged); } +bool Combobox::IsMenuRunning() const { + return menu_runner_ && menu_runner_->IsRunning(); +} + void Combobox::OnThemeChanged() { View::OnThemeChanged(); SetBackground( @@ -678,7 +682,7 @@ // Allow |menu_runner_| to be set by the testing API, but if this method is // ever invoked recursively, ensure the old menu is closed. - if (!menu_runner_ || menu_runner_->IsRunning()) { + if (!menu_runner_ || IsMenuRunning()) { menu_runner_ = std::make_unique<MenuRunner>( menu_model_.get(), MenuRunner::COMBOBOX, base::BindRepeating(&Combobox::OnMenuClosed, base::Unretained(this),
diff --git a/ui/views/controls/combobox/combobox.h b/ui/views/controls/combobox/combobox.h index 32c4cec..29dba45 100644 --- a/ui/views/controls/combobox/combobox.h +++ b/ui/views/controls/combobox/combobox.h
@@ -104,6 +104,13 @@ void SetSizeToLargestLabel(bool size_to_largest_label); bool GetSizeToLargestLabel() const { return size_to_largest_label_; } + // Use the time when combobox was closed in order for parent view to not + // treat a user event already treated by the combobox. + base::TimeTicks GetClosedTime() { return closed_time_; } + + // Returns whether or not the menu is currently running. + bool IsMenuRunning() const; + // Overridden from View: gfx::Size CalculatePreferredSize() const override; void OnBoundsChanged(const gfx::Rect& previous_bounds) override;