diff --git a/DEPS b/DEPS index 86037fe..ab830d5e 100644 --- a/DEPS +++ b/DEPS
@@ -311,15 +311,15 @@ # 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': '351f2b691639284c49915ae31f7fcc8cae7bda4f', + 'skia_revision': 'e96cb91c730324d81e4600de0bcbb3e1d133040f', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '08b9a2279b351b5f8ae0f4de8c8194d62e245883', + 'v8_revision': '07c1bc654d188fffeda01d5d50ac7a93c8e1f961', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '122b292d96c923b67ca3065c89d90714daec46f6', + 'angle_revision': '0e3d200d9caed5306dd74afdfe0f78152af8b01e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -327,7 +327,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '70c2db3e99bf97e1afbcd22ca37ef3b5ed101a51', + 'pdfium_revision': '21ac43e7fb73582dec513672d8a6c5f3908d441b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -398,7 +398,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': 'f74ead4522edc13813e53493f8b6712d793855ee', + 'devtools_frontend_revision': '5d1603a5d2e4bfb95aedc71298d7f4bccb45b891', # 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. @@ -438,7 +438,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': 'ed70ac0399fc13caf9cc63b9e3d1c0e975c37b51', + 'dawn_revision': 'b5879ac034aff8319e34c3645280bcf242cff6ac', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -478,7 +478,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'cros_components_revision': 'fb81e965fbaabf2be1475a180630a011b0e21d3e', + 'cros_components_revision': 'f47d8a6a115863f55f529e04b6302186a0df46b0', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -818,7 +818,7 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - 'f92a3dbb19f1b2e7eba93fa66743dcdc48fdd08e', + '14e0cef4d2c104adb11da44c94e43ce8d9311b84', 'condition': 'checkout_android and checkout_src_internal', }, @@ -847,7 +847,7 @@ }, 'src/ios/third_party/material_components_ios/src': { - 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '63cfd8c6b21176aa594ca8bb5f3aa602b1e6ed52', + 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '973011dd3df68bdea2076cd45610f756ce89920f', 'condition': 'checkout_ios', }, @@ -1013,7 +1013,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'ev8uu14lKo-cysFlhDbKbHdTNEQ8izE37c55Wv_EUJUC', + 'version': 'v8JL3E5KtNlFmho-mGQhRh5dg4wY33bqvymlJ0MKCdoC', }, ], 'condition': 'checkout_android', @@ -1254,13 +1254,13 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'c5305b39f473d64ddcb313a22584e22666b1da3b', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'f0fba1d307d511620e29c9d2b623abc6904e794c', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), 'src/third_party/devtools-frontend-internal': { - 'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + 'e07d8560b78c6bdc967960c66d6452e9f89e2199', + 'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + 'a5e5af40f7f1fc0a8fa577a9292609967326d045', 'condition': 'checkout_src_internal', }, @@ -1730,7 +1730,7 @@ Var('pdfium_git') + '/pdfium.git' + '@' + Var('pdfium_revision'), 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '442335b6aee106bc7cc024f2d85dd5cf03dec521', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '92e38d71f075f5cd47e3703b2dcb7dbb911266af', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1915,7 +1915,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '086261bcd213f8ae6f57ebdc293283ed6262097d', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '0c1c7221853b34f3d407dc698c01ad30dbb4e635', + Var('webrtc_git') + '/src.git' + '@' + '365a5717ae0defda2ec179c866290801543b0307', # Wuffs' canonical repository is at github.com/google/wuffs, but we use # Skia's mirror of Wuffs, the same as in upstream Skia's DEPS file. @@ -2073,7 +2073,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/projector_app/app', - 'version': '_0am1HjNwAk_RDqQX1o-8LkhW0DIRg8ckRZZLPjwU38C', + 'version': 'wDBCXbtdye0P5nlGPv81QMzHC8EHsQWC2vYdYqxICJ8C', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -4204,7 +4204,7 @@ 'src/ios_internal': { 'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' + - 'f9a4ee0b40a5bfd8db3dcc29f53527d0d1c72973', + '25494ef1cc0dff02b43c08dae16318fb403797a5', 'condition': 'checkout_ios and checkout_src_internal', },
diff --git a/ash/components/arc/compat_mode/resize_confirmation_dialog_view.cc b/ash/components/arc/compat_mode/resize_confirmation_dialog_view.cc index dc39646e..7cdfca5 100644 --- a/ash/components/arc/compat_mode/resize_confirmation_dialog_view.cc +++ b/ash/components/arc/compat_mode/resize_confirmation_dialog_view.cc
@@ -30,6 +30,14 @@ namespace arc { +void ResizeConfirmationDialogView::TestApi::SelectDoNotAskCheckbox() { + if (chromeos::features::IsJellyEnabled()) { + view_->do_not_ask_checkbox_jelly_->SetSelected(true); + } else { + view_->do_not_ask_checkbox_->SetChecked(true); + } +} + ResizeConfirmationDialogView::ResizeConfirmationDialogView( ResizeConfirmationCallback callback) : callback_(std::move(callback)) {
diff --git a/ash/components/arc/compat_mode/resize_confirmation_dialog_view.h b/ash/components/arc/compat_mode/resize_confirmation_dialog_view.h index 7ba1ccc8f..d5ac6d5 100644 --- a/ash/components/arc/compat_mode/resize_confirmation_dialog_view.h +++ b/ash/components/arc/compat_mode/resize_confirmation_dialog_view.h
@@ -40,9 +40,7 @@ views::LabelButton* accept_button() const { return view_->accept_button_; } views::LabelButton* cancel_button() const { return view_->cancel_button_; } - views::Checkbox* do_not_ask_checkbox() const { - return view_->do_not_ask_checkbox_; - } + void SelectDoNotAskCheckbox(); private: const raw_ptr<ResizeConfirmationDialogView, ExperimentalAsh> view_;
diff --git a/ash/components/arc/compat_mode/resize_confirmation_dialog_view_unittest.cc b/ash/components/arc/compat_mode/resize_confirmation_dialog_view_unittest.cc index 7c69df7..26bfd7a8 100644 --- a/ash/components/arc/compat_mode/resize_confirmation_dialog_view_unittest.cc +++ b/ash/components/arc/compat_mode/resize_confirmation_dialog_view_unittest.cc
@@ -7,6 +7,7 @@ #include <memory> #include "ash/components/arc/compat_mode/test/compat_mode_test_base.h" +#include "ash/style/ash_color_provider.h" #include "base/functional/bind.h" #include "base/memory/raw_ptr.h" #include "testing/gtest/include/gtest/gtest.h" @@ -40,8 +41,9 @@ protected: void ClickDialogButton(bool accept, bool with_checkbox) { ResizeConfirmationDialogView::TestApi dialog_view_test(dialog_view_); - if (with_checkbox) - dialog_view_test.do_not_ask_checkbox()->SetChecked(true); + if (with_checkbox) { + dialog_view_test.SelectDoNotAskCheckbox(); + } auto* target_button = accept ? dialog_view_test.accept_button() : dialog_view_test.cancel_button(); @@ -68,6 +70,9 @@ // A LayoutProvider must exist in scope in order to set up views. views::LayoutProvider layout_provider; + // An AshColorProvider must exist in scope in order to set up views. + ash::AshColorProvider ash_color_provider_; + raw_ptr<ResizeConfirmationDialogView, ExperimentalAsh> dialog_view_; std::unique_ptr<views::Widget> widget_; };
diff --git a/ash/fast_ink/fast_ink_host_frame_utils_unittest.cc b/ash/fast_ink/fast_ink_host_frame_utils_unittest.cc index 17bcb76..2b809f4 100644 --- a/ash/fast_ink/fast_ink_host_frame_utils_unittest.cc +++ b/ash/fast_ink/fast_ink_host_frame_utils_unittest.cc
@@ -18,7 +18,6 @@ #include "components/viz/common/quads/compositor_frame.h" #include "components/viz/common/quads/texture_draw_quad.h" #include "components/viz/common/resources/resource_format.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/resource_id.h" #include "components/viz/common/resources/shared_image_format_utils.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/ash/fast_ink/fast_ink_host_unittest.cc b/ash/fast_ink/fast_ink_host_unittest.cc index 36b9243..242763de 100644 --- a/ash/fast_ink/fast_ink_host_unittest.cc +++ b/ash/fast_ink/fast_ink_host_unittest.cc
@@ -21,7 +21,6 @@ #include "components/viz/common/quads/compositor_frame.h" #include "components/viz/common/quads/compositor_render_pass.h" #include "components/viz/common/quads/texture_draw_quad.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/resource_id.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/aura/window.h"
diff --git a/ash/fast_ink/view_tree_host_root_view_frame_factory.cc b/ash/fast_ink/view_tree_host_root_view_frame_factory.cc index f15b0a9..c5577c96 100644 --- a/ash/fast_ink/view_tree_host_root_view_frame_factory.cc +++ b/ash/fast_ink/view_tree_host_root_view_frame_factory.cc
@@ -13,7 +13,6 @@ #include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/quads/compositor_frame.h" #include "components/viz/common/quads/texture_draw_quad.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/resource_id.h" #include "components/viz/common/resources/shared_image_format_utils.h" #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
diff --git a/ash/login/README.md b/ash/login/README.md new file mode 100644 index 0000000..fce4aac --- /dev/null +++ b/ash/login/README.md
@@ -0,0 +1,38 @@ +# Entities used on the login/lock screen + +The main entities used to show the login/lock screen UI. + +- `//ash/public/cpp/`: + - This folder contains inferfaces that are implemented in ash or chrome and +are used to communicate between ash and chrome services. + - [`LoginScreenClient`](/ash/public/cpp/login_screen_client.h) - handles +method calls sent from ash to chrome & handles messages from chrome to ash. +Forwards some of the calls to the `Delegate`. + +- `//chrome/browser/ash/login/ui/`: + - This folder contains implementations of login and OOBE UIs. + - [`LoginDisplayHostMojo`](/chrome/browser/ash/login/ui/ +login_display_host_mojo.h) - a `LoginDisplayHost` instance that implements +`LoginScreenClient` and sends requests to the views-based sign in. Handles calls +like `HandleAuthenticateUserWith...()`. Owned by +`ChromeBrowserMainExtraPartsAsh`. + +- `//ash/login/`: + - This folder contains the implementation of login UI views (buttons, inputs, +etc), and additional classes that handle notifications and update the UI. Also +see [ash/login/ui/README.md](/ash/login/ui/README.md) + - [`LoginScreenController`](/ash/login/login_screen_controller.h) - mostly +forwards requests to `LoginScreenClient` or calls `Shelf` APIs directly. Owned +by `Shell`. + - [`LoginDataDispatcher`](/ash/login/ui/login_data_dispatcher.h) - provides +access to data notification events needed by the lock/login screen (via the +observer). Owned by `LoginScreenController`. + - [`LockContentsView`](/ash/login/ui/lock_contents_view.h) - hosts the root +view for the login/lock screen. Receives notifications from the +`LoginDataDispatcher` and updates the UI. Owned by `LockScreen`. + +- `//chrome/browser/ash/login/lock/`: + - This folder contains the lock screen - specific logic for the login UIs. + - [`ViewsScreenLocker`](/chrome/browser/ash/login/lock/views_screen_locker.h) +handles calls between ash and chrome on the lock screen by implementing +Delegate interfaces.
diff --git a/ash/rounded_display/rounded_display_frame_factory.cc b/ash/rounded_display/rounded_display_frame_factory.cc index 0b3940b..020e093 100644 --- a/ash/rounded_display/rounded_display_frame_factory.cc +++ b/ash/rounded_display/rounded_display_frame_factory.cc
@@ -18,7 +18,6 @@ #include "components/viz/common/quads/compositor_frame.h" #include "components/viz/common/quads/texture_draw_quad.h" #include "components/viz/common/resources/resource_format.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/resource_id.h" #include "components/viz/common/resources/shared_image_format.h" #include "components/viz/common/resources/shared_image_format_utils.h"
diff --git a/ash/webui/camera_app_ui/camera_app_ui.cc b/ash/webui/camera_app_ui/camera_app_ui.cc index 025870e4..22c7dff5f 100644 --- a/ash/webui/camera_app_ui/camera_app_ui.cc +++ b/ash/webui/camera_app_ui/camera_app_ui.cc
@@ -19,7 +19,6 @@ #include "components/arc/intent_helper/arc_intent_helper_bridge.h" #include "components/content_settings/core/common/content_settings_types.h" #include "components/media_device_salt/media_device_salt_service.h" -#include "components/media_device_salt/media_device_salt_service_factory.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/devtools_agent_host.h" @@ -140,14 +139,19 @@ // Translates the renderer-side source ID to video device id. void TranslateVideoDeviceId( content::BrowserContext* browser_context, + media_device_salt::MediaDeviceSaltService* salt_service, const url::Origin& origin, const std::string& source_id, base::OnceCallback<void(const absl::optional<std::string>&)> callback) { - media_device_salt::MediaDeviceSaltService* salt_service = - media_device_salt::MediaDeviceSaltServiceFactory::GetInstance() - ->GetForBrowserContext(browser_context); - salt_service->GetSalt( - base::BindOnce(&GotSalt, origin, source_id, std::move(callback))); + if (salt_service) { + salt_service->GetSalt( + base::BindOnce(&GotSalt, origin, source_id, std::move(callback))); + } else { + // If the embedder does not provide a salt service, use the browser + // context's unique ID as salt. + GotSalt(origin, source_id, std::move(callback), + browser_context->UniqueId()); + } } void HandleCameraResult( @@ -171,8 +175,10 @@ } std::unique_ptr<media::CameraAppDeviceProviderImpl> -CreateCameraAppDeviceProvider(const url::Origin& security_origin, - content::BrowserContext* context) { +CreateCameraAppDeviceProvider( + content::BrowserContext* browser_context, + media_device_salt::MediaDeviceSaltService* salt_service, + const url::Origin& security_origin) { mojo::PendingRemote<cros::mojom::CameraAppDeviceBridge> device_bridge; auto device_bridge_receiver = device_bridge.InitWithNewPipeAndPassReceiver(); @@ -180,8 +186,9 @@ content::GetVideoCaptureService().ConnectToCameraAppDeviceBridge( std::move(device_bridge_receiver)); - auto mapping_callback = base::BindRepeating(&TranslateVideoDeviceId, context, - std::move(security_origin)); + auto mapping_callback = + base::BindRepeating(&TranslateVideoDeviceId, browser_context, + salt_service, std::move(security_origin)); return std::make_unique<media::CameraAppDeviceProviderImpl>( std::move(device_bridge), std::move(mapping_callback)); @@ -275,9 +282,11 @@ void CameraAppUI::BindInterface( mojo::PendingReceiver<cros::mojom::CameraAppDeviceProvider> receiver) { + content::BrowserContext* browser_context = + web_ui()->GetWebContents()->GetBrowserContext(); provider_ = CreateCameraAppDeviceProvider( - url::Origin::Create(GURL(kChromeUICameraAppURL)), - web_ui()->GetWebContents()->GetBrowserContext()); + browser_context, delegate_->GetMediaDeviceSaltService(browser_context), + url::Origin::Create(GURL(kChromeUICameraAppURL))); provider_->Bind(std::move(receiver)); }
diff --git a/ash/webui/camera_app_ui/camera_app_ui_delegate.h b/ash/webui/camera_app_ui/camera_app_ui_delegate.h index 29e9b06..4ac18c7 100644 --- a/ash/webui/camera_app_ui/camera_app_ui_delegate.h +++ b/ash/webui/camera_app_ui/camera_app_ui_delegate.h
@@ -11,10 +11,15 @@ #include "base/functional/callback.h" namespace content { +class BrowserContext; class WebContents; class WebUIDataSource; } // namespace content +namespace media_device_salt { +class MediaDeviceSaltService; +} // namespace media_device_salt + namespace ash { class HoldingSpaceClient; @@ -102,6 +107,11 @@ // Gets the file path by given file |name|. virtual base::FilePath GetFilePathByName(const std::string& name) = 0; + + // Returns a service that provides persistent salts for generating media + // device IDs. Can be null if the embedder does not support persistent salts. + virtual media_device_salt::MediaDeviceSaltService* GetMediaDeviceSaltService( + content::BrowserContext* context) = 0; }; } // namespace ash
diff --git a/ash/webui/camera_app_ui/resources/js/device/camera3_device_info.ts b/ash/webui/camera_app_ui/resources/js/device/camera3_device_info.ts index c913106d..ca9ce57b 100644 --- a/ash/webui/camera_app_ui/resources/js/device/camera3_device_info.ts +++ b/ash/webui/camera_app_ui/resources/js/device/camera3_device_info.ts
@@ -66,8 +66,12 @@ readonly supportPTZ: boolean, ) { this.deviceId = deviceInfo.deviceId; + // If all fps supported by the camera is lower than 24, use the maximum + // supported fps. + const maxSupportedFps = + Math.max(...videoResolutionFpses.map(({maxFps}) => maxFps)); for (const {width, height, maxFps} of videoResolutionFpses) { - if (maxFps < 24) { + if (maxFps < 24 && maxFps !== maxSupportedFps) { continue; } const r = new Resolution(width, height);
diff --git a/base/BUILD.gn b/base/BUILD.gn index 3d1ee55..359818f 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -229,7 +229,11 @@ defines = [ "BASE_IMPLEMENTATION" ] configs += [ "//build/config/compiler:enable_arc" ] deps = [ - "//base:base_static", + ":base_static", + ":debugging_buildflags", + ":logging_buildflags", + ":tracing_buildflags", + "//base/allocator/partition_allocator:buildflags", "//base/numerics:base_numerics", "//build:blink_buildflags", "//third_party/abseil-cpp:absl",
diff --git a/base/allocator/partition_allocator/pointers/raw_ptr.h b/base/allocator/partition_allocator/pointers/raw_ptr.h index b035bfcdf..ece9b9b 100644 --- a/base/allocator/partition_allocator/pointers/raw_ptr.h +++ b/base/allocator/partition_allocator/pointers/raw_ptr.h
@@ -1176,6 +1176,12 @@ // This is not meant to be added manually. You can ignore this flag. constexpr auto FlakyDanglingUntriaged = base::RawPtrTraits::kMayDangle; +// Dangling raw_ptr that is more likely to cause UAF: its memory was freed in +// one task, and the raw_ptr was released in a different one. +// +// This is not meant to be added manually. You can ignore this flag. +constexpr auto DanglingAcrossTasks = base::RawPtrTraits::kMayDangle; + // The use of pointer arithmetic with raw_ptr is strongly discouraged and // disabled by default. Usually a container like span<> should be used // instead of the raw_ptr.
diff --git a/base/files/file_descriptor_watcher_posix.h b/base/files/file_descriptor_watcher_posix.h index a252651d..ef4c26a 100644 --- a/base/files/file_descriptor_watcher_posix.h +++ b/base/files/file_descriptor_watcher_posix.h
@@ -76,7 +76,7 @@ // Controller is deleted, ownership of |watcher_| is transfered to a delete // task posted to the MessageLoopForIO. This ensures that |watcher_| isn't // deleted while it is being used by the MessageLoopForIO. - raw_ptr<Watcher, DanglingUntriaged> watcher_; + raw_ptr<Watcher, DanglingAcrossTasks> watcher_; // An event for the watcher to notify controller that it's destroyed. // As the |watcher_| is owned by Controller, always outlives the Watcher.
diff --git a/base/message_loop/message_pump_libevent.h b/base/message_loop/message_pump_libevent.h index 0389de96..fc5881a1 100644 --- a/base/message_loop/message_pump_libevent.h +++ b/base/message_loop/message_pump_libevent.h
@@ -93,7 +93,7 @@ friend class RefCounted<EpollInterest>; ~EpollInterest(); - const raw_ptr<FdWatchController, DanglingUntriaged> controller_; + const raw_ptr<FdWatchController, DanglingAcrossTasks> controller_; const EpollInterestParams params_; bool active_ = true; bool was_controller_destroyed_ = false;
diff --git a/base/observer_list_internal.h b/base/observer_list_internal.h index fb903e8f..e17c311 100644 --- a/base/observer_list_internal.h +++ b/base/observer_list_internal.h
@@ -54,7 +54,7 @@ #endif // DCHECK_IS_ON() private: - raw_ptr<void, DanglingUntriaged> ptr_; + raw_ptr<void, DanglingAcrossTasks> ptr_; #if DCHECK_IS_ON() base::debug::StackTrace stack_; #endif // DCHECK_IS_ON()
diff --git a/base/synchronization/waitable_event_watcher.h b/base/synchronization/waitable_event_watcher.h index 78617c5..d23f8850 100644 --- a/base/synchronization/waitable_event_watcher.h +++ b/base/synchronization/waitable_event_watcher.h
@@ -144,7 +144,7 @@ scoped_refptr<Flag> cancel_flag_; // Enqueued in the wait list of the watched WaitableEvent. - raw_ptr<AsyncWaiter, DanglingUntriaged> waiter_ = nullptr; + raw_ptr<AsyncWaiter, DanglingAcrossTasks> waiter_ = nullptr; // Kernel of the watched WaitableEvent. scoped_refptr<WaitableEvent::WaitableEventKernel> kernel_;
diff --git a/base/test/test_trace_processor.cc b/base/test/test_trace_processor.cc index 0df3a536a..a9c64df3 100644 --- a/base/test/test_trace_processor.cc +++ b/base/test/test_trace_processor.cc
@@ -8,32 +8,58 @@ #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) +TraceConfig DefaultTraceConfig(const StringPiece& category_filter_string, + bool privacy_filtering) { + TraceConfig trace_config; + auto* buffer_config = trace_config.add_buffers(); + buffer_config->set_size_kb(4 * 1024); + + auto* data_source = trace_config.add_data_sources(); + auto* source_config = data_source->mutable_config(); + source_config->set_name("track_event"); + source_config->set_target_buffer(0); + + perfetto::protos::gen::TrackEventConfig track_event_config; + base::trace_event::TraceConfigCategoryFilter category_filter; + category_filter.InitializeFromString(category_filter_string); + + // If no categories are explicitly enabled, enable the default ones. + // Otherwise only matching categories are enabled. + if (!category_filter.included_categories().empty()) { + track_event_config.add_disabled_categories("*"); + } + for (const auto& included_category : category_filter.included_categories()) { + track_event_config.add_enabled_categories(included_category); + } + for (const auto& disabled_category : category_filter.disabled_categories()) { + track_event_config.add_enabled_categories(disabled_category); + } + for (const auto& excluded_category : category_filter.excluded_categories()) { + track_event_config.add_disabled_categories(excluded_category); + } + + source_config->set_track_event_config_raw( + track_event_config.SerializeAsString()); + + if (privacy_filtering) { + track_event_config.set_filter_debug_annotations(true); + track_event_config.set_filter_dynamic_event_names(true); + } + + return trace_config; +} + TestTraceProcessor::TestTraceProcessor() = default; TestTraceProcessor::~TestTraceProcessor() = default; -void TestTraceProcessor::StartTrace(const StringPiece& category_filter_string) { - session_ = perfetto::Tracing::NewTrace(); - perfetto::protos::gen::TraceConfig config = - TracingEnvironment::GetDefaultTraceConfig(); - for (auto& data_source : *config.mutable_data_sources()) { - perfetto::protos::gen::TrackEventConfig track_event_config; - base::trace_event::TraceConfigCategoryFilter category_filter; - category_filter.InitializeFromString(category_filter_string); - for (const auto& included_category : - category_filter.included_categories()) { - track_event_config.add_enabled_categories(included_category); - } - for (const auto& disabled_category : - category_filter.disabled_categories()) { - track_event_config.add_enabled_categories(disabled_category); - } - for (const auto& excluded_category : - category_filter.excluded_categories()) { - track_event_config.add_disabled_categories(excluded_category); - } - data_source.mutable_config()->set_track_event_config_raw( - track_event_config.SerializeAsString()); - } +void TestTraceProcessor::StartTrace(const StringPiece& category_filter_string, + bool privacy_filtering) { + StartTrace(DefaultTraceConfig(category_filter_string, privacy_filtering)); +} + +void TestTraceProcessor::StartTrace(const TraceConfig& config, + perfetto::BackendType backend) { + session_ = perfetto::Tracing::NewTrace(backend); session_->Setup(config); // Some tests run the tracing service on the main thread and StartBlocking() // can deadlock so use a RunLoop instead.
diff --git a/base/test/test_trace_processor.h b/base/test/test_trace_processor.h index 343d607..88d7920 100644 --- a/base/test/test_trace_processor.h +++ b/base/test/test_trace_processor.h
@@ -15,12 +15,15 @@ #include "base/test/trace_test_utils.h" #include "base/types/expected.h" -// TODO(rasikan): Put these functions in a class. - namespace base::test { #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) +using perfetto::protos::gen::TraceConfig; + +TraceConfig DefaultTraceConfig(const StringPiece& category_filter_string, + bool privacy_filtering); + // Use TestTraceProcessor to record Perfetto traces in unit and browser tests. // This API can be used to start and stop traces, run SQL queries on the trace // and write expectations against the query result. @@ -48,7 +51,11 @@ TestTraceProcessor(); ~TestTraceProcessor(); - void StartTrace(const StringPiece& category_filter_string); + void StartTrace(const StringPiece& category_filter_string, + bool privacy_filtering = false); + void StartTrace( + const TraceConfig& config, + perfetto::BackendType backend = perfetto::kUnspecifiedBackend); absl::Status StopAndParseTrace();
diff --git a/base/threading/sequence_bound_internal.h b/base/threading/sequence_bound_internal.h index 0e4b37c..72f9aba5 100644 --- a/base/threading/sequence_bound_internal.h +++ b/base/threading/sequence_bound_internal.h
@@ -150,7 +150,7 @@ // Storage originally allocated by `AlignedAlloc()`. Maintained separately // from `ptr_` since the original, unadjusted pointer needs to be passed to // `AlignedFree()`. - raw_ptr<void, DanglingUntriaged> alloc_ = nullptr; + raw_ptr<void, DanglingAcrossTasks> alloc_ = nullptr; }; template <typename T, typename CrossThreadTraits>
diff --git a/base/values.cc b/base/values.cc index 5f68e4a9..28c6f40 100644 --- a/base/values.cc +++ b/base/values.cc
@@ -909,28 +909,20 @@ base::to_address(storage_.cend())); } -// TODO(crbug.com/1446739): Implement reverse iterators in -// CheckedContiguousIterator and use them here. -std::vector<Value>::reverse_iterator Value::List::rend() { - return storage_.rend(); +Value::List::reverse_iterator Value::List::rend() { + return reverse_iterator(begin()); } -// TODO(crbug.com/1446739): Implement reverse iterators in -// CheckedContiguousIterator and use them here. -std::vector<Value>::const_reverse_iterator Value::List::rend() const { - return storage_.rend(); +Value::List::const_reverse_iterator Value::List::rend() const { + return const_reverse_iterator(begin()); } -// TODO(crbug.com/1446739): Implement reverse iterators in -// CheckedContiguousIterator and use them here. -std::vector<Value>::reverse_iterator Value::List::rbegin() { - return storage_.rbegin(); +Value::List::reverse_iterator Value::List::rbegin() { + return reverse_iterator(end()); } -// TODO(crbug.com/1446739): Implement reverse iterators in -// CheckedContiguousIterator and use them here. -std::vector<Value>::const_reverse_iterator Value::List::rbegin() const { - return storage_.rbegin(); +Value::List::const_reverse_iterator Value::List::rbegin() const { + return const_reverse_iterator(end()); } const Value& Value::List::front() const {
diff --git a/base/values.h b/base/values.h index 3f8087fe..46014594 100644 --- a/base/values.h +++ b/base/values.h
@@ -137,11 +137,10 @@ // // Lists support: // - `empty()`, `size()`, `begin()`, `end()`, `cbegin()`, `cend()`, -// `front()`, `back()`, `reserve()`, `operator[]`, `clear()`, `erase()`: -// Identical to the STL container equivalents, with additional safety -// checks, e.g. `operator[]` will `CHECK()` if the index is out of range. -// - `rbegin()` and `rend()` are also supported, but there are no safety checks -// (see crbug.com/1446739). +// `rbegin()`, `rend()`, `front()`, `back()`, `reserve()`, `operator[]`, +// `clear()`, `erase()`: Identical to the STL container equivalents, with +// additional safety checks, e.g. `operator[]` will `CHECK()` if the index +// is out of range. // - `Clone()`: Create a deep copy. // - `Append()`: Append a value to the end of the list. Accepts `Value` or any // of the subtypes that `Value` can hold. @@ -588,6 +587,8 @@ public: using iterator = CheckedContiguousIterator<Value>; using const_iterator = CheckedContiguousConstIterator<Value>; + using reverse_iterator = std::reverse_iterator<iterator>; + using const_reverse_iterator = std::reverse_iterator<const_iterator>; using value_type = Value; // Creates a list with the given capacity reserved. @@ -628,12 +629,12 @@ // Returns a reverse iterator preceding the first value in this list. May // not be dereferenced. - std::vector<Value>::reverse_iterator rend(); - std::vector<Value>::const_reverse_iterator rend() const; + reverse_iterator rend(); + const_reverse_iterator rend() const; // Returns a reverse iterator to the last value in this list. - std::vector<Value>::reverse_iterator rbegin(); - std::vector<Value>::const_reverse_iterator rbegin() const; + reverse_iterator rbegin(); + const_reverse_iterator rbegin() const; // Returns a reference to the first value in the container. Fails with // `CHECK()` if the list is empty.
diff --git a/build/config/clang/clang.gni b/build/config/clang/clang.gni index 69883e6a..3cb0553 100644 --- a/build/config/clang/clang.gni +++ b/build/config/clang/clang.gni
@@ -18,7 +18,7 @@ enable_check_raw_ptr_fields = build_with_chromium && !is_official_build && ((is_linux && !is_castos) || (is_android && !is_cast_android) || is_mac || - is_win || is_chromeos_lacros || is_chromeos_ash) + is_win || is_chromeos_lacros) clang_base_path = default_clang_base_path
diff --git a/build/config/rust.gni b/build/config/rust.gni index 25fc7aa..617b6b0 100644 --- a/build/config/rust.gni +++ b/build/config/rust.gni
@@ -90,8 +90,8 @@ enable_rust_json = enable_all_rust_features # Support for chrome://crash-rust to check crash dump collection works. - enable_rust_crash = is_linux || is_android || is_fuchsia || is_chromeos || - enable_all_rust_features + enable_rust_crash = + is_linux || is_android || is_fuchsia || enable_all_rust_features # Support for QR code generation - see https://crbug.com/1431991. enable_rust_qr = is_linux || is_android || enable_all_rust_features
diff --git a/cc/layers/heads_up_display_layer_impl.cc b/cc/layers/heads_up_display_layer_impl.cc index 57b5c9b..60e3b06 100644 --- a/cc/layers/heads_up_display_layer_impl.cc +++ b/cc/layers/heads_up_display_layer_impl.cc
@@ -43,7 +43,6 @@ #include "components/viz/common/quads/texture_draw_quad.h" #include "components/viz/common/resources/bitmap_allocation.h" #include "components/viz/common/resources/platform_color.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/shared_image_format.h" #include "gpu/GLES2/gl2extchromium.h" #include "gpu/command_buffer/client/context_support.h"
diff --git a/cc/raster/raster_buffer_provider_perftest.cc b/cc/raster/raster_buffer_provider_perftest.cc index ad15e0ba..42a5f4bb 100644 --- a/cc/raster/raster_buffer_provider_perftest.cc +++ b/cc/raster/raster_buffer_provider_perftest.cc
@@ -25,7 +25,6 @@ #include "components/viz/common/gpu/context_cache_controller.h" #include "components/viz/common/gpu/raster_context_provider.h" #include "components/viz/common/resources/platform_color.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/shared_image_format_utils.h" #include "components/viz/test/test_context_provider.h" #include "components/viz/test/test_context_support.h"
diff --git a/cc/raster/task.h b/cc/raster/task.h index f650e8d3..67572d95 100644 --- a/cc/raster/task.h +++ b/cc/raster/task.h
@@ -138,8 +138,8 @@ Edge(const Task* task, Task* dependent) : task(task), dependent(dependent) {} - raw_ptr<const Task, DanglingUntriaged> task; - raw_ptr<Task, DanglingUntriaged> dependent; + raw_ptr<const Task, DanglingAcrossTasks> task; + raw_ptr<Task, DanglingAcrossTasks> dependent; }; TaskGraph();
diff --git a/cc/resources/resource_pool.cc b/cc/resources/resource_pool.cc index 55977af..b778fd6b 100644 --- a/cc/resources/resource_pool.cc +++ b/cc/resources/resource_pool.cc
@@ -26,7 +26,6 @@ #include "cc/base/container_util.h" #include "components/viz/client/client_resource_provider.h" #include "components/viz/common/gpu/raster_context_provider.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/shared_image_format_utils.h" #include "gpu/command_buffer/client/context_support.h" #include "gpu/command_buffer/common/capabilities.h"
diff --git a/cc/scheduler/scheduler.h b/cc/scheduler/scheduler.h index 7afa104..48ba8f0 100644 --- a/cc/scheduler/scheduler.h +++ b/cc/scheduler/scheduler.h
@@ -296,7 +296,7 @@ // Owned by LayerTreeHostImpl and is destroyed when LayerTreeHostImpl is // destroyed. - raw_ptr<CompositorFrameReportingController, DanglingUntriaged> + raw_ptr<CompositorFrameReportingController, DanglingAcrossTasks> compositor_frame_reporting_controller_; // What the latest deadline was, and when it was scheduled.
diff --git a/cc/slim/frame_sink_impl.cc b/cc/slim/frame_sink_impl.cc index 5d2c812..c74744e 100644 --- a/cc/slim/frame_sink_impl.cc +++ b/cc/slim/frame_sink_impl.cc
@@ -20,7 +20,6 @@ #include "components/viz/common/features.h" #include "components/viz/common/quads/compositor_frame.h" #include "components/viz/common/resources/platform_color.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/resource_id.h" #include "components/viz/common/resources/shared_image_format.h" #include "components/viz/common/resources/shared_image_format_utils.h"
diff --git a/cc/tiles/tile_manager.cc b/cc/tiles/tile_manager.cc index 91a5f42..238b378 100644 --- a/cc/tiles/tile_manager.cc +++ b/cc/tiles/tile_manager.cc
@@ -179,7 +179,7 @@ TileResolution tile_resolution_; int layer_id_; uint64_t source_prepare_tiles_id_; - raw_ptr<void, DanglingUntriaged> tile_tracing_id_; + raw_ptr<void, DanglingAcrossTasks> tile_tracing_id_; uint64_t new_content_id_; int source_frame_number_; std::unique_ptr<RasterBuffer> raster_buffer_;
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 256f599..394d0a39 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -111,7 +111,6 @@ #include "components/viz/common/quads/solid_color_draw_quad.h" #include "components/viz/common/resources/bitmap_allocation.h" #include "components/viz/common/resources/platform_color.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/shared_image_format.h" #include "components/viz/common/resources/shared_image_format_utils.h" #include "components/viz/common/traced_value.h"
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index 47da404..65dae60 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -76,6 +76,7 @@ "java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkActivity.java", "java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkAddEditFolderActivity.java", "java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkEditActivity.java", + "java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkFolderPickerActivity.java", "java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkFolderSelectActivity.java", "java/src/org/chromium/chrome/browser/app/creator/CreatorActionDelegateImpl.java", "java/src/org/chromium/chrome/browser/app/creator/CreatorActivity.java", @@ -157,6 +158,10 @@ "java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java", "java/src/org/chromium/chrome/browser/bookmarks/BookmarkDelegate.java", "java/src/org/chromium/chrome/browser/bookmarks/BookmarkFeatures.java", + "java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerCoordinator.java", + "java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerMediator.java", + "java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerProperties.java", + "java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerViewBinder.java", "java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderRow.java", "java/src/org/chromium/chrome/browser/bookmarks/BookmarkImageFetcher.java", "java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemRow.java",
diff --git a/chrome/android/expectations/monochrome_public_bundle__chrome.AndroidManifest.expected b/chrome/android/expectations/monochrome_public_bundle__chrome.AndroidManifest.expected index c46158a9..bcf510e0 100644 --- a/chrome/android/expectations/monochrome_public_bundle__chrome.AndroidManifest.expected +++ b/chrome/android/expectations/monochrome_public_bundle__chrome.AndroidManifest.expected
@@ -105,6 +105,14 @@ android:theme="@style/Theme.Chromium.DialogWhenLarge" android:windowSoftInputMode="stateHidden"> </activity> # DIFF-ANCHOR: 766e66bd + <activity # DIFF-ANCHOR: 002f9e99 + android:name="org.chromium.chrome.browser.app.bookmarks.BookmarkFolderPickerActivity" + android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize" + android:exported="false" + android:label="@string/bookmark_choose_folder" + android:theme="@style/Theme.Chromium.DialogWhenLarge" + android:windowSoftInputMode="stateAlwaysHidden"> + </activity> # DIFF-ANCHOR: 002f9e99 <activity # DIFF-ANCHOR: 8f8d0c81 android:name="org.chromium.chrome.browser.app.bookmarks.BookmarkFolderSelectActivity" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize"
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml index 6f3722c..aa421c8 100644 --- a/chrome/android/java/AndroidManifest.xml +++ b/chrome/android/java/AndroidManifest.xml
@@ -667,6 +667,13 @@ android:exported="false" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize"> </activity> + <activity android:name="org.chromium.chrome.browser.app.bookmarks.BookmarkFolderPickerActivity" + android:theme="@style/Theme.Chromium.DialogWhenLarge" + android:windowSoftInputMode="stateAlwaysHidden" + android:label="@string/bookmark_choose_folder" + android:exported="false" + android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize"> + </activity> <!-- Activities for downloads. --> <activity-alias android:name="org.chromium.chrome.browser.download.DownloadActivity"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkFolderPickerActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkFolderPickerActivity.java new file mode 100644 index 0000000..492b67f3 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkFolderPickerActivity.java
@@ -0,0 +1,14 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.app.bookmarks; + +import org.chromium.chrome.browser.SynchronousInitializationActivity; + +/** + * The activity that enables the user to pick the parent folder for the given {@link BookmarkId}. + * Used for the improved android bookmarks manager. + */ +// TODO(crbug.com/1448933): Implement new folder picker activity. +public class BookmarkFolderPickerActivity extends SynchronousInitializationActivity {}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerCoordinator.java new file mode 100644 index 0000000..5f0e58db --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerCoordinator.java
@@ -0,0 +1,9 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.bookmarks; + +/** Mediator for the folder select activity. */ +// TODO(crbug.com/1448933): Implement new folder picker activity. +public class BookmarkFolderPickerCoordinator {}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerMediator.java new file mode 100644 index 0000000..b12ec3c --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerMediator.java
@@ -0,0 +1,9 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.bookmarks; + +/** Mediator for the folder picker activity. */ +// TODO(crbug.com/1448933): Implement new folder picker activity. +class BookmarkFolderPickerMediator {}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerProperties.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerProperties.java new file mode 100644 index 0000000..d196bf1b --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerProperties.java
@@ -0,0 +1,9 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.bookmarks; + +/** Properties for the folder picker activity. */ +// TODO(crbug.com/1448933): Implement new folder picker activity. +class BookmarkFolderPickerProperties {}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerViewBinder.java new file mode 100644 index 0000000..3daee71 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerViewBinder.java
@@ -0,0 +1,9 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.bookmarks; + +/** View binder for the folder picker activity. */ +// TODO(crbug.com/1448933): Implement new folder picker activity. +class BookmarkFolderPickerViewBinder {}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectActivityCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectActivityCoordinator.java new file mode 100644 index 0000000..cac2b4f --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectActivityCoordinator.java
@@ -0,0 +1,9 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.bookmarks; + +/** Coordinator for the folder select activity. */ +// TODO(crbug.com/1448933): Implement new folder select activity. +public class BookmarkFolderPickerCoordinator {}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectActivityMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectActivityMediator.java new file mode 100644 index 0000000..001c80a1 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectActivityMediator.java
@@ -0,0 +1,9 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.bookmarks; + +/** Mediator for the folder select activity. */ +// TODO(crbug.com/1448933): Implement new folder select activity. +class BookmarkFolderPickerMediator {}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectActivityProperties.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectActivityProperties.java new file mode 100644 index 0000000..971dd867 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectActivityProperties.java
@@ -0,0 +1,9 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.bookmarks; + +/** Properties for the folder select activity. */ +// TODO(crbug.com/1448933): Implement new folder select activity. +class BookmarkFolderPickerProperties {}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectActivityViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectActivityViewBinder.java new file mode 100644 index 0000000..29260d2 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectActivityViewBinder.java
@@ -0,0 +1,9 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.bookmarks; + +/** View binder for the folder select activity. */ +// TODO(crbug.com/1448933): Implement new folder select activity. +class BookmarkFolderPickerViewBinder {}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/PasswordMigrationWarningBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/PasswordMigrationWarningBridge.java index b690b21e3..354a017 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/PasswordMigrationWarningBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/PasswordMigrationWarningBridge.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.password_manager; +import android.app.Activity; import android.content.Context; import org.chromium.base.ContextUtils; @@ -31,6 +32,17 @@ if (context == null) return; // The export flow won't work unless the sheet is started with an Activity as a Context. if (ContextUtils.activityFromContext(context) == null) return; + showWarningInternal(context, bottomSheetController, profile); + } + + @CalledByNative + static void showWarningWithActivity( + Activity activity, BottomSheetController bottomSheetController, Profile profile) { + showWarningInternal(activity, bottomSheetController, profile); + } + + private static void showWarningInternal( + Context context, BottomSheetController bottomSheetController, Profile profile) { PasswordMigrationWarningCoordinator passwordMigrationWarningCoordinator = new PasswordMigrationWarningCoordinator(context, profile, bottomSheetController, SyncConsentActivityLauncherImpl.get(), new SettingsLauncherImpl(),
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordManagerHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordManagerHandler.java index a133f05..ff7e04e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordManagerHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordManagerHandler.java
@@ -4,12 +4,14 @@ package org.chromium.chrome.browser.password_manager.settings; +import android.app.Activity; import android.content.Context; import androidx.annotation.VisibleForTesting; import org.chromium.base.Callback; import org.chromium.base.IntStringCallback; +import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; import org.chromium.components.browser_ui.settings.SettingsLauncher; /** @@ -82,8 +84,12 @@ boolean isBlockedCredential); /** - * Checks whether the all the conditions for the migraiton warning to be shown are met. - * This includes the flag check, whether there was another warning shown in the past month, etc. + * Calls C++ to trigger the migration warning. The C++ util centralizes the showing logic such + * that it can ensure that all appropriate checks are done an that the timestamp for showing + * the warning is uniformly recorded. + * + * @param activity the activity used to show the warning and potentially the export flow. + * @param bottomSheetController the controller displaying the warning bottom sheet. */ - boolean shouldShowMigrationWarning(); + void showMigrationWarning(Activity activity, BottomSheetController bottomSheetController); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java index a545759..f3f4ee59 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java
@@ -39,13 +39,10 @@ import org.chromium.chrome.browser.password_manager.PasswordManagerHelper; import org.chromium.chrome.browser.preferences.Pref; import org.chromium.chrome.browser.profiles.Profile; -import org.chromium.chrome.browser.pwd_migration.PasswordMigrationWarningCoordinator; import org.chromium.chrome.browser.settings.ChromeManagedPreferenceDelegate; import org.chromium.chrome.browser.settings.ProfileDependentSetting; import org.chromium.chrome.browser.settings.SettingsLauncherImpl; -import org.chromium.chrome.browser.signin.SyncConsentActivityLauncherImpl; import org.chromium.chrome.browser.sync.SyncServiceFactory; -import org.chromium.chrome.browser.sync.settings.ManageSyncSettings; import org.chromium.chrome.browser.sync.settings.SyncSettingsUtils; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; import org.chromium.components.browser_ui.settings.ChromeBasePreference; @@ -403,18 +400,10 @@ } } - if (!mNoPasswords - && PasswordManagerHandlerProvider.getInstance() - .getPasswordManagerHandler() - .shouldShowMigrationWarning()) { - PasswordMigrationWarningCoordinator passwordMigrationWarningCoordinator = - new PasswordMigrationWarningCoordinator(getContext(), mProfile, - mBottomSheetController, SyncConsentActivityLauncherImpl.get(), - new SettingsLauncherImpl(), ManageSyncSettings.class, new ExportFlow(), - (PasswordListObserver observer) - -> PasswordManagerHandlerProvider.getInstance().addObserver( - observer)); - passwordMigrationWarningCoordinator.showWarning(); + if (!mNoPasswords) { + PasswordManagerHandlerProvider.getInstance() + .getPasswordManagerHandler() + .showMigrationWarning(getActivity(), mBottomSheetController); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordUIView.java b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordUIView.java index 90cd277..9e764aa 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordUIView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordUIView.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.password_manager.settings; +import android.app.Activity; import android.content.Context; import androidx.annotation.VisibleForTesting; @@ -12,6 +13,7 @@ import org.chromium.base.IntStringCallback; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.NativeMethods; +import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; import org.chromium.components.browser_ui.settings.SettingsLauncher; /** @@ -111,8 +113,11 @@ } @Override - public boolean shouldShowMigrationWarning() { - return PasswordUIViewJni.get().shouldShowMigrationWarning(); + public void showMigrationWarning( + Activity activity, BottomSheetController bottomSheetController) { + if (mNativePasswordUIViewAndroid == 0) return; + PasswordUIViewJni.get().showMigrationWarning( + mNativePasswordUIViewAndroid, activity, bottomSheetController); } /** @@ -173,6 +178,7 @@ SettingsLauncher launcher, int index, PasswordUIView caller); void handleShowBlockedCredentialView(long nativePasswordUIViewAndroid, Context context, SettingsLauncher launcher, int index, PasswordUIView caller); - boolean shouldShowMigrationWarning(); + void showMigrationWarning(long nativePasswordUIViewAndroid, Activity activity, + BottomSheetController bottomSheetController); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/AddressEditor.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/AddressEditor.java index a40fff5..7407a5b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/AddressEditor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/AddressEditor.java
@@ -13,6 +13,7 @@ import static org.chromium.chrome.browser.autofill.editors.EditorProperties.DropdownFieldProperties.DROPDOWN_KEY_VALUE_LIST; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.EDITOR_FIELDS; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.EDITOR_TITLE; +import static org.chromium.chrome.browser.autofill.editors.EditorProperties.FORM_VALID; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.FieldProperties.CUSTOM_ERROR_MESSAGE; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.FieldProperties.INVALID_ERROR_MESSAGE; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.FieldProperties.IS_FULL_LINE; @@ -24,11 +25,9 @@ import static org.chromium.chrome.browser.autofill.editors.EditorProperties.ItemType.DROPDOWN; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.ItemType.TEXT_INPUT; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.SHOW_REQUIRED_INDICATOR; -import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.LENGTH_COUNTER_LIMIT_NONE; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.TEXT_ALL_KEYS; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.TEXT_FORMATTER; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.TEXT_INPUT_TYPE; -import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.TEXT_LENGTH_COUNTER_LIMIT; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.TEXT_SUGGESTIONS; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextInputType.ALPHA_NUMERIC_INPUT; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextInputType.PERSON_NAME_INPUT; @@ -37,6 +36,7 @@ import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextInputType.REGION_INPUT; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextInputType.STREET_ADDRESS_INPUT; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.VISIBLE; +import static org.chromium.chrome.browser.autofill.editors.EditorProperties.isFormValid; import android.app.ProgressDialog; import android.text.TextUtils; @@ -57,6 +57,7 @@ import org.chromium.chrome.browser.autofill.editors.EditorBase; import org.chromium.chrome.browser.autofill.editors.EditorDialogViewBinder; import org.chromium.chrome.browser.autofill.editors.EditorProperties.EditorFieldValidator; +import org.chromium.chrome.browser.autofill.editors.EditorProperties.ItemType; import org.chromium.payments.mojom.AddressErrors; import org.chromium.ui.modelutil.ListModel; import org.chromium.ui.modelutil.MVCListAdapter.ListItem; @@ -81,7 +82,7 @@ @Deprecated public class AddressEditor extends EditorBase<AutofillAddress> implements GetSubKeysRequestDelegate { - private final Map<Integer, ListItem> mAddressFields = new HashMap<>(); + private final Map<Integer, PropertyModel> mAddressFields = new HashMap<>(); private final Set<String> mPhoneNumbers = new HashSet<>(); private final boolean mSaveToDisk; private final PhoneNumberUtil.CountryAwareFormatTextWatcher mPhoneFormatter; @@ -93,9 +94,16 @@ @Nullable private PropertyModel mPhoneField; @Nullable + private PropertyModel mAdminAreaField; + private @ItemType int mAdminAreaFieldType; + @Nullable private List<AddressUiComponent> mAddressUiComponents; private boolean mAdminAreasLoaded; private String mRecentlySelectedCountry; + private Callback<AutofillAddress> mDoneCallback; + private Callback<AutofillAddress> mCancelCallback; + private boolean mAddressNew; + private AutofillAddress mAddress; private AutofillProfile mProfile; private ProgressDialog mProgressDialog; @Nullable @@ -184,22 +192,23 @@ final Callback<AutofillAddress> doneCallback, final Callback<AutofillAddress> cancelCallback) { super.edit(toEdit, doneCallback, cancelCallback); - if (mAutofillProfileBridge == null) mAutofillProfileBridge = new AutofillProfileBridge(); + mDoneCallback = doneCallback; + mCancelCallback = cancelCallback; // If |toEdit| is null, we're creating a new autofill profile with the country code of the // default locale on this device. final String editTitle; - final AutofillAddress address; - if (toEdit == null) { - address = new AutofillAddress(mContext, AutofillProfile.builder().build()); + mAddressNew = toEdit == null; + if (mAddressNew) { + mAddress = new AutofillAddress(mContext, AutofillProfile.builder().build()); editTitle = mContext.getString(R.string.autofill_create_profile); } else { - address = toEdit; + mAddress = toEdit; editTitle = toEdit.getEditTitle(); } - mProfile = address.getProfile(); + mProfile = mAddress.getProfile(); // When edit is called, a new form is started, so the country on the // dropdown list is not changed. => mRecentlySelectedCountry should be null. @@ -247,47 +256,40 @@ if (mAddressFields.isEmpty()) { // City, dependent locality, and organization don't have any special formatting hints. mAddressFields.put(AddressField.LOCALITY, - new ListItem(TEXT_INPUT, - new PropertyModel.Builder(TEXT_ALL_KEYS) - .with(TEXT_INPUT_TYPE, PLAIN_TEXT_INPUT) - .build())); + new PropertyModel.Builder(TEXT_ALL_KEYS) + .with(TEXT_INPUT_TYPE, PLAIN_TEXT_INPUT) + .build()); mAddressFields.put(AddressField.DEPENDENT_LOCALITY, - new ListItem(TEXT_INPUT, - new PropertyModel.Builder(TEXT_ALL_KEYS) - .with(TEXT_INPUT_TYPE, PLAIN_TEXT_INPUT) - .build())); + new PropertyModel.Builder(TEXT_ALL_KEYS) + .with(TEXT_INPUT_TYPE, PLAIN_TEXT_INPUT) + .build()); mAddressFields.put(AddressField.ORGANIZATION, - new ListItem(TEXT_INPUT, - new PropertyModel.Builder(TEXT_ALL_KEYS) - .with(TEXT_INPUT_TYPE, PLAIN_TEXT_INPUT) - .build())); + new PropertyModel.Builder(TEXT_ALL_KEYS) + .with(TEXT_INPUT_TYPE, PLAIN_TEXT_INPUT) + .build()); // Sorting code and postal code (a.k.a. ZIP code) should show both letters and digits on // the keyboard, if possible. mAddressFields.put(AddressField.SORTING_CODE, - new ListItem(TEXT_INPUT, - new PropertyModel.Builder(TEXT_ALL_KEYS) - .with(TEXT_INPUT_TYPE, ALPHA_NUMERIC_INPUT) - .build())); + new PropertyModel.Builder(TEXT_ALL_KEYS) + .with(TEXT_INPUT_TYPE, ALPHA_NUMERIC_INPUT) + .build()); mAddressFields.put(AddressField.POSTAL_CODE, - new ListItem(TEXT_INPUT, - new PropertyModel.Builder(TEXT_ALL_KEYS) - .with(TEXT_INPUT_TYPE, ALPHA_NUMERIC_INPUT) - .build())); + new PropertyModel.Builder(TEXT_ALL_KEYS) + .with(TEXT_INPUT_TYPE, ALPHA_NUMERIC_INPUT) + .build()); // Street line field can contain \n to indicate line breaks. mAddressFields.put(AddressField.STREET_ADDRESS, - new ListItem(TEXT_INPUT, - new PropertyModel.Builder(TEXT_ALL_KEYS) - .with(TEXT_INPUT_TYPE, STREET_ADDRESS_INPUT) - .build())); + new PropertyModel.Builder(TEXT_ALL_KEYS) + .with(TEXT_INPUT_TYPE, STREET_ADDRESS_INPUT) + .build()); // Android has special formatting rules for names. mAddressFields.put(AddressField.RECIPIENT, - new ListItem(TEXT_INPUT, - new PropertyModel.Builder(TEXT_ALL_KEYS) - .with(TEXT_INPUT_TYPE, PERSON_NAME_INPUT) - .build())); + new PropertyModel.Builder(TEXT_ALL_KEYS) + .with(TEXT_INPUT_TYPE, PERSON_NAME_INPUT) + .build()); } // Phone number is present for all countries. @@ -309,7 +311,6 @@ mContext.getString( R.string.payments_phone_invalid_validation_message)) .with(IS_FULL_LINE, true) - .with(TEXT_LENGTH_COUNTER_LIMIT, LENGTH_COUNTER_LIMIT_NONE) .build(); } @@ -317,44 +318,59 @@ // that's being edited. mPhoneField.set(VALUE, mProfile.getPhoneNumber()); - // If the user clicks [Cancel], send |toEdit| address back to the caller, which was the - // original state (could be null, a complete address, a partial address). - Runnable onCancel = () -> { - // This makes sure that onSubKeysReceived returns early if it's - // ever called when Cancel has already occurred. - mAdminAreasLoaded = true; - PersonalDataManager.getInstance().cancelPendingGetSubKeys(); - cancelCallback.onResult(toEdit); - - // Clean up the state of this editor. - reset(); - }; - - // If the user clicks [Done], save changes on disk, mark the address "complete" if possible, - // and send it back to the caller. - Runnable onDone = () -> { - mAdminAreasLoaded = true; - PersonalDataManager.getInstance().cancelPendingGetSubKeys(); - commitChanges(mProfile); - address.completeAddress(mProfile); - doneCallback.onResult(address); - - // Clean up the state of this editor. - reset(); - }; - mEditorModel = new PropertyModel.Builder(ALL_KEYS) .with(EDITOR_TITLE, editTitle) .with(SHOW_REQUIRED_INDICATOR, true) .with(EDITOR_FIELDS, new ListModel()) - .with(DONE_RUNNABLE, onDone) - .with(CANCEL_RUNNABLE, onCancel) + .with(DONE_RUNNABLE, this::onDone) + .with(CANCEL_RUNNABLE, this::onCancel) + .with(FORM_VALID, true) .build(); mEditorMCP = PropertyModelChangeProcessor.create( mEditorModel, mEditorDialog, EditorDialogViewBinder::bindEditorDialogView); loadAdminAreasForCountry(mCountryField.get(VALUE)); - if (mAddressErrors != null) mEditorDialog.validateForm(); + mEditorModel.set(FORM_VALID, mAddressErrors == null || isFormValid(mEditorModel)); + } + + private void onDone() { + if (!isFormValid(mEditorModel)) { + // Note: triggering editor error messages and focused field update using temporary + // property. + // TODO(crbug.com/1435314): remove this temporary logic. + mEditorModel.set(FORM_VALID, true); + mEditorModel.set(FORM_VALID, false); + return; + } + mEditorModel.set(VISIBLE, false); + + // This makes sure that onSubKeysReceived returns early if it's + // ever called when Done has already occurred. + mAdminAreasLoaded = true; + PersonalDataManager.getInstance().cancelPendingGetSubKeys(); + + // Commit changes to the address and send modified address to the caller. + commitChanges(mProfile); + mAddress.completeAddress(mProfile); + mDoneCallback.onResult(mAddress); + + // Clean up the state of this editor. + reset(); + } + + private void onCancel() { + mEditorModel.set(VISIBLE, false); + + // This makes sure that onSubKeysReceived returns early if it's + // ever called when Cancel has already occurred. + mAdminAreasLoaded = true; + PersonalDataManager.getInstance().cancelPendingGetSubKeys(); + + // Send unchanged address to the caller. + mCancelCallback.onResult(mAddressNew ? null : mAddress); + + // Clean up the state of this editor. + reset(); } private void showProgressDialog() { @@ -385,15 +401,17 @@ for (int i = 0; i < mAddressUiComponents.size(); i++) { AddressUiComponent component = mAddressUiComponents.get(i); visibleFields.add(component.id); + PropertyModel fieldModel = component.id == AddressField.ADMIN_AREA + ? mAdminAreaField + : mAddressFields.get(component.id); if (component.id != AddressField.COUNTRY) { - setProfileField( - profile, component.id, mAddressFields.get(component.id).model.get(VALUE)); + setProfileField(profile, component.id, fieldModel.get(VALUE)); } } // Clear the fields that are hidden from the user interface, so // AutofillAddress.toPaymentAddress() will send them to the renderer as empty strings. - for (Map.Entry<Integer, ListItem> entry : mAddressFields.entrySet()) { + for (Map.Entry<Integer, PropertyModel> entry : mAddressFields.entrySet()) { if (!visibleFields.contains(entry.getKey())) { setProfileField(profile, entry.getKey(), ""); } @@ -459,10 +477,11 @@ private void setAddressFieldValuesFromCache() { // Address fields are cached, so their values need to be updated for every new profile // that's being edited. - for (Map.Entry<Integer, ListItem> entry : mAddressFields.entrySet()) { - entry.getValue().model.set( - VALUE, AutofillAddress.getProfileField(mProfile, entry.getKey())); + for (Map.Entry<Integer, PropertyModel> entry : mAddressFields.entrySet()) { + entry.getValue().set(VALUE, AutofillAddress.getProfileField(mProfile, entry.getKey())); } + mAdminAreaField.set( + VALUE, AutofillAddress.getProfileField(mProfile, AddressField.ADMIN_AREA)); } @Override @@ -475,22 +494,7 @@ // subkeys. if (mEditorDialog.isDismissed()) return; - // When there is a timeout in the subkey request process, the admin area codes/names will be - // null. - mAddressFields.put(AddressField.ADMIN_AREA, - (adminAreaCodes != null && adminAreaNames != null && adminAreaCodes.length != 0 - && adminAreaCodes.length == adminAreaNames.length) - ? new ListItem(DROPDOWN, - new PropertyModel.Builder(DROPDOWN_ALL_KEYS) - .with(DROPDOWN_KEY_VALUE_LIST, - AutofillProfileBridge.getAdminAreaDropdownList( - adminAreaCodes, adminAreaNames)) - .with(DROPDOWN_HINT, mContext.getString(R.string.select)) - .build()) - : new ListItem(TEXT_INPUT, - new PropertyModel.Builder(TEXT_ALL_KEYS) - .with(TEXT_INPUT_TYPE, REGION_INPUT) - .build())); + initializeAdminAreaField(adminAreaCodes, adminAreaNames); // Admin areas need to be fetched in two cases: // 1. Initial loading of the form. @@ -512,13 +516,25 @@ } } - private static boolean contains(String[] haystack, String needle) { - if (haystack == null || haystack.length == 0) return false; - if (TextUtils.isEmpty(needle)) return true; - for (int i = 0; i < haystack.length; ++i) { - if (TextUtils.equals(haystack[i], needle)) return true; + private void initializeAdminAreaField( + @Nullable String[] adminAreaCodes, @Nullable String[] adminAreaNames) { + // When there is a timeout in the subkey request process, the admin area codes/names will be + // null. + if (adminAreaCodes == null || adminAreaNames == null || adminAreaCodes.length == 0 + || adminAreaCodes.length != adminAreaNames.length) { + mAdminAreaField = new PropertyModel.Builder(TEXT_ALL_KEYS) + .with(TEXT_INPUT_TYPE, REGION_INPUT) + .build(); + mAdminAreaFieldType = TEXT_INPUT; + return; } - return false; + mAdminAreaField = new PropertyModel.Builder(DROPDOWN_ALL_KEYS) + .with(DROPDOWN_KEY_VALUE_LIST, + AutofillProfileBridge.getAdminAreaDropdownList( + adminAreaCodes, adminAreaNames)) + .with(DROPDOWN_HINT, mContext.getString(R.string.select)) + .build(); + mAdminAreaFieldType = DROPDOWN; } /** Requests the list of admin areas. */ @@ -554,8 +570,15 @@ for (int i = 0; i < mAddressUiComponents.size(); i++) { AddressUiComponent component = mAddressUiComponents.get(i); - ListItem fieldItem = mAddressFields.get(component.id); - PropertyModel field = fieldItem.model; + final PropertyModel field; + final @ItemType int fieldType; + if (component.id == AddressField.ADMIN_AREA) { + field = mAdminAreaField; + fieldType = mAdminAreaFieldType; + } else { + field = mAddressFields.get(component.id); + fieldType = TEXT_INPUT; + } // Labels depend on country, e.g., state is called province in some countries. These are // already localized. @@ -574,7 +597,7 @@ } field.set(CUSTOM_ERROR_MESSAGE, getAddressError(component.id)); - editorFields.add(fieldItem); + editorFields.add(new ListItem(fieldType, field)); } // Phone number (and email if applicable) are the last fields of the address. mPhoneField.set(CUSTOM_ERROR_MESSAGE, mAddressErrors != null ? mAddressErrors.phone : null); @@ -610,10 +633,5 @@ return !TextUtils.isEmpty(value) && PhoneNumberUtil.isPossibleNumber(value, mCountryCode); } - - @Override - public boolean isLengthMaximum(@Nullable String value) { - return false; - } } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ContactEditor.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ContactEditor.java index d2daad9..41103bd4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ContactEditor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ContactEditor.java
@@ -9,6 +9,7 @@ import static org.chromium.chrome.browser.autofill.editors.EditorProperties.DONE_RUNNABLE; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.EDITOR_FIELDS; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.EDITOR_TITLE; +import static org.chromium.chrome.browser.autofill.editors.EditorProperties.FORM_VALID; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.FieldProperties.CUSTOM_ERROR_MESSAGE; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.FieldProperties.INVALID_ERROR_MESSAGE; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.FieldProperties.IS_FULL_LINE; @@ -19,16 +20,15 @@ import static org.chromium.chrome.browser.autofill.editors.EditorProperties.FieldProperties.VALUE; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.ItemType.TEXT_INPUT; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.SHOW_REQUIRED_INDICATOR; -import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.LENGTH_COUNTER_LIMIT_NONE; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.TEXT_ALL_KEYS; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.TEXT_FORMATTER; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.TEXT_INPUT_TYPE; -import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.TEXT_LENGTH_COUNTER_LIMIT; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.TEXT_SUGGESTIONS; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextInputType.EMAIL_ADDRESS_INPUT; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextInputType.PERSON_NAME_INPUT; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextInputType.PHONE_NUMBER_INPUT; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.VISIBLE; +import static org.chromium.chrome.browser.autofill.editors.EditorProperties.isFormValid; import android.telephony.PhoneNumberUtils; import android.text.TextUtils; @@ -85,6 +85,13 @@ private EditorFieldValidator mPhoneValidator; @Nullable private EditorFieldValidator mEmailValidator; + private boolean mContactNew; + private AutofillContact mContact; + private Optional<PropertyModel> mNameField; + private Optional<PropertyModel> mPhoneField; + private Optional<PropertyModel> mEmailField; + private Callback<AutofillContact> mDoneCallback; + private Callback<AutofillContact> mCancelCallback; /** * Builds a contact information editor. @@ -204,15 +211,17 @@ final Callback<AutofillContact> doneCallback, final Callback<AutofillContact> cancelCallback) { super.edit(toEdit, doneCallback, cancelCallback); + mDoneCallback = doneCallback; + mCancelCallback = cancelCallback; - final AutofillContact contact = toEdit == null - ? new AutofillContact(mContext, AutofillProfile.builder().build(), null, null, null, - INVALID_NAME | INVALID_PHONE_NUMBER | INVALID_EMAIL, mRequestPayerName, - mRequestPayerPhone, mRequestPayerEmail) - : toEdit; + mContactNew = toEdit == null; + mContact = mContactNew ? new AutofillContact(mContext, AutofillProfile.builder().build(), + null, null, null, INVALID_NAME | INVALID_PHONE_NUMBER | INVALID_EMAIL, + mRequestPayerName, mRequestPayerPhone, mRequestPayerEmail) + : toEdit; final String nameCustomErrorMessage = mPayerErrors != null ? mPayerErrors.name : null; - final Optional<PropertyModel> nameField = Optional.ofNullable(mRequestPayerName + mNameField = Optional.ofNullable(mRequestPayerName ? new PropertyModel.Builder(TEXT_ALL_KEYS) .with(TEXT_INPUT_TYPE, PERSON_NAME_INPUT) .with(LABEL, @@ -225,13 +234,12 @@ R.string.pref_edit_dialog_field_required_validation_message)) .with(CUSTOM_ERROR_MESSAGE, nameCustomErrorMessage) .with(IS_FULL_LINE, true) - .with(TEXT_LENGTH_COUNTER_LIMIT, LENGTH_COUNTER_LIMIT_NONE) - .with(VALUE, contact.getPayerName()) + .with(VALUE, mContact.getPayerName()) .build() : null); final String phoneCustomErrorMessage = mPayerErrors != null ? mPayerErrors.phone : null; - final Optional<PropertyModel> phoneField = Optional.ofNullable(mRequestPayerPhone + mPhoneField = Optional.ofNullable(mRequestPayerPhone ? new PropertyModel.Builder(TEXT_ALL_KEYS) .with(TEXT_INPUT_TYPE, PHONE_NUMBER_INPUT) .with(LABEL, @@ -250,13 +258,12 @@ R.string.payments_phone_invalid_validation_message)) .with(CUSTOM_ERROR_MESSAGE, phoneCustomErrorMessage) .with(IS_FULL_LINE, true) - .with(TEXT_LENGTH_COUNTER_LIMIT, LENGTH_COUNTER_LIMIT_NONE) - .with(VALUE, contact.getPayerPhone()) + .with(VALUE, mContact.getPayerPhone()) .build() : null); final String emailCustomErrorMessage = mPayerErrors != null ? mPayerErrors.email : null; - final Optional<PropertyModel> emailField = Optional.ofNullable(mRequestPayerEmail + mEmailField = Optional.ofNullable(mRequestPayerEmail ? new PropertyModel.Builder(TEXT_ALL_KEYS) .with(TEXT_INPUT_TYPE, EMAIL_ADDRESS_INPUT) .with(LABEL, @@ -273,8 +280,7 @@ R.string.payments_email_invalid_validation_message)) .with(CUSTOM_ERROR_MESSAGE, emailCustomErrorMessage) .with(IS_FULL_LINE, true) - .with(TEXT_LENGTH_COUNTER_LIMIT, LENGTH_COUNTER_LIMIT_NONE) - .with(VALUE, contact.getPayerEmail()) + .with(VALUE, mContact.getPayerEmail()) .build() : null); @@ -283,77 +289,88 @@ : toEdit.getEditTitle(); ListModel<ListItem> editorFields = new ListModel<>(); - if (nameField.isPresent()) { - editorFields.add(new ListItem(TEXT_INPUT, nameField.get())); + if (mNameField.isPresent()) { + editorFields.add(new ListItem(TEXT_INPUT, mNameField.get())); } - if (phoneField.isPresent()) { - editorFields.add(new ListItem(TEXT_INPUT, phoneField.get())); + if (mPhoneField.isPresent()) { + editorFields.add(new ListItem(TEXT_INPUT, mPhoneField.get())); } - if (emailField.isPresent()) { - editorFields.add(new ListItem(TEXT_INPUT, emailField.get())); + if (mEmailField.isPresent()) { + editorFields.add(new ListItem(TEXT_INPUT, mEmailField.get())); } - // If the user clicks [Cancel], send |toEdit| contact back to the caller, which was the - // original state (could be null, a complete contact, a partial contact). - Runnable onCancel = () -> { - cancelCallback.onResult(toEdit); - - // Clean up the state of this editor. - reset(); - }; - - Runnable onDone = () -> { - String name = null; - String phone = null; - String email = null; - AutofillProfile profile = contact.getProfile(); - - if (nameField.isPresent()) { - name = nameField.get().get(VALUE); - profile.setFullName(name); - } - - if (phoneField.isPresent()) { - phone = phoneField.get().get(VALUE); - profile.setPhoneNumber(phone); - } - - if (emailField.isPresent()) { - email = emailField.get().get(VALUE); - profile.setEmailAddress(email); - } - - if (mSaveToDisk) { - profile.setGUID(PersonalDataManager.getInstance().setProfileToLocal(profile)); - } - - if (profile.getGUID().isEmpty()) { - assert !mSaveToDisk; - - // Set a fake guid for a new temp AutofillProfile. - profile.setGUID(UUID.randomUUID().toString()); - } - - profile.setIsLocal(true); - contact.completeContact(profile.getGUID(), name, phone, email); - doneCallback.onResult(contact); - - // Clean up the state of this editor. - reset(); - }; - mEditorModel = new PropertyModel.Builder(ALL_KEYS) .with(EDITOR_TITLE, editorTitle) .with(SHOW_REQUIRED_INDICATOR, true) .with(EDITOR_FIELDS, editorFields) - .with(DONE_RUNNABLE, onDone) - .with(CANCEL_RUNNABLE, onCancel) + .with(DONE_RUNNABLE, this::onDone) + .with(CANCEL_RUNNABLE, this::onCancel) + .with(FORM_VALID, true) .build(); mEditorMCP = PropertyModelChangeProcessor.create( mEditorModel, mEditorDialog, EditorDialogViewBinder::bindEditorDialogView); mEditorModel.set(VISIBLE, true); - if (mPayerErrors != null) mEditorDialog.validateForm(); + mEditorModel.set(FORM_VALID, mPayerErrors == null || isFormValid(mEditorModel)); + } + + private void onDone() { + if (!isFormValid(mEditorModel)) { + // Note: triggering editor error messages and focused field update using temporary + // property. + // TODO(crbug.com/1435314): remove this temporary logic. + mEditorModel.set(FORM_VALID, true); + mEditorModel.set(FORM_VALID, false); + return; + } + mEditorModel.set(VISIBLE, false); + + String name = null; + String phone = null; + String email = null; + AutofillProfile profile = mContact.getProfile(); + + if (mNameField.isPresent()) { + name = mNameField.get().get(VALUE); + profile.setFullName(name); + } + + if (mPhoneField.isPresent()) { + phone = mPhoneField.get().get(VALUE); + profile.setPhoneNumber(phone); + } + + if (mEmailField.isPresent()) { + email = mEmailField.get().get(VALUE); + profile.setEmailAddress(email); + } + + if (mSaveToDisk) { + profile.setGUID(PersonalDataManager.getInstance().setProfileToLocal(profile)); + } + + if (profile.getGUID().isEmpty()) { + assert !mSaveToDisk; + + // Set a fake guid for a new temp AutofillProfile. + profile.setGUID(UUID.randomUUID().toString()); + } + + profile.setIsLocal(true); + mContact.completeContact(profile.getGUID(), name, phone, email); + mDoneCallback.onResult(mContact); + + // Clean up the state of this editor. + reset(); + } + + private void onCancel() { + mEditorModel.set(VISIBLE, false); + + mCancelCallback.onResult(mContactNew ? null : mContact); + + // Clean up the state of this editor. + reset(); } private EditorFieldValidator getPhoneValidator() { @@ -369,11 +386,6 @@ PhoneNumberUtils.stripSeparators(value)); } } - - @Override - public boolean isLengthMaximum(@Nullable String value) { - return false; - } }; } return mPhoneValidator; @@ -386,11 +398,6 @@ public boolean isValid(@Nullable String value) { return value != null && Patterns.EMAIL_ADDRESS.matcher(value).matches(); } - - @Override - public boolean isLengthMaximum(@Nullable String value) { - return false; - } }; } return mEmailValidator;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java index 747ed23..78c5a22 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java
@@ -75,6 +75,7 @@ import org.chromium.components.browser_ui.accessibility.AccessibilitySettings; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; import org.chromium.components.browser_ui.bottomsheet.BottomSheetControllerFactory; +import org.chromium.components.browser_ui.bottomsheet.ManagedBottomSheetController; import org.chromium.components.browser_ui.modaldialog.AppModalPresenter; import org.chromium.components.browser_ui.settings.CustomDividerFragment; import org.chromium.components.browser_ui.settings.FragmentSettingsLauncher; @@ -122,7 +123,7 @@ private ScrimCoordinator mScrim; - private BottomSheetController mBottomSheetController; + private ManagedBottomSheetController mBottomSheetController; private OneshotSupplierImpl<BottomSheetController> mBottomSheetControllerSupplier = new OneshotSupplierImpl<>(); @@ -403,6 +404,14 @@ } private void initBackPressHandler() { + // Handlers registered last will be called first. + registerMainFragmentBackPressHandler(); + if (ChromeFeatureList.sPrivacyGuidePostMVP.isEnabled()) { + registerBottomSheetBackPressHandler(); + } + } + + private void registerMainFragmentBackPressHandler() { Fragment activeFragment = getMainFragment(); if (BackPressManager.isSecondaryActivityEnabled()) { if (activeFragment instanceof BackPressHandler) { @@ -418,6 +427,22 @@ } } + private void registerBottomSheetBackPressHandler() { + if (mBottomSheetController == null) return; + + BackPressHandler bottomSheetBackPressHandler = + mBottomSheetController.getBottomSheetBackPressHandler(); + if (bottomSheetBackPressHandler != null) { + if (BackPressManager.isSecondaryActivityEnabled()) { + BackPressHelper.create(this, getOnBackPressedDispatcher(), + bottomSheetBackPressHandler, SecondaryActivity.SETTINGS); + } else { + BackPressHelper.create(this, getOnBackPressedDispatcher(), + mBottomSheetController::handleBackPress, SecondaryActivity.SETTINGS); + } + } + } + @Override public void onAttachFragment(Fragment fragment) { if (fragment instanceof ProfileDependentSetting) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/settings/FakePasswordManagerHandler.java b/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/settings/FakePasswordManagerHandler.java index 5ea4ab7c..d527978e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/settings/FakePasswordManagerHandler.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/settings/FakePasswordManagerHandler.java
@@ -4,12 +4,14 @@ package org.chromium.chrome.browser.password_manager.settings; +import android.app.Activity; import android.content.Context; import androidx.annotation.Nullable; import org.chromium.base.Callback; import org.chromium.base.IntStringCallback; +import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; import org.chromium.components.browser_ui.settings.SettingsLauncher; import java.util.ArrayList; @@ -38,7 +40,7 @@ @Nullable private String mExportTargetPath; - private boolean mShouldShowWarning; + private boolean mShowWarningWasCalled; private int mSerializationInvocationCount; @@ -49,11 +51,6 @@ void setSavedPasswordExceptions(ArrayList<String> savedPasswordExceptions) { mSavedPasswordExeptions = savedPasswordExceptions; } - - void setShouldShowWarning(boolean shouldShowWarning) { - mShouldShowWarning = shouldShowWarning; - } - IntStringCallback getExportSuccessCallback() { return mExportSuccessCallback; } @@ -66,6 +63,10 @@ return mExportTargetPath; } + boolean wasShowWarningCalled() { + return mShowWarningWasCalled; + } + /** * Constructor. * @param observer The only observer. @@ -122,10 +123,10 @@ Context context, SettingsLauncher launcher, int index, boolean isBlockedCredential) { assert false : "Define this method before starting to use it in tests."; } - @Override - public boolean shouldShowMigrationWarning() { - return mShouldShowWarning; + public void showMigrationWarning( + Activity activity, BottomSheetController bottomSheetController) { + mShowWarningWasCalled = true; } public int getSerializationInvocationCount() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettingsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettingsTest.java index 73aacff..a42751a5 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettingsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettingsTest.java
@@ -4,13 +4,13 @@ package org.chromium.chrome.browser.password_manager.settings; -import static androidx.test.espresso.matcher.ViewMatchers.withId; import static androidx.test.espresso.matcher.ViewMatchers.withText; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.when; import static org.chromium.ui.test.util.ViewUtils.onViewWaiting; -import static org.chromium.ui.test.util.ViewUtils.waitForView; import androidx.test.filters.MediumTest; import androidx.test.filters.SmallTest; @@ -47,7 +47,6 @@ import org.chromium.components.sync.SyncService; import org.chromium.components.user_prefs.UserPrefs; import org.chromium.content_public.browser.test.util.TestThreadUtils; -import org.chromium.ui.test.util.ViewUtils; /** * Tests for the "Passwords" settings screen. These tests are not batchable (without significant @@ -139,16 +138,16 @@ ChromeSwitchPreference onOffSwitch = (ChromeSwitchPreference) savedPasswordPrefs.findPreference( PasswordSettings.PREF_SAVE_PASSWORDS_SWITCH); - Assert.assertTrue(onOffSwitch.isChecked()); + assertTrue(onOffSwitch.isChecked()); onOffSwitch.performClick(); - Assert.assertFalse(getPrefService().getBoolean(Pref.CREDENTIALS_ENABLE_SERVICE)); + assertFalse(getPrefService().getBoolean(Pref.CREDENTIALS_ENABLE_SERVICE)); Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( OFFER_TO_SAVE_PASSWORDS_HISTOGRAM, 0)); onOffSwitch.performClick(); - Assert.assertTrue(getPrefService().getBoolean(Pref.CREDENTIALS_ENABLE_SERVICE)); + assertTrue(getPrefService().getBoolean(Pref.CREDENTIALS_ENABLE_SERVICE)); Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( OFFER_TO_SAVE_PASSWORDS_HISTOGRAM, 1)); @@ -165,7 +164,7 @@ ChromeSwitchPreference onOffSwitch = (ChromeSwitchPreference) savedPasswordPrefs.findPreference( PasswordSettings.PREF_SAVE_PASSWORDS_SWITCH); - Assert.assertFalse(onOffSwitch.isChecked()); + assertFalse(onOffSwitch.isChecked()); }); } @@ -269,15 +268,15 @@ ChromeSwitchPreference onOffSwitch = (ChromeSwitchPreference) passwordPrefs.findPreference( PasswordSettings.PREF_AUTOSIGNIN_SWITCH); - Assert.assertTrue(onOffSwitch.isChecked()); + assertTrue(onOffSwitch.isChecked()); onOffSwitch.performClick(); - Assert.assertFalse(getPrefService().getBoolean(Pref.CREDENTIALS_ENABLE_AUTOSIGNIN)); + assertFalse(getPrefService().getBoolean(Pref.CREDENTIALS_ENABLE_AUTOSIGNIN)); Assert.assertEquals( 1, RecordHistogram.getHistogramValueCountForTesting(AUTO_SIGNIN_HISTOGRAM, 0)); onOffSwitch.performClick(); - Assert.assertTrue(getPrefService().getBoolean(Pref.CREDENTIALS_ENABLE_AUTOSIGNIN)); + assertTrue(getPrefService().getBoolean(Pref.CREDENTIALS_ENABLE_AUTOSIGNIN)); Assert.assertEquals( 1, RecordHistogram.getHistogramValueCountForTesting(AUTO_SIGNIN_HISTOGRAM, 1)); @@ -292,7 +291,7 @@ ChromeSwitchPreference onOffSwitch = (ChromeSwitchPreference) passwordPrefs.findPreference( PasswordSettings.PREF_AUTOSIGNIN_SWITCH); - Assert.assertFalse(onOffSwitch.isChecked()); + assertFalse(onOffSwitch.isChecked()); }); } @@ -342,12 +341,10 @@ @Feature({"Preferences"}) public void testLocalPasswordsMigrationSheetTriggeredWhenShouldShow() { mTestHelper.setPasswordSourceWithMultipleEntries(PasswordSettingsTestHelper.GREEK_GODS); + assertFalse(mTestHelper.getHandler().wasShowWarningCalled()); SettingsActivity activity = mTestHelper.startPasswordSettingsFromMainSettings( mPasswordSettingsActivityTestRule); - mTestHelper.getHandler().setShouldShowWarning(true); - waitForView( - withId(org.chromium.chrome.browser.pwd_migration.R.id.pwd_migration_warning_sheet), - ViewUtils.VIEW_VISIBLE); + assertTrue(mTestHelper.getHandler().wasShowWarningCalled()); } private static PrefService getPrefService() {
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/payments/AddressEditorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/payments/AddressEditorTest.java index 2c6fb3c..120562b 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/payments/AddressEditorTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/payments/AddressEditorTest.java
@@ -30,9 +30,7 @@ import static org.chromium.chrome.browser.autofill.editors.EditorProperties.ItemType.DROPDOWN; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.ItemType.TEXT_INPUT; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.SHOW_REQUIRED_INDICATOR; -import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.LENGTH_COUNTER_LIMIT_NONE; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.TEXT_INPUT_TYPE; -import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.TEXT_LENGTH_COUNTER_LIMIT; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.setDropdownKey; import android.app.Activity; @@ -63,6 +61,8 @@ import org.chromium.chrome.browser.autofill.AutofillProfileBridgeJni; import org.chromium.chrome.browser.autofill.PersonalDataManager; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; +import org.chromium.chrome.browser.autofill.PhoneNumberUtil; +import org.chromium.chrome.browser.autofill.PhoneNumberUtilJni; import org.chromium.chrome.browser.autofill.editors.EditorDialogView; import org.chromium.chrome.browser.autofill.editors.EditorProperties.DropdownKeyValue; import org.chromium.chrome.browser.autofill.editors.EditorProperties.TextInputType; @@ -124,6 +124,8 @@ @Mock private AutofillProfileBridge.Natives mAutofillProfileBridgeJni; + @Mock + private PhoneNumberUtil.Natives mPhoneNumberUtilJni; @Mock private EditorDialogView mEditorDialog; @@ -160,6 +162,8 @@ }) .when(mAutofillProfileBridgeJni) .getRequiredFields(anyString(), anyList()); + mJniMocker.mock(PhoneNumberUtilJni.TEST_HOOKS, mPhoneNumberUtilJni); + when(mPhoneNumberUtilJni.isPossibleNumber(anyString(), anyString())).thenReturn(true); mActivity = Robolectric.setupActivity(TestActivity.class); @@ -215,8 +219,8 @@ } private static void validateTextField(ListItem fieldItem, String value, - @TextInputType int textInputType, String label, boolean isRequired, boolean isFullLine, - int lengthCounter) { + @TextInputType int textInputType, String label, boolean isRequired, + boolean isFullLine) { assertEquals(TEXT_INPUT, fieldItem.type); PropertyModel field = fieldItem.model; @@ -225,7 +229,6 @@ assertEquals(label, field.get(LABEL)); assertEquals(isRequired, field.get(IS_REQUIRED)); assertEquals(isFullLine, field.get(IS_FULL_LINE)); - assertEquals(lengthCounter, field.get(TEXT_LENGTH_COUNTER_LIMIT)); } private void validateShownFields(PropertyModel editorModel, AutofillProfile profile) { @@ -247,15 +250,15 @@ validateTextField(editorFields.get(1), profile.getFullName(), TextInputType.PERSON_NAME_INPUT, /*label=*/"full name label", - /*isRequired=*/true, /*isFullLine=*/true, LENGTH_COUNTER_LIMIT_NONE); + /*isRequired=*/true, /*isFullLine=*/true); validateTextField(editorFields.get(2), profile.getRegion(), TextInputType.REGION_INPUT, /*label=*/"admin area label", - /*isRequired=*/true, /*isFullLine=*/true, LENGTH_COUNTER_LIMIT_NONE); + /*isRequired=*/true, /*isFullLine=*/true); // Locality field is forced to occupy full line. validateTextField(editorFields.get(3), profile.getLocality(), TextInputType.PLAIN_TEXT_INPUT, /*label=*/"locality label", - /*isRequired=*/true, /*isFullLine=*/true, LENGTH_COUNTER_LIMIT_NONE); + /*isRequired=*/true, /*isFullLine=*/true); // Note: dependent locality is a required field for address profiles stored in Google // account, but it's still marked as optional by the editor when the corresponding field in @@ -263,26 +266,26 @@ // profiles. validateTextField(editorFields.get(4), profile.getDependentLocality(), TextInputType.PLAIN_TEXT_INPUT, /*label=*/"dependent locality label", - /*isRequired=*/true, /*isFullLine=*/true, LENGTH_COUNTER_LIMIT_NONE); + /*isRequired=*/true, /*isFullLine=*/true); validateTextField(editorFields.get(5), profile.getCompanyName(), TextInputType.PLAIN_TEXT_INPUT, /*label=*/"organization label", - /*isRequired=*/false, /*isFullLine=*/true, LENGTH_COUNTER_LIMIT_NONE); + /*isRequired=*/false, /*isFullLine=*/true); validateTextField(editorFields.get(6), profile.getSortingCode(), TextInputType.ALPHA_NUMERIC_INPUT, /*label=*/"sorting code label", - /*isRequired=*/false, /*isFullLine=*/false, LENGTH_COUNTER_LIMIT_NONE); + /*isRequired=*/false, /*isFullLine=*/false); validateTextField(editorFields.get(7), profile.getPostalCode(), TextInputType.ALPHA_NUMERIC_INPUT, /*label=*/"postal code label", - /*isRequired=*/true, /*isFullLine=*/false, LENGTH_COUNTER_LIMIT_NONE); + /*isRequired=*/true, /*isFullLine=*/false); validateTextField(editorFields.get(8), profile.getStreetAddress(), TextInputType.STREET_ADDRESS_INPUT, /*label=*/"street address label", - /*isRequired=*/true, /*isFullLine=*/true, LENGTH_COUNTER_LIMIT_NONE); + /*isRequired=*/true, /*isFullLine=*/true); validateTextField(editorFields.get(9), profile.getPhoneNumber(), TextInputType.PHONE_NUMBER_INPUT, mActivity.getString(R.string.autofill_profile_editor_phone_number), - /*isRequired=*/true, /*isFullLine=*/true, LENGTH_COUNTER_LIMIT_NONE); + /*isRequired=*/true, /*isFullLine=*/true); } @Test @@ -344,7 +347,7 @@ validateTextField(editorFields.get(1), sProfile.getPhoneNumber(), TextInputType.PHONE_NUMBER_INPUT, mActivity.getString(R.string.autofill_profile_editor_phone_number), - /*isRequired=*/true, /*isFullLine=*/true, LENGTH_COUNTER_LIMIT_NONE); + /*isRequired=*/true, /*isFullLine=*/true); } @Test
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/payments/ContactEditorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/payments/ContactEditorTest.java index a1a3f83..0d20f5f 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/payments/ContactEditorTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/payments/ContactEditorTest.java
@@ -19,9 +19,7 @@ import static org.chromium.chrome.browser.autofill.editors.EditorProperties.FieldProperties.VALUE; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.ItemType.TEXT_INPUT; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.SHOW_REQUIRED_INDICATOR; -import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.LENGTH_COUNTER_LIMIT_NONE; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.TEXT_INPUT_TYPE; -import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.TEXT_LENGTH_COUNTER_LIMIT; import android.app.Activity; @@ -97,7 +95,6 @@ assertEquals(label, field.get(LABEL)); assertTrue(field.get(IS_REQUIRED)); assertTrue(field.get(IS_FULL_LINE)); - assertEquals(LENGTH_COUNTER_LIMIT_NONE, field.get(TEXT_LENGTH_COUNTER_LIMIT)); } @Test @@ -395,7 +392,7 @@ /*saveToDisk=*/false); editor.setEditorDialog(mEditorDialog); AutofillContact contact = new AutofillContact(mActivity, new AutofillProfile(sProfile), - null, "Payer phone", null, ContactEditor.COMPLETE, false, true, false); + null, "+4900000000000", null, ContactEditor.COMPLETE, false, true, false); editor.edit(contact, unused -> {}); PropertyModel editorModel = editor.getEditorModelForTesting(); @@ -403,13 +400,13 @@ ListModel<ListItem> editorFields = editorModel.get(EDITOR_FIELDS); assertEquals(1, editorFields.size()); - editorFields.get(0).model.set(VALUE, "Modified phone"); + editorFields.get(0).model.set(VALUE, "+490111111111"); editorModel.get(DONE_RUNNABLE).run(); assertNull(contact.getPayerName()); - assertEquals("Modified phone", contact.getPayerPhone()); + assertEquals("+490111111111", contact.getPayerPhone()); assertNull(contact.getPayerEmail()); - assertEquals("Modified phone", contact.getProfile().getPhoneNumber()); + assertEquals("+490111111111", contact.getProfile().getPhoneNumber()); } @Test @@ -421,7 +418,7 @@ /*saveToDisk=*/false); editor.setEditorDialog(mEditorDialog); AutofillContact contact = new AutofillContact(mActivity, new AutofillProfile(sProfile), - null, null, "Payer email", ContactEditor.COMPLETE, false, false, true); + null, null, "example@gmail.com", ContactEditor.COMPLETE, false, false, true); editor.edit(contact, unused -> {}); PropertyModel editorModel = editor.getEditorModelForTesting(); @@ -429,13 +426,13 @@ ListModel<ListItem> editorFields = editorModel.get(EDITOR_FIELDS); assertEquals(1, editorFields.size()); - editorFields.get(0).model.set(VALUE, "Modified email"); + editorFields.get(0).model.set(VALUE, "modified@gmail.com"); editorModel.get(DONE_RUNNABLE).run(); assertNull(contact.getPayerName()); assertNull(contact.getPayerPhone()); - assertEquals("Modified email", contact.getPayerEmail()); - assertEquals("Modified email", contact.getProfile().getEmailAddress()); + assertEquals("modified@gmail.com", contact.getPayerEmail()); + assertEquals("modified@gmail.com", contact.getProfile().getEmailAddress()); } @Test @@ -446,9 +443,9 @@ /*requestPayerEmail=*/true, /*saveToDisk=*/false); editor.setEditorDialog(mEditorDialog); - AutofillContact contact = - new AutofillContact(mActivity, new AutofillProfile(sProfile), "Payer name", - "Payer phone", "Payer email", ContactEditor.COMPLETE, true, true, true); + AutofillContact contact = new AutofillContact(mActivity, new AutofillProfile(sProfile), + "Payer name", "+4900000000000", "example@gmail.com", ContactEditor.COMPLETE, true, + true, true); editor.edit(contact, unused -> {}); PropertyModel editorModel = editor.getEditorModelForTesting(); @@ -457,15 +454,15 @@ ListModel<ListItem> editorFields = editorModel.get(EDITOR_FIELDS); assertEquals(3, editorFields.size()); editorFields.get(0).model.set(VALUE, "Modified name"); - editorFields.get(1).model.set(VALUE, "Modified phone"); - editorFields.get(2).model.set(VALUE, "Modified email"); + editorFields.get(1).model.set(VALUE, "+490111111111"); + editorFields.get(2).model.set(VALUE, "modified@gmail.com"); editorModel.get(DONE_RUNNABLE).run(); assertEquals("Modified name", contact.getPayerName()); - assertEquals("Modified phone", contact.getPayerPhone()); - assertEquals("Modified email", contact.getPayerEmail()); + assertEquals("+490111111111", contact.getPayerPhone()); + assertEquals("modified@gmail.com", contact.getPayerEmail()); assertEquals("Modified name", contact.getProfile().getFullName()); - assertEquals("Modified phone", contact.getProfile().getPhoneNumber()); - assertEquals("Modified email", contact.getProfile().getEmailAddress()); + assertEquals("+490111111111", contact.getProfile().getPhoneNumber()); + assertEquals("modified@gmail.com", contact.getProfile().getEmailAddress()); } }
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index f077884..c1339efe 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -9327,6 +9327,14 @@ (Chrome error pages) </message> + <!-- TODO(crbug.com/1433644): Add final string. --> + <message name="IDS_STORAGE_ACCESS_MANAGE_TEXT" translateable="false" desc="The text on the button to manage the StorageAcccess permission. The StorageAccess API is called 'Embedded content' in user visible UIs"> + Embedded content settings + </message> + <message name="IDS_STORAGE_ACCESS_MANAGE_TOOLTIP" translateable="false" desc="The tooltip on the button to manage the StorageAcccess permission. The StorageAccess API is called 'Embedded content' in user visible UIs"> + Go to embedded content settings + </message> + <!-- Automatic updates --> <if expr="is_macosx"> <message name="IDS_PROMOTE_INFOBAR_TEXT" desc="The text to show in the automatic update setup infobar. Mac-only.">
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 2c25378..51777c8 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -321,6 +321,8 @@ "component_updater/desktop_sharing_hub_component_remover.h", "component_updater/first_party_sets_component_installer.cc", "component_updater/first_party_sets_component_installer.h", + "component_updater/masked_domain_list_component_installer.cc", + "component_updater/masked_domain_list_component_installer.h", "component_updater/mei_preload_component_installer.cc", "component_updater/mei_preload_component_installer.h", "component_updater/pki_metadata_component_installer.cc", @@ -742,6 +744,8 @@ "media/webrtc/desktop_media_picker_manager.h", "media/webrtc/media_capture_devices_dispatcher.cc", "media/webrtc/media_capture_devices_dispatcher.h", + "media/webrtc/media_device_salt_service_factory.cc", + "media/webrtc/media_device_salt_service_factory.h", "media/webrtc/media_stream_capture_indicator.cc", "media/webrtc/media_stream_capture_indicator.h", "media/webrtc/media_stream_device_permission_context.cc",
diff --git a/chrome/browser/ash/login/oobe_quick_start/second_device_auth_broker.cc b/chrome/browser/ash/login/oobe_quick_start/second_device_auth_broker.cc index 9edc916..5f10d9d461 100644 --- a/chrome/browser/ash/login/oobe_quick_start/second_device_auth_broker.cc +++ b/chrome/browser/ash/login/oobe_quick_start/second_device_auth_broker.cc
@@ -80,14 +80,8 @@ constexpr char kHttpMethod[] = "POST"; constexpr char kHttpContentType[] = "application/json"; -constexpr char kGetChallengeDataRequest[] = R"( - { - "target_device_type": "CHROME_OS", - "target_droidguard_data": { - "target_droidguard_response": "1", - "device_id": "1", - "timestamp": "1" - } +constexpr char kGetChallengeDataRequest[] = R"({ + "target_device_type": "CHROME_OS" })"; constexpr auto kRejectionReasonErrorMap = base::MakeFixedFlatMap<
diff --git a/chrome/browser/ash/login/screens/gaia_screen.cc b/chrome/browser/ash/login/screens/gaia_screen.cc index d41a9bd4..3d67028 100644 --- a/chrome/browser/ash/login/screens/gaia_screen.cc +++ b/chrome/browser/ash/login/screens/gaia_screen.cc
@@ -13,7 +13,11 @@ #include "base/values.h" #include "chrome/browser/ash/login/ui/login_display_host.h" #include "chrome/browser/ash/login/wizard_context.h" +#include "chrome/browser/ash/policy/core/browser_policy_connector_ash.h" +#include "chrome/browser/ash/settings/cros_settings.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/browser_process_platform_part.h" +#include "chrome/browser/enterprise/util/managed_browser_utils.h" #include "chrome/browser/ui/webui/ash/login/gaia_screen_handler.h" #include "components/account_id/account_id.h" #include "components/user_manager/known_user.h" @@ -28,6 +32,7 @@ constexpr char kUserActionStartEnrollment[] = "startEnrollment"; constexpr char kUserActionReloadDefault[] = "reloadDefault"; constexpr char kUserActionRetry[] = "retry"; +constexpr char kUserActionEnterIdentifier[] = "identifierEntered"; bool ShouldPrepareForRecovery(const AccountId& account_id) { if (!features::IsCryptohomeRecoveryEnabled() || !account_id.is_valid()) { @@ -198,6 +203,10 @@ LoadOnline(EmptyAccountId()); } else if (action_id == kUserActionRetry) { LoadOnline(EmptyAccountId()); + } else if (action_id == kUserActionEnterIdentifier) { + CHECK_EQ(2u, args.size()); + const std::string& email = args[1].GetString(); + HandleIdentifierEntered(email); } else { BaseScreen::OnUserAction(args); } @@ -222,6 +231,16 @@ exit_callback_.Run(Result::CANCEL); } +void GaiaScreen::HandleIdentifierEntered(const std::string& user_email) { + if (MaybeTriggerEnrollmentNudge(user_email)) { + return; + } + + if (view_) { + view_->CheckIfAllowlisted(user_email); + } +} + void GaiaScreen::OnGetAuthFactorsConfiguration( std::unique_ptr<UserContext> user_context, absl::optional<AuthenticationError> error) { @@ -260,4 +279,43 @@ view_->LoadGaiaAsync(account); } +bool GaiaScreen::MaybeTriggerEnrollmentNudge(const std::string& user_email) { + const bool is_enterprise_managed = g_browser_process->platform_part() + ->browser_policy_connector_ash() + ->IsDeviceEnterpriseManaged(); + if (is_enterprise_managed) { + // Device either already went through enterprise enrollment flow or goes + // through it right now. No need for nudging. + return false; + } + const bool is_first_user = + user_manager::UserManager::Get()->GetUsers().empty(); + if (!is_first_user) { + // Enrollment nudge targets only initial OOBE flow on unowned devices. + // Current user is not a first user which means that device is already + // owned. + return false; + } + const std::string email_domain = + chrome::enterprise_util::GetDomainFromEmail(user_email); + if (chrome::enterprise_util::IsKnownConsumerDomain(email_domain)) { + // User doesn't belong to a managed domain, so enrollment nudging can't + // apply. + return false; + } + + // TODO(b/271104781): replace this check with a policy fetch through a special + // DM server API when it is available. + if (!ash::features::IsEnrollmentNudgingForTestingEnabled()) { + return false; + } + + if (!view_) { + return false; + } + + view_->ShowEnrollmentNudge(email_domain); + return true; +} + } // namespace ash
diff --git a/chrome/browser/ash/login/screens/gaia_screen.h b/chrome/browser/ash/login/screens/gaia_screen.h index 76821476..3f03bf4 100644 --- a/chrome/browser/ash/login/screens/gaia_screen.h +++ b/chrome/browser/ash/login/screens/gaia_screen.h
@@ -75,6 +75,7 @@ void HideImpl() override; void OnUserAction(const base::Value::List& args) override; bool HandleAccelerator(LoginAcceleratorAction action) override; + void HandleIdentifierEntered(const std::string& account_identifier); void OnGetAuthFactorsConfiguration(std::unique_ptr<UserContext> user_context, absl::optional<AuthenticationError> error); @@ -83,6 +84,10 @@ void OnGaiaReauthTokenFetched(const AccountId& account, const std::string& token); + // Triggers the enrollment nudge flow and returns true if all requirements are + // met, otherwise does nothing and returns false. + bool MaybeTriggerEnrollmentNudge(const std::string& user_email); + AuthFactorEditor auth_factor_editor_; std::unique_ptr<GaiaReauthTokenFetcher> gaia_reauth_token_fetcher_;
diff --git a/chrome/browser/ash/policy/dlp/files_policy_notification_manager_browsertest.cc b/chrome/browser/ash/policy/dlp/files_policy_notification_manager_browsertest.cc index 3f5ec021..e59e4510 100644 --- a/chrome/browser/ash/policy/dlp/files_policy_notification_manager_browsertest.cc +++ b/chrome/browser/ash/policy/dlp/files_policy_notification_manager_browsertest.cc
@@ -640,11 +640,20 @@ std::unique_ptr<policy::MockDlpFilesControllerAsh> files_controller_; }; +// TODO(crbug.com/1458326): Re-enable this test +#if defined(MEMORY_SANITIZER) +#define MAYBE_MultiFileOKShowsDialogOverFilesApp \ + DISABLED_MultiFileOKShowsDialogOverFilesApp +#else +#define MAYBE_MultiFileOKShowsDialogOverFilesApp \ + MultiFileOKShowsDialogOverFilesApp +#endif + // Tests that clicking the OK button on a warning notification shown for copy or // move IO task with multiple warning files shows a dialog instead of continuing // the action, and opens the Files App only if there's not one opened already. IN_PROC_BROWSER_TEST_P(OnIONotificationClickedTest, - MultiFileOKShowsDialogOverFilesApp) { + MAYBE_MultiFileOKShowsDialogOverFilesApp) { policy::GetIOTaskController(browser()->profile())->AddObserver(&observer_); auto [type, action] = GetParam();
diff --git a/chrome/browser/ash/system_web_apps/apps/camera_app/chrome_camera_app_ui_delegate.cc b/chrome/browser/ash/system_web_apps/apps/camera_app/chrome_camera_app_ui_delegate.cc index 2a0ac63..9318791 100644 --- a/chrome/browser/ash/system_web_apps/apps/camera_app/chrome_camera_app_ui_delegate.cc +++ b/chrome/browser/ash/system_web_apps/apps/camera_app/chrome_camera_app_ui_delegate.cc
@@ -27,6 +27,7 @@ #include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/devtools/devtools_window.h" #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h" +#include "chrome/browser/media/webrtc/media_device_salt_service_factory.h" #include "chrome/browser/metrics/chrome_metrics_service_accessor.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/ash/holding_space/holding_space_keyed_service.h" @@ -521,3 +522,10 @@ // same sequence. storage_monitor_weak_ptr_ = storage_monitor_.get()->GetWeakPtr(); } + +media_device_salt::MediaDeviceSaltService* +ChromeCameraAppUIDelegate::GetMediaDeviceSaltService( + content::BrowserContext* context) { + return MediaDeviceSaltServiceFactory::GetInstance()->GetForBrowserContext( + context); +}
diff --git a/chrome/browser/ash/system_web_apps/apps/camera_app/chrome_camera_app_ui_delegate.h b/chrome/browser/ash/system_web_apps/apps/camera_app/chrome_camera_app_ui_delegate.h index 9b8fce4..033c396 100644 --- a/chrome/browser/ash/system_web_apps/apps/camera_app/chrome_camera_app_ui_delegate.h +++ b/chrome/browser/ash/system_web_apps/apps/camera_app/chrome_camera_app_ui_delegate.h
@@ -144,6 +144,8 @@ void StopStorageMonitor() override; void OpenStorageManagement() override; base::FilePath GetFilePathByName(const std::string& name) override; + media_device_salt::MediaDeviceSaltService* GetMediaDeviceSaltService( + content::BrowserContext* context) override; private: base::FilePath GetMyFilesFolder();
diff --git a/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/editors/AddressEditorCoordinator.java b/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/editors/AddressEditorCoordinator.java index 534187a..6173466 100644 --- a/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/editors/AddressEditorCoordinator.java +++ b/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/editors/AddressEditorCoordinator.java
@@ -153,7 +153,7 @@ * Shows editor dialog to the user. */ public void showEditorDialog() { - mEditorModel = mMediator.buildEditorModel(); + mEditorModel = mMediator.getEditorModel(); PropertyModelChangeProcessor.create( mEditorModel, mEditorDialog, EditorDialogViewBinder::bindEditorDialogView); mEditorModel.set(VISIBLE, true);
diff --git a/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/editors/AddressEditorMediator.java b/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/editors/AddressEditorMediator.java index 9237685..da99a626 100644 --- a/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/editors/AddressEditorMediator.java +++ b/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/editors/AddressEditorMediator.java
@@ -22,6 +22,7 @@ import static org.chromium.chrome.browser.autofill.editors.EditorProperties.EDITOR_FIELDS; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.EDITOR_TITLE; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.FOOTER_MESSAGE; +import static org.chromium.chrome.browser.autofill.editors.EditorProperties.FORM_VALID; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.FieldProperties.INVALID_ERROR_MESSAGE; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.FieldProperties.IS_FULL_LINE; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.FieldProperties.IS_REQUIRED; @@ -32,18 +33,17 @@ import static org.chromium.chrome.browser.autofill.editors.EditorProperties.ItemType.DROPDOWN; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.ItemType.TEXT_INPUT; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.SHOW_REQUIRED_INDICATOR; -import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TRIGGER_DONE_CALLBACK_BEFORE_CLOSE_ANIMATION; -import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.LENGTH_COUNTER_LIMIT_NONE; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.TEXT_ALL_KEYS; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.TEXT_FORMATTER; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.TEXT_INPUT_TYPE; -import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.TEXT_LENGTH_COUNTER_LIMIT; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextInputType.ALPHA_NUMERIC_INPUT; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextInputType.EMAIL_ADDRESS_INPUT; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextInputType.PERSON_NAME_INPUT; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextInputType.PHONE_NUMBER_INPUT; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextInputType.PLAIN_TEXT_INPUT; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextInputType.STREET_ADDRESS_INPUT; +import static org.chromium.chrome.browser.autofill.editors.EditorProperties.VISIBLE; +import static org.chromium.chrome.browser.autofill.editors.EditorProperties.isFormValid; import android.content.Context; import android.text.TextUtils; @@ -114,6 +114,9 @@ private boolean mAllowDelete; private boolean mShouldTriggerDoneCallbackBeforeCloseAnimation; + @Nullable + private PropertyModel mEditorModel; + /** * The list of possible address fields for editing is determined statically. * @@ -232,7 +235,6 @@ mContext.getString( R.string.payments_phone_invalid_validation_message)) .with(IS_FULL_LINE, true) - .with(TEXT_LENGTH_COUNTER_LIMIT, LENGTH_COUNTER_LIMIT_NONE) .build(); // Phone number is present for all countries. @@ -246,7 +248,6 @@ mContext.getString( R.string.payments_email_invalid_validation_message)) .with(IS_FULL_LINE, true) - .with(TEXT_LENGTH_COUNTER_LIMIT, LENGTH_COUNTER_LIMIT_NONE) .build(); // TODO(crbug.com/1445020): Use localized string. @@ -309,8 +310,12 @@ * [ email address field ] <----- only present if purpose is Purpose.AUTOFILL_SETTINGS. * [ address nickname ] <----- only present if nickname support is enabled. */ - PropertyModel buildEditorModel() { - PropertyModel editorModel = + PropertyModel getEditorModel() { + if (mEditorModel != null) { + return mEditorModel; + } + + mEditorModel = new PropertyModel.Builder(ALL_KEYS) .with(EDITOR_TITLE, getEditorTitle()) .with(CUSTOM_DONE_BUTTON_TEXT, mCustomDoneButtonText) @@ -318,8 +323,6 @@ .with(DELETE_CONFIRMATION_TITLE, getDeleteConfirmationTitle()) .with(DELETE_CONFIRMATION_TEXT, getDeleteConfirmationText()) .with(SHOW_REQUIRED_INDICATOR, false) - .with(TRIGGER_DONE_CALLBACK_BEFORE_CLOSE_ANIMATION, - mShouldTriggerDoneCallbackBeforeCloseAnimation) .with(EDITOR_FIELDS, buildEditorFieldList(AutofillAddress.getCountryCode(mProfileToEdit), mProfileToEdit.getLanguageCode())) @@ -327,9 +330,10 @@ // If the user clicks [Cancel], send |toEdit| address back to the caller, // which was the original state (could be null, a complete address, a // partial address). - .with(CANCEL_RUNNABLE, mDelegate::onCancel) + .with(CANCEL_RUNNABLE, this::onCancelEditing) .with(ALLOW_DELETE, mAllowDelete) .with(DELETE_RUNNABLE, () -> mDelegate.onDelete(mAddressToEdit)) + .with(FORM_VALID, true) .build(); mCountryField.set(DROPDOWN_CALLBACK, new Callback<String>() { @@ -338,7 +342,7 @@ */ @Override public void onResult(String countryCode) { - editorModel.set(EDITOR_FIELDS, + mEditorModel.set(EDITOR_FIELDS, buildEditorFieldList(countryCode, Locale.getDefault().getLanguage())); mPhoneFormatter.setCountryCode(countryCode); @@ -346,7 +350,7 @@ } }); - return editorModel; + return mEditorModel; } private boolean shouldDisplayRequiredErrorIfFieldEmpty(AddressUiComponent component) { @@ -422,11 +426,17 @@ } private void onCommitChanges() { - // If the user clicks [Done], save changes on disk, mark the address - // "complete" if possible, - // and send it back to the caller. - commitChanges(mProfileToEdit); + if (!isFormValid(mEditorModel)) { + // Note: triggering editor error messages and focused field update using temporary + // property. + // TODO(crbug.com/1435314): remove this temporary logic. + mEditorModel.set(FORM_VALID, true); + mEditorModel.set(FORM_VALID, false); + return; + } + mEditorModel.set(VISIBLE, false); + commitChanges(mProfileToEdit); // The address cannot be marked "complete" because it has not been // checked for all required fields. mAddressToEdit.updateAddress(mProfileToEdit); @@ -434,6 +444,12 @@ mDelegate.onDone(mAddressToEdit); } + private void onCancelEditing() { + mEditorModel.set(VISIBLE, false); + + mDelegate.onCancel(); + } + /** Saves the edited profile on disk. */ private void commitChanges(AutofillProfile profile) { String country = mCountryField.get(VALUE); @@ -636,10 +652,5 @@ return TextUtils.isEmpty(value) ? mAllowEmptyValue : PhoneNumberUtil.isPossibleNumber(value, mCountryCode); } - - @Override - public boolean isLengthMaximum(@Nullable String value) { - return false; - } } }
diff --git a/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/editors/EditorDialogView.java b/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/editors/EditorDialogView.java index 134c3f2..4375f6b 100644 --- a/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/editors/EditorDialogView.java +++ b/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/editors/EditorDialogView.java
@@ -56,6 +56,8 @@ import java.util.ArrayList; import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; /** * The editor dialog. Can be used for editing contact information, shipping address, @@ -75,6 +77,7 @@ /** Duration of the animation to hide the UI. */ private static final int DIALOG_EXIT_ANIMATION_MS = 195; + @Nullable private static EditorObserverForTest sObserverForTest; private final Activity mActivity; @@ -90,7 +93,6 @@ private final ViewGroup mContentView; private final View mFooter; private Button mDoneButton; - private boolean mFormWasValid; private Animator mDialogInOutAnimator; private boolean mIsDismissed; @@ -104,7 +106,6 @@ @Nullable private String mDeleteConfirmationText; - private boolean mTriggerDoneCallbackBeforeCloseAnimation; private Runnable mDeleteRunnable; private Runnable mDoneRunnable; private Runnable mCancelRunnable; @@ -197,11 +198,6 @@ mDeleteConfirmationText = deleteConfirmationText; } - public void setShouldTriggerDoneCallbackBeforeCloseAnimation( - boolean triggerDoneCallbackBeforeCloseAnimation) { - mTriggerDoneCallbackBeforeCloseAnimation = triggerDoneCallbackBeforeCloseAnimation; - } - public void setShowRequiredIndicator(boolean showRequiredIndicator) { for (FieldView view : mFieldViews) { view.setShowRequiredIndicator(showRequiredIndicator); @@ -245,6 +241,31 @@ } } + public void findAndScrollToInvalidField() { + // Iterate over all the fields to update what errors are displayed, which is necessary + // to to clear existing errors on any newly valid fields. + mFieldViews.forEach(view -> view.updateDisplayedError(!view.isValid())); + + // Make sure that focus is on an invalid field. + @Nullable + FieldView focusedField = getTextFieldView(getCurrentFocus()); + if (focusedField != null && !focusedField.isValid()) { + // The focused field is invalid, but it may be scrolled off screen. Scroll to it. + focusedField.scrollToAndFocus(); + } else { + // Some fields are invalid, but none of the are focused. Scroll to the first invalid + // field and focus it. + Optional<FieldView> invalidField = + mFieldViews.stream().filter(view -> !view.isValid()).findAny(); + assert invalidField.isPresent(); + invalidField.get().scrollToAndFocus(); + } + + if (sObserverForTest != null) { + sObserverForTest.onEditorValidationError(); + } + } + public void setEditorFields( ListModel<ListItem> editorFields, boolean shouldShowRequiredIndicator) { prepareEditor(editorFields, shouldShowRequiredIndicator); @@ -289,12 +310,7 @@ // Cancel editing when the user hits the back arrow. toolbar.setNavigationContentDescription(R.string.cancel); toolbar.setNavigationIcon(getTintedBackIcon()); - toolbar.setNavigationOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - animateOutDialog(); - } - }); + toolbar.setNavigationOnClickListener(view -> mCancelRunnable.run()); // The top shadow is handled by the toolbar, so hide the one used in the field editor. FadingEdgeScrollView scrollView = @@ -310,43 +326,8 @@ SettingsUtils.getShowShadowOnScrollListener(scrollView, shadow)); } - /** - * Checks if all of the fields in the form are valid and updates the displayed errors. If there - * are any invalid fields, makes sure that one of them is focused. Called when user taps [SAVE]. - * - * @return Whether all fields contain valid information. - */ - public boolean validateForm() { - final List<FieldView> invalidViews = getViewsWithInvalidInformation(true); - - // Iterate over all the fields to update what errors are displayed, which is necessary to - // to clear existing errors on any newly valid fields. - for (int i = 0; i < mFieldViews.size(); i++) { - FieldView fieldView = mFieldViews.get(i); - fieldView.updateDisplayedError(invalidViews.contains(fieldView)); - } - - if (!invalidViews.isEmpty()) { - // Make sure that focus is on an invalid field. - FieldView focusedField = getTextFieldView(getCurrentFocus()); - if (invalidViews.contains(focusedField)) { - // The focused field is invalid, but it may be scrolled off screen. Scroll to it. - focusedField.scrollToAndFocus(); - } else { - // Some fields are invalid, but none of the are focused. Scroll to the first invalid - // field and focus it. - invalidViews.get(0).scrollToAndFocus(); - } - } - - if (!invalidViews.isEmpty() && sObserverForTest != null) { - sObserverForTest.onEditorValidationError(); - } - - return invalidViews.isEmpty(); - } - /** @return The validatable item for the given view. */ + @Nullable private FieldView getTextFieldView(View v) { if (v instanceof TextView && v.getParent() != null && v.getParent() instanceof FieldView) { return (FieldView) v.getParent(); @@ -363,16 +344,9 @@ if (mDialogInOutAnimator != null) return; if (view.getId() == R.id.editor_dialog_done_button) { - if (validateForm()) { - if (mTriggerDoneCallbackBeforeCloseAnimation) { - mDoneRunnable.run(); - } - mFormWasValid = true; - animateOutDialog(); - return; - } + mDoneRunnable.run(); } else if (view.getId() == R.id.payments_edit_cancel_button) { - animateOutDialog(); + mCancelRunnable.run(); } } @@ -415,14 +389,6 @@ @Override public void onDismiss(DialogInterface dialog) { mIsDismissed = true; - if (mFormWasValid) { - if (!mTriggerDoneCallbackBeforeCloseAnimation) { - mDoneRunnable.run(); - } - mFormWasValid = false; - } else { - mCancelRunnable.run(); - } removeTextChangedListeners(); } @@ -620,7 +586,9 @@ // because the user would not learn about the elements that are // above the focused field. if (!ChromeAccessibilityUtil.get().isAccessibilityEnabled()) { - List<FieldView> invalidViews = getViewsWithInvalidInformation(false); + List<FieldView> invalidViews = mFieldViews.stream() + .filter(view -> !view.isValid()) + .collect(Collectors.toList()); if (!invalidViews.isEmpty()) { // Immediately focus the first invalid field to make it faster to edit. invalidViews.get(0).scrollToAndFocus(); @@ -681,18 +649,6 @@ } } - private List<FieldView> getViewsWithInvalidInformation(boolean findAll) { - List<FieldView> invalidViews = new ArrayList<>(); - for (int i = 0; i < mFieldViews.size(); i++) { - FieldView fieldView = mFieldViews.get(i); - if (!fieldView.isValid()) { - invalidViews.add(fieldView); - if (!findAll) break; - } - } - return invalidViews; - } - /** @return The View with all fields of this editor. */ @VisibleForTesting public View getContentViewForTest() {
diff --git a/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/editors/EditorDialogViewBinder.java b/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/editors/EditorDialogViewBinder.java index 1146371..bbc6e2d 100644 --- a/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/editors/EditorDialogViewBinder.java +++ b/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/editors/EditorDialogViewBinder.java
@@ -14,8 +14,8 @@ import static org.chromium.chrome.browser.autofill.editors.EditorProperties.EDITOR_FIELDS; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.EDITOR_TITLE; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.FOOTER_MESSAGE; +import static org.chromium.chrome.browser.autofill.editors.EditorProperties.FORM_VALID; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.SHOW_REQUIRED_INDICATOR; -import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TRIGGER_DONE_CALLBACK_BEFORE_CLOSE_ANIMATION; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.VISIBLE; import org.chromium.ui.modelutil.PropertyKey; @@ -46,9 +46,6 @@ view.setDeleteConfirmationText(model.get(DELETE_CONFIRMATION_TEXT)); } else if (propertyKey == SHOW_REQUIRED_INDICATOR) { view.setShowRequiredIndicator(model.get(SHOW_REQUIRED_INDICATOR)); - } else if (propertyKey == TRIGGER_DONE_CALLBACK_BEFORE_CLOSE_ANIMATION) { - view.setShouldTriggerDoneCallbackBeforeCloseAnimation( - model.get(TRIGGER_DONE_CALLBACK_BEFORE_CLOSE_ANIMATION)); } else if (propertyKey == EDITOR_FIELDS) { view.setEditorFields(model.get(EDITOR_FIELDS), model.get(SHOW_REQUIRED_INDICATOR)); } else if (propertyKey == DONE_RUNNABLE) { @@ -61,6 +58,10 @@ view.setDeleteRunnable(model.get(DELETE_RUNNABLE)); } else if (propertyKey == VISIBLE) { view.setVisible(model.get(VISIBLE)); + } else if (propertyKey == FORM_VALID) { + if (!model.get(FORM_VALID)) { + view.findAndScrollToInvalidField(); + } } else { assert false : "Unhandled update to property:" + propertyKey; }
diff --git a/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/editors/EditorProperties.java b/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/editors/EditorProperties.java index 0236954..39f0c65 100644 --- a/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/editors/EditorProperties.java +++ b/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/editors/EditorProperties.java
@@ -49,15 +49,6 @@ new PropertyModel.ReadableObjectPropertyKey<>("delete_confirmation_text"); public static final PropertyModel.ReadableBooleanPropertyKey SHOW_REQUIRED_INDICATOR = new PropertyModel.ReadableBooleanPropertyKey("show_required_indicator"); - /** - * If true, done callback is triggered immediately after the user clicked - * on the done button. Otherwise, by default, it is triggered only after the dialog is - * dismissed with animation. - */ - public static final PropertyModel - .ReadableBooleanPropertyKey TRIGGER_DONE_CALLBACK_BEFORE_CLOSE_ANIMATION = - new PropertyModel.ReadableBooleanPropertyKey( - "trigger_done_callback_before_close_animation"); public static final PropertyModel.WritableObjectPropertyKey<ListModel<ListItem>> EDITOR_FIELDS = new PropertyModel.WritableObjectPropertyKey<>("editor_fields"); @@ -74,11 +65,18 @@ public static final PropertyModel.WritableBooleanPropertyKey VISIBLE = new PropertyModel.WritableBooleanPropertyKey("visible"); + /** + * This property is temporary way to trigger field error message update process. + * It also triggers field focus update. + * TODO(crbug.com/1435314): remove this property once fields are updated through MCP. + */ + public static final PropertyModel.WritableBooleanPropertyKey FORM_VALID = + new PropertyModel.WritableBooleanPropertyKey("form_valid"); public static final PropertyKey[] ALL_KEYS = {EDITOR_TITLE, CUSTOM_DONE_BUTTON_TEXT, FOOTER_MESSAGE, DELETE_CONFIRMATION_TITLE, DELETE_CONFIRMATION_TEXT, - SHOW_REQUIRED_INDICATOR, TRIGGER_DONE_CALLBACK_BEFORE_CLOSE_ANIMATION, EDITOR_FIELDS, - DONE_RUNNABLE, CANCEL_RUNNABLE, ALLOW_DELETE, DELETE_RUNNABLE, VISIBLE}; + SHOW_REQUIRED_INDICATOR, EDITOR_FIELDS, DONE_RUNNABLE, CANCEL_RUNNABLE, ALLOW_DELETE, + DELETE_RUNNABLE, VISIBLE, FORM_VALID}; private EditorProperties() {} @@ -132,15 +130,6 @@ * @return True if the value is valid. */ boolean isValid(@Nullable String value); - - /** - * Called to check whether the length of the field value is maximum. - * - * @param value The value of the field to check. - * @return True if the field value length is maximum among all the possible valid values in - * this field. - */ - boolean isLengthMaximum(@Nullable String value); } /** @@ -222,23 +211,17 @@ * Properties specific for the text fields. */ public static class TextFieldProperties { - /* Indicates that the length counter is disabled. */ - public static final int LENGTH_COUNTER_LIMIT_NONE = 0; - public static final PropertyModel.ReadableIntPropertyKey TEXT_INPUT_TYPE = new PropertyModel.ReadableIntPropertyKey("text_input_type"); public static final PropertyModel.WritableObjectPropertyKey<List<String>> TEXT_SUGGESTIONS = new PropertyModel.WritableObjectPropertyKey<>("suggestions"); public static final PropertyModel.ReadableObjectPropertyKey<TextWatcher> TEXT_FORMATTER = new PropertyModel.ReadableObjectPropertyKey<>("formatter"); - public static final PropertyModel.ReadableIntPropertyKey TEXT_LENGTH_COUNTER_LIMIT = - new PropertyModel.ReadableIntPropertyKey("length_counter_limit"); public static final PropertyKey[] TEXT_SPECIFIC_KEYS = { TEXT_INPUT_TYPE, TEXT_SUGGESTIONS, TEXT_FORMATTER, - TEXT_LENGTH_COUNTER_LIMIT, }; public static final PropertyKey[] TEXT_ALL_KEYS = @@ -283,11 +266,6 @@ } } - public static boolean hasMaximumLength(PropertyModel textField) { - EditorFieldValidator validator = textField.get(FieldProperties.VALIDATOR); - return validator != null && validator.isLengthMaximum(textField.get(FieldProperties.VALUE)); - } - public static @Nullable String getValidationErrorMessage(PropertyModel textField) { final String customErrorMessage = textField.get(FieldProperties.CUSTOM_ERROR_MESSAGE); if (!TextUtils.isEmpty(customErrorMessage)) { @@ -308,6 +286,15 @@ return null; } + public static boolean isFormValid(PropertyModel editorModel) { + for (ListItem item : editorModel.get(EditorProperties.EDITOR_FIELDS)) { + if (!isFieldValid(item.model)) { + return false; + } + } + return true; + } + public static boolean isFieldValid(PropertyModel textField) { return getValidationErrorMessage(textField) == null; }
diff --git a/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/editors/TextFieldView.java b/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/editors/TextFieldView.java index 0eddb91..88c0954e 100644 --- a/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/editors/TextFieldView.java +++ b/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/editors/TextFieldView.java
@@ -8,10 +8,8 @@ import static org.chromium.chrome.browser.autofill.editors.EditorProperties.FieldProperties.IS_REQUIRED; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.FieldProperties.LABEL; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.FieldProperties.VALUE; -import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.LENGTH_COUNTER_LIMIT_NONE; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.TEXT_FORMATTER; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.TEXT_INPUT_TYPE; -import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.TEXT_LENGTH_COUNTER_LIMIT; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.TEXT_SUGGESTIONS; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextInputType.ALPHA_NUMERIC_INPUT; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextInputType.EMAIL_ADDRESS_INPUT; @@ -20,19 +18,16 @@ import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextInputType.REGION_INPUT; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextInputType.STREET_ADDRESS_INPUT; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.getValidationErrorMessage; -import static org.chromium.chrome.browser.autofill.editors.EditorProperties.hasMaximumLength; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.isFieldValid; import android.content.Context; import android.text.Editable; -import android.text.InputFilter; import android.text.InputType; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.accessibility.AccessibilityEvent; -import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.ArrayAdapter; import android.widget.AutoCompleteTextView; @@ -115,10 +110,6 @@ // Show no errors until the user has already tried to edit the field once. updateDisplayedError(!isFieldValid(mEditorFieldModel)); } - - if (mEditorFieldModel.get(TEXT_LENGTH_COUNTER_LIMIT) != LENGTH_COUNTER_LIMIT_NONE) { - mInputLayout.setCounterEnabled(hasFocus); - } } }); @@ -131,13 +122,6 @@ if (sObserverForTest != null) { sObserverForTest.onEditorTextUpdate(); } - if (!hasMaximumLength(mEditorFieldModel)) return; - updateDisplayedError(true); - if (isValid()) { - // Simulate editor action to select next selectable field. - mEditorActionListener.onEditorAction(mInput, EditorInfo.IME_ACTION_NEXT, - new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER)); - } } @Override @@ -157,13 +141,6 @@ mInput.setThreshold(0); } - final int lengthCounter = mEditorFieldModel.get(TEXT_LENGTH_COUNTER_LIMIT); - if (lengthCounter != LENGTH_COUNTER_LIMIT_NONE) { - // Limit input length for field and counter. - mInput.setFilters(new InputFilter[] {new InputFilter.LengthFilter(lengthCounter)}); - mInputLayout.setCounterMaxLength(lengthCounter); - } - if (mEditorFieldModel.get(TEXT_FORMATTER) != null) { mInput.addTextChangedListener(mEditorFieldModel.get(TEXT_FORMATTER)); mEditorFieldModel.get(TEXT_FORMATTER).afterTextChanged(mInput.getText());
diff --git a/chrome/browser/autofill/android/junit/src/org/chromium/chrome/browser/autofill/editors/AddressEditorTest.java b/chrome/browser/autofill/android/junit/src/org/chromium/chrome/browser/autofill/editors/AddressEditorTest.java index 218f1ef..e5b5a68e 100644 --- a/chrome/browser/autofill/android/junit/src/org/chromium/chrome/browser/autofill/editors/AddressEditorTest.java +++ b/chrome/browser/autofill/android/junit/src/org/chromium/chrome/browser/autofill/editors/AddressEditorTest.java
@@ -35,9 +35,7 @@ import static org.chromium.chrome.browser.autofill.editors.EditorProperties.ItemType.DROPDOWN; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.ItemType.TEXT_INPUT; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.SHOW_REQUIRED_INDICATOR; -import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.LENGTH_COUNTER_LIMIT_NONE; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.TEXT_INPUT_TYPE; -import static org.chromium.chrome.browser.autofill.editors.EditorProperties.TextFieldProperties.TEXT_LENGTH_COUNTER_LIMIT; import static org.chromium.chrome.browser.autofill.editors.EditorProperties.setDropdownKey; import android.app.Activity; @@ -69,6 +67,8 @@ import org.chromium.chrome.browser.autofill.AutofillProfileBridgeJni; import org.chromium.chrome.browser.autofill.PersonalDataManager; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; +import org.chromium.chrome.browser.autofill.PhoneNumberUtil; +import org.chromium.chrome.browser.autofill.PhoneNumberUtilJni; import org.chromium.chrome.browser.autofill.Source; import org.chromium.chrome.browser.autofill.editors.AddressEditorCoordinator.Delegate; import org.chromium.chrome.browser.autofill.editors.EditorProperties.DropdownKeyValue; @@ -157,6 +157,8 @@ @Mock private AutofillProfileBridge.Natives mAutofillProfileBridgeJni; + @Mock + private PhoneNumberUtil.Natives mPhoneNumberUtilJni; @Mock private EditorDialogView mEditorDialog; @@ -207,6 +209,8 @@ }) .when(mAutofillProfileBridgeJni) .getRequiredFields(anyString(), anyList()); + mJniMocker.mock(PhoneNumberUtilJni.TEST_HOOKS, mPhoneNumberUtilJni); + when(mPhoneNumberUtilJni.isPossibleNumber(anyString(), anyString())).thenReturn(true); IdentityServicesProvider.setInstanceForTests(mIdentityServicesProvider); when(mIdentityServicesProvider.getIdentityManager(mProfile)).thenReturn(mIdentityManager); @@ -273,8 +277,8 @@ } private static void validateTextField(ListItem fieldItem, String value, - @TextInputType int textInputType, String label, boolean isRequired, boolean isFullLine, - int lengthCounter) { + @TextInputType int textInputType, String label, boolean isRequired, + boolean isFullLine) { Assert.assertEquals(TEXT_INPUT, fieldItem.type); PropertyModel field = fieldItem.model; @@ -283,7 +287,6 @@ Assert.assertEquals(label, field.get(LABEL)); Assert.assertEquals(isRequired, field.get(IS_REQUIRED)); Assert.assertEquals(isFullLine, field.get(IS_FULL_LINE)); - Assert.assertEquals(lengthCounter, field.get(TEXT_LENGTH_COUNTER_LIMIT)); } private static void checkModelHasExpectedValues(PropertyModel editorModel, @@ -327,17 +330,15 @@ // Note: honorific prefix always comes before the full name field. validateTextField(editorFields.get(1), profile.getHonorificPrefix(), TextInputType.PLAIN_TEXT_INPUT, - mActivity.getString(R.string.autofill_profile_editor_honorific_prefix), false, true, - LENGTH_COUNTER_LIMIT_NONE); + mActivity.getString(R.string.autofill_profile_editor_honorific_prefix), false, + true); validateTextField(editorFields.get(2), profile.getFullName(), - TextInputType.PERSON_NAME_INPUT, "full name label", shouldMarkFieldsRequired, true, - LENGTH_COUNTER_LIMIT_NONE); + TextInputType.PERSON_NAME_INPUT, "full name label", shouldMarkFieldsRequired, true); validateTextField(editorFields.get(3), profile.getRegion(), TextInputType.PLAIN_TEXT_INPUT, - "admin area label", false, true, LENGTH_COUNTER_LIMIT_NONE); + "admin area label", false, true); // Locality field is forced to occupy full line. validateTextField(editorFields.get(4), profile.getLocality(), - TextInputType.PLAIN_TEXT_INPUT, "locality label", shouldMarkFieldsRequired, true, - LENGTH_COUNTER_LIMIT_NONE); + TextInputType.PLAIN_TEXT_INPUT, "locality label", shouldMarkFieldsRequired, true); // Note: dependent locality is a required field for address profiles stored in Google // account, but it's still marked as optional by the editor when the corresponding field in @@ -345,21 +346,19 @@ // profiles. validateTextField(editorFields.get(5), profile.getDependentLocality(), TextInputType.PLAIN_TEXT_INPUT, "dependent locality label", - shouldMarkFieldsRequiredWhenAddressFieldEmpty, true, LENGTH_COUNTER_LIMIT_NONE); + shouldMarkFieldsRequiredWhenAddressFieldEmpty, true); validateTextField(editorFields.get(6), profile.getCompanyName(), - TextInputType.PLAIN_TEXT_INPUT, "organization label", false, true, - LENGTH_COUNTER_LIMIT_NONE); + TextInputType.PLAIN_TEXT_INPUT, "organization label", false, true); validateTextField(editorFields.get(7), profile.getSortingCode(), - TextInputType.ALPHA_NUMERIC_INPUT, "sorting code label", false, false, - LENGTH_COUNTER_LIMIT_NONE); + TextInputType.ALPHA_NUMERIC_INPUT, "sorting code label", false, false); validateTextField(editorFields.get(8), profile.getPostalCode(), TextInputType.ALPHA_NUMERIC_INPUT, "postal code label", shouldMarkFieldsRequired, - false, LENGTH_COUNTER_LIMIT_NONE); + false); validateTextField(editorFields.get(9), profile.getStreetAddress(), TextInputType.STREET_ADDRESS_INPUT, "street address label", - shouldMarkFieldsRequired, true, LENGTH_COUNTER_LIMIT_NONE); + shouldMarkFieldsRequired, true); } @Test @@ -649,12 +648,10 @@ validateTextField(editorFields.get(1), sLocalProfile.getPhoneNumber(), TextInputType.PHONE_NUMBER_INPUT, - mActivity.getString(R.string.autofill_profile_editor_phone_number), false, true, - LENGTH_COUNTER_LIMIT_NONE); + mActivity.getString(R.string.autofill_profile_editor_phone_number), false, true); validateTextField(editorFields.get(2), sLocalProfile.getEmailAddress(), TextInputType.EMAIL_ADDRESS_INPUT, - mActivity.getString(R.string.autofill_profile_editor_email_address), false, true, - LENGTH_COUNTER_LIMIT_NONE); + mActivity.getString(R.string.autofill_profile_editor_email_address), false, true); } @Test @@ -678,8 +675,8 @@ // editorFields[3] - nickname field. Assert.assertEquals(4, editorFields.size()); - validateTextField(editorFields.get(3), null, TextInputType.PLAIN_TEXT_INPUT, "Label", false, - true, LENGTH_COUNTER_LIMIT_NONE); + validateTextField( + editorFields.get(3), null, TextInputType.PLAIN_TEXT_INPUT, "Label", false, true); } @Test
diff --git a/chrome/browser/background/background_mode_manager.h b/chrome/browser/background/background_mode_manager.h index 7ea25b0..84eb3b55 100644 --- a/chrome/browser/background/background_mode_manager.h +++ b/chrome/browser/background/background_mode_manager.h
@@ -413,7 +413,7 @@ // Reference to the ProfileAttributesStorage. It is used to update the // background app status of profiles when they open/close background apps. - raw_ptr<ProfileAttributesStorage, DanglingUntriaged> profile_storage_; + raw_ptr<ProfileAttributesStorage, DanglingAcrossTasks> profile_storage_; // Registrars for managing our change observers. base::CallbackListSubscription on_app_terminating_subscription_;
diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_process_impl.h index c495d31..15405463 100644 --- a/chrome/browser/browser_process_impl.h +++ b/chrome/browser/browser_process_impl.h
@@ -269,7 +269,7 @@ const std::unique_ptr<PrefService> local_state_; // |metrics_services_manager_| owns this. - raw_ptr<ChromeMetricsServicesManagerClient, DanglingUntriaged> + raw_ptr<ChromeMetricsServicesManagerClient, DanglingAcrossTasks> metrics_services_manager_client_ = nullptr; // Must be destroyed before |local_state_|.
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc index 2c94cc6..ff6138f 100644 --- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc +++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
@@ -52,6 +52,7 @@ #include "chrome/browser/media/history/media_history_keyed_service.h" #include "chrome/browser/media/history/media_history_keyed_service_factory.h" #include "chrome/browser/media/media_engagement_service.h" +#include "chrome/browser/media/webrtc/media_device_salt_service_factory.h" #include "chrome/browser/media/webrtc/webrtc_event_log_manager.h" #include "chrome/browser/optimization_guide/optimization_guide_keyed_service.h" #include "chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h" @@ -102,7 +103,6 @@ #include "components/keyed_service/core/service_access_type.h" #include "components/language/core/browser/url_language_histogram.h" #include "components/media_device_salt/media_device_salt_service.h" -#include "components/media_device_salt/media_device_salt_service_factory.h" #include "components/nacl/browser/nacl_browser.h" #include "components/nacl/browser/pnacl_host.h" #include "components/no_state_prefetch/browser/no_state_prefetch_manager.h" @@ -642,8 +642,8 @@ privacy_sandbox_settings->OnCookiesCleared(); auto* media_device_salt_service = - media_device_salt::MediaDeviceSaltServiceFactory::GetInstance() - ->GetForBrowserContext(profile_); + MediaDeviceSaltServiceFactory::GetInstance()->GetForBrowserContext( + profile_); if (media_device_salt_service) { media_device_salt_service->ResetSalt(); }
diff --git a/chrome/browser/captive_portal/captive_portal_browsertest.cc b/chrome/browser/captive_portal/captive_portal_browsertest.cc index eb6a13e..ba9ba6c 100644 --- a/chrome/browser/captive_portal/captive_portal_browsertest.cc +++ b/chrome/browser/captive_portal/captive_portal_browsertest.cc
@@ -2037,9 +2037,8 @@ EXPECT_EQ(1, login_tab_index); content::WebContentsDestroyedWatcher destroyed_watcher( tab_strip_model->GetActiveWebContents()); - EXPECT_EQ(2, tab_strip_model->count()); - tab_strip_model->CloseWebContentsAt(tab_strip_model->active_index(), 0); - EXPECT_EQ(1, tab_strip_model->count()); + EXPECT_TRUE( + tab_strip_model->CloseWebContentsAt(tab_strip_model->active_index(), 0)); destroyed_watcher.Wait(); MultiNavigationObserver navigation_observer; content::ExecuteScriptAsync(rfh, kClickConnectButtonJS);
diff --git a/chrome/browser/chrome_browser_field_trials.h b/chrome/browser/chrome_browser_field_trials.h index 15457d1..cccb243 100644 --- a/chrome/browser/chrome_browser_field_trials.h +++ b/chrome/browser/chrome_browser_field_trials.h
@@ -37,7 +37,7 @@ private: // Weak pointer to the local state prefs store. - const raw_ptr<PrefService, DanglingUntriaged> local_state_; + const raw_ptr<PrefService, DanglingAcrossTasks> local_state_; #if BUILDFLAG(IS_ANDROID) // VariationID to be used for FREMobileIdentityConsistencyFieldTrial.
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index d772f6c3b..6114a4f4 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -85,6 +85,7 @@ #include "chrome/browser/media/webrtc/capture_policy_utils.h" #include "chrome/browser/media/webrtc/chrome_screen_enumerator.h" #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h" +#include "chrome/browser/media/webrtc/media_device_salt_service_factory.h" #include "chrome/browser/media/webrtc/webrtc_logging_controller.h" #include "chrome/browser/memory/chrome_browser_main_extra_parts_memory.h" #include "chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.h" @@ -226,7 +227,6 @@ #include "components/lens/buildflags.h" #include "components/live_caption/caption_util.h" #include "components/media_device_salt/media_device_salt_service.h" -#include "components/media_device_salt/media_device_salt_service_factory.h" #include "components/media_router/browser/presentation/presentation_service_delegate_impl.h" #include "components/media_router/browser/presentation/receiver_presentation_service_delegate_impl.h" #include "components/media_router/browser/presentation/web_contents_presentation_manager.h" @@ -7204,8 +7204,8 @@ url, site_for_cookies, top_frame_origin, cookie_settings->SettingOverridesForStorage()); media_device_salt::MediaDeviceSaltService* salt_service = - media_device_salt::MediaDeviceSaltServiceFactory::GetInstance() - ->GetForBrowserContext(browser_context); + MediaDeviceSaltServiceFactory::GetInstance()->GetForBrowserContext( + browser_context); if (!salt_service) { std::move(callback).Run(allowed, browser_context->UniqueId()); return;
diff --git a/chrome/browser/chrome_multiprofile_startup_browsertest.cc b/chrome/browser/chrome_multiprofile_startup_browsertest.cc index 7bd71a0..38e91c1e 100644 --- a/chrome/browser/chrome_multiprofile_startup_browsertest.cc +++ b/chrome/browser/chrome_multiprofile_startup_browsertest.cc
@@ -159,7 +159,7 @@ } } - raw_ptr<MockMainExtraParts, DanglingUntriaged> mock_part_; + raw_ptr<MockMainExtraParts, DanglingAcrossTasks> mock_part_; }; IN_PROC_BROWSER_TEST_P(ChromeMultiProfileStartupBrowserTestBase,
diff --git a/chrome/browser/chromeos/extensions/echo_private/echo_private_apitest.cc b/chrome/browser/chromeos/extensions/echo_private/echo_private_apitest.cc index f8e2da8d..ed3edb6 100644 --- a/chrome/browser/chromeos/extensions/echo_private/echo_private_apitest.cc +++ b/chrome/browser/chromeos/extensions/echo_private/echo_private_apitest.cc
@@ -121,9 +121,7 @@ return false; } - int previous_tab_count = tab_strip->count(); - tab_strip->CloseWebContentsAt(tab_index, 0); - return (previous_tab_count - 1) == tab_strip->count(); + return tab_strip->CloseWebContentsAt(tab_index, 0); } protected:
diff --git a/chrome/browser/commerce/coupons/coupon_db.h b/chrome/browser/commerce/coupons/coupon_db.h index 99b1e7e..e2d3e18 100644 --- a/chrome/browser/commerce/coupons/coupon_db.h +++ b/chrome/browser/commerce/coupons/coupon_db.h
@@ -59,7 +59,7 @@ void OnOperationFinished(bool success); private: - raw_ptr<SessionProtoDB<coupon_db::CouponContentProto>, DanglingUntriaged> + raw_ptr<SessionProtoDB<coupon_db::CouponContentProto>, DanglingAcrossTasks> proto_db_; base::WeakPtrFactory<CouponDB> weak_ptr_factory_{this}; };
diff --git a/chrome/browser/component_updater/masked_domain_list_component_installer.cc b/chrome/browser/component_updater/masked_domain_list_component_installer.cc new file mode 100644 index 0000000..22232f8 --- /dev/null +++ b/chrome/browser/component_updater/masked_domain_list_component_installer.cc
@@ -0,0 +1,31 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/component_updater/masked_domain_list_component_installer.h" + +#include "base/logging.h" +#include "components/component_updater/installer_policies/masked_domain_list_component_installer_policy.h" +#include "content/public/browser/network_service_instance.h" +#include "services/network/public/mojom/network_service.mojom.h" + +namespace component_updater { + +void RegisterMaskedDomainListComponent(ComponentUpdateService* cus) { + if (!MaskedDomainListComponentInstallerPolicy::IsEnabled()) { + return; + } + + VLOG(1) << "Registering Masked Domain List component."; + + auto policy = std::make_unique<MaskedDomainListComponentInstallerPolicy>( + /*on_list_ready=*/base::BindRepeating( + [](base::Version version, std::string raw_mdl) { + VLOG(1) << "Received Masked Domain List"; + content::GetNetworkService()->UpdateMaskedDomainList(raw_mdl); + })); + + base::MakeRefCounted<ComponentInstaller>(std::move(policy)) + ->Register(cus, base::OnceClosure(), base::TaskPriority::USER_BLOCKING); +} +} // namespace component_updater
diff --git a/chrome/browser/component_updater/masked_domain_list_component_installer.h b/chrome/browser/component_updater/masked_domain_list_component_installer.h new file mode 100644 index 0000000..3680232 --- /dev/null +++ b/chrome/browser/component_updater/masked_domain_list_component_installer.h
@@ -0,0 +1,16 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_COMPONENT_UPDATER_MASKED_DOMAIN_LIST_COMPONENT_INSTALLER_H_ +#define CHROME_BROWSER_COMPONENT_UPDATER_MASKED_DOMAIN_LIST_COMPONENT_INSTALLER_H_ + +#include "components/component_updater/component_installer.h" + +namespace component_updater { + +void RegisterMaskedDomainListComponent(ComponentUpdateService* cus); + +} + +#endif // CHROME_BROWSER_COMPONENT_UPDATER_MASKED_DOMAIN_LIST_COMPONENT_INSTALLER_H_
diff --git a/chrome/browser/component_updater/masked_domain_list_component_installer_unittest.cc b/chrome/browser/component_updater/masked_domain_list_component_installer_unittest.cc new file mode 100644 index 0000000..58fceb4 --- /dev/null +++ b/chrome/browser/component_updater/masked_domain_list_component_installer_unittest.cc
@@ -0,0 +1,69 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/component_updater/masked_domain_list_component_installer.h" + +#include "base/check.h" +#include "base/files/scoped_temp_dir.h" +#include "base/test/scoped_feature_list.h" +#include "components/component_updater/mock_component_updater_service.h" +#include "content/public/browser/network_service_instance.h" +#include "content/public/test/browser_task_environment.h" +#include "services/network/network_service.h" +#include "services/network/public/cpp/features.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace component_updater { + +namespace { +using ::testing::_; + +} // namespace + +class MaskedDomainListComponentInstallerPolicyTest : public ::testing::Test { + public: + MaskedDomainListComponentInstallerPolicyTest() { + CHECK(component_install_dir_.CreateUniqueTempDir()); + content::GetNetworkService(); // Initializes Network Service. + } + + protected: + content::BrowserTaskEnvironment env_; + base::test::ScopedFeatureList scoped_feature_list_; + + base::ScopedTempDir component_install_dir_; +}; + +TEST_F(MaskedDomainListComponentInstallerPolicyTest, FeatureDisabled) { + scoped_feature_list_.InitAndDisableFeature( + network::features::kMaskedDomainList); + auto service = + std::make_unique<component_updater::MockComponentUpdateService>(); + EXPECT_CALL(*service, RegisterComponent(_)).Times(0); + RegisterMaskedDomainListComponent(service.get()); + + env_.RunUntilIdle(); +} + +TEST_F(MaskedDomainListComponentInstallerPolicyTest, + FeatureEnabled_NoFileExists) { + scoped_feature_list_.InitWithFeatures( + {network::features::kMaskedDomainList, + net::features::kEnableIpProtectionProxy}, + {}); + auto service = + std::make_unique<component_updater::MockComponentUpdateService>(); + + EXPECT_CALL(*service, RegisterComponent(_)).Times(1); + RegisterMaskedDomainListComponent(service.get()); + env_.RunUntilIdle(); + + // If no file has been passed, the allow list is not enabled. + EXPECT_FALSE(network::NetworkService::GetNetworkServiceForTesting() + ->network_service_proxy_allow_list() + ->IsEnabled()); +} + +} // namespace component_updater
diff --git a/chrome/browser/component_updater/registration.cc b/chrome/browser/component_updater/registration.cc index cd040d38..00f049e 100644 --- a/chrome/browser/component_updater/registration.cc +++ b/chrome/browser/component_updater/registration.cc
@@ -27,6 +27,7 @@ #include "chrome/browser/component_updater/file_type_policies_component_installer.h" #include "chrome/browser/component_updater/first_party_sets_component_installer.h" #include "chrome/browser/component_updater/hyphenation_component_installer.h" +#include "chrome/browser/component_updater/masked_domain_list_component_installer.h" #include "chrome/browser/component_updater/mei_preload_component_installer.h" #include "chrome/browser/component_updater/pki_metadata_component_installer.h" #include "chrome/browser/component_updater/privacy_sandbox_attestations_component_installer.h" @@ -37,7 +38,6 @@ #include "chrome/common/chrome_paths.h" #include "components/component_updater/component_updater_service.h" #include "components/component_updater/installer_policies/autofill_states_component_installer.h" -#include "components/component_updater/installer_policies/masked_domain_list_component_installer.h" #include "components/component_updater/installer_policies/on_device_head_suggest_component_installer.h" #include "components/component_updater/installer_policies/optimization_hints_component_installer.h" #include "components/component_updater/installer_policies/safety_tips_component_installer.h"
diff --git a/chrome/browser/download/bubble/download_bubble_ui_controller.h b/chrome/browser/download/bubble/download_bubble_ui_controller.h index 452539e5..f293b467 100644 --- a/chrome/browser/download/bubble/download_bubble_ui_controller.h +++ b/chrome/browser/download/bubble/download_bubble_ui_controller.h
@@ -125,7 +125,7 @@ // DownloadDisplayController and DownloadBubbleUIController have the same // lifetime. Both are owned, constructed together, and destructed together by // DownloadToolbarButtonView. If one is valid, so is the other. - raw_ptr<DownloadDisplayController, DanglingUntriaged> display_controller_; + raw_ptr<DownloadDisplayController, DanglingAcrossTasks> display_controller_; absl::optional<base::Time> last_partial_view_shown_time_ = absl::nullopt;
diff --git a/chrome/browser/download/download_query.cc b/chrome/browser/download/download_query.cc index 69872aa0..8c18b81 100644 --- a/chrome/browser/download/download_query.cc +++ b/chrome/browser/download/download_query.cc
@@ -279,7 +279,7 @@ break; // break the switch but not the loop } } - CHECK_NE(left->GetId(), right->GetId()); + CHECK(left == right || left->GetId() != right->GetId()); return left->GetId() < right->GetId(); }
diff --git a/chrome/browser/enterprise/connectors/reporting/extension_install_event_router.h b/chrome/browser/enterprise/connectors/reporting/extension_install_event_router.h index af815ab..7226b67bc 100644 --- a/chrome/browser/enterprise/connectors/reporting/extension_install_event_router.h +++ b/chrome/browser/enterprise/connectors/reporting/extension_install_event_router.h
@@ -38,7 +38,7 @@ void StartObserving(); private: - raw_ptr<RealtimeReportingClient, DanglingUntriaged> reporting_client_ = + raw_ptr<RealtimeReportingClient, DanglingAcrossTasks> reporting_client_ = nullptr; raw_ptr<extensions::ExtensionRegistry, DanglingUntriaged> extension_registry_ = nullptr;
diff --git a/chrome/browser/enterprise/idle/idle_service_interactive_uitest.cc b/chrome/browser/enterprise/idle/idle_service_interactive_uitest.cc index 5bd371b..5254ba3 100644 --- a/chrome/browser/enterprise/idle/idle_service_interactive_uitest.cc +++ b/chrome/browser/enterprise/idle/idle_service_interactive_uitest.cc
@@ -218,7 +218,7 @@ private: testing::NiceMock<policy::MockConfigurationPolicyProvider> policy_providers_[2]; - raw_ptr<MockIdleTimeProvider, DanglingUntriaged> idle_time_provider_; + raw_ptr<MockIdleTimeProvider, DanglingAcrossTasks> idle_time_provider_; scoped_refptr<base::TestMockTimeTaskRunner> task_runner_; std::unique_ptr<ui::test::ScopedIdleProviderForTest> scoped_idle_provider_; std::unique_ptr<ScopedKeepAlive> keep_alive_;
diff --git a/chrome/browser/extensions/api/debugger/debugger_apitest.cc b/chrome/browser/extensions/api/debugger/debugger_apitest.cc index 46b52a82..e0062b9 100644 --- a/chrome/browser/extensions/api/debugger/debugger_apitest.cc +++ b/chrome/browser/extensions/api/debugger/debugger_apitest.cc
@@ -402,9 +402,7 @@ EXPECT_EQ(1u, manager3->infobar_count()); // Closing tab should not affect anything. - EXPECT_EQ(2, another_browser->tab_strip_model()->count()); - another_browser->tab_strip_model()->CloseWebContentsAt(1, 0); - EXPECT_EQ(1, another_browser->tab_strip_model()->count()); + ASSERT_TRUE(another_browser->tab_strip_model()->CloseWebContentsAt(1, 0)); manager3 = nullptr; EXPECT_EQ(1u, manager1->infobar_count()); EXPECT_EQ(1u, manager2->infobar_count());
diff --git a/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_api.cc b/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_api.cc index fe334e2..2a3548fc 100644 --- a/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_api.cc +++ b/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_api.cc
@@ -12,8 +12,8 @@ #include "base/lazy_instance.h" #include "base/strings/string_number_conversions.h" #include "chrome/browser/extensions/extension_tab_util.h" +#include "chrome/browser/media/webrtc/media_device_salt_service_factory.h" #include "components/media_device_salt/media_device_salt_service.h" -#include "components/media_device_salt/media_device_salt_service_factory.h" #include "content/public/browser/audio_service.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" @@ -127,8 +127,8 @@ base::OnceCallback<void(media::AudioDeviceDescriptions)> device_descriptions_callback) { media_device_salt::MediaDeviceSaltService* salt_service = - media_device_salt::MediaDeviceSaltServiceFactory::GetInstance() - ->GetForBrowserContext(browser_context()); + MediaDeviceSaltServiceFactory::GetInstance()->GetForBrowserContext( + browser_context()); if (!salt_service) { GotSalt(is_input_devices, std::move(device_descriptions_callback), browser_context()->UniqueId());
diff --git a/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_browsertest.cc b/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_browsertest.cc index 50d8c12d..ca8e5d9 100644 --- a/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_browsertest.cc +++ b/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_browsertest.cc
@@ -23,6 +23,7 @@ #include "chrome/browser/extensions/component_loader.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/extensions/extension_tab_util.h" +#include "chrome/browser/media/webrtc/media_device_salt_service_factory.h" #include "chrome/browser/media/webrtc/webrtc_log_uploader.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/recently_audible_helper.h" @@ -31,7 +32,6 @@ #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "components/media_device_salt/media_device_salt_service.h" -#include "components/media_device_salt/media_device_salt_service_factory.h" #include "components/network_session_configurator/common/network_switches.h" #include "content/public/browser/audio_service.h" #include "content/public/browser/browser_thread.h" @@ -127,8 +127,8 @@ std::string GetMediaDeviceIDSalt() { media_device_salt::MediaDeviceSaltService* salt_service = - media_device_salt::MediaDeviceSaltServiceFactory::GetInstance() - ->GetForBrowserContext(profile()); + MediaDeviceSaltServiceFactory::GetInstance()->GetForBrowserContext( + profile()); base::test::TestFuture<const std::string&> future; salt_service->GetSalt(future.GetCallback()); return future.Get();
diff --git a/chrome/browser/extensions/chrome_app_sorting.h b/chrome/browser/extensions/chrome_app_sorting.h index ebb6b61e..77180ed0 100644 --- a/chrome/browser/extensions/chrome_app_sorting.h +++ b/chrome/browser/extensions/chrome_app_sorting.h
@@ -184,9 +184,9 @@ const raw_ptr<content::BrowserContext, DanglingUntriaged> browser_context_ = nullptr; - raw_ptr<const web_app::WebAppRegistrar, DanglingUntriaged> + raw_ptr<const web_app::WebAppRegistrar, DanglingAcrossTasks> web_app_registrar_ = nullptr; - raw_ptr<web_app::WebAppSyncBridge, DanglingUntriaged> web_app_sync_bridge_ = + raw_ptr<web_app::WebAppSyncBridge, DanglingAcrossTasks> web_app_sync_bridge_ = nullptr; base::ScopedObservation<web_app::WebAppRegistrar, web_app::WebAppRegistrarObserver>
diff --git a/chrome/browser/extensions/chrome_content_verifier_delegate.h b/chrome/browser/extensions/chrome_content_verifier_delegate.h index c9d5c13c0..504291a 100644 --- a/chrome/browser/extensions/chrome_content_verifier_delegate.h +++ b/chrome/browser/extensions/chrome_content_verifier_delegate.h
@@ -92,7 +92,7 @@ // Returns information needed for content verification of |extension|. VerifyInfo GetVerifyInfo(const Extension& extension) const; - raw_ptr<content::BrowserContext, DanglingUntriaged> context_; + raw_ptr<content::BrowserContext, DanglingAcrossTasks> context_; VerifyInfo::Mode default_mode_; // This maps an extension id to a backoff entry for slowing down
diff --git a/chrome/browser/extensions/chrome_extensions_browser_client.cc b/chrome/browser/extensions/chrome_extensions_browser_client.cc index 3b63061..356f9c4d 100644 --- a/chrome/browser/extensions/chrome_extensions_browser_client.cc +++ b/chrome/browser/extensions/chrome_extensions_browser_client.cc
@@ -44,6 +44,7 @@ #include "chrome/browser/extensions/menu_manager.h" #include "chrome/browser/extensions/updater/chrome_update_client_config.h" #include "chrome/browser/external_protocol/external_protocol_handler.h" +#include "chrome/browser/media/webrtc/media_device_salt_service_factory.h" #include "chrome/browser/net/system_network_context_manager.h" #include "chrome/browser/profiles/keep_alive/profile_keep_alive_types.h" #include "chrome/browser/profiles/keep_alive/scoped_profile_keep_alive.h" @@ -971,4 +972,11 @@ ChromePasswordReuseDetectionManagerClient::CreateForWebContents(web_contents); } +media_device_salt::MediaDeviceSaltService* +ChromeExtensionsBrowserClient::GetMediaDeviceSaltService( + content::BrowserContext* context) { + return MediaDeviceSaltServiceFactory::GetInstance()->GetForBrowserContext( + context); +} + } // namespace extensions
diff --git a/chrome/browser/extensions/chrome_extensions_browser_client.h b/chrome/browser/extensions/chrome_extensions_browser_client.h index 0cb8f00b..52eed1e 100644 --- a/chrome/browser/extensions/chrome_extensions_browser_client.h +++ b/chrome/browser/extensions/chrome_extensions_browser_client.h
@@ -253,6 +253,8 @@ callback) override; void CreatePasswordReuseDetectionManager( content::WebContents* web_contents) const override; + media_device_salt::MediaDeviceSaltService* GetMediaDeviceSaltService( + content::BrowserContext* context) override; private: friend struct base::LazyInstanceTraitsBase<ChromeExtensionsBrowserClient>;
diff --git a/chrome/browser/extensions/component_loader.h b/chrome/browser/extensions/component_loader.h index 01ce06c9..6f88731 100644 --- a/chrome/browser/extensions/component_loader.h +++ b/chrome/browser/extensions/component_loader.h
@@ -227,7 +227,7 @@ raw_ptr<Profile> profile_; - raw_ptr<ExtensionSystem, DanglingUntriaged> extension_system_; + raw_ptr<ExtensionSystem, DanglingAcrossTasks> extension_system_; // List of registered component extensions (see mojom::ManifestLocation). typedef std::vector<ComponentExtensionInfo> RegisteredComponentExtensions;
diff --git a/chrome/browser/extensions/content_script_apitest.cc b/chrome/browser/extensions/content_script_apitest.cc index 4d345336..9b67fd3 100644 --- a/chrome/browser/extensions/content_script_apitest.cc +++ b/chrome/browser/extensions/content_script_apitest.cc
@@ -902,10 +902,8 @@ // should never get a chance to run (and we shouldn't crash). dialog_wait.Run(); EXPECT_FALSE(listener.was_satisfied()); - EXPECT_EQ(2, browser()->tab_strip_model()->count()); - browser()->tab_strip_model()->CloseWebContentsAt( - browser()->tab_strip_model()->active_index(), 0); - EXPECT_EQ(1, browser()->tab_strip_model()->count()); + EXPECT_TRUE(browser()->tab_strip_model()->CloseWebContentsAt( + browser()->tab_strip_model()->active_index(), 0)); EXPECT_FALSE(listener.was_satisfied()); }
diff --git a/chrome/browser/extensions/extension_service.h b/chrome/browser/extensions/extension_service.h index 952ff7b..1e890114 100644 --- a/chrome/browser/extensions/extension_service.h +++ b/chrome/browser/extensions/extension_service.h
@@ -658,7 +658,7 @@ raw_ptr<Profile> profile_ = nullptr; // The ExtensionSystem for the profile above. - raw_ptr<ExtensionSystem, DanglingUntriaged> system_ = nullptr; + raw_ptr<ExtensionSystem, DanglingAcrossTasks> system_ = nullptr; // Preferences for the owning profile. raw_ptr<ExtensionPrefs, DanglingUntriaged> extension_prefs_ = nullptr;
diff --git a/chrome/browser/extensions/extension_util.cc b/chrome/browser/extensions/extension_util.cc index bf49364..2d0a7b6c 100644 --- a/chrome/browser/extensions/extension_util.cc +++ b/chrome/browser/extensions/extension_util.cc
@@ -19,6 +19,7 @@ #include "chrome/browser/ui/webui/extensions/extension_icon_source.h" #include "chrome/common/extensions/api/url_handlers/url_handlers_parser.h" #include "chrome/common/extensions/sync_helper.h" +#include "components/prefs/pref_service.h" #include "components/variations/variations_associated_data.h" #include "content/public/browser/site_instance.h" #include "extensions/browser/disable_reason.h" @@ -26,6 +27,7 @@ #include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" #include "extensions/browser/extension_util.h" +#include "extensions/browser/pref_names.h" #include "extensions/common/extension.h" #include "extensions/common/extension_icon_set.h" #include "extensions/common/extension_urls.h" @@ -69,13 +71,60 @@ return ReloadExtension(extension_id, context); } +// Returns true if the extension ID is found in the InstallForceList policy. Is +// checked by HasIsolatedStorage() when the extension is not found in the +// registry. +bool IsForceInstalledExtension(const ExtensionId& extension_id, + content::BrowserContext* context) { + ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(context); + const PrefService::Preference* const pref = + extension_prefs->pref_service()->FindPreference( + pref_names::kInstallForceList); + if (!pref || !pref->IsManaged() || + pref->GetType() != base::Value::Type::DICT) { + return false; + } + for (const auto item : pref->GetValue()->GetDict()) { + if (extension_id == item.first) { + return true; + } + } + return false; +} + +// Returns true if the profile is a sign-in profile and the extension is policy +// installed. `is_policy_installed` can be passed to the method if its value is +// known (i.e. the extension was found in the registry and the extension +// location was checked). If no value is passed for `is_policy_installed`, the +// force-installed list will be queried for the extension ID. +bool IsLoginScreenExtension( + ExtensionId extension_id, + content::BrowserContext* context, + absl::optional<bool> is_policy_installed = absl::nullopt) { +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Verify the force-installed extension list if no value for + // `is_policy_installed` was passed. + if (is_policy_installed == absl::nullopt) { + is_policy_installed = IsForceInstalledExtension(extension_id, context); + } + Profile* profile = Profile::FromBrowserContext(context); + return profile && ash::ProfileHelper::IsSigninProfile(profile) && + is_policy_installed.value(); +#else + return false; +#endif +} + } // namespace -bool HasIsolatedStorage(const std::string& extension_id, +bool HasIsolatedStorage(const ExtensionId& extension_id, content::BrowserContext* context) { const Extension* extension = ExtensionRegistry::Get(context)->GetInstalledExtension(extension_id); - return extension && HasIsolatedStorage(*extension, context); + // Extension is null when the extension is cleaned up after it's unloaded and + // won't be present in the ExtensionRegistry. + return extension ? HasIsolatedStorage(*extension, context) + : IsLoginScreenExtension(extension_id, context); } bool HasIsolatedStorage(const Extension& extension, @@ -83,9 +132,7 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) const bool is_policy_extension = Manifest::IsPolicyLocation(extension.location()); - Profile* profile = Profile::FromBrowserContext(context); - if (profile && ash::ProfileHelper::IsSigninProfile(profile) && - is_policy_extension) { + if (IsLoginScreenExtension(extension.id(), context, is_policy_extension)) { return true; } #endif
diff --git a/chrome/browser/extensions/extension_util_unittest.cc b/chrome/browser/extensions/extension_util_unittest.cc index c0ca42a..c364431 100644 --- a/chrome/browser/extensions/extension_util_unittest.cc +++ b/chrome/browser/extensions/extension_util_unittest.cc
@@ -4,20 +4,27 @@ #include "chrome/browser/extensions/extension_util.h" +#include "base/memory/raw_ptr.h" #include "base/memory/scoped_refptr.h" +#include "base/strings/strcat.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/extensions/chrome_test_extension_loader.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_service_test_base.h" +#include "chrome/browser/extensions/external_provider_impl.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_constants.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile_manager.h" +#include "components/policy/core/common/mock_configuration_policy_provider.h" +#include "components/policy/core/common/policy_service_impl.h" #include "components/sessions/content/session_tab_helper.h" +#include "components/sync_preferences/testing_pref_service_syncable.h" #include "content/public/test/web_contents_tester.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_util.h" +#include "extensions/browser/pref_names.h" #include "extensions/browser/test_extension_registry_observer.h" #include "extensions/common/extension_builder.h" #include "extensions/common/mojom/manifest.mojom-shared.h" @@ -27,28 +34,19 @@ namespace extensions { +namespace { + +#if BUILDFLAG(IS_CHROMEOS_ASH) +constexpr char kExtensionUpdateUrl[] = + "https://clients2.google.com/service/update2/crx"; // URL of Chrome Web + // Store backend. +#endif + +} // namespace + class ExtensionUtilUnittest : public ExtensionServiceTestBase { public: - void SetUp() override { - InitializeEmptyExtensionService(); - testing_profile_manager_ = std::make_unique<TestingProfileManager>( - TestingBrowserProcess::GetGlobal(), &testing_local_state_); - ASSERT_TRUE(testing_profile_manager_->SetUp()); - signin_profile_ = - testing_profile_manager_->CreateTestingProfile(chrome::kInitialProfile); - } - - scoped_refptr<const Extension> BuildPolicyInstalledExtension() { - return ExtensionBuilder("foo_ext") - .SetLocation(mojom::ManifestLocation::kExternalPolicyDownload) - .Build(); - } - - protected: - raw_ptr<TestingProfile, DanglingUntriaged> signin_profile_; - - private: - std::unique_ptr<TestingProfileManager> testing_profile_manager_; + void SetUp() override { InitializeEmptyExtensionService(); } }; TEST_F(ExtensionUtilUnittest, SetAllowFileAccess) { @@ -187,26 +185,68 @@ ExtensionBuilder("foo_ext").Build(); EXPECT_FALSE(extension->is_platform_app()); EXPECT_FALSE(util::HasIsolatedStorage(*extension.get(), profile())); - - // Extensions running on the sign-in screen, installed by policy have isolated - // storage. -#if BUILDFLAG(IS_CHROMEOS_ASH) - scoped_refptr<const Extension> policy_extension = - BuildPolicyInstalledExtension(); - EXPECT_FALSE(policy_extension->is_platform_app()); - EXPECT_TRUE( - util::HasIsolatedStorage(*policy_extension.get(), signin_profile_)); -#endif } +#if BUILDFLAG(IS_CHROMEOS_ASH) +class ExtensionUtilWithSigninProfileUnittest : public ExtensionUtilUnittest { + public: + void SetUp() override { + ExtensionUtilUnittest::SetUp(); + + testing_profile_manager_ = std::make_unique<TestingProfileManager>( + TestingBrowserProcess::GetGlobal(), &testing_local_state_); + ASSERT_TRUE(testing_profile_manager_->SetUp()); + auto policy_service = std::make_unique<policy::PolicyServiceImpl>( + std::vector<policy::ConfigurationPolicyProvider*>{policy_provider()}); + signin_profile_ = testing_profile_manager_->CreateTestingProfile( + chrome::kInitialProfile, /*prefs=*/nullptr, + base::UTF8ToUTF16(chrome::kInitialProfile), 0, + TestingProfile::TestingFactories(), + /*is_supervised_profile=*/false, /*is_new_profile=*/absl::nullopt, + std::move(policy_service)); + signin_profile_prefs_ = signin_profile_->GetTestingPrefService(); + } + + void TearDown() override { + signin_profile_ = nullptr; + signin_profile_prefs_ = nullptr; + testing_profile_manager_->DeleteAllTestingProfiles(); + ExtensionUtilUnittest::TearDown(); + } + + scoped_refptr<const Extension> BuildPolicyInstalledExtension() { + return ExtensionBuilder("foo_ext") + .SetLocation(mojom::ManifestLocation::kExternalPolicyDownload) + .Build(); + } + + void SetupForceList(const ExtensionIdList& extension_ids) { + base::Value::Dict dict = base::Value::Dict(); + for (const auto& extension_id : extension_ids) { + dict.Set(extension_id, + base::Value::Dict().Set(ExternalProviderImpl::kExternalUpdateUrl, + kExtensionUpdateUrl)); + } + signin_profile_prefs_->SetManagedPref(pref_names::kInstallForceList, + std::move(dict)); + } + + protected: + raw_ptr<TestingProfile> signin_profile_; + + private: + std::unique_ptr<TestingProfileManager> testing_profile_manager_; + raw_ptr<sync_preferences::TestingPrefServiceSyncable> signin_profile_prefs_; +}; + // HasIsolatedStorage() will be called when an extension is disabled, more // precisely when its service worker is unregistered. At that moment the // extension is already added to the disabled list of the extension registry. // The method needs to still be able to correctly specify if the extension's // storage is isolated or not, even if the extension is disabled. // Regression test for b/279763783. -#if BUILDFLAG(IS_CHROMEOS_ASH) -TEST_F(ExtensionUtilUnittest, HasIsolatedStorageOnDisabledExtension) { +TEST_F(ExtensionUtilWithSigninProfileUnittest, + HasIsolatedStorageOnDisabledExtension) { scoped_refptr<const Extension> policy_extension = BuildPolicyInstalledExtension(); const std::string& policy_extension_id = policy_extension->id(); @@ -228,7 +268,7 @@ EXPECT_FALSE(util::HasIsolatedStorage(policy_extension_id, signin_profile_)); } -TEST_F(ExtensionUtilUnittest, +TEST_F(ExtensionUtilWithSigninProfileUnittest, HasIsolatedStorageOnTerminatedOrBlockedExtension) { scoped_refptr<const Extension> policy_extension = BuildPolicyInstalledExtension(); @@ -260,6 +300,47 @@ extension_registry->RemoveBlocked(policy_extension_id); EXPECT_FALSE(util::HasIsolatedStorage(policy_extension_id, signin_profile_)); } + +// Verifies that the force-installed extension policy is checked in case it +// was not found in the extension registry. When an extension is unloaded, we +// clean up state from the extension. For service worker-based extensions, +// this includes unregistering the worker, which requires access to the +// storage partition. At this point, since the extension is unloaded, it won't +// be present in the registry, but we still need to determine if the extension +// has isolated storage to pinpoint the correct storage partition. +// Regression test for b/287924795. +TEST_F(ExtensionUtilWithSigninProfileUnittest, + HasIsolatedStorageForForceInstalledExtensions) { + scoped_refptr<const Extension> extension1 = BuildPolicyInstalledExtension(); + scoped_refptr<const Extension> extension2 = BuildPolicyInstalledExtension(); + ExtensionRegistry* extension_registry = + ExtensionRegistry::Get(signin_profile_); + extension_registry->AddEnabled(extension1); + extension_registry->AddEnabled(extension2); + + // Extensions are found in the registry, are policy-installed and run on the + // sign-in screen. + EXPECT_TRUE(util::HasIsolatedStorage(extension1->id(), signin_profile_)); + EXPECT_TRUE(util::HasIsolatedStorage(extension2->id(), signin_profile_)); + + extension_registry->RemoveEnabled(extension1->id()); + extension_registry->RemoveEnabled(extension2->id()); + + // Extensions are not found in the registry and are not force-installed. + EXPECT_FALSE(util::HasIsolatedStorage(extension1->id(), signin_profile_)); + EXPECT_FALSE(util::HasIsolatedStorage(extension2->id(), signin_profile_)); + + ExtensionIdList extension_ids; + extension_ids.push_back(extension1->id()); + extension_ids.push_back(extension2->id()); + SetupForceList(extension_ids); + + // Extensions are not found in the registry, but are force-installed and run + // on the sign-in screen. + EXPECT_TRUE(util::HasIsolatedStorage(extension1->id(), signin_profile_)); + EXPECT_TRUE(util::HasIsolatedStorage(extension2->id(), signin_profile_)); +} + #endif } // namespace extensions
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 000034291..74d4bf6 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -6175,7 +6175,7 @@ { "name": "page-info-about-this-site-improved-bottomsheet", "owners": [ "dullweber", "eokoyomon", "zalmashni@google.com" ], - "expiry_milestone": 116 + "expiry_milestone": 118 }, { "name": "page-info-about-this-site-keep-side-panel-open-on-same-tab-navs",
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java index 7c89ebe..ad7a499 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -550,6 +550,8 @@ public static final CachedFlag sInstanceSwitcher = new CachedFlag(INSTANCE_SWITCHER, true); public static final CachedFlag sInstantStart = new CachedFlag(INSTANT_START, false); public static final CachedFlag sInterestFeedV2 = new CachedFlag(INTEREST_FEED_V2, true); + public static final CachedFlag sPrivacyGuidePostMVP = + new CachedFlag(PRIVACY_GUIDE_POST_MVP, false); public static final CachedFlag sOmniboxMatchToolbarAndStatusBarColor = new CachedFlag(OMNIBOX_MATCH_TOOLBAR_AND_STATUS_BAR_COLOR, false); public static final CachedFlag sOmniboxModernizeVisualUpdate = @@ -645,6 +647,7 @@ sInstanceSwitcher, sInstantStart, sInterestFeedV2, + sPrivacyGuidePostMVP, sOmniboxMatchToolbarAndStatusBarColor, sOmniboxModernizeVisualUpdate, sOmniboxMostVisitedTilesAddRecycledViewPool,
diff --git a/chrome/browser/font_family_cache.h b/chrome/browser/font_family_cache.h index 459a2595..6ec531bb 100644 --- a/chrome/browser/font_family_cache.h +++ b/chrome/browser/font_family_cache.h
@@ -83,7 +83,7 @@ // Weak reference. // Note: The lifetime of this object is tied to the lifetime of the // PrefService, so there is no worry about an invalid pointer. - raw_ptr<const PrefService, DanglingUntriaged> prefs_; + raw_ptr<const PrefService, DanglingAcrossTasks> prefs_; // Reacts to profile font changes. |font_change_registrar_| will be // automatically unregistered when the FontPrefChangeNotifier is destroyed as
diff --git a/chrome/browser/media/media_engagement_browsertest.cc b/chrome/browser/media/media_engagement_browsertest.cc index 37527c2..27d4ec9 100644 --- a/chrome/browser/media/media_engagement_browsertest.cc +++ b/chrome/browser/media/media_engagement_browsertest.cc
@@ -243,9 +243,7 @@ } void CloseTab() { - const int previous_tab_count = browser()->tab_strip_model()->count(); - browser()->tab_strip_model()->CloseWebContentsAt(0, 0); - EXPECT_EQ(previous_tab_count - 1, browser()->tab_strip_model()->count()); + EXPECT_TRUE(browser()->tab_strip_model()->CloseWebContentsAt(0, 0)); } void LoadSubFrame(const GURL& url) {
diff --git a/components/media_device_salt/media_device_salt_service_factory.cc b/chrome/browser/media/webrtc/media_device_salt_service_factory.cc similarity index 76% rename from components/media_device_salt/media_device_salt_service_factory.cc rename to chrome/browser/media/webrtc/media_device_salt_service_factory.cc index a2fcddbe..1dc95ce52 100644 --- a/components/media_device_salt/media_device_salt_service_factory.cc +++ b/chrome/browser/media/webrtc/media_device_salt_service_factory.cc
@@ -2,23 +2,22 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/media_device_salt/media_device_salt_service_factory.h" +#include "chrome/browser/media/webrtc/media_device_salt_service_factory.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/media_device_salt/media_device_salt_service.h" #include "components/user_prefs/user_prefs.h" #include "content/public/browser/browser_context.h" -namespace media_device_salt { - MediaDeviceSaltServiceFactory* MediaDeviceSaltServiceFactory::GetInstance() { static base::NoDestructor<MediaDeviceSaltServiceFactory> factory; return factory.get(); } -MediaDeviceSaltService* MediaDeviceSaltServiceFactory::GetForBrowserContext( +media_device_salt::MediaDeviceSaltService* +MediaDeviceSaltServiceFactory::GetForBrowserContext( content::BrowserContext* context) { - return static_cast<MediaDeviceSaltService*>( + return static_cast<media_device_salt::MediaDeviceSaltService*>( GetInstance()->GetServiceForBrowserContext(context, true)); } @@ -30,8 +29,6 @@ std::unique_ptr<KeyedService> MediaDeviceSaltServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { - return std::make_unique<MediaDeviceSaltService>( + return std::make_unique<media_device_salt::MediaDeviceSaltService>( user_prefs::UserPrefs::Get(context)); } - -} // namespace media_device_salt
diff --git a/components/media_device_salt/media_device_salt_service_factory.h b/chrome/browser/media/webrtc/media_device_salt_service_factory.h similarity index 80% rename from components/media_device_salt/media_device_salt_service_factory.h rename to chrome/browser/media/webrtc/media_device_salt_service_factory.h index 3fa5be5c..882dda9 100644 --- a/components/media_device_salt/media_device_salt_service_factory.h +++ b/chrome/browser/media/webrtc/media_device_salt_service_factory.h
@@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_MEDIA_DEVICE_SALT_MEDIA_DEVICE_SALT_SERVICE_FACTORY_H_ -#define COMPONENTS_MEDIA_DEVICE_SALT_MEDIA_DEVICE_SALT_SERVICE_FACTORY_H_ +#ifndef CHROME_BROWSER_MEDIA_WEBRTC_MEDIA_DEVICE_SALT_SERVICE_FACTORY_H_ +#define CHROME_BROWSER_MEDIA_WEBRTC_MEDIA_DEVICE_SALT_SERVICE_FACTORY_H_ #include "base/no_destructor.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h" namespace media_device_salt { - class MediaDeviceSaltService; +} // namespace media_device_salt class MediaDeviceSaltServiceFactory : public BrowserContextKeyedServiceFactory { public: @@ -22,7 +22,7 @@ static MediaDeviceSaltServiceFactory* GetInstance(); // Returns the MediaDeviceSaltService associated with |context|. - static MediaDeviceSaltService* GetForBrowserContext( + static media_device_salt::MediaDeviceSaltService* GetForBrowserContext( content::BrowserContext* context); private: @@ -36,6 +36,4 @@ content::BrowserContext* context) const override; }; -} // namespace media_device_salt - -#endif // COMPONENTS_MEDIA_DEVICE_SALT_MEDIA_DEVICE_SALT_SERVICE_FACTORY_H_ +#endif // CHROME_BROWSER_MEDIA_WEBRTC_MEDIA_DEVICE_SALT_SERVICE_FACTORY_H_
diff --git a/chrome/browser/media/webrtc/media_device_salt_service_factory_unittest.cc b/chrome/browser/media/webrtc/media_device_salt_service_factory_unittest.cc new file mode 100644 index 0000000..4dd0ea3 --- /dev/null +++ b/chrome/browser/media/webrtc/media_device_salt_service_factory_unittest.cc
@@ -0,0 +1,27 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/media/webrtc/media_device_salt_service_factory.h" + +#include "base/test/test_future.h" +#include "chrome/test/base/testing_profile.h" +#include "components/media_device_salt/media_device_salt_service.h" +#include "content/public/test/browser_task_environment.h" +#include "testing/gtest/include/gtest/gtest.h" + +TEST(MediaDeviceSaltServiceFactoryTest, Test) { + content::BrowserTaskEnvironment task_environment; + TestingProfile profile; + + MediaDeviceSaltServiceFactory* factory = + MediaDeviceSaltServiceFactory::GetInstance(); + ASSERT_TRUE(factory); + + auto* service = factory->GetForBrowserContext(&profile); + ASSERT_TRUE(service); + + base::test::TestFuture<const std::string&> future; + service->GetSalt(future.GetCallback()); + EXPECT_FALSE(future.Get().empty()); +}
diff --git a/chrome/browser/media/webrtc/media_stream_devices_controller_browsertest.cc b/chrome/browser/media/webrtc/media_stream_devices_controller_browsertest.cc index b72efcf..2b60ca4 100644 --- a/chrome/browser/media/webrtc/media_stream_devices_controller_browsertest.cc +++ b/chrome/browser/media/webrtc/media_stream_devices_controller_browsertest.cc
@@ -978,10 +978,8 @@ // PermissionRequestManager for the WebContents and uses that reference in its // destructor, it has to be destroyed before the tab. prompt_factory_.reset(); - int previous_tab_count = browser()->tab_strip_model()->count(); - browser()->tab_strip_model()->CloseWebContentsAt( - prompt_contents_index, TabCloseTypes::CLOSE_USER_GESTURE); - EXPECT_EQ(previous_tab_count - 1, browser()->tab_strip_model()->count()); + ASSERT_TRUE(browser()->tab_strip_model()->CloseWebContentsAt( + prompt_contents_index, TabCloseTypes::CLOSE_USER_GESTURE)); base::RunLoop().RunUntilIdle(); VerifyResultState(
diff --git a/chrome/browser/metrics/chrome_feature_list_creator.h b/chrome/browser/metrics/chrome_feature_list_creator.h index 808e056..df5c081 100644 --- a/chrome/browser/metrics/chrome_feature_list_creator.h +++ b/chrome/browser/metrics/chrome_feature_list_creator.h
@@ -120,7 +120,7 @@ std::string actual_locale_; // This is owned by |metrics_services_manager_| but we need to expose it. - raw_ptr<ChromeMetricsServicesManagerClient, DanglingUntriaged> + raw_ptr<ChromeMetricsServicesManagerClient, DanglingAcrossTasks> metrics_services_manager_client_; std::unique_ptr<metrics_services_manager::MetricsServicesManager>
diff --git a/chrome/browser/metrics/usage_scenario/tab_usage_scenario_tracker_browsertest.cc b/chrome/browser/metrics/usage_scenario/tab_usage_scenario_tracker_browsertest.cc index e3dad879..e8917be 100644 --- a/chrome/browser/metrics/usage_scenario/tab_usage_scenario_tracker_browsertest.cc +++ b/chrome/browser/metrics/usage_scenario/tab_usage_scenario_tracker_browsertest.cc
@@ -199,10 +199,8 @@ ->GetActiveWebContents() ->GetPrimaryMainFrame() ->GetPageUkmSourceId(); - int previous_tab_count = browser()->tab_strip_model()->count(); - browser()->tab_strip_model()->CloseWebContentsAt( - 0, TabCloseTypes::CLOSE_USER_GESTURE); - EXPECT_EQ(previous_tab_count - 1, browser()->tab_strip_model()->count()); + EXPECT_TRUE(browser()->tab_strip_model()->CloseWebContentsAt( + 0, TabCloseTypes::CLOSE_USER_GESTURE)); tick_clock_.Advance(kInterval); interval_data = data_store_.ResetIntervalData(); EXPECT_EQ(2U, interval_data.max_tab_count); @@ -454,10 +452,8 @@ tick_clock_.Advance(kInterval * 2); auto expected_source_id = contents->GetPrimaryMainFrame()->GetPageUkmSourceId(); - int previous_tab_count = browser()->tab_strip_model()->count(); - browser()->tab_strip_model()->CloseWebContentsAt( - 1, TabCloseTypes::CLOSE_USER_GESTURE); - EXPECT_EQ(previous_tab_count - 1, browser()->tab_strip_model()->count()); + EXPECT_TRUE(browser()->tab_strip_model()->CloseWebContentsAt( + 1, TabCloseTypes::CLOSE_USER_GESTURE)); auto interval_data = data_store_.ResetIntervalData(); EXPECT_EQ(2U, interval_data.max_tab_count); @@ -558,13 +554,8 @@ ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER); Browser* browser2 = BrowserList::GetInstance()->get(1); - int previous_browser1_tab_count = browser()->tab_strip_model()->count(); - int previous_browser2_tab_count = browser2->tab_strip_model()->count(); - browser2->tab_strip_model()->CloseWebContentsAt( - 0, TabCloseTypes::CLOSE_USER_GESTURE); - EXPECT_EQ(previous_browser1_tab_count, browser()->tab_strip_model()->count()); - EXPECT_EQ(previous_browser2_tab_count - 1, - browser2->tab_strip_model()->count()); + EXPECT_TRUE(browser2->tab_strip_model()->CloseWebContentsAt( + 0, TabCloseTypes::CLOSE_USER_GESTURE)); tick_clock_.Advance(kInterval); auto interval_data = data_store_.ResetIntervalData();
diff --git a/chrome/browser/page_load_metrics/observers/https_engagement_metrics/https_engagement_page_load_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/https_engagement_metrics/https_engagement_page_load_metrics_observer_browsertest.cc index ef56d20..088700e 100644 --- a/chrome/browser/page_load_metrics/observers/https_engagement_metrics/https_engagement_page_load_metrics_observer_browsertest.cc +++ b/chrome/browser/page_load_metrics/observers/https_engagement_metrics/https_engagement_page_load_metrics_observer_browsertest.cc
@@ -102,9 +102,7 @@ content::WebContentsDestroyedWatcher destroyed_watcher( tab_strip_model->GetWebContentsAt(0)); - int previous_tab_count = tab_strip_model->count(); - tab_strip_model->CloseWebContentsAt(0, 0); - EXPECT_EQ(previous_tab_count - 1, tab_strip_model->count()); + EXPECT_TRUE(tab_strip_model->CloseWebContentsAt(0, 0)); destroyed_watcher.Wait(); EXPECT_EQ(1, tab_strip_model->count()); @@ -128,9 +126,7 @@ content::WebContentsDestroyedWatcher destroyed_watcher( tab_strip_model->GetWebContentsAt(1)); - int previous_tab_count = tab_strip_model->count(); - tab_strip_model->CloseWebContentsAt(1, 0); - EXPECT_EQ(previous_tab_count - 1, tab_strip_model->count()); + EXPECT_TRUE(tab_strip_model->CloseWebContentsAt(1, 0)); destroyed_watcher.Wait(); EXPECT_EQ(1, tab_strip_model->count()); } @@ -155,9 +151,7 @@ base::TimeTicks start = base::TimeTicks::Now(); content::WebContentsDestroyedWatcher destroyed_watcher( tab_strip_model->GetWebContentsAt(0)); - int previous_tab_count = tab_strip_model->count(); - tab_strip_model->CloseWebContentsAt(0, 0); - EXPECT_EQ(previous_tab_count - 1, tab_strip_model->count()); + EXPECT_TRUE(tab_strip_model->CloseWebContentsAt(0, 0)); destroyed_watcher.Wait(); // Now the background tab should have moved to the foreground. @@ -294,9 +288,8 @@ browser(), https_test_server_->GetURL("/simple.html"))); content::WebContentsDestroyedWatcher destroyed_watcher( tab_strip_model->GetActiveWebContents()); - int previous_tab_count = tab_strip_model->count(); - tab_strip_model->CloseWebContentsAt(tab_strip_model->active_index(), 0); - EXPECT_EQ(previous_tab_count - 1, tab_strip_model->count()); + EXPECT_TRUE( + tab_strip_model->CloseWebContentsAt(tab_strip_model->active_index(), 0)); destroyed_watcher.Wait(); histogram_tester_.ExpectTotalCount(internal::kHttpEngagementHistogram, 0); histogram_tester_.ExpectTotalCount(internal::kHttpsEngagementHistogram, 0);
diff --git a/chrome/browser/page_load_metrics/observers/multi_tab_loading_page_load_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/multi_tab_loading_page_load_metrics_observer_browsertest.cc index 05d686f..2250cc8a 100644 --- a/chrome/browser/page_load_metrics/observers/multi_tab_loading_page_load_metrics_observer_browsertest.cc +++ b/chrome/browser/page_load_metrics/observers/multi_tab_loading_page_load_metrics_observer_browsertest.cc
@@ -101,9 +101,7 @@ TabStripModel* tab_strip_model = browser()->tab_strip_model(); content::WebContentsDestroyedWatcher destroyed_watcher( tab_strip_model->GetWebContentsAt(0)); - int previous_tab_count = tab_strip_model->count(); - tab_strip_model->CloseWebContentsAt(0, 0); - EXPECT_EQ(previous_tab_count - 1, tab_strip_model->count()); + EXPECT_TRUE(tab_strip_model->CloseWebContentsAt(0, 0)); destroyed_watcher.Wait(); // Now the background tab should have moved to the foreground.
diff --git a/chrome/browser/page_load_metrics/observers/security_state_page_load_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/security_state_page_load_metrics_observer_browsertest.cc index 17d9e62..85e4579 100644 --- a/chrome/browser/page_load_metrics/observers/security_state_page_load_metrics_observer_browsertest.cc +++ b/chrome/browser/page_load_metrics/observers/security_state_page_load_metrics_observer_browsertest.cc
@@ -294,10 +294,8 @@ run_loop.Run(); // The UKM isn't recorded until the page is destroyed. - int previous_tab_count = browser()->tab_strip_model()->count(); - browser()->tab_strip_model()->CloseWebContentsAt(1, - TabCloseTypes::CLOSE_NONE); - ASSERT_EQ(previous_tab_count - 1, browser()->tab_strip_model()->count()); + ASSERT_TRUE(browser()->tab_strip_model()->CloseWebContentsAt( + 1, TabCloseTypes::CLOSE_NONE)); histogram_tester.ExpectTotalCount( kSiteEngagementHistogramPrefix + (test_case.expect_safety_tip
diff --git a/chrome/browser/password_manager/android/local_passwords_migration_warning_util.cc b/chrome/browser/password_manager/android/local_passwords_migration_warning_util.cc index ca7309c8..ffda68d 100644 --- a/chrome/browser/password_manager/android/local_passwords_migration_warning_util.cc +++ b/chrome/browser/password_manager/android/local_passwords_migration_warning_util.cc
@@ -3,13 +3,18 @@ // found in the LICENSE file. #include "chrome/browser/password_manager/android/local_passwords_migration_warning_util.h" + +#include "base/android/scoped_java_ref.h" #include "base/time/time.h" #include "chrome/android/chrome_jni_headers/PasswordMigrationWarningBridge_jni.h" #include "chrome/browser/profiles/profile_android.h" +#include "chrome/browser/sync/sync_service_factory.h" +#include "components/password_manager/core/browser/password_bubble_experiment.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 "ui/android/window_android.h" +#include "ui/gfx/native_widget_types.h" using base::android::AttachCurrentThread; @@ -27,24 +32,54 @@ if (!ShouldShowWarning(profile)) { return; } + SaveWarningShownTimestamp(profile->GetPrefs()); + Java_PasswordMigrationWarningBridge_showWarning( AttachCurrentThread(), window->GetJavaObject(), ProfileAndroid::FromProfile(profile)->GetJavaObject()); +} + +void ShowWarningWithActivity( + const base::android::JavaParamRef<jobject>& activity, + const base::android::JavaParamRef<jobject>& bottom_sheet_controller, + Profile* profile) { + if (!ShouldShowWarning(profile)) { + return; + } SaveWarningShownTimestamp(profile->GetPrefs()); + + Java_PasswordMigrationWarningBridge_showWarningWithActivity( + AttachCurrentThread(), activity, bottom_sheet_controller, + ProfileAndroid::FromProfile(profile)->GetJavaObject()); } bool ShouldShowWarning(Profile* profile) { + if (profile->IsOffTheRecord()) { + return false; + } + if (!base::FeatureList::IsEnabled( password_manager::features:: kUnifiedPasswordManagerLocalPasswordsMigrationWarning)) { return false; } + PrefService* pref_service = profile->GetPrefs(); + bool is_warning_acknowledged = pref_service->GetBoolean( + password_manager::prefs::kUserAcknowledgedLocalPasswordsMigrationWarning); + if (is_warning_acknowledged) { + return false; + } + + if (password_bubble_experiment::HasChosenToSyncPasswords( + SyncServiceFactory::GetForProfile(profile))) { + return false; + } + if (password_manager::features::kIgnoreMigrationWarningTimeout.Get()) { return true; } - PrefService* pref_service = profile->GetPrefs(); base::Time last_shown_timestamp = pref_service->GetTime( password_manager::prefs::kLocalPasswordsMigrationWarningShownTimestamp); base::TimeDelta time_since_last_shown = @@ -53,8 +88,6 @@ return false; } - // TODO(crbug.com/1451827): Check whether the user is already syncing - // passwords. return true; }
diff --git a/chrome/browser/password_manager/android/local_passwords_migration_warning_util.h b/chrome/browser/password_manager/android/local_passwords_migration_warning_util.h index 66126b6..e60f8b7 100644 --- a/chrome/browser/password_manager/android/local_passwords_migration_warning_util.h +++ b/chrome/browser/password_manager/android/local_passwords_migration_warning_util.h
@@ -13,6 +13,13 @@ // Shows the local password migration warning. void ShowWarning(const gfx::NativeWindow window, Profile* profile); +// Shows the local password migration warning. `activity` is provided from +// java. +void ShowWarningWithActivity( + const base::android::JavaParamRef<jobject>& activity, + const base::android::JavaParamRef<jobject>& bottom_sheet_controller, + Profile* profile); + // Returns whether the UPM local passwords migration warning should be // displayed. `profile` is used to retrieve necessary services for checking // the conditions.
diff --git a/chrome/browser/password_manager/android/local_passwords_migration_warning_util_unittest.cc b/chrome/browser/password_manager/android/local_passwords_migration_warning_util_unittest.cc index fa89ec7..90054b8 100644 --- a/chrome/browser/password_manager/android/local_passwords_migration_warning_util_unittest.cc +++ b/chrome/browser/password_manager/android/local_passwords_migration_warning_util_unittest.cc
@@ -5,15 +5,24 @@ #include "chrome/browser/password_manager/android/local_passwords_migration_warning_util.h" #include "base/test/scoped_feature_list.h" #include "base/time/time.h" +#include "chrome/browser/sync/sync_service_factory.h" #include "chrome/test/base/testing_profile.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 "components/sync/test/test_sync_service.h" #include "components/sync_preferences/testing_pref_service_syncable.h" #include "content/public/test/browser_task_environment.h" #include "testing/gtest/include/gtest/gtest.h" +namespace { +std::unique_ptr<KeyedService> TestingSyncFactoryFunction( + content::BrowserContext* context) { + return std::make_unique<syncer::TestSyncService>(); +} +} // namespace + class LocalPasswordsMigrationWarningUtilTest : public testing::Test { protected: LocalPasswordsMigrationWarningUtilTest() = default; @@ -23,14 +32,23 @@ return profile_.GetTestingPrefService(); } - Profile* profile() { return &profile_; } + syncer::TestSyncService* sync_service() { return fake_sync_service_; } + + TestingProfile* profile() { return &profile_; } base::test::TaskEnvironment* task_env() { return &task_env_; } + void SetUp() override { + fake_sync_service_ = static_cast<syncer::TestSyncService*>( + SyncServiceFactory::GetInstance()->SetTestingFactoryAndUse( + profile(), base::BindRepeating(&TestingSyncFactoryFunction))); + } + private: content::BrowserTaskEnvironment task_env_{ base::test::TaskEnvironment::TimeSource::MOCK_TIME}; TestingProfile profile_; + raw_ptr<syncer::TestSyncService> fake_sync_service_; }; TEST_F(LocalPasswordsMigrationWarningUtilTest, @@ -51,6 +69,7 @@ password_manager::prefs::kLocalPasswordsMigrationWarningShownTimestamp, base::Time::Now()); task_env()->FastForwardBy(base::Days(31)); + sync_service()->SetHasSyncConsent(false); EXPECT_TRUE(local_password_migration::ShouldShowWarning(profile())); } @@ -63,5 +82,64 @@ password_manager::prefs::kLocalPasswordsMigrationWarningShownTimestamp, base::Time::Now()); task_env()->FastForwardBy(base::Days(29)); + sync_service()->SetHasSyncConsent(false); EXPECT_FALSE(local_password_migration::ShouldShowWarning(profile())); } + +TEST_F(LocalPasswordsMigrationWarningUtilTest, + TestShouldNotShowWhenAcknowledged) { + base::test::ScopedFeatureList scoped_feature_list( + password_manager::features:: + kUnifiedPasswordManagerLocalPasswordsMigrationWarning); + pref_service()->SetBoolean( + password_manager::prefs::kUserAcknowledgedLocalPasswordsMigrationWarning, + true); + EXPECT_FALSE(local_password_migration::ShouldShowWarning(profile())); +} + +TEST_F(LocalPasswordsMigrationWarningUtilTest, + TestShouldNotShowWhenSyncingOnlyPasswords) { + base::test::ScopedFeatureList scoped_feature_list( + password_manager::features:: + kUnifiedPasswordManagerLocalPasswordsMigrationWarning); + sync_service()->SetHasSyncConsent(true); + sync_service()->GetUserSettings()->SetSelectedTypes( + /* sync_everything = */ false, {syncer::UserSelectableType::kPasswords}); + EXPECT_FALSE(local_password_migration::ShouldShowWarning(profile())); +} + +TEST_F(LocalPasswordsMigrationWarningUtilTest, + TestShouldNotShowWhenSyncingEverything) { + base::test::ScopedFeatureList scoped_feature_list( + password_manager::features:: + kUnifiedPasswordManagerLocalPasswordsMigrationWarning); + sync_service()->SetHasSyncConsent(true); + sync_service()->GetUserSettings()->SetSelectedTypes( + /* sync_everything = */ true, {}); + EXPECT_FALSE(local_password_migration::ShouldShowWarning(profile())); +} + +TEST_F(LocalPasswordsMigrationWarningUtilTest, + TestShouldShowWhenNotSyncingPasswords) { + base::test::ScopedFeatureList scoped_feature_list( + password_manager::features:: + kUnifiedPasswordManagerLocalPasswordsMigrationWarning); + sync_service()->SetHasSyncConsent(true); + sync_service()->GetUserSettings()->SetSelectedTypes( + /* sync_everything = */ false, {syncer::UserSelectableType::kBookmarks}); + EXPECT_TRUE(local_password_migration::ShouldShowWarning(profile())); +} + +TEST_F(LocalPasswordsMigrationWarningUtilTest, TestShouldNotShowInIncognito) { + base::test::ScopedFeatureList scoped_feature_list( + password_manager::features:: + kUnifiedPasswordManagerLocalPasswordsMigrationWarning); + sync_service()->GetUserSettings()->SetSelectedTypes( + /* sync_everything = */ false, {}); + TestingProfile::Builder off_the_record_builder; + Profile* off_the_record_profile = + off_the_record_builder.BuildIncognito(profile()); + + EXPECT_FALSE( + local_password_migration::ShouldShowWarning(off_the_record_profile)); +}
diff --git a/chrome/browser/password_manager/android/password_ui_view_android.cc b/chrome/browser/password_manager/android/password_ui_view_android.cc index a3d18ac39..648b5480 100644 --- a/chrome/browser/password_manager/android/password_ui_view_android.cc +++ b/chrome/browser/password_manager/android/password_ui_view_android.cc
@@ -279,6 +279,14 @@ context, settings_launcher); } +void PasswordUIViewAndroid::ShowMigrationWarning( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& activity, + const base::android::JavaParamRef<jobject>& bottom_sheet_controller) { + local_password_migration::ShowWarningWithActivity( + activity, bottom_sheet_controller, ProfileManager::GetLastUsedProfile()); +} + void PasswordUIViewAndroid::OnEditUIDismissed() { credential_edit_bridge_.reset(); } @@ -302,11 +310,6 @@ identity_manager); } -jboolean JNI_PasswordUIView_ShouldShowMigrationWarning(JNIEnv* env) { - return local_password_migration::ShouldShowWarning( - ProfileManager::GetLastUsedProfile()); -} - // static static jlong JNI_PasswordUIView_Init(JNIEnv* env, const JavaParamRef<jobject>& obj) {
diff --git a/chrome/browser/password_manager/android/password_ui_view_android.h b/chrome/browser/password_manager/android/password_ui_view_android.h index 840d8ec..d026f5f 100644 --- a/chrome/browser/password_manager/android/password_ui_view_android.h +++ b/chrome/browser/password_manager/android/password_ui_view_android.h
@@ -94,6 +94,10 @@ const base::android::JavaRef<jobject>& settings_launcher, int index, const base::android::JavaParamRef<jobject>& obj); + void ShowMigrationWarning( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& activity, + const base::android::JavaParamRef<jobject>& controller); // Destroy the native implementation. void Destroy(JNIEnv*, const base::android::JavaRef<jobject>&);
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.h b/chrome/browser/password_manager/chrome_password_manager_client.h index 287499d..c6b570e 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client.h +++ b/chrome/browser/password_manager/chrome_password_manager_client.h
@@ -400,7 +400,7 @@ #endif // BUILDFLAG(IS_ANDROID) raw_ptr<password_manager::ContentPasswordManagerDriverFactory, - DanglingUntriaged> + DanglingAcrossTasks> driver_factory_; // As a mojo service, will be registered into service registry
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc index f919208c..80b56646 100644 --- a/chrome/browser/pdf/pdf_extension_test.cc +++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -304,10 +304,8 @@ // the middle of initialization. In https://crbug.com/1295431, the extension // process exited here and caused a crash when the second PDF resumed. EXPECT_EQ(2U, GetGuestViewManager()->GetCurrentGuestCount()); - ASSERT_EQ(2, browser()->tab_strip_model()->count()); - browser()->tab_strip_model()->CloseWebContentsAt( - 0, TabCloseTypes::CLOSE_USER_GESTURE); - ASSERT_EQ(1, browser()->tab_strip_model()->count()); + ASSERT_TRUE(browser()->tab_strip_model()->CloseWebContentsAt( + 0, TabCloseTypes::CLOSE_USER_GESTURE)); // `TestGuestViewManager` manages the guests by the order of creation. GetGuestViewManager()->WaitForFirstGuestDeleted(); EXPECT_EQ(1U, GetGuestViewManager()->GetCurrentGuestCount());
diff --git a/chrome/browser/policy/cloud/cloud_policy_invalidator.h b/chrome/browser/policy/cloud/cloud_policy_invalidator.h index 23df0ad..13c1af14 100644 --- a/chrome/browser/policy/cloud/cloud_policy_invalidator.h +++ b/chrome/browser/policy/cloud/cloud_policy_invalidator.h
@@ -201,7 +201,7 @@ raw_ptr<base::Clock> clock_; // The invalidation service. - raw_ptr<invalidation::InvalidationService, DanglingUntriaged> + raw_ptr<invalidation::InvalidationService, DanglingAcrossTasks> invalidation_service_; // Whether the invalidator currently has the ability to receive invalidations.
diff --git a/chrome/browser/privacy_guide/android/BUILD.gn b/chrome/browser/privacy_guide/android/BUILD.gn index 5c0f54c..1e6ee23a 100644 --- a/chrome/browser/privacy_guide/android/BUILD.gn +++ b/chrome/browser/privacy_guide/android/BUILD.gn
@@ -26,6 +26,7 @@ deps = [ ":java_resources", "//base:base_java", + "//chrome/browser/back_press/android:java", "//chrome/browser/privacy_sandbox/android:java", "//chrome/browser/profiles/android:java", "//chrome/browser/safe_browsing/android:java",
diff --git a/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideBottomSheetView.java b/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideBottomSheetView.java index 2b4d1b2..f2adc685 100644 --- a/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideBottomSheetView.java +++ b/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideBottomSheetView.java
@@ -8,14 +8,20 @@ import androidx.annotation.Nullable; +import org.chromium.base.supplier.ObservableSupplierImpl; import org.chromium.components.browser_ui.bottomsheet.BottomSheetContent; /** Bottom sheet view for displaying privacy guide control explanations */ public class PrivacyGuideBottomSheetView implements BottomSheetContent { private final View mContentView; + private final Runnable mCloseBottomSheetCallback; + private ObservableSupplierImpl<Boolean> mBackPressStateChangedSupplier = + new ObservableSupplierImpl<>(); - PrivacyGuideBottomSheetView(View contentView) { + PrivacyGuideBottomSheetView(View contentView, Runnable closeBottomSheetCallback) { mContentView = contentView; + mCloseBottomSheetCallback = closeBottomSheetCallback; + mBackPressStateChangedSupplier.set(true); } @Override @@ -58,6 +64,22 @@ } @Override + public boolean handleBackPress() { + onBackPressed(); + return true; + } + + @Override + public void onBackPressed() { + mCloseBottomSheetCallback.run(); + } + + @Override + public ObservableSupplierImpl<Boolean> getBackPressStateChangedSupplier() { + return mBackPressStateChangedSupplier; + } + + @Override public int getSheetContentDescriptionStringId() { return R.string.privacy_guide_explanation_content_description; }
diff --git a/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/SafeBrowsingFragment.java b/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/SafeBrowsingFragment.java index 30946b7..06de44e 100644 --- a/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/SafeBrowsingFragment.java +++ b/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/SafeBrowsingFragment.java
@@ -27,6 +27,7 @@ private RadioButtonWithDescriptionAndAuxButton mStandardProtection; private RadioButtonWithDescriptionAndAuxButton mEnhancedProtection; private BottomSheetController mBottomSheetController; + private PrivacyGuideBottomSheetView mBottomSheetView; @Override public View onCreateView( @@ -95,10 +96,16 @@ } private void displayBottomSheet(View sheetContent) { - PrivacyGuideBottomSheetView bottomSheet = new PrivacyGuideBottomSheetView(sheetContent); + mBottomSheetView = new PrivacyGuideBottomSheetView(sheetContent, this::closeBottomSheet); // TODO(crbug.com/1287979): Re-enable animation once bug is fixed if (mBottomSheetController != null) { - mBottomSheetController.requestShowContent(bottomSheet, false); + mBottomSheetController.requestShowContent(mBottomSheetView, false); + } + } + + private void closeBottomSheet() { + if (mBottomSheetController != null && mBottomSheetView != null) { + mBottomSheetController.hideContent(mBottomSheetView, true); } }
diff --git a/chrome/browser/privacy_guide/android/javatests/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideFragmentTest.java b/chrome/browser/privacy_guide/android/javatests/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideFragmentTest.java index 32f615ac..34c544e 100644 --- a/chrome/browser/privacy_guide/android/javatests/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideFragmentTest.java +++ b/chrome/browser/privacy_guide/android/javatests/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideFragmentTest.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.privacy_guide; import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.Espresso.pressBack; import static androidx.test.espresso.action.ViewActions.click; import static androidx.test.espresso.action.ViewActions.scrollTo; import static androidx.test.espresso.assertion.ViewAssertions.matches; @@ -928,6 +929,38 @@ @Test @LargeTest @Feature({"PrivacyGuide"}) + @Features.EnableFeatures(ChromeFeatureList.PRIVACY_GUIDE_POST_MVP) + public void testSafeBrowsingCard_enhancedBottomSheetBackButtonBehaviour() { + launchPrivacyGuide(); + goToSafeBrowsingCard(); + + clickOnArrowNextToRadioButtonWithText(R.string.privacy_guide_safe_browsing_enhanced_title); + onViewWaiting(withId(R.id.sb_enhanced_sheet)).check(matches(isDisplayed())); + + pressBack(); + onViewWaiting(withText(R.string.privacy_guide_safe_browsing_enhanced_title)) + .check(matches(isDisplayed())); + } + + @Test + @LargeTest + @Feature({"PrivacyGuide"}) + @Features.EnableFeatures(ChromeFeatureList.PRIVACY_GUIDE_POST_MVP) + public void testSafeBrowsingCard_standardBottomSheetBackButtonBehaviour() { + launchPrivacyGuide(); + goToSafeBrowsingCard(); + + clickOnArrowNextToRadioButtonWithText(R.string.privacy_guide_safe_browsing_standard_title); + onViewWaiting(withId(R.id.sb_standard_sheet)).check(matches(isDisplayed())); + + pressBack(); + onViewWaiting(withText(R.string.privacy_guide_safe_browsing_standard_title)) + .check(matches(isDisplayed())); + } + + @Test + @LargeTest + @Feature({"PrivacyGuide"}) public void testCookiesCard_nextClickCookiesUserAction() { launchPrivacyGuide(); goToCompletionCard();
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc index 4cb1025..44eb09b 100644 --- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc +++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -82,6 +82,7 @@ #include "chrome/browser/media/media_engagement_service_factory.h" #include "chrome/browser/media/router/chrome_media_router_factory.h" #include "chrome/browser/media/router/presentation/chrome_local_presentation_manager_factory.h" +#include "chrome/browser/media/webrtc/media_device_salt_service_factory.h" #include "chrome/browser/media/webrtc/webrtc_event_log_manager_keyed_service_factory.h" #include "chrome/browser/media_galleries/media_galleries_preferences_factory.h" #include "chrome/browser/metrics/variations/google_groups_updater_service_factory.h" @@ -195,7 +196,6 @@ #include "components/commerce/core/proto/commerce_subscription_db_content.pb.h" #include "components/commerce/core/proto/persisted_state_db_content.pb.h" #include "components/enterprise/content/clipboard_restriction_service.h" -#include "components/media_device_salt/media_device_salt_service_factory.h" #include "components/offline_pages/buildflags/buildflags.h" #include "components/omnibox/browser/autocomplete_controller_emitter.h" #include "components/optimization_guide/core/optimization_guide_switches.h" @@ -742,7 +742,7 @@ #if !BUILDFLAG(IS_ANDROID) ManagedConfigurationAPIFactory::GetInstance(); #endif - media_device_salt::MediaDeviceSaltServiceFactory::GetInstance(); + MediaDeviceSaltServiceFactory::GetInstance(); #if BUILDFLAG(IS_ANDROID) MediaDrmOriginIdManagerFactory::GetInstance(); #endif
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc index b6a35bd..5320b19 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc
@@ -386,8 +386,6 @@ // Whether a profile is using a default avatar name (eg. Pickles or Person 1). registry->RegisterBooleanPref(prefs::kProfileUsingDefaultName, true); registry->RegisterStringPref(prefs::kProfileName, std::string()); - - registry->RegisterStringPref(prefs::kSupervisedUserId, std::string()); #if BUILDFLAG(IS_ANDROID) uint32_t home_page_flags = PrefRegistry::NO_REGISTRATION_FLAGS; #else
diff --git a/chrome/browser/profiles/profile_key.h b/chrome/browser/profiles/profile_key.h index b32d9eb..c0005a2 100644 --- a/chrome/browser/profiles/profile_key.h +++ b/chrome/browser/profiles/profile_key.h
@@ -49,7 +49,7 @@ private: raw_ptr<PrefService> prefs_ = nullptr; - raw_ptr<leveldb_proto::ProtoDatabaseProvider, DanglingUntriaged> + raw_ptr<leveldb_proto::ProtoDatabaseProvider, DanglingAcrossTasks> db_provider_ = nullptr; // Points to the original (non off-the-record) ProfileKey.
diff --git a/chrome/browser/resources/chromeos/login/screens/common/gaia_signin.js b/chrome/browser/resources/chromeos/login/screens/common/gaia_signin.js index 8e860599..9931f83 100644 --- a/chrome/browser/resources/chromeos/login/screens/common/gaia_signin.js +++ b/chrome/browser/resources/chromeos/login/screens/common/gaia_signin.js
@@ -856,7 +856,7 @@ * @private */ onIdentifierEnteredMessage_(e) { - chrome.send('identifierEntered', [e.detail.accountIdentifier]); + this.userActed(['identifierEntered', e.detail.accountIdentifier]); } /**
diff --git a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc index 0b3bb74..828437a 100644 --- a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc +++ b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
@@ -606,12 +606,12 @@ private: std::unique_ptr<TestSafeBrowsingServiceFactory> sb_factory_; // Owned by the V4Database. - raw_ptr<TestV4DatabaseFactory, DanglingUntriaged> v4_db_factory_; + raw_ptr<TestV4DatabaseFactory, DanglingAcrossTasks> v4_db_factory_; // Owned by the V4GetHashProtocolManager. - raw_ptr<TestV4GetHashProtocolManagerFactory, DanglingUntriaged> + raw_ptr<TestV4GetHashProtocolManagerFactory, DanglingAcrossTasks> v4_get_hash_factory_; // Owned by the V4Database. - raw_ptr<TestV4StoreFactory, DanglingUntriaged> store_factory_; + raw_ptr<TestV4StoreFactory, DanglingAcrossTasks> store_factory_; #if defined(ADDRESS_SANITIZER) // TODO(lukasza): https://crbug.com/971820: Disallow renderer crashes once the @@ -1303,7 +1303,8 @@ // Depending on the threat_type classification, if an embedded resource is // marked as Malware, an interstitial may be shown. -IN_PROC_BROWSER_TEST_P(V4SafeBrowsingServiceMetadataTest, MalwareImg) { +// TODO(crbug.com/1320123): Re-enable this test +IN_PROC_BROWSER_TEST_P(V4SafeBrowsingServiceMetadataTest, DISABLED_MalwareImg) { GURL main_url = embedded_test_server()->GetURL(kMalwarePage); GURL img_url = embedded_test_server()->GetURL(kMalwareImg);
diff --git a/chrome/browser/safe_browsing/test_safe_browsing_database_helper.h b/chrome/browser/safe_browsing/test_safe_browsing_database_helper.h index 57119403..5eaa575 100644 --- a/chrome/browser/safe_browsing/test_safe_browsing_database_helper.h +++ b/chrome/browser/safe_browsing/test_safe_browsing_database_helper.h
@@ -65,11 +65,13 @@ private: std::unique_ptr<safe_browsing::TestSafeBrowsingServiceFactory> sb_factory_; // Owned by the V4Database. - raw_ptr<InsertingDatabaseFactory, DanglingUntriaged> v4_db_factory_ = nullptr; + raw_ptr<InsertingDatabaseFactory, DanglingAcrossTasks> v4_db_factory_ = + nullptr; // Owned by the V4GetHashProtocolManager. Will stay nullptr if the v4 hash // factory is not being mocked. - raw_ptr<safe_browsing::TestV4GetHashProtocolManagerFactory, DanglingUntriaged> + raw_ptr<safe_browsing::TestV4GetHashProtocolManagerFactory, + DanglingAcrossTasks> v4_get_hash_factory_ = nullptr; };
diff --git a/chrome/browser/safe_browsing/v4_embedded_test_server_browsertest.cc b/chrome/browser/safe_browsing/v4_embedded_test_server_browsertest.cc index 3bf67536..a263259 100644 --- a/chrome/browser/safe_browsing/v4_embedded_test_server_browsertest.cc +++ b/chrome/browser/safe_browsing/v4_embedded_test_server_browsertest.cc
@@ -120,7 +120,7 @@ std::unique_ptr<net::MappedHostResolver> mapped_host_resolver_; // Owned by the V4Database. - raw_ptr<TestV4DatabaseFactory, DanglingUntriaged> v4_db_factory_ = nullptr; + raw_ptr<TestV4DatabaseFactory, DanglingAcrossTasks> v4_db_factory_ = nullptr; }; IN_PROC_BROWSER_TEST_F(V4EmbeddedTestServerBrowserTest, SimpleTest) {
diff --git a/chrome/browser/sharing/sharing_fcm_handler.h b/chrome/browser/sharing/sharing_fcm_handler.h index c5c897a..97928072 100644 --- a/chrome/browser/sharing/sharing_fcm_handler.h +++ b/chrome/browser/sharing/sharing_fcm_handler.h
@@ -101,7 +101,7 @@ absl::optional<std::string> message_id, SharingChannelType channel_type); - const raw_ptr<gcm::GCMDriver, DanglingUntriaged> gcm_driver_; + const raw_ptr<gcm::GCMDriver, DanglingAcrossTasks> gcm_driver_; raw_ptr<syncer::DeviceInfoTracker, DanglingUntriaged> device_info_tracker_; raw_ptr<SharingFCMSender, DanglingUntriaged> sharing_fcm_sender_; raw_ptr<SharingHandlerRegistry, DanglingUntriaged> handler_registry_;
diff --git a/chrome/browser/sharing/sharing_fcm_sender.h b/chrome/browser/sharing/sharing_fcm_sender.h index 5f6d925..678acc6 100644 --- a/chrome/browser/sharing/sharing_fcm_sender.h +++ b/chrome/browser/sharing/sharing_fcm_sender.h
@@ -142,7 +142,7 @@ raw_ptr<SharingMessageBridge, DanglingUntriaged> sharing_message_bridge_; raw_ptr<SharingSyncPreference, DanglingUntriaged> sync_preference_; raw_ptr<VapidKeyManager, DanglingUntriaged> vapid_key_manager_; - raw_ptr<gcm::GCMDriver, DanglingUntriaged> gcm_driver_; + raw_ptr<gcm::GCMDriver, DanglingAcrossTasks> gcm_driver_; raw_ptr<syncer::LocalDeviceInfoProvider, DanglingUntriaged> local_device_info_provider_; raw_ptr<syncer::SyncService, DanglingUntriaged> sync_service_;
diff --git a/chrome/browser/site_isolation/chrome_site_per_process_browsertest.cc b/chrome/browser/site_isolation/chrome_site_per_process_browsertest.cc index aaa3f2f8..42d6328 100644 --- a/chrome/browser/site_isolation/chrome_site_per_process_browsertest.cc +++ b/chrome/browser/site_isolation/chrome_site_per_process_browsertest.cc
@@ -1160,9 +1160,8 @@ // Close the second tab. This should return false to indicate that we're // waiting for the beforeunload dialog. - int previous_tab_count = tab_strip_model->count(); - tab_strip_model->CloseWebContentsAt(tab_strip_model->active_index(), 0); - EXPECT_EQ(previous_tab_count, tab_strip_model->count()); + EXPECT_FALSE( + tab_strip_model->CloseWebContentsAt(tab_strip_model->active_index(), 0)); // Cancel the dialog and make sure the tab stays alive. auto* dialog = ui_test_utils::WaitForAppModalDialog(); @@ -1172,8 +1171,8 @@ EXPECT_EQ(2, browser()->tab_strip_model()->count()); // Try closing the tab again. - tab_strip_model->CloseWebContentsAt(tab_strip_model->active_index(), 0); - EXPECT_EQ(previous_tab_count, tab_strip_model->count()); + EXPECT_FALSE( + tab_strip_model->CloseWebContentsAt(tab_strip_model->active_index(), 0)); // Accept the dialog and wait for tab close to complete. content::WebContentsDestroyedWatcher destroyed_watcher(second_web_contents); @@ -1210,10 +1209,10 @@ EXPECT_TRUE(ExecJs(child, "window.onbeforeunload = () => { return 'x' };")); content::PrepContentsForBeforeUnloadTest(second_web_contents); - // Close the second tab. This should return false to indicate that we're + // Close the second tab. This should return false to indicate that we're // waiting for the beforeunload dialog. - tab_strip_model->CloseWebContentsAt(tab_strip_model->active_index(), 0); - EXPECT_EQ(2, tab_strip_model->count()); + EXPECT_FALSE( + tab_strip_model->CloseWebContentsAt(tab_strip_model->active_index(), 0)); // Cancel the dialog and make sure the tab stays alive. auto* dialog = ui_test_utils::WaitForAppModalDialog(); @@ -1223,8 +1222,8 @@ EXPECT_EQ(2, browser()->tab_strip_model()->count()); // Try closing the tab again. - tab_strip_model->CloseWebContentsAt(tab_strip_model->active_index(), 0); - EXPECT_EQ(2, tab_strip_model->count()); + EXPECT_FALSE( + tab_strip_model->CloseWebContentsAt(tab_strip_model->active_index(), 0)); // Accept the dialog and wait for tab close to complete. content::WebContentsDestroyedWatcher destroyed_watcher(second_web_contents); @@ -1276,8 +1275,8 @@ // Close the second tab. This should return false to indicate that we're // waiting for the beforeunload dialog. - tab_strip_model->CloseWebContentsAt(tab_strip_model->active_index(), 0); - EXPECT_EQ(2, tab_strip_model->count()); + EXPECT_FALSE( + tab_strip_model->CloseWebContentsAt(tab_strip_model->active_index(), 0)); // From the first tab, execute window.close() on the popup and wait for the // second WebContents to be destroyed. @@ -1332,8 +1331,8 @@ // Close the second tab. This should return false to indicate that we're // waiting for the beforeunload dialog. - tab_strip_model->CloseWebContentsAt(tab_strip_model->active_index(), 0); - EXPECT_EQ(2, tab_strip_model->count()); + EXPECT_FALSE( + tab_strip_model->CloseWebContentsAt(tab_strip_model->active_index(), 0)); // From the first tab, execute window.close() on the popup and wait for the // second WebContents to be destroyed.
diff --git a/chrome/browser/subresource_filter/subresource_filter_history_observer.h b/chrome/browser/subresource_filter/subresource_filter_history_observer.h index 6a3e3d5c..74e24f4 100644 --- a/chrome/browser/subresource_filter/subresource_filter_history_observer.h +++ b/chrome/browser/subresource_filter/subresource_filter_history_observer.h
@@ -47,7 +47,7 @@ // Outlives this object. raw_ptr<subresource_filter::SubresourceFilterContentSettingsManager, - DanglingUntriaged> + DanglingAcrossTasks> settings_manager_; };
diff --git a/chrome/browser/supervised_user/supervised_user_service_factory.cc b/chrome/browser/supervised_user/supervised_user_service_factory.cc index 7414706..496a406 100644 --- a/chrome/browser/supervised_user/supervised_user_service_factory.cc +++ b/chrome/browser/supervised_user/supervised_user_service_factory.cc
@@ -9,6 +9,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_key.h" +#include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/supervised_user/kids_chrome_management/kids_chrome_management_client_factory.h" #include "chrome/browser/supervised_user/supervised_user_browser_utils.h" #include "chrome/browser/supervised_user/supervised_user_settings_service_factory.h" @@ -72,6 +73,7 @@ // static KeyedService* SupervisedUserServiceFactory::BuildInstanceFor(Profile* profile) { return new supervised_user::SupervisedUserService( + IdentityManagerFactory::GetForProfile(profile), KidsChromeManagementClientFactory::GetInstance()->GetForProfile(profile), *profile->GetPrefs(), *SupervisedUserSettingsServiceFactory::GetInstance()->GetForKey( @@ -98,6 +100,7 @@ DependsOn( extensions::ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); #endif + DependsOn(IdentityManagerFactory::GetInstance()); DependsOn(KidsChromeManagementClientFactory::GetInstance()); DependsOn(SyncServiceFactory::GetInstance()); DependsOn(SupervisedUserSettingsServiceFactory::GetInstance());
diff --git a/chrome/browser/sync/sessions/sync_sessions_router_tab_helper.h b/chrome/browser/sync/sessions/sync_sessions_router_tab_helper.h index c2639ad3..f17827c 100644 --- a/chrome/browser/sync/sessions/sync_sessions_router_tab_helper.h +++ b/chrome/browser/sync/sessions/sync_sessions_router_tab_helper.h
@@ -78,9 +78,9 @@ // |router_| is a KeyedService and is guaranteed to outlive |this|. raw_ptr<SyncSessionsWebContentsRouter, DanglingUntriaged> router_; - raw_ptr<ChromeTranslateClient, DanglingUntriaged> chrome_translate_client_; + raw_ptr<ChromeTranslateClient, DanglingAcrossTasks> chrome_translate_client_; - raw_ptr<favicon::FaviconDriver, DanglingUntriaged> favicon_driver_; + raw_ptr<favicon::FaviconDriver, DanglingAcrossTasks> favicon_driver_; WEB_CONTENTS_USER_DATA_KEY_DECL(); };
diff --git a/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc b/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc index e6905da6..20a469bb 100644 --- a/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc
@@ -201,22 +201,18 @@ base::test::ScopedFeatureList features_override_; }; -class SingleClientBookmarksSyncTestWithEnabledThrottling : public SyncTest { +class SingleClientBookmarksThrottlingSyncTest : public SyncTest { public: - SingleClientBookmarksSyncTestWithEnabledThrottling() - : SyncTest(SINGLE_CLIENT) { - features_override_.InitAndEnableFeature( - syncer::kSyncExtensionTypesThrottling); - } + SingleClientBookmarksThrottlingSyncTest() : SyncTest(SINGLE_CLIENT) {} void SetUpInProcessBrowserTestFixture() override { SyncTest::SetUpInProcessBrowserTestFixture(); create_services_subscription_ = BrowserContextDependencyManager::GetInstance() - ->RegisterCreateServicesCallbackForTesting(base::BindRepeating( - &SingleClientBookmarksSyncTestWithEnabledThrottling:: - OnWillCreateBrowserContextServices, - base::Unretained(this))); + ->RegisterCreateServicesCallbackForTesting( + base::BindRepeating(&SingleClientBookmarksThrottlingSyncTest:: + OnWillCreateBrowserContextServices, + base::Unretained(this))); } void OnWillCreateBrowserContextServices(content::BrowserContext* context) { @@ -246,7 +242,6 @@ private: base::CallbackListSubscription create_services_subscription_; - base::test::ScopedFeatureList features_override_; }; class SingleClientBookmarksSyncTestWithEnforcedBookmarksCountLimit @@ -1857,8 +1852,7 @@ .value()); } -IN_PROC_BROWSER_TEST_F(SingleClientBookmarksSyncTestWithEnabledThrottling, - DepleteQuota) { +IN_PROC_BROWSER_TEST_F(SingleClientBookmarksThrottlingSyncTest, DepleteQuota) { ASSERT_TRUE(SetupClients()); // Setup custom quota params: to effectively never refill. @@ -1891,7 +1885,7 @@ // Recovering from depleted quota is tested by another test. } -IN_PROC_BROWSER_TEST_F(SingleClientBookmarksSyncTestWithEnabledThrottling, +IN_PROC_BROWSER_TEST_F(SingleClientBookmarksThrottlingSyncTest, DepletedQuotaDoesNotStopCommitCycle) { ASSERT_TRUE(SetupClients()); @@ -1926,7 +1920,7 @@ ModelTypeHistogramValue(syncer::BOOKMARKS))); } -IN_PROC_BROWSER_TEST_F(SingleClientBookmarksSyncTestWithEnabledThrottling, +IN_PROC_BROWSER_TEST_F(SingleClientBookmarksThrottlingSyncTest, DoNotDepleteQuota) { ASSERT_TRUE(SetupClients()); @@ -1970,7 +1964,7 @@ } // TODO(crbug.com/1447535): Disabled due to flakiness. -IN_PROC_BROWSER_TEST_F(SingleClientBookmarksSyncTestWithEnabledThrottling, +IN_PROC_BROWSER_TEST_F(SingleClientBookmarksThrottlingSyncTest, DISABLED_DepleteQuotaAndRecover) { ASSERT_TRUE(SetupClients());
diff --git a/chrome/browser/sync/test/integration/single_client_passwords_sync_test.cc b/chrome/browser/sync/test/integration/single_client_passwords_sync_test.cc index 9595f20..fb79a6f2 100644 --- a/chrome/browser/sync/test/integration/single_client_passwords_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_passwords_sync_test.cc
@@ -95,49 +95,14 @@ } }; -class SingleClientPasswordsSyncTestWithBaseSpecificsInMetadata - : public SyncTest { +class SingleClientPasswordsSyncTestWithNotes : public SyncTest { public: - SingleClientPasswordsSyncTestWithBaseSpecificsInMetadata() - : SyncTest(SINGLE_CLIENT) { + SingleClientPasswordsSyncTestWithNotes() : SyncTest(SINGLE_CLIENT) { feature_list_.InitWithFeatures( - /*enabled_features=*/{syncer::kCacheBaseEntitySpecificsInMetadata}, + /*enabled_features=*/{syncer::kPasswordNotesWithBackup}, /*disabled_features=*/{}); } - ~SingleClientPasswordsSyncTestWithBaseSpecificsInMetadata() override = - default; - - private: - base::test::ScopedFeatureList feature_list_; -}; - -class SingleClientPasswordsSyncTestWithBaseSpecificsInMetadataAndNotes - : public SyncTest { - public: - SingleClientPasswordsSyncTestWithBaseSpecificsInMetadataAndNotes() - : SyncTest(SINGLE_CLIENT) { - feature_list_.InitWithFeatures( - /*enabled_features=*/{syncer::kCacheBaseEntitySpecificsInMetadata, - syncer::kPasswordNotesWithBackup}, - /*disabled_features=*/{}); - } - ~SingleClientPasswordsSyncTestWithBaseSpecificsInMetadataAndNotes() override = - default; - - private: - base::test::ScopedFeatureList feature_list_; -}; - -class SingleClientPasswordsSyncTestWithCachingSpecificsEnabledAfterRestart - : public SyncTest { - public: - SingleClientPasswordsSyncTestWithCachingSpecificsEnabledAfterRestart() - : SyncTest(SINGLE_CLIENT) { - feature_list_.InitWithFeatureState( - syncer::kCacheBaseEntitySpecificsInMetadata, GetTestPreCount() == 0); - } - ~SingleClientPasswordsSyncTestWithCachingSpecificsEnabledAfterRestart() - override = default; + ~SingleClientPasswordsSyncTestWithNotes() override = default; private: base::test::ScopedFeatureList feature_list_; @@ -620,7 +585,7 @@ } #endif // !BUILDFLAG(IS_CHROMEOS_ASH) -IN_PROC_BROWSER_TEST_F(SingleClientPasswordsSyncTestWithBaseSpecificsInMetadata, +IN_PROC_BROWSER_TEST_F(SingleClientPasswordsSyncTest, PreservesUnsupportedFieldsDataOnCommits) { // Create an unsupported field with an unused tag. const std::string kUnsupportedField = @@ -671,9 +636,8 @@ cryptographer.get(), "new_password", kUnsupportedField))); } -IN_PROC_BROWSER_TEST_F( - SingleClientPasswordsSyncTestWithBaseSpecificsInMetadataAndNotes, - PreservesUnsupportedNotesFieldsDataOnCommits) { +IN_PROC_BROWSER_TEST_F(SingleClientPasswordsSyncTestWithNotes, + PreservesUnsupportedNotesFieldsDataOnCommits) { // Create an unsupported field in the PasswordSpecificsData_Notes with an // unused tag. const std::string kUnsupportedNotesField = @@ -751,52 +715,6 @@ } } -IN_PROC_BROWSER_TEST_F( - SingleClientPasswordsSyncTestWithCachingSpecificsEnabledAfterRestart, - PRE_PasswordBridgeIgnoresEntriesWithoutCachedBaseSpecificOnRestart) { - // Disabled by the test fixture. - ASSERT_FALSE(base::FeatureList::IsEnabled( - syncer::kCacheBaseEntitySpecificsInMetadata)); - - // Add password entity with caching entity specifics disabled in the PRE test. - ASSERT_TRUE(SetupClients()) << "SetupClients() failed."; - PasswordForm form = CreateTestPasswordForm(0); - GetProfilePasswordStoreInterface(0)->AddLogin(form); - ASSERT_EQ(1, GetPasswordCount(0)); - - // Setup sync, wait for its completion, and make sure changes were synced. - ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; - ASSERT_TRUE(UpdatedProgressMarkerChecker(GetSyncService(0)).Wait()); -} - -// Regression test for crrev.com/c/3755526. Checks that password bridge ignores -// entries without a password field in entity specifics cache (added by the PRE -// test with `syncer::kCacheBaseEntitySpecificsInMetadata` disabled). -IN_PROC_BROWSER_TEST_F( - SingleClientPasswordsSyncTestWithCachingSpecificsEnabledAfterRestart, - PasswordBridgeIgnoresEntriesWithoutCachedBaseSpecificOnRestart) { - // Enabled by the test fixture. - ASSERT_TRUE(base::FeatureList::IsEnabled( - syncer::kCacheBaseEntitySpecificsInMetadata)); - - base::HistogramTester histogram_tester; - ASSERT_TRUE(SetupClients()) << "SetupClients() failed."; - ASSERT_EQ(1, GetPasswordCount(0)); - - // Wait for data types to be ready for sync (and hence model types are - // loaded). - ASSERT_TRUE(GetClient(0)->AwaitSyncSetupCompletion()); - - // The original metric is defined in password_sync_bridge.cc. - const int kNone = 0; - // Since the local base entity specifics cache doesn't contain supported - // fields, running into the initial sync flow is not expected. Since the - // bridge is initialized for both account and profile store, the metric is - // expected to be recorded twice. - histogram_tester.ExpectUniqueSample("PasswordManager.SyncMetadataReadError2", - kNone, /*expected_bucket_count=*/2); -} - // The follow 3 tests are testing the interaction between clients that support // and don't support notes. The test fixture enables the features for even // number of PREs.
diff --git a/chrome/browser/sync/test/integration/single_client_user_events_sync_test.cc b/chrome/browser/sync/test/integration/single_client_user_events_sync_test.cc index e43cb7c5..20ce4f1 100644 --- a/chrome/browser/sync/test/integration/single_client_user_events_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_user_events_sync_test.cc
@@ -50,18 +50,6 @@ } }; -class SingleClientUserEventsSyncTestWithEnabledThrottling - : public SingleClientUserEventsSyncTest { - public: - SingleClientUserEventsSyncTestWithEnabledThrottling() { - features_override_.InitAndEnableFeature( - syncer::kSyncExtensionTypesThrottling); - } - - private: - base::test::ScopedFeatureList features_override_; -}; - IN_PROC_BROWSER_TEST_F(SingleClientUserEventsSyncTest, Sanity) { ASSERT_TRUE(SetupSync()); EXPECT_EQ( @@ -248,8 +236,7 @@ // This is an analogy to SingleClientBookmarksSyncTest.DepleteQuota, tested on // a datatype that has no quota restrictions. -IN_PROC_BROWSER_TEST_F(SingleClientUserEventsSyncTestWithEnabledThrottling, - NoQuotaApplied) { +IN_PROC_BROWSER_TEST_F(SingleClientUserEventsSyncTest, NoQuotaApplied) { ASSERT_TRUE(SetupSync()); // Add enough user events that would deplete quota in the initial cycle. syncer::UserEventService* event_service =
diff --git a/chrome/browser/sync_file_system/local/sync_file_system_backend.h b/chrome/browser/sync_file_system/local/sync_file_system_backend.h index 2748e3922..c58cd484b 100644 --- a/chrome/browser/sync_file_system/local/sync_file_system_backend.h +++ b/chrome/browser/sync_file_system/local/sync_file_system_backend.h
@@ -95,7 +95,7 @@ // |profile_| will initially be valid but may be destroyed before |this|, so // it should be checked before being accessed. - raw_ptr<Profile, DanglingUntriaged> profile_; + raw_ptr<Profile, DanglingAcrossTasks> profile_; // A flag to skip the initialization sequence of SyncFileSystemService for // testing.
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd index 33a8c36af..e539ed47 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -4083,13 +4083,13 @@ Manage account </message> <message name="IDS_ACCESSIBILITY_TOOLBAR_BTN_IDENTITY_DISC_WITH_NAME_AND_EMAIL" desc="The content description for a toolbar button displaying user profile picture. Tapping on this button navigates to 'Sync and Google services' page in settings"> - Signed in as <ph name="USER_NAME">%1$s<ex>Peter Parker</ex></ph>. <ph name="USER_EMAIL">%2$s<ex>peter.parker@gmail.com</ex></ph>. Button. Opens settings. + Signed in as <ph name="USER_NAME">%1$s<ex>Peter Parker</ex></ph>. <ph name="USER_EMAIL">%2$s<ex>peter.parker@gmail.com</ex></ph>. Opens settings. </message> <message name="IDS_ACCESSIBILITY_TOOLBAR_BTN_IDENTITY_DISC_WITH_NAME" desc="The content description for a toolbar button displaying user profile picture, for users who don't have a readable email address. Tapping on this button navigates to 'Sync and Google services' page in settings"> - Signed in as <ph name="USER_NAME">%s<ex>Bruce Wayne</ex></ph>. Button. Opens settings. + Signed in as <ph name="USER_NAME">%s<ex>Bruce Wayne</ex></ph>. Opens settings. </message> <message name="IDS_ACCESSIBILITY_TOOLBAR_BTN_SIGNED_OUT_IDENTITY_DISC" desc="The content description for a toolbar button displaying the signed-out avatar. Tapping on this button navigates to 'Turn on Sync' page in settings"> - Signed out. Button. Opens dialog to sign in and turn on sync. + Signed out. Opens dialog to sign in and turn on sync. </message> <message name="IDS_ACCESSIBILITY_TOOLBAR_BTN_HOME" desc="Content description for the home button."> Home
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ACCESSIBILITY_TOOLBAR_BTN_IDENTITY_DISC_WITH_NAME.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ACCESSIBILITY_TOOLBAR_BTN_IDENTITY_DISC_WITH_NAME.png.sha1 index 46b560c..27152453 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ACCESSIBILITY_TOOLBAR_BTN_IDENTITY_DISC_WITH_NAME.png.sha1 +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ACCESSIBILITY_TOOLBAR_BTN_IDENTITY_DISC_WITH_NAME.png.sha1
@@ -1 +1 @@ -07dfa23554442801c1ace4b0f9705311f50a4190 \ No newline at end of file +b356d0087512a0a7f90f14fa566b5c80e24702e1 \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ACCESSIBILITY_TOOLBAR_BTN_IDENTITY_DISC_WITH_NAME_AND_EMAIL.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ACCESSIBILITY_TOOLBAR_BTN_IDENTITY_DISC_WITH_NAME_AND_EMAIL.png.sha1 index 46b560c..54352cb5 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ACCESSIBILITY_TOOLBAR_BTN_IDENTITY_DISC_WITH_NAME_AND_EMAIL.png.sha1 +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ACCESSIBILITY_TOOLBAR_BTN_IDENTITY_DISC_WITH_NAME_AND_EMAIL.png.sha1
@@ -1 +1 @@ -07dfa23554442801c1ace4b0f9705311f50a4190 \ No newline at end of file +29a58bf7c796a2e97dc401fb7e004fff848cbf35 \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ACCESSIBILITY_TOOLBAR_BTN_SIGNED_OUT_IDENTITY_DISC.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ACCESSIBILITY_TOOLBAR_BTN_SIGNED_OUT_IDENTITY_DISC.png.sha1 index b90976f1..54352cb5 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ACCESSIBILITY_TOOLBAR_BTN_SIGNED_OUT_IDENTITY_DISC.png.sha1 +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ACCESSIBILITY_TOOLBAR_BTN_SIGNED_OUT_IDENTITY_DISC.png.sha1
@@ -1 +1 @@ -08869ca759e078de6a5c680d231722da7e5beb98 \ No newline at end of file +29a58bf7c796a2e97dc401fb7e004fff848cbf35 \ No newline at end of file
diff --git a/chrome/browser/ui/ash/shelf/app_shortcut_shelf_item_controller_browsertest.cc b/chrome/browser/ui/ash/shelf/app_shortcut_shelf_item_controller_browsertest.cc index 90cf7cf..b109f311 100644 --- a/chrome/browser/ui/ash/shelf/app_shortcut_shelf_item_controller_browsertest.cc +++ b/chrome/browser/ui/ash/shelf/app_shortcut_shelf_item_controller_browsertest.cc
@@ -133,12 +133,12 @@ /*command_id=*/0, ui::EF_NONE, display::kInvalidDisplayId); - // Shift-clicking on an item should not close it as it is a pinned home tab. + // Shift-clicking on an item should close it. EXPECT_EQ(2u, GetAppMenuItems(0).size()); GetShelfItemDelegate()->ExecuteCommand(/*from_context_menu=*/false, /*command_id=*/0, ui::EF_SHIFT_DOWN, display::kInvalidDisplayId); - EXPECT_EQ(2u, GetAppMenuItems(0).size()); + EXPECT_EQ(1u, GetAppMenuItems(0).size()); } // Test interacting with the app menu with shift key down: the app menu has @@ -179,16 +179,10 @@ /*command_id=*/0, ui::EF_NONE, display::kInvalidDisplayId); - // Shift-clicking on an item should not close it if it is a pinned home tab. + // Shift-clicking on a item should close it. EXPECT_EQ(3u, GetAppMenuItems(ui::EF_SHIFT_DOWN).size()); GetShelfItemDelegate()->ExecuteCommand(/*from_context_menu=*/false, /*command_id=*/0, ui::EF_SHIFT_DOWN, display::kInvalidDisplayId); - EXPECT_EQ(3u, GetAppMenuItems(ui::EF_SHIFT_DOWN).size()); - - // Shift-clicking on an item that is not a pinned home tab should close it. - GetShelfItemDelegate()->ExecuteCommand(/*from_context_menu=*/false, - /*command_id=*/1, ui::EF_SHIFT_DOWN, - display::kInvalidDisplayId); EXPECT_EQ(2u, GetAppMenuItems(ui::EF_SHIFT_DOWN).size()); }
diff --git a/chrome/browser/ui/autofill/autofill_context_menu_manager.cc b/chrome/browser/ui/autofill/autofill_context_menu_manager.cc index 2d9c1a70..01016587 100644 --- a/chrome/browser/ui/autofill/autofill_context_menu_manager.cc +++ b/chrome/browser/ui/autofill/autofill_context_menu_manager.cc
@@ -256,7 +256,7 @@ chrome::ShowFeedbackPage( browser_, chrome::kFeedbackSourceAutofillContextMenu, /*description_template=*/std::string(), - /*description_placeholder_text=*/std::string(kFeedbackPlaceholder), + /*description_placeholder_text=*/kFeedbackPlaceholder, /*category_tag=*/"dogfood_autofill_feedback", /*extra_diagnostics=*/std::string(), /*autofill_metadata=*/
diff --git a/chrome/browser/ui/autofill/save_update_address_profile_bubble_controller_impl_unittest.cc b/chrome/browser/ui/autofill/save_update_address_profile_bubble_controller_impl_unittest.cc index 17f7f38..8e97a9d6 100644 --- a/chrome/browser/ui/autofill/save_update_address_profile_bubble_controller_impl_unittest.cc +++ b/chrome/browser/ui/autofill/save_update_address_profile_bubble_controller_impl_unittest.cc
@@ -113,11 +113,10 @@ Run(AutofillClient::SaveAddressProfileOfferUserDecision::kIgnored, testing::_)); // Close controller tab. - int previous_tab_count = browser()->tab_strip_model()->count(); - browser()->tab_strip_model()->CloseWebContentsAt( + EXPECT_TRUE(browser()->tab_strip_model()->CloseWebContentsAt( tab_strip_model->GetIndexOfWebContents(controller_web_contents), - TabCloseTypes::CLOSE_USER_GESTURE); - EXPECT_EQ(previous_tab_count - 1, browser()->tab_strip_model()->count()); + TabCloseTypes::CLOSE_USER_GESTURE)); + EXPECT_EQ(1, tab_strip_model->count()); } // This is testing that when the SaveAddressProfilePromptOptions has the
diff --git a/chrome/browser/ui/bookmarks/bookmark_browsertest.cc b/chrome/browser/ui/bookmarks/bookmark_browsertest.cc index 52fb323..d798540 100644 --- a/chrome/browser/ui/bookmarks/bookmark_browsertest.cc +++ b/chrome/browser/ui/bookmarks/bookmark_browsertest.cc
@@ -303,9 +303,9 @@ auto close_all_tabs_except_first = [](Browser* browser) { int num_tabs = browser->tab_strip_model()->GetTabCount(); for (int i = 0; i < num_tabs - 1; ++i) { - browser->tab_strip_model()->CloseWebContentsAt(num_tabs - 1 - i, 0); + ASSERT_TRUE( + browser->tab_strip_model()->CloseWebContentsAt(num_tabs - 1 - i, 0)); } - EXPECT_EQ(1, browser->tab_strip_model()->count()); }; auto open_urls_and_test = [®ular_browser, &incognito_browser, &bbar,
diff --git a/chrome/browser/ui/bookmarks/bookmark_tab_helper.h b/chrome/browser/ui/bookmarks/bookmark_tab_helper.h index 91868a2..359b9c43 100644 --- a/chrome/browser/ui/bookmarks/bookmark_tab_helper.h +++ b/chrome/browser/ui/bookmarks/bookmark_tab_helper.h
@@ -104,7 +104,7 @@ // The BookmarkDrag is used to forward bookmark drag and drop events to // extensions. - raw_ptr<BookmarkDrag, DanglingUntriaged> bookmark_drag_; + raw_ptr<BookmarkDrag, DanglingAcrossTasks> bookmark_drag_; WEB_CONTENTS_USER_DATA_KEY_DECL(); };
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h index 2cbbda0..55d2b67 100644 --- a/chrome/browser/ui/browser.h +++ b/chrome/browser/ui/browser.h
@@ -247,7 +247,7 @@ Type type; // The associated profile. - raw_ptr<Profile, DanglingUntriaged> profile; + raw_ptr<Profile, DanglingAcrossTasks> profile; // Specifies the browser `is_trusted_source_` value. bool trusted_source = false; @@ -1189,7 +1189,7 @@ const Type type_; // This Browser's profile. - const raw_ptr<Profile, DanglingUntriaged> profile_; + const raw_ptr<Profile, DanglingAcrossTasks> profile_; // Prevent Profile deletion until this browser window is closed. std::unique_ptr<ScopedProfileKeepAlive> profile_keep_alive_;
diff --git a/chrome/browser/ui/browser_navigator_browsertest.cc b/chrome/browser/ui/browser_navigator_browsertest.cc index 6748989d..8a476df 100644 --- a/chrome/browser/ui/browser_navigator_browsertest.cc +++ b/chrome/browser/ui/browser_navigator_browsertest.cc
@@ -697,10 +697,8 @@ NavigateHelper(GURL("chrome://about"), browser(), WindowOpenDisposition::NEW_FOREGROUND_TAB, true); - int previous_tab_count = browser()->tab_strip_model()->count(); browser()->tab_strip_model()->CloseWebContentsAt(0, TabCloseTypes::CLOSE_NONE); - EXPECT_EQ(previous_tab_count - 1, browser()->tab_strip_model()->count()); // This expects a new WebContents, since we just closed the tab. NavigateHelper(singleton_url, browser(), WindowOpenDisposition::SWITCH_TO_TAB, true, nullptr /* expected_contents */); @@ -1612,10 +1610,8 @@ observer.Wait(); } - int previous_tab_count = browser()->tab_strip_model()->count(); - browser()->tab_strip_model()->CloseWebContentsAt( - 2, TabCloseTypes::CLOSE_USER_GESTURE); - EXPECT_EQ(previous_tab_count - 1, browser()->tab_strip_model()->count()); + EXPECT_TRUE(browser()->tab_strip_model()->CloseWebContentsAt( + 2, TabCloseTypes::CLOSE_USER_GESTURE)); EXPECT_EQ(0, browser()->tab_strip_model()->active_index()); }
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 e89a2f60..f439e355 100644 --- a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc +++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
@@ -703,6 +703,12 @@ WebContents* web_contents) : ContentSettingBubbleModel(delegate, web_contents) { set_title(l10n_util::GetStringUTF16(IDS_SITE_SETTINGS_TYPE_STORAGE_ACCESS)); + + // TODO(crbug.com/1433644): Consider to add subtitles to all permissions. + set_subtitle(url_formatter::FormatUrlForSecurityDisplay( + web_contents->GetURL(), + url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC)); + set_message(l10n_util::GetStringFUTF16( IDS_STORAGE_ACCESS_PERMISSION_BUBBLE_MESSAGE, url_formatter::FormatUrlForSecurityDisplay( @@ -713,6 +719,11 @@ PageSpecificContentSettings::GetForFrame(&GetPage().GetMainDocument()); set_site_list(page_content_settings->GetTwoSiteRequests( ContentSettingsType::STORAGE_ACCESS)); + + set_manage_text_style(ManageTextStyle::kHoverButton); + set_manage_text(l10n_util::GetStringUTF16(IDS_STORAGE_ACCESS_MANAGE_TEXT)); + set_manage_tooltip( + l10n_util::GetStringUTF16(IDS_STORAGE_ACCESS_MANAGE_TOOLTIP)); } ContentSettingStorageAccessBubbleModel::
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.h b/chrome/browser/ui/content_settings/content_setting_bubble_model.h index d9fc9a5..1c8d1b1 100644 --- a/chrome/browser/ui/content_settings/content_setting_bubble_model.h +++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.h
@@ -135,6 +135,9 @@ kButton, // Manage text is used as a checkbox title. kCheckbox, + // Manage text is shown in a HoverButton. The "Manage" and "Done" buttons + // are hidden. + kHoverButton, }; struct BubbleContent { @@ -146,6 +149,7 @@ ~BubbleContent(); std::u16string title; + std::u16string subtitle; std::u16string message; // Whether the user can modify the content of the bubble. // False if controlled by policy, etc. @@ -156,6 +160,7 @@ std::u16string custom_link; bool custom_link_enabled = false; std::u16string manage_text; + std::u16string manage_tooltip; ManageTextStyle manage_text_style = ManageTextStyle::kButton; MediaMenuMap media_menus; bool show_learn_more = false; @@ -242,6 +247,9 @@ content::Page& GetPage() const { return web_contents_->GetPrimaryPage(); } void set_title(const std::u16string& title) { bubble_content_.title = title; } + void set_subtitle(const std::u16string& subtitle) { + bubble_content_.subtitle = subtitle; + } void set_message(const std::u16string& message) { bubble_content_.message = message; } @@ -263,6 +271,9 @@ void set_manage_text(const std::u16string& text) { bubble_content_.manage_text = text; } + void set_manage_tooltip(const std::u16string& text) { + bubble_content_.manage_tooltip = text; + } void set_manage_text_style(ManageTextStyle manage_text_style) { bubble_content_.manage_text_style = manage_text_style; }
diff --git a/chrome/browser/ui/passwords/manage_passwords_state.h b/chrome/browser/ui/passwords/manage_passwords_state.h index c2fdcee..4817210 100644 --- a/chrome/browser/ui/passwords/manage_passwords_state.h +++ b/chrome/browser/ui/passwords/manage_passwords_state.h
@@ -163,7 +163,7 @@ password_manager::ui::State state_; // The client used for logging. - raw_ptr<password_manager::PasswordManagerClient, DanglingUntriaged> client_; + raw_ptr<password_manager::PasswordManagerClient, DanglingAcrossTasks> client_; // Whether the last attempt to authenticate to opt-in using password account // storage failed.
diff --git a/chrome/browser/ui/tabs/pinned_tab_service_browsertest.cc b/chrome/browser/ui/tabs/pinned_tab_service_browsertest.cc index 1e0ea7d4..fd265f9 100644 --- a/chrome/browser/ui/tabs/pinned_tab_service_browsertest.cc +++ b/chrome/browser/ui/tabs/pinned_tab_service_browsertest.cc
@@ -81,9 +81,9 @@ profile, ProfileKeepAliveOrigin::kBrowserWindow); BrowserRemovalWaiter waiter(browser()); tab_strip_model->SetTabPinned(0, false); - int previous_tab_count = tab_strip_model->count(); - tab_strip_model->CloseWebContentsAt(0, TabCloseTypes::CLOSE_NONE); - EXPECT_EQ(previous_tab_count - 1, tab_strip_model->count()); + EXPECT_TRUE( + tab_strip_model->CloseWebContentsAt(0, TabCloseTypes::CLOSE_NONE)); + EXPECT_TRUE(tab_strip_model->empty()); waiter.WaitForRemoval(); // Let's see it's cleared out properly.
diff --git a/chrome/browser/ui/tabs/tab_strip_model.cc b/chrome/browser/ui/tabs/tab_strip_model.cc index 311daa4..2878ae66 100644 --- a/chrome/browser/ui/tabs/tab_strip_model.cc +++ b/chrome/browser/ui/tabs/tab_strip_model.cc
@@ -56,10 +56,6 @@ #include "chrome/browser/ui/web_applications/web_app_dialog_utils.h" #include "chrome/browser/ui/web_applications/web_app_launch_utils.h" #include "chrome/browser/ui/web_applications/web_app_tabbed_utils.h" -#include "chrome/browser/web_applications/policy/web_app_policy_manager.h" -#include "chrome/browser/web_applications/web_app_id.h" -#include "chrome/browser/web_applications/web_app_provider.h" -#include "chrome/browser/web_applications/web_app_tab_helper.h" #include "chrome/common/url_constants.h" #include "chrome/grit/generated_resources.h" #include "components/content_settings/core/browser/host_content_settings_map.h" @@ -125,7 +121,7 @@ ui::PAGE_TRANSITION_AUTO_TOPLEVEL); } -// Installs RenderWidgetVisibilityTracker when the active tab has changed. +// Intalls RenderWidgetVisibilityTracker when the active tab has changed. std::unique_ptr<RenderWidgetHostVisibilityTracker> InstallRenderWigetVisibilityTracker(const TabStripSelectionChange& selection) { if (!selection.active_tab_changed()) @@ -270,7 +266,7 @@ // // Once the notification for change of active web contents has been sent, // this field is set to nullptr. - raw_ptr<WebContents, DanglingUntriaged> initially_active_web_contents = + raw_ptr<WebContents, DanglingAcrossTasks> initially_active_web_contents = nullptr; // The WebContents that were recently detached. Observers need to be notified @@ -718,10 +714,10 @@ CloseTabs(closing_tabs, TabCloseTypes::CLOSE_CREATE_HISTORICAL_TAB); } -void TabStripModel::CloseWebContentsAt(int index, uint32_t close_types) { +bool TabStripModel::CloseWebContentsAt(int index, uint32_t close_types) { CHECK(ContainsIndex(index)); WebContents* contents = GetWebContentsAt(index); - CloseTabs(base::span<WebContents* const>(&contents, 1u), close_types); + return CloseTabs(base::span<WebContents* const>(&contents, 1u), close_types); } bool TabStripModel::TabsAreLoading() const { @@ -831,12 +827,7 @@ } bool TabStripModel::IsTabClosable(int index) const { - return PolicyAllowsTabClosing(GetWebContentsAt(index)) && - (!web_app::IsPinnedHomeTab(this, index) || count() == 1); -} - -bool TabStripModel::IsTabClosable(const content::WebContents* contents) const { - return IsTabClosable(GetIndexOfWebContents(contents)); + return !web_app::IsPinnedHomeTab(this, index) || count() == 1; } absl::optional<tab_groups::TabGroupId> TabStripModel::GetTabGroupForTab( @@ -1870,29 +1861,21 @@ return index; } -void TabStripModel::CloseTabs(base::span<content::WebContents* const> items, +bool TabStripModel::CloseTabs(base::span<content::WebContents* const> items, uint32_t close_types) { - std::vector<content::WebContents*> filtered_items; - base::ranges::copy_if(items, std::back_inserter(filtered_items), - [this](content::WebContents* const contents) { - return IsTabClosable(contents); - }); + if (items.empty()) + return true; - if (filtered_items.empty()) { - return; - } - - const bool closing_all = static_cast<int>(filtered_items.size()) == count(); + const bool closing_all = static_cast<int>(items.size()) == count(); base::WeakPtr<TabStripModel> ref = weak_factory_.GetWeakPtr(); if (closing_all) { - for (auto& observer : observers_) { + for (auto& observer : observers_) observer.WillCloseAllTabs(this); - } } DetachNotifications notifications(GetActiveWebContents(), selection_model_); const bool closed_all = - CloseWebContentses(filtered_items, close_types, ¬ifications); + CloseWebContentses(items, close_types, ¬ifications); // When unload handler is triggered for all items, we should wait for the // result. @@ -1900,7 +1883,7 @@ SendDetachWebContentsNotifications(¬ifications); if (!ref) - return; + return closed_all; if (closing_all) { // CloseAllTabsStopped is sent with reason kCloseAllCompleted if // closed_all; otherwise kCloseAllCanceled is sent. @@ -1909,6 +1892,8 @@ this, closed_all ? TabStripModelObserver::kCloseAllCompleted : TabStripModelObserver::kCloseAllCanceled); } + + return closed_all; } bool TabStripModel::CloseWebContentses( @@ -2630,24 +2615,6 @@ } } -bool TabStripModel::PolicyAllowsTabClosing( - content::WebContents* contents) const { - if (!contents) { - return true; - } - - web_app::WebAppProvider* provider = - web_app::WebAppProvider::GetForWebContents(contents); - // Can be null if there is no tab helper or app id. - const web_app::AppId* app_id = web_app::WebAppTabHelper::GetAppId(contents); - if (!app_id) { - return true; - } - - return !delegate()->IsForWebApp() || - !provider->policy_manager().IsPreventCloseEnabled(*app_id); -} - int TabStripModel::DetermineInsertionIndex(ui::PageTransition transition, bool foreground) { int tab_count = count();
diff --git a/chrome/browser/ui/tabs/tab_strip_model.h b/chrome/browser/ui/tabs/tab_strip_model.h index 5656b5d..b396ba4 100644 --- a/chrome/browser/ui/tabs/tab_strip_model.h +++ b/chrome/browser/ui/tabs/tab_strip_model.h
@@ -114,7 +114,7 @@ // guaranteed to be valid for the life time of the notification (and // possibly longer). std::unique_ptr<content::WebContents> owned_contents; - raw_ptr<content::WebContents, DanglingUntriaged> contents; + raw_ptr<content::WebContents, DanglingAcrossTasks> contents; // The index of the WebContents in the original selection model of the tab // strip [prior to any tabs being removed, if multiple tabs are being @@ -214,8 +214,11 @@ absl::optional<tab_groups::TabGroupId> group = absl::nullopt); // Closes the WebContents at the specified index. This causes the // WebContents to be destroyed, but it may not happen immediately. - // |close_types| is a bitmask of CloseTypes. - void CloseWebContentsAt(int index, uint32_t close_types); + // |close_types| is a bitmask of CloseTypes. Returns true if the + // WebContents was closed immediately, false if it was not closed (we + // may be waiting for a response from an onunload handler, or waiting for the + // user to confirm closure). + bool CloseWebContentsAt(int index, uint32_t close_types); // Replaces the WebContents at |index| with |new_contents|. The // WebContents that was at |index| is returned and its ownership returns @@ -347,10 +350,6 @@ // Returns true if the tab at |index| is allowed to be closed. bool IsTabClosable(int index) const; - // Returns true if the tab corresponding to |contents| is allowed to be - // closed. - bool IsTabClosable(const content::WebContents* contents) const; - // Returns the group that contains the tab at |index|, or nullopt if the tab // index is invalid or not grouped. absl::optional<tab_groups::TabGroupId> GetTabGroupForTab( @@ -670,7 +669,10 @@ // the page in question has an unload event the WebContents will not be // destroyed until after the event has completed, which will then call back // into this method. - void CloseTabs(base::span<content::WebContents* const> items, + // + // Returns true if the WebContentses were closed immediately, false if we + // are waiting for the result of an onunload handler. + bool CloseTabs(base::span<content::WebContents* const> items, uint32_t close_types); // |close_types| is a bitmask of the types in CloseTypes. @@ -799,9 +801,6 @@ // Takes the |selection| change and decides whether to forget the openers. void OnActiveTabChanged(const TabStripSelectionChange& selection); - // Checks if policy allows a tab to be closed. - bool PolicyAllowsTabClosing(content::WebContents* contents) const; - // Determine where to shift selection after a tab is closed. absl::optional<int> DetermineNewSelectedIndex(int removed_index) const; @@ -819,7 +818,7 @@ base::ObserverList<TabStripModelObserver>::Unchecked observers_; // A profile associated with this TabStripModel. - raw_ptr<Profile, DanglingUntriaged> profile_; + raw_ptr<Profile, DanglingAcrossTasks> profile_; // True if all tabs are currently being closed via CloseAllTabs. bool closing_all_ = false;
diff --git a/chrome/browser/ui/tabs/tab_strip_model_browsertest.cc b/chrome/browser/ui/tabs/tab_strip_model_browsertest.cc deleted file mode 100644 index 6ff2d2c6..0000000 --- a/chrome/browser/ui/tabs/tab_strip_model_browsertest.cc +++ /dev/null
@@ -1,155 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/tabs/tab_strip_model.h" - -#include "base/json/json_reader.h" -#include "base/test/scoped_feature_list.h" -#include "base/values.h" -#include "chrome/browser/policy/policy_test_utils.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" -#include "chrome/browser/web_applications/test/web_app_install_test_utils.h" -#include "chrome/browser/web_applications/web_app_id.h" -#include "chrome/browser/web_applications/web_app_id_constants.h" -#include "chrome/browser/web_applications/web_app_install_info.h" -#include "chrome/common/chrome_features.h" -#include "components/policy/core/browser/browser_policy_connector.h" -#include "components/policy/core/browser/browser_policy_connector_base.h" -#include "components/policy/core/common/mock_configuration_policy_provider.h" -#include "components/policy/core/common/policy_map.h" -#include "components/policy/policy_constants.h" -#include "content/public/test/browser_test.h" -#include "ui/base/window_open_disposition.h" -#include "url/gurl.h" - -namespace { -constexpr char kCalculatorAppUrl[] = "https://calculator.apps.chrome/"; - -constexpr char kPreventCloseEnabledForCalculator[] = R"([ - { - "manifest_id": "https://calculator.apps.chrome/", - "run_on_os_login": "run_windowed", - "prevent_close_after_run_on_login": true - } -])"; - -#if BUILDFLAG(IS_CHROMEOS) -constexpr bool kShouldPreventClose = true; -#else -constexpr bool kShouldPreventClose = false; -#endif // BUILDFLAG(IS_CHROMEOS) - -} // namespace - -class TabStripModelPreventCloseTest : public policy::PolicyTest { - public: - TabStripModelPreventCloseTest() { - scoped_feature_list_.InitWithFeatures( - /*enabled_features=*/{features::kDesktopPWAsEnforceWebAppSettingsPolicy, - features::kDesktopPWAsPreventClose}, - /*disabled_features=*/{}); - } - TabStripModelPreventCloseTest(const TabStripModelPreventCloseTest&) = delete; - TabStripModelPreventCloseTest& operator=( - const TabStripModelPreventCloseTest&) = delete; - ~TabStripModelPreventCloseTest() override = default; - - void SetUpInProcessBrowserTestFixture() override { - provider_.SetDefaultReturns( - /*is_initialization_complete_return=*/true, - /*is_first_policy_load_complete_return=*/true); - policy::BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_); - } - - void TearDownInProcessBrowserTestFixture() override { - ClearWebAppSettings(); - policy::PolicyTest::TearDownInProcessBrowserTestFixture(); - } - - void SetWebAppSettings(base::StringPiece config) { - policy::PolicyMap policies; - SetPolicy(&policies, policy::key::kWebAppSettings, - ReturnPolicyValueFromJson(config)); - provider_.UpdateChromePolicy(policies); - } - - void ClearWebAppSettings() { SetWebAppSettings(/*config=*/"[]"); } - - void InstallPWA(const GURL& app_url, const web_app::AppId& app_id) { - auto web_app_info = std::make_unique<web_app::WebAppInstallInfo>(); - web_app_info->start_url = app_url; - web_app_info->scope = app_url.GetWithoutFilename(); - web_app::AppId installed_app_id = web_app::test::InstallWebApp( - browser()->profile(), std::move(web_app_info)); - EXPECT_EQ(app_id, installed_app_id); - } - - Browser* LaunchPWA(const web_app::AppId& app_id, bool launch_in_window) { - return launch_in_window - ? web_app::LaunchWebAppBrowserAndWait( - profile(), app_id, WindowOpenDisposition::NEW_WINDOW) - : web_app::LaunchBrowserForWebAppInTab(profile(), app_id); - } - - base::Value ReturnPolicyValueFromJson(base::StringPiece policy) { - auto result = base::JSONReader::ReadAndReturnValueWithError( - policy, base::JSONParserOptions::JSON_ALLOW_TRAILING_COMMAS); - DCHECK(result.has_value()) << result.error().message; - DCHECK(result->is_list()); - return std::move(*result); - } - - Profile* profile() { return browser()->profile(); } - - private: - base::test::ScopedFeatureList scoped_feature_list_; - testing::NiceMock<policy::MockConfigurationPolicyProvider> provider_; -}; - -IN_PROC_BROWSER_TEST_F(TabStripModelPreventCloseTest, - PreventCloseEnforedByPolicy) { - InstallPWA(GURL(kCalculatorAppUrl), web_app::kCalculatorAppId); - SetWebAppSettings(kPreventCloseEnabledForCalculator); - - Browser* const browser = - LaunchPWA(web_app::kCalculatorAppId, /*launch_in_window=*/true); - ASSERT_TRUE(browser); - - TabStripModel* const tab_strip_model = browser->tab_strip_model(); - EXPECT_EQ(1, tab_strip_model->count()); - EXPECT_EQ(!kShouldPreventClose, tab_strip_model->IsTabClosable( - tab_strip_model->GetActiveWebContents())); - - tab_strip_model->CloseAllTabs(); - EXPECT_EQ(kShouldPreventClose ? 1 : 0, tab_strip_model->count()); - - if (kShouldPreventClose) { - ClearWebAppSettings(); - EXPECT_TRUE(tab_strip_model->IsTabClosable( - tab_strip_model->GetActiveWebContents())); - - tab_strip_model->CloseAllTabs(); - EXPECT_EQ(0, tab_strip_model->count()); - } -} - -IN_PROC_BROWSER_TEST_F(TabStripModelPreventCloseTest, - PreventCloseEnforedByPolicyTabbedAppShallBeClosable) { - InstallPWA(GURL(kCalculatorAppUrl), web_app::kCalculatorAppId); - SetWebAppSettings(kPreventCloseEnabledForCalculator); - - Browser* const browser = - LaunchPWA(web_app::kCalculatorAppId, /*launch_in_window=*/false); - ASSERT_TRUE(browser); - - TabStripModel* const tab_strip_model = browser->tab_strip_model(); - EXPECT_EQ(2, tab_strip_model->count()); - EXPECT_TRUE( - tab_strip_model->IsTabClosable(tab_strip_model->GetActiveWebContents())); - - tab_strip_model->CloseAllTabs(); - EXPECT_EQ(0, tab_strip_model->count()); -}
diff --git a/chrome/browser/ui/tabs/tab_strip_model_observer.h b/chrome/browser/ui/tabs/tab_strip_model_observer.h index 4f489ebd..63cabb9 100644 --- a/chrome/browser/ui/tabs/tab_strip_model_observer.h +++ b/chrome/browser/ui/tabs/tab_strip_model_observer.h
@@ -230,7 +230,7 @@ return selected_tabs_were_removed || old_model != new_model; } - raw_ptr<content::WebContents, DanglingUntriaged> old_contents = nullptr; + raw_ptr<content::WebContents, DanglingAcrossTasks> old_contents = nullptr; raw_ptr<content::WebContents, DanglingUntriaged> new_contents = nullptr; ui::ListSelectionModel old_model;
diff --git a/chrome/browser/ui/tabs/tab_strip_model_unittest.cc b/chrome/browser/ui/tabs/tab_strip_model_unittest.cc index 76e6f35..7fadd11 100644 --- a/chrome/browser/ui/tabs/tab_strip_model_unittest.cc +++ b/chrome/browser/ui/tabs/tab_strip_model_unittest.cc
@@ -622,9 +622,8 @@ // Test CloseWebContentsAt { - int previous_tab_count = tabstrip.count(); - tabstrip.CloseWebContentsAt(2, TabCloseTypes::CLOSE_NONE); - EXPECT_EQ(previous_tab_count - 1, tabstrip.count()); + EXPECT_TRUE(tabstrip.CloseWebContentsAt(2, TabCloseTypes::CLOSE_NONE)); + EXPECT_EQ(2, tabstrip.count()); EXPECT_EQ(5, observer.GetStateCount()); State s1(raw_contents3, 2, MockTabStripModelObserver::CLOSE); @@ -1066,11 +1065,9 @@ EXPECT_EQ(2, tabstrip.GetIndexOfLastWebContentsOpenedBy(raw_child11, 1)); // Closing a tab should cause its children to inherit the tab's opener. - int previous_tab_count = tabstrip.count(); - tabstrip.CloseWebContentsAt(1, - TabCloseTypes::CLOSE_USER_GESTURE | - TabCloseTypes::CLOSE_CREATE_HISTORICAL_TAB); - EXPECT_EQ(previous_tab_count - 1, tabstrip.count()); + EXPECT_EQ(true, tabstrip.CloseWebContentsAt( + 1, TabCloseTypes::CLOSE_USER_GESTURE | + TabCloseTypes::CLOSE_CREATE_HISTORICAL_TAB)); EXPECT_EQ("1 111 12 2", GetTabStripStateString(tabstrip)); EXPECT_EQ(1, GetID(tabstrip.GetActiveWebContents())); // opener1 is now the opener of 111, so has two adjacent descendants (111, 12) @@ -1986,9 +1983,7 @@ // and make sure the correct tab gets selected when the new tab is closed. tabstrip.AppendWebContents(CreateWebContents(), true); EXPECT_EQ(2, tabstrip.active_index()); - int previous_tab_count = tabstrip.count(); tabstrip.CloseWebContentsAt(2, TabCloseTypes::CLOSE_NONE); - EXPECT_EQ(previous_tab_count - 1, tabstrip.count()); EXPECT_EQ(0, tabstrip.active_index()); // Clean up after ourselves.
diff --git a/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc b/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc index 60505fe..4d42ca3 100644 --- a/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc +++ b/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc
@@ -803,8 +803,14 @@ SaveCardBubbleViewsFullFormBrowserTestWithAutofillUpstream, ::testing::Bool()); +// TODO(crbug.com/1455908): FindViewInBubbleById() hits CHECK. +#if BUILDFLAG(IS_LINUX) +#define MAYBE_AlertAccessibleEvent DISABLED_AlertAccessibleEvent +#else +#define MAYBE_AlertAccessibleEvent AlertAccessibleEvent +#endif IN_PROC_BROWSER_TEST_P(SaveCardBubbleViewsFullFormBrowserTest, - AlertAccessibleEvent) { + MAYBE_AlertAccessibleEvent) { views::test::AXEventCounter counter(views::AXEventManager::Get()); EXPECT_EQ(0, counter.GetCount(ax::mojom::Event::kAlert)); @@ -885,9 +891,8 @@ // dismissed and then immediately torn down (e.g. by closing browser window) // before the asynchronous close completes. Regression test for // https://crbug.com/842577 . -// -// TODO(crbug.com/1360234): Flaky on Mac. -#if BUILDFLAG(IS_MAC) +// TODO(crbug.com/1455908): FindViewInBubbleById() hits CHECK. +#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) #define MAYBE_Local_SynchronousCloseAfterAsynchronousClose \ DISABLED_Local_SynchronousCloseAfterAsynchronousClose #else @@ -1160,9 +1165,17 @@ // Tests the upload save bubble. Ensures that the bubble surfaces a textfield // requesting cardholder name if cardholder name is missing. +// TODO(crbug.com/1455908): FindViewInBubbleById() hits CHECK. +#if BUILDFLAG(IS_LINUX) +#define MAYBE_Upload_SubmittingFormWithMissingNamesRequestsCardholderNameIfExpOn \ + DISABLED_Upload_SubmittingFormWithMissingNamesRequestsCardholderNameIfExpOn +#else +#define MAYBE_Upload_SubmittingFormWithMissingNamesRequestsCardholderNameIfExpOn \ + Upload_SubmittingFormWithMissingNamesRequestsCardholderNameIfExpOn +#endif IN_PROC_BROWSER_TEST_P( SaveCardBubbleViewsFullFormBrowserTestWithAutofillUpstream, - Upload_SubmittingFormWithMissingNamesRequestsCardholderNameIfExpOn) { + MAYBE_Upload_SubmittingFormWithMissingNamesRequestsCardholderNameIfExpOn) { // Start sync. ASSERT_TRUE(SetupSync()); @@ -1352,9 +1365,17 @@ // Tests the upload save bubble. Ensures that if cardholder name is explicitly // requested and the user accepts the dialog after changing it, the correct // metric is logged. +// TODO(crbug.com/1455908): FindViewInBubbleById() hits CHECK. +#if BUILDFLAG(IS_LINUX) +#define MAYBE_Upload_CardholderNameRequested_SubmittingChangedValueLogsEditedMetric \ + DISABLED_Upload_CardholderNameRequested_SubmittingChangedValueLogsEditedMetric +#else +#define MAYBE_Upload_CardholderNameRequested_SubmittingChangedValueLogsEditedMetric \ + Upload_CardholderNameRequested_SubmittingChangedValueLogsEditedMetric +#endif IN_PROC_BROWSER_TEST_P( SaveCardBubbleViewsFullFormBrowserTestWithAutofillUpstream, - Upload_CardholderNameRequested_SubmittingChangedValueLogsEditedMetric) { + MAYBE_Upload_CardholderNameRequested_SubmittingChangedValueLogsEditedMetric) { // Start sync. ASSERT_TRUE(SetupSync()); // Set the user's full name. @@ -1796,9 +1817,17 @@ // Tests the upload save bubble. Ensures that the bubble surfaces a pair of // dropdowns requesting expiration date if expiration date month is missing and // year is detected but passed. +// TODO(crbug.com/1455908): FindViewInBubbleById() hits CHECK. +#if BUILDFLAG(IS_LINUX) +#define MAYBE_Upload_SubmittingFormWithExpirationDateMonthAndYearExpired \ + DISABLED_Upload_SubmittingFormWithExpirationDateMonthAndYearExpired +#else +#define MAYBE_Upload_SubmittingFormWithExpirationDateMonthAndYearExpired \ + Upload_SubmittingFormWithExpirationDateMonthAndYearExpired +#endif IN_PROC_BROWSER_TEST_P( SaveCardBubbleViewsFullFormBrowserTestWithAutofillUpstream, - Upload_SubmittingFormWithExpirationDateMonthAndYearExpired) { + MAYBE_Upload_SubmittingFormWithExpirationDateMonthAndYearExpired) { SetUpForEditableExpirationDate(); // Fill form with a valid month but a passed year. FillFormWithSpecificExpirationDate("08", "2000"); @@ -1837,8 +1866,16 @@ // boolean to branch local vs. upload logic. // Tests the local save bubble. Ensures that clicking the [No thanks] button // successfully causes a strike to be added. +// TODO(crbug.com/1455908): FindViewInBubbleById() hits CHECK. +#if BUILDFLAG(IS_LINUX) +#define MAYBE_StrikeDatabase_Local_AddStrikeIfBubbleDeclined \ + DISABLED_StrikeDatabase_Local_AddStrikeIfBubbleDeclined +#else +#define MAYBE_StrikeDatabase_Local_AddStrikeIfBubbleDeclined \ + StrikeDatabase_Local_AddStrikeIfBubbleDeclined +#endif IN_PROC_BROWSER_TEST_P(SaveCardBubbleViewsFullFormBrowserTest, - StrikeDatabase_Local_AddStrikeIfBubbleDeclined) { + MAYBE_StrikeDatabase_Local_AddStrikeIfBubbleDeclined) { FillForm(); SubmitFormAndWaitForCardLocalSaveBubble(); @@ -1881,8 +1918,16 @@ // example of declining the prompt three times and ensuring that the // offer-to-save bubble does not appear on the fourth try. Then, ensures that no // strikes are added if the card already has max strikes. +// TODO(crbug.com/1455908): FindViewInBubbleById() hits CHECK. +#if BUILDFLAG(IS_LINUX) +#define MAYBE_StrikeDatabase_Local_FullFlowTest \ + DISABLED_StrikeDatabase_Local_FullFlowTest +#else +#define MAYBE_StrikeDatabase_Local_FullFlowTest \ + StrikeDatabase_Local_FullFlowTest +#endif IN_PROC_BROWSER_TEST_P(SaveCardBubbleViewsFullFormBrowserTest, - StrikeDatabase_Local_FullFlowTest) { + MAYBE_StrikeDatabase_Local_FullFlowTest) { // Show and ignore the bubble enough times in order to accrue maximum strikes. for (int i = 0; i < credit_card_save_manager_->GetCreditCardSaveStrikeDatabase() @@ -1943,9 +1988,17 @@ // example of declining the prompt three times and ensuring that the // offer-to-save bubble does not appear on the fourth try. Then, ensures that no // strikes are added if the card already has max strikes. +// TODO(crbug.com/1455908): FindViewInBubbleById() hits CHECK. +#if BUILDFLAG(IS_LINUX) +#define MAYBE_StrikeDatabase_Upload_FullFlowTest \ + DISABLED_StrikeDatabase_Upload_FullFlowTest +#else +#define MAYBE_StrikeDatabase_Upload_FullFlowTest \ + StrikeDatabase_Upload_FullFlowTest +#endif IN_PROC_BROWSER_TEST_P( SaveCardBubbleViewsFullFormBrowserTestWithAutofillUpstream, - StrikeDatabase_Upload_FullFlowTest) { + MAYBE_StrikeDatabase_Upload_FullFlowTest) { // Start sync. ASSERT_TRUE(SetupSync()); @@ -2014,9 +2067,15 @@ } // Tests to ensure the card nickname is shown correctly in the Upstream bubble. +// TODO(crbug.com/1455908): FindViewInBubbleById() hits CHECK. +#if BUILDFLAG(IS_LINUX) +#define MAYBE_LocalCardHasNickname DISABLED_LocalCardHasNickname +#else +#define MAYBE_LocalCardHasNickname LocalCardHasNickname +#endif IN_PROC_BROWSER_TEST_P( SaveCardBubbleViewsFullFormBrowserTestWithAutofillUpstream, - LocalCardHasNickname) { + MAYBE_LocalCardHasNickname) { base::HistogramTester histogram_tester; CreditCard card = test::GetCreditCard(); // Set card number to match the number to be filled in the form. @@ -2055,8 +2114,15 @@ // Tests the local save bubble. Ensures that clicking the [Save] button // successfully causes the bubble to go away. +// TODO(crbug.com/1455908): FindViewInBubbleById() hits CHECK. +#if BUILDFLAG(IS_LINUX) +#define MAYBE_Local_ClickingSaveClosesBubble \ + DISABLED_Local_ClickingSaveClosesBubble +#else +#define MAYBE_Local_ClickingSaveClosesBubble Local_ClickingSaveClosesBubble +#endif IN_PROC_BROWSER_TEST_P(SaveCardBubbleViewsFullFormBrowserTest, - Local_ClickingSaveClosesBubble) { + MAYBE_Local_ClickingSaveClosesBubble) { FillForm(); SubmitFormAndWaitForCardLocalSaveBubble();
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h index f3ec625..dedb545 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h
@@ -370,7 +370,8 @@ PrefChangeRegistrar profile_pref_registrar_; // Used for opening urls. - raw_ptr<content::PageNavigator, DanglingUntriaged> page_navigator_ = nullptr; + raw_ptr<content::PageNavigator, DanglingAcrossTasks> page_navigator_ = + nullptr; // BookmarkModel that owns the entries and folders that are shown in this // view. This is owned by the Profile.
diff --git a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.h b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.h index 02bac22..582b5cd 100644 --- a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.h +++ b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.h
@@ -167,7 +167,7 @@ // Provides a callback that returns the page navigator base::RepeatingCallback<content::PageNavigator*()> GetPageNavigatorGetter(); - raw_ptr<views::MenuButton, DanglingUntriaged> overflow_button_; + raw_ptr<views::MenuButton, DanglingAcrossTasks> overflow_button_; // Used to show the overflow menu when clicked. raw_ptr<views::BubbleDialogDelegate> bubble_delegate_ = nullptr; @@ -176,7 +176,8 @@ raw_ptr<SavedTabGroupModel> saved_tab_group_model_; // The page navigator used to create tab groups - raw_ptr<content::PageNavigator, DanglingUntriaged> page_navigator_ = nullptr; + raw_ptr<content::PageNavigator, DanglingAcrossTasks> page_navigator_ = + nullptr; raw_ptr<Browser> browser_; // During a drag and drop session, `drag_data_` owns the state for the drag.
diff --git a/chrome/browser/ui/views/content_setting_bubble_contents.cc b/chrome/browser/ui/views/content_setting_bubble_contents.cc index 8a93399..80c4db4 100644 --- a/chrome/browser/ui/views/content_setting_bubble_contents.cc +++ b/chrome/browser/ui/views/content_setting_bubble_contents.cc
@@ -5,21 +5,20 @@ #include "chrome/browser/ui/views/content_setting_bubble_contents.h" #include <algorithm> +#include <memory> #include <utility> #include <vector> #include "base/memory/raw_ptr.h" #include "base/ranges/algorithm.h" #include "base/strings/utf_string_conversions.h" -#include "build/build_config.h" #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h" #include "chrome/browser/ui/content_settings/content_setting_bubble_model.h" #include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/views/chrome_layout_provider.h" -#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/content_setting_site_row_view.h" +#include "chrome/browser/ui/views/controls/rich_hover_button.h" #include "chrome/grit/generated_resources.h" -#include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/strings/grit/components_strings.h" #include "components/vector_icons/vector_icons.h" #include "content/public/browser/navigation_handle.h" @@ -29,20 +28,14 @@ #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/base/models/combobox_model.h" #include "ui/base/models/image_model.h" -#include "ui/base/resource/resource_bundle.h" #include "ui/base/ui_base_features.h" #include "ui/color/color_id.h" #include "ui/color/color_provider.h" -#include "ui/gfx/color_utils.h" #include "ui/gfx/geometry/insets.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/paint_vector_icon.h" -#include "ui/gfx/vector_icon_types.h" -#include "ui/views/border.h" #include "ui/views/controls/button/image_button.h" #include "ui/views/controls/button/image_button_factory.h" -#include "ui/views/controls/button/label_button_border.h" -#include "ui/views/controls/button/md_text_button.h" #include "ui/views/controls/button/radio_button.h" #include "ui/views/controls/combobox/combobox.h" #include "ui/views/controls/image_view.h" @@ -71,6 +64,20 @@ : std::u16string(); } +ui::ImageModel GetSiteSettingsIcon() { + return ui::ImageModel::FromVectorIcon( + features::IsChromeRefresh2023() ? vector_icons::kSettingsChromeRefreshIcon + : vector_icons::kSettingsIcon, + ui::kColorIcon); +} + +ui::ImageModel GetLaunchIcon() { + return ui::ImageModel::FromVectorIcon( + features::IsChromeRefresh2023() ? vector_icons::kLaunchChromeRefreshIcon + : vector_icons::kLaunchIcon, + ui::kColorIconSecondary); +} + bool ShouldShowMediaDeviceMenus(ContentSettingBubbleModel* model) { return model->AsMediaStreamBubbleModel() && model->bubble_content().is_user_modifiable; @@ -490,6 +497,12 @@ const ContentSettingBubbleModel::BubbleContent& bubble_content = content_setting_bubble_model_->bubble_content(); + if (!bubble_content.subtitle.empty()) { + SetSubtitle(bubble_content.subtitle); + auto separator = std::make_unique<views::Separator>(); + rows.push_back({std::move(separator), LayoutRowType::FULL_WIDTH}); + } + if (!bubble_content.message.empty()) { auto message_label = std::make_unique<views::Label>( bubble_content.message, views::style::CONTEXT_LABEL, @@ -578,6 +591,25 @@ rows.push_back({std::move(manage_checkbox), LayoutRowType::DEFAULT}); } + if (bubble_content.manage_text_style == + ContentSettingBubbleModel::ManageTextStyle::kHoverButton) { + SetButtons(ui::DIALOG_BUTTON_NONE); + auto separator = std::make_unique<views::Separator>(); + rows.push_back({std::move(separator), LayoutRowType::DEFAULT}); + + auto site_settings_link = std::make_unique<RichHoverButton>( + base::BindRepeating( + [](ContentSettingBubbleContents* bubble) { + bubble->GetWidget()->Close(); + bubble->content_setting_bubble_model_->OnManageButtonClicked(); + }, + this), + GetSiteSettingsIcon(), bubble_content.manage_text, + /*secondary_text=*/std::u16string(), bubble_content.manage_tooltip, + /*subtitle_text=*/std::u16string(), GetLaunchIcon()); + rows.push_back({std::move(site_settings_link), LayoutRowType::FULL_WIDTH}); + } + // We have to apply the left and right margins manually, because rows using // LayoutRowType::FULL_WIDTH need to not have them applied to look correct. const int left_margin = margins().left();
diff --git a/chrome/browser/ui/views/desktop_capture/share_this_tab_source_view.cc b/chrome/browser/ui/views/desktop_capture/share_this_tab_source_view.cc index f521655..d4b27daa 100644 --- a/chrome/browser/ui/views/desktop_capture/share_this_tab_source_view.cc +++ b/chrome/browser/ui/views/desktop_capture/share_this_tab_source_view.cc
@@ -12,9 +12,13 @@ #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_widget_host_view.h" #include "media/base/video_util.h" +#include "ui/base/metadata/metadata_impl_macros.h" +#include "ui/gfx/canvas.h" +#include "ui/gfx/geometry/skia_conversions.h" #include "ui/gfx/image/image_skia_operations.h" #include "ui/gfx/text_constants.h" #include "ui/views/layout/box_layout.h" +#include "ui/views/layout/layout_provider.h" namespace { @@ -63,6 +67,36 @@ FROM_HERE, base::BindOnce(std::move(reply), hash, image)); } +// TODO(crbug.com/1458354): Add support for rounded image corners to ImageView +class RoundedCornerImageView : public views::ImageView { + public: + METADATA_HEADER(RoundedCornerImageView); + RoundedCornerImageView() = default; + RoundedCornerImageView(const RoundedCornerImageView&) = delete; + RoundedCornerImageView& operator=(const RoundedCornerImageView&) = delete; + + // views::ImageView: + bool GetCanProcessEventsWithinSubtree() const override { return false; } + + protected: + // views::ImageView: + void OnPaint(gfx::Canvas* canvas) override; +}; + +void RoundedCornerImageView::OnPaint(gfx::Canvas* canvas) { + SkPath mask; + CHECK(GetLayoutProvider()); + const int corner_radius = + GetLayoutProvider()->GetCornerRadiusMetric(views::Emphasis::kMedium); + mask.addRoundRect(gfx::RectToSkRect(GetImageBounds()), corner_radius, + corner_radius); + canvas->ClipPath(mask, true); + ImageView::OnPaint(canvas); +} + +BEGIN_METADATA(RoundedCornerImageView, views::ImageView) +END_METADATA + } // namespace ShareThisTabSourceView::ShareThisTabSourceView( @@ -82,7 +116,7 @@ throbber_->SetBoundsRect(kThrobberRect); throbber_->Start(); - image_view_ = AddChildView(std::make_unique<views::ImageView>()); + image_view_ = AddChildView(std::make_unique<RoundedCornerImageView>()); image_view_->SetVisible(false); image_view_->SetBoundsRect(kPreviewRect);
diff --git a/chrome/browser/ui/views/extensions/extension_install_dialog_view_browsertest.cc b/chrome/browser/ui/views/extensions/extension_install_dialog_view_browsertest.cc index e3fd5be..3710d18 100644 --- a/chrome/browser/ui/views/extensions/extension_install_dialog_view_browsertest.cc +++ b/chrome/browser/ui/views/extensions/extension_install_dialog_view_browsertest.cc
@@ -308,9 +308,8 @@ int tab1_idx = tab_strip_model->GetIndexOfWebContents(originator_contents); content::WebContentsDestroyedWatcher tab_destroyed_watcher( tab_strip_model->GetWebContentsAt(tab1_idx)); - int previous_tab_count = tab_strip_model->count(); - tab_strip_model->CloseWebContentsAt(tab1_idx, TabCloseTypes::CLOSE_NONE); - EXPECT_EQ(previous_tab_count - 1, tab_strip_model->count()); + EXPECT_TRUE(tab_strip_model->CloseWebContentsAt(tab1_idx, + TabCloseTypes::CLOSE_NONE)); tab_destroyed_watcher.Wait(); }
diff --git a/chrome/browser/ui/views/extensions/extension_install_friction_dialog_view_browsertest.cc b/chrome/browser/ui/views/extensions/extension_install_friction_dialog_view_browsertest.cc index d56c1a6..cfb5fe0d 100644 --- a/chrome/browser/ui/views/extensions/extension_install_friction_dialog_view_browsertest.cc +++ b/chrome/browser/ui/views/extensions/extension_install_friction_dialog_view_browsertest.cc
@@ -107,9 +107,8 @@ int tab1_idx = tab_strip_model->GetIndexOfWebContents(originator_contents); content::WebContentsDestroyedWatcher tab_destroyed_watcher( tab_strip_model->GetWebContentsAt(tab1_idx)); - int previous_tab_count = tab_strip_model->count(); - tab_strip_model->CloseWebContentsAt(tab1_idx, TabCloseTypes::CLOSE_NONE); - EXPECT_EQ(previous_tab_count - 1, tab_strip_model->count()); + EXPECT_TRUE(tab_strip_model->CloseWebContentsAt(tab1_idx, + TabCloseTypes::CLOSE_NONE)); tab_destroyed_watcher.Wait(); }
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_container.h b/chrome/browser/ui/views/extensions/extensions_toolbar_container.h index 0f45497..97bdc1b8 100644 --- a/chrome/browser/ui/views/extensions/extensions_toolbar_container.h +++ b/chrome/browser/ui/views/extensions/extensions_toolbar_container.h
@@ -318,7 +318,8 @@ // `extensions_features::kExtensionsMenuAccessControl` experiment is released. // Exactly one of `extensions_button_ and `extensions_controls_` is created; // the other is null. - const raw_ptr<ExtensionsToolbarButton, DanglingUntriaged> extensions_button_; + const raw_ptr<ExtensionsToolbarButton, DanglingAcrossTasks> + extensions_button_; const raw_ptr<ExtensionsToolbarControls, DanglingUntriaged> extensions_controls_; DisplayMode display_mode_;
diff --git a/chrome/browser/ui/views/frame/browser_root_view.h b/chrome/browser/ui/views/frame/browser_root_view.h index b81de341..c9df835 100644 --- a/chrome/browser/ui/views/frame/browser_root_view.h +++ b/chrome/browser/ui/views/frame/browser_root_view.h
@@ -138,7 +138,7 @@ std::unique_ptr<ui::LayerTreeOwner> drag_image_layer_owner); // The BrowserView. - raw_ptr<BrowserView, DanglingUntriaged> browser_view_ = nullptr; + raw_ptr<BrowserView, DanglingAcrossTasks> browser_view_ = nullptr; // Used to calculate partial offsets in scrolls that occur for a smooth // scroll device.
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h index 31ecd1e..ccdf5ffe 100644 --- a/chrome/browser/ui/views/frame/browser_view.h +++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -993,7 +993,7 @@ // The view that manages the tab strip, toolbar, and sometimes the bookmark // bar. Stacked top in the view hiearachy so it can be used to slide out // the top views in immersive fullscreen. - raw_ptr<TopContainerView, DanglingUntriaged> top_container_ = nullptr; + raw_ptr<TopContainerView, DanglingAcrossTasks> top_container_ = nullptr; // Menu button and page status icons. Only used by web-app windows. raw_ptr<WebAppFrameToolbarView, DanglingUntriaged> web_app_frame_toolbar_ = @@ -1006,11 +1006,11 @@ raw_ptr<views::Label, DanglingUntriaged> web_app_window_title_ = nullptr; // The view that contains the tabstrip, new tab button, and grab handle space. - raw_ptr<TabStripRegionView, DanglingUntriaged> tab_strip_region_view_ = + raw_ptr<TabStripRegionView, DanglingAcrossTasks> tab_strip_region_view_ = nullptr; // The TabStrip. - raw_ptr<TabStrip, DanglingUntriaged> tabstrip_ = nullptr; + raw_ptr<TabStrip, DanglingAcrossTasks> tabstrip_ = nullptr; // the webui based tabstrip, when applicable. see https://crbug.com/989131. raw_ptr<WebUITabStripContainerView, DanglingUntriaged> webui_tab_strip_ = @@ -1024,7 +1024,7 @@ std::unique_ptr<AccessibilityModeObserver> accessibility_mode_observer_; // The Toolbar containing the navigation buttons, menus and the address bar. - raw_ptr<ToolbarView, DanglingUntriaged> toolbar_ = nullptr; + raw_ptr<ToolbarView, DanglingAcrossTasks> toolbar_ = nullptr; // The OverlayView for the widget, which is used to host `top_container_` // during immersive reveal. @@ -1059,7 +1059,7 @@ std::unique_ptr<BookmarkBarView> bookmark_bar_view_; // Separator between top container and contents. - raw_ptr<views::View, DanglingUntriaged> contents_separator_ = nullptr; + raw_ptr<views::View, DanglingAcrossTasks> contents_separator_ = nullptr; // Loading bar (part of top container for / WebUI tab strip). raw_ptr<TopContainerLoadingBar, DanglingUntriaged> loading_bar_ = nullptr; @@ -1067,37 +1067,38 @@ // The do-nothing view which controls the z-order of the find bar widget // relative to views which paint into layers and views with an associated // NativeView. - raw_ptr<View, DanglingUntriaged> find_bar_host_view_ = nullptr; + raw_ptr<View, DanglingAcrossTasks> find_bar_host_view_ = nullptr; // The download shelf. raw_ptr<DownloadShelf, DanglingUntriaged> download_shelf_ = nullptr; // The InfoBarContainerView that contains InfoBars for the current tab. - raw_ptr<InfoBarContainerView, DanglingUntriaged> infobar_container_ = nullptr; + raw_ptr<InfoBarContainerView, DanglingAcrossTasks> infobar_container_ = + nullptr; // The view that contains the selected WebContents. - raw_ptr<ContentsWebView, DanglingUntriaged> contents_web_view_ = nullptr; + raw_ptr<ContentsWebView, DanglingAcrossTasks> contents_web_view_ = nullptr; // The view that contains devtools window for the selected WebContents. - raw_ptr<views::WebView, DanglingUntriaged> devtools_web_view_ = nullptr; + raw_ptr<views::WebView, DanglingAcrossTasks> devtools_web_view_ = nullptr; // The view managing the devtools and contents positions. // Handled by ContentsLayoutManager. - raw_ptr<views::View, DanglingUntriaged> contents_container_ = nullptr; + raw_ptr<views::View, DanglingAcrossTasks> contents_container_ = nullptr; // The side panel aligned to the left or the right side of the browser window // depending on the kSidePanelHorizontalAlignment pref's value. - raw_ptr<SidePanel, DanglingUntriaged> unified_side_panel_ = nullptr; - raw_ptr<views::View, DanglingUntriaged> right_aligned_side_panel_separator_ = - nullptr; + raw_ptr<SidePanel, DanglingAcrossTasks> unified_side_panel_ = nullptr; + raw_ptr<views::View, DanglingAcrossTasks> + right_aligned_side_panel_separator_ = nullptr; // The side search side panel. - raw_ptr<views::View, DanglingUntriaged> left_aligned_side_panel_separator_ = + raw_ptr<views::View, DanglingAcrossTasks> left_aligned_side_panel_separator_ = nullptr; // Provides access to the toolbar buttons this browser view uses. Buttons may // appear in a hosted app frame or in a tabbed UI toolbar. - raw_ptr<ToolbarButtonProvider, DanglingUntriaged> toolbar_button_provider_ = + raw_ptr<ToolbarButtonProvider, DanglingAcrossTasks> toolbar_button_provider_ = nullptr; // The handler responsible for showing autofill bubbles.
diff --git a/chrome/browser/ui/views/frame/browser_view_layout.h b/chrome/browser/ui/views/frame/browser_view_layout.h index fc57462c..5d3dec20 100644 --- a/chrome/browser/ui/views/frame/browser_view_layout.h +++ b/chrome/browser/ui/views/frame/browser_view_layout.h
@@ -175,27 +175,27 @@ // Child views that the layout manager manages. // NOTE: If you add a view, try to add it as a views::View, which makes // testing much easier. - const raw_ptr<views::View, DanglingUntriaged> top_container_; + const raw_ptr<views::View, DanglingAcrossTasks> top_container_; const raw_ptr<WebAppFrameToolbarView, DanglingUntriaged> web_app_frame_toolbar_; const raw_ptr<views::Label, DanglingUntriaged> web_app_window_title_; - const raw_ptr<TabStripRegionView, DanglingUntriaged> tab_strip_region_view_; - const raw_ptr<views::View, DanglingUntriaged> toolbar_; - const raw_ptr<InfoBarContainerView, DanglingUntriaged> infobar_container_; - const raw_ptr<views::View, DanglingUntriaged> contents_container_; - const raw_ptr<views::View, DanglingUntriaged> + const raw_ptr<TabStripRegionView, DanglingAcrossTasks> tab_strip_region_view_; + const raw_ptr<views::View, DanglingAcrossTasks> toolbar_; + const raw_ptr<InfoBarContainerView, DanglingAcrossTasks> infobar_container_; + const raw_ptr<views::View, DanglingAcrossTasks> contents_container_; + const raw_ptr<views::View, DanglingAcrossTasks> left_aligned_side_panel_separator_; - const raw_ptr<views::View, DanglingUntriaged> unified_side_panel_; - const raw_ptr<views::View, DanglingUntriaged> + const raw_ptr<views::View, DanglingAcrossTasks> unified_side_panel_; + const raw_ptr<views::View, DanglingAcrossTasks> right_aligned_side_panel_separator_; - const raw_ptr<ImmersiveModeController, DanglingUntriaged> + const raw_ptr<ImmersiveModeController, DanglingAcrossTasks> immersive_mode_controller_; - const raw_ptr<views::View, DanglingUntriaged> contents_separator_; + const raw_ptr<views::View, DanglingAcrossTasks> contents_separator_; raw_ptr<views::View, DanglingUntriaged> webui_tab_strip_ = nullptr; raw_ptr<views::View, DanglingUntriaged> loading_bar_ = nullptr; - raw_ptr<TabStrip, DanglingUntriaged> tab_strip_ = nullptr; - raw_ptr<BookmarkBarView, DanglingUntriaged> bookmark_bar_ = nullptr; + raw_ptr<TabStrip, DanglingAcrossTasks> tab_strip_ = nullptr; + raw_ptr<BookmarkBarView, DanglingAcrossTasks> bookmark_bar_ = nullptr; raw_ptr<views::View, DanglingUntriaged> download_shelf_ = nullptr; // The widget displaying a border on top of contents container for
diff --git a/chrome/browser/ui/views/frame/desktop_browser_frame_aura.h b/chrome/browser/ui/views/frame/desktop_browser_frame_aura.h index 0951fef..0e93907 100644 --- a/chrome/browser/ui/views/frame/desktop_browser_frame_aura.h +++ b/chrome/browser/ui/views/frame/desktop_browser_frame_aura.h
@@ -66,7 +66,7 @@ raw_ptr<BrowserFrame> browser_frame_; // Owned by the RootWindow. - raw_ptr<BrowserDesktopWindowTreeHost, DanglingUntriaged> + raw_ptr<BrowserDesktopWindowTreeHost, DanglingAcrossTasks> browser_desktop_window_tree_host_; std::unique_ptr<wm::VisibilityController> visibility_controller_;
diff --git a/chrome/browser/ui/views/frame/tab_strip_region_view.h b/chrome/browser/ui/views/frame/tab_strip_region_view.h index 0c6a448..8bbedfac 100644 --- a/chrome/browser/ui/views/frame/tab_strip_region_view.h +++ b/chrome/browser/ui/views/frame/tab_strip_region_view.h
@@ -85,9 +85,9 @@ void UpdateNewTabButtonBorder(); raw_ptr<views::FlexLayout, DanglingUntriaged> layout_manager_ = nullptr; - raw_ptr<views::View, DanglingUntriaged> tab_strip_container_ = nullptr; + raw_ptr<views::View, DanglingAcrossTasks> tab_strip_container_ = nullptr; raw_ptr<views::View, DanglingUntriaged> reserved_grab_handle_space_ = nullptr; - raw_ptr<TabStrip, DanglingUntriaged> tab_strip_ = nullptr; + raw_ptr<TabStrip, DanglingAcrossTasks> tab_strip_ = nullptr; raw_ptr<TabStripScrollContainer, DanglingUntriaged> tab_strip_scroll_container_ = nullptr; raw_ptr<NewTabButton, DanglingUntriaged> new_tab_button_ = nullptr;
diff --git a/chrome/browser/ui/views/frame/web_contents_close_handler.h b/chrome/browser/ui/views/frame/web_contents_close_handler.h index 1077eb2..1e160262e 100644 --- a/chrome/browser/ui/views/frame/web_contents_close_handler.h +++ b/chrome/browser/ui/views/frame/web_contents_close_handler.h
@@ -43,7 +43,7 @@ // close was canceled. void OnStillHaventClosed(); - raw_ptr<WebContentsCloseHandlerDelegate, DanglingUntriaged> delegate_; + raw_ptr<WebContentsCloseHandlerDelegate, DanglingAcrossTasks> delegate_; // If true, WillCloseAllTabs() has been invoked. bool in_close_;
diff --git a/chrome/browser/ui/views/passwords/password_bubble_interactive_uitest.cc b/chrome/browser/ui/views/passwords/password_bubble_interactive_uitest.cc index 69968f3a..70d77e4 100644 --- a/chrome/browser/ui/views/passwords/password_bubble_interactive_uitest.cc +++ b/chrome/browser/ui/views/passwords/password_bubble_interactive_uitest.cc
@@ -393,9 +393,7 @@ EXPECT_TRUE(IsBubbleShowing()); // Close the tab. - int previous_tab_count = tab_model->count(); - tab_model->CloseWebContentsAt(0, 0); - ASSERT_EQ(previous_tab_count - 1, tab_model->count()); + ASSERT_TRUE(tab_model->CloseWebContentsAt(0, 0)); EXPECT_FALSE(IsBubbleShowing()); // The bubble is now hidden, but not destroyed. However, the WebContents _is_
diff --git a/chrome/browser/ui/views/performance_controls/battery_saver_button_browsertest.cc b/chrome/browser/ui/views/performance_controls/battery_saver_button_browsertest.cc index f992c6c..e3b75593 100644 --- a/chrome/browser/ui/views/performance_controls/battery_saver_button_browsertest.cc +++ b/chrome/browser/ui/views/performance_controls/battery_saver_button_browsertest.cc
@@ -96,9 +96,9 @@ } private: - raw_ptr<base::test::TestSamplingEventSource, DanglingUntriaged> + raw_ptr<base::test::TestSamplingEventSource, DanglingAcrossTasks> sampling_source_; - raw_ptr<base::test::TestBatteryLevelProvider, DanglingUntriaged> + raw_ptr<base::test::TestBatteryLevelProvider, DanglingAcrossTasks> battery_level_provider_; // Only used on platforms without a battery level provider implementation. std::unique_ptr<base::BatteryStateSampler> battery_state_sampler_;
diff --git a/chrome/browser/ui/views/sharing/sharing_icon_view.h b/chrome/browser/ui/views/sharing/sharing_icon_view.h index f3d2b1b..dc971b6 100644 --- a/chrome/browser/ui/views/sharing/sharing_icon_view.h +++ b/chrome/browser/ui/views/sharing/sharing_icon_view.h
@@ -58,7 +58,7 @@ void UpdateOpacity(); private: - raw_ptr<SharingUiController, DanglingUntriaged> last_controller_ = nullptr; + raw_ptr<SharingUiController, DanglingAcrossTasks> last_controller_ = nullptr; bool loading_animation_ = false; bool should_show_error_ = false; GetControllerCallback get_controller_callback_;
diff --git a/chrome/browser/ui/views/status_bubble_views.h b/chrome/browser/ui/views/status_bubble_views.h index f17d92c..ecbb078 100644 --- a/chrome/browser/ui/views/status_bubble_views.h +++ b/chrome/browser/ui/views/status_bubble_views.h
@@ -153,7 +153,7 @@ // going outside the bounds of the hosting widget. std::unique_ptr<views::Widget> popup_; - raw_ptr<views::View, DanglingUntriaged> base_view_; + raw_ptr<views::View, DanglingAcrossTasks> base_view_; raw_ptr<StatusView, DanglingUntriaged> view_ = nullptr; // Manages the expansion of a status bubble to fit a long URL.
diff --git a/chrome/browser/ui/views/tabs/new_tab_button.h b/chrome/browser/ui/views/tabs/new_tab_button.h index 6f882fa3..6f307b2 100644 --- a/chrome/browser/ui/views/tabs/new_tab_button.h +++ b/chrome/browser/ui/views/tabs/new_tab_button.h
@@ -91,7 +91,7 @@ void PaintFill(gfx::Canvas* canvas) const; // Tab strip that contains this button. - raw_ptr<TabStrip, DanglingUntriaged> tab_strip_; + raw_ptr<TabStrip, DanglingAcrossTasks> tab_strip_; // Contains our ink drop layer so it can paint above our background. raw_ptr<views::InkDropContainerView, DanglingUntriaged> ink_drop_container_;
diff --git a/chrome/browser/ui/views/tabs/tab.cc b/chrome/browser/ui/views/tabs/tab.cc index f79595d..5597e4c2a 100644 --- a/chrome/browser/ui/views/tabs/tab.cc +++ b/chrome/browser/ui/views/tabs/tab.cc
@@ -137,7 +137,7 @@ } private: - const raw_ptr<TabStyleViews, DanglingUntriaged> tab_style_views_; + const raw_ptr<TabStyleViews, DanglingAcrossTasks> tab_style_views_; }; } // namespace
diff --git a/chrome/browser/ui/views/tabs/tab_container_impl.h b/chrome/browser/ui/views/tabs/tab_container_impl.h index c9d42fd2..3a7c264d 100644 --- a/chrome/browser/ui/views/tabs/tab_container_impl.h +++ b/chrome/browser/ui/views/tabs/tab_container_impl.h
@@ -336,7 +336,7 @@ const raw_ref<TabContainerController, DanglingUntriaged> controller_; - const raw_ptr<TabHoverCardController, DanglingUntriaged> + const raw_ptr<TabHoverCardController, DanglingAcrossTasks> hover_card_controller_; // May be nullptr in tests. @@ -351,7 +351,7 @@ // This view is animated by `bounds_animator_` to guarantee that this // container's bounds change smoothly when tabs are animated into or out of // this container. - const raw_ref<views::View, DanglingUntriaged> overall_bounds_view_; + const raw_ref<views::View, DanglingAcrossTasks> overall_bounds_view_; // Responsible for animating tabs in response to model changes. views::BoundsAnimator bounds_animator_;
diff --git a/chrome/browser/ui/views/tabs/tab_slot_animation_delegate.h b/chrome/browser/ui/views/tabs/tab_slot_animation_delegate.h index 32a1743..52fb4201 100644 --- a/chrome/browser/ui/views/tabs/tab_slot_animation_delegate.h +++ b/chrome/browser/ui/views/tabs/tab_slot_animation_delegate.h
@@ -28,7 +28,7 @@ private: const raw_ptr<TabContainer, DanglingUntriaged> tab_container_; - const raw_ptr<TabSlotView, DanglingUntriaged> slot_view_; + const raw_ptr<TabSlotView, DanglingAcrossTasks> slot_view_; }; #endif // CHROME_BROWSER_UI_VIEWS_TABS_TAB_SLOT_ANIMATION_DELEGATE_H_
diff --git a/chrome/browser/ui/views/tabs/tab_strip.h b/chrome/browser/ui/views/tabs/tab_strip.h index 9fb8e73..0c3e8f9 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.h +++ b/chrome/browser/ui/views/tabs/tab_strip.h
@@ -421,10 +421,10 @@ std::unique_ptr<TabHoverCardController> hover_card_controller_; - raw_ref<TabDragContextImpl, DanglingUntriaged> drag_context_; + raw_ref<TabDragContextImpl, DanglingAcrossTasks> drag_context_; // The View parent for the tabs and the various group views. - raw_ref<TabContainer, DanglingUntriaged> tab_container_; + raw_ref<TabContainer, DanglingAcrossTasks> tab_container_; // The background offset used by inactive tabs to match the frame image. int background_offset_ = 0;
diff --git a/chrome/browser/ui/views/toolbar/chrome_labs_button.h b/chrome/browser/ui/views/toolbar/chrome_labs_button.h index 3f7fb47..b63dac06 100644 --- a/chrome/browser/ui/views/toolbar/chrome_labs_button.h +++ b/chrome/browser/ui/views/toolbar/chrome_labs_button.h
@@ -44,7 +44,7 @@ raw_ptr<BrowserView, DanglingUntriaged> browser_view_; - raw_ptr<const ChromeLabsModel, DanglingUntriaged> model_; + raw_ptr<const ChromeLabsModel, DanglingAcrossTasks> model_; raw_ptr<views::DotIndicator> new_experiments_indicator_;
diff --git a/chrome/browser/ui/views/toolbar/chrome_labs_coordinator.h b/chrome/browser/ui/views/toolbar/chrome_labs_coordinator.h index c5f1fa1..acbb6cd2 100644 --- a/chrome/browser/ui/views/toolbar/chrome_labs_coordinator.h +++ b/chrome/browser/ui/views/toolbar/chrome_labs_coordinator.h
@@ -64,7 +64,7 @@ raw_ptr<ChromeLabsButton, DanglingUntriaged> anchor_view_; raw_ptr<Browser, DanglingUntriaged> browser_; - raw_ptr<const ChromeLabsModel, DanglingUntriaged> chrome_labs_model_; + raw_ptr<const ChromeLabsModel, DanglingAcrossTasks> chrome_labs_model_; raw_ptr<ChromeLabsBubbleView, DanglingUntriaged> chrome_labs_bubble_view_ = nullptr;
diff --git a/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.h b/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.h index 449704d..0ab6a0f 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.h +++ b/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.h
@@ -112,7 +112,7 @@ // The main view is nominally always present and is last child in the view // hierarchy. - raw_ptr<views::View, DanglingUntriaged> main_item_ = nullptr; + raw_ptr<views::View, DanglingAcrossTasks> main_item_ = nullptr; // Override for the icon color. If not set, |kColorToolbarButtonIcon| is used. absl::optional<SkColor> icon_color_;
diff --git a/chrome/browser/ui/web_applications/web_app_ui_manager_impl.h b/chrome/browser/ui/web_applications/web_app_ui_manager_impl.h index e3bffef..907bbf7 100644 --- a/chrome/browser/ui/web_applications/web_app_ui_manager_impl.h +++ b/chrome/browser/ui/web_applications/web_app_ui_manager_impl.h
@@ -108,7 +108,7 @@ const raw_ptr<Profile> profile_; raw_ptr<WebAppSyncBridge> sync_bridge_ = nullptr; - raw_ptr<OsIntegrationManager, DanglingUntriaged> os_integration_manager_ = + raw_ptr<OsIntegrationManager, DanglingAcrossTasks> os_integration_manager_ = nullptr; std::map<AppId, std::vector<base::OnceClosure>> windows_closed_requests_map_;
diff --git a/chrome/browser/ui/webui/ash/login/gaia_screen_handler.cc b/chrome/browser/ui/webui/ash/login/gaia_screen_handler.cc index f3cb2a35..b65076f6 100644 --- a/chrome/browser/ui/webui/ash/login/gaia_screen_handler.cc +++ b/chrome/browser/ui/webui/ash/login/gaia_screen_handler.cc
@@ -63,7 +63,6 @@ #include "chrome/browser/certificate_provider/certificate_provider_service_factory.h" #include "chrome/browser/certificate_provider/pin_dialog_manager.h" #include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/enterprise/util/managed_browser_utils.h" #include "chrome/browser/lifetime/browser_shutdown.h" #include "chrome/browser/net/nss_temp_certs_cache_chromeos.h" #include "chrome/browser/net/system_network_context_manager.h" @@ -648,7 +647,6 @@ AddCallback("samlChallengeMachineKey", &GaiaScreenHandler::HandleSamlChallengeMachineKey); AddCallback("loginWebuiReady", &GaiaScreenHandler::HandleGaiaUIReady); - AddCallback("identifierEntered", &GaiaScreenHandler::HandleIdentifierEntered); AddCallback("authExtensionLoaded", &GaiaScreenHandler::HandleAuthExtensionLoaded); AddCallback("setIsFirstSigninStep", @@ -663,14 +661,6 @@ &GaiaScreenHandler::HandleShowLoadingTimeoutError); } -void GaiaScreenHandler::HandleIdentifierEntered(const std::string& user_email) { - if (MaybeTriggerEnrollmentNudge(user_email)) { - return; - } - - CheckIfAllowlisted(user_email); -} - void GaiaScreenHandler::HandleAuthExtensionLoaded() { VLOG(1) << "Auth extension finished loading"; // Recreate the client cert usage observer, in order to track only the certs @@ -1341,6 +1331,10 @@ gaia_reauth_request_token_ = reauth_request_token; } +void GaiaScreenHandler::ShowEnrollmentNudge(const std::string& email_domain) { + CallExternalAPI("showEnrollmentNudge", email_domain); +} + void GaiaScreenHandler::LoadAuthExtension(bool force) { VLOG(1) << "LoadAuthExtension, force: " << force; if (!initialized_) { @@ -1592,42 +1586,6 @@ std::move(scraped_saml_passwords), std::move(user_context)); } -bool GaiaScreenHandler::MaybeTriggerEnrollmentNudge( - const std::string& user_email) { - const bool is_enterprise_managed = g_browser_process->platform_part() - ->browser_policy_connector_ash() - ->IsDeviceEnterpriseManaged(); - if (is_enterprise_managed) { - // Device either already went through enterprise enrollment flow or goes - // through it right now. No need for nudging. - return false; - } - const bool is_first_user = - user_manager::UserManager::Get()->GetUsers().empty(); - if (!is_first_user) { - // Enrollment nudge targets only initial OOBE flow on unowned devices. - // Current user is not a first user which means that device is already - // owned. - return false; - } - const std::string email_domain = - chrome::enterprise_util::GetDomainFromEmail(user_email); - if (chrome::enterprise_util::IsKnownConsumerDomain(email_domain)) { - // User doesn't belong to a managed domain, so enrollment nudging can't - // apply. - return false; - } - - // TODO(b/271104781): replace this check with a policy fetch through a special - // DM server API when it is available. - if (!ash::features::IsEnrollmentNudgingForTestingEnabled()) { - return false; - } - - CallExternalAPI("showEnrollmentNudge", email_domain); - return true; -} - void GaiaScreenHandler::CheckIfAllowlisted(const std::string& user_email) { // We cannot tell a user type from the identifier, so we delay checking if // the account should be allowed.
diff --git a/chrome/browser/ui/webui/ash/login/gaia_screen_handler.h b/chrome/browser/ui/webui/ash/login/gaia_screen_handler.h index c17f578..b5b44433 100644 --- a/chrome/browser/ui/webui/ash/login/gaia_screen_handler.h +++ b/chrome/browser/ui/webui/ash/login/gaia_screen_handler.h
@@ -93,6 +93,10 @@ // for recovery. virtual void SetReauthRequestToken( const std::string& reauth_request_token) = 0; + // Shows pop-up saying that enrollment is required for user's managed domain. + virtual void ShowEnrollmentNudge(const std::string& email_domain) = 0; + // Checks if user's email is allowlisted. + virtual void CheckIfAllowlisted(const std::string& user_email) = 0; // Show sign-in screen for the given credentials. `services` is a list of // services returned by userInfo call as JSON array. Should be an empty array @@ -148,6 +152,8 @@ void ShowAllowlistCheckFailedError() override; void ReloadGaiaAuthenticator() override; void SetReauthRequestToken(const std::string& reauth_request_token) override; + void ShowEnrollmentNudge(const std::string& email_domain) override; + void CheckIfAllowlisted(const std::string& user_email) override; void ShowSigninScreenForTest(const std::string& username, const std::string& password, @@ -244,8 +250,6 @@ void HandleGaiaUIReady(); - void HandleIdentifierEntered(const std::string& account_identifier); - void HandleAuthExtensionLoaded(); // Allows WebUI to control the login shelf's guest and apps buttons visibility @@ -347,9 +351,6 @@ void SAMLConfirmPassword(::login::StringList scraped_saml_passwords, std::unique_ptr<UserContext> user_context); - bool MaybeTriggerEnrollmentNudge(const std::string& user_email); - void CheckIfAllowlisted(const std::string& user_email); - // Current state of Gaia frame. FrameState frame_state_ = FRAME_STATE_UNKNOWN;
diff --git a/chrome/browser/web_applications/externally_managed_app_manager.h b/chrome/browser/web_applications/externally_managed_app_manager.h index df2e6dfd..f1b5ed7 100644 --- a/chrome/browser/web_applications/externally_managed_app_manager.h +++ b/chrome/browser/web_applications/externally_managed_app_manager.h
@@ -256,9 +256,9 @@ base::OnceClosure registrations_complete_callback_; - raw_ptr<WebAppUiManager, DanglingUntriaged> ui_manager_ = nullptr; - raw_ptr<WebAppInstallFinalizer, DanglingUntriaged> finalizer_ = nullptr; - raw_ptr<WebAppCommandScheduler, DanglingUntriaged> command_scheduler_ = + raw_ptr<WebAppUiManager, DanglingAcrossTasks> ui_manager_ = nullptr; + raw_ptr<WebAppInstallFinalizer, DanglingAcrossTasks> finalizer_ = nullptr; + raw_ptr<WebAppCommandScheduler, DanglingAcrossTasks> command_scheduler_ = nullptr; const raw_ptr<Profile> profile_;
diff --git a/chrome/browser/web_applications/manifest_update_manager.h b/chrome/browser/web_applications/manifest_update_manager.h index 81bd89f7d..007c56f 100644 --- a/chrome/browser/web_applications/manifest_update_manager.h +++ b/chrome/browser/web_applications/manifest_update_manager.h
@@ -191,13 +191,13 @@ static bool& BypassWindowCloseWaitingForTesting(); raw_ptr<WebAppRegistrar, DanglingUntriaged> registrar_ = nullptr; - raw_ptr<WebAppUiManager, DanglingUntriaged> ui_manager_ = nullptr; + raw_ptr<WebAppUiManager, DanglingAcrossTasks> ui_manager_ = nullptr; #if BUILDFLAG(IS_CHROMEOS_ASH) raw_ptr<const ash::SystemWebAppDelegateMap, DanglingUntriaged> system_web_apps_delegate_map_ = nullptr; #endif - raw_ptr<WebAppInstallManager, DanglingUntriaged> install_manager_ = nullptr; - raw_ptr<WebAppCommandScheduler, DanglingUntriaged> command_scheduler_ = + raw_ptr<WebAppInstallManager, DanglingAcrossTasks> install_manager_ = nullptr; + raw_ptr<WebAppCommandScheduler, DanglingAcrossTasks> command_scheduler_ = nullptr; base::ScopedObservation<WebAppInstallManager, WebAppInstallManagerObserver>
diff --git a/chrome/browser/web_applications/os_integration/web_app_shortcut_manager.h b/chrome/browser/web_applications/os_integration/web_app_shortcut_manager.h index 0077ca2..952087f8 100644 --- a/chrome/browser/web_applications/os_integration/web_app_shortcut_manager.h +++ b/chrome/browser/web_applications/os_integration/web_app_shortcut_manager.h
@@ -173,11 +173,11 @@ const raw_ptr<Profile> profile_; - raw_ptr<WebAppRegistrar, DanglingUntriaged> registrar_ = nullptr; - raw_ptr<WebAppIconManager, DanglingUntriaged> icon_manager_ = nullptr; - raw_ptr<WebAppFileHandlerManager, DanglingUntriaged> file_handler_manager_ = + raw_ptr<WebAppRegistrar, DanglingAcrossTasks> registrar_ = nullptr; + raw_ptr<WebAppIconManager, DanglingAcrossTasks> icon_manager_ = nullptr; + raw_ptr<WebAppFileHandlerManager, DanglingAcrossTasks> file_handler_manager_ = nullptr; - raw_ptr<WebAppProtocolHandlerManager, DanglingUntriaged> + raw_ptr<WebAppProtocolHandlerManager, DanglingAcrossTasks> protocol_handler_manager_ = nullptr; base::WeakPtrFactory<WebAppShortcutManager> weak_ptr_factory_{this};
diff --git a/chrome/browser/web_applications/policy/web_app_policy_manager.h b/chrome/browser/web_applications/policy/web_app_policy_manager.h index 89c7e7e..f070d1fb 100644 --- a/chrome/browser/web_applications/policy/web_app_policy_manager.h +++ b/chrome/browser/web_applications/policy/web_app_policy_manager.h
@@ -189,7 +189,7 @@ raw_ptr<const ash::SystemWebAppDelegateMap, DanglingUntriaged> system_web_apps_delegate_map_ = nullptr; #endif - raw_ptr<OsIntegrationManager, DanglingUntriaged> os_integration_manager_ = + raw_ptr<OsIntegrationManager, DanglingAcrossTasks> os_integration_manager_ = nullptr; PrefChangeRegistrar pref_change_registrar_; PrefChangeRegistrar local_state_pref_change_registrar_;
diff --git a/chrome/browser/web_applications/preinstalled_web_app_manager.h b/chrome/browser/web_applications/preinstalled_web_app_manager.h index 7d15e92..1894cf8 100644 --- a/chrome/browser/web_applications/preinstalled_web_app_manager.h +++ b/chrome/browser/web_applications/preinstalled_web_app_manager.h
@@ -175,8 +175,8 @@ int force_reinstall_for_milestone); raw_ptr<WebAppRegistrar, DanglingUntriaged> registrar_ = nullptr; - raw_ptr<const WebAppUiManager, DanglingUntriaged> ui_manager_ = nullptr; - raw_ptr<ExternallyManagedAppManager, DanglingUntriaged> + raw_ptr<const WebAppUiManager, DanglingAcrossTasks> ui_manager_ = nullptr; + raw_ptr<ExternallyManagedAppManager, DanglingAcrossTasks> externally_managed_app_manager_ = nullptr; const raw_ptr<Profile> profile_;
diff --git a/chrome/browser/web_applications/web_app_icon_manager.h b/chrome/browser/web_applications/web_app_icon_manager.h index 82f3062..b0a4dae 100644 --- a/chrome/browser/web_applications/web_app_icon_manager.h +++ b/chrome/browser/web_applications/web_app_icon_manager.h
@@ -242,7 +242,7 @@ gfx::ImageSkia converted_image); raw_ptr<WebAppRegistrar, DanglingUntriaged> registrar_; - raw_ptr<WebAppInstallManager, DanglingUntriaged> install_manager_; + raw_ptr<WebAppInstallManager, DanglingAcrossTasks> install_manager_; base::FilePath web_apps_directory_; scoped_refptr<FileUtilsWrapper> utils_; scoped_refptr<base::SequencedTaskRunner> icon_task_runner_;
diff --git a/chrome/browser/web_applications/web_app_install_finalizer.h b/chrome/browser/web_applications/web_app_install_finalizer.h index b6b0265..c42aa32 100644 --- a/chrome/browser/web_applications/web_app_install_finalizer.h +++ b/chrome/browser/web_applications/web_app_install_finalizer.h
@@ -243,18 +243,18 @@ const AppId& app_id, const WebAppInstallInfo& new_web_app_info); - raw_ptr<WebAppInstallManager, DanglingUntriaged> install_manager_ = nullptr; + raw_ptr<WebAppInstallManager, DanglingAcrossTasks> install_manager_ = nullptr; raw_ptr<WebAppRegistrar, DanglingUntriaged> registrar_ = nullptr; raw_ptr<WebAppSyncBridge, DanglingUntriaged> sync_bridge_ = nullptr; - raw_ptr<WebAppUiManager, DanglingUntriaged> ui_manager_ = nullptr; - raw_ptr<OsIntegrationManager, DanglingUntriaged> os_integration_manager_ = + raw_ptr<WebAppUiManager, DanglingAcrossTasks> ui_manager_ = nullptr; + raw_ptr<OsIntegrationManager, DanglingAcrossTasks> os_integration_manager_ = nullptr; raw_ptr<WebAppIconManager, DanglingUntriaged> icon_manager_ = nullptr; - raw_ptr<WebAppPolicyManager, DanglingUntriaged> policy_manager_ = nullptr; + raw_ptr<WebAppPolicyManager, DanglingAcrossTasks> policy_manager_ = nullptr; raw_ptr<WebAppTranslationManager, DanglingUntriaged> translation_manager_ = nullptr; - raw_ptr<WebAppCommandManager, DanglingUntriaged> command_manager_ = nullptr; - raw_ptr<WebAppOriginAssociationManager, DanglingUntriaged> + raw_ptr<WebAppCommandManager, DanglingAcrossTasks> command_manager_ = nullptr; + raw_ptr<WebAppOriginAssociationManager, DanglingAcrossTasks> origin_association_manager_ = nullptr; const raw_ptr<Profile> profile_;
diff --git a/chrome/browser/web_applications/web_app_registrar.h b/chrome/browser/web_applications/web_app_registrar.h index 6eefa2dc..68260f96 100644 --- a/chrome/browser/web_applications/web_app_registrar.h +++ b/chrome/browser/web_applications/web_app_registrar.h
@@ -530,8 +530,8 @@ private: const raw_ptr<Profile> profile_; - raw_ptr<WebAppPolicyManager, DanglingUntriaged> policy_manager_ = nullptr; - raw_ptr<WebAppTranslationManager, DanglingUntriaged> translation_manager_ = + raw_ptr<WebAppPolicyManager, DanglingAcrossTasks> policy_manager_ = nullptr; + raw_ptr<WebAppTranslationManager, DanglingAcrossTasks> translation_manager_ = nullptr; base::ScopedObservation<ProfileManager, ProfileManagerObserver>
diff --git a/chrome/browser/web_applications/web_app_sync_bridge.h b/chrome/browser/web_applications/web_app_sync_bridge.h index a0254af..a20507b4 100644 --- a/chrome/browser/web_applications/web_app_sync_bridge.h +++ b/chrome/browser/web_applications/web_app_sync_bridge.h
@@ -226,9 +226,9 @@ std::unique_ptr<WebAppDatabase> database_; const raw_ptr<WebAppRegistrarMutable, DanglingUntriaged> registrar_; - raw_ptr<WebAppCommandManager, DanglingUntriaged> command_manager_; - raw_ptr<WebAppCommandScheduler, DanglingUntriaged> command_scheduler_; - raw_ptr<WebAppInstallManager, DanglingUntriaged> install_manager_; + raw_ptr<WebAppCommandManager, DanglingAcrossTasks> command_manager_; + raw_ptr<WebAppCommandScheduler, DanglingAcrossTasks> command_scheduler_; + raw_ptr<WebAppInstallManager, DanglingAcrossTasks> install_manager_; base::OneShotEvent on_sync_connected_;
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 00becf1b..5e145f2 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1687823988-498cc1bd24cdee556cb70ef87f293b9522f58636.profdata +chrome-linux-main-1687845407-147206efc0c24cfd192464c1153ed8fb2274f49c.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index fc0e495..306d222 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1687845407-2fbcc5ef33335cd7837d337c67c9fc2d0b193290.profdata +chrome-mac-arm-main-1687867043-1061de77ad0901c9b8489b0558746297cfee7a11.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index d4260c171..0d665904 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1687823988-db3f2f35c91f5b9069e9bb9675db7de036054dab.profdata +chrome-mac-main-1687845407-30c24b7eac8a3387d6b3dad7fddc47be77c7a0f7.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index fbf6aad..0103529 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1687834535-9aeb1b5b573fb2ab28ce7731127ad97f3bafb8fc.profdata +chrome-win32-main-1687856322-4e9150603b0604097161cba9f7f63a291794d0f7.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 9ef37c9d2..50e3220 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1687834535-9620309ba0c3ba9bb66781c55cda238b6ecaa330.profdata +chrome-win64-main-1687856322-302c353499e17bd67d3171f0e1ba147f239253f2.profdata
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index cabc94a4..c2c4314 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2368,7 +2368,6 @@ "../browser/ui/tab_modal_confirm_dialog_browsertest.h", "../browser/ui/tab_ui_helper_browsertest.cc", "../browser/ui/tabs/pinned_tab_service_browsertest.cc", - "../browser/ui/tabs/tab_strip_model_browsertest.cc", "../browser/ui/test/browser_ui_browsertest.cc", "../browser/ui/test/popup_browsertest.cc", "../browser/ui/test/popup_fullscreen_browsertest.cc", @@ -5676,6 +5675,7 @@ "../browser/component_updater/chrome_component_updater_configurator_unittest.cc", "../browser/component_updater/crl_set_component_installer_unittest.cc", "../browser/component_updater/first_party_sets_component_installer_unittest.cc", + "../browser/component_updater/masked_domain_list_component_installer_unittest.cc", "../browser/component_updater/origin_trials_component_installer_unittest.cc", "../browser/component_updater/pki_metadata_component_installer_unittest.cc", "../browser/component_updater/privacy_sandbox_attestations_component_installer_unittest.cc", @@ -5769,6 +5769,7 @@ # as presentation_service_delegate_impl.* files. "../browser/media/router/presentation/presentation_service_delegate_impl_unittest.cc", "../browser/media/webrtc/capture_policy_utils_unittest.cc", + "../browser/media/webrtc/media_device_salt_service_factory_unittest.cc", "../browser/media/webrtc/media_stream_device_permission_context_unittest.cc", "../browser/metrics/chrome_browser_main_extra_parts_metrics_unittest.cc", "../browser/metrics/chrome_metrics_extensions_helper_unittest.cc", @@ -6330,6 +6331,7 @@ "//components/live_caption:constants", "//components/lookalikes/core", "//components/lookalikes/core:safety_tips", + "//components/media_device_salt", "//components/media_router/common/providers/cast/channel", "//components/media_router/common/providers/cast/channel:test_support", "//components/memory_pressure:test_support",
diff --git a/chrome/test/base/in_process_browser_test.h b/chrome/test/base/in_process_browser_test.h index 22550828..8534e586 100644 --- a/chrome/test/base/in_process_browser_test.h +++ b/chrome/test/base/in_process_browser_test.h
@@ -387,7 +387,7 @@ // If no browser is created in BrowserMain(), then |browser_| will remain // nullptr unless SelectFirstBrowser() is called after the creation of the // first browser instance at a later time. - raw_ptr<Browser, DanglingUntriaged> browser_ = nullptr; + raw_ptr<Browser, DanglingAcrossTasks> browser_ = nullptr; // Used to run the process until the BrowserProcess signals the test to quit. std::unique_ptr<base::RunLoop> run_loop_;
diff --git a/chrome/test/chromedriver/capabilities.cc b/chrome/test/chromedriver/capabilities.cc index a29dc8e..0b2d485 100644 --- a/chrome/test/chromedriver/capabilities.cc +++ b/chrome/test/chromedriver/capabilities.cc
@@ -198,13 +198,10 @@ absl::optional<bool> mobile = metrics->FindBool("mobile"); if (metrics->Find("mobile") && !mobile.has_value()) return Status(kInvalidArgument, "'mobile' must be a boolean"); - // We don't infere deviceMetrics.mobile form mobile_ua because - // mobile device may have no "Mobile" word in its userAgent. - // Example: Lumia 950 (Chrome on Windows 10 Mobile) if (!mobile.has_value()) { // Due to legacy reasons missing 'deviceMetrics.mobile' is inferred as // true. - VLOG(0) << "Inferring 'deviceMetrics.mobile' as true"; + VLOG(logging::LOGGING_INFO) << "Inferring 'deviceMetrics.mobile' as true"; mobile = true; } @@ -217,10 +214,11 @@ } if (!touch.has_value()) { - VLOG(0) << "Inferring 'deviceMetrics.touch' as true."; + VLOG(logging::LOGGING_INFO) << "Inferring 'deviceMetrics.touch' as true."; } if (!maybe_device_scale_factor.has_value()) { - VLOG(0) << "Inferring 'deviceMetrics.pixelRatio' as 0."; + VLOG(logging::LOGGING_INFO) + << "Inferring 'deviceMetrics.pixelRatio' as 0."; } DeviceMetrics device_metrics{width, height, @@ -230,8 +228,9 @@ } if (mobile_ua && !mobile_device.device_metrics.has_value()) { - VLOG(0) << "The 'userAgent' value corresponds to a mobile UserAgent but " - "'deviceMetrics' is not provided."; + VLOG(logging::LOGGING_INFO) + << "The 'userAgent' value corresponds to a mobile UserAgent but " + "'deviceMetrics' is not provided."; } if (mobile_emulation->Find("clientHints")) { @@ -269,38 +268,28 @@ if (client_hints_dict.Find("mobile") && !mobile.has_value()) { return Status(kInvalidArgument, "'clientHints.mobile' must be a boolean"); } - if (mobile_device.device_metrics.has_value()) { - if (mobile.has_value() && - mobile_device.device_metrics->mobile != mobile.value()) { - VLOG(logging::LOGGING_WARNING) - << "The mobility in 'deviceMetrics.mobile' contradicts " - "'clientHints.mobile' value."; - } - if (!mobile.has_value()) { - VLOG(0) << "Inferring 'clientHints.mobile' as 'deviceMetrics.mobile'."; - mobile = mobile_device.device_metrics->mobile; - } - } else { - if (mobile.has_value() && mobile.value()) { - VLOG(0) << "User does not provide 'deviceMetrics' while " - "'clintHints.mobile' is true"; - } - // We don't infere deviceMetrics.mobile form mobile_ua because - // mobile device may have no "Mobile" word in its userAgent. - // Example: Lumia 950 (Chrome on Windows 10 Mobile) - if (!mobile.has_value()) { - VLOG(0) << "Inferring 'clientHints.mobile' as false"; + if (!mobile.has_value()) { + if (base::ToUpperASCII(client_hints.platform) == "ANDROID" && + mobile_device.user_agent.has_value()) { + VLOG(logging::LOGGING_INFO) + << "Inferring 'clientHints.mobile' from 'userAgent' as " + << mobile_ua; + mobile = mobile_ua; + } else { + VLOG(logging::LOGGING_INFO) + << "Inferring 'clientHints.mobile' as false"; mobile = false; } } - // All the paths above assign some value to 'mobile' - if (mobile_device.user_agent.has_value() && mobile_ua && !mobile.value()) { - // Presence of word Mobile in UserAgent clearly hints that the device is - // mobile. The opposite is not true. - VLOG(logging::LOGGING_WARNING) - << "The mobility in 'userAgent' contradicts " - "'clientHints.mobile' value."; + if (mobile_device.device_metrics.has_value()) { + if (mobile.has_value() && mobile.value() && + !mobile_device.device_metrics->mobile) { + VLOG(logging::LOGGING_WARNING) + << "The mobility in 'clientHints.mobile' contradicts " + "'deviceMetrics.mobile' value."; + } } + // All the paths above assign some value to 'mobile' client_hints.mobile = mobile.value(); if (client_hints_dict.Find("architecture")) { @@ -312,7 +301,8 @@ } client_hints.architecture = *architecture; } else { - VLOG(0) << "Inferring 'clientHints.architecture' as an empty string."; + VLOG(logging::LOGGING_INFO) + << "Inferring 'clientHints.architecture' as an empty string."; client_hints.architecture = ""; } @@ -324,7 +314,8 @@ } client_hints.bitness = *bitness; } else { - VLOG(0) << "Inferring 'clientHints.bitness' as an empty string."; + VLOG(logging::LOGGING_INFO) + << "Inferring 'clientHints.bitness' as an empty string."; client_hints.bitness = ""; } @@ -360,7 +351,8 @@ client_hints.brands = std::move(brands); } else { - VLOG(0) << "Inferring 'clientHints.brands' as browser defined."; + VLOG(logging::LOGGING_INFO) + << "Inferring 'clientHints.brands' as browser defined."; } if (client_hints_dict.Find("fullVersionList")) { @@ -397,7 +389,8 @@ client_hints.full_version_list = std::move(full_version_list); } else { - VLOG(0) << "Inferring 'clientHints.fullversionList' as browser defined."; + VLOG(logging::LOGGING_INFO) + << "Inferring 'clientHints.fullversionList' as browser defined."; } if (client_hints_dict.Find("model")) { @@ -406,12 +399,14 @@ return Status(kInvalidArgument, "'clientHints.model' must be a string"); } if (!client_hints.mobile && model->size() > 0) { - VLOG(0) << "User provides 'clientHints.model' for a non-mobile " - "platform as indicated by 'clientHints.mobile'"; + VLOG(logging::LOGGING_INFO) + << "User provides 'clientHints.model' for a non-mobile " + "platform as indicated by 'clientHints.mobile'"; } client_hints.model = *model; } else { - VLOG(0) << "Inferring 'clientHints.model' as an empty string."; + VLOG(logging::LOGGING_INFO) + << "Inferring 'clientHints.model' as an empty string."; client_hints.model = ""; } @@ -424,7 +419,8 @@ } client_hints.platform_version = *platform_version; } else { - VLOG(0) << "Inferring 'clientHints.platformVersion' as an empty string."; + VLOG(logging::LOGGING_INFO) + << "Inferring 'clientHints.platformVersion' as an empty string."; client_hints.platform_version = ""; } @@ -436,25 +432,24 @@ } client_hints.wow64 = *wow64; } else { - VLOG(0) << "Inferring 'clientHints.wow64' as false."; + VLOG(logging::LOGGING_INFO) << "Inferring 'clientHints.wow64' as false."; client_hints.wow64 = false; } mobile_device.client_hints = std::move(client_hints); } else if (mobile_device.user_agent.has_value()) { - VLOG(0) + VLOG(logging::LOGGING_INFO) << "Operating in legacy emulation mode as 'mobileEmulation' contains " "no 'clientHints'."; ClientHints client_hints; - client_hints.mobile = mobile_device.device_metrics.has_value() - ? mobile_device.device_metrics->mobile - : false; if (!MobileDevice::GuessPlatform(mobile_device.user_agent.value(), &client_hints.platform)) { // In legacy mode we allow platform to be empty. // Otherwise we might break the users' tests. client_hints.platform = ""; } + client_hints.mobile = + client_hints.platform == "Android" ? mobile_ua : false; // Empty value corresponds to the result of GetCpuArchitecture in // //content/common/user_agent.cc. client_hints.architecture = ""; @@ -464,17 +459,18 @@ client_hints.model = ""; client_hints.platform_version = ""; client_hints.wow64 = false; - VLOG(0) << "No 'clientHints' found. Operating in legacy mode. " - << "Inferring clientHints as: " - << "{architecture='" << client_hints.architecture << "'" - << ", bitness='" << client_hints.bitness << "'" - << ", brands=<browser-defined>" - << ", fullVersionList=<browser-defined>" - << ", mobile=" << std::boolalpha << client_hints.mobile - << ", model='" << client_hints.model << "'" - << ", platform='" << client_hints.platform << "'" - << ", platformVersion='" << client_hints.platform_version << "'" - << ", wow64=" << std::boolalpha << client_hints.wow64 << "}"; + VLOG(logging::LOGGING_INFO) + << "No 'clientHints' found. Operating in legacy mode. " + << "Inferring clientHints as: " + << "{architecture='" << client_hints.architecture << "'" + << ", bitness='" << client_hints.bitness << "'" + << ", brands=<browser-defined>" + << ", fullVersionList=<browser-defined>" + << ", mobile=" << std::boolalpha << client_hints.mobile << ", model='" + << client_hints.model << "'" + << ", platform='" << client_hints.platform << "'" + << ", platformVersion='" << client_hints.platform_version << "'" + << ", wow64=" << std::boolalpha << client_hints.wow64 << "}"; mobile_device.client_hints = std::move(client_hints); }
diff --git a/chrome/test/chromedriver/capabilities_unittest.cc b/chrome/test/chromedriver/capabilities_unittest.cc index e4dd8b3..398eff67 100644 --- a/chrome/test/chromedriver/capabilities_unittest.cc +++ b/chrome/test/chromedriver/capabilities_unittest.cc
@@ -825,7 +825,8 @@ TEST(ParseClientHints, MinimalistMobileAndroid) { Capabilities capabilities; const std::string mobile_emulation = - "{\"deviceMetrics\": {}, \"clientHints\": {\"platform\": \"Android\"}}"; + "{\"deviceMetrics\": {}, \"clientHints\": {\"platform\": \"Android\", " + "\"mobile\": true}}"; base::Value::Dict caps = CreateCapabilitiesDict(mobile_emulation); EXPECT_TRUE(StatusOk(capabilities.Parse(caps))); ASSERT_TRUE(capabilities.mobile_device.has_value()); @@ -845,8 +846,8 @@ TEST(ParseClientHints, MinimalistTabletAndroid) { Capabilities capabilities; const std::string mobile_emulation = - "{\"deviceMetrics\": {\"mobile\": false}," - "\"clientHints\": {\"platform\": \"Android\"}}"; + "{\"deviceMetrics\": {}," + "\"clientHints\": {\"platform\": \"Android\", \"mobile\": false}}"; base::Value::Dict caps = CreateCapabilitiesDict(mobile_emulation); EXPECT_TRUE(StatusOk(capabilities.Parse(caps))); ASSERT_TRUE(capabilities.mobile_device.has_value()); @@ -894,7 +895,7 @@ Capabilities capabilities; const std::string mobile_emulation = base::StringPrintf( "{\"deviceMetrics\": {}," - "\"clientHints\": {\"platform\": \"%s\"}}", + "\"clientHints\": {\"platform\": \"%s\", \"mobile\": true}}", expected_platform.c_str()); base::Value::Dict caps = CreateCapabilitiesDict(mobile_emulation); EXPECT_TRUE(StatusOk(capabilities.Parse(caps))); @@ -917,8 +918,8 @@ const std::string expected_user_agent = GetParam().second; Capabilities capabilities; const std::string mobile_emulation = base::StringPrintf( - "{\"deviceMetrics\": {\"mobile\": false}," - "\"clientHints\": {\"platform\": \"%s\"}}", + "{\"deviceMetrics\": {}," + "\"clientHints\": {\"platform\": \"%s\", \"mobile\": false}}", expected_platform.c_str()); base::Value::Dict caps = CreateCapabilitiesDict(mobile_emulation); EXPECT_TRUE(StatusOk(capabilities.Parse(caps))); @@ -950,7 +951,7 @@ Capabilities capabilities; const std::string mobile_emulation = base::StringPrintf( "{\"userAgent\": \"%s\", \"deviceMetrics\": {}," - "\"clientHints\": {\"platform\": \"Custom\"}}", + "\"clientHints\": {\"platform\": \"Custom\", \"mobile\": true}}", kUserAgentMobileChromeOnIOS); base::Value::Dict caps = CreateCapabilitiesDict(mobile_emulation); EXPECT_TRUE(StatusOk(capabilities.Parse(caps))); @@ -974,8 +975,8 @@ TEST(ParseClientHints, MinimalistCustomTablet) { Capabilities capabilities; const std::string mobile_emulation = base::StringPrintf( - "{\"userAgent\": \"%s\", \"deviceMetrics\": {\"mobile\": false}," - "\"clientHints\": {\"platform\": \"Custom\"}}", + "{\"userAgent\": \"%s\", \"deviceMetrics\": {}," + "\"clientHints\": {\"platform\": \"Custom\", \"mobile\": false}}", kUserAgentNonMobileChromeOnIOS); base::Value::Dict caps = CreateCapabilitiesDict(mobile_emulation); EXPECT_TRUE(StatusOk(capabilities.Parse(caps))); @@ -996,10 +997,12 @@ EXPECT_TRUE(reduced_user_agent.empty()); } -class InferClientHintsOnAndroid : public testing::TestWithParam<std::string> {}; +class InferClientHintsOnAndroid + : public testing::TestWithParam<std::pair<std::string, bool>> {}; TEST_P(InferClientHintsOnAndroid, NoDeviceMetrics) { - const std::string input_user_agent = GetParam(); + const std::string input_user_agent = GetParam().first; + const bool expected_is_mobile = GetParam().second; const std::string mobile_emulation = base::StringPrintf("{\"userAgent\": \"%s\"}", input_user_agent.c_str()); Capabilities capabilities; @@ -1013,16 +1016,16 @@ EXPECT_TRUE(capabilities.mobile_device->user_agent.has_value()); ASSERT_EQ(input_user_agent, capabilities.mobile_device->user_agent.value()); EXPECT_EQ("Android", client_hints.platform); - // Inferred as non-mobile due to the lack of device metrics - EXPECT_EQ(false, client_hints.mobile); + EXPECT_EQ(expected_is_mobile, client_hints.mobile); std::string reduced_user_agent; EXPECT_TRUE(StatusOk(capabilities.mobile_device->GetReducedUserAgent( "114", &reduced_user_agent))); - EXPECT_EQ(kUserAgentNonMobileChromeOnAndroid, reduced_user_agent); + EXPECT_EQ(input_user_agent, reduced_user_agent); } TEST_P(InferClientHintsOnAndroid, MobileDeviceMetrics) { - const std::string input_user_agent = GetParam(); + const std::string input_user_agent = GetParam().first; + const bool expected_is_mobile = GetParam().second; const std::string mobile_emulation = base::StringPrintf("{\"userAgent\": \"%s\", \"deviceMetrics\": {}}", input_user_agent.c_str()); @@ -1037,16 +1040,16 @@ EXPECT_TRUE(capabilities.mobile_device->user_agent.has_value()); ASSERT_EQ(input_user_agent, capabilities.mobile_device->user_agent.value()); EXPECT_EQ("Android", client_hints.platform); - // Deriverd from deviceMetrics.mobile that always defaults to true - EXPECT_EQ(true, client_hints.mobile); + EXPECT_EQ(expected_is_mobile, client_hints.mobile); std::string reduced_user_agent; EXPECT_TRUE(StatusOk(capabilities.mobile_device->GetReducedUserAgent( "114", &reduced_user_agent))); - EXPECT_EQ(kUserAgentMobileChromeOnAndroid, reduced_user_agent); + EXPECT_EQ(input_user_agent, reduced_user_agent); } TEST_P(InferClientHintsOnAndroid, TabletDeviceMetrics) { - const std::string input_user_agent = GetParam(); + const std::string input_user_agent = GetParam().first; + const bool expected_is_mobile = GetParam().second; const std::string mobile_emulation = base::StringPrintf( "{\"userAgent\": \"%s\", \"deviceMetrics\": {\"mobile\": false}}", input_user_agent.c_str()); @@ -1062,17 +1065,18 @@ ASSERT_EQ(input_user_agent, capabilities.mobile_device->user_agent.value()); EXPECT_EQ("Android", client_hints.platform); // Deriverd from deviceMetrics.mobile - EXPECT_EQ(false, client_hints.mobile); + EXPECT_EQ(expected_is_mobile, client_hints.mobile); std::string reduced_user_agent; EXPECT_TRUE(StatusOk(capabilities.mobile_device->GetReducedUserAgent( "114", &reduced_user_agent))); - EXPECT_EQ(kUserAgentNonMobileChromeOnAndroid, reduced_user_agent); + EXPECT_EQ(input_user_agent, reduced_user_agent); } -INSTANTIATE_TEST_SUITE_P(Inference, - InferClientHintsOnAndroid, - testing::Values(kUserAgentMobileChromeOnAndroid, - kUserAgentNonMobileChromeOnAndroid)); +INSTANTIATE_TEST_SUITE_P( + Inference, + InferClientHintsOnAndroid, + testing::Values(std::make_pair(kUserAgentMobileChromeOnAndroid, true), + std::make_pair(kUserAgentNonMobileChromeOnAndroid, false))); class InferClientHintsPerPlatform : public testing::TestWithParam<std::pair<std::string, std::string>> {}; @@ -1120,8 +1124,7 @@ ASSERT_EQ(expected_user_agent, capabilities.mobile_device->user_agent.value()); EXPECT_EQ(expected_platform, client_hints.platform); - // Deriverd from deviceMetrics.mobile that always defaults to true - EXPECT_EQ(true, client_hints.mobile); + EXPECT_EQ(false, client_hints.mobile); std::string reduced_user_agent; EXPECT_TRUE(StatusOk(capabilities.mobile_device->GetReducedUserAgent( "114", &reduced_user_agent))); @@ -1181,7 +1184,6 @@ EXPECT_TRUE(capabilities.mobile_device->user_agent.has_value()); ASSERT_EQ(input_user_agent, capabilities.mobile_device->user_agent.value()); EXPECT_EQ("", client_hints.platform); - // Inferred as non-mobile due to the lack of device metrics EXPECT_EQ(false, client_hints.mobile); std::string reduced_user_agent; EXPECT_TRUE(capabilities.mobile_device @@ -1206,8 +1208,7 @@ EXPECT_TRUE(capabilities.mobile_device->user_agent.has_value()); ASSERT_EQ(input_user_agent, capabilities.mobile_device->user_agent.value()); EXPECT_EQ("", client_hints.platform); - // Deriverd from deviceMetrics.mobile that always defaults to true - EXPECT_EQ(true, client_hints.mobile); + EXPECT_EQ(false, client_hints.mobile); std::string reduced_user_agent; EXPECT_TRUE(capabilities.mobile_device ->GetReducedUserAgent("114", &reduced_user_agent) @@ -1231,7 +1232,6 @@ EXPECT_TRUE(capabilities.mobile_device->user_agent.has_value()); ASSERT_EQ(input_user_agent, capabilities.mobile_device->user_agent.value()); EXPECT_EQ("", client_hints.platform); - // Deriverd from deviceMetrics.mobile EXPECT_EQ(false, client_hints.mobile); std::string reduced_user_agent; EXPECT_TRUE(capabilities.mobile_device
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py index ea4be2a..c9397a84 100755 --- a/chrome/test/chromedriver/test/run_py_tests.py +++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -5172,9 +5172,10 @@ self.assertFalse(driver.w3c_compliant) def testClientHintsMobileLegacy(self): - expected_ua = 'Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 5 Bui' - 'ld/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chr' - 'ome/18.0.1025.166 Mobile Safari/535.19' + expected_ua = ''.join(['Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 5', + 'Build/JOP40D) AppleWebKit/535.19', + '(KHTML, like Gecko) Chrome/18.0.1025.166 Mobile', + 'Safari/535.19']) driver = self.CreateDriver( mobile_emulation = { 'deviceMetrics': {'width': 360, 'height': 640, 'pixelRatio': 3}, @@ -5225,6 +5226,7 @@ 'platformVersion': '17', 'architecture': 'arm', 'bitness': '32', + 'mobile': True, 'model': 'Special', } })
diff --git a/chromeos/ash/components/auth_panel/BUILD.gn b/chromeos/ash/components/auth_panel/BUILD.gn index 7266408..b5fcd8c 100644 --- a/chromeos/ash/components/auth_panel/BUILD.gn +++ b/chromeos/ash/components/auth_panel/BUILD.gn
@@ -14,6 +14,8 @@ "//ui/views", ] sources = [ + "auth_factor_store.cc", + "auth_factor_store.h", "auth_panel.cc", "auth_panel.h", "auth_panel_event_dispatcher.cc",
diff --git a/chromeos/ash/components/auth_panel/auth_factor_store.cc b/chromeos/ash/components/auth_panel/auth_factor_store.cc new file mode 100644 index 0000000..a7a9fc27 --- /dev/null +++ b/chromeos/ash/components/auth_panel/auth_factor_store.cc
@@ -0,0 +1,33 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/ash/components/auth_panel/auth_factor_store.h" + +#include "base/notreached.h" +#include "chromeos/ash/components/osauth/public/common_types.h" + +namespace ash { + +AuthFactorStore::AuthFactorStore() = default; + +AuthFactorStore::~AuthFactorStore() = default; + +void AuthFactorStore::OnUserAction( + AshAuthFactor factor, + const AuthPanelEventDispatcher::UserAction& action) { + NOTIMPLEMENTED(); +} + +void AuthFactorStore::OnFactorStateChanged(AshAuthFactor factor, + AuthFactorState state) { + NOTIMPLEMENTED(); +} + +void AuthFactorStore::OnAuthVerdict( + AshAuthFactor factor, + AuthPanelEventDispatcher::AuthVerdict verdict) { + NOTIMPLEMENTED(); +} + +} // namespace ash
diff --git a/chromeos/ash/components/auth_panel/auth_factor_store.h b/chromeos/ash/components/auth_panel/auth_factor_store.h new file mode 100644 index 0000000..d4b7169 --- /dev/null +++ b/chromeos/ash/components/auth_panel/auth_factor_store.h
@@ -0,0 +1,34 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_ASH_COMPONENTS_AUTH_PANEL_AUTH_FACTOR_STORE_H_ +#define CHROMEOS_ASH_COMPONENTS_AUTH_PANEL_AUTH_FACTOR_STORE_H_ + +#include "base/callback_list.h" +#include "chromeos/ash/components/auth_panel/auth_panel_event_dispatcher.h" +#include "chromeos/ash/components/auth_panel/factor_auth_view.h" +#include "chromeos/ash/components/osauth/public/common_types.h" + +namespace ash { + +// This class encapsulates the UI state of `AuthPanel`. +class AuthFactorStore { + public: + using OnStateUpdatedCallback = base::RepeatingCallback<void()>; + + AuthFactorStore(); + ~AuthFactorStore(); + + void Subscribe(OnStateUpdatedCallback callback); + + void OnUserAction(AshAuthFactor factor, + const AuthPanelEventDispatcher::UserAction& action); + void OnFactorStateChanged(AshAuthFactor factor, AuthFactorState state); + void OnAuthVerdict(AshAuthFactor factor, + AuthPanelEventDispatcher::AuthVerdict verdict); +}; + +} // namespace ash + +#endif // CHROMEOS_ASH_COMPONENTS_AUTH_PANEL_AUTH_FACTOR_STORE_H_
diff --git a/chromeos/ash/components/auth_panel/auth_panel.cc b/chromeos/ash/components/auth_panel/auth_panel.cc index f0659b4..ffe59f98 100644 --- a/chromeos/ash/components/auth_panel/auth_panel.cc +++ b/chromeos/ash/components/auth_panel/auth_panel.cc
@@ -6,54 +6,53 @@ #include "base/logging.h" #include "base/notreached.h" +#include "chromeos/ash/components/auth_panel/auth_factor_store.h" #include "chromeos/ash/components/auth_panel/auth_panel_event_dispatcher.h" #include "chromeos/ash/components/auth_panel/factor_auth_view.h" #include "chromeos/ash/components/auth_panel/factor_auth_view_factory.h" +#include "chromeos/ash/components/osauth/public/auth_factor_status_consumer.h" #include "chromeos/ash/components/osauth/public/common_types.h" namespace ash { AuthPanel::AuthPanel(std::unique_ptr<FactorAuthViewFactory> view_factory, + std::unique_ptr<AuthFactorStore> store, std::unique_ptr<AuthPanelEventDispatcher> event_dispatcher) - : view_factory_(std::move(view_factory)), - event_dispatcher_(std::move(event_dispatcher)) {} + : event_dispatcher_(std::move(event_dispatcher)), + view_factory_(std::move(view_factory)), + store_(std::move(store)) {} AuthPanel::~AuthPanel() = default; void AuthPanel::InitializeUi(AuthFactorsSet factors, AuthHubConnector* connector) { - CHECK(views_.empty()); - for (const auto factor : factors) { - auto view = view_factory_->CreateFactorAuthView(factor); - view->OnFactorStateChanged(AuthFactorState::kCheckingForPresence); - views_[factor] = std::move(view); + for (auto&& factor : factors) { + views_.push_back(view_factory_->CreateFactorAuthView(factor)); + event_dispatcher_->DispatchEvent(factor, + AuthFactorState::kCheckingForPresence); } } void AuthPanel::OnFactorListChanged(FactorsStatusMap factors_with_status) { - views_.clear(); for (const auto& [factor, status] : factors_with_status) { - auto view = view_factory_->CreateFactorAuthView(factor); - view->OnFactorStateChanged(status); - views_[factor] = std::move(view); + event_dispatcher_->DispatchEvent(factor, status); } } void AuthPanel::OnFactorStatusesChanged(FactorsStatusMap incremental_update) { for (const auto& [factor, status] : incremental_update) { - CHECK(views_.contains(factor)); - views_[factor]->OnFactorStateChanged(status); + event_dispatcher_->DispatchEvent(factor, status); } } void AuthPanel::OnFactorAuthFailure(AshAuthFactor factor) { - CHECK(views_.contains(factor)); - views_[factor]->OnAuthFailure(); + event_dispatcher_->DispatchEvent( + factor, AuthPanelEventDispatcher::AuthVerdict::kFailure); } void AuthPanel::OnFactorAuthSuccess(AshAuthFactor factor) { - CHECK(views_.contains(factor)); - views_[factor]->OnAuthSuccess(); + event_dispatcher_->DispatchEvent( + factor, AuthPanelEventDispatcher::AuthVerdict::kSuccess); } void AuthPanel::OnEndAuthentication() {
diff --git a/chromeos/ash/components/auth_panel/auth_panel.h b/chromeos/ash/components/auth_panel/auth_panel.h index 26b3046a..341aff3 100644 --- a/chromeos/ash/components/auth_panel/auth_panel.h +++ b/chromeos/ash/components/auth_panel/auth_panel.h
@@ -5,15 +5,16 @@ #ifndef CHROMEOS_ASH_COMPONENTS_AUTH_PANEL_AUTH_PANEL_H_ #define CHROMEOS_ASH_COMPONENTS_AUTH_PANEL_AUTH_PANEL_H_ -#include <memory> +#include <vector> #include "base/containers/flat_map.h" -#include "chromeos/ash/components/auth_panel/auth_panel_event_dispatcher.h" #include "chromeos/ash/components/osauth/public/auth_factor_status_consumer.h" #include "chromeos/ash/components/osauth/public/common_types.h" namespace ash { +class AuthPanelEventDispatcher; +class AuthFactorStore; class FactorAuthView; class FactorAuthViewFactory; @@ -28,6 +29,7 @@ class AuthPanel : public AuthFactorStatusConsumer { public: AuthPanel(std::unique_ptr<FactorAuthViewFactory> view_factory, + std::unique_ptr<AuthFactorStore> store, std::unique_ptr<AuthPanelEventDispatcher> event_dispatcher); AuthPanel(const AuthPanel&) = delete; AuthPanel(AuthPanel&&) = delete; @@ -45,9 +47,10 @@ void OnEndAuthentication() override; private: - base::flat_map<AshAuthFactor, std::unique_ptr<FactorAuthView>> views_; - std::unique_ptr<FactorAuthViewFactory> view_factory_; std::unique_ptr<AuthPanelEventDispatcher> event_dispatcher_; + std::unique_ptr<FactorAuthViewFactory> view_factory_; + std::unique_ptr<AuthFactorStore> store_; + std::vector<std::unique_ptr<FactorAuthView>> views_; }; } // namespace ash
diff --git a/chromeos/ash/components/auth_panel/auth_panel_event_dispatcher.cc b/chromeos/ash/components/auth_panel/auth_panel_event_dispatcher.cc index 2cbe5bd80..6854dfe3 100644 --- a/chromeos/ash/components/auth_panel/auth_panel_event_dispatcher.cc +++ b/chromeos/ash/components/auth_panel/auth_panel_event_dispatcher.cc
@@ -9,12 +9,14 @@ namespace ash { -AuthPanelEventDispatcher::AuthPanelEventDispatcher() = default; +AuthPanelEventDispatcher::AuthPanelEventDispatcher( + base::raw_ptr<AuthFactorStore> store) + : store_(store) {} AuthPanelEventDispatcher::~AuthPanelEventDispatcher() = default; void AuthPanelEventDispatcher::DispatchEvent(AshAuthFactor factor, - UserAction action) { + const UserAction& action) { NOTIMPLEMENTED(); }
diff --git a/chromeos/ash/components/auth_panel/auth_panel_event_dispatcher.h b/chromeos/ash/components/auth_panel/auth_panel_event_dispatcher.h index c47d41a..4da37df 100644 --- a/chromeos/ash/components/auth_panel/auth_panel_event_dispatcher.h +++ b/chromeos/ash/components/auth_panel/auth_panel_event_dispatcher.h
@@ -8,15 +8,37 @@ #include "chromeos/ash/components/osauth/public/auth_factor_status_consumer.h" #include "chromeos/ash/components/osauth/public/common_types.h" +#include "base/containers/flat_map.h" +#include "base/memory/weak_ptr.h" +#include "chromeos/ash/components/auth_panel/factor_auth_view.h" +#include "chromeos/ash/components/osauth/public/auth_factor_status_consumer.h" +#include "chromeos/ash/components/osauth/public/common_types.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + namespace ash { +class AuthFactorStore; + // This class is responsible for dispatching auth panel ui events to // `AuthFactorStore`. class AuthPanelEventDispatcher { public: - enum UserAction { - // Emitted whenever the user presses the pin/password toggle button. - kPasswordPinToggle, + struct UserAction { + enum Type { + // Emitted whenever the user presses the pin/password toggle button. + kPasswordPinToggle, + kMaxValue = kPasswordPinToggle, + }; + + UserAction(); + ~UserAction(); + UserAction(const UserAction& other) = delete; + UserAction& operator=(const UserAction& other) = delete; + UserAction(UserAction&& other) = delete; + UserAction& operator=(UserAction&& other) = delete; + + Type type; + absl::optional<std::string> value; }; enum AuthVerdict { @@ -24,16 +46,19 @@ kFailure, }; - AuthPanelEventDispatcher(); + explicit AuthPanelEventDispatcher(base::raw_ptr<AuthFactorStore> store); ~AuthPanelEventDispatcher(); AuthPanelEventDispatcher(const AuthPanelEventDispatcher&) = delete; AuthPanelEventDispatcher(AuthPanelEventDispatcher&&) = delete; AuthPanelEventDispatcher& operator=(const AuthPanelEventDispatcher&) = delete; AuthPanelEventDispatcher& operator=(AuthPanelEventDispatcher&&) = delete; - void DispatchEvent(AshAuthFactor factor, UserAction action); - void DispatchEvent(AshAuthFactor factor, AuthVerdict verdict); + void DispatchEvent(AshAuthFactor factor, const UserAction& action); void DispatchEvent(AshAuthFactor factor, AuthFactorState state); + void DispatchEvent(AshAuthFactor factor, AuthVerdict verdict); + + private: + base::raw_ptr<AuthFactorStore> store_; }; } // namespace ash
diff --git a/chromeos/ash/components/auth_panel/factor_auth_view_factory.cc b/chromeos/ash/components/auth_panel/factor_auth_view_factory.cc index 889ea3f..924e9c42 100644 --- a/chromeos/ash/components/auth_panel/factor_auth_view_factory.cc +++ b/chromeos/ash/components/auth_panel/factor_auth_view_factory.cc
@@ -10,8 +10,8 @@ namespace ash { -std::unique_ptr<FactorAuthView> FactorAuthViewFactory::CreateFactorAuthView( - AshAuthFactor factor) { +[[nodiscard]] std::unique_ptr<FactorAuthView> +FactorAuthViewFactory::CreateFactorAuthView(AshAuthFactor factor) { switch (factor) { case AshAuthFactor::kGaiaPassword: return CreatePasswordView();
diff --git a/chromeos/ash/components/auth_panel/factor_auth_view_factory.h b/chromeos/ash/components/auth_panel/factor_auth_view_factory.h index 965d43b..80126b3 100644 --- a/chromeos/ash/components/auth_panel/factor_auth_view_factory.h +++ b/chromeos/ash/components/auth_panel/factor_auth_view_factory.h
@@ -13,11 +13,10 @@ namespace ash { -// This class is responsible for creating the different `FactorAuthView` objects -// that will be owned and managed by `AuthPanel`. This is done mainly to -// facilitate dependency injection and testing and to centralize the creation -// logic into one class, freeing up `AuthPanel` to deal exclusively with UI -// update logic. +// This class is responsible for creating the different `FactorAuthView` +// objects. This is done mainly to facilitate dependency injection and testing +// and to centralize the creation logic into one class, freeing up `AuthPanel` +// to deal exclusively with UI update logic. class FactorAuthViewFactory { public: using FactorAuthViewCreator =
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn index c86a6f0..fde59611 100644 --- a/components/autofill/core/browser/BUILD.gn +++ b/components/autofill/core/browser/BUILD.gn
@@ -975,6 +975,7 @@ "personal_data_manager_test_base.h", "personal_data_manager_unittest.cc", "profile_requirement_utils_unittest.cc", + "profile_token_quality_unittest.cc", "randomized_encoder_unittest.cc", "rationalization_util_unittest.cc", "single_field_form_fill_router_unittest.cc",
diff --git a/components/autofill/core/browser/autofill_field.cc b/components/autofill/core/browser/autofill_field.cc index 68c0e89..b91c1bb 100644 --- a/components/autofill/core/browser/autofill_field.cc +++ b/components/autofill/core/browser/autofill_field.cc
@@ -33,7 +33,8 @@ // default prediction. We don't need to store it, because its meaning is that // there is no default prediction. bool IsDefaultPrediction(const FieldPrediction& prediction) { - constexpr DenseSet<FieldPrediction::Source, FieldPrediction::Source_MAX> + constexpr DenseSet<FieldPrediction::Source, FieldPrediction::Source(0), + FieldPrediction::Source_MAX> default_sources = {FieldPrediction::SOURCE_AUTOFILL_DEFAULT, FieldPrediction::SOURCE_PASSWORDS_DEFAULT, FieldPrediction::SOURCE_OVERRIDE};
diff --git a/components/autofill/core/browser/autofill_profile_import_process.cc b/components/autofill/core/browser/autofill_profile_import_process.cc index 1084b61..f580baf 100644 --- a/components/autofill/core/browser/autofill_profile_import_process.cc +++ b/components/autofill/core/browser/autofill_profile_import_process.cc
@@ -11,6 +11,7 @@ #include "components/autofill/core/browser/field_types.h" #include "components/autofill/core/browser/metrics/profile_import_metrics.h" #include "components/autofill/core/browser/personal_data_manager.h" +#include "components/autofill/core/browser/profile_requirement_utils.h" #include "components/autofill/core/common/autofill_clock.h" #include "components/autofill/core/common/autofill_features.h" @@ -296,13 +297,9 @@ return; } // Check the eligiblity of the user and profile. - if (!personal_data_manager_->IsEligibleForAddressAccountStorage() || - personal_data_manager_->IsProfileMigrationBlocked(profile.guid()) || - !personal_data_manager_->IsCountryEligibleForAccountStorage( - base::UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_COUNTRY)))) { - return; + if (IsEligibleForMigrationToAccount(*personal_data_manager_, profile)) { + migration_candidate = profile; } - migration_candidate = profile; } std::vector<AutofillProfile> ProfileImportProcess::GetResultingProfiles() {
diff --git a/components/autofill/core/browser/browser_autofill_manager.cc b/components/autofill/core/browser/browser_autofill_manager.cc index c280d79..896ac49 100644 --- a/components/autofill/core/browser/browser_autofill_manager.cc +++ b/components/autofill/core/browser/browser_autofill_manager.cc
@@ -1016,7 +1016,7 @@ if (!GetCachedFormAndField(form, field, &form_structure, &autofill_field)) return; - auto* logger = GetEventFormLogger(autofill_field->Type().group()); + auto* logger = GetEventFormLogger(*autofill_field); if (logger) logger->OnPopupSuppressed(*form_structure, *autofill_field); } @@ -1049,7 +1049,7 @@ profile_form_bitmask = data_util::DetermineGroups(*form_structure); } - auto* logger = GetEventFormLogger(autofill_field->Type().group()); + auto* logger = GetEventFormLogger(*autofill_field); if (!autofill_field->is_autofilled) { if (logger) logger->OnTypedIntoNonFilledField(); @@ -1580,7 +1580,7 @@ client()->GetSecurityLevelForUmaHistograms(), profile_form_bitmask); } - auto* logger = GetEventFormLogger(autofill_field->Type().group()); + auto* logger = GetEventFormLogger(*autofill_field); if (logger) { logger->OnDidShowSuggestions(*form_structure, *autofill_field, form_structure->form_parsed_timestamp(), @@ -1712,7 +1712,7 @@ if (!GetCachedFormAndField(form, field, &form_structure, &autofill_field)) return; - auto* logger = GetEventFormLogger(autofill_field->Type().group()); + auto* logger = GetEventFormLogger(*autofill_field); if (logger) logger->OnUserHideSuggestions(*form_structure, *autofill_field); } @@ -1877,7 +1877,7 @@ if (delta >= kLimitBeforeRefill) return; - auto* logger = GetEventFormLogger(autofill_field->Type().group()); + auto* logger = GetEventFormLogger(*autofill_field); if (logger) { logger->OnAutofilledFieldWasClearedByJavaScriptShortlyAfterFill( *form_structure); @@ -2026,7 +2026,7 @@ FormInteractionCounts form_interaction_counts = {}; if (submitted_form->field_count() > 0) { const AutofillField* autofill_field = submitted_form->field(0); - auto* logger = GetEventFormLogger(autofill_field->Type().group()); + auto* logger = GetEventFormLogger(*autofill_field); if (logger) { form_interaction_counts = logger->form_interaction_counts(); } @@ -3264,7 +3264,7 @@ if (context->focused_field->Type().group() == FieldTypeGroup::kCreditCard) { context->is_filling_credit_card = true; } - auto* logger = GetEventFormLogger(context->focused_field->Type().group()); + auto* logger = GetEventFormLogger(*context->focused_field); if (logger) { logger->OnDidInteractWithAutofillableForm(*(context->form_structure), sync_state_); @@ -3419,9 +3419,16 @@ #endif autofill_metrics::FormEventLoggerBase* -BrowserAutofillManager::GetEventFormLogger( - FieldTypeGroup field_type_group) const { - switch (FieldTypeGroupToFormType(field_type_group)) { +BrowserAutofillManager::GetEventFormLogger(const AutofillField& field) const { + if (field.ShouldSuppressSuggestionsAndFillingByDefault()) { + // Ignore ac=unrecognized fields in key metrics: Prior to + // `kAutofillPredictionsForAutocompleteUnrecognized`, ac=unrecognized fields + // did not receive a type prediction and were consequently not associated to + // any event logger. To retain the same baseline for key metrics, continue + // to exclude such fields. + return nullptr; + } + switch (FieldTypeGroupToFormType(field.Type().group())) { case FormType::kAddressForm: return address_form_event_logger_.get(); case FormType::kCreditCardForm: @@ -3430,8 +3437,7 @@ case FormType::kUnknownFormType: return nullptr; } - NOTREACHED(); - return nullptr; + NOTREACHED_NORETURN(); } void BrowserAutofillManager::PreProcessStateMatchingTypes( @@ -3663,7 +3669,18 @@ void BrowserAutofillManager::SetFastCheckoutRunId( FieldTypeGroup field_type_group, int64_t run_id) { - GetEventFormLogger(field_type_group)->SetFastCheckoutRunId(run_id); + switch (FieldTypeGroupToFormType(field_type_group)) { + case FormType::kAddressForm: + address_form_event_logger_->SetFastCheckoutRunId(run_id); + return; + case FormType::kCreditCardForm: + credit_card_form_event_logger_->SetFastCheckoutRunId(run_id); + break; + case FormType::kPasswordForm: + case FormType::kUnknownFormType: + // FastCheckout only supports address and credit card forms. + NOTREACHED(); + } } } // namespace autofill
diff --git a/components/autofill/core/browser/browser_autofill_manager.h b/components/autofill/core/browser/browser_autofill_manager.h index 72dbbe0..a684139 100644 --- a/components/autofill/core/browser/browser_autofill_manager.h +++ b/components/autofill/core/browser/browser_autofill_manager.h
@@ -737,10 +737,10 @@ bool ShouldShowVirtualCardOption(FormStructure* form_structure); #endif - // Returns an appropriate EventFormLogger for the given |field_type_group|. - // May return nullptr. + // Returns an appropriate EventFormLogger, depending on the given `field`'s + // type. May return nullptr. autofill_metrics::FormEventLoggerBase* GetEventFormLogger( - FieldTypeGroup field_type_group) const; + const AutofillField& field) const; void SetDataList(const std::vector<std::u16string>& values, const std::vector<std::u16string>& labels);
diff --git a/components/autofill/core/browser/browser_autofill_manager_unittest.cc b/components/autofill/core/browser/browser_autofill_manager_unittest.cc index db79e66..81449c1 100644 --- a/components/autofill/core/browser/browser_autofill_manager_unittest.cc +++ b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
@@ -3663,6 +3663,49 @@ ExpectFilledForm(filled_form, fill_data, /*card_fill_data=*/absl::nullopt); } +// Tests that when `kAutofillPredictionsForAutocompleteUnrecognized` is enabled, +// fields with unrecognized autocomplete attribute don't contribute to key +// metrics. +TEST_F(BrowserAutofillManagerTest, AutocompleteUnrecognizedFields_KeyMetrics) { + base::test::ScopedFeatureList feature( + features::kAutofillPredictionsForAutocompleteUnrecognized); + + // Create an address form where field 1 has an unrecognized autocomplete + // attribute. + FormData form; + test::CreateTestAddressFormData(&form); + ASSERT_GE(form.fields.size(), 2u); + form.fields[1].parsed_autocomplete = + AutocompleteParsingResult{.field_type = HtmlFieldType::kUnrecognized}; + + // Interact with an ac != unrecognized field: Expect key metrics to be + // emitted. Note that "interacting" means querying suggestions, usually + // caused by clicking into a field. + { + FormsSeen({form}); + GetAutofillSuggestions(form, form.fields[0]); + FormSubmitted(form); + + base::HistogramTester histogram_tester; + browser_autofill_manager_->Reset(); + histogram_tester.ExpectTotalCount( + "Autofill.KeyMetrics.FillingAssistance.Address", 1); + } + + // Interact with an ac = unrecognized field: Expect no key metric to be + // emitted. + { + FormsSeen({form}); + GetAutofillSuggestions(form, form.fields[1]); + FormSubmitted(form); + + base::HistogramTester histogram_tester; + browser_autofill_manager_->Reset(); + histogram_tester.ExpectTotalCount( + "Autofill.KeyMetrics.FillingAssistance.Address", 0); + } +} + TEST_F(BrowserAutofillManagerTest, WillFillCreditCardNumber) { // Set up our form data. FormData form = CreateTestCreditCardFormData(true, false);
diff --git a/components/autofill/core/browser/field_types.h b/components/autofill/core/browser/field_types.h index 2de9e93..1deab10 100644 --- a/components/autofill/core/browser/field_types.h +++ b/components/autofill/core/browser/field_types.h
@@ -405,7 +405,8 @@ kMaxValue = kIban, }; -using ServerFieldTypeSet = DenseSet<ServerFieldType, MAX_VALID_FIELD_TYPE>; +using ServerFieldTypeSet = + DenseSet<ServerFieldType, NO_SERVER_DATA, MAX_VALID_FIELD_TYPE>; std::ostream& operator<<(std::ostream& o, ServerFieldTypeSet field_type_set);
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc index a1a8a59..0f88e97 100644 --- a/components/autofill/core/browser/form_structure.cc +++ b/components/autofill/core/browser/form_structure.cc
@@ -1690,7 +1690,15 @@ DenseSet<FormType> FormStructure::GetFormTypes() const { DenseSet<FormType> form_types; for (const auto& field : fields_) { - form_types.insert(FieldTypeGroupToFormType(field->Type().group())); + if (field->ShouldSuppressSuggestionsAndFillingByDefault()) { + // When `kAutofillPredictionsForAutocompleteUnrecognized` is enabled, + // types are predicted for fields with unrecognized autocomplete + // attribute. They are excluded from the form types, to keep the baseline + // for key and quality metrics. + form_types.insert(FormType::kUnknownFormType); + } else { + form_types.insert(FieldTypeGroupToFormType(field->Type().group())); + } } return form_types; }
diff --git a/components/autofill/core/browser/form_structure_unittest.cc b/components/autofill/core/browser/form_structure_unittest.cc index da59f50..498e9ff 100644 --- a/components/autofill/core/browser/form_structure_unittest.cc +++ b/components/autofill/core/browser/form_structure_unittest.cc
@@ -6783,4 +6783,22 @@ ElementsAre(0, 0, 1, 0, 0, 0)); } +// Tests that when `kAutofillPredictionsForAutocompleteUnrecognized` is enabled, +// forms that are completely annotated with ac=unrecognized are not classified +// as address forms. +TEST_F(FormStructureTestImpl, GetFormTypes_AutocompleteUnrecognized) { + base::test::ScopedFeatureList feature( + features::kAutofillPredictionsForAutocompleteUnrecognized); + + FormData form; + test::CreateTestAddressFormData(&form); + for (FormFieldData& field : form.fields) { + field.parsed_autocomplete = + AutocompleteParsingResult{.field_type = HtmlFieldType::kUnrecognized}; + } + FormStructure form_structure(form); + EXPECT_THAT(form_structure.GetFormTypes(), + UnorderedElementsAre(FormType::kUnknownFormType)); +} + } // namespace autofill
diff --git a/components/autofill/core/browser/metrics/autofill_metrics.h b/components/autofill/core/browser/metrics/autofill_metrics.h index 19aa3f3..f637e9d 100644 --- a/components/autofill/core/browser/metrics/autofill_metrics.h +++ b/components/autofill/core/browser/metrics/autofill_metrics.h
@@ -653,8 +653,9 @@ kMaxValue = kIsInSubFrame }; - using FormEventSet = - DenseSet<autofill_metrics::FormEvent, autofill_metrics::NUM_FORM_EVENTS>; + using FormEventSet = DenseSet<autofill_metrics::FormEvent, + autofill_metrics::FormEvent(0), + autofill_metrics::NUM_FORM_EVENTS>; // Utility class for determining the seamlessness of a credit card fill. class CreditCardSeamlessness {
diff --git a/components/autofill/core/browser/payments/credit_card_access_manager.h b/components/autofill/core/browser/payments/credit_card_access_manager.h index adf082d..a5660b2 100644 --- a/components/autofill/core/browser/payments/credit_card_access_manager.h +++ b/components/autofill/core/browser/payments/credit_card_access_manager.h
@@ -453,7 +453,7 @@ raw_ptr<PersonalDataManager> personal_data_manager_; // For logging metrics. - raw_ptr<autofill_metrics::CreditCardFormEventLogger, DanglingUntriaged> + raw_ptr<autofill_metrics::CreditCardFormEventLogger, DanglingAcrossTasks> form_event_logger_; // Timestamp used for preflight call metrics.
diff --git a/components/autofill/core/browser/profile_requirement_utils.cc b/components/autofill/core/browser/profile_requirement_utils.cc index a2d0d08..e2835037 100644 --- a/components/autofill/core/browser/profile_requirement_utils.cc +++ b/components/autofill/core/browser/profile_requirement_utils.cc
@@ -4,6 +4,7 @@ #include "components/autofill/core/browser/profile_requirement_utils.h" +#include "base/strings/utf_string_conversions.h" #include "components/autofill/core/browser/field_types.h" #include "components/autofill/core/browser/geo/autofill_country.h" #include "components/autofill/core/common/autofill_internals/log_message.h" @@ -106,7 +107,6 @@ GetAutofillProfileRequirementResult(profile, predicted_country_code, app_locale, /*import_log_buffer=*/nullptr); - return !base::ranges::any_of( kMinimumAddressRequirementViolations, [&](AddressImportRequirement address_requirement_violation) { @@ -115,4 +115,13 @@ }); } +bool IsEligibleForMigrationToAccount( + const PersonalDataManager& personal_data_manager, + const AutofillProfile& profile) { + return personal_data_manager.IsEligibleForAddressAccountStorage() && + !personal_data_manager.IsProfileMigrationBlocked(profile.guid()) && + personal_data_manager.IsCountryEligibleForAccountStorage( + base::UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_COUNTRY))); +} + } // namespace autofill
diff --git a/components/autofill/core/browser/profile_requirement_utils.h b/components/autofill/core/browser/profile_requirement_utils.h index 9fc05d08..8047775 100644 --- a/components/autofill/core/browser/profile_requirement_utils.h +++ b/components/autofill/core/browser/profile_requirement_utils.h
@@ -9,6 +9,7 @@ #include "components/autofill/core/browser/data_model/autofill_profile.h" #include "components/autofill/core/browser/metrics/profile_import_metrics.h" +#include "components/autofill/core/browser/personal_data_manager.h" #include "components/autofill/core/common/logging/log_buffer.h" namespace autofill { @@ -52,6 +53,12 @@ const std::string& predicted_country_code, const std::string& app_locale); +// Returns true if the profile can be migrated to the Account. Only sufficiently +// complete profiles are migrated and this method does not check for the +// completeness of the `profile`. +bool IsEligibleForMigrationToAccount( + const PersonalDataManager& personal_data_manager, + const AutofillProfile& profile); } // namespace autofill #endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PROFILE_REQUIREMENT_UTILS_H_
diff --git a/components/autofill/core/browser/profile_token_quality.cc b/components/autofill/core/browser/profile_token_quality.cc index 9ca1844..f9a49a94 100644 --- a/components/autofill/core/browser/profile_token_quality.cc +++ b/components/autofill/core/browser/profile_token_quality.cc
@@ -8,12 +8,16 @@ #include <vector> #include "base/check.h" +#include "base/containers/circular_deque.h" +#include "base/containers/contains.h" +#include "base/containers/fixed_flat_map.h" #include "base/notreached.h" #include "components/autofill/core/browser/autofill_field.h" #include "components/autofill/core/browser/data_model/autofill_profile.h" #include "components/autofill/core/browser/field_types.h" #include "components/autofill/core/browser/form_structure.h" #include "components/autofill/core/browser/personal_data_manager.h" +#include "components/autofill/core/browser/webdata/autofill_table.h" namespace autofill { @@ -25,6 +29,38 @@ return types; } +// Only a subset of the `GetSupportedTypes()` is stored. Every non-stored type +// is derived from a stored type. This function returns the stored type of +// `type`. If `type` is already a stored type, `type` is returned. +// +// ADDRESS_HOME_ADDRESS is not handled, since it is an artificial, unused type +// to represent the root node of the address tree. The type is not stored and +// not used for filling. +ServerFieldType GetStoredTypeOf(ServerFieldType type) { + if (base::Contains(AutofillTable::GetStoredTypesForAutofillProfile(), type)) { + return type; + } + CHECK_NE(type, ADDRESS_HOME_ADDRESS); + static const auto kStoredTypeOf = + base::MakeFixedFlatMap<ServerFieldType, ServerFieldType>( + {{ADDRESS_HOME_LINE1, ADDRESS_HOME_STREET_ADDRESS}, + {ADDRESS_HOME_LINE2, ADDRESS_HOME_STREET_ADDRESS}, + {ADDRESS_HOME_LINE3, ADDRESS_HOME_STREET_ADDRESS}, + {NAME_MIDDLE_INITIAL, NAME_MIDDLE}, + {PHONE_HOME_NUMBER, PHONE_HOME_WHOLE_NUMBER}, + {PHONE_HOME_CITY_CODE, PHONE_HOME_WHOLE_NUMBER}, + {PHONE_HOME_CITY_CODE_WITH_TRUNK_PREFIX, PHONE_HOME_WHOLE_NUMBER}, + {PHONE_HOME_COUNTRY_CODE, PHONE_HOME_WHOLE_NUMBER}, + {PHONE_HOME_CITY_AND_NUMBER, PHONE_HOME_WHOLE_NUMBER}, + {PHONE_HOME_CITY_AND_NUMBER_WITHOUT_TRUNK_PREFIX, + PHONE_HOME_WHOLE_NUMBER}, + {PHONE_HOME_NUMBER_PREFIX, PHONE_HOME_WHOLE_NUMBER}, + {PHONE_HOME_NUMBER_SUFFIX, PHONE_HOME_WHOLE_NUMBER}}); + auto* it = kStoredTypeOf.find(type); + CHECK_NE(it, kStoredTypeOf.end()); + return it->second; +} + } // namespace ProfileTokenQuality::ProfileTokenQuality(AutofillProfile* profile) @@ -42,12 +78,40 @@ return false; } +void ProfileTokenQuality::AddObservationForTesting( + ServerFieldType field_type, + ObservationType observation_type) { + AddObservation(field_type, Observation{.type = observation_type}); +} + std::vector<ProfileTokenQuality::ObservationType> ProfileTokenQuality::GetObservationTypesForFieldType( ServerFieldType type) const { CHECK(GetSupportedTypes(*profile_).contains(type)); - NOTIMPLEMENTED(); - return {}; + const auto it = observations_.find(GetStoredTypeOf(type)); + if (it == observations_.end()) { + return {}; + } + std::vector<ObservationType> types; + types.reserve(it->second.size()); + for (const Observation& observation : it->second) { + types.push_back(observation.type); + } + return types; +} + +void ProfileTokenQuality::AddObservation(ServerFieldType type, + Observation observation) { + CHECK(GetSupportedTypes(*profile_).contains(type)); + CHECK_NE(observation.type, ObservationType::kNone); + base::circular_deque<Observation>& observations = + observations_[GetStoredTypeOf(type)]; + CHECK_LE(observations.size(), kMaxObservationsPerToken); + static_assert(kMaxObservationsPerToken > 0); + if (observations.size() == kMaxObservationsPerToken) { + observations.pop_front(); + } + observations.push_back(std::move(observation)); } ProfileTokenQuality::FormAndFieldSignatureHash
diff --git a/components/autofill/core/browser/profile_token_quality.h b/components/autofill/core/browser/profile_token_quality.h index 4edd0c4..0666a72 100644 --- a/components/autofill/core/browser/profile_token_quality.h +++ b/components/autofill/core/browser/profile_token_quality.h
@@ -108,6 +108,9 @@ const FormData& form_data, const PersonalDataManager& pdm); + void AddObservationForTesting(ServerFieldType field_type, + ObservationType observation_type); + // Returns all `ObservationType`s available for the `type`. The resulting // vector has at most `kMaxNumberOfObservations` items. It is guaranteed that // no observation type is `kNone`. @@ -138,6 +141,11 @@ FormSignature form_signature, FieldSignature field_signature) const; + // Adds the `observation` to the `observations_` for the stored type of + // `type`. The oldest existing observation for that type is discarded, if + // the limit of `kMaxObservationsPerToken` is exceeded. + void AddObservation(ServerFieldType type, Observation observation); + // The profile for which observations are collected. Not null. base::raw_ptr<AutofillProfile> profile_;
diff --git a/components/autofill/core/browser/profile_token_quality_unittest.cc b/components/autofill/core/browser/profile_token_quality_unittest.cc new file mode 100644 index 0000000..3c4f5c4 --- /dev/null +++ b/components/autofill/core/browser/profile_token_quality_unittest.cc
@@ -0,0 +1,62 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/autofill/core/browser/profile_token_quality.h" + +#include <vector> + +#include "components/autofill/core/browser/data_model/autofill_profile.h" +#include "components/autofill/core/browser/field_types.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace autofill { + +using ObservationType = ProfileTokenQuality::ObservationType; + +// Ensures that `ProfileTokenQualityTest` supports all supported types of +// `AutofillProfile`. In particular, this test ensures that whenever a new +// non-stored type is added, the map in `GetStoredTypeOf()` is updated +// accordingly. If the type is supposed to be stored, it should be added to +// `AutofillTable::GetStoredTypesForAutofillProfile()`. +TEST(ProfileTokenQualityTest, AllSupportedTypesHandled) { + ServerFieldTypeSet supported_types; + AutofillProfile profile; + profile.GetSupportedTypes(&supported_types); + ProfileTokenQuality quality(&profile); + for (ServerFieldType type : supported_types) { + // See comment above `GetStoredTypeOf()` why this type is special. + if (type == ADDRESS_HOME_ADDRESS) { + continue; + } + // `GetObservationTypesForFieldType()` will internally call + // `GetStoredTypeOf()`. A `CHECK()` will fail if the mapping is incomplete. + EXPECT_TRUE(quality.GetObservationTypesForFieldType(type).empty()); + } +} + +TEST(ProfileTokenQualityTest, GetObservationTypesForFieldType) { + AutofillProfile profile; + ProfileTokenQuality quality(&profile); + + EXPECT_TRUE(quality.GetObservationTypesForFieldType(NAME_FIRST).empty()); + + quality.AddObservationForTesting(NAME_FIRST, ObservationType::kAccepted); + EXPECT_THAT(quality.GetObservationTypesForFieldType(NAME_FIRST), + testing::UnorderedElementsAre(ObservationType::kAccepted)); + EXPECT_TRUE(quality.GetObservationTypesForFieldType(NAME_LAST).empty()); + + // Test that if more than `kMaxObservationsPerToken` observations are added, + // only the first `kMaxObservationsPerToken` are returned. + for (size_t i = 0; i < ProfileTokenQuality::kMaxObservationsPerToken; i++) { + quality.AddObservationForTesting(NAME_FIRST, + ObservationType::kEditedToSimilarValue); + } + EXPECT_THAT(quality.GetObservationTypesForFieldType(NAME_FIRST), + testing::UnorderedElementsAreArray(std::vector<ObservationType>( + ProfileTokenQuality::kMaxObservationsPerToken, + ObservationType::kEditedToSimilarValue))); +} + +} // namespace autofill
diff --git a/components/autofill/core/browser/webdata/contact_info_sync_bridge.cc b/components/autofill/core/browser/webdata/contact_info_sync_bridge.cc index eb93ec9..1aebf9b 100644 --- a/components/autofill/core/browser/webdata/contact_info_sync_bridge.cc +++ b/components/autofill/core/browser/webdata/contact_info_sync_bridge.cc
@@ -316,9 +316,7 @@ change_processor()->ReportError( {FROM_HERE, "Failed reading CONTACT_INFO metadata from WebDatabase."}); return; - } else if (base::FeatureList::IsEnabled( - syncer::kCacheBaseEntitySpecificsInMetadata) && - SyncMetadataCacheContainsSupportedFields( + } else if (SyncMetadataCacheContainsSupportedFields( batch->GetAllMetadata())) { // Caching entity specifics is meant to preserve fields not supported in a // given browser version during commits to the server. If the cache
diff --git a/components/autofill/core/common/dense_set.h b/components/autofill/core/common/dense_set.h index 800d5ad..9002d52 100644 --- a/components/autofill/core/common/dense_set.h +++ b/components/autofill/core/common/dense_set.h
@@ -158,7 +158,7 @@ // representation. // // The lower and upper bounds of elements storable in a container are -// [T(0), kMaxValue]. By default, kMaxValue is T::kMaxValue. +// [kMinValue, kMaxValue]. The default is [0, T::kMaxValue]. // // The `packed` parameter indicates whether the memory consumption of a DenseSet // object should be minimized. That comes at the cost of slightly larger code @@ -167,25 +167,50 @@ // Time and space complexity: // - insert(), erase(), contains() run in time O(1) // - empty(), size(), iteration run in time O(kMaxValue) -// - sizeof(DenseSet) is, for N = kMaxValue + 1, +// - sizeof(DenseSet) is, for N = `kMaxValue - kMinValue + 1, // - if `!packed`: the minimum of {1, 2, 4, 8 * ceil(N / 64)} bytes that has // at least N bits; // - if `packed`: ceil(N / 8) bytes. // // Iterators are invalidated when the owning container is destructed or moved, // or when the element the iterator points to is erased from the container. -template <typename T, T kMaxValue = T::kMaxValue, bool packed = false> +template <typename T, + T kMinValue = T(0), + T kMaxValue = T::kMaxValue, + bool packed = false> class DenseSet { private: - // The index of a bit. - using Index = std::make_unsigned_t<T>; - static_assert(std::is_integral<T>::value || std::is_enum<T>::value); - static_assert(0 <= base::checked_cast<Index>(kMaxValue) + 1); + + // Needed for std::conditional_t. + struct Wrapper { + using type = T; + }; + + // For arithmetic on `T`. + using UnderlyingType = typename std::conditional_t<std::is_enum<T>::value, + std::underlying_type<T>, + Wrapper>::type; + + // The index of a bit in the underlying bitset. Use + // value_to_index() and index_to_value() for conversion. + using Index = std::make_unsigned_t<UnderlyingType>; + + // We can't use `base::to_underlying()` because `T` may be not an enum. + static constexpr UnderlyingType to_underlying(T x) { + return static_cast<UnderlyingType>(x); + } + + static_assert(to_underlying(kMinValue) <= to_underlying(kMaxValue)); // The maximum supported bit index. Indexing starts at 0, so kMaxBitIndex == - // 63 means we need 64 bits. - static constexpr size_t kMaxBitIndex = base::checked_cast<Index>(kMaxValue); + // 63 means we need 64 bits. This is a `size_t` to avoid `kMaxBitIndex + 1` + // from overflowing. + static constexpr size_t kMaxBitIndex = base::checked_cast<Index>( + to_underlying(kMaxValue) - to_underlying(kMinValue)); + + static_assert(kMaxBitIndex < + std::numeric_limits<decltype(kMaxBitIndex)>::max()); public: // The bitset is represented as array of words. @@ -450,23 +475,17 @@ using Bitset = internal::Bitset<Word, kNumWords>; - // Needed to use std::conditional_t. - // Must be declared outside of index_to_value() to avoid compiler errors. - struct Wrapper { - using type = T; - }; - static constexpr Index value_to_index(T x) { - DCHECK(index_to_value(0) <= x && x <= kMaxValue); - return base::checked_cast<Index>(x); + DCHECK_LE(kMinValue, x); + DCHECK_LE(x, kMaxValue); + return base::checked_cast<Index>(to_underlying(x) - + to_underlying(kMinValue)); } static constexpr T index_to_value(Index i) { DCHECK_LE(i, base::checked_cast<Index>(kMaxValue)); - using UnderlyingType = - typename std::conditional_t<std::is_enum<T>::value, - std::underlying_type<T>, Wrapper>::type; - return static_cast<T>(base::checked_cast<UnderlyingType>(i)); + return static_cast<T>(base::checked_cast<UnderlyingType>(i) + + to_underlying(kMinValue)); } Bitset bitset_{};
diff --git a/components/autofill/core/common/dense_set_unittest.cc b/components/autofill/core/common/dense_set_unittest.cc index 8c4ccbf..1119acd0 100644 --- a/components/autofill/core/common/dense_set_unittest.cc +++ b/components/autofill/core/common/dense_set_unittest.cc
@@ -15,43 +15,43 @@ namespace autofill { TEST(DenseSetTest, size_of) { - EXPECT_EQ(sizeof(DenseSet<size_t, 1>), 1u); - EXPECT_EQ(sizeof(DenseSet<size_t, 7>), 1u); - EXPECT_EQ(sizeof(DenseSet<size_t, 8>), 2u); - EXPECT_EQ(sizeof(DenseSet<size_t, 15>), 2u); - EXPECT_EQ(sizeof(DenseSet<size_t, 16>), 4u); - EXPECT_EQ(sizeof(DenseSet<size_t, 31>), 4u); - EXPECT_EQ(sizeof(DenseSet<size_t, 32>), 8u); - EXPECT_EQ(sizeof(DenseSet<size_t, 63>), 8u); - EXPECT_EQ(sizeof(DenseSet<size_t, 64>), 16u); - EXPECT_EQ(sizeof(DenseSet<size_t, 127>), 16u); - EXPECT_EQ(sizeof(DenseSet<size_t, 255>), 32u); + EXPECT_EQ(sizeof(DenseSet<size_t, 0, 1>), 1u); + EXPECT_EQ(sizeof(DenseSet<size_t, 0, 7>), 1u); + EXPECT_EQ(sizeof(DenseSet<size_t, 0, 8>), 2u); + EXPECT_EQ(sizeof(DenseSet<size_t, 0, 15>), 2u); + EXPECT_EQ(sizeof(DenseSet<size_t, 0, 16>), 4u); + EXPECT_EQ(sizeof(DenseSet<size_t, 0, 31>), 4u); + EXPECT_EQ(sizeof(DenseSet<size_t, 0, 32>), 8u); + EXPECT_EQ(sizeof(DenseSet<size_t, 0, 63>), 8u); + EXPECT_EQ(sizeof(DenseSet<size_t, 0, 64>), 16u); + EXPECT_EQ(sizeof(DenseSet<size_t, 0, 127>), 16u); + EXPECT_EQ(sizeof(DenseSet<size_t, 0, 255>), 32u); } TEST(DenseSetTest, initialization) { enum class T : size_t { - One = 1, - Two = 2, - Three = 3, - Four = 4, - Five = 5, - kMaxValue = Five, + kOne = 1, + kTwo = 2, + kThree = 3, + kFour = 4, + kFive = 5, + kMaxValue = kFive, }; - using DS = DenseSet<T, T::kMaxValue>; + using DS = DenseSet<T>; DS s; EXPECT_TRUE(s.empty()); EXPECT_EQ(s.size(), 0u); EXPECT_EQ(DS(s.begin(), s.end()), s); - s.insert(T::Two); - s.insert(T::Four); - s.insert(T::One); + s.insert(T::kTwo); + s.insert(T::kFour); + s.insert(T::kOne); EXPECT_EQ(s.size(), 3u); EXPECT_EQ(DS(s.begin(), s.end()), s); EXPECT_EQ(DS(s.cbegin(), s.cend()), s); EXPECT_EQ(DS(s.rbegin(), s.rend()), s); EXPECT_EQ(DS(s.crbegin(), s.crend()), s); - EXPECT_EQ(DS({T::Four, T::Two, T::One}), s); + EXPECT_EQ(DS({T::kFour, T::kTwo, T::kOne}), s); } TEST(DenseSetTest, initializer_list) { @@ -63,35 +63,35 @@ { constexpr size_t kMax = 10; - constexpr DenseSet<size_t, kMax> set{0, 1, kMax - 2, kMax - 1, kMax}; + constexpr DenseSet<size_t, 0, kMax> set{0, 1, kMax - 2, kMax - 1, kMax}; EXPECT_THAT(std::vector<size_t>(set.begin(), set.end()), ::testing::ElementsAre(0, 1, kMax - 2, kMax - 1, kMax)); } { constexpr size_t kMax = kMaxValueForConstexpr; - constexpr DenseSet<size_t, kMax> set{0, 1, kMax - 2, kMax - 1, kMax}; + constexpr DenseSet<size_t, 0, kMax> set{0, 1, kMax - 2, kMax - 1, kMax}; EXPECT_THAT(std::vector<size_t>(set.begin(), set.end()), ::testing::ElementsAre(0, 1, kMax - 2, kMax - 1, kMax)); } { constexpr size_t kMax = kMaxValueForConstexpr + 1; - DenseSet<size_t, kMax> set{0, 1, kMax - 2, kMax - 1, kMax}; + DenseSet<size_t, 0, kMax> set{0, 1, kMax - 2, kMax - 1, kMax}; EXPECT_THAT(std::vector<size_t>(set.begin(), set.end()), ::testing::ElementsAre(0, 1, kMax - 2, kMax - 1, kMax)); } { constexpr size_t kMax = kMaxValueForConstexpr + 2; - DenseSet<size_t, kMax> set{0, 1, kMax - 2, kMax - 1, kMax}; + DenseSet<size_t, 0, kMax> set{0, 1, kMax - 2, kMax - 1, kMax}; EXPECT_THAT(std::vector<size_t>(set.begin(), set.end()), ::testing::ElementsAre(0, 1, kMax - 2, kMax - 1, kMax)); } { constexpr size_t kMax = kMaxValueForConstexpr + 100; - DenseSet<size_t, kMax> set{0, 1, kMax - 2, kMax - 1, kMax}; + DenseSet<size_t, 0, kMax> set{0, 1, kMax - 2, kMax - 1, kMax}; EXPECT_THAT(std::vector<size_t>(set.begin(), set.end()), ::testing::ElementsAre(0, 1, kMax - 2, kMax - 1, kMax)); } @@ -99,21 +99,21 @@ TEST(DenseSetTest, data) { { - constexpr DenseSet<size_t, 23> set{0, 1, 2, 3, 4, 20, 23}; + constexpr DenseSet<size_t, 0, 23> set{0, 1, 2, 3, 4, 20, 23}; EXPECT_THAT( set.data(), ElementsAre((1ULL << 0) | (1ULL << 1) | (1ULL << 2) | (1ULL << 3) | (1ULL << 4) | (1ULL << 20) | (1ULL << 23))); } { - constexpr DenseSet<size_t, 31> set{0, 1, 2, 3, 4, 20, 31}; + constexpr DenseSet<size_t, 0, 31> set{0, 1, 2, 3, 4, 20, 31}; EXPECT_THAT( set.data(), ElementsAre((1ULL << 0) | (1ULL << 1) | (1ULL << 2) | (1ULL << 3) | (1ULL << 4) | (1ULL << 20) | (1ULL << 31))); } { - constexpr DenseSet<size_t, 63> set{0, 1, 63}; + constexpr DenseSet<size_t, 0, 63> set{0, 1, 63}; EXPECT_THAT(set.data(), ElementsAre((1ULL << 0) | (1ULL << 1) | (1ULL << 63))); } @@ -121,19 +121,20 @@ TEST(DenseSetTest, iterators_begin_end) { enum class T : int { - One = 1, - Two = 2, - Three = 3, - Four = 4, - Five = 5, - kMaxValue = Five, + kMinusOne = -1, + kOne = 1, + kTwo = 2, + kThree = 3, + kFour = 4, + kFive = 5, + kMaxValue = kFive, }; - using DS = DenseSet<T, T::kMaxValue>; + using DS = DenseSet<T, T::kMinusOne, T::kMaxValue>; DS s; - s.insert(T::Two); - s.insert(T::Four); - s.insert(T::One); + s.insert(T::kTwo); + s.insert(T::kFour); + s.insert(T::kOne); EXPECT_EQ(s.size(), 3u); EXPECT_EQ(std::distance(s.begin(), s.end()), 3); @@ -143,9 +144,9 @@ auto x2 = *it++; auto x3 = *it++; EXPECT_EQ(it, s.end()); - EXPECT_EQ(x1, T::One); - EXPECT_EQ(x2, T::Two); - EXPECT_EQ(x3, T::Four); + EXPECT_EQ(x1, T::kOne); + EXPECT_EQ(x2, T::kTwo); + EXPECT_EQ(x3, T::kFour); } { @@ -154,29 +155,30 @@ auto x2 = *++it; auto x3 = *++it; EXPECT_NE(it, s.end()); - EXPECT_EQ(x1, T::One); - EXPECT_EQ(x2, T::Two); - EXPECT_EQ(x3, T::Four); + EXPECT_EQ(x1, T::kOne); + EXPECT_EQ(x2, T::kTwo); + EXPECT_EQ(x3, T::kFour); } - EXPECT_THAT(s, ::testing::ElementsAre(T::One, T::Two, T::Four)); + EXPECT_THAT(s, ::testing::ElementsAre(T::kOne, T::kTwo, T::kFour)); } TEST(DenseSetTest, iterators_begin_end_reverse) { - enum class T : char { - One = 1, - Two = 2, - Three = 3, - Four = 4, - Five = 5, - kMaxValue = Five, + enum class T : int8_t { + kMinusOne = -1, + kOne = 1, + kTwo = 2, + kThree = 3, + kFour = 4, + kFive = 5, + kMaxValue = kFive }; - using DS = DenseSet<T, T::kMaxValue>; + using DS = DenseSet<T, T::kMinusOne, T::kMaxValue>; DS s; - s.insert(T::Two); - s.insert(T::Four); - s.insert(T::One); + s.insert(T::kTwo); + s.insert(T::kFour); + s.insert(T::kOne); EXPECT_EQ(s.size(), 3u); { @@ -186,9 +188,9 @@ auto x2 = *it--; auto x1 = *it; EXPECT_EQ(it, s.begin()); - EXPECT_EQ(x1, T::One); - EXPECT_EQ(x2, T::Two); - EXPECT_EQ(x3, T::Four); + EXPECT_EQ(x1, T::kOne); + EXPECT_EQ(x2, T::kTwo); + EXPECT_EQ(x3, T::kFour); } { @@ -197,27 +199,28 @@ auto x2 = *--it; auto x1 = *--it; EXPECT_EQ(it, s.begin()); - EXPECT_EQ(x1, T::One); - EXPECT_EQ(x2, T::Two); - EXPECT_EQ(x3, T::Four); + EXPECT_EQ(x1, T::kOne); + EXPECT_EQ(x2, T::kTwo); + EXPECT_EQ(x3, T::kFour); } } TEST(DenseSetTest, iterators_rbegin_rend) { enum class T { - One = 1, - Two = 2, - Three = 3, - Four = 4, - Five = 5, - kMaxValue = Five + kMinusOne = -1, + kOne = 1, + kTwo = 2, + kThree = 3, + kFour = 4, + kFive = 5, + kMaxValue = kFive }; - using DS = DenseSet<T, T::kMaxValue>; + using DS = DenseSet<T, T::kMinusOne, T::kMaxValue>; DS s; - s.insert(T::Two); - s.insert(T::Four); - s.insert(T::One); + s.insert(T::kTwo); + s.insert(T::kFour); + s.insert(T::kOne); EXPECT_EQ(s.size(), 3u); EXPECT_EQ(std::distance(s.rbegin(), s.rend()), 3); @@ -227,9 +230,9 @@ auto x2 = *it++; auto x1 = *it++; EXPECT_EQ(it, s.rend()); - EXPECT_EQ(x1, T::One); - EXPECT_EQ(x2, T::Two); - EXPECT_EQ(x3, T::Four); + EXPECT_EQ(x1, T::kOne); + EXPECT_EQ(x2, T::kTwo); + EXPECT_EQ(x3, T::kFour); } { @@ -238,62 +241,63 @@ auto x2 = *++it; auto x1 = *++it; EXPECT_NE(it, s.rend()); - EXPECT_EQ(x1, T::One); - EXPECT_EQ(x2, T::Two); - EXPECT_EQ(x3, T::Four); + EXPECT_EQ(x1, T::kOne); + EXPECT_EQ(x2, T::kTwo); + EXPECT_EQ(x3, T::kFour); } EXPECT_THAT(std::vector<T>(s.rbegin(), s.rend()), - ::testing::ElementsAre(T::Four, T::Two, T::One)); + ::testing::ElementsAre(T::kFour, T::kTwo, T::kOne)); } TEST(DenseSetTest, lookup) { enum class T { - One = 1, - Two = 2, - Three = 3, - Four = 4, - Five = 5, - kMaxValue = Five + kMinusOne = -1, + kOne = 1, + kTwo = 2, + kThree = 3, + kFour = 4, + kFive = 5, + kMaxValue = kFive }; - using DS = DenseSet<T, T::kMaxValue>; + using DS = DenseSet<T, T::kMinusOne, T::kMaxValue>; DS s; - s.insert(T::Two); - s.insert(T::Four); - s.insert(T::One); + s.insert(T::kTwo); + s.insert(T::kFour); + s.insert(T::kOne); EXPECT_FALSE(s.contains(static_cast<T>(0))); - EXPECT_TRUE(s.contains(T::One)); - EXPECT_TRUE(s.contains(T::Two)); - EXPECT_FALSE(s.contains(T::Three)); - EXPECT_TRUE(s.contains(T::Four)); - EXPECT_FALSE(s.contains(T::Five)); + EXPECT_TRUE(s.contains(T::kOne)); + EXPECT_TRUE(s.contains(T::kTwo)); + EXPECT_FALSE(s.contains(T::kThree)); + EXPECT_TRUE(s.contains(T::kFour)); + EXPECT_FALSE(s.contains(T::kFive)); EXPECT_EQ(s.contains(static_cast<T>(0)), 0u); - EXPECT_EQ(s.contains(T::One), 1u); - EXPECT_EQ(s.contains(T::Two), 1u); - EXPECT_EQ(s.contains(T::Three), 0u); - EXPECT_EQ(s.contains(T::Four), 1u); - EXPECT_EQ(s.contains(T::Five), 0u); + EXPECT_EQ(s.contains(T::kOne), 1u); + EXPECT_EQ(s.contains(T::kTwo), 1u); + EXPECT_EQ(s.contains(T::kThree), 0u); + EXPECT_EQ(s.contains(T::kFour), 1u); + EXPECT_EQ(s.contains(T::kFive), 0u); EXPECT_EQ(s.find(static_cast<T>(0)), s.end()); - EXPECT_NE(s.find(T::One), s.end()); - EXPECT_NE(s.find(T::Two), s.end()); - EXPECT_EQ(s.find(T::Three), s.end()); - EXPECT_NE(s.find(T::Four), s.end()); - EXPECT_EQ(s.find(T::Five), s.end()); + EXPECT_NE(s.find(T::kOne), s.end()); + EXPECT_NE(s.find(T::kTwo), s.end()); + EXPECT_EQ(s.find(T::kThree), s.end()); + EXPECT_NE(s.find(T::kFour), s.end()); + EXPECT_EQ(s.find(T::kFive), s.end()); - EXPECT_EQ(*s.find(T::One), T::One); - EXPECT_EQ(*s.find(T::Two), T::Two); - EXPECT_EQ(*s.find(T::Four), T::Four); + EXPECT_EQ(*s.find(T::kOne), T::kOne); + EXPECT_EQ(*s.find(T::kTwo), T::kTwo); + EXPECT_EQ(*s.find(T::kFour), T::kFour); EXPECT_NE(s.find(static_cast<T>(0)), s.lower_bound(static_cast<T>(0))); - EXPECT_EQ(s.find(T::One), s.lower_bound(T::One)); - EXPECT_EQ(s.find(T::Two), s.lower_bound(T::Two)); - EXPECT_NE(s.find(T::Three), s.lower_bound(T::Three)); - EXPECT_EQ(s.find(T::Four), s.lower_bound(T::Four)); - EXPECT_EQ(s.find(T::Five), s.lower_bound(T::Five)); + EXPECT_EQ(s.find(T::kOne), s.lower_bound(T::kOne)); + EXPECT_EQ(s.find(T::kTwo), s.lower_bound(T::kTwo)); + EXPECT_NE(s.find(T::kThree), s.lower_bound(T::kThree)); + EXPECT_EQ(s.find(T::kFour), s.lower_bound(T::kFour)); + EXPECT_EQ(s.find(T::kFive), s.lower_bound(T::kFive)); DS t; EXPECT_TRUE(t.empty()); @@ -323,20 +327,27 @@ } TEST(DenseSetTest, iterators_lower_upper_bound) { - enum class T { One = 1, Two = 2, Three = 3, Four = 4, Five = 5 }; - using DS = DenseSet<T, T::Five>; + enum class T { + kMinusOne = -1, + kOne = 1, + kTwo = 2, + kThree = 3, + kFour = 4, + kFive = 5 + }; + using DS = DenseSet<T, T::kMinusOne, T::kFive>; DS s; - s.insert(T::Two); - s.insert(T::Four); - s.insert(T::One); + s.insert(T::kTwo); + s.insert(T::kFour); + s.insert(T::kOne); EXPECT_EQ(s.size(), 3u); EXPECT_EQ(s.lower_bound(static_cast<T>(0)), s.begin()); - EXPECT_EQ(s.lower_bound(T::One), s.begin()); + EXPECT_EQ(s.lower_bound(T::kOne), s.begin()); - EXPECT_EQ(s.upper_bound(T::Four), s.end()); - EXPECT_EQ(s.upper_bound(T::Five), s.end()); + EXPECT_EQ(s.upper_bound(T::kFour), s.end()); + EXPECT_EQ(s.upper_bound(T::kFive), s.end()); { auto it = s.lower_bound(static_cast<T>(0)); @@ -345,46 +356,46 @@ } { - auto it = s.lower_bound(T::One); - auto jt = s.upper_bound(T::One); + auto it = s.lower_bound(T::kOne); + auto jt = s.upper_bound(T::kOne); auto x1 = *it++; EXPECT_EQ(it, jt); - EXPECT_EQ(x1, T::One); + EXPECT_EQ(x1, T::kOne); } { - auto it = s.lower_bound(T::Four); - auto jt = s.upper_bound(T::Four); + auto it = s.lower_bound(T::kFour); + auto jt = s.upper_bound(T::kFour); auto x3 = *it++; EXPECT_EQ(it, jt); - EXPECT_EQ(x3, T::Four); + EXPECT_EQ(x3, T::kFour); } { - auto it = s.lower_bound(T::Five); - auto jt = s.upper_bound(T::Five); + auto it = s.lower_bound(T::kFive); + auto jt = s.upper_bound(T::kFive); EXPECT_EQ(it, jt); } { - auto it = s.lower_bound(T::One); - auto jt = s.upper_bound(T::Five); + auto it = s.lower_bound(T::kOne); + auto jt = s.upper_bound(T::kFive); auto x1 = *it++; auto x2 = *it++; auto x3 = *it++; EXPECT_EQ(it, jt); - EXPECT_EQ(x1, T::One); - EXPECT_EQ(x2, T::Two); - EXPECT_EQ(x3, T::Four); + EXPECT_EQ(x1, T::kOne); + EXPECT_EQ(x2, T::kTwo); + EXPECT_EQ(x3, T::kFour); } { - auto it = s.lower_bound(T::Three); - auto jt = s.upper_bound(T::Four); + auto it = s.lower_bound(T::kThree); + auto jt = s.upper_bound(T::kFour); auto x3 = *it++; EXPECT_EQ(jt, s.end()); EXPECT_EQ(it, jt); - EXPECT_EQ(x3, T::Four); + EXPECT_EQ(x3, T::kFour); } EXPECT_EQ(static_cast<size_t>(std::distance(s.begin(), s.end())), s.size()); @@ -392,43 +403,43 @@ } TEST(DenseSetTest, max_size) { - const int One = 1; - const int Two = 2; - // const int Three = 3; - const int Four = 4; - // const int Five = 5; + const int kOne = 1; + const int kTwo = 2; + // const int kThree = 3; + const int kFour = 4; + // const int kFive = 5; const int kMaxValue = 5; - using DS = DenseSet<int, kMaxValue>; + using DS = DenseSet<int, 0, kMaxValue>; DS s; EXPECT_TRUE(s.empty()); EXPECT_EQ(s.size(), 0u); EXPECT_EQ(s.max_size(), 6u); - s.insert(Two); + s.insert(kTwo); EXPECT_FALSE(s.empty()); EXPECT_EQ(s.size(), 1u); - s.insert(Four); + s.insert(kFour); EXPECT_FALSE(s.empty()); EXPECT_EQ(s.size(), 2u); - s.insert(One); + s.insert(kOne); EXPECT_FALSE(s.empty()); EXPECT_EQ(s.size(), 3u); EXPECT_EQ(s.max_size(), 6u); } TEST(DenseSetTest, modifiers) { - const size_t One = 1; - const size_t Two = 2; - const size_t Three = 3; - const size_t Four = 4; - // const size_t Five = 5; + const size_t kOne = 1; + const size_t kTwo = 2; + const size_t kThree = 3; + const size_t kFour = 4; + // const size_t kFive = 5; const size_t kMaxValue = 5; - using DS = DenseSet<size_t, kMaxValue>; + using DS = DenseSet<size_t, 0, kMaxValue>; DS s; - s.insert(Two); - s.insert(Four); - s.insert(One); + s.insert(kTwo); + s.insert(kFour); + s.insert(kOne); EXPECT_EQ(s.size(), 3u); auto EXPECT_INSERTION = [](auto& set, auto value, bool took_place) { @@ -438,58 +449,58 @@ DS t; EXPECT_NE(s, t); - EXPECT_INSERTION(t, Two, true); - EXPECT_INSERTION(t, Two, false); - EXPECT_INSERTION(t, Four, true); - EXPECT_INSERTION(t, Four, false); - EXPECT_INSERTION(t, One, true); - EXPECT_INSERTION(t, One, false); + EXPECT_INSERTION(t, kTwo, true); + EXPECT_INSERTION(t, kTwo, false); + EXPECT_INSERTION(t, kFour, true); + EXPECT_INSERTION(t, kFour, false); + EXPECT_INSERTION(t, kOne, true); + EXPECT_INSERTION(t, kOne, false); EXPECT_EQ(s, t); EXPECT_EQ(t.size(), 3u); - EXPECT_INSERTION(t, Three, true); - EXPECT_INSERTION(t, Three, false); - EXPECT_EQ(t.erase(Three), 1u); - EXPECT_EQ(t.erase(Three), 0u); + EXPECT_INSERTION(t, kThree, true); + EXPECT_INSERTION(t, kThree, false); + EXPECT_EQ(t.erase(kThree), 1u); + EXPECT_EQ(t.erase(kThree), 0u); EXPECT_EQ(s, t); EXPECT_EQ(t.size(), 3u); - EXPECT_EQ(s.erase(One), 1u); - EXPECT_EQ(t.erase(Four), 1u); + EXPECT_EQ(s.erase(kOne), 1u); + EXPECT_EQ(t.erase(kFour), 1u); EXPECT_NE(s, t); EXPECT_EQ(s.size(), 2u); EXPECT_EQ(t.size(), 2u); - EXPECT_INSERTION(s, One, true); - EXPECT_INSERTION(t, Four, true); + EXPECT_INSERTION(s, kOne, true); + EXPECT_INSERTION(t, kFour, true); EXPECT_EQ(s, t); EXPECT_EQ(s.size(), 3u); EXPECT_EQ(t.size(), 3u); - EXPECT_EQ(s.erase(s.find(One)), s.find(Two)); - EXPECT_EQ(t.erase(t.lower_bound(One), t.upper_bound(One)), t.find(Two)); - EXPECT_FALSE(s.contains(One)); + EXPECT_EQ(s.erase(s.find(kOne)), s.find(kTwo)); + EXPECT_EQ(t.erase(t.lower_bound(kOne), t.upper_bound(kOne)), t.find(kTwo)); + EXPECT_FALSE(s.contains(kOne)); EXPECT_EQ(s, t); EXPECT_EQ(s.size(), 2u); EXPECT_EQ(t.size(), 2u); - EXPECT_INSERTION(s, One, true); - EXPECT_INSERTION(t, One, true); + EXPECT_INSERTION(s, kOne, true); + EXPECT_INSERTION(t, kOne, true); EXPECT_EQ(s, t); EXPECT_EQ(s.size(), 3u); EXPECT_EQ(t.size(), 3u); - EXPECT_EQ(s.erase(s.find(Two), s.end()), s.end()); - EXPECT_EQ(t.erase(t.lower_bound(Two), t.upper_bound(Four)), t.end()); - EXPECT_TRUE(s.contains(One)); + EXPECT_EQ(s.erase(s.find(kTwo), s.end()), s.end()); + EXPECT_EQ(t.erase(t.lower_bound(kTwo), t.upper_bound(kFour)), t.end()); + EXPECT_TRUE(s.contains(kOne)); EXPECT_EQ(s, t); EXPECT_EQ(s.size(), 1u); EXPECT_EQ(t.size(), 1u); - EXPECT_INSERTION(s, Two, true); - EXPECT_INSERTION(t, Two, true); - EXPECT_INSERTION(s, Four, true); - EXPECT_INSERTION(t, Four, true); + EXPECT_INSERTION(s, kTwo, true); + EXPECT_INSERTION(t, kTwo, true); + EXPECT_INSERTION(s, kFour, true); + EXPECT_INSERTION(t, kFour, true); EXPECT_EQ(s, t); EXPECT_EQ(s.size(), 3u); EXPECT_EQ(t.size(), 3u); @@ -498,7 +509,7 @@ EXPECT_EQ(s, DS()); EXPECT_TRUE(s.empty()); - s.insert(Three); + s.insert(kThree); s.insert_all(t); EXPECT_EQ(s.size(), 4u); EXPECT_EQ(t.size(), 3u); @@ -506,20 +517,20 @@ EXPECT_FALSE(s.contains_none(t)); EXPECT_TRUE(s.contains_any(t)); EXPECT_TRUE(s.contains_all(t)); - EXPECT_TRUE(s.contains(Three)); + EXPECT_TRUE(s.contains(kThree)); EXPECT_FALSE(t.contains_none(s)); EXPECT_TRUE(t.contains_any(s)); EXPECT_FALSE(t.contains_all(s)); s.erase_all(t); EXPECT_EQ(s.size(), 1u); - EXPECT_TRUE(s.contains(Three)); + EXPECT_TRUE(s.contains(kThree)); EXPECT_TRUE(s.contains_none(t)); EXPECT_FALSE(s.contains_any(t)); EXPECT_FALSE(s.contains_all(t)); s.insert_all(t); - s.erase(Three); + s.erase(kThree); EXPECT_EQ(s.size(), 3u); EXPECT_EQ(s, t); @@ -527,11 +538,11 @@ EXPECT_TRUE(s.empty()); EXPECT_INSERTION(s, *t.begin(), true); - EXPECT_TRUE(s.contains(One)); + EXPECT_TRUE(s.contains(kOne)); EXPECT_INSERTION(s, *std::next(t.begin()), true); - EXPECT_TRUE(s.contains(Two)); + EXPECT_TRUE(s.contains(kTwo)); EXPECT_INSERTION(s, *std::prev(t.end()), true); - EXPECT_TRUE(s.contains(Four)); + EXPECT_TRUE(s.contains(kFour)); EXPECT_EQ(s, t); EXPECT_EQ(s.size(), 3u); EXPECT_EQ(t.size(), 3u); @@ -539,7 +550,7 @@ TEST(DenseSetTest, std_set) { constexpr size_t kMaxValue = 50; - DenseSet<size_t, kMaxValue> dense_set; + DenseSet<size_t, 0, kMaxValue> dense_set; std::set<size_t> std_set; auto expect_equivalence = [&] {
diff --git a/components/bookmarks/browser/bookmark_model.h b/components/bookmarks/browser/bookmark_model.h index 8258c2b..183c033 100644 --- a/components/bookmarks/browser/bookmark_model.h +++ b/components/bookmarks/browser/bookmark_model.h
@@ -483,12 +483,12 @@ // |owned_root_|. Once loading has completed, |owned_root_| is destroyed and // this is set to url_index_->root(). |owned_root_| is done as lots of // existing code assumes the root is non-null while loading. - raw_ptr<BookmarkNode, DanglingUntriaged> root_ = nullptr; + raw_ptr<BookmarkNode, DanglingAcrossTasks> root_ = nullptr; - raw_ptr<BookmarkPermanentNode, DanglingUntriaged> bookmark_bar_node_ = + raw_ptr<BookmarkPermanentNode, DanglingAcrossTasks> bookmark_bar_node_ = nullptr; - raw_ptr<BookmarkPermanentNode, DanglingUntriaged> other_node_ = nullptr; - raw_ptr<BookmarkPermanentNode, DanglingUntriaged> mobile_node_ = nullptr; + raw_ptr<BookmarkPermanentNode, DanglingAcrossTasks> other_node_ = nullptr; + raw_ptr<BookmarkPermanentNode, DanglingAcrossTasks> mobile_node_ = nullptr; // The maximum ID assigned to the bookmark nodes in the model. int64_t next_node_id_ = 1;
diff --git a/components/component_updater/installer_policies/BUILD.gn b/components/component_updater/installer_policies/BUILD.gn index 983e308..39fb776 100644 --- a/components/component_updater/installer_policies/BUILD.gn +++ b/components/component_updater/installer_policies/BUILD.gn
@@ -18,8 +18,8 @@ "autofill_states_component_installer.h", "client_side_phishing_component_installer_policy.cc", "client_side_phishing_component_installer_policy.h", - "masked_domain_list_component_installer.cc", - "masked_domain_list_component_installer.h", + "masked_domain_list_component_installer_policy.cc", + "masked_domain_list_component_installer_policy.h", "origin_trials_component_installer.cc", "origin_trials_component_installer.h", "safety_tips_component_installer.cc", @@ -63,7 +63,7 @@ testonly = true sources = [ "autofill_states_component_installer_unittest.cc", - "masked_domain_list_component_installer_unittest.cc", + "masked_domain_list_component_installer_policy_unittest.cc", "optimization_hints_component_installer_unittest.cc", "trust_token_key_commitments_component_installer_policy_unittest.cc", ]
diff --git a/components/component_updater/installer_policies/masked_domain_list_component_installer.cc b/components/component_updater/installer_policies/masked_domain_list_component_installer_policy.cc similarity index 75% rename from components/component_updater/installer_policies/masked_domain_list_component_installer.cc rename to components/component_updater/installer_policies/masked_domain_list_component_installer_policy.cc index 888d181..34b3c3d 100644 --- a/components/component_updater/installer_policies/masked_domain_list_component_installer.cc +++ b/components/component_updater/installer_policies/masked_domain_list_component_installer_policy.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/component_updater/installer_policies/masked_domain_list_component_installer.h" +#include "components/component_updater/installer_policies/masked_domain_list_component_installer_policy.h" #include <utility> @@ -13,12 +13,10 @@ #include "base/functional/bind.h" #include "base/functional/callback.h" #include "base/logging.h" -#include "base/no_destructor.h" #include "base/task/thread_pool.h" #include "base/version.h" #include "components/component_updater/component_installer.h" #include "services/network/public/cpp/features.h" -#include "third_party/abseil-cpp/absl/types/optional.h" using component_updater::ComponentUpdateService; @@ -28,7 +26,7 @@ MaskedDomainListComponentInstallerPolicy::ListReadyRepeatingCallback; constexpr base::FilePath::CharType kMaskedDomainListFileName[] = - FILE_PATH_LITERAL("list.json"); + FILE_PATH_LITERAL("list.pb"); // The SHA256 of the SubjectPublicKeyInfo used to sign the extension. // The extension id is: cffplpkejcbdpfnfabnjikeicbedmifn @@ -42,18 +40,12 @@ constexpr base::FilePath::CharType kMaskedDomainListRelativeInstallDir[] = FILE_PATH_LITERAL("MaskedDomainListPreloaded"); -base::File OpenFile(const base::FilePath& pb_path) { - return base::File(pb_path, base::File::FLAG_OPEN | base::File::FLAG_READ); -} - -bool IsMaskedDomainListEnabled() { - // TODO(aakallam): move this to a more accessible location. - return base::FeatureList::IsEnabled(network::features::kMaskedDomainList); -} - -base::TaskPriority GetTaskPriority() { - return IsMaskedDomainListEnabled() ? base::TaskPriority::USER_BLOCKING - : base::TaskPriority::BEST_EFFORT; +std::string ReadFile(const base::FilePath& pb_path) { + std::string raw_list; + base::ScopedFILE file(FileToFILE( + base::File(pb_path, base::File::FLAG_OPEN | base::File::FLAG_READ), "r")); + CHECK(base::ReadStreamToString(file.get(), &raw_list)); + return raw_list; } } // namespace @@ -75,6 +67,10 @@ return true; } +bool MaskedDomainListComponentInstallerPolicy::IsEnabled() { + return base::FeatureList::IsEnabled(network::features::kMaskedDomainList); +} + bool MaskedDomainListComponentInstallerPolicy::RequiresNetworkEncryption() const { // Update checks and pings associated with this component do not require @@ -100,7 +96,7 @@ const base::Version& version, const base::FilePath& install_dir, base::Value::Dict manifest) { - if (install_dir.empty() || !IsMaskedDomainListEnabled()) { + if (install_dir.empty() || !IsEnabled()) { return; } @@ -108,8 +104,8 @@ << version.GetString() << " in " << install_dir.value(); base::ThreadPool::PostTaskAndReplyWithResult( - FROM_HERE, {base::MayBlock(), GetTaskPriority()}, - base::BindOnce(&OpenFile, GetInstalledPath(install_dir)), + FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_BLOCKING}, + base::BindOnce(&ReadFile, GetInstalledPath(install_dir)), base::BindOnce(on_list_ready_, version)); } @@ -142,22 +138,4 @@ return update_client::InstallerAttributes(); } -void RegisterMaskedDomainListComponent(ComponentUpdateService* cus) { - if (!IsMaskedDomainListEnabled()) { - return; - } - - VLOG(1) << "Registering Masked Domain List component."; - - auto policy = std::make_unique<MaskedDomainListComponentInstallerPolicy>( - /*on_list_ready=*/base::BindRepeating( - [](base::Version version, base::File list_file) { - VLOG(1) << "Received Masked Domain List"; - // TODO(aakallam): do something with the file - })); - - base::MakeRefCounted<ComponentInstaller>(std::move(policy)) - ->Register(cus, base::OnceClosure(), GetTaskPriority()); -} - } // namespace component_updater
diff --git a/components/component_updater/installer_policies/masked_domain_list_component_installer.h b/components/component_updater/installer_policies/masked_domain_list_component_installer_policy.h similarity index 84% rename from components/component_updater/installer_policies/masked_domain_list_component_installer.h rename to components/component_updater/installer_policies/masked_domain_list_component_installer_policy.h index b64d854..0ff4a3fb 100644 --- a/components/component_updater/installer_policies/masked_domain_list_component_installer.h +++ b/components/component_updater/installer_policies/masked_domain_list_component_installer_policy.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_COMPONENT_UPDATER_INSTALLER_POLICIES_MASKED_DOMAIN_LIST_COMPONENT_INSTALLER_H_ -#define COMPONENTS_COMPONENT_UPDATER_INSTALLER_POLICIES_MASKED_DOMAIN_LIST_COMPONENT_INSTALLER_H_ +#ifndef COMPONENTS_COMPONENT_UPDATER_INSTALLER_POLICIES_MASKED_DOMAIN_LIST_COMPONENT_INSTALLER_POLICY_H_ +#define COMPONENTS_COMPONENT_UPDATER_INSTALLER_POLICIES_MASKED_DOMAIN_LIST_COMPONENT_INSTALLER_POLICY_H_ #include <stdint.h> @@ -32,7 +32,7 @@ : public ComponentInstallerPolicy { public: using ListReadyRepeatingCallback = - base::RepeatingCallback<void(base::Version, base::File)>; + base::RepeatingCallback<void(base::Version, std::string)>; // |on_list_ready| will be called on the UI thread when the list is ready. It // is exposed here for testing. @@ -45,14 +45,18 @@ MaskedDomainListComponentInstallerPolicy operator=( const MaskedDomainListComponentInstallerPolicy&) = delete; + static bool IsEnabled(); + + static base::FilePath GetInstalledPath(const base::FilePath& base); + private: - FRIEND_TEST_ALL_PREFIXES(MaskedDomainListComponentInstallerTest, + FRIEND_TEST_ALL_PREFIXES(MaskedDomainListComponentInstallerPolicyTest, NonexistentFile); - FRIEND_TEST_ALL_PREFIXES(MaskedDomainListComponentInstallerTest, + FRIEND_TEST_ALL_PREFIXES(MaskedDomainListComponentInstallerPolicyTest, NonexistentFile_OnComponentReady); - FRIEND_TEST_ALL_PREFIXES(MaskedDomainListComponentInstallerTest, + FRIEND_TEST_ALL_PREFIXES(MaskedDomainListComponentInstallerPolicyTest, LoadsFile_OnComponentReady); - FRIEND_TEST_ALL_PREFIXES(MaskedDomainListComponentInstallerTest, + FRIEND_TEST_ALL_PREFIXES(MaskedDomainListComponentInstallerPolicyTest, LoadsNewListWhenUpdated); // The following methods override ComponentInstallerPolicy. @@ -72,8 +76,6 @@ std::string GetName() const override; update_client::InstallerAttributes GetInstallerAttributes() const override; - static base::FilePath GetInstalledPath(const base::FilePath& base); - ListReadyRepeatingCallback on_list_ready_; }; @@ -83,4 +85,4 @@ } // namespace component_updater -#endif // COMPONENTS_COMPONENT_UPDATER_INSTALLER_POLICIES_MASKED_DOMAIN_LIST_COMPONENT_INSTALLER_H_ +#endif // COMPONENTS_COMPONENT_UPDATER_INSTALLER_POLICIES_MASKED_DOMAIN_LIST_COMPONENT_INSTALLER_POLICY_H_
diff --git a/components/component_updater/installer_policies/masked_domain_list_component_installer_policy_unittest.cc b/components/component_updater/installer_policies/masked_domain_list_component_installer_policy_unittest.cc new file mode 100644 index 0000000..a2e46848 --- /dev/null +++ b/components/component_updater/installer_policies/masked_domain_list_component_installer_policy_unittest.cc
@@ -0,0 +1,108 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/component_updater/installer_policies/masked_domain_list_component_installer_policy.h" + +#include "base/check.h" +#include "base/files/file.h" +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/logging.h" +#include "base/test/repeating_test_future.h" +#include "base/test/scoped_feature_list.h" +#include "base/test/task_environment.h" +#include "base/version.h" +#include "components/component_updater/mock_component_updater_service.h" +#include "services/network/public/cpp/features.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace component_updater { + +namespace { +using ::testing::_; + +} // namespace + +class MaskedDomainListComponentInstallerPolicyTest : public ::testing::Test { + public: + MaskedDomainListComponentInstallerPolicyTest() { + CHECK(component_install_dir_.CreateUniqueTempDir()); + } + + protected: + base::test::TaskEnvironment env_; + base::test::ScopedFeatureList scoped_feature_list_; + + base::ScopedTempDir component_install_dir_; +}; + +TEST_F(MaskedDomainListComponentInstallerPolicyTest, + LoadsFile_OnComponentReady) { + scoped_feature_list_.InitAndEnableFeature( + network::features::kMaskedDomainList); + const base::Version version = base::Version("0.0.1"); + const std::string expectation = "some list contents"; + base::test::RepeatingTestFuture<base::Version, std::string> future; + auto policy = MaskedDomainListComponentInstallerPolicy(future.GetCallback()); + + ASSERT_TRUE(base::WriteFile( + MaskedDomainListComponentInstallerPolicy::GetInstalledPath( + component_install_dir_.GetPath()), + expectation)); + + policy.ComponentReady(version, component_install_dir_.GetPath(), + base::Value::Dict()); + + std::tuple<base::Version, std::string> got = future.Take(); + EXPECT_TRUE(std::get<0>(got).IsValid()); + EXPECT_EQ(std::get<0>(got), version); + EXPECT_EQ(std::get<1>(got), expectation); +} + +TEST_F(MaskedDomainListComponentInstallerPolicyTest, LoadsNewListWhenUpdated) { + scoped_feature_list_.InitAndEnableFeature( + network::features::kMaskedDomainList); + + base::test::RepeatingTestFuture<base::Version, std::string> future; + auto policy = MaskedDomainListComponentInstallerPolicy(future.GetCallback()); + + const base::Version version1 = base::Version("0.0.1"); + const std::string list_v1 = "MDL v1"; + base::ScopedTempDir dir_v1; + ASSERT_TRUE( + dir_v1.CreateUniqueTempDirUnderPath(component_install_dir_.GetPath())); + ASSERT_TRUE(base::WriteFile( + MaskedDomainListComponentInstallerPolicy::GetInstalledPath( + dir_v1.GetPath()), + list_v1)); + policy.ComponentReady(version1, dir_v1.GetPath(), base::Value::Dict()); + + std::tuple<base::Version, std::string> got = future.Take(); + EXPECT_TRUE(std::get<0>(got).IsValid()); + EXPECT_EQ(std::get<0>(got), version1); + EXPECT_EQ(std::get<1>(got), list_v1); + + // Install newer version of the component, which should be picked up + // when calling ComponentReady again. + const base::Version version2 = base::Version("0.0.2"); + const std::string list_v2 = "MDL v2"; + base::ScopedTempDir dir_v2; + ASSERT_TRUE( + dir_v2.CreateUniqueTempDirUnderPath(component_install_dir_.GetPath())); + ASSERT_TRUE(base::WriteFile( + MaskedDomainListComponentInstallerPolicy::GetInstalledPath( + dir_v2.GetPath()), + list_v2)); + policy.ComponentReady(version2, dir_v2.GetPath(), base::Value::Dict()); + + std::tuple<base::Version, std::string> got2 = future.Take(); + EXPECT_TRUE(std::get<0>(got2).IsValid()); + EXPECT_EQ(std::get<0>(got2), version2); + EXPECT_EQ(std::get<1>(got2), list_v2); + + env_.RunUntilIdle(); +} + +} // namespace component_updater
diff --git a/components/component_updater/installer_policies/masked_domain_list_component_installer_unittest.cc b/components/component_updater/installer_policies/masked_domain_list_component_installer_unittest.cc deleted file mode 100644 index a2fdf9b1..0000000 --- a/components/component_updater/installer_policies/masked_domain_list_component_installer_unittest.cc +++ /dev/null
@@ -1,156 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/component_updater/installer_policies/masked_domain_list_component_installer.h" - -#include "base/check.h" -#include "base/files/file.h" -#include "base/files/file_util.h" -#include "base/files/scoped_temp_dir.h" -#include "base/logging.h" -#include "base/test/repeating_test_future.h" -#include "base/test/scoped_feature_list.h" -#include "base/test/task_environment.h" -#include "base/version.h" -#include "components/component_updater/mock_component_updater_service.h" -#include "services/network/public/cpp/features.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace component_updater { - -namespace { -using ::testing::_; - -std::string ReadToString(base::File file) { - std::string contents; - base::ScopedFILE scoped_file(base::FileToFILE(std::move(file), "r")); - return base::ReadStreamToString(scoped_file.get(), &contents) ? contents : ""; -} - -} // namespace - -class MaskedDomainListComponentInstallerTest : public ::testing::Test { - public: - MaskedDomainListComponentInstallerTest() { - CHECK(component_install_dir_.CreateUniqueTempDir()); - } - - protected: - base::test::TaskEnvironment env_; - base::test::ScopedFeatureList scoped_feature_list_; - - base::ScopedTempDir component_install_dir_; -}; - -TEST_F(MaskedDomainListComponentInstallerTest, FeatureDisabled) { - scoped_feature_list_.InitAndDisableFeature( - network::features::kMaskedDomainList); - auto service = - std::make_unique<component_updater::MockComponentUpdateService>(); - EXPECT_CALL(*service, RegisterComponent(_)).Times(0); - RegisterMaskedDomainListComponent(service.get()); - - env_.RunUntilIdle(); -} - -TEST_F(MaskedDomainListComponentInstallerTest, FeatureEnabled) { - scoped_feature_list_.InitAndEnableFeature( - network::features::kMaskedDomainList); - auto service = - std::make_unique<component_updater::MockComponentUpdateService>(); - EXPECT_CALL(*service, RegisterComponent(_)).Times(1); - RegisterMaskedDomainListComponent(service.get()); - - env_.RunUntilIdle(); -} - -TEST_F(MaskedDomainListComponentInstallerTest, - NonexistentFile_OnComponentReady) { - scoped_feature_list_.InitAndEnableFeature( - network::features::kMaskedDomainList); - ASSERT_TRUE(base::DeleteFile( - MaskedDomainListComponentInstallerPolicy::GetInstalledPath( - component_install_dir_.GetPath()))); - - base::test::RepeatingTestFuture<base::Version, base::File> future; - MaskedDomainListComponentInstallerPolicy(future.GetCallback()) - .ComponentReady(base::Version(), component_install_dir_.GetPath(), - base::Value::Dict()); - - std::tuple<base::Version, base::File> got = future.Take(); - EXPECT_FALSE(std::get<0>(got).IsValid()); - EXPECT_FALSE(std::get<1>(got).IsValid()); -} - -TEST_F(MaskedDomainListComponentInstallerTest, LoadsFile_OnComponentReady) { - scoped_feature_list_.InitAndEnableFeature( - network::features::kMaskedDomainList); - const base::Version version = base::Version("0.0.1"); - const std::string expectation = "some list contents"; - base::test::RepeatingTestFuture<base::Version, base::File> future; - auto policy = MaskedDomainListComponentInstallerPolicy(future.GetCallback()); - - ASSERT_TRUE(base::WriteFile( - MaskedDomainListComponentInstallerPolicy::GetInstalledPath( - component_install_dir_.GetPath()), - expectation)); - - policy.ComponentReady(version, component_install_dir_.GetPath(), - base::Value::Dict()); - - std::tuple<base::Version, base::File> got = future.Take(); - EXPECT_TRUE(std::get<0>(got).IsValid()); - EXPECT_EQ(std::get<0>(got), version); - EXPECT_TRUE(std::get<1>(got).IsValid()); - EXPECT_EQ(ReadToString(std::move(std::get<1>(got))), expectation); -} - -TEST_F(MaskedDomainListComponentInstallerTest, LoadsNewListWhenUpdated) { - scoped_feature_list_.InitAndEnableFeature( - network::features::kMaskedDomainList); - - base::test::RepeatingTestFuture<base::Version, base::File> future; - auto policy = MaskedDomainListComponentInstallerPolicy(future.GetCallback()); - - const base::Version version1 = base::Version("0.0.1"); - const std::string list_v1 = "MDL v1"; - base::ScopedTempDir dir_v1; - ASSERT_TRUE( - dir_v1.CreateUniqueTempDirUnderPath(component_install_dir_.GetPath())); - ASSERT_TRUE(base::WriteFile( - MaskedDomainListComponentInstallerPolicy::GetInstalledPath( - dir_v1.GetPath()), - list_v1)); - policy.ComponentReady(version1, dir_v1.GetPath(), base::Value::Dict()); - - std::tuple<base::Version, base::File> got = future.Take(); - EXPECT_TRUE(std::get<0>(got).IsValid()); - EXPECT_EQ(std::get<0>(got), version1); - EXPECT_TRUE(std::get<1>(got).IsValid()); - EXPECT_EQ(ReadToString(std::move(std::get<1>(got))), list_v1); - - // Install newer version of the component, which should be picked up - // when calling ComponentReady again. - const base::Version version2 = base::Version("0.0.2"); - const std::string list_v2 = "MDL v2"; - base::ScopedTempDir dir_v2; - ASSERT_TRUE( - dir_v2.CreateUniqueTempDirUnderPath(component_install_dir_.GetPath())); - ASSERT_TRUE(base::WriteFile( - MaskedDomainListComponentInstallerPolicy::GetInstalledPath( - dir_v2.GetPath()), - list_v2)); - policy.ComponentReady(version2, dir_v2.GetPath(), base::Value::Dict()); - - std::tuple<base::Version, base::File> got2 = future.Take(); - EXPECT_TRUE(std::get<0>(got2).IsValid()); - EXPECT_EQ(std::get<0>(got2), version2); - EXPECT_TRUE(std::get<1>(got2).IsValid()); - EXPECT_EQ(ReadToString(std::move(std::get<1>(got2))), list_v2); - - env_.RunUntilIdle(); -} - -} // namespace component_updater
diff --git a/components/download/internal/background_service/scheduler/scheduler_impl.h b/components/download/internal/background_service/scheduler/scheduler_impl.h index df20e2b4..53dcd9e 100644 --- a/components/download/internal/background_service/scheduler/scheduler_impl.h +++ b/components/download/internal/background_service/scheduler/scheduler_impl.h
@@ -54,7 +54,7 @@ const DeviceStatus& device_status); // Used to create platform dependent background tasks. - raw_ptr<TaskScheduler, DanglingUntriaged> task_scheduler_; + raw_ptr<TaskScheduler, DanglingAcrossTasks> task_scheduler_; // Download service configuration. raw_ptr<Configuration, DanglingUntriaged> config_;
diff --git a/components/feedback/redaction_tool/BUILD.gn b/components/feedback/redaction_tool/BUILD.gn index 1ad1dfa..09bc571 100644 --- a/components/feedback/redaction_tool/BUILD.gn +++ b/components/feedback/redaction_tool/BUILD.gn
@@ -4,11 +4,14 @@ static_library("redaction_tool") { sources = [ + "inprocess_metrics_recorder.cc", + "inprocess_metrics_recorder.h", "ip_address.cc", "ip_address.h", "pii_types.h", "redaction_tool.cc", "redaction_tool.h", + "redaction_tool_metrics_recorder.h", "url_canon.h", "url_canon_internal.cc", "url_canon_internal.h", @@ -33,7 +36,12 @@ source_set("unit_tests") { testonly = true - sources = [ "redaction_tool_unittest.cc" ] + sources = [ + "inprocess_metrics_tester.cc", + "inprocess_metrics_tester.h", + "metrics_tester.h", + "redaction_tool_unittest.cc", + ] deps = [ ":redaction_tool", "//base/test:test_support",
diff --git a/components/feedback/redaction_tool/inprocess_metrics_recorder.cc b/components/feedback/redaction_tool/inprocess_metrics_recorder.cc new file mode 100644 index 0000000..772857f --- /dev/null +++ b/components/feedback/redaction_tool/inprocess_metrics_recorder.cc
@@ -0,0 +1,25 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/feedback/redaction_tool/inprocess_metrics_recorder.h" + +#include "base/metrics/histogram_macros.h" + +namespace redaction { + +std::unique_ptr<RedactionToolMetricsRecorder> +RedactionToolMetricsRecorder::Create() { + return std::make_unique<InprocessMetricsRecorder>(); +} + +void InprocessMetricsRecorder::RecordPIIRedactedHistogram(PIIType pii_type) { + UMA_HISTOGRAM_ENUMERATION(kPIIRedactedHistogram, pii_type); +} + +void InprocessMetricsRecorder::RecordCreditCardRedactionHistogram( + CreditCardDetection step) { + UMA_HISTOGRAM_ENUMERATION(kCreditCardRedactionHistogram, step); +} + +} // namespace redaction
diff --git a/components/feedback/redaction_tool/inprocess_metrics_recorder.h b/components/feedback/redaction_tool/inprocess_metrics_recorder.h new file mode 100644 index 0000000..8aba68b --- /dev/null +++ b/components/feedback/redaction_tool/inprocess_metrics_recorder.h
@@ -0,0 +1,29 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_FEEDBACK_REDACTION_TOOL_INPROCESS_METRICS_RECORDER_H_ +#define COMPONENTS_FEEDBACK_REDACTION_TOOL_INPROCESS_METRICS_RECORDER_H_ + +#include "components/feedback/redaction_tool/redaction_tool_metrics_recorder.h" + +namespace redaction { + +// Record the metrics and store them in a memory location of the program. +// This is the default implementation for the `RedactionToolMetricsRecorder` in +// Chromium. +class InprocessMetricsRecorder : public RedactionToolMetricsRecorder { + public: + InprocessMetricsRecorder() = default; + InprocessMetricsRecorder(const InprocessMetricsRecorder&) = delete; + InprocessMetricsRecorder& operator=(const InprocessMetricsRecorder&) = delete; + ~InprocessMetricsRecorder() override = default; + + // redaction::RedactionToolMetricsRecorder: + void RecordPIIRedactedHistogram(PIIType pii_type) override; + void RecordCreditCardRedactionHistogram(CreditCardDetection step) override; +}; + +} // namespace redaction + +#endif
diff --git a/components/feedback/redaction_tool/inprocess_metrics_tester.cc b/components/feedback/redaction_tool/inprocess_metrics_tester.cc new file mode 100644 index 0000000..3646b4d --- /dev/null +++ b/components/feedback/redaction_tool/inprocess_metrics_tester.cc
@@ -0,0 +1,25 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/feedback/redaction_tool/inprocess_metrics_tester.h" + +#include "components/feedback/redaction_tool/inprocess_metrics_recorder.h" + +namespace redaction { + +std::unique_ptr<MetricsTester> MetricsTester::Create() { + return std::make_unique<InprocessMetricsTester>(); +} + +size_t InprocessMetricsTester::GetBucketCount(base::StringPiece histogram_name, + int histogram_value) { + return histogram_tester_.GetBucketCount(histogram_name, histogram_value); +} + +std::unique_ptr<RedactionToolMetricsRecorder> +InprocessMetricsTester::SetupRecorder() { + return std::make_unique<InprocessMetricsRecorder>(); +} + +} // namespace redaction
diff --git a/components/feedback/redaction_tool/inprocess_metrics_tester.h b/components/feedback/redaction_tool/inprocess_metrics_tester.h new file mode 100644 index 0000000..8a2aef0 --- /dev/null +++ b/components/feedback/redaction_tool/inprocess_metrics_tester.h
@@ -0,0 +1,33 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_FEEDBACK_REDACTION_TOOL_INPROCESS_METRICS_TESTER_H_ +#define COMPONENTS_FEEDBACK_REDACTION_TOOL_INPROCESS_METRICS_TESTER_H_ + +#include "base/test/metrics/histogram_tester.h" +#include "components/feedback/redaction_tool/metrics_tester.h" + +namespace redaction { + +// A class used for testing to retrieve bucket values for histograms. +// This is the default implementation for the `MetricsTester` in Chromium. +class InprocessMetricsTester : public MetricsTester { + public: + InprocessMetricsTester() = default; + InprocessMetricsTester(const InprocessMetricsTester&) = delete; + InprocessMetricsTester& operator=(const InprocessMetricsTester&) = delete; + ~InprocessMetricsTester() override = default; + + // redaction::MetricsTester: + size_t GetBucketCount(base::StringPiece histogram_name, + int histogram_value) override; + std::unique_ptr<RedactionToolMetricsRecorder> SetupRecorder() override; + + private: + const base::HistogramTester histogram_tester_; +}; + +} // namespace redaction + +#endif
diff --git a/components/feedback/redaction_tool/metrics_tester.h b/components/feedback/redaction_tool/metrics_tester.h new file mode 100644 index 0000000..b9d0fb8 --- /dev/null +++ b/components/feedback/redaction_tool/metrics_tester.h
@@ -0,0 +1,39 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_FEEDBACK_REDACTION_TOOL_METRICS_TESTER_H_ +#define COMPONENTS_FEEDBACK_REDACTION_TOOL_METRICS_TESTER_H_ + +#include <memory> + +#include "base/strings/string_piece.h" +#include "components/feedback/redaction_tool/redaction_tool_metrics_recorder.h" + +namespace redaction { + +// A helper class for testing metric collection on Chromium and ChromiumOS. +class MetricsTester { + public: + // Create a new instance of the default implementation for this platform. + static std::unique_ptr<MetricsTester> Create(); + + MetricsTester() = default; + MetricsTester(const MetricsTester&) = delete; + MetricsTester& operator=(const MetricsTester&) = delete; + virtual ~MetricsTester() = default; + + // Get the number of times a histogram value was recorded while this instance + // exists and the values are recorded with the recorder from + // `SetupRecorder()`. + virtual size_t GetBucketCount(base::StringPiece histogram_name, + int histogram_value) = 0; + + // Create a `RedactionToolMetricsRecorder` that is configured so it can return + // metric values in `GetBucketCount()`. + virtual std::unique_ptr<RedactionToolMetricsRecorder> SetupRecorder() = 0; +}; + +} // namespace redaction + +#endif // COMPONENTS_FEEDBACK_REDACTION_TOOL_METRICS_TESTER_H_
diff --git a/components/feedback/redaction_tool/redaction_tool.cc b/components/feedback/redaction_tool/redaction_tool.cc index 4f130e78..912813c 100644 --- a/components/feedback/redaction_tool/redaction_tool.cc +++ b/components/feedback/redaction_tool/redaction_tool.cc
@@ -10,7 +10,6 @@ #include <vector> #include "base/files/file_path.h" -#include "base/metrics/histogram_macros.h" #include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" @@ -529,26 +528,6 @@ }; constexpr size_t kNumUnredactedMacs = std::size(kUnredactedMacAddresses); -void RecordPIIRedactedHistogram(const PIIType pii_type) { - UMA_HISTOGRAM_ENUMERATION("Feedback.RedactionTool", pii_type); -} - -// These values are logged to UMA. Entries should not be renumbered and -// numeric values should never be reused. Please keep in sync with -// "CreditCardDetection" in //tools/metrics/histograms/enums.xml. -enum class CreditCardDetection { - kRegexMatch = 1, - kTimestamp = 2, - kRepeatedChars = 3, - kDoesntValidate = 4, - kValidated = 5, - kMaxValue = kValidated, -}; - -void RecordCreditCardRedactionHistogram(CreditCardDetection step) { - UMA_HISTOGRAM_ENUMERATION("Feedback.RedactionTool.CreditCardMatch", step); -} - bool IsFeatureEnabled(const base::Feature& feature) { return base::FeatureList::GetInstance() ? base::FeatureList::IsEnabled(feature) @@ -557,7 +536,15 @@ } // namespace RedactionTool::RedactionTool(const char* const* first_party_extension_ids) - : first_party_extension_ids_(first_party_extension_ids) { + : RedactionTool(first_party_extension_ids, + RedactionToolMetricsRecorder::Create()) {} + +RedactionTool::RedactionTool( + const char* const* first_party_extension_ids, + std::unique_ptr<RedactionToolMetricsRecorder> metrics_recorder) + : first_party_extension_ids_(first_party_extension_ids), + metrics_recorder_(std::move(metrics_recorder)) { + CHECK(metrics_recorder_); DETACH_FROM_SEQUENCE(sequence_checker_); // Identity-map these, so we don't mangle them. for (const char* mac : kUnredactedMacAddresses) { @@ -705,7 +692,7 @@ } result.append(skipped); result += replacement_mac; - RecordPIIRedactedHistogram(PIIType::kMACAddress); + metrics_recorder_->RecordPIIRedactedHistogram(PIIType::kMACAddress); } result.append(text); @@ -763,7 +750,7 @@ result += replacement_hash; - RecordPIIRedactedHistogram(PIIType::kStableIdentifier); + metrics_recorder_->RecordPIIRedactedHistogram(PIIType::kStableIdentifier); } result.append(text); @@ -830,7 +817,8 @@ if (detected != nullptr) { (*detected)[PIIType::kAndroidAppStoragePath].emplace(app_specific); } - RecordPIIRedactedHistogram(PIIType::kAndroidAppStoragePath); + metrics_recorder_->RecordPIIRedactedHistogram( + PIIType::kAndroidAppStoragePath); } result.append(text); @@ -867,20 +855,23 @@ while (FindAndConsumeAndGetSkipped(&text, *cc_re, &skipped, &sequence, &post_sequence)) { result.append(skipped); - RecordCreditCardRedactionHistogram(CreditCardDetection::kRegexMatch); + metrics_recorder_->RecordCreditCardRedactionHistogram( + CreditCardDetection::kRegexMatch); // Timestamps in ms have a surprisingly high number of false positives. // Also log entries but those usually only match if there are several spaces // tying unrelated numbers together. if (post_sequence.find("ms") != re2::StringPiece::npos) { - RecordCreditCardRedactionHistogram(CreditCardDetection::kTimestamp); + metrics_recorder_->RecordCreditCardRedactionHistogram( + CreditCardDetection::kTimestamp); result.append(sequence); result.append(post_sequence); continue; } if (HasRepeatedChar(sequence, ' ') || HasRepeatedChar(sequence, '-')) { - RecordCreditCardRedactionHistogram(CreditCardDetection::kRepeatedChars); + metrics_recorder_->RecordCreditCardRedactionHistogram( + CreditCardDetection::kRepeatedChars); result.append(sequence); result.append(post_sequence); continue; @@ -893,18 +884,21 @@ if (cc_it != credit_cards_.cend()) { result += cc_it->second; result.append(post_sequence); - RecordCreditCardRedactionHistogram(CreditCardDetection::kValidated); + metrics_recorder_->RecordCreditCardRedactionHistogram( + CreditCardDetection::kValidated); + metrics_recorder_->RecordPIIRedactedHistogram(PIIType::kCreditCard); continue; } if (redaction::IsValidCreditCardNumber(number)) { - RecordCreditCardRedactionHistogram(CreditCardDetection::kValidated); + metrics_recorder_->RecordCreditCardRedactionHistogram( + CreditCardDetection::kValidated); const auto& [it, success] = credit_cards_.emplace( number, base::StrCat({"(CREDITCARD: ", base::NumberToString(credit_cards_.size() + 1), ")"})); if (redact_credit_cards_) { - RecordPIIRedactedHistogram(PIIType::kCreditCard); + metrics_recorder_->RecordPIIRedactedHistogram(PIIType::kCreditCard); result += it->second; } else { result.append(sequence); @@ -913,7 +907,8 @@ (*detected)[PIIType::kCreditCard].insert(it->first); } } else { - RecordCreditCardRedactionHistogram(CreditCardDetection::kDoesntValidate); + metrics_recorder_->RecordCreditCardRedactionHistogram( + CreditCardDetection::kDoesntValidate); result.append(sequence); } result.append(post_sequence); @@ -961,6 +956,7 @@ previous_iban != ibans_.end()) { result += previous_iban->second; result.append(post_separating_char); + metrics_recorder_->RecordPIIRedactedHistogram(PIIType::kIBAN); continue; } @@ -1027,7 +1023,7 @@ (*detected)[PIIType::kIBAN].insert(it->first); } - RecordPIIRedactedHistogram(PIIType::kIBAN); + metrics_recorder_->RecordPIIRedactedHistogram(PIIType::kIBAN); } result.append(text); @@ -1099,7 +1095,7 @@ result.append(pre_matched_id); result += replacement_id; result.append(post_matched_id); - RecordPIIRedactedHistogram(pattern.pii_type); + metrics_recorder_->RecordPIIRedactedHistogram(pattern.pii_type); } result.append(text); @@ -1181,46 +1177,46 @@ re2::StringPiece skipped; re2::StringPiece matched_id; while (FindAndConsumeAndGetSkipped(&text, *re, &skipped, &matched_id)) { + result.append(skipped); + if (IsUrlExempt(matched_id, first_party_extension_ids_)) { - result.append(skipped); result.append(matched_id); continue; } - std::string matched_id_as_string(matched_id); - std::string replacement_id; - if (identifier_space->count(matched_id_as_string) == 0) { - replacement_id = MaybeScrubIPAddress(matched_id_as_string); - if (replacement_id != matched_id_as_string) { - // Double-check overly opportunistic IPv4 address matching. - if ((strcmp("IPv4", pattern.alias) == 0) && - ShouldSkipIPAddress(skipped)) { - result.append(skipped); - result.append(matched_id); - continue; - } - // The weird NumberToString trick is because Windows does not like - // to deal with %zu and a size_t in printf, nor does it support %llu. - replacement_id = base::StringPrintf( - "(%s: %s)", - replacement_id.empty() ? pattern.alias : replacement_id.c_str(), - base::NumberToString(identifier_space->size() + 1).c_str()); - (*identifier_space)[matched_id_as_string] = replacement_id; - if (detected != nullptr) { - (*detected)[pattern.pii_type].insert(matched_id_as_string); - } - } - } else { - replacement_id = (*identifier_space)[matched_id_as_string]; - if (detected != nullptr) { - (*detected)[pattern.pii_type].insert(matched_id_as_string); - } + const std::string matched_id_as_string(matched_id); + if (const auto previous_replacement = + identifier_space->find(matched_id_as_string); + previous_replacement != identifier_space->end()) { + metrics_recorder_->RecordPIIRedactedHistogram(pattern.pii_type); + result.append(previous_replacement->second); + continue; } - result.append(skipped); - result += replacement_id; + const std::string scrubbed_match = + MaybeScrubIPAddress(matched_id_as_string); + if (scrubbed_match == matched_id_as_string || + // Double-check overly opportunistic IPv4 address matching. + ((strcmp("IPv4", pattern.alias) == 0) && + ShouldSkipIPAddress(skipped))) { + result.append(matched_id); + continue; + } - RecordPIIRedactedHistogram(pattern.pii_type); + // The weird NumberToString trick is because Windows does not like + // to deal with %zu and a size_t in printf, nor does it support %llu. + const auto [redacted_pair, success] = identifier_space->insert_or_assign( + matched_id_as_string, + base::StringPrintf( + "(%s: %s)", + scrubbed_match.empty() ? pattern.alias : scrubbed_match.c_str(), + base::NumberToString(identifier_space->size() + 1).c_str())); + if (detected != nullptr) { + (*detected)[pattern.pii_type].insert(matched_id_as_string); + } + + result += redacted_pair->second; + metrics_recorder_->RecordPIIRedactedHistogram(pattern.pii_type); } result.append(text); @@ -1233,6 +1229,14 @@ : redactor_(new RedactionTool(first_party_extension_ids)), task_runner_(task_runner) {} +RedactionToolContainer::RedactionToolContainer( + scoped_refptr<base::SequencedTaskRunner> task_runner, + const char* const* first_party_extension_ids, + std::unique_ptr<RedactionToolMetricsRecorder> metrics_recorder) + : redactor_(new RedactionTool(first_party_extension_ids, + std::move(metrics_recorder))), + task_runner_(task_runner) {} + RedactionToolContainer::~RedactionToolContainer() { task_runner_->DeleteSoon(FROM_HERE, std::move(redactor_)); }
diff --git a/components/feedback/redaction_tool/redaction_tool.h b/components/feedback/redaction_tool/redaction_tool.h index f35858b0..5e59b51 100644 --- a/components/feedback/redaction_tool/redaction_tool.h +++ b/components/feedback/redaction_tool/redaction_tool.h
@@ -17,6 +17,7 @@ #include "base/sequence_checker.h" #include "base/task/sequenced_task_runner.h" #include "components/feedback/redaction_tool/pii_types.h" +#include "components/feedback/redaction_tool/redaction_tool_metrics_recorder.h" namespace re2 { class RE2; @@ -57,6 +58,10 @@ // party extension IDs whose URLs won't be redacted. It is OK to pass null for // that value if it's OK to redact those URLs or they won't be present. explicit RedactionTool(const char* const* first_party_extension_ids); + // The `metrics_recorder` is the instance of recorder that should be used on + // this instance instead of the default for the platform. + RedactionTool(const char* const* first_party_extension_ids, + std::unique_ptr<RedactionToolMetricsRecorder> metrics_recorder); ~RedactionTool(); // Return a map of [PII-sensitive data type -> set of data] that are detected @@ -192,6 +197,8 @@ bool redact_credit_cards_ = false; + std::unique_ptr<RedactionToolMetricsRecorder> metrics_recorder_; + SEQUENCE_CHECKER(sequence_checker_); }; @@ -205,6 +212,10 @@ explicit RedactionToolContainer( scoped_refptr<base::SequencedTaskRunner> task_runner, const char* const* first_party_extension_ids); + explicit RedactionToolContainer( + scoped_refptr<base::SequencedTaskRunner> task_runner, + const char* const* first_party_extension_ids, + std::unique_ptr<RedactionToolMetricsRecorder> metrics_recorder); // Returns a pointer to the instance of this redactor. May only be called // on |task_runner_|.
diff --git a/components/feedback/redaction_tool/redaction_tool_metrics_recorder.h b/components/feedback/redaction_tool/redaction_tool_metrics_recorder.h new file mode 100644 index 0000000..68996f34 --- /dev/null +++ b/components/feedback/redaction_tool/redaction_tool_metrics_recorder.h
@@ -0,0 +1,54 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_FEEDBACK_REDACTION_TOOL_REDACTION_TOOL_METRICS_RECORDER_H_ +#define COMPONENTS_FEEDBACK_REDACTION_TOOL_REDACTION_TOOL_METRICS_RECORDER_H_ + +#include <memory> + +#include "components/feedback/redaction_tool/pii_types.h" + +namespace redaction { + +// These values are logged to UMA. Entries should not be renumbered and +// numeric values should never be reused. Please keep in sync with +// "CreditCardDetection" in //tools/metrics/histograms/enums.xml. +enum class CreditCardDetection { + kRegexMatch = 1, + kTimestamp = 2, + kRepeatedChars = 3, + kDoesntValidate = 4, + kValidated = 5, + kMaxValue = kValidated, +}; + +inline constexpr char kPIIRedactedHistogram[] = "Feedback.RedactionTool"; +inline constexpr char kCreditCardRedactionHistogram[] = + "Feedback.RedactionTool.CreditCardMatch"; + +// This class is the platform independent interface to record histograms using +// the platform specific libraries. +class RedactionToolMetricsRecorder { + public: + // Create a new instance of the platform default implementation. + static std::unique_ptr<RedactionToolMetricsRecorder> Create(); + + RedactionToolMetricsRecorder() = default; + RedactionToolMetricsRecorder(const RedactionToolMetricsRecorder&) = delete; + RedactionToolMetricsRecorder& operator=(const RedactionToolMetricsRecorder&) = + delete; + virtual ~RedactionToolMetricsRecorder() = default; + + // Record when a bit of PII of the type `pii_type` was redacted by the + // redaction tool. + virtual void RecordPIIRedactedHistogram(PIIType pii_type) = 0; + + // Records the `step` that was reached when validating a series of numbers + // against credit card checks. + virtual void RecordCreditCardRedactionHistogram(CreditCardDetection step) = 0; +}; + +} // namespace redaction + +#endif // COMPONENTS_FEEDBACK_REDACTION_TOOL_REDACTION_TOOL_METRICS_RECORDER_H_
diff --git a/components/feedback/redaction_tool/redaction_tool_unittest.cc b/components/feedback/redaction_tool/redaction_tool_unittest.cc index e5c6426..409505d 100644 --- a/components/feedback/redaction_tool/redaction_tool_unittest.cc +++ b/components/feedback/redaction_tool/redaction_tool_unittest.cc
@@ -8,9 +8,10 @@ #include <set> #include <utility> +#include "base/location.h" #include "base/strings/string_util.h" -#include "base/test/metrics/histogram_tester.h" #include "build/chromeos_buildflags.h" +#include "components/feedback/redaction_tool/metrics_tester.h" #include "components/feedback/redaction_tool/pii_types.h" namespace redaction { @@ -35,8 +36,22 @@ const StringWithRedaction kStringsWithRedactions[] = { {"aaaaaaaa [SSID=123aaaaaa]aaaaa", // SSID. "aaaaaaaa [SSID=(SSID: 1)]aaaaa", PIIType::kSSID}, + {"chrome://resources/foo", // Secure chrome resource, exempt. + "chrome://resources/foo", PIIType::kNone}, + {"chrome://settings/crisper.js", // Exempt settings URLs. + "chrome://settings/crisper.js", PIIType::kNone}, + // Exempt first party extension. + {"chrome-extension://nkoccljplnhpfnfiajclkommnmllphnl/foobar.js", + "chrome-extension://nkoccljplnhpfnfiajclkommnmllphnl/foobar.js", + PIIType::kNone}, {"aaaaaaaahttp://tets.comaaaaaaa", // URL. "aaaaaaaa(URL: 1)", PIIType::kURL}, + {"chrome://resources/f?user=bar", // Potentially PII in parameter. + "(URL: 2)", PIIType::kURL}, + {"chrome-extension://nkoccljplnhpfnfiajclkommnmllphnl/foobar.js?bar=x", + "(URL: 3)", PIIType::kURL}, // Potentially PII in parameter. + {"isolated-app://airugqztij5biqquuk3mfwpsaibuegaqcitgfchwuosuofdjabzqaaac/", + "(URL: 4)", PIIType::kURL}, // URL {"u:object_r:system_data_file:s0:c512,c768", // No PII, it is an SELinux // context. "u:object_r:system_data_file:s0:c512,c768", PIIType::kNone}, @@ -172,20 +187,6 @@ "(IPv6: 18)", PIIType::kIPAddress}, {"aa:aa:aa:aa:aa:aa", // MAC address (BSSID). "(MAC OUI=aa:aa:aa IFACE=1)", PIIType::kMACAddress}, - {"chrome://resources/foo", // Secure chrome resource, exempt. - "chrome://resources/foo", PIIType::kNone}, - {"chrome://settings/crisper.js", // Exempt settings URLs. - "chrome://settings/crisper.js", PIIType::kNone}, - // Exempt first party extension. - {"chrome-extension://nkoccljplnhpfnfiajclkommnmllphnl/foobar.js", - "chrome-extension://nkoccljplnhpfnfiajclkommnmllphnl/foobar.js", - PIIType::kNone}, - {"chrome://resources/f?user=bar", // Potentially PII in parameter. - "(URL: 2)", PIIType::kURL}, - {"chrome-extension://nkoccljplnhpfnfiajclkommnmllphnl/foobar.js?bar=x", - "(URL: 3)", PIIType::kURL}, // Potentially PII in parameter. - {"isolated-app://airugqztij5biqquuk3mfwpsaibuegaqcitgfchwuosuofdjabzqaaac/", - "(URL: 4)", PIIType::kURL}, // URL {"/root/27540283740a0897ab7c8de0f809add2bacde78f/foo", "/root/(HASH:2754 1)/foo", PIIType::kStableIdentifier}, // Hash string. {"B3mcFTkQAHofv94DDTUuVJGGEI/BbzsyDncplMCR2P4=", "(UID: 1)", @@ -255,6 +256,12 @@ }; class RedactionToolTest : public testing::Test { + public: + RedactionToolTest() + : metrics_tester_(MetricsTester::Create()), + redactor_(kFakeFirstPartyExtensionIDs, + metrics_tester_->SetupRecorder()) {} + protected: std::string RedactMACAddresses(const std::string& input) { return redactor_.RedactMACAddresses(input, nullptr); @@ -286,7 +293,21 @@ return redactor_.RedactCustomPatternWithoutContext(input, pattern, nullptr); } - RedactionTool redactor_{kFakeFirstPartyExtensionIDs}; + template <typename T> + void ExpectBucketCount( + const base::StringPiece histogram_name, + const T enum_value, + const size_t expected_count, + const base::Location location = base::Location::Current()) { + const size_t actual_count = metrics_tester_->GetBucketCount( + histogram_name, static_cast<int>(enum_value)); + + EXPECT_EQ(actual_count, expected_count) + << location.file_name() << ":" << location.line_number(); + } + + std::unique_ptr<MetricsTester> metrics_tester_; + RedactionTool redactor_; }; TEST_F(RedactionToolTest, Redact) { @@ -628,21 +649,18 @@ redactor_.EnableCreditCardRedaction(true); std::string redaction_input; std::string redaction_output; - constexpr char kHistogramName[] = "Feedback.RedactionTool.CreditCardMatch"; - enum class CreditCardDetection { - kRegexMatch = 1, - kTimestamp = 2, - kRepeatedChars = 3, - kDoesntValidate = 4, - kValidated = 5, - }; using enum CreditCardDetection; - const base::HistogramTester histogram_tester; - histogram_tester.ExpectBucketCount(kHistogramName, kRegexMatch, 0); - histogram_tester.ExpectBucketCount(kHistogramName, kTimestamp, 0); - histogram_tester.ExpectBucketCount(kHistogramName, kRepeatedChars, 0); - histogram_tester.ExpectBucketCount(kHistogramName, kDoesntValidate, 0); - histogram_tester.ExpectBucketCount(kHistogramName, kValidated, 0); + ExpectBucketCount(kCreditCardRedactionHistogram, kRegexMatch, 0); + ExpectBucketCount(kCreditCardRedactionHistogram, kTimestamp, 0); + ExpectBucketCount(kCreditCardRedactionHistogram, kRepeatedChars, 0); + ExpectBucketCount(kCreditCardRedactionHistogram, kDoesntValidate, 0); + ExpectBucketCount(kCreditCardRedactionHistogram, kValidated, 0); + + for (int enum_int = static_cast<int>(PIIType::kNone) + 1; + enum_int <= static_cast<int>(PIIType::kMaxValue); ++enum_int) { + const PIIType enum_value = static_cast<PIIType>(enum_int); + ExpectBucketCount(kPIIRedactedHistogram, enum_value, 0); + } for (const auto& s : kStringsWithRedactions) { redaction_input.append(s.pre_redaction).append("\n"); @@ -650,11 +668,29 @@ } EXPECT_EQ(redaction_output, redactor_.Redact(redaction_input)); - histogram_tester.ExpectBucketCount(kHistogramName, kRegexMatch, 16); - histogram_tester.ExpectBucketCount(kHistogramName, kTimestamp, 2); - histogram_tester.ExpectBucketCount(kHistogramName, kRepeatedChars, 1); - histogram_tester.ExpectBucketCount(kHistogramName, kDoesntValidate, 8); - histogram_tester.ExpectBucketCount(kHistogramName, kValidated, 5); + for (int enum_int = static_cast<int>(PIIType::kNone) + 1; + enum_int <= static_cast<int>(PIIType::kMaxValue); ++enum_int) { + const PIIType enum_value = static_cast<PIIType>(enum_int); + const size_t expected_count = base::ranges::count_if( + kStringsWithRedactions, + [enum_value](const StringWithRedaction& string_with_redaction) { + return string_with_redaction.pii_type == enum_value; + }); + ExpectBucketCount(kPIIRedactedHistogram, enum_value, expected_count); + } + // This isn't handled by the redaction tool but rather in the + // `UiHierarchyDataCollector`. It's part of the enum for historical reasons. + ExpectBucketCount(kPIIRedactedHistogram, PIIType::kUIHierarchyWindowTitles, + 0); + // This isn't handled by the redaction tool but rather in Shill. It's part of + // the enum for historical reasons. + ExpectBucketCount(kPIIRedactedHistogram, PIIType::kEAP, 0); + + ExpectBucketCount(kCreditCardRedactionHistogram, kRegexMatch, 16); + ExpectBucketCount(kCreditCardRedactionHistogram, kTimestamp, 2); + ExpectBucketCount(kCreditCardRedactionHistogram, kRepeatedChars, 1); + ExpectBucketCount(kCreditCardRedactionHistogram, kDoesntValidate, 8); + ExpectBucketCount(kCreditCardRedactionHistogram, kValidated, 5); } TEST_F(RedactionToolTest, RedactAndKeepSelected) {
diff --git a/components/gcm_driver/instance_id/instance_id_driver.h b/components/gcm_driver/instance_id/instance_id_driver.h index eae2fa0d..a5dc8421 100644 --- a/components/gcm_driver/instance_id/instance_id_driver.h +++ b/components/gcm_driver/instance_id/instance_id_driver.h
@@ -48,7 +48,7 @@ private: // Owned by GCMProfileServiceFactory, which is a dependency of // InstanceIDProfileServiceFactory, which owns this. - raw_ptr<gcm::GCMDriver, DanglingUntriaged> gcm_driver_; + raw_ptr<gcm::GCMDriver, DanglingAcrossTasks> gcm_driver_; std::map<std::string, std::unique_ptr<InstanceID>> instance_id_map_; };
diff --git a/components/history/core/browser/expire_history_backend.h b/components/history/core/browser/expire_history_backend.h index dfcab38..5d87bc4 100644 --- a/components/history/core/browser/expire_history_backend.h +++ b/components/history/core/browser/expire_history_backend.h
@@ -275,9 +275,9 @@ raw_ptr<HistoryBackendNotifier> notifier_; // Non-owning pointers to the databases we deal with (MAY BE NULL). - raw_ptr<HistoryDatabase, DanglingUntriaged> + raw_ptr<HistoryDatabase, DanglingAcrossTasks> main_db_; // Main history database. - raw_ptr<favicon::FaviconDatabase, DanglingUntriaged> favicon_db_; + raw_ptr<favicon::FaviconDatabase, DanglingAcrossTasks> favicon_db_; // The threshold for "old" history where we will automatically delete it. base::TimeDelta expiration_threshold_; @@ -304,7 +304,7 @@ std::unique_ptr<ExpiringVisitsReader> auto_subframe_visits_reader_; // The HistoryBackendClient; may be null. - raw_ptr<HistoryBackendClient, DanglingUntriaged> backend_client_; + raw_ptr<HistoryBackendClient, DanglingAcrossTasks> backend_client_; scoped_refptr<base::SequencedTaskRunner> task_runner_;
diff --git a/components/history/core/browser/sync/history_sync_bridge.h b/components/history/core/browser/sync/history_sync_bridge.h index ec581a9..80df1e45 100644 --- a/components/history/core/browser/sync/history_sync_bridge.h +++ b/components/history/core/browser/sync/history_sync_bridge.h
@@ -154,7 +154,7 @@ // A non-owning pointer to the database, which is for storing sync metadata // and state. Can be null in case of unrecoverable database errors. - raw_ptr<HistorySyncMetadataDatabase, DanglingUntriaged> + raw_ptr<HistorySyncMetadataDatabase, DanglingAcrossTasks> sync_metadata_database_; // HistoryBackend uses SequencedTaskRunner, so this makes sure
diff --git a/components/history/core/browser/sync/typed_url_sync_bridge.h b/components/history/core/browser/sync/typed_url_sync_bridge.h index 8c270e5..d83b85a0 100644 --- a/components/history/core/browser/sync/typed_url_sync_bridge.h +++ b/components/history/core/browser/sync/typed_url_sync_bridge.h
@@ -245,7 +245,7 @@ // A non-owning pointer to the database, which is for storing typed urls sync // metadata and state. - raw_ptr<TypedURLSyncMetadataDatabase, DanglingUntriaged> + raw_ptr<TypedURLSyncMetadataDatabase, DanglingAcrossTasks> sync_metadata_database_; // Since HistoryBackend use SequencedTaskRunner, so should use SequenceChecker
diff --git a/components/leveldb_proto/internal/proto_leveldb_wrapper.h b/components/leveldb_proto/internal/proto_leveldb_wrapper.h index 8c85619..477b211 100644 --- a/components/leveldb_proto/internal/proto_leveldb_wrapper.h +++ b/components/leveldb_proto/internal/proto_leveldb_wrapper.h
@@ -151,7 +151,7 @@ // Used to run blocking tasks in-order, must be the TaskRunner that |db_| // relies on. scoped_refptr<base::SequencedTaskRunner> task_runner_; - raw_ptr<LevelDB, DanglingUntriaged> db_ = nullptr; + raw_ptr<LevelDB, DanglingAcrossTasks> db_ = nullptr; // The identifier used when recording metrics to determine the source of the // LevelDB calls, likely the database client name.
diff --git a/components/media_device_salt/BUILD.gn b/components/media_device_salt/BUILD.gn index 2c5b4e2..d1d7301 100644 --- a/components/media_device_salt/BUILD.gn +++ b/components/media_device_salt/BUILD.gn
@@ -8,8 +8,6 @@ "media_device_id_salt.h", "media_device_salt_service.cc", "media_device_salt_service.h", - "media_device_salt_service_factory.cc", - "media_device_salt_service_factory.h", ] deps = [
diff --git a/components/media_device_salt/media_device_salt_service_unittest.cc b/components/media_device_salt/media_device_salt_service_unittest.cc index 8fbdb9b4..d4f1ad2 100644 --- a/components/media_device_salt/media_device_salt_service_unittest.cc +++ b/components/media_device_salt/media_device_salt_service_unittest.cc
@@ -2,12 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/media_device_salt/media_device_salt_service_factory.h" +#include "components/media_device_salt/media_device_salt_service.h" #include "base/test/test_future.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/media_device_salt/media_device_id_salt.h" -#include "components/media_device_salt/media_device_salt_service.h" #include "components/sync_preferences/testing_pref_service_syncable.h" #include "components/user_prefs/user_prefs.h" #include "content/public/test/browser_task_environment.h" @@ -30,16 +29,10 @@ ASSERT_TRUE(pref_service_.FindPreference( media_device_salt::prefs::kMediaDeviceIdSalt)); - MediaDeviceSaltServiceFactory* factory = - MediaDeviceSaltServiceFactory::GetInstance(); - ASSERT_TRUE(factory); - - service_ = factory->GetForBrowserContext(&browser_context_); - ASSERT_TRUE(service_); + service_ = std::make_unique<MediaDeviceSaltService>(&pref_service_); } void TearDown() override { - service_ = nullptr; BrowserContextDependencyManager::GetInstance() ->DestroyBrowserContextServices(&browser_context_); } @@ -60,7 +53,7 @@ content::BrowserTaskEnvironment task_environment_; content::TestBrowserContext browser_context_; sync_preferences::TestingPrefServiceSyncable pref_service_; - raw_ptr<MediaDeviceSaltService> service_; + std::unique_ptr<MediaDeviceSaltService> service_; }; TEST_F(MediaDeviceSaltServiceTest, GetAndResetSalt) {
diff --git a/components/metrics/metrics_state_manager.h b/components/metrics/metrics_state_manager.h index c6aa6f0..77d8002 100644 --- a/components/metrics/metrics_state_manager.h +++ b/components/metrics/metrics_state_manager.h
@@ -340,7 +340,7 @@ // Weak pointer to an enabled state provider. Used to know whether the user // has consented to reporting, and if reporting should be done. - raw_ptr<EnabledStateProvider, DanglingUntriaged> enabled_state_provider_; + raw_ptr<EnabledStateProvider, DanglingAcrossTasks> enabled_state_provider_; // Specified options for controlling trial randomization. const EntropyParams entropy_params_;
diff --git a/components/omnibox/browser/location_bar_model_impl.h b/components/omnibox/browser/location_bar_model_impl.h index 38fe02be..60f3b9b 100644 --- a/components/omnibox/browser/location_bar_model_impl.h +++ b/components/omnibox/browser/location_bar_model_impl.h
@@ -53,7 +53,7 @@ std::u16string GetFormattedURL( url_formatter::FormatUrlTypes format_types) const; - raw_ptr<LocationBarModelDelegate, DanglingUntriaged> delegate_; + raw_ptr<LocationBarModelDelegate, DanglingAcrossTasks> delegate_; const size_t max_url_display_chars_; };
diff --git a/components/omnibox/browser/shortcuts_backend.h b/components/omnibox/browser/shortcuts_backend.h index bc39024..2bfd17c 100644 --- a/components/omnibox/browser/shortcuts_backend.h +++ b/components/omnibox/browser/shortcuts_backend.h
@@ -166,7 +166,7 @@ // Deletes all of the shortcuts. bool DeleteAllShortcuts(); - raw_ptr<TemplateURLService, DanglingUntriaged> template_url_service_; + raw_ptr<TemplateURLService, DanglingAcrossTasks> template_url_service_; std::unique_ptr<SearchTermsData> search_terms_data_; CurrentState current_state_;
diff --git a/components/optimization_guide/core/hints_manager.h b/components/optimization_guide/core/hints_manager.h index b3aaaaf..006d110 100644 --- a/components/optimization_guide/core/hints_manager.h +++ b/components/optimization_guide/core/hints_manager.h
@@ -503,7 +503,7 @@ raw_ptr<TopHostProvider, DanglingUntriaged> top_host_provider_ = nullptr; // The tab URL provider that can be queried. Not owned. - raw_ptr<TabUrlProvider, DanglingUntriaged> tab_url_provider_ = nullptr; + raw_ptr<TabUrlProvider, DanglingAcrossTasks> tab_url_provider_ = nullptr; // The timer used to schedule fetching hints from the remote Optimization // Guide Service.
diff --git a/components/password_manager/content/browser/content_password_manager_driver_factory.h b/components/password_manager/content/browser/content_password_manager_driver_factory.h index e71dcb8..99dea60 100644 --- a/components/password_manager/content/browser/content_password_manager_driver_factory.h +++ b/components/password_manager/content/browser/content_password_manager_driver_factory.h
@@ -72,8 +72,8 @@ std::map<content::RenderFrameHost*, ContentPasswordManagerDriver> frame_driver_map_; - raw_ptr<PasswordManagerClient, DanglingUntriaged> password_client_; - raw_ptr<autofill::AutofillClient, DanglingUntriaged> autofill_client_; + raw_ptr<PasswordManagerClient, DanglingAcrossTasks> password_client_; + raw_ptr<autofill::AutofillClient, DanglingAcrossTasks> autofill_client_; WEB_CONTENTS_USER_DATA_KEY_DECL(); };
diff --git a/components/password_manager/core/browser/affiliation/affiliation_service_impl.h b/components/password_manager/core/browser/affiliation/affiliation_service_impl.h index a01dfa6..c6cd6d1 100644 --- a/components/password_manager/core/browser/affiliation/affiliation_service_impl.h +++ b/components/password_manager/core/browser/affiliation/affiliation_service_impl.h
@@ -129,7 +129,7 @@ // living on the backend thread. It will be deleted asynchronously during // shutdown on the backend thread, so it will outlive |this| along with all // its in-flight tasks. - raw_ptr<AffiliationBackend, DanglingUntriaged> backend_; + raw_ptr<AffiliationBackend, DanglingAcrossTasks> backend_; raw_ptr<PrefService> pref_service_;
diff --git a/components/password_manager/core/browser/password_reuse_manager_impl.h b/components/password_manager/core/browser/password_reuse_manager_impl.h index 9407c86..b540880 100644 --- a/components/password_manager/core/browser/password_reuse_manager_impl.h +++ b/components/password_manager/core/browser/password_reuse_manager_impl.h
@@ -111,7 +111,7 @@ // living on the background thread. It will be deleted asynchronously during // shutdown on the background thread, so it will outlive |this| along with all // its in-flight tasks. - raw_ptr<PasswordReuseDetector, DanglingUntriaged> reuse_detector_ = nullptr; + raw_ptr<PasswordReuseDetector, DanglingAcrossTasks> reuse_detector_ = nullptr; // Notifies PasswordReuseManager about sign-in events. std::unique_ptr<PasswordStoreSigninNotifier> notifier_;
diff --git a/components/password_manager/core/browser/password_store.h b/components/password_manager/core/browser/password_store.h index e70a7bf..a449867 100644 --- a/components/password_manager/core/browser/password_store.h +++ b/components/password_manager/core/browser/password_store.h
@@ -216,7 +216,7 @@ std::unique_ptr<AffiliatedMatchHelper> affiliated_match_helper_; - raw_ptr<PrefService, DanglingUntriaged> prefs_ = nullptr; + raw_ptr<PrefService, DanglingAcrossTasks> prefs_ = nullptr; InitStatus init_status_ = InitStatus::kUnknown; };
diff --git a/components/password_manager/core/browser/sync/password_sync_bridge.cc b/components/password_manager/core/browser/sync/password_sync_bridge.cc index b547260..6b44bbd 100644 --- a/components/password_manager/core/browser/sync/password_sync_bridge.cc +++ b/components/password_manager/core/browser/sync/password_sync_bridge.cc
@@ -287,9 +287,7 @@ syncer::PASSWORDS); batch = std::make_unique<syncer::MetadataBatch>(); sync_metadata_read_error = SyncMetadataReadError::kReadSuccessButCleared; - } else if (base::FeatureList::IsEnabled( - syncer::kCacheBaseEntitySpecificsInMetadata) && - SyncMetadataCacheContainsSupportedFields( + } else if (SyncMetadataCacheContainsSupportedFields( batch->GetAllMetadata())) { // Caching entity specifics is meant to preserve fields not supported in a // given browser version during commits to the server. If the cache
diff --git a/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc b/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc index a03dd1f3..78e0413 100644 --- a/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc +++ b/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc
@@ -925,9 +925,6 @@ TEST_F(PasswordSyncBridgeTest, ShouldRemoveSyncMetadataWhenSpecificsCacheContainsSupportedFields) { base::HistogramTester histogram_tester; - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature( - syncer::kCacheBaseEntitySpecificsInMetadata); ON_CALL(*mock_sync_metadata_store_sync(), GetAllSyncMetadata) .WillByDefault([&]() { @@ -964,10 +961,6 @@ TEST_F( PasswordSyncBridgeTest, ShouldNotRemoveSyncMetadataWhenSpecificsCacheContainsUnsupportedFieldsOnly) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature( - syncer::kCacheBaseEntitySpecificsInMetadata); - ON_CALL(*mock_sync_metadata_store_sync(), GetAllSyncMetadata) .WillByDefault([&]() { // Create entity with a cached unsupported field. @@ -1125,10 +1118,6 @@ TEST_F(PasswordSyncBridgeTest, ShouldNotRemoveSyncMetadataWhenSpecificsCacheIsEmpty) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature( - syncer::kCacheBaseEntitySpecificsInMetadata); - ON_CALL(*mock_sync_metadata_store_sync(), GetAllSyncMetadata) .WillByDefault([&]() { // Create entity with empty `possibly_trimmed_base_specifics`.
diff --git a/components/policy/core/common/cloud/cloud_policy_core.h b/components/policy/core/common/cloud/cloud_policy_core.h index 1c4b484..1efb1cd 100644 --- a/components/policy/core/common/cloud/cloud_policy_core.h +++ b/components/policy/core/common/cloud/cloud_policy_core.h
@@ -136,7 +136,7 @@ std::string policy_type_; std::string settings_entity_id_; - raw_ptr<CloudPolicyStore, DanglingUntriaged> store_; + raw_ptr<CloudPolicyStore, DanglingAcrossTasks> store_; scoped_refptr<base::SequencedTaskRunner> task_runner_; network::NetworkConnectionTrackerGetter network_connection_tracker_getter_; std::unique_ptr<CloudPolicyClient> client_;
diff --git a/components/policy/core/common/policy_statistics_collector.h b/components/policy/core/common/policy_statistics_collector.h index 2376fcd..11796ed 100644 --- a/components/policy/core/common/policy_statistics_collector.h +++ b/components/policy/core/common/policy_statistics_collector.h
@@ -80,7 +80,7 @@ GetChromePolicyDetailsCallback get_details_; Schema chrome_schema_; raw_ptr<PolicyService> policy_service_; - raw_ptr<PrefService, DanglingUntriaged> prefs_; + raw_ptr<PrefService, DanglingAcrossTasks> prefs_; base::CancelableOnceClosure update_callback_;
diff --git a/components/prefs/pref_change_registrar.h b/components/prefs/pref_change_registrar.h index 13134d6..8034a35 100644 --- a/components/prefs/pref_change_registrar.h +++ b/components/prefs/pref_change_registrar.h
@@ -74,7 +74,7 @@ using ObserverMap = std::map<std::string, NamedChangeCallback>; ObserverMap observers_; - raw_ptr<PrefService, DanglingUntriaged> service_; + raw_ptr<PrefService, DanglingAcrossTasks> service_; }; #endif // COMPONENTS_PREFS_PREF_CHANGE_REGISTRAR_H_
diff --git a/components/privacy_sandbox/privacy_sandbox_settings_impl.h b/components/privacy_sandbox/privacy_sandbox_settings_impl.h index 14915b6..1a7e4a1c 100644 --- a/components/privacy_sandbox/privacy_sandbox_settings_impl.h +++ b/components/privacy_sandbox/privacy_sandbox_settings_impl.h
@@ -160,7 +160,8 @@ base::ObserverList<Observer>::Unchecked observers_; std::unique_ptr<Delegate> delegate_; - raw_ptr<HostContentSettingsMap, DanglingUntriaged> host_content_settings_map_; + raw_ptr<HostContentSettingsMap, DanglingAcrossTasks> + host_content_settings_map_; scoped_refptr<content_settings::CookieSettings> cookie_settings_; raw_ptr<PrefService, DanglingUntriaged> pref_service_; PrefChangeRegistrar pref_change_registrar_;
diff --git a/components/renderer_context_menu/context_menu_delegate.cc b/components/renderer_context_menu/context_menu_delegate.cc index 79c9eb1..9970599 100644 --- a/components/renderer_context_menu/context_menu_delegate.cc +++ b/components/renderer_context_menu/context_menu_delegate.cc
@@ -21,7 +21,7 @@ ContextMenuDelegate* menu_delegate() { return menu_delegate_; } private: - raw_ptr<ContextMenuDelegate, DanglingUntriaged> + raw_ptr<ContextMenuDelegate, DanglingAcrossTasks> menu_delegate_; // not owned by us. };
diff --git a/components/segmentation_platform/embedder/default_model/device_switcher_result_dispatcher.h b/components/segmentation_platform/embedder/default_model/device_switcher_result_dispatcher.h index 78348b7..8e2ba09 100644 --- a/components/segmentation_platform/embedder/default_model/device_switcher_result_dispatcher.h +++ b/components/segmentation_platform/embedder/default_model/device_switcher_result_dispatcher.h
@@ -66,7 +66,7 @@ const raw_ptr<SegmentationPlatformService> segmentation_service_; const raw_ptr<syncer::SyncService> sync_service_; const raw_ptr<PrefService> prefs_; - const raw_ptr<FieldTrialRegister, DanglingUntriaged> field_trial_register_; + const raw_ptr<FieldTrialRegister, DanglingAcrossTasks> field_trial_register_; ClassificationResultCallback waiting_callback_; absl::optional<ClassificationResult> latest_result_;
diff --git a/components/segmentation_platform/internal/selection/segment_result_provider.cc b/components/segmentation_platform/internal/selection/segment_result_provider.cc index b9de92a..bc871c9 100644 --- a/components/segmentation_platform/internal/selection/segment_result_provider.cc +++ b/components/segmentation_platform/internal/selection/segment_result_provider.cc
@@ -75,7 +75,7 @@ private: struct RequestState { std::unordered_map<DefaultModelManager::SegmentSource, - raw_ptr<ModelProvider, DanglingUntriaged>> + raw_ptr<ModelProvider, DanglingAcrossTasks>> model_providers; DefaultModelManager::SegmentInfoList available_segments; std::unique_ptr<GetResultOptions> options;
diff --git a/components/segmentation_platform/internal/signals/signal_filter_processor.h b/components/segmentation_platform/internal/signals/signal_filter_processor.h index 3daf5b8..1f02420 100644 --- a/components/segmentation_platform/internal/signals/signal_filter_processor.h +++ b/components/segmentation_platform/internal/signals/signal_filter_processor.h
@@ -55,7 +55,7 @@ const raw_ptr<StorageService, DanglingUntriaged> storage_service_; const raw_ptr<UserActionSignalHandler> user_action_signal_handler_; const raw_ptr<HistogramSignalHandler> histogram_signal_handler_; - const raw_ptr<HistoryServiceObserver, DanglingUntriaged> history_observer_; + const raw_ptr<HistoryServiceObserver, DanglingAcrossTasks> history_observer_; const base::flat_set<SegmentId> segment_ids_; base::WeakPtrFactory<SignalFilterProcessor> weak_ptr_factory_{this};
diff --git a/components/sessions/core/session_id_generator.h b/components/sessions/core/session_id_generator.h index 1b6b12d..996b7384 100644 --- a/components/sessions/core/session_id_generator.h +++ b/components/sessions/core/session_id_generator.h
@@ -56,7 +56,7 @@ void IncrementValueBy(int increment); SEQUENCE_CHECKER(sequence_checker_); - raw_ptr<PrefService, DanglingUntriaged> local_state_; + raw_ptr<PrefService, DanglingAcrossTasks> local_state_; SessionID::id_type last_value_; // Used to override the random number generator for tests.
diff --git a/components/signin/internal/identity_manager/accounts_cookie_mutator_impl.h b/components/signin/internal/identity_manager/accounts_cookie_mutator_impl.h index 031b5f6d..b0941415 100644 --- a/components/signin/internal/identity_manager/accounts_cookie_mutator_impl.h +++ b/components/signin/internal/identity_manager/accounts_cookie_mutator_impl.h
@@ -86,10 +86,10 @@ }; raw_ptr<SigninClient> signin_client_; - raw_ptr<ProfileOAuth2TokenService, DanglingUntriaged> token_service_; - raw_ptr<GaiaCookieManagerService, DanglingUntriaged> + raw_ptr<ProfileOAuth2TokenService, DanglingAcrossTasks> token_service_; + raw_ptr<GaiaCookieManagerService, DanglingAcrossTasks> gaia_cookie_manager_service_; - raw_ptr<AccountTrackerService, DanglingUntriaged> account_tracker_service_; + raw_ptr<AccountTrackerService, DanglingAcrossTasks> account_tracker_service_; }; } // namespace signin
diff --git a/components/signin/internal/identity_manager/accounts_mutator_impl.h b/components/signin/internal/identity_manager/accounts_mutator_impl.h index 97adc260..4b20a74 100644 --- a/components/signin/internal/identity_manager/accounts_mutator_impl.h +++ b/components/signin/internal/identity_manager/accounts_mutator_impl.h
@@ -73,9 +73,9 @@ #endif private: - raw_ptr<ProfileOAuth2TokenService, DanglingUntriaged> token_service_; - raw_ptr<AccountTrackerService, DanglingUntriaged> account_tracker_service_; - raw_ptr<PrimaryAccountManager, DanglingUntriaged> primary_account_manager_; + raw_ptr<ProfileOAuth2TokenService, DanglingAcrossTasks> token_service_; + raw_ptr<AccountTrackerService, DanglingAcrossTasks> account_tracker_service_; + raw_ptr<PrimaryAccountManager, DanglingAcrossTasks> primary_account_manager_; #if BUILDFLAG(ENABLE_DICE_SUPPORT) raw_ptr<PrefService> pref_service_; #endif
diff --git a/components/signin/internal/identity_manager/diagnostics_provider_impl.h b/components/signin/internal/identity_manager/diagnostics_provider_impl.h index 6cf700c..d66acb7 100644 --- a/components/signin/internal/identity_manager/diagnostics_provider_impl.h +++ b/components/signin/internal/identity_manager/diagnostics_provider_impl.h
@@ -38,9 +38,9 @@ base::TimeDelta GetDelayBeforeMakingCookieRequests() const override; private: - raw_ptr<GaiaCookieManagerService, DanglingUntriaged> + raw_ptr<GaiaCookieManagerService, DanglingAcrossTasks> gaia_cookie_manager_service_; - raw_ptr<ProfileOAuth2TokenService, DanglingUntriaged> + raw_ptr<ProfileOAuth2TokenService, DanglingAcrossTasks> profile_oauth2_token_service_; };
diff --git a/components/signin/internal/identity_manager/primary_account_mutator_impl.h b/components/signin/internal/identity_manager/primary_account_mutator_impl.h index e304308..ff87a8c 100644 --- a/components/signin/internal/identity_manager/primary_account_mutator_impl.h +++ b/components/signin/internal/identity_manager/primary_account_mutator_impl.h
@@ -49,8 +49,9 @@ // Pointers to the services used by the PrimaryAccountMutatorImpl. They // *must* outlive this instance. - raw_ptr<AccountTrackerService, DanglingUntriaged> account_tracker_ = nullptr; - raw_ptr<PrimaryAccountManager, DanglingUntriaged> primary_account_manager_ = + raw_ptr<AccountTrackerService, DanglingAcrossTasks> account_tracker_ = + nullptr; + raw_ptr<PrimaryAccountManager, DanglingAcrossTasks> primary_account_manager_ = nullptr; raw_ptr<PrefService> pref_service_ = nullptr; raw_ptr<SigninClient> signin_client_ = nullptr;
diff --git a/components/sqlite_proto/table_manager.h b/components/sqlite_proto/table_manager.h index d8e9541..26cbfbc 100644 --- a/components/sqlite_proto/table_manager.h +++ b/components/sqlite_proto/table_manager.h
@@ -73,7 +73,7 @@ friend class base::RefCountedThreadSafe<TableManager>; scoped_refptr<base::SequencedTaskRunner> db_task_runner_; - raw_ptr<sql::Database, DanglingUntriaged> db_; + raw_ptr<sql::Database, DanglingAcrossTasks> db_; }; } // namespace sqlite_proto
diff --git a/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.h b/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.h index 43faaaa..efdb4af 100644 --- a/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.h +++ b/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.h
@@ -114,7 +114,7 @@ // Must outlive this class. For root frame navigations, this member will be // nullptr until NotifyPageActivationWithRuleset is called. - raw_ptr<VerifiedRuleset::Handle, DanglingUntriaged> ruleset_handle_; + raw_ptr<VerifiedRuleset::Handle, DanglingAcrossTasks> ruleset_handle_; // Will be set to true when DEFER is called in WillProcessResponse. bool deferred_ = false;
diff --git a/components/subresource_filter/content/browser/ads_intervention_manager.h b/components/subresource_filter/content/browser/ads_intervention_manager.h index a98d1f3..3983a98 100644 --- a/components/subresource_filter/content/browser/ads_intervention_manager.h +++ b/components/subresource_filter/content/browser/ads_intervention_manager.h
@@ -103,7 +103,7 @@ private: // The SubresourceFilterContentSettingsManager is guaranteed to outlive the // AdsInterventionManager. Both are bound to the profile. - raw_ptr<SubresourceFilterContentSettingsManager, DanglingUntriaged> + raw_ptr<SubresourceFilterContentSettingsManager, DanglingAcrossTasks> settings_manager_ = nullptr; raw_ptr<base::Clock, DanglingUntriaged> clock_;
diff --git a/components/subresource_filter/content/browser/verified_ruleset_dealer.h b/components/subresource_filter/content/browser/verified_ruleset_dealer.h index 554086b5..cf1964cc1 100644 --- a/components/subresource_filter/content/browser/verified_ruleset_dealer.h +++ b/components/subresource_filter/content/browser/verified_ruleset_dealer.h
@@ -116,7 +116,7 @@ private: // Note: Raw pointer, |dealer_| already holds a reference to |task_runner_|. - raw_ptr<base::SequencedTaskRunner, DanglingUntriaged> task_runner_; + raw_ptr<base::SequencedTaskRunner, DanglingAcrossTasks> task_runner_; std::unique_ptr<VerifiedRulesetDealer, base::OnTaskRunnerDeleter> dealer_; SEQUENCE_CHECKER(sequence_checker_); };
diff --git a/components/supervised_user/core/browser/BUILD.gn b/components/supervised_user/core/browser/BUILD.gn index 5d96032c..01b321b 100644 --- a/components/supervised_user/core/browser/BUILD.gn +++ b/components/supervised_user/core/browser/BUILD.gn
@@ -141,8 +141,12 @@ deps = [ ":fetcher", "//base", + "//components/safe_search_api", + "//components/signin/public/identity_manager", + "//components/supervised_user/core/browser", "//components/supervised_user/core/browser/proto", "//net/traffic_annotation", + "//services/network/public/cpp", "//url", ] } @@ -176,6 +180,8 @@ "//base/test:test_support", "//components/prefs:test_support", "//components/resources:components_resources", + "//components/signin/public/base", + "//components/signin/public/identity_manager", "//components/signin/public/identity_manager:test_support", "//components/strings:components_strings_grit", "//components/supervised_user/core/browser/proto",
diff --git a/components/supervised_user/core/browser/child_account_service.cc b/components/supervised_user/core/browser/child_account_service.cc index 22dfeb5..fd00935 100644 --- a/components/supervised_user/core/browser/child_account_service.cc +++ b/components/supervised_user/core/browser/child_account_service.cc
@@ -192,7 +192,17 @@ return; } - SetSupervisionStatusAndNotifyObservers(info.is_child_account == + signin::Tribool is_child_account = info.is_child_account; +#if BUILDFLAG(IS_IOS) + if (base::FeatureList::IsEnabled( + supervised_user::kEnableSupervisionOnDesktopAndIOS)) { + // AccountInfo::is_child_account is not set on iOS; use capabilities. + CHECK(is_child_account == signin::Tribool::kUnknown); + is_child_account = info.capabilities.is_subject_to_parental_controls(); + CHECK(is_child_account != signin::Tribool::kUnknown); + } +#endif // BUILDFLAG(IS_IOS) + SetSupervisionStatusAndNotifyObservers(is_child_account == signin::Tribool::kTrue); }
diff --git a/components/supervised_user/core/browser/kids_chrome_management_client.cc b/components/supervised_user/core/browser/kids_chrome_management_client.cc index 5d21d20..8828278 100644 --- a/components/supervised_user/core/browser/kids_chrome_management_client.cc +++ b/components/supervised_user/core/browser/kids_chrome_management_client.cc
@@ -312,34 +312,49 @@ return; } - std::unique_ptr<network::SimpleURLLoader> simple_url_loader = - network::SimpleURLLoader::Create(std::move(req->resource_request), - req->traffic_annotation); + requests_loaders_[req] = network::SimpleURLLoader::Create( + std::move(req->resource_request), req->traffic_annotation); + network::SimpleURLLoader* simple_url_loader = requests_loaders_[req].get(); simple_url_loader->AttachStringForUpload(request_data, kClassifyUrlDataContentType); - auto* const simple_url_loader_ptr = simple_url_loader.get(); - simple_url_loader_ptr->DownloadToString( + // `this` is guaranteed to exist when the callback is called, because the + // KidsChromeManagementClient class owns `simple_url_loader`, and deleting the + // the simple_url_loader during the request will cause the callback not to be + // called. + // TODO(https://crbug.com/1444748): Write a test making sure that this cannot + // cause a UAF. The test needs to: + // - Start a ClassifyURL request. + // - Start a loader and pause it before completion. + // - Kill the KidsChromeManagementClient. Note that this will not work unless + // DCHECKs are turned off, because we otherwise check that callback_ has + // been run. + simple_url_loader->DownloadToString( url_loader_factory_.get(), base::BindOnce(&KidsChromeManagementClient::OnSimpleLoaderComplete, - base::UnsafeDanglingUntriaged(this), it, - std::move(simple_url_loader), token_info), + base::Unretained(this), it, token_info), /*max_body_size*/ 128); } void KidsChromeManagementClient::OnSimpleLoaderComplete( KidsChromeRequestList::iterator it, - std::unique_ptr<network::SimpleURLLoader> simple_url_loader, signin::AccessTokenInfo token_info, std::unique_ptr<std::string> response_body) { int response_code = -1; + KidsChromeManagementRequest* req = it->get(); + + // Get back the SimpleURLLoader from the stored map. + CHECK(requests_loaders_[req]); + std::unique_ptr<network::SimpleURLLoader> simple_url_loader = + std::move(requests_loaders_[req]); + requests_loaders_.erase(req); + if (simple_url_loader->ResponseInfo() && simple_url_loader->ResponseInfo()->headers) { response_code = simple_url_loader->ResponseInfo()->headers->response_code(); - KidsChromeManagementRequest* req = it->get(); // Handle first HTTP_UNAUTHORIZED response by removing access token and // restarting the request from the beginning (fetching access token). if (response_code == net::HTTP_UNAUTHORIZED && !req->access_token_expired) {
diff --git a/components/supervised_user/core/browser/kids_chrome_management_client.h b/components/supervised_user/core/browser/kids_chrome_management_client.h index 8e8191c..d7dc47a 100644 --- a/components/supervised_user/core/browser/kids_chrome_management_client.h +++ b/components/supervised_user/core/browser/kids_chrome_management_client.h
@@ -92,7 +92,6 @@ void OnSimpleLoaderComplete( KidsChromeRequestList::iterator kids_chrome_request, - std::unique_ptr<network::SimpleURLLoader> simple_url_loader, signin::AccessTokenInfo token_info, std::unique_ptr<std::string> response_body); @@ -109,6 +108,13 @@ // List of requests in execution. KidsChromeRequestList requests_in_progress_; + + // Stores the SimpleURLLoaders currently running requests. They are stored in + // this map during OnAccessTokenFetchComplete and removed in + // OnSimpleLoaderComplete. + std::map<KidsChromeManagementRequest*, + std::unique_ptr<network::SimpleURLLoader>> + requests_loaders_; }; #endif // COMPONENTS_SUPERVISED_USER_CORE_BROWSER_KIDS_CHROME_MANAGEMENT_CLIENT_H_
diff --git a/components/supervised_user/core/browser/kids_chrome_management_test_utils.cc b/components/supervised_user/core/browser/kids_chrome_management_test_utils.cc index a0d37c7..554a06ee 100644 --- a/components/supervised_user/core/browser/kids_chrome_management_test_utils.cc +++ b/components/supervised_user/core/browser/kids_chrome_management_test_utils.cc
@@ -3,8 +3,67 @@ // found in the LICENSE file. #include "components/supervised_user/core/browser/kids_chrome_management_test_utils.h" + +#include <utility> + +#include "base/check.h" #include "base/strings/strcat.h" #include "base/strings/string_piece.h" +#include "base/task/single_thread_task_runner.h" +#include "components/signin/public/identity_manager/identity_manager.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" + +using kids_chrome_management::ClassifyUrlResponse; + +namespace kids_management { + +KidsChromeManagementClientForTesting::KidsChromeManagementClientForTesting( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, + signin::IdentityManager* identity_manager) + : KidsChromeManagementClient(url_loader_factory, identity_manager) {} + +KidsChromeManagementClientForTesting::~KidsChromeManagementClientForTesting() = + default; + +void KidsChromeManagementClientForTesting::ClassifyURL( + std::unique_ptr<kids_chrome_management::ClassifyUrlRequest> request_proto, + KidsChromeManagementClient::KidsChromeManagementCallback callback) { + // Drop the request if the response is not configured. + if (response_proto_) { + base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), + std::move(response_proto_), error_code_)); + } +} + +void KidsChromeManagementClientForTesting::SetResponseWithError( + std::unique_ptr<ClassifyUrlResponse> response_proto, + KidsChromeManagementClient::ErrorCode error_code) { + response_proto_ = std::move(response_proto); + error_code_ = error_code; +} + +ClassifyUrlResponse::DisplayClassification ConvertClassification( + safe_search_api::ClientClassification classification) { + switch (classification) { + case safe_search_api::ClientClassification::kAllowed: + return ClassifyUrlResponse::ALLOWED; + case safe_search_api::ClientClassification::kRestricted: + return ClassifyUrlResponse::RESTRICTED; + case safe_search_api::ClientClassification::kUnknown: + return ClassifyUrlResponse::UNKNOWN_DISPLAY_CLASSIFICATION; + } +} + +std::unique_ptr<ClassifyUrlResponse> BuildResponseProto( + safe_search_api::ClientClassification classification) { + auto response_proto = std::make_unique<ClassifyUrlResponse>(); + response_proto->set_display_classification( + ConvertClassification(classification)); + return response_proto; +} + +} // namespace kids_management namespace supervised_user {
diff --git a/components/supervised_user/core/browser/kids_chrome_management_test_utils.h b/components/supervised_user/core/browser/kids_chrome_management_test_utils.h index 1a66975..0d54bb72 100644 --- a/components/supervised_user/core/browser/kids_chrome_management_test_utils.h +++ b/components/supervised_user/core/browser/kids_chrome_management_test_utils.h
@@ -5,9 +5,56 @@ #ifndef COMPONENTS_SUPERVISED_USER_CORE_BROWSER_KIDS_CHROME_MANAGEMENT_TEST_UTILS_H_ #define COMPONENTS_SUPERVISED_USER_CORE_BROWSER_KIDS_CHROME_MANAGEMENT_TEST_UTILS_H_ +#include <memory> + +#include "base/memory/scoped_refptr.h" #include "base/strings/string_piece.h" +#include "components/safe_search_api/url_checker_client.h" +#include "components/supervised_user/core/browser/kids_chrome_management_client.h" #include "components/supervised_user/core/browser/proto/kidschromemanagement_messages.pb.h" +namespace network { +class SharedURLLoaderFactory; +} // namespace network + +namespace signin { +class IdentityManager; +} // namespace signin + +namespace kids_management { + +class KidsChromeManagementClientForTesting : public KidsChromeManagementClient { + public: + KidsChromeManagementClientForTesting( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, + signin::IdentityManager* identity_manager); + + ~KidsChromeManagementClientForTesting() override; + + void ClassifyURL( + std::unique_ptr<kids_chrome_management::ClassifyUrlRequest> request_proto, + KidsChromeManagementClient::KidsChromeManagementCallback callback) + override; + + void SetResponseWithError( + std::unique_ptr<kids_chrome_management::ClassifyUrlResponse> + response_proto, + KidsChromeManagementClient::ErrorCode error_code); + + private: + std::unique_ptr<kids_chrome_management::ClassifyUrlResponse> response_proto_; + KidsChromeManagementClient::ErrorCode error_code_; +}; + +kids_chrome_management::ClassifyUrlResponse::DisplayClassification +ConvertClassification(safe_search_api::ClientClassification classification); + +// Returns a fake response proto with a response according to |classification|. +std::unique_ptr<kids_chrome_management::ClassifyUrlResponse> BuildResponseProto( + safe_search_api::ClientClassification classification); + +} // namespace kids_management + namespace supervised_user { void SetFamilyMemberAttributesForTesting(
diff --git a/components/supervised_user/core/browser/kids_management_url_checker_client_unittest.cc b/components/supervised_user/core/browser/kids_management_url_checker_client_unittest.cc index db320da..c869429 100644 --- a/components/supervised_user/core/browser/kids_management_url_checker_client_unittest.cc +++ b/components/supervised_user/core/browser/kids_management_url_checker_client_unittest.cc
@@ -10,11 +10,11 @@ #include "base/functional/bind.h" #include "base/memory/ptr_util.h" #include "base/memory/raw_ptr.h" -#include "base/task/single_thread_task_runner.h" #include "base/test/task_environment.h" #include "base/values.h" #include "components/signin/public/identity_manager/identity_test_environment.h" #include "components/supervised_user/core/browser/kids_chrome_management_client.h" +#include "components/supervised_user/core/browser/kids_chrome_management_test_utils.h" #include "components/supervised_user/core/browser/proto/kidschromemanagement_messages.pb.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #include "services/network/test/test_url_loader_factory.h" @@ -23,58 +23,8 @@ using testing::_; -namespace { - using kids_chrome_management::ClassifyUrlResponse; -ClassifyUrlResponse::DisplayClassification ConvertClassification( - safe_search_api::ClientClassification classification) { - switch (classification) { - case safe_search_api::ClientClassification::kAllowed: - return ClassifyUrlResponse::ALLOWED; - case safe_search_api::ClientClassification::kRestricted: - return ClassifyUrlResponse::RESTRICTED; - case safe_search_api::ClientClassification::kUnknown: - return ClassifyUrlResponse::UNKNOWN_DISPLAY_CLASSIFICATION; - } -} - -// Build fake response proto with a response according to |classification|. -std::unique_ptr<ClassifyUrlResponse> BuildResponseProto( - safe_search_api::ClientClassification classification) { - auto response_proto = std::make_unique<ClassifyUrlResponse>(); - - response_proto->set_display_classification( - ConvertClassification(classification)); - return response_proto; -} - -class KidsChromeManagementClientForTesting : public KidsChromeManagementClient { - public: - using KidsChromeManagementClient::KidsChromeManagementClient; - - void ClassifyURL( - std::unique_ptr<kids_chrome_management::ClassifyUrlRequest> request_proto, - KidsChromeManagementClient::KidsChromeManagementCallback callback) - override { - base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), - std::move(response_proto_), error_code_)); - } - - void SetupResponse(std::unique_ptr<ClassifyUrlResponse> response_proto, - KidsChromeManagementClient::ErrorCode error_code) { - response_proto_ = std::move(response_proto); - error_code_ = error_code; - } - - private: - std::unique_ptr<ClassifyUrlResponse> response_proto_; - KidsChromeManagementClient::ErrorCode error_code_; -}; - -} // namespace - class KidsManagementURLCheckerClientTest : public testing::Test { public: KidsManagementURLCheckerClientTest() = default; @@ -86,7 +36,7 @@ void SetUp() override { test_kids_chrome_management_client_ = - std::make_unique<KidsChromeManagementClientForTesting>( + std::make_unique<kids_management::KidsChromeManagementClientForTesting>( base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( &test_url_loader_factory_), identity_test_env_.identity_manager()); @@ -97,7 +47,7 @@ protected: void SetupClientResponse(std::unique_ptr<ClassifyUrlResponse> response_proto, KidsChromeManagementClient::ErrorCode error_code) { - test_kids_chrome_management_client_->SetupResponse( + test_kids_chrome_management_client_->SetResponseWithError( std::move(response_proto), error_code); } @@ -127,7 +77,7 @@ network::TestURLLoaderFactory test_url_loader_factory_; signin::IdentityTestEnvironment identity_test_env_; - std::unique_ptr<KidsChromeManagementClientForTesting> + std::unique_ptr<kids_management::KidsChromeManagementClientForTesting> test_kids_chrome_management_client_; std::unique_ptr<KidsManagementURLCheckerClient> url_classifier_; }; @@ -141,7 +91,7 @@ EXPECT_CALL(*this, OnCheckDone(url, classification)); - SetupClientResponse(BuildResponseProto(classification), + SetupClientResponse(kids_management::BuildResponseProto(classification), KidsChromeManagementClient::ErrorCode::kSuccess); CheckURL(url); @@ -154,7 +104,7 @@ EXPECT_CALL(*this, OnCheckDone(url, classification)); - SetupClientResponse(BuildResponseProto(classification), + SetupClientResponse(kids_management::BuildResponseProto(classification), KidsChromeManagementClient::ErrorCode::kSuccess); CheckURL(url); } @@ -166,7 +116,7 @@ safe_search_api::ClientClassification classification = safe_search_api::ClientClassification::kUnknown; - SetupClientResponse(BuildResponseProto(classification), + SetupClientResponse(kids_management::BuildResponseProto(classification), KidsChromeManagementClient::ErrorCode::kTokenError); EXPECT_CALL(*this, OnCheckDone(url, classification)); @@ -180,7 +130,7 @@ safe_search_api::ClientClassification classification = safe_search_api::ClientClassification::kUnknown; - SetupClientResponse(BuildResponseProto(classification), + SetupClientResponse(kids_management::BuildResponseProto(classification), KidsChromeManagementClient::ErrorCode::kNetworkError); EXPECT_CALL(*this, OnCheckDone(url, classification)); @@ -194,7 +144,7 @@ safe_search_api::ClientClassification classification = safe_search_api::ClientClassification::kUnknown; - SetupClientResponse(BuildResponseProto(classification), + SetupClientResponse(kids_management::BuildResponseProto(classification), KidsChromeManagementClient::ErrorCode::kHttpError); EXPECT_CALL(*this, OnCheckDone(url, classification)); @@ -209,7 +159,7 @@ safe_search_api::ClientClassification classification = safe_search_api::ClientClassification::kUnknown; - SetupClientResponse(BuildResponseProto(classification), + SetupClientResponse(kids_management::BuildResponseProto(classification), KidsChromeManagementClient::ErrorCode::kServiceError); EXPECT_CALL(*this, OnCheckDone(url, classification));
diff --git a/components/supervised_user/core/browser/supervised_user_service.cc b/components/supervised_user/core/browser/supervised_user_service.cc index f26156e..67d56759 100644 --- a/components/supervised_user/core/browser/supervised_user_service.cc +++ b/components/supervised_user/core/browser/supervised_user_service.cc
@@ -19,6 +19,7 @@ #include "build/build_config.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" +#include "components/signin/public/identity_manager/identity_manager.h" #include "components/supervised_user/core/browser/kids_chrome_management_client.h" #include "components/supervised_user/core/browser/supervised_user_service_observer.h" #include "components/supervised_user/core/browser/supervised_user_settings_service.h" @@ -42,6 +43,7 @@ // static void SupervisedUserService::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) { + registry->RegisterStringPref(prefs::kSupervisedUserId, std::string()); registry->RegisterDictionaryPref(prefs::kSupervisedUserManualHosts); registry->RegisterDictionaryPref(prefs::kSupervisedUserManualURLs); registry->RegisterIntegerPref(prefs::kDefaultSupervisedUserFilteringBehavior, @@ -147,7 +149,6 @@ } bool SupervisedUserService::IsURLFilteringEnabled() const { -// TODO(b/271413641): Use capabilities to verify if filtering is enabled on iOS. #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS) return IsSubjectToParentalControls(); #else @@ -187,6 +188,7 @@ } SupervisedUserService::SupervisedUserService( + signin::IdentityManager* identity_manager, KidsChromeManagementClient* kids_chrome_management_client, PrefService& user_prefs, SupervisedUserSettingsService& settings_service, @@ -197,6 +199,7 @@ : user_prefs_(user_prefs), settings_service_(settings_service), sync_service_(sync_service), + identity_manager_(identity_manager), kids_chrome_management_client_(kids_chrome_management_client), delegate_(nullptr), url_filter_(std::move(check_webstore_url_callback),
diff --git a/components/supervised_user/core/browser/supervised_user_service.h b/components/supervised_user/core/browser/supervised_user_service.h index c0f8f22..4ac19c2 100644 --- a/components/supervised_user/core/browser/supervised_user_service.h +++ b/components/supervised_user/core/browser/supervised_user_service.h
@@ -28,14 +28,18 @@ class Version; } // namespace base -namespace user_prefs { -class PrefRegistrySyncable; -} // namespace user_prefs +namespace signin { +class IdentityManager; +} // namespace signin namespace syncer { class SyncService; } // namespace syncer +namespace user_prefs { +class PrefRegistrySyncable; +} // namespace user_prefs + namespace supervised_user { class SupervisedUserSettingsService; @@ -152,6 +156,7 @@ // an instance of this service. // Public to allow visibility to iOS factory. SupervisedUserService( + signin::IdentityManager* identity_manager, KidsChromeManagementClient* kids_chrome_management_client, PrefService& user_prefs, supervised_user::SupervisedUserSettingsService& settings_service, @@ -200,6 +205,8 @@ const raw_ref<syncer::SyncService> sync_service_; + raw_ptr<signin::IdentityManager> identity_manager_; + raw_ptr<KidsChromeManagementClient> kids_chrome_management_client_; bool active_ = false;
diff --git a/components/supervised_user/core/browser/supervised_user_service_unittest.cc b/components/supervised_user/core/browser/supervised_user_service_unittest.cc index 274073f..9f8c057 100644 --- a/components/supervised_user/core/browser/supervised_user_service_unittest.cc +++ b/components/supervised_user/core/browser/supervised_user_service_unittest.cc
@@ -22,6 +22,9 @@ #include "components/prefs/pref_service.h" #include "components/prefs/scoped_user_pref_update.h" #include "components/prefs/testing_pref_service.h" +#include "components/signin/public/base/consent_level.h" +#include "components/signin/public/identity_manager/account_capabilities_test_mutator.h" +#include "components/signin/public/identity_manager/account_info.h" #include "components/signin/public/identity_manager/identity_test_environment.h" #include "components/supervised_user/core/browser/kids_chrome_management_client.h" #include "components/supervised_user/core/browser/supervised_user_settings_service.h" @@ -38,8 +41,8 @@ namespace { -constexpr char kExampleUrl0[] = "http://www.example0.com"; -constexpr char kExampleUrl1[] = "http://www.example1.com/123"; +const char kExampleUrl0[] = "http://www.example0.com"; +const char kExampleUrl1[] = "http://www.example1.com/123"; } // namespace @@ -55,9 +58,9 @@ base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( &test_url_loader_factory_), identity_test_env_.identity_manager()) { - // Specify if the user is supervised. - syncable_pref_service_.registry()->RegisterStringPref( - prefs::kSupervisedUserId, std::string()); + settings_service_.Init(syncable_pref_service_.user_prefs_store()); + SupervisedUserService::RegisterProfilePrefs( + syncable_pref_service_.registry()); if (is_supervised) { syncable_pref_service_.SetString(prefs::kSupervisedUserId, kChildAccountSUID); @@ -65,13 +68,9 @@ syncable_pref_service_.ClearPref(prefs::kSupervisedUserId); } - settings_service_.Init(syncable_pref_service_.user_prefs_store()); - SupervisedUserService::RegisterProfilePrefs( - syncable_pref_service_.registry()); - service_ = std::make_unique<SupervisedUserService>( - &kids_chrome_management_client_, syncable_pref_service_, - settings_service_, sync_service_, + identity_test_env_.identity_manager(), &kids_chrome_management_client_, + syncable_pref_service_, settings_service_, sync_service_, /*check_webstore_url_callback=*/ base::BindRepeating([](const GURL& url) { return false; }), std::make_unique<FilterDelegateImpl>(),
diff --git a/components/sync/base/features.cc b/components/sync/base/features.cc index c6817e8..61e60f8 100644 --- a/components/sync/base/features.cc +++ b/components/sync/base/features.cc
@@ -8,10 +8,6 @@ namespace syncer { -BASE_FEATURE(kCacheBaseEntitySpecificsInMetadata, - "CacheBaseEntitySpecificsInMetadata", - base::FEATURE_ENABLED_BY_DEFAULT); - BASE_FEATURE(kDeferredSyncStartupCustomDelay, "DeferredSyncStartupCustomDelay", base::FEATURE_DISABLED_BY_DEFAULT); @@ -43,10 +39,6 @@ "SyncAutofillWalletUsageData", base::FEATURE_DISABLED_BY_DEFAULT); -BASE_FEATURE(kSyncExtensionTypesThrottling, - "SyncExtensionTypesThrottling", - base::FEATURE_ENABLED_BY_DEFAULT); - BASE_FEATURE(kSyncSegmentationDataType, "SyncSegmentationDataType", base::FEATURE_DISABLED_BY_DEFAULT);
diff --git a/components/sync/base/features.h b/components/sync/base/features.h index 9fd4fe8..e6e9e09 100644 --- a/components/sync/base/features.h +++ b/components/sync/base/features.h
@@ -10,11 +10,6 @@ namespace syncer { -// If enabled, EntitySpecifics will be cached in EntityMetadata in order to -// prevent data loss caused by older clients dealing with unknown proto fields -// (introduced later). -BASE_DECLARE_FEATURE(kCacheBaseEntitySpecificsInMetadata); - // Customizes the delay of a deferred sync startup. BASE_DECLARE_FEATURE(kDeferredSyncStartupCustomDelay); inline constexpr base::FeatureParam<int> @@ -65,12 +60,6 @@ // Controls whether to enable syncing of Autofill Wallet Usage Data. BASE_DECLARE_FEATURE(kSyncAutofillWalletUsageData); -// Causes the sync engine to count a quota for commits of data types that can -// be committed by extension JS API. If the quota is depleted, an extra long -// nudge delay is applied to that data type. As a result, more changes are -// likely to get combined into one commit message. -BASE_DECLARE_FEATURE(kSyncExtensionTypesThrottling); - // If enabled, Segmentation data type will be synced. BASE_DECLARE_FEATURE(kSyncSegmentationDataType);
diff --git a/components/sync/engine/cycle/data_type_tracker.cc b/components/sync/engine/cycle/data_type_tracker.cc index cb84d7bc46..a3c8e60 100644 --- a/components/sync/engine/cycle/data_type_tracker.cc +++ b/components/sync/engine/cycle/data_type_tracker.cc
@@ -201,8 +201,7 @@ // Sanity check the hardcode value for kMinLocalChangeNudgeDelay. DCHECK_GE(local_change_nudge_delay_, kMinLocalChangeNudgeDelay); - if (CanGetCommitsFromExtensions(type) && - base::FeatureList::IsEnabled(kSyncExtensionTypesThrottling)) { + if (CanGetCommitsFromExtensions(type)) { quota_ = std::make_unique<CommitQuota>(kInitialTokensForExtensionTypes, kRefillIntervalForExtensionTypes); }
diff --git a/components/sync/model/client_tag_based_model_type_processor.cc b/components/sync/model/client_tag_based_model_type_processor.cc index eba17dc..2d27b92 100644 --- a/components/sync/model/client_tag_based_model_type_processor.cc +++ b/components/sync/model/client_tag_based_model_type_processor.cc
@@ -1382,10 +1382,7 @@ const std::string& storage_key) const { DCHECK(entity_tracker_); DCHECK(!storage_key.empty()); - if (!base::FeatureList::IsEnabled( - syncer::kCacheBaseEntitySpecificsInMetadata)) { - return sync_pb::EntitySpecifics::default_instance(); - } + ProcessorEntity* entity = entity_tracker_->GetEntityForStorageKey(storage_key); if (entity == nullptr) {
diff --git a/components/sync/model/client_tag_based_model_type_processor_unittest.cc b/components/sync/model/client_tag_based_model_type_processor_unittest.cc index 8f80c03..1b515c1 100644 --- a/components/sync/model/client_tag_based_model_type_processor_unittest.cc +++ b/components/sync/model/client_tag_based_model_type_processor_unittest.cc
@@ -660,8 +660,6 @@ // Test that an initial sync handles local and remote items properly. TEST_F(ClientTagBasedModelTypeProcessorTest, ShouldMergeLocalAndRemoteChanges) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(kCacheBaseEntitySpecificsInMetadata); ModelReadyToSync(); OnSyncStarting(); @@ -700,8 +698,6 @@ TEST_F(ClientTagBasedModelTypeProcessorTest, ShouldExposePossiblyTrimmedRemoteSpecifics) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(kCacheBaseEntitySpecificsInMetadata); ModelReadyToSync(); OnSyncStarting(); @@ -996,8 +992,6 @@ // Creates a new item locally. // Thoroughly tests the data generated by a local item creation. TEST_F(ClientTagBasedModelTypeProcessorTest, ShouldCommitLocalCreation) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(kCacheBaseEntitySpecificsInMetadata); base::HistogramTester histogram_tester; InitializeToReadyState(); ASSERT_EQ(0U, worker()->GetNumPendingCommits()); @@ -1057,8 +1051,6 @@ // hash. TEST_F(ClientTagBasedModelTypeProcessorTest, CommitShouldOverwriteExistingItem) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(kCacheBaseEntitySpecificsInMetadata); base::HistogramTester histogram_tester; // Provide custom client tags for this test. bridge()->SetSupportsGetClientTag(false);
diff --git a/components/sync/model/client_tag_based_remote_update_handler_unittest.cc b/components/sync/model/client_tag_based_remote_update_handler_unittest.cc index 9b17ee2..1e85594 100644 --- a/components/sync/model/client_tag_based_remote_update_handler_unittest.cc +++ b/components/sync/model/client_tag_based_remote_update_handler_unittest.cc
@@ -127,9 +127,6 @@ // Thoroughly tests the data generated by a server item creation. TEST_F(ClientTagBasedRemoteUpdateHandlerTest, ShouldProcessRemoteCreation) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(kCacheBaseEntitySpecificsInMetadata); - ProcessSingleUpdate(GenerateUpdate(kKey1, kValue1)); EXPECT_EQ(1u, db()->data_count()); EXPECT_EQ(1u, db()->metadata_count()); @@ -179,9 +176,6 @@ TEST_F(ClientTagBasedRemoteUpdateHandlerTest, ShouldNotClearTrimmedSpecificsOnNoopRemoteUpdates) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(kCacheBaseEntitySpecificsInMetadata); - const std::string kUnknownField = "unknown_field"; // Initial update containing unsupported fields. @@ -236,9 +230,6 @@ } TEST_F(ClientTagBasedRemoteUpdateHandlerTest, ShouldProcessRemoteUpdates) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(kCacheBaseEntitySpecificsInMetadata); - ProcessSingleUpdate(GenerateUpdate(kKey1, kValue1)); ASSERT_EQ(1U, ProcessorEntityCount()); ASSERT_EQ(1U, db()->data_change_count());
diff --git a/components/sync/model/forwarding_model_type_controller_delegate.h b/components/sync/model/forwarding_model_type_controller_delegate.h index c10615ef..c65999d 100644 --- a/components/sync/model/forwarding_model_type_controller_delegate.h +++ b/components/sync/model/forwarding_model_type_controller_delegate.h
@@ -41,7 +41,7 @@ void ClearMetadataWhileStopped() override; private: - const raw_ptr<ModelTypeControllerDelegate, DanglingUntriaged> other_; + const raw_ptr<ModelTypeControllerDelegate, DanglingAcrossTasks> other_; }; } // namespace syncer
diff --git a/components/sync/model/processor_entity.cc b/components/sync/model/processor_entity.cc index 59c6b68f..f1f42afd 100644 --- a/components/sync/model/processor_entity.cc +++ b/components/sync/model/processor_entity.cc
@@ -171,10 +171,8 @@ metadata_.set_modification_time( TimeToProtoTime(update.entity.modification_time)); UpdateSpecificsHash(update.entity.specifics); - if (base::FeatureList::IsEnabled(kCacheBaseEntitySpecificsInMetadata)) { - *metadata_.mutable_possibly_trimmed_base_specifics() = - std::move(trimmed_specifics); - } + *metadata_.mutable_possibly_trimmed_base_specifics() = + std::move(trimmed_specifics); } void ProcessorEntity::RecordForcedRemoteUpdate( @@ -202,12 +200,11 @@ // it remembers specifics hash before the modifications. IncrementSequenceNumber(modification_time); UpdateSpecificsHash(data->specifics); - if (base::FeatureList::IsEnabled(kCacheBaseEntitySpecificsInMetadata)) { - *metadata_.mutable_possibly_trimmed_base_specifics() = - std::move(trimmed_specifics); - } - if (!data->creation_time.is_null()) + *metadata_.mutable_possibly_trimmed_base_specifics() = + std::move(trimmed_specifics); + if (!data->creation_time.is_null()) { metadata_.set_creation_time(TimeToProtoTime(data->creation_time)); + } metadata_.set_modification_time(TimeToProtoTime(modification_time)); metadata_.set_is_deleted(false);
diff --git a/components/sync/model/processor_entity_tracker_unittest.cc b/components/sync/model/processor_entity_tracker_unittest.cc index f59b6e1..405d4b7 100644 --- a/components/sync/model/processor_entity_tracker_unittest.cc +++ b/components/sync/model/processor_entity_tracker_unittest.cc
@@ -325,9 +325,6 @@ } TEST_F(ProcessorEntityTrackerTest, ShouldUpdateSpecificsCacheOnLocalCreation) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(kCacheBaseEntitySpecificsInMetadata); - std::unique_ptr<EntityData> entity_data = std::make_unique<EntityData>( GenerateEntityData(kStorageKey1, kClientTagHash1)); sync_pb::EntitySpecifics specifics_for_caching; @@ -343,9 +340,6 @@ } TEST_F(ProcessorEntityTrackerTest, ShouldUpdateSpecificsCacheOnRemoteCreation) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(kCacheBaseEntitySpecificsInMetadata); - sync_pb::EntitySpecifics specifics_for_caching; specifics_for_caching.mutable_preference()->set_name("name"); specifics_for_caching.mutable_preference()->set_value("value");
diff --git a/components/sync/model/processor_entity_unittest.cc b/components/sync/model/processor_entity_unittest.cc index 7822478..4dd9cf63 100644 --- a/components/sync/model/processor_entity_unittest.cc +++ b/components/sync/model/processor_entity_unittest.cc
@@ -676,8 +676,6 @@ } TEST_F(ProcessorEntityTest, UpdatesSpecificsCacheOnRemoteUpdates) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(kCacheBaseEntitySpecificsInMetadata); std::unique_ptr<ProcessorEntity> entity = CreateNew(); const base::Time mtime = base::Time::Now(); UpdateResponseData update = @@ -691,9 +689,6 @@ } TEST_F(ProcessorEntityTest, UpdatesSpecificsCacheOnLocalUpdates) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(kCacheBaseEntitySpecificsInMetadata); - std::unique_ptr<ProcessorEntity> entity = CreateNew(); sync_pb::EntitySpecifics specifics_for_caching = GenerateSpecifics(kName, kValue2);
diff --git a/components/sync/nigori/cryptographer_impl.cc b/components/sync/nigori/cryptographer_impl.cc index 70d7be8..c886274 100644 --- a/components/sync/nigori/cryptographer_impl.cc +++ b/components/sync/nigori/cryptographer_impl.cc
@@ -66,10 +66,6 @@ *proto.mutable_key_bag() = key_bag_.ToProto(); proto.set_default_key_name(default_encryption_key_name_); *proto.mutable_cross_user_sharing_keys() = cross_user_sharing_keys_.ToProto(); - // TODO(crbug/1445056): once NigoriKeyBag is properly forked and encrypted - // remove the additional copy. - proto.mutable_key_bag()->mutable_cross_user_sharing_private_key()->CopyFrom( - proto.cross_user_sharing_keys().private_key()); return proto; }
diff --git a/components/sync/nigori/nigori_key_bag.cc b/components/sync/nigori/nigori_key_bag.cc index 7d38119..91d27c4 100644 --- a/components/sync/nigori/nigori_key_bag.cc +++ b/components/sync/nigori/nigori_key_bag.cc
@@ -10,6 +10,7 @@ #include "base/logging.h" #include "base/notreached.h" #include "components/sync/engine/nigori/nigori.h" +#include "components/sync/protocol/nigori_local_data.pb.h" #include "components/sync/protocol/nigori_specifics.pb.h" namespace syncer { @@ -48,7 +49,8 @@ } // static -NigoriKeyBag NigoriKeyBag::CreateFromProto(const sync_pb::NigoriKeyBag& proto) { +NigoriKeyBag NigoriKeyBag::CreateFromProto( + const sync_pb::LocalNigoriKeyBag& proto) { NigoriKeyBag output; for (const sync_pb::NigoriKey& key : proto.key()) { if (output.AddKeyFromProto(key).empty()) { @@ -64,8 +66,8 @@ NigoriKeyBag::~NigoriKeyBag() = default; -sync_pb::NigoriKeyBag NigoriKeyBag::ToProto() const { - sync_pb::NigoriKeyBag output; +sync_pb::LocalNigoriKeyBag NigoriKeyBag::ToProto() const { + sync_pb::LocalNigoriKeyBag output; for (const auto& [key_name, nigori] : nigori_map_) { *output.add_key() = NigoriToProto(*nigori, key_name); }
diff --git a/components/sync/nigori/nigori_key_bag.h b/components/sync/nigori/nigori_key_bag.h index 052a3a1..ab74b93 100644 --- a/components/sync/nigori/nigori_key_bag.h +++ b/components/sync/nigori/nigori_key_bag.h
@@ -14,7 +14,7 @@ namespace sync_pb { class EncryptedData; class NigoriKey; -class NigoriKeyBag; +class LocalNigoriKeyBag; } // namespace sync_pb namespace syncer { @@ -27,7 +27,8 @@ public: static NigoriKeyBag CreateEmpty(); // Deserialization from proto. - static NigoriKeyBag CreateFromProto(const sync_pb::NigoriKeyBag& key_bag); + static NigoriKeyBag CreateFromProto( + const sync_pb::LocalNigoriKeyBag& key_bag); NigoriKeyBag(NigoriKeyBag&& other); ~NigoriKeyBag(); @@ -35,7 +36,7 @@ NigoriKeyBag& operator=(NigoriKeyBag&&) = default; // Serialization to proto. - sync_pb::NigoriKeyBag ToProto() const; + sync_pb::LocalNigoriKeyBag ToProto() const; // Makes a deep copy of |*this|. NigoriKeyBag Clone() const;
diff --git a/components/sync/nigori/nigori_key_bag_unittest.cc b/components/sync/nigori/nigori_key_bag_unittest.cc index c5b52889..86c6f810 100644 --- a/components/sync/nigori/nigori_key_bag_unittest.cc +++ b/components/sync/nigori/nigori_key_bag_unittest.cc
@@ -8,6 +8,7 @@ #include "components/sync/engine/nigori/key_derivation_params.h" #include "components/sync/engine/nigori/nigori.h" +#include "components/sync/protocol/nigori_local_data.pb.h" #include "components/sync/protocol/nigori_specifics.pb.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -66,7 +67,7 @@ } TEST(NigoriKeyBagTest, ShouldConvertEmptyToProto) { - EXPECT_EQ(sync_pb::NigoriKeyBag().SerializeAsString(), + EXPECT_EQ(sync_pb::LocalNigoriKeyBag().SerializeAsString(), NigoriKeyBag::CreateEmpty().ToProto().SerializeAsString()); } @@ -74,7 +75,7 @@ NigoriKeyBag key_bag = NigoriKeyBag::CreateEmpty(); const std::string key_name = key_bag.AddKey(CreateTestNigori("password1")); - sync_pb::NigoriKeyBag proto = key_bag.ToProto(); + sync_pb::LocalNigoriKeyBag proto = key_bag.ToProto(); ASSERT_THAT(proto.key(), SizeIs(1)); // Callers of ToProto() rely on the deprecated name field being populated, // since it gets exposed to the sync protocol, and hence subject to backward @@ -86,7 +87,7 @@ } TEST(NigoriKeyBagTest, ShouldCreateEmptyFromProto) { - EXPECT_THAT(NigoriKeyBag::CreateFromProto(sync_pb::NigoriKeyBag()), + EXPECT_THAT(NigoriKeyBag::CreateFromProto(sync_pb::LocalNigoriKeyBag()), SizeIs(0)); } @@ -112,7 +113,7 @@ const std::string key_name2 = original_key_bag.AddKey(CreateTestNigori("password2")); - sync_pb::NigoriKeyBag malformed_proto = original_key_bag.ToProto(); + sync_pb::LocalNigoriKeyBag malformed_proto = original_key_bag.ToProto(); ASSERT_THAT(malformed_proto.key(), SizeIs(2)); malformed_proto.mutable_key(1)->set_encryption_key("malformed-key"); @@ -149,7 +150,7 @@ const std::string actual_key_name_in_proto = NigoriKeyBag::CreateEmpty().AddKey(CreateTestNigori("password2")); - sync_pb::NigoriKeyBag proto = original_key_bag.ToProto(); + sync_pb::LocalNigoriKeyBag proto = original_key_bag.ToProto(); proto.mutable_key(0)->set_deprecated_name(actual_key_name_in_proto); NigoriKeyBag restored_key_bag = NigoriKeyBag::CreateFromProto(proto);
diff --git a/components/sync/nigori/nigori_state.cc b/components/sync/nigori/nigori_state.cc index 1fdba73..477d9f6 100644 --- a/components/sync/nigori/nigori_state.cc +++ b/components/sync/nigori/nigori_state.cc
@@ -58,8 +58,14 @@ sync_pb::CryptographerData proto = cryptographer.ToProto(); DCHECK(!proto.key_bag().key().empty()); + sync_pb::NigoriKeyBag keys_for_encryption; + + keys_for_encryption.mutable_key()->CopyFrom(proto.key_bag().key()); + keys_for_encryption.mutable_cross_user_sharing_private_key()->CopyFrom( + proto.cross_user_sharing_keys().private_key()); + // Encrypt the bag with the default Nigori. - return cryptographer.Encrypt(proto.key_bag(), encrypted); + return cryptographer.Encrypt(keys_for_encryption, encrypted); } // Writes deprecated per-type encryption fields. Can be removed once <M82
diff --git a/components/sync/nigori/nigori_sync_bridge_impl.cc b/components/sync/nigori/nigori_sync_bridge_impl.cc index 40c5f5d8..022472d 100644 --- a/components/sync/nigori/nigori_sync_bridge_impl.cc +++ b/components/sync/nigori/nigori_sync_bridge_impl.cc
@@ -812,8 +812,11 @@ const std::string new_default_key_name = state_.pending_keys->key_name(); DCHECK(key_bag.HasKey(new_default_key_name)); - NigoriKeyBag new_key_bag = - NigoriKeyBag::CreateFromProto(decrypted_pending_keys); + NigoriKeyBag new_key_bag = NigoriKeyBag::CreateEmpty(); + base::ranges::for_each(decrypted_pending_keys.key(), + [&new_key_bag](sync_pb::NigoriKey key) { + new_key_bag.AddKeyFromProto(key); + }); if (!new_key_bag.HasKey(new_default_key_name)) { // Protocol violation.
diff --git a/components/sync/protocol/nigori_local_data.proto b/components/sync/protocol/nigori_local_data.proto index b1bbfb2..2a3004e 100644 --- a/components/sync/protocol/nigori_local_data.proto +++ b/components/sync/protocol/nigori_local_data.proto
@@ -24,10 +24,14 @@ repeated CrossUserSharingPrivateKey private_key = 1; } +message LocalNigoriKeyBag { + // Used for encrypting within the sync account boundary. + repeated NigoriKey key = 2; +} + message CryptographerData { // Contains all known Nigori keys. - // TODO(crbug/1445056): fork the NigoriKeyBag into a local proto. - optional NigoriKeyBag key_bag = 1; + optional LocalNigoriKeyBag key_bag = 1; // Default key is the key, that should be used for encryption. Can be empty // in case we have pending keys (waiting for explicit passphrase, or client
diff --git a/components/sync/test/nigori_test_utils.cc b/components/sync/test/nigori_test_utils.cc index 79fbbe5..9aa5317 100644 --- a/components/sync/test/nigori_test_utils.cc +++ b/components/sync/test/nigori_test_utils.cc
@@ -6,6 +6,7 @@ #include "base/base64.h" #include "base/check.h" +#include "base/ranges/algorithm.h" #include "components/sync/base/time.h" #include "components/sync/engine/nigori/key_derivation_params.h" #include "components/sync/engine/nigori/nigori.h" @@ -187,7 +188,10 @@ sync_pb::NigoriKeyBag decrypted_keys; EXPECT_TRUE(decrypted_keys.ParseFromString(decrypted_keys_str)); - NigoriKeyBag key_bag = NigoriKeyBag::CreateFromProto(decrypted_keys); + NigoriKeyBag key_bag = NigoriKeyBag::CreateEmpty(); + base::ranges::for_each( + decrypted_keys.key(), + [&key_bag](sync_pb::NigoriKey key) { key_bag.AddKeyFromProto(key); }); cryptographer->EmplaceKeysFrom(key_bag); return cryptographer;
diff --git a/components/sync_bookmarks/bookmark_model_type_processor.h b/components/sync_bookmarks/bookmark_model_type_processor.h index e458039a..7ed4eca 100644 --- a/components/sync_bookmarks/bookmark_model_type_processor.h +++ b/components/sync_bookmarks/bookmark_model_type_processor.h
@@ -156,13 +156,13 @@ // The bookmark model we are processing local changes from and forwarding // remote changes to. It is set during ModelReadyToSync(), which is called // during startup, as part of the bookmark-loading process. - raw_ptr<bookmarks::BookmarkModel, DanglingUntriaged> bookmark_model_ = + raw_ptr<bookmarks::BookmarkModel, DanglingAcrossTasks> bookmark_model_ = nullptr; // Used to when processing remote updates to apply favicon information. It's // not set at start up because it's only avialable after the bookmark model // has been loaded. - raw_ptr<favicon::FaviconService, DanglingUntriaged> favicon_service_ = + raw_ptr<favicon::FaviconService, DanglingAcrossTasks> favicon_service_ = nullptr; // Used to suspend bookmark undo when processing remote changes.
diff --git a/components/user_prefs/user_prefs.h b/components/user_prefs/user_prefs.h index 4efdacc..62702f3 100644 --- a/components/user_prefs/user_prefs.h +++ b/components/user_prefs/user_prefs.h
@@ -36,7 +36,7 @@ explicit UserPrefs(PrefService* prefs); // Non-owning; owned by embedder. - raw_ptr<PrefService, DanglingUntriaged> prefs_; + raw_ptr<PrefService, DanglingAcrossTasks> prefs_; }; } // namespace user_prefs
diff --git a/components/viz/common/BUILD.gn b/components/viz/common/BUILD.gn index 8093228..ca605c3 100644 --- a/components/viz/common/BUILD.gn +++ b/components/viz/common/BUILD.gn
@@ -47,8 +47,6 @@ defines = [ "VIZ_RESOURCE_FORMAT_IMPLEMENTATION" ] sources = [ - "resources/resource_format_utils.cc", - "resources/resource_format_utils.h", "resources/resource_sizes.h", "resources/shared_image_format_utils.cc", "resources/shared_image_format_utils.h",
diff --git a/components/viz/common/resources/bitmap_allocation.cc b/components/viz/common/resources/bitmap_allocation.cc index 150f175..f5352bf93 100644 --- a/components/viz/common/resources/bitmap_allocation.cc +++ b/components/viz/common/resources/bitmap_allocation.cc
@@ -13,7 +13,6 @@ #include "base/memory/read_only_shared_memory_region.h" #include "base/process/memory.h" #include "build/build_config.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/resource_sizes.h" #include "mojo/public/cpp/system/platform_handle.h" #include "ui/gfx/geometry/size.h"
diff --git a/components/viz/common/resources/resource_format_utils.cc b/components/viz/common/resources/resource_format_utils.cc deleted file mode 100644 index eb983f5..0000000 --- a/components/viz/common/resources/resource_format_utils.cc +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright 2016 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/viz/common/resources/resource_format_utils.h" - -#include <GLES2/gl2.h> -#include <GLES2/gl2ext.h> -#include <GLES2/gl2extchromium.h> - -#include <ostream> - -#include "base/check_op.h" -#include "base/logging.h" -#include "base/notreached.h" -#include "build/chromeos_buildflags.h" -#include "ui/gfx/buffer_types.h" - -namespace viz { - -} // namespace viz
diff --git a/components/viz/common/resources/resource_format_utils.h b/components/viz/common/resources/resource_format_utils.h deleted file mode 100644 index 7a41e31..0000000 --- a/components/viz/common/resources/resource_format_utils.h +++ /dev/null
@@ -1,15 +0,0 @@ -// Copyright 2016 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_VIZ_COMMON_RESOURCES_RESOURCE_FORMAT_UTILS_H_ -#define COMPONENTS_VIZ_COMMON_RESOURCES_RESOURCE_FORMAT_UTILS_H_ - -#include "components/viz/common/resources/resource_format.h" -#include "components/viz/common/viz_resource_format_export.h" - -namespace viz { - -} // namespace viz - -#endif // COMPONENTS_VIZ_COMMON_RESOURCES_RESOURCE_FORMAT_UTILS_H_
diff --git a/components/viz/common/resources/resource_format_utils_unittest.cc b/components/viz/common/resources/resource_format_utils_unittest.cc index b5d3c0e..eca486e 100644 --- a/components/viz/common/resources/resource_format_utils_unittest.cc +++ b/components/viz/common/resources/resource_format_utils_unittest.cc
@@ -4,7 +4,6 @@ #include <vector> -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/shared_image_format_utils.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/components/viz/common/resources/shared_bitmap.cc b/components/viz/common/resources/shared_bitmap.cc index 5410068..02ade0b 100644 --- a/components/viz/common/resources/shared_bitmap.cc +++ b/components/viz/common/resources/shared_bitmap.cc
@@ -10,7 +10,6 @@ #include "base/numerics/safe_math.h" #include "base/rand_util.h" #include "base/strings/string_number_conversions.h" -#include "components/viz/common/resources/resource_format_utils.h" namespace viz {
diff --git a/components/viz/common/resources/shared_image_format_utils.cc b/components/viz/common/resources/shared_image_format_utils.cc index ff052085..d963b5d 100644 --- a/components/viz/common/resources/shared_image_format_utils.cc +++ b/components/viz/common/resources/shared_image_format_utils.cc
@@ -12,7 +12,6 @@ #include "base/logging.h" #include "base/notreached.h" #include "components/viz/common/resources/resource_format.h" -#include "components/viz/common/resources/resource_format_utils.h" namespace viz {
diff --git a/components/viz/service/display/display_resource_provider_software.cc b/components/viz/service/display/display_resource_provider_software.cc index 6881ba15..d5bd2c73 100644 --- a/components/viz/service/display/display_resource_provider_software.cc +++ b/components/viz/service/display/display_resource_provider_software.cc
@@ -7,7 +7,6 @@ #include <memory> #include <vector> -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/service/display/shared_bitmap_manager.h" #include "third_party/skia/include/core/SkImage.h"
diff --git a/components/viz/service/display/display_resource_provider_software_unittest.cc b/components/viz/service/display/display_resource_provider_software_unittest.cc index cfcbef86..dcc8f33 100644 --- a/components/viz/service/display/display_resource_provider_software_unittest.cc +++ b/components/viz/service/display/display_resource_provider_software_unittest.cc
@@ -23,7 +23,6 @@ #include "components/viz/client/client_resource_provider.h" #include "components/viz/common/resources/bitmap_allocation.h" #include "components/viz/common/resources/release_callback.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/returned_resource.h" #include "components/viz/common/resources/shared_bitmap.h" #include "components/viz/service/display/shared_bitmap_manager.h"
diff --git a/components/viz/service/display/resolved_frame_data.h b/components/viz/service/display/resolved_frame_data.h index 6edf2d9..e4632c4 100644 --- a/components/viz/service/display/resolved_frame_data.h +++ b/components/viz/service/display/resolved_frame_data.h
@@ -43,7 +43,7 @@ FixedPassData& operator=(FixedPassData&& other); ~FixedPassData(); - raw_ptr<CompositorRenderPass, DanglingUntriaged> render_pass = nullptr; + raw_ptr<CompositorRenderPass, DanglingAcrossTasks> render_pass = nullptr; // DrawQuads in |render_pass| that can contribute additional damage (eg. // surface and render passes) that need to be visited during the prewalk phase // of aggregation. Stored in front-to-back order like in |render_pass|.
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc index 192afb7..bac1aba 100644 --- a/components/viz/service/display/skia_renderer.cc +++ b/components/viz/service/display/skia_renderer.cc
@@ -40,7 +40,6 @@ #include "components/viz/common/quads/tile_draw_quad.h" #include "components/viz/common/quads/yuv_video_draw_quad.h" #include "components/viz/common/resources/platform_color.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/shared_image_format_utils.h" #include "components/viz/common/skia_helper.h" #include "components/viz/service/debugger/viz_debugger.h"
diff --git a/components/viz/service/display_embedder/output_presenter_fuchsia.cc b/components/viz/service/display_embedder/output_presenter_fuchsia.cc index e16f1778..fb64272f 100644 --- a/components/viz/service/display_embedder/output_presenter_fuchsia.cc +++ b/components/viz/service/display_embedder/output_presenter_fuchsia.cc
@@ -13,7 +13,6 @@ #include "base/notreached.h" #include "components/viz/common/features.h" #include "components/viz/common/gpu/vulkan_context_provider.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/service/display_embedder/skia_output_surface_dependency.h" #include "gpu/command_buffer/service/external_semaphore.h" #include "ui/gfx/geometry/rect_conversions.h"
diff --git a/components/viz/service/display_embedder/skia_output_device_dcomp.cc b/components/viz/service/display_embedder/skia_output_device_dcomp.cc index 6ad24cc..c506b5e 100644 --- a/components/viz/service/display_embedder/skia_output_device_dcomp.cc +++ b/components/viz/service/display_embedder/skia_output_device_dcomp.cc
@@ -12,7 +12,6 @@ #include "base/functional/callback_helpers.h" #include "base/memory/scoped_refptr.h" #include "components/viz/common/gpu/context_lost_reason.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/shared_image_format.h" #include "components/viz/service/display/dc_layer_overlay.h" #include "gpu/command_buffer/common/mailbox.h"
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.cc b/components/viz/service/display_embedder/skia_output_surface_impl.cc index e263e108..ba707bf0 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl.cc
@@ -24,7 +24,6 @@ #include "components/viz/common/frame_sinks/begin_frame_source.h" #include "components/viz/common/frame_sinks/copy_output_request.h" #include "components/viz/common/frame_sinks/copy_output_util.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/shared_image_format_utils.h" #include "components/viz/service/display/external_use_client.h" #include "components/viz/service/display/output_surface_client.h"
diff --git a/components/viz/service/hit_test/hit_test_aggregator.h b/components/viz/service/hit_test/hit_test_aggregator.h index 4a6b09b8..60cde91 100644 --- a/components/viz/service/hit_test/hit_test_aggregator.h +++ b/components/viz/service/hit_test/hit_test_aggregator.h
@@ -80,7 +80,7 @@ const raw_ptr<HitTestAggregatorDelegate> delegate_; - const raw_ptr<LatestLocalSurfaceIdLookupDelegate, DanglingUntriaged> + const raw_ptr<LatestLocalSurfaceIdLookupDelegate, DanglingAcrossTasks> local_surface_id_lookup_delegate_; // This is the FrameSinkId for the corresponding root CompositorFrameSink.
diff --git a/components/viz/test/test_context_provider.cc b/components/viz/test/test_context_provider.cc index 67bd6447..7edb9a5 100644 --- a/components/viz/test/test_context_provider.cc +++ b/components/viz/test/test_context_provider.cc
@@ -19,7 +19,6 @@ #include "base/notreached.h" #include "build/build_config.h" #include "components/viz/common/gpu/context_cache_controller.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/shared_image_format_utils.h" #include "components/viz/test/test_gles2_interface.h" #include "components/viz/test/test_raster_interface.h"
diff --git a/components/viz/test/test_in_process_context_provider.cc b/components/viz/test/test_in_process_context_provider.cc index 936519e..c6a5353 100644 --- a/components/viz/test/test_in_process_context_provider.cc +++ b/components/viz/test/test_in_process_context_provider.cc
@@ -12,7 +12,6 @@ #include "base/task/single_thread_task_runner.h" #include "base/types/optional_util.h" #include "components/viz/common/gpu/context_cache_controller.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/shared_image_format_utils.h" #include "components/viz/service/gl/gpu_service_impl.h" #include "components/viz/test/test_gpu_service_holder.h"
diff --git a/components/viz/test/test_shared_bitmap_manager.cc b/components/viz/test/test_shared_bitmap_manager.cc index fad1a30..025ce2db 100644 --- a/components/viz/test/test_shared_bitmap_manager.cc +++ b/components/viz/test/test_shared_bitmap_manager.cc
@@ -11,7 +11,6 @@ #include "base/memory/read_only_shared_memory_region.h" #include "base/notreached.h" #include "components/viz/common/resources/bitmap_allocation.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "mojo/public/cpp/system/platform_handle.h" namespace viz {
diff --git a/components/webapps/browser/banners/app_banner_manager.h b/components/webapps/browser/banners/app_banner_manager.h index 64d5f6d..4abe842c 100644 --- a/components/webapps/browser/banners/app_banner_manager.h +++ b/components/webapps/browser/banners/app_banner_manager.h
@@ -479,7 +479,7 @@ InstallableStatusCode TerminationCode() const; // Fetches the data required to display a banner for the current page. - raw_ptr<InstallableManager, DanglingUntriaged> manager_; + raw_ptr<InstallableManager, DanglingAcrossTasks> manager_; // The manifest object. This is never null, it will instead be an empty // manifest so callers don't have to worry about null checks.
diff --git a/components/webdata/common/web_database_table.h b/components/webdata/common/web_database_table.h index 9ecacb5d..9972493 100644 --- a/components/webdata/common/web_database_table.h +++ b/components/webdata/common/web_database_table.h
@@ -55,8 +55,8 @@ // class exists. Since lifetime of WebDatabaseTable objects slightly // exceeds that of WebDatabase, they should not be used in // ~WebDatabaseTable. - raw_ptr<sql::Database, DanglingUntriaged> db_; - raw_ptr<sql::MetaTable, DanglingUntriaged> meta_table_; + raw_ptr<sql::Database, DanglingAcrossTasks> db_; + raw_ptr<sql::MetaTable, DanglingAcrossTasks> meta_table_; }; #endif // COMPONENTS_WEBDATA_COMMON_WEB_DATABASE_TABLE_H_
diff --git a/content/browser/accessibility/browser_accessibility_com_win.cc b/content/browser/accessibility/browser_accessibility_com_win.cc index 68dcc9b..b5b6eed 100644 --- a/content/browser/accessibility/browser_accessibility_com_win.cc +++ b/content/browser/accessibility/browser_accessibility_com_win.cc
@@ -55,6 +55,18 @@ BrowserAccessibilityComWin::WinAttributes::~WinAttributes() {} // +// BrowserAccessibilityComWin::UpdateState +// + +BrowserAccessibilityComWin::UpdateState::UpdateState( + std::unique_ptr<WinAttributes> old_win_attributes, + ui::AXLegacyHypertext old_hypertext) + : old_win_attributes(std::move(old_win_attributes)), + old_hypertext(std::move(old_hypertext)) {} + +BrowserAccessibilityComWin::UpdateState::~UpdateState() = default; + +// // BrowserAccessibilityComWin // BrowserAccessibilityComWin::BrowserAccessibilityComWin() @@ -317,11 +329,13 @@ if (!new_text) return E_INVALIDARG; - if (!old_win_attributes_) + if (!update_state_) { return E_FAIL; + } size_t start, old_len, new_len; - ComputeHypertextRemovedAndInserted(&start, &old_len, &new_len); + ComputeHypertextRemovedAndInserted(update_state_->old_hypertext, &start, + &old_len, &new_len); if (new_len == 0) return E_FAIL; @@ -342,15 +356,17 @@ if (!old_text) return E_INVALIDARG; - if (!old_win_attributes_) + if (!update_state_) { return E_FAIL; + } size_t start, old_len, new_len; - ComputeHypertextRemovedAndInserted(&start, &old_len, &new_len); + ComputeHypertextRemovedAndInserted(update_state_->old_hypertext, &start, + &old_len, &new_len); if (old_len == 0) return E_FAIL; - std::u16string old_hypertext = old_hypertext_.hypertext; + const std::u16string& old_hypertext = update_state_->old_hypertext.hypertext; std::u16string substr = old_hypertext.substr(start, old_len); old_text->text = SysAllocString(base::as_wcstr(substr)); old_text->start = static_cast<LONG>(start); @@ -1486,12 +1502,14 @@ // void BrowserAccessibilityComWin::UpdateStep1ComputeWinAttributes() { - // Swap win_attributes_ to old_win_attributes_, allowing us to see - // exactly what changed and fire appropriate events. Note that - // old_win_attributes_ is cleared at the end of UpdateStep3FireEvents. - old_win_attributes_.swap(win_attributes_); + DCHECK(!update_state_); + DCHECK(win_attributes_); - old_hypertext_ = hypertext_; + // Move win_attributes_ and hypertext_ into update_state_, allowing us to see + // exactly what changed and fire appropriate events. Note that update_state_ + // is destroyed at the end of UpdateStep3FireEvents. + update_state_ = std::make_unique<UpdateState>(std::move(win_attributes_), + std::move(hypertext_)); hypertext_ = ui::AXLegacyHypertext(); win_attributes_ = std::make_unique<WinAttributes>(); @@ -1514,26 +1532,34 @@ } void BrowserAccessibilityComWin::UpdateStep2ComputeHypertext() { + DCHECK(update_state_); UpdateComputedHypertext(); } void BrowserAccessibilityComWin::UpdateStep3FireEvents() { + DCHECK(update_state_); + DCHECK(update_state_->old_win_attributes); + const bool ignored = owner()->IsIgnored(); + const auto& old_win_attributes = *update_state_->old_win_attributes; + // Suppress all of these events when the node is ignored, or when the ignored // state has changed on a node that isn't part of an active live region. - if (ignored || (old_win_attributes_->ignored != ignored && + if (ignored || (old_win_attributes.ignored != ignored && !owner()->GetData().IsContainedInActiveLiveRegion() && !owner()->GetData().IsActiveLiveRegionRoot())) { + update_state_.reset(); return; } // The rest of the events only fire on changes, not on new objects. - if (old_win_attributes_->ia_role != 0) { + if (old_win_attributes.ia_role != 0) { // Fire an event if the description, help, or value changes. - if (description() != old_win_attributes_->description) + if (description() != old_win_attributes.description) { FireNativeEvent(EVENT_OBJECT_DESCRIPTIONCHANGE); + } // Fire an event if this container object has scrolled. int sx = 0; @@ -1550,10 +1576,11 @@ // Do not fire removed/inserted when a name change event will be fired by // AXEventGenerator, as they are providing redundant information and will // lead to duplicate announcements. - if (name() == old_win_attributes_->name || + if (name() == old_win_attributes.name || GetNameFrom() == ax::mojom::NameFrom::kContents) { size_t start, old_len, new_len; - ComputeHypertextRemovedAndInserted(&start, &old_len, &new_len); + ComputeHypertextRemovedAndInserted(update_state_->old_hypertext, &start, + &old_len, &new_len); if (old_len > 0) { // In-process screen readers may call IAccessibleText::get_oldText // in reaction to this event to retrieve the text that was removed. @@ -1567,8 +1594,7 @@ } } - old_win_attributes_.reset(nullptr); - old_hypertext_ = ui::AXLegacyHypertext(); + update_state_.reset(); } BrowserAccessibilityManager* BrowserAccessibilityComWin::Manager() const {
diff --git a/content/browser/accessibility/browser_accessibility_com_win.h b/content/browser/accessibility/browser_accessibility_com_win.h index 6168606..0966a3e4 100644 --- a/content/browser/accessibility/browser_accessibility_com_win.h +++ b/content/browser/accessibility/browser_accessibility_com_win.h
@@ -432,9 +432,21 @@ std::unique_ptr<WinAttributes> win_attributes_; + // Holds transient state needed only while processing a tree update. + struct UpdateState { + UpdateState(std::unique_ptr<WinAttributes> old_win_attributes, + ui::AXLegacyHypertext old_hypertext); + UpdateState(const UpdateState&) = delete; + UpdateState& operator=(const UpdateState&) = delete; + ~UpdateState(); + + std::unique_ptr<WinAttributes> old_win_attributes; + ui::AXLegacyHypertext old_hypertext; + }; + // Only valid during the scope of a IA2_EVENT_TEXT_REMOVED or // IA2_EVENT_TEXT_INSERTED event. - std::unique_ptr<WinAttributes> old_win_attributes_; + std::unique_ptr<UpdateState> update_state_; // The previous scroll position, so we can tell if this object scrolled. int previous_scroll_x_;
diff --git a/content/browser/attribution_reporting/attribution_internals_handler_impl.cc b/content/browser/attribution_reporting/attribution_internals_handler_impl.cc index 6e85fef5..6e800e50 100644 --- a/content/browser/attribution_reporting/attribution_internals_handler_impl.cc +++ b/content/browser/attribution_reporting/attribution_internals_handler_impl.cc
@@ -255,8 +255,14 @@ ContentBrowserClient::AttributionReportingOperation::kAny, /*rfh=*/nullptr, /*source_origin=*/nullptr, /*destination_origin=*/nullptr, /*reporting_origin=*/nullptr); + + // TODO(apaseltiner): This is a layering violation: The internals handler + // should query the manager for its configuration, not the command line, + // especially since `AttributionManager::SetDebugMode()` can cause its value + // to change after initialization. bool debug_mode = base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kAttributionReportingDebugMode); + std::move(callback).Run(attribution_reporting_enabled, debug_mode, AttributionManager::GetSupport()); }
diff --git a/content/browser/attribution_reporting/attribution_manager.h b/content/browser/attribution_reporting/attribution_manager.h index 851bf3c..139d968e 100644 --- a/content/browser/attribution_reporting/attribution_manager.h +++ b/content/browser/attribution_reporting/attribution_manager.h
@@ -16,6 +16,7 @@ #include "content/public/browser/attribution_data_model.h" #include "content/public/browser/storage_partition.h" #include "services/network/public/mojom/attribution.mojom-forward.h" +#include "third_party/abseil-cpp/absl/types/optional.h" namespace attribution_reporting { class SuitableOrigin; @@ -116,6 +117,12 @@ BrowsingDataFilterBuilder* filter_builder, bool delete_rate_limit_data, base::OnceClosure done) = 0; + + // If debug mode is enabled, noise and delays are disabled to facilitate + // testing, whether automated or manual. If `enabled` is `absl::nullopt`, + // falls back to `switches::kAttributionReportingDebugMode`. + virtual void SetDebugMode(absl::optional<bool> enabled, + base::OnceClosure done) = 0; }; } // namespace content
diff --git a/content/browser/attribution_reporting/attribution_manager_impl.cc b/content/browser/attribution_reporting/attribution_manager_impl.cc index 3674380..fd8c539 100644 --- a/content/browser/attribution_reporting/attribution_manager_impl.cc +++ b/content/browser/attribution_reporting/attribution_manager_impl.cc
@@ -350,10 +350,8 @@ } } -std::unique_ptr<AttributionStorageDelegate> MakeStorageDelegate() { - bool debug_mode = base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kAttributionReportingDebugMode); - +std::unique_ptr<AttributionStorageDelegate> MakeStorageDelegate( + bool debug_mode) { if (debug_mode) { return std::make_unique<AttributionStorageDelegateImpl>( AttributionNoiseMode::kNone, AttributionDelayMode::kNone); @@ -468,7 +466,8 @@ user_data_directory, /*max_pending_events=*/1000, std::move(special_storage_policy), - MakeStorageDelegate(), + MakeStorageDelegate(base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kAttributionReportingDebugMode)), std::make_unique<AttributionCookieCheckerImpl>(storage_partition), std::make_unique<AttributionReportNetworkSender>( storage_partition->GetURLLoaderFactoryForBrowserProcess()), @@ -1418,4 +1417,17 @@ : OsRegistrationResult::kRejectedByOs); } +void AttributionManagerImpl::SetDebugMode(absl::optional<bool> enabled, + base::OnceClosure done) { + bool debug_mode = + enabled.value_or(base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kAttributionReportingDebugMode)); + + // TODO(apaseltiner): Observers should be notified when the debug mode changes + // so they can re-query its value. + attribution_storage_.AsyncCall(&AttributionStorage::SetDelegate) + .WithArgs(MakeStorageDelegate(debug_mode)) + .Then(std::move(done)); +} + } // namespace content
diff --git a/content/browser/attribution_reporting/attribution_manager_impl.h b/content/browser/attribution_reporting/attribution_manager_impl.h index d7a0ec4..2153e3a 100644 --- a/content/browser/attribution_reporting/attribution_manager_impl.h +++ b/content/browser/attribution_reporting/attribution_manager_impl.h
@@ -139,6 +139,8 @@ const attribution_reporting::SuitableOrigin& reporting_origin, attribution_reporting::mojom::SourceType, attribution_reporting::mojom::SourceRegistrationError) override; + void SetDebugMode(absl::optional<bool> enabled, + base::OnceClosure done) override; void GetAllDataKeys( base::OnceCallback<void(std::set<DataKey>)> callback) override;
diff --git a/content/browser/attribution_reporting/attribution_storage.h b/content/browser/attribution_reporting/attribution_storage.h index d8fe58c7..d68a8744 100644 --- a/content/browser/attribution_reporting/attribution_storage.h +++ b/content/browser/attribution_reporting/attribution_storage.h
@@ -5,6 +5,7 @@ #ifndef CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_STORAGE_H_ #define CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_STORAGE_H_ +#include <memory> #include <set> #include <vector> @@ -20,6 +21,7 @@ namespace content { +class AttributionStorageDelegate; class AttributionTrigger; class CreateReportResult; class StorableSource; @@ -118,6 +120,8 @@ base::Time delete_end, StoragePartition::StorageKeyMatcherFunction filter, bool delete_rate_limit_data = true) = 0; + + virtual void SetDelegate(std::unique_ptr<AttributionStorageDelegate>) = 0; }; } // namespace content
diff --git a/content/browser/attribution_reporting/attribution_storage_delegate.h b/content/browser/attribution_reporting/attribution_storage_delegate.h index 09f7b11..2ffc0bb 100644 --- a/content/browser/attribution_reporting/attribution_storage_delegate.h +++ b/content/browser/attribution_reporting/attribution_storage_delegate.h
@@ -32,7 +32,9 @@ class StoredSource; // Storage delegate that can supplied to extend basic attribution storage -// functionality like annotating reports. +// functionality like annotating reports. Users and subclasses must NOT assume +// that the delegate has the same lifetime as the `AttributionManager` or +// `AttributionStorage` classes. class CONTENT_EXPORT AttributionStorageDelegate { public: // Both bounds are inclusive.
diff --git a/content/browser/attribution_reporting/attribution_storage_sql.cc b/content/browser/attribution_reporting/attribution_storage_sql.cc index 5098af8..4b70f2e 100644 --- a/content/browser/attribution_reporting/attribution_storage_sql.cc +++ b/content/browser/attribution_reporting/attribution_storage_sql.cc
@@ -3135,4 +3135,12 @@ /*delete_rate_limit_data=*/true); } +void AttributionStorageSql::SetDelegate( + std::unique_ptr<AttributionStorageDelegate> delegate) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(delegate); + rate_limit_table_.SetDelegate(*delegate); + delegate_ = std::move(delegate); +} + } // namespace content
diff --git a/content/browser/attribution_reporting/attribution_storage_sql.h b/content/browser/attribution_reporting/attribution_storage_sql.h index e1c88b7..ec8cbd3 100644 --- a/content/browser/attribution_reporting/attribution_storage_sql.h +++ b/content/browser/attribution_reporting/attribution_storage_sql.h
@@ -126,6 +126,7 @@ base::Time delete_end, StoragePartition::StorageKeyMatcherFunction filter, bool delete_rate_limit_data) override; + void SetDelegate(std::unique_ptr<AttributionStorageDelegate>) override; [[nodiscard]] attribution_reporting::mojom::StoreSourceResult CheckDestinationThrottler(const StorableSource& source);
diff --git a/content/browser/attribution_reporting/rate_limit_table.cc b/content/browser/attribution_reporting/rate_limit_table.cc index eadc9f8..c358ba04 100644 --- a/content/browser/attribution_reporting/rate_limit_table.cc +++ b/content/browser/attribution_reporting/rate_limit_table.cc
@@ -523,4 +523,9 @@ } } +void RateLimitTable::SetDelegate(const AttributionStorageDelegate& delegate) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + delegate_ = delegate; +} + } // namespace content
diff --git a/content/browser/attribution_reporting/rate_limit_table.h b/content/browser/attribution_reporting/rate_limit_table.h index 084dbe9..4c7e6f6f 100644 --- a/content/browser/attribution_reporting/rate_limit_table.h +++ b/content/browser/attribution_reporting/rate_limit_table.h
@@ -120,6 +120,8 @@ void AppendRateLimitDataKeys(sql::Database* db, std::set<AttributionDataModel::DataKey>& keys); + void SetDelegate(const AttributionStorageDelegate&); + private: [[nodiscard]] bool AddRateLimit( sql::Database* db, @@ -148,7 +150,7 @@ [[nodiscard]] bool DeleteExpiredRateLimits(sql::Database* db) VALID_CONTEXT_REQUIRED(sequence_checker_); - const raw_ref<const AttributionStorageDelegate> delegate_ + raw_ref<const AttributionStorageDelegate> delegate_ GUARDED_BY_CONTEXT(sequence_checker_); // Time at which `DeleteExpiredRateLimits()` was last called. Initialized to
diff --git a/content/browser/attribution_reporting/test/mock_attribution_manager.h b/content/browser/attribution_reporting/test/mock_attribution_manager.h index d689645a..e285bd8 100644 --- a/content/browser/attribution_reporting/test/mock_attribution_manager.h +++ b/content/browser/attribution_reporting/test/mock_attribution_manager.h
@@ -108,6 +108,11 @@ (OsRegistration, GlobalRenderFrameHostId), (override)); + MOCK_METHOD(void, + SetDebugMode, + (absl::optional<bool> enabled, base::OnceClosure done), + (override)); + void AddObserver(AttributionObserver*) override; void RemoveObserver(AttributionObserver*) override; AttributionDataHostManager* GetDataHostManager() override;
diff --git a/content/browser/child_process_security_policy_impl.cc b/content/browser/child_process_security_policy_impl.cc index 2bfca65c..701cf15 100644 --- a/content/browser/child_process_security_policy_impl.cc +++ b/content/browser/child_process_security_policy_impl.cc
@@ -719,7 +719,7 @@ FileSystemMap filesystem_permissions_; raw_ptr<BrowserContext> browser_context_; - raw_ptr<ResourceContext, DanglingUntriaged> resource_context_; + raw_ptr<ResourceContext, DanglingAcrossTasks> resource_context_; }; // IsolatedOriginEntry implementation.
diff --git a/content/browser/content_index/content_index_context_impl.h b/content/browser/content_index/content_index_context_impl.h index d19aa6a..6098074 100644 --- a/content/browser/content_index/content_index_context_impl.h +++ b/content/browser/content_index/content_index_context_impl.h
@@ -58,7 +58,7 @@ ~ContentIndexContextImpl() override; - raw_ptr<ContentIndexProvider, DanglingUntriaged> provider_; + raw_ptr<ContentIndexProvider, DanglingAcrossTasks> provider_; ContentIndexDatabase content_index_database_; };
diff --git a/content/browser/content_index/content_index_database.h b/content/browser/content_index/content_index_database.h index 8e44d794..af84d331 100644 --- a/content/browser/content_index/content_index_database.h +++ b/content/browser/content_index/content_index_database.h
@@ -173,7 +173,7 @@ void BlockOrigin(const url::Origin& origin); void UnblockOrigin(const url::Origin& origin); - raw_ptr<ContentIndexProvider, DanglingUntriaged> provider_; + raw_ptr<ContentIndexProvider, DanglingAcrossTasks> provider_; // A map from origins to how many times it's been blocked. base::flat_map<url::Origin, int> blocked_origins_;
diff --git a/content/browser/devtools/protocol/storage_handler.cc b/content/browser/devtools/protocol/storage_handler.cc index 0df7060..6c71e05 100644 --- a/content/browser/devtools/protocol/storage_handler.cc +++ b/content/browser/devtools/protocol/storage_handler.cc
@@ -18,6 +18,7 @@ #include "components/services/storage/privileged/mojom/indexed_db_control.mojom.h" #include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "components/services/storage/public/mojom/cache_storage_control.mojom.h" +#include "content/browser/attribution_reporting/attribution_manager.h" #include "content/browser/devtools/protocol/browser_handler.h" #include "content/browser/devtools/protocol/handler_helpers.h" #include "content/browser/devtools/protocol/network.h" @@ -443,6 +444,7 @@ SetInterestGroupTracking(false); shared_storage_observer_.reset(); quota_manager_observer_.reset(); + ResetAttributionReportingLocalTestingMode(); return Response::Success(); } @@ -1607,5 +1609,41 @@ base::NumberToString(bucket_locator.id.value())); } +void StorageHandler::SetAttributionReportingLocalTestingMode( + bool enabled, + std::unique_ptr<SetAttributionReportingLocalTestingModeCallback> callback) { + if (!storage_partition_) { + callback->sendFailure(Response::InternalError()); + return; + } + + auto* manager = static_cast<StoragePartitionImpl*>(storage_partition_) + ->GetAttributionManager(); + if (!manager) { + callback->sendFailure(Response::InternalError()); + return; + } + + manager->SetDebugMode( + enabled, + base::BindOnce( + &SetAttributionReportingLocalTestingModeCallback::sendSuccess, + std::move(callback))); +} + +void StorageHandler::ResetAttributionReportingLocalTestingMode() { + if (!storage_partition_) { + return; + } + + auto* manager = static_cast<StoragePartitionImpl*>(storage_partition_) + ->GetAttributionManager(); + if (!manager) { + return; + } + + manager->SetDebugMode(/*enabled=*/absl::nullopt, base::DoNothing()); +} + } // namespace protocol } // namespace content
diff --git a/content/browser/devtools/protocol/storage_handler.h b/content/browser/devtools/protocol/storage_handler.h index 803c971..44c3317 100644 --- a/content/browser/devtools/protocol/storage_handler.h +++ b/content/browser/devtools/protocol/storage_handler.h
@@ -137,6 +137,11 @@ DispatchResponse DeleteStorageBucket( std::unique_ptr<protocol::Storage::StorageBucket> bucket) override; + void SetAttributionReportingLocalTestingMode( + bool enabled, + std::unique_ptr<SetAttributionReportingLocalTestingModeCallback>) + override; + private: // See definition for lifetime information. class CacheStorageObserver; @@ -184,6 +189,8 @@ Response FindStoragePartition(const Maybe<std::string>& browser_context_id, StoragePartition** storage_partition); + void ResetAttributionReportingLocalTestingMode(); + std::unique_ptr<Storage::Frontend> frontend_; StoragePartition* storage_partition_{nullptr}; RenderFrameHostImpl* frame_host_ = nullptr;
diff --git a/content/browser/devtools/protocol_config.json b/content/browser/devtools/protocol_config.json index 09e0729..80de7c9 100644 --- a/content/browser/devtools/protocol_config.json +++ b/content/browser/devtools/protocol_config.json
@@ -100,7 +100,7 @@ { "domain": "Storage", "exclude": ["runBounceTrackingMitigations"], - "async": ["getUsageAndQuota", "clearDataForOrigin", "clearDataForStorageKey", "getCookies", "setCookies", "clearCookies", "overrideQuotaForOrigin", "getTrustTokens", "clearTrustTokens", "getInterestGroupDetails", "getSharedStorageMetadata", "getSharedStorageEntries", "setSharedStorageEntry", "deleteSharedStorageEntry", "clearSharedStorageEntries", "resetSharedStorageBudget", "getStorageBucketList"] + "async": ["getUsageAndQuota", "clearDataForOrigin", "clearDataForStorageKey", "getCookies", "setCookies", "clearCookies", "overrideQuotaForOrigin", "getTrustTokens", "clearTrustTokens", "getInterestGroupDetails", "getSharedStorageMetadata", "getSharedStorageEntries", "setSharedStorageEntry", "deleteSharedStorageEntry", "clearSharedStorageEntries", "resetSharedStorageBudget", "getStorageBucketList", "setAttributionReportingLocalTestingMode"] }, { "domain": "SystemInfo",
diff --git a/content/browser/file_system_access/file_system_access_manager_impl.h b/content/browser/file_system_access/file_system_access_manager_impl.h index 9ee18d60..73253dc8 100644 --- a/content/browser/file_system_access/file_system_access_manager_impl.h +++ b/content/browser/file_system_access/file_system_access_manager_impl.h
@@ -545,7 +545,7 @@ const scoped_refptr<ChromeBlobStorageContext> blob_context_; base::SequenceBound<storage::FileSystemOperationRunner> operation_runner_ GUARDED_BY_CONTEXT(sequence_checker_); - raw_ptr<FileSystemAccessPermissionContext, DanglingUntriaged> + raw_ptr<FileSystemAccessPermissionContext, DanglingAcrossTasks> permission_context_ GUARDED_BY_CONTEXT(sequence_checker_); // All the mojo receivers for this FileSystemAccessManager itself. Keeps
diff --git a/content/browser/loader/navigation_url_loader_impl.h b/content/browser/loader/navigation_url_loader_impl.h index 731783a..6f5e26f 100644 --- a/content/browser/loader/navigation_url_loader_impl.h +++ b/content/browser/loader/navigation_url_loader_impl.h
@@ -233,7 +233,7 @@ raw_ptr<NavigationURLLoaderDelegate, DanglingUntriaged> delegate_; raw_ptr<BrowserContext> browser_context_; raw_ptr<StoragePartitionImpl> storage_partition_; - raw_ptr<ServiceWorkerMainResourceHandle, DanglingUntriaged> + raw_ptr<ServiceWorkerMainResourceHandle, DanglingAcrossTasks> service_worker_handle_; std::unique_ptr<network::ResourceRequest> resource_request_;
diff --git a/content/browser/media/media_devices_util.cc b/content/browser/media/media_devices_util.cc index 5537942..f05f41f1 100644 --- a/content/browser/media/media_devices_util.cc +++ b/content/browser/media/media_devices_util.cc
@@ -176,6 +176,13 @@ return; } + // Check that the frame is not in the prerendering state. Media playback is + // deferred while prerendering. So this check should pass and ensures the + // condition to call GetPageUkmSourceId below as the data collection policy + // disallows recording UKMs while prerendering. + CHECK(!frame_host->IsInLifecycleState( + RenderFrameHost::LifecycleState::kPrerendering)); + net::SiteForCookies site_for_cookies = frame_host->ComputeSiteForCookies(); url::Origin origin = frame_host->GetLastCommittedOrigin(); bool has_focus = frame_host->GetView() && frame_host->GetView()->HasFocus();
diff --git a/content/browser/notifications/platform_notification_context_impl.h b/content/browser/notifications/platform_notification_context_impl.h index bbd2aa78..64de8c4 100644 --- a/content/browser/notifications/platform_notification_context_impl.h +++ b/content/browser/notifications/platform_notification_context_impl.h
@@ -334,7 +334,7 @@ const scoped_refptr<base::SequencedTaskRunner>& task_runner); base::FilePath path_; - raw_ptr<BrowserContext, DanglingUntriaged> browser_context_; + raw_ptr<BrowserContext, DanglingAcrossTasks> browser_context_; scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_;
diff --git a/content/browser/notifications/platform_notification_service_proxy.h b/content/browser/notifications/platform_notification_service_proxy.h index 26cf026..45e3642 100644 --- a/content/browser/notifications/platform_notification_service_proxy.h +++ b/content/browser/notifications/platform_notification_service_proxy.h
@@ -116,8 +116,9 @@ scoped_refptr<ServiceWorkerRegistration> registration); scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_; - raw_ptr<BrowserContext, DanglingUntriaged> browser_context_; - raw_ptr<PlatformNotificationService, DanglingUntriaged> notification_service_; + raw_ptr<BrowserContext, DanglingAcrossTasks> browser_context_; + raw_ptr<PlatformNotificationService, DanglingAcrossTasks> + notification_service_; base::WeakPtrFactory<PlatformNotificationServiceProxy> weak_ptr_factory_ui_{ this}; base::WeakPtrFactory<PlatformNotificationServiceProxy> weak_ptr_factory_io_{
diff --git a/content/browser/preloading/prerenderer_impl.cc b/content/browser/preloading/prerenderer_impl.cc index 1ed8dd2..e4ba62388 100644 --- a/content/browser/preloading/prerenderer_impl.cc +++ b/content/browser/preloading/prerenderer_impl.cc
@@ -139,7 +139,7 @@ // For now, start the first candidate for a URL only if there are no // matching prerenders. We could be cleverer in the future. if (matching_prerenders.empty()) { - DCHECK_GT(matching_candidates.size(), 0u); + CHECK_GT(matching_candidates.size(), 0u); candidates_to_start.push_back(std::move(matching_candidates[0])); } @@ -179,7 +179,11 @@ bool PrerendererImpl::MaybePrerender( const blink::mojom::SpeculationCandidatePtr& candidate) { - DCHECK_EQ(candidate->action, blink::mojom::SpeculationAction::kPrerender); + CHECK_EQ(candidate->action, blink::mojom::SpeculationAction::kPrerender); + + // Prerendering frames should not trigger any prerender request. + CHECK(!render_frame_host_->IsInLifecycleState( + RenderFrameHost::LifecycleState::kPrerendering)); if (!registry_) return false;
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index c380910e..4bcf6c0a 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -11420,6 +11420,10 @@ void RenderFrameHostImpl::BindVideoEncoderMetricsProviderReceiver( mojo::PendingReceiver<media::mojom::VideoEncoderMetricsProvider> receiver) { + // Ensure the frame is not in the prerendering state as we don't record UKM + // while prerendering. This is ensured as the BrowserInterfaceBinders defers + // binding until the frame's activation. + CHECK(!IsInLifecycleState(LifecycleState::kPrerendering)); media::VideoEncoderMetricsProvider::Create(GetPageUkmSourceId(), std::move(receiver)); }
diff --git a/content/browser/renderer_host/render_widget_host_browsertest.cc b/content/browser/renderer_host/render_widget_host_browsertest.cc index 452f120..2cdfb07 100644 --- a/content/browser/renderer_host/render_widget_host_browsertest.cc +++ b/content/browser/renderer_host/render_widget_host_browsertest.cc
@@ -22,6 +22,7 @@ #include "content/browser/renderer_host/render_widget_host_input_event_router.h" #include "content/browser/renderer_host/render_widget_host_view_base.h" #include "content/browser/web_contents/web_contents_impl.h" +#include "content/common/content_navigation_policy.h" #include "content/public/browser/render_widget_host_observer.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" @@ -864,7 +865,9 @@ </style> <div id='target'></div>)HTML"; + LoadStopObserver load_stop_observer(shell()->web_contents()); EXPECT_TRUE(NavigateToURL(shell(), GURL(kTestPageURL))); + load_stop_observer.Wait(); const gfx::Size root_view_size = view()->GetVisibleViewportSize(); const int kDisplayFeatureLength = 10; @@ -872,9 +875,11 @@ DisplayFeature emulated_display_feature{ DisplayFeature::Orientation::kVertical, offset, /* mask_length */ kDisplayFeatureLength}; - MockDisplayFeature mock_display_feature(view()); - mock_display_feature.SetDisplayFeature(&emulated_display_feature); - host()->SynchronizeVisualProperties(); + { + MockDisplayFeature mock_display_feature(view()); + mock_display_feature.SetDisplayFeature(&emulated_display_feature); + host()->SynchronizeVisualProperties(); + } EXPECT_EQ( base::NumberToString(emulated_display_feature.offset) + "px", @@ -882,9 +887,24 @@ // Ensure that the environment variables have the correct values in the new // document that is created on reloading the page. - LoadStopObserver load_stop_observer(shell()->web_contents()); + LoadStopObserver load_stop_observer2(shell()->web_contents()); + TestNavigationManager navigation_manager(shell()->web_contents(), + GURL(kTestPageURL)); shell()->Reload(); - load_stop_observer.Wait(); + EXPECT_TRUE(navigation_manager.WaitForResponse()); + if (ShouldCreateNewHostForAllFrames()) { + // When RenderDocument is enabled, a new RenderWidgetHost will be created + // after the reload, so we need to call SynchronizeVisualProperties() again. + RenderWidgetHostImpl* target_rwh = static_cast<RenderWidgetHostImpl*>( + navigation_manager.GetNavigationHandle() + ->GetRenderFrameHost() + ->GetRenderWidgetHost()); + MockDisplayFeature mock_display_feature(target_rwh->GetView()); + mock_display_feature.SetDisplayFeature(&emulated_display_feature); + target_rwh->SynchronizeVisualProperties(); + } + EXPECT_TRUE(navigation_manager.WaitForNavigationFinished()); + load_stop_observer2.Wait(); EXPECT_EQ( base::NumberToString(emulated_display_feature.offset) + "px",
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index c01cc787..e811438 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -1623,7 +1623,9 @@ ukm::SourceId RenderWidgetHostViewAura::GetClientSourceForMetrics() const { RenderFrameHostImpl* frame = GetFocusedFrame(); - if (frame) { + // ukm::SourceId is not available while prerendering. + if (frame && !frame->IsInLifecycleState( + RenderFrameHost::LifecycleState::kPrerendering)) { return frame->GetPageUkmSourceId(); } return ukm::SourceId();
diff --git a/content/browser/webui/web_ui_url_loader_factory.cc b/content/browser/webui/web_ui_url_loader_factory.cc index 0f189ba4..a911283 100644 --- a/content/browser/webui/web_ui_url_loader_factory.cc +++ b/content/browser/webui/web_ui_url_loader_factory.cc
@@ -399,7 +399,7 @@ scheme_(scheme), allowed_hosts_(std::move(allowed_hosts)) {} - raw_ptr<BrowserContext, DanglingUntriaged> browser_context_; + raw_ptr<BrowserContext, DanglingAcrossTasks> browser_context_; int const frame_tree_node_id_; const std::string scheme_; const base::flat_set<std::string> allowed_hosts_; // if empty all allowed.
diff --git a/content/public/browser/browser_message_filter.h b/content/public/browser/browser_message_filter.h index 5bb4d89..2fe2caf4 100644 --- a/content/public/browser/browser_message_filter.h +++ b/content/public/browser/browser_message_filter.h
@@ -142,7 +142,7 @@ // classes. Internal keeps a reference to this class, which is why there's a // weak pointer back. This class could outlive Internal based on what the // child class does in its OnDestruct method. - raw_ptr<Internal, DanglingUntriaged> internal_ = nullptr; + raw_ptr<Internal, DanglingAcrossTasks> internal_ = nullptr; raw_ptr<IPC::Sender> sender_ = nullptr; base::Process peer_process_;
diff --git a/content/public/test/browser_test_base.h b/content/public/test/browser_test_base.h index 4b38c78d..cd4823f 100644 --- a/content/public/test/browser_test_base.h +++ b/content/public/test/browser_test_base.h
@@ -305,7 +305,7 @@ bool allow_network_access_to_host_resolutions_ = false; - raw_ptr<BrowserMainParts, DanglingUntriaged> browser_main_parts_ = nullptr; + raw_ptr<BrowserMainParts, DanglingAcrossTasks> browser_main_parts_ = nullptr; #if BUILDFLAG(IS_POSIX) bool handle_sigterm_;
diff --git a/dbus/bus.h b/dbus/bus.h index 139a8ae2..c4278eef 100644 --- a/dbus/bus.h +++ b/dbus/bus.h
@@ -729,7 +729,7 @@ const ConnectionType connection_type_; scoped_refptr<base::SequencedTaskRunner> dbus_task_runner_; base::WaitableEvent on_shutdown_; - raw_ptr<DBusConnection, DanglingUntriaged> connection_; + raw_ptr<DBusConnection, DanglingAcrossTasks> connection_; base::PlatformThreadId origin_thread_id_; scoped_refptr<base::SequencedTaskRunner> origin_task_runner_;
diff --git a/dbus/message.h b/dbus/message.h index 2a265b39..4e70da9 100644 --- a/dbus/message.h +++ b/dbus/message.h
@@ -140,7 +140,7 @@ std::string ToStringInternal(const std::string& indent, MessageReader* reader); - raw_ptr<DBusMessage, DanglingUntriaged> raw_message_; + raw_ptr<DBusMessage, DanglingAcrossTasks> raw_message_; }; // MessageCall is a type of message used for calling a method via D-Bus.
diff --git a/docs/windows_build_instructions.md b/docs/windows_build_instructions.md index 95911e9..9930541 100644 --- a/docs/windows_build_instructions.md +++ b/docs/windows_build_instructions.md
@@ -133,9 +133,11 @@ $ git config --global branch.autosetuprebase always ``` -Create a `chromium` directory for the checkout and change to it (you can call -this whatever you like and put it wherever you like, as -long as the full path has no spaces): +Create a `chromium` directory for the checkout and change to it. You can call +this whatever you like and put it wherever you like, as long as the full path +has no spaces. However there are some performance benefits for Googlers in +placing the directory under `C:\src\` +(See [Why is my build slow?](https://chromium.googlesource.com/chromium/src/+/main/docs/windows_build_instructions.md#why-is-my-build-slow)). ```shell $ mkdir chromium && cd chromium
diff --git a/extensions/browser/api/declarative/rules_registry_service.h b/extensions/browser/api/declarative/rules_registry_service.h index eb168af2..ec91182 100644 --- a/extensions/browser/api/declarative/rules_registry_service.h +++ b/extensions/browser/api/declarative/rules_registry_service.h
@@ -170,7 +170,7 @@ // Weak pointer into rule_registries_ to make it easier to handle content rule // conditions. - raw_ptr<ContentRulesRegistry, DanglingUntriaged> content_rules_registry_; + raw_ptr<ContentRulesRegistry, DanglingAcrossTasks> content_rules_registry_; // Listen to extension load, unloaded notification. base::ScopedObservation<ExtensionRegistry, ExtensionRegistryObserver>
diff --git a/extensions/browser/api/webcam_private/webcam_private_api_chromeos.cc b/extensions/browser/api/webcam_private/webcam_private_api_chromeos.cc index e1b7bf3a..841c009 100644 --- a/extensions/browser/api/webcam_private/webcam_private_api_chromeos.cc +++ b/extensions/browser/api/webcam_private/webcam_private_api_chromeos.cc
@@ -9,7 +9,6 @@ #include "base/functional/bind.h" #include "base/lazy_instance.h" #include "components/media_device_salt/media_device_salt_service.h" -#include "components/media_device_salt/media_device_salt_service_factory.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/media_device_id.h" #include "content/public/browser/resource_context.h" @@ -17,6 +16,7 @@ #include "extensions/browser/api/webcam_private/ip_webcam.h" #include "extensions/browser/api/webcam_private/v4l2_webcam.h" #include "extensions/browser/api/webcam_private/visca_webcam.h" +#include "extensions/browser/extensions_browser_client.h" #include "extensions/browser/process_manager.h" #include "extensions/browser/process_manager_factory.h" #include "mojo/public/cpp/bindings/pending_remote.h" @@ -114,12 +114,19 @@ return; } - media_device_salt::MediaDeviceSaltService* salt_service = - media_device_salt::MediaDeviceSaltServiceFactory::GetInstance() - ->GetForBrowserContext(browser_context_); - salt_service->GetSalt(base::BindOnce( - &WebcamPrivateAPI::GetDeviceIdOnUIThread, weak_ptr_factory_.GetWeakPtr(), - extension_id, webcam_id, std::move(callback))); + if (media_device_salt::MediaDeviceSaltService* salt_service = + ExtensionsBrowserClient::Get()->GetMediaDeviceSaltService( + browser_context_)) { + salt_service->GetSalt( + base::BindOnce(&WebcamPrivateAPI::GetDeviceIdOnUIThread, + weak_ptr_factory_.GetWeakPtr(), extension_id, webcam_id, + std::move(callback))); + } else { + // If the embedder does not provide a salt service, use the browser + // context's unique ID as salt. + GetDeviceIdOnUIThread(extension_id, webcam_id, std::move(callback), + browser_context_->UniqueId()); + } } void WebcamPrivateAPI::GetDeviceIdOnUIThread( @@ -208,12 +215,18 @@ const std::string& extension_id, const std::string& device_id, base::OnceCallback<void(const std::string&)> webcam_id_callback) { - media_device_salt::MediaDeviceSaltService* salt_service = - media_device_salt::MediaDeviceSaltServiceFactory::GetInstance() - ->GetForBrowserContext(browser_context_); - salt_service->GetSalt(base::BindOnce( - &WebcamPrivateAPI::FinalizeGetWebcamId, weak_ptr_factory_.GetWeakPtr(), - extension_id, device_id, std::move(webcam_id_callback))); + if (media_device_salt::MediaDeviceSaltService* salt_service = + ExtensionsBrowserClient::Get()->GetMediaDeviceSaltService( + browser_context_)) { + salt_service->GetSalt(base::BindOnce( + &WebcamPrivateAPI::FinalizeGetWebcamId, weak_ptr_factory_.GetWeakPtr(), + extension_id, device_id, std::move(webcam_id_callback))); + } else { + // If the embedder does not provide a salt service, use the browser + // context's unique ID as salt. + FinalizeGetWebcamId(extension_id, device_id, std::move(webcam_id_callback), + browser_context_->UniqueId()); + } } void WebcamPrivateAPI::FinalizeGetWebcamId(
diff --git a/extensions/browser/content_verifier.h b/extensions/browser/content_verifier.h index bb41a42..8a2ddff 100644 --- a/extensions/browser/content_verifier.h +++ b/extensions/browser/content_verifier.h
@@ -211,7 +211,7 @@ // Updated and accessed only on IO thread. bool shutdown_on_io_ = false; - const raw_ptr<content::BrowserContext, DanglingUntriaged> context_; + const raw_ptr<content::BrowserContext, DanglingAcrossTasks> context_; // Guards creation of |hash_helper_|, limiting number of creation to <= 1. // Accessed only on IO thread.
diff --git a/extensions/browser/extension_function_dispatcher.h b/extensions/browser/extension_function_dispatcher.h index f7237b3..224f550 100644 --- a/extensions/browser/extension_function_dispatcher.h +++ b/extensions/browser/extension_function_dispatcher.h
@@ -154,7 +154,7 @@ raw_ptr<content::BrowserContext, DanglingUntriaged> browser_context_; - raw_ptr<Delegate, DanglingUntriaged> delegate_; + raw_ptr<Delegate, DanglingAcrossTasks> delegate_; // This map doesn't own either the keys or the values. When a RenderFrameHost // instance goes away, the corresponding entry in this map (if exists) will be
diff --git a/extensions/browser/extension_prefs.h b/extensions/browser/extension_prefs.h index 9e25be7..055d02e 100644 --- a/extensions/browser/extension_prefs.h +++ b/extensions/browser/extension_prefs.h
@@ -944,7 +944,7 @@ base::FilePath install_directory_; // Weak pointer, owned by BrowserContext. - raw_ptr<ExtensionPrefValueMap, DanglingUntriaged> extension_pref_value_map_; + raw_ptr<ExtensionPrefValueMap, DanglingAcrossTasks> extension_pref_value_map_; raw_ptr<base::Clock> clock_;
diff --git a/extensions/browser/extensions_browser_client.cc b/extensions/browser/extensions_browser_client.cc index 4cf9c169..25e577f 100644 --- a/extensions/browser/extensions_browser_client.cc +++ b/extensions/browser/extensions_browser_client.cc
@@ -244,4 +244,10 @@ void ExtensionsBrowserClient::CreatePasswordReuseDetectionManager( content::WebContents* web_contents) const {} +media_device_salt::MediaDeviceSaltService* +ExtensionsBrowserClient::GetMediaDeviceSaltService( + content::BrowserContext* context) { + return nullptr; +} + } // namespace extensions
diff --git a/extensions/browser/extensions_browser_client.h b/extensions/browser/extensions_browser_client.h index fbef1f4..d4e2981 100644 --- a/extensions/browser/extensions_browser_client.h +++ b/extensions/browser/extensions_browser_client.h
@@ -70,6 +70,10 @@ class CancelableTaskTracker; } // namespace base +namespace media_device_salt { +class MediaDeviceSaltService; +} // namespace media_device_salt + namespace extensions { class ComponentExtensionResourceManager; @@ -516,6 +520,11 @@ virtual void CreatePasswordReuseDetectionManager( content::WebContents* web_contents) const; + // Returns a service that provides persistent salts for generating media + // device IDs. Can be null if the embedder does not support persistent salts. + virtual media_device_salt::MediaDeviceSaltService* GetMediaDeviceSaltService( + content::BrowserContext* context); + private: std::vector<std::unique_ptr<ExtensionsBrowserAPIProvider>> providers_; };
diff --git a/extensions/shell/browser/shell_content_browser_client.h b/extensions/shell/browser/shell_content_browser_client.h index 60bb55e..d5cc865 100644 --- a/extensions/shell/browser/shell_content_browser_client.h +++ b/extensions/shell/browser/shell_content_browser_client.h
@@ -157,7 +157,7 @@ const Extension* GetExtension(content::SiteInstance* site_instance); // Owned by content::BrowserMainLoop. - raw_ptr<ShellBrowserMainParts, DanglingUntriaged> browser_main_parts_; + raw_ptr<ShellBrowserMainParts, DanglingAcrossTasks> browser_main_parts_; // Owned by ShellBrowserMainParts. raw_ptr<ShellBrowserMainDelegate, DanglingUntriaged> browser_main_delegate_;
diff --git a/gin/per_isolate_data.h b/gin/per_isolate_data.h index eddf82a..7d7ee79 100644 --- a/gin/per_isolate_data.h +++ b/gin/per_isolate_data.h
@@ -88,7 +88,7 @@ // PerIsolateData doesn't actually own |isolate_|. Instead, the isolate is // owned by the IsolateHolder, which also owns the PerIsolateData. - raw_ptr<v8::Isolate, DanglingUntriaged> isolate_; + raw_ptr<v8::Isolate, DanglingAcrossTasks> isolate_; raw_ptr<v8::ArrayBuffer::Allocator, DanglingUntriaged> allocator_; ObjectTemplateMap object_templates_; FunctionTemplateMap function_templates_;
diff --git a/gin/public/isolate_holder.h b/gin/public/isolate_holder.h index 10caab6..39f3c07b 100644 --- a/gin/public/isolate_holder.h +++ b/gin/public/isolate_holder.h
@@ -143,7 +143,7 @@ void SetUp(scoped_refptr<base::SingleThreadTaskRunner> task_runner); std::unique_ptr<v8::SnapshotCreator> snapshot_creator_; - raw_ptr<v8::Isolate, DanglingUntriaged> isolate_; + raw_ptr<v8::Isolate, DanglingAcrossTasks> isolate_; std::unique_ptr<PerIsolateData> isolate_data_; std::unique_ptr<V8IsolateMemoryDumpProvider> isolate_memory_dump_provider_; AccessMode access_mode_;
diff --git a/gpu/command_buffer/client/DEPS b/gpu/command_buffer/client/DEPS index f1b9fd6a..ca1fa12 100644 --- a/gpu/command_buffer/client/DEPS +++ b/gpu/command_buffer/client/DEPS
@@ -4,6 +4,5 @@ "+components/nacl/common/buildflags.h", "+third_party/skia", "+components/viz/common/resources/resource_format.h", - "+components/viz/common/resources/resource_format_utils.h", "+components/viz/common/resources/shared_image_format.h", ]
diff --git a/gpu/command_buffer/client/raster_implementation_gles.cc b/gpu/command_buffer/client/raster_implementation_gles.cc index 44adf17..f6250c6 100644 --- a/gpu/command_buffer/client/raster_implementation_gles.cc +++ b/gpu/command_buffer/client/raster_implementation_gles.cc
@@ -17,7 +17,6 @@ #include "cc/paint/paint_op_buffer_serializer.h" #include "cc/paint/transfer_cache_entry.h" #include "cc/paint/transfer_cache_serialize_helper.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "gpu/GLES2/gl2extchromium.h" #include "gpu/command_buffer/client/gl_helper.h" #include "gpu/command_buffer/client/gles2_implementation.h"
diff --git a/gpu/command_buffer/client/raster_implementation_gles_unittest.cc b/gpu/command_buffer/client/raster_implementation_gles_unittest.cc index e61de24..0a5c9b2 100644 --- a/gpu/command_buffer/client/raster_implementation_gles_unittest.cc +++ b/gpu/command_buffer/client/raster_implementation_gles_unittest.cc
@@ -15,7 +15,6 @@ #include "base/containers/flat_map.h" #include "cc/paint/display_item_list.h" #include "cc/paint/image_provider.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "gpu/GLES2/gl2extchromium.h" #include "gpu/command_buffer/client/client_test_helper.h" #include "gpu/command_buffer/client/context_support.h"
diff --git a/gpu/command_buffer/common/DEPS b/gpu/command_buffer/common/DEPS index a48b092..57d9fa0c 100644 --- a/gpu/command_buffer/common/DEPS +++ b/gpu/command_buffer/common/DEPS
@@ -1,6 +1,5 @@ include_rules = [ "+components/viz/common/resources/resource_format.h", - "+components/viz/common/resources/resource_format_utils.h", "+third_party/skia/include", ] specific_include_rules = {
diff --git a/gpu/command_buffer/service/DEPS b/gpu/command_buffer/service/DEPS index 3f5062f..a373fd73 100644 --- a/gpu/command_buffer/service/DEPS +++ b/gpu/command_buffer/service/DEPS
@@ -10,7 +10,6 @@ "+components/viz/common/gpu/vulkan_context_provider.h", "+components/viz/common/resources/resource_format.h", "+components/viz/common/resources/shared_image_format.h", - "+components/viz/common/resources/resource_format_utils.h", "+components/viz/common/resources/resource_sizes.h", "+components/viz/common/resources/shared_image_format.h", "+components/viz/common/resources/shared_image_format_utils.h",
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc index f352ac9..7cb4361 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc
@@ -7,7 +7,6 @@ #include "base/command_line.h" #include "base/strings/string_number_conversions.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/command_buffer/common/id_allocator.h"
diff --git a/gpu/command_buffer/service/gles2_external_framebuffer_unittest.cc b/gpu/command_buffer/service/gles2_external_framebuffer_unittest.cc index 215e634..73d8c966 100644 --- a/gpu/command_buffer/service/gles2_external_framebuffer_unittest.cc +++ b/gpu/command_buffer/service/gles2_external_framebuffer_unittest.cc
@@ -8,7 +8,6 @@ #include "base/command_line.h" #include "build/build_config.h" #include "components/viz/common/resources/resource_format.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "gpu/command_buffer/common/mailbox.h" #include "gpu/command_buffer/common/shared_image_usage.h" #include "gpu/command_buffer/service/service_utils.h"
diff --git a/gpu/command_buffer/service/raster_decoder_unittest_base.cc b/gpu/command_buffer/service/raster_decoder_unittest_base.cc index 06fc541..6723ae82 100644 --- a/gpu/command_buffer/service/raster_decoder_unittest_base.cc +++ b/gpu/command_buffer/service/raster_decoder_unittest_base.cc
@@ -17,7 +17,6 @@ #include "base/functional/callback_helpers.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/command_buffer/common/raster_cmd_format.h" #include "gpu/command_buffer/common/shared_image_usage.h"
diff --git a/gpu/command_buffer/service/shared_image/d3d_image_backing_factory_unittest.cc b/gpu/command_buffer/service/shared_image/d3d_image_backing_factory_unittest.cc index 9957f3c..1b76778 100644 --- a/gpu/command_buffer/service/shared_image/d3d_image_backing_factory_unittest.cc +++ b/gpu/command_buffer/service/shared_image/d3d_image_backing_factory_unittest.cc
@@ -15,7 +15,6 @@ #include "base/test/test_timeouts.h" #include "cc/test/pixel_comparator.h" #include "cc/test/pixel_test_utils.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/shared_image_format.h" #include "components/viz/common/resources/shared_image_format_utils.h" #include "gpu/command_buffer/common/shared_image_usage.h"
diff --git a/gpu/command_buffer/service/shared_image/gl_ozone_image_representation.cc b/gpu/command_buffer/service/shared_image/gl_ozone_image_representation.cc index 1caf040..614e715e 100644 --- a/gpu/command_buffer/service/shared_image/gl_ozone_image_representation.cc +++ b/gpu/command_buffer/service/shared_image/gl_ozone_image_representation.cc
@@ -8,7 +8,6 @@ #include "base/check.h" #include "base/memory/ptr_util.h" #include "base/memory/scoped_refptr.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "gpu/command_buffer/service/gl_utils.h" #include "gpu/command_buffer/service/memory_tracking.h" #include "gpu/command_buffer/service/shared_image/ozone_image_backing.h"
diff --git a/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm b/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm index 6824784..472f5b0 100644 --- a/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm +++ b/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm
@@ -9,7 +9,6 @@ #include "base/memory/scoped_policy.h" #include "base/trace_event/memory_dump_manager.h" #include "components/viz/common/gpu/metal_context_provider.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/resource_sizes.h" #include "components/viz/common/resources/shared_image_format_utils.h" #include "gpu/command_buffer/common/shared_image_trace_utils.h"
diff --git a/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory.mm b/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory.mm index 7b9a513..adfef30 100644 --- a/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory.mm +++ b/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory.mm
@@ -6,7 +6,6 @@ #include "base/memory/scoped_refptr.h" #include "build/build_config.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/resource_sizes.h" #include "components/viz/common/resources/shared_image_format_utils.h" #include "gpu/command_buffer/common/shared_image_usage.h"
diff --git a/gpu/command_buffer/service/shared_image/shared_image_format_service_utils.cc b/gpu/command_buffer/service/shared_image/shared_image_format_service_utils.cc index 175ed6f..f3160fe 100644 --- a/gpu/command_buffer/service/shared_image/shared_image_format_service_utils.cc +++ b/gpu/command_buffer/service/shared_image/shared_image_format_service_utils.cc
@@ -13,7 +13,6 @@ #include "base/notreached.h" #include "build/buildflag.h" #include "components/viz/common/resources/resource_format.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/shared_image_format_utils.h" namespace gpu {
diff --git a/gpu/command_buffer/service/shared_image/shared_image_format_service_utils_mac.mm b/gpu/command_buffer/service/shared_image/shared_image_format_service_utils_mac.mm index 3346641..01161c3d 100644 --- a/gpu/command_buffer/service/shared_image/shared_image_format_service_utils_mac.mm +++ b/gpu/command_buffer/service/shared_image/shared_image_format_service_utils_mac.mm
@@ -8,7 +8,6 @@ #include "base/check_op.h" #include "base/logging.h" -#include "components/viz/common/resources/resource_format_utils.h" namespace gpu {
diff --git a/gpu/command_buffer/service/shared_image/shared_image_representation.cc b/gpu/command_buffer/service/shared_image/shared_image_representation.cc index 9ba20c6..6e31238 100644 --- a/gpu/command_buffer/service/shared_image/shared_image_representation.cc +++ b/gpu/command_buffer/service/shared_image/shared_image_representation.cc
@@ -7,7 +7,6 @@ #include "base/debug/dump_without_crashing.h" #include "base/strings/stringprintf.h" #include "build/build_config.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/shared_image_format_utils.h" #include "gpu/command_buffer/service/shared_context_state.h" #include "gpu/command_buffer/service/shared_image/shared_image_format_service_utils.h"
diff --git a/gpu/command_buffer/service/shared_image/shared_image_test_base.cc b/gpu/command_buffer/service/shared_image/shared_image_test_base.cc index c8bc44e5..3ed3b2a9 100644 --- a/gpu/command_buffer/service/shared_image/shared_image_test_base.cc +++ b/gpu/command_buffer/service/shared_image/shared_image_test_base.cc
@@ -9,7 +9,6 @@ #include "base/command_line.h" #include "cc/test/pixel_comparator.h" #include "cc/test/pixel_test_utils.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/shared_image_format_utils.h" #include "gpu/command_buffer/service/service_utils.h" #include "gpu/command_buffer/service/shared_image/shared_image_representation.h"
diff --git a/gpu/command_buffer/service/shared_image/skia_gl_image_representation.cc b/gpu/command_buffer/service/shared_image/skia_gl_image_representation.cc index b135341..1365e90 100644 --- a/gpu/command_buffer/service/shared_image/skia_gl_image_representation.cc +++ b/gpu/command_buffer/service/shared_image/skia_gl_image_representation.cc
@@ -6,7 +6,6 @@ #include "base/check_op.h" #include "base/memory/ptr_util.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/shared_image_format_utils.h" #include "gpu/command_buffer/service/shared_context_state.h" #include "gpu/command_buffer/service/shared_image/shared_image_format_service_utils.h"
diff --git a/gpu/command_buffer/service/shared_image/video_surface_texture_image_backing.cc b/gpu/command_buffer/service/shared_image/video_surface_texture_image_backing.cc index fac11002..4a81c023 100644 --- a/gpu/command_buffer/service/shared_image/video_surface_texture_image_backing.cc +++ b/gpu/command_buffer/service/shared_image/video_surface_texture_image_backing.cc
@@ -7,7 +7,6 @@ #include <utility> #include "base/task/single_thread_task_runner.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/resource_sizes.h" #include "gpu/command_buffer/common/shared_image_usage.h" #include "gpu/command_buffer/service/abstract_texture_android.h"
diff --git a/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory_unittest.cc b/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory_unittest.cc index 9cf60ef7d..00160b3 100644 --- a/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory_unittest.cc +++ b/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory_unittest.cc
@@ -8,7 +8,6 @@ #include "build/build_config.h" #include "cc/test/pixel_comparator.h" #include "cc/test/pixel_test_utils.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/shared_image_format.h" #include "gpu/command_buffer/common/mailbox.h" #include "gpu/command_buffer/common/shared_image_usage.h"
diff --git a/gpu/command_buffer/service/skia_utils.cc b/gpu/command_buffer/service/skia_utils.cc index 537a0c1d..d9bbfb9f 100644 --- a/gpu/command_buffer/service/skia_utils.cc +++ b/gpu/command_buffer/service/skia_utils.cc
@@ -8,7 +8,6 @@ #include "base/logging.h" #include "build/build_config.h" #include "components/viz/common/resources/resource_format.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "gpu/command_buffer/service/feature_info.h" #include "gpu/command_buffer/service/shared_context_state.h" #include "gpu/config/gpu_finch_features.h"
diff --git a/gpu/command_buffer/service/transfer_buffer_manager.h b/gpu/command_buffer/service/transfer_buffer_manager.h index c77fecf..3a01918 100644 --- a/gpu/command_buffer/service/transfer_buffer_manager.h +++ b/gpu/command_buffer/service/transfer_buffer_manager.h
@@ -44,7 +44,7 @@ typedef base::flat_map<int32_t, scoped_refptr<Buffer>> BufferMap; BufferMap registered_buffers_; size_t shared_memory_bytes_allocated_; - raw_ptr<MemoryTracker, DanglingUntriaged> memory_tracker_; + raw_ptr<MemoryTracker, DanglingAcrossTasks> memory_tracker_; }; } // namespace gpu
diff --git a/gpu/ipc/client/DEPS b/gpu/ipc/client/DEPS index 919bf7a4..4bb85ef 100644 --- a/gpu/ipc/client/DEPS +++ b/gpu/ipc/client/DEPS
@@ -18,7 +18,6 @@ "+components/viz/test/test_gpu_memory_buffer_manager.h", ], "client_shared_image_interface.cc": [ - "+components/viz/common/resources/resource_format_utils.h", "+components/viz/common/resources/shared_image_format.h", "+components/viz/common/resources/shared_image_format_utils.h", ]
diff --git a/gpu/ipc/service/DEPS b/gpu/ipc/service/DEPS index 024b81c..4cbd6a9 100644 --- a/gpu/ipc/service/DEPS +++ b/gpu/ipc/service/DEPS
@@ -6,7 +6,6 @@ "+components/viz/common/gpu/vulkan_context_provider.h", "+components/viz/common/overlay_state/win/overlay_state_service.h", "+components/viz/common/resources/resource_format.h", - "+components/viz/common/resources/resource_format_utils.h", "+components/viz/common/resources/resource_sizes.h", "+components/viz/common/resources/shared_image_format.h", "+components/viz/common/resources/shared_image_format_utils.h",
diff --git a/gpu/ipc/service/gpu_memory_buffer_factory_android_hardware_buffer.cc b/gpu/ipc/service/gpu_memory_buffer_factory_android_hardware_buffer.cc index 75c84e86..b9918b5 100644 --- a/gpu/ipc/service/gpu_memory_buffer_factory_android_hardware_buffer.cc +++ b/gpu/ipc/service/gpu_memory_buffer_factory_android_hardware_buffer.cc
@@ -9,7 +9,6 @@ #include "base/containers/contains.h" #include "base/logging.h" #include "build/build_config.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "gpu/command_buffer/common/gpu_memory_buffer_support.h" #include "gpu/command_buffer/service/ahardwarebuffer_utils.h" #include "gpu/ipc/common/gpu_memory_buffer_impl_android_hardware_buffer.h"
diff --git a/headless/lib/browser/headless_browser_impl.h b/headless/lib/browser/headless_browser_impl.h index 64854082..ce26da4 100644 --- a/headless/lib/browser/headless_browser_impl.h +++ b/headless/lib/browser/headless_browser_impl.h
@@ -121,14 +121,14 @@ base::OnceCallback<void(HeadlessBrowser*)> on_start_callback_; absl::optional<HeadlessBrowser::Options> options_; - raw_ptr<HeadlessBrowserMainParts, DanglingUntriaged> browser_main_parts_ = + raw_ptr<HeadlessBrowserMainParts, DanglingAcrossTasks> browser_main_parts_ = nullptr; int exit_code_ = 0; base::flat_map<std::string, std::unique_ptr<HeadlessBrowserContextImpl>> browser_contexts_; - raw_ptr<HeadlessBrowserContext, DanglingUntriaged> default_browser_context_ = - nullptr; + raw_ptr<HeadlessBrowserContext, DanglingAcrossTasks> + default_browser_context_ = nullptr; scoped_refptr<content::DevToolsAgentHost> agent_host_; std::unique_ptr<HeadlessRequestContextManager> system_request_context_manager_;
diff --git a/headless/public/headless_web_contents.h b/headless/public/headless_web_contents.h index f6896cd4..27f865ee 100644 --- a/headless/public/headless_web_contents.h +++ b/headless/public/headless_web_contents.h
@@ -98,7 +98,7 @@ explicit Builder(HeadlessBrowserContextImpl* browser_context); - raw_ptr<HeadlessBrowserContextImpl, DanglingUntriaged> browser_context_; + raw_ptr<HeadlessBrowserContextImpl, DanglingAcrossTasks> browser_context_; GURL initial_url_ = GURL("about:blank"); gfx::Size window_size_;
diff --git a/headless/test/headless_browser_browsertest.cc b/headless/test/headless_browser_browsertest.cc index a06f837..17c7797 100644 --- a/headless/test/headless_browser_browsertest.cc +++ b/headless/test/headless_browser_browsertest.cc
@@ -431,8 +431,9 @@ void OnTargetCrashed(const base::Value::Dict&) { FinishAsynchronousTest(); } protected: - raw_ptr<HeadlessBrowserContext, DanglingUntriaged> browser_context_ = nullptr; - raw_ptr<HeadlessWebContents, DanglingUntriaged> web_contents_ = nullptr; + raw_ptr<HeadlessBrowserContext, DanglingAcrossTasks> browser_context_ = + nullptr; + raw_ptr<HeadlessWebContents, DanglingAcrossTasks> web_contents_ = nullptr; SimpleDevToolsProtocolClient devtools_client_; base::FilePath crash_dumps_dir_; };
diff --git a/headless/test/headless_browser_context_browsertest.cc b/headless/test/headless_browser_context_browsertest.cc index 7f240260..f3c5e83 100644 --- a/headless/test/headless_browser_context_browsertest.cc +++ b/headless/test/headless_browser_context_browsertest.cc
@@ -122,8 +122,9 @@ } private: - raw_ptr<HeadlessBrowserContext, DanglingUntriaged> browser_context_ = nullptr; - raw_ptr<HeadlessWebContents, DanglingUntriaged> web_contents2_ = nullptr; + raw_ptr<HeadlessBrowserContext, DanglingAcrossTasks> browser_context_ = + nullptr; + raw_ptr<HeadlessWebContents, DanglingAcrossTasks> web_contents2_ = nullptr; SimpleDevToolsProtocolClient devtools_client2_; };
diff --git a/headless/test/headless_browser_user_agent_metadata_browsertest.cc b/headless/test/headless_browser_user_agent_metadata_browsertest.cc index f8f326f..b0127de 100644 --- a/headless/test/headless_browser_user_agent_metadata_browsertest.cc +++ b/headless/test/headless_browser_user_agent_metadata_browsertest.cc
@@ -119,7 +119,7 @@ } protected: - raw_ptr<HeadlessWebContents, DanglingUntriaged> web_contents_; + raw_ptr<HeadlessWebContents, DanglingAcrossTasks> web_contents_; SimpleDevToolsProtocolClient devtools_client_; // Get the version of the HeadlessChrome brand from the brand list. @@ -411,7 +411,7 @@ } protected: - raw_ptr<HeadlessWebContents, DanglingUntriaged> web_contents_; + raw_ptr<HeadlessWebContents, DanglingAcrossTasks> web_contents_; SimpleDevToolsProtocolClient devtools_client_; // HandleRequest will capture headers with this path in `got_headers_`. std::string capture_headers_for_path_;
diff --git a/headless/test/headless_devtooled_browsertest.h b/headless/test/headless_devtooled_browsertest.h index dcefc63c..3ad2b482 100644 --- a/headless/test/headless_devtooled_browsertest.h +++ b/headless/test/headless_devtooled_browsertest.h
@@ -52,8 +52,8 @@ void RunTest(); - raw_ptr<HeadlessBrowserContext, DanglingUntriaged> browser_context_; - raw_ptr<HeadlessWebContents, DanglingUntriaged> web_contents_; + raw_ptr<HeadlessBrowserContext, DanglingAcrossTasks> browser_context_; + raw_ptr<HeadlessWebContents, DanglingAcrossTasks> web_contents_; simple_devtools_protocol_client::SimpleDevToolsProtocolClient devtools_client_; simple_devtools_protocol_client::SimpleDevToolsProtocolClient
diff --git a/headless/test/headless_web_contents_browsertest.cc b/headless/test/headless_web_contents_browsertest.cc index e3f4390f..7b34037 100644 --- a/headless/test/headless_web_contents_browsertest.cc +++ b/headless/test/headless_web_contents_browsertest.cc
@@ -481,9 +481,9 @@ base::Unretained(this))); } - raw_ptr<HeadlessBrowserContext, DanglingUntriaged> browser_context_ = + raw_ptr<HeadlessBrowserContext, DanglingAcrossTasks> browser_context_ = nullptr; // Not owned. - raw_ptr<HeadlessWebContentsImpl, DanglingUntriaged> web_contents_ = + raw_ptr<HeadlessWebContentsImpl, DanglingAcrossTasks> web_contents_ = nullptr; // Not owned. bool page_ready_ = false;
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg index 7c3971c..df7d1fc 100644 --- a/infra/config/generated/luci/cr-buildbucket.cfg +++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -29471,11 +29471,14 @@ ' },' ' "$build/siso": {' ' "configs": [' - ' "remote_all"' + ' "remote_all",' + ' "rewrapper_to_reproxy"' ' ],' ' "enable_cloud_profiler": true,' ' "enable_cloud_trace": true,' - ' "experiments": [],' + ' "experiments": [' + ' "use-reproxy"' + ' ],' ' "project": "rbe-chromium-untrusted"' ' },' ' "$recipe_engine/resultdb/test_presentation": {' @@ -29598,8 +29601,7 @@ ' },' ' "$build/siso": {' ' "configs": [' - ' "remote_all",' - ' "rewrapper_to_reproxy"' + ' "remote_all"' ' ],' ' "enable_cloud_profiler": true,' ' "enable_cloud_trace": true,'
diff --git a/infra/config/subprojects/chromium/ci/chromium.fyi.star b/infra/config/subprojects/chromium/ci/chromium.fyi.star index 8afde2eb..d626c10 100644 --- a/infra/config/subprojects/chromium/ci/chromium.fyi.star +++ b/infra/config/subprojects/chromium/ci/chromium.fyi.star
@@ -1494,6 +1494,9 @@ category = "buildperf", short_name = "lnx", ), + # TODO(b/273407069): enable reproxy mode by default. + siso_configs = ["remote_all", "rewrapper_to_reproxy"], + siso_experiments = ["use-reproxy"], ) build_perf_builder( @@ -1525,8 +1528,6 @@ category = "buildperf", short_name = "lnxss", ), - # TODO(b/273407069): enable reproxy mode by default. - siso_configs = ["remote_all", "rewrapper_to_reproxy"], ) build_perf_builder(
diff --git a/ios/chrome/app/application_delegate/app_state_observer.h b/ios/chrome/app/application_delegate/app_state_observer.h index 802976f..bb56723c 100644 --- a/ios/chrome/app/application_delegate/app_state_observer.h +++ b/ios/chrome/app/application_delegate/app_state_observer.h
@@ -80,7 +80,7 @@ willTransitionToInitStage:(InitStage)nextInitStage; // Called right after the app is transitioned out of to the -// `previousInitStage`. he init stage of the app at that +// `previousInitStage`. The init stage of the app at that // moment is `previousInitStage` + 1. - (void)appState:(AppState*)appState didTransitionFromInitStage:(InitStage)previousInitStage;
diff --git a/ios/chrome/browser/application_context/BUILD.gn b/ios/chrome/browser/application_context/BUILD.gn index 088b2b6..fe483f7 100644 --- a/ios/chrome/browser/application_context/BUILD.gn +++ b/ios/chrome/browser/application_context/BUILD.gn
@@ -37,13 +37,13 @@ "//ios/chrome/browser/gcm", "//ios/chrome/browser/history", "//ios/chrome/browser/metrics", - "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/policy", "//ios/chrome/browser/prefs", "//ios/chrome/browser/push_notification:push_notification_service", "//ios/chrome/browser/segmentation_platform", "//ios/chrome/browser/shared/model/application_context", "//ios/chrome/browser/shared/model/browser_state", + "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/shared/model/prefs:browser_prefs", "//ios/chrome/browser/shared/model/prefs:pref_names", "//ios/chrome/browser/update_client",
diff --git a/ios/chrome/browser/autofill/BUILD.gn b/ios/chrome/browser/autofill/BUILD.gn index d8f223a..85b8e208 100644 --- a/ios/chrome/browser/autofill/BUILD.gn +++ b/ios/chrome/browser/autofill/BUILD.gn
@@ -59,9 +59,9 @@ "//components/sync/service", "//components/variations/service", "//ios/chrome/browser/history", - "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/shared/model/application_context", "//ios/chrome/browser/shared/model/browser_state", + "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/shared/model/prefs:pref_names", "//ios/chrome/browser/shared/ui/util:util_swift", "//ios/chrome/browser/shared/ui/util/image", @@ -192,9 +192,9 @@ "//ios/chrome/app/application_delegate:app_state_header", "//ios/chrome/browser/infobars", "//ios/chrome/browser/passwords", - "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/shared/coordinator/chrome_coordinator", "//ios/chrome/browser/shared/model/browser_state:test_support", + "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/ssl", "//ios/chrome/browser/sync:sync", "//ios/chrome/browser/ui/autofill",
diff --git a/ios/chrome/browser/autofill/message/BUILD.gn b/ios/chrome/browser/autofill/message/BUILD.gn index 46b11c99..283feb5 100644 --- a/ios/chrome/browser/autofill/message/BUILD.gn +++ b/ios/chrome/browser/autofill/message/BUILD.gn
@@ -9,4 +9,4 @@ "save_card_message_with_links.mm", ] deps = [ "//url:url" ] -} \ No newline at end of file +}
diff --git a/ios/chrome/browser/browser_state/BUILD.gn b/ios/chrome/browser/browser_state/BUILD.gn index 6b9c5705..15cb0c0 100644 --- a/ios/chrome/browser/browser_state/BUILD.gn +++ b/ios/chrome/browser/browser_state/BUILD.gn
@@ -72,6 +72,8 @@ "//components/proxy_config/ios", "//components/signin/ios/browser:active_state_manager", "//components/signin/public/identity_manager", + "//components/supervised_user/core/browser", + "//components/supervised_user/core/common", "//components/sync_preferences", "//components/user_prefs", "//components/variations/service",
diff --git a/ios/chrome/browser/browser_state/chrome_browser_state_manager_impl.mm b/ios/chrome/browser/browser_state/chrome_browser_state_manager_impl.mm index b479209..7ff6a73 100644 --- a/ios/chrome/browser/browser_state/chrome_browser_state_manager_impl.mm +++ b/ios/chrome/browser/browser_state/chrome_browser_state_manager_impl.mm
@@ -20,21 +20,25 @@ #import "components/prefs/pref_service.h" #import "components/signin/ios/browser/active_state_manager.h" #import "components/signin/public/identity_manager/identity_manager.h" +#import "components/supervised_user/core/browser/supervised_user_settings_service.h" #import "ios/chrome/browser/browser_state/chrome_browser_state_impl.h" #import "ios/chrome/browser/browser_state/constants.h" #import "ios/chrome/browser/browser_state/off_the_record_chrome_browser_state_impl.h" #import "ios/chrome/browser/browser_state_metrics/browser_state_metrics.h" #import "ios/chrome/browser/optimization_guide/optimization_guide_service.h" #import "ios/chrome/browser/optimization_guide/optimization_guide_service_factory.h" -#import "ios/chrome/browser/shared/model/paths/paths.h" #import "ios/chrome/browser/push_notification/push_notification_browser_state_service_factory.h" #import "ios/chrome/browser/segmentation_platform/segmentation_platform_service_factory.h" #import "ios/chrome/browser/shared/model/application_context/application_context.h" #import "ios/chrome/browser/shared/model/browser_state/browser_state_info_cache.h" +#import "ios/chrome/browser/shared/model/paths/paths.h" #import "ios/chrome/browser/shared/model/prefs/pref_names.h" #import "ios/chrome/browser/signin/account_consistency_service_factory.h" #import "ios/chrome/browser/signin/account_reconcilor_factory.h" #import "ios/chrome/browser/signin/identity_manager_factory.h" +#import "ios/chrome/browser/supervised_user/child_account_service_factory.h" +#import "ios/chrome/browser/supervised_user/supervised_user_service_factory.h" +#import "ios/chrome/browser/supervised_user/supervised_user_settings_service_factory.h" #import "ios/chrome/browser/unified_consent/unified_consent_service_factory.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -229,6 +233,19 @@ browser_state); PushNotificationBrowserStateServiceFactory::GetForBrowserState(browser_state); + + // For //chrome/browser/profiles, SupervisedUserSettingsService is a + // SimpleKeyedService and is initialized before the creation of + // `ProfileKeyedService`s. + + // For //ios, SupervisedUserSettingsService is a BrowserStateKeyedService and + // is initialized here. + SupervisedUserSettingsServiceFactory::GetForBrowserState(browser_state) + ->Init(browser_state->GetStatePath(), + browser_state->GetIOTaskRunner().get(), + /*load_synchronously=*/true); + ChildAccountServiceFactory::GetForBrowserState(browser_state)->Init(); + SupervisedUserServiceFactory::GetForBrowserState(browser_state)->Init(); } void ChromeBrowserStateManagerImpl::AddBrowserStateToCache(
diff --git a/ios/chrome/browser/browsing_data/BUILD.gn b/ios/chrome/browser/browsing_data/BUILD.gn index 59af350..0b053e97 100644 --- a/ios/chrome/browser/browsing_data/BUILD.gn +++ b/ios/chrome/browser/browsing_data/BUILD.gn
@@ -61,7 +61,6 @@ "//ios/chrome/browser/language", "//ios/chrome/browser/optimization_guide", "//ios/chrome/browser/passwords", - "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/reading_list:reading_list_remover", "//ios/chrome/browser/search_engines", "//ios/chrome/browser/sessions", @@ -69,6 +68,7 @@ "//ios/chrome/browser/sessions:session_service", "//ios/chrome/browser/shared/model/application_context", "//ios/chrome/browser/shared/model/browser_state", + "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/signin", "//ios/chrome/browser/snapshots", "//ios/chrome/browser/sync",
diff --git a/ios/chrome/browser/crash_report/BUILD.gn b/ios/chrome/browser/crash_report/BUILD.gn index 4625a3b..5d9ff31 100644 --- a/ios/chrome/browser/crash_report/BUILD.gn +++ b/ios/chrome/browser/crash_report/BUILD.gn
@@ -37,9 +37,9 @@ "//components/previous_session_info", "//components/upload_list", "//ios/chrome/app:tests_hook", - "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/shared/model/application_context", "//ios/chrome/browser/shared/model/browser_state", + "//ios/chrome/browser/shared/model/paths", "//ios/chrome/common", "//ios/chrome/common/app_group", "//ios/chrome/common/crash_report", @@ -69,10 +69,10 @@ "//ios/chrome/app/theme", "//ios/chrome/browser/infobars", "//ios/chrome/browser/infobars:public", - "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/shared/coordinator/scene:scene_state_header", "//ios/chrome/browser/shared/model/browser", "//ios/chrome/browser/shared/model/browser_state", + "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/shared/model/web_state_list", "//ios/chrome/browser/shared/public/features", "//ios/chrome/browser/shared/ui/symbols",
diff --git a/ios/chrome/browser/metrics/BUILD.gn b/ios/chrome/browser/metrics/BUILD.gn index 2af0eac..a352efd 100644 --- a/ios/chrome/browser/metrics/BUILD.gn +++ b/ios/chrome/browser/metrics/BUILD.gn
@@ -104,11 +104,11 @@ "//ios/chrome/browser/default_browser:utils", "//ios/chrome/browser/history", "//ios/chrome/browser/ntp:features", - "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/shared/coordinator/scene:scene_state_header", "//ios/chrome/browser/shared/model/application_context", "//ios/chrome/browser/shared/model/browser", "//ios/chrome/browser/shared/model/browser_state", + "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/shared/model/prefs:pref_names", "//ios/chrome/browser/shared/model/url:constants", "//ios/chrome/browser/shared/model/web_state_list",
diff --git a/ios/chrome/browser/optimization_guide/BUILD.gn b/ios/chrome/browser/optimization_guide/BUILD.gn index cac84cc1..cb47cfe 100644 --- a/ios/chrome/browser/optimization_guide/BUILD.gn +++ b/ios/chrome/browser/optimization_guide/BUILD.gn
@@ -34,11 +34,11 @@ "//components/variations", "//ios/chrome/browser/download/background_service", "//ios/chrome/browser/metrics:accessor", - "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/push_notification:push_notification_client", "//ios/chrome/browser/shared/model/application_context", "//ios/chrome/browser/shared/model/browser", "//ios/chrome/browser/shared/model/browser_state", + "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/shared/model/web_state_list", "//ios/web", ]
diff --git a/ios/chrome/browser/policy/BUILD.gn b/ios/chrome/browser/policy/BUILD.gn index 5669dd8..f9091b6 100644 --- a/ios/chrome/browser/policy/BUILD.gn +++ b/ios/chrome/browser/policy/BUILD.gn
@@ -85,12 +85,12 @@ "//components/variations/service", "//components/version_info:version_info", "//ios/chrome/app/application_delegate:app_state_header", - "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/shared/coordinator/scene:scene_state_browser_agent", "//ios/chrome/browser/shared/coordinator/scene:scene_state_header", "//ios/chrome/browser/shared/model/application_context", "//ios/chrome/browser/shared/model/browser", "//ios/chrome/browser/shared/model/browser_state", + "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/shared/model/prefs:pref_names", "//ios/chrome/browser/shared/public/commands", "//ios/chrome/browser/signin", @@ -213,7 +213,6 @@ "//google_apis", "//ios/chrome/app/application_delegate:app_state_header", "//ios/chrome/browser/flags:system_flags", - "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/prefs", "//ios/chrome/browser/shared/coordinator/scene:scene_state_browser_agent", "//ios/chrome/browser/shared/coordinator/scene:scene_state_header", @@ -221,6 +220,7 @@ "//ios/chrome/browser/shared/model/application_context", "//ios/chrome/browser/shared/model/browser/test:test_support", "//ios/chrome/browser/shared/model/browser_state:test_support", + "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/shared/model/prefs:browser_prefs", "//ios/chrome/browser/shared/model/prefs:pref_names", "//ios/chrome/browser/shared/public/commands", @@ -320,10 +320,10 @@ "//components/policy/core/browser", "//components/policy/core/common", "//google_apis", - "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/policy_url_blocking", "//ios/chrome/browser/shared/model/application_context", "//ios/chrome/browser/shared/model/browser_state", + "//ios/chrome/browser/shared/model/paths", "//ios/chrome/test/app:test_support", ] frameworks = [ "Foundation.framework" ]
diff --git a/ios/chrome/browser/reading_list/BUILD.gn b/ios/chrome/browser/reading_list/BUILD.gn index 95c644a7..19b1402 100644 --- a/ios/chrome/browser/reading_list/BUILD.gn +++ b/ios/chrome/browser/reading_list/BUILD.gn
@@ -50,10 +50,10 @@ "//ios/chrome/app/strings:ios_strings_grit", "//ios/chrome/browser/favicon", "//ios/chrome/browser/history", - "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/shared/model/application_context", "//ios/chrome/browser/shared/model/browser", "//ios/chrome/browser/shared/model/browser_state", + "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/shared/model/url:constants", "//ios/chrome/browser/shared/model/web_state_list", "//ios/chrome/browser/shared/public/commands", @@ -141,8 +141,8 @@ "//components/reading_list/core:test_support", "//components/sync/base", "//ios/chrome/browser/dom_distiller", - "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/shared/model/browser_state:test_support", + "//ios/chrome/browser/shared/model/paths", "//ios/web", "//ios/web/public", "//ios/web/public/test",
diff --git a/ios/chrome/browser/segmentation_platform/BUILD.gn b/ios/chrome/browser/segmentation_platform/BUILD.gn index 806e72d..007fc49 100644 --- a/ios/chrome/browser/segmentation_platform/BUILD.gn +++ b/ios/chrome/browser/segmentation_platform/BUILD.gn
@@ -32,10 +32,10 @@ "//ios/chrome/browser/history", "//ios/chrome/browser/metrics:accessor", "//ios/chrome/browser/optimization_guide", - "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/shared/model/application_context", "//ios/chrome/browser/shared/model/browser", "//ios/chrome/browser/shared/model/browser_state", + "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/shared/model/web_state_list", "//ios/chrome/browser/sync", ]
diff --git a/ios/chrome/browser/sessions/BUILD.gn b/ios/chrome/browser/sessions/BUILD.gn index 3a976eab2..40b077c 100644 --- a/ios/chrome/browser/sessions/BUILD.gn +++ b/ios/chrome/browser/sessions/BUILD.gn
@@ -196,9 +196,9 @@ "//base/test:test_support", "//ios/chrome/browser/main", "//ios/chrome/browser/ntp", - "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/shared/model/browser/test:test_support", "//ios/chrome/browser/shared/model/browser_state:test_support", + "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/shared/model/url:constants", "//ios/chrome/browser/shared/model/web_state_list", "//ios/chrome/browser/shared/model/web_state_list/test:test_support",
diff --git a/ios/chrome/browser/shared/coordinator/scene/BUILD.gn b/ios/chrome/browser/shared/coordinator/scene/BUILD.gn index ec4dbea..5381678 100644 --- a/ios/chrome/browser/shared/coordinator/scene/BUILD.gn +++ b/ios/chrome/browser/shared/coordinator/scene/BUILD.gn
@@ -101,7 +101,6 @@ "//ios/chrome/browser/main", "//ios/chrome/browser/ntp", "//ios/chrome/browser/ntp:features", - "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/policy", "//ios/chrome/browser/policy:policy_util", "//ios/chrome/browser/promos_manager:factory", @@ -114,6 +113,7 @@ "//ios/chrome/browser/shared/coordinator/layout_guide:layout_guide_scene_agent", "//ios/chrome/browser/shared/model/application_context", "//ios/chrome/browser/shared/model/browser_state", + "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/shared/model/prefs:pref_names", "//ios/chrome/browser/shared/model/url", "//ios/chrome/browser/shared/model/url:constants",
diff --git a/ios/chrome/browser/shared/coordinator/scene/OWNERS b/ios/chrome/browser/shared/coordinator/scene/OWNERS new file mode 100644 index 0000000..b98e1d4 --- /dev/null +++ b/ios/chrome/browser/shared/coordinator/scene/OWNERS
@@ -0,0 +1,2 @@ +edchin@chromium.org +marq@chromium.org
diff --git a/ios/chrome/browser/shared/coordinator/scene/scene_delegate.mm b/ios/chrome/browser/shared/coordinator/scene/scene_delegate.mm index 2aa8f61..80eceaf 100644 --- a/ios/chrome/browser/shared/coordinator/scene/scene_delegate.mm +++ b/ios/chrome/browser/shared/coordinator/scene/scene_delegate.mm
@@ -50,6 +50,10 @@ @synthesize sceneState = _sceneState; @synthesize sceneController = _sceneController; +- (void)dealloc { + CHECK(!_sceneState); +} + - (SceneState*)sceneState { if (!_sceneState) { MainApplicationDelegate* appDelegate = @@ -92,7 +96,7 @@ return _window; } -#pragma mark Connecting and Disconnecting the Scene +#pragma mark - UISceneDelegate - (void)scene:(UIScene*)scene willConnectToSession:(UISceneSession*)session @@ -107,6 +111,14 @@ } } +- (void)sceneDidDisconnect:(UIScene*)scene { + CHECK(_sceneState); + self.sceneState.activationLevel = SceneActivationLevelUnattached; + _sceneState = nil; +} + +#pragma mark - private + - (WindowActivityOrigin)originFromSession:(UISceneSession*)session options:(UISceneConnectionOptions*)options { WindowActivityOrigin origin = WindowActivityUnknownOrigin; @@ -136,10 +148,6 @@ return origin; } -- (void)sceneDidDisconnect:(UIScene*)scene { - self.sceneState.activationLevel = SceneActivationLevelUnattached; -} - #pragma mark Transitioning to the Foreground - (void)sceneWillEnterForeground:(UIScene*)scene {
diff --git a/ios/chrome/browser/supervised_user/BUILD.gn b/ios/chrome/browser/supervised_user/BUILD.gn index 276a49c4..a0e6e39 100644 --- a/ios/chrome/browser/supervised_user/BUILD.gn +++ b/ios/chrome/browser/supervised_user/BUILD.gn
@@ -46,6 +46,7 @@ "//services/network/public/cpp", ] } + source_set("unit_tests") { configs += [ "//build/config/compiler:enable_arc" ] testonly = true @@ -56,36 +57,27 @@ "supervised_user_metrics_service_factory_unittest.mm", "supervised_user_service_factory_unittest.mm", "supervised_user_settings_service_factory_unittest.mm", + "supervised_user_url_filter_tab_helper_unittest.mm", ] deps = [ ":supervised_user", "//base/test:test_support", + "//components/signin/public/identity_manager", + "//components/signin/public/identity_manager:test_support", "//components/supervised_user/core/browser", "//components/supervised_user/core/browser:list_family_members_service", + "//components/supervised_user/core/browser:test_support", "//components/supervised_user/core/common", + "//components/sync_preferences", + "//components/sync_preferences:test_support", + "//ios/chrome/browser/shared/model/application_context:application_context", "//ios/chrome/browser/shared/model/browser_state:test_support", + "//ios/chrome/browser/shared/model/prefs:browser_prefs", + "//ios/chrome/browser/signin", + "//ios/chrome/browser/signin:test_support", + "//ios/chrome/test:test_support", "//ios/web/public/test", + "//services/network:test_support", + "//testing/gtest", ] } - -source_set("eg2_tests") { - configs += [ - "//build/config/compiler:enable_arc", - "//build/config/ios:xctest_config", - ] - testonly = true - sources = [ "supervised_user_url_filter_egtest.mm" ] - deps = [ - "//base", - "//components/strings", - "//components/strings:components_strings_grit", - "//components/supervised_user/core/common", - "//ios/chrome/browser/policy:eg_test_support+eg2", - "//ios/chrome/test/earl_grey:eg_test_support+eg2", - "//ios/testing/earl_grey:eg_test_support+eg2", - "//ios/web/public/test/http_server", - "//net:test_support", - "//ui/base", - ] - frameworks = [ "UIKit.framework" ] -}
diff --git a/ios/chrome/browser/supervised_user/supervised_user_service_factory.mm b/ios/chrome/browser/supervised_user/supervised_user_service_factory.mm index 3d0472d..f5571a9 100644 --- a/ios/chrome/browser/supervised_user/supervised_user_service_factory.mm +++ b/ios/chrome/browser/supervised_user/supervised_user_service_factory.mm
@@ -13,6 +13,7 @@ #import "ios/chrome/browser/first_run/first_run.h" #import "ios/chrome/browser/shared/model/application_context/application_context.h" #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h" +#import "ios/chrome/browser/signin/identity_manager_factory.h" #import "ios/chrome/browser/supervised_user/kids_chrome_management_client_factory.h" #import "ios/chrome/browser/supervised_user/supervised_user_settings_service_factory.h" #import "ios/chrome/browser/sync/sync_service_factory.h" @@ -75,6 +76,7 @@ : BrowserStateKeyedServiceFactory( "SupervisedUserService", BrowserStateDependencyManager::GetInstance()) { + DependsOn(IdentityManagerFactory::GetInstance()); DependsOn(KidsChromeManagementClientFactory::GetInstance()); DependsOn(SyncServiceFactory::GetInstance()); DependsOn(SupervisedUserSettingsServiceFactory::GetInstance()); @@ -98,6 +100,7 @@ // TODO (b/279766165): Once have an active Settings Service instance, initialize // this service on ChromeBrowserStateManagerImpl::DoFinalInitForServices(). return std::make_unique<supervised_user::SupervisedUserService>( + IdentityManagerFactory::GetForBrowserState(browser_state), KidsChromeManagementClientFactory::GetForBrowserState(browser_state), *user_prefs, *settings_service, *sync_service, // iOS does not support extensions, check_webstore_url_callback returns
diff --git a/ios/chrome/browser/supervised_user/supervised_user_url_filter_egtest.mm b/ios/chrome/browser/supervised_user/supervised_user_url_filter_egtest.mm deleted file mode 100644 index 6e575c8..0000000 --- a/ios/chrome/browser/supervised_user/supervised_user_url_filter_egtest.mm +++ /dev/null
@@ -1,60 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import <string> - -#import "base/feature_list.h" -#import "components/strings/grit/components_strings.h" -#import "components/supervised_user/core/common/features.h" -#import "ios/chrome/test/earl_grey/chrome_earl_grey.h" -#import "ios/chrome/test/earl_grey/chrome_matchers.h" -#import "ios/chrome/test/earl_grey/chrome_test_case.h" -#import "ios/testing/earl_grey/app_launch_configuration.h" -#import "ios/testing/earl_grey/earl_grey_test.h" -#import "net/base/net_errors.h" -#import "net/test/embedded_test_server/embedded_test_server.h" -#import "ui/base/l10n/l10n_util.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -// Tests the SupervisedUserURLFilter. -@interface SupervisedUserURLFilterTestCase : ChromeTestCase -@end - -@implementation SupervisedUserURLFilterTestCase - -- (AppLaunchConfiguration)appConfigurationForTestCase { - AppLaunchConfiguration config; - config.features_enabled.push_back( - supervised_user::kFilterWebsitesForSupervisedUsersOnDesktopAndIOS); - return config; -} - -- (void)setUp { - [super setUp]; - GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); -} - -- (void)tearDown { - [super tearDown]; -} - -// Tests that a page load is blocked when the URL is filtered. -- (void)testBlockedSiteDisplaysErrorOnPageLoad { - [ChromeEarlGrey loadURL:self.testServer->GetURL("/filtered")]; - [ChromeEarlGrey - waitForWebStateContainingText:l10n_util::GetStringUTF8( - IDS_BLOCK_INTERSTITIAL_TITLE)]; -} - -// Tests that unfiltered sites are loaded normally. -- (void)testUnfilteredSiteIsLoaded { - [ChromeEarlGrey loadURL:self.testServer->GetURL("/echo")]; - // Expected text set by embedded_test_server handler. - [ChromeEarlGrey waitForWebStateContainingText:"Echo"]; -} - -@end
diff --git a/ios/chrome/browser/supervised_user/supervised_user_url_filter_tab_helper.mm b/ios/chrome/browser/supervised_user/supervised_user_url_filter_tab_helper.mm index da5d26d..b09af6b5 100644 --- a/ios/chrome/browser/supervised_user/supervised_user_url_filter_tab_helper.mm +++ b/ios/chrome/browser/supervised_user/supervised_user_url_filter_tab_helper.mm
@@ -4,15 +4,23 @@ #import "ios/chrome/browser/supervised_user/supervised_user_url_filter_tab_helper.h" +#import "base/functional/callback.h" +#import "base/memory/weak_ptr.h" #import "base/strings/sys_string_conversions.h" #import "components/prefs/pref_service.h" +#import "components/supervised_user/core/browser/kids_chrome_management_client.h" #import "components/supervised_user/core/browser/supervised_user_interstitial.h" +#import "components/supervised_user/core/browser/supervised_user_service.h" +#import "components/supervised_user/core/browser/supervised_user_url_filter.h" +#import "components/supervised_user/core/common/features.h" #import "components/supervised_user/core/common/pref_names.h" #import "components/supervised_user/core/common/supervised_user_utils.h" #import "ios/chrome/browser/shared/model/application_context/application_context.h" #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h" +#import "ios/chrome/browser/supervised_user/kids_chrome_management_client_factory.h" #import "ios/chrome/browser/supervised_user/supervised_user_error.h" #import "ios/chrome/browser/supervised_user/supervised_user_error_container.h" +#import "ios/chrome/browser/supervised_user/supervised_user_service_factory.h" #import "ios/net/protocol_handler_util.h" #import "net/base/mac/url_conversions.h" #import "net/base/net_errors.h" @@ -22,29 +30,40 @@ #error "This file requires ARC support." #endif +using PolicyDecision = web::WebStatePolicyDecider::PolicyDecision; + namespace { -const char kFilteredURLExample[] = "/filtered"; +void OnURLFilteringDone( + base::WeakPtr<web::WebState> weak_web_state, + GURL request_url, + bool is_main_frame, + web::WebStatePolicyDecider::PolicyDecisionCallback policy_decision_callback, + supervised_user::SupervisedUserURLFilter::FilteringBehavior + filtering_behavior, + supervised_user::FilteringBehaviorReason reason, + bool uncertain /*unused*/) { + // Allow navigation by default. + PolicyDecision decision = PolicyDecision::Allow(); + web::WebState* web_state = weak_web_state.get(); -// Fake supervised user custodian information displayed in the interstitial. -// They will be fetched by the child account service once it is migrated to -// components. -void CreateMockData(web::WebState* web_state) { - ChromeBrowserState* browser_state = - ChromeBrowserState::FromBrowserState(web_state->GetBrowserState()); + if (!web_state) { + // Cancel the request if the corresponding `web_state` is destroyed. + decision = PolicyDecision::Cancel(); + } else if (filtering_behavior == supervised_user::SupervisedUserURLFilter:: + FilteringBehavior::BLOCK) { + SupervisedUserErrorContainer* container = + SupervisedUserErrorContainer::FromWebState(web_state); + CHECK(container); + container->SetSupervisedUserErrorInfo( + std::make_unique<SupervisedUserErrorContainer::SupervisedUserErrorInfo>( + request_url, is_main_frame, + // TODO(b/265761985): Update once we have this information. + /*is_already_requested=*/false, reason)); + decision = CreateSupervisedUserInterstitialErrorDecision(); + } - browser_state->GetPrefs()->SetString(prefs::kSupervisedUserCustodianEmail, - "primary@gmail.com"); - browser_state->GetPrefs()->SetString(prefs::kSupervisedUserCustodianName, - "Primary Name"); - browser_state->GetPrefs()->SetString( - prefs::kSupervisedUserSecondCustodianName, "Secondary Name"); - browser_state->GetPrefs()->SetString( - prefs::kSupervisedUserSecondCustodianEmail, "secondary@gmail.com"); - browser_state->GetPrefs()->SetString( - prefs::kSupervisedUserCustodianProfileImageURL, "thisurl.com"); - browser_state->GetPrefs()->SetString( - prefs::kSupervisedUserSecondCustodianProfileImageURL, "otherurl.com"); + std::move(policy_decision_callback).Run(decision); } } // namespace @@ -59,30 +78,34 @@ NSURLRequest* request, web::WebStatePolicyDecider::RequestInfo request_info, web::WebStatePolicyDecider::PolicyDecisionCallback callback) { - // TODO(b/265761985): integrate with SupervisedUserService::GetURLFilter(). - if ([request.URL.absoluteString containsString:@(kFilteredURLExample)]) { - supervised_user::FilteringBehaviorReason reason = - supervised_user::FilteringBehaviorReason:: - DEFAULT; // TODO(b/265761985): Extract reason from filtering. - // TODO(b/279765349): Remove once we have real data to populate the - // interstitial. - CreateMockData(web_state()); + ChromeBrowserState* chrome_browser_state = + ChromeBrowserState::FromBrowserState(web_state()->GetBrowserState()); - SupervisedUserErrorContainer* container = - SupervisedUserErrorContainer::FromWebState(web_state()); - CHECK(container); - container->SetSupervisedUserErrorInfo( - std::make_unique<SupervisedUserErrorContainer::SupervisedUserErrorInfo>( - GURL(base::SysNSStringToUTF8(request.URL.absoluteString)), - request_info.target_frame_is_main, - // TODO(b/265761985): Update once we have this information. - /*is_already_requested=*/false, reason)); - - std::move(callback).Run(CreateSupervisedUserInterstitialErrorDecision()); + // SupervisedUserService is not created for the off-the-record browser state. + if (chrome_browser_state->IsOffTheRecord()) { + std::move(callback).Run(PolicyDecision::Allow()); return; } - std::move(callback).Run(web::WebStatePolicyDecider::PolicyDecision::Allow()); + supervised_user::SupervisedUserService* supervised_user_service = + SupervisedUserServiceFactory::GetForBrowserState(chrome_browser_state); + + if (!supervised_user_service->IsURLFilteringEnabled()) { + std::move(callback).Run(PolicyDecision::Allow()); + return; + } + + // Set up the callback taking filtering results, and perform URL filtering. + GURL request_url = net::GURLWithNSURL(request.URL); + supervised_user::SupervisedUserURLFilter::FilteringBehaviorCallback + filtering_behavior_callback = base::BindOnce( + &OnURLFilteringDone, web_state()->GetWeakPtr(), request_url, + request_info.target_frame_is_main, std::move(callback)); + + supervised_user_service->GetURLFilter() + ->GetFilteringBehaviorForURLWithAsyncChecks( + request_url, std::move(filtering_behavior_callback), + /*skip_manual_parent_filter=*/false); } WEB_STATE_USER_DATA_KEY_IMPL(SupervisedUserURLFilterTabHelper)
diff --git a/ios/chrome/browser/supervised_user/supervised_user_url_filter_tab_helper_unittest.mm b/ios/chrome/browser/supervised_user/supervised_user_url_filter_tab_helper_unittest.mm new file mode 100644 index 0000000..ad08cf6 --- /dev/null +++ b/ios/chrome/browser/supervised_user/supervised_user_url_filter_tab_helper_unittest.mm
@@ -0,0 +1,203 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/supervised_user/supervised_user_url_filter_tab_helper.h" + +#import "base/memory/scoped_refptr.h" +#import "base/task/single_thread_task_runner.h" +#import "base/test/scoped_feature_list.h" +#import "components/signin/public/identity_manager/account_capabilities_test_mutator.h" +#import "components/signin/public/identity_manager/identity_manager.h" +#import "components/signin/public/identity_manager/identity_test_utils.h" +#import "components/supervised_user/core/browser/kids_chrome_management_client.h" +#import "components/supervised_user/core/browser/kids_chrome_management_test_utils.h" +#import "components/supervised_user/core/browser/supervised_user_service.h" +#import "components/supervised_user/core/browser/supervised_user_settings_service.h" +#import "components/supervised_user/core/common/features.h" +#import "components/sync_preferences/pref_service_mock_factory.h" +#import "components/sync_preferences/pref_service_syncable.h" +#import "ios/chrome/browser/shared/model/application_context/application_context.h" +#import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h" +#import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state_manager.h" +#import "ios/chrome/browser/shared/model/prefs/browser_prefs.h" +#import "ios/chrome/browser/signin/identity_manager_factory.h" +#import "ios/chrome/browser/signin/identity_test_environment_browser_state_adaptor.h" +#import "ios/chrome/browser/supervised_user/child_account_service_factory.h" +#import "ios/chrome/browser/supervised_user/supervised_user_error_container.h" +#import "ios/chrome/browser/supervised_user/supervised_user_service_factory.h" +#import "ios/chrome/browser/supervised_user/supervised_user_settings_service_factory.h" +#import "ios/chrome/test/testing_application_context.h" +#import "ios/web/public/navigation/web_state_policy_decider.h" +#import "ios/web/public/test/fakes/fake_web_state.h" +#import "ios/web/public/test/web_task_environment.h" +#import "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" +#import "services/network/test/test_url_loader_factory.h" +#import "testing/gtest/include/gtest/gtest.h" +#import "testing/platform_test.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace { + +const char kTestEmail[] = "test@gmail.com"; + +} // namespace + +class SupervisedUserURLFilterTabHelperTest : public PlatformTest { + protected: + SupervisedUserURLFilterTabHelperTest() { + TestChromeBrowserState::Builder builder; + builder.AddTestingFactory( + IdentityManagerFactory::GetInstance(), + base::BindRepeating(IdentityTestEnvironmentBrowserStateAdaptor:: + BuildIdentityManagerForTests)); + + chrome_browser_state_ = builder.Build(); + web_state_.SetBrowserState(chrome_browser_state_.get()); + SupervisedUserURLFilterTabHelper::CreateForWebState(&web_state_); + SupervisedUserErrorContainer::CreateForWebState(&web_state_); + + kids_chrome_management_client_ = + std::make_unique<kids_management::KidsChromeManagementClientForTesting>( + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory_), + IdentityManagerFactory::GetForBrowserState( + chrome_browser_state_.get())); + } + + void SetUp() override { + scoped_feature_list_.InitWithFeatures( + {supervised_user::kEnableSupervisionOnDesktopAndIOS, + supervised_user::kFilterWebsitesForSupervisedUsersOnDesktopAndIOS}, + {}); + } + + // Signs the user into `email` as the primary Chrome account and sets the + // given parental control capabilities on this account. + void SignIn(const std::string& email, bool is_subject_to_parental_controls) { + AccountInfo account = signin::MakePrimaryAccountAvailable( + IdentityManagerFactory::GetForBrowserState(chrome_browser_state_.get()), + email, signin::ConsentLevel::kSignin); + AccountCapabilitiesTestMutator mutator(&account.capabilities); + mutator.set_is_subject_to_parental_controls( + is_subject_to_parental_controls); + signin::UpdateAccountInfoForAccount( + IdentityManagerFactory::GetForBrowserState(chrome_browser_state_.get()), + account); + + // Initialize supervised_user services. + SupervisedUserSettingsServiceFactory::GetForBrowserState( + chrome_browser_state_.get()) + ->Init(chrome_browser_state_->GetStatePath(), + chrome_browser_state_->GetIOTaskRunner().get(), + /*load_synchronously=*/true); + ChildAccountServiceFactory::GetForBrowserState(chrome_browser_state_.get()) + ->Init(); + + supervised_user::SupervisedUserService* supervised_user_service = + SupervisedUserServiceFactory::GetForBrowserState( + chrome_browser_state_.get()); + supervised_user_service->Init(); + + EXPECT_EQ(supervised_user_service->IsSubjectToParentalControls(), + is_subject_to_parental_controls); + + // Set up the AsyncURLChecker with KidsChromeManagementClientForTesting. + supervised_user_service->GetURLFilter()->InitAsyncURLChecker( + kids_chrome_management_client_.get()); + } + + // Calls `ShouldAllowRequest` for a request with the given `url_string` and + // whether whether the navigation target frame is the main frame. + // Returns true if the URL request is blocked. + bool IsURLBlocked(NSString* url_string, bool target_frame_is_main) { + // Prepare the mock client response. + std::unique_ptr<kids_chrome_management::ClassifyUrlResponse> + response_proto = kids_management::BuildResponseProto(classification_); + kids_chrome_management_client_->SetResponseWithError( + std::move(response_proto), + KidsChromeManagementClient::ErrorCode::kSuccess); + + // Set up for `ShouldAllowRequest`. + const web::WebStatePolicyDecider::RequestInfo request_info( + ui::PageTransition::PAGE_TRANSITION_LINK, target_frame_is_main, + /*target_frame_is_cross_origin=*/false, + /*has_user_gesture=*/false); + __block bool callback_called = false; + __block web::WebStatePolicyDecider::PolicyDecision request_policy = + web::WebStatePolicyDecider::PolicyDecision::Allow(); + base::RunLoop run_loop; + auto quit_closure = run_loop.QuitClosure(); + auto callback = + base::BindOnce(^(web::WebStatePolicyDecider::PolicyDecision decision) { + request_policy = decision; + callback_called = true; + std::move(quit_closure).Run(); + }); + web_state_.ShouldAllowRequest( + [NSURLRequest requestWithURL:[NSURL URLWithString:url_string]], + request_info, std::move(callback)); + run_loop.Run(); + EXPECT_TRUE(callback_called); + + return request_policy.ShouldCancelNavigation(); + } + + // Returns true if the URL request is blocked for any navigation target frame. + bool IsURLBlocked(NSString* url_string) { + bool is_url_blocked_main_frame = + IsURLBlocked(url_string, /*target_frame_is_main=*/true); + bool is_url_blocked_sub_frame = + IsURLBlocked(url_string, /*target_frame_is_main=*/false); + EXPECT_EQ(is_url_blocked_main_frame, is_url_blocked_sub_frame); + return is_url_blocked_main_frame && is_url_blocked_sub_frame; + } + + void AllowAllSitesForSupervisedUser() { + classification_ = safe_search_api::ClientClassification::kAllowed; + } + + void RestrictAllSitesForSupervisedUser() { + classification_ = safe_search_api::ClientClassification::kRestricted; + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; + web::WebTaskEnvironment task_environment_; + network::TestURLLoaderFactory test_url_loader_factory_; + std::unique_ptr<TestChromeBrowserState> chrome_browser_state_; + web::FakeWebState web_state_; + std::unique_ptr<kids_management::KidsChromeManagementClientForTesting> + kids_chrome_management_client_; + safe_search_api::ClientClassification classification_; +}; + +TEST_F(SupervisedUserURLFilterTabHelperTest, + BlockCertainSitesForSupervisedUser) { + SignIn(kTestEmail, + /*is_subject_to_parental_controls=*/true); + RestrictAllSitesForSupervisedUser(); + EXPECT_TRUE(IsURLBlocked(@"http://blockedurl.com")); + AllowAllSitesForSupervisedUser(); + EXPECT_FALSE(IsURLBlocked(@"http://allowedurl.com")); +} + +TEST_F(SupervisedUserURLFilterTabHelperTest, + AllowsAllSitesForNonSupervisedUser) { + SignIn(kTestEmail, + /*is_subject_to_parental_controls=*/false); + RestrictAllSitesForSupervisedUser(); + EXPECT_FALSE(IsURLBlocked(@"http://blockedurl.com")); + AllowAllSitesForSupervisedUser(); + EXPECT_FALSE(IsURLBlocked(@"http://allowedurl.com")); +} + +TEST_F(SupervisedUserURLFilterTabHelperTest, AllowsAllSitesWhenLoggedOut) { + RestrictAllSitesForSupervisedUser(); + EXPECT_FALSE(IsURLBlocked(@"http://blockedurl.com")); + AllowAllSitesForSupervisedUser(); + EXPECT_FALSE(IsURLBlocked(@"http://allowedurl.com")); +}
diff --git a/ios/chrome/browser/ui/authentication/cells/signin_promo_view_consumer.h b/ios/chrome/browser/ui/authentication/cells/signin_promo_view_consumer.h index cf475441..7475c1f 100644 --- a/ios/chrome/browser/ui/authentication/cells/signin_promo_view_consumer.h +++ b/ios/chrome/browser/ui/authentication/cells/signin_promo_view_consumer.h
@@ -26,6 +26,9 @@ @optional +// Called when the sign-in in progress status changes. +- (void)promoProgressStateDidChange; + // Called when the sign-in is finished. - (void)signinDidFinish;
diff --git a/ios/chrome/browser/ui/authentication/signed_in_accounts/signed_in_accounts_table_view_controller.mm b/ios/chrome/browser/ui/authentication/signed_in_accounts/signed_in_accounts_table_view_controller.mm index 4e90271e..80e554d0 100644 --- a/ios/chrome/browser/ui/authentication/signed_in_accounts/signed_in_accounts_table_view_controller.mm +++ b/ios/chrome/browser/ui/authentication/signed_in_accounts/signed_in_accounts_table_view_controller.mm
@@ -51,6 +51,8 @@ (ChromeAccountManagerService*)accountManagerService { self = [super initWithStyle:UITableViewStylePlain]; if (self) { + CHECK(identityManager); + CHECK(accountManagerService); _identityManager = identityManager; _accountManagerService = accountManagerService; _accountManagerServiceObserver.reset(
diff --git a/ios/chrome/browser/ui/authentication/signed_in_accounts/signed_in_accounts_view_controller.mm b/ios/chrome/browser/ui/authentication/signed_in_accounts/signed_in_accounts_view_controller.mm index ca22b1a4..a25f2d0 100644 --- a/ios/chrome/browser/ui/authentication/signed_in_accounts/signed_in_accounts_view_controller.mm +++ b/ios/chrome/browser/ui/authentication/signed_in_accounts/signed_in_accounts_view_controller.mm
@@ -84,6 +84,8 @@ (id<ApplicationSettingsCommands>)dispatcher { self = [super initWithNibName:nil bundle:nil]; if (self) { + CHECK(browserState); + CHECK(dispatcher); _browserState = browserState; _dispatcher = dispatcher; _identityManager = @@ -137,6 +139,7 @@ _identityManager = nullptr; _identityManagerObserver.reset(); _dispatcher = nil; + _browserState = nullptr; } #pragma mark UIViewController
diff --git a/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.h b/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.h index 3cc42a8..8c9e76b 100644 --- a/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.h +++ b/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.h
@@ -7,6 +7,7 @@ #import <Foundation/Foundation.h> +#import "components/sync/base/model_type.h" #import "ios/chrome/browser/ui/authentication/cells/signin_promo_view.h" #import "ios/chrome/browser/ui/authentication/cells/signin_promo_view_delegate.h" @@ -23,6 +24,10 @@ enum class AccessPoint; } +namespace syncer { +class SyncService; +} + namespace ios { // Enums for the sign-in promo view state. Those states are sequential, with no // way to go backwards. All states can be skipped except `NeverVisible` and @@ -100,6 +105,7 @@ (ChromeAccountManagerService*)accountManagerService authService:(AuthenticationService*)authService prefService:(PrefService*)prefService + syncService:(syncer::SyncService*)syncService accessPoint:(signin_metrics::AccessPoint)accessPoint presenter:(id<SigninPresenter>)presenter baseViewController:(UIViewController*)baseViewController @@ -116,6 +122,9 @@ // never been shown, or it is already hidden, this method does nothing. - (void)signinPromoViewIsHidden; +// Set the data type that should be synced before the sign-in completes. +- (void)setDataTypeToWaitForInitialSync:(syncer::ModelType)dataType; + // Disconnects the mediator, this method needs to be called when the sign-in // promo view is removed from the view hierarchy (it or one of its superviews is // removed). The mediator should not be used after this called.
diff --git a/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm b/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm index 36835966..c4b206e 100644 --- a/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm +++ b/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm
@@ -24,6 +24,7 @@ #import "ios/chrome/browser/signin/chrome_account_manager_service.h" #import "ios/chrome/browser/signin/chrome_account_manager_service_observer_bridge.h" #import "ios/chrome/browser/signin/system_identity.h" +#import "ios/chrome/browser/sync/sync_observer_bridge.h" #import "ios/chrome/browser/ui/authentication/authentication_flow.h" #import "ios/chrome/browser/ui/authentication/cells/signin_promo_view_configurator.h" #import "ios/chrome/browser/ui/authentication/cells/signin_promo_view_consumer.h" @@ -496,7 +497,8 @@ } // namespace @interface SigninPromoViewMediator () <ChromeAccountManagerServiceObserver, - IdentityChooserCoordinatorDelegate> + IdentityChooserCoordinatorDelegate, + SyncObserverModelBridge> // Redefined to be readwrite. @property(nonatomic, strong, readwrite) id<SystemIdentity> identity; @@ -539,6 +541,10 @@ UIViewController* _baseViewController; // Sign-in flow, used only when `self.signInOnly` is `YES`. AuthenticationFlow* _authenticationFlow; + // Sync service. + syncer::SyncService* _syncService; + // Observer for changes to the sync state. + std::unique_ptr<SyncObserverBridge> _syncObserverBridge; // Coordinator for the user to select an account. IdentityChooserCoordinator* _identityChooserCoordinator; // Coordinator to add an account. @@ -546,6 +552,8 @@ // TODO(crbug.com/1448830): This class should not need to block the UI. // The UI blocker is only used in sign-in only cases. std::unique_ptr<ScopedUIBlocker> _uiBlocker; + // The type of data that should be synced before the sign-in completes. + syncer::ModelType _dataTypeToWaitForInitialSync; } + (void)registerBrowserStatePrefs:(user_prefs::PrefRegistrySyncable*)registry { @@ -634,6 +642,7 @@ (ChromeAccountManagerService*)accountManagerService authService:(AuthenticationService*)authService prefService:(PrefService*)prefService + syncService:(syncer::SyncService*)syncService accessPoint:(signin_metrics::AccessPoint)accessPoint presenter:(id<SigninPresenter>)presenter baseViewController:(UIViewController*)baseViewController { @@ -645,12 +654,20 @@ _accountManagerService = accountManagerService; _authService = authService; _prefService = prefService; + _syncService = syncService; _accessPoint = accessPoint; + _dataTypeToWaitForInitialSync = syncer::ModelType::UNSPECIFIED; _presenter = presenter; _baseViewController = baseViewController; _accountManagerServiceObserver = std::make_unique<ChromeAccountManagerServiceObserverBridge>( self, _accountManagerService); + // Starting the sync state observation enables the sign-in progress to be + // set to YES even if the user hasn't interacted with the promo. It is + // intentional to keep UX consistency, given the initial sync cancellation + // which should end the sign-in progress is tricky to detect. + _syncObserverBridge = + std::make_unique<SyncObserverBridge>(self, _syncService); id<SystemIdentity> defaultIdentity = [self defaultIdentity]; if (defaultIdentity) { @@ -758,12 +775,19 @@ self.signinPromoViewVisible = NO; } +- (void)setDataTypeToWaitForInitialSync:(syncer::ModelType)dataType { + _dataTypeToWaitForInitialSync = dataType; + [self updateSignInProgressWithSyncState]; +} + - (void)disconnect { [self signinPromoViewIsRemoved]; self.consumer = nil; self.accountManagerService = nullptr; self.authService = nullptr; + _syncService = nullptr; _accountManagerServiceObserver.reset(); + _syncObserverBridge.reset(); } #pragma mark - Public properties @@ -825,6 +849,10 @@ } _signinInProgress = signinInProgress; SigninPromoViewConfigurator* configurator = [self createConfigurator]; + if ([self.consumer + respondsToSelector:@selector(promoProgressStateDidChange)]) { + [self.consumer promoProgressStateDidChange]; + } [self.consumer configureSigninPromoWithConfigurator:configurator identityChanged:NO]; } @@ -945,6 +973,10 @@ __weak __typeof(self) weakSelf = self; [_authenticationFlow startSignInWithCompletion:^(BOOL success) { [weakSelf signInFlowCompletedForSignInOnly]; + if ([weakSelf shouldWaitForInitialSync]) { + return; + } + weakSelf.signinInProgress = NO; if ([weakConsumer respondsToSelector:@selector(signinDidFinish)]) { [weakConsumer signinDidFinish]; } @@ -956,7 +988,6 @@ - (void)signInFlowCompletedForSignInOnly { DCHECK(self.signInOnly) << base::SysNSStringToUTF8([self description]); _uiBlocker.reset(); - self.signinInProgress = NO; } - (void)startAddAccountForSignInOnly { @@ -1029,6 +1060,29 @@ displayedCount); } +// Whether the sign-in needs to wait for the end of the initial sync to +// complete. +- (BOOL)shouldWaitForInitialSync { + return _dataTypeToWaitForInitialSync != syncer::ModelType::UNSPECIFIED; +} + +// If initial sync is needed before the sign-in completes, set the +// `signinInProgress` according to the initial sync state. +- (void)updateSignInProgressWithSyncState { + if (![self shouldWaitForInitialSync]) { + return; + } + self.signinInProgress = [self isPerformingInitialSync]; +} + +// Whether the initial sync of the ModelType given by +// `_dataTypeToWaitForInitialSync` is in progress. +- (BOOL)isPerformingInitialSync { + CHECK(_dataTypeToWaitForInitialSync != syncer::ModelType::UNSPECIFIED); + return _syncService->GetTypesWithPendingDownloadForInitialSync().Has( + _dataTypeToWaitForInitialSync); +} + #pragma mark - ChromeAccountManagerServiceObserver - (void)identityListChanged { @@ -1175,6 +1229,29 @@ [self startSignInOnlyFlow]; } +#pragma mark - SyncObserverModelBridge + +// If additional data sync is needed during sign-in, update `signinInProgress` +// to match the sync progress state when the sync state changes. This is needed +// especially when the sign-in is undone during initial sync and +// `onSyncConfigurationCompleted` is not called. +- (void)onSyncStateChanged { + [self updateSignInProgressWithSyncState]; +} + +// If additional data sync is needed during sign-in, set `signinInProgress` +// to NO when the initial sync finishes for the data type. +- (void)onSyncConfigurationCompleted { + if (![self shouldWaitForInitialSync] || [self isPerformingInitialSync]) { + return; + } + // Handle sign-in completion. + self.signinInProgress = NO; + if ([self.consumer respondsToSelector:@selector(signinDidFinish)]) { + [self.consumer signinDidFinish]; + } +} + #pragma mark - NSObject - (NSString*)description {
diff --git a/ios/chrome/browser/ui/authentication/signin_promo_view_mediator_unittest.mm b/ios/chrome/browser/ui/authentication/signin_promo_view_mediator_unittest.mm index bfda9a76..8d50295 100644 --- a/ios/chrome/browser/ui/authentication/signin_promo_view_mediator_unittest.mm +++ b/ios/chrome/browser/ui/authentication/signin_promo_view_mediator_unittest.mm
@@ -113,6 +113,7 @@ chrome_browser_state_.get()) authService:GetAuthenticationService() prefService:chrome_browser_state_.get()->GetPrefs() + syncService:GetSyncService() accessPoint:access_point presenter:nil baseViewController:nil]; @@ -143,6 +144,10 @@ chrome_browser_state_.get()); } + syncer::SyncService* GetSyncService() { + return SyncServiceFactory::GetForBrowserState(chrome_browser_state_.get()); + } + // Creates the default identity and adds it into the ChromeIdentityService. void AddDefaultIdentity() { fake_system_identity_manager()->AddIdentity(identity_); @@ -455,6 +460,7 @@ signin_metrics::PromoAction:: PROMO_ACTION_NEW_ACCOUNT_NO_EXISTING_ACCOUNT completion:completion_arg]); + OCMExpect([consumer_ promoProgressStateDidChange]); ExpectConfiguratorNotification(NO /* identity changed */); [mediator_ signinPromoViewDidTapSigninWithNewAccount:signin_promo_view_]; EXPECT_TRUE(mediator_.signinInProgress); @@ -462,6 +468,7 @@ mediator_.signinPromoViewState); EXPECT_NE(nil, (id)completion); // Stop sign-in. + OCMExpect([consumer_ promoProgressStateDidChange]); OCMExpect([consumer_ signinDidFinish]); ExpectConfiguratorNotification(NO /* identity changed */); completion(YES); @@ -489,6 +496,7 @@ signin_metrics::PromoAction:: PROMO_ACTION_NEW_ACCOUNT_NO_EXISTING_ACCOUNT completion:completion_arg]); + OCMExpect([consumer_ promoProgressStateDidChange]); ExpectConfiguratorNotification(NO /* identity changed */); // Starts sign-in without identity. [mediator_ signinPromoViewDidTapSigninWithNewAccount:signin_promo_view_]; @@ -497,6 +505,7 @@ // No consumer notification should be expected. fake_system_identity_manager()->WaitForServiceCallbacksToComplete(); // Finishs the sign-in. + OCMExpect([consumer_ promoProgressStateDidChange]); OCMExpect([consumer_ signinDidFinish]); ExpectConfiguratorNotification(NO /* identity changed */); completion(YES); @@ -520,6 +529,7 @@ promoAction:signin_metrics::PromoAction:: PROMO_ACTION_WITH_DEFAULT completion:completion_arg]); + OCMExpect([consumer_ promoProgressStateDidChange]); ExpectConfiguratorNotification(NO /* identity changed */); // Starts sign-in with an identity. [mediator_ signinPromoViewDidTapSigninWithDefaultAccount:signin_promo_view_]; @@ -532,6 +542,7 @@ // Spins the run loop to wait for the profile image update. fake_system_identity_manager()->WaitForServiceCallbacksToComplete(); // Finishs the sign-in. + OCMExpect([consumer_ promoProgressStateDidChange]); OCMExpect([consumer_ signinDidFinish]); ExpectConfiguratorNotification(NO /* identity changed */); completion(YES); @@ -594,6 +605,7 @@ promoAction:signin_metrics::PromoAction:: PROMO_ACTION_WITH_DEFAULT completion:completion_arg]); + OCMExpect([consumer_ promoProgressStateDidChange]); ExpectConfiguratorNotification(NO /* identity changed */); // Start sign-in with an identity. [mediator_ signinPromoViewDidTapSigninWithDefaultAccount:signin_promo_view_]; @@ -626,6 +638,7 @@ promoAction:signin_metrics::PromoAction:: PROMO_ACTION_WITH_DEFAULT completion:completion_arg]); + OCMExpect([consumer_ promoProgressStateDidChange]); ExpectConfiguratorNotification(NO /* identity changed */); // Start sign-in with an identity. [mediator_ signinPromoViewDidTapSigninWithDefaultAccount:signin_promo_view_];
diff --git a/ios/chrome/browser/ui/authentication/signout_action_sheet_coordinator.mm b/ios/chrome/browser/ui/authentication/signout_action_sheet_coordinator.mm index 879ae8c..75a0647a 100644 --- a/ios/chrome/browser/ui/authentication/signout_action_sheet_coordinator.mm +++ b/ios/chrome/browser/ui/authentication/signout_action_sheet_coordinator.mm
@@ -93,6 +93,10 @@ self.actionSheetCoordinator = nil; } +- (void)dealloc { + DCHECK(!self.actionSheetCoordinator); +} + #pragma mark - ActionSheetCoordinator properties - (NSString*)title {
diff --git a/ios/chrome/browser/ui/authentication/signout_action_sheet_coordinator_unittest.mm b/ios/chrome/browser/ui/authentication/signout_action_sheet_coordinator_unittest.mm index b193843c..f490b04a 100644 --- a/ios/chrome/browser/ui/authentication/signout_action_sheet_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/authentication/signout_action_sheet_coordinator_unittest.mm
@@ -71,6 +71,12 @@ SyncSetupServiceFactory::GetForBrowserState(browser_state_.get())); } + void TearDown() override { + [signout_coordinator_ stop]; + signout_coordinator_ = nil; + PlatformTest::TearDown(); + } + // Identity services. AuthenticationService* authentication_service() { return AuthenticationServiceFactory::GetForBrowserState(
diff --git a/ios/chrome/browser/ui/bookmarks/home/bookmark_promo_controller.h b/ios/chrome/browser/ui/bookmarks/home/bookmark_promo_controller.h index 4ffe2ea..1163b2d9 100644 --- a/ios/chrome/browser/ui/bookmarks/home/bookmark_promo_controller.h +++ b/ios/chrome/browser/ui/bookmarks/home/bookmark_promo_controller.h
@@ -12,6 +12,10 @@ @class SigninPromoViewConfigurator; @class SigninPromoViewMediator; +namespace syncer { +class SyncService; +} + @protocol BookmarkPromoControllerDelegate // Controls the state of the promo. @@ -46,6 +50,7 @@ // Designated initializer. // `baseViewController` is the view to present UI for sign-in. - (instancetype)initWithBrowser:(Browser*)browser + syncService:(syncer::SyncService*)syncService delegate:(id<BookmarkPromoControllerDelegate>)delegate presenter:(id<SigninPresenter>)presenter baseViewController:(UIViewController*)baseViewController
diff --git a/ios/chrome/browser/ui/bookmarks/home/bookmark_promo_controller.mm b/ios/chrome/browser/ui/bookmarks/home/bookmark_promo_controller.mm index d40ba12..aacdaa6 100644 --- a/ios/chrome/browser/ui/bookmarks/home/bookmark_promo_controller.mm +++ b/ios/chrome/browser/ui/bookmarks/home/bookmark_promo_controller.mm
@@ -42,6 +42,7 @@ } - (instancetype)initWithBrowser:(Browser*)browser + syncService:(syncer::SyncService*)syncService delegate:(id<BookmarkPromoControllerDelegate>)delegate presenter:(id<SigninPresenter>)presenter baseViewController:(UIViewController*)baseViewController { @@ -62,11 +63,17 @@ authService:AuthenticationServiceFactory::GetForBrowserState( browserState) prefService:browserState->GetPrefs() + syncService:syncService accessPoint:signin_metrics::AccessPoint:: ACCESS_POINT_BOOKMARK_MANAGER presenter:presenter baseViewController:baseViewController]; _signinPromoViewMediator.consumer = self; + if (base::FeatureList::IsEnabled( + bookmarks::kEnableBookmarksAccountStorage)) { + [_signinPromoViewMediator + setDataTypeToWaitForInitialSync:syncer::ModelType::BOOKMARKS]; + } [self updateShouldShowSigninPromo]; } return self; @@ -147,7 +154,8 @@ _signinPromoViewMediator.signInOnly = NO; return; } - if ([self.delegate isPerformingInitialSync]) { + + if (self.signinPromoViewMediator.signinInProgress) { // The user is opted into syncing bookmarks, but the first sync is not // finished yet - keep the promo visible to show the spinner. self.shouldShowSigninPromo = YES; @@ -184,6 +192,10 @@ identityChanged:identityChanged]; } +- (void)promoProgressStateDidChange { + [self updateShouldShowSigninPromo]; +} + - (void)signinDidFinish { [self updateShouldShowSigninPromo]; }
diff --git a/ios/chrome/browser/ui/bookmarks/home/bookmarks_home_mediator.mm b/ios/chrome/browser/ui/bookmarks/home/bookmarks_home_mediator.mm index d6e9ca7..7630b08 100644 --- a/ios/chrome/browser/ui/bookmarks/home/bookmarks_home_mediator.mm +++ b/ios/chrome/browser/ui/bookmarks/home/bookmarks_home_mediator.mm
@@ -146,8 +146,10 @@ _syncedBookmarksObserver = std::make_unique<sync_bookmarks::SyncedBookmarksObserverBridge>( self, browserState); + _syncService = SyncServiceFactory::GetForBrowserState(browserState); _bookmarkPromoController = [[BookmarkPromoController alloc] initWithBrowser:_browser.get() + syncService:_syncService delegate:self presenter:self baseViewController:_baseViewController]; @@ -162,8 +164,6 @@ _prefObserverBridge->ObserveChangesForPreference( bookmarks::prefs::kManagedBookmarks, _prefChangeRegistrar.get()); - _syncService = SyncServiceFactory::GetForBrowserState(browserState); - [self computePromoTableViewData]; [self computeBookmarkTableViewData]; }
diff --git a/ios/chrome/browser/ui/ntp/feed_top_section/BUILD.gn b/ios/chrome/browser/ui/ntp/feed_top_section/BUILD.gn index 5adb9041..e64b9434 100644 --- a/ios/chrome/browser/ui/ntp/feed_top_section/BUILD.gn +++ b/ios/chrome/browser/ui/ntp/feed_top_section/BUILD.gn
@@ -25,6 +25,7 @@ "//ios/chrome/browser/shared/model/browser_state", "//ios/chrome/browser/shared/public/commands", "//ios/chrome/browser/signin", + "//ios/chrome/browser/sync", "//ios/chrome/browser/ui/authentication", "//ios/chrome/browser/ui/authentication:signin_presenter", "//ios/chrome/browser/ui/authentication/cells",
diff --git a/ios/chrome/browser/ui/ntp/feed_top_section/feed_top_section_coordinator.mm b/ios/chrome/browser/ui/ntp/feed_top_section/feed_top_section_coordinator.mm index d92987a..5d5ffd41 100644 --- a/ios/chrome/browser/ui/ntp/feed_top_section/feed_top_section_coordinator.mm +++ b/ios/chrome/browser/ui/ntp/feed_top_section/feed_top_section_coordinator.mm
@@ -14,6 +14,7 @@ #import "ios/chrome/browser/signin/chrome_account_manager_service.h" #import "ios/chrome/browser/signin/chrome_account_manager_service_factory.h" #import "ios/chrome/browser/signin/identity_manager_factory.h" +#import "ios/chrome/browser/sync/sync_service_factory.h" #import "ios/chrome/browser/ui/authentication/signin_presenter.h" #import "ios/chrome/browser/ui/authentication/signin_promo_view_mediator.h" #import "ios/chrome/browser/ui/ntp/feed_top_section/feed_top_section_mediator.h" @@ -51,6 +52,8 @@ IdentityManagerFactory::GetForBrowserState(browserState); AuthenticationService* authenticationService = AuthenticationServiceFactory::GetForBrowserState(browserState); + syncer::SyncService* syncService = + SyncServiceFactory::GetForBrowserState(browserState); self.feedTopSectionMediator = [[FeedTopSectionMediator alloc] initWithConsumer:self.feedTopSectionViewController identityManager:identityManager @@ -65,6 +68,7 @@ authService:AuthenticationServiceFactory::GetForBrowserState( browserState) prefService:browserState->GetPrefs() + syncService:syncService accessPoint:signin_metrics::AccessPoint:: ACCESS_POINT_NTP_FEED_TOP_PROMO presenter:self
diff --git a/ios/chrome/browser/ui/promos_manager/promos_manager_coordinator.mm b/ios/chrome/browser/ui/promos_manager/promos_manager_coordinator.mm index 39cd66d60..8364f77 100644 --- a/ios/chrome/browser/ui/promos_manager/promos_manager_coordinator.mm +++ b/ios/chrome/browser/ui/promos_manager/promos_manager_coordinator.mm
@@ -81,8 +81,8 @@ std::map<promos_manager::Promo, id<StandardPromoAlertProvider>>> _alertProviderPromos; - // The currently displayed promo, if any. - absl::optional<promos_manager::Promo> current_promo; + // The currently displayed promo data, if any. + absl::optional<PromoDisplayData> _currentPromoData; } // A mediator that observes when it's a good time to display a promo. @@ -170,7 +170,7 @@ } - (void)displayPromoCallback:(BOOL)isFirstShownPromo { - absl::optional<promos_manager::Promo> nextPromoForDisplay = + absl::optional<PromoDisplayData> nextPromoForDisplay = [self.mediator nextPromoForDisplay:isFirstShownPromo]; if (nextPromoForDisplay.has_value()) { @@ -197,9 +197,10 @@ } - (void)promoWasDismissed { - if (ShouldPromosManagerUseFET() && current_promo.has_value()) { + if (ShouldPromosManagerUseFET() && _currentPromoData.has_value() && + !_currentPromoData.value().was_forced) { PromoConfigsSet configs = [self promoImpressionLimits]; - auto it = configs.find(current_promo.value()); + auto it = configs.find(_currentPromoData.value().promo); if (it == configs.end() || !it->feature_engagement_feature) { return; } @@ -209,25 +210,27 @@ self.browser->GetBrowserState()); tracker->Dismissed(*it->feature_engagement_feature); } - current_promo = absl::nullopt; + _currentPromoData = absl::nullopt; } -- (void)displayPromo:(promos_manager::Promo)promo { +- (void)displayPromo:(PromoDisplayData)promoData { if (tests_hook::DisablePromoManagerFullScreenPromos()) { return; } + promos_manager::Promo promo = promoData.promo; + // Trying to display a promo while the previous dismissal was not communicated // back to the promos manager. // TODO(crbug.com/1452233): Remove once all promos dismiss themselves. - if (current_promo.has_value()) { + if (_currentPromoData.has_value()) { static crash_reporter::CrashKeyString<40> key("current-promo"); crash_reporter::ScopedCrashKeyString crashKey( - &key, ShortNameForPromo(current_promo.value())); + &key, ShortNameForPromo(_currentPromoData.value().promo)); base::debug::DumpWithoutCrashing(); } - current_promo = promo; + _currentPromoData = promoData; auto handler_it = _displayHandlerPromos.find(promo); auto provider_it = _viewProviderPromos.find(promo);
diff --git a/ios/chrome/browser/ui/promos_manager/promos_manager_mediator.h b/ios/chrome/browser/ui/promos_manager/promos_manager_mediator.h index 0b85b71c..ef77acdd 100644 --- a/ios/chrome/browser/ui/promos_manager/promos_manager_mediator.h +++ b/ios/chrome/browser/ui/promos_manager/promos_manager_mediator.h
@@ -12,6 +12,12 @@ #import "ios/chrome/browser/promos_manager/promos_manager.h" #import "third_party/abseil-cpp/absl/types/optional.h" +// Data used and cached to know what promo to show. +struct PromoDisplayData { + promos_manager::Promo promo; + bool was_forced; +}; + // A mediator that (1) communicates with the PromosManager to find the next // promo (promos_manager::Promo), if any, to display, and (2) records the // display impression of said promo. @@ -33,8 +39,7 @@ // Queries the PromosManager for the next promo (promos_manager::Promo) to // display, if any. Allows for special behavior if this is the first promo // shown. -- (absl::optional<promos_manager::Promo>)nextPromoForDisplay: - (BOOL)isFirstShownPromo; +- (absl::optional<PromoDisplayData>)nextPromoForDisplay:(BOOL)isFirstShownPromo; // The Promos Manager used for deciding which promo should be displayed, if any. @property(nonatomic, assign) PromosManager* promosManager;
diff --git a/ios/chrome/browser/ui/promos_manager/promos_manager_mediator.mm b/ios/chrome/browser/ui/promos_manager/promos_manager_mediator.mm index 4e816c41..3d86f353 100644 --- a/ios/chrome/browser/ui/promos_manager/promos_manager_mediator.mm +++ b/ios/chrome/browser/ui/promos_manager/promos_manager_mediator.mm
@@ -39,7 +39,7 @@ _promosManager->RecordImpression(promo); } -- (absl::optional<promos_manager::Promo>)nextPromoForDisplay: +- (absl::optional<PromoDisplayData>)nextPromoForDisplay: (BOOL)isFirstShownPromo { DCHECK_NE(_promosManager, nullptr); // Only check for a forced promo the first time around, to prevent infinite @@ -50,10 +50,16 @@ absl::optional<promos_manager::Promo> forcedPromo = [self forcedPromoToDisplay]; if (forcedPromo) { - return forcedPromo; + return PromoDisplayData{.promo = forcedPromo.value(), .was_forced = true}; } } - return self.promosManager->NextPromoForDisplay(); + + absl::optional<promos_manager::Promo> promo = + self.promosManager->NextPromoForDisplay(); + if (promo) { + return PromoDisplayData{.promo = promo.value(), .was_forced = false}; + } + return absl::nullopt; } // Returns the promo selected in the Force Promo experimental setting.
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm b/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm index 5f3dbd2..cb576c3 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm
@@ -205,12 +205,15 @@ accountManagerService:accountManagerService authService:_authService prefService:_prefService + syncService:_syncService accessPoint:signin_metrics::AccessPoint:: ACCESS_POINT_READING_LIST presenter:self baseViewController:self.tableViewController]; _signinPromoViewMediator.signInOnly = YES; _signinPromoViewMediator.consumer = self; + [_signinPromoViewMediator + setDataTypeToWaitForInitialSync:syncer::ModelType::READING_LIST]; [self updateSignInPromoVisibility]; [super start]; @@ -575,6 +578,10 @@ identityChanged:identityChanged]; } +- (void)promoProgressStateDidChange { + [self updateSignInPromoVisibility]; +} + - (void)signinDidFinish { [self updateSignInPromoVisibility]; } @@ -629,8 +636,12 @@ self.shouldShowSignInPromo = NO; return; } + if (_identityManager->HasPrimaryAccount(signin::ConsentLevel::kSignin)) { - self.shouldShowSignInPromo = NO; + // If the user is signed-in with the promo (thus opted-in for Reading List + // account storage), the promo should stay visible during the initial sync + // and a spinner should be shown on it. + self.shouldShowSignInPromo = _signinPromoViewMediator.signinInProgress; } else { const std::string lastSignedInGaiaId = _prefService->GetString(prefs::kGoogleServicesLastGaiaId);
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.mm b/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.mm index a08c30d..9f329cb 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.mm
@@ -705,8 +705,7 @@ (SigninPromoViewConfigurator*)promoConfigurator identityChanged:(BOOL)identityChanged { if (![self.tableViewModel - hasSectionForSectionIdentifier:kSectionIdentifierSignInPromo] || - !identityChanged) { + hasSectionForSectionIdentifier:kSectionIdentifierSignInPromo]) { return; }
diff --git a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm index 522680b9..463fe5a 100644 --- a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm +++ b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
@@ -721,6 +721,7 @@ authService:AuthenticationServiceFactory::GetForBrowserState( self.browserState) prefService:self.browserState->GetPrefs() + syncService:self.syncService accessPoint:signin_metrics::AccessPoint:: ACCESS_POINT_RECENT_TABS presenter:self
diff --git a/ios/chrome/browser/ui/settings/autofill/autofill_profile_table_view_controller.mm b/ios/chrome/browser/ui/settings/autofill/autofill_profile_table_view_controller.mm index dbce625..93a3003b 100644 --- a/ios/chrome/browser/ui/settings/autofill/autofill_profile_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/autofill/autofill_profile_table_view_controller.mm
@@ -10,7 +10,10 @@ #import "base/metrics/user_metrics.h" #import "base/metrics/user_metrics_action.h" #import "base/strings/sys_string_conversions.h" +#import "base/strings/utf_string_conversions.h" +#import "components/autofill/core/browser/geo/country_data.h" #import "components/autofill/core/browser/personal_data_manager.h" +#import "components/autofill/core/browser/profile_requirement_utils.h" #import "components/autofill/core/common/autofill_features.h" #import "components/autofill/core/common/autofill_prefs.h" #import "components/autofill/ios/browser/personal_data_manager_observer_bridge.h" @@ -263,13 +266,7 @@ AutofillAddressProfileSource::AutofillSyncableProfile; } else { item.autofillProfileSource = AutofillLocalProfile; - if (base::FeatureList::IsEnabled( - autofill::features::kAutofillAccountProfileStorage) && - base::FeatureList::IsEnabled(syncer::kSyncEnableContactInfoDataType) && - base::FeatureList::IsEnabled( - syncer::kSyncEnableContactInfoDataTypeInTransportMode) && - // Denotes that the user is signed-in. - self.userEmail != nil) { + if ([self shouldShowCloudOffIconForProfile:autofillProfile]) { item.image = CustomSymbolTemplateWithPointSize( kCloudSlashSymbol, kCloudSlashSymbolPointSize); } @@ -761,4 +758,23 @@ [self.autofillProfileEditCoordinator start]; } +// Returns YES if the cloud off icon should be shown next to the profile. Only +// those profiles, that are eligible for the migration to Account show cloud off +// icon. +- (BOOL)shouldShowCloudOffIconForProfile: + (const autofill::AutofillProfile&)profile { + std::string country_code = base::UTF16ToUTF8( + profile.GetRawInfo(autofill::ServerFieldType::ADDRESS_HOME_COUNTRY)); + const std::vector<std::string>& country_codes = + autofill::CountryDataMap::GetInstance()->country_codes(); + return base::Contains(country_codes, country_code) && + IsEligibleForMigrationToAccount(*_personalDataManager, profile) && + base::FeatureList::IsEnabled( + syncer::kSyncEnableContactInfoDataTypeInTransportMode) && + // Denotes that the user is signed-in. + self.userEmail != nil && + IsMinimumAddress(profile, country_code, + _personalDataManager->app_locale()); +} + @end
diff --git a/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.mm b/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.mm index 31c3ff1e..1123738 100644 --- a/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.mm +++ b/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.mm
@@ -108,6 +108,11 @@ animated:YES]; } +- (void)stop { + [self.signOutCoordinator stop]; + _signOutCoordinator = nil; +} + #pragma mark - Private - (void)authenticationFlowDidComplete {
diff --git a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_coordinator.mm b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_coordinator.mm index a81fbd4..499ae0a1 100644 --- a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_coordinator.mm +++ b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_coordinator.mm
@@ -174,6 +174,8 @@ syncSetupService->CommitSyncChanges(); _syncObserver.reset(); + [self.signoutActionSheetCoordinator stop]; + _signoutActionSheetCoordinator = nil; } #pragma mark - Properties
diff --git a/ios/chrome/browser/ui/settings/settings_table_view_controller.mm b/ios/chrome/browser/ui/settings/settings_table_view_controller.mm index 807fb7b4..bf08ae9 100644 --- a/ios/chrome/browser/ui/settings/settings_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
@@ -611,6 +611,8 @@ authService:AuthenticationServiceFactory:: GetForBrowserState(_browserState) prefService:_browserState->GetPrefs() + syncService:SyncServiceFactory::GetForBrowserState( + _browserState) accessPoint:signin_metrics::AccessPoint:: ACCESS_POINT_SETTINGS presenter:self
diff --git a/ios/chrome/browser/web/BUILD.gn b/ios/chrome/browser/web/BUILD.gn index ef8bffd1..cbf6bd5 100644 --- a/ios/chrome/browser/web/BUILD.gn +++ b/ios/chrome/browser/web/BUILD.gn
@@ -277,7 +277,6 @@ "//ios/chrome/browser/open_from_clipboard", "//ios/chrome/browser/optimization_guide", "//ios/chrome/browser/passwords", - "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/policy", "//ios/chrome/browser/prerender", "//ios/chrome/browser/promos_manager", @@ -286,6 +285,7 @@ "//ios/chrome/browser/search_engines", "//ios/chrome/browser/shared/model/application_context", "//ios/chrome/browser/shared/model/browser_state", + "//ios/chrome/browser/shared/model/paths", "//ios/chrome/browser/shared/model/prefs:pref_names", "//ios/chrome/browser/shared/model/url", "//ios/chrome/browser/shared/model/url:constants",
diff --git a/ios/chrome/test/earl_grey2/BUILD.gn b/ios/chrome/test/earl_grey2/BUILD.gn index b4958a4d..a9c10f63 100644 --- a/ios/chrome/test/earl_grey2/BUILD.gn +++ b/ios/chrome/test/earl_grey2/BUILD.gn
@@ -91,7 +91,6 @@ "//ios/chrome/browser/policy_url_blocking:eg2_tests", "//ios/chrome/browser/prerender:eg2_tests", "//ios/chrome/browser/safe_browsing:eg2_tests", - "//ios/chrome/browser/supervised_user:eg2_tests", "//ios/chrome/browser/ui/autofill:eg2_tests", "//ios/chrome/browser/ui/autofill/branding:eg2_tests", "//ios/chrome/browser/ui/autofill/manual_fill:eg2_tests",
diff --git a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 index 6f0e2ec6..9c213e3 100644 --- a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@ -d6365ec598375f905de8c35a4a6b6a50e3843e1f \ No newline at end of file +d1b940509cf2479a8ea2097695fe7f172377f75e \ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 index 3d151308..dab9686 100644 --- a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@ -59525ff49d8eac61747f2638ff309de6df3b8b7e \ No newline at end of file +468289da5674685612458cbf2436e362567e9c75 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 index 8de1eed..181c80c 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -a0391ddd3b2b8e60deec1a91054ee97d5f173d4f \ No newline at end of file +b7223d41e49fb84afdb79238b7b41f07880bc6be \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 index 32b066f..55e40c09 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -05368807b9fd6f4ecfe720ecceb8121e9610533c \ No newline at end of file +9794e1b7f945743501337a6f27aebf4d4fa802bb \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 index c4fd716..cd5a4e2 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -083f1c8cf8b6bc2f9f23e7cb19f467b88e4a5d61 \ No newline at end of file +a09ed1a882cf43d192c98ba3734285478ad69f5e \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 index e0db0b8..090e02f 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -e659499d525e5ebb7360bbc71cdcc9dcb001447f \ No newline at end of file +aea15d247dcdde4142dea1d5f9245166daa3e7f9 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 index c023d4a..ed23e87 100644 --- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -5ae99231fcf60cb3c04cfd023b6890f7357150c9 \ No newline at end of file +3e7a60d90053762d27e3aa2fda7a1012e382df57 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 index 33e121c..c8548d6 100644 --- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -fd3d7fc5cb0c77e6eef6c369daea1483bacf9e51 \ No newline at end of file +52dab00d433c6abacc059fd2715082b59c03987a \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 index 06f3f4c..0f72d005 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -9e397433f6aecc4c8c611fc2562d8281d51fc107 \ No newline at end of file +ccca59fcb24a249d260e6edef472d90760b3d0a3 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 index da334a5..9f24d2b 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -10683931cd225e06bc9c92022c1d10d262491bbb \ No newline at end of file +bbe31d9999fbe4ff8864530fd600d7a7cc66a552 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 index 49256bf5..c6f3c9d 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -70c67676f4ea7ca005ebe889b1d883d319f2b4cd \ No newline at end of file +1dbc38e55d2ded1faeaf1bdcc37637df058eb7b4 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 index d1bdde02..71933b2 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -39f40a3cdd5860d92d6ee3b8000d3c1a20de4743 \ No newline at end of file +9ef0a68d2dc57744c98e45711e9206bde3bcfade \ No newline at end of file
diff --git a/ios/web/public/web_view_only/BUILD.gn b/ios/web/public/web_view_only/BUILD.gn index b27f62a..29de8ba 100644 --- a/ios/web/public/web_view_only/BUILD.gn +++ b/ios/web/public/web_view_only/BUILD.gn
@@ -12,8 +12,8 @@ deps = [ "//ios/web/web_view_only" ] visibility = [ - "//ios/web_view:*", "//ios/web/web_view_only:unittests", + "//ios/web_view:*", ] }
diff --git a/ipc/ipc_channel_mojo.cc b/ipc/ipc_channel_mojo.cc index 50bb176..881322a 100644 --- a/ipc/ipc_channel_mojo.cc +++ b/ipc/ipc_channel_mojo.cc
@@ -100,7 +100,7 @@ const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; const Forwarder forwarder_; - const raw_ref<mojo::AssociatedGroupController, DanglingUntriaged> + const raw_ref<mojo::AssociatedGroupController, DanglingAcrossTasks> group_controller_; };
diff --git a/media/audio/audio_device_stats_reporter.cc b/media/audio/audio_device_stats_reporter.cc index 10426bd..9ae781e 100644 --- a/media/audio/audio_device_stats_reporter.cc +++ b/media/audio/audio_device_stats_reporter.cc
@@ -45,13 +45,6 @@ // delays up to 1s. /*bucket_count = */ 50, type)), - delay_difference_log_callback_(CreateAggregateCallback( - "DelayDifference", - params.latency_tag(), - /*max_value = */ 1000, // Measured in ms. Allows us to differentiate - // delay differences up to 1s. - /*bucket_count = */ 50, - type)), glitch_count_log_callback_(CreateAggregateCallback( "GlitchCount", params.latency_tag(), @@ -88,8 +81,6 @@ ++stats_.callback_count; stats_.glitch_count += glitch_info.count; stats_.glitch_duration += glitch_info.duration; - stats_.largest_delay = std::max(delay, stats_.largest_delay); - stats_.smallest_delay = std::min(delay, stats_.smallest_delay); if (stats_.callback_count >= 1000) { UploadStats(stats_, SamplingPeriod::kIntervals); @@ -111,21 +102,13 @@ int glitch_duration_permille = std::round(1000 * stats.glitch_duration / stats_duration); - DCHECK_NE(stats.largest_delay, base::TimeDelta::Min()); - DCHECK_NE(stats.smallest_delay, base::TimeDelta::Max()); - int delay_difference_ms = - (stats.largest_delay - stats.smallest_delay).InMilliseconds(); - glitch_count_log_callback_.Run(stats.glitch_count, sampling_period); - delay_difference_log_callback_.Run(delay_difference_ms, sampling_period); glitch_duration_log_callback_.Run(glitch_duration_permille, sampling_period); } // Used to generate callbacks for: -// Media.AudioOutputDevice.AudioServiceDelayDifference.*.* // Media.AudioOutputDevice.AudioServiceGlitchCount.*.* // Media.AudioOutputDevice.AudioServiceDroppedAudio.*.* -// Media.AudioInputDevice.AudioServiceDelayDifference.* // Media.AudioInputDevice.AudioServiceGlitchCount.* // Media.AudioInputDevice.AudioServiceDroppedAudio.* // |latency| is ignored for input.
diff --git a/media/audio/audio_device_stats_reporter.h b/media/audio/audio_device_stats_reporter.h index 6bf1fe38a..8e82f394 100644 --- a/media/audio/audio_device_stats_reporter.h +++ b/media/audio/audio_device_stats_reporter.h
@@ -48,8 +48,6 @@ int callback_count = 0; int glitch_count = 0; base::TimeDelta glitch_duration; - base::TimeDelta smallest_delay = base::TimeDelta::Max(); - base::TimeDelta largest_delay = base::TimeDelta::Min(); }; // Logs data aggregated over intervals. @@ -82,7 +80,6 @@ // Callback functions for writing to the histograms. const RealtimeLogCallback delay_log_callback_; - const AggregateLogCallback delay_difference_log_callback_; const AggregateLogCallback glitch_count_log_callback_; const AggregateLogCallback glitch_duration_log_callback_;
diff --git a/media/audio/audio_device_stats_reporter_unittest.cc b/media/audio/audio_device_stats_reporter_unittest.cc index 4d722ad..f68d3af 100644 --- a/media/audio/audio_device_stats_reporter_unittest.cc +++ b/media/audio/audio_device_stats_reporter_unittest.cc
@@ -20,10 +20,6 @@ namespace { const std::string kRenderDelay = "Media.AudioOutputDevice.AudioServiceDelay"; -const std::string kRenderDelayDifferenceShort = - "Media.AudioOutputDevice.AudioServiceDelayDifference.Short"; -const std::string kRenderDelayDifferenceIntervals = - "Media.AudioOutputDevice.AudioServiceDelayDifference.Intervals"; const std::string kRenderGlitchCountShort = "Media.AudioOutputDevice.AudioServiceGlitchCount.Short"; const std::string kRenderGlitchCountIntervals = @@ -34,10 +30,6 @@ "Media.AudioOutputDevice.AudioServiceGlitchDuration.Intervals"; const std::string kCaptureDelay = "Media.AudioInputDevice.AudioServiceDelay"; -const std::string kCaptureDelayDifferenceShort = - "Media.AudioInputDevice.AudioServiceDelayDifference.Short"; -const std::string kCaptureDelayDifferenceIntervals = - "Media.AudioInputDevice.AudioServiceDelayDifference.Intervals"; const std::string kCaptureGlitchCountShort = "Media.AudioInputDevice.AudioServiceGlitchCount.Short"; const std::string kCaptureGlitchCountIntervals = @@ -98,9 +90,6 @@ histogram_tester_.ExpectBucketCount(kRenderDelay + latency_tag_, 60, 50); histogram_tester_.ExpectBucketCount(kRenderDelay, 140, 50); histogram_tester_.ExpectBucketCount(kRenderDelay + latency_tag_, 140, 50); - histogram_tester_.ExpectBucketCount(kRenderDelayDifferenceShort, 80, 1); - histogram_tester_.ExpectBucketCount( - kRenderDelayDifferenceShort + latency_tag_, 80, 1); histogram_tester_.ExpectBucketCount(kRenderGlitchCountShort, 50, 1); histogram_tester_.ExpectBucketCount(kRenderGlitchCountShort + latency_tag_, 50, 1); @@ -108,7 +97,6 @@ histogram_tester_.ExpectBucketCount(kRenderGlitchDurationShort + latency_tag_, 500, 1); - histogram_tester_.ExpectTotalCount(kRenderDelayDifferenceIntervals, 0); histogram_tester_.ExpectTotalCount(kRenderGlitchCountIntervals, 0); histogram_tester_.ExpectTotalCount(kRenderGlitchDurationIntervals, 0); } @@ -152,9 +140,6 @@ histogram_tester_.ExpectBucketCount(kRenderDelay, 140, 500); histogram_tester_.ExpectBucketCount(kRenderDelay + latency_tag_, 140, 500); - histogram_tester_.ExpectBucketCount(kRenderDelayDifferenceIntervals, 80, 1); - histogram_tester_.ExpectBucketCount( - kRenderDelayDifferenceIntervals + latency_tag_, 80, 1); histogram_tester_.ExpectBucketCount(kRenderGlitchCountIntervals, 500, 1); histogram_tester_.ExpectBucketCount( kRenderGlitchCountIntervals + latency_tag_, 500, 1); @@ -167,9 +152,6 @@ histogram_tester_.ExpectBucketCount(kRenderDelay + latency_tag_, 10, 500); histogram_tester_.ExpectBucketCount(kRenderDelay, 190, 500); histogram_tester_.ExpectBucketCount(kRenderDelay + latency_tag_, 190, 500); - histogram_tester_.ExpectBucketCount(kRenderDelayDifferenceIntervals, 180, 1); - histogram_tester_.ExpectBucketCount( - kRenderDelayDifferenceIntervals + latency_tag_, 180, 1); histogram_tester_.ExpectBucketCount(kRenderGlitchCountIntervals, 250, 1); histogram_tester_.ExpectBucketCount( kRenderGlitchCountIntervals + latency_tag_, 250, 1); @@ -182,7 +164,6 @@ histogram_tester_.ExpectBucketCount(kRenderDelay + latency_tag_, 100, 500); reporter_.reset(); - histogram_tester_.ExpectTotalCount(kRenderDelayDifferenceShort, 0); histogram_tester_.ExpectTotalCount(kRenderGlitchCountShort, 0); histogram_tester_.ExpectTotalCount(kRenderGlitchDurationShort, 0); } @@ -238,11 +219,9 @@ histogram_tester_.ExpectBucketCount(kCaptureDelay, 60, 50); histogram_tester_.ExpectBucketCount(kCaptureDelay, 140, 50); - histogram_tester_.ExpectBucketCount(kCaptureDelayDifferenceShort, 80, 1); histogram_tester_.ExpectBucketCount(kCaptureGlitchCountShort, 50, 1); histogram_tester_.ExpectBucketCount(kCaptureGlitchDurationShort, 500, 1); - histogram_tester_.ExpectTotalCount(kCaptureDelayDifferenceIntervals, 0); histogram_tester_.ExpectTotalCount(kCaptureGlitchCountIntervals, 0); histogram_tester_.ExpectTotalCount(kCaptureGlitchDurationIntervals, 0); } @@ -281,14 +260,12 @@ histogram_tester_.ExpectBucketCount(kCaptureDelay, 60, 500); histogram_tester_.ExpectBucketCount(kCaptureDelay, 140, 500); - histogram_tester_.ExpectBucketCount(kCaptureDelayDifferenceIntervals, 80, 1); histogram_tester_.ExpectBucketCount(kCaptureGlitchCountIntervals, 500, 1); histogram_tester_.ExpectBucketCount(kCaptureGlitchDurationIntervals, 500, 1); // Data from the second interval. histogram_tester_.ExpectBucketCount(kCaptureDelay, 10, 500); histogram_tester_.ExpectBucketCount(kCaptureDelay, 190, 500); - histogram_tester_.ExpectBucketCount(kCaptureDelayDifferenceIntervals, 180, 1); histogram_tester_.ExpectBucketCount(kCaptureGlitchCountIntervals, 250, 1); histogram_tester_.ExpectBucketCount(kCaptureGlitchDurationIntervals, 250, 1); @@ -296,7 +273,6 @@ histogram_tester_.ExpectBucketCount(kCaptureDelay, 100, 500); reporter_.reset(); - histogram_tester_.ExpectTotalCount(kCaptureDelayDifferenceShort, 0); histogram_tester_.ExpectTotalCount(kCaptureGlitchCountShort, 0); histogram_tester_.ExpectTotalCount(kCaptureGlitchDurationShort, 0); }
diff --git a/media/capture/BUILD.gn b/media/capture/BUILD.gn index e39e96f..4c3112f6 100644 --- a/media/capture/BUILD.gn +++ b/media/capture/BUILD.gn
@@ -272,6 +272,8 @@ if (is_linux) { sources += [ + "video/linux/v4l2_capture_delegate_gpu_helper.cc", + "video/linux/v4l2_capture_delegate_gpu_helper.h", "video/linux/v4l2_gpu_memory_buffer_tracker.cc", "video/linux/v4l2_gpu_memory_buffer_tracker.h", "video/linux/video_capture_gpu_memory_buffer_manager.cc", @@ -469,7 +471,11 @@ } if (is_linux) { - sources += [ "video/linux/v4l2_gpu_memory_buffer_tracker_unittest.cc" ] + sources += [ + "video/linux/v4l2_capture_delegate_gpu_helper_unittest.cc", + "video/linux/v4l2_gpu_memory_buffer_tracker_unittest.cc", + ] + data += [ "//media/test/data/one_frame_1280x720.mjpeg" ] } if (is_android) {
diff --git a/media/capture/video/apple/video_capture_device_avfoundation.mm b/media/capture/video/apple/video_capture_device_avfoundation.mm index c6e47da..4e2c635 100644 --- a/media/capture/video/apple/video_capture_device_avfoundation.mm +++ b/media/capture/video/apple/video_capture_device_avfoundation.mm
@@ -407,11 +407,14 @@ // yes/no and preserve aspect ratio yes/no when scaling. Currently we set // cropping and preservation. NSDictionary* videoSettingsDictionary = @{ +#if BUILDFLAG(IS_MAC) (id)kCVPixelBufferWidthKey : @(width), (id)kCVPixelBufferHeightKey : @(height), - (id)kCVPixelBufferPixelFormatTypeKey : @(best_fourcc), - AVVideoScalingModeKey : AVVideoScalingModeResizeAspectFill + AVVideoScalingModeKey : AVVideoScalingModeResizeAspectFill, +#endif + (id)kCVPixelBufferPixelFormatTypeKey : @(best_fourcc) }; + _captureVideoDataOutput.videoSettings = videoSettingsDictionary; #if (!defined(__IPHONE_7_0) || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0)
diff --git a/media/capture/video/linux/v4l2_capture_delegate_gpu_helper.cc b/media/capture/video/linux/v4l2_capture_delegate_gpu_helper.cc new file mode 100644 index 0000000..5c6fcff --- /dev/null +++ b/media/capture/video/linux/v4l2_capture_delegate_gpu_helper.cc
@@ -0,0 +1,266 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/capture/video/linux/v4l2_capture_delegate_gpu_helper.h" + +#include "third_party/libyuv/include/libyuv.h" +#include "ui/gfx/gpu_memory_buffer.h" + +namespace media { + +namespace { +constexpr media::VideoPixelFormat kTargetPixelFormat = + media::VideoPixelFormat::PIXEL_FORMAT_NV12; +constexpr gfx::BufferFormat kTargetBufferFormat = + gfx::BufferFormat::YUV_420_BIPLANAR; + +libyuv::FourCC VideoCaptureFormatToLibyuvFourcc( + const VideoCaptureFormat& capture_format) { + const int chopped_width = capture_format.frame_size.width() & 1; + const int chopped_height = capture_format.frame_size.height() & 1; + libyuv::FourCC fourcc_format = libyuv::FOURCC_ANY; + + switch (capture_format.pixel_format) { + case PIXEL_FORMAT_UNKNOWN: // Color format not set. + break; + case PIXEL_FORMAT_I420: + DCHECK(!chopped_width && !chopped_height); + fourcc_format = libyuv::FOURCC_I420; + break; + case PIXEL_FORMAT_YV12: + DCHECK(!chopped_width && !chopped_height); + fourcc_format = libyuv::FOURCC_YV12; + break; + case PIXEL_FORMAT_NV12: + DCHECK(!chopped_width && !chopped_height); + fourcc_format = libyuv::FOURCC_NV12; + break; + case PIXEL_FORMAT_NV21: + DCHECK(!chopped_width && !chopped_height); + fourcc_format = libyuv::FOURCC_NV21; + break; + case PIXEL_FORMAT_YUY2: + DCHECK(!chopped_width); + fourcc_format = libyuv::FOURCC_YUY2; + break; + case PIXEL_FORMAT_UYVY: + DCHECK(!chopped_width); + fourcc_format = libyuv::FOURCC_UYVY; + break; + case PIXEL_FORMAT_RGB24: + fourcc_format = libyuv::FOURCC_RAW; + break; + case PIXEL_FORMAT_ARGB: + // Windows platforms e.g. send the data vertically flipped sometimes. + fourcc_format = libyuv::FOURCC_ARGB; + break; + case PIXEL_FORMAT_MJPEG: + fourcc_format = libyuv::FOURCC_MJPG; + break; + default: + NOTREACHED(); + } + return fourcc_format; +} + +libyuv::RotationMode TranslateRotation(int rotation_degrees) { + DCHECK_EQ(0, rotation_degrees % 90) << " Rotation must be a multiple of 90, " + "now: " + << rotation_degrees; + libyuv::RotationMode rotation_mode = libyuv::kRotate0; + if (rotation_degrees == 90) { + rotation_mode = libyuv::kRotate90; + } else if (rotation_degrees == 180) { + rotation_mode = libyuv::kRotate180; + } else if (rotation_degrees == 270) { + rotation_mode = libyuv::kRotate270; + } + return rotation_mode; +} + +} // namespace + +V4L2CaptureDelegateGpuHelper::V4L2CaptureDelegateGpuHelper( + std::unique_ptr<gpu::GpuMemoryBufferSupport> gmb_support) + : gmb_support_(gmb_support + ? std::move(gmb_support) + : std::make_unique<gpu::GpuMemoryBufferSupport>()) {} + +V4L2CaptureDelegateGpuHelper::~V4L2CaptureDelegateGpuHelper() = default; + +int V4L2CaptureDelegateGpuHelper::OnIncomingCapturedData( + VideoCaptureDevice::Client* client, + const uint8_t* sample, + size_t sample_size, + const VideoCaptureFormat& capture_format, + const gfx::ColorSpace& data_color_space, + int rotation, + base::TimeTicks reference_time, + base::TimeDelta timestamp, + int frame_feedback_id) { + if (!client) { + return -1; + } + + // Align destination resolution to be even. + int dst_width = capture_format.frame_size.width() & ~1; + int dst_height = capture_format.frame_size.height() & ~1; + if (rotation == 90 || rotation == 270) { + std::swap(dst_width, dst_height); + } + const gfx::Size dimensions(dst_width, dst_height); + VideoCaptureDevice::Client::Buffer capture_buffer; + auto reservation_result_code = client->ReserveOutputBuffer( + dimensions, kTargetPixelFormat, frame_feedback_id, &capture_buffer); + if (reservation_result_code != + VideoCaptureDevice::Client::ReserveResult::kSucceeded) { + DLOG(ERROR) << "Failed to reserve output capture buffer: " + << (int)reservation_result_code; + client->OnFrameDropped( + ConvertReservationFailureToFrameDropReason(reservation_result_code)); + return -1; + } + + std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buff = + gmb_support_->CreateGpuMemoryBufferImplFromHandle( + capture_buffer.handle_provider->GetGpuMemoryBufferHandle(), + dimensions, kTargetBufferFormat, + gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, base::NullCallback()); + if (!gpu_memory_buff || !gpu_memory_buff->Map()) { + DLOG(ERROR) << "Failed to allocate gpu memory buffer buffer."; + client->OnFrameDropped(ConvertReservationFailureToFrameDropReason( + VideoCaptureDevice::Client::ReserveResult::kAllocationFailed)); + return -1; + } + + uint8_t* dst_y = (uint8_t*)gpu_memory_buff->memory(VideoFrame::kYPlane); + uint8_t* dst_uv = (uint8_t*)gpu_memory_buff->memory(VideoFrame::kUVPlane); + const int dst_stride_y = gpu_memory_buff->stride(VideoFrame::kYPlane); + const int dst_stride_uv = gpu_memory_buff->stride(VideoFrame::kUVPlane); + int status = ConvertCaptureDataToNV12( + sample, sample_size, capture_format, dimensions, data_color_space, + rotation, dst_y, dst_uv, dst_stride_y, dst_stride_uv); + + gpu_memory_buff->Unmap(); + + if (status != 0) { + DLOG(ERROR) << "Failed to convert capture data."; + client->OnFrameDropped(ConvertReservationFailureToFrameDropReason( + VideoCaptureDevice::Client::ReserveResult::kSucceeded)); + return status; + } + + client->OnIncomingCapturedBufferExt( + std::move(capture_buffer), + VideoCaptureFormat(dimensions, capture_format.frame_rate, + kTargetPixelFormat), + gfx::ColorSpace(), reference_time, timestamp, gfx::Rect(dimensions), + VideoFrameMetadata()); + return status; +} + +int V4L2CaptureDelegateGpuHelper::ConvertCaptureDataToNV12( + const uint8_t* sample, + size_t sample_size, + const VideoCaptureFormat& capture_format, + const gfx::Size& dimensions, + const gfx::ColorSpace& data_color_space, + int rotation, + uint8_t* dst_y, + uint8_t* dst_uv, + int dst_stride_y, + int dst_stride_uv) { + const libyuv::FourCC fourcc = + VideoCaptureFormatToLibyuvFourcc(capture_format); + const libyuv::RotationMode rotation_mode = TranslateRotation(rotation); + if (rotation_mode == libyuv::RotationMode::kRotate0 && + IsNV12ConvertSupported(fourcc)) { + return FastConvertToNV12(sample, sample_size, capture_format, dst_y, dst_uv, + dst_stride_y, dst_stride_uv); + } + + const size_t i420_size = VideoFrame::AllocationSize( + VideoPixelFormat::PIXEL_FORMAT_I420, dimensions); + i420_buffer_.reserve(i420_size); + if (!i420_buffer_.data()) { + return -1; + } + + uint8_t* i420_y = i420_buffer_.data(); + uint8_t* i420_u = + i420_y + VideoFrame::PlaneSize(VideoPixelFormat::PIXEL_FORMAT_I420, + VideoFrame::kYPlane, dimensions) + .GetArea(); + uint8_t* i420_v = + i420_u + VideoFrame::PlaneSize(VideoPixelFormat::PIXEL_FORMAT_I420, + VideoFrame::kUPlane, dimensions) + .GetArea(); + std::vector<int32_t> i420_strides = VideoFrame::ComputeStrides( + VideoPixelFormat::PIXEL_FORMAT_I420, dimensions); + const int i420_stride_y = i420_strides[VideoFrame::kYPlane]; + const int i420_stride_u = i420_strides[VideoFrame::kUPlane]; + const int i420_stride_v = i420_strides[VideoFrame::kVPlane]; + + const int width = capture_format.frame_size.width(); + const int height = capture_format.frame_size.height(); + const int crop_width = width & ~1; + const int crop_height = height & ~1; + int status = libyuv::ConvertToI420( + sample, sample_size, i420_y, i420_stride_y, i420_u, i420_stride_u, i420_v, + i420_stride_v, 0, 0, width, height, crop_width, crop_height, + rotation_mode, fourcc); + if (status != 0) { + return status; + } + + status = libyuv::I420ToNV12(i420_y, i420_stride_y, i420_u, i420_stride_u, + i420_v, i420_stride_v, dst_y, dst_stride_y, + dst_uv, dst_stride_uv, width, height); + + return status; +} + +int V4L2CaptureDelegateGpuHelper::FastConvertToNV12( + const uint8_t* sample, + size_t sample_size, + const VideoCaptureFormat& capture_format, + uint8_t* dst_y, + uint8_t* dst_uv, + int dst_stride_y, + int dst_stride_uv) { + const int src_width = capture_format.frame_size.width(); + const int src_height = capture_format.frame_size.height(); + const uint8_t* src_uv = sample + (src_width * src_height); + + const libyuv::FourCC fourcc = + VideoCaptureFormatToLibyuvFourcc(capture_format); + switch (libyuv::CanonicalFourCC(fourcc)) { + case libyuv::FOURCC_YUY2: + return libyuv::YUY2ToNV12(sample, src_width * 2, dst_y, dst_stride_y, + dst_uv, dst_stride_uv, src_width, src_height); + case libyuv::FOURCC_MJPG: + return libyuv::MJPGToNV12(sample, sample_size, dst_y, dst_stride_y, + dst_uv, dst_stride_uv, src_width, src_height, + src_width, src_height); + case libyuv::FOURCC_NV12: + return libyuv::NV12Copy(sample, src_width, src_uv, src_width, dst_y, + dst_stride_y, dst_uv, dst_stride_uv, src_width, + src_height); + default: + return -1; + } +} + +bool V4L2CaptureDelegateGpuHelper::IsNV12ConvertSupported(uint32_t fourcc) { + switch (libyuv::CanonicalFourCC(fourcc)) { + case libyuv::FOURCC_NV12: + case libyuv::FOURCC_YUY2: + case libyuv::FOURCC_MJPG: + return true; + default: + return false; + } +} + +} // namespace media
diff --git a/media/capture/video/linux/v4l2_capture_delegate_gpu_helper.h b/media/capture/video/linux/v4l2_capture_delegate_gpu_helper.h new file mode 100644 index 0000000..f7e8baba --- /dev/null +++ b/media/capture/video/linux/v4l2_capture_delegate_gpu_helper.h
@@ -0,0 +1,79 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_CAPTURE_VIDEO_LINUX_V4L2_CAPTURE_DELEGATE_GPU_HELPER_H_ +#define MEDIA_CAPTURE_VIDEO_LINUX_V4L2_CAPTURE_DELEGATE_GPU_HELPER_H_ + +#include <vector> + +#include "gpu/ipc/common/gpu_memory_buffer_support.h" +#include "media/capture/video/video_capture_device.h" + +namespace media { + +// V4L2CaptureDelegate GPU memory buffer helper. +// This class is a helper to covert video capture data into `NV12` format and +// copy into GPU memory buffer. +class CAPTURE_EXPORT V4L2CaptureDelegateGpuHelper { + public: + explicit V4L2CaptureDelegateGpuHelper( + std::unique_ptr<gpu::GpuMemoryBufferSupport> gmb_support = nullptr); + + V4L2CaptureDelegateGpuHelper(const V4L2CaptureDelegateGpuHelper&) = delete; + V4L2CaptureDelegateGpuHelper& operator=(const V4L2CaptureDelegateGpuHelper&) = + delete; + + ~V4L2CaptureDelegateGpuHelper(); + + public: + // The `V4L2CaptureDelegate` calls and passes the member + // `V4L2CaptureDelegate::client_`. This method requests the GPU memory buffer + // by `V4L2CaptureDelegate::client_`. Then, it converts and copies the capture + // data into the GPU memory buffer with `NV12` format. At last, it notifies + // the client that data coming by calling + // `VideoCaptureDeviceClient::OnIncomingCapturedBufferExt()`. + // The |rotation| value should be 0, 90, 180, or 270. + int OnIncomingCapturedData(VideoCaptureDevice::Client* client, + const uint8_t* sample, + size_t sample_size, + const VideoCaptureFormat& format, + const gfx::ColorSpace& data_color_space, + int rotation, + base::TimeTicks reference_time, + base::TimeDelta timestamp, + int frame_feedback_id = 0); + + private: + int ConvertCaptureDataToNV12(const uint8_t* sample, + size_t sample_size, + const VideoCaptureFormat& format, + const gfx::Size& dimensions, + const gfx::ColorSpace& data_color_space, + int rotation, + uint8_t* dst_y, + uint8_t* dst_uv, + int dst_stride_y, + int dst_stride_uv); + + // This method directly converts the sample data into `NV12` format when the + // input `VideoCaptureFormat` supported. + int FastConvertToNV12(const uint8_t* sample, + size_t sample_size, + const VideoCaptureFormat& format, + uint8_t* dst_y, + uint8_t* dst_uv, + int dst_stride_y, + int dst_stride_uv); + + bool IsNV12ConvertSupported(uint32_t fourcc); + + std::unique_ptr<gpu::GpuMemoryBufferSupport> gmb_support_; + // I420 buffer used when can't directly convert video sample data into `NV12` + // format. + std::vector<uint8_t> i420_buffer_; +}; + +} // namespace media + +#endif // !MEDIA_CAPTURE_VIDEO_LINUX_V4L2_CAPTURE_DELEGATE_GPU_HELPER_H_
diff --git a/media/capture/video/linux/v4l2_capture_delegate_gpu_helper_unittest.cc b/media/capture/video/linux/v4l2_capture_delegate_gpu_helper_unittest.cc new file mode 100644 index 0000000..1b55e094 --- /dev/null +++ b/media/capture/video/linux/v4l2_capture_delegate_gpu_helper_unittest.cc
@@ -0,0 +1,379 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +#include "media/capture/video/linux/v4l2_capture_delegate_gpu_helper.h" + +#include "base/command_line.h" +#include "base/test/bind.h" +#include "base/test/task_environment.h" +#include "media/base/test_data_util.h" +#include "media/capture/video/mock_gpu_memory_buffer_manager.h" +#include "media/video/fake_gpu_memory_buffer.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::_; +using testing::A; +using testing::AtLeast; +using testing::AtMost; +using testing::Invoke; +using testing::InvokeWithoutArgs; + +namespace media { + +namespace { + +constexpr char kMjpegFrameFile[] = "one_frame_1280x720.mjpeg"; +class MockV4l2GpuClient : public VideoCaptureDevice::Client { + public: + void OnIncomingCapturedData(const uint8_t* data, + int length, + const VideoCaptureFormat& frame_format, + const gfx::ColorSpace& color_space, + int clockwise_rotation, + bool flip_y, + base::TimeTicks reference_time, + base::TimeDelta timestamp, + int frame_feedback_id = 0) override {} + + void OnIncomingCapturedGfxBuffer(gfx::GpuMemoryBuffer* buffer, + const VideoCaptureFormat& frame_format, + int clockwise_rotation, + base::TimeTicks reference_time, + base::TimeDelta timestamp, + int frame_feedback_id = 0) override {} + + void OnIncomingCapturedExternalBuffer( + CapturedExternalVideoBuffer buffer, + std::vector<CapturedExternalVideoBuffer> scaled_buffers, + base::TimeTicks reference_time, + base::TimeDelta timestamp, + const gfx::Rect& visible_rect) override {} + + void OnCaptureConfigurationChanged() override {} + + MOCK_METHOD4(ReserveOutputBuffer, + ReserveResult(const gfx::Size&, VideoPixelFormat, int, Buffer*)); + + void OnIncomingCapturedBuffer(Buffer buffer, + const VideoCaptureFormat& format, + base::TimeTicks reference_, + base::TimeDelta timestamp) override {} + + MOCK_METHOD7(OnIncomingCapturedBufferExt, + void(Buffer, + const VideoCaptureFormat&, + const gfx::ColorSpace&, + base::TimeTicks, + base::TimeDelta, + gfx::Rect, + const VideoFrameMetadata&)); + + MOCK_METHOD3(OnError, + void(VideoCaptureError, + const base::Location&, + const std::string&)); + + MOCK_METHOD1(OnFrameDropped, void(VideoCaptureFrameDropReason)); + + double GetBufferPoolUtilization() const override { return 0.0; } + + void OnStarted() override {} +}; + +class MockCaptureHandleProvider + : public VideoCaptureDevice::Client::Buffer::HandleProvider { + public: + MockCaptureHandleProvider(const gfx::Size& size, gfx::BufferFormat format) { + gmb_ = std::make_unique<FakeGpuMemoryBuffer>(size, format); + } + // Duplicate as an writable (unsafe) shared memory region. + base::UnsafeSharedMemoryRegion DuplicateAsUnsafeRegion() override { + return base::UnsafeSharedMemoryRegion(); + } + + // Access a |VideoCaptureBufferHandle| for local, writable memory. + std::unique_ptr<VideoCaptureBufferHandle> GetHandleForInProcessAccess() + override { + return nullptr; + } + + // Clone a |GpuMemoryBufferHandle| for IPC. + gfx::GpuMemoryBufferHandle GetGpuMemoryBufferHandle() override { + gfx::GpuMemoryBufferHandle handle; + return gmb_->CloneHandle(); + } + std::unique_ptr<FakeGpuMemoryBuffer> gmb_; +}; + +class InvalidGpuMemoryBufferSupport : public gpu::GpuMemoryBufferSupport { + public: + std::unique_ptr<gpu::GpuMemoryBufferImpl> CreateGpuMemoryBufferImplFromHandle( + gfx::GpuMemoryBufferHandle handle, + const gfx::Size& size, + gfx::BufferFormat format, + gfx::BufferUsage usage, + gpu::GpuMemoryBufferImpl::DestructionCallback callback, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager = nullptr, + scoped_refptr<base::UnsafeSharedMemoryPool> pool = nullptr, + base::span<uint8_t> premapped_memory = base::span<uint8_t>()) override { + return nullptr; + } +}; +} // namespace + +class V4l2CaptureDelegateGpuHelperTest + : public ::testing::TestWithParam<VideoCaptureFormat> { + public: + V4l2CaptureDelegateGpuHelperTest() {} + ~V4l2CaptureDelegateGpuHelperTest() override = default; + + public: + void SetUp() override {} + + void TearDown() override { task_environment_.RunUntilIdle(); } + + void SetUpWithFakeGpuMemoryBufferSupport() { + std::unique_ptr<FakeGpuMemoryBufferSupport> gbm_support = + std::make_unique<FakeGpuMemoryBufferSupport>(); + v4l2_gpu_helper_ = + std::make_unique<V4L2CaptureDelegateGpuHelper>(std::move(gbm_support)); + } + void SetUpWithInvalidGpuMemoryBufferSupport() { + std::unique_ptr<InvalidGpuMemoryBufferSupport> gbm_support = + std::make_unique<InvalidGpuMemoryBufferSupport>(); + v4l2_gpu_helper_ = + std::make_unique<V4L2CaptureDelegateGpuHelper>(std::move(gbm_support)); + } + + std::unique_ptr<std::vector<uint8_t>> ReadSampleData( + VideoCaptureFormat format) { + std::unique_ptr<std::vector<uint8_t>> sample = + std::make_unique<std::vector<uint8_t>>(); + if (format.pixel_format == VideoPixelFormat::PIXEL_FORMAT_MJPEG) { + auto file_path = media::GetTestDataFilePath(kMjpegFrameFile); + if (!file_path.empty()) { + FILE* fp = fopen(file_path.value().c_str(), "rb"); + if (fp) { + fseek(fp, 0, SEEK_END); + size_t size = ftell(fp); + sample->resize(size); + fseek(fp, 0, SEEK_SET); + size_t read_size = fread(sample->data(), 1, size, fp); + EXPECT_EQ(size, read_size); + fclose(fp); + } + } + } else { + auto size = + VideoFrame::AllocationSize(format.pixel_format, format.frame_size); + sample->resize(size); + } + return sample; + } + + protected: + base::test::TaskEnvironment task_environment_; + std::unique_ptr<V4L2CaptureDelegateGpuHelper> v4l2_gpu_helper_; +}; + +TEST_F(V4l2CaptureDelegateGpuHelperTest, FailureAsInvalidClient) { + SetUpWithFakeGpuMemoryBufferSupport(); + constexpr int kRotation = 0; + const base::TimeTicks reference_time = base::TimeTicks::Now(); + const base::TimeDelta timestamp = reference_time - reference_time; + const VideoCaptureFormat capture_format = VideoCaptureFormat( + gfx::Size(1280, 720), 30.0f, VideoPixelFormat::PIXEL_FORMAT_YUY2); + std::unique_ptr<std::vector<uint8_t>> sample = ReadSampleData(capture_format); + + int status = v4l2_gpu_helper_->OnIncomingCapturedData( + nullptr, sample->data(), sample->size(), capture_format, + gfx::ColorSpace(), kRotation, reference_time, timestamp); + EXPECT_NE(status, 0); +} + +TEST_F(V4l2CaptureDelegateGpuHelperTest, + FailureAsInvalidMJPEGCaptureSampleData) { + SetUpWithFakeGpuMemoryBufferSupport(); + constexpr int kRotation = 0; + const base::TimeTicks reference_time = base::TimeTicks::Now(); + const base::TimeDelta timestamp = reference_time - reference_time; + const VideoCaptureFormat capture_format = VideoCaptureFormat( + gfx::Size(1280, 720), 30.0f, VideoPixelFormat::PIXEL_FORMAT_MJPEG); + std::unique_ptr<std::vector<uint8_t>> sample = ReadSampleData(capture_format); + MockV4l2GpuClient client; + + if (sample) { + // corrupt the sample data + uint8_t* data = sample->data(); + for (size_t i = 0; i < 0xff && i < sample->size(); i++) { + data[i] = 0xff; + } + } + + EXPECT_CALL(client, ReserveOutputBuffer(_, _, _, _)) + .WillRepeatedly( + Invoke([](const gfx::Size& size, VideoPixelFormat pixel_format, + int feedback_id, + VideoCaptureDevice::Client::Buffer* capture_buffer) { + EXPECT_EQ(pixel_format, PIXEL_FORMAT_NV12); + capture_buffer->handle_provider = + std::make_unique<MockCaptureHandleProvider>( + size, gfx::BufferFormat::YUV_420_BIPLANAR); + return VideoCaptureDevice::Client::ReserveResult::kSucceeded; + })); + EXPECT_CALL(client, OnFrameDropped(_)) + .WillRepeatedly(Invoke([](VideoCaptureFrameDropReason reason) { + EXPECT_EQ(reason, VideoCaptureFrameDropReason::kNone); + })); + + int status = v4l2_gpu_helper_->OnIncomingCapturedData( + &client, sample->data(), sample->size(), capture_format, + gfx::ColorSpace(), kRotation, reference_time, timestamp); + EXPECT_NE(status, 0); +} + +TEST_F(V4l2CaptureDelegateGpuHelperTest, FailureAsReserveOutputBufferErr) { + SetUpWithFakeGpuMemoryBufferSupport(); + constexpr int kRotation = 0; + const base::TimeTicks reference_time = base::TimeTicks::Now(); + const base::TimeDelta timestamp = reference_time - reference_time; + const VideoCaptureFormat capture_format = VideoCaptureFormat( + gfx::Size(1280, 720), 30.0f, VideoPixelFormat::PIXEL_FORMAT_YUY2); + std::unique_ptr<std::vector<uint8_t>> sample = ReadSampleData(capture_format); + MockV4l2GpuClient client; + + EXPECT_CALL(client, ReserveOutputBuffer(_, _, _, _)) + .WillRepeatedly( + Invoke([](const gfx::Size& size, VideoPixelFormat pixel_format, + int feedback_id, + VideoCaptureDevice::Client::Buffer* capture_buffer) { + return VideoCaptureDevice::Client::ReserveResult::kAllocationFailed; + })); + EXPECT_CALL(client, OnFrameDropped(_)) + .WillRepeatedly(Invoke([](VideoCaptureFrameDropReason reason) { + EXPECT_EQ( + reason, + VideoCaptureFrameDropReason::kBufferPoolBufferAllocationFailed); + })); + + int status = v4l2_gpu_helper_->OnIncomingCapturedData( + &client, sample->data(), sample->size(), capture_format, + gfx::ColorSpace(), kRotation, reference_time, timestamp); + EXPECT_NE(status, 0); +} + +TEST_F(V4l2CaptureDelegateGpuHelperTest, + FailureAsInvalidCreateGpuMemoryBuffer) { + SetUpWithInvalidGpuMemoryBufferSupport(); + constexpr int kRotation = 0; + const base::TimeTicks reference_time = base::TimeTicks::Now(); + const base::TimeDelta timestamp = reference_time - reference_time; + const VideoCaptureFormat capture_format = VideoCaptureFormat( + gfx::Size(1280, 720), 30.0f, VideoPixelFormat::PIXEL_FORMAT_YUY2); + std::unique_ptr<std::vector<uint8_t>> sample = ReadSampleData(capture_format); + MockV4l2GpuClient client; + + EXPECT_CALL(client, ReserveOutputBuffer(_, _, _, _)) + .WillRepeatedly( + Invoke([](const gfx::Size& size, VideoPixelFormat pixel_format, + int feedback_id, + VideoCaptureDevice::Client::Buffer* capture_buffer) { + EXPECT_EQ(pixel_format, PIXEL_FORMAT_NV12); + capture_buffer->handle_provider = + std::make_unique<MockCaptureHandleProvider>( + size, gfx::BufferFormat::YUV_420_BIPLANAR); + return VideoCaptureDevice::Client::ReserveResult::kSucceeded; + })); + EXPECT_CALL(client, OnFrameDropped(_)) + .WillRepeatedly(Invoke([](VideoCaptureFrameDropReason reason) { + EXPECT_EQ( + reason, + VideoCaptureFrameDropReason::kBufferPoolBufferAllocationFailed); + })); + + int status = v4l2_gpu_helper_->OnIncomingCapturedData( + &client, sample->data(), sample->size(), capture_format, + gfx::ColorSpace(), kRotation, reference_time, timestamp); + EXPECT_NE(status, 0); +} + +TEST_F(V4l2CaptureDelegateGpuHelperTest, SuccessRotationIsNotZero) { + SetUpWithFakeGpuMemoryBufferSupport(); + constexpr int kRotation = 180; + const base::TimeTicks reference_time = base::TimeTicks::Now(); + const base::TimeDelta timestamp = reference_time - reference_time; + const VideoCaptureFormat capture_format = VideoCaptureFormat( + gfx::Size(1280, 720), 30.0f, VideoPixelFormat::PIXEL_FORMAT_YUY2); + std::unique_ptr<std::vector<uint8_t>> sample = ReadSampleData(capture_format); + MockV4l2GpuClient client; + + EXPECT_CALL(client, ReserveOutputBuffer(_, _, _, _)) + .WillRepeatedly( + Invoke([](const gfx::Size& size, VideoPixelFormat pixel_format, + int feedback_id, + VideoCaptureDevice::Client::Buffer* capture_buffer) { + EXPECT_EQ(pixel_format, PIXEL_FORMAT_NV12); + capture_buffer->handle_provider = + std::make_unique<MockCaptureHandleProvider>( + size, gfx::BufferFormat::YUV_420_BIPLANAR); + return VideoCaptureDevice::Client::ReserveResult::kSucceeded; + })); + EXPECT_CALL(client, OnIncomingCapturedBufferExt(_, _, _, _, _, _, _)) + .WillRepeatedly(InvokeWithoutArgs([]() {})); + + int status = v4l2_gpu_helper_->OnIncomingCapturedData( + &client, sample->data(), sample->size(), capture_format, + gfx::ColorSpace(), kRotation, reference_time, timestamp); + + EXPECT_EQ(status, 0); +} + +TEST_P(V4l2CaptureDelegateGpuHelperTest, SuccessConvertWithCaptureParam) { + SetUpWithFakeGpuMemoryBufferSupport(); + constexpr int kRotation = 0; + const base::TimeTicks reference_time = base::TimeTicks::Now(); + const base::TimeDelta timestamp = reference_time - reference_time; + const VideoCaptureFormat& capture_format = GetParam(); + const std::unique_ptr<std::vector<uint8_t>> sample = + ReadSampleData(capture_format); + MockV4l2GpuClient client; + + EXPECT_CALL(client, ReserveOutputBuffer(_, _, _, _)) + .WillRepeatedly( + Invoke([](const gfx::Size& size, VideoPixelFormat pixel_format, + int feedback_id, + VideoCaptureDevice::Client::Buffer* capture_buffer) { + EXPECT_EQ(pixel_format, PIXEL_FORMAT_NV12); + capture_buffer->handle_provider = + std::make_unique<MockCaptureHandleProvider>( + size, gfx::BufferFormat::YUV_420_BIPLANAR); + return VideoCaptureDevice::Client::ReserveResult::kSucceeded; + })); + EXPECT_CALL(client, OnIncomingCapturedBufferExt(_, _, _, _, _, _, _)) + .WillRepeatedly(InvokeWithoutArgs([]() {})); + + int status = v4l2_gpu_helper_->OnIncomingCapturedData( + &client, sample->data(), sample->size(), capture_format, + gfx::ColorSpace(), kRotation, reference_time, timestamp); + EXPECT_EQ(status, 0); +} + +INSTANTIATE_TEST_SUITE_P( + All, + V4l2CaptureDelegateGpuHelperTest, + ::testing::Values( + VideoCaptureFormat(gfx::Size(1280, 720), + 30.0f, + VideoPixelFormat::PIXEL_FORMAT_NV12), + VideoCaptureFormat(gfx::Size(1280, 720), + 30.0f, + VideoPixelFormat::PIXEL_FORMAT_YUY2), + VideoCaptureFormat(gfx::Size(1280, 720), + 30.0f, + VideoPixelFormat::PIXEL_FORMAT_MJPEG), + VideoCaptureFormat(gfx::Size(1280, 720), + 30.0f, + VideoPixelFormat::PIXEL_FORMAT_RGB24))); + +} // namespace media
diff --git a/media/gpu/DEPS b/media/gpu/DEPS index 2a7e6a79c..427823a 100644 --- a/media/gpu/DEPS +++ b/media/gpu/DEPS
@@ -18,7 +18,6 @@ "-media/base/media_export.h", # SharedImageVideo uses it. - "+components/viz/common/resources/resource_format_utils.h", "+components/viz/common/resources/resource_sizes.h", # Chrome OS specific JEA/MJDA.
diff --git a/media/gpu/ipc/service/picture_buffer_manager.cc b/media/gpu/ipc/service/picture_buffer_manager.cc index 1908729f..2dd84ca 100644 --- a/media/gpu/ipc/service/picture_buffer_manager.cc +++ b/media/gpu/ipc/service/picture_buffer_manager.cc
@@ -14,7 +14,6 @@ #include "base/synchronization/lock.h" #include "base/task/single_thread_task_runner.h" #include "base/thread_annotations.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "gpu/command_buffer/common/mailbox_holder.h" #include "ui/gfx/gpu_memory_buffer.h"
diff --git a/media/gpu/test/raw_video.cc b/media/gpu/test/raw_video.cc index a85a72b..7730d8a0 100644 --- a/media/gpu/test/raw_video.cc +++ b/media/gpu/test/raw_video.cc
@@ -15,6 +15,7 @@ #include "base/synchronization/waitable_event.h" #include "base/threading/thread.h" #include "media/base/media.h" +#include "media/base/media_serializers.h" #include "media/base/video_decoder_config.h" #include "media/base/video_frame.h" #include "media/base/video_types.h" @@ -56,154 +57,6 @@ return success ? std::move(mmapped_file) : nullptr; } -void DecodeVP9Task(base::span<const uint8_t> data, - const gfx::Size& resolution, - const size_t num_frames, - const size_t video_frame_size, - uint8_t* dst_buffer, - bool* success, - base::WaitableEvent* done) { - *success = false; - InitializeMediaLibrary(); - - // Initialize ffmpeg with the compressed video data. - InMemoryUrlProtocol protocol(&data[0], data.size(), false); - FFmpegGlue glue(&protocol); - ASSERT_TRUE(glue.OpenContext()); - - // Find the first VP9 stream in the file. - int stream_index = -1; - VideoDecoderConfig config; - for (size_t i = 0; i < glue.format_context()->nb_streams; ++i) { - AVStream* stream = glue.format_context()->streams[i]; - const AVCodecParameters* codec_parameters = stream->codecpar; - const AVMediaType codec_type = codec_parameters->codec_type; - const AVCodecID codec_id = codec_parameters->codec_id; - if (codec_type == AVMEDIA_TYPE_VIDEO && codec_id == AV_CODEC_ID_VP9) { - *success = AVStreamToVideoDecoderConfig(stream, &config) && - config.IsValidConfig(); - stream_index = i; - break; - } - } - if (!*success) { - done->Signal(); - return; - } - - auto on_frame_decoded = [](const gfx::Size& resolution, - const size_t video_frame_size, - uint8_t* const dst_buffer, - size_t* decode_frame_count, - scoped_refptr<VideoFrame> frame) { - ASSERT_EQ(frame->format(), VideoPixelFormat::PIXEL_FORMAT_I420); - size_t num_planes = VideoFrame::NumPlanes(frame->format()); - uint8_t* dst_plane = dst_buffer + video_frame_size * (*decode_frame_count); - // Copy the resolution area. - for (size_t plane = 0; plane < num_planes; ++plane) { - const int stride = frame->stride(plane); - const int rows = - VideoFrame::Rows(plane, frame->format(), resolution.height()); - const int row_bytes = - VideoFrame::RowBytes(plane, frame->format(), resolution.width()); - // VideoFrame::PlaneSize() cannot be used because it computes the - // plane size with resolutions aligned by two while our test code - // works with a succinct buffer size. - const uint8_t* src = frame->data(plane); - libyuv::CopyPlane(src, stride, dst_plane, row_bytes, row_bytes, rows); - dst_plane += (rows * row_bytes); - } - *decode_frame_count += 1; - }; - - size_t decode_frame_count = 0; - // Setup the VP9 decoder. - DecoderStatus init_result; - VpxVideoDecoder decoder( - media::OffloadableVideoDecoder::OffloadState::kOffloaded); - media::VideoDecoder::InitCB init_cb = - base::BindOnce([](DecoderStatus* save_to, - DecoderStatus save_from) { *save_to = save_from; }, - &init_result); - decoder.Initialize( - config, false, nullptr, std::move(init_cb), - base::BindRepeating(on_frame_decoded, resolution, video_frame_size, - dst_buffer, &decode_frame_count), - base::NullCallback()); - if (!init_result.is_ok()) { - done->Signal(); - return; - } - - // Start decoding and wait until all frames are ready. - AVPacket packet = {}; - size_t num_decoded_frames = 0; - while (av_read_frame(glue.format_context(), &packet) >= 0 && - num_decoded_frames < num_frames) { - if (packet.stream_index == stream_index) { - media::VideoDecoder::DecodeCB decode_cb = base::BindOnce( - [](bool* success, DecoderStatus status) { - *success = (status.is_ok()); - }, - success); - decoder.Decode(DecoderBuffer::CopyFrom(packet.data, packet.size), - std::move(decode_cb)); - if (!*success) { - break; - } - num_decoded_frames++; - } - av_packet_unref(&packet); - } - - done->Signal(); -} - -// Decode the vp9 data and returns the raw I420 data. Returns empty vector on -// fatal. -std::unique_ptr<base::MemoryMappedFile> DecodeAndLoadVP9Data( - const base::FilePath& data_file_path, - const gfx::Size& resolution, - size_t video_frame_size, - size_t num_read_frames) { - base::MemoryMappedFile compressed_data_mmap_file; - if (!compressed_data_mmap_file.Initialize( - data_file_path, base::MemoryMappedFile::READ_ONLY)) { - LOG(ERROR) << "Failed to read file: " << data_file_path; - return nullptr; - } - base::span<const uint8_t> compressed_data(compressed_data_mmap_file.data(), - compressed_data_mmap_file.length()); - - auto decompressed_data_mmap_file = - CreateMemoryMappedFile(video_frame_size * num_read_frames); - if (!decompressed_data_mmap_file) { - LOG(ERROR) << "Failed to create memory mapped file for decompressed data"; - return nullptr; - } - // The VpxVideoDecoder requires running on a SequencedTaskRunner, so we - // can't decode the video on the main test thread. - base::Thread decode_thread("DecodeThread"); - if (!decode_thread.Start()) { - LOG(ERROR) << "Failed to start decode thread"; - return nullptr; - } - - bool success = false; - base::WaitableEvent done; - decode_thread.task_runner()->PostTask( - FROM_HERE, - base::BindOnce(&DecodeVP9Task, compressed_data, resolution, - num_read_frames, video_frame_size, - decompressed_data_mmap_file->data(), &success, &done)); - done.Wait(); - decode_thread.Stop(); - if (!success) { - return nullptr; - } - return decompressed_data_mmap_file; -} - std::unique_ptr<base::MemoryMappedFile> LoadRawData( const base::FilePath& data_file_path, size_t video_frame_size, @@ -222,6 +75,208 @@ } } // namespace +class VP9Decoder { + public: + static std::unique_ptr<VP9Decoder> Create( + const base::FilePath& vp9_webm_data_file_path, + const VideoFrameLayout& layout, + size_t num_read_frames); + + std::vector<uint8_t> DecodeNextFrame() { + // If this is the first decode, then starts the thread. + if (!decoder_thread_.IsRunning()) { + LOG_IF(FATAL, !decoder_thread_.Start()) + << "Failed to start decoder thread"; + DecoderStatus result; + base::WaitableEvent event; + // base::Unretained(this) is safe because this is blocking call. + decoder_thread_.task_runner()->PostTask( + FROM_HERE, base::BindOnce(&VP9Decoder::InitializeTask, + base::Unretained(this), &result, &event)); + event.Wait(); + LOG_ASSERT(result.is_ok()) + << "Failed to initialize VpxVideoDecoder: " << MediaSerialize(result) + << "with config=" << config_.AsHumanReadableString(); + } + + std::vector<uint8_t> decoded_frame_buffer; + base::WaitableEvent done; + decoder_thread_.task_runner()->PostTask( + FROM_HERE, + base::BindOnce(&VP9Decoder::DecodeNextFrameTask, base::Unretained(this), + &decoded_frame_buffer, &done)); + done.Wait(); + CHECK(!decoded_frame_buffer.empty()); + return decoded_frame_buffer; + } + + ~VP9Decoder() { + if (decoder_thread_.IsRunning()) { + decoder_thread_.task_runner()->DeleteSoon(FROM_HERE, + std::move(vpx_decoder_)); + } + } + + private: + VP9Decoder(std::unique_ptr<base::MemoryMappedFile> vp9_data_mmap_file, + const std::vector<base::span<const uint8_t>>& vp9_data_chunks, + const VideoDecoderConfig& config, + const VideoFrameLayout& layout) + : vp9_data_mmap_file_(std::move(vp9_data_mmap_file)), + config_(config), + layout_(layout), + decoder_thread_("VP9DecoderThread"), + vp9_data_chunks_(vp9_data_chunks) { + DETACH_FROM_SEQUENCE(decoder_sequence_); + } + + void OnFrameDecoded(scoped_refptr<VideoFrame> frame) { + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_); + last_decoded_frame_ = std::move(frame); + } + + void InitializeTask(DecoderStatus* result, base::WaitableEvent* event) { + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_); + vpx_decoder_ = std::make_unique<VpxVideoDecoder>( + OffloadableVideoDecoder::OffloadState::kOffloaded); + vpx_decoder_->Initialize( + config_, + /*low_delay*/ false, + /*CdmContext*/ nullptr, + base::BindOnce([](DecoderStatus* save_to, + DecoderStatus save_from) { *save_to = save_from; }, + result), + // base::Unretained(this) is safe because |vpx_decoder_| is owned by + // this. + base::BindRepeating(&VP9Decoder::OnFrameDecoded, + base::Unretained(this)), + /*waiting_cb=*/base::NullCallback()); + event->Signal(); + } + + void DecodeNextFrameTask(std::vector<uint8_t>* decoded_frame_buffer, + base::WaitableEvent* done) { + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_); + CHECK_LT(next_frame_index_, vp9_data_chunks_.size()); + base::span<const uint8_t> chunk = vp9_data_chunks_[next_frame_index_]; + DecoderStatus decode_status{DecoderStatus::Codes::kOk}; + vpx_decoder_->Decode( + DecoderBuffer::CopyFrom(chunk.data(), chunk.size()), + base::BindOnce([](DecoderStatus* out_status, + DecoderStatus status) { *out_status = status; }, + &decode_status)); + LOG_ASSERT(decode_status.is_ok()) + << "Failed to decode the " << next_frame_index_ + << "-th vp9 chunk: " << MediaSerialize(decode_status); + LOG_ASSERT(!!last_decoded_frame_) << "|last_decoded_frame_| is not filled"; + *decoded_frame_buffer = CreateBufferFromFrame(*last_decoded_frame_); + last_decoded_frame_.reset(); + next_frame_index_++; + done->Signal(); + } + + std::vector<uint8_t> CreateBufferFromFrame( + const VideoFrame& i420_frame) const { + LOG_ASSERT(i420_frame.format() == VideoPixelFormat::PIXEL_FORMAT_I420); + std::vector<uint8_t> buffer; + buffer.resize(layout_.planes()[2].offset + layout_.planes()[2].size); + // Copy the resolution area. + uint8_t* dst_plane = buffer.data(); + for (size_t plane = 0; plane < 3; ++plane) { + const int stride = i420_frame.stride(plane); + const int rows = VideoFrame::Rows(plane, i420_frame.format(), + layout_.coded_size().height()); + const int row_bytes = VideoFrame::RowBytes(plane, i420_frame.format(), + layout_.coded_size().width()); + // VideoFrame::PlaneSize() cannot be used because it computes the + // plane size with resolutions aligned by two while our test code + // works with a succinct buffer size. + const uint8_t* src = i420_frame.data(plane); + libyuv::CopyPlane(src, stride, dst_plane, row_bytes, row_bytes, rows); + dst_plane += (rows * row_bytes); + } + return buffer; + } + + const std::unique_ptr<base::MemoryMappedFile> vp9_data_mmap_file_; + const VideoDecoderConfig config_; + const VideoFrameLayout layout_; + + base::Thread decoder_thread_; + const std::vector<base::span<const uint8_t>> vp9_data_chunks_ + GUARDED_BY_CONTEXT(decoder_sequence_); + std::unique_ptr<VpxVideoDecoder> vpx_decoder_ + GUARDED_BY_CONTEXT(decoder_sequence_); + size_t next_frame_index_ GUARDED_BY_CONTEXT(decoder_sequence_){0}; + scoped_refptr<VideoFrame> last_decoded_frame_ + GUARDED_BY_CONTEXT(decoder_sequence_); + SEQUENCE_CHECKER(decoder_sequence_); +}; + +// static +std::unique_ptr<VP9Decoder> VP9Decoder::Create( + const base::FilePath& vp9_webm_data_file_path, + const VideoFrameLayout& layout, + size_t num_read_frames) { + base::MemoryMappedFile vp9_webm_data_mmap_file; + if (!vp9_webm_data_mmap_file.Initialize(vp9_webm_data_file_path, + base::MemoryMappedFile::READ_ONLY)) { + LOG(ERROR) << "Failed to read file: " << vp9_webm_data_file_path; + return nullptr; + } + base::span<const uint8_t> vp9_webm_data(vp9_webm_data_mmap_file.data(), + vp9_webm_data_mmap_file.length()); + + InitializeMediaLibrary(); + + // Initialize ffmpeg with the compressed video data. + InMemoryUrlProtocol protocol(vp9_webm_data.data(), vp9_webm_data.size(), + /*streaming=*/false); + FFmpegGlue glue(&protocol); + LOG_ASSERT(glue.OpenContext()) << "Failed to open AVFormatContext"; + // Find the first VP9 stream in the file. + absl::optional<size_t> vp9_stream_index; + VideoDecoderConfig config; + for (size_t i = 0; i < glue.format_context()->nb_streams; ++i) { + AVStream* stream = glue.format_context()->streams[i]; + const AVCodecParameters* codec_parameters = stream->codecpar; + const AVMediaType codec_type = codec_parameters->codec_type; + const AVCodecID codec_id = codec_parameters->codec_id; + if (codec_type == AVMEDIA_TYPE_VIDEO && codec_id == AV_CODEC_ID_VP9 && + AVStreamToVideoDecoderConfig(stream, &config) && + config.IsValidConfig()) { + vp9_stream_index = i; + break; + } + } + if (!vp9_stream_index) { + return nullptr; + } + + auto vp9_data_mmap_file = CreateMemoryMappedFile(vp9_webm_data.size()); + uint8_t* const vp9_data = vp9_data_mmap_file->data(); + size_t vp9_data_size = 0; + AVPacket packet = {}; + size_t num_packets = 0; + std::vector<base::span<const uint8_t>> vp9_data_chunks(num_read_frames); + while (av_read_frame(glue.format_context(), &packet) >= 0 && + num_packets < num_read_frames) { + if (base::checked_cast<size_t>(packet.stream_index) == + (*vp9_stream_index)) { + LOG_ASSERT(vp9_data_size + packet.size <= vp9_data_mmap_file->length()) + << "The vp9 data size must be less than webm file size"; + std::memcpy(vp9_data + vp9_data_size, packet.data, packet.size); + vp9_data_chunks[num_packets] = base::span<const uint8_t>( + vp9_data + vp9_data_size, base::checked_cast<size_t>(packet.size)); + vp9_data_size += packet.size; + num_packets++; + } + av_packet_unref(&packet); + } + return base::WrapUnique<VP9Decoder>(new VP9Decoder( + std::move(vp9_data_mmap_file), vp9_data_chunks, config, layout)); +} + RawVideo::RawVideo(std::unique_ptr<base::MemoryMappedFile> memory_mapped_file, const Metadata& metadata, size_t video_frame_size) @@ -371,10 +426,18 @@ } std::unique_ptr<base::MemoryMappedFile> memory_mapped_file; + if (is_vp9_data) { // If the given data is compressed video (i.e. vp9 webm), then we decode. - memory_mapped_file = DecodeAndLoadVP9Data( - data_file_path, resolution, video_frame_size, metadata.num_frames); + auto vp9_decoder = VP9Decoder::Create( + data_file_path, *metadata.frame_layout, metadata.num_frames); + memory_mapped_file = + CreateMemoryMappedFile(video_frame_size * metadata.num_frames); + for (size_t i = 0; i < metadata.num_frames; ++i) { + auto buffer = vp9_decoder->DecodeNextFrame(); + memcpy(memory_mapped_file->data() + i * video_frame_size, buffer.data(), + buffer.size()); + } } else { memory_mapped_file = LoadRawData(data_file_path, video_frame_size, metadata.num_frames); @@ -390,6 +453,8 @@ std::unique_ptr<RawVideo> RawVideo::CreateNV12Video() const { LOG_ASSERT(FrameLayout().format() == PIXEL_FORMAT_I420) << "The pixel format of source video is not I420"; + LOG_ASSERT(memory_mapped_file_) << "CreateNV12Video() is supported only if " + << "|memory_mapped_file_| is valid"; auto nv12_layout = CreateVideoFrameLayout(PIXEL_FORMAT_NV12, Resolution(), 1u /* alignment*/); LOG_ASSERT(nv12_layout) << "Failed creating VideoFrameLayout";
diff --git a/media/gpu/windows/d3d11_texture_wrapper.cc b/media/gpu/windows/d3d11_texture_wrapper.cc index 7816d63c..d4c99887 100644 --- a/media/gpu/windows/d3d11_texture_wrapper.cc +++ b/media/gpu/windows/d3d11_texture_wrapper.cc
@@ -11,7 +11,6 @@ #include "base/task/bind_post_task.h" #include "base/task/single_thread_task_runner.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "gpu/command_buffer/common/constants.h" #include "gpu/command_buffer/common/shared_image_usage.h" #include "gpu/command_buffer/service/dxgi_shared_handle_manager.h"
diff --git a/media/renderers/video_frame_rgba_to_yuva_converter.cc b/media/renderers/video_frame_rgba_to_yuva_converter.cc index 882514d..d1a73054 100644 --- a/media/renderers/video_frame_rgba_to_yuva_converter.cc +++ b/media/renderers/video_frame_rgba_to_yuva_converter.cc
@@ -8,7 +8,6 @@ #include "base/memory/ptr_util.h" #include "base/memory/raw_ptr.h" #include "components/viz/common/gpu/raster_context_provider.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/shared_image_format_utils.h" #include "gpu/command_buffer/client/raster_interface.h" #include "gpu/command_buffer/client/shared_image_interface.h"
diff --git a/media/renderers/video_frame_yuv_converter.cc b/media/renderers/video_frame_yuv_converter.cc index b5a2a74..0a2dae2a 100644 --- a/media/renderers/video_frame_yuv_converter.cc +++ b/media/renderers/video_frame_yuv_converter.cc
@@ -8,7 +8,6 @@ #include "base/logging.h" #include "components/viz/common/gpu/raster_context_provider.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "gpu/command_buffer/client/raster_interface.h" #include "gpu/command_buffer/client/shared_image_interface.h" #include "gpu/command_buffer/common/shared_image_usage.h"
diff --git a/media/renderers/video_frame_yuv_mailboxes_holder.cc b/media/renderers/video_frame_yuv_mailboxes_holder.cc index dc815ee..64247e76 100644 --- a/media/renderers/video_frame_yuv_mailboxes_holder.cc +++ b/media/renderers/video_frame_yuv_mailboxes_holder.cc
@@ -8,7 +8,6 @@ #include "base/logging.h" #include "components/viz/common/gpu/raster_context_provider.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/shared_image_format.h" #include "gpu/GLES2/gl2extchromium.h" #include "gpu/command_buffer/client/raster_interface.h"
diff --git a/media/renderers/video_resource_updater.cc b/media/renderers/video_resource_updater.cc index c126ddc..93baf36 100644 --- a/media/renderers/video_resource_updater.cc +++ b/media/renderers/video_resource_updater.cc
@@ -34,7 +34,6 @@ #include "components/viz/common/quads/video_hole_draw_quad.h" #include "components/viz/common/quads/yuv_video_draw_quad.h" #include "components/viz/common/resources/bitmap_allocation.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/resource_sizes.h" #include "components/viz/common/resources/shared_image_format_utils.h" #include "gpu/GLES2/gl2extchromium.h"
diff --git a/media/test/data/README.md b/media/test/data/README.md index 6dc8c528..6aa3184a 100644 --- a/media/test/data/README.md +++ b/media/test/data/README.md
@@ -1544,3 +1544,5 @@ ffmpeg -i bear6.wav -c:a dtsxS -b:a 160000 -movflags frag_keyframe -y bear_dtsx.mp4 # truncate to size of moov box (truncate -s) ``` +### one_frame_1280x720.mjpeg +It's a single frame mjpeg data. Resolution: 1280x720, color primary: sRGB, transfer function: BT.709, color matrix: BT.601, color range: full-range.
diff --git a/media/test/data/one_frame_1280x720.mjpeg b/media/test/data/one_frame_1280x720.mjpeg new file mode 100644 index 0000000..5078353 --- /dev/null +++ b/media/test/data/one_frame_1280x720.mjpeg Binary files differ
diff --git a/media/test/media_bundle_data.filelist b/media/test/media_bundle_data.filelist index b5e8f07..0fffe6f 100644 --- a/media/test/media_bundle_data.filelist +++ b/media/test/media_bundle_data.filelist
@@ -375,6 +375,7 @@ data/noise-xhe-aac.mp4 data/nonzero-start-time.webm data/npot-video.h264 +data/one_frame_1280x720.mjpeg data/opus-trimming-test.mp4 data/opus-trimming-test.ogg data/opus-trimming-test.webm
diff --git a/media/unit_tests_bundle_data.filelist b/media/unit_tests_bundle_data.filelist index 51436ae..147a4d8 100644 --- a/media/unit_tests_bundle_data.filelist +++ b/media/unit_tests_bundle_data.filelist
@@ -387,6 +387,7 @@ //media/test/data/noise-xhe-aac.mp4 //media/test/data/nonzero-start-time.webm //media/test/data/npot-video.h264 +//media/test/data/one_frame_1280x720.mjpeg //media/test/data/opus-trimming-test.mp4 //media/test/data/opus-trimming-test.ogg //media/test/data/opus-trimming-test.webm
diff --git a/mojo/core/channel.h b/mojo/core/channel.h index 83f39d46..d7a9cb2 100644 --- a/mojo/core/channel.h +++ b/mojo/core/channel.h
@@ -491,7 +491,7 @@ class ReadBuffer; const bool is_for_ipcz_; - raw_ptr<Delegate, DanglingUntriaged> delegate_; + raw_ptr<Delegate, DanglingAcrossTasks> delegate_; HandlePolicy handle_policy_; const std::unique_ptr<ReadBuffer> read_buffer_;
diff --git a/mojo/public/cpp/bindings/lib/sequence_local_sync_event_watcher.cc b/mojo/public/cpp/bindings/lib/sequence_local_sync_event_watcher.cc index f367934..b3bac4a 100644 --- a/mojo/public/cpp/bindings/lib/sequence_local_sync_event_watcher.cc +++ b/mojo/public/cpp/bindings/lib/sequence_local_sync_event_watcher.cc
@@ -258,7 +258,7 @@ private: const base::WeakPtr<SequenceLocalState> weak_shared_state_; - const raw_ptr<SequenceLocalState, DanglingUntriaged> shared_state_; + const raw_ptr<SequenceLocalState, DanglingAcrossTasks> shared_state_; WatcherStateMap::iterator watcher_state_iterator_; const scoped_refptr<WatcherState> watcher_state_; };
diff --git a/net/http/http_cache_transaction.h b/net/http/http_cache_transaction.h index ef6a8631..e8c363c 100644 --- a/net/http/http_cache_transaction.h +++ b/net/http/http_cache_transaction.h
@@ -658,7 +658,7 @@ // |external_validation_| contains the value of those headers. ValidationHeaders external_validation_; base::WeakPtr<HttpCache> cache_; - raw_ptr<HttpCache::ActiveEntry, DanglingUntriaged> entry_ = nullptr; + raw_ptr<HttpCache::ActiveEntry, DanglingAcrossTasks> entry_ = nullptr; // This field is not a raw_ptr<> because it was filtered by the rewriter for: // #addr-of RAW_PTR_EXCLUSION HttpCache::ActiveEntry* new_entry_ = nullptr;
diff --git a/services/network/shared_dictionary/shared_dictionary_network_transaction.cc b/services/network/shared_dictionary/shared_dictionary_network_transaction.cc index 1e28a9a0..2f7b8e9 100644 --- a/services/network/shared_dictionary/shared_dictionary_network_transaction.cc +++ b/services/network/shared_dictionary/shared_dictionary_network_transaction.cc
@@ -214,7 +214,7 @@ return net::ERR_IO_PENDING; } - if (header_status_ == HeaderStatus::kUknown) { + if (header_status_ == HeaderStatus::kUnknown) { header_status_ = ContentEncodingIsSbrOnly( *network_transaction_->GetResponseInfo()->headers) ? HeaderStatus::kSharedBrotliUsed
diff --git a/services/network/shared_dictionary/shared_dictionary_network_transaction.h b/services/network/shared_dictionary/shared_dictionary_network_transaction.h index 0858244..c983089 100644 --- a/services/network/shared_dictionary/shared_dictionary_network_transaction.h +++ b/services/network/shared_dictionary/shared_dictionary_network_transaction.h
@@ -100,7 +100,7 @@ kFailed, }; enum class HeaderStatus { - kUknown, + kUnknown, kSharedBrotliUsed, kSharedBrotliNotUsed, }; @@ -134,7 +134,7 @@ origin_check_callback_; DictionaryStatus dictionary_status_ = DictionaryStatus::kNoDictionary; - HeaderStatus header_status_ = HeaderStatus::kUknown; + HeaderStatus header_status_ = HeaderStatus::kUnknown; std::unique_ptr<PendingReadTask> pending_read_task_;
diff --git a/services/viz/public/cpp/gpu/context_provider_command_buffer.cc b/services/viz/public/cpp/gpu/context_provider_command_buffer.cc index b9993aa..ad7816e 100644 --- a/services/viz/public/cpp/gpu/context_provider_command_buffer.cc +++ b/services/viz/public/cpp/gpu/context_provider_command_buffer.cc
@@ -25,7 +25,6 @@ #include "base/trace_event/memory_dump_provider.h" #include "build/build_config.h" #include "components/viz/common/gpu/context_cache_controller.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/shared_image_format_utils.h" #include "gpu/command_buffer/client/gles2_cmd_helper.h" #include "gpu/command_buffer/client/gles2_trace_implementation.h"
diff --git a/storage/browser/blob/blob_transport_strategy.h b/storage/browser/blob/blob_transport_strategy.h index e25aa6d..264e122 100644 --- a/storage/browser/blob/blob_transport_strategy.h +++ b/storage/browser/blob/blob_transport_strategy.h
@@ -51,7 +51,7 @@ BlobTransportStrategy(BlobDataBuilder* builder, ResultCallback result_callback); - raw_ptr<BlobDataBuilder, DanglingUntriaged> builder_; + raw_ptr<BlobDataBuilder, DanglingAcrossTasks> builder_; ResultCallback result_callback_; };
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 6e275b00..01c841f 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -5049,24 +5049,6 @@ ] } ], - "DownweightAutocompleteSearchResultsStudy": [ - { - "platforms": [ - "chromeos" - ], - "experiments": [ - { - "name": "EnabledWithCutoff_20221221", - "params": { - "enable_cutoff": "true" - }, - "enable_features": [ - "LauncherFuzzyMatchForOmnibox" - ] - } - ] - } - ], "EcheNetworkConnectionState": [ { "platforms": [
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl index 9ea4cfa..03804964 100644 --- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl +++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -9634,6 +9634,12 @@ parameters string bucketId + # https://wicg.github.io/attribution-reporting-api/ + experimental command setAttributionReportingLocalTestingMode + parameters + # If enabled, noise is suppressed and reports are sent immediately. + boolean enabled + # The SystemInfo domain defines methods and events for querying low-level system information. experimental domain SystemInfo
diff --git a/third_party/blink/renderer/core/css/resolver/font_builder.cc b/third_party/blink/renderer/core/css/resolver/font_builder.cc index bddbb98..0f3b7c7 100644 --- a/third_party/blink/renderer/core/css/resolver/font_builder.cc +++ b/third_party/blink/renderer/core/css/resolver/font_builder.cc
@@ -220,10 +220,9 @@ font_description_.SetFontVariantAlternates(variant_alternates); } -void FontBuilder::SetFontSmoothing(FontSmoothingMode foont_smoothing_mode) { +void FontBuilder::SetFontSmoothing(FontSmoothingMode font_smoothing_mode) { Set(PropertySetFlag::kFontSmoothing); - - font_description_.SetFontSmoothing(foont_smoothing_mode); + font_description_.SetFontSmoothing(font_smoothing_mode); } void FontBuilder::SetFeatureSettings( @@ -392,88 +391,175 @@ font_description.SetComputedSize(computed_size); } -void FontBuilder::UpdateFontDescription(FontDescription& description, +bool FontBuilder::UpdateFontDescription(FontDescription& description, FontOrientation font_orientation) { + bool modified = false; if (IsSet(PropertySetFlag::kFamily)) { - description.SetGenericFamily(font_description_.GenericFamily()); - description.SetFamily(font_description_.Family()); + if (description.GenericFamily() != font_description_.GenericFamily() || + description.Family() != font_description_.Family()) { + modified = true; + description.SetGenericFamily(font_description_.GenericFamily()); + description.SetFamily(font_description_.Family()); + } } if (IsSet(PropertySetFlag::kSize)) { - description.SetKeywordSize(font_description_.KeywordSize()); - description.SetSpecifiedSize(font_description_.SpecifiedSize()); - description.SetIsAbsoluteSize(font_description_.IsAbsoluteSize()); + if (description.KeywordSize() != font_description_.KeywordSize() || + description.SpecifiedSize() != font_description_.SpecifiedSize() || + description.IsAbsoluteSize() != font_description_.IsAbsoluteSize()) { + modified = true; + description.SetKeywordSize(font_description_.KeywordSize()); + description.SetSpecifiedSize(font_description_.SpecifiedSize()); + description.SetIsAbsoluteSize(font_description_.IsAbsoluteSize()); + } } if (IsSet(PropertySetFlag::kSizeAdjust)) { - description.SetSizeAdjust(font_description_.SizeAdjust()); + if (description.SizeAdjust() != font_description_.SizeAdjust()) { + modified = true; + description.SetSizeAdjust(font_description_.SizeAdjust()); + } } if (IsSet(PropertySetFlag::kWeight)) { - description.SetWeight(font_description_.Weight()); + if (description.Weight() != font_description_.Weight()) { + modified = true; + description.SetWeight(font_description_.Weight()); + } } if (IsSet(PropertySetFlag::kStretch)) { - description.SetStretch(font_description_.Stretch()); + if (description.Stretch() != font_description_.Stretch()) { + modified = true; + description.SetStretch(font_description_.Stretch()); + } } if (IsSet(PropertySetFlag::kFeatureSettings)) { - description.SetFeatureSettings(font_description_.FeatureSettings()); + if (description.FeatureSettings() != font_description_.FeatureSettings()) { + modified = true; + description.SetFeatureSettings(font_description_.FeatureSettings()); + } } if (IsSet(PropertySetFlag::kLocale)) { - description.SetLocale(font_description_.Locale()); + if (description.Locale() != font_description_.Locale()) { + modified = true; + description.SetLocale(font_description_.Locale()); + } } if (IsSet(PropertySetFlag::kStyle)) { - description.SetStyle(font_description_.Style()); + if (description.Style() != font_description_.Style()) { + modified = true; + description.SetStyle(font_description_.Style()); + } } if (IsSet(PropertySetFlag::kVariantCaps)) { - description.SetVariantCaps(font_description_.VariantCaps()); + if (description.VariantCaps() != font_description_.VariantCaps()) { + modified = true; + description.SetVariantCaps(font_description_.VariantCaps()); + } } if (IsSet(PropertySetFlag::kVariantEastAsian)) { - description.SetVariantEastAsian(font_description_.VariantEastAsian()); + if (description.VariantEastAsian() != + font_description_.VariantEastAsian()) { + modified = true; + description.SetVariantEastAsian(font_description_.VariantEastAsian()); + } } if (IsSet(PropertySetFlag::kVariantLigatures)) { - description.SetVariantLigatures(font_description_.GetVariantLigatures()); + if (description.GetVariantLigatures() != + font_description_.GetVariantLigatures()) { + modified = true; + description.SetVariantLigatures(font_description_.GetVariantLigatures()); + } } if (IsSet(PropertySetFlag::kVariantNumeric)) { - description.SetVariantNumeric(font_description_.VariantNumeric()); + if (description.VariantNumeric() != font_description_.VariantNumeric()) { + modified = true; + description.SetVariantNumeric(font_description_.VariantNumeric()); + } } if (IsSet(PropertySetFlag::kVariationSettings)) { - description.SetVariationSettings(font_description_.VariationSettings()); + if (description.VariationSettings() != + font_description_.VariationSettings()) { + modified = true; + description.SetVariationSettings(font_description_.VariationSettings()); + } } if (IsSet(PropertySetFlag::kFontSynthesisWeight)) { - description.SetFontSynthesisWeight( - font_description_.GetFontSynthesisWeight()); + if (description.GetFontSynthesisWeight() != + font_description_.GetFontSynthesisWeight()) { + modified = true; + description.SetFontSynthesisWeight( + font_description_.GetFontSynthesisWeight()); + } } if (IsSet(PropertySetFlag::kFontSynthesisStyle)) { - description.SetFontSynthesisStyle( - font_description_.GetFontSynthesisStyle()); + if (description.GetFontSynthesisStyle() != + font_description_.GetFontSynthesisStyle()) { + modified = true; + description.SetFontSynthesisStyle( + font_description_.GetFontSynthesisStyle()); + } } if (IsSet(PropertySetFlag::kFontSynthesisSmallCaps)) { - description.SetFontSynthesisSmallCaps( - font_description_.GetFontSynthesisSmallCaps()); + if (description.GetFontSynthesisSmallCaps() != + font_description_.GetFontSynthesisSmallCaps()) { + modified = true; + description.SetFontSynthesisSmallCaps( + font_description_.GetFontSynthesisSmallCaps()); + } } if (IsSet(PropertySetFlag::kTextRendering)) { - description.SetTextRendering(font_description_.TextRendering()); + if (description.TextRendering() != font_description_.TextRendering()) { + modified = true; + description.SetTextRendering(font_description_.TextRendering()); + } } if (IsSet(PropertySetFlag::kKerning)) { - description.SetKerning(font_description_.GetKerning()); + if (description.GetKerning() != font_description_.GetKerning()) { + modified = true; + description.SetKerning(font_description_.GetKerning()); + } } if (IsSet(PropertySetFlag::kFontOpticalSizing)) { - description.SetFontOpticalSizing(font_description_.FontOpticalSizing()); + if (description.FontOpticalSizing() != + font_description_.FontOpticalSizing()) { + modified = true; + description.SetFontOpticalSizing(font_description_.FontOpticalSizing()); + } } if (IsSet(PropertySetFlag::kFontPalette)) { - description.SetFontPalette(font_description_.GetFontPalette()); + if (description.GetFontPalette() != font_description_.GetFontPalette()) { + modified = true; + description.SetFontPalette(font_description_.GetFontPalette()); + } } if (IsSet(PropertySetFlag::kFontVariantAlternates)) { - description.SetFontVariantAlternates( - font_description_.GetFontVariantAlternates()); + if (description.GetFontVariantAlternates() != + font_description_.GetFontVariantAlternates()) { + modified = true; + description.SetFontVariantAlternates( + font_description_.GetFontVariantAlternates()); + } } if (IsSet(PropertySetFlag::kFontSmoothing)) { - description.SetFontSmoothing(font_description_.FontSmoothing()); + if (description.FontSmoothing() != font_description_.FontSmoothing()) { + modified = true; + description.SetFontSmoothing(font_description_.FontSmoothing()); + } } if (IsSet(PropertySetFlag::kTextOrientation) || IsSet(PropertySetFlag::kWritingMode)) { - description.SetOrientation(font_orientation); + if (description.Orientation() != font_orientation) { + modified = true; + description.SetOrientation(font_orientation); + } } if (IsSet(PropertySetFlag::kVariantPosition)) { - description.SetVariantPosition(font_description_.VariantPosition()); + if (description.VariantPosition() != font_description_.VariantPosition()) { + modified = true; + description.SetVariantPosition(font_description_.VariantPosition()); + } + } + if (!modified && !IsSet(PropertySetFlag::kEffectiveZoom)) { + return false; } float size = description.SpecifiedSize(); @@ -487,6 +573,7 @@ if (size && description.HasSizeAdjust()) { description.SetAdjustedSize(size); } + return true; } FontSelector* FontBuilder::FontSelectorFromTreeScope( @@ -524,7 +611,12 @@ : builder.GetFontDescription(); FontDescription description = builder.GetFontDescription(); - UpdateFontDescription(description, builder.ComputeFontOrientation()); + if (!UpdateFontDescription(description, builder.ComputeFontOrientation())) { + // Early exit; nothing was actually changed (i.e., everything that was set + // already matched the initial/parent style). + flags_ = 0; + return; + } UpdateSpecifiedSize(description, parent_description); UpdateComputedSize(description, builder);
diff --git a/third_party/blink/renderer/core/css/resolver/font_builder.h b/third_party/blink/renderer/core/css/resolver/font_builder.h index 5555ddab..8bce0915 100644 --- a/third_party/blink/renderer/core/css/resolver/font_builder.h +++ b/third_party/blink/renderer/core/css/resolver/font_builder.h
@@ -88,7 +88,9 @@ void SetVariantPosition(FontDescription::FontVariantPosition); // FIXME: These need to just vend a Font object eventually. - void UpdateFontDescription(FontDescription&, + // UpdateFontDescription() returns true if any properties were actually + // changed. + bool UpdateFontDescription(FontDescription&, FontOrientation = FontOrientation::kHorizontal); void CreateFont(ComputedStyleBuilder&, const ComputedStyle* parent_style); void CreateInitialFont(ComputedStyleBuilder&);
diff --git a/third_party/blink/renderer/core/html/track/text_track_container.cc b/third_party/blink/renderer/core/html/track/text_track_container.cc index 5540132..6ea0e8e 100644 --- a/third_party/blink/renderer/core/html/track/text_track_container.cc +++ b/third_party/blink/renderer/core/html/track/text_track_container.cc
@@ -123,9 +123,8 @@ // for lack of per-spec vh/vw support) but the whole media element is used // for cue rendering. This is inconsistent. See also the somewhat related // spec bug: https://www.w3.org/Bugs/Public/show_bug.cgi?id=28105 - LayoutSize video_size = To<LayoutBox>(media_layout_object)->ContentSize(); - LayoutUnit smallest_dimension = - std::min(video_size.Height(), video_size.Width()); + PhysicalSize video_size = To<LayoutBox>(media_layout_object)->ContentSize(); + LayoutUnit smallest_dimension = std::min(video_size.height, video_size.width); float font_size = smallest_dimension * 0.05f; if (media_layout_object->GetFrame()) font_size /= media_layout_object->GetFrame()->PageZoomFactor();
diff --git a/third_party/blink/renderer/core/layout/layout_box.h b/third_party/blink/renderer/core/layout/layout_box.h index 0afc674..50c12b2 100644 --- a/third_party/blink/renderer/core/layout/layout_box.h +++ b/third_party/blink/renderer/core/layout/layout_box.h
@@ -639,9 +639,9 @@ return (ClientHeight() - PaddingTop() - PaddingBottom()) .ClampNegativeToZero(); } - LayoutSize ContentSize() const { + PhysicalSize ContentSize() const { NOT_DESTROYED(); - return LayoutSize(ContentWidth(), ContentHeight()); + return PhysicalSize(ContentWidth(), ContentHeight()); } LayoutUnit ContentLogicalWidth() const { NOT_DESTROYED();
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 c553328..db733488 100644 --- a/third_party/blink/renderer/core/paint/box_paint_invalidator.cc +++ b/third_party/blink/renderer/core/paint/box_paint_invalidator.cc
@@ -403,7 +403,7 @@ // crbug.com/490533 if ((style.BackgroundLayers().AnyLayerUsesContentBox() || style.MaskLayers().AnyLayerUsesContentBox()) && - PhysicalSizeToBeNoop(box_.ContentSize()) != box_.Size()) { + box_.ContentSize() != box_.Size()) { return true; }
diff --git a/third_party/blink/renderer/core/resize_observer/resize_observer_entry.cc b/third_party/blink/renderer/core/resize_observer/resize_observer_entry.cc index 9fcdfb3..17fb1c4d 100644 --- a/third_party/blink/renderer/core/resize_observer/resize_observer_entry.cc +++ b/third_party/blink/renderer/core/resize_observer/resize_observer_entry.cc
@@ -40,8 +40,8 @@ void ResizeObserverEntry::PopulateFromLayoutBox(const LayoutBox& layout_box) { const ComputedStyle& style = layout_box.StyleRef(); - LayoutRect content_rect( - LayoutPoint(layout_box.PaddingLeft(), layout_box.PaddingTop()), + PhysicalRect content_rect( + PhysicalOffset(layout_box.PaddingLeft(), layout_box.PaddingTop()), layout_box.ContentSize()); content_rect_ = ResizeObserverUtilities::ZoomAdjustedLayoutRect(content_rect, style);
diff --git a/third_party/blink/renderer/core/resize_observer/resize_observer_utilities.cc b/third_party/blink/renderer/core/resize_observer/resize_observer_utilities.cc index c1696f6..7ec8d04 100644 --- a/third_party/blink/renderer/core/resize_observer/resize_observer_utilities.cc +++ b/third_party/blink/renderer/core/resize_observer/resize_observer_utilities.cc
@@ -69,7 +69,7 @@ } DOMRectReadOnly* ResizeObserverUtilities::ZoomAdjustedLayoutRect( - LayoutRect content_rect, + PhysicalRect content_rect, const ComputedStyle& style) { content_rect.SetX( AdjustForAbsoluteZoom::AdjustLayoutUnit(content_rect.X(), style));
diff --git a/third_party/blink/renderer/core/resize_observer/resize_observer_utilities.h b/third_party/blink/renderer/core/resize_observer/resize_observer_utilities.h index 8e9af44..c21a5237 100644 --- a/third_party/blink/renderer/core/resize_observer/resize_observer_utilities.h +++ b/third_party/blink/renderer/core/resize_observer/resize_observer_utilities.h
@@ -17,8 +17,8 @@ class DOMRectReadOnly; class LayoutBox; class LayoutObject; -class LayoutRect; class LayoutSize; +struct PhysicalRect; // Helper functions for ResizeObserverEntry and ResizeObservation. class ResizeObserverUtilities { @@ -38,7 +38,7 @@ const LayoutObject& layout_object, const ComputedStyle& style); - static DOMRectReadOnly* ZoomAdjustedLayoutRect(LayoutRect content_rect, + static DOMRectReadOnly* ZoomAdjustedLayoutRect(PhysicalRect content_rect, const ComputedStyle& style); };
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.cc index 7a9c010..63300ff 100644 --- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.cc +++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.cc
@@ -737,8 +737,7 @@ MLOperand* MLGraphBuilder::concat(const HeapVector<Member<MLOperand>>& inputs, const uint32_t axis, ExceptionState& exception_state) { - auto* concat = - MakeGarbageCollected<MLOperator>(this, MLOperator::OperatorKind::kConcat); + auto* concat = MakeGarbageCollected<MLConcatOperator>(this, axis); if (inputs.empty()) { exception_state.ThrowDOMException(DOMExceptionCode::kDataError, "The inputs should not be empty.");
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_xnnpack.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_xnnpack.cc index afd5073..c3d41b3 100644 --- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_xnnpack.cc +++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_xnnpack.cc
@@ -1581,27 +1581,12 @@ return xnn_status_success; } -// Helper to find the concat axis by comparing the first input shape and output -// shape which is already calculated by `MLGraphBuilder::concat()`. -absl::optional<uint32_t> GetConcatAxis(const MLOperator* concat) { - // The output tensor should has the same shape size with all the input tensors - const auto& output_dims = concat->Outputs()[0]->Dimensions(); - for (const auto& input : concat->Inputs()) { - CHECK_EQ(input->Dimensions().size(), output_dims.size()); - } - const auto& input_dims = concat->Inputs()[0]->Dimensions(); - for (wtf_size_t i = 0; i < input_dims.size(); ++i) { - if (input_dims[i] != output_dims[i]) { - return i; - } - } - return absl::nullopt; -} - xnn_status DefineXnnNodeForConcat(xnn_subgraph_t subgraph, - const MLOperator* concat, + const MLOperator* ml_operator, const OperandValueIdMap& operand_value_id_map, String& error_message) { + const MLConcatOperator* concat = + static_cast<const MLConcatOperator*>(ml_operator); const auto inputs_size = concat->Inputs().size(); Vector<uint32_t> input_ids(inputs_size); for (uint32_t i = 0; i < inputs_size; ++i) { @@ -1616,25 +1601,20 @@ xnn_define_copy(subgraph, input_ids[0], output_id, flags)); return xnn_status_success; } - absl::optional<uint32_t> axis = GetConcatAxis(concat); - if (!axis) { - error_message = "Can not find the concat axis."; - return xnn_status_unsupported_parameter; - } + const auto axis = concat->Axis(); switch (inputs_size) { case 2u: - XNN_CHECK_STATUS_AND_SET_ERROR_MESSAGE( - xnn_define_concatenate2(subgraph, axis.value(), input_ids[0], - input_ids[1], output_id, flags)); + XNN_CHECK_STATUS_AND_SET_ERROR_MESSAGE(xnn_define_concatenate2( + subgraph, axis, input_ids[0], input_ids[1], output_id, flags)); break; case 3u: - XNN_CHECK_STATUS_AND_SET_ERROR_MESSAGE(xnn_define_concatenate3( - subgraph, axis.value(), input_ids[0], input_ids[1], input_ids[2], - output_id, flags)); + XNN_CHECK_STATUS_AND_SET_ERROR_MESSAGE( + xnn_define_concatenate3(subgraph, axis, input_ids[0], input_ids[1], + input_ids[2], output_id, flags)); break; case 4u: XNN_CHECK_STATUS_AND_SET_ERROR_MESSAGE(xnn_define_concatenate4( - subgraph, axis.value(), input_ids[0], input_ids[1], input_ids[2], + subgraph, axis, input_ids[0], input_ids[1], input_ids[2], input_ids[3], output_id, flags)); break; default:
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_operator.cc b/third_party/blink/renderer/modules/ml/webnn/ml_operator.cc index 3957e087..ca74b7d4 100644 --- a/third_party/blink/renderer/modules/ml/webnn/ml_operator.cc +++ b/third_party/blink/renderer/modules/ml/webnn/ml_operator.cc
@@ -121,6 +121,16 @@ is_connected_ = true; } +MLConcatOperator::MLConcatOperator(MLGraphBuilder* builder, const uint32_t axis) + : MLOperator(builder, MLOperator::OperatorKind::kConcat, nullptr), + axis_(axis) {} + +MLConcatOperator::~MLConcatOperator() = default; + +uint32_t MLConcatOperator::Axis() const { + return axis_; +} + MLPadOperator::MLPadOperator(MLGraphBuilder* builder, const Vector<uint32_t>& beginning_padding, const Vector<uint32_t>& ending_padding,
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_operator.h b/third_party/blink/renderer/modules/ml/webnn/ml_operator.h index ab78498..d1174c5 100644 --- a/third_party/blink/renderer/modules/ml/webnn/ml_operator.h +++ b/third_party/blink/renderer/modules/ml/webnn/ml_operator.h
@@ -108,6 +108,21 @@ HeapVector<Member<const MLOperand>> outputs_; }; +class MODULES_EXPORT MLConcatOperator : public MLOperator { + public: + MLConcatOperator(MLGraphBuilder* builder, const uint32_t axis); + + MLConcatOperator(const MLConcatOperator&) = delete; + MLConcatOperator& operator=(const MLConcatOperator&) = delete; + + ~MLConcatOperator(); + + uint32_t Axis() const; + + private: + uint32_t axis_; +}; + class MODULES_EXPORT MLPadOperator : public MLOperator { public: MLPadOperator(MLGraphBuilder* builder,
diff --git a/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc b/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc index 8555485..e10c9982 100644 --- a/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc +++ b/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc
@@ -9,7 +9,6 @@ #include "base/task/single_thread_task_runner.h" #include "components/viz/common/resources/release_callback.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/shared_image_format_utils.h" #include "gpu/GLES2/gl2extchromium.h" #include "gpu/command_buffer/client/gles2_interface.h"
diff --git a/third_party/blink/renderer/platform/graphics/canvas_color_params.cc b/third_party/blink/renderer/platform/graphics/canvas_color_params.cc index 318005b6..6892376 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_color_params.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_color_params.cc
@@ -5,7 +5,6 @@ #include "third_party/blink/renderer/platform/graphics/canvas_color_params.h" #include "cc/paint/skia_paint_canvas.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/khronos/GLES2/gl2.h" #include "third_party/khronos/GLES2/gl2ext.h"
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource.cc b/third_party/blink/renderer/platform/graphics/canvas_resource.cc index 9612482..3647799 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_resource.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_resource.cc
@@ -12,7 +12,6 @@ #include "base/trace_event/trace_event.h" #include "build/build_config.h" #include "components/viz/common/resources/bitmap_allocation.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/shared_image_format.h" #include "components/viz/common/resources/shared_image_format_utils.h" #include "components/viz/common/resources/transferable_resource.h"
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc index 1f004d7..f4c2de6 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc
@@ -19,7 +19,6 @@ #include "cc/paint/decode_stashing_image_provider.h" #include "cc/paint/display_item_list.h" #include "cc/tiles/software_image_decode_cache.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/shared_image_format_utils.h" #include "gpu/GLES2/gl2extchromium.h" #include "gpu/command_buffer/client/raster_interface.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 3d05cf4..9dbda9a 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
@@ -8,7 +8,6 @@ #include "cc/layers/texture_layer.h" #include "cc/resources/cross_thread_shared_bitmap.h" #include "components/viz/common/resources/bitmap_allocation.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/shared_bitmap.h" #include "components/viz/common/resources/shared_image_format_utils.h" #include "components/viz/common/resources/transferable_resource.h"
diff --git a/third_party/blink/web_tests/SlowTests b/third_party/blink/web_tests/SlowTests index 786d48d..4cc4d6a 100644 --- a/third_party/blink/web_tests/SlowTests +++ b/third_party/blink/web_tests/SlowTests
@@ -884,7 +884,6 @@ crbug.com/1091716 [ Mac12 ] svg/as-object/sizing/svg-in-object-placeholder-percentage-percentage-no-intrinsic-ratio.html [ Slow ] crbug.com/1091716 [ Release Win ] svg/as-object/sizing/svg-in-object-placeholder-percentage-percentage-no-intrinsic-ratio.html [ Slow ] crbug.com/1233743 [ Linux ] svg/filters/feDisplacementMap.svg [ Slow ] -crbug.com/1233743 [ Mac12 ] svg/filters/feDisplacementMap.svg [ Slow ] crbug.com/1233743 [ Release Win ] svg/filters/feDisplacementMap.svg [ Slow ] crbug.com/1043669 [ Mac Release ] inspector-protocol/emulation/set-vision-deficiency.js [ Slow ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 7553b24..f8978e2 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -212,8 +212,6 @@ # --- Skia roll test suppressions # --- END Skia roll test suppresions -# Sheriff on 2020-09-03 -crbug.com/1124352 media/picture-in-picture/controls/picture-in-picture-button.html [ Crash Pass ] # These fail due to subtle anti-aliasing differences cause by the fact that # <canvas> renders via IOSurface and OffscreenCanvas does not. @@ -1310,7 +1308,6 @@ crbug.com/1377794 [ Win ] external/wpt/css/css-fonts/font-variant-emoji-1.html [ Failure ] crbug.com/1377794 [ Mac ] external/wpt/css/css-fonts/font-variant-emoji-2.html [ Failure ] crbug.com/1375884 external/wpt/css/css-fonts/rlh-in-monospace.html [ Failure ] -crbug.com/1456655 external/wpt/css/css-fonts/format-specifiers-variations.html [ Failure ] crbug.com/1317062 external/wpt/html/rendering/non-replaced-elements/phrasing-content-0/br-wbr-content/content-property.tentative.html [ Failure ] @@ -1825,7 +1822,6 @@ crbug.com/821455 editing/pasteboard/drag-files-to-editable-element.html [ Failure ] -crbug.com/1170052 external/wpt/mediacapture-streams/MediaStreamTrack-MediaElement-disabled-audio-is-silence.https.html [ Pass Timeout ] crbug.com/1174937 external/wpt/mediacapture-streams/MediaStream-clone.https.html [ Crash ] @@ -3194,7 +3190,10 @@ crbug.com/626703 external/wpt/input-events/input-events-get-target-ranges-joining-dl-element-and-another-list.tentative.html?Delete [ Failure Timeout ] crbug.com/626703 external/wpt/input-events/input-events-get-target-ranges-deleting-in-list-items.tentative.html?Backspace,ol [ Failure Timeout ] crbug.com/626703 external/wpt/input-events/input-events-get-target-ranges-deleting-in-list-items.tentative.html?Delete,ol [ Failure Timeout ] -crbug.com/626703 [ Mac ] external/wpt/webxr/xr_viewport_scale.https.html [ Failure Timeout ] +crbug.com/626703 [ Mac10.15 Release ] external/wpt/webxr/xr_viewport_scale.https.html [ Failure Timeout ] +crbug.com/626703 [ Mac11 Release ] external/wpt/webxr/xr_viewport_scale.https.html [ Failure Timeout ] +crbug.com/626703 [ Mac12 Release ] external/wpt/webxr/xr_viewport_scale.https.html [ Failure Timeout ] +crbug.com/626703 [ Mac13 ] external/wpt/webxr/xr_viewport_scale.https.html [ Failure Timeout ] crbug.com/626703 external/wpt/infrastructure/testdriver/actions/iframe.html [ Failure Timeout ] crbug.com/626703 external/wpt/infrastructure/testdriver/actions/crossOrigin.sub.html [ Timeout ] crbug.com/626703 external/wpt/input-events/input-events-get-target-ranges-during-and-after-dispatch.tentative.html [ Failure Timeout ]
diff --git a/third_party/blink/web_tests/external/wpt/webrtc-extensions/RTCRtpTransceiver-headerExtensionControl.html b/third_party/blink/web_tests/external/wpt/webrtc-extensions/RTCRtpTransceiver-headerExtensionControl.html index 79eba02..796d35d 100644 --- a/third_party/blink/web_tests/external/wpt/webrtc-extensions/RTCRtpTransceiver-headerExtensionControl.html +++ b/third_party/blink/web_tests/external/wpt/webrtc-extensions/RTCRtpTransceiver-headerExtensionControl.html
@@ -94,7 +94,7 @@ t.add_cleanup(() => pc.close()); const transceiver = pc.addTransceiver('audio'); const capabilities = transceiver.getHeaderExtensionsToNegotiate(); - let capability = capabilities.find((capability) => { + const capability = capabilities.find((capability) => { return capability.uri === 'urn:ietf:params:rtp-hdrext:sdes:mid'; }); ['sendonly', 'recvonly', 'inactive', 'stopped'].map(direction => { @@ -109,14 +109,14 @@ const pc = new RTCPeerConnection(); t.add_cleanup(() => pc.close()); const transceiver = pc.addTransceiver('audio'); - let capabilities = transceiver.getHeaderExtensionsToNegotiate(); - let selected_capability = capabilities.find((capability) => { + const capabilities = transceiver.getHeaderExtensionsToNegotiate(); + const selected_capability = capabilities.find((capability) => { return capability.direction === 'sendrecv' && capability.uri !== 'urn:ietf:params:rtp-hdrext:sdes:mid'; }); selected_capability.direction = 'stopped'; const offered_capabilities = transceiver.getHeaderExtensionsToNegotiate(); - let altered_capability = capabilities.find((capability) => { + const altered_capability = capabilities.find((capability) => { return capability.uri === selected_capability.uri && capability.direction === 'stopped'; }); @@ -292,4 +292,66 @@ } }, 'Prior to negotiation, getNegotiatedHeaderExtensions() returns `stopped` for all extensions.'); +promise_test(async t => { + const pc1 = new RTCPeerConnection(); + t.add_cleanup(() => pc1.close()); + const pc2 = new RTCPeerConnection(); + t.add_cleanup(() => pc2.close()); + + // Disable a non-mandatory extension before first negotiation. + const transceiver = pc1.addTransceiver('video'); + const capabilities = transceiver.getHeaderExtensionsToNegotiate(); + const selected_capability = capabilities.find((capability) => { + return capability.direction === 'sendrecv' && + capability.uri !== 'urn:ietf:params:rtp-hdrext:sdes:mid'; + }); + selected_capability.direction = 'stopped'; + transceiver.setHeaderExtensionsToNegotiate(capabilities); + + await negotiate(pc1, pc2); + const negotiated_capabilites = transceiver.getNegotiatedHeaderExtensions(); + + const local_negotiated = transceiver.getNegotiatedHeaderExtensions().find(ext => { + return ext.uri === selected_capability.uri; + }); + assert_equals(local_negotiated.direction, 'stopped'); + const remote_negotiated = pc2.getTransceivers()[0].getNegotiatedHeaderExtensions().find(ext => { + return ext.uri === selected_capability.uri; + }); + assert_equals(remote_negotiated.direction, 'stopped'); +}, 'Answer header extensions are a subset of the offered header extensions'); + +promise_test(async t => { + const pc1 = new RTCPeerConnection(); + t.add_cleanup(() => pc1.close()); + const pc2 = new RTCPeerConnection(); + t.add_cleanup(() => pc2.close()); + + // Disable a non-mandatory extension before first negotiation. + const transceiver = pc1.addTransceiver('video'); + const capabilities = transceiver.getHeaderExtensionsToNegotiate(); + const selected_capability = capabilities.find((capability) => { + return capability.direction === 'sendrecv' && + capability.uri !== 'urn:ietf:params:rtp-hdrext:sdes:mid'; + }); + selected_capability.direction = 'stopped'; + transceiver.setHeaderExtensionsToNegotiate(capabilities); + + await negotiate(pc1, pc2); + // Negotiate, switching sides. + await negotiate(pc2, pc1); + + // PC2 will re-offer the extension. + const remote_reoffered = pc2.getTransceivers()[0].getHeaderExtensionsToNegotiate().find(ext => { + return ext.uri === selected_capability.uri; + }); + assert_equals(remote_reoffered.direction, 'sendrecv'); + + // But PC1 will still reject the extension. + const negotiated_capabilites = transceiver.getNegotiatedHeaderExtensions(); + const local_negotiated = transceiver.getNegotiatedHeaderExtensions().find(ext => { + return ext.uri === selected_capability.uri; + }); + assert_equals(local_negotiated.direction, 'stopped'); +}, 'A subsequent offer from the other side will reoffer extensions not negotiated by the initial offerer'); </script>
diff --git a/third_party/blink/web_tests/http/tests/devtools/indexeddb/database-refresh-view.js b/third_party/blink/web_tests/http/tests/devtools/indexeddb/database-refresh-view.js index 2795112..a51e4ef 100644 --- a/third_party/blink/web_tests/http/tests/devtools/indexeddb/database-refresh-view.js +++ b/third_party/blink/web_tests/http/tests/devtools/indexeddb/database-refresh-view.js
@@ -9,7 +9,11 @@ (async function() { TestRunner.addResult(`Tests refreshing the database information and data views.\n`); await TestRunner.loadLegacyModule('console'); - // Note: every test that uses a storage API must manually clean-up state from previous tests. + await TestRunner.navigatePromise('http://127.0.0.1:8000/devtools/indexeddb/resources/without-indexed-db.html'); + await ApplicationTestRunner.setupIndexedDBHelpers(); + + // Note: every test that uses a storage API must manually clean-up state from + // previous tests. await ApplicationTestRunner.resetState(); await TestRunner.loadLegacyModule('console'); @@ -62,13 +66,8 @@ ApplicationTestRunner.dumpIndexedDBTree(); // Create database - try { - ApplicationTestRunner.createDatabaseAsync(databaseName); - await new Promise(waitDatabaseAdded); - } catch (e) { - TestRunner.addResult(await TestRunnet.evaluateInPageAsync('window.location.href')); - throw e; - } + ApplicationTestRunner.createDatabaseAsync(databaseName); + await new Promise(waitDatabaseAdded); var idbDatabaseTreeElement = UI.panels.resources.sidebar.indexedDBListTreeElement.idbDatabaseTreeElements[0]; databaseId = idbDatabaseTreeElement.databaseId; TestRunner.addResult('Created database.');
diff --git a/third_party/blink/web_tests/http/tests/devtools/indexeddb/delete-entry.js b/third_party/blink/web_tests/http/tests/devtools/indexeddb/delete-entry.js index 92781e9..7899d31 100644 --- a/third_party/blink/web_tests/http/tests/devtools/indexeddb/delete-entry.js +++ b/third_party/blink/web_tests/http/tests/devtools/indexeddb/delete-entry.js
@@ -8,6 +8,8 @@ (async function() { TestRunner.addResult(`Tests object store and index entry deletion.\n`); await TestRunner.loadLegacyModule('console'); + await TestRunner.navigatePromise('http://127.0.0.1:8000/devtools/indexeddb/resources/without-indexed-db.html'); + await ApplicationTestRunner.setupIndexedDBHelpers(); // Note: every test that uses a storage API must manually clean-up state from previous tests. await ApplicationTestRunner.resetState();
diff --git a/third_party/blink/web_tests/http/tests/devtools/indexeddb/live-update-indexeddb-content.js b/third_party/blink/web_tests/http/tests/devtools/indexeddb/live-update-indexeddb-content.js index 72cbdb0..cef35ee 100644 --- a/third_party/blink/web_tests/http/tests/devtools/indexeddb/live-update-indexeddb-content.js +++ b/third_party/blink/web_tests/http/tests/devtools/indexeddb/live-update-indexeddb-content.js
@@ -8,6 +8,8 @@ (async function() { TestRunner.addResult(`Tests that the IndexedDB database content live updates.\n`); await TestRunner.loadLegacyModule('console'); + await TestRunner.navigatePromise('http://127.0.0.1:8000/devtools/indexeddb/resources/without-indexed-db.html'); + await ApplicationTestRunner.setupIndexedDBHelpers(); // Note: every test that uses a storage API must manually clean-up state from previous tests. await ApplicationTestRunner.resetState();
diff --git a/third_party/blink/web_tests/http/tests/devtools/indexeddb/live-update-indexeddb-list.js b/third_party/blink/web_tests/http/tests/devtools/indexeddb/live-update-indexeddb-list.js index 8d10e33..1c4fae3 100644 --- a/third_party/blink/web_tests/http/tests/devtools/indexeddb/live-update-indexeddb-list.js +++ b/third_party/blink/web_tests/http/tests/devtools/indexeddb/live-update-indexeddb-list.js
@@ -8,6 +8,8 @@ (async function() { TestRunner.addResult(`Tests that the IndexedDB database list live updates.\n`); await TestRunner.loadLegacyModule('console'); + await TestRunner.navigatePromise('http://127.0.0.1:8000/devtools/indexeddb/resources/without-indexed-db.html'); + await ApplicationTestRunner.setupIndexedDBHelpers(); // Note: every test that uses a storage API must manually clean-up state from previous tests. await ApplicationTestRunner.resetState();
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/attribution-reporting/set-local-testing-mode-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/attribution-reporting/set-local-testing-mode-expected.txt new file mode 100644 index 0000000..c1309f1 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/attribution-reporting/set-local-testing-mode-expected.txt
@@ -0,0 +1,14 @@ +Test that the Storage.setAttributionReportingLocalTestingMode command is handled. +{ + id : <number> + result : { + } + sessionId : <string> +} +{ + id : <number> + result : { + } + sessionId : <string> +} +
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/attribution-reporting/set-local-testing-mode.js b/third_party/blink/web_tests/http/tests/inspector-protocol/attribution-reporting/set-local-testing-mode.js new file mode 100644 index 0000000..f30d0746 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/attribution-reporting/set-local-testing-mode.js
@@ -0,0 +1,16 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(async function(testRunner) { + const {dp} = await testRunner.startBlank( + 'Test that the Storage.setAttributionReportingLocalTestingMode command is handled.'); + + testRunner.log(await dp.Storage.setAttributionReportingLocalTestingMode( + {enabled: true})); + + testRunner.log(await dp.Storage.setAttributionReportingLocalTestingMode( + {enabled: false})); + + testRunner.completeTest(); +})
diff --git a/tools/metrics/histograms/metadata/media/histograms.xml b/tools/metrics/histograms/metadata/media/histograms.xml index 53c1d5bc..6df2a37 100644 --- a/tools/metrics/histograms/metadata/media/histograms.xml +++ b/tools/metrics/histograms/metadata/media/histograms.xml
@@ -1416,21 +1416,6 @@ </summary> </histogram> -<histogram name="Media.AudioInputDevice.AudioServiceDelayDifference{Duration}" - units="ms" expires_after="2023-08-01"> - <owner>fhernqvist@google.com</owner> - <owner>olka@chromium.org</owner> - <owner>webrtc-audio-uma@google.com</owner> - <summary> - The difference between the largest and the lowest audio capture delay - observed during the sample interval. This stat considers the audio capture - delay in the Audio Service, including the IPC and the OS. Logged at the end - of each 1000-callback interval for Intervals. Logged at the end of the - stream for Short. - </summary> - <token key="Duration" variants="AudioAggregationDuration"/> -</histogram> - <histogram name="Media.AudioInputDevice.AudioServiceGlitchCount{Duration}" units="glitches" expires_after="2024-02-01"> <owner>fhernqvist@google.com</owner> @@ -1539,25 +1524,6 @@ </summary> </histogram> -<histogram - name="Media.AudioOutputDevice.AudioServiceDelayDifference{Duration}{LatencyTag}" - units="ms" expires_after="2023-08-01"> - <owner>fhernqvist@google.com</owner> - <owner>olka@chromium.org</owner> - <owner>dalecurtis@chromium.org</owner> - <owner>tguilbert@chromium.org</owner> - <owner>webrtc-audio-uma@google.com</owner> - <summary> - The difference between the largest and the lowest audio playout delay - observed during the sample interval. This stat considers the audio playout - delay in the Audio Service, including the IPC and the OS. Logged at the end - of each 1000-callback interval for Intervals. Logged at the end of the - stream for Short. - </summary> - <token key="Duration" variants="AudioAggregationDuration"/> - <token key="LatencyTag" variants="AudioLatencyTag"/> -</histogram> - <histogram name="Media.AudioOutputDevice.AudioServiceDelay{LatencyTag}" units="ms" expires_after="2024-02-01"> <owner>fhernqvist@google.com</owner>
diff --git a/ui/accessibility/platform/ax_platform_node_base.cc b/ui/accessibility/platform/ax_platform_node_base.cc index 525eaef..c22a88f 100644 --- a/ui/accessibility/platform/ax_platform_node_base.cc +++ b/ui/accessibility/platform/ax_platform_node_base.cc
@@ -10,6 +10,7 @@ #include <sstream> #include <string> #include <unordered_map> +#include <utility> #include "base/no_destructor.h" #include "base/numerics/checked_math.h" @@ -1640,6 +1641,18 @@ AXLegacyHypertext::AXLegacyHypertext(const AXLegacyHypertext& other) = default; AXLegacyHypertext& AXLegacyHypertext::operator=( const AXLegacyHypertext& other) = default; +AXLegacyHypertext::AXLegacyHypertext(AXLegacyHypertext&& other) noexcept + : needs_update(std::exchange(other.needs_update, true)), + hyperlink_offset_to_index(std::move(other.hyperlink_offset_to_index)), + hyperlinks(std::move(other.hyperlinks)), + hypertext(std::move(other.hypertext)) {} +AXLegacyHypertext& AXLegacyHypertext::operator=(AXLegacyHypertext&& other) { + needs_update = std::exchange(other.needs_update, true); + hyperlink_offset_to_index = std::move(other.hyperlink_offset_to_index); + hyperlinks = std::move(other.hyperlinks); + hypertext = std::move(other.hypertext); + return *this; +} // TODO(nektar): To be able to use AXNode in Views, move this logic to AXNode. void AXPlatformNodeBase::UpdateComputedHypertext() const {
diff --git a/ui/accessibility/platform/ax_platform_node_base.h b/ui/accessibility/platform/ax_platform_node_base.h index ac22478..8696761 100644 --- a/ui/accessibility/platform/ax_platform_node_base.h +++ b/ui/accessibility/platform/ax_platform_node_base.h
@@ -43,6 +43,8 @@ ~AXLegacyHypertext(); AXLegacyHypertext(const AXLegacyHypertext& other); AXLegacyHypertext& operator=(const AXLegacyHypertext& other); + AXLegacyHypertext(AXLegacyHypertext&& other) noexcept; + AXLegacyHypertext& operator=(AXLegacyHypertext&& other); // A flag that should be set if the hypertext information in this struct is // out-of-date and needs to be updated. This flag should always be set upon
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc index 80987a3d..672276a 100644 --- a/ui/accessibility/platform/ax_platform_node_win.cc +++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -7920,13 +7920,6 @@ return false; } -void AXPlatformNodeWin::ComputeHypertextRemovedAndInserted(size_t* start, - size_t* old_len, - size_t* new_len) { - AXPlatformNodeBase::ComputeHypertextRemovedAndInserted(old_hypertext_, start, - old_len, new_len); -} - double AXPlatformNodeWin::GetHorizontalScrollPercent() { if (!IsHorizontallyScrollable()) return UIA_ScrollPatternNoScroll;
diff --git a/ui/accessibility/platform/ax_platform_node_win.h b/ui/accessibility/platform/ax_platform_node_win.h index 1dd6214..38f6c87 100644 --- a/ui/accessibility/platform/ax_platform_node_win.h +++ b/ui/accessibility/platform/ax_platform_node_win.h
@@ -1220,8 +1220,6 @@ // Relationships between this node and other nodes. std::vector<Microsoft::WRL::ComPtr<AXPlatformRelationWin>> relations_; - AXLegacyHypertext old_hypertext_; - // These protected methods are still used by BrowserAccessibilityComWin. At // some point post conversion, we can probably move these to be private // methods. @@ -1233,9 +1231,6 @@ // Also, in IA2, text that includes embedded objects is called hypertext. // Returns true if the current object is an IA2 hyperlink. bool IsHyperlink(); - void ComputeHypertextRemovedAndInserted(size_t* start, - size_t* old_len, - size_t* new_len); // If offset is a member of IA2TextSpecialOffsets this function updates the // value of offset and returns, otherwise offset remains unchanged.
diff --git a/ui/aura/window.h b/ui/aura/window.h index 3120672..6777b11 100644 --- a/ui/aura/window.h +++ b/ui/aura/window.h
@@ -733,7 +733,7 @@ // parent during its parents destruction. bool owned_by_parent_ = true; - raw_ptr<WindowDelegate, DanglingUntriaged> delegate_; + raw_ptr<WindowDelegate, DanglingAcrossTasks> delegate_; // The Window's parent. raw_ptr<Window> parent_ = nullptr;
diff --git a/ui/aura/window_tree_host.h b/ui/aura/window_tree_host.h index c85e519e..cf045970 100644 --- a/ui/aura/window_tree_host.h +++ b/ui/aura/window_tree_host.h
@@ -448,7 +448,7 @@ // valid during its deletion. (Window's dtor notifies observers that may // attempt to reach back up to access this object which will be valid until // the end of the dtor). - raw_ptr<Window, DanglingUntriaged> window_; // Owning. + raw_ptr<Window, DanglingAcrossTasks> window_; // Owning. // Keeps track of the occlusion state of the host, and used to send // notifications to observers when it changes.
diff --git a/ui/base/models/simple_menu_model.h b/ui/base/models/simple_menu_model.h index 5ffe789..6a74342e 100644 --- a/ui/base/models/simple_menu_model.h +++ b/ui/base/models/simple_menu_model.h
@@ -275,7 +275,8 @@ void OnMenuClosed(); ItemVector items_; - const raw_ptr<Delegate, DanglingUntriaged> delegate_; + + raw_ptr<Delegate, DanglingAcrossTasks> delegate_; base::WeakPtrFactory<SimpleMenuModel> method_factory_{this}; };
diff --git a/ui/compositor/layer_tree_owner.h b/ui/compositor/layer_tree_owner.h index a4e16b3..9cac37473 100644 --- a/ui/compositor/layer_tree_owner.h +++ b/ui/compositor/layer_tree_owner.h
@@ -34,7 +34,7 @@ const Layer* root() const { return root_; } private: - raw_ptr<Layer, DanglingUntriaged> root_; + raw_ptr<Layer, DanglingAcrossTasks> root_; }; } // namespace
diff --git a/ui/gl/gl_bindings.h b/ui/gl/gl_bindings.h index 4b8e2ac..92056e43 100644 --- a/ui/gl/gl_bindings.h +++ b/ui/gl/gl_bindings.h
@@ -534,7 +534,7 @@ struct GL_EXPORT CurrentGL { raw_ptr<GLApi, DanglingUntriaged> Api = nullptr; raw_ptr<DriverGL, DanglingUntriaged> Driver = nullptr; - raw_ptr<const GLVersionInfo, DanglingUntriaged> Version = nullptr; + raw_ptr<const GLVersionInfo, DanglingAcrossTasks> Version = nullptr; }; #if defined(USE_EGL)
diff --git a/ui/views/layout/proposed_layout.h b/ui/views/layout/proposed_layout.h index 7fdd058..e0517e8 100644 --- a/ui/views/layout/proposed_layout.h +++ b/ui/views/layout/proposed_layout.h
@@ -27,7 +27,7 @@ std::string ToString() const; - raw_ptr<View, DanglingUntriaged> child_view = nullptr; + raw_ptr<View, DanglingAcrossTasks> child_view = nullptr; bool visible = false; gfx::Rect bounds; SizeBounds available_size;
diff --git a/ui/views/view.h b/ui/views/view.h index eec8861..3c0ce69 100644 --- a/ui/views/view.h +++ b/ui/views/view.h
@@ -2344,7 +2344,7 @@ // Context menus ------------------------------------------------------------- // The menu controller. - raw_ptr<ContextMenuController, DanglingUntriaged> context_menu_controller_ = + raw_ptr<ContextMenuController, DanglingAcrossTasks> context_menu_controller_ = nullptr; // Drag and drop -------------------------------------------------------------
diff --git a/ui/views/view_targeter.h b/ui/views/view_targeter.h index 8205412..f2839a66 100644 --- a/ui/views/view_targeter.h +++ b/ui/views/view_targeter.h
@@ -60,7 +60,7 @@ // ViewTargeter does not own the |delegate_|, but |delegate_| must // outlive the targeter. - raw_ptr<ViewTargeterDelegate, DanglingUntriaged> delegate_; + raw_ptr<ViewTargeterDelegate, DanglingAcrossTasks> delegate_; }; } // namespace views
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h index fbee21c..b60c0f8e 100644 --- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h +++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
@@ -301,7 +301,7 @@ // This is the return value from GetNativeView(). // WARNING: this may be NULL, in particular during shutdown it becomes NULL. - raw_ptr<aura::Window, DanglingUntriaged> content_window_; + raw_ptr<aura::Window, DanglingAcrossTasks> content_window_; base::WeakPtr<internal::NativeWidgetDelegate> native_widget_delegate_;
diff --git a/ui/views/window/client_view.h b/ui/views/window/client_view.h index 0c9d5af..7c90ab43 100644 --- a/ui/views/window/client_view.h +++ b/ui/views/window/client_view.h
@@ -73,7 +73,7 @@ private: // The View that this ClientView contains. - raw_ptr<View, DanglingUntriaged> contents_view_; + raw_ptr<View, DanglingAcrossTasks> contents_view_; }; BEGIN_VIEW_BUILDER(VIEWS_EXPORT, ClientView, View)
diff --git a/ui/webui/examples/browser/content_browser_client.h b/ui/webui/examples/browser/content_browser_client.h index 9889828b..b7862c1 100644 --- a/ui/webui/examples/browser/content_browser_client.h +++ b/ui/webui/examples/browser/content_browser_client.h
@@ -30,7 +30,7 @@ std::unique_ptr<content::DevToolsManagerDelegate> CreateDevToolsManagerDelegate() override; - raw_ptr<BrowserMainParts> browser_main_parts_ = nullptr; + raw_ptr<BrowserMainParts, DanglingAcrossTasks> browser_main_parts_ = nullptr; }; } // namespace webui_examples