diff --git a/DEPS b/DEPS index 514ac20..b080e01 100644 --- a/DEPS +++ b/DEPS
@@ -304,15 +304,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': '2ac149cfc794eca005e75ea5c83cc18309c5ffec', + 'skia_revision': 'b0f56d43aa08a7d46707e73f5deb6a615e9b6cf0', # 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': 'b0a3a06aa78a9beb4e8485eb502b20b2abe2abbf', + 'v8_revision': '0fc5685d7e665a163f91b728bb6a4334514d05e6', # 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': '9524c639ae58ccbf523511f4c059719f02f66e0d', + 'angle_revision': '435e557c5f7e425abdc54612e7bcae462b78cf29', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -331,7 +331,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Fuchsia sdk # and whatever else without interference from each other. - 'fuchsia_version': 'version:12.20230324.0.1', + 'fuchsia_version': 'version:12.20230324.2.1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling google-toolbox-for-mac # and whatever else without interference from each other. @@ -431,7 +431,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': 'd3a1f1f68deb6bd1149170d65af292732b365a59', + 'dawn_revision': 'aff2b43596d4b8429083e40debf71da62afc2861', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -790,12 +790,12 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - '87620c614a4bc0ba106c5898e334c53b7c90554f', + '36fa9155528e9810390f35ca35ce15464b7f645a', 'condition': 'checkout_android and checkout_src_internal', }, 'src/docs/website': { - 'url': Var('chromium_git') + '/website.git' + '@' + '049c271a3726ba530df735240bddd8cc5d63ba14', + 'url': Var('chromium_git') + '/website.git' + '@' + 'd02ea1f75859af4aecc3c6a561d4efb33197d2cb', }, 'src/ios/third_party/earl_grey2/src': { @@ -987,7 +987,7 @@ }, 'src/third_party/androidx_javascriptengine/src': { - 'url': Var('chromium_git') + '/aosp/platform/frameworks/support/javascriptengine/javascriptengine/src.git' + '@' + '5fa7f8147a178691325db20142005742070335dc', + 'url': Var('chromium_git') + '/aosp/platform/frameworks/support/javascriptengine/javascriptengine/src.git' + '@' + '8fc6d80d8f5fcb120f9a5074bbf2e4df02e23d9f', 'condition': 'checkout_android', }, @@ -1198,7 +1198,7 @@ # Tools used when building Chrome for Chrome OS. This affects both the Simple # Chrome workflow, as well as the chromeos-chrome ebuild. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '324dfc74b569a67598de148e85b2eb833bda1ecb', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'de3428b38fe70dd593c66c0988472f649f948b36', 'condition': 'checkout_chromeos', }, @@ -1230,7 +1230,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'ec4dd35d180ae98d245132ae8374a25130712b8d', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '8422acf6870290b05896201ba1c4d97e76688a9c', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1564,7 +1564,7 @@ Var('chromium_git') + '/webm/libwebp.git' + '@' + 'fd7b5d48464475408d32d2611bdb6947d4246b97', 'src/third_party/libyuv': - Var('chromium_git') + '/libyuv/libyuv.git' + '@' + '1a971f8cc3513766f3497ed73e613217b860935d', + Var('chromium_git') + '/libyuv/libyuv.git' + '@' + '464c51a0353c71f08fe45f683d6a97a638d47833', 'src/third_party/lighttpd': { 'url': Var('chromium_git') + '/chromium/deps/lighttpd.git' + '@' + Var('lighttpd_revision'), @@ -1702,7 +1702,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '156b10d4c91bcfaa6157255150f0175d5ef36d69', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '98e4886b5735e9d96d9d842967fb78bdfdc729fa', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1847,7 +1847,7 @@ 'dep_type': 'cipd', }, - 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@672a6d1840c9c91d62cee2c37fd45d731be6e9fe', + 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@3fc72f611482f8c7a959d66fbee71a750d27a001', 'src/third_party/vulkan_memory_allocator': Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + 'ebe84bec02c041d28f902da0214bf442743fc907', @@ -1887,7 +1887,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '904c74af6fee0530ce33434974aa0df6316fdef1', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '94b51210f8c42c8052b905bc6ba00c3e1aa1fdb8', + Var('webrtc_git') + '/src.git' + '@' + '55c7298c2bbaae647f09b4720212c872dee24ef7', # 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. @@ -1964,7 +1964,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': Var('chrome_git') + '/chrome/src-internal.git@885866a9a43a04a16ae729cfc9498fbe51cf17d6', + 'url': Var('chrome_git') + '/chrome/src-internal.git@687418f825955bff7f560556620defab3a2117bd', 'condition': 'checkout_src_internal', }, @@ -2005,7 +2005,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/media_app/app', - 'version': 'fVgEaUd1xAgUvnnFnLow9K2OkdHWSAK9Y5t--e-AVM8C', + 'version': 'rFFTmlJTbIIGcVsL90SA7Q8M1nynqs_HDW-y6wksjzEC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 295cbb6f..386b31f 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -6841,3 +6841,28 @@ 'scripts on iOS.', error_paths)) return results + +def CheckLibcxxRevisionsMatch(input_api, output_api): + """Check to make sure the libc++ version matches across deps files.""" + + DEPS_FILES = [ 'DEPS', 'buildtools/deps_revisions.gni' ] + + file_filter = lambda f: f.LocalPath().replace( + input_api.os_path.sep, '/') in DEPS_FILES + changed_deps_files = input_api.AffectedFiles(file_filter=file_filter) + if not changed_deps_files: + return [] + + def LibcxxRevision(file): + file = input_api.os_path.join(input_api.PresubmitLocalPath(), + *file.split('/')) + return input_api.re.search( + r'libcxx_revision.*[:=].*[\'"](\w+)[\'"]', + input_api.ReadFile(file)).group(1) + + if len(set([LibcxxRevision(f) for f in DEPS_FILES])) == 1: + return [] + + return [output_api.PresubmitError( + 'libcxx_revision not equal across %s' % ', '.join(DEPS_FILES), + changed_deps_files)]
diff --git a/android_webview/browser/gfx/vulkan_gl_interop.cc b/android_webview/browser/gfx/vulkan_gl_interop.cc index 86200014..49b3742 100644 --- a/android_webview/browser/gfx/vulkan_gl_interop.cc +++ b/android_webview/browser/gfx/vulkan_gl_interop.cc
@@ -23,8 +23,9 @@ #include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkPaint.h" #include "third_party/skia/include/core/SkSamplingOptions.h" -#include "third_party/skia/include/gpu/GrTypes.h" #include "third_party/skia/include/gpu/GrBackendSemaphore.h" +#include "third_party/skia/include/gpu/GrTypes.h" +#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h" #include "third_party/skia/include/gpu/vk/GrVkBackendContext.h" #include "third_party/skia/include/gpu/vk/GrVkExtensions.h" #include "third_party/skia/include/private/chromium/GrVkSecondaryCBDrawContext.h" @@ -321,7 +322,7 @@ // Create an SkImage from AHB. GrBackendTexture backend_texture(params.width, params.height, pending_draw->image_info); - pending_draw->ahb_skimage = SkImage::MakeFromTexture( + pending_draw->ahb_skimage = SkImages::BorrowTextureFrom( vulkan_context_provider_->GetGrContext(), backend_texture, kBottomLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kPremul_SkAlphaType, color_space);
diff --git a/android_webview/tools/system_webview_shell/test/data/webexposed/not-webview-exposed.txt b/android_webview/tools/system_webview_shell/test/data/webexposed/not-webview-exposed.txt index a1e62f1..a1b3362 100644 --- a/android_webview/tools/system_webview_shell/test/data/webexposed/not-webview-exposed.txt +++ b/android_webview/tools/system_webview_shell/test/data/webexposed/not-webview-exposed.txt
@@ -240,13 +240,6 @@ # crbug.com/1326898 interface FontData -# The Popover API (crbug.com/1307772) is enabled by the fieldtrial_testing_config, -# but only for desktop and Android platforms. It is not shipped to stable yet, -# on any platform. -interface HTMLElement : Element - method hidePopover - method showPopover - # FedCM API is not implemented on WebView. crbug.com/1340252 interface IdentityCredential : Credential
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index c4dbe95..71f164d 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -3136,6 +3136,7 @@ "system/camera/camera_effects_controller_unittest.cc", "system/caps_lock_notification_controller_unittest.cc", "system/cast/cast_feature_pod_controller_unittest.cc", + "system/cast/cast_notification_controller_unittest.cc", "system/cast/tray_cast_unittest.cc", "system/channel_indicator/channel_indicator_quick_settings_view_unittest.cc", "system/channel_indicator/channel_indicator_unittest.cc",
diff --git a/ash/app_list/BUILD.gn b/ash/app_list/BUILD.gn index fcdded8..e36fdcb 100644 --- a/ash/app_list/BUILD.gn +++ b/ash/app_list/BUILD.gn
@@ -107,6 +107,8 @@ "views/folder_header_view_delegate.h", "views/ghost_image_view.cc", "views/ghost_image_view.h", + "views/launcher_search_iph_view.cc", + "views/launcher_search_iph_view.h", "views/page_switcher.cc", "views/page_switcher.h", "views/paged_apps_grid_view.cc",
diff --git a/ash/app_list/app_list_controller_impl.cc b/ash/app_list/app_list_controller_impl.cc index 802db3f..6a4f419c 100644 --- a/ash/app_list/app_list_controller_impl.cc +++ b/ash/app_list/app_list_controller_impl.cc
@@ -11,6 +11,8 @@ #include "ash/app_list/app_list_bubble_presenter.h" #include "ash/app_list/app_list_model_provider.h" #include "ash/app_list/app_list_presenter_impl.h" +#include "ash/app_list/app_list_view_delegate.h" +#include "ash/app_list/model/search/search_box_model.h" #include "ash/app_list/views/app_list_item_view.h" #include "ash/app_list/views/app_list_main_view.h" #include "ash/app_list/views/app_list_toast_container_view.h" @@ -19,6 +21,7 @@ #include "ash/app_list/views/contents_view.h" #include "ash/app_list/views/search_box_view.h" #include "ash/assistant/assistant_controller_impl.h" +#include "ash/assistant/model/assistant_ui_model.h" #include "ash/assistant/ui/assistant_view_delegate.h" #include "ash/assistant/util/assistant_util.h" #include "ash/assistant/util/deep_link_util.h" @@ -324,18 +327,26 @@ return client_->GetNotifier(); } +std::unique_ptr<ScopedIphSession> +AppListControllerImpl::CreateLauncherSearchIphSession() { + if (!client_) { + return nullptr; + } + return client_->CreateLauncherSearchIphSession(); +} + void AppListControllerImpl::SetActiveModel(int profile_id, AppListModel* model, SearchModel* search_model) { profile_id_ = profile_id; model_provider_->SetActiveModel(model, search_model); - UpdateAssistantVisibility(); + UpdateSearchBoxUiVisibilities(); } void AppListControllerImpl::ClearActiveModel() { profile_id_ = kAppListInvalidProfileID; model_provider_->ClearActiveModel(); - UpdateAssistantVisibility(); + UpdateSearchBoxUiVisibilities(); } void AppListControllerImpl::DismissAppList() { @@ -848,16 +859,16 @@ void AppListControllerImpl::OnAssistantStatusChanged( assistant::AssistantStatus status) { - UpdateAssistantVisibility(); + UpdateSearchBoxUiVisibilities(); } void AppListControllerImpl::OnAssistantSettingsEnabled(bool enabled) { - UpdateAssistantVisibility(); + UpdateSearchBoxUiVisibilities(); } void AppListControllerImpl::OnAssistantFeatureAllowedChanged( assistant::AssistantAllowedState state) { - UpdateAssistantVisibility(); + UpdateSearchBoxUiVisibilities(); } void AppListControllerImpl::OnDisplayConfigurationChanged() { @@ -883,7 +894,7 @@ } void AppListControllerImpl::OnAssistantReady() { - UpdateAssistantVisibility(); + UpdateSearchBoxUiVisibilities(); } void AppListControllerImpl::OnUiVisibilityChanged( @@ -1187,7 +1198,7 @@ } void AppListControllerImpl::ViewShown(int64_t display_id) { - UpdateAssistantVisibility(); + UpdateSearchBoxUiVisibilities(); if (client_) client_->ViewShown(display_id); @@ -1608,9 +1619,15 @@ return model_provider_->search_model(); } -void AppListControllerImpl::UpdateAssistantVisibility() { +void AppListControllerImpl::UpdateSearchBoxUiVisibilities() { GetSearchModel()->search_box()->SetShowAssistantButton( IsAssistantAllowedAndEnabled()); + + if (!client_) { + return; + } + + client_->QueryWouldTriggerLauncherSearchIph(); } int64_t AppListControllerImpl::GetDisplayIdToShowAppListOn() {
diff --git a/ash/app_list/app_list_controller_impl.h b/ash/app_list/app_list_controller_impl.h index c98b620b..0a58206c 100644 --- a/ash/app_list/app_list_controller_impl.h +++ b/ash/app_list/app_list_controller_impl.h
@@ -16,6 +16,7 @@ #include "ash/ash_export.h" #include "ash/assistant/model/assistant_ui_model_observer.h" #include "ash/display/window_tree_host_manager.h" +#include "ash/public/cpp/app_list/app_list_client.h" #include "ash/public/cpp/app_list/app_list_controller.h" #include "ash/public/cpp/app_list/app_list_model_delegate.h" #include "ash/public/cpp/assistant/controller/assistant_controller_observer.h" @@ -144,6 +145,8 @@ // AppListViewDelegate: AppListNotifier* GetNotifier() override; + std::unique_ptr<ash::ScopedIphSession> CreateLauncherSearchIphSession() + override; void StartAssistant() override; void StartSearch(const std::u16string& raw_query) override; void StartZeroStateSearch(base::OnceClosure callback, @@ -347,8 +350,9 @@ std::unique_ptr<AppListItem> CreateAppListItem( std::unique_ptr<AppListItemMetadata> metadata); - // Update the visibility of Assistant functionality. - void UpdateAssistantVisibility(); + + // Update the visibility of UIs controlled by `SearchBoxModel`. + void UpdateSearchBoxUiVisibilities(); int64_t GetDisplayIdToShowAppListOn();
diff --git a/ash/app_list/app_list_test_view_delegate.cc b/ash/app_list/app_list_test_view_delegate.cc index 38488d18..8a497ab77 100644 --- a/ash/app_list/app_list_test_view_delegate.cc +++ b/ash/app_list/app_list_test_view_delegate.cc
@@ -196,6 +196,11 @@ return nullptr; } +std::unique_ptr<ScopedIphSession> +AppListTestViewDelegate::CreateLauncherSearchIphSession() { + return nullptr; +} + void AppListTestViewDelegate::RecordAppLaunched( ash::AppListLaunchedFrom launched_from) { RecordAppListAppLaunched(launched_from, app_list_view_state_,
diff --git a/ash/app_list/app_list_test_view_delegate.h b/ash/app_list/app_list_test_view_delegate.h index 9da3d23..ab2fe8bf 100644 --- a/ash/app_list/app_list_test_view_delegate.h +++ b/ash/app_list/app_list_test_view_delegate.h
@@ -16,6 +16,7 @@ #include "ash/app_list/app_list_view_delegate.h" #include "ash/app_list/model/app_list_test_model.h" #include "ash/app_list/model/search/search_model.h" +#include "ash/public/cpp/app_list/app_list_client.h" #include "ash/public/cpp/app_list/app_list_types.h" #include "base/functional/callback_forward.h" #include "ui/base/models/simple_menu_model.h" @@ -102,6 +103,7 @@ bool AppListTargetVisibility() const override; bool IsInTabletMode() override; AppListNotifier* GetNotifier() override; + std::unique_ptr<ScopedIphSession> CreateLauncherSearchIphSession() override; void LoadIcon(const std::string& app_id) override {} bool HasValidProfile() const override; bool ShouldHideContinueSection() const override;
diff --git a/ash/app_list/app_list_view_delegate.h b/ash/app_list/app_list_view_delegate.h index d42a2790..adf74a7a 100644 --- a/ash/app_list/app_list_view_delegate.h +++ b/ash/app_list/app_list_view_delegate.h
@@ -11,9 +11,11 @@ #include "ash/app_list/app_list_metrics.h" #include "ash/assistant/ui/assistant_view_delegate.h" +#include "ash/public/cpp/app_list/app_list_client.h" #include "ash/public/cpp/app_list/app_list_types.h" #include "ash/public/cpp/ash_public_export.h" #include "base/functional/callback_forward.h" +#include "base/memory/weak_ptr.h" #include "ui/base/ui_base_types.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/rect.h" @@ -38,6 +40,13 @@ // delegate. virtual AppListNotifier* GetNotifier() = 0; + // Creates a `ScopedIphSession` for interacting with LauncherSearchHelpUi + // feature. A caller must show an IPH UI after this returns a session. This + // returns nullptr if `feature_engagement::Tracker::ShouldTriggerHelpUI` + // returns false. + virtual std::unique_ptr<ScopedIphSession> + CreateLauncherSearchIphSession() = 0; + // Invoked to start a new Google Assistant session. virtual void StartAssistant() = 0;
diff --git a/ash/app_list/model/search/search_box_model.cc b/ash/app_list/model/search/search_box_model.cc index 555eb2f..354ea966 100644 --- a/ash/app_list/model/search/search_box_model.cc +++ b/ash/app_list/model/search/search_box_model.cc
@@ -7,6 +7,7 @@ #include <utility> #include "ash/app_list/model/search/search_box_model_observer.h" +#include "ash/public/cpp/app_list/app_list_client.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" @@ -24,6 +25,18 @@ observer.ShowAssistantChanged(); } +void SearchBoxModel::SetWouldTriggerIph(bool would_trigger_iph) { + if (would_trigger_iph_ == would_trigger_iph) { + return; + } + + would_trigger_iph_ = would_trigger_iph; + + for (auto& observer : observers_) { + observer.OnWouldTriggerIphChanged(); + } +} + void SearchBoxModel::SetSearchEngineIsGoogle(bool is_google) { if (is_google == search_engine_is_google_) return;
diff --git a/ash/app_list/model/search/search_box_model.h b/ash/app_list/model/search/search_box_model.h index 46b6846..d44a6c5 100644 --- a/ash/app_list/model/search/search_box_model.h +++ b/ash/app_list/model/search/search_box_model.h
@@ -6,6 +6,8 @@ #define ASH_APP_LIST_MODEL_SEARCH_SEARCH_BOX_MODEL_H_ #include "ash/app_list/model/app_list_model_export.h" +#include "ash/public/cpp/app_list/app_list_client.h" +#include "base/memory/weak_ptr.h" #include "base/observer_list.h" namespace ash { @@ -24,6 +26,9 @@ void SetShowAssistantButton(bool show); bool show_assistant_button() const { return show_assistant_button_; } + void SetWouldTriggerIph(bool would_trigger_iph); + bool would_trigger_iph() const { return would_trigger_iph_; } + void SetSearchEngineIsGoogle(bool is_google); bool search_engine_is_google() const { return search_engine_is_google_; } @@ -34,6 +39,11 @@ bool search_engine_is_google_ = false; bool show_assistant_button_ = false; + // `would_trigger_iph_` indicates whether we should START showing an IPH or + // not. This can be set to false while an IPH is being shown and the IPH + // should be kept showing. + bool would_trigger_iph_ = false; + base::ObserverList<SearchBoxModelObserver> observers_; };
diff --git a/ash/app_list/model/search/search_box_model_observer.h b/ash/app_list/model/search/search_box_model_observer.h index 6ba5e45..47584322 100644 --- a/ash/app_list/model/search/search_box_model_observer.h +++ b/ash/app_list/model/search/search_box_model_observer.h
@@ -19,6 +19,10 @@ // Invoked when whether to show Assistant is changed. virtual void ShowAssistantChanged() = 0; + // Invoked when whether an IPH should be triggered or not have been + // changed. + virtual void OnWouldTriggerIphChanged() = 0; + protected: ~SearchBoxModelObserver() override = default; };
diff --git a/ash/app_list/model/search/search_model.cc b/ash/app_list/model/search/search_model.cc index 948f813..0bc77d83 100644 --- a/ash/app_list/model/search/search_model.cc +++ b/ash/app_list/model/search/search_model.cc
@@ -23,6 +23,10 @@ search_box_->SetSearchEngineIsGoogle(is_google); } +void SearchModel::SetWouldTriggerLauncherSearchIph(bool would_trigger) { + search_box_->SetWouldTriggerIph(would_trigger); +} + std::vector<SearchResult*> SearchModel::FilterSearchResultsByFunction( SearchResults* results, const base::RepeatingCallback<bool(const SearchResult&)>& result_filter,
diff --git a/ash/app_list/model/search/search_model.h b/ash/app_list/model/search/search_model.h index 64142dd..b9ca4d6 100644 --- a/ash/app_list/model/search/search_model.h +++ b/ash/app_list/model/search/search_model.h
@@ -39,6 +39,9 @@ return search_box_->search_engine_is_google(); } + void SetWouldTriggerLauncherSearchIph(bool would_trigger); + bool would_trigger_iph() const { return search_box_->would_trigger_iph(); } + // Filter the given |results| by those which |result_filter| returns true for. // The returned list is truncated to |max_results|. static std::vector<SearchResult*> FilterSearchResultsByFunction(
diff --git a/ash/app_list/test_app_list_client.cc b/ash/app_list/test_app_list_client.cc index 6c47494c..043887f 100644 --- a/ash/app_list/test_app_list_client.cc +++ b/ash/app_list/test_app_list_client.cc
@@ -83,6 +83,13 @@ return nullptr; } +void TestAppListClient::QueryWouldTriggerLauncherSearchIph() {} + +std::unique_ptr<ScopedIphSession> +TestAppListClient::CreateLauncherSearchIphSession() { + return nullptr; +} + std::vector<TestAppListClient::SearchResultActionId> TestAppListClient::GetAndResetInvokedResultActions() { std::vector<SearchResultActionId> result;
diff --git a/ash/app_list/test_app_list_client.h b/ash/app_list/test_app_list_client.h index f5e6722..1103f1e 100644 --- a/ash/app_list/test_app_list_client.h +++ b/ash/app_list/test_app_list_client.h
@@ -59,6 +59,8 @@ const std::string& setting_name, const std::map<std::string, int>& values) override {} AppListNotifier* GetNotifier() override; + void QueryWouldTriggerLauncherSearchIph() override; + std::unique_ptr<ScopedIphSession> CreateLauncherSearchIphSession() override; void LoadIcon(int profile_id, const std::string& app_id) override {} ash::AppListSortOrder GetPermanentSortingOrder() const override; void CommitTemporarySortOrder() override;
diff --git a/ash/app_list/views/app_list_bubble_view.cc b/ash/app_list/views/app_list_bubble_view.cc index 78c30837..13f3bda 100644 --- a/ash/app_list/views/app_list_bubble_view.cc +++ b/ash/app_list/views/app_list_bubble_view.cc
@@ -493,6 +493,9 @@ } a11y_announcer_->AnnounceAppListShown(); MaybeFocusAndActivateSearchBox(); + // As `current_page_` is reset to `kNone` in `OnHideAnimationEnded`, we + // can expect that this gets called every time a launcher gets shown. + search_box_view_->SetIsIphAllowed(true); break; case AppListBubblePage::kSearch: if (previous_page == AppListBubblePage::kApps) { @@ -503,6 +506,7 @@ search_page_->SetVisible(true); } MaybeFocusAndActivateSearchBox(); + search_box_view_->SetIsIphAllowed(false); break; case AppListBubblePage::kAssistant: if (showing_folder_) @@ -517,6 +521,7 @@ search_box_view_->SetSearchBoxActive(false, /*event_type=*/ui::ET_UNKNOWN); assistant_page_->RequestFocus(); + search_box_view_->SetIsIphAllowed(false); break; } } @@ -754,6 +759,7 @@ apps_page_->SetVisible(true); search_page_->SetVisible(false); assistant_page_->SetVisible(false); + search_box_view_->SetIsIphAllowed(false); is_hiding_ = false; if (on_hide_animation_ended_)
diff --git a/ash/app_list/views/launcher_search_iph_view.cc b/ash/app_list/views/launcher_search_iph_view.cc new file mode 100644 index 0000000..2dafe00 --- /dev/null +++ b/ash/app_list/views/launcher_search_iph_view.cc
@@ -0,0 +1,55 @@ +// 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 "ash/app_list/views/launcher_search_iph_view.h" + +#include <memory> +#include <utility> + +#include "ash/public/cpp/app_list/app_list_client.h" +#include "ui/gfx/font_list.h" +#include "ui/gfx/text_constants.h" +#include "ui/views/controls/label.h" +#include "ui/views/layout/box_layout.h" + +namespace ash { +namespace { +constexpr int kVerticalInset = 20; +constexpr int kHorizontalInset = 24; + +constexpr int kTitleTextFontSize = 20; +constexpr int kDescriptionTextFontSize = 16; + +constexpr char16_t kTitleTextPlaceholder[] = u"Title text"; +constexpr char16_t kDescriptionTextPlaceholder[] = u"Description text"; +} // namespace + +LauncherSearchIphView::LauncherSearchIphView( + std::unique_ptr<ScopedIphSession> scoped_iph_session) + : scoped_iph_session_(std::move(scoped_iph_session)) { + SetID(kViewId); + + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical, + gfx::Insets::VH(kVerticalInset, kHorizontalInset))); + + raw_ptr<views::Label> title_label = + AddChildView(std::make_unique<views::Label>(kTitleTextPlaceholder)); + title_label->SetFontList(gfx::FontList().DeriveWithSizeDelta( + kTitleTextFontSize - gfx::FontList().GetFontSize())); + title_label->SetLineHeight(kTitleTextFontSize); + title_label->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_TO_HEAD); + + raw_ptr<views::Label> description_label = + AddChildView(std::make_unique<views::Label>(kDescriptionTextPlaceholder)); + description_label->SetFontList(gfx::FontList().DeriveWithSizeDelta( + kDescriptionTextFontSize - gfx::FontList().GetFontSize())); + description_label->SetLineHeight(kDescriptionTextFontSize); + description_label->SetHorizontalAlignment( + gfx::HorizontalAlignment::ALIGN_TO_HEAD); +} + +LauncherSearchIphView::~LauncherSearchIphView() = default; + +} // namespace ash
diff --git a/ash/app_list/views/launcher_search_iph_view.h b/ash/app_list/views/launcher_search_iph_view.h new file mode 100644 index 0000000..155c863 --- /dev/null +++ b/ash/app_list/views/launcher_search_iph_view.h
@@ -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. + +#ifndef ASH_APP_LIST_VIEWS_LAUNCHER_SEARCH_IPH_VIEW_H_ +#define ASH_APP_LIST_VIEWS_LAUNCHER_SEARCH_IPH_VIEW_H_ + +#include <memory> + +#include "ash/public/cpp/app_list/app_list_client.h" +#include "ui/views/view.h" + +namespace ash { + +class LauncherSearchIphView : public views::View { + public: + static constexpr int kViewId = 1; + + explicit LauncherSearchIphView( + std::unique_ptr<ScopedIphSession> scoped_iph_session); + ~LauncherSearchIphView() override; + + private: + std::unique_ptr<ScopedIphSession> scoped_iph_session_; + + base::WeakPtrFactory<LauncherSearchIphView> weak_ptr_factory_{this}; +}; + +} // namespace ash + +#endif // ASH_APP_LIST_VIEWS_LAUNCHER_SEARCH_IPH_VIEW_H_
diff --git a/ash/app_list/views/search_box_view.cc b/ash/app_list/views/search_box_view.cc index b81a76c..bf09fab 100644 --- a/ash/app_list/views/search_box_view.cc +++ b/ash/app_list/views/search_box_view.cc
@@ -10,10 +10,12 @@ #include <vector> #include "ash/app_list/app_list_metrics.h" +#include "ash/app_list/app_list_model_provider.h" #include "ash/app_list/app_list_util.h" #include "ash/app_list/app_list_view_delegate.h" #include "ash/app_list/model/search/search_box_model.h" #include "ash/app_list/model/search/search_model.h" +#include "ash/app_list/views/launcher_search_iph_view.h" #include "ash/app_list/views/result_selection_controller.h" #include "ash/app_list/views/search_box_view_delegate.h" #include "ash/app_list/views/search_result_base_view.h" @@ -233,6 +235,8 @@ assistant_button->SetAccessibleName(assistant_button_label); assistant_button->SetTooltipText(assistant_button_label); SetShowAssistantButton(search_box_model->show_assistant_button()); + + UpdateIphViewVisibility(); } SearchBoxView::~SearchBoxView() { @@ -293,6 +297,11 @@ ResetForShow(); UpdateSearchIcon(); ShowAssistantChanged(); + + // `UpdateIphViewVisibility` expect that `AppListModelProvider` returns the + // new model. + CHECK(search_model == AppListModelProvider::Get()->search_model()); + UpdateIphViewVisibility(); } void SearchBoxView::UpdateKeyboardVisibility() { @@ -793,6 +802,16 @@ return kBubbleLauncherSearchBoxButtonSizeDip; } +void SearchBoxView::SetIsIphAllowed(bool iph_allowed) { + if (is_iph_allowed_ == iph_allowed) { + return; + } + + is_iph_allowed_ = iph_allowed; + + UpdateIphViewVisibility(); +} + void SearchBoxView::CloseButtonPressed() { delegate_->CloseButtonPressed(); } @@ -1198,6 +1217,36 @@ ->show_assistant_button()); } +void SearchBoxView::UpdateIphViewVisibility() { + const bool would_trigger_iph = + AppListModelProvider::Get()->search_model()->would_trigger_iph(); + const bool is_iph_showing = iph_view() != nullptr; + + const bool should_show_iph = + is_iph_allowed_ && (would_trigger_iph || is_iph_showing); + + if (should_show_iph == is_iph_showing) { + return; + } + + if (should_show_iph) { + std::unique_ptr<ScopedIphSession> scoped_iph_session = + view_delegate_->CreateLauncherSearchIphSession(); + if (!scoped_iph_session) { + return; + } + + SetIphView( + std::make_unique<LauncherSearchIphView>(std::move(scoped_iph_session))); + } else { + DeleteIphView(); + } +} + +void SearchBoxView::OnWouldTriggerIphChanged() { + UpdateIphViewVisibility(); +} + bool SearchBoxView::ShouldProcessAutocomplete() { // IME sets composition text while the user is typing, so avoid handling // autocomplete in this case to avoid conflicts.
diff --git a/ash/app_list/views/search_box_view.h b/ash/app_list/views/search_box_view.h index bc2a65d8..d56a9192 100644 --- a/ash/app_list/views/search_box_view.h +++ b/ash/app_list/views/search_box_view.h
@@ -161,6 +161,9 @@ int GetSearchBoxIconSize(); int GetSearchBoxButtonSize(); + // Sets whether an IPH can be shown now or not. + void SetIsIphAllowed(bool iph_allowed); + private: class FocusRingLayer; @@ -183,6 +186,9 @@ // Updates the search box placeholder text and accessible name. void UpdatePlaceholderTextAndAccessibleName(); + // Updates the visibility of an IPH view. + void UpdateIphViewVisibility(); + // Notifies SearchBoxViewDelegate that the autocomplete text is valid. void AcceptAutocompleteText(); @@ -209,6 +215,7 @@ // Overridden from SearchBoxModelObserver: void SearchEngineChanged() override; void ShowAssistantChanged() override; + void OnWouldTriggerIphChanged() override; // Updates search_box() for the |selected_result|. Should be called when the // selected search result changes. @@ -250,6 +257,9 @@ // The corner radius of the search box background. int corner_radius_ = 0; + // Whether an IPH is allowed to be shown or not. + bool is_iph_allowed_ = false; + // Set by SearchResultPageView when the accessibility selection moves to a // search result view - the value is the ID of the currently selected result // view.
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 175f5e7..2fec6d1 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -573,6 +573,12 @@ <message name="IDS_ASH_STATUS_TRAY_CAST_STOP_CASTING" desc="Label for a button in the system tray popup to stop casting to a Chromecast device."> Stop casting </message> + <message name="IDS_ASH_STATUS_TRAY_CAST_PAUSE" desc="Label for a button in the cast notification to pause the current cast mirroring session to a Chromecast device"> + Pause + </message> + <message name="IDS_ASH_STATUS_TRAY_CAST_RESUME" desc="Label for a button in the cast notification to resume a paused cast mirroring session to a Chromecast device"> + Resume + </message> <message name="IDS_ASH_STATUS_TRAY_QUIET_MODE_TOOLTIP" desc="The tooltip text for the status area icon to tell do-not-disturb mode is currently on."> Do Not Disturb is on </message>
diff --git a/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_CAST_PAUSE.png.sha1 b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_CAST_PAUSE.png.sha1 new file mode 100644 index 0000000..c0c8e18 --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_CAST_PAUSE.png.sha1
@@ -0,0 +1 @@ +2edac68f443630f69e2637436584cea3a2518a18 \ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_CAST_RESUME.png.sha1 b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_CAST_RESUME.png.sha1 new file mode 100644 index 0000000..a31f4e7 --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_CAST_RESUME.png.sha1
@@ -0,0 +1 @@ +52349d54056e89b16f316e071365c3775a8f2310 \ No newline at end of file
diff --git a/ash/assistant/ui/main_stage/assistant_zero_state_view.cc b/ash/assistant/ui/main_stage/assistant_zero_state_view.cc index 0efe2f6..7c5dd82 100644 --- a/ash/assistant/ui/main_stage/assistant_zero_state_view.cc +++ b/ash/assistant/ui/main_stage/assistant_zero_state_view.cc
@@ -47,6 +47,24 @@ constexpr auto kToastMarginDip = gfx::Insets::TLBR(0, 24, 4, 24); constexpr auto kToastPreferredSizeDip = gfx::Size(496, 64); +bool ShouldShowGreetingOrOnboarding(bool in_tablet_mode) { + if (assistant::features::IsAssistantLearnMoreEnabled()) { + return !in_tablet_mode; + } + return true; +} + +bool ShouldShowSpacer(bool in_tablet_mode) { + if (assistant::features::IsAssistantLearnMoreEnabled()) { + return !in_tablet_mode; + } + return false; +} + +bool ShouldShowLearnMoreToast() { + return assistant::features::IsAssistantLearnMoreEnabled(); +} + } // namespace AssistantZeroStateView::AssistantZeroStateView(AssistantViewDelegate* delegate) @@ -131,31 +149,37 @@ greeting_label_->SetText( l10n_util::GetStringUTF16(IDS_ASH_ASSISTANT_PROMPT_DEFAULT)); - if (assistant::features::IsAssistantLearnMoreEnabled()) { - // Spacer. - auto* spacer = AddChildView(std::make_unique<views::View>()); - layout->SetFlexForView(spacer, 1); + // Spacer. + spacer_ = AddChildView(std::make_unique<views::View>()); + layout->SetFlexForView(spacer_, 1); - // Learn more toast. - // TODO(b/274527683, b/274525194): add i18n and a11y supports. - learn_more_toast_ = AddChildView( - AppListToastView::Builder(u"Learn more about Google Assistant") - .SetButton(l10n_util::GetStringUTF16(IDS_ASH_LEARN_MORE), - base::BindRepeating( - &AssistantZeroStateView::OnLearnMoreButtonPressed, - base::Unretained(this))) - .Build()); - learn_more_toast_->SetID(AssistantViewID::kLearnMoreToast); - learn_more_toast_->SetProperty(views::kMarginsKey, kToastMarginDip); - learn_more_toast_->SetPreferredSize(kToastPreferredSizeDip); - learn_more_toast_->SetTitleLabelMaximumWidth(); - } + // Learn more toast. + // TODO(b/274527683, b/274525194): add i18n and a11y supports. + learn_more_toast_ = AddChildView( + AppListToastView::Builder(u"Learn more about Google Assistant") + .SetButton(l10n_util::GetStringUTF16(IDS_ASH_LEARN_MORE), + base::BindRepeating( + &AssistantZeroStateView::OnLearnMoreButtonPressed, + base::Unretained(this))) + .Build()); + learn_more_toast_->SetID(AssistantViewID::kLearnMoreToast); + learn_more_toast_->SetProperty(views::kMarginsKey, kToastMarginDip); + learn_more_toast_->SetPreferredSize(kToastPreferredSizeDip); + learn_more_toast_->SetTitleLabelMaximumWidth(); } void AssistantZeroStateView::UpdateLayout() { + const bool show_greeting_or_onboarding = + ShouldShowGreetingOrOnboarding(delegate_->IsTabletMode()); const bool show_onboarding = delegate_->ShouldShowOnboarding(); - onboarding_view_->SetVisible(show_onboarding); - greeting_label_->SetVisible(!show_onboarding); + onboarding_view_->SetVisible(show_greeting_or_onboarding && show_onboarding); + greeting_label_->SetVisible(show_greeting_or_onboarding && !show_onboarding); + + const bool show_spacer = ShouldShowSpacer(delegate_->IsTabletMode()); + spacer_->SetVisible(show_spacer); + + const bool show_learn_more_toast = ShouldShowLearnMoreToast(); + learn_more_toast_->SetVisible(show_learn_more_toast); } void AssistantZeroStateView::OnLearnMoreButtonPressed() {
diff --git a/ash/assistant/ui/main_stage/assistant_zero_state_view.h b/ash/assistant/ui/main_stage/assistant_zero_state_view.h index 540a9a7..9e5454bb 100644 --- a/ash/assistant/ui/main_stage/assistant_zero_state_view.h +++ b/ash/assistant/ui/main_stage/assistant_zero_state_view.h
@@ -60,6 +60,7 @@ // Owned by view hierarchy; AssistantOnboardingView* onboarding_view_ = nullptr; views::Label* greeting_label_ = nullptr; + base::raw_ptr<views::View> spacer_ = nullptr; base::raw_ptr<AppListToastView> learn_more_toast_ = nullptr; base::ScopedObservation<AssistantController, AssistantControllerObserver>
diff --git a/ash/assistant/ui/main_stage/assistant_zero_state_view_unittest.cc b/ash/assistant/ui/main_stage/assistant_zero_state_view_unittest.cc index 8635d5d..aea34a2 100644 --- a/ash/assistant/ui/main_stage/assistant_zero_state_view_unittest.cc +++ b/ash/assistant/ui/main_stage/assistant_zero_state_view_unittest.cc
@@ -96,7 +96,9 @@ AppListToastView* learn_more_toast = static_cast<AppListToastView*>( page_view()->GetViewByID(AssistantViewID::kLearnMoreToast)); - ASSERT_FALSE(learn_more_toast); + ASSERT_TRUE(learn_more_toast); + ASSERT_FALSE(learn_more_toast->GetVisible()); + ASSERT_FALSE(learn_more_toast->IsDrawn()); } TEST_F(AssistantZeroStateViewUnittest, LearnMoreToastViewIsVisible) { @@ -123,8 +125,85 @@ page_view()->GetViewByID(AssistantViewID::kLearnMoreToast)); ASSERT_TRUE(learn_more_toast); ASSERT_TRUE(learn_more_toast->GetVisible()); + ASSERT_TRUE(learn_more_toast->IsDrawn()); MockTextInteraction().WithTextResponse("The response"); + ASSERT_TRUE(learn_more_toast->GetVisible()); + ASSERT_FALSE(learn_more_toast->IsDrawn()); +} + +TEST_F(AssistantZeroStateViewUnittest, + LearnMoreToastViewIsNotVisible_TabletMode) { + base::test::ScopedFeatureList feature_list_; + feature_list_.InitAndDisableFeature( + assistant::features::kEnableAssistantLearnMore); + + SetNumberOfSessionsWhereOnboardingShown( + assistant::ui::kOnboardingMaxSessionsShown); + SetTabletMode(true); + ShowAssistantUi(); + + const views::Label* greeting_label = static_cast<views::Label*>( + page_view()->GetViewByID(AssistantViewID::kGreetingLabel)); + ASSERT_TRUE(greeting_label); + ASSERT_TRUE(greeting_label->GetVisible()); + ASSERT_TRUE(greeting_label->IsDrawn()); + + AppListToastView* learn_more_toast = static_cast<AppListToastView*>( + page_view()->GetViewByID(AssistantViewID::kLearnMoreToast)); + ASSERT_TRUE(learn_more_toast); + ASSERT_FALSE(learn_more_toast->GetVisible()); + ASSERT_FALSE(learn_more_toast->IsDrawn()); +} + +TEST_F(AssistantZeroStateViewUnittest, LearnMoreToastViewIsVisible_TabletMode) { + base::test::ScopedFeatureList scoped_feature_list( + assistant::features::kEnableAssistantLearnMore); + + SetNumberOfSessionsWhereOnboardingShown( + assistant::ui::kOnboardingMaxSessionsShown); + SetTabletMode(true); + ShowAssistantUi(); + + const views::Label* greeting_label = static_cast<views::Label*>( + page_view()->GetViewByID(AssistantViewID::kGreetingLabel)); + ASSERT_TRUE(greeting_label); + ASSERT_FALSE(greeting_label->GetVisible()); + ASSERT_FALSE(greeting_label->IsDrawn()); + + AppListToastView* learn_more_toast = static_cast<AppListToastView*>( + page_view()->GetViewByID(AssistantViewID::kLearnMoreToast)); + ASSERT_TRUE(learn_more_toast); + ASSERT_TRUE(learn_more_toast->GetVisible()); + ASSERT_TRUE(learn_more_toast->IsDrawn()); +} + +TEST_F(AssistantZeroStateViewUnittest, + LearnMoreToastViewIsNotVisibleAfterResponse_TabletMode) { + base::test::ScopedFeatureList scoped_feature_list( + assistant::features::kEnableAssistantLearnMore); + + SetNumberOfSessionsWhereOnboardingShown( + assistant::ui::kOnboardingMaxSessionsShown); + SetTabletMode(true); + ShowAssistantUi(); + // Show Assistant UI in text mode, which is required to set text query. + TapOnAndWait(keyboard_input_toggle()); + + const views::Label* greeting_label = static_cast<views::Label*>( + page_view()->GetViewByID(AssistantViewID::kGreetingLabel)); + ASSERT_TRUE(greeting_label); + ASSERT_FALSE(greeting_label->GetVisible()); + ASSERT_FALSE(greeting_label->IsDrawn()); + + AppListToastView* learn_more_toast = static_cast<AppListToastView*>( + page_view()->GetViewByID(AssistantViewID::kLearnMoreToast)); + ASSERT_TRUE(learn_more_toast); + ASSERT_TRUE(learn_more_toast->GetVisible()); + ASSERT_TRUE(learn_more_toast->IsDrawn()); + + MockTextInteraction().WithTextResponse("The response"); + ASSERT_TRUE(learn_more_toast->GetVisible()); ASSERT_FALSE(learn_more_toast->IsDrawn()); }
diff --git a/ash/capture_mode/capture_label_view.cc b/ash/capture_mode/capture_label_view.cc index bc902971..92da696 100644 --- a/ash/capture_mode/capture_label_view.cc +++ b/ash/capture_mode/capture_label_view.cc
@@ -20,6 +20,7 @@ #include "base/task/single_thread_task_runner.h" #include "base/task/task_runner.h" #include "base/time/time.h" +#include "chromeos/constants/chromeos_features.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/compositor/layer.h" @@ -176,11 +177,11 @@ label_->SetEnabledColorId(kColorAshTextColorPrimary); label_->SetBackgroundColor(SK_ColorTRANSPARENT); - if (features::IsDarkLightModeEnabled()) { - SetBorder(std::make_unique<views::HighlightBorder>( - kCaptureLabelRadius, views::HighlightBorder::Type::kHighlightBorder2, - /*use_light_colors=*/false)); - } + capture_mode_util::MaybeSetHighlightBorder( + this, kCaptureLabelRadius, + chromeos::features::IsJellyrollEnabled() + ? views::HighlightBorder::Type::kHighlightBorderNoShadow + : views::HighlightBorder::Type::kHighlightBorder2); shadow_->SetRoundedCornerRadius(kCaptureLabelRadius); }
diff --git a/ash/capture_mode/capture_mode_bar_view.cc b/ash/capture_mode/capture_mode_bar_view.cc index 1082147..b718d9a 100644 --- a/ash/capture_mode/capture_mode_bar_view.cc +++ b/ash/capture_mode/capture_mode_bar_view.cc
@@ -13,6 +13,7 @@ #include "ash/capture_mode/capture_mode_session_focus_cycler.h" #include "ash/capture_mode/capture_mode_source_view.h" #include "ash/capture_mode/capture_mode_type_view.h" +#include "ash/capture_mode/capture_mode_util.h" #include "ash/constants/ash_features.h" #include "ash/public/cpp/style/color_provider.h" #include "ash/resources/vector_icons/vector_icons.h" @@ -24,6 +25,7 @@ #include "ash/style/icon_button.h" #include "ash/style/system_shadow.h" #include "base/functional/bind.h" +#include "chromeos/constants/chromeos_features.h" #include "ui/aura/window.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/metadata/metadata_impl_macros.h" @@ -112,11 +114,12 @@ separator_2_->SetColorId(ui::kColorAshSystemUIMenuSeparator); separator_2_->SetPreferredLength(kSeparatorHeight); - if (features::IsDarkLightModeEnabled()) { - SetBorder(std::make_unique<views::HighlightBorder>( - kBorderRadius, views::HighlightBorder::Type::kHighlightBorder2, - /*use_light_colors=*/false)); - } + capture_mode_util::MaybeSetHighlightBorder( + this, kBorderRadius, + chromeos::features::IsJellyrollEnabled() + ? views::HighlightBorder::Type::kHighlightBorderOnShadow + : views::HighlightBorder::Type::kHighlightBorder2); + shadow_->SetRoundedCornerRadius(kBorderRadius); }
diff --git a/ash/capture_mode/capture_mode_settings_view.cc b/ash/capture_mode/capture_mode_settings_view.cc index 0f50e0e..dc9a367 100644 --- a/ash/capture_mode/capture_mode_settings_view.cc +++ b/ash/capture_mode/capture_mode_settings_view.cc
@@ -13,6 +13,7 @@ #include "ash/capture_mode/capture_mode_metrics.h" #include "ash/capture_mode/capture_mode_session.h" #include "ash/capture_mode/capture_mode_session_focus_cycler.h" +#include "ash/capture_mode/capture_mode_util.h" #include "ash/constants/ash_features.h" #include "ash/public/cpp/style/color_provider.h" #include "ash/resources/vector_icons/vector_icons.h" @@ -23,6 +24,7 @@ #include "base/files/file_path.h" #include "base/functional/bind.h" #include "capture_mode_menu_toggle_button.h" +#include "chromeos/constants/chromeos_features.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/compositor/layer.h" @@ -161,11 +163,11 @@ SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kVertical)); - if (features::IsDarkLightModeEnabled()) { - SetBorder(std::make_unique<views::HighlightBorder>( - kCornerRadius, views::HighlightBorder::Type::kHighlightBorder1, - /*use_light_colors=*/false)); - } + capture_mode_util::MaybeSetHighlightBorder( + this, kCornerRadius, + chromeos::features::IsJellyrollEnabled() + ? views::HighlightBorder::Type::kHighlightBorderOnShadow + : views::HighlightBorder::Type::kHighlightBorder1); shadow_->SetRoundedCornerRadius(kCornerRadius); }
diff --git a/ash/capture_mode/capture_mode_util.cc b/ash/capture_mode/capture_mode_util.cc index 78f6331..d84b6897 100644 --- a/ash/capture_mode/capture_mode_util.cc +++ b/ash/capture_mode/capture_mode_util.cc
@@ -546,4 +546,15 @@ return total; } +void MaybeSetHighlightBorder(views::View* view, + int corner_radius, + views::HighlightBorder::Type type) { + if (!features::IsDarkLightModeEnabled()) { + return; + } + + view->SetBorder(std::make_unique<views::HighlightBorder>( + corner_radius, type, /*use_light_color=*/false)); +} + } // namespace ash::capture_mode_util
diff --git a/ash/capture_mode/capture_mode_util.h b/ash/capture_mode/capture_mode_util.h index e8963f9..ce04ca6f 100644 --- a/ash/capture_mode/capture_mode_util.h +++ b/ash/capture_mode/capture_mode_util.h
@@ -15,6 +15,7 @@ #include "ui/gfx/animation/tween.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/size.h" +#include "ui/views/highlight_border.h" namespace aura { class Window; @@ -208,6 +209,12 @@ // differ based on whether `is_in_projector_mode` is true or false. int GetNumberOfSupportedRecordingTypes(bool is_in_projector_mode); +// Sets a highlight border to the `view` with given rounded corner radius and +// type. +void MaybeSetHighlightBorder(views::View* view, + int corner_radius, + views::HighlightBorder::Type type); + } // namespace capture_mode_util } // namespace ash
diff --git a/ash/capture_mode/key_item_view.cc b/ash/capture_mode/key_item_view.cc index fd38452..847a179 100644 --- a/ash/capture_mode/key_item_view.cc +++ b/ash/capture_mode/key_item_view.cc
@@ -7,6 +7,7 @@ #include <memory> #include "ash/capture_mode/capture_mode_util.h" +#include "chromeos/constants/chromeos_features.h" #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/base/models/image_model.h" #include "ui/chromeos/styles/cros_tokens_color_mappings.h" @@ -47,6 +48,12 @@ SetBackground( views::CreateRoundedRectBackground(GetColor(), kKeyItemHeight / 2)); layer()->SetFillsBoundsOpaquely(false); + + capture_mode_util::MaybeSetHighlightBorder( + this, kKeyItemHeight / 2, + chromeos::features::IsJellyrollEnabled() + ? views::HighlightBorder::Type::kHighlightBorderOnShadow + : views::HighlightBorder::Type::kHighlightBorder1); } KeyItemView::~KeyItemView() = default; @@ -54,9 +61,6 @@ void KeyItemView::OnThemeChanged() { views::View::OnThemeChanged(); GetBackground()->SetNativeControlColor(GetColor()); - SetBorder(std::make_unique<views::HighlightBorder>( - kKeyItemHeight / 2, views::HighlightBorder::Type::kHighlightBorder1, - /*use_light_colors=*/false)); SchedulePaint(); }
diff --git a/ash/capture_mode/recording_type_menu_view.cc b/ash/capture_mode/recording_type_menu_view.cc index e92f7c7..ecbdb13 100644 --- a/ash/capture_mode/recording_type_menu_view.cc +++ b/ash/capture_mode/recording_type_menu_view.cc
@@ -6,12 +6,14 @@ #include "ash/capture_mode/capture_mode_controller.h" #include "ash/capture_mode/capture_mode_types.h" +#include "ash/capture_mode/capture_mode_util.h" #include "ash/constants/ash_features.h" #include "ash/public/cpp/style/color_provider.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/strings/grit/ash_strings.h" #include "ash/style/ash_color_id.h" #include "ash/style/system_shadow.h" +#include "chromeos/constants/chromeos_features.h" #include "ui/base/l10n/l10n_util.h" #include "ui/compositor/layer.h" #include "ui/gfx/geometry/point.h" @@ -71,11 +73,11 @@ l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_LABEL_GIF_RECORD), ToInt(RecordingType::kGif)); - if (features::IsDarkLightModeEnabled()) { - SetBorder(std::make_unique<views::HighlightBorder>( - kCornerRadius, views::HighlightBorder::Type::kHighlightBorder1, - /*use_light_colors=*/false)); - } + capture_mode_util::MaybeSetHighlightBorder( + this, kCornerRadius, + chromeos::features::IsJellyrollEnabled() + ? views::HighlightBorder::Type::kHighlightBorderOnShadow + : views::HighlightBorder::Type::kHighlightBorder1); shadow_->SetRoundedCornerRadius(kCornerRadius); }
diff --git a/ash/components/arc/BUILD.gn b/ash/components/arc/BUILD.gn index db6f855..ab62a12 100644 --- a/ash/components/arc/BUILD.gn +++ b/ash/components/arc/BUILD.gn
@@ -309,8 +309,6 @@ "test/fake_app_host.h", "test/fake_app_instance.cc", "test/fake_app_instance.h", - "test/fake_apps_tracker.cc", - "test/fake_apps_tracker.h", "test/fake_arc_bridge_host.cc", "test/fake_arc_bridge_host.h", "test/fake_arc_session.cc", @@ -378,7 +376,6 @@ deps = [ ":arc", - "//ash/components/arc/enterprise", "//ash/constants", "//base", "//components/keyed_service/content", @@ -415,7 +412,6 @@ "compat_mode/resize_util_unittest.cc", "compat_mode/touch_mode_mouse_rewriter_unittest.cc", "crash_collector/arc_crash_collector_bridge_unittest.cc", - "enterprise/arc_data_remove_requested_pref_handler_unittest.cc", "ime/arc_ime_service_unittest.cc", "ime/key_event_result_receiver_unittest.cc", "lock_screen/arc_lock_screen_bridge_unittest.cc", @@ -449,7 +445,6 @@ ":arc", "//ash:test_support", "//ash/components/arc:arc_test_support", - "//ash/components/arc/enterprise", "//ash/components/arc/media_session", "//ash/components/arc/video_accelerator:common", "//ash/constants",
diff --git a/ash/components/arc/arc_prefs.cc b/ash/components/arc/arc_prefs.cc index 1f533f5..506aacc 100644 --- a/ash/components/arc/arc_prefs.cc +++ b/ash/components/arc/arc_prefs.cc
@@ -155,9 +155,6 @@ // Android properties. Used only in ARCVM. const char kArcSerialNumberSalt[] = "arc.serialno_salt"; -// A preference to keep time intervals when snapshotting is allowed. -const char kArcSnapshotHours[] = "arc.snapshot_hours"; - // A preferece to keep ARC snapshot related info in dictionary. const char kArcSnapshotInfo[] = "arc.snapshot"; @@ -174,7 +171,6 @@ // Sorted in lexicographical order. RegisterDailyMetricsPrefs(registry); registry->RegisterStringPref(kArcSerialNumberSalt, std::string()); - registry->RegisterDictionaryPref(kArcSnapshotHours); registry->RegisterDictionaryPref(kArcSnapshotInfo); registry->RegisterTimePref(kArcVmmSwapOutTime, base::Time()); registry->RegisterDictionaryPref(kStabilityMetrics);
diff --git a/ash/components/arc/arc_prefs.h b/ash/components/arc/arc_prefs.h index 2d8f33e..adab747 100644 --- a/ash/components/arc/arc_prefs.h +++ b/ash/components/arc/arc_prefs.h
@@ -55,7 +55,6 @@ ARC_EXPORT extern const char kAnrPendingCount[]; ARC_EXPORT extern const char kAnrPendingDuration[]; ARC_EXPORT extern const char kArcSerialNumberSalt[]; -ARC_EXPORT extern const char kArcSnapshotHours[]; ARC_EXPORT extern const char kArcSnapshotInfo[]; ARC_EXPORT extern const char kArcVmmSwapOutTime[]; ARC_EXPORT extern const char kStabilityMetrics[];
diff --git a/ash/components/arc/arc_util_unittest.cc b/ash/components/arc/arc_util_unittest.cc index e0edaed..9dcb1187 100644 --- a/ash/components/arc/arc_util_unittest.cc +++ b/ash/components/arc/arc_util_unittest.cc
@@ -30,6 +30,7 @@ #include "components/user_manager/fake_user_manager.h" #include "components/user_manager/scoped_user_manager.h" #include "components/user_manager/user.h" +#include "components/user_manager/user_manager.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/test/test_windows.h" @@ -415,7 +416,11 @@ // An ephemeral user is a logged in user but unknown to UserManager when // ephemeral policy is set. - fake_user_manager->SetEphemeralUsersEnabled(true); + fake_user_manager->SetEphemeralModeConfig( + user_manager::UserManager::EphemeralModeConfig( + /* included_by_default= */ true, + /* include_list= */ std::vector<AccountId>{}, + /* exclude_list= */ std::vector<AccountId>{})); fake_user_manager->UserLoggedIn( AccountId::FromUserEmailGaiaId("test@test.com", "9876543210"), "test@test.com-hash", false /* browser_restart */, false /* is_child */);
diff --git a/ash/components/arc/enterprise/BUILD.gn b/ash/components/arc/enterprise/BUILD.gn deleted file mode 100644 index 2c1d054..0000000 --- a/ash/components/arc/enterprise/BUILD.gn +++ /dev/null
@@ -1,32 +0,0 @@ -# Copyright 2020 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//build/config/chromeos/ui_mode.gni") - -assert(is_chromeos_ash) - -static_library("enterprise") { - sources = [ - "arc_apps_tracker.h", - "arc_data_remove_requested_pref_handler.cc", - "arc_data_remove_requested_pref_handler.h", - ] - - deps = [ - "//ash/components/arc:prefs", - "//ash/constants", - "//base", - "//chromeos/ash/components/cryptohome", - "//chromeos/ash/components/dbus", - "//chromeos/ash/components/dbus/arc", - "//chromeos/ash/components/dbus/upstart:upstart", - "//chromeos/ash/components/policy", - "//chromeos/dbus/power", - "//components/prefs", - "//components/session_manager/core", - "//components/user_manager", - "//ui/gl", - "//ui/ozone", - ] -}
diff --git a/ash/components/arc/enterprise/DEPS b/ash/components/arc/enterprise/DEPS deleted file mode 100644 index 80681d044..0000000 --- a/ash/components/arc/enterprise/DEPS +++ /dev/null
@@ -1,3 +0,0 @@ -include_rules = [ - "+chromeos/ash/components/policy/weekly_time", -]
diff --git a/ash/components/arc/enterprise/OWNERS b/ash/components/arc/enterprise/OWNERS deleted file mode 100644 index 05055c9..0000000 --- a/ash/components/arc/enterprise/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -file://chrome/browser/ash/arc/enterprise/OWNERS
diff --git a/ash/components/arc/enterprise/arc_apps_tracker.h b/ash/components/arc/enterprise/arc_apps_tracker.h deleted file mode 100644 index 148b9a0c..0000000 --- a/ash/components/arc/enterprise/arc_apps_tracker.h +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ASH_COMPONENTS_ARC_ENTERPRISE_ARC_APPS_TRACKER_H_ -#define ASH_COMPONENTS_ARC_ENTERPRISE_ARC_APPS_TRACKER_H_ - -#include "base/functional/callback_forward.h" - -namespace arc { -namespace data_snapshotd { - -// This class tracks installation of the list of ARC apps. -class ArcAppsTracker { - public: - // The destruction of the instance stops tracking installation of the list of - // ARC apps and compliance with policy. - virtual ~ArcAppsTracker() = default; - - // Starts tracking installation of the list of ARC apps. - // Invokes a repeating callback |update_callback| when the number of installed - // tracked apps changes. |update_callback| is invoked with the percent of - // installed tracked apps in a range of 0..100. - // Invokes a |finish_callback| once ARC is compliant with policy and the - // apps tracking is finished. - // |update_callback| is guaranteed to be never invoked after - // |finish_callback|. - virtual void StartTracking(base::RepeatingCallback<void(int)> update_callback, - base::OnceClosure finish_callback) = 0; -}; - -} // namespace data_snapshotd -} // namespace arc - -#endif // ASH_COMPONENTS_ARC_ENTERPRISE_ARC_APPS_TRACKER_H_
diff --git a/ash/components/arc/enterprise/arc_data_remove_requested_pref_handler.cc b/ash/components/arc/enterprise/arc_data_remove_requested_pref_handler.cc deleted file mode 100644 index 3fce40a..0000000 --- a/ash/components/arc/enterprise/arc_data_remove_requested_pref_handler.cc +++ /dev/null
@@ -1,50 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ash/components/arc/enterprise/arc_data_remove_requested_pref_handler.h" - -#include "ash/components/arc/arc_prefs.h" -#include "base/memory/ptr_util.h" -#include "components/prefs/pref_service.h" - -namespace arc { -namespace data_snapshotd { - -// static -std::unique_ptr<ArcDataRemoveRequestedPrefHandler> -ArcDataRemoveRequestedPrefHandler::Create(PrefService* prefs, - base::OnceClosure callback) { - if (prefs->GetBoolean(prefs::kArcDataRemoveRequested)) { - std::move(callback).Run(); - return nullptr; - } - return base::WrapUnique( - new ArcDataRemoveRequestedPrefHandler(prefs, std::move(callback))); -} - -ArcDataRemoveRequestedPrefHandler::~ArcDataRemoveRequestedPrefHandler() = - default; - -ArcDataRemoveRequestedPrefHandler::ArcDataRemoveRequestedPrefHandler( - PrefService* prefs, - base::OnceClosure callback) { - DCHECK(prefs); - DCHECK(!prefs->GetBoolean(prefs::kArcDataRemoveRequested)); - - pref_change_registrar_.Init(prefs); - pref_change_registrar_.Add( - prefs::kArcDataRemoveRequested, - base::BindRepeating(&ArcDataRemoveRequestedPrefHandler::OnPrefChanged, - weak_ptr_factory_.GetWeakPtr())); - callback_ = std::move(callback); -} - -void ArcDataRemoveRequestedPrefHandler::OnPrefChanged() { - if (callback_.is_null()) - return; - std::move(callback_).Run(); -} - -} // namespace data_snapshotd -} // namespace arc
diff --git a/ash/components/arc/enterprise/arc_data_remove_requested_pref_handler.h b/ash/components/arc/enterprise/arc_data_remove_requested_pref_handler.h deleted file mode 100644 index c16d385..0000000 --- a/ash/components/arc/enterprise/arc_data_remove_requested_pref_handler.h +++ /dev/null
@@ -1,54 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ASH_COMPONENTS_ARC_ENTERPRISE_ARC_DATA_REMOVE_REQUESTED_PREF_HANDLER_H_ -#define ASH_COMPONENTS_ARC_ENTERPRISE_ARC_DATA_REMOVE_REQUESTED_PREF_HANDLER_H_ - -#include "base/functional/callback.h" -#include "base/memory/weak_ptr.h" -#include "components/prefs/pref_change_registrar.h" - -class PrefService; - -namespace arc { -namespace data_snapshotd { - -// This class handles ARC data remove requests and notifies the owner if ARC -// data remove is requested. -class ArcDataRemoveRequestedPrefHandler final { - public: - ArcDataRemoveRequestedPrefHandler(const ArcDataRemoveRequestedPrefHandler&) = - delete; - ArcDataRemoveRequestedPrefHandler& operator=( - const ArcDataRemoveRequestedPrefHandler&) = delete; - ~ArcDataRemoveRequestedPrefHandler(); - - // Creates the instance if ARC data removal is not requested yet, otherwise - // returns nullptr and calls |callback| right away. - // |callback| is called once ARC data removal is requested. - static std::unique_ptr<ArcDataRemoveRequestedPrefHandler> Create( - PrefService* prefs, - base::OnceClosure callback); - - private: - // The instance observes the changes of kArcDataRemoveRequested in |prefs|. - // |callback| is invoked once the pref is set. - ArcDataRemoveRequestedPrefHandler(PrefService* prefs, - base::OnceClosure callback); - void OnPrefChanged(); - - // If |callback| is a valid callback, it is invoked once ARC data remove is - // requested. - base::OnceClosure callback_; - // Observes changes to kArcDataRemoveRequested pref. - PrefChangeRegistrar pref_change_registrar_; - - base::WeakPtrFactory<ArcDataRemoveRequestedPrefHandler> weak_ptr_factory_{ - this}; -}; - -} // namespace data_snapshotd -} // namespace arc - -#endif // ASH_COMPONENTS_ARC_ENTERPRISE_ARC_DATA_REMOVE_REQUESTED_PREF_HANDLER_H_
diff --git a/ash/components/arc/enterprise/arc_data_remove_requested_pref_handler_unittest.cc b/ash/components/arc/enterprise/arc_data_remove_requested_pref_handler_unittest.cc deleted file mode 100644 index 3743b1ad..0000000 --- a/ash/components/arc/enterprise/arc_data_remove_requested_pref_handler_unittest.cc +++ /dev/null
@@ -1,64 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <memory> - -#include "ash/components/arc/arc_prefs.h" -#include "ash/components/arc/enterprise/arc_data_remove_requested_pref_handler.h" -#include "ash/components/arc/session/arc_data_remover.h" -#include "base/run_loop.h" -#include "base/test/task_environment.h" -#include "chromeos/ash/components/cryptohome/cryptohome_parameters.h" -#include "components/prefs/testing_pref_service.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -class PrefService; - -namespace arc { -namespace data_snapshotd { - -class ArcDataRemoveRequestedPrefHandlerTest : public testing::Test { - protected: - void SetUp() override { - arc::prefs::RegisterProfilePrefs(pref_service_.registry()); - arc_data_remover_ = std::make_unique<ArcDataRemover>( - pref_service(), cryptohome::Identification()); - } - - void TearDown() override { arc_data_remover_.reset(); } - - PrefService* pref_service() { return &pref_service_; } - ArcDataRemover* arc_data_remover() { return arc_data_remover_.get(); } - - private: - base::test::TaskEnvironment task_environment_; - TestingPrefServiceSimple pref_service_; - std::unique_ptr<ArcDataRemover> arc_data_remover_; -}; - -TEST_F(ArcDataRemoveRequestedPrefHandlerTest, RemoveInProcess) { - // Schedule ARC data remove before initializing observer. - arc_data_remover()->Schedule(); - EXPECT_TRUE(arc_data_remover()->IsScheduledForTesting()); - base::RunLoop run_loop; - auto handler = ArcDataRemoveRequestedPrefHandler::Create( - pref_service(), run_loop.QuitClosure()); - run_loop.Run(); -} - -TEST_F(ArcDataRemoveRequestedPrefHandlerTest, BasicRemove) { - EXPECT_FALSE(arc_data_remover()->IsScheduledForTesting()); - base::RunLoop run_loop; - auto handler = ArcDataRemoveRequestedPrefHandler::Create( - pref_service(), run_loop.QuitClosure()); - - // Schedule ARC data remove. - arc_data_remover()->Schedule(); - EXPECT_TRUE(arc_data_remover()->IsScheduledForTesting()); - run_loop.Run(); -} - -} // namespace data_snapshotd -} // namespace arc
diff --git a/ash/components/arc/enterprise/arc_snapshot_reboot_notification.h b/ash/components/arc/enterprise/arc_snapshot_reboot_notification.h deleted file mode 100644 index 38b3b39..0000000 --- a/ash/components/arc/enterprise/arc_snapshot_reboot_notification.h +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ASH_COMPONENTS_ARC_ENTERPRISE_ARC_SNAPSHOT_REBOOT_NOTIFICATION_H_ -#define ASH_COMPONENTS_ARC_ENTERPRISE_ARC_SNAPSHOT_REBOOT_NOTIFICATION_H_ - -#include "base/functional/callback_forward.h" - -namespace arc { -namespace data_snapshotd { - -class ArcSnapshotRebootNotification { - public: - virtual ~ArcSnapshotRebootNotification() = default; - - // Sets a user consent callback |callback| to be invoked once the user - // consents to reboot the device. - virtual void SetUserConsentCallback( - const base::RepeatingClosure& callback) = 0; - - // Shows a snapshot reboot notification. - virtual void Show() = 0; - - // Hides a snapshot reboot notification. - virtual void Hide() = 0; -}; - -} // namespace data_snapshotd -} // namespace arc - -#endif // ASH_COMPONENTS_ARC_ENTERPRISE_ARC_SNAPSHOT_REBOOT_NOTIFICATION_H_
diff --git a/ash/components/arc/session/BUILD.gn b/ash/components/arc/session/BUILD.gn index 69778d96..cf7c248 100644 --- a/ash/components/arc/session/BUILD.gn +++ b/ash/components/arc/session/BUILD.gn
@@ -48,7 +48,6 @@ "//ash/components/arc:arc_base_utils", "//ash/components/arc:arc_features", "//ash/components/arc:prefs", - "//ash/components/arc/enterprise", "//ash/components/arc/mojom", "//ash/constants:constants", "//ash/public/cpp",
diff --git a/ash/components/arc/test/fake_apps_tracker.cc b/ash/components/arc/test/fake_apps_tracker.cc deleted file mode 100644 index 0ca1189f..0000000 --- a/ash/components/arc/test/fake_apps_tracker.cc +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ash/components/arc/test/fake_apps_tracker.h" - -namespace arc { -namespace data_snapshotd { - -FakeAppsTracker::FakeAppsTracker() = default; -FakeAppsTracker::~FakeAppsTracker() = default; - -void FakeAppsTracker::StartTracking( - base::RepeatingCallback<void(int)> update_callback, - base::OnceClosure finish_callback) { - start_tracking_num_++; - update_callback_ = std::move(update_callback); - finish_callback_ = std::move(finish_callback); -} - -} // namespace data_snapshotd -} // namespace arc
diff --git a/ash/components/arc/test/fake_apps_tracker.h b/ash/components/arc/test/fake_apps_tracker.h deleted file mode 100644 index 802ed4b..0000000 --- a/ash/components/arc/test/fake_apps_tracker.h +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ASH_COMPONENTS_ARC_TEST_FAKE_APPS_TRACKER_H_ -#define ASH_COMPONENTS_ARC_TEST_FAKE_APPS_TRACKER_H_ - -#include "ash/components/arc/enterprise/arc_apps_tracker.h" -#include "base/functional/callback.h" - -namespace arc { -namespace data_snapshotd { - -// Fake implementation of ArcAppsTracker for tests. -class FakeAppsTracker : public ArcAppsTracker { - public: - FakeAppsTracker(); - FakeAppsTracker(const FakeAppsTracker&) = delete; - FakeAppsTracker& operator=(const FakeAppsTracker&) = delete; - ~FakeAppsTracker() override; - - // ArcAppsTracker overrides: - void StartTracking(base::RepeatingCallback<void(int)> update_callback, - base::OnceClosure finish_callback) override; - - base::RepeatingCallback<void(int)>& update_callback() { - return update_callback_; - } - base::OnceClosure finish_callback() { return std::move(finish_callback_); } - int start_tracking_num() const { return start_tracking_num_; } - - private: - int start_tracking_num_ = 0; - base::RepeatingCallback<void(int)> update_callback_; - base::OnceClosure finish_callback_; -}; - -} // namespace data_snapshotd -} // namespace arc - -#endif // ASH_COMPONENTS_ARC_TEST_FAKE_APPS_TRACKER_H_
diff --git a/ash/components/arc/test/fake_snapshot_reboot_notification.cc b/ash/components/arc/test/fake_snapshot_reboot_notification.cc deleted file mode 100644 index 74050ff36..0000000 --- a/ash/components/arc/test/fake_snapshot_reboot_notification.cc +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ash/components/arc/test/fake_snapshot_reboot_notification.h" - -namespace arc { -namespace data_snapshotd { - -FakeSnapshotRebootNotification::FakeSnapshotRebootNotification() = default; -FakeSnapshotRebootNotification::~FakeSnapshotRebootNotification() = default; - -void FakeSnapshotRebootNotification::SetUserConsentCallback( - const base::RepeatingClosure& closure) { - user_consent_callback_ = closure; -} - -void FakeSnapshotRebootNotification::Show() { - shown_ = true; -} - -void FakeSnapshotRebootNotification::Hide() { - shown_ = false; -} - -void FakeSnapshotRebootNotification::Click() { - user_consent_callback_.Run(); -} - -} // namespace data_snapshotd -} // namespace arc
diff --git a/ash/in_session_auth/auth_dialog_contents_view.cc b/ash/in_session_auth/auth_dialog_contents_view.cc index 7a82c65..83b3bd9 100644 --- a/ash/in_session_auth/auth_dialog_contents_view.cc +++ b/ash/in_session_auth/auth_dialog_contents_view.cc
@@ -470,7 +470,7 @@ /*authenticated_by_pin=*/false), base::BindRepeating(&AuthDialogContentsView::OnInputTextChanged, base::Unretained(this)), - base::DoNothing(), views::Button::PressedCallback()); + base::DoNothing()); } void AuthDialogContentsView::AddPinPadView() { @@ -503,7 +503,7 @@ /*authenticated_by_pin=*/true), base::BindRepeating(&AuthDialogContentsView::OnInputTextChanged, base::Unretained(this)), - base::DoNothing(), views::Button::PressedCallback()); + base::DoNothing()); } pin_pad_view_->SetVisible(true); }
diff --git a/ash/login/ui/lock_contents_view.cc b/ash/login/ui/lock_contents_view.cc index d137c250..6a0533d1 100644 --- a/ash/login/ui/lock_contents_view.cc +++ b/ash/login/ui/lock_contents_view.cc
@@ -2242,21 +2242,6 @@ } } -void LockContentsView::OnEasyUnlockIconTapped() { - UserState* state = FindStateForUser( - CurrentBigUserView()->GetCurrentUser().basic_user_info.account_id); - DCHECK(state); - DCHECK(state->easy_unlock_icon_info); - - if (state->easy_unlock_icon_info->hardlock_on_click) { - AccountId user = - CurrentBigUserView()->GetCurrentUser().basic_user_info.account_id; - Shell::Get()->login_screen_controller()->HardlockPod(user); - // TODO(jdufault): This should get called as a result of HardlockPod. - OnTapToUnlockEnabledForUserChanged(user, false /*enabled*/); - } -} - void LockContentsView::OnParentAccessValidationFinished( const AccountId& account_id, bool access_granted) { @@ -2343,8 +2328,6 @@ &LockContentsView::RemoveUser, base::Unretained(this), is_primary); auth_user_callbacks.on_easy_unlock_icon_hovered = base::BindRepeating( &LockContentsView::OnEasyUnlockIconHovered, base::Unretained(this)); - auth_user_callbacks.on_easy_unlock_icon_tapped = base::BindRepeating( - &LockContentsView::OnEasyUnlockIconTapped, base::Unretained(this)); auth_user_callbacks.on_auth_factor_is_hiding_password_changed = base::BindRepeating( &LockContentsView::OnAuthFactorIsHidingPasswordChanged,
diff --git a/ash/login/ui/lock_contents_view.h b/ash/login/ui/lock_contents_view.h index 5f7d1ba..4ed71308 100644 --- a/ash/login/ui/lock_contents_view.h +++ b/ash/login/ui/lock_contents_view.h
@@ -343,8 +343,6 @@ // Called when the easy unlock icon is hovered. void OnEasyUnlockIconHovered(); - // Called when the easy unlock icon is tapped. - void OnEasyUnlockIconTapped(); // Called when LoginAuthFactorsView enters/exits a state where an auth // factor wants to hide the password and pin fields.
diff --git a/ash/login/ui/login_auth_user_view.cc b/ash/login/ui/login_auth_user_view.cc index 92abe134..46d3974 100644 --- a/ash/login/ui/login_auth_user_view.cc +++ b/ash/login/ui/login_auth_user_view.cc
@@ -1047,8 +1047,7 @@ base::Unretained(this)), base::BindRepeating(&LoginAuthUserView::OnPasswordTextChanged, base::Unretained(this)), - callbacks.on_easy_unlock_icon_hovered, - callbacks.on_easy_unlock_icon_tapped); + callbacks.on_easy_unlock_icon_hovered); auto pin_input_view = std::make_unique<LoginPinInputView>(); pin_input_view_ = pin_input_view.get();
diff --git a/ash/login/ui/login_auth_user_view.h b/ash/login/ui/login_auth_user_view.h index d3c6e64..4350454 100644 --- a/ash/login/ui/login_auth_user_view.h +++ b/ash/login/ui/login_auth_user_view.h
@@ -146,8 +146,6 @@ LoginUserView::OnRemove on_remove; // Called when the easy unlock icon is hovered. OnEasyUnlockIconHovered on_easy_unlock_icon_hovered; - // Called when the easy unlock icon is tapped. - views::Button::PressedCallback on_easy_unlock_icon_tapped; // Called when LoginAuthFactorsView enters/exits a state where an auth // factor wants to hide the password and pin. base::RepeatingCallback<void(bool)>
diff --git a/ash/login/ui/login_auth_user_view_unittest.cc b/ash/login/ui/login_auth_user_view_unittest.cc index 50f4d5b..bc17510a 100644 --- a/ash/login/ui/login_auth_user_view_unittest.cc +++ b/ash/login/ui/login_auth_user_view_unittest.cc
@@ -114,8 +114,6 @@ LoginAuthUserView::Callbacks auth_callbacks; auth_callbacks.on_auth = base::DoNothing(); auth_callbacks.on_easy_unlock_icon_hovered = base::DoNothing(); - auth_callbacks.on_easy_unlock_icon_tapped = - views::Button::PressedCallback(); auth_callbacks.on_tap = base::DoNothing(); auth_callbacks.on_remove_warning_shown = base::DoNothing(); auth_callbacks.on_remove = base::DoNothing();
diff --git a/ash/login/ui/login_password_view.cc b/ash/login/ui/login_password_view.cc index 9b6678a5..3a7afddf 100644 --- a/ash/login/ui/login_password_view.cc +++ b/ash/login/ui/login_password_view.cc
@@ -315,12 +315,10 @@ ~EasyUnlockIcon() override = default; - void Init(const OnEasyUnlockIconHovered& on_hovered, - views::Button::PressedCallback on_tapped) { + void Init(const OnEasyUnlockIconHovered& on_hovered) { DCHECK(on_hovered); on_hovered_ = on_hovered; - SetCallback(std::move(on_tapped)); hover_notifier_ = std::make_unique<HoverNotifier>( this, base::BindRepeating( @@ -687,14 +685,12 @@ void LoginPasswordView::Init( const OnPasswordSubmit& on_submit, const OnPasswordTextChanged& on_password_text_changed, - const OnEasyUnlockIconHovered& on_easy_unlock_icon_hovered, - views::Button::PressedCallback on_easy_unlock_icon_tapped) { + const OnEasyUnlockIconHovered& on_easy_unlock_icon_hovered) { DCHECK(on_submit); DCHECK(on_password_text_changed); on_submit_ = on_submit; on_password_text_changed_ = on_password_text_changed; - easy_unlock_icon_->Init(on_easy_unlock_icon_hovered, - std::move(on_easy_unlock_icon_tapped)); + easy_unlock_icon_->Init(on_easy_unlock_icon_hovered); } void LoginPasswordView::SetEnabledOnEmptyPassword(bool enabled) {
diff --git a/ash/login/ui/login_password_view.h b/ash/login/ui/login_password_view.h index 9df99d11..368304d 100644 --- a/ash/login/ui/login_password_view.h +++ b/ash/login/ui/login_password_view.h
@@ -15,7 +15,6 @@ #include "ui/base/ime/ash/ime_keyboard.h" #include "ui/base/metadata/metadata_header_macros.h" #include "ui/compositor/layer_animation_observer.h" -#include "ui/views/controls/button/button.h" #include "ui/views/controls/textfield/textfield_controller.h" #include "ui/views/view.h" @@ -104,8 +103,7 @@ // changes. void Init(const OnPasswordSubmit& on_submit, const OnPasswordTextChanged& on_password_text_changed, - const OnEasyUnlockIconHovered& on_easy_unlock_icon_hovered, - views::Button::PressedCallback on_easy_unlock_icon_tapped); + const OnEasyUnlockIconHovered& on_easy_unlock_icon_hovered); // Whether or not the password field is enabled when there is no text. void SetEnabledOnEmptyPassword(bool enabled);
diff --git a/ash/login/ui/login_password_view_test.cc b/ash/login/ui/login_password_view_test.cc index 8b35e819..520ae70b 100644 --- a/ash/login/ui/login_password_view_test.cc +++ b/ash/login/ui/login_password_view_test.cc
@@ -50,8 +50,6 @@ base::BindRepeating(&LoginPasswordViewTest::OnPasswordTextChanged, base::Unretained(this)), base::BindRepeating(&LoginPasswordViewTest::OnEasyUnlockIconHovered, - base::Unretained(this)), - base::BindRepeating(&LoginPasswordViewTest::OnEasyUnlockIconTapped, base::Unretained(this))); SetWidget(CreateWidgetWithContent(view_)); @@ -64,7 +62,6 @@ is_password_field_empty_ = is_empty; } void OnEasyUnlockIconHovered() { easy_unlock_icon_hovered_called_ = true; } - void OnEasyUnlockIconTapped() { easy_unlock_icon_tapped_called_ = true; } LoginPasswordView* view_ = nullptr; absl::optional<std::u16string> password_;
diff --git a/ash/public/cpp/BUILD.gn b/ash/public/cpp/BUILD.gn index aacacbc..0a3a570 100644 --- a/ash/public/cpp/BUILD.gn +++ b/ash/public/cpp/BUILD.gn
@@ -12,6 +12,8 @@ sources = [ "accelerator_configuration.cc", "accelerator_configuration.h", + "accelerator_keycode_lookup_cache.cc", + "accelerator_keycode_lookup_cache.h", "accelerators.cc", "accelerators.h", "accelerators_util.cc", @@ -449,6 +451,7 @@ "//components/session_manager:base", "//components/user_manager", "//components/version_info:channel", + "//ui/base/ime/ash", "//ui/base/ime/ash:ime_types", "//ui/gfx", ] @@ -459,6 +462,7 @@ source_set("unit_tests") { testonly = true sources = [ + "accelerator_keycode_lookup_cache_unittest.cc", "accelerators_util_unittest.cc", "ambient/ambient_metrics_unittest.cc", "ambient/ambient_prefs_unittest.cc", @@ -486,6 +490,7 @@ deps = [ ":cpp", ":test_support", + "//ash:test_support", "//base", "//base/test:test_support", "//chromeos/ui/vector_icons", @@ -495,6 +500,7 @@ "//skia", "//testing/gtest", "//ui/aura:test_support", + "//ui/base:test_support", "//ui/chromeos/styles:cros_styles_views", "//ui/chromeos/styles:cros_tokens_color_mappings", "//ui/compositor_extra",
diff --git a/ash/public/cpp/accelerator_keycode_lookup_cache.cc b/ash/public/cpp/accelerator_keycode_lookup_cache.cc new file mode 100644 index 0000000..b037573e --- /dev/null +++ b/ash/public/cpp/accelerator_keycode_lookup_cache.cc
@@ -0,0 +1,65 @@ +// 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 "ash/public/cpp/accelerator_keycode_lookup_cache.h" + +#include <string> + +#include "base/no_destructor.h" +#include "ui/base/ime/ash/input_method_manager.h" +#include "ui/events/keycodes/keyboard_codes_posix.h" + +namespace ash { +namespace { + +AcceleratorKeycodeLookupCache* g_instance = nullptr; + +} // namespace + +AcceleratorKeycodeLookupCache* AcceleratorKeycodeLookupCache::Get() { + return g_instance; +} + +AcceleratorKeycodeLookupCache::AcceleratorKeycodeLookupCache() { + CHECK(!g_instance); + g_instance = this; + + DCHECK(input_method::InputMethodManager::Get()); + input_method::InputMethodManager::Get()->AddObserver(this); +} + +AcceleratorKeycodeLookupCache::~AcceleratorKeycodeLookupCache() { + CHECK(input_method::InputMethodManager::Get()); + input_method::InputMethodManager::Get()->RemoveObserver(this); + + CHECK_EQ(g_instance, this); + g_instance = nullptr; +} + +void AcceleratorKeycodeLookupCache::InputMethodChanged( + input_method::InputMethodManager* manager, + Profile* profile, + bool show_message) { + key_code_to_string16_cache_.clear(); +} + +absl::optional<std::u16string> AcceleratorKeycodeLookupCache::Find( + ui::KeyboardCode key_code) { + const auto& found_iter = key_code_to_string16_cache_.find(key_code); + if (found_iter == key_code_to_string16_cache_.end()) { + return absl::nullopt; + } + return found_iter->second; +} + +void AcceleratorKeycodeLookupCache::InsertOrAssign(ui::KeyboardCode key_code, + std::u16string description) { + key_code_to_string16_cache_.insert_or_assign(key_code, description); +} + +void AcceleratorKeycodeLookupCache::Clear() { + key_code_to_string16_cache_.clear(); +} + +} // namespace ash
diff --git a/ash/public/cpp/accelerator_keycode_lookup_cache.h b/ash/public/cpp/accelerator_keycode_lookup_cache.h new file mode 100644 index 0000000..11251a8 --- /dev/null +++ b/ash/public/cpp/accelerator_keycode_lookup_cache.h
@@ -0,0 +1,55 @@ +// 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 ASH_PUBLIC_CPP_ACCELERATOR_KEYCODE_LOOKUP_CACHE_H_ +#define ASH_PUBLIC_CPP_ACCELERATOR_KEYCODE_LOOKUP_CACHE_H_ + +#include <map> +#include <string> + +#include "ash/public/cpp/ash_public_export.h" +#include "ui/base/ime/ash/input_method_manager.h" +#include "ui/events/keycodes/keyboard_codes_posix.h" + +namespace ash { + +// Thin class that observe IME change events and updates the static cache for +// more efficient lookups for `KeycodeToKeyString()`. +class ASH_PUBLIC_EXPORT AcceleratorKeycodeLookupCache + : public input_method::InputMethodManager::Observer { + public: + // Get the singleton instance. + static AcceleratorKeycodeLookupCache* Get(); + + AcceleratorKeycodeLookupCache(); + AcceleratorKeycodeLookupCache(const AcceleratorKeycodeLookupCache&) = delete; + AcceleratorKeycodeLookupCache& operator=( + const AcceleratorKeycodeLookupCache&) = delete; + ~AcceleratorKeycodeLookupCache() override; + + // InputMethodManager::Observer + // The cache is invalid when the IME changes, so this observer notifies us + // when to clear the cache. + void InputMethodChanged(input_method::InputMethodManager* manager, + Profile* profile, + bool show_message) override; + + absl::optional<std::u16string> Find(ui::KeyboardCode key_code); + + void InsertOrAssign(ui::KeyboardCode key_code, std::u16string description); + + void Clear(); + + private: + friend class AcceleratorKeycodeLookupCacheTest; + + // A cache of Keycode to string16 so that we don't have to perform a + // reverse lookup for the DomKey for every accelerator. + // On IME changes, this cache resets. + std::map<ui::KeyboardCode, std::u16string> key_code_to_string16_cache_; +}; + +} // namespace ash + +#endif // ASH_PUBLIC_CPP_ACCELERATOR_KEYCODE_LOOKUP_CACHE_H_ \ No newline at end of file
diff --git a/ash/public/cpp/accelerator_keycode_lookup_cache_unittest.cc b/ash/public/cpp/accelerator_keycode_lookup_cache_unittest.cc new file mode 100644 index 0000000..e47a068 --- /dev/null +++ b/ash/public/cpp/accelerator_keycode_lookup_cache_unittest.cc
@@ -0,0 +1,88 @@ +// 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 "ash/public/cpp/accelerator_keycode_lookup_cache.h" + +#include <memory> +#include <string> + +#include "ui/base/ime/ash/input_method_manager.h" +#include "ui/base/ime/ash/mock_input_method_manager.h" +#include "ui/events/keycodes/keyboard_codes_posix.h" +#include "ui/events/ozone/layout/keyboard_layout_engine_manager.h" +#include "ui/events/ozone/layout/stub/stub_keyboard_layout_engine.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace ash { + +class AcceleratorKeycodeLookupCacheTest : public testing::Test { + public: + class TestInputMethodManager : public input_method::MockInputMethodManager { + public: + void AddObserver( + input_method::InputMethodManager::Observer* observer) override { + observers_.AddObserver(observer); + } + + void RemoveObserver( + input_method::InputMethodManager::Observer* observer) override { + observers_.RemoveObserver(observer); + } + + // Calls all observers with Observer::InputMethodChanged + void NotifyInputMethodChanged() { + for (auto& observer : observers_) { + observer.InputMethodChanged( + /*manager=*/this, /*profile=*/nullptr, /*show_message=*/false); + } + } + + base::ObserverList<InputMethodManager::Observer>::Unchecked observers_; + }; + + AcceleratorKeycodeLookupCacheTest() { + input_method_manager_ = new TestInputMethodManager(); + input_method::InputMethodManager::Initialize(input_method_manager_); + + layout_engine_ = std::make_unique<ui::StubKeyboardLayoutEngine>(); + ui::KeyboardLayoutEngineManager::ResetKeyboardLayoutEngine(); + ui::KeyboardLayoutEngineManager::SetKeyboardLayoutEngine( + layout_engine_.get()); + + lookup_cache_ = std::make_unique<AcceleratorKeycodeLookupCache>(); + } + + ~AcceleratorKeycodeLookupCacheTest() override = default; + + protected: + std::map<ui::KeyboardCode, std::u16string> cache() { + return lookup_cache_->key_code_to_string16_cache_; + } + + std::unique_ptr<AcceleratorKeycodeLookupCache> lookup_cache_; + std::unique_ptr<ui::StubKeyboardLayoutEngine> layout_engine_; + // Test global singleton. Delete is handled by InputMethodManager::Shutdown(). + base::raw_ptr<TestInputMethodManager> input_method_manager_; +}; + +TEST_F(AcceleratorKeycodeLookupCacheTest, ImeChanged) { + const std::u16string expected = u"a"; + + EXPECT_TRUE(cache().empty()); + lookup_cache_->InsertOrAssign(ui::KeyboardCode::VKEY_A, expected); + // Expect the cache to be populated. + absl::optional<std::u16string> found_key_string = + lookup_cache_->Find(ui::KeyboardCode::VKEY_A); + EXPECT_TRUE(found_key_string.has_value()); + EXPECT_EQ(expected, found_key_string.value()); + + // Trigger IME change event, expect the cache to be cleared. + input_method_manager_->NotifyInputMethodChanged(); + EXPECT_TRUE(cache().empty()); + found_key_string = lookup_cache_->Find(ui::KeyboardCode::VKEY_A); + EXPECT_FALSE(found_key_string.has_value()); +} + +} // namespace ash
diff --git a/ash/public/cpp/accelerators_util.cc b/ash/public/cpp/accelerators_util.cc index 22f2165..cde5223 100644 --- a/ash/public/cpp/accelerators_util.cc +++ b/ash/public/cpp/accelerators_util.cc
@@ -6,8 +6,10 @@ #include <string> +#include "ash/public/cpp/accelerator_keycode_lookup_cache.h" #include "base/logging.h" #include "base/strings/utf_string_conversions.h" +#include "ui/base/ime/ash/input_method_manager.h" #include "ui/base/ui_base_features.h" #include "ui/events/event_constants.h" #include "ui/events/keycodes/dom/dom_codes_array.h" @@ -71,6 +73,8 @@ // normally in the loop below. For the positional keys, the |DomCode| is // then mapped to the |DomKey| in the current layout which represents the // glyph/character that appears on the key (and usually when typed). + + // Positional keys are direct lookups, no need to store in the cache. if (remap_positional_key && ::features::IsImprovedKeyboardShortcutsEnabled()) { ui::DomCode dom_code = @@ -91,16 +95,38 @@ } } + const absl::optional<std::u16string> cached_key_string = + AcceleratorKeycodeLookupCache::Get()->Find(key_code); + // Cache hit, return immediately. + if (cached_key_string.has_value()) { + return std::move(cached_key_string).value(); + } + + // Cache miss, get the key string and store it. for (const auto& dom_code : ui::kDomCodesArray) { if (!layout_engine->Lookup(dom_code, /*event_flags=*/ui::EF_NONE, &dom_key, &key_code_to_compare)) { continue; } - if (key_code_to_compare != key_code || !dom_key.IsValid() || - dom_key.IsDeadKey()) { + + // Even though this isn't what we're looking for, we should still populate + // the cache as we're iterating through the DomCode array. + if (key_code_to_compare != key_code) { + AcceleratorKeycodeLookupCache::Get()->InsertOrAssign( + key_code_to_compare, + base::UTF8ToUTF16(ui::KeycodeConverter::DomKeyToKeyString(dom_key))); continue; } - return base::UTF8ToUTF16(ui::KeycodeConverter::DomKeyToKeyString(dom_key)); + + if (!dom_key.IsValid() || dom_key.IsDeadKey()) { + continue; + } + + // Found the correct lookup, cache and return the string. + const std::u16string key_string = + base::UTF8ToUTF16(ui::KeycodeConverter::DomKeyToKeyString(dom_key)); + AcceleratorKeycodeLookupCache::Get()->InsertOrAssign(key_code, key_string); + return key_string; } return std::u16string(); }
diff --git a/ash/public/cpp/accelerators_util_unittest.cc b/ash/public/cpp/accelerators_util_unittest.cc index 2f52b22..9291e2a 100644 --- a/ash/public/cpp/accelerators_util_unittest.cc +++ b/ash/public/cpp/accelerators_util_unittest.cc
@@ -7,7 +7,11 @@ #include <memory> #include <string> +#include "ash/public/cpp/accelerator_keycode_lookup_cache.h" +#include "ash/shell.h" +#include "ash/test/ash_test_base.h" #include "base/strings/utf_string_conversions.h" +#include "ui/base/ime/ash/mock_input_method_manager.h" #include "ui/events/keycodes/dom/dom_codes_array.h" #include "ui/events/keycodes/dom/dom_key.h" #include "ui/events/keycodes/keyboard_codes_posix.h" @@ -18,7 +22,7 @@ namespace ash { -class AcceleratorsUtilTest : public testing::Test { +class AcceleratorsUtilTest : public AshTestBase { public: AcceleratorsUtilTest() { layout_engine_ = std::make_unique<ui::StubKeyboardLayoutEngine>(); @@ -35,7 +39,16 @@ TEST_F(AcceleratorsUtilTest, BasicDomCode) { const std::u16string expected = u"a"; + + absl::optional<std::u16string> found_key_string = + AcceleratorKeycodeLookupCache::Get()->Find(ui::KeyboardCode::VKEY_A); + EXPECT_FALSE(found_key_string.has_value()); EXPECT_EQ(expected, KeycodeToKeyString(ui::KeyboardCode::VKEY_A)); + // Expect the cache to be populated. + found_key_string = + AcceleratorKeycodeLookupCache::Get()->Find(ui::KeyboardCode::VKEY_A); + EXPECT_TRUE(found_key_string.has_value()); + EXPECT_EQ(expected, found_key_string.value()); } TEST_F(AcceleratorsUtilTest, PositionalKeyCode) { @@ -64,7 +77,16 @@ TEST_F(AcceleratorsUtilTest, NonAlphanumericKey) { const std::u16string expected = u"Meta"; + absl::optional<std::u16string> found_key_string = + AcceleratorKeycodeLookupCache::Get()->Find( + ui::KeyboardCode::VKEY_COMMAND); + EXPECT_FALSE(found_key_string.has_value()); EXPECT_EQ(expected, KeycodeToKeyString(ui::KeyboardCode::VKEY_COMMAND)); + + found_key_string = AcceleratorKeycodeLookupCache::Get()->Find( + ui::KeyboardCode::VKEY_COMMAND); + EXPECT_TRUE(found_key_string.has_value()); + EXPECT_EQ(expected, found_key_string.value()); } } // namespace ash
diff --git a/ash/public/cpp/app_list/app_list_client.h b/ash/public/cpp/app_list/app_list_client.h index e20babb..6c16af6 100644 --- a/ash/public/cpp/app_list/app_list_client.h +++ b/ash/public/cpp/app_list/app_list_client.h
@@ -117,6 +117,16 @@ // implementation, this can return nullptr. virtual AppListNotifier* GetNotifier() = 0; + // Queries whether launcher search IPH should be shown and update + // SearchBoxModel. + virtual void QueryWouldTriggerLauncherSearchIph() = 0; + + // `feature_engagement::Tracker` needs to be initialized before this method + // gets called. Call `WouldTriggerLauncherSearchIph` to initialize it. This + // returns false if the tracker is not initialized yet. + virtual std::unique_ptr<ScopedIphSession> + CreateLauncherSearchIphSession() = 0; + // Invoked to load an icon of the app identified by `app_id`. virtual void LoadIcon(int profile_id, const std::string& app_id) = 0;
diff --git a/ash/public/cpp/app_list/app_list_types.h b/ash/public/cpp/app_list/app_list_types.h index 234d79f..25d47a1 100644 --- a/ash/public/cpp/app_list/app_list_types.h +++ b/ash/public/cpp/app_list/app_list_types.h
@@ -748,6 +748,18 @@ int position_index; }; +// `ScopedIphSession` manages an IPH session. A UI must show an IPH once an +// IPH session gets created. Also the UI must destroy +// `ScopedIphSession` when it has stopped showing an IPH. +class ASH_PUBLIC_EXPORT ScopedIphSession { + public: + ScopedIphSession() = default; + virtual ~ScopedIphSession() = default; + + ScopedIphSession(const ScopedIphSession&) = delete; + ScopedIphSession& operator=(const ScopedIphSession&) = delete; +}; + using SearchResultIdWithPositionIndices = std::vector<SearchResultIdWithPositionIndex>;
diff --git a/ash/public/cpp/cast_config_controller.h b/ash/public/cpp/cast_config_controller.h index 8d4c40e..78f9c89 100644 --- a/ash/public/cpp/cast_config_controller.h +++ b/ash/public/cpp/cast_config_controller.h
@@ -40,6 +40,11 @@ kDesktop, }; +struct FreezeInfo { + bool can_freeze = false; + bool is_frozen = false; +}; + struct ASH_PUBLIC_EXPORT CastRoute { std::string id; std::string title; @@ -50,6 +55,10 @@ // What is source of the content? For example, we could be DIAL casting a // tab or mirroring the entire desktop. ContentSource content_source = ContentSource::kUnknown; + + // The state of freeze for the route. Is the route able to be frozen, and + // is it currently frozen? + FreezeInfo freeze_info; }; struct ASH_PUBLIC_EXPORT SinkAndRoute { @@ -110,6 +119,11 @@ // A user-initiated request to stop the given cast session. virtual void StopCasting(const std::string& route_id) = 0; + // Freezes and Unfreezes a cast mirroring route (Displayed to users as + // pause/resume). + virtual void FreezeRoute(const std::string& route_id) = 0; + virtual void UnfreezeRoute(const std::string& route_id) = 0; + protected: CastConfigController(); virtual ~CastConfigController();
diff --git a/ash/public/cpp/login_types.h b/ash/public/cpp/login_types.h index bfbf4b47..864edb4 100644 --- a/ash/public/cpp/login_types.h +++ b/ash/public/cpp/login_types.h
@@ -173,11 +173,6 @@ // TODO(jdufault): Always populate and use |aria_label|, even if |tooltip| is // non-empty. std::u16string aria_label; - // If true, clicking the easy unlock icon should fire a hardlock event which - // will disable easy unlock. The hardlock event will request a new icon - // display via a separate EasyUnlockIconsOption update. See - // LoginScreenClient::HardlockPod. - bool hardlock_on_click = false; }; // Enterprise information about a managed device.
diff --git a/ash/public/mojom/accelerator_keys_mojom_traits.cc b/ash/public/mojom/accelerator_keys_mojom_traits.cc index f993b206..c8bcd59 100644 --- a/ash/public/mojom/accelerator_keys_mojom_traits.cc +++ b/ash/public/mojom/accelerator_keys_mojom_traits.cc
@@ -582,6 +582,9 @@ case mojom_vkey::kKeyL: *out = ui::KeyboardCode::VKEY_L; return true; + case mojom_vkey::kKeyM: + *out = ui::KeyboardCode::VKEY_M; + return true; case mojom_vkey::kKeyN: *out = ui::KeyboardCode::VKEY_N; return true;
diff --git a/ash/quick_pair/fast_pair_handshake/fast_pair_encryption_fuzzer.cc b/ash/quick_pair/fast_pair_handshake/fast_pair_encryption_fuzzer.cc index 07dc8b95..66f3ee92 100644 --- a/ash/quick_pair/fast_pair_handshake/fast_pair_encryption_fuzzer.cc +++ b/ash/quick_pair/fast_pair_handshake/fast_pair_encryption_fuzzer.cc
@@ -36,42 +36,59 @@ } // namespace +namespace ash { +namespace quick_pair { +namespace fast_pair_encryption { + extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // Enforce a minimum input size so that we can pass in valid parameters - // to EncryptBytes and GenerateKeysWithEcdhKeyAgreement. - if (size < 2 * ash::quick_pair::fast_pair_decryption::kBlockByteSize) + // to EncryptBytes(), GenerateKeysWithEcdhKeyAgreement(), + // GenerateHmacSha256(), and EncryptAdditionalData(). + size_t min_size = 2 * ash::quick_pair::fast_pair_decryption::kBlockByteSize + + kNonceSizeBytes + kSecretKeySizeBytes; + if (size < min_size) { return 0; + } + // Generate data needed for testing. static base::NoDestructor<Environment> env; FuzzedDataProvider fuzzed_data(data, size); std::vector<uint8_t> aes_key_bytes = fuzzed_data.ConsumeBytes<uint8_t>( ash::quick_pair::fast_pair_decryption::kBlockByteSize); std::array<uint8_t, ash::quick_pair::fast_pair_decryption::kBlockByteSize> - aes_key_arr; - std::copy_n(aes_key_bytes.begin(), - ash::quick_pair::fast_pair_decryption::kBlockByteSize, - aes_key_arr.begin()); + aes_key_arr{*aes_key_bytes.data()}; std::vector<uint8_t> data_bytes = fuzzed_data.ConsumeBytes<uint8_t>( ash::quick_pair::fast_pair_decryption::kBlockByteSize); std::array<uint8_t, ash::quick_pair::fast_pair_decryption::kBlockByteSize> - data_arr; - std::copy_n(data_bytes.begin(), - ash::quick_pair::fast_pair_decryption::kBlockByteSize, - data_arr.begin()); + data_arr{*data_bytes.data()}; - ash::quick_pair::fast_pair_encryption::EncryptBytes(aes_key_arr, data_arr); + std::vector<uint8_t> secret_key_bytes = + fuzzed_data.ConsumeBytes<uint8_t>(kSecretKeySizeBytes); + std::array<uint8_t, kSecretKeySizeBytes> secret_key_arr{ + *secret_key_bytes.data()}; + + std::vector<uint8_t> nonce_bytes = + fuzzed_data.ConsumeBytes<uint8_t>(kNonceSizeBytes); + std::array<uint8_t, kNonceSizeBytes> nonce_arr{*nonce_bytes.data()}; + + std::string input_data_string = fuzzed_data.ConsumeRandomLengthString(); + std::vector<uint8_t> input_data{input_data_string.begin(), + input_data_string.end()}; + + // Test FastPairEncryption functions with generated data. + EncryptBytes(aes_key_arr, data_arr); + GenerateHmacSha256(secret_key_arr, nonce_arr, input_data); + EncryptAdditionalData(secret_key_arr, nonce_arr, input_data); // In order to fuzz a valid EC_POINT, the fuzz needs to have at least // kXSize + kYSize bytes remaining. For simplicity, exit early if there // are not exactly as many bytes as required. - if (size != 2 * ash::quick_pair::fast_pair_decryption::kBlockByteSize + - kXSize + kYSize) { + if (fuzzed_data.remaining_bytes() < kXSize + kYSize) { std::string invalid_len_string = fuzzed_data.ConsumeRandomLengthString(); - ash::quick_pair::fast_pair_encryption::GenerateKeysWithEcdhKeyAgreement( - invalid_len_string); + GenerateKeysWithEcdhKeyAgreement(invalid_len_string); return 0; } @@ -109,8 +126,11 @@ std::string anti_spoofing_key(buffer.data() + 1, buffer.data() + kKeySize); DCHECK(anti_spoofing_key.length() == kKeySize - 1); - ash::quick_pair::fast_pair_encryption::GenerateKeysWithEcdhKeyAgreement( - anti_spoofing_key); + GenerateKeysWithEcdhKeyAgreement(anti_spoofing_key); return 0; } + +} // namespace fast_pair_encryption +} // namespace quick_pair +} // namespace ash
diff --git a/ash/search_box/search_box_view_base.cc b/ash/search_box/search_box_view_base.cc index 7bcc3085..15a1db27 100644 --- a/ash/search_box/search_box_view_base.cc +++ b/ash/search_box/search_box_view_base.cc
@@ -36,6 +36,7 @@ #include "ui/views/controls/image_view.h" #include "ui/views/controls/label.h" #include "ui/views/controls/textfield/textfield.h" +#include "ui/views/layout/box_layout.h" #include "ui/views/layout/box_layout_view.h" #include "ui/views/layout/fill_layout.h" #include "ui/views/layout/layout_provider.h" @@ -346,7 +347,11 @@ const int between_child_spacing = kInnerPadding - views::LayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_TEXTFIELD_HORIZONTAL_TEXT_PADDING); - content_container_ = AddChildView(std::make_unique<views::BoxLayoutView>()); + iph_container_ = AddChildView(std::make_unique<views::BoxLayoutView>()); + iph_container_->SetOrientation(views::BoxLayout::Orientation::kVertical); + + content_container_ = + iph_container_->AddChildView(std::make_unique<views::BoxLayoutView>()); content_container_->SetCrossAxisAlignment( views::BoxLayout::CrossAxisAlignment::kCenter); content_container_->SetMinimumCrossAxisSize(kSearchBoxPreferredHeight); @@ -497,6 +502,20 @@ return search_icon_; } +void SearchBoxViewBase::SetIphView(std::unique_ptr<views::View> view) { + if (iph_view()) { + DCHECK(false) << "SetIphView gets called with an IPH view being shown."; + + DeleteIphView(); + } + + iph_view_tracker_.SetView(iph_container_->AddChildView(std::move(view))); +} + +void SearchBoxViewBase::DeleteIphView() { + iph_container_->RemoveChildViewT(iph_view()); +} + void SearchBoxViewBase::MaybeSetAutocompleteGhostText( const std::u16string& title, const std::u16string& category) {
diff --git a/ash/search_box/search_box_view_base.h b/ash/search_box/search_box_view_base.h index fe0436c..8cb5fb8 100644 --- a/ash/search_box/search_box_view_base.h +++ b/ash/search_box/search_box_view_base.h
@@ -17,6 +17,7 @@ #include "ui/views/controls/button/image_button.h" #include "ui/views/controls/textfield/textfield_controller.h" #include "ui/views/view.h" +#include "ui/views/view_tracker.h" namespace gfx { class ImageSkia; @@ -85,6 +86,10 @@ views::ImageView* search_icon(); views::Textfield* search_box() { return search_box_; } + void SetIphView(std::unique_ptr<views::View> iph_view); + void DeleteIphView(); + raw_ptr<views::View> iph_view() { return iph_view_tracker_.view(); } + // Called when the query in the search box textfield changes. The search box // implementation is expected to handle the new query. // `query` the new search box query. @@ -218,6 +223,7 @@ void OnEnabledChanged(); // Owned by views hierarchy. + raw_ptr<views::BoxLayoutView> iph_container_; views::BoxLayoutView* content_container_; SearchIconImageView* search_icon_ = nullptr; SearchBoxImageButton* assistant_button_ = nullptr; @@ -233,6 +239,8 @@ views::View* search_box_button_container_ = nullptr; + views::ViewTracker iph_view_tracker_; + // Whether the search box is active. bool is_search_box_active_ = false; // Whether to show close button if the search box is active and empty.
diff --git a/ash/shelf/hotseat_widget.cc b/ash/shelf/hotseat_widget.cc index 5872d90..deb1cb68 100644 --- a/ash/shelf/hotseat_widget.cc +++ b/ash/shelf/hotseat_widget.cc
@@ -25,8 +25,11 @@ #include "ash/wm/overview/overview_controller.h" #include "ash/wm/overview/overview_observer.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" +#include "base/functional/bind.h" +#include "base/functional/callback_helpers.h" #include "base/i18n/rtl.h" #include "base/metrics/histogram_macros.h" +#include "chromeos/constants/chromeos_features.h" #include "ui/aura/scoped_window_targeter.h" #include "ui/aura/window_targeter.h" #include "ui/compositor/animation_throughput_reporter.h" @@ -426,6 +429,10 @@ // Updates the hotseat background. void UpdateTranslucentBackground(); + // Updates the highlight border rounded corner radius or the type according to + // the visibility of shadow. + void UpdateHighlightBorder(bool update_corner_radius); + void SetTranslucentBackground(const gfx::Rect& translucent_background_bounds); // Sets whether the background should be blurred as requested by the argument, @@ -476,6 +483,9 @@ SkColor target_color_ = SK_ColorTRANSPARENT; std::unique_ptr<SystemShadow> shadow_; + + // The type of highlight border. + views::HighlightBorder::Type border_type_; }; HotseatWidget::DelegateView::~DelegateView() { @@ -524,6 +534,11 @@ } void HotseatWidget::DelegateView::UpdateTranslucentBackground() { + // Update highlight border after updating the visibility of shadow. + base::ScopedClosureRunner update_highlight_border( + base::BindOnce(&DelegateView::UpdateHighlightBorder, + base::Unretained(this), /*update_corner_radius=*/false)); + if (!HotseatWidget::ShouldShowHotseatBackground()) { translucent_background_->SetVisible(false); SetBackgroundBlur(false); @@ -548,6 +563,31 @@ shadow_->SetContentBounds(background_bounds); } +void HotseatWidget::DelegateView::UpdateHighlightBorder( + bool update_corner_radius) { + const bool is_jelly_enabled = chromeos::features::IsJellyrollEnabled(); + views::HighlightBorder::Type border_type; + if (!is_jelly_enabled) { + border_type = views::HighlightBorder::Type::kHighlightBorder1; + } else { + border_type = shadow_->GetLayer()->visible() + ? views::HighlightBorder::Type::kHighlightBorderOnShadow + : views::HighlightBorder::Type::kHighlightBorderNoShadow; + } + + if (GetBorder() && !update_corner_radius && border_type_ == border_type) { + return; + } + + const float radius = hotseat_widget_->GetHotseatSize() / 2.0f; + border_type_ = border_type; + auto border = std::make_unique<views::HighlightBorder>( + radius, border_type_, + /*use_light_colors=*/!features::IsDarkLightModeEnabled() && + !is_jelly_enabled); + translucent_background_->SetBorder(std::move(border)); +} + void HotseatWidget::DelegateView::SetTranslucentBackground( const gfx::Rect& background_bounds) { DCHECK(HotseatWidget::ShouldShowHotseatBackground()); @@ -595,12 +635,7 @@ if (translucent_background_->layer()->rounded_corner_radii() != rounded_corners) { translucent_background_->layer()->SetRoundedCornerRadius(rounded_corners); - if (features::IsDarkLightModeEnabled()) { - translucent_background_->SetBorder( - std::make_unique<views::HighlightBorder>( - radius, views::HighlightBorder::Type::kHighlightBorder1, - /*use_light_colors=*/!features::IsDarkLightModeEnabled())); - } + UpdateHighlightBorder(/*update_corner_radius=*/true); } const gfx::Rect mirrored_bounds = GetMirroredRect(background_bounds); @@ -886,7 +921,9 @@ if (hotseat_target_state == HotseatState::kShownHomeLauncher) { if (ShelfConfig::Get()->elevate_tablet_mode_app_bar()) { - return gfx::Size(shelf_bounds.width(), hotseat_size); + return gfx::Size( + shelf_bounds.width() - ShelfConfig::Get()->button_spacing() * 2, + hotseat_size); } } return app_bar_size;
diff --git a/ash/shelf/shelf_widget.cc b/ash/shelf/shelf_widget.cc index 967a225..60fe0744 100644 --- a/ash/shelf/shelf_widget.cc +++ b/ash/shelf/shelf_widget.cc
@@ -38,6 +38,7 @@ #include "ash/wm/work_area_insets.h" #include "base/command_line.h" #include "base/functional/bind.h" +#include "chromeos/constants/chromeos_features.h" #include "ui/compositor/layer.h" #include "ui/compositor/layer_delegate.h" #include "ui/compositor/layer_owner.h" @@ -289,7 +290,9 @@ SkColor background_color_; float corner_radius_ = 0.0f; views::HighlightBorder::Type highlight_border_type_ = - views::HighlightBorder::Type::kHighlightBorder1; + chromeos::features::IsJellyrollEnabled() + ? views::HighlightBorder::Type::kHighlightBorderNoShadow + : views::HighlightBorder::Type::kHighlightBorder1; }; } // namespace @@ -938,7 +941,10 @@ return; hotseat_transition_animator_->OnHotseatStateChanged(old_state, new_state); - if (new_state == HotseatState::kExtended) { + if (chromeos::features::IsJellyrollEnabled()) { + delegate_view_->opaque_background()->SetBorderType( + views::HighlightBorder::Type::kHighlightBorderNoShadow); + } else if (new_state == HotseatState::kExtended) { delegate_view_->opaque_background()->SetBorderType( views::HighlightBorder::Type::kHighlightBorder2); } else {
diff --git a/ash/shell.cc b/ash/shell.cc index cf3f858..3f5264f 100644 --- a/ash/shell.cc +++ b/ash/shell.cc
@@ -92,6 +92,7 @@ #include "ash/multi_device_setup/multi_device_notification_presenter.h" #include "ash/policy/policy_recommendation_restorer.h" #include "ash/projector/projector_controller_impl.h" +#include "ash/public/cpp/accelerator_keycode_lookup_cache.h" #include "ash/public/cpp/ash_prefs.h" #include "ash/public/cpp/holding_space/holding_space_controller.h" #include "ash/public/cpp/nearby_share_delegate.h" @@ -115,6 +116,7 @@ #include "ash/shutdown_controller_impl.h" #include "ash/style/ash_color_mixer.h" #include "ash/style/ash_color_provider.h" +#include "ash/style/color_palette_controller.h" #include "ash/style/dark_light_mode_controller_impl.h" #include "ash/style/style_util.h" #include "ash/system/audio/audio_effects_controller.h" @@ -922,6 +924,10 @@ ash_color_provider_.reset(); + // Depends on `dark_light_mode_controller_` and `wallpaper_controller_` so it + // should be destroyed first. + color_palette_controller_.reset(); + // Depends on `geolocation_controller_` and `wallpaper_controller_`, so it // must be destructed before the geolocation controller and wallpaper // controller. @@ -1234,6 +1240,9 @@ dark_light_mode_controller_ = std::make_unique<DarkLightModeControllerImpl>(); + color_palette_controller_ = ColorPaletteController::Create( + dark_light_mode_controller_.get(), wallpaper_controller_.get()); + // Privacy Screen depends on the display manager, so initialize it after // display manager was properly initialized. privacy_screen_controller_ = std::make_unique<PrivacyScreenController>(); @@ -1318,6 +1327,9 @@ cursor_manager_->SetDisplay( display::Screen::GetScreen()->GetPrimaryDisplay()); + // Must be initialized after InputMethodManager. + accelerator_keycode_lookup_cache_ = + std::make_unique<AcceleratorKeycodeLookupCache>(); ash_accelerator_configuration_ = std::make_unique<AshAcceleratorConfiguration>(); ash_accelerator_configuration_->Initialize();
diff --git a/ash/shell.h b/ash/shell.h index d53c57d65..ff0b1e23 100644 --- a/ash/shell.h +++ b/ash/shell.h
@@ -89,6 +89,7 @@ namespace ash { class AcceleratorControllerImpl; +class AcceleratorKeycodeLookupCache; class AcceleratorTracker; class AccessibilityControllerImpl; class AccessibilityDelegate; @@ -115,6 +116,7 @@ class CalendarController; class CameraEffectsController; class CaptureModeController; +class ColorPaletteController; class ControlVHistogramRecorder; class CrosDisplayConfig; class DarkLightModeControllerImpl; @@ -429,6 +431,9 @@ CameraEffectsController* camera_effects_controller() { return camera_effects_controller_.get(); } + ColorPaletteController* color_palette_controller() { + return color_palette_controller_.get(); + } CrosDisplayConfig* cros_display_config() { return cros_display_config_.get(); } @@ -891,6 +896,8 @@ std::unique_ptr<AshAcceleratorConfiguration> ash_accelerator_configuration_; std::unique_ptr<AcceleratorControllerImpl> accelerator_controller_; + std::unique_ptr<AcceleratorKeycodeLookupCache> + accelerator_keycode_lookup_cache_; std::unique_ptr<AccessibilityControllerImpl> accessibility_controller_; std::unique_ptr<AccessibilityDelegate> accessibility_delegate_; std::unique_ptr<AccessibilityFocusRingControllerImpl> @@ -909,6 +916,7 @@ std::unique_ptr<BrightnessControlDelegate> brightness_control_delegate_; std::unique_ptr<CalendarController> calendar_controller_; std::unique_ptr<CameraEffectsController> camera_effects_controller_; + std::unique_ptr<ColorPaletteController> color_palette_controller_; std::unique_ptr<CrosDisplayConfig> cros_display_config_; std::unique_ptr<curtain::SecurityCurtainController> security_curtain_controller_;
diff --git a/ash/system/cast/cast_feature_pod_controller_unittest.cc b/ash/system/cast/cast_feature_pod_controller_unittest.cc index 59dae6f..5720d297 100644 --- a/ash/system/cast/cast_feature_pod_controller_unittest.cc +++ b/ash/system/cast/cast_feature_pod_controller_unittest.cc
@@ -39,6 +39,8 @@ } void CastToSink(const std::string& sink_id) override {} void StopCasting(const std::string& route_id) override {} + void FreezeRoute(const std::string& route_id) override {} + void UnfreezeRoute(const std::string& route_id) override {} bool has_media_router_ = true; bool has_sinks_and_routes_ = false;
diff --git a/ash/system/cast/cast_notification_controller.cc b/ash/system/cast/cast_notification_controller.cc index fab9632..6a0b64d 100644 --- a/ash/system/cast/cast_notification_controller.cc +++ b/ash/system/cast/cast_notification_controller.cc
@@ -91,7 +91,17 @@ displayed_route_id_ = route.id; message_center::RichNotificationData data; - data.buttons.push_back(message_center::ButtonInfo( + + if (route.freeze_info.can_freeze) { + displayed_route_is_frozen_ = route.freeze_info.is_frozen; + data.buttons.emplace_back(message_center::ButtonInfo( + displayed_route_is_frozen_ + ? l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_CAST_RESUME) + : l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_CAST_PAUSE))); + freeze_button_index_ = data.buttons.size() - 1; + } + + data.buttons.emplace_back(message_center::ButtonInfo( l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_CAST_STOP))); std::unique_ptr<Notification> notification = CreateSystemNotificationPtr( @@ -103,7 +113,7 @@ NotificationCatalogName::kCast), data, base::MakeRefCounted<message_center::HandleNotificationClickDelegate>( - base::BindRepeating(&CastNotificationController::StopCasting, + base::BindRepeating(&CastNotificationController::PressedCallback, weak_ptr_factory_.GetWeakPtr())), kSystemMenuCastIcon, message_center::SystemNotificationWarningLevel::NORMAL); @@ -114,9 +124,29 @@ } } -void CastNotificationController::StopCasting(absl::optional<int> button_index) { +void CastNotificationController::PressedCallback( + absl::optional<int> button_index) { + if (freeze_button_index_ && button_index == freeze_button_index_) { + FreezePressed(); + } else { + // Handles the case that the stop button is pressed, or the notification is + // pressed not on a button. + StopCasting(); + } +} + +void CastNotificationController::StopCasting() { CastConfigController::Get()->StopCasting(displayed_route_id_); base::RecordAction(base::UserMetricsAction("StatusArea_Cast_StopCast")); } +void CastNotificationController::FreezePressed() { + auto* controller = CastConfigController::Get(); + if (displayed_route_is_frozen_) { + controller->UnfreezeRoute(displayed_route_id_); + } else { + controller->FreezeRoute(displayed_route_id_); + } +} + } // namespace ash
diff --git a/ash/system/cast/cast_notification_controller.h b/ash/system/cast/cast_notification_controller.h index 805b820..4dcc493 100644 --- a/ash/system/cast/cast_notification_controller.h +++ b/ash/system/cast/cast_notification_controller.h
@@ -7,12 +7,14 @@ #include "ash/public/cpp/cast_config_controller.h" +#include "ash/ash_export.h" #include "base/memory/weak_ptr.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace ash { -class CastNotificationController : public CastConfigController::Observer { +class ASH_EXPORT CastNotificationController + : public CastConfigController::Observer { public: CastNotificationController(); @@ -26,12 +28,27 @@ void OnDevicesUpdated(const std::vector<SinkAndRoute>& devices) override; private: - void StopCasting(absl::optional<int> button_index); + // The callback that is triggered when the cast notification is pressed, + // either on the body or buttons. + void PressedCallback(absl::optional<int> button_index); + + // Stops casting to the current displayed_route_id_ + void StopCasting(); + + // If the current displayed_route_id_ can be frozen / unfrozen (displayed as + // pause / resume to users), then this function freezes or unfreezes the + // route given by displayed_route_id_ depending on its current state. + void FreezePressed(); // The cast activity id that we are displaying. If the user stops a cast, we // send this value to the config delegate so that we stop the right cast. std::string displayed_route_id_; + // Freeze info for the route we are currently displaying. If the user + // interacts with a cast, we use these values. + absl::optional<int> freeze_button_index_; + bool displayed_route_is_frozen_ = false; + base::WeakPtrFactory<CastNotificationController> weak_ptr_factory_{this}; };
diff --git a/ash/system/cast/cast_notification_controller_unittest.cc b/ash/system/cast/cast_notification_controller_unittest.cc new file mode 100644 index 0000000..f657137 --- /dev/null +++ b/ash/system/cast/cast_notification_controller_unittest.cc
@@ -0,0 +1,218 @@ +// 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 "ash/system/cast/cast_notification_controller.h" + +#include "ash/public/cpp/cast_config_controller.h" +#include "ash/test/ash_test_base.h" +#include "ui/message_center/message_center.h" + +namespace ash { +namespace { + +class TestCastConfigController : public CastConfigController { + public: + TestCastConfigController() = default; + TestCastConfigController(const TestCastConfigController&) = delete; + TestCastConfigController& operator=(const TestCastConfigController&) = delete; + ~TestCastConfigController() override = default; + + // CastConfigController: + void AddObserver(Observer* observer) override {} + void RemoveObserver(Observer* observer) override {} + bool HasMediaRouterForPrimaryProfile() const override { return true; } + bool HasSinksAndRoutes() const override { return has_sinks_and_routes_; } + bool HasActiveRoute() const override { return has_active_routes_; } + bool AccessCodeCastingEnabled() const override { + return access_code_casting_enabled_; + } + void RequestDeviceRefresh() override {} + const std::vector<SinkAndRoute>& GetSinksAndRoutes() override { + return sinks_and_routes_; + } + void CastToSink(const std::string& sink_id) override {} + void StopCasting(const std::string& route_id) override { + ++stop_casting_count_; + stop_casting_route_id_ = route_id; + } + void FreezeRoute(const std::string& route_id) override { + ++freeze_route_count_; + freeze_route_route_id_ = route_id; + } + void UnfreezeRoute(const std::string& route_id) override { + ++unfreeze_route_count_; + unfreeze_route_route_id_ = route_id; + } + + bool has_sinks_and_routes_ = false; + bool has_active_routes_ = false; + bool access_code_casting_enabled_ = false; + std::vector<SinkAndRoute> sinks_and_routes_; + size_t stop_casting_count_ = 0; + std::string stop_casting_route_id_; + size_t freeze_route_count_ = 0; + std::string freeze_route_route_id_; + size_t unfreeze_route_count_ = 0; + std::string unfreeze_route_route_id_; +}; + +SinkAndRoute CreateDeviceNoRoute() { + SinkAndRoute device; + device.sink.id = "fake_sink_id_noroute"; + device.sink.name = "Sink Name NoRoute"; + device.sink.sink_icon_type = SinkIconType::kCast; + + return device; +} + +SinkAndRoute CreateDeviceNonlocalRoute() { + SinkAndRoute device; + device.sink.id = "fake_sink_id_nonlocalroute"; + device.sink.name = "Sink Name NonlocalRoute"; + device.sink.sink_icon_type = SinkIconType::kCast; + device.route.id = "fake_route_id_nonlocalroute"; + device.route.title = "Casting tab"; + device.route.is_local_source = false; + device.route.content_source = ContentSource::kTab; + + return device; +} + +SinkAndRoute CreateDeviceLocalRoute() { + SinkAndRoute device; + device.sink.id = "fake_sink_id_localroute"; + device.sink.name = "Sink Name localRoute"; + device.sink.sink_icon_type = SinkIconType::kCast; + device.route.id = "fake_route_id_localroute"; + device.route.title = "Casting tab"; + device.route.is_local_source = true; + device.route.content_source = ContentSource::kTab; + + return device; +} + +} // namespace + +class CastNotificationControllerTest : public AshTestBase { + public: + CastNotificationControllerTest() = default; + + CastNotificationControllerTest(const CastNotificationControllerTest&) = + delete; + CastNotificationControllerTest& operator=( + const CastNotificationControllerTest&) = delete; + + ~CastNotificationControllerTest() override = default; + + void SetUp() override { + AshTestBase::SetUp(); + notification_controller_ = std::make_unique<CastNotificationController>(); + } + + message_center::Notification* GetNotification() { + return message_center::MessageCenter::Get()->FindNotificationById( + "chrome://cast"); + } + + void ClickOnNotificationButton(int index = 0) { + message_center::MessageCenter::Get()->ClickOnNotificationButton( + "chrome://cast", index); + } + + void ClickOnNotificationBody() { + message_center::MessageCenter::Get()->ClickOnNotification("chrome://cast"); + } + + std::unique_ptr<CastNotificationController> notification_controller_; + TestCastConfigController cast_config_; +}; + +TEST_F(CastNotificationControllerTest, Notification) { + // There should be no cast notification to start with. + EXPECT_FALSE(GetNotification()); + + // A device with no route should not create a notification. + cast_config_.has_sinks_and_routes_ = true; + notification_controller_->OnDevicesUpdated({CreateDeviceNoRoute()}); + EXPECT_FALSE(GetNotification()); + + // A device with a non-local route should not create a notification. + cast_config_.has_active_routes_ = true; + notification_controller_->OnDevicesUpdated({CreateDeviceNonlocalRoute()}); + EXPECT_FALSE(GetNotification()); + + // A device with a local route should create a pinned notification. + notification_controller_->OnDevicesUpdated({CreateDeviceLocalRoute()}); + EXPECT_TRUE(GetNotification()->pinned()); + + cast_config_.has_sinks_and_routes_ = false; + cast_config_.has_active_routes_ = false; + notification_controller_->OnDevicesUpdated({}); + EXPECT_FALSE(GetNotification()); +} + +TEST_F(CastNotificationControllerTest, StopCasting) { + // Create notification. + cast_config_.has_sinks_and_routes_ = true; + cast_config_.has_active_routes_ = true; + SinkAndRoute device = CreateDeviceLocalRoute(); + notification_controller_->OnDevicesUpdated({device}); + EXPECT_TRUE(GetNotification()->pinned()); + + ClickOnNotificationBody(); + EXPECT_EQ(cast_config_.stop_casting_count_, 1u); + EXPECT_EQ(cast_config_.stop_casting_route_id_, device.route.id); + + cast_config_.stop_casting_route_id_ = ""; + + ClickOnNotificationButton(0); + EXPECT_EQ(cast_config_.stop_casting_count_, 2u); + EXPECT_EQ(cast_config_.stop_casting_route_id_, device.route.id); +} + +TEST_F(CastNotificationControllerTest, FreezeUi) { + // Create notification. + cast_config_.has_sinks_and_routes_ = true; + cast_config_.has_active_routes_ = true; + SinkAndRoute device = CreateDeviceLocalRoute(); + // Make the device "freezable" so the freeze (pause) button appears. + device.route.freeze_info.can_freeze = true; + notification_controller_->OnDevicesUpdated({device}); + EXPECT_TRUE(GetNotification()->pinned()); + + // There should be two notification buttons. + EXPECT_EQ(GetNotification()->buttons().size(), 2u); + + // The first button should be the freeze button. + ClickOnNotificationButton(0); + EXPECT_EQ(cast_config_.freeze_route_count_, 1u); + EXPECT_EQ(cast_config_.stop_casting_count_, 0u); + EXPECT_EQ(cast_config_.freeze_route_route_id_, device.route.id); + + // The second button should be the stop button. + ClickOnNotificationButton(1); + EXPECT_EQ(cast_config_.freeze_route_count_, 1u); + EXPECT_EQ(cast_config_.stop_casting_count_, 1u); + EXPECT_EQ(cast_config_.stop_casting_route_id_, device.route.id); + + cast_config_.stop_casting_route_id_ = ""; + + // Clicking on the notification body should still stop casting. + ClickOnNotificationBody(); + EXPECT_EQ(cast_config_.freeze_route_count_, 1u); + EXPECT_EQ(cast_config_.stop_casting_count_, 2u); + EXPECT_EQ(cast_config_.stop_casting_route_id_, device.route.id); + + // Set the device to a frozen state, then regenerate the notification. + device.route.freeze_info.is_frozen = true; + notification_controller_->OnDevicesUpdated({device}); + + // The first button should now call unfreeze. + ClickOnNotificationButton(0); + EXPECT_EQ(cast_config_.unfreeze_route_count_, 1u); + EXPECT_EQ(cast_config_.stop_casting_count_, 2u); + EXPECT_EQ(cast_config_.unfreeze_route_route_id_, device.route.id); +} + +} // namespace ash
diff --git a/ash/system/cast/tray_cast_unittest.cc b/ash/system/cast/tray_cast_unittest.cc index 78fb9d7a..d5265196 100644 --- a/ash/system/cast/tray_cast_unittest.cc +++ b/ash/system/cast/tray_cast_unittest.cc
@@ -50,6 +50,8 @@ ++stop_casting_count_; stop_casting_route_id_ = route_id; } + void FreezeRoute(const std::string& route_id) override {} + void UnfreezeRoute(const std::string& route_id) override {} bool access_code_casting_enabled_ = false; std::vector<SinkAndRoute> sinks_and_routes_;
diff --git a/ash/system/unified/quick_settings_view_unittest.cc b/ash/system/unified/quick_settings_view_unittest.cc index c8a6e13..2ace971 100644 --- a/ash/system/unified/quick_settings_view_unittest.cc +++ b/ash/system/unified/quick_settings_view_unittest.cc
@@ -48,6 +48,8 @@ } void CastToSink(const std::string& sink_id) override {} void StopCasting(const std::string& route_id) override {} + void FreezeRoute(const std::string& route_id) override {} + void UnfreezeRoute(const std::string& route_id) override {} bool has_media_router_ = true; bool has_sinks_and_routes_ = false;
diff --git a/ash/webui/shortcut_customization_ui/backend/accelerator_layout_table.cc b/ash/webui/shortcut_customization_ui/backend/accelerator_layout_table.cc index 4ab9612..c52d82c 100644 --- a/ash/webui/shortcut_customization_ui/backend/accelerator_layout_table.cc +++ b/ash/webui/shortcut_customization_ui/backend/accelerator_layout_table.cc
@@ -398,8 +398,8 @@ {ui::Accelerator(ui::VKEY_BROWSER_BACK, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN)})}, {NonConfigurableActions::kAmbientOpenRightClickMenu, - NonConfigurableAcceleratorDetails({ui::Accelerator( - ui::VKEY_VOLUME_UP, ui::EF_COMMAND_DOWN | ui::EF_SHIFT_DOWN)})}, + NonConfigurableAcceleratorDetails( + {ui::Accelerator(ui::VKEY_F10, ui::EF_SHIFT_DOWN)})}, {NonConfigurableActions::kAmbientDisplayHiddenFiles, NonConfigurableAcceleratorDetails( {ui::Accelerator(ui::VKEY_OEM_PERIOD, ui::EF_CONTROL_DOWN)})},
diff --git a/ash/wm/native_cursor_manager_ash.cc b/ash/wm/native_cursor_manager_ash.cc index f399934..8ff97ed 100644 --- a/ash/wm/native_cursor_manager_ash.cc +++ b/ash/wm/native_cursor_manager_ash.cc
@@ -14,7 +14,6 @@ #include "ui/aura/window_tree_host.h" #include "ui/base/cursor/cursor.h" #include "ui/base/cursor/mojom/cursor_type.mojom-shared.h" -#include "ui/base/layout.h" #include "ui/wm/core/cursor_loader.h" #include "ui/wm/core/native_cursor_manager_delegate.h" @@ -79,15 +78,9 @@ void NativeCursorManagerAsh::SetDisplay( const display::Display& display, ::wm::NativeCursorManagerDelegate* delegate) { - DCHECK(display.is_valid()); - - const float original_scale = display.device_scale_factor(); - // And use the nearest resource scale factor. - const float cursor_scale = ui::GetScaleForResourceScaleFactor( - ui::GetSupportedResourceScaleFactor(original_scale)); - - if (cursor_loader_.SetDisplayData(display.panel_rotation(), cursor_scale)) + if (cursor_loader_.SetDisplay(display)) { SetCursor(delegate->GetCursor(), delegate); + } Shell::Get() ->window_tree_host_manager()
diff --git a/base/task/sequence_manager/work_queue.cc b/base/task/sequence_manager/work_queue.cc index 0f04cfe..53d5aa2 100644 --- a/base/task/sequence_manager/work_queue.cc +++ b/base/task/sequence_manager/work_queue.cc
@@ -6,7 +6,6 @@ #include "base/containers/stack_container.h" #include "base/debug/alias.h" -#include "base/metrics/field_trial_params.h" #include "base/task/sequence_manager/fence.h" #include "base/task/sequence_manager/sequence_manager_impl.h" #include "base/task/sequence_manager/task_order.h"
diff --git a/base/task/sequence_manager/work_queue.h b/base/task/sequence_manager/work_queue.h index 3d11c67..48af3e7 100644 --- a/base/task/sequence_manager/work_queue.h +++ b/base/task/sequence_manager/work_queue.h
@@ -163,8 +163,6 @@ void CollectTasksOlderThan(TaskOrder reference, std::vector<const Task*>* result) const; - bool RemoveAllCancelledTasksFromFrontImpl(); - bool InsertFenceImpl(Fence fence); TaskQueueImpl::TaskDeque tasks_;
diff --git a/base/threading/thread_restrictions.h b/base/threading/thread_restrictions.h index 861c5f9d..f37e3cf 100644 --- a/base/threading/thread_restrictions.h +++ b/base/threading/thread_restrictions.h
@@ -294,6 +294,9 @@ namespace ios_web_view { class WebViewBrowserState; } +namespace io_thread { +class IOSIOThread; +} namespace leveldb::port { class CondVar; } // namespace leveldb::port @@ -428,7 +431,6 @@ namespace web { class WebMainLoop; -class WebSubThread; } // namespace web namespace webrtc { @@ -615,6 +617,7 @@ friend class extensions::UnpackedInstaller; friend class font_service::internal::MappedFontFile; friend class ios_web_view::WebViewBrowserState; + friend class io_thread::IOSIOThread; friend class media::FileVideoCaptureDeviceFactory; friend class memory_instrumentation::OSMetrics; friend class memory_pressure::UserLevelMemoryPressureSignalGenerator; @@ -637,7 +640,6 @@ friend class ui::DrmDisplayHostManager; friend class ui::ScopedAllowBlockingForGbmSurface; friend class ui::SelectFileDialogLinux; - friend class web::WebSubThread; friend class weblayer::BrowserContextImpl; friend class weblayer::ContentBrowserClientImpl; friend class weblayer::ProfileImpl;
diff --git a/base/values.cc b/base/values.cc index bab5ccec..d8353335 100644 --- a/base/values.cc +++ b/base/values.cc
@@ -1355,10 +1355,6 @@ return GetDict().size(); } -bool Value::DictEmpty() const { - return GetDict().empty(); -} - bool operator==(const Value& lhs, const Value& rhs) { return lhs.data_ == rhs.data_; }
diff --git a/base/values.h b/base/values.h index aa7c2d43..e1c4cf8 100644 --- a/base/values.h +++ b/base/values.h
@@ -911,9 +911,6 @@ // DEPRECATED: prefer `Value::Dict::size()`. size_t DictSize() const; - // DEPRECATED: prefer `Value::Dict::empty()`. - bool DictEmpty() const; - // Note: Do not add more types. See the file-level comment above for why. // Comparison operators so that Values can easily be used with standard
diff --git a/base/win/win_util.cc b/base/win/win_util.cc index d08976d..0d81e7c 100644 --- a/base/win/win_util.cc +++ b/base/win/win_util.cc
@@ -690,7 +690,7 @@ } } -std::wstring WStringFromGUID(REFGUID rguid) { +std::wstring WStringFromGUID(const ::GUID& rguid) { // This constant counts the number of characters in the formatted string, // including the null termination character. constexpr int kGuidStringCharacters =
diff --git a/base/win/win_util.h b/base/win/win_util.h index 7ad82fc..8dfeca4 100644 --- a/base/win/win_util.h +++ b/base/win/win_util.h
@@ -200,7 +200,7 @@ BASE_EXPORT void EnableHighDPISupport(); // Returns a string representation of |rguid|. -BASE_EXPORT std::wstring WStringFromGUID(REFGUID rguid); +BASE_EXPORT std::wstring WStringFromGUID(const ::GUID& rguid); // Attempts to pin user32.dll to ensure it remains loaded. If it isn't loaded // yet, the module will first be loaded and then the pin will be attempted. If
diff --git a/build/config/rust.gni b/build/config/rust.gni index deafd5e..f6e50771 100644 --- a/build/config/rust.gni +++ b/build/config/rust.gni
@@ -15,7 +15,14 @@ # Whether to allow Rust code to be part of the Chromium *build process*. # This can be used to create Rust test binaries, even if the flag below # is false. + # TODO(crbug.com/1386212): Mac + # TODO(crbug.com/1271215): Windows # TODO(crbug.com/1426472): use_clang_coverage + # TODO(crbug.com/1427362): using_sanitizer + # TODO(crbug.com/1427364): target_cpu != "x86" + # There is no specific bug for target_os == host_os since nor for + # !is_official_build, since this is just a matter of rolling things out + # slowly and carefully and there may be no actual bugs there. enable_rust = is_linux && !is_official_build && !using_sanitizer && target_cpu != "x86" && !use_clang_coverage && is_clang && !is_castos && target_os == host_os
diff --git a/build/fuchsia/linux_internal.sdk.sha1 b/build/fuchsia/linux_internal.sdk.sha1 index 11f3c9a7..cb916829 100644 --- a/build/fuchsia/linux_internal.sdk.sha1 +++ b/build/fuchsia/linux_internal.sdk.sha1
@@ -1 +1 @@ -12.20230324.1.1 +12.20230324.2.1
diff --git a/build_overrides/build.gni b/build_overrides/build.gni index 1ad7363f8..5b7bc4d 100644 --- a/build_overrides/build.gni +++ b/build_overrides/build.gni
@@ -51,7 +51,7 @@ gtest_enable_absl_printers = !is_nacl # Allows third-party repositories to use C++17 for MSVC builds - # TODO(crbug.com/1380553) Remove once ANGLE's MSVC C++20 build passes + # TODO(https://crbug.com/pdfium/1932) Remove once pdfium builds on MSVC C++20 msvc_use_cxx17 = false }
diff --git a/cc/input/input_handler.cc b/cc/input/input_handler.cc index 51b88ed..e01cc7bf 100644 --- a/cc/input/input_handler.cc +++ b/cc/input/input_handler.cc
@@ -127,7 +127,7 @@ bool unification_enabled = base::FeatureList::IsEnabled(features::kScrollUnification); - if (target_element_id && !scroll_state->is_main_thread_hit_tested()) { + if (target_element_id && !scroll_state->main_thread_hit_tested_reasons()) { TRACE_EVENT_INSTANT0("cc", "Latched scroll node provided", TRACE_EVENT_SCOPE_THREAD); // If the caller passed in an element_id we can skip all the hit-testing @@ -154,7 +154,7 @@ // scroll in the given direction. This mode is only used when scroll // unification is enabled and the targeted scroller comes back from a // main thread hit test. - DCHECK(scroll_state->data()->is_main_thread_hit_tested); + DCHECK(scroll_state->main_thread_hit_tested_reasons()); DCHECK(unification_enabled); starting_node = scroll_tree.FindNodeFromElementId(target_element_id); @@ -177,7 +177,7 @@ compositor_delegate_->DeviceScaleFactor()); if (unification_enabled) { - if (scroll_state->data()->is_main_thread_hit_tested) { + if (scroll_state->main_thread_hit_tested_reasons()) { // The client should have discarded the scroll when the hit test came // back with an invalid element id. If we somehow get here, we should // drop the scroll as continuing could cause us to infinitely bounce @@ -199,7 +199,9 @@ TRACE_EVENT_SCOPE_THREAD); scroll_status.thread = InputHandler::ScrollThread::SCROLL_ON_IMPL_THREAD; - scroll_status.needs_main_thread_hit_test = true; + DCHECK(scroll_hit_test.main_thread_hit_test_reasons); + scroll_status.main_thread_hit_test_reasons = + scroll_hit_test.main_thread_hit_test_reasons; return scroll_status; } @@ -323,7 +325,7 @@ // Since we provided an ElementId, there should never be a need to perform a // hit test. - DCHECK(!scroll_status.needs_main_thread_hit_test); + DCHECK(!scroll_status.main_thread_hit_test_reasons); return scroll_status; } @@ -1456,6 +1458,8 @@ // this, we have to get a hit test from the main thread. if (!IsInitialScrollHitTestReliable(layer_impl, scroller_layer)) { TRACE_EVENT_INSTANT0("cc", "Failed Hit Test", TRACE_EVENT_SCOPE_THREAD); + result.main_thread_hit_test_reasons = + MainThreadScrollingReason::kFailedHitTest; return result; } @@ -1465,6 +1469,8 @@ // failure. if (ActiveTree().PointHitsNonFastScrollableRegion(device_viewport_point, *layer_impl)) { + result.main_thread_hit_test_reasons = + MainThreadScrollingReason::kNonFastScrollableRegion; return result; } }
diff --git a/cc/input/input_handler.h b/cc/input/input_handler.h index ddc65a8..59bba52 100644 --- a/cc/input/input_handler.h +++ b/cc/input/input_handler.h
@@ -207,31 +207,16 @@ InputHandler& operator=(const InputHandler&) = delete; struct ScrollStatus { - ScrollStatus() = default; - ScrollStatus(ScrollThread thread, uint32_t main_thread_scrolling_reasons) - : thread(thread), - main_thread_scrolling_reasons(main_thread_scrolling_reasons) {} - ScrollStatus(ScrollThread thread, - uint32_t main_thread_scrolling_reasons, - bool needs_main_thread_hit_test) - : thread(thread), - main_thread_scrolling_reasons(main_thread_scrolling_reasons), - needs_main_thread_hit_test(needs_main_thread_hit_test) {} ScrollThread thread = ScrollThread::SCROLL_ON_IMPL_THREAD; // This should be set to nonzero iff `thread` is SCROLL_ON_MAIN_THREAD. uint32_t main_thread_scrolling_reasons = MainThreadScrollingReason::kNotScrollingOnMain; - // TODO(crbug.com/1155758): This is a temporary workaround for GuestViews - // as they create viewport nodes and want to bubble scroll if the - // viewport cannot scroll in the given delta directions. There should be - // a parameter to ThreadInputHandler to specify whether unused delta is - // consumed by the viewport or bubbles to the parent. - bool viewport_cannot_scroll = false; - // Used only in scroll unification. Tells the caller that the input handler - // detected a case where it cannot reliably target a scroll node and needs - // the main thread to perform a hit test. - bool needs_main_thread_hit_test = false; + // Used only in scroll unification. If nonzero, it tells the caller that + // the input handler detected a case where it cannot reliably target a + // scroll node and needs the main thread to perform a hit test. + uint32_t main_thread_hit_test_reasons = + MainThreadScrollingReason::kNotScrollingOnMain; // Used only in scroll unification. A nonzero value means we have performed // the scroll (i.e. updated the offset in the scroll tree) on the compositor @@ -241,7 +226,15 @@ // from the MainThreadScrollingReason enum. (Unification avoids setting // main_thread_scrolling_reasons, to keep that field consistent with // semantics of ScrollThread::SCROLL_ON_IMPL_THREAD.) - uint32_t main_thread_repaint_reasons = 0; + uint32_t main_thread_repaint_reasons = + MainThreadScrollingReason::kNotScrollingOnMain; + + // TODO(crbug.com/1155758): This is a temporary workaround for GuestViews + // as they create viewport nodes and want to bubble scroll if the + // viewport cannot scroll in the given delta directions. There should be + // a parameter to ThreadInputHandler to specify whether unused delta is + // consumed by the viewport or bubbles to the parent. + bool viewport_cannot_scroll = false; }; enum class TouchStartOrMoveEventListenerType { @@ -638,6 +631,8 @@ struct ScrollHitTestResult { raw_ptr<ScrollNode> scroll_node; bool hit_test_successful; + uint32_t main_thread_hit_test_reasons = + MainThreadScrollingReason::kNotScrollingOnMain; }; ScrollHitTestResult HitTestScrollNode( const gfx::PointF& device_viewport_point) const;
diff --git a/cc/input/scroll_state.h b/cc/input/scroll_state.h index 4b67824..85cf70b 100644 --- a/cc/input/scroll_state.h +++ b/cc/input/scroll_state.h
@@ -93,8 +93,8 @@ return data_.current_native_scrolling_element(); } - bool is_main_thread_hit_tested() const { - return data_.is_main_thread_hit_tested; + uint32_t main_thread_hit_tested_reasons() const { + return data_.main_thread_hit_tested_reasons; } ScrollStateData* data() { return &data_; }
diff --git a/cc/input/scroll_state_data.cc b/cc/input/scroll_state_data.cc index 24dfd0a..54c0e2b 100644 --- a/cc/input/scroll_state_data.cc +++ b/cc/input/scroll_state_data.cc
@@ -26,8 +26,7 @@ delta_granularity(ui::ScrollGranularity::kScrollByPrecisePixel), caused_scroll_x(false), caused_scroll_y(false), - is_scroll_chain_cut(false), - is_main_thread_hit_tested(false) {} + is_scroll_chain_cut(false) {} ScrollStateData::ScrollStateData(const ScrollStateData&) = default;
diff --git a/cc/input/scroll_state_data.h b/cc/input/scroll_state_data.h index 00b7fb9b..39a8f87 100644 --- a/cc/input/scroll_state_data.h +++ b/cc/input/scroll_state_data.h
@@ -8,6 +8,7 @@ #include <stdint.h> #include "cc/cc_export.h" +#include "cc/input/main_thread_scrolling_reason.h" #include "cc/trees/property_tree.h" #include "ui/events/types/scroll_types.h" @@ -72,9 +73,10 @@ void set_current_native_scrolling_element(ElementId element_id); // Used in scroll unification to specify that a scroll state has been hit - // tested on the main thread. If this is true, the hit test result will be + // tested on the main thread. If this is nonzero, the hit test result will be // placed in the current_native_scrolling_element_. - bool is_main_thread_hit_tested; + uint32_t main_thread_hit_tested_reasons = + MainThreadScrollingReason::kNotScrollingOnMain; private: // The id of the last native element to respond to a scroll, or 0 if none
diff --git a/cc/paint/discardable_image_map_unittest.cc b/cc/paint/discardable_image_map_unittest.cc index 15d7306..fe8a8c7 100644 --- a/cc/paint/discardable_image_map_unittest.cc +++ b/cc/paint/discardable_image_map_unittest.cc
@@ -1130,12 +1130,13 @@ nullptr /* color_space */); bitmap.allocPixels(info); bitmap.eraseColor(SK_AlphaTRANSPARENT); - PaintImage discardable_image = PaintImageBuilder::WithDefault() - .set_id(PaintImage::GetNextId()) - .set_is_high_bit_depth(true) - .set_image(SkImage::MakeFromBitmap(bitmap), - PaintImage::GetNextContentId()) - .TakePaintImage(); + PaintImage discardable_image = + PaintImageBuilder::WithDefault() + .set_id(PaintImage::GetNextId()) + .set_is_high_bit_depth(true) + .set_image(SkImages::RasterFromBitmap(bitmap), + PaintImage::GetNextContentId()) + .TakePaintImage(); FakeContentLayerClient content_layer_client; content_layer_client.set_bounds(visible_rect.size());
diff --git a/cc/paint/image_transfer_cache_entry.cc b/cc/paint/image_transfer_cache_entry.cc index 1d0f1e9..24e5a30 100644 --- a/cc/paint/image_transfer_cache_entry.cc +++ b/cc/paint/image_transfer_cache_entry.cc
@@ -23,6 +23,7 @@ #include "third_party/skia/include/gpu/GrBackendSurface.h" #include "third_party/skia/include/gpu/GrDirectContext.h" #include "third_party/skia/include/gpu/GrYUVABackendTextures.h" +#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h" #include "ui/gfx/color_conversion_sk_filter_cache.h" #include "ui/gfx/hdr_metadata.h" @@ -43,7 +44,7 @@ // first extracted out of the |plane_images| (and work is flushed on each one). // Note that we assume that the image is opaque (no alpha plane). Then, a // SkImage is created out of those textures using the -// SkImage::MakeFromYUVATextures() API. Finally, |image_color_space| is the +// SkImages::TextureFromYUVATextures() API. Finally, |image_color_space| is the // color space of the resulting image after applying |yuv_color_space| // (converting from YUV to RGB). This is assumed to be sRGB if nullptr. // @@ -80,7 +81,7 @@ GrYUVABackendTextures yuva_backend_textures( yuva_info, plane_backend_textures.data(), kTopLeft_GrSurfaceOrigin); Context* ctx = new Context{plane_images}; - sk_sp<SkImage> image = SkImage::MakeFromYUVATextures( + sk_sp<SkImage> image = SkImages::TextureFromYUVATextures( context, yuva_backend_textures, std::move(image_color_space), ReleaseContext, ctx); if (!image) { @@ -569,7 +570,8 @@ return false; } - sk_sp<SkImage> plane = SkImage::MakeFromRaster(pixmap, nullptr, nullptr); + sk_sp<SkImage> plane = + SkImages::RasterFromPixmap(pixmap, nullptr, nullptr); if (!plane) { DLOG(ERROR) << "Failed to create image from plane pixmap"; return false; @@ -598,7 +600,8 @@ DLOG(ERROR) << "Failed to read pixmap"; return false; } - rgba_pixmap_image = SkImage::MakeFromRaster(rgba_pixmap, nullptr, nullptr); + rgba_pixmap_image = + SkImages::RasterFromPixmap(rgba_pixmap, nullptr, nullptr); if (!rgba_pixmap_image) { DLOG(ERROR) << "Failed to create image from plane pixmap"; return false; @@ -664,7 +667,7 @@ // a copy of it, because `rgba_pixmap` is directly referencing the transfer // buffer's memory, and will go away after this this call. if (image_ == rgba_pixmap_image) { - image_ = SkImage::MakeRasterCopy(rgba_pixmap); + image_ = SkImages::RasterFromPixmapCopy(rgba_pixmap); if (!image_) { DLOG(ERROR) << "Failed to create raster copy"; return false;
diff --git a/cc/paint/image_transfer_cache_entry_unittest.cc b/cc/paint/image_transfer_cache_entry_unittest.cc index 6a42297..4b42164 100644 --- a/cc/paint/image_transfer_cache_entry_unittest.cc +++ b/cc/paint/image_transfer_cache_entry_unittest.cc
@@ -29,6 +29,7 @@ #include "third_party/skia/include/gpu/GrBackendSurface.h" #include "third_party/skia/include/gpu/GrDirectContext.h" #include "third_party/skia/include/gpu/GrTypes.h" +#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h" #include "third_party/skia/include/gpu/gl/GrGLInterface.h" #include "third_party/skia/include/gpu/gl/GrGLTypes.h" #include "ui/gfx/geometry/size.h" @@ -188,7 +189,7 @@ DCHECK(!allocated_texture.hasMipMaps()); DCHECK(allocated_texture_info.fTarget == GL_TEXTURE_2D); *released = false; - return SkImage::MakeFromTexture( + return SkImages::BorrowTextureFrom( gr_context, allocated_texture, kTopLeft_GrSurfaceOrigin, texture_format == GL_RG8_EXT ? kR8G8_unorm_SkColorType : kAlpha_8_SkColorType,
diff --git a/cc/paint/oop_pixeltest.cc b/cc/paint/oop_pixeltest.cc index d772404..4a71543 100644 --- a/cc/paint/oop_pixeltest.cc +++ b/cc/paint/oop_pixeltest.cc
@@ -40,6 +40,7 @@ #include "third_party/skia/include/core/SkColorSpace.h" #include "third_party/skia/include/core/SkColorType.h" #include "third_party/skia/include/core/SkGraphics.h" +#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkPictureRecorder.h" #include "third_party/skia/include/core/SkRect.h" #include "third_party/skia/include/core/SkSurface.h" @@ -89,7 +90,7 @@ green.setColor(SkColors::kGreen); canvas.drawRect(SkRect::MakeXYWH(10, 20, 30, 40), green); - return SkImage::MakeFromBitmap(bitmap); + return SkImages::RasterFromBitmap(bitmap); } constexpr size_t kCacheLimitBytes = 1024 * 1024; @@ -651,7 +652,7 @@ SkColor4f color{image_pq_pixel, image_pq_pixel, image_pq_pixel, 1.f}; canvas.drawColor(color); - image = SkImage::MakeFromBitmap(bitmap); + image = SkImages::RasterFromBitmap(bitmap); image = image->reinterpretColorSpace( SkColorSpace::MakeRGB(pq, SkNamedGamut::kSRGB)); }
diff --git a/cc/paint/paint_filter.cc b/cc/paint/paint_filter.cc index f9ec2d47..650065f6 100644 --- a/cc/paint/paint_filter.cc +++ b/cc/paint/paint_filter.cc
@@ -23,6 +23,7 @@ #include "cc/paint/scoped_raster_flags.h" #include "third_party/skia/include/core/SkColorFilter.h" #include "third_party/skia/include/core/SkColorSpace.h" +#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkScalar.h" #include "third_party/skia/include/core/SkString.h" #include "third_party/skia/include/core/SkTileMode.h" @@ -755,9 +756,9 @@ int height = SkScalarCeilToInt(record_bounds.height()); SkMatrix originAdjust = SkMatrix::Translate(-record_bounds.fLeft, -record_bounds.fTop); - auto image = SkImage::MakeFromPicture( + auto image = SkImages::DeferredFromPicture( std::move(picture), SkISize::Make(width, height), &originAdjust, - nullptr, SkImage::BitDepth::kU8, SkColorSpace::MakeSRGB()); + nullptr, SkImages::BitDepth::kU8, SkColorSpace::MakeSRGB()); // Must account for the raster scale when drawing the picture image, SkRect src = SkRect::MakeWH(record_bounds.width(), record_bounds.height());
diff --git a/cc/paint/paint_image.cc b/cc/paint/paint_image.cc index 31c63fc..fcd775bc 100644 --- a/cc/paint/paint_image.cc +++ b/cc/paint/paint_image.cc
@@ -110,7 +110,7 @@ return PaintImageBuilder::WithDefault() .set_id(PaintImage::GetNextId()) - .set_image(SkImage::MakeFromBitmap(bitmap), + .set_image(SkImages::RasterFromBitmap(bitmap), PaintImage::GetNextContentId()) .TakePaintImage(); } @@ -181,15 +181,15 @@ if (sk_image_) { cached_sk_image_ = sk_image_; } else if (paint_record_) { - cached_sk_image_ = SkImage::MakeFromPicture( + cached_sk_image_ = SkImages::DeferredFromPicture( paint_record_->ToSkPicture(gfx::RectToSkRect(paint_record_rect_)), SkISize::Make(paint_record_rect_.width(), paint_record_rect_.height()), - nullptr, nullptr, SkImage::BitDepth::kU8, SkColorSpace::MakeSRGB()); + nullptr, nullptr, SkImages::BitDepth::kU8, SkColorSpace::MakeSRGB()); } else if (paint_image_generator_) { - cached_sk_image_ = - SkImage::MakeFromGenerator(std::make_unique<SkiaPaintImageGenerator>( - paint_image_generator_, kDefaultFrameIndex, - kDefaultGeneratorClientId)); + cached_sk_image_ = SkImages::DeferredFromGenerator( + std::make_unique<SkiaPaintImageGenerator>(paint_image_generator_, + kDefaultFrameIndex, + kDefaultGeneratorClientId)); } else if (texture_backing_) { cached_sk_image_ = texture_backing_->GetAcceleratedSkImage(); } @@ -362,7 +362,7 @@ return GetSwSkImage(); sk_sp<SkImage> image = - SkImage::MakeFromGenerator(std::make_unique<SkiaPaintImageGenerator>( + SkImages::DeferredFromGenerator(std::make_unique<SkiaPaintImageGenerator>( paint_image_generator_, index, client_id)); return image; }
diff --git a/cc/paint/paint_op_buffer_unittest.cc b/cc/paint/paint_op_buffer_unittest.cc index 453dfc7..a0abe2aa 100644 --- a/cc/paint/paint_op_buffer_unittest.cc +++ b/cc/paint/paint_op_buffer_unittest.cc
@@ -2743,7 +2743,7 @@ SkBitmap bitmap; bitmap.allocPixelsFlags(SkImageInfo::MakeN32Premul(10, 10), SkBitmap::kZeroPixels_AllocFlag); - sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap); + sk_sp<SkImage> image = SkImages::RasterFromBitmap(bitmap); size_t i = index_++; return ScopedResult(DecodedDrawImage(image, nullptr, src_rect_offset_[i], scale_[i], quality_[i], true));
diff --git a/cc/paint/paint_op_reader.cc b/cc/paint/paint_op_reader.cc index 54cd0dc..e940735 100644 --- a/cc/paint/paint_op_reader.cc +++ b/cc/paint/paint_op_reader.cc
@@ -34,6 +34,7 @@ #include "cc/paint/transfer_cache_deserialize_helper.h" #include "components/crash/core/common/crash_key.h" #include "third_party/skia/include/core/SkColorSpace.h" +#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkPath.h" #include "third_party/skia/include/core/SkRRect.h" #include "third_party/skia/include/core/SkSerialProcs.h" @@ -361,7 +362,7 @@ *image = PaintImageBuilder::WithDefault() .set_id(PaintImage::GetNextId()) - .set_texture_image(SkImage::MakeRasterCopy(pixmap), + .set_texture_image(SkImages::RasterFromPixmapCopy(pixmap), PaintImage::kNonLazyStableId) .TakePaintImage(); }
diff --git a/cc/paint/paint_op_writer.cc b/cc/paint/paint_op_writer.cc index 8fcb3d10..4623bb2 100644 --- a/cc/paint/paint_op_writer.cc +++ b/cc/paint/paint_op_writer.cc
@@ -25,6 +25,7 @@ #include "third_party/skia/include/core/SkColorSpace.h" #include "third_party/skia/include/core/SkData.h" #include "third_party/skia/include/core/SkFlattenable.h" +#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkM44.h" #include "third_party/skia/include/core/SkMatrix.h" #include "third_party/skia/include/core/SkPath.h" @@ -986,8 +987,8 @@ // Nested records are used for picture shaders and filters. These are always // converted to a fixed scale mode (hence |post_scale|), which means they are - // first rendered offscreen via SkImage::MakeFromPicture. This inherently does - // not support lcd text, so reflect that in the serialization options. + // first rendered offscreen via SkImages::DeferredFromPicture. This inherently + // does not support lcd text, so reflect that in the serialization options. PaintOp::SerializeOptions lcd_disabled_options = *options_; lcd_disabled_options.can_use_lcd_text = false; SimpleBufferSerializer serializer(memory_, remaining_bytes_,
diff --git a/cc/paint/paint_shader.cc b/cc/paint/paint_shader.cc index c809f53..84e1a7f6 100644 --- a/cc/paint/paint_shader.cc +++ b/cc/paint/paint_shader.cc
@@ -16,6 +16,7 @@ #include "cc/paint/paint_op_writer.h" #include "cc/paint/paint_record.h" #include "third_party/skia/include/core/SkColorSpace.h" +#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkPictureRecorder.h" #include "third_party/skia/include/effects/SkGradientShader.h" @@ -460,10 +461,10 @@ // For fixed scale, we create an image shader with an image backed by // the picture. case ScalingBehavior::kFixedScale: { - auto image = SkImage::MakeFromPicture( + auto image = SkImages::DeferredFromPicture( sk_cached_picture_, SkISize::Make(tile_.width(), tile_.height()), nullptr, nullptr, - SkImage::BitDepth::kU8, SkColorSpace::MakeSRGB()); + SkImages::BitDepth::kU8, SkColorSpace::MakeSRGB()); return image->makeShader(tx_, ty_, sampling, base::OptionalToPtr(local_matrix_)); }
diff --git a/cc/paint/paint_shader_unittest.cc b/cc/paint/paint_shader_unittest.cc index f5a9a2ec..fa6419d00 100644 --- a/cc/paint/paint_shader_unittest.cc +++ b/cc/paint/paint_shader_unittest.cc
@@ -50,7 +50,7 @@ SkBitmap bitmap; bitmap.allocN32Pixels(10, 10); bitmap.eraseColor(SK_ColorBLACK); - sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap); + sk_sp<SkImage> image = SkImages::RasterFromBitmap(bitmap); return ScopedResult(DecodedDrawImage(image, nullptr, SkSize::MakeEmpty(), SkSize::Make(1.0f, 1.0f), draw_image.filter_quality(), true));
diff --git a/cc/paint/scoped_raster_flags_unittest.cc b/cc/paint/scoped_raster_flags_unittest.cc index b58c6aa..36671a7 100644 --- a/cc/paint/scoped_raster_flags_unittest.cc +++ b/cc/paint/scoped_raster_flags_unittest.cc
@@ -34,7 +34,7 @@ SkBitmap bitmap; bitmap.allocN32Pixels(10, 10); - sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap); + sk_sp<SkImage> image = SkImages::RasterFromBitmap(bitmap); return ScopedResult( DecodedDrawImage(image, nullptr, SkSize::MakeEmpty(),
diff --git a/cc/raster/playback_image_provider_unittest.cc b/cc/raster/playback_image_provider_unittest.cc index b36625f..7d17ce77 100644 --- a/cc/raster/playback_image_provider_unittest.cc +++ b/cc/raster/playback_image_provider_unittest.cc
@@ -26,7 +26,7 @@ sk_sp<SkImage> CreateRasterImage() { SkBitmap bitmap; bitmap.allocN32Pixels(10, 10); - return SkImage::MakeFromBitmap(bitmap); + return SkImages::RasterFromBitmap(bitmap); } DecodedDrawImage CreateDecode() {
diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc index 6d3f5f3..cdcd5930 100644 --- a/cc/scheduler/scheduler.cc +++ b/cc/scheduler/scheduler.cc
@@ -777,9 +777,7 @@ FROM_HERE, deadline_, base::BindOnce(&Scheduler::OnBeginImplFrameDeadline, base::Unretained(this)), - deadline_mode_ == DeadlineMode::LATE - ? base::subtle::DelayPolicy::kFlexibleNoSooner - : base::subtle::DelayPolicy::kPrecise); + base::subtle::DelayPolicy::kPrecise); } }
diff --git a/cc/slim/layer_tree_impl.cc b/cc/slim/layer_tree_impl.cc index 25efb179..8f76aacd 100644 --- a/cc/slim/layer_tree_impl.cc +++ b/cc/slim/layer_tree_impl.cc
@@ -716,13 +716,14 @@ // Viz expects the visible rect to be a subrect of layer_rect (ie `bounds()`). // So intersect here unconditionally in case this layer is not // `masks_to_bounds()`. - gfx::RectF clip(layer.bounds().width(), layer.bounds().height()); - clip.Intersect(clip_in_layer); - if (!clip_in_layer.IsEmpty() && layer.HasDrawableContent() && - UpdateOcclusionRect(layer, data, transform_to_target, opacity, clip)) { + gfx::RectF visible_rectf(layer.bounds().width(), layer.bounds().height()); + visible_rectf.Intersect(clip_in_layer); + if (!visible_rectf.IsEmpty() && layer.HasDrawableContent() && + UpdateOcclusionRect(layer, data, transform_to_target, opacity, + visible_rectf)) { layer.AppendQuads(render_pass, data, transform_to_root, transform_to_target, clip_in_target ? &integer_clip_in_target : nullptr, - gfx::ToEnclosingRect(clip), opacity); + gfx::ToEnclosingRect(visible_rectf), opacity); } }
diff --git a/cc/slim/slim_layer_tree_compositor_frame_unittest.cc b/cc/slim/slim_layer_tree_compositor_frame_unittest.cc index 87dd4518..caae273 100644 --- a/cc/slim/slim_layer_tree_compositor_frame_unittest.cc +++ b/cc/slim/slim_layer_tree_compositor_frame_unittest.cc
@@ -1028,6 +1028,29 @@ EXPECT_EQ(child_quad->shared_quad_state->clip_rect, gfx::Rect(25, 25)); } +TEST_F(SlimLayerTreeCompositorFrameTest, CompletelyClippedLayer) { + auto root_layer = CreateSolidColorLayer(viewport_.size(), SkColors::kGray); + layer_tree_->SetRoot(root_layer); + + auto clip_and_scale_layer = Layer::Create(); + clip_and_scale_layer->SetMasksToBounds(true); + clip_and_scale_layer->SetBounds(gfx::Size(50, 50)); + root_layer->AddChild(clip_and_scale_layer); + + auto clipped_layer = CreateSolidColorLayer(gfx::Size(25, 25), SkColors::kRed); + clipped_layer->SetPosition(gfx::PointF(60.0f, 60.0f)); + clip_and_scale_layer->AddChild(clipped_layer); + + viz::CompositorFrame frame = ProduceFrame(); + ASSERT_EQ(frame.render_pass_list.size(), 1u); + auto& pass = frame.render_pass_list.back(); + ASSERT_THAT( + pass->quad_list, + ElementsAre(AllOf(viz::IsSolidColorQuad(SkColors::kGray), + viz::HasRect(viewport_), viz::HasVisibleRect(viewport_), + viz::HasTransform(gfx::Transform())))); +} + TEST_F(SlimLayerTreeCompositorFrameTest, NonAxisAlignedClip) { auto root_layer = CreateSolidColorLayer(viewport_.size(), SkColors::kGray); layer_tree_->SetRoot(root_layer);
diff --git a/cc/test/skia_common.cc b/cc/test/skia_common.cc index 02ea414..1fd5e022 100644 --- a/cc/test/skia_common.cc +++ b/cc/test/skia_common.cc
@@ -26,6 +26,7 @@ #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkColorSpace.h" +#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkImageGenerator.h" #include "third_party/skia/include/core/SkImageInfo.h" #include "third_party/skia/include/core/SkPixmap.h" @@ -225,7 +226,7 @@ bitmap.eraseColor(SK_AlphaTRANSPARENT); return PaintImageBuilder::WithDefault() .set_id(PaintImage::GetNextId()) - .set_image(SkImage::MakeFromBitmap(bitmap), + .set_image(SkImages::RasterFromBitmap(bitmap), PaintImage::GetNextContentId()) .TakePaintImage(); } @@ -289,7 +290,7 @@ return PaintImageBuilder::WithDefault() .set_id(PaintImage::GetNextId()) .set_texture_image( - SkImage::MakeFromBitmap(bitmap)->makeTextureImage(context.get()), + SkImages::RasterFromBitmap(bitmap)->makeTextureImage(context.get()), PaintImage::GetNextContentId()) .TakePaintImage(); }
diff --git a/cc/tiles/gpu_image_decode_cache.cc b/cc/tiles/gpu_image_decode_cache.cc index a106e3a..65947972 100644 --- a/cc/tiles/gpu_image_decode_cache.cc +++ b/cc/tiles/gpu_image_decode_cache.cc
@@ -50,6 +50,7 @@ #include "third_party/skia/include/core/SkColorFilter.h" #include "third_party/skia/include/core/SkColorSpace.h" #include "third_party/skia/include/core/SkData.h" +#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkImageInfo.h" #include "third_party/skia/include/core/SkPixmap.h" #include "third_party/skia/include/core/SkRect.h" @@ -60,6 +61,7 @@ #include "third_party/skia/include/gpu/GrBackendSurface.h" #include "third_party/skia/include/gpu/GrDirectContext.h" #include "third_party/skia/include/gpu/GrYUVABackendTextures.h" +#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h" #include "ui/gfx/color_space.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/skia_conversions.h" @@ -433,11 +435,12 @@ } sk_sp<SkColorSpace> color_space = image->refColorSpace(); GrBackendTexture backend_texture; - SkImage::BackendTextureReleaseProc release_proc; - SkImage::MakeBackendTextureFromSkImage(context, std::move(image), - &backend_texture, &release_proc); - return SkImage::MakeFromTexture(context, backend_texture, origin, color_type, - kPremul_SkAlphaType, std::move(color_space)); + SkImages::BackendTextureReleaseProc release_proc; + SkImages::GetBackendTextureFromImage(context, std::move(image), + &backend_texture, &release_proc); + return SkImages::BorrowTextureFrom(context, backend_texture, origin, + color_type, kPremul_SkAlphaType, + std::move(color_space)); } // Immediately deletes an SkImage, preventing caching of that image. Must be @@ -2200,9 +2203,9 @@ backing_memory->Unlock(); backing_memory.reset(); } else { - image_y = SkImage::MakeFromRaster(pixmap_y, release_proc, nullptr); - image_u = SkImage::MakeFromRaster(pixmap_u, release_proc, nullptr); - image_v = SkImage::MakeFromRaster(pixmap_v, release_proc, nullptr); + image_y = SkImages::RasterFromPixmap(pixmap_y, release_proc, nullptr); + image_u = SkImages::RasterFromPixmap(pixmap_u, release_proc, nullptr); + image_v = SkImages::RasterFromPixmap(pixmap_v, release_proc, nullptr); } } else { // RGBX decoding is the default path. SkPixmap pixmap(image_info, backing_memory->data(), @@ -2212,7 +2215,7 @@ backing_memory->Unlock(); backing_memory.reset(); } else { - image = SkImage::MakeFromRaster(pixmap, release_proc, nullptr); + image = SkImages::RasterFromPixmap(pixmap, release_proc, nullptr); } } } @@ -3236,7 +3239,7 @@ target_color_space = nullptr; } - sk_sp<SkImage> yuva_image = SkImage::MakeFromYUVATextures( + sk_sp<SkImage> yuva_image = SkImages::TextureFromYUVATextures( context_->GrContext(), yuva_backend_textures, std::move(decoded_color_space)); if (target_color_space)
diff --git a/cc/tiles/gpu_image_decode_cache_perftest.cc b/cc/tiles/gpu_image_decode_cache_perftest.cc index e7ae689..78aae1b 100644 --- a/cc/tiles/gpu_image_decode_cache_perftest.cc +++ b/cc/tiles/gpu_image_decode_cache_perftest.cc
@@ -35,7 +35,7 @@ sk_sp<SkImage> CreateImage(int width, int height) { SkBitmap bitmap; bitmap.allocPixels(SkImageInfo::MakeS32(width, height, kPremul_SkAlphaType)); - return SkImage::MakeFromBitmap(bitmap); + return SkImages::RasterFromBitmap(bitmap); } SkM44 CreateMatrix(const SkSize& scale) {
diff --git a/cc/tiles/gpu_image_decode_cache_unittest.cc b/cc/tiles/gpu_image_decode_cache_unittest.cc index b2a8d3a..cb21cc08 100644 --- a/cc/tiles/gpu_image_decode_cache_unittest.cc +++ b/cc/tiles/gpu_image_decode_cache_unittest.cc
@@ -1455,7 +1455,7 @@ PaintImage image = PaintImageBuilder::WithDefault() .set_id(PaintImage::kInvalidId) .set_is_high_bit_depth(true) - .set_image(SkImage::MakeFromBitmap(bitmap), + .set_image(SkImages::RasterFromBitmap(bitmap), PaintImage::GetNextContentId()) .TakePaintImage(); @@ -1509,7 +1509,7 @@ PaintImage image = PaintImageBuilder::WithDefault() .set_id(PaintImage::kInvalidId) .set_is_high_bit_depth(true) - .set_image(SkImage::MakeFromBitmap(bitmap), + .set_image(SkImages::RasterFromBitmap(bitmap), PaintImage::GetNextContentId()) .TakePaintImage();
diff --git a/cc/tiles/image_controller_unittest.cc b/cc/tiles/image_controller_unittest.cc index 7d3d944..4ed33efe 100644 --- a/cc/tiles/image_controller_unittest.cc +++ b/cc/tiles/image_controller_unittest.cc
@@ -407,9 +407,7 @@ EXPECT_TRUE(task->HasCompleted()); } -// TODO(crbug.com/1336053): Re-enable this test -TEST_F(ImageControllerTest, - DISABLED_QueueImageDecodeChangeControllerWithTaskQueued) { +TEST_F(ImageControllerTest, QueueImageDecodeChangeControllerWithTaskQueued) { scoped_refptr<BlockingTask> task_one(new BlockingTask); cache()->SetTaskToUse(task_one);
diff --git a/cc/tiles/software_image_decode_cache_perftest.cc b/cc/tiles/software_image_decode_cache_perftest.cc index a0838d4..afe2c7a 100644 --- a/cc/tiles/software_image_decode_cache_perftest.cc +++ b/cc/tiles/software_image_decode_cache_perftest.cc
@@ -30,7 +30,7 @@ sk_sp<SkImage> CreateImage(int width, int height) { SkBitmap bitmap; bitmap.allocPixels(SkImageInfo::MakeN32Premul(width, height)); - return SkImage::MakeFromBitmap(bitmap); + return SkImages::RasterFromBitmap(bitmap); } SkM44 CreateMatrix(const SkSize& scale) {
diff --git a/cc/tiles/software_image_decode_cache_unittest.cc b/cc/tiles/software_image_decode_cache_unittest.cc index 21abcc3..2102dd4 100644 --- a/cc/tiles/software_image_decode_cache_unittest.cc +++ b/cc/tiles/software_image_decode_cache_unittest.cc
@@ -2029,7 +2029,7 @@ PaintImage image = PaintImageBuilder::WithDefault() .set_id(PaintImage::kInvalidId) .set_is_high_bit_depth(true) - .set_image(SkImage::MakeFromBitmap(bitmap), + .set_image(SkImages::RasterFromBitmap(bitmap), PaintImage::GetNextContentId()) .TakePaintImage(); @@ -2055,7 +2055,7 @@ PaintImage image = PaintImageBuilder::WithDefault() .set_id(PaintImage::kInvalidId) .set_is_high_bit_depth(true) - .set_image(SkImage::MakeFromBitmap(bitmap), + .set_image(SkImages::RasterFromBitmap(bitmap), PaintImage::GetNextContentId()) .TakePaintImage();
diff --git a/cc/tiles/software_image_decode_cache_utils.cc b/cc/tiles/software_image_decode_cache_utils.cc index 6ad9df8..8fa45c1d 100644 --- a/cc/tiles/software_image_decode_cache_utils.cc +++ b/cc/tiles/software_image_decode_cache_utils.cc
@@ -18,6 +18,7 @@ #include "cc/paint/paint_flags.h" #include "cc/tiles/mipmap_util.h" #include "third_party/skia/include/core/SkColorSpace.h" +#include "third_party/skia/include/core/SkImage.h" #include "ui/gfx/geometry/skia_conversions.h" namespace cc { @@ -327,7 +328,7 @@ tracing_id_(g_next_tracing_id_.GetNext()) { DCHECK(memory); SkPixmap pixmap(image_info_, memory->data(), image_info_.minRowBytes()); - image_ = SkImage::MakeFromRaster( + image_ = SkImages::RasterFromPixmap( pixmap, [](const void* pixels, void* context) {}, nullptr); }
diff --git a/cc/tiles/tile_manager_unittest.cc b/cc/tiles/tile_manager_unittest.cc index be7d554..3612462d 100644 --- a/cc/tiles/tile_manager_unittest.cc +++ b/cc/tiles/tile_manager_unittest.cc
@@ -49,6 +49,7 @@ #include "components/viz/test/begin_frame_args_test.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkImageGenerator.h" #include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/skia/include/core/SkSurface.h" @@ -3722,7 +3723,7 @@ PaintImage hdr_image = PaintImageBuilder::WithDefault() .set_id(PaintImage::kInvalidId) .set_is_high_bit_depth(true) - .set_image(SkImage::MakeFromBitmap(bitmap), + .set_image(SkImages::RasterFromBitmap(bitmap), PaintImage::GetNextContentId()) .TakePaintImage();
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 5f394ac..78d403d 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -571,7 +571,8 @@ ui::ScrollInputType::kWheel); if (base::FeatureList::IsEnabled(features::kScrollUnification)) { ASSERT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - ASSERT_TRUE(status.needs_main_thread_hit_test); + ASSERT_EQ(MainThreadScrollingReason::kFailedHitTest, + status.main_thread_hit_test_reasons); } else { ASSERT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); ASSERT_EQ(MainThreadScrollingReason::kFailedHitTest, @@ -586,7 +587,8 @@ ui::ScrollInputType::kWheel); if (base::FeatureList::IsEnabled(features::kScrollUnification)) { ASSERT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - ASSERT_TRUE(status.needs_main_thread_hit_test); + ASSERT_EQ(MainThreadScrollingReason::kFailedHitTest, + status.main_thread_hit_test_reasons); } else { ASSERT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); ASSERT_EQ(MainThreadScrollingReason::kFailedHitTest, @@ -1348,7 +1350,8 @@ scroll_state.get(), ui::ScrollInputType::kWheel); if (base::FeatureList::IsEnabled(features::kScrollUnification)) { EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_FALSE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_hit_test_reasons); EXPECT_EQ( MainThreadScrollingReason::kThreadedScrollingDisabled, host_impl_->CurrentlyScrollingNode()->main_thread_scrolling_reasons); @@ -1676,7 +1679,10 @@ ui::ScrollInputType::kWheel); if (base::FeatureList::IsEnabled(features::kScrollUnification)) { EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_FALSE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_scrolling_reasons); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_hit_test_reasons); EXPECT_EQ( MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects, host_impl_->CurrentlyScrollingNode()->main_thread_scrolling_reasons); @@ -1693,7 +1699,10 @@ ui::ScrollInputType::kTouchscreen); if (base::FeatureList::IsEnabled(features::kScrollUnification)) { EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_FALSE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_scrolling_reasons); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_hit_test_reasons); EXPECT_EQ( MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects, host_impl_->CurrentlyScrollingNode()->main_thread_scrolling_reasons); @@ -1752,7 +1761,8 @@ EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, status.main_thread_scrolling_reasons); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest, + status.main_thread_hit_test_reasons); } else { EXPECT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest, @@ -1906,7 +1916,8 @@ EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, status.main_thread_scrolling_reasons); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, + status.main_thread_hit_test_reasons); } else { EXPECT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, @@ -1922,7 +1933,8 @@ EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, status.main_thread_scrolling_reasons); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, + status.main_thread_hit_test_reasons); } else { EXPECT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, @@ -1987,7 +1999,8 @@ EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, status.main_thread_scrolling_reasons); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, + status.main_thread_hit_test_reasons); } else { EXPECT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, @@ -2016,7 +2029,8 @@ EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, status.main_thread_scrolling_reasons); - EXPECT_FALSE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_hit_test_reasons); GetInputHandler().ScrollUpdate(UpdateState(gfx::Point(), gfx::Vector2d(0, 1), ui::ScrollInputType::kWheel) @@ -2033,7 +2047,8 @@ EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, status.main_thread_scrolling_reasons); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, + status.main_thread_hit_test_reasons); } else { EXPECT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, @@ -2092,7 +2107,8 @@ ASSERT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); ASSERT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, status.main_thread_scrolling_reasons); - ASSERT_TRUE(status.needs_main_thread_hit_test); + ASSERT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, + status.main_thread_hit_test_reasons); } else { ASSERT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); ASSERT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, @@ -2147,7 +2163,8 @@ EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, status.main_thread_scrolling_reasons); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, + status.main_thread_hit_test_reasons); } else { EXPECT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, @@ -2222,7 +2239,8 @@ ASSERT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); ASSERT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, status.main_thread_scrolling_reasons); - ASSERT_TRUE(status.needs_main_thread_hit_test); + ASSERT_EQ(MainThreadScrollingReason::kFailedHitTest, + status.main_thread_hit_test_reasons); } else { ASSERT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); ASSERT_EQ(MainThreadScrollingReason::kFailedHitTest, @@ -2278,7 +2296,8 @@ EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, status.main_thread_scrolling_reasons); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest, + status.main_thread_hit_test_reasons); } else { EXPECT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest, @@ -2339,7 +2358,8 @@ ASSERT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); ASSERT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, status.main_thread_scrolling_reasons); - ASSERT_TRUE(status.needs_main_thread_hit_test); + ASSERT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, + status.main_thread_hit_test_reasons); } else { ASSERT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); ASSERT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, @@ -2394,7 +2414,8 @@ EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, status.main_thread_scrolling_reasons); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, + status.main_thread_hit_test_reasons); } else { EXPECT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, @@ -2487,7 +2508,8 @@ EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, status.main_thread_scrolling_reasons); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest, + status.main_thread_hit_test_reasons); } else { EXPECT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest, @@ -3378,7 +3400,8 @@ // We don't have a layer for the scroller but we didn't hit a non-fast // scrolling region or fail hit testing the layer - we don't need a main // thread hit test in this case. - EXPECT_FALSE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_hit_test_reasons); } else { EXPECT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNoScrollingLayer, @@ -8265,10 +8288,15 @@ ui::ScrollInputType::kWheel); if (base::FeatureList::IsEnabled(features::kScrollUnification)) { EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_FALSE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_scrolling_reasons); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_hit_test_reasons); EXPECT_EQ( MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects, host_impl_->CurrentlyScrollingNode()->main_thread_scrolling_reasons); + EXPECT_EQ(MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects, + status.main_thread_repaint_reasons); } else { // Scrolling fails because the content layer is asking to be scrolled on the // main thread. @@ -11949,7 +11977,8 @@ ui::ScrollInputType::kWheel); if (base::FeatureList::IsEnabled(features::kScrollUnification)) { EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest, + status.main_thread_hit_test_reasons); } else { EXPECT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest, @@ -11992,7 +12021,8 @@ ui::ScrollInputType::kWheel); if (base::FeatureList::IsEnabled(features::kScrollUnification)) { EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest, + status.main_thread_hit_test_reasons); } else { EXPECT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest, @@ -17868,8 +17898,9 @@ ScrollStatus status = GetInputHandler().ScrollBegin( scroll_state.get(), ui::ScrollInputType::kWheel); - if (status.needs_main_thread_hit_test) + if (status.main_thread_hit_test_reasons) { to_be_continued_scroll_begin_ = std::move(scroll_state); + } return status; } @@ -17882,7 +17913,8 @@ std::move(to_be_continued_scroll_begin_); scroll_state->data()->set_current_native_scrolling_element(element_id); - scroll_state->data()->is_main_thread_hit_tested = true; + scroll_state->data()->main_thread_hit_tested_reasons = + MainThreadScrollingReason::kFailedHitTest; return GetInputHandler().ScrollBegin(scroll_state.get(), ui::ScrollInputType::kWheel); @@ -17976,7 +18008,8 @@ ScrollStatus status = ScrollBegin(gfx::Vector2d(0, 10)); EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, + status.main_thread_hit_test_reasons); // The scroll hasn't started yet though. EXPECT_FALSE(CurrentlyScrollingNode()); @@ -17989,7 +18022,8 @@ ScrollStatus status = ContinuedScrollBegin(ScrollerElementId()); EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_FALSE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_hit_test_reasons); EXPECT_TRUE(CurrentlyScrollingNode()); EXPECT_EQ(ScrollerNode(), CurrentlyScrollingNode()); @@ -18034,7 +18068,8 @@ { ScrollStatus status = ScrollBegin(gfx::Vector2d(0, 10)); - ASSERT_TRUE(status.needs_main_thread_hit_test); + ASSERT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, + status.main_thread_hit_test_reasons); status = ContinuedScrollBegin(ScrollerElementId()); // Since the hit tested scroller in ContinuedScrollBegin was fully @@ -18108,7 +18143,8 @@ { ScrollStatus status = ScrollBegin(gfx::Vector2d(0, 10)); EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest, + status.main_thread_hit_test_reasons); } // Resolving the hit test should allow the scroller underneath to scroll as @@ -18116,7 +18152,8 @@ { ScrollStatus status = ContinuedScrollBegin(ScrollerElementId()); EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_FALSE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_hit_test_reasons); EXPECT_TRUE(CurrentlyScrollingNode()); EXPECT_EQ(ScrollerNode(), CurrentlyScrollingNode()); @@ -18133,7 +18170,8 @@ { ScrollStatus status = ScrollBegin(gfx::Vector2d(0, 10)); EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_FALSE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_hit_test_reasons); } } @@ -18160,8 +18198,9 @@ // test parameter. { ScrollStatus status = ScrollBegin(gfx::Vector2d(0, 10)); - if (status.needs_main_thread_hit_test) + if (status.main_thread_hit_test_reasons) { ContinuedScrollBegin(ScrollerElementId()); + } ASSERT_EQ(ScrollerNode(), CurrentlyScrollingNode());
diff --git a/cc/trees/layer_tree_host_pixeltest_tiles.cc b/cc/trees/layer_tree_host_pixeltest_tiles.cc index 38cc42f..64a1cb3 100644 --- a/cc/trees/layer_tree_host_pixeltest_tiles.cc +++ b/cc/trees/layer_tree_host_pixeltest_tiles.cc
@@ -238,7 +238,7 @@ ::testing::PrintToStringParamName()); #if BUILDFLAG(IS_CHROMEOS_ASH) || defined(MEMORY_SANITIZER) || \ - defined(ADDRESS_SANITIZER) || BUILDFLAG(IS_FUCHSIA) + defined(ADDRESS_SANITIZER) // TODO(crbug.com/1045521): Flakes on all slower bots. #define MAYBE_PartialRaster DISABLED_PartialRaster #else @@ -288,7 +288,7 @@ // Flaky on Linux TSAN. https://crbug.com/707711 #define MAYBE_PartialRaster DISABLED_PartialRaster #elif BUILDFLAG(IS_CHROMEOS_ASH) || defined(MEMORY_SANITIZER) || \ - defined(ADDRESS_SANITIZER) || BUILDFLAG(IS_FUCHSIA) + defined(ADDRESS_SANITIZER) // TODO(crbug.com/1045521): Flakes on all slower bots. #define MAYBE_PartialRaster DISABLED_PartialRaster #else
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index 63a8384..d945084d 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc
@@ -88,6 +88,7 @@ #include "testing/gmock/include/gmock/gmock.h" #include "third_party/khronos/GLES2/gl2.h" #include "third_party/khronos/GLES2/gl2ext.h" +#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkPicture.h" #include "third_party/skia/include/gpu/GrDirectContext.h" #include "ui/gfx/animation/keyframe/timing_function.h" @@ -8429,7 +8430,7 @@ bitmap_.allocN32Pixels(10, 10); PaintImage image = PaintImageBuilder::WithDefault() .set_id(PaintImage::GetNextId()) - .set_image(SkImage::MakeFromBitmap(bitmap_), + .set_image(SkImages::RasterFromBitmap(bitmap_), PaintImage::GetNextContentId()) .TakePaintImage(); auto callback = base::BindOnce(
diff --git a/cc/trees/layer_tree_host_unittest_scroll.cc b/cc/trees/layer_tree_host_unittest_scroll.cc index c9d0e87..dd5adcd 100644 --- a/cc/trees/layer_tree_host_unittest_scroll.cc +++ b/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -1613,7 +1613,8 @@ ui::ScrollInputType::kTouchscreen); if (base::FeatureList::IsEnabled(features::kScrollUnification)) { EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, + status.main_thread_hit_test_reasons); impl->GetInputHandler().ScrollEnd(); } else { EXPECT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); @@ -1625,7 +1626,8 @@ BeginState(gfx::Point(21, 21), gfx::Vector2dF(0, 1)).get(), ui::ScrollInputType::kTouchscreen); EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_FALSE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_hit_test_reasons); EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, status.main_thread_scrolling_reasons); @@ -1687,7 +1689,9 @@ &scroll_state, ui::ScrollInputType::kTouchscreen); if (base::FeatureList::IsEnabled(features::kScrollUnification)) { EXPECT_EQ(impl->CurrentlyScrollingNode(), scroller_scroll_node); - EXPECT_FALSE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_hit_test_reasons); + ; } else { // Despite the fact that we hit the scroller, which has no main thread // scrolling reason, we still must fallback to main thread scrolling due @@ -1710,7 +1714,9 @@ &scroll_state, ui::ScrollInputType::kTouchscreen); if (base::FeatureList::IsEnabled(features::kScrollUnification)) { EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_FALSE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_hit_test_reasons); + ; EXPECT_EQ(impl->CurrentlyScrollingNode(), impl->OuterViewportScrollNode()); } else { @@ -2815,7 +2821,9 @@ // Hitting a non fast region should request a hit test from the main // thread. EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, + status.main_thread_hit_test_reasons); + ; impl->GetInputHandler().ScrollEnd(); } else { // Prior to scroll unification, this forces scrolling to the main @@ -2834,7 +2842,9 @@ ui::ScrollInputType::kTouchscreen); if (base::FeatureList::IsEnabled(features::kScrollUnification)) { EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_FALSE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_hit_test_reasons); + ; } else { EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, @@ -2854,7 +2864,9 @@ // layer is scrollable from the compositor thread so no need to involve // the main thread. EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_FALSE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_hit_test_reasons); + ; EXPECT_EQ(scroll_node, impl->CurrentlyScrollingNode()); impl->GetInputHandler().ScrollEnd(); } else {
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index a54d039..04e11bca 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -15,6 +15,7 @@ import("//chrome/android/expectations/expectations.gni") import("//chrome/android/features/dev_ui/dev_ui_module.gni") import("//chrome/android/features/start_surface/start_surface_java_sources.gni") +import("//chrome/android/features/tab_ui/buildflags.gni") import("//chrome/android/features/tab_ui/tab_management_java_sources.gni") import("//chrome/android/features/vr/public_vr_java_sources.gni") import("//chrome/android/feed/feed_java_sources.gni") @@ -105,19 +106,7 @@ android_resources("chrome_app_java_resources") { sources = chrome_java_resources - sources += [ - "//chrome/android/java/res_app/layout/main.xml", - "//chrome/android/java/res_chromium/drawable-hdpi/fre_product_logo.png", - "//chrome/android/java/res_chromium/drawable-hdpi/product_logo_name.png", - "//chrome/android/java/res_chromium/drawable-mdpi/fre_product_logo.png", - "//chrome/android/java/res_chromium/drawable-mdpi/product_logo_name.png", - "//chrome/android/java/res_chromium/drawable-xhdpi/fre_product_logo.png", - "//chrome/android/java/res_chromium/drawable-xhdpi/product_logo_name.png", - "//chrome/android/java/res_chromium/drawable-xxhdpi/fre_product_logo.png", - "//chrome/android/java/res_chromium/drawable-xxhdpi/product_logo_name.png", - "//chrome/android/java/res_chromium/drawable-xxxhdpi/fre_product_logo.png", - "//chrome/android/java/res_chromium/drawable-xxxhdpi/product_logo_name.png", - ] + sources += [ "//chrome/android/java/res_app/layout/main.xml" ] deps = [ ":chrome_base_module_resources", @@ -607,13 +596,8 @@ sources += public_vr_java_sources - # Include sources from tab_management_java_sources.gni. + # Include sources from public_tab_management_java_sources.gni. sources += public_tab_management_java_sources - - # TODO(crbug/1422324): Make tab_ui/ a module so that these sources can be included in "chrome_all_java". - sources += internal_tab_management_java_sources - - # Include sources for start_surface_java_sources.gni sources += start_surface_java_sources if (enable_arcore) { deps += [ "//third_party/arcore-android-sdk-client:com_google_ar_core_java__ignored_manifest" ] @@ -733,6 +717,13 @@ "//components/messages/android/internal:java", "//components/segmentation_platform/internal:internal_java", ] + + if (disable_tab_ui_dfm) { + deps += [ + "//chrome/android/features/tab_ui:java", + "//chrome/android/features/tab_ui:module_desc_java", + ] + } } action_with_pydeps("chrome_android_java_google_api_keys_srcjar") { @@ -839,6 +830,7 @@ "//chrome/android/features/keyboard_accessory:internal_java", "//chrome/android/features/start_surface:java_resources", "//chrome/android/features/start_surface:public_java", + "//chrome/android/features/tab_ui:java", "//chrome/android/features/tab_ui:tab_suggestions_java", "//chrome/android/features/tab_ui/public:java", "//chrome/android/modules/image_editor/provider:java", @@ -1263,7 +1255,6 @@ "javatests/src/org/chromium/chrome/browser/tab/WebContentsStateBridgeTest.java", "javatests/src/org/chromium/chrome/browser/tab/state/FilePersistedTabDataStorageTest.java", "javatests/src/org/chromium/chrome/browser/tab/state/PersistedTabDataTest.java", - "javatests/src/org/chromium/chrome/browser/tab/state/PriceDropMetricsLoggerTest.java", "javatests/src/org/chromium/chrome/browser/tabmodel/AsyncTabCreationParamsManagerTest.java", "javatests/src/org/chromium/chrome/browser/tabmodel/RestoreMigrateTest.java", "javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreUnitTest.java", @@ -1402,6 +1393,7 @@ "//chrome/android/features/keyboard_accessory/public:public_java", "//chrome/android/features/start_surface:java_resources", "//chrome/android/features/start_surface:public_java", + "//chrome/android/features/tab_ui:java", "//chrome/android/features/tab_ui:java_resources", "//chrome/android/features/tab_ui:tab_suggestions_java", "//chrome/android/features/tab_ui:test_support_javalib", @@ -1925,26 +1917,6 @@ } } - # Overrides icon / name defined in chrome_app_java_resources. - android_resources("chrome_public_apk_resources") { - resource_overlay = true - sources = [ - "java/res_chromium/drawable-hdpi/fre_product_logo.png", - "java/res_chromium/drawable-hdpi/product_logo_name.png", - "java/res_chromium/drawable-mdpi/fre_product_logo.png", - "java/res_chromium/drawable-mdpi/product_logo_name.png", - "java/res_chromium/drawable-xhdpi/fre_product_logo.png", - "java/res_chromium/drawable-xhdpi/product_logo_name.png", - "java/res_chromium/drawable-xxhdpi/fre_product_logo.png", - "java/res_chromium/drawable-xxhdpi/product_logo_name.png", - "java/res_chromium/drawable-xxxhdpi/fre_product_logo.png", - "java/res_chromium/drawable-xxxhdpi/product_logo_name.png", - ] - - # Dep needed to ensure override works properly. - deps = [ ":chrome_app_java_resources" ] - } - # Overrides icon / name defined in chrome_base_module_resources. android_resources("chrome_public_apk_base_module_resources") { resource_overlay = true
diff --git a/chrome/android/chrome_junit_test_java_sources.gni b/chrome/android/chrome_junit_test_java_sources.gni index 2c1be0a..37bc1b73 100644 --- a/chrome/android/chrome_junit_test_java_sources.gni +++ b/chrome/android/chrome_junit_test_java_sources.gni
@@ -132,6 +132,7 @@ "junit/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabHandleStrategyFactoryTest.java", "junit/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabSideSheetStrategyTest.java", "junit/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabTestRule.java", + "junit/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabVersionCompatTest.java", "junit/src/org/chromium/chrome/browser/customtabs/features/sessionrestore/SessionRestoreManagerUnitTest.java", "junit/src/org/chromium/chrome/browser/customtabs/features/sessionrestore/SessionRestoreMessageControllerUnitTest.java", "junit/src/org/chromium/chrome/browser/customtabs/features/sessionrestore/SessionRestoreUtilsUnitTest.java",
diff --git a/chrome/android/chrome_test_apk_tmpl.gni b/chrome/android/chrome_test_apk_tmpl.gni index 113c1e40..4f98e7e6 100644 --- a/chrome/android/chrome_test_apk_tmpl.gni +++ b/chrome/android/chrome_test_apk_tmpl.gni
@@ -6,10 +6,11 @@ # Dependencies that are common to any chrome_public derivative targets. chrome_public_shared_deps = [ + "//chrome/android:chrome_app_java_resources", "//chrome/android:chrome_public_apk_base_module_resources", - "//chrome/android:chrome_public_apk_resources", "//chrome/android:chrome_public_base_module_java", "//chrome/android:chrome_public_non_pak_assets", + "//components/browser_ui/styles/android:chrome_public_apk_resources", "//gin:v8_snapshot_assets", "//third_party/icu:icu_assets", ]
diff --git a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceCoordinator.java b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceCoordinator.java index 3029b16..7d969d8d 100644 --- a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceCoordinator.java +++ b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceCoordinator.java
@@ -61,7 +61,7 @@ import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tasks.ReturnToChromeUtil; import org.chromium.chrome.browser.tasks.tab_management.TabManagementDelegate.TabSwitcherType; -import org.chromium.chrome.browser.tasks.tab_management.TabManagementDelegateProvider; +import org.chromium.chrome.browser.tasks.tab_management.TabManagementModuleProvider; import org.chromium.chrome.browser.tasks.tab_management.TabSwitcher; import org.chromium.chrome.browser.tasks.tab_management.TabSwitcherCustomViewManager; import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities; @@ -327,7 +327,7 @@ ViewGroup feedPlaceholderParentView = null; if (!mIsStartSurfaceEnabled && !mIsStartSurfaceRefactorEnabled) { // Create Tab switcher directly to save one layer in the view hierarchy. - mGridTabSwitcher = TabManagementDelegateProvider.getDelegate().createGridTabSwitcher( + mGridTabSwitcher = TabManagementModuleProvider.getDelegate().createGridTabSwitcher( activity, activityLifecycleDispatcher, tabModelSelector, tabContentManager, browserControlsManager, tabCreatorManager, menuOrKeyboardActionController, containerView, multiWindowModeStateDispatcher, scrimCoordinator, @@ -876,7 +876,7 @@ mWindowAndroid); if (tabSwitcherType == TabSwitcherType.CAROUSEL) { mTabSwitcherModule = - TabManagementDelegateProvider.getDelegate().createCarouselTabSwitcher(mActivity, + TabManagementModuleProvider.getDelegate().createCarouselTabSwitcher(mActivity, mActivityLifecycleDispatcher, mTabModelSelector, mTabContentManager, mBrowserControlsManager, mTabCreatorManager, mMenuOrKeyboardActionController,
diff --git a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayout.java b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayout.java index c7dafce..fc24112 100644 --- a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayout.java +++ b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayout.java
@@ -897,6 +897,11 @@ return super.canHostBeFocusable(); } + @Override + public boolean isRunningAnimations() { + return mDeferredAnimationRunnable != null || mTabToSwitcherAnimation != null; + } + /** * Shrink/Expand animation is disabled for Tablet TabSwitcher launch polish. * @return Whether shrink/expand animation is enabled.
diff --git a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/TasksSurfaceCoordinator.java b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/TasksSurfaceCoordinator.java index a12290f..af4ad59 100644 --- a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/TasksSurfaceCoordinator.java +++ b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/TasksSurfaceCoordinator.java
@@ -43,7 +43,7 @@ import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tasks.ReturnToChromeUtil; import org.chromium.chrome.browser.tasks.tab_management.TabManagementDelegate.TabSwitcherType; -import org.chromium.chrome.browser.tasks.tab_management.TabManagementDelegateProvider; +import org.chromium.chrome.browser.tasks.tab_management.TabManagementModuleProvider; import org.chromium.chrome.browser.tasks.tab_management.TabSwitcher; import org.chromium.chrome.browser.tasks.tab_management.TabSwitcherCustomViewManager; import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities; @@ -122,7 +122,7 @@ mModalDialogManager = modalDialogManager; mParentTabSupplier = parentTabSupplier; if (tabSwitcherType == TabSwitcherType.CAROUSEL) { - mTabSwitcher = TabManagementDelegateProvider.getDelegate().createCarouselTabSwitcher( + mTabSwitcher = TabManagementModuleProvider.getDelegate().createCarouselTabSwitcher( activity, activityLifecycleDispatcher, tabModelSelector, tabContentManager, browserControlsStateProvider, tabCreatorManager, menuOrKeyboardActionController, mView.getCarouselTabSwitcherContainer(), multiWindowModeStateDispatcher, @@ -131,8 +131,8 @@ } else if (tabSwitcherType == TabSwitcherType.GRID) { assert incognitoReauthControllerSupplier != null : "Valid Incognito re-auth controller supplier needed to create GTS."; - mTabSwitcher = TabManagementDelegateProvider.getDelegate().createGridTabSwitcher( - activity, activityLifecycleDispatcher, tabModelSelector, tabContentManager, + mTabSwitcher = TabManagementModuleProvider.getDelegate().createGridTabSwitcher(activity, + activityLifecycleDispatcher, tabModelSelector, tabContentManager, browserControlsStateProvider, tabCreatorManager, menuOrKeyboardActionController, mView.getBodyViewContainer(), multiWindowModeStateDispatcher, scrimCoordinator, rootView, dynamicResourceLoaderSupplier, snackbarManager, modalDialogManager,
diff --git a/chrome/android/features/tab_ui/BUILD.gn b/chrome/android/features/tab_ui/BUILD.gn index 10b2f5f..40fd609 100644 --- a/chrome/android/features/tab_ui/BUILD.gn +++ b/chrome/android/features/tab_ui/BUILD.gn
@@ -4,8 +4,9 @@ import("//build/config/android/rules.gni") import("//build/config/locales.gni") -import("//chrome/android/features/android_library_factory_tmpl.gni") +import("//chrome/android/features/tab_ui/buildflags.gni") import("//chrome/common/features.gni") +import("//components/module_installer/android/module_desc_java.gni") import("//tools/grit/grit_rule.gni") java_strings_grd("java_strings_grd") { @@ -89,6 +90,166 @@ ] } +android_library("java") { + sources = [ + "java/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupUtils.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/ClosableTabGridView.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/CouponCardView.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/IncognitoReauthPromoMessageService.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/IncognitoReauthPromoViewModel.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/IphMessageCardViewModel.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/IphMessageService.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/LargeMessageCardView.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/LargeMessageCardViewBinder.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardProviderCoordinator.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardProviderMediator.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardView.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardViewBinder.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardViewProperties.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardViewUtils.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/MessageService.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/MultiThumbnailCardProvider.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/PriceCardView.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/PriceMessageCardViewModel.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/PriceMessageService.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/SelectableTabGridView.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogCoordinator.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMenuCoordinator.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMenuItemBinder.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMenuItemProperties.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogView.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridIphDialogCoordinator.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridIphDialogView.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallback.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridPanelProperties.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridPanelViewBinder.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridThumbnailView.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupTitleEditor.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiProperties.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiToolbarView.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiViewBinder.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabListContainerProperties.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabListContainerViewBinder.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabListModel.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabListRecyclerView.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewBinder.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateImpl.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabProperties.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorAction.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorActionProperties.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorActionProvider.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorActionViewLayout.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorBookmarkAction.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorCloseAction.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorCoordinator.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorGroupAction.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorLayout.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorLayoutBinder.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMediator.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMenu.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMenuAdapter.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMenuItem.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorProperties.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorSelectionAction.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorShareAction.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorToolbar.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorUngroupAction.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabStripSnapshotter.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabStripViewBinder.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabSuggestionMessageCardViewModel.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabSuggestionMessageService.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherCoordinator.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiMetricsHelper.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/BaselineTabSuggestionProvider.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/StaleTabSuggestionProvider.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabContextObserver.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabSuggestionProvider.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabSuggestionProviderConfiguration.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabSuggestionsClientFetcher.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabSuggestionsFetcher.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabSuggestionsFetcherResults.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabSuggestionsOrchestrator.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabSuggestionsRanker.java", + ] + + deps = [ + ":java_resources", + ":tab_suggestions_java", + "//base:base_java", + "//chrome/android:chrome_java", + "//chrome/android:ui_locale_string_resources", + "//chrome/android/features/start_surface:public_java", + "//chrome/android/features/tab_ui/public:java", + "//chrome/app:java_strings_grd", + "//chrome/browser/android/lifecycle:java", + "//chrome/browser/back_press/android:java", + "//chrome/browser/browser_controls/android:java", + "//chrome/browser/commerce/price_tracking/android:java", + "//chrome/browser/endpoint_fetcher:java", + "//chrome/browser/feature_engagement:java", + "//chrome/browser/feed/android:java", + "//chrome/browser/flags:java", + "//chrome/browser/incognito:java", + "//chrome/browser/lens:java", + "//chrome/browser/preferences:java", + "//chrome/browser/profiles/android:java", + "//chrome/browser/search_engines/android:java", + "//chrome/browser/share:java", + "//chrome/browser/signin/services/android:java", + "//chrome/browser/tab:java", + "//chrome/browser/tab_group:java", + "//chrome/browser/tabmodel:java", + "//chrome/browser/ui/android/favicon:java", + "//chrome/browser/ui/android/layouts:java", + "//chrome/browser/ui/android/native_page:java", + "//chrome/browser/ui/android/night_mode:java", + "//chrome/browser/ui/android/omnibox:java", + "//chrome/browser/ui/android/strings:ui_strings_grd", + "//chrome/browser/ui/android/theme:java", + "//chrome/browser/ui/android/toolbar:java", + "//chrome/browser/ui/messages/android:java", + "//chrome/browser/util:java", + "//components/browser_ui/bottomsheet/android:java", + "//components/browser_ui/share/android:java", + "//components/browser_ui/styles/android:java", + "//components/browser_ui/util/android:java", + "//components/browser_ui/widget/android:java", + "//components/embedder_support/android:util_java", + "//components/embedder_support/android:web_contents_delegate_java", + "//components/favicon/android:java", + "//components/feature_engagement:feature_engagement_java", + "//components/policy/android:policy_java", + "//components/prefs/android:java", + "//components/search_engines/android:java", + "//components/signin/public/android:java", + "//components/site_engagement/content/android:java", + "//components/user_prefs/android:java", + "//content/public/android:content_java", + "//content/public/android:content_java_resources", + "//net/android:net_java", + "//third_party/android_deps:material_design_java", + "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_appcompat_appcompat_java", + "//third_party/androidx:androidx_appcompat_appcompat_resources_java", + "//third_party/androidx:androidx_collection_collection_java", + "//third_party/androidx:androidx_core_core_java", + "//third_party/androidx:androidx_lifecycle_lifecycle_runtime_java", + "//third_party/androidx:androidx_recyclerview_recyclerview_java", + "//third_party/androidx:androidx_vectordrawable_vectordrawable_animated_java", + "//ui/android:ui_java", + "//ui/base/mojom:mojom_java", + "//url:gurl_java", + ] + resources_package = "org.chromium.chrome.tab_ui" +} + android_library("unit_device_javatests") { testonly = true sources = [ @@ -103,14 +264,18 @@ "javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorLayoutBinderTest.java", ] + # NOTE: the chrome/android:chrome_java dep is necessary to include the + # public_tab_management_java_sources. deps = [ + ":java", ":java_resources", - ":tab_suggestions_java", ":test_support_javalib", "//base:base_java", "//base:base_java_test_support", "//base/test:test_support_java", "//chrome/android:chrome_java", + "//chrome/android/features/tab_ui:java", + "//chrome/android/features/tab_ui:tab_suggestions_java", "//chrome/browser/commerce/price_tracking/android:java", "//chrome/browser/flags:java", "//chrome/browser/optimization_guide/android:java", @@ -175,6 +340,7 @@ sources = [ "javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java" ] deps = [ + ":java", "//base:base_java", "//base:base_java_test_support", "//chrome/android:chrome_java", @@ -199,3 +365,7 @@ "//ui/android:ui_no_recycler_view_java", ] } + +module_desc_java("module_desc_java") { + module_name = "tab_management" +}
diff --git a/chrome/android/features/tab_ui/buildflags.gni b/chrome/android/features/tab_ui/buildflags.gni new file mode 100644 index 0000000..1243188 --- /dev/null +++ b/chrome/android/features/tab_ui/buildflags.gni
@@ -0,0 +1,8 @@ +# Copyright 2019 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +declare_args() { + # Controls the feature being a DFM or not. + disable_tab_ui_dfm = true +}
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallback.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallback.java index 14d3463..efb823d 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallback.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallback.java
@@ -268,39 +268,47 @@ mActionAttempted = true; } - // The following is the entry point for the longpress action for TabSelectionEditorV2. - // If the conditions mentioned below are avoided, the block will trigger and perform a - // longpress action on the held tab, bringing up the selection editor interface. + // There is a bug with ItemTouchHelper where on longpress, if the held tab is not + // dragged (no movement occurs), then the gesture will not actually be consumed by the + // ItemTouchHelper. This manifests as a MOTION_UP event being propagated to child view + // click handlers and resulting in a real "click" occurring despite the action having + // technically been consumed as a longpress by this class. The downstream click + // handlers running can result in a tab being selected or closed in an unexpected manner + // and due to a race condition between animations a phantom tab can even remain in the + // UI (see crbug.com/1425336). + // + // To avoid this it is necessary for TabListMediator to attach an additional + // OnItemTouchListener that resolves after the OnItemTouchListener attached by the + // ItemTouchHelper that TabGridItemTouchHelperCallback is bound to. This additional + // OnItemTouchListener will block the MOTION_UP event preventing the unintended action + // from resolving. // // This block will not trigger if: // a swipe was started but unfinished as mSelectedTabIndex may not be set. // a swipe, move or group/ungroup happens. // a tab is moved beyond a minimum distance from its original location. // - // An edge case exists where on longpress, if the held tab is not dragged (no movement - // occurs), the MOTION_UP event on release will not be intercepted by the below attached - // onLongPressTabItemEventListener. After processing the longpress action, the MOTION_UP - // event will propagate down to the subsequent recyclerViews and be consumed there, - // resulting in a click on the tab grid card. The unwanted click behaviour will be - // blocked by the logic below if the conditions are met. - if (mOnLongPressTabItemEventListener != null - && (mSelectedTabIndex != TabModel.INVALID_TAB_INDEX - && mSelectedTabIndex < mModel.size() && !mActionAttempted - && mModel.get(mSelectedTabIndex).model.get(CARD_TYPE) == TAB - && TabUiFeatureUtilities.ENABLE_TAB_SELECTION_EDITOR_V2_LONGPRESS_ENTRY - .getValue())) { - int tabId = mModel.get(mSelectedTabIndex).model.get(TabProperties.TAB_ID); + // Otherwise, the unwanted click behaviour will be blocked. + if (mSelectedTabIndex != TabModel.INVALID_TAB_INDEX && mSelectedTabIndex < mModel.size() + && !mActionAttempted + && mModel.get(mSelectedTabIndex).model.get(CARD_TYPE) == TAB) { // If the child was ever dragged or swiped do not consume the next action, as the // longpress will resolve safely due to the listener intercepting the DRAG event // and negating any further action. However, if we just release the tab without // starting a swipe or drag then it is possible the longpress instead resolves as a - // MOTION_UP click event which leads to tab selection occurring in the selection - // editor or resulting in clicking the tab itself. This issue can be avoided by - // requesting to block the next action. + // MOTION_UP click event leading to the problems described above. if (!mActionStarted) { mShouldBlockAction = true; } - mOnLongPressTabItemEventListener.onLongPressEvent(tabId); + + // The following is the entry point for the longpress action for + // TabSelectionEditorV2. + if (mOnLongPressTabItemEventListener != null + && TabUiFeatureUtilities.ENABLE_TAB_SELECTION_EDITOR_V2_LONGPRESS_ENTRY + .getValue()) { + int tabId = mModel.get(mSelectedTabIndex).model.get(TabProperties.TAB_ID); + mOnLongPressTabItemEventListener.onLongPressEvent(tabId); + } } mHoveredTabIndex = TabModel.INVALID_TAB_INDEX; mSelectedTabIndex = TabModel.INVALID_TAB_INDEX;
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java index 7588835..e218fd9f 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java
@@ -4,6 +4,8 @@ package org.chromium.chrome.browser.tasks.tab_management; +import static org.chromium.chrome.browser.tasks.tab_management.TabManagementModuleProvider.SYNTHETIC_TRIAL_POSTFIX; + import android.app.Activity; import android.content.Context; import android.view.LayoutInflater; @@ -19,10 +21,12 @@ import org.chromium.base.supplier.OneshotSupplier; import org.chromium.base.supplier.Supplier; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.layouts.LayoutStateProvider; import org.chromium.chrome.browser.layouts.LayoutType; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; import org.chromium.chrome.browser.lifecycle.PauseResumeWithNativeObserver; +import org.chromium.chrome.browser.metrics.UmaSessionStats; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.state.CriticalPersistedTabData; import org.chromium.chrome.browser.tabmodel.IncognitoStateProvider; @@ -138,6 +142,12 @@ BottomControlsCoordinator.BottomControlsVisibilityController visibilityController, Callback<Object> onModelTokenChange) { try (TraceEvent e = TraceEvent.scoped("TabGroupUiCoordinator.initializeWithNative")) { + if (UmaSessionStats.isMetricsServiceAvailable()) { + UmaSessionStats.registerSyntheticFieldTrial( + ChromeFeatureList.TAB_GROUPS_ANDROID + SYNTHETIC_TRIAL_POSTFIX, + "Downloaded_Enabled"); + } + mTabStripCoordinator = new TabListCoordinator(TabListCoordinator.TabListMode.STRIP, mContext, mTabModelSelector, null, null, false, null, null, TabProperties.UiType.STRIP, null, null, mTabListContainerView, true,
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java index 3dc7fe7..ffde309 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java
@@ -329,14 +329,15 @@ mContext.getResources().getDimension( R.dimen.bottom_sheet_peek_height)); - // The block below creates an instance of the ItemTouchHelper and also utilizes the - // TabGridItemTouchHelperCallback and its shouldBlockAction after attaching to the - // recycler view. The block action function determines if on longpress, a propagated - // MOTION_UP click event should be intercepted and negated by this listener to - // prevent selection state issues from occurring on subsequent recycler view layers - // should the MOTION_UP event continue propagating. The motion events concerning the - // longpress action are consumed by this recycler view, which is why the solution - // targets this recycler view rather than the selection editor recycler view. + // Creates an instance of the ItemTouchHelper using TabGridItemTouchHelperCallback + // and attach a downsteam mOnItemTouchListener that watches for + // TabGridItemTouchHelperCallback#shouldBlockAction() to occur. This determines if + // on a longpress the final MOTION_UP event should be intercepted if it should have + // been filtered in the ItemTouchHelper, but was not handled. This then allows + // the mOnItemTouchHelper to intercept the event and prevent subsequent downstream + // click handlers from receiving an input possibly causing unexpected behaviors. + // + // See similar comments in TabGridItemTouchHelperCallback for more details. mItemTouchHelper = new ItemTouchHelper(callback); mItemTouchHelper.attachToRecyclerView(mRecyclerView); mOnItemTouchListener = new OnItemTouchListener() { @@ -344,13 +345,14 @@ public boolean onInterceptTouchEvent( RecyclerView recyclerView, MotionEvent event) { // There can be an edge case when adding the block action logic where - // minimal movement not picked up by the actionStarted bool in onChildDraw - // can result in a block action request with a DRAG event. The event gets - // consumed and no erroneous selection would have occurred as it is not a - // pure longpress, but due to the active block request, subsequent - // intercepted actions may be blocked or have weird behaviours. This check - // ensures that for a given action, if a block is requested, the MOTION_UP - // event which results in a propagated click must be present to block it. + // minimal movement not picked up by the mItemTouchHelper can result in + // attempting to block an action that did have a DRAG event. Actually, + // blocking the next event in this can result in an unexpected event + // being consumed leading to an unexpected sequence of MotionEvents. + // This bad sequence can then result in invalid UI & click state for + // downstream touch handlers. This additional check ensures that for a + // given action, if a block is requested it must be the UP motion that + // ends the input. if (callback.shouldBlockAction() && (event.getActionMasked() == MotionEvent.ACTION_UP || event.getActionMasked()
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegate.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegate.java index dfa354a..85534c8 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegate.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegate.java
@@ -36,6 +36,7 @@ import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; import org.chromium.components.browser_ui.widget.MenuOrKeyboardActionController; import org.chromium.components.browser_ui.widget.scrim.ScrimCoordinator; +import org.chromium.components.module_installer.builder.ModuleInterface; import org.chromium.ui.modaldialog.ModalDialogManager; import org.chromium.ui.resources.dynamics.DynamicResourceLoader; @@ -44,7 +45,10 @@ /** * Interface to get access to components concerning tab management. + * TODO(crbug.com/982018): Move DFM configurations to 'chrome/android/modules/start_surface/' */ +@ModuleInterface(module = "tab_management", + impl = "org.chromium.chrome.browser.tasks.tab_management.TabManagementDelegateImpl") public interface TabManagementDelegate { @IntDef({TabSwitcherType.GRID, TabSwitcherType.CAROUSEL, TabSwitcherType.SINGLE, TabSwitcherType.NONE})
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateImpl.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateImpl.java index 25ce5c73b0..64dece91 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateImpl.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateImpl.java
@@ -4,6 +4,8 @@ package org.chromium.chrome.browser.tasks.tab_management; +import static org.chromium.chrome.browser.tasks.tab_management.TabManagementModuleProvider.SYNTHETIC_TRIAL_POSTFIX; + import android.app.Activity; import android.content.Context; import android.view.ViewGroup; @@ -22,9 +24,11 @@ import org.chromium.chrome.browser.compositor.layouts.LayoutRenderHost; import org.chromium.chrome.browser.compositor.layouts.LayoutUpdateHost; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.incognito.reauth.IncognitoReauthController; import org.chromium.chrome.browser.layouts.LayoutStateProvider; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; +import org.chromium.chrome.browser.metrics.UmaSessionStats; import org.chromium.chrome.browser.multiwindow.MultiWindowModeStateDispatcher; import org.chromium.chrome.browser.tabmodel.IncognitoStateProvider; import org.chromium.chrome.browser.tabmodel.TabCreatorManager; @@ -68,6 +72,12 @@ @NonNull ModalDialogManager modalDialogManager, @NonNull OneshotSupplier<IncognitoReauthController> incognitoReauthControllerSupplier, @Nullable BackPressManager backPressManager) { + if (UmaSessionStats.isMetricsServiceAvailable()) { + UmaSessionStats.registerSyntheticFieldTrial( + ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID + SYNTHETIC_TRIAL_POSTFIX, + "Downloaded_Enabled"); + } + return new TabSwitcherCoordinator(activity, activityLifecycleDispatcher, tabModelSelector, tabContentManager, browserControlsStateProvider, tabCreatorManager, menuOrKeyboardActionController, containerView, multiWindowModeStateDispatcher,
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateProvider.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateProvider.java deleted file mode 100644 index a69a791..0000000 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateProvider.java +++ /dev/null
@@ -1,22 +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. - -package org.chromium.chrome.browser.tasks.tab_management; - -/** - * Provider class for {@link TabManagementDelegate}. - */ -public class TabManagementDelegateProvider { - private static TabManagementDelegateImpl sTabManagementDelegateImpl; - - /** - * Returns {@link TabManagementDelegate} implementation. - */ - public static TabManagementDelegate getDelegate() { - if (sTabManagementDelegateImpl == null) { - sTabManagementDelegateImpl = new TabManagementDelegateImpl(); - } - return sTabManagementDelegateImpl; - } -}
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementModuleProvider.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementModuleProvider.java new file mode 100644 index 0000000..afe03fcc --- /dev/null +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementModuleProvider.java
@@ -0,0 +1,55 @@ +// Copyright 2019 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.tasks.tab_management; + +import androidx.annotation.Nullable; + +import org.chromium.chrome.browser.flags.ChromeFeatureList; +import org.chromium.chrome.browser.metrics.UmaSessionStats; +/** + * Provider class for TabManagementModule. + */ +public class TabManagementModuleProvider { + public static final String SYNTHETIC_TRIAL_POSTFIX = "SyntheticTrial"; + + /** + * Returns {@link TabManagementDelegate} implementation if the module is installed. null, + * otherwise. + */ + public static @Nullable TabManagementDelegate getDelegate() { + if (!TabManagementModule.isInstalled()) { + TabManagementModule.installDeferred(); + if (UmaSessionStats.isMetricsServiceAvailable()) { + UmaSessionStats.registerSyntheticFieldTrial( + ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID + SYNTHETIC_TRIAL_POSTFIX, + "DownloadAttempted"); + UmaSessionStats.registerSyntheticFieldTrial( + ChromeFeatureList.TAB_GROUPS_ANDROID + SYNTHETIC_TRIAL_POSTFIX, + "DownloadAttempted"); + } + return null; + } + if (UmaSessionStats.isMetricsServiceAvailable()) { + if (!ChromeFeatureList.isEnabled(ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID)) { + UmaSessionStats.registerSyntheticFieldTrial( + ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID + SYNTHETIC_TRIAL_POSTFIX, + "Downloaded_Control"); + } + if (!ChromeFeatureList.isEnabled(ChromeFeatureList.TAB_GROUPS_ANDROID)) { + UmaSessionStats.registerSyntheticFieldTrial( + ChromeFeatureList.TAB_GROUPS_ANDROID + SYNTHETIC_TRIAL_POSTFIX, + "Downloaded_Control"); + } + } + return TabManagementModule.getImpl(); + } + + /** + * Returns whether TabManagementModule is supported by checking if the module is installed. + */ + public static boolean isTabManagementModuleSupported() { + return getDelegate() != null; + } +}
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherLayout.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherLayout.java index dd15d7d..5eff80bf 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherLayout.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherLayout.java
@@ -728,6 +728,11 @@ return super.canHostBeFocusable(); } + @Override + public boolean isRunningAnimations() { + return mDeferredAnimationRunnable != null || mTabToSwitcherAnimation != null; + } + /** * Shrink/Expand animation is disabled for Tablet TabSwitcher launch polish. * @return Whether shrink/expand animation is enabled.
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiFeatureUtilities.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiFeatureUtilities.java index cec62710..e9a2160 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiFeatureUtilities.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiFeatureUtilities.java
@@ -97,6 +97,24 @@ private static Boolean sTabManagementModuleSupportedForTesting; /** + * Set whether the tab management module is supported for testing. + */ + public static void setTabManagementModuleSupportedForTesting(@Nullable Boolean enabled) { + sTabManagementModuleSupportedForTesting = enabled; + } + + /** + * @return Whether the tab management module is supported. + */ + private static boolean isTabManagementModuleSupported() { + if (sTabManagementModuleSupportedForTesting != null) { + return sTabManagementModuleSupportedForTesting; + } + + return TabManagementModuleProvider.isTabManagementModuleSupported(); + } + + /** * @return Whether the Grid Tab Switcher UI is enabled and available for use. * @param context The activity context. */ @@ -106,7 +124,7 @@ } // Having Tab Groups or Start implies Grid Tab Switcher. - return isTabGroupsAndroidEnabled(context) + return isTabManagementModuleSupported() || isTabGroupsAndroidEnabled(context) || ReturnToChromeUtil.isStartSurfaceEnabled(context); } @@ -160,7 +178,8 @@ } return !DeviceClassManager.enableAccessibilityLayout(context) - && ChromeFeatureList.sTabGroupsAndroid.isEnabled(); + && ChromeFeatureList.sTabGroupsAndroid.isEnabled() + && isTabManagementModuleSupported(); } /**
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java index d1c1f083..92e72fe 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java
@@ -186,6 +186,7 @@ public void setUp() { MockitoAnnotations.initMocks(this); Intents.init(); + TabUiFeatureUtilities.setTabManagementModuleSupportedForTesting(true); mActivityTestRule.startMainActivityOnBlankPage(); CriteriaHelper.pollUiThread( mActivityTestRule.getActivity().getTabModelSelector()::isTabStateInitialized); @@ -194,6 +195,7 @@ @After public void tearDown() { TabSelectionEditorShareAction.setIntentCallbackForTesting(null); + TabUiFeatureUtilities.setTabManagementModuleSupportedForTesting(null); ActivityTestUtils.clearActivityOrientation(mActivityTestRule.getActivity()); Intents.release(); }
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallbackUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallbackUnitTest.java index 3a6947e..cd47e15e 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallbackUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallbackUnitTest.java
@@ -798,6 +798,36 @@ } @Test + public void onLongPress_blockNextAction() { + initAndAssertAllProperties(); + + // Simulate the selection of card#1 in TabListModel. + mItemTouchHelperCallback.setSelectedTabIndexForTesting(POSITION1); + + mItemTouchHelperCallback.onSelectedChanged( + mMockViewHolder1, ItemTouchHelper.ACTION_STATE_IDLE); + + assertTrue(mItemTouchHelperCallback.shouldBlockAction()); + } + + @Test + public void onLongPressWithDrag_dontBlockNextAction() { + initAndAssertAllProperties(); + + // Simulate the selection of card#1 in TabListModel. + mItemTouchHelperCallback.setSelectedTabIndexForTesting(POSITION1); + + // Pretend a drag started. + mItemTouchHelperCallback.onChildDraw(mCanvas, mRecyclerView, mDummyViewHolder1, 10, 5, + ItemTouchHelper.ACTION_STATE_DRAG, true); + + mItemTouchHelperCallback.onSelectedChanged( + mMockViewHolder1, ItemTouchHelper.ACTION_STATE_IDLE); + + assertFalse(mItemTouchHelperCallback.shouldBlockAction()); + } + + @Test @Features.EnableFeatures({ChromeFeatureList.TAB_SELECTION_EDITOR_V2}) public void onLongPress_triggerTabSelectionEditor() { TabUiFeatureUtilities.ENABLE_TAB_SELECTION_EDITOR_V2_LONGPRESS_ENTRY.setForTesting(true); @@ -811,6 +841,7 @@ mMockViewHolder1, ItemTouchHelper.ACTION_STATE_IDLE); verify(mOnLongPressTabItemEventListener).onLongPressEvent(TAB1_ID); + assertTrue(mItemTouchHelperCallback.shouldBlockAction()); TabUiFeatureUtilities.ENABLE_TAB_SELECTION_EDITOR_V2_LONGPRESS_ENTRY.setForTesting(false); } @@ -831,6 +862,7 @@ mMockViewHolder1, ItemTouchHelper.ACTION_STATE_IDLE); verify(mOnLongPressTabItemEventListener, never()).onLongPressEvent(TAB1_ID); + assertFalse(mItemTouchHelperCallback.shouldBlockAction()); TabUiFeatureUtilities.ENABLE_TAB_SELECTION_EDITOR_V2_LONGPRESS_ENTRY.setForTesting(false); }
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabUiFeatureUtilitiesUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabUiFeatureUtilitiesUnitTest.java index 71bb61c8..760cc62 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabUiFeatureUtilitiesUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabUiFeatureUtilitiesUnitTest.java
@@ -80,7 +80,7 @@ cacheFeatureFlags(); CachedFeatureFlags.resetFlagsForTesting(); - assertFalse(TabUiFeatureUtilities.isGridTabSwitcherEnabled( + assertTrue(TabUiFeatureUtilities.isGridTabSwitcherEnabled( ContextUtils.getApplicationContext())); assertFalse(TabUiFeatureUtilities.isTabGroupsAndroidEnabled( ContextUtils.getApplicationContext())); @@ -93,7 +93,7 @@ cacheFeatureFlags(); CachedFeatureFlags.resetFlagsForTesting(); - assertFalse(TabUiFeatureUtilities.isGridTabSwitcherEnabled( + assertTrue(TabUiFeatureUtilities.isGridTabSwitcherEnabled( ContextUtils.getApplicationContext())); assertFalse(TabUiFeatureUtilities.isTabGroupsAndroidEnabled( ContextUtils.getApplicationContext())); @@ -129,7 +129,7 @@ cacheFeatureFlags(); CachedFeatureFlags.resetFlagsForTesting(); - assertFalse(TabUiFeatureUtilities.isGridTabSwitcherEnabled( + assertTrue(TabUiFeatureUtilities.isGridTabSwitcherEnabled( ContextUtils.getApplicationContext())); assertFalse(TabUiFeatureUtilities.isTabGroupsAndroidEnabled( ContextUtils.getApplicationContext())); @@ -152,7 +152,7 @@ cacheFeatureFlags(); CachedFeatureFlags.resetFlagsForTesting(); - assertFalse(TabUiFeatureUtilities.isGridTabSwitcherEnabled( + assertTrue(TabUiFeatureUtilities.isGridTabSwitcherEnabled( ContextUtils.getApplicationContext())); assertFalse(TabUiFeatureUtilities.isTabGroupsAndroidEnabled( ContextUtils.getApplicationContext())); @@ -167,7 +167,7 @@ cacheFeatureFlags(); CachedFeatureFlags.resetFlagsForTesting(); - assertFalse(TabUiFeatureUtilities.isGridTabSwitcherEnabled( + assertTrue(TabUiFeatureUtilities.isGridTabSwitcherEnabled( ContextUtils.getApplicationContext())); assertFalse(TabUiFeatureUtilities.isTabGroupsAndroidEnabled( ContextUtils.getApplicationContext())); @@ -205,7 +205,7 @@ cacheFeatureFlags(); CachedFeatureFlags.resetFlagsForTesting(); - assertFalse(TabUiFeatureUtilities.isGridTabSwitcherEnabled( + assertTrue(TabUiFeatureUtilities.isGridTabSwitcherEnabled( ContextUtils.getApplicationContext())); assertFalse(TabUiFeatureUtilities.isTabGroupsAndroidEnabled( ContextUtils.getApplicationContext())); @@ -228,7 +228,7 @@ cacheFeatureFlags(); CachedFeatureFlags.resetFlagsForTesting(); - assertFalse(TabUiFeatureUtilities.isGridTabSwitcherEnabled( + assertTrue(TabUiFeatureUtilities.isGridTabSwitcherEnabled( ContextUtils.getApplicationContext())); assertFalse(TabUiFeatureUtilities.isTabGroupsAndroidEnabled( ContextUtils.getApplicationContext())); @@ -242,7 +242,7 @@ DeviceClassManager.resetForTesting(); cacheFeatureFlags(); - assertFalse(TabUiFeatureUtilities.isGridTabSwitcherEnabled( + assertTrue(TabUiFeatureUtilities.isGridTabSwitcherEnabled( ContextUtils.getApplicationContext())); assertFalse(TabUiFeatureUtilities.isTabGroupsAndroidEnabled( ContextUtils.getApplicationContext())); @@ -279,7 +279,7 @@ DeviceClassManager.resetForTesting(); cacheFeatureFlags(); - assertFalse(TabUiFeatureUtilities.isGridTabSwitcherEnabled( + assertTrue(TabUiFeatureUtilities.isGridTabSwitcherEnabled( ContextUtils.getApplicationContext())); assertFalse(TabUiFeatureUtilities.isTabGroupsAndroidEnabled( ContextUtils.getApplicationContext())); @@ -302,7 +302,7 @@ cacheFeatureFlags(); CachedFeatureFlags.resetFlagsForTesting(); - assertFalse(TabUiFeatureUtilities.isGridTabSwitcherEnabled( + assertTrue(TabUiFeatureUtilities.isGridTabSwitcherEnabled( ContextUtils.getApplicationContext())); assertFalse(TabUiFeatureUtilities.isTabGroupsAndroidEnabled( ContextUtils.getApplicationContext())); @@ -316,7 +316,7 @@ DeviceClassManager.resetForTesting(); cacheFeatureFlags(); - assertFalse(TabUiFeatureUtilities.isGridTabSwitcherEnabled( + assertTrue(TabUiFeatureUtilities.isGridTabSwitcherEnabled( ContextUtils.getApplicationContext())); assertFalse(TabUiFeatureUtilities.isTabGroupsAndroidEnabled( ContextUtils.getApplicationContext())); @@ -343,7 +343,7 @@ DeviceClassManager.GTS_ACCESSIBILITY_SUPPORT.setForTesting(true); TabUiFeatureUtilities.GTS_ACCESSIBILITY_LIST_MODE.setForTesting(false); - assertFalse(TabUiFeatureUtilities.isGridTabSwitcherEnabled( + assertTrue(TabUiFeatureUtilities.isGridTabSwitcherEnabled( ContextUtils.getApplicationContext())); assertFalse(TabUiFeatureUtilities.isTabGroupsAndroidEnabled( ContextUtils.getApplicationContext())); @@ -357,7 +357,7 @@ DeviceClassManager.resetForTesting(); cacheFeatureFlags(); - assertFalse(TabUiFeatureUtilities.isGridTabSwitcherEnabled( + assertTrue(TabUiFeatureUtilities.isGridTabSwitcherEnabled( ContextUtils.getApplicationContext())); assertFalse(TabUiFeatureUtilities.isTabGroupsAndroidEnabled( ContextUtils.getApplicationContext())); @@ -380,7 +380,7 @@ cacheFeatureFlags(); CachedFeatureFlags.resetFlagsForTesting(); - assertFalse(TabUiFeatureUtilities.isGridTabSwitcherEnabled( + assertTrue(TabUiFeatureUtilities.isGridTabSwitcherEnabled( ContextUtils.getApplicationContext())); assertFalse(TabUiFeatureUtilities.isTabGroupsAndroidEnabled( ContextUtils.getApplicationContext())); @@ -396,7 +396,7 @@ DeviceClassManager.resetForTesting(); cacheFeatureFlags(); - assertFalse(TabUiFeatureUtilities.isGridTabSwitcherEnabled( + assertTrue(TabUiFeatureUtilities.isGridTabSwitcherEnabled( ContextUtils.getApplicationContext())); assertFalse(TabUiFeatureUtilities.isTabGroupsAndroidEnabled( ContextUtils.getApplicationContext())); @@ -574,7 +574,7 @@ DeviceClassManager.resetForTesting(); cacheFeatureFlags(); - assertFalse(TabUiFeatureUtilities.isGridTabSwitcherEnabled( + assertTrue(TabUiFeatureUtilities.isGridTabSwitcherEnabled( ContextUtils.getApplicationContext())); assertFalse(TabUiFeatureUtilities.isTabGroupsAndroidEnabled( ContextUtils.getApplicationContext())); @@ -601,7 +601,7 @@ DeviceClassManager.GTS_ACCESSIBILITY_SUPPORT.setForTesting(true); TabUiFeatureUtilities.GTS_ACCESSIBILITY_LIST_MODE.setForTesting(false); - assertFalse(TabUiFeatureUtilities.isGridTabSwitcherEnabled( + assertTrue(TabUiFeatureUtilities.isGridTabSwitcherEnabled( ContextUtils.getApplicationContext())); assertFalse(TabUiFeatureUtilities.isTabGroupsAndroidEnabled( ContextUtils.getApplicationContext())); @@ -615,7 +615,7 @@ DeviceClassManager.resetForTesting(); cacheFeatureFlags(); - assertFalse(TabUiFeatureUtilities.isGridTabSwitcherEnabled( + assertTrue(TabUiFeatureUtilities.isGridTabSwitcherEnabled( ContextUtils.getApplicationContext())); assertFalse(TabUiFeatureUtilities.isTabGroupsAndroidEnabled( ContextUtils.getApplicationContext())); @@ -697,7 +697,7 @@ DeviceClassManager.resetForTesting(); cacheFeatureFlags(); - assertFalse(TabUiFeatureUtilities.isGridTabSwitcherEnabled( + assertTrue(TabUiFeatureUtilities.isGridTabSwitcherEnabled( ContextUtils.getApplicationContext())); assertFalse(TabUiFeatureUtilities.isTabGroupsAndroidEnabled( ContextUtils.getApplicationContext())); @@ -765,7 +765,7 @@ DeviceClassManager.GTS_ACCESSIBILITY_SUPPORT.setForTesting(false); TabUiFeatureUtilities.GTS_ACCESSIBILITY_LIST_MODE.setForTesting(false); - assertFalse(TabUiFeatureUtilities.isGridTabSwitcherEnabled( + assertTrue(TabUiFeatureUtilities.isGridTabSwitcherEnabled( ContextUtils.getApplicationContext())); assertFalse(TabUiFeatureUtilities.isTabGroupsAndroidEnabled( ContextUtils.getApplicationContext())); @@ -779,7 +779,7 @@ DeviceClassManager.resetForTesting(); cacheFeatureFlags(); - assertFalse(TabUiFeatureUtilities.isGridTabSwitcherEnabled( + assertTrue(TabUiFeatureUtilities.isGridTabSwitcherEnabled( ContextUtils.getApplicationContext())); assertFalse(TabUiFeatureUtilities.isTabGroupsAndroidEnabled( ContextUtils.getApplicationContext())); @@ -819,7 +819,7 @@ CachedFeatureFlags.resetFlagsForTesting(); // Pretend that we've flipped the continuation flag. ChromeFeatureList.sTabGroupsContinuationAndroid.setForTesting(false); - assertFalse(TabUiFeatureUtilities.isGridTabSwitcherEnabled( + assertTrue(TabUiFeatureUtilities.isGridTabSwitcherEnabled( ContextUtils.getApplicationContext())); assertFalse(TabUiFeatureUtilities.isTabGroupsAndroidEnabled( ContextUtils.getApplicationContext()));
diff --git a/chrome/android/features/tab_ui/tab_management_java_sources.gni b/chrome/android/features/tab_ui/tab_management_java_sources.gni index 1b94193..d2cee08c 100644 --- a/chrome/android/features/tab_ui/tab_management_java_sources.gni +++ b/chrome/android/features/tab_ui/tab_management_java_sources.gni
@@ -2,8 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -# These should reside within the public/ subdirectory, but cannot due to -# dependency issues. public_tab_management_java_sources = [ "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/pseudotab/PseudoTab.java", "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/pseudotab/TabAttributeCache.java", @@ -12,6 +10,7 @@ "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUi.java", "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListFaviconProvider.java", "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegate.java", + "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementModuleProvider.java", "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcher.java", "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherLayout.java", "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiFeatureUtilities.java", @@ -19,101 +18,6 @@ "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/UndoGroupSnackbarController.java", ] -# TODO(crbug/1422324): Modularize tab_ui/ or figure out a mechanism to enforce -# the rule below. -# TabManagementDelegateProvider should be the only class inside this block that -# is used externally as it is intended to mimic an android_library_factory for -# accessing the elements of this module. However, it is not possible to -# modularize this code at present due to a reliance on chrome_java. -internal_tab_management_java_sources = [ - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupUtils.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/ClosableTabGridView.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/CouponCardView.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/IncognitoReauthPromoMessageService.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/IncognitoReauthPromoViewModel.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/IphMessageCardViewModel.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/IphMessageService.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/LargeMessageCardView.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/LargeMessageCardViewBinder.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardProviderCoordinator.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardProviderMediator.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardView.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardViewBinder.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardViewProperties.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardViewUtils.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MessageService.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MultiThumbnailCardProvider.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/PriceCardView.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/PriceMessageCardViewModel.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/PriceMessageService.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/SelectableTabGridView.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogCoordinator.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMenuCoordinator.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMenuItemBinder.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMenuItemProperties.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogView.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridIphDialogCoordinator.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridIphDialogView.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallback.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridPanelProperties.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridPanelViewBinder.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridThumbnailView.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupTitleEditor.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiProperties.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiToolbarView.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiViewBinder.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListContainerProperties.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListContainerViewBinder.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListModel.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListRecyclerView.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewBinder.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateImpl.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateProvider.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabProperties.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorAction.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorActionProperties.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorActionProvider.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorActionViewLayout.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorBookmarkAction.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorCloseAction.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorCoordinator.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorGroupAction.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorLayout.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorLayoutBinder.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMediator.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMenu.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMenuAdapter.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMenuItem.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorProperties.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorSelectionAction.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorShareAction.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorToolbar.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorUngroupAction.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabStripSnapshotter.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabStripViewBinder.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSuggestionMessageCardViewModel.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSuggestionMessageService.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherCoordinator.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiMetricsHelper.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/BaselineTabSuggestionProvider.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/StaleTabSuggestionProvider.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabContextObserver.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabSuggestionProvider.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabSuggestionProviderConfiguration.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabSuggestionsClientFetcher.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabSuggestionsFetcher.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabSuggestionsFetcherResults.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabSuggestionsOrchestrator.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabSuggestionsRanker.java", -] - tab_management_test_java_sources = [ "//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/AssertsTest.java", "//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/CloseAllTabsDialogTest.java",
diff --git a/chrome/android/features/tab_ui/tab_ui_module.gni b/chrome/android/features/tab_ui/tab_ui_module.gni new file mode 100644 index 0000000..3fad048 --- /dev/null +++ b/chrome/android/features/tab_ui/tab_ui_module.gni
@@ -0,0 +1,11 @@ +# Copyright 2019 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//chrome/android/features/tab_ui/buildflags.gni") + +tab_ui_module_desc = { + name = "tab_ui" + java_deps = [ "//chrome/android/features/tab_ui:java" ] + android_manifest = "//chrome/android/features/tab_ui/AndroidManifest.xml" +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index 8e641636..9b5188a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -172,7 +172,7 @@ import org.chromium.chrome.browser.tasks.TasksUma; import org.chromium.chrome.browser.tasks.tab_management.CloseAllTabsDialog; import org.chromium.chrome.browser.tasks.tab_management.TabGroupUi; -import org.chromium.chrome.browser.tasks.tab_management.TabManagementDelegateProvider; +import org.chromium.chrome.browser.tasks.tab_management.TabManagementModuleProvider; import org.chromium.chrome.browser.tasks.tab_management.TabSwitcher; import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities; import org.chromium.chrome.browser.toolbar.ToolbarButtonInProductHelpController; @@ -740,7 +740,7 @@ private void createGridTabSwitcher( CompositorViewHolder compositorViewHolder, ViewGroup tabSwitcherContainer) { - mTabSwitcherSupplier.set(TabManagementDelegateProvider.getDelegate().createGridTabSwitcher( + mTabSwitcherSupplier.set(TabManagementModuleProvider.getDelegate().createGridTabSwitcher( this, getLifecycleDispatcher(), getTabModelSelector(), getTabContentManager(), getBrowserControlsManager(), getTabCreatorManagerSupplier().get(), getMenuOrKeyboardActionController(), tabSwitcherContainer, @@ -2202,7 +2202,7 @@ : "Quick delete is not supported in Incognito."; QuickDeleteMetricsDelegate.recordHistogram( - QuickDeleteMetricsDelegate.PrivacyQuickDelete.MENU_ITEM_CLICKED); + QuickDeleteMetricsDelegate.QuickDeleteAction.MENU_ITEM_CLICKED); new QuickDeleteController( this, getModalDialogManager(), getSnackbarManager(), getLayoutManager())
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java index 459195d..eede55e6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
@@ -81,6 +81,7 @@ ChromeFeatureList.sCctResizable90MaximumHeight, ChromeFeatureList.sCctResizableForThirdParties, ChromeFeatureList.sCctResizableSideSheet, + ChromeFeatureList.sCctResizableSideSheetDiscoverFeedSettings, ChromeFeatureList.sCctResizableSideSheetForThirdParties, ChromeFeatureList.sCctRetainableStateInMemory, ChromeFeatureList.sCctToolbarCustomizations,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/OWNERS index 1bb0ea0..2ace08e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/OWNERS +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/OWNERS
@@ -1,3 +1,3 @@ file://chrome/browser/flags/OWNERS -per-file CachedChromeFlags.java=* +per-file ChromeCachedFlags.java=*
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/tabmodel/ChromeTabModelFilterFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/app/tabmodel/ChromeTabModelFilterFactory.java index 0d7e832..6a65a1f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/tabmodel/ChromeTabModelFilterFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/tabmodel/ChromeTabModelFilterFactory.java
@@ -13,7 +13,7 @@ import org.chromium.chrome.browser.tabmodel.TabModelFilter; import org.chromium.chrome.browser.tabmodel.TabModelFilterFactory; import org.chromium.chrome.browser.tasks.tab_management.TabManagementDelegate; -import org.chromium.chrome.browser.tasks.tab_management.TabManagementDelegateProvider; +import org.chromium.chrome.browser.tasks.tab_management.TabManagementModuleProvider; import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities; import javax.inject.Inject; @@ -44,9 +44,10 @@ @Override public TabModelFilter createTabModelFilter(TabModel model) { if (TabUiFeatureUtilities.isTabGroupsAndroidEnabled(mContext)) { - TabManagementDelegate tabManagementDelegate = - TabManagementDelegateProvider.getDelegate(); - return tabManagementDelegate.createTabGroupModelFilter(model); + TabManagementDelegate tabManagementDelegate = TabManagementModuleProvider.getDelegate(); + if (tabManagementDelegate != null) { + return tabManagementDelegate.createTabGroupModelFilter(model); + } } return new EmptyTabModelFilter(model); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopupBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopupBridge.java index a83fca6d..f590a96c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopupBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopupBridge.java
@@ -28,7 +28,6 @@ import org.chromium.components.autofill.AutofillSuggestion; import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContentsAccessibility; -import org.chromium.ui.DropdownItem; import org.chromium.ui.base.ViewAndroidDelegate; import org.chromium.ui.base.WindowAndroid; import org.chromium.url.GURL; @@ -187,30 +186,22 @@ String secondaryLabel, String sublabel, String secondarySublabel, String itemTag, int iconId, boolean isIconAtStart, int suggestionId, boolean isDeletable, boolean isLabelMultiline, boolean isLabelBold, GURL customIconUrl) { - int drawableId = iconId == 0 ? DropdownItem.NO_ICON : iconId; - AutofillSuggestion.Builder builder = new AutofillSuggestion.Builder() - .setLabel(label) - .setSecondaryLabel(secondaryLabel) - .setSubLabel(sublabel) - .setSecondarySubLabel(secondarySublabel) - .setItemTag(itemTag) - .setIconId(drawableId) - .setIsIconAtStart(isIconAtStart) - .setSuggestionId(suggestionId) - .setIsDeletable(isDeletable) - .setIsMultiLineLabel(isLabelMultiline) - .setIsBoldLabel(isLabelBold); - if (customIconUrl != null && customIconUrl.isValid()) { - builder.setCustomIcon( - PersonalDataManager.getInstance() - .getCustomImageForAutofillSuggestionIfAvailable( - AutofillUiUtils.getCCIconURLWithParams(customIconUrl, - mContext.getResources().getDimensionPixelSize( - R.dimen.autofill_dropdown_icon_width), - mContext.getResources().getDimensionPixelSize( - R.dimen.autofill_dropdown_icon_height)))); - } - array[index] = builder.build(); + array[index] = + new AutofillSuggestion.Builder() + .setLabel(label) + .setSecondaryLabel(secondaryLabel) + .setSubLabel(sublabel) + .setSecondarySubLabel(secondarySublabel) + .setItemTag(itemTag) + .setIsIconAtStart(isIconAtStart) + .setSuggestionId(suggestionId) + .setIsDeletable(isDeletable) + .setIsMultiLineLabel(isLabelMultiline) + .setIsBoldLabel(isLabelBold) + .setIconDrawable(AutofillUiUtils.getCardIcon(mContext, customIconUrl, + iconId, R.dimen.autofill_dropdown_icon_width, + R.dimen.autofill_dropdown_icon_height, /* showCustomIcon= */ true)) + .build(); } private @Nullable WebContentsViewRectProvider tryCreateRectProvider(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java index 755cdef2..f719731 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
@@ -1367,7 +1367,7 @@ // See http://crbug/236424 // TODO(aberent) Find a better place to put this, possibly as part of a wider // redesign of focus control. - if (mUrlBar != null) mUrlBar.clearFocus(); + if (mUrlBar != null && mUrlBar.isFocused()) mUrlBar.clearFocus(); boolean wasVisible = false; if (hasFocus()) { wasVisible = KeyboardVisibilityDelegate.getInstance().hideKeyboard(this);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java index 2809004c..42a95d63 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java
@@ -793,4 +793,9 @@ */ @LayoutType public abstract int getLayoutType(); + + /** Returns whether the layout is currently running animations. */ + public boolean isRunningAnimations() { + return false; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java index 10de789..7faaae5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java
@@ -33,7 +33,7 @@ import org.chromium.chrome.browser.tabmodel.TabModelUtils; import org.chromium.chrome.browser.tasks.ReturnToChromeUtil; import org.chromium.chrome.browser.tasks.tab_management.TabManagementDelegate; -import org.chromium.chrome.browser.tasks.tab_management.TabManagementDelegateProvider; +import org.chromium.chrome.browser.tasks.tab_management.TabManagementModuleProvider; import org.chromium.chrome.browser.tasks.tab_management.TabSwitcher; import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities; import org.chromium.chrome.browser.theme.TopUiThemeColorProvider; @@ -168,8 +168,7 @@ if (isRefactorEnabled) { assert tabSwitcher != null; - TabManagementDelegate tabManagementDelegate = - TabManagementDelegateProvider.getDelegate(); + TabManagementDelegate tabManagementDelegate = TabManagementModuleProvider.getDelegate(); assert tabManagementDelegate != null; mTabSwitcherLayout = tabManagementDelegate.createTabSwitcherLayout(context, this,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerImpl.java index f05ff8b..3a22616 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerImpl.java
@@ -59,6 +59,7 @@ import org.chromium.chrome.browser.theme.ThemeUtils; import org.chromium.chrome.browser.theme.TopUiThemeColorProvider; import org.chromium.chrome.browser.toolbar.ControlContainer; +import org.chromium.chrome.browser.toolbar.ToolbarFeatures; import org.chromium.chrome.browser.toolbar.bottom.ScrollingBottomViewSceneLayer; import org.chromium.chrome.browser.toolbar.top.TopToolbarOverlayCoordinator; import org.chromium.chrome.browser.ui.native_page.NativePage; @@ -473,14 +474,17 @@ } mUpdateRequested = false; - // TODO(mdjones): Remove the time related params from this method. The new animation system - // has its own timer. - boolean areAnimatorsComplete = mAnimationHandler.pushUpdate(); - // TODO(crbug.com/1070281): Remove after the FrameRequestSupplier migrates to the animation // system. final Layout layout = getActiveLayout(); + // TODO(mdjones): Remove the time related params from this method. The new animation system + // has its own timer. + boolean areAnimatorsComplete = mAnimationHandler.pushUpdate(); + if (layout != null && ToolbarFeatures.shouldDelayTransitionsForAnimation()) { + areAnimatorsComplete &= !layout.isRunningAnimations(); + } + // TODO(crbug.com/1070281): Layout itself should decide when it's done hiding and done // showing. if (layout != null && layout.onUpdate(timeMs, dtMs) && areAnimatorsComplete) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java index 0171b6c..679accb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
@@ -112,14 +112,14 @@ * layout. */ public static final String EXTRA_ACTIVITY_SIDE_SHEET_POSITION = - "androidx.browser.customtabs.extra.EXTRA_ACTIVITY_SIDE_SHEET_POSITION"; + "androidx.browser.customtabs.extra.ACTIVITY_SIDE_SHEET_POSITION"; /** * Extra that defines the behavior of the opening animation of the side sheet. * It is set to {@link #ACTIVITY_SIDE_SHEET_SLIDE_IN_FROM_SIDE} by default. */ public static final String EXTRA_ACTIVITY_SIDE_SHEET_SLIDE_IN_BEHAVIOR = - "androidx.browser.customtabs.extra.EXTRA_ACTIVITY_SIDE_SHEET_SLIDE_IN_BEHAVIOR"; + "androidx.browser.customtabs.extra.ACTIVITY_SIDE_SHEET_SLIDE_IN_BEHAVIOR"; /** * Extra used to keep the caller alive. Its value is an Intent. @@ -260,7 +260,7 @@ /** Extra that enables the maximization button on the side sheet Custom Tab toolbar. */ public static final String EXTRA_ACTIVITY_SIDE_SHEET_ENABLE_MAXIMIZATION = - "androix.browser.customtabs.extra.EXTRA_ACTIVITY_SIDE_SHEET_ENABLE_MAXIMIZATION"; + "androix.browser.customtabs.extra.ACTIVITY_SIDE_SHEET_ENABLE_MAXIMIZATION"; /** * Extra that, if set in combination with
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabDisplayManager.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabDisplayManager.java index ff48286b..6e0b6dd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabDisplayManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabDisplayManager.java
@@ -23,7 +23,6 @@ import org.chromium.chrome.browser.browserservices.intents.BrowserServicesIntentDataProvider; import org.chromium.chrome.browser.customtabs.features.partialcustomtab.PartialCustomTabBaseStrategy.PartialCustomTabType; import org.chromium.chrome.browser.customtabs.features.toolbar.CustomTabToolbar; -import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.fullscreen.FullscreenManager; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; import org.chromium.chrome.browser.lifecycle.ConfigurationChangedObserver; @@ -210,14 +209,13 @@ private @PartialCustomTabType int calculatePartialCustomTabType() { return calculatePartialCustomTabType(mActivity, mUnclampedInitialWidth, - mUnclampedInitialHeight, mVersionCompat::getDisplayWidthDp, mBreakPointDp, - ChromeFeatureList.sCctResizableSideSheetForThirdParties.isEnabled()); + mUnclampedInitialHeight, mVersionCompat::getDisplayWidthDp, mBreakPointDp); } @VisibleForTesting static @PartialCustomTabType int calculatePartialCustomTabType(Activity activity, int initialWidth, int initialHeight, Supplier<Integer> displayWidthDpSupplier, - int breakPointDp, boolean ssEnabled) { + int breakPointDp) { // TODO(crbug.com/1407227) Until we are able to handle multi-window case for both // bottom-sheet and side-sheet we will display a full-size PCCT. if (MultiWindowUtils.getInstance().isInMultiWindowMode(activity)) { @@ -229,13 +227,13 @@ int displayWidthDp = -1; if (initialWidth > 0 && initialHeight > 0) { if (displayWidthDp < 0) displayWidthDp = displayWidthDpSupplier.get(); - return displayWidthDp < breakPointDp || !ssEnabled ? PartialCustomTabType.BOTTOM_SHEET - : PartialCustomTabType.SIDE_SHEET; + return displayWidthDp < breakPointDp ? PartialCustomTabType.BOTTOM_SHEET + : PartialCustomTabType.SIDE_SHEET; } if (initialWidth > 0) { if (displayWidthDp < 0) displayWidthDp = displayWidthDpSupplier.get(); - return displayWidthDp < breakPointDp || !ssEnabled ? PartialCustomTabType.FULL_SIZE - : PartialCustomTabType.SIDE_SHEET; + return displayWidthDp < breakPointDp ? PartialCustomTabType.FULL_SIZE + : PartialCustomTabType.SIDE_SHEET; } if (initialHeight > 0) { return PartialCustomTabType.BOTTOM_SHEET; @@ -262,8 +260,7 @@ @PartialCustomTabType int type = calculatePartialCustomTabType(activity, provider.getInitialActivityWidth(), provider.getInitialActivityHeight(), displayWidthDpSupplier, - provider.getActivityBreakPoint(), - ChromeFeatureList.sCctResizableSideSheetForThirdParties.isEnabled()); + provider.getActivityBreakPoint()); @AnimRes int start_anim_id = defaultResId;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabVersionCompat.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabVersionCompat.java index 0d9aff3..fdf2e306 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabVersionCompat.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabVersionCompat.java
@@ -11,6 +11,7 @@ import android.os.Build; import android.util.DisplayMetrics; import android.view.Display; +import android.view.DisplayCutout; import android.view.Surface; import android.view.View; import android.view.WindowInsets; @@ -219,8 +220,6 @@ @Override @Px int getDisplayWidth() { - // TODO(crbug.com/1425558): The width on the devices with the display cutout, - // when it is in landscape mode, is not correct. Fix this. Display display = mActivity.getWindowManager().getDefaultDisplay(); Point size = new Point(); display.getSize(size); @@ -284,16 +283,25 @@ @Px int getXOffset() { Display display = mActivity.getWindowManager().getDefaultDisplay(); - if (!DeviceFormFactor.isTablet() && display.getRotation() == Surface.ROTATION_270) { + if (!DeviceFormFactor.isNonMultiDisplayContextOnTablet(mActivity) + && display.getRotation() == Surface.ROTATION_270) { // On the phone in reverse-landscape mode, navigation bar is located on the left // side of the screen. The origin of x should be offset as much. - DisplayMetrics displayMetrics = getDisplayMetrics(); - int wholeWidth = displayMetrics.widthPixels; - return wholeWidth - getDisplayWidth(); + // |getDisplayWidth()| already takes into account the display cutout insets on + // both sides. Subtract the right inset since it doesn't affect the offset. + int wholeWidth = getDisplayMetrics().widthPixels; + return wholeWidth - getDisplayWidth() - getDisplayCutoutRightInset(display); } return 0; } + private static int getDisplayCutoutRightInset(Display display) { + // TODO(crbug.com/1425558): Make this work on P. + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) return 0; + DisplayCutout cutout = display.getCutout(); + return cutout != null ? cutout.getSafeInsetRight() : 0; + } + @Override boolean setImeStateCallback(Callback<Boolean> callback) { View contentFrame = mActivity.findViewById(android.R.id.content);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/ActivityTabStartupMetricsTracker.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/ActivityTabStartupMetricsTracker.java index ab12868..5479d74d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/metrics/ActivityTabStartupMetricsTracker.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/ActivityTabStartupMetricsTracker.java
@@ -162,6 +162,10 @@ FIRST_PAINT_OCCURRED_PRE_FOREGROUND_HISTOGRAM, true); } + RecordHistogram.recordMediumTimesHistogram( + "Startup.Android.Cold.TimeToForegroundSessionStart", + SystemClock.uptimeMillis() - mActivityStartTimeMs); + UmaUtils.removeObserver(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java index 8c40f43..a023668 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -108,7 +108,7 @@ import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; import org.chromium.chrome.browser.tasks.ReturnToChromeUtil; import org.chromium.chrome.browser.tasks.tab_management.TabGroupUi; -import org.chromium.chrome.browser.tasks.tab_management.TabManagementDelegateProvider; +import org.chromium.chrome.browser.tasks.tab_management.TabManagementModuleProvider; import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities; import org.chromium.chrome.browser.theme.ThemeColorProvider; import org.chromium.chrome.browser.theme.ThemeColorProvider.ThemeColorObserver; @@ -933,6 +933,9 @@ if (layoutType == LayoutType.TAB_SWITCHER) { mToolbar.onTabSwitcherTransitionFinished(); } + if (ToolbarFeatures.shouldDelayTransitionsForAnimation()) { + mToolbar.onTransitionEnd(); + } } @Override @@ -947,6 +950,9 @@ mControlContainer.invalidateBitmap(); } } + if (ToolbarFeatures.shouldDelayTransitionsForAnimation()) { + mToolbar.onTransitionStart(); + } } @Override @@ -1279,7 +1285,7 @@ */ public void enableBottomControls() { View root = ((ViewStub) mActivity.findViewById(R.id.bottom_controls_stub)).inflate(); - mTabGroupUi = TabManagementDelegateProvider.getDelegate().createTabGroupUi(mActivity, + mTabGroupUi = TabManagementModuleProvider.getDelegate().createTabGroupUi(mActivity, root.findViewById(R.id.bottom_container_slot), mIncognitoStateProvider, mScrimCoordinator, mOmniboxFocusStateSupplier, mBottomSheetController, mActivityLifecycleDispatcher, mIsWarmOnResumeSupplier, mTabModelSelector,
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/app/appmenu/OverviewAppMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/app/appmenu/OverviewAppMenuTest.java index b6d0255..c30cf37 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/app/appmenu/OverviewAppMenuTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/app/appmenu/OverviewAppMenuTest.java
@@ -24,7 +24,6 @@ import org.chromium.chrome.browser.layouts.LayoutTestUtils; import org.chromium.chrome.browser.layouts.LayoutType; import org.chromium.chrome.browser.ui.appmenu.AppMenuTestSupport; -import org.chromium.chrome.browser.util.ChromeAccessibilityUtil; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.util.browser.Features; @@ -48,9 +47,6 @@ @Before public void setUp() { mActivityTestRule.startMainActivityOnBlankPage(); - } - - private void openTabSwitcher() { LayoutTestUtils.startShowingAndWaitForLayout( mActivityTestRule.getActivity().getLayoutManager(), LayoutType.TAB_SWITCHER, true); } @@ -61,7 +57,6 @@ @Features.EnableFeatures({ChromeFeatureList.TAB_GROUPS_ANDROID}) @Features.DisableFeatures({ChromeFeatureList.START_SURFACE_ANDROID}) public void testAllMenuItemsWithoutStartSurface() throws Exception { - openTabSwitcher(); TestThreadUtils.runOnUiThreadBlocking(() -> { AppMenuTestSupport.showAppMenu(mActivityTestRule.getAppMenuCoordinator(), null, false); }); @@ -75,7 +70,6 @@ @Features.EnableFeatures({ChromeFeatureList.TAB_GROUPS_ANDROID}) @Features.DisableFeatures({ChromeFeatureList.START_SURFACE_ANDROID}) public void testIncognitoAllMenuItemsWithoutStartSurface() throws Exception { - openTabSwitcher(); TestThreadUtils.runOnUiThreadBlocking(() -> { mActivityTestRule.getActivity().getTabModelSelector().selectModel(true); AppMenuTestSupport.showAppMenu(mActivityTestRule.getAppMenuCoordinator(), null, false); @@ -91,7 +85,6 @@ EnableFeatures({ChromeFeatureList.START_SURFACE_ANDROID, ChromeFeatureList.TAB_GROUPS_ANDROID}) @Features.DisableFeatures({ChromeFeatureList.TAB_SELECTION_EDITOR_V2}) public void testAllMenuItemsWithStartSurface() throws Exception { - openTabSwitcher(); TestThreadUtils.runOnUiThreadBlocking(() -> { AppMenuTestSupport.showAppMenu(mActivityTestRule.getAppMenuCoordinator(), null, false); }); @@ -106,7 +99,6 @@ ChromeFeatureList.TAB_GROUPS_ANDROID, ChromeFeatureList.TAB_SELECTION_EDITOR_V2}) public void testAllMenuItemsWithStartSurfaceAndSelectTabs() throws Exception { - openTabSwitcher(); TestThreadUtils.runOnUiThreadBlocking(() -> { AppMenuTestSupport.showAppMenu(mActivityTestRule.getAppMenuCoordinator(), null, false); }); @@ -121,7 +113,6 @@ @Features. EnableFeatures({ChromeFeatureList.START_SURFACE_ANDROID, ChromeFeatureList.TAB_GROUPS_ANDROID}) public void testIncognitoAllMenuItemsWithStartSurface() throws Exception { - openTabSwitcher(); TestThreadUtils.runOnUiThreadBlocking(() -> { mActivityTestRule.getActivity().getTabModelSelector().selectModel(true); AppMenuTestSupport.showAppMenu(mActivityTestRule.getAppMenuCoordinator(), null, false); @@ -137,7 +128,6 @@ ChromeFeatureList.TAB_GROUPS_ANDROID, ChromeFeatureList.TAB_SELECTION_EDITOR_V2}) public void testIncognitoAllMenuItemsWithStartSurfaceAndSelectTabs() throws Exception { - openTabSwitcher(); TestThreadUtils.runOnUiThreadBlocking(() -> { mActivityTestRule.getActivity().getTabModelSelector().selectModel(true); AppMenuTestSupport.showAppMenu(mActivityTestRule.getAppMenuCoordinator(), null, false); @@ -155,7 +145,6 @@ @CommandLineFlags.Add({"force-fieldtrials=Study/Group", "force-fieldtrial-params=Study.Group:open_ntp_instead_of_start/true"}) public void testNewTabIsEnabledWithStartSurfaceV2() throws Exception { - openTabSwitcher(); // clang-format on TestThreadUtils.runOnUiThreadBlocking(() -> { AppMenuTestSupport.showAppMenu(mActivityTestRule.getAppMenuCoordinator(), null, false); @@ -171,19 +160,12 @@ @Features. DisableFeatures({ChromeFeatureList.START_SURFACE_ANDROID, ChromeFeatureList.TAB_GROUPS_ANDROID}) public void testGroupTabsIsDisabled() throws Exception { - // Force accessibility mode as that is the only way to get a tab switcher with the flags on - // this test being disabled. - TestThreadUtils.runOnUiThreadBlocking( - () -> { ChromeAccessibilityUtil.get().setAccessibilityEnabledForTesting(true); }); - openTabSwitcher(); TestThreadUtils.runOnUiThreadBlocking(() -> { AppMenuTestSupport.showAppMenu(mActivityTestRule.getAppMenuCoordinator(), null, false); }); assertNull(AppMenuTestSupport.getMenuItemPropertyModel( mActivityTestRule.getAppMenuCoordinator(), R.id.menu_group_tabs)); - TestThreadUtils.runOnUiThreadBlocking( - () -> { ChromeAccessibilityUtil.get().setAccessibilityEnabledForTesting(null); }); } @Test @@ -192,7 +174,6 @@ @Features.EnableFeatures({ChromeFeatureList.TAB_GROUPS_ANDROID}) @Features.DisableFeatures({ChromeFeatureList.START_SURFACE_ANDROID}) public void testGroupTabsIsEnabled() throws Exception { - openTabSwitcher(); TestThreadUtils.runOnUiThreadBlocking(() -> { AppMenuTestSupport.showAppMenu(mActivityTestRule.getAppMenuCoordinator(), null, false); }); @@ -207,7 +188,6 @@ @Features.EnableFeatures({ChromeFeatureList.START_SURFACE_ANDROID}) @Features.DisableFeatures({ChromeFeatureList.TAB_GROUPS_ANDROID}) public void testGroupTabsIsDisabledWithStartSurface() throws Exception { - openTabSwitcher(); TestThreadUtils.runOnUiThreadBlocking(() -> { AppMenuTestSupport.showAppMenu(mActivityTestRule.getAppMenuCoordinator(), null, false); }); @@ -223,7 +203,6 @@ @Features. EnableFeatures({ChromeFeatureList.START_SURFACE_ANDROID, ChromeFeatureList.TAB_GROUPS_ANDROID}) public void testGroupTabsIsEnabledWithStartSurface() throws Exception { - openTabSwitcher(); TestThreadUtils.runOnUiThreadBlocking(() -> { AppMenuTestSupport.showAppMenu(mActivityTestRule.getAppMenuCoordinator(), null, false); }); @@ -241,7 +220,6 @@ ChromeFeatureList.TAB_GROUPS_ANDROID, ChromeFeatureList.TAB_SELECTION_EDITOR_V2}) public void testGroupTabsIsEnabledWithStartSurfaceAndSelectTabs() throws Exception { - openTabSwitcher(); TestThreadUtils.runOnUiThreadBlocking(() -> { AppMenuTestSupport.showAppMenu(mActivityTestRule.getAppMenuCoordinator(), null, false); });
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/app/appmenu/TabbedAppMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/app/appmenu/TabbedAppMenuTest.java index f96c769..e767ac5 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/app/appmenu/TabbedAppMenuTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/app/appmenu/TabbedAppMenuTest.java
@@ -462,7 +462,7 @@ HistogramWatcher histogramWatcher = HistogramWatcher.newBuilder() .expectIntRecords("Privacy.QuickDelete", - QuickDeleteMetricsDelegate.PrivacyQuickDelete.MENU_ITEM_CLICKED, 1) + QuickDeleteMetricsDelegate.QuickDeleteAction.MENU_ITEM_CLICKED, 1) .build(); MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(),
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java index 7c814fae..f9b7e47 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java
@@ -58,8 +58,6 @@ import org.chromium.chrome.browser.accessibility_tab_switcher.OverviewListLayout; import org.chromium.chrome.browser.compositor.layouts.Layout.LayoutState; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; -import org.chromium.chrome.browser.device.DeviceClassManager; -import org.chromium.chrome.browser.flags.CachedFeatureFlags; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.init.ChromeBrowserInitializer; @@ -473,7 +471,6 @@ // Verify accessibility TabUiTestHelper.finishActivity(mActivityTestRule.getActivity()); - DeviceClassManager.GTS_ACCESSIBILITY_SUPPORT.setForTesting(true); setAccessibilityEnabledForTesting(true); verifyTabSwitcherLayoutEnable(TabListCoordinator.TabListMode.GRID); } @@ -489,12 +486,10 @@ @Features.DisableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION) public void testTabSwitcherLayout_Enabled_LowEndPhone() throws Exception { // clang-format on - DeviceClassManager.GTS_LOW_END_SUPPORT.setForTesting(true); verifyTabSwitcherLayoutEnable(TabListCoordinator.TabListMode.LIST); // Test Accessibility TabUiTestHelper.finishActivity(mActivityTestRule.getActivity()); - DeviceClassManager.GTS_ACCESSIBILITY_SUPPORT.setForTesting(true); setAccessibilityEnabledForTesting(true); verifyTabSwitcherLayoutEnable(TabListCoordinator.TabListMode.LIST); } @@ -763,7 +758,6 @@ ChromeFeatureList.sTabGridLayoutAndroid.setForTesting(null); ChromeFeatureList.sTabGroupsAndroid.setForTesting(null); setAccessibilityEnabledForTesting(null); - CachedFeatureFlags.resetFlagsForTesting(); } private void launchAndVerifyOverviewListLayout() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/StartupLoadingMetricsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/StartupLoadingMetricsTest.java index 8710b13..4cf02736 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/StartupLoadingMetricsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/StartupLoadingMetricsTest.java
@@ -137,6 +137,11 @@ } private void assertHistogramsRecordedAsExpected(int expectedCount, String histogramSuffix) { + assertHistogramsRecordedAsExpectedWithBackgroundInfo(expectedCount, histogramSuffix, false); + } + + private void assertHistogramsRecordedAsExpectedWithBackgroundInfo( + int expectedCount, String histogramSuffix, boolean inBackground) { boolean isTabbedSuffix = histogramSuffix.equals(TABBED_SUFFIX); // Check that the new first navigation commit is always recorded for the tabbed activity. @@ -184,6 +189,12 @@ RecordHistogram.getHistogramTotalCountForTesting( FIRST_VISIBLE_CONTENT_HISTOGRAM2)); } + + if (!inBackground) { + Assert.assertEquals(1, + RecordHistogram.getHistogramTotalCountForTesting( + "Startup.Android.Cold.TimeToForegroundSessionStart")); + } } /** @@ -299,7 +310,8 @@ Tab tab = mTabbedActivityTestRule.getActivity().getActivityTab(); ChromeTabUtils.waitForTabPageLoaded(tab, (String) null); }); - assertHistogramsRecordedAsExpected(0, TABBED_SUFFIX); + assertHistogramsRecordedAsExpectedWithBackgroundInfo(0, TABBED_SUFFIX, true); + runAndWaitForPageLoadMetricsRecorded(() -> { // Put Chrome in foreground before loading a new page. ChromeApplicationTestUtils.launchChrome(InstrumentationRegistry.getTargetContext());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxPedalsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxPedalsTest.java index 88a38c7..e026c63b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxPedalsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxPedalsTest.java
@@ -20,13 +20,11 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.ClassRule; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.chromium.base.FeatureList; import org.chromium.base.ThreadUtils; -import org.chromium.base.test.metrics.HistogramTestRule; import org.chromium.base.test.params.ParameterAnnotations; import org.chromium.base.test.params.ParameterSet; import org.chromium.base.test.params.ParameterizedRunner; @@ -35,6 +33,7 @@ import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Criteria; import org.chromium.base.test.util.CriteriaHelper; +import org.chromium.base.test.util.HistogramWatcher; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.settings.AutofillPaymentMethodsFragment; import org.chromium.chrome.browser.browsing_data.ClearBrowsingDataTabsFragment; @@ -93,9 +92,6 @@ public static @ClassRule DisableAnimationsTestRule sDisableAnimationsRule = new DisableAnimationsTestRule(); - @Rule - public HistogramTestRule mHistogramTester = new HistogramTestRule(); - private OmniboxTestUtils mOmniboxUtils; private boolean mIncognito; private LocationBarLayout mLocationBarLayout; @@ -214,15 +210,15 @@ } /** - * Ensure the histogram for the pedal suggestion was recorded. + * Create a HistogramWatcher expecting both the shown and used histograms are recorded. * * @param pedalType The Omnibox pedal type. */ - private void verifyHistogram(@OmniboxPedalType int pedalType) { - Assert.assertEquals( - 1, mHistogramTester.getHistogramValueCount("Omnibox.PedalShown", pedalType)); - Assert.assertEquals(1, - mHistogramTester.getHistogramValueCount("Omnibox.SuggestionUsed.Pedal", pedalType)); + private HistogramWatcher newHistogramExpectations(@OmniboxPedalType int pedalType) { + return HistogramWatcher.newBuilder() + .expectIntRecord("Omnibox.PedalShown", pedalType) + .expectIntRecord("Omnibox.SuggestionUsed.Pedal", pedalType) + .build(); } /** @@ -286,6 +282,9 @@ @Test @MediumTest public void testClearBrowsingDataOmniboxPedalSuggestion() throws InterruptedException { + HistogramWatcher histogramWatcher = + newHistogramExpectations(OmniboxPedalType.CLEAR_BROWSING_DATA); + // Generate the clear browsing data pedal. typeInOmnibox("Clear data"); @@ -303,12 +302,15 @@ checkSettingsWasShownAndOmniboxNoFocus( settingsActivity, ClearBrowsingDataTabsFragment.class); - verifyHistogram(OmniboxPedalType.CLEAR_BROWSING_DATA); + histogramWatcher.assertExpected(); } @Test @MediumTest public void testManagePasswordsOmniboxPedalSuggestion() throws InterruptedException { + HistogramWatcher histogramWatcher = + newHistogramExpectations(OmniboxPedalType.MANAGE_PASSWORDS); + // Generate the manage passwords pedal. typeInOmnibox("Manage passwords"); @@ -320,12 +322,15 @@ checkSettingsWasShownAndOmniboxNoFocus(settingsActivity, PasswordSettings.class); - verifyHistogram(OmniboxPedalType.MANAGE_PASSWORDS); + histogramWatcher.assertExpected(); } @Test @MediumTest public void testManagePaymentMethodsOmniboxPedalSuggestion() throws InterruptedException { + HistogramWatcher histogramWatcher = + newHistogramExpectations(OmniboxPedalType.UPDATE_CREDIT_CARD); + // Generate the manage payment methods pedal. typeInOmnibox("Manage payment methods"); @@ -338,12 +343,15 @@ checkSettingsWasShownAndOmniboxNoFocus( settingsActivity, AutofillPaymentMethodsFragment.class); - verifyHistogram(OmniboxPedalType.UPDATE_CREDIT_CARD); + histogramWatcher.assertExpected(); } @Test @MediumTest public void testOpenIncognitoTabOmniboxPedalSuggestion() throws InterruptedException { + HistogramWatcher histogramWatcher = + newHistogramExpectations(OmniboxPedalType.LAUNCH_INCOGNITO); + // Generate the open incognito pedal. typeInOmnibox("Open Incognito"); @@ -357,12 +365,19 @@ Criteria.checkThat(tab.isIncognito(), Matchers.is(true)); }); - verifyHistogram(OmniboxPedalType.LAUNCH_INCOGNITO); + histogramWatcher.assertExpected(); } @Test @MediumTest public void testRunChromeSafetyCheckOmniboxPedalSuggestion() throws InterruptedException { + HistogramWatcher histogramWatcher = + newHistogramExpectations(OmniboxPedalType.RUN_CHROME_SAFETY_CHECK); + HistogramWatcher safetyCheckHistogramWatcher = + HistogramWatcher.newBuilder() + .expectAnyRecord("Settings.SafetyCheck.UpdatesResult") + .build(); + // Generate the run chrome safety check pedal. typeInOmnibox("Run safety check"); @@ -374,19 +389,18 @@ checkSettingsWasShownAndOmniboxNoFocus(settingsActivity, SafetyCheckSettingsFragment.class); - verifyHistogram(OmniboxPedalType.RUN_CHROME_SAFETY_CHECK); + histogramWatcher.assertExpected(); // Make sure the safety check was ran. - CriteriaHelper.pollUiThread(() -> { - Criteria.checkThat( - mHistogramTester.getHistogramTotalCount("Settings.SafetyCheck.UpdatesResult"), - Matchers.is(1)); - }); + safetyCheckHistogramWatcher.pollInstrumentationThreadUntilSatisfied(); } @Test @MediumTest public void testManageSiteSettingsOmniboxPedalSuggestion() throws InterruptedException { + HistogramWatcher histogramWatcher = + newHistogramExpectations(OmniboxPedalType.MANAGE_SITE_SETTINGS); + // Generate the manage site setting pedal. typeInOmnibox("Change site permissions"); @@ -398,12 +412,15 @@ checkSettingsWasShownAndOmniboxNoFocus(settingsActivity, SiteSettings.class); - verifyHistogram(OmniboxPedalType.MANAGE_SITE_SETTINGS); + histogramWatcher.assertExpected(); } @Test @MediumTest public void testManageChromeSettingsOmniboxPedalSuggestion() throws InterruptedException { + HistogramWatcher histogramWatcher = + newHistogramExpectations(OmniboxPedalType.MANAGE_CHROME_SETTINGS); + // Generate the manage chrome settings pedal. typeInOmnibox("manage settings"); @@ -415,12 +432,15 @@ checkSettingsWasShownAndOmniboxNoFocus(settingsActivity, MainSettings.class); - verifyHistogram(OmniboxPedalType.MANAGE_CHROME_SETTINGS); + histogramWatcher.assertExpected(); } @Test @MediumTest public void testViewYourChromeHistoryOmniboxPedalSuggestion() throws InterruptedException { + HistogramWatcher histogramWatcher = + newHistogramExpectations(OmniboxPedalType.VIEW_CHROME_HISTORY); + // Generate the view chrome history pedal. typeInOmnibox("view chrome history"); @@ -438,7 +458,7 @@ Matchers.startsWith(UrlConstants.NATIVE_HISTORY_URL)); }); - verifyHistogram(OmniboxPedalType.VIEW_CHROME_HISTORY); + histogramWatcher.assertExpected(); return; } @@ -448,13 +468,16 @@ // Make sure the history setting page was opened. Assert.assertNotNull("Could not find the history activity", historyActivity); - verifyHistogram(OmniboxPedalType.VIEW_CHROME_HISTORY); + histogramWatcher.assertExpected(); } @Test @MediumTest public void testManageAccessibilitySettingsOmniboxPedalSuggestion() throws InterruptedException { + HistogramWatcher histogramWatcher = + newHistogramExpectations(OmniboxPedalType.MANAGE_CHROME_ACCESSIBILITY); + // Generate the manage accessibility setting pedal. typeInOmnibox("Chrome accessibility"); @@ -467,12 +490,15 @@ checkSettingsWasShownAndOmniboxNoFocus(settingsActivity, AccessibilitySettings.class); - verifyHistogram(OmniboxPedalType.MANAGE_CHROME_ACCESSIBILITY); + histogramWatcher.assertExpected(); } @Test @MediumTest public void testPedalsStartedOnCtrlEnterKeyStroke() throws Exception { + HistogramWatcher histogramWatcher = + newHistogramExpectations(OmniboxPedalType.MANAGE_CHROME_ACCESSIBILITY); + typeInOmnibox("Chrome accessibility"); SuggestionInfo<BaseSuggestionView> pedal = mOmniboxUtils.findSuggestionWithActionChips(); Assert.assertNotNull(pedal.view); @@ -489,12 +515,15 @@ checkSettingsWasShownAndOmniboxNoFocus( (SettingsActivity) mTargetActivity, AccessibilitySettings.class); - verifyHistogram(OmniboxPedalType.MANAGE_CHROME_ACCESSIBILITY); + histogramWatcher.assertExpected(); } @Test @MediumTest public void testPlayChromeDinoGameOmniboxPedalSuggestion() throws InterruptedException { + HistogramWatcher histogramWatcher = + newHistogramExpectations(OmniboxPedalType.PLAY_CHROME_DINO_GAME); + // Generate the play chrome dino game pedal. typeInOmnibox("Dino game"); @@ -510,7 +539,7 @@ tab.getUrl().getSpec(), Matchers.startsWith(UrlConstants.CHROME_DINO_URL)); }); - verifyHistogram(OmniboxPedalType.PLAY_CHROME_DINO_GAME); + histogramWatcher.assertExpected(); } @Test(expected = AssertionError.class)
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/privacy/settings/PrivacySettingsFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/privacy/settings/PrivacySettingsFragmentTest.java index 42f42f5..5e17782c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/privacy/settings/PrivacySettingsFragmentTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/privacy/settings/PrivacySettingsFragmentTest.java
@@ -13,7 +13,6 @@ import static androidx.test.espresso.matcher.ViewMatchers.withId; import static androidx.test.espresso.matcher.ViewMatchers.withText; -import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.chromium.base.test.util.Batch.PER_CLASS; @@ -29,17 +28,16 @@ import org.hamcrest.Matcher; import org.junit.After; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; -import org.chromium.base.test.metrics.HistogramTestRule; import org.chromium.base.test.util.Batch; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.CriteriaHelper; import org.chromium.base.test.util.Feature; +import org.chromium.base.test.util.HistogramWatcher; import org.chromium.base.test.util.JniMocker; import org.chromium.base.test.util.UserActionTester; import org.chromium.chrome.R; @@ -55,7 +53,6 @@ import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.util.ChromeRenderTestRule; import org.chromium.chrome.test.util.browser.Features; -import org.chromium.content_public.browser.test.NativeLibraryTestUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils; import java.io.IOException; @@ -90,9 +87,6 @@ @Rule public JniMocker mocker = new JniMocker(); - @Rule - public HistogramTestRule mHistogramTestRule = new HistogramTestRule(); - private FakePrivacySandboxBridge mFakePrivacySandboxBridge; private UserActionTester mActionTester; @@ -128,12 +122,6 @@ return null; } - @BeforeClass - public static void setUpBeforeActivityLaunched() { - // Only needs to be loaded once and needs to be loaded before HistogramTestRule. - NativeLibraryTestUtils.loadNativeLibraryNoBrowserProcess(); - } - @Before public void setUp() { mFakePrivacySandboxBridge = new FakePrivacySandboxBridge(); @@ -283,16 +271,13 @@ mSettingsActivityTestRule.startSettingsActivity(); PrivacySettings fragment = mSettingsActivityTestRule.getFragment(); - assertEquals(0, - mHistogramTestRule.getHistogramValueCount( - ENTRY_EXIT_HISTOGRAM, PrivacyGuideInteractions.SETTINGS_LINK_ROW_ENTRY)); + var histogram = HistogramWatcher.newSingleRecordWatcher( + ENTRY_EXIT_HISTOGRAM, PrivacyGuideInteractions.SETTINGS_LINK_ROW_ENTRY); // Scroll down and open Privacy Guide page. scrollToSetting(withText(R.string.prefs_privacy_guide_title)); onView(withText(R.string.prefs_privacy_guide_title)).perform(click()); - assertEquals(1, - mHistogramTestRule.getHistogramValueCount( - ENTRY_EXIT_HISTOGRAM, PrivacyGuideInteractions.SETTINGS_LINK_ROW_ENTRY)); + histogram.assertExpected(); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/PriceDropMetricsLoggerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/PriceDropMetricsLoggerTest.java deleted file mode 100644 index 6443c717..0000000 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/PriceDropMetricsLoggerTest.java +++ /dev/null
@@ -1,181 +0,0 @@ -// Copyright 2021 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.tab.state; - -import static org.mockito.Mockito.doReturn; - -import androidx.test.filters.SmallTest; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import org.chromium.base.test.BaseJUnit4ClassRunner; -import org.chromium.base.test.UiThreadTest; -import org.chromium.base.test.metrics.HistogramTestRule; -import org.chromium.base.test.util.Batch; -import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.chrome.browser.flags.ChromeSwitches; -import org.chromium.content_public.browser.test.NativeLibraryTestUtils; -import org.chromium.content_public.browser.test.util.TestThreadUtils; - -import java.util.concurrent.TimeUnit; - -/** - * Test relating to {@link PriceDropsMetricsLogger} - */ -@RunWith(BaseJUnit4ClassRunner.class) -@Batch(Batch.UNIT_TESTS) -@CommandLineFlags. -Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, "force-fieldtrials=Study/Group"}) -public class PriceDropMetricsLoggerTest { - @Rule - public HistogramTestRule mHistogramTestRule = new HistogramTestRule(); - - @Mock - private ShoppingPersistedTabData mShoppingPersistedTabData; - - private PriceDropMetricsLogger mPriceDropMetricsLogger; - - @BeforeClass - public static void setUpClass() { - // Needs to load before HistogramTestRule is applied. - NativeLibraryTestUtils.loadNativeLibraryNoBrowserProcess(); - } - - @Before - public void setUp() { - TestThreadUtils.runOnUiThreadBlocking(() -> MockitoAnnotations.initMocks(this)); - doReturn("offer-id").when(mShoppingPersistedTabData).getMainOfferId(); - doReturn(true).when(mShoppingPersistedTabData).hasPriceMicros(); - doReturn(true).when(mShoppingPersistedTabData).hasPreviousPriceMicros(); - mPriceDropMetricsLogger = new PriceDropMetricsLogger(mShoppingPersistedTabData); - } - - @UiThreadTest - @SmallTest - @Test - public void testTabUsageStatus() { - Assert.assertEquals(PriceDropMetricsLogger.TabUsageStatus.ABANDONED, - PriceDropMetricsLogger.getTabUsageStatus(TimeUnit.DAYS.toMillis(100))); - Assert.assertEquals(PriceDropMetricsLogger.TabUsageStatus.ABANDONED, - PriceDropMetricsLogger.getTabUsageStatus(TimeUnit.DAYS.toMillis(90))); - Assert.assertEquals(PriceDropMetricsLogger.TabUsageStatus.STALE, - PriceDropMetricsLogger.getTabUsageStatus(TimeUnit.DAYS.toMillis(45))); - Assert.assertEquals(PriceDropMetricsLogger.TabUsageStatus.STALE, - PriceDropMetricsLogger.getTabUsageStatus(TimeUnit.DAYS.toMillis(1))); - Assert.assertEquals(PriceDropMetricsLogger.TabUsageStatus.ACTIVE, - PriceDropMetricsLogger.getTabUsageStatus(TimeUnit.HOURS.toMillis(12))); - } - - @UiThreadTest - @SmallTest - @Test - public void testMetricsStaleTabNavigation() { - mPriceDropMetricsLogger.logPriceDropMetrics( - "NavigationComplete", TimeUnit.DAYS.toMillis(45)); - Assert.assertEquals(1, - mHistogramTestRule.getHistogramTotalCount( - "Commerce.PriceDrops.StaleTabNavigationComplete.IsProductDetailPage")); - Assert.assertEquals(1, - mHistogramTestRule.getHistogramTotalCount( - "Commerce.PriceDrops.StaleTabNavigationComplete.ContainsPrice")); - Assert.assertEquals(1, - mHistogramTestRule.getHistogramTotalCount( - "Commerce.PriceDrops.StaleTabNavigationComplete.ContainsPriceDrop")); - } - - @UiThreadTest - @SmallTest - @Test - public void testMetrics2StaleTabEnterTabSwitcher() { - mPriceDropMetricsLogger.logPriceDropMetrics("EnterTabSwitcher", TimeUnit.DAYS.toMillis(45)); - Assert.assertEquals(1, - mHistogramTestRule.getHistogramTotalCount( - "Commerce.PriceDrops.StaleTabEnterTabSwitcher.IsProductDetailPage")); - Assert.assertEquals(1, - mHistogramTestRule.getHistogramTotalCount( - "Commerce.PriceDrops.StaleTabEnterTabSwitcher.ContainsPrice")); - Assert.assertEquals(1, - mHistogramTestRule.getHistogramTotalCount( - "Commerce.PriceDrops.StaleTabEnterTabSwitcher.ContainsPriceDrop")); - } - - @UiThreadTest - @SmallTest - @Test - public void testMetricsActiveTabNavigationComplete() { - mPriceDropMetricsLogger.logPriceDropMetrics( - "NavigationComplete", TimeUnit.HOURS.toMillis(12)); - Assert.assertEquals(1, - mHistogramTestRule.getHistogramTotalCount( - "Commerce.PriceDrops.ActiveTabNavigationComplete.IsProductDetailPage")); - Assert.assertEquals(1, - mHistogramTestRule.getHistogramTotalCount( - "Commerce.PriceDrops.ActiveTabNavigationComplete.ContainsPrice")); - Assert.assertEquals(1, - mHistogramTestRule.getHistogramTotalCount( - "Commerce.PriceDrops.ActiveTabNavigationComplete.ContainsPriceDrop")); - } - - @UiThreadTest - @SmallTest - @Test - public void testMetricsActiveTabEnterTabSwitcher() { - mPriceDropMetricsLogger.logPriceDropMetrics( - "EnterTabSwitcher", TimeUnit.HOURS.toMillis(12)); - Assert.assertEquals(1, - mHistogramTestRule.getHistogramTotalCount( - "Commerce.PriceDrops.ActiveTabEnterTabSwitcher.IsProductDetailPage")); - Assert.assertEquals(1, - mHistogramTestRule.getHistogramTotalCount( - "Commerce.PriceDrops.ActiveTabEnterTabSwitcher.ContainsPrice")); - Assert.assertEquals(1, - mHistogramTestRule.getHistogramTotalCount( - "Commerce.PriceDrops.ActiveTabEnterTabSwitcher.ContainsPriceDrop")); - } - - @UiThreadTest - @SmallTest - @Test - public void testMetricsPriceNoPriceDrop() { - mPriceDropMetricsLogger.logPriceDropMetrics( - "EnterTabSwitcher", TimeUnit.HOURS.toMillis(12)); - Assert.assertEquals(1, - mHistogramTestRule.getHistogramTotalCount( - "Commerce.PriceDrops.ActiveTabEnterTabSwitcher.IsProductDetailPage")); - Assert.assertEquals(1, - mHistogramTestRule.getHistogramTotalCount( - "Commerce.PriceDrops.ActiveTabEnterTabSwitcher.ContainsPrice")); - Assert.assertEquals(1, - mHistogramTestRule.getHistogramTotalCount( - "Commerce.PriceDrops.ActiveTabEnterTabSwitcher.ContainsPriceDrop")); - } - - @UiThreadTest - @SmallTest - @Test - public void testEmptyPriceDropResponse() { - doReturn(null).when(mShoppingPersistedTabData).getMainOfferId(); - doReturn(false).when(mShoppingPersistedTabData).hasPriceMicros(); - doReturn(false).when(mShoppingPersistedTabData).hasPreviousPriceMicros(); - mPriceDropMetricsLogger.logPriceDropMetrics( - "EnterTabSwitcher", TimeUnit.HOURS.toMillis(12)); - Assert.assertEquals(1, - mHistogramTestRule.getHistogramValueCount( - "Commerce.PriceDrops.ActiveTabEnterTabSwitcher.IsProductDetailPage", 0)); - Assert.assertEquals(1, - mHistogramTestRule.getHistogramValueCount( - "Commerce.PriceDrops.ActiveTabEnterTabSwitcher.ContainsPrice", 0)); - Assert.assertEquals(1, - mHistogramTestRule.getHistogramValueCount( - "Commerce.PriceDrops.ActiveTabEnterTabSwitcher.ContainsPriceDrop", 0)); - } -}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/top/AdaptiveToolbarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/top/AdaptiveToolbarTest.java index 03de736..170c4f2a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/top/AdaptiveToolbarTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/top/AdaptiveToolbarTest.java
@@ -69,7 +69,6 @@ @Test @MediumTest // clang-format off - @Features.EnableFeatures(ChromeFeatureList.TAB_GROUPS_ANDROID) @CommandLineFlags.Add({"enable-features=" + ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID + "<Study", "force-fieldtrials=Study/Group", NO_NEW_TAB_VARIATION_PARAMS}) public void testTopToolbar_WithGTS() throws InterruptedException { @@ -92,7 +91,6 @@ @Test @MediumTest // clang-format off - @Features.EnableFeatures(ChromeFeatureList.TAB_GROUPS_ANDROID) @CommandLineFlags.Add({"enable-features=" + ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID + "<Study", "force-fieldtrials=Study/Group", NEW_TAB_VARIATION_PARAMS}) public void testTopToolbar_NewTabVariation() { @@ -119,7 +117,6 @@ @Test @MediumTest // clang-format off - @Features.EnableFeatures(ChromeFeatureList.TAB_GROUPS_ANDROID) @CommandLineFlags.Add({"enable-features=" + ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID + "<Study", "force-fieldtrials=Study/Group", NEW_TAB_VARIATION_PARAMS}) public void testTopToolbar_NewTabVariation_IncognitoDisabled() {
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/AutofillSuggestionTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/AutofillSuggestionTest.java index 1ae952cf..1ae27785 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/AutofillSuggestionTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/AutofillSuggestionTest.java
@@ -4,9 +4,12 @@ package org.chromium.chrome.browser.autofill; import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; import androidx.test.filters.SmallTest; @@ -24,10 +27,14 @@ @Test @SmallTest public void testAutofillSuggestion_toBuilder() { - AutofillSuggestion suggestion = - new AutofillSuggestion("label", "secondary_label", "sublabel", "secondary_sublabel", - "item_tag", 1, true, 1, true, true, true, "feature_for_iph", - mock(GURL.class), Bitmap.createBitmap(100, 200, Bitmap.Config.ARGB_8888)); + Bitmap bitmapIcon = mock(Bitmap.class); + when(bitmapIcon.sameAs(any(Bitmap.class))).thenReturn(true); + BitmapDrawable drawableIcon = mock(BitmapDrawable.class); + when(drawableIcon.getBitmap()).thenReturn(bitmapIcon); + + AutofillSuggestion suggestion = new AutofillSuggestion("label", "secondary_label", + "sublabel", "secondary_sublabel", "item_tag", 1, true, 1, true, true, true, + "feature_for_iph", mock(GURL.class), drawableIcon); assertEquals(suggestion.toBuilder().build(), suggestion); } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabDisplayManagerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabDisplayManagerTest.java index e454aa4..9455d05 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabDisplayManagerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabDisplayManagerTest.java
@@ -183,35 +183,6 @@ } @Test - @Features.DisableFeatures({ChromeFeatureList.CCT_RESIZABLE_SIDE_SHEET_FOR_THIRD_PARTIES}) - public void - transitionFromBottomSheetTo900dpBottomSheetWhenOrientationChangedToLandscape_andDisable3P() { - mPCCTTestRule.configPortraitMode(); - PartialCustomTabDisplayManager displayManager = createPcctDisplayManager(); - - assertEquals("Bottom-Sheet should be the active strategy", - PartialCustomTabType.BOTTOM_SHEET, displayManager.getActiveStrategyType()); - verify(mPCCTTestRule.mOnActivityLayoutCallback) - .onActivityLayout(anyInt(), anyInt(), anyInt(), anyInt(), - eq(ACTIVITY_LAYOUT_STATE_BOTTOM_SHEET)); - clearInvocations(mPCCTTestRule.mOnActivityLayoutCallback); - mPCCTTestRule.configLandscapeMode(); - displayManager.onConfigurationChanged(mPCCTTestRule.mConfiguration); - - PartialCustomTabTestRule.waitForAnimationToFinish(); - - // the density in this case is 1.0 - assertEquals("Should be 900dp width bottom sheet", BOTTOM_SHEET_MAX_WIDTH_DP, - (int) (mPCCTTestRule.getWindowAttributes().width)); - assertEquals("Bottom-Sheet should be the active strategy", - PartialCustomTabType.BOTTOM_SHEET, displayManager.getActiveStrategyType()); - verify(mPCCTTestRule.mOnActivityLayoutCallback) - .onActivityLayout(anyInt(), anyInt(), anyInt(), anyInt(), - eq(ACTIVITY_LAYOUT_STATE_BOTTOM_SHEET)); - clearInvocations(mPCCTTestRule.mOnActivityLayoutCallback); - } - - @Test public void transitionFromBottomSheetTo900dpBottomSheetWhenOrientationChangedToLandscape_andHeightSetWidthNot() { mPCCTTestRule.configPortraitMode(); @@ -403,26 +374,25 @@ int initHeight = 0; Supplier<Integer> displayWidthDp = null; int breakPointDp = 0; - boolean ssEnabled = true; // side sheet feature flag // Multi-window mode -> FULL MultiWindowUtils.getInstance().setIsInMultiWindowModeForTesting(true); assertEquals("Type should be FULL_SIZE", PartialCustomTabType.FULL_SIZE, PartialCustomTabDisplayManager.calculatePartialCustomTabType( - null, initWidth, initHeight, displayWidthDp, breakPointDp, ssEnabled)); + null, initWidth, initHeight, displayWidthDp, breakPointDp)); // Zero initial width/height -> FULL MultiWindowUtils.getInstance().setIsInMultiWindowModeForTesting(false); assertEquals("Type should be FULL_SIZE", PartialCustomTabType.FULL_SIZE, PartialCustomTabDisplayManager.calculatePartialCustomTabType( - null, initWidth, initHeight, displayWidthDp, breakPointDp, ssEnabled)); + null, initWidth, initHeight, displayWidthDp, breakPointDp)); // Non-zero height -> BOTTOM_SHEET initWidth = 0; initHeight = 500; assertEquals("Type should be BOTTOM_SHEET", PartialCustomTabType.BOTTOM_SHEET, PartialCustomTabDisplayManager.calculatePartialCustomTabType( - null, initWidth, initHeight, displayWidthDp, breakPointDp, ssEnabled)); + null, initWidth, initHeight, displayWidthDp, breakPointDp)); // Non-zero width -> either FULL_SIZE or SIDE_SHEET initWidth = 500; @@ -431,18 +401,12 @@ breakPointDp = 1200; assertEquals("Type should be FULL_SIZE", PartialCustomTabType.FULL_SIZE, PartialCustomTabDisplayManager.calculatePartialCustomTabType( - null, initWidth, initHeight, displayWidthDp, breakPointDp, ssEnabled)); + null, initWidth, initHeight, displayWidthDp, breakPointDp)); breakPointDp = 800; assertEquals("Type should be SIDE_SHEET", PartialCustomTabType.SIDE_SHEET, PartialCustomTabDisplayManager.calculatePartialCustomTabType( - null, initWidth, initHeight, displayWidthDp, breakPointDp, ssEnabled)); - - ssEnabled = false; - assertEquals("Type should be FULL_SIZE", PartialCustomTabType.FULL_SIZE, - PartialCustomTabDisplayManager.calculatePartialCustomTabType( - null, initWidth, initHeight, displayWidthDp, breakPointDp, ssEnabled)); - ssEnabled = true; + null, initWidth, initHeight, displayWidthDp, breakPointDp)); // Non-zero width/height -> either SIDE_SHEET or BOTTOM_SHEET initWidth = 300; @@ -451,13 +415,7 @@ breakPointDp = 400; assertEquals("Type should be SIDE_SHEET", PartialCustomTabType.SIDE_SHEET, PartialCustomTabDisplayManager.calculatePartialCustomTabType( - null, initWidth, initHeight, displayWidthDp, breakPointDp, ssEnabled)); - - ssEnabled = false; - assertEquals("Type should be BOTTOM SHEET", PartialCustomTabType.BOTTOM_SHEET, - PartialCustomTabDisplayManager.calculatePartialCustomTabType( - null, initWidth, initHeight, displayWidthDp, breakPointDp, ssEnabled)); - ssEnabled = true; + null, initWidth, initHeight, displayWidthDp, breakPointDp)); initWidth = 300; initHeight = 500; @@ -465,7 +423,7 @@ breakPointDp = 1200; assertEquals("Type should be BOTTOM_SHEET", PartialCustomTabType.BOTTOM_SHEET, PartialCustomTabDisplayManager.calculatePartialCustomTabType( - null, initWidth, initHeight, displayWidthDp, breakPointDp, ssEnabled)); + null, initWidth, initHeight, displayWidthDp, breakPointDp)); } @Test
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabVersionCompatTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabVersionCompatTest.java new file mode 100644 index 0000000..0753de4 --- /dev/null +++ b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabVersionCompatTest.java
@@ -0,0 +1,71 @@ +// 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.customtabs.features.partialcustomtab; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; + +import static org.chromium.chrome.browser.customtabs.features.partialcustomtab.PartialCustomTabTestRule.DEVICE_HEIGHT; +import static org.chromium.chrome.browser.customtabs.features.partialcustomtab.PartialCustomTabTestRule.DEVICE_WIDTH; + +import android.app.Activity; +import android.graphics.Point; +import android.graphics.Rect; +import android.os.Build; +import android.view.Display; +import android.view.DisplayCutout; +import android.view.Surface; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; +import org.robolectric.annotation.LooperMode; +import org.robolectric.annotation.LooperMode.Mode; + +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.chrome.test.util.browser.Features; + +/** Tests for {@link PartialCustomTabVersionCompat}. */ +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +@LooperMode(Mode.PAUSED) +public class PartialCustomTabVersionCompatTest { + @Rule + public TestRule mFeaturesProcessorRule = new Features.JUnitProcessor(); + @Rule + public final PartialCustomTabTestRule mPCCTTestRule = new PartialCustomTabTestRule(); + + @Config(sdk = Build.VERSION_CODES.Q) + @Test + public void getXOffset_cutoutWidthIsExcluded() { + final int cutoutWidth = 200; + final int navbarWidth = 150; + + Activity activity = mPCCTTestRule.mActivity; + var vc = PartialCustomTabVersionCompat.create(activity, () -> {}); + + final int displayWidth = DEVICE_WIDTH - cutoutWidth - navbarWidth; + mPCCTTestRule.mDisplaySize = new Point(displayWidth, DEVICE_HEIGHT); + + // Set a non-zero cutout right inset. + Display display = mPCCTTestRule.mDisplay; + Rect insets = new Rect(0, 0, 200, 0); + var cutout = new DisplayCutout(insets, null); + when(display.getCutout()).thenReturn(cutout); + + // Reverse lanscape mode. Navbar on the left, and the cutout on the right. + // Cutout on the right doesn't count when calculating the x offset. + when(display.getRotation()).thenReturn(Surface.ROTATION_270); + assertEquals(navbarWidth, vc.getXOffset()); + + // Landscape mode. Cutout on the left, and navbar on the right. + // Verify that the cutout width is again excluded from the offset, since the content + // area doesn't include it. + when(display.getRotation()).thenReturn(Surface.ROTATION_90); + assertEquals(0, vc.getXOffset()); + } +}
diff --git a/chrome/android/modules/chrome_feature_modules.gni b/chrome/android/modules/chrome_feature_modules.gni index 08b4d3c..1a73a9d 100644 --- a/chrome/android/modules/chrome_feature_modules.gni +++ b/chrome/android/modules/chrome_feature_modules.gni
@@ -4,6 +4,7 @@ import("//build/config/android/config.gni") import("//chrome/android/features/dev_ui/dev_ui_module.gni") +import("//chrome/android/features/tab_ui/tab_ui_module.gni") import("//chrome/android/modules/buildflags.gni") import( "//chrome/android/modules/cablev2_authenticator/cablev2_authenticator_module.gni") @@ -52,6 +53,9 @@ if (false) { # AR DFM is currently disabled monochrome_module_descs += [ ar_module_desc ] } +if (!disable_tab_ui_dfm) { + monochrome_module_descs += [ tab_ui_module_desc ] +} monochrome_module_descs += [ cablev2_authenticator_module_desc ] # Modules shipped in Trichrome (Android Q+).
diff --git a/chrome/app/os_settings_search_tag_strings.grdp b/chrome/app/os_settings_search_tag_strings.grdp index 4cb2abb..8c2c27b 100644 --- a/chrome/app/os_settings_search_tag_strings.grdp +++ b/chrome/app/os_settings_search_tag_strings.grdp
@@ -493,6 +493,12 @@ <message name="IDS_OS_SETTINGS_TAG_KEYBOARD_FUNCTION_KEYS" desc="Text for search result item which, when clicked, navigates the user to keyboard settings, with a toggle to enable/disable treating the top row as function keys."> Keyboard function keys </message> + <message name="IDS_OS_SETTINGS_TAG_KEYBOARD_BLOCK_META_FKEY_COMBO_REWRITES" translateable="false" desc="Text for search result item which, when clicked, navigates the user to keyboard settings, with a toggle to enable/disable system/launcher keys to switch the top row between function keys and chromeos actions."> + Block meta F-key combo rewrites + </message> + <message name="IDS_OS_SETTINGS_TAG_KEYBOARD_REMAP_KEYS" translateable="false" desc="Text for search result item which, when clicked, navigates the user to keyboard settings, with a button leading the user to remap keyboard keys page."> + Remap keyboard keys + </message> <message name="IDS_OS_SETTINGS_TAG_KEYBOARD_AUTO_REPEAT" desc="Text for search result item which, when clicked, navigates the user to keyboard settings, with toggles/sliders to set the auto-repeat state. Alternate phrase for: 'Keyboard repeat latency'"> Keyboard auto-repeat </message>
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index 9fcac612..a2e0a9e5 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -82,6 +82,18 @@ <message name="IDS_SETTINGS_ACCESSIBLE_IMAGE_LABELS_SUBTITLE" desc="Subtitle for screen reader image labels feature."> If an image doesn’t have a useful description, Chrome will try to provide one for you. To create descriptions, images are sent to Google. </message> + <message name="IDS_SETTINGS_PDF_OCR_DOWNLOAD_COMPLETE" desc="Success message when it has downloaded PDF OCR files."> + Text recognition files downloaded + </message> + <message name="IDS_SETTINGS_PDF_OCR_DOWNLOAD_ERROR" desc="Generic error message when it fails to download PDF OCR files."> + Can't download text recognition files. Try again later. + </message> + <message name="IDS_SETTINGS_PDF_OCR_DOWNLOAD_PROGRESS" desc="Download progress indicator after PDF OCR is enabled. The user needs to download certain files for the feature to work."> + Downloading text recognition files… <ph name="PERCENT">$1<ex>17</ex></ph>% + </message> + <message name="IDS_SETTINGS_PDF_OCR_DOWNLOADING" desc="Generic message when it has started downloading PDF OCR files."> + Downloading text recognition files + </message> <message name="IDS_SETTINGS_PDF_OCR_TITLE" desc="Description for screen reader pdf ocr feature."> Convert images to text </message>
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_PDF_OCR_DOWNLOADING.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_PDF_OCR_DOWNLOADING.png.sha1 new file mode 100644 index 0000000..59332a8 --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_PDF_OCR_DOWNLOADING.png.sha1
@@ -0,0 +1 @@ +6bb4f4ded1bbf4cee2bf3d201662619f83360dad \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_PDF_OCR_DOWNLOAD_COMPLETE.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_PDF_OCR_DOWNLOAD_COMPLETE.png.sha1 new file mode 100644 index 0000000..6ec2862 --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_PDF_OCR_DOWNLOAD_COMPLETE.png.sha1
@@ -0,0 +1 @@ +fec0cb5a26982e2a91eef4282afaa389c83ba18a \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_PDF_OCR_DOWNLOAD_ERROR.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_PDF_OCR_DOWNLOAD_ERROR.png.sha1 new file mode 100644 index 0000000..95f9f27 --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_PDF_OCR_DOWNLOAD_ERROR.png.sha1
@@ -0,0 +1 @@ +2a121ec0b53ac30f41e86e6290c6ad14b06ac665 \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_PDF_OCR_DOWNLOAD_PROGRESS.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_PDF_OCR_DOWNLOAD_PROGRESS.png.sha1 new file mode 100644 index 0000000..590a2e83 --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_PDF_OCR_DOWNLOAD_PROGRESS.png.sha1
@@ -0,0 +1 @@ +95df580928a239075d7e3bd0202c9c26265c334a \ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 4607e1b..1fac0cd 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -3872,6 +3872,8 @@ "new_tab_page/chrome_colors/chrome_colors_factory.h", "new_tab_page/chrome_colors/chrome_colors_service.cc", "new_tab_page/chrome_colors/chrome_colors_service.h", + "new_tab_page/customize_chrome/customize_chrome_feature_promo_helper.cc", + "new_tab_page/customize_chrome/customize_chrome_feature_promo_helper.h", "new_tab_page/modules/drive/drive_handler.cc", "new_tab_page/modules/drive/drive_handler.h", "new_tab_page/modules/drive/drive_service.cc", @@ -4965,7 +4967,6 @@ "//ash/components/arc", "//ash/components/arc:arc_base", "//ash/components/arc:arc_base_utils", - "//ash/components/arc/enterprise", "//ash/components/arc/mojom", "//ash/constants", "//ash/public/cpp", @@ -5358,6 +5359,8 @@ "lacros/screen_orientation_delegate_lacros.h", "lacros/standalone_browser_test_controller.cc", "lacros/standalone_browser_test_controller.h", + "lacros/sync/crosapi_session_sync_favicon_delegate.cc", + "lacros/sync/crosapi_session_sync_favicon_delegate.h", "lacros/sync/crosapi_session_sync_notifier.cc", "lacros/sync/crosapi_session_sync_notifier.h", "lacros/sync/sync_crosapi_manager_lacros.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 7d60bc0..95957d4 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -5071,6 +5071,11 @@ kOsCrOS, FEATURE_VALUE_TYPE( features::kExperimentalAccessibilityColorEnhancementSettings)}, + {"expose-out-of-process-video-decoding-to-lacros", + flag_descriptions::kExposeOutOfProcessVideoDecodingToLacrosName, + flag_descriptions::kExposeOutOfProcessVideoDecodingToLacrosDescription, + kOsCrOS, + FEATURE_VALUE_TYPE(media::kExposeOutOfProcessVideoDecodingToLacros)}, {"enable-system-proxy-for-system-services", flag_descriptions::kSystemProxyForSystemServicesName, flag_descriptions::kSystemProxyForSystemServicesDescription, kOsCrOS, @@ -6217,10 +6222,6 @@ flag_descriptions::kParallelDownloadingDescription, kOsAll, FEATURE_VALUE_TYPE(download::features::kParallelDownloading)}, - {"enable-pointer-lock-options", flag_descriptions::kPointerLockOptionsName, - flag_descriptions::kPointerLockOptionsDescription, kOsDesktop, - FEATURE_VALUE_TYPE(features::kPointerLockOptions)}, - #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) {"enable-async-dns", flag_descriptions::kAsyncDnsName, flag_descriptions::kAsyncDnsDescription, kOsWin | kOsLinux, @@ -6571,6 +6572,12 @@ {"cct-resizable-side-sheet", flag_descriptions::kCCTResizableSideSheetName, flag_descriptions::kCCTResizableSideSheetDescription, kOsAndroid, FEATURE_VALUE_TYPE(chrome::android::kCCTResizableSideSheet)}, + {"cct-resizable-side-sheet-discover-feed-settings", + flag_descriptions::kCCTResizableSideSheetDiscoverFeedSettingsName, + flag_descriptions::kCCTResizableSideSheetDiscoverFeedSettingsDescription, + kOsAndroid, + FEATURE_VALUE_TYPE( + chrome::android::kCCTResizableSideSheetDiscoverFeedSettings)}, {"cct-resizable-side-sheet-for-third-parties", flag_descriptions::kCCTResizableSideSheetForThirdPartiesName, flag_descriptions::kCCTResizableSideSheetForThirdPartiesDescription, @@ -7147,6 +7154,14 @@ "LocalWebApprovals")}, #endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) + {"use-out-of-process-video-decoding", + flag_descriptions::kUseOutOfProcessVideoDecodingName, + flag_descriptions::kUseOutOfProcessVideoDecodingDescription, + kOsLinux | kOsCrOS | kOsLacros, + FEATURE_VALUE_TYPE(media::kUseOutOfProcessVideoDecoding)}, +#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) + #if BUILDFLAG(ENABLE_SUPERVISED_USERS) {"enable-web-filter-interstitial-refresh", flag_descriptions::kWebFilterInterstitialRefreshName, @@ -9408,6 +9423,10 @@ flag_descriptions::kWebUIOmniboxPopupDescription, kOsDesktop, FEATURE_VALUE_TYPE(omnibox::kWebUIOmniboxPopup)}, + {"webui-system-font", flag_descriptions::kWebUiSystemFontName, + flag_descriptions::kWebUiSystemFontDescription, kOsAll, + FEATURE_VALUE_TYPE(features::kWebUiSystemFont)}, + #if BUILDFLAG(IS_CHROMEOS_ASH) {"arc-nearby-share-fuse-box", flag_descriptions::kArcNearbyShareFuseBoxName, flag_descriptions::kArcNearbyShareFuseBoxDescription, kOsCrOS, @@ -9442,12 +9461,6 @@ kOsAndroid | kOsDesktop, FEATURE_VALUE_TYPE(features::kEnableWebUsbOnExtensionServiceWorker)}, - {"autofill-enable-cvc-for-vcn-yellow-path", - flag_descriptions::kAutofillEnableCvcForVcnYellowPathName, - flag_descriptions::kAutofillEnableCvcForVcnYellowPathDescription, kOsAll, - FEATURE_VALUE_TYPE( - autofill::features::kAutofillEnableCvcForVcnYellowPath)}, - #if BUILDFLAG(IS_CHROMEOS_ASH) {"enable-holding-space-predictability", flag_descriptions::kHoldingSpacePredictabilityName,
diff --git a/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/MainActivity.java b/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/MainActivity.java index cd428f4e..1488b2b4 100644 --- a/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/MainActivity.java +++ b/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/MainActivity.java
@@ -94,7 +94,7 @@ /** Extra that enables the maximization button on the side sheet Custom Tab toolbar. */ public static final String EXTRA_ACTIVITY_SIDE_SHEET_ENABLE_MAXIMIZATION = - "androix.browser.customtabs.extra.EXTRA_ACTIVITY_SIDE_SHEET_ENABLE_MAXIMIZATION"; + "androix.browser.customtabs.extra.ACTIVITY_SIDE_SHEET_ENABLE_MAXIMIZATION"; /** * Minimal height the bottom sheet CCT should show is half of the display height. @@ -152,14 +152,14 @@ public static final int ACTIVITY_SIDE_SHEET_POSITION_END = 2; public static final String EXTRA_ACTIVITY_SIDE_SHEET_POSITION = - "androidx.browser.customtabs.extra.EXTRA_ACTIVITY_SIDE_SHEET_POSITION"; + "androidx.browser.customtabs.extra.ACTIVITY_SIDE_SHEET_POSITION"; public static final int ACTIVITY_SIDE_SHEET_SLIDE_IN_DEFAULT = 0; public static final int ACTIVITY_SIDE_SHEET_SLIDE_IN_FROM_BOTTOM = 1; public static final int ACTIVITY_SIDE_SHEET_SLIDE_IN_FROM_SIDE = 2; public static final String EXTRA_ACTIVITY_SIDE_SHEET_SLIDE_IN_BEHAVIOR = - "androidx.browser.customtabs.extra.EXTRA_ACTIVITY_SIDE_SHEET_SLIDE_IN_BEHAVIOR"; + "androidx.browser.customtabs.extra.ACTIVITY_SIDE_SHEET_SLIDE_IN_BEHAVIOR"; /** * Once per second, asks the framework for the process importance, and logs any change.
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc index 7622434..e5386e4 100644 --- a/chrome/browser/apps/guest_view/web_view_browsertest.cc +++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -6501,11 +6501,14 @@ load_observer.Wait(); } - // Expect that we stayed in the same (default) SiteInstance and - // RenderFrameHost. + // Expect that we stayed in the same (default) SiteInstance. main_frame = GetGuestRenderFrameHost(); ASSERT_TRUE(main_frame); - EXPECT_EQ(main_frame->GetGlobalId(), original_id); + if (!content::WillSameSiteNavigationsChangeRenderFrameHosts()) { + // The RenderFrameHost will stay the same when we don't change + // RenderFrameHosts on same-SiteInstance navigations. + EXPECT_EQ(main_frame->GetGlobalId(), original_id); + } EXPECT_EQ(starting_instance, main_frame->GetSiteInstance()); EXPECT_FALSE(main_frame->GetSiteInstance()->RequiresDedicatedProcess()); EXPECT_FALSE(main_frame->GetProcess()->IsProcessLockedToSiteForTesting()); @@ -6517,6 +6520,7 @@ content::RenderFrameHost* subframe = content::ChildFrameAt(main_frame, 0); ASSERT_TRUE(subframe); EXPECT_TRUE(NavigateToURLFromRenderer(subframe, frame_url)); + subframe = content::ChildFrameAt(main_frame, 0); EXPECT_EQ(main_frame->GetSiteInstance(), subframe->GetSiteInstance()); EXPECT_EQ(main_frame->GetProcess(), subframe->GetProcess()); EXPECT_TRUE(subframe->GetSiteInstance()->IsGuest());
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn index 4d45f91..5e8f39ac 100644 --- a/chrome/browser/ash/BUILD.gn +++ b/chrome/browser/ash/BUILD.gn
@@ -274,8 +274,6 @@ "arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.h", "arc/enterprise/arc_enterprise_reporting_service.cc", "arc/enterprise/arc_enterprise_reporting_service.h", - "arc/enterprise/arc_force_installed_apps_tracker.cc", - "arc/enterprise/arc_force_installed_apps_tracker.h", "arc/enterprise/cert_store/arc_cert_installer.cc", "arc/enterprise/cert_store/arc_cert_installer.h", "arc/enterprise/cert_store/arc_cert_installer_utils.cc", @@ -3339,7 +3337,6 @@ "//ash/components/arc:arc_base", "//ash/components/arc:arc_base_utils", "//ash/components/arc:prefs", - "//ash/components/arc/enterprise", "//ash/components/arc/mojom", "//ash/components/arc/mojom:media", "//ash/components/arc/mojom:oemcrypto", @@ -4721,6 +4718,10 @@ "../ui/webui/settings/ash/os_apps_page/mojom/app_type_mojom_traits_unittest.cc", "../ui/webui/settings/ash/os_settings_manager_unittest.cc", "../ui/webui/settings/ash/os_settings_section_unittest.cc", + + # TODO(crbug.com/1393069): Move to under `enable_screen_ai_service` + # when PDF OCR becomes available on windows, macOS, and linux. + "../ui/webui/settings/ash/pdf_ocr_handler_unittest.cc", "../ui/webui/settings/ash/privacy_hub_handler_unittest.cc", "../ui/webui/settings/ash/search/per_session_settings_user_action_tracker_unittest.cc", "../ui/webui/settings/ash/search/search_handler_unittest.cc", @@ -4870,7 +4871,6 @@ "arc/bluetooth/arc_floss_bridge_unittest.cc", "arc/boot_phase_monitor/arc_boot_phase_monitor_bridge_unittest.cc", "arc/enterprise/arc_enterprise_reporting_service_unittest.cc", - "arc/enterprise/arc_force_installed_apps_tracker_unittest.cc", "arc/enterprise/cert_store/arc_cert_installer_unittest.cc", "arc/extensions/arc_support_message_host_unittest.cc", "arc/file_system_watcher/arc_file_system_watcher_service_unittest.cc", @@ -5700,7 +5700,6 @@ "//ash/components/arc:compat_mode_test_support", "//ash/components/arc:notification_test_support", "//ash/components/arc:prefs", - "//ash/components/arc/enterprise", "//ash/components/arc/mojom", "//ash/components/arc/session", "//ash/components/arc/session:arc_base_enums", @@ -6046,6 +6045,7 @@ "//components/services/app_service/public/cpp:test_support", "//components/services/app_service/public/protos", "//components/services/filesystem/public/mojom", + "//components/services/screen_ai/public/cpp:screen_ai_install_state", "//components/session_manager:base", "//components/session_manager/core", "//components/sessions:test_support",
diff --git a/chrome/browser/ash/app_list/app_list_client_impl.cc b/chrome/browser/ash/app_list/app_list_client_impl.cc index e00fd682..2c67efe 100644 --- a/chrome/browser/ash/app_list/app_list_client_impl.cc +++ b/chrome/browser/ash/app_list/app_list_client_impl.cc
@@ -9,13 +9,17 @@ #include <utility> #include <vector> +#include "ash/app_list/app_list_view_delegate.h" +#include "ash/public/cpp/app_list/app_list_client.h" #include "ash/public/cpp/app_list/app_list_controller.h" #include "ash/public/cpp/app_list/app_list_types.h" #include "ash/public/cpp/new_window_delegate.h" #include "ash/public/cpp/tablet_mode.h" #include "ash/shell.h" #include "ash/system/federated/federated_service_controller_impl.h" +#include "base/feature_list.h" #include "base/functional/bind.h" +#include "base/memory/weak_ptr.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" @@ -32,6 +36,7 @@ #include "chrome/browser/ash/app_list/search/search_controller_factory.h" #include "chrome/browser/ash/crosapi/browser_util.h" #include "chrome/browser/ash/crosapi/url_handler_ash.h" +#include "chrome/browser/feature_engagement/tracker_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/search_engines/template_url_service_factory.h" @@ -47,6 +52,8 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h" #include "chromeos/crosapi/cpp/gurl_os_handler_utils.h" +#include "components/feature_engagement/public/feature_constants.h" +#include "components/feature_engagement/public/tracker.h" #include "components/session_manager/core/session_manager.h" #include "ui/base/page_transition_types.h" #include "ui/display/types/display_constants.h" @@ -117,6 +124,21 @@ } } +class ScopedIphSessionImpl : public ash::ScopedIphSession { + public: + explicit ScopedIphSessionImpl(raw_ptr<feature_engagement::Tracker> tracker, + const base::Feature& iph_feature) + : tracker_(tracker), iph_feature_(iph_feature) { + CHECK(tracker_); + } + + ~ScopedIphSessionImpl() override { tracker_->Dismissed(iph_feature_); } + + private: + raw_ptr<feature_engagement::Tracker> tracker_; + const base::Feature& iph_feature_; +}; + } // namespace AppListClientImpl::AppListClientImpl() @@ -527,6 +549,7 @@ SetUpSearchUI(); OnTemplateURLServiceChanged(); + QueryWouldTriggerLauncherSearchIph(); } void AppListClientImpl::SetUpSearchUI() { @@ -668,6 +691,36 @@ return app_list_notifier_.get(); } +void AppListClientImpl::QueryWouldTriggerLauncherSearchIph() { + // This can be called before a `Profile` is set to `AppListClientImpl`. If a + // `Profile` is not set yet, return here. `AppListClientImpl::SetProfile` will + // call this method once a `Profile` is set. + if (!current_model_updater_) { + return; + } + + current_model_updater_->QueryWouldTriggerLauncherSearchIph(); +} + +std::unique_ptr<ash::ScopedIphSession> +AppListClientImpl::CreateLauncherSearchIphSession() { + if (profile_ == nullptr) { + return nullptr; + } + + raw_ptr<feature_engagement::Tracker> tracker = + feature_engagement::TrackerFactory::GetForBrowserContext(profile_); + if (!tracker->ShouldTriggerHelpUI( + feature_engagement::kIPHLauncherSearchHelpUiFeature)) { + return nullptr; + } + + // If we call `ShouldTriggerHelpUI` above, we must show an IPH, i.e. we must + // return `ScopedIphSessionImpl`. + return std::make_unique<ScopedIphSessionImpl>( + tracker, feature_engagement::kIPHLauncherSearchHelpUiFeature); +} + void AppListClientImpl::LoadIcon(int profile_id, const std::string& app_id) { auto* requested_model_updater = profile_model_mappings_[profile_id]; if (requested_model_updater != current_model_updater_ ||
diff --git a/chrome/browser/ash/app_list/app_list_client_impl.h b/chrome/browser/ash/app_list/app_list_client_impl.h index 19f2f00..97cafd51 100644 --- a/chrome/browser/ash/app_list/app_list_client_impl.h +++ b/chrome/browser/ash/app_list/app_list_client_impl.h
@@ -20,6 +20,7 @@ #include "base/scoped_observation.h" #include "base/time/time.h" #include "chrome/browser/ash/app_list/app_list_controller_delegate.h" +#include "components/feature_engagement/public/tracker.h" #include "components/search_engines/template_url_service.h" #include "components/search_engines/template_url_service_observer.h" #include "components/session_manager/core/session_manager_observer.h" @@ -104,6 +105,9 @@ const std::string& setting_name, const std::map<std::string, int>& values) override; ash::AppListNotifier* GetNotifier() override; + void QueryWouldTriggerLauncherSearchIph() override; + std::unique_ptr<ash::ScopedIphSession> CreateLauncherSearchIphSession() + override; void LoadIcon(int profile_id, const std::string& app_id) override; ash::AppListSortOrder GetPermanentSortingOrder() const override;
diff --git a/chrome/browser/ash/app_list/app_list_model_updater.h b/chrome/browser/ash/app_list/app_list_model_updater.h index 4341c93..d0e50a0 100644 --- a/chrome/browser/ash/app_list/app_list_model_updater.h +++ b/chrome/browser/ash/app_list/app_list_model_updater.h
@@ -120,6 +120,7 @@ virtual size_t BadgedItemCount() = 0; // For SearchModel: virtual bool SearchEngineIsGoogle() = 0; + virtual void QueryWouldTriggerLauncherSearchIph() = 0; // Notifies when the app list gets hidden. virtual void OnAppListHidden() = 0;
diff --git a/chrome/browser/ash/app_list/app_list_sort_browsertest.cc b/chrome/browser/ash/app_list/app_list_sort_browsertest.cc index f359257..aaa7389 100644 --- a/chrome/browser/ash/app_list/app_list_sort_browsertest.cc +++ b/chrome/browser/ash/app_list/app_list_sort_browsertest.cc
@@ -1410,7 +1410,7 @@ gfx::ImageSkia icon; icon = gfx::ImageSkiaOperations::CreateImageWithCircleBackground( icon_size / 2, icon_color, icon); - const sk_sp<SkImage> image = SkImage::MakeFromBitmap(*icon.bitmap()); + const sk_sp<SkImage> image = SkImages::RasterFromBitmap(*icon.bitmap()); const sk_sp<SkData> png_data( image->encodeToData(SkEncodedImageFormat::kPNG, /*quality=*/100)); icon_file.Write(0, (const char*)png_data->data(), png_data->size());
diff --git a/chrome/browser/ash/app_list/chrome_app_list_model_updater.cc b/chrome/browser/ash/app_list/chrome_app_list_model_updater.cc index 5bc7fcc..929ea05 100644 --- a/chrome/browser/ash/app_list/chrome_app_list_model_updater.cc +++ b/chrome/browser/ash/app_list/chrome_app_list_model_updater.cc
@@ -15,6 +15,7 @@ #include "ash/public/cpp/app_list/app_list_controller.h" #include "ash/public/cpp/app_list/app_list_metrics.h" #include "ash/public/cpp/tablet_mode.h" +#include "base/feature_list.h" #include "base/functional/bind.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/ash/app_list/app_list_controller_delegate.h" @@ -24,6 +25,10 @@ #include "chrome/browser/ash/app_list/reorder/app_list_reorder_core.h" #include "chrome/browser/ash/app_list/reorder/app_list_reorder_delegate.h" #include "chrome/browser/ash/app_list/search/chrome_search_result.h" +#include "chrome/browser/feature_engagement/tracker_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "components/feature_engagement/public/feature_constants.h" +#include "components/feature_engagement/public/tracker.h" #include "extensions/common/constants.h" #include "ui/base/models/menu_model.h" @@ -283,6 +288,44 @@ search_model_.SetSearchEngineIsGoogle(is_google); } +void ChromeAppListModelUpdater::QueryWouldTriggerLauncherSearchIph() { + raw_ptr<feature_engagement::Tracker> tracker = + feature_engagement::TrackerFactory::GetForBrowserContext(profile_); + if (!tracker) { + // Set false as a fail-safe behavior. + search_model_.SetWouldTriggerLauncherSearchIph(false); + return; + } + + // `AddOnInitializedCallback` will call the callback immediately if it's + // already initialized. + tracker->AddOnInitializedCallback(base::BindOnce( + &ChromeAppListModelUpdater::OnFeatureEngagementTrackerInitialized, + weak_ptr_factory_.GetWeakPtr())); +} + +void ChromeAppListModelUpdater::OnFeatureEngagementTrackerInitialized( + bool success) { + if (!success) { + // Set false as a fail-safe behavior. + search_model_.SetWouldTriggerLauncherSearchIph(false); + return; + } + + // To be on a safer side, query tracker instance again to minimize the + // duration of holding a tracker object. + raw_ptr<feature_engagement::Tracker> tracker = + feature_engagement::TrackerFactory::GetForBrowserContext(profile_); + if (!tracker) { + // Set false as a fail-safe behavior. + search_model_.SetWouldTriggerLauncherSearchIph(false); + return; + } + + search_model_.SetWouldTriggerLauncherSearchIph(tracker->WouldTriggerHelpUI( + feature_engagement::kIPHLauncherSearchHelpUiFeature)); +} + void ChromeAppListModelUpdater::PublishSearchResults( const std::vector<ChromeSearchResult*>& results, const std::vector<ash::AppListSearchResultCategory>& categories) {
diff --git a/chrome/browser/ash/app_list/chrome_app_list_model_updater.h b/chrome/browser/ash/app_list/chrome_app_list_model_updater.h index 332a61f3..38cb761 100644 --- a/chrome/browser/ash/app_list/chrome_app_list_model_updater.h +++ b/chrome/browser/ash/app_list/chrome_app_list_model_updater.h
@@ -53,6 +53,7 @@ void RemoveItem(const std::string& id, bool is_uninstall) override; void SetStatus(ash::AppListModelStatus status) override; void SetSearchEngineIsGoogle(bool is_google) override; + void QueryWouldTriggerLauncherSearchIph() override; void PublishSearchResults( const std::vector<ChromeSearchResult*>& results, const std::vector<ash::AppListSearchResultCategory>& categories) override; @@ -201,6 +202,8 @@ // list is sorted by color. void MaybeUpdatePositionWhenIconColorChange(ash::AppListItemMetadata* data); + void OnFeatureEngagementTrackerInitialized(bool success); + // Indicates the profile that the model updater is associated with. Profile* const profile_ = nullptr;
diff --git a/chrome/browser/ash/app_list/launcher_search_iph_browsertest.cc b/chrome/browser/ash/app_list/launcher_search_iph_browsertest.cc new file mode 100644 index 0000000..6373c4f --- /dev/null +++ b/chrome/browser/ash/app_list/launcher_search_iph_browsertest.cc
@@ -0,0 +1,188 @@ +// 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 "ash/app_list/app_list_public_test_util.h" +#include "ash/app_list/views/assistant/assistant_test_api_impl.h" +#include "ash/app_list/views/launcher_search_iph_view.h" +#include "ash/app_list/views/search_box_view.h" +#include "ash/assistant/assistant_controller_impl.h" +#include "ash/assistant/test/test_assistant_service.h" +#include "ash/public/cpp/test/app_list_test_api.h" +#include "ash/shell.h" +#include "base/command_line.h" +#include "base/run_loop.h" +#include "base/scoped_observation.h" +#include "chrome/browser/ash/app_list/app_list_client_impl.h" +#include "chrome/browser/ui/ash/assistant/assistant_test_mixin.h" +#include "chrome/test/base/mixin_based_in_process_browser_test.h" +#include "components/feature_engagement/public/feature_constants.h" +#include "components/feature_engagement/test/scoped_iph_feature_list.h" +#include "content/public/test/browser_test.h" +#include "ui/aura/window.h" +#include "ui/events/test/event_generator.h" +#include "ui/views/controls/button/image_button.h" +#include "ui/views/view.h" +#include "ui/views/view_observer.h" + +namespace { +class ViewWaiter : public views::ViewObserver { + public: + ViewWaiter(raw_ptr<views::View> observed_view, int view_id) + : observed_view_(observed_view), view_id_(view_id) {} + + void Run() { + if (observed_view_->GetViewByID(view_id_)) { + return; + } + + scoped_observation_.Observe(observed_view_); + run_loop.Run(); + } + + void OnViewHierarchyChanged( + views::View* observed_view, + const views::ViewHierarchyChangedDetails& details) override { + if (observed_view_->GetViewByID(view_id_)) { + run_loop.Quit(); + } + } + + private: + raw_ptr<views::View> observed_view_; + int view_id_; + base::ScopedObservation<views::View, ViewWaiter> scoped_observation_{this}; + base::RunLoop run_loop; +}; + +bool IsLauncherSearchIphViewVisible() { + raw_ptr<ash::SearchBoxView> search_box_view = ash::GetSearchBoxView(); + if (!search_box_view) { + return false; + } + + raw_ptr<views::View> launcher_search_iph_view = + search_box_view->GetViewByID(ash::LauncherSearchIphView::kViewId); + if (!launcher_search_iph_view) { + return false; + } + + return launcher_search_iph_view->GetVisible(); +} +} // namespace + +class AppListIphBrowserTest : public MixinBasedInProcessBrowserTest { + public: + void SetUpOnMainThread() override { + ash::Shell::Get()->assistant_controller()->SetAssistant(&test_service_); + test_api_impl_.EnableAssistantAndWait(); + MixinBasedInProcessBrowserTest::SetUpOnMainThread(); + } + + void TearDownOnMainThread() override { + test_api_impl_.SetAssistantEnabled(false); + } + + private: + ash::TestAssistantService test_service_; + ash::AssistantTestApiImpl test_api_impl_; +}; + +class AppListIphBrowerTestWithDemoMode : public AppListIphBrowserTest { + public: + void SetUpCommandLine(base::CommandLine* command_line) override { + scoped_iph_feature_list_ = + std::make_unique<feature_engagement::test::ScopedIphFeatureList>(); + scoped_iph_feature_list_->InitForDemo( + feature_engagement::kIPHLauncherSearchHelpUiFeature); + + MixinBasedInProcessBrowserTest::SetUpCommandLine(command_line); + } + + private: + std::unique_ptr<feature_engagement::test::ScopedIphFeatureList> + scoped_iph_feature_list_; +}; + +IN_PROC_BROWSER_TEST_F(AppListIphBrowserTest, + LauncherSearchIphNotShownByDefault) { + raw_ptr<AppListClientImpl> client_impl = AppListClientImpl::GetInstance(); + client_impl->UpdateProfile(); + + client_impl->ShowAppList(ash::AppListShowSource::kSearchKey); + ash::AppListTestApi().WaitForBubbleWindow( + /*wait_for_opening_animation=*/false); + EXPECT_FALSE(IsLauncherSearchIphViewVisible()); +} + +IN_PROC_BROWSER_TEST_F(AppListIphBrowerTestWithDemoMode, LauncherSearchIph) { + raw_ptr<AppListClientImpl> client_impl = AppListClientImpl::GetInstance(); + client_impl->UpdateProfile(); + + client_impl->ShowAppList(ash::AppListShowSource::kSearchKey); + ash::AppListTestApi().WaitForBubbleWindow( + /*wait_for_opening_animation=*/false); + raw_ptr<ash::SearchBoxView> search_box_view = ash::GetSearchBoxView(); + ASSERT_TRUE(search_box_view); + // There is an async call for checking IPH trigger condition. + ViewWaiter(search_box_view, ash::LauncherSearchIphView::kViewId).Run(); + EXPECT_TRUE(IsLauncherSearchIphViewVisible()); + + // Dismiss the app list and show it again. IPH won't be shown this time. Note + // that this is IPH demo mode behavior. + client_impl->DismissView(); + ASSERT_FALSE(client_impl->GetAppListWindow()); + + client_impl->ShowAppList(ash::AppListShowSource::kSearchKey); + ash::AppListTestApi().WaitForBubbleWindow( + /*wait_for_opening_animation=*/false); + + EXPECT_FALSE(IsLauncherSearchIphViewVisible()); +} + +IN_PROC_BROWSER_TEST_F(AppListIphBrowerTestWithDemoMode, + LauncherSearchIphSearch) { + raw_ptr<AppListClientImpl> client_impl = AppListClientImpl::GetInstance(); + client_impl->UpdateProfile(); + + client_impl->ShowAppList(ash::AppListShowSource::kSearchKey); + ash::AppListTestApi().WaitForBubbleWindow( + /*wait_for_opening_animation=*/false); + raw_ptr<ash::SearchBoxView> search_box_view = ash::GetSearchBoxView(); + ASSERT_TRUE(search_box_view); + // There is an async call for checking IPH trigger condition. + ViewWaiter(search_box_view, ash::LauncherSearchIphView::kViewId).Run(); + EXPECT_TRUE(IsLauncherSearchIphViewVisible()); + + // Do search and confirm that the IPH gets dismissed. + ash::AppListTestApi().SimulateSearch(u"Test"); + EXPECT_FALSE(IsLauncherSearchIphViewVisible()); +} + +IN_PROC_BROWSER_TEST_F(AppListIphBrowerTestWithDemoMode, + LauncherSearchIphAssistant) { + raw_ptr<AppListClientImpl> client_impl = AppListClientImpl::GetInstance(); + client_impl->UpdateProfile(); + + client_impl->ShowAppList(ash::AppListShowSource::kSearchKey); + ash::AppListTestApi().WaitForBubbleWindow( + /*wait_for_opening_animation=*/false); + raw_ptr<ash::SearchBoxView> search_box_view = ash::GetSearchBoxView(); + ASSERT_TRUE(search_box_view); + // There is an async call for checking IPH trigger condition. + ViewWaiter(search_box_view, ash::LauncherSearchIphView::kViewId).Run(); + EXPECT_TRUE(IsLauncherSearchIphViewVisible()); + + // Clicks Assistant button to open Assistant UI and confirm that IPH gets + // dismissed. + raw_ptr<views::ImageButton> assistant_button = + search_box_view->assistant_button(); + ASSERT_TRUE(assistant_button); + ui::test::EventGenerator event_generator( + assistant_button->GetWidget()->GetNativeWindow()->GetRootWindow()); + event_generator.MoveMouseToInHost( + assistant_button->GetBoundsInScreen().CenterPoint()); + event_generator.ClickLeftButton(); + + EXPECT_FALSE(IsLauncherSearchIphViewVisible()); +}
diff --git a/chrome/browser/ash/app_list/test/fake_app_list_model_updater.cc b/chrome/browser/ash/app_list/test/fake_app_list_model_updater.cc index e2d647d..a26d8d7 100644 --- a/chrome/browser/ash/app_list/test/fake_app_list_model_updater.cc +++ b/chrome/browser/ash/app_list/test/fake_app_list_model_updater.cc
@@ -189,6 +189,8 @@ return search_engine_is_google_; } +void FakeAppListModelUpdater::QueryWouldTriggerLauncherSearchIph() {} + void FakeAppListModelUpdater::PublishSearchResults( const std::vector<ChromeSearchResult*>& results, const std::vector<ash::AppListSearchResultCategory>& categories) {
diff --git a/chrome/browser/ash/app_list/test/fake_app_list_model_updater.h b/chrome/browser/ash/app_list/test/fake_app_list_model_updater.h index dc13be8..d7baa125 100644 --- a/chrome/browser/ash/app_list/test/fake_app_list_model_updater.h +++ b/chrome/browser/ash/app_list/test/fake_app_list_model_updater.h
@@ -70,6 +70,7 @@ // For SearchModel: bool SearchEngineIsGoogle() override; + void QueryWouldTriggerLauncherSearchIph() override; const std::vector<ChromeSearchResult*>& search_results() const { return search_results_; }
diff --git a/chrome/browser/ash/apps/apk_web_app_installer.cc b/chrome/browser/ash/apps/apk_web_app_installer.cc index c72306f1e..b2265e48 100644 --- a/chrome/browser/ash/apps/apk_web_app_installer.cc +++ b/chrome/browser/ash/apps/apk_web_app_installer.cc
@@ -38,6 +38,7 @@ // static void ApkWebAppInstaller::Install(Profile* profile, + const std::string& package_name, arc::mojom::WebAppInfoPtr web_app_info, arc::mojom::RawIconPngDataPtr icon, InstallFinishCallback callback, @@ -50,7 +51,7 @@ // CompleteInstallation(). auto* installer = new ApkWebAppInstaller(profile, std::move(callback), weak_owner); - installer->Start(std::move(web_app_info), std::move(icon)); + installer->Start(package_name, std::move(web_app_info), std::move(icon)); } ApkWebAppInstaller::ApkWebAppInstaller(Profile* profile, @@ -64,7 +65,8 @@ ApkWebAppInstaller::~ApkWebAppInstaller() = default; -void ApkWebAppInstaller::Start(arc::mojom::WebAppInfoPtr web_app_info, +void ApkWebAppInstaller::Start(const std::string& package_name, + arc::mojom::WebAppInfoPtr web_app_info, arc::mojom::RawIconPngDataPtr icon) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); if (!weak_owner_.get()) { @@ -94,6 +96,8 @@ web_app_install_info_->scope = GURL(web_app_info->scope_url); DCHECK(web_app_install_info_->scope.is_valid()); + web_app_install_info_->additional_policy_ids.push_back(package_name); + // The install_url and the start_url seem to be same in this case // as far as ExternallyInstalledWebAppPrefs are concerned. // This is because inside OnWebAppCreated(), the start_url is @@ -183,6 +187,8 @@ arc_install_info->start_url = std::move(web_app_install_info->start_url); arc_install_info->scope = std::move(web_app_install_info->scope); arc_install_info->theme_color = web_app_install_info->theme_color; + arc_install_info->additional_policy_ids = + std::move(web_app_install_info->additional_policy_ids); // Take the first icon (there should only be one). if (web_app_install_info->icon_bitmaps.any.size() > 0) { auto& [sizePx, bitmap] =
diff --git a/chrome/browser/ash/apps/apk_web_app_installer.h b/chrome/browser/ash/apps/apk_web_app_installer.h index f257e55..e43cc48 100644 --- a/chrome/browser/ash/apps/apk_web_app_installer.h +++ b/chrome/browser/ash/apps/apk_web_app_installer.h
@@ -47,6 +47,7 @@ // with either the id of the installed web app if installation was successful, // or an empty id if not. static void Install(Profile* profile, + const std::string& package_name, arc::mojom::WebAppInfoPtr web_app_info, arc::mojom::RawIconPngDataPtr icon, InstallFinishCallback callback, @@ -60,7 +61,8 @@ virtual ~ApkWebAppInstaller(); // Starts the installation flow by decoding icon data. - void Start(arc::mojom::WebAppInfoPtr web_app_info, + void Start(const std::string& package_name, + arc::mojom::WebAppInfoPtr web_app_info, arc::mojom::RawIconPngDataPtr icon); // Calls |callback_| with |id|, and deletes this object. Virtual for testing.
diff --git a/chrome/browser/ash/apps/apk_web_app_installer_unittest.cc b/chrome/browser/ash/apps/apk_web_app_installer_unittest.cc index 35c4337..ba20ebd 100644 --- a/chrome/browser/ash/apps/apk_web_app_installer_unittest.cc +++ b/chrome/browser/ash/apps/apk_web_app_installer_unittest.cc
@@ -104,7 +104,7 @@ FakeApkWebAppInstaller apk_web_app_installer( profile(), weak_ptr_factory_.GetWeakPtr(), run_loop.QuitClosure()); - apk_web_app_installer.Start(GetWebAppInfo(), GetIconBytes()); + apk_web_app_installer.Start("package", GetWebAppInfo(), GetIconBytes()); run_loop.Run(); EXPECT_FALSE(apk_web_app_installer.complete_installation_called()); @@ -135,7 +135,7 @@ profile(), weak_ptr_factory_.GetWeakPtr(), run_loop.QuitClosure()); weak_ptr_factory_.InvalidateWeakPtrs(); - apk_web_app_installer.Start(GetWebAppInfo(), GetIconBytes()); + apk_web_app_installer.Start("package", GetWebAppInfo(), GetIconBytes()); run_loop.Run(); EXPECT_EQ("", apk_web_app_installer.id()); @@ -151,7 +151,7 @@ FakeApkWebAppInstaller apk_web_app_installer( profile(), weak_ptr_factory_.GetWeakPtr(), run_loop.QuitClosure()); - apk_web_app_installer.Start(GetWebAppInfo(), GetIconBytes()); + apk_web_app_installer.Start("package", GetWebAppInfo(), GetIconBytes()); weak_ptr_factory_.InvalidateWeakPtrs(); run_loop.Run(); @@ -165,7 +165,8 @@ FakeApkWebAppInstaller apk_web_app_installer( profile(), weak_ptr_factory_.GetWeakPtr(), run_loop.QuitClosure()); - apk_web_app_installer.Start(/*web_app_install_info=*/nullptr, GetIconBytes()); + apk_web_app_installer.Start("package", /*web_app_install_info=*/nullptr, + GetIconBytes()); run_loop.Run(); EXPECT_EQ("", apk_web_app_installer.id()); @@ -180,7 +181,7 @@ FakeApkWebAppInstaller apk_web_app_installer( profile(), weak_ptr_factory_.GetWeakPtr(), run_loop.QuitClosure()); - apk_web_app_installer.Start(GetWebAppInfo(), {}); + apk_web_app_installer.Start("package", GetWebAppInfo(), {}); run_loop.Run(); EXPECT_EQ("", apk_web_app_installer.id());
diff --git a/chrome/browser/ash/apps/apk_web_app_service.cc b/chrome/browser/ash/apps/apk_web_app_service.cc index 7c21eb8..8ab70fb2 100644 --- a/chrome/browser/ash/apps/apk_web_app_service.cc +++ b/chrome/browser/ash/apps/apk_web_app_service.cc
@@ -132,7 +132,7 @@ const std::string& package_name, arc::mojom::WebAppInfoPtr web_app_info, arc::mojom::RawIconPngDataPtr icon) { - ApkWebAppInstaller::Install(profile_, std::move(web_app_info), + ApkWebAppInstaller::Install(profile_, package_name, std::move(web_app_info), std::move(icon), std::move(callback), weak_ptr_factory_.GetWeakPtr()); } @@ -497,7 +497,7 @@ arc::mojom::WebAppInfoPtr web_app_info, arc::mojom::RawIconPngDataPtr icon) { ApkWebAppInstaller::Install( - profile_, std::move(web_app_info), std::move(icon), + profile_, package_name, std::move(web_app_info), std::move(icon), base::BindOnce(&ApkWebAppService::OnDidFinishInstall, weak_ptr_factory_.GetWeakPtr(), package_name), weak_ptr_factory_.GetWeakPtr());
diff --git a/chrome/browser/ash/arc/enterprise/arc_data_snapshotd_delegate.cc b/chrome/browser/ash/arc/enterprise/arc_data_snapshotd_delegate.cc deleted file mode 100644 index adb3fa8..0000000 --- a/chrome/browser/ash/arc/enterprise/arc_data_snapshotd_delegate.cc +++ /dev/null
@@ -1,108 +0,0 @@ -// Copyright 2020 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/ash/arc/enterprise/arc_data_snapshotd_delegate.h" - -#include "chrome/browser/ash/login/chrome_restart_request.h" -#include "chrome/browser/ash/arc/arc_util.h" -#include "chrome/browser/ash/arc/enterprise/arc_force_installed_apps_tracker.h" -#include "chrome/browser/ash/arc/enterprise/arc_snapshot_reboot_notification_impl.h" -#include "chrome/browser/ash/arc/session/arc_session_manager.h" - -namespace arc { -namespace data_snapshotd { - -namespace { - -// Returns true if ARC is active and running. -bool IsArcActive(arc::ArcSessionManager::State state) { - return state == ArcSessionManager::State::ACTIVE; -} - -// Returns true if ARC is stopped. -bool IsArcStopped(arc::ArcSessionManager::State state) { - return state == ArcSessionManager::State::STOPPED; -} - -} // namespace - -ArcDataSnapshotdDelegate::ArcDataSnapshotdDelegate() - : arc_session_manager_(arc::ArcSessionManager::Get()) { - DCHECK(arc_session_manager_); -} - -ArcDataSnapshotdDelegate::~ArcDataSnapshotdDelegate() { - if (!arc_stopped_callback_.is_null()) - NotifyArcStopped(false /* success */); -} - -void ArcDataSnapshotdDelegate::RequestStopArcInstance( - base::OnceCallback<void(bool)> stopped_callback) { - DCHECK(!stopped_callback.is_null()); - if (!arc_stopped_callback_.is_null()) { - // Previous request to stop ARC has not been satisfied yet. - LOG(WARNING) << "Requested to stop ARC twice."; - // Report failure to both callbacks. - NotifyArcStopped(false /* success */); - std::move(stopped_callback).Run(false /* success */); - return; - } - if (!IsArcActive(arc_session_manager_->state())) { - if (!stopped_callback.is_null()) - std::move(stopped_callback).Run(false /* success */); - return; - } - - arc_stopped_callback_ = std::move(stopped_callback); - arc_session_manager_->AddObserver(this); - - // ARC is expected to be active and running here. - arc_session_manager_->RequestDisable(); -} - -PrefService* ArcDataSnapshotdDelegate::GetProfilePrefService() { - DCHECK(arc_session_manager_->profile()); - return arc_session_manager_->profile()->GetPrefs(); -} - -std::unique_ptr<ArcSnapshotRebootNotification> -ArcDataSnapshotdDelegate::CreateRebootNotification() { - return std::make_unique<ArcSnapshotRebootNotificationImpl>(); -} - -std::unique_ptr<ArcAppsTracker> ArcDataSnapshotdDelegate::CreateAppsTracker() { - return std::make_unique<ArcForceInstalledAppsTracker>(); -} - -void ArcDataSnapshotdDelegate::RestartChrome( - const base::CommandLine& command_line) { - ash::RestartChrome(command_line, ash::RestartChromeReason::kUserless); -} - -void ArcDataSnapshotdDelegate::OnArcSessionStopped(arc::ArcStopReason reason) { - switch (reason) { - case arc::ArcStopReason::SHUTDOWN: - // This shutdown is triggered only by RequestStopArcInstance. - // It is guaranteed that user is not able to influence ArcEnabled pref. - // If ARC is disabled by policy, the ARC snapshot feature gets disabled. - DCHECK(IsArcStopped(arc_session_manager_->state())); - NotifyArcStopped(true /* success */); - return; - case arc::ArcStopReason::GENERIC_BOOT_FAILURE: - case arc::ArcStopReason::CRASH: - case arc::ArcStopReason::LOW_DISK_SPACE: - NotifyArcStopped(false /* success */); - return; - } -} - -void ArcDataSnapshotdDelegate::NotifyArcStopped(bool success) { - DCHECK(!arc_stopped_callback_.is_null()); - std::move(arc_stopped_callback_).Run(success); - - arc_session_manager_->RemoveObserver(this); -} - -} // namespace data_snapshotd -} // namespace arc
diff --git a/chrome/browser/ash/arc/enterprise/arc_data_snapshotd_delegate_unittest.cc b/chrome/browser/ash/arc/enterprise/arc_data_snapshotd_delegate_unittest.cc deleted file mode 100644 index 7787951..0000000 --- a/chrome/browser/ash/arc/enterprise/arc_data_snapshotd_delegate_unittest.cc +++ /dev/null
@@ -1,208 +0,0 @@ -// Copyright 2020 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/ash/arc/enterprise/arc_data_snapshotd_delegate.h" - -#include "ash/components/arc/arc_prefs.h" -#include "ash/components/arc/test/arc_util_test_support.h" -#include "ash/components/arc/test/fake_arc_session.h" -#include "base/command_line.h" -#include "base/run_loop.h" -#include "base/test/bind.h" -#include "chrome/browser/ash/arc/arc_util.h" -#include "chrome/browser/ash/arc/session/arc_session_manager.h" -#include "chrome/browser/ash/arc/test/test_arc_session_manager.h" -#include "chrome/browser/ash/login/users/fake_chrome_user_manager.h" -#include "chrome/test/base/testing_profile.h" -#include "chromeos/ash/components/dbus/concierge/concierge_client.h" -#include "components/prefs/pref_service.h" -#include "components/user_manager/scoped_user_manager.h" -#include "components/user_manager/user_manager.h" -#include "content/public/test/browser_task_environment.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace arc { -namespace data_snapshotd { - -namespace { - -// This class is observer of ArcSessionManager. It makes sure that all ARC -// started/stopped events are tracked. -class TestObserver : public arc::ArcSessionManagerObserver { - public: - TestObserver() = default; - TestObserver(const TestObserver&) = delete; - TestObserver& operator=(const TestObserver&) = delete; - - // arc::ArcSessionManagerObserver overrides: - void OnArcStarted() override { - EXPECT_FALSE(start_closure_.is_null()); - std::move(start_closure_).Run(); - } - void OnArcSessionStopped(arc::ArcStopReason reason) override { - EXPECT_FALSE(stop_closure_.is_null()); - std::move(stop_closure_).Run(); - } - - void set_start_closure(base::OnceClosure closure) { - start_closure_ = std::move(closure); - } - void set_stop_closure(base::OnceClosure closure) { - stop_closure_ = std::move(closure); - } - - private: - base::OnceClosure start_closure_; - base::OnceClosure stop_closure_; -}; - -} // namespace - -class ArcDataSnapshotdDelegateTest : public testing::Test { - public: - ArcDataSnapshotdDelegateTest() - : user_manager_enabler_(std::make_unique<ash::FakeChromeUserManager>()) { - SetArcAvailableCommandLineForTesting( - base::CommandLine::ForCurrentProcess()); - ArcSessionManager::EnableCheckAndroidManagementForTesting(false); - - ash::ConciergeClient::InitializeFake(/*fake_cicerone_client=*/nullptr); - ash::SessionManagerClient::InitializeFakeInMemory(); - - TestingProfile::Builder profile_builder; - profile_builder.SetProfileName("user@gmail.com"); - testing_profile_ = profile_builder.Build(); - - const AccountId account_id(AccountId::FromUserEmailGaiaId( - testing_profile_->GetProfileUserName(), "1234567890")); - GetFakeUserManager()->AddUser(account_id); - GetFakeUserManager()->LoginUser(account_id); - } - - ArcDataSnapshotdDelegateTest(const ArcDataSnapshotdDelegateTest&) = delete; - ArcDataSnapshotdDelegateTest& operator=(const ArcDataSnapshotdDelegateTest&) = - delete; - - ~ArcDataSnapshotdDelegateTest() override { - ash::SessionManagerClient::Shutdown(); - ash::ConciergeClient::Shutdown(); - } - - void SetUp() override { - arc_session_manager_ = - arc::CreateTestArcSessionManager(std::make_unique<ArcSessionRunner>( - base::BindRepeating(FakeArcSession::Create))); - - arc_session_manager_->SetProfile(testing_profile_.get()); - - PrefService* const prefs = testing_profile_->GetPrefs(); - prefs->SetBoolean(prefs::kArcEnabled, true); - - arc_session_manager_->Initialize(); - arc_session_manager_->AddObserver(&test_observer_); - - delegate_ = std::make_unique<ArcDataSnapshotdDelegate>(); - } - - void TearDown() override { - delegate_.reset(); - arc_session_manager_->RemoveObserver(&test_observer_); - arc_session_manager_.reset(); - } - - void EnableArc() { - base::RunLoop run_loop; - test_observer_.set_start_closure(run_loop.QuitClosure()); - arc_session_manager_->StartArcForTesting(); - run_loop.Run(); - EXPECT_TRUE( - IsArcPlayStoreEnabledForProfile(arc_session_manager_->profile())); - } - - void DisableArcPref() { - PrefService* const prefs = testing_profile_->GetPrefs(); - prefs->SetBoolean(prefs::kArcEnabled, false); - EXPECT_FALSE( - IsArcPlayStoreEnabledForProfile(arc_session_manager_->profile())); - } - - void ExpectArcStopped(base::OnceClosure closure) { - test_observer_.set_stop_closure(std::move(closure)); - } - - ArcDataSnapshotdDelegate* delegate() { return delegate_.get(); } - - private: - ash::FakeChromeUserManager* GetFakeUserManager() const { - return static_cast<ash::FakeChromeUserManager*>( - user_manager::UserManager::Get()); - } - - content::BrowserTaskEnvironment task_environment_; - TestObserver test_observer_; - user_manager::ScopedUserManager user_manager_enabler_; - std::unique_ptr<TestingProfile> testing_profile_; - std::unique_ptr<ArcDataSnapshotdDelegate> delegate_; - std::unique_ptr<arc::ArcSessionManager> arc_session_manager_; -}; - -// Tests ARC was stopped before the request. -TEST_F(ArcDataSnapshotdDelegateTest, BasicArcPreStopped) { - EXPECT_EQ(arc::ArcSessionManager::State::STOPPED, - arc::ArcSessionManager::Get()->state()); - base::RunLoop run_loop; - delegate()->RequestStopArcInstance( - base::BindLambdaForTesting([&run_loop](bool success) { - EXPECT_FALSE(success); - run_loop.Quit(); - })); - run_loop.Run(); -} - -// Tests ARC is running and then stopped scenario. -TEST_F(ArcDataSnapshotdDelegateTest, BasicArcActive) { - EnableArc(); - EXPECT_EQ(arc::ArcSessionManager::State::ACTIVE, - arc::ArcSessionManager::Get()->state()); - - base::RunLoop run_loop; - ExpectArcStopped(run_loop.QuitClosure()); - delegate()->RequestStopArcInstance( - base::BindLambdaForTesting([](bool success) { EXPECT_TRUE(success); })); - run_loop.Run(); -} - -// Tests ARC is running and RequestStopArcInstance is called twice before ARC is -// stopped. -// RequestDisable() is a sync way of stopping ARC, need to interfere from -// test_observer and re-enable ARC to fake this scenario. -TEST_F(ArcDataSnapshotdDelegateTest, DoubleArcStop) { - EnableArc(); - EXPECT_EQ(arc::ArcSessionManager::State::ACTIVE, - arc::ArcSessionManager::Get()->state()); - - base::RunLoop run_loop; - // Expect ARC to be stopped for the first time. - ExpectArcStopped(base::BindLambdaForTesting([&]() { - // Request ARC to be stopped for the second time. - delegate()->RequestStopArcInstance( - base::BindLambdaForTesting([&run_loop](bool success) { - // ARC is requested to be stopped for the second time. It is - // an incorrect scenario, both callbacks return failures. - EXPECT_FALSE(success); - run_loop.Quit(); - })); - })); - // Request ARC to be stooped the first time. - delegate()->RequestStopArcInstance( - base::BindLambdaForTesting([](bool success) { - // ARC is requested to be stopped twice. It is an incorrect scenario, - // both callbacks return failures. - EXPECT_FALSE(success); - })); - run_loop.Run(); -} - -} // namespace data_snapshotd -} // namespace arc
diff --git a/chrome/browser/ash/arc/enterprise/arc_force_installed_apps_tracker.cc b/chrome/browser/ash/arc/enterprise/arc_force_installed_apps_tracker.cc deleted file mode 100644 index 72254a6..0000000 --- a/chrome/browser/ash/arc/enterprise/arc_force_installed_apps_tracker.cc +++ /dev/null
@@ -1,354 +0,0 @@ -// Copyright 2020 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/ash/arc/enterprise/arc_force_installed_apps_tracker.h" - -#include <algorithm> -#include <vector> - -#include "base/containers/flat_map.h" -#include "base/functional/bind.h" -#include "base/json/json_reader.h" -#include "base/memory/weak_ptr.h" -#include "base/task/sequenced_task_runner.h" -#include "base/values.h" -#include "chrome/browser/ash/app_list/arc/arc_app_list_prefs.h" -#include "chrome/browser/ash/arc/policy/arc_policy_bridge.h" -#include "chrome/browser/ash/arc/policy/arc_policy_util.h" -#include "chrome/browser/ash/arc/session/arc_session_manager.h" -#include "chrome/browser/policy/profile_policy_connector.h" -#include "components/policy/core/common/policy_map.h" -#include "components/policy/core/common/policy_namespace.h" -#include "components/policy/core/common/policy_service.h" -#include "components/policy/policy_constants.h" - -namespace arc { -namespace data_snapshotd { - -namespace { - -// Gets the profile from ArcSessionManager. -Profile* GetProfile() { - auto* session_manager = ArcSessionManager::Get(); - DCHECK(session_manager); - return session_manager->profile(); -} - -} // namespace - -// This class starts observing force-installed/required ARC apps installation -// steps on creation and stops on destruction. -// It notifies back the caller via passed |update_callback| if the number of -// installed observing apps changes. -class ArcForceInstalledAppsObserver : public ArcAppListPrefs::Observer, - public policy::PolicyService::Observer { - public: - ArcForceInstalledAppsObserver( - ArcAppListPrefs* prefs, - policy::PolicyService* policy_service, - base::RepeatingCallback<void(int)> update_callback); - ArcForceInstalledAppsObserver(const ArcForceInstalledAppsObserver&) = delete; - ArcForceInstalledAppsObserver& operator=( - const ArcForceInstalledAppsObserver&) = delete; - ~ArcForceInstalledAppsObserver() override; - - // ArcAppListPrefs::Observer overrides: - void OnPackageInstalled( - const arc::mojom::ArcPackageInfo& package_info) override; - void OnPackageRemoved(const std::string& package_name, - bool uninstalled) override; - - // PolicyService::Observer overrides. - void OnPolicyUpdated(const policy::PolicyNamespace& ns, - const policy::PolicyMap& previous, - const policy::PolicyMap& current) override; - - private: - // Update the list of installed packages if the list of tracking packages is - // changed. - void UpdateInstalledPackages(); - - // Returns a [0..100] number - the percentage of installed packages among - // tracking packages. - // If there are no tracking packages, returns 100%, since no packages are - // awaited to be installed. - int CalculateInstallationProgress(); - - // Not owned singleton. Initialized in ctor. - ArcAppListPrefs* prefs_ = nullptr; - // Not owned singleton. Initialized in ctor. - policy::PolicyService* policy_service_ = nullptr; - // This callback is invoked when the number of installed tracking packages is - // changed. The floored percentage of installed tracking packages is passed to - // the callback. - base::RepeatingCallback<void(int)> update_callback_; - - // Maps tracking package names into whether the package is installed. - base::flat_map<std::string, bool> tracking_packages_; - // Number of installed packages among tracking packages. - int installed_packages_num_ = 0; -}; - -class PolicyComplianceObserver : public arc::ArcPolicyBridge::Observer { - public: - PolicyComplianceObserver(arc::ArcPolicyBridge* arc_policy_bridge, - base::OnceClosure finish_callback); - PolicyComplianceObserver& operator=(const PolicyComplianceObserver&) = delete; - PolicyComplianceObserver(const PolicyComplianceObserver&) = delete; - - ~PolicyComplianceObserver() override; - - // arc::ArcPolicyBridge::Observer override: - void OnComplianceReportReceived( - const base::Value* compliance_report) override; - - private: - // Parses initial compliance report JSON. - void ProcessInitialComplianceReport(std::string last_report); - - // Not owned singleton. Initialized in ctor. - arc::ArcPolicyBridge* arc_policy_bridge_ = nullptr; - - // This callback is invoked once ARC is compliant with ARC policy. - base::OnceClosure finish_callback_; - - base::WeakPtrFactory<PolicyComplianceObserver> weak_ptr_factory_{this}; -}; - -ArcForceInstalledAppsObserver::ArcForceInstalledAppsObserver( - ArcAppListPrefs* prefs, - policy::PolicyService* policy_service, - base::RepeatingCallback<void(int)> update_callback) - : prefs_(prefs), - policy_service_(policy_service), - update_callback_(std::move(update_callback)) { - DCHECK(prefs_); - DCHECK(policy_service_); - prefs_->AddObserver(this); - policy_service_->AddObserver(policy::POLICY_DOMAIN_CHROME, this); - // Initialize the tracking and installed packages lists. - const policy::PolicyNamespace policy_namespace(policy::POLICY_DOMAIN_CHROME, - std::string()); - OnPolicyUpdated(policy_namespace, policy::PolicyMap(), - policy_service_->GetPolicies(policy_namespace)); -} - -ArcForceInstalledAppsObserver::~ArcForceInstalledAppsObserver() { - prefs_->RemoveObserver(this); - policy_service_->RemoveObserver(policy::POLICY_DOMAIN_CHROME, this); -} - -void ArcForceInstalledAppsObserver::OnPackageInstalled( - const arc::mojom::ArcPackageInfo& package_info) { - auto iter = tracking_packages_.find(package_info.package_name); - if (iter == tracking_packages_.end()) { - // Installed non-required/force-installed ARC system package. - VLOG(1) << "Installed not tracking package " << package_info.package_name; - return; - } - bool& installed = iter->second; - if (!installed) { - // If installed package is among tracking packages and not yet installed, - // mark it as installed. - installed = true; - installed_packages_num_++; - update_callback_.Run(CalculateInstallationProgress()); - } -} - -void ArcForceInstalledAppsObserver::OnPackageRemoved( - const std::string& package_name, - bool uninstalled) { - auto iter = tracking_packages_.find(package_name); - if (uninstalled && iter != tracking_packages_.end() && iter->second) { - // If an installed package is removed, proceed. - iter->second = false; - installed_packages_num_--; - update_callback_.Run(CalculateInstallationProgress()); - } -} - -void ArcForceInstalledAppsObserver::OnPolicyUpdated( - const policy::PolicyNamespace& ns, - const policy::PolicyMap& previous, - const policy::PolicyMap& current) { - if (ns.domain != policy::POLICY_DOMAIN_CHROME) - return; - const base::Value* const arc_policy = - current.GetValue(policy::key::kArcPolicy, base::Value::Type::STRING); - tracking_packages_.clear(); - - // Track packages only if ArcPolicy is set. - if (arc_policy) { - // Get the required packages from ArcPolicy. - auto required_packages = - arc::policy_util::GetRequestedPackagesFromArcPolicy( - arc_policy->GetString()); - // Mark all required packages not yet installed in |tracking_packages_|. - tracking_packages_ = base::MakeFlatMap<std::string, bool>( - required_packages, {}, - [](const std::string& v) { return std::make_pair(v, false); }); - } - UpdateInstalledPackages(); -} - -void ArcForceInstalledAppsObserver::UpdateInstalledPackages() { - DCHECK(prefs_); - installed_packages_num_ = 0; - auto all_installed_packages = prefs_->GetPackagesFromPrefs(); - for (const auto& package_name : all_installed_packages) { - auto package = tracking_packages_.find(package_name); - if (package != tracking_packages_.end() && !package->second) { - // If tracking this package, mark it as installed. - package->second = true; - installed_packages_num_++; - } - } - if (!update_callback_.is_null()) - update_callback_.Run(CalculateInstallationProgress()); -} - -int ArcForceInstalledAppsObserver::CalculateInstallationProgress() { - return tracking_packages_.empty() - ? 100 - : installed_packages_num_ * 100 / tracking_packages_.size(); -} - -PolicyComplianceObserver::PolicyComplianceObserver( - arc::ArcPolicyBridge* arc_policy_bridge, - base::OnceClosure finish_callback) - : arc_policy_bridge_(arc_policy_bridge), - finish_callback_(std::move(finish_callback)) { - DCHECK(arc_policy_bridge); - arc_policy_bridge_->AddObserver(this); - - // Check last compliance report. - auto last_report = arc_policy_bridge->get_arc_policy_compliance_report(); - if (last_report.empty()) - return; - base::SequencedTaskRunner::GetCurrentDefault()->PostTask( - FROM_HERE, - base::BindOnce(&PolicyComplianceObserver::ProcessInitialComplianceReport, - weak_ptr_factory_.GetWeakPtr(), std::move(last_report))); -} - -PolicyComplianceObserver::~PolicyComplianceObserver() { - arc_policy_bridge_->RemoveObserver(this); -} - -void PolicyComplianceObserver::OnComplianceReportReceived( - const base::Value* compliance_report) { - const base::Value::List* const details = - compliance_report->GetDict().FindList("nonComplianceDetails"); - if (!details) { - // ARC policy compliant. - if (!finish_callback_.is_null()) - std::move(finish_callback_).Run(); - return; - } - - bool is_android_id_reset = true; - for (const auto& detail : *details) { - const base::Value::Dict& detail_dict = detail.GetDict(); - absl::optional<int> reason = detail_dict.FindInt("nonComplianceReason"); - const std::string* const setting_name = - detail_dict.FindString("settingName"); - if (!reason || !setting_name) { - continue; - } - // Not compliant with ARC applications policy. - if (*setting_name == policy_util::kArcPolicyKeyApplications) { - return; - } - // android_id is expected to be reset, but still not reset by clouddpc. - if (*setting_name == ArcPolicyBridge::kResetAndroidIdEnabled) { - is_android_id_reset = false; - continue; - } - } - // If compliant with ARC applications policy, android ID is expected to be - // reset shortly. - // Force a compliance report. - if (!is_android_id_reset) { - arc_policy_bridge_->OnPolicyUpdated( - policy::PolicyNamespace(), policy::PolicyMap(), policy::PolicyMap()); - return; - } - if (!finish_callback_.is_null()) - std::move(finish_callback_).Run(); -} - -void PolicyComplianceObserver::ProcessInitialComplianceReport( - std::string last_report) { - absl::optional<base::Value> last_report_value = - base::JSONReader::Read(last_report); - if (!last_report_value.has_value()) - return; - OnComplianceReportReceived(&last_report_value.value()); -} - -ArcForceInstalledAppsTracker::ArcForceInstalledAppsTracker() = default; - -ArcForceInstalledAppsTracker::~ArcForceInstalledAppsTracker() = default; - -// static -std::unique_ptr<ArcForceInstalledAppsTracker> -ArcForceInstalledAppsTracker::CreateForTesting( - ArcAppListPrefs* prefs, - policy::PolicyService* policy_service, - arc::ArcPolicyBridge* arc_policy_bridge) { - return base::WrapUnique(new ArcForceInstalledAppsTracker( - prefs, policy_service, arc_policy_bridge)); -} - -void ArcForceInstalledAppsTracker::StartTracking( - base::RepeatingCallback<void(int)> update_callback, - base::OnceClosure finish_callback) { - DCHECK(!apps_observer_); - DCHECK(!policy_compliance_observer_); - - Initialize(); - apps_observer_ = std::make_unique<ArcForceInstalledAppsObserver>( - prefs_, policy_service_, std::move(update_callback)); - policy_compliance_observer_ = std::make_unique<PolicyComplianceObserver>( - arc_policy_bridge_, - base::BindOnce(&ArcForceInstalledAppsTracker::OnTrackingFinished, - weak_ptr_factory_.GetWeakPtr(), - std::move(finish_callback))); -} - -ArcForceInstalledAppsTracker::ArcForceInstalledAppsTracker( - ArcAppListPrefs* prefs, - policy::PolicyService* policy_service, - arc::ArcPolicyBridge* arc_policy_bridge) - : prefs_(prefs), - policy_service_(policy_service), - arc_policy_bridge_(arc_policy_bridge) {} - -void ArcForceInstalledAppsTracker::Initialize() { - if (prefs_ && policy_service_ && arc_policy_bridge_) - return; - auto* profile = GetProfile(); - DCHECK(profile); - - prefs_ = ArcAppListPrefs::Get(profile); - - auto* profile_policy_connector = profile->GetProfilePolicyConnector(); - DCHECK(profile_policy_connector); - - policy_service_ = profile_policy_connector->policy_service(); - - arc_policy_bridge_ = arc::ArcPolicyBridge::GetForBrowserContext(profile); -} - -void ArcForceInstalledAppsTracker::OnTrackingFinished( - base::OnceClosure finish_callback) { - apps_observer_.reset(); - policy_compliance_observer_.reset(); - - std::move(finish_callback).Run(); -} - -} // namespace data_snapshotd -} // namespace arc
diff --git a/chrome/browser/ash/arc/enterprise/arc_force_installed_apps_tracker.h b/chrome/browser/ash/arc/enterprise/arc_force_installed_apps_tracker.h deleted file mode 100644 index 550f04b8..0000000 --- a/chrome/browser/ash/arc/enterprise/arc_force_installed_apps_tracker.h +++ /dev/null
@@ -1,78 +0,0 @@ -// Copyright 2020 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_ASH_ARC_ENTERPRISE_ARC_FORCE_INSTALLED_APPS_TRACKER_H_ -#define CHROME_BROWSER_ASH_ARC_ENTERPRISE_ARC_FORCE_INSTALLED_APPS_TRACKER_H_ - -#include <memory> - -#include "ash/components/arc/enterprise/arc_apps_tracker.h" -#include "base/functional/callback.h" -#include "base/memory/weak_ptr.h" - -class ArcAppListPrefs; - -namespace policy { - -class PolicyService; - -} // namespace policy - -namespace arc { - -class ArcPolicyBridge; - -namespace data_snapshotd { - -class ArcForceInstalledAppsObserver; -class PolicyComplianceObserver; - -// This class tracks ARC apps that are required to be installed by ArcPolicy. -class ArcForceInstalledAppsTracker : public ArcAppsTracker { - public: - ArcForceInstalledAppsTracker(); - ArcForceInstalledAppsTracker(const ArcForceInstalledAppsTracker&) = delete; - ArcForceInstalledAppsTracker& operator=(const ArcForceInstalledAppsTracker&) = - delete; - ~ArcForceInstalledAppsTracker() override; - - // Creates instance for testing. - static std::unique_ptr<ArcForceInstalledAppsTracker> CreateForTesting( - ArcAppListPrefs* prefs, - policy::PolicyService* policy_service, - arc::ArcPolicyBridge* arc_policy_bridge); - - // ArcAppsTracker overrides: - void StartTracking(base::RepeatingCallback<void(int)> update_callback, - base::OnceClosure finish_callback) override; - - private: - ArcForceInstalledAppsTracker(ArcAppListPrefs* prefs, - policy::PolicyService* policy_service, - arc::ArcPolicyBridge* arc_policy_bridge); - - // Helper method to initialize |prefs_| and |policy_service_|. - void Initialize(); - - // Helper method to be invoked once ARC is policy compliant. - void OnTrackingFinished(base::OnceClosure finish_callback); - - // Not owned singleton. Initialized in StartTracking. - ArcAppListPrefs* prefs_ = nullptr; - // Not owned singleton. Initialized in StartTracking. - policy::PolicyService* policy_service_ = nullptr; - // Not owned singleton. Initialized in StartTracking. - arc::ArcPolicyBridge* arc_policy_bridge_ = nullptr; - - // Created in StartTracking, destroyed in OnTrackingFinished or dtor. - std::unique_ptr<ArcForceInstalledAppsObserver> apps_observer_; - std::unique_ptr<PolicyComplianceObserver> policy_compliance_observer_; - - base::WeakPtrFactory<ArcForceInstalledAppsTracker> weak_ptr_factory_{this}; -}; - -} // namespace data_snapshotd -} // namespace arc - -#endif // CHROME_BROWSER_ASH_ARC_ENTERPRISE_ARC_FORCE_INSTALLED_APPS_TRACKER_H_
diff --git a/chrome/browser/ash/arc/enterprise/arc_force_installed_apps_tracker_unittest.cc b/chrome/browser/ash/arc/enterprise/arc_force_installed_apps_tracker_unittest.cc deleted file mode 100644 index 7e55393..0000000 --- a/chrome/browser/ash/arc/enterprise/arc_force_installed_apps_tracker_unittest.cc +++ /dev/null
@@ -1,346 +0,0 @@ -// Copyright 2020 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/ash/arc/enterprise/arc_force_installed_apps_tracker.h" - -#include <string> - -#include "ash/components/arc/session/arc_bridge_service.h" -#include "base/barrier_closure.h" -#include "base/functional/callback_helpers.h" -#include "base/run_loop.h" -#include "base/test/bind.h" -#include "chrome/browser/ash/app_list/arc/arc_app_list_prefs.h" -#include "chrome/browser/ash/app_list/arc/arc_app_test.h" -#include "chrome/browser/ash/arc/policy/arc_policy_bridge.h" -#include "chrome/test/base/testing_profile.h" -#include "components/policy/core/common/mock_policy_service.h" -#include "components/policy/core/common/policy_map.h" -#include "components/policy/core/common/policy_service.h" -#include "components/policy/policy_constants.h" -#include "content/public/test/browser_task_environment.h" -#include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h" -#include "testing/gtest/include/gtest/gtest.h" - -using testing::_; -using testing::ReturnRef; - -namespace arc { -namespace data_snapshotd { - -namespace { - -constexpr char kBasicPackageName[] = "basic.package"; -constexpr char kBasicPackageName2[] = "basic.package.2"; -constexpr char kFakePackageName[] = "fake.package"; -constexpr char kArcPolicyValue[] = - "{\"applications\":" - "[{\"packageName\":\"basic.package\"," - "\"installType\":\"FORCE_INSTALLED\"," - "}]}"; -constexpr char kArcPolicyValue2[] = - "{\"applications\":" - "[{\"packageName\":\"basic.package\"," - "\"installType\":\"FORCE_INSTALLED\"," - "}," - "{\"packageName\":\"basic.package.2\"," - "\"installType\":\"REQUIRED\"," - "}]}"; - -constexpr char kComplianceReportEmptyJson[] = "{}"; -constexpr char kComplianceReportNonCompliantJson[] = - "{\"nonComplianceDetails\":" - "[{\"settingName\":\"applications\",\"nonComplianceReason\":1}]}"; -constexpr char kComplianceReportCompliantJson[] = - "{\"nonComplianceDetails\":" - "[{\"settingName\":\"value\",\"nonComplianceReason\":\"value\"}]}"; -constexpr char kComplianceReportAndroidIdNonCompliantJson[] = - "{\"nonComplianceDetails\":" - "[{\"settingName\":\"resetAndroidIdEnabled\"," - "\"nonComplianceReason\":1}]}"; -} // namespace - -class ArcForceInstalledAppsTrackerTest : public testing::Test { - public: - ArcForceInstalledAppsTrackerTest() = default; - ArcForceInstalledAppsTrackerTest(const ArcForceInstalledAppsTrackerTest&) = - delete; - ArcForceInstalledAppsTrackerTest& operator=( - const ArcForceInstalledAppsTrackerTest&) = delete; - - void SetUp() override { - profile_ = std::make_unique<TestingProfile>(); - - arc_app_test_.SetUp(profile_.get()); - policy_bridge_ = - std::make_unique<arc::ArcPolicyBridge>(profile_.get(), &arc_bridge_); - tracker_ = ArcForceInstalledAppsTracker::CreateForTesting( - prefs(), policy_service(), policy_bridge_.get()); - } - - void TearDown() override { - tracker_.reset(); - policy_bridge_.reset(); - arc_app_test_.TearDown(); - profile_.reset(); - policy_map_.Clear(); - } - - void InstallPackage(const std::string& package_name) { - auto package_info = mojom::ArcPackageInfo::New(); - package_info->package_name = package_name; - app_host()->OnPackageAdded(std::move(package_info)); - } - - void UninstallPackage(const std::string package_name) { - app_host()->OnPackageRemoved(package_name); - } - - void SetArcPolicyValue(const std::string& arc_policy_value) { - policy_map().Set(policy::key::kArcPolicy, policy::POLICY_LEVEL_MANDATORY, - policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD, - base::Value(arc_policy_value), nullptr); - } - - void ReportCompliant() { ReportCompliance(kComplianceReportCompliantJson); } - void ReportCompliantEmpty() { ReportCompliance(kComplianceReportEmptyJson); } - - void ReportNonCompliant() { - ReportCompliance(kComplianceReportNonCompliantJson); - } - - void ReportAndroidIdNonCompliant() { - ReportCompliance(kComplianceReportAndroidIdNonCompliantJson); - } - - policy::PolicyMap& policy_map() { return policy_map_; } - policy::MockPolicyService* policy_service() { return &policy_service_; } - arc::ArcPolicyBridge* arc_policy_bridge() { return policy_bridge_.get(); } - ArcForceInstalledAppsTracker* tracker() { return tracker_.get(); } - - private: - void ReportCompliance(const std::string& compliance_json) { - base::RunLoop run_loop; - arc_policy_bridge()->ReportCompliance( - compliance_json, - base::BindLambdaForTesting( - [&run_loop](const std::string& response) { run_loop.Quit(); })); - run_loop.Run(); - } - - ArcAppListPrefs* prefs() { return arc_app_test_.arc_app_list_prefs(); } - arc::mojom::AppHost* app_host() { return prefs(); } - - content::BrowserTaskEnvironment task_environment_; - data_decoder::test::InProcessDataDecoder in_process_data_decoder_; - std::unique_ptr<TestingProfile> profile_; - ArcAppTest arc_app_test_; - policy::MockPolicyService policy_service_; - arc::ArcBridgeService arc_bridge_; - std::unique_ptr<arc::ArcPolicyBridge> policy_bridge_; - std::unique_ptr<ArcForceInstalledAppsTracker> tracker_; - policy::PolicyMap policy_map_; -}; - -TEST_F(ArcForceInstalledAppsTrackerTest, InvalidCallbacks) { - EXPECT_CALL(*policy_service(), AddObserver(_, _)); - EXPECT_CALL(*policy_service(), GetPolicies(_)) - .WillOnce(ReturnRef(policy_map())); - tracker()->StartTracking(base::NullCallback(), base::NullCallback()); - - EXPECT_CALL(*policy_service(), RemoveObserver(_, _)); -} - -TEST_F(ArcForceInstalledAppsTrackerTest, EmptyPolicy) { - EXPECT_CALL(*policy_service(), AddObserver(_, _)); - EXPECT_CALL(*policy_service(), GetPolicies(_)) - .WillOnce(ReturnRef(policy_map())); - bool is_policy_compliant = false; - base::RunLoop run_loop; - tracker()->StartTracking(base::BindLambdaForTesting([&run_loop](int percent) { - // All tracking apps are installed. - EXPECT_EQ(100, percent); - run_loop.Quit(); - }), - base::BindLambdaForTesting([&is_policy_compliant]() { - is_policy_compliant = true; - })); - run_loop.Run(); - - EXPECT_FALSE(is_policy_compliant); - - EXPECT_CALL(*policy_service(), RemoveObserver(_, _)); - ReportCompliantEmpty(); - EXPECT_TRUE(is_policy_compliant); -} - -TEST_F(ArcForceInstalledAppsTrackerTest, Basic) { - SetArcPolicyValue(kArcPolicyValue2); - EXPECT_CALL(*policy_service(), AddObserver(_, _)); - EXPECT_CALL(*policy_service(), GetPolicies(_)) - .WillOnce(ReturnRef(policy_map())); - base::RunLoop run_loop; - base::RepeatingClosure closure = - base::BarrierClosure(3, run_loop.QuitClosure()); - int package_number = 0; - tracker()->StartTracking( - base::BindLambdaForTesting([&closure, &package_number](int percent) { - EXPECT_EQ(package_number * 50, percent); - package_number++; - closure.Run(); - }), - base::DoNothing()); - - // Install not required package. - InstallPackage(kFakePackageName); - // Install 2 required packages. - InstallPackage(kBasicPackageName); - InstallPackage(kBasicPackageName2); - - run_loop.Run(); - - EXPECT_CALL(*policy_service(), RemoveObserver(_, _)); -} - -TEST_F(ArcForceInstalledAppsTrackerTest, AlreadyInstalledPackages) { - InstallPackage(kBasicPackageName); - - SetArcPolicyValue(kArcPolicyValue2); - EXPECT_CALL(*policy_service(), AddObserver(_, _)); - EXPECT_CALL(*policy_service(), GetPolicies(_)) - .WillOnce(ReturnRef(policy_map())); - - base::RunLoop run_loop; - base::RepeatingClosure closure = - base::BarrierClosure(2, run_loop.QuitClosure()); - int package_number = 1; - tracker()->StartTracking( - base::BindLambdaForTesting([&closure, &package_number](int percent) { - EXPECT_EQ(package_number * 50, percent); - package_number++; - closure.Run(); - }), - base::DoNothing()); - - InstallPackage(kBasicPackageName2); - - run_loop.Run(); - - EXPECT_CALL(*policy_service(), RemoveObserver(_, _)); -} - -// Tests the case when tracking packages list changes. -TEST_F(ArcForceInstalledAppsTrackerTest, OnPolicyUpdated) { - SetArcPolicyValue(kArcPolicyValue2); - policy::PolicyService::Observer* observer = nullptr; - EXPECT_CALL(*policy_service(), AddObserver(_, _)) - .WillOnce(testing::SaveArg<1>(&observer)); - EXPECT_CALL(*policy_service(), GetPolicies(_)) - .WillRepeatedly(ReturnRef(policy_map())); - base::RunLoop run_loop; - base::RepeatingClosure closure = - base::BarrierClosure(4, run_loop.QuitClosure()); - int package_number = 0; - int max_package_number = 2; - tracker()->StartTracking( - base::BindLambdaForTesting( - [&closure, &package_number, &max_package_number](int percent) { - EXPECT_EQ(package_number * 100 / max_package_number, percent); - package_number++; - closure.Run(); - }), - base::DoNothing()); - - InstallPackage(kBasicPackageName2); - - SetArcPolicyValue(kArcPolicyValue); - package_number = 0; - max_package_number = 1; - EXPECT_TRUE(observer); - - const policy::PolicyNamespace policy_namespace(policy::POLICY_DOMAIN_CHROME, - std::string()); - observer->OnPolicyUpdated(policy_namespace, policy::PolicyMap(), - policy_service()->GetPolicies(policy_namespace)); - - InstallPackage(kBasicPackageName); - - run_loop.Run(); - - EXPECT_CALL(*policy_service(), RemoveObserver(_, _)); -} - -// Tests the uninstall tracking package scenario. -TEST_F(ArcForceInstalledAppsTrackerTest, UninstalledPackages) { - SetArcPolicyValue(kArcPolicyValue); - EXPECT_CALL(*policy_service(), AddObserver(_, _)); - EXPECT_CALL(*policy_service(), GetPolicies(_)) - .WillOnce(ReturnRef(policy_map())); - base::RunLoop run_loop; - base::RepeatingClosure closure = - base::BarrierClosure(4, run_loop.QuitClosure()); - int package_number = 0; - tracker()->StartTracking( - base::BindLambdaForTesting([&closure, &package_number](int percent) { - EXPECT_EQ(package_number * 100, percent); - package_number++; - closure.Run(); - }), - base::DoNothing()); - - InstallPackage(kBasicPackageName); - package_number = 0; - UninstallPackage(kBasicPackageName); - package_number = 1; - InstallPackage(kBasicPackageName); - run_loop.Run(); - - EXPECT_CALL(*policy_service(), RemoveObserver(_, _)); -} - -TEST_F(ArcForceInstalledAppsTrackerTest, PolicyCompliance) { - EXPECT_CALL(*policy_service(), AddObserver(_, _)); - EXPECT_CALL(*policy_service(), GetPolicies(_)) - .WillOnce(ReturnRef(policy_map())); - bool is_policy_compliant = false; - tracker()->StartTracking(base::DoNothing(), - base::BindLambdaForTesting([&is_policy_compliant]() { - is_policy_compliant = true; - })); - - EXPECT_FALSE(is_policy_compliant); - - ReportNonCompliant(); - EXPECT_FALSE(is_policy_compliant); - - ReportAndroidIdNonCompliant(); - EXPECT_FALSE(is_policy_compliant); - - EXPECT_CALL(*policy_service(), RemoveObserver(_, _)); - ReportCompliant(); - EXPECT_TRUE(is_policy_compliant); - - // Report compliance second time. Ignore. - is_policy_compliant = false; - ReportCompliant(); - EXPECT_FALSE(is_policy_compliant); -} - -TEST_F(ArcForceInstalledAppsTrackerTest, PolicyCompliantOnStart) { - ReportCompliant(); - - EXPECT_CALL(*policy_service(), AddObserver(_, _)); - EXPECT_CALL(*policy_service(), GetPolicies(_)) - .WillOnce(ReturnRef(policy_map())); - EXPECT_CALL(*policy_service(), RemoveObserver(_, _)); - base::RunLoop run_loop; - tracker()->StartTracking( - base::DoNothing(), - base::BindLambdaForTesting([&run_loop]() { run_loop.Quit(); })); - - run_loop.Run(); -} - -} // namespace data_snapshotd -} // namespace arc
diff --git a/chrome/browser/ash/arc/policy/arc_policy_bridge.cc b/chrome/browser/ash/arc/policy/arc_policy_bridge.cc index 65602fa..34f339b 100644 --- a/chrome/browser/ash/arc/policy/arc_policy_bridge.cc +++ b/chrome/browser/ash/arc/policy/arc_policy_bridge.cc
@@ -467,9 +467,6 @@ const char ArcPolicyBridge::kManagedConfiguration[] = "managedConfiguration"; // static -const char ArcPolicyBridge::kResetAndroidIdEnabled[] = "resetAndroidIdEnabled"; - -// static ArcPolicyBridge* ArcPolicyBridge::GetForBrowserContext( content::BrowserContext* context) { return ArcPolicyBridgeFactory::GetForBrowserContext(context);
diff --git a/chrome/browser/ash/arc/policy/arc_policy_bridge.h b/chrome/browser/ash/arc/policy/arc_policy_bridge.h index 25862ca..df8d3ed 100644 --- a/chrome/browser/ash/arc/policy/arc_policy_bridge.h +++ b/chrome/browser/ash/arc/policy/arc_policy_bridge.h
@@ -110,7 +110,6 @@ static const char kApplications[]; static const char kPackageName[]; static const char kManagedConfiguration[]; - static const char kResetAndroidIdEnabled[]; // Returns singleton instance for the given BrowserContext, // or nullptr if the browser |context| is not allowed to use ARC.
diff --git a/chrome/browser/ash/arc/tracing/arc_app_performance_tracing.cc b/chrome/browser/ash/arc/tracing/arc_app_performance_tracing.cc index 2e8d5c2..1f6f6e7 100644 --- a/chrome/browser/ash/arc/tracing/arc_app_performance_tracing.cc +++ b/chrome/browser/ash/arc/tracing/arc_app_performance_tracing.cc
@@ -210,15 +210,22 @@ DetachActiveWindow(); // Ignore any non-ARC++ window. - if (arc::GetWindowTaskId(gained_active) <= 0) + const auto maybe_task_id = arc::GetWindowTaskId(gained_active); + if (!maybe_task_id.has_value()) { return; + } // Ghost window is not an actual app window. if (gained_active->GetProperty(ash::full_restore::kArcGhostSurface)) return; + exo::Surface* const surface = exo::GetShellRootSurface(gained_active); + if (!surface) { + return; + } + // Observe active ARC++ window. - AttachActiveWindow(gained_active); + AttachActiveWindow(gained_active, surface); StartJankinessTracing(); @@ -459,14 +466,13 @@ session_.reset(); } -void ArcAppPerformanceTracing::AttachActiveWindow(aura::Window* window) { +void ArcAppPerformanceTracing::AttachActiveWindow(aura::Window* window, + exo::Surface* surface) { DCHECK(window); DCHECK(!arc_active_window_); arc_active_window_ = window; arc_active_window_->AddObserver(this); - exo::Surface* const surface = exo::GetShellRootSurface(window); - DCHECK(surface); // Use scoped surface observer to be safe on the surface // destruction. |exo::GetShellRootSurface| would fail in case // the surface gets destroyed before widget.
diff --git a/chrome/browser/ash/arc/tracing/arc_app_performance_tracing.h b/chrome/browser/ash/arc/tracing/arc_app_performance_tracing.h index 86cc795..c8c72c2 100644 --- a/chrome/browser/ash/arc/tracing/arc_app_performance_tracing.h +++ b/chrome/browser/ash/arc/tracing/arc_app_performance_tracing.h
@@ -137,7 +137,7 @@ void MaybeStopTracing(); // Attaches observer to the |window| and stores at as |arc_active_window_|. - void AttachActiveWindow(aura::Window* window); + void AttachActiveWindow(aura::Window* window, exo::Surface* surface); // Detaches observer from |arc_active_window_| and resets // |arc_active_window_|.
diff --git a/chrome/browser/ash/arc/tracing/arc_app_performance_tracing_unittest.cc b/chrome/browser/ash/arc/tracing/arc_app_performance_tracing_unittest.cc index a937c01..203981cd 100644 --- a/chrome/browser/ash/arc/tracing/arc_app_performance_tracing_unittest.cc +++ b/chrome/browser/ash/arc/tracing/arc_app_performance_tracing_unittest.cc
@@ -315,9 +315,18 @@ views::Widget* const arc_widget = StartArcFocusAppTracing(); ASSERT_TRUE(tracing_helper().GetTracingSession()); EXPECT_TRUE(tracing_helper().GetTracingSession()->tracing_active()); + exo::SetShellRootSurface(arc_widget->GetNativeWindow(), nullptr); ResetRootSurface(); ASSERT_TRUE(tracing_helper().GetTracingSession()); EXPECT_FALSE(tracing_helper().GetTracingSession()->tracing_active()); + + // Try to re-active window without surface + tracing_helper().GetTracing()->OnWindowActivated( + wm::ActivationChangeObserver::ActivationReason::ACTIVATION_CLIENT, + arc_widget->GetNativeWindow(), arc_widget->GetNativeWindow()); + + EXPECT_FALSE(tracing_helper().GetTracingSession()); + arc_widget->Close(); }
diff --git a/chrome/browser/ash/chrome_browser_main_parts_ash.cc b/chrome/browser/ash/chrome_browser_main_parts_ash.cc index 415b3c9..e001074 100644 --- a/chrome/browser/ash/chrome_browser_main_parts_ash.cc +++ b/chrome/browser/ash/chrome_browser_main_parts_ash.cc
@@ -260,7 +260,7 @@ #include "dbus/object_path.h" #include "device/bluetooth/bluetooth_adapter_factory.h" #include "net/base/network_change_notifier.h" -#include "net/base/network_change_notifier_posix.h" +#include "net/base/network_change_notifier_passive.h" #include "printing/backend/print_backend.h" #include "rlz/buildflags/buildflags.h" #include "services/audio/public/cpp/sounds/sounds_manager.h" @@ -741,7 +741,7 @@ // about_flags settings are applied in ChromeBrowserMainParts::PreCreateThreads. int ChromeBrowserMainPartsAsh::PreMainMessageLoopRun() { network_change_manager_client_ = std::make_unique<NetworkChangeManagerClient>( - static_cast<net::NetworkChangeNotifierPosix*>( + static_cast<net::NetworkChangeNotifierPassive*>( content::GetNetworkChangeNotifier())); // Set the crypto thread after the IO thread has been created/started.
diff --git a/chrome/browser/ash/crosapi/crosapi_ash.cc b/chrome/browser/ash/crosapi/crosapi_ash.cc index b874a6ce..7f746f39 100644 --- a/chrome/browser/ash/crosapi/crosapi_ash.cc +++ b/chrome/browser/ash/crosapi/crosapi_ash.cc
@@ -771,13 +771,11 @@ void CrosapiAsh::BindStableVideoDecoderFactory( mojo::GenericPendingReceiver receiver) { #if BUILDFLAG(USE_VAAPI) || BUILDFLAG(USE_V4L2_CODEC) - // TODO(b/171813538): if launching out-of-process video decoding for LaCrOS - // with Finch, we may need to tell LaCrOS somehow if this feature is enabled - // in ash-chrome. Otherwise, we may run into a situation in which the feature - // is enabled for LaCrOS but not for ash-chrome. auto r = receiver.As<media::stable::mojom::StableVideoDecoderFactory>(); - if (r && base::FeatureList::IsEnabled(media::kUseOutOfProcessVideoDecoding)) + if (r && base::FeatureList::IsEnabled( + media::kExposeOutOfProcessVideoDecodingToLacros)) { content::LaunchStableVideoDecoderFactory(std::move(r)); + } #endif // BUILDFLAG(USE_VAAPI) || BUILDFLAG(USE_V4L2_CODEC) }
diff --git a/chrome/browser/ash/extensions/file_manager/private_api_thumbnail.cc b/chrome/browser/ash/extensions/file_manager/private_api_thumbnail.cc index 5be4ee7..75af55c 100644 --- a/chrome/browser/ash/extensions/file_manager/private_api_thumbnail.cc +++ b/chrome/browser/ash/extensions/file_manager/private_api_thumbnail.cc
@@ -56,7 +56,7 @@ DLOG(WARNING) << "Got an invalid bitmap"; return std::string(); } - sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap); + sk_sp<SkImage> image = SkImages::RasterFromBitmap(bitmap); sk_sp<SkData> png_data(image->encodeToData(SkEncodedImageFormat::kPNG, 100)); if (!png_data) { DLOG(WARNING) << "Thumbnail encoding error";
diff --git a/chrome/browser/ash/login/easy_unlock/smartlock_state_handler.cc b/chrome/browser/ash/login/easy_unlock/smartlock_state_handler.cc index f8c0150..63690fa 100644 --- a/chrome/browser/ash/login/easy_unlock/smartlock_state_handler.cc +++ b/chrome/browser/ash/login/easy_unlock/smartlock_state_handler.cc
@@ -65,10 +65,6 @@ return proximity_auth::ScreenlockBridge::USER_POD_CUSTOM_ICON_NONE; } -bool HardlockOnClick(SmartLockState state) { - return state != SmartLockState::kInactive; -} - size_t GetTooltipResourceId(SmartLockState state) { switch (state) { case SmartLockState::kInactive: @@ -191,9 +187,6 @@ proximity_auth::ScreenlockBridge::UserPodCustomIconInfo icon_info; icon_info.SetIcon(icon); - if (HardlockOnClick(state_)) - icon_info.SetHardlockOnClick(); - UpdateTooltipOptions(&icon_info); // For states without tooltips, we still need to set an accessibility label.
diff --git a/chrome/browser/ash/login/existing_user_controller.cc b/chrome/browser/ash/login/existing_user_controller.cc index d53b607..557db121 100644 --- a/chrome/browser/ash/login/existing_user_controller.cc +++ b/chrome/browser/ash/login/existing_user_controller.cc
@@ -1573,9 +1573,10 @@ user_manager::KnownUser known_user(g_browser_process->local_state()); std::string device_id = known_user.GetDeviceId(user_context.GetAccountId()); if (device_id.empty()) { - bool is_ephemeral = ChromeUserManager::Get()->AreEphemeralUsersEnabled() && - user_context.GetAccountId() != - ChromeUserManager::Get()->GetOwnerAccountId(); + const bool is_ephemeral = ChromeUserManager::Get()->IsEphemeralAccountId( + user_context.GetAccountId()) && + user_context.GetAccountId() != + ChromeUserManager::Get()->GetOwnerAccountId(); device_id = GenerateSigninScopedDeviceId(is_ephemeral); } user_context.SetDeviceId(device_id);
diff --git a/chrome/browser/ash/login/user_board_view_mojo.cc b/chrome/browser/ash/login/user_board_view_mojo.cc index eb023d0..fdd594a 100644 --- a/chrome/browser/ash/login/user_board_view_mojo.cc +++ b/chrome/browser/ash/login/user_board_view_mojo.cc
@@ -56,9 +56,6 @@ if (!user_pod_icon_info.aria_label().empty()) easy_unlock_icon_info.aria_label = user_pod_icon_info.aria_label(); - if (user_pod_icon_info.hardlock_on_click()) - easy_unlock_icon_info.hardlock_on_click = true; - return easy_unlock_icon_info; }
diff --git a/chrome/browser/ash/login/users/chrome_user_manager_impl.cc b/chrome/browser/ash/login/users/chrome_user_manager_impl.cc index 5e78399f..b523730 100644 --- a/chrome/browser/ash/login/users/chrome_user_manager_impl.cc +++ b/chrome/browser/ash/login/users/chrome_user_manager_impl.cc
@@ -52,6 +52,7 @@ #include "chrome/browser/ash/login/users/multi_profile_user_controller.h" #include "chrome/browser/ash/login/users/supervised_user_manager_impl.h" #include "chrome/browser/ash/policy/core/browser_policy_connector_ash.h" +#include "chrome/browser/ash/policy/core/device_local_account.h" #include "chrome/browser/ash/policy/external_data/handlers/crostini_ansible_playbook_external_data_handler.h" #include "chrome/browser/ash/policy/external_data/handlers/preconfigured_desk_templates_external_data_handler.h" #include "chrome/browser/ash/policy/external_data/handlers/print_servers_external_data_handler.h" @@ -254,6 +255,38 @@ << "The user profile was loaded before we mounted the cryptohome."; } +user_manager::UserManager::EphemeralModeConfig CreateEphemeralModeConfig( + ash::CrosSettings* cros_settings) { + DCHECK(cros_settings); + + bool ephemeral_users_enabled = false; + cros_settings->GetBoolean(ash::kAccountsPrefEphemeralUsersEnabled, + &ephemeral_users_enabled); + + std::vector<AccountId> ephemeral_accounts, non_ephemeral_accounts; + + const auto accounts = policy::GetDeviceLocalAccounts(cros_settings); + for (const auto& account : accounts) { + switch (account.ephemeral_mode) { + case policy::DeviceLocalAccount::EphemeralMode::kEnable: + ephemeral_accounts.push_back(AccountId::FromUserEmail(account.user_id)); + break; + case policy::DeviceLocalAccount::EphemeralMode::kDisable: + non_ephemeral_accounts.push_back( + AccountId::FromUserEmail(account.user_id)); + break; + case policy::DeviceLocalAccount::EphemeralMode::kUnset: + case policy::DeviceLocalAccount::EphemeralMode::kFollowDeviceWidePolicy: + // Do nothing. + break; + } + } + + return user_manager::UserManager::EphemeralModeConfig( + ephemeral_users_enabled, std::move(ephemeral_accounts), + std::move(non_ephemeral_accounts)); +} + } // namespace // static @@ -665,10 +698,11 @@ ChromeUserManager::IsUserNonCryptohomeDataEphemeral(account_id); } -bool ChromeUserManagerImpl::AreEphemeralUsersEnabled() const { +bool ChromeUserManagerImpl::IsEphemeralAccountId( + const AccountId& account_id) const { policy::BrowserPolicyConnectorAsh* connector = g_browser_process->platform_part()->browser_policy_connector_ash(); - return GetEphemeralUsersEnabled() && + return GetEphemeralModeConfig().IsAccountIdIncluded(account_id) && (connector->IsDeviceEnterpriseManaged() || GetOwnerAccountId().is_valid()); } @@ -735,7 +769,7 @@ if (!GetLocalState()) return; - SetEphemeralUsersEnabled(false); + SetEphemeralModeConfig(EphemeralModeConfig()); SetOwnerId(EmptyAccountId()); // Schedule a callback if device policy has not yet been verified. @@ -746,10 +780,7 @@ return; } - bool ephemeral_users_enabled = false; - cros_settings_->GetBoolean(kAccountsPrefEphemeralUsersEnabled, - &ephemeral_users_enabled); - SetEphemeralUsersEnabled(ephemeral_users_enabled); + SetEphemeralModeConfig(CreateEphemeralModeConfig(cros_settings_)); std::string owner_email; cros_settings_->GetString(kDeviceOwner, &owner_email); @@ -765,14 +796,15 @@ // If ephemeral users are enabled and we are on the login screen, take this // opportunity to clean up by removing all regular users except the owner. - if (GetEphemeralUsersEnabled() && !IsUserLoggedIn()) { + if (!IsUserLoggedIn()) { ScopedListPrefUpdate prefs_users_update(GetLocalState(), user_manager::kRegularUsersPref); prefs_users_update->clear(); for (user_manager::UserList::iterator it = users_.begin(); it != users_.end();) { const AccountId account_id = (*it)->GetAccountId(); - if ((*it)->HasGaiaAccount() && account_id != GetOwnerAccountId()) { + if ((*it)->HasGaiaAccount() && account_id != GetOwnerAccountId() && + IsEphemeralAccountId(account_id)) { user_manager::UserManager::Get()->NotifyUserToBeRemoved(account_id); RemoveNonCryptohomeData(account_id); DeleteUser(*it);
diff --git a/chrome/browser/ash/login/users/chrome_user_manager_impl.h b/chrome/browser/ash/login/users/chrome_user_manager_impl.h index d8296fe2..92e63517 100644 --- a/chrome/browser/ash/login/users/chrome_user_manager_impl.h +++ b/chrome/browser/ash/login/users/chrome_user_manager_impl.h
@@ -99,7 +99,7 @@ bool IsGuestSessionAllowed() const override; bool IsGaiaUserAllowed(const user_manager::User& user) const override; bool IsUserAllowed(const user_manager::User& user) const override; - bool AreEphemeralUsersEnabled() const override; + bool IsEphemeralAccountId(const AccountId& account_id) const override; const AccountId& GetGuestAccountId() const override; bool IsFirstExecAfterBoot() const override; void AsyncRemoveCryptohome(const AccountId& account_id) const override;
diff --git a/chrome/browser/ash/login/users/fake_chrome_user_manager.cc b/chrome/browser/ash/login/users/fake_chrome_user_manager.cc index f312597b..5c2c341 100644 --- a/chrome/browser/ash/login/users/fake_chrome_user_manager.cc +++ b/chrome/browser/ash/login/users/fake_chrome_user_manager.cc
@@ -193,8 +193,9 @@ /*profile=*/nullptr); } -bool FakeChromeUserManager::AreEphemeralUsersEnabled() const { - return fake_ephemeral_users_enabled_; +bool FakeChromeUserManager::IsEphemeralAccountId( + const AccountId& account_id) const { + return fake_ephemeral_mode_config_.IsAccountIdIncluded(account_id); } void FakeChromeUserManager::LoginUser(const AccountId& account_id,
diff --git a/chrome/browser/ash/login/users/fake_chrome_user_manager.h b/chrome/browser/ash/login/users/fake_chrome_user_manager.h index 4fdca70d..fa3a5be 100644 --- a/chrome/browser/ash/login/users/fake_chrome_user_manager.h +++ b/chrome/browser/ash/login/users/fake_chrome_user_manager.h
@@ -8,6 +8,7 @@ #include <map> #include <memory> #include <string> +#include <utility> #include "base/functional/callback_forward.h" #include "base/memory/raw_ptr.h" @@ -133,7 +134,7 @@ bool IsGuestSessionAllowed() const override; bool IsGaiaUserAllowed(const user_manager::User& user) const override; bool IsUserAllowed(const user_manager::User& user) const override; - bool AreEphemeralUsersEnabled() const override; + bool IsEphemeralAccountId(const AccountId& account_id) const override; PrefService* GetLocalState() const override; const AccountId& GetGuestAccountId() const override; bool IsFirstExecAfterBoot() const override; @@ -186,8 +187,8 @@ GetRemovedUserCache() const override; void MarkReporterInitialized() override; - void set_ephemeral_users_enabled(bool ephemeral_users_enabled) { - fake_ephemeral_users_enabled_ = ephemeral_users_enabled; + void set_ephemeral_mode_config(EphemeralModeConfig ephemeral_mode_config) { + fake_ephemeral_mode_config_ = std::move(ephemeral_mode_config); } // TODO(mukai): remove this. @@ -236,7 +237,7 @@ user_manager::User* GetActiveUserInternal() const; std::unique_ptr<FakeSupervisedUserManager> supervised_user_manager_; - bool fake_ephemeral_users_enabled_ = false; + EphemeralModeConfig fake_ephemeral_mode_config_; bool current_user_new_ = false; bool current_user_ephemeral_ = false; bool current_user_child_ = false;
diff --git a/chrome/browser/ash/login/users/user_manager_unittest.cc b/chrome/browser/ash/login/users/user_manager_unittest.cc index 2e015e8..12b5d708 100644 --- a/chrome/browser/ash/login/users/user_manager_unittest.cc +++ b/chrome/browser/ash/login/users/user_manager_unittest.cc
@@ -5,6 +5,8 @@ #include <cstdlib> #include <cstring> #include <memory> +#include <utility> +#include <vector> #include "ash/constants/ash_pref_names.h" #include "ash/constants/ash_switches.h" @@ -12,8 +14,10 @@ #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/run_loop.h" +#include "base/values.h" #include "chrome/browser/ash/login/users/avatar/user_image_manager_impl.h" #include "chrome/browser/ash/login/users/chrome_user_manager_impl.h" +#include "chrome/browser/ash/policy/core/device_local_account.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/ash/settings/scoped_cros_settings_test_helper.h" #include "chrome/browser/ash/wallpaper_handlers/test_backdrop_fetcher_delegate.h" @@ -30,6 +34,7 @@ #include "chromeos/ash/components/cryptohome/system_salt_getter.h" #include "chromeos/ash/components/dbus/concierge/concierge_client.h" #include "chromeos/ash/components/settings/cros_settings_names.h" +#include "components/account_id/account_id.h" #include "components/prefs/pref_service.h" #include "components/user_manager/known_user.h" #include "components/user_manager/remove_user_delegate.h" @@ -45,6 +50,17 @@ namespace ash { +namespace { + +constexpr char kDeviceLocalAccountId[] = "device_local_account"; + +AccountId CreateDeviceLocalKioskAppAccountId(const std::string& account_id) { + return AccountId::FromUserEmail(policy::GenerateDeviceLocalAccountUserId( + kDeviceLocalAccountId, policy::DeviceLocalAccount::TYPE_KIOSK_APP)); +} + +} // namespace + static constexpr char kEmail[] = "user@example.com"; class UnittestRemoveUserDelegate : public user_manager::RemoveUserDelegate { @@ -171,12 +187,14 @@ user_manager::UserManager::Get()); } - bool GetUserManagerEphemeralUsersEnabled() const { - return GetChromeUserManager()->GetEphemeralUsersEnabled(); + bool IsEphemeralAccountId(const AccountId& account_id) const { + return GetChromeUserManager()->IsEphemeralAccountId(account_id); } - void SetUserManagerEphemeralUsersEnabled(bool ephemeral_users_enabled) { - GetChromeUserManager()->SetEphemeralUsersEnabled(ephemeral_users_enabled); + void SetEphemeralModeConfig( + user_manager::UserManager::EphemeralModeConfig ephemeral_mode_config) { + GetChromeUserManager()->SetEphemeralModeConfig( + std::move(ephemeral_mode_config)); } AccountId GetUserManagerOwnerId() const { @@ -212,6 +230,24 @@ settings_helper_.SetString(kDeviceOwner, owner); } + void SetDeviceLocalKioskAppAccount( + const std::string& account_id, + const std::string& kiosk_app_id, + policy::DeviceLocalAccount::EphemeralMode ephemeral_mode) { + settings_helper_.Set( + kAccountsPrefDeviceLocalAccounts, + base::Value(base::Value::List().Append( + base::Value::Dict() + .Set(kAccountsPrefDeviceLocalAccountsKeyId, account_id) + .Set(kAccountsPrefDeviceLocalAccountsKeyType, + static_cast<int>( + policy::DeviceLocalAccount::TYPE_KIOSK_APP)) + .Set(kAccountsPrefDeviceLocalAccountsKeyEphemeralMode, + static_cast<int>(ephemeral_mode)) + .Set(kAccountsPrefDeviceLocalAccountsKeyKioskAppId, + kiosk_app_id)))); + } + void RetrieveTrustedDevicePolicies() { GetChromeUserManager()->RetrieveTrustedDevicePolicies(); } @@ -250,17 +286,120 @@ }; TEST_F(UserManagerTest, RetrieveTrustedDevicePolicies) { - SetUserManagerEphemeralUsersEnabled(true); + SetEphemeralModeConfig(user_manager::UserManager::EphemeralModeConfig( + /* included_by_default= */ true, + /* include_list= */ std::vector<AccountId>{}, + /* exclude_list= */ std::vector<AccountId>{})); SetUserManagerOwnerId(EmptyAccountId()); SetDeviceSettings(false, owner_account_id_at_invalid_domain_.GetUserEmail(), false); RetrieveTrustedDevicePolicies(); - EXPECT_FALSE(GetUserManagerEphemeralUsersEnabled()); + EXPECT_FALSE(IsEphemeralAccountId(EmptyAccountId())); + EXPECT_EQ(GetUserManagerOwnerId(), owner_account_id_at_invalid_domain_); } +// Tests that `UserManager` correctly parses device-wide ephemeral users policy +// by calling `IsEphemeralAccountId(account_id)` function. +TEST_F(UserManagerTest, IsEphemeralAccountIdUsesEphemeralUsersEnabledPolicy) { + EXPECT_FALSE(IsEphemeralAccountId(EmptyAccountId())); + + SetDeviceSettings(true, owner_account_id_at_invalid_domain_.GetUserEmail(), + false); + RetrieveTrustedDevicePolicies(); + + EXPECT_TRUE(IsEphemeralAccountId(EmptyAccountId())); +} + +// Tests that `UserManager` correctly parses device-local accounts with +// ephemeral mode equals to `kFollowDeviceWidePolicy` by calling +// `IsEphemeralAccountId(account_id)` function. +TEST_F(UserManagerTest, + IsEphemeralAccountIdRespectsFollowDeviceWidePolicyEphemeralMode) { + const AccountId account_id = + CreateDeviceLocalKioskAppAccountId(kDeviceLocalAccountId); + + EXPECT_FALSE(IsEphemeralAccountId(account_id)); + + SetDeviceSettings(true, owner_account_id_at_invalid_domain_.GetUserEmail(), + false); + SetDeviceLocalKioskAppAccount( + kDeviceLocalAccountId, "", + policy::DeviceLocalAccount::EphemeralMode::kFollowDeviceWidePolicy); + RetrieveTrustedDevicePolicies(); + EXPECT_TRUE(IsEphemeralAccountId(account_id)); + + SetDeviceSettings(false, owner_account_id_at_invalid_domain_.GetUserEmail(), + false); + RetrieveTrustedDevicePolicies(); + EXPECT_FALSE(IsEphemeralAccountId(account_id)); +} + +// Tests that `UserManager` correctly parses device-local accounts with +// ephemeral mode equals to `kUnset` by calling +// `IsEphemeralAccountId(account_id)` function. +TEST_F(UserManagerTest, IsEphemeralAccountIdRespectsUnsetEphemeralMode) { + const AccountId account_id = + CreateDeviceLocalKioskAppAccountId(kDeviceLocalAccountId); + + EXPECT_FALSE(IsEphemeralAccountId(account_id)); + + SetDeviceSettings(true, owner_account_id_at_invalid_domain_.GetUserEmail(), + false); + SetDeviceLocalKioskAppAccount( + kDeviceLocalAccountId, "", + policy::DeviceLocalAccount::EphemeralMode::kUnset); + RetrieveTrustedDevicePolicies(); + EXPECT_TRUE(IsEphemeralAccountId(account_id)); + + SetDeviceSettings(false, owner_account_id_at_invalid_domain_.GetUserEmail(), + false); + RetrieveTrustedDevicePolicies(); + EXPECT_FALSE(IsEphemeralAccountId(account_id)); +} + +// Tests that `UserManager` correctly parses device-local accounts with +// ephemeral mode equals to `kDisable` by calling +// `IsEphemeralAccountId(account_id)` function. +TEST_F(UserManagerTest, IsEphemeralAccountIdRespectsDisableEphemeralMode) { + const AccountId account_id = + CreateDeviceLocalKioskAppAccountId(kDeviceLocalAccountId); + + EXPECT_FALSE(IsEphemeralAccountId(account_id)); + + SetDeviceSettings(true, owner_account_id_at_invalid_domain_.GetUserEmail(), + false); + SetDeviceLocalKioskAppAccount( + kDeviceLocalAccountId, "", + policy::DeviceLocalAccount::EphemeralMode::kDisable); + RetrieveTrustedDevicePolicies(); + + EXPECT_TRUE(IsEphemeralAccountId(EmptyAccountId())); + EXPECT_FALSE(IsEphemeralAccountId(account_id)); +} + +// Tests that `UserManager` correctly parses device-local accounts with +// ephemeral mode equals to `kEnable` by calling +// `IsEphemeralAccountId(account_id)` function. +TEST_F(UserManagerTest, IsEphemeralAccountIdRespectssEnableEphemeralMode) { + const AccountId account_id = + CreateDeviceLocalKioskAppAccountId(kDeviceLocalAccountId); + + EXPECT_FALSE(IsEphemeralAccountId(account_id)); + + SetDeviceSettings(false, owner_account_id_at_invalid_domain_.GetUserEmail(), + false); + SetDeviceLocalKioskAppAccount( + kDeviceLocalAccountId, "", + policy::DeviceLocalAccount::EphemeralMode::kEnable); + RetrieveTrustedDevicePolicies(); + + EXPECT_FALSE(IsEphemeralAccountId(EmptyAccountId())); + EXPECT_TRUE(IsEphemeralAccountId(account_id)); +} + TEST_F(UserManagerTest, RemoveUser) { std::unique_ptr<MockRemoveUserManager> user_manager = CreateMockRemoveUserManager();
diff --git a/chrome/browser/ash/network_change_manager_client.cc b/chrome/browser/ash/network_change_manager_client.cc index bd87630..23a11f0e 100644 --- a/chrome/browser/ash/network_change_manager_client.cc +++ b/chrome/browser/ash/network_change_manager_client.cc
@@ -12,7 +12,7 @@ #include "chromeos/crosapi/mojom/network_change.mojom.h" #include "content/public/browser/network_service_instance.h" #include "content/public/common/network_service_util.h" -#include "net/base/network_change_notifier_posix.h" +#include "net/base/network_change_notifier_passive.h" #include "services/network/public/mojom/network_service.mojom.h" namespace ash { @@ -22,7 +22,7 @@ } NetworkChangeManagerClient::NetworkChangeManagerClient( - net::NetworkChangeNotifierPosix* network_change_notifier) + net::NetworkChangeNotifierPassive* network_change_notifier) : connection_type_(net::NetworkChangeNotifier::GetConnectionType()), connection_subtype_(net::NetworkChangeNotifier::GetConnectionSubtype()), network_change_notifier_(network_change_notifier) {
diff --git a/chrome/browser/ash/network_change_manager_client.h b/chrome/browser/ash/network_change_manager_client.h index 9f4fddb..465e10d 100644 --- a/chrome/browser/ash/network_change_manager_client.h +++ b/chrome/browser/ash/network_change_manager_client.h
@@ -21,7 +21,7 @@ } // namespace crosapi::mojom namespace net { -class NetworkChangeNotifierPosix; +class NetworkChangeNotifierPassive; } // namespace net namespace ash { @@ -29,14 +29,14 @@ class NetworkStateHandler; // This class listens to Shill for network change events and notifies both -// the local NetworkChangeNotifierPosix, and the network service via +// the local NetworkChangeNotifierPassive, and the network service via // the NetworkChangeManager if the network service is enabled. class NetworkChangeManagerClient : public chromeos::PowerManagerClient::Observer, public NetworkStateHandlerObserver { public: explicit NetworkChangeManagerClient( - net::NetworkChangeNotifierPosix* network_change_notifier); + net::NetworkChangeNotifierPassive* network_change_notifier); NetworkChangeManagerClient(const NetworkChangeManagerClient&) = delete; NetworkChangeManagerClient& operator=(const NetworkChangeManagerClient&) = @@ -118,7 +118,7 @@ base::ScopedObservation<NetworkStateHandler, NetworkStateHandlerObserver> network_state_handler_observer_{this}; - net::NetworkChangeNotifierPosix* network_change_notifier_; + net::NetworkChangeNotifierPassive* network_change_notifier_; mojo::Remote<network::mojom::NetworkChangeManager> network_change_manager_; mojo::RemoteSet<crosapi::mojom::NetworkChangeObserver> lacros_network_change_observers_;
diff --git a/chrome/browser/ash/network_change_manager_client_unittest.cc b/chrome/browser/ash/network_change_manager_client_unittest.cc index 714cbd6..983d42b07 100644 --- a/chrome/browser/ash/network_change_manager_client_unittest.cc +++ b/chrome/browser/ash/network_change_manager_client_unittest.cc
@@ -15,7 +15,7 @@ #include "chromeos/dbus/power/power_manager_client.h" #include "content/public/test/browser_task_environment.h" #include "net/base/network_change_notifier.h" -#include "net/base/network_change_notifier_posix.h" +#include "net/base/network_change_notifier_passive.h" #include "testing/gtest/include/gtest/gtest.h" namespace ash { @@ -110,8 +110,8 @@ NetworkChangeNotifierConnectionTypeUpdated) { // Create a NetworkChangeNotifier with a non-NONE connection type. content::BrowserTaskEnvironment task_environment_; - std::unique_ptr<net::NetworkChangeNotifierPosix> network_change_notifier( - static_cast<net::NetworkChangeNotifierPosix*>( + std::unique_ptr<net::NetworkChangeNotifierPassive> network_change_notifier( + static_cast<net::NetworkChangeNotifierPassive*>( net::NetworkChangeNotifier::CreateIfNeeded().release())); network_change_notifier->OnConnectionChanged( net::NetworkChangeNotifier::CONNECTION_UNKNOWN); @@ -153,7 +153,7 @@ network_change_notifier_ = net::NetworkChangeNotifier::CreateIfNeeded(); chromeos::PowerManagerClient::InitializeFake(); proxy_ = std::make_unique<NetworkChangeManagerClient>( - static_cast<net::NetworkChangeNotifierPosix*>( + static_cast<net::NetworkChangeNotifierPassive*>( network_change_notifier_.get())); }
diff --git a/chrome/browser/ash/phonehub/browser_tabs_metadata_fetcher_impl.cc b/chrome/browser/ash/phonehub/browser_tabs_metadata_fetcher_impl.cc index 201e28a..2652276 100644 --- a/chrome/browser/ash/phonehub/browser_tabs_metadata_fetcher_impl.cc +++ b/chrome/browser/ash/phonehub/browser_tabs_metadata_fetcher_impl.cc
@@ -11,6 +11,7 @@ #include "components/favicon_base/favicon_types.h" #include "components/sync_sessions/synced_session.h" #include "components/ukm/scheme_constants.h" +#include "ui/gfx/image/image_skia.h" namespace ash { namespace phonehub { @@ -137,6 +138,7 @@ void BrowserTabsMetadataFetcherImpl::FetchForeignSyncedPhoneSessionMetadata( const ForeignSyncedSessionAsh& session, + SyncedSessionClientAsh* synced_session_client_ash, base::OnceCallback<void(BrowserTabsMetadataResponse)> callback) { // A new fetch was made, return a absl::nullopt to the previous |callback_|. if (!callback_.is_null()) { @@ -144,17 +146,38 @@ std::move(callback_).Run(absl::nullopt); } - // TODO(b/260599791): Fetch favicons before invoking the callback. We may need - // to include the favicons directly in the Mojo payload that we receive from - // Lacros. - std::move(callback).Run( - GetSortedMetadataWithoutFaviconsFromForeignSyncedSession(session)); + std::vector<BrowserTabsModel::BrowserTabMetadata> results = + GetSortedMetadataWithoutFaviconsFromForeignSyncedSession(session); + BrowserTabsModel::BrowserTabMetadata* results_buffer = results.data(); + size_t results_size = results.size(); + + // When |barrier| is run |num_tabs_to_display| times, it will run + // |OnAllFaviconsFetched|. + base::RepeatingClosure barrier = base::BarrierClosure( + results_size, base::BindOnce(&BrowserTabsMetadataFetcherImpl:: + OnAllForeignSyncedSessionFaviconsFetched, + weak_ptr_factory_.GetWeakPtr(), + std::move(results), std::move(callback))); + + for (size_t i = 0; i < results_size; ++i) { + synced_session_client_ash->GetFaviconImageForPageURL( + results_buffer[i].url, + base::BindOnce( + &BrowserTabsMetadataFetcherImpl::OnForeignSyncedSessionFaviconReady, + weak_ptr_factory_.GetWeakPtr(), results_buffer + i, barrier)); + } } void BrowserTabsMetadataFetcherImpl::OnAllFaviconsFetched() { std::move(callback_).Run(std::move(results_)); } +void BrowserTabsMetadataFetcherImpl::OnAllForeignSyncedSessionFaviconsFetched( + std::vector<BrowserTabsModel::BrowserTabMetadata> results, + base::OnceCallback<void(BrowserTabsMetadataResponse)> callback) { + std::move(callback).Run(std::move(results)); +} + void BrowserTabsMetadataFetcherImpl::OnFaviconReady( size_t index_in_results, base::OnceClosure done_closure, @@ -165,5 +188,13 @@ std::move(done_closure).Run(); } +void BrowserTabsMetadataFetcherImpl::OnForeignSyncedSessionFaviconReady( + BrowserTabsModel::BrowserTabMetadata* tab, + base::OnceClosure done_closure, + const gfx::ImageSkia& favicon) { + tab->favicon = gfx::Image(favicon); + std::move(done_closure).Run(); +} + } // namespace phonehub } // namespace ash
diff --git a/chrome/browser/ash/phonehub/browser_tabs_metadata_fetcher_impl.h b/chrome/browser/ash/phonehub/browser_tabs_metadata_fetcher_impl.h index 94021b2..840ec920 100644 --- a/chrome/browser/ash/phonehub/browser_tabs_metadata_fetcher_impl.h +++ b/chrome/browser/ash/phonehub/browser_tabs_metadata_fetcher_impl.h
@@ -5,6 +5,9 @@ #ifndef CHROME_BROWSER_ASH_PHONEHUB_BROWSER_TABS_METADATA_FETCHER_IMPL_H_ #define CHROME_BROWSER_ASH_PHONEHUB_BROWSER_TABS_METADATA_FETCHER_IMPL_H_ +#include <vector> + +#include "base/functional/callback_forward.h" #include "base/memory/weak_ptr.h" #include "chromeos/ash/components/phonehub/browser_tabs_metadata_fetcher.h" #include "chromeos/ash/components/phonehub/browser_tabs_model.h" @@ -17,9 +20,13 @@ class HistoryUiFaviconRequestHandler; } // namespace favicon +namespace gfx { +class ImageSkia; +} // namespace gfx namespace ash { struct ForeignSyncedSessionAsh; +class SyncedSessionClientAsh; namespace phonehub { @@ -43,14 +50,22 @@ base::OnceCallback<void(BrowserTabsMetadataResponse)> callback) override; void FetchForeignSyncedPhoneSessionMetadata( const ForeignSyncedSessionAsh& session, + SyncedSessionClientAsh* synced_session_client_ash, base::OnceCallback<void(BrowserTabsMetadataResponse)> callback) override; private: void OnAllFaviconsFetched(); + void OnAllForeignSyncedSessionFaviconsFetched( + std::vector<BrowserTabsModel::BrowserTabMetadata> results, + base::OnceCallback<void(BrowserTabsMetadataResponse)> callback); void OnFaviconReady( size_t index_in_results, base::OnceClosure done_closure, const favicon_base::FaviconImageResult& favicon_image_result); + void OnForeignSyncedSessionFaviconReady( + BrowserTabsModel::BrowserTabMetadata* tab, + base::OnceClosure done_closure, + const gfx::ImageSkia& favicon); favicon::HistoryUiFaviconRequestHandler* const favicon_request_handler_; std::vector<BrowserTabsModel::BrowserTabMetadata> results_;
diff --git a/chrome/browser/ash/phonehub/browser_tabs_metadata_fetcher_impl_unittest.cc b/chrome/browser/ash/phonehub/browser_tabs_metadata_fetcher_impl_unittest.cc index 5a8c2a5..e56c9d2f 100644 --- a/chrome/browser/ash/phonehub/browser_tabs_metadata_fetcher_impl_unittest.cc +++ b/chrome/browser/ash/phonehub/browser_tabs_metadata_fetcher_impl_unittest.cc
@@ -145,7 +145,7 @@ void AttemptFetchForeignSyncedPhoneSessionMetadata( const ForeignSyncedSessionAsh& session) { browser_tabs_metadata_job_.FetchForeignSyncedPhoneSessionMetadata( - session, + session, &synced_session_client_ash_, base::BindOnce( &BrowserTabsMetadataFetcherImplTest::OnBrowserTabMetadataFetched, base::Unretained(this))); @@ -182,6 +182,7 @@ BrowserTabsMetadataFetcherImpl browser_tabs_metadata_job_; absl::optional<std::vector<BrowserTabsModel::BrowserTabMetadata>> actual_browser_tabs_metadata_; + SyncedSessionClientAsh synced_session_client_ash_; std::map<SessionID, std::unique_ptr<sync_sessions::SyncedSessionWindow>> windows;
diff --git a/chrome/browser/ash/phonehub/browser_tabs_model_provider_impl.cc b/chrome/browser/ash/phonehub/browser_tabs_model_provider_impl.cc index 8763319..c4746a8 100644 --- a/chrome/browser/ash/phonehub/browser_tabs_model_provider_impl.cc +++ b/chrome/browser/ash/phonehub/browser_tabs_model_provider_impl.cc
@@ -214,7 +214,7 @@ return; } browser_tabs_metadata_fetcher_->FetchForeignSyncedPhoneSessionMetadata( - host_phone_session.value(), + host_phone_session.value(), synced_session_client_ash_, base::BindOnce(&BrowserTabsModelProviderImpl::OnMetadataFetched, weak_ptr_factory_.GetWeakPtr())); }
diff --git a/chrome/browser/ash/policy/core/device_policy_decoder.cc b/chrome/browser/ash/policy/core/device_policy_decoder.cc index aac60fc..30449f0 100644 --- a/chrome/browser/ash/policy/core/device_policy_decoder.cc +++ b/chrome/browser/ash/policy/core/device_policy_decoder.cc
@@ -1971,15 +1971,6 @@ } } - if (policy.has_arc_data_snapshot_hours()) { - const em::DeviceArcDataSnapshotHoursProto& container( - policy.arc_data_snapshot_hours()); - if (container.has_arc_data_snapshot_hours()) { - SetJsonDevicePolicy(key::kDeviceArcDataSnapshotHours, - container.arc_data_snapshot_hours(), policies); - } - } - if (policy.has_device_allow_mgs_to_store_display_properties()) { const em::BooleanPolicyProto& container( policy.device_allow_mgs_to_store_display_properties());
diff --git a/chrome/browser/ash/release_notes/release_notes_storage_unittest.cc b/chrome/browser/ash/release_notes/release_notes_storage_unittest.cc index 665d9f9..e87abe2 100644 --- a/chrome/browser/ash/release_notes/release_notes_storage_unittest.cc +++ b/chrome/browser/ash/release_notes/release_notes_storage_unittest.cc
@@ -5,6 +5,8 @@ #include "chrome/browser/ash/release_notes/release_notes_storage.h" #include <memory> +#include <utility> +#include <vector> #include "ash/constants/ash_features.h" #include "base/test/scoped_feature_list.h" @@ -56,7 +58,11 @@ builder.OverridePolicyConnectorIsManagedForTesting(is_managed_); if (is_ephemeral_) { // Enabling ephemeral users passes the |IsEphemeralUserProfile| check. - user_manager_->set_ephemeral_users_enabled(true); + user_manager_->set_ephemeral_mode_config( + user_manager::UserManager::EphemeralModeConfig( + /* included_by_default= */ true, + /* include_list= */ std::vector<AccountId>{}, + /* exclude_list= */ std::vector<AccountId>{})); } else if (is_unicorn_) { user_manager_->set_current_user_child(true); builder.SetIsSupervisedProfile();
diff --git a/chrome/browser/ash/sync/synced_session_client_ash.cc b/chrome/browser/ash/sync/synced_session_client_ash.cc index 6eed0ce9..42393dd 100644 --- a/chrome/browser/ash/sync/synced_session_client_ash.cc +++ b/chrome/browser/ash/sync/synced_session_client_ash.cc
@@ -96,6 +96,27 @@ } } +void SyncedSessionClientAsh::SetFaviconDelegate( + mojo::PendingRemote<crosapi::mojom::SyncedSessionClientFaviconDelegate> + delegate) { + if (favicon_delegate_.is_bound()) { + favicon_delegate_.reset(); + } + + favicon_delegate_.Bind(std::move(delegate)); +} + +void SyncedSessionClientAsh::GetFaviconImageForPageURL( + const GURL& url, + base::OnceCallback<void(const gfx::ImageSkia&)> callback) { + if (!favicon_delegate_.is_bound()) { + std::move(callback).Run(gfx::ImageSkia()); + return; + } + + favicon_delegate_->GetFaviconImageForPageURL(url, std::move(callback)); +} + void SyncedSessionClientAsh::AddObserver(Observer* observer) { observers_.AddObserver(observer); }
diff --git a/chrome/browser/ash/sync/synced_session_client_ash.h b/chrome/browser/ash/sync/synced_session_client_ash.h index 92aad17b..2625004 100644 --- a/chrome/browser/ash/sync/synced_session_client_ash.h +++ b/chrome/browser/ash/sync/synced_session_client_ash.h
@@ -9,6 +9,7 @@ #include <string> #include <vector> +#include "base/functional/callback_forward.h" #include "base/observer_list.h" #include "base/observer_list_types.h" #include "base/time/time.h" @@ -16,6 +17,7 @@ #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver_set.h" +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "url/gurl.h" @@ -98,6 +100,13 @@ void OnForeignSyncedPhoneSessionsUpdated( std::vector<crosapi::mojom::SyncedSessionPtr> sessions) override; void OnSessionSyncEnabledChanged(bool enabled) override; + void SetFaviconDelegate( + mojo::PendingRemote<crosapi::mojom::SyncedSessionClientFaviconDelegate> + delegate) override; + + void GetFaviconImageForPageURL( + const GURL& url, + base::OnceCallback<void(const gfx::ImageSkia&)> callback); const std::vector<ForeignSyncedSessionAsh>& last_foreign_synced_phone_sessions() const { @@ -108,6 +117,8 @@ private: mojo::ReceiverSet<crosapi::mojom::SyncedSessionClient> receivers_; + mojo::Remote<crosapi::mojom::SyncedSessionClientFaviconDelegate> + favicon_delegate_; base::ObserverList<Observer> observers_; std::vector<ForeignSyncedSessionAsh> last_foreign_synced_phone_sessions_; bool is_session_sync_enabled_ = false;
diff --git a/chrome/browser/ash/sync/synced_session_client_ash_unittest.cc b/chrome/browser/ash/sync/synced_session_client_ash_unittest.cc index 7c96261..71b221a 100644 --- a/chrome/browser/ash/sync/synced_session_client_ash_unittest.cc +++ b/chrome/browser/ash/sync/synced_session_client_ash_unittest.cc
@@ -4,13 +4,17 @@ #include "chrome/browser/ash/sync/synced_session_client_ash.h" +#include "base/test/bind.h" #include "base/test/task_environment.h" +#include "base/test/test_future.h" #include "base/time/time.h" #include "chromeos/crosapi/mojom/synced_session_client.mojom.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/favicon_size.h" +#include "ui/gfx/image/image_unittest_util.h" #include "url/gurl.h" namespace ash { @@ -72,6 +76,43 @@ bool is_session_sync_enabled_ = false; }; +class FakeCrosapiSessionSyncFaviconDelegate + : public crosapi::mojom::SyncedSessionClientFaviconDelegate { + public: + FakeCrosapiSessionSyncFaviconDelegate() = default; + FakeCrosapiSessionSyncFaviconDelegate( + const FakeCrosapiSessionSyncFaviconDelegate&) = delete; + FakeCrosapiSessionSyncFaviconDelegate& operator=( + const FakeCrosapiSessionSyncFaviconDelegate&) = delete; + ~FakeCrosapiSessionSyncFaviconDelegate() override = default; + + // crosapi::mojom::SyncedSessionClientFaviconDelegate: + void GetFaviconImageForPageURL( + const GURL& url, + GetFaviconImageForPageURLCallback callback) override { + std::move(callback).Run(*result_image_); + } + + mojo::PendingRemote<crosapi::mojom::SyncedSessionClientFaviconDelegate> + CreateRemote() { + return receiver_.BindNewPipeAndPassRemote(); + } + + void SetResultImage(gfx::ImageSkia* image) { result_image_ = image; } + + private: + mojo::Receiver<crosapi::mojom::SyncedSessionClientFaviconDelegate> receiver_{ + this}; + gfx::ImageSkia* result_image_ = nullptr; +}; + +gfx::ImageSkia GetTestImage() { + SkBitmap bitmap; + bitmap.allocN32Pixels(gfx::kFaviconSize, gfx::kFaviconSize); + bitmap.eraseColor(SK_ColorBLUE); + return gfx::Image::CreateFrom1xBitmap(bitmap).AsImageSkia(); +} + } // namespace class SyncedSessionClientAshTest : public testing::Test { @@ -89,6 +130,13 @@ client_->AddObserver(test_observer_.get()); } + void RequestFaviconImage(gfx::ImageSkia expected_image) { + base::test::TestFuture<const gfx::ImageSkia&> future; + client_->GetFaviconImageForPageURL(GURL(kTestUrl), future.GetCallback()); + EXPECT_TRUE(gfx::test::AreImagesEqual(gfx::Image(expected_image), + gfx::Image(future.Get()))); + } + SyncedSessionClientAsh* client() { DCHECK(client_); return client_.get(); @@ -135,4 +183,21 @@ EXPECT_FALSE(test_observer()->IsSessionSyncEnabled()); } +TEST_F(SyncedSessionClientAshTest, GetFaviconImage_NoRemote) { + RequestFaviconImage(gfx::ImageSkia()); +} + +TEST_F(SyncedSessionClientAshTest, GetFaviconImage_ImagesMatch) { + FakeCrosapiSessionSyncFaviconDelegate favicon_delegate; + client()->SetFaviconDelegate(favicon_delegate.CreateRemote()); + + gfx::ImageSkia empty_image; + favicon_delegate.SetResultImage(&empty_image); + RequestFaviconImage(gfx::ImageSkia()); + + gfx::ImageSkia test_image = GetTestImage(); + favicon_delegate.SetResultImage(&test_image); + RequestFaviconImage(GetTestImage()); +} + } // namespace ash
diff --git a/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/AutofillUiUtils.java b/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/AutofillUiUtils.java index c166787e..876a280b 100644 --- a/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/AutofillUiUtils.java +++ b/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/AutofillUiUtils.java
@@ -29,6 +29,7 @@ import android.widget.TextView; import androidx.annotation.IntDef; +import androidx.annotation.Nullable; import androidx.annotation.Px; import androidx.annotation.VisibleForTesting; import androidx.appcompat.content.res.AppCompatResources; @@ -500,11 +501,13 @@ * @param widthId Resource Id for the width spec. * @param heightId Resource Id for the height spec. * @param showCustomIcon If true, custom card icon is fetched, else, default icon is fetched. - * @return {@link Drawable} that can be set as the card icon. + * @return {@link Drawable} that can be set as the card icon. If neither the custom icon nor the + * default icon is available, returns null. */ - public static Drawable getCardIcon(Context context, GURL cardArtUrl, int defaultIconId, - int widthId, int heightId, boolean showCustomIcon) { - Drawable defaultIcon = AppCompatResources.getDrawable(context, defaultIconId); + public static @Nullable Drawable getCardIcon(Context context, GURL cardArtUrl, + int defaultIconId, int widthId, int heightId, boolean showCustomIcon) { + Drawable defaultIcon = + defaultIconId == 0 ? null : AppCompatResources.getDrawable(context, defaultIconId); if (!showCustomIcon || !cardArtUrl.isValid()) { return defaultIcon; }
diff --git a/chrome/browser/autofill/iban_manager_factory.cc b/chrome/browser/autofill/iban_manager_factory.cc index 0ff6ca83..f94b1630 100644 --- a/chrome/browser/autofill/iban_manager_factory.cc +++ b/chrome/browser/autofill/iban_manager_factory.cc
@@ -33,10 +33,8 @@ KeyedService* IBANManagerFactory::BuildServiceInstanceFor( content::BrowserContext* context) const { - Profile* profile = Profile::FromBrowserContext(context); - IBANManager* service = - new IBANManager(PersonalDataManagerFactory::GetForBrowserContext(context), - profile->IsOffTheRecord()); + IBANManager* service = new IBANManager( + PersonalDataManagerFactory::GetForBrowserContext(context)); return service; }
diff --git a/chrome/browser/autofill/test/android/java/src/org/chromium/chrome/browser/autofill/PersonalDataManagerTest.java b/chrome/browser/autofill/test/android/java/src/org/chromium/chrome/browser/autofill/PersonalDataManagerTest.java index f194ea4..b4cc176 100644 --- a/chrome/browser/autofill/test/android/java/src/org/chromium/chrome/browser/autofill/PersonalDataManagerTest.java +++ b/chrome/browser/autofill/test/android/java/src/org/chromium/chrome/browser/autofill/PersonalDataManagerTest.java
@@ -720,4 +720,23 @@ .getBitmap())); }); } + + @Test + @SmallTest + @Feature({"Autofill"}) + public void testGetCardIcon_customIconUrlAndDefaultIconIdUnavailable_nothingReturned() + throws TimeoutException { + Context context = ContextUtils.getApplicationContext(); + int widthId = R.dimen.autofill_dropdown_icon_width; + int heightId = R.dimen.autofill_dropdown_icon_height; + Bitmap scaledTestCardArtImage = Bitmap.createScaledBitmap(TEST_CARD_ART_IMAGE, + context.getResources().getDimensionPixelSize(widthId), + context.getResources().getDimensionPixelSize(heightId), true); + + TestThreadUtils.runOnUiThreadBlocking(() -> { + // If neither the custom icon nor the default icon is available, null is returned. + assertEquals(null, + AutofillUiUtils.getCardIcon(context, new GURL(""), 0, widthId, heightId, true)); + }); + } }
diff --git a/chrome/browser/background_sync/background_sync_controller_impl_unittest.cc b/chrome/browser/background_sync/background_sync_controller_impl_unittest.cc index 2d3bde2c..cb0809ba 100644 --- a/chrome/browser/background_sync/background_sync_controller_impl_unittest.cc +++ b/chrome/browser/background_sync/background_sync_controller_impl_unittest.cc
@@ -6,6 +6,7 @@ #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" +#include "base/metrics/field_trial_params.h" #include "build/build_config.h" #include "chrome/browser/background_sync/background_sync_delegate_impl.h" #include "chrome/browser/history/history_service_factory.h" @@ -119,7 +120,7 @@ "TrUe"; field_parameters[BackgroundSyncControllerImpl::kInitialRetryParameterName] = "100"; - ASSERT_TRUE(variations::AssociateVariationParams( + ASSERT_TRUE(base::AssociateFieldTrialParams( BackgroundSyncControllerImpl::kFieldTrialName, kFieldTrialGroup, field_parameters)); @@ -158,7 +159,7 @@ "500"; field_parameters [BackgroundSyncControllerImpl::kMinPeriodicSyncEventsInterval] = "43200"; - ASSERT_TRUE(variations::AssociateVariationParams( + ASSERT_TRUE(base::AssociateFieldTrialParams( BackgroundSyncControllerImpl::kFieldTrialName, kFieldTrialGroup, field_parameters));
diff --git a/chrome/browser/bluetooth/web_bluetooth_browsertest.cc b/chrome/browser/bluetooth/web_bluetooth_browsertest.cc index 581374e..0d3c0190 100644 --- a/chrome/browser/bluetooth/web_bluetooth_browsertest.cc +++ b/chrome/browser/bluetooth/web_bluetooth_browsertest.cc
@@ -603,7 +603,7 @@ std::map<std::string, std::string> params; params["Bluetooth"] = permissions::PermissionContextBase::kPermissionsKillSwitchBlockedValue; - variations::AssociateVariationParams( + base::AssociateFieldTrialParams( permissions::PermissionContextBase::kPermissionsKillSwitchFieldStudy, "TestGroup", params); base::FieldTrialList::CreateFieldTrial( @@ -645,8 +645,8 @@ // Create a field trial with test parameter. std::map<std::string, std::string> params; params["blocklist_additions"] = "ed5f25a4:e"; - variations::AssociateVariationParams("WebBluetoothBlocklist", "TestGroup", - params); + base::AssociateFieldTrialParams("WebBluetoothBlocklist", "TestGroup", + params); base::FieldTrialList::CreateFieldTrial("WebBluetoothBlocklist", "TestGroup"); }
diff --git a/chrome/browser/chrome_content_browser_client_unittest.cc b/chrome/browser/chrome_content_browser_client_unittest.cc index 87e812f..bfe5321 100644 --- a/chrome/browser/chrome_content_browser_client_unittest.cc +++ b/chrome/browser/chrome_content_browser_client_unittest.cc
@@ -14,6 +14,7 @@ #include "base/functional/callback_helpers.h" #include "base/memory/raw_ptr.h" #include "base/metrics/field_trial.h" +#include "base/metrics/field_trial_params.h" #include "base/run_loop.h" #include "base/strings/strcat.h" #include "base/strings/utf_string_conversions.h" @@ -373,7 +374,7 @@ params.insert(std::make_pair(key1, value1)); params.insert(std::make_pair(key2, value2)); CreateFieldTrial(trial_name, kFakeGroupName); - variations::AssociateVariationParams(trial_name, kFakeGroupName, params); + base::AssociateFieldTrialParams(trial_name, kFakeGroupName, params); } void AppendContentBrowserClientSwitches() {
diff --git a/chrome/browser/dom_distiller/tab_utils_browsertest.cc b/chrome/browser/dom_distiller/tab_utils_browsertest.cc index 502e813..144c199 100644 --- a/chrome/browser/dom_distiller/tab_utils_browsertest.cc +++ b/chrome/browser/dom_distiller/tab_utils_browsertest.cc
@@ -361,12 +361,6 @@ GURL url1(article_url()); content::WebContents* initial_web_contents = browser()->tab_strip_model()->GetActiveWebContents(); - content::RenderFrameHost* main_frame = browser() - ->tab_strip_model() - ->GetActiveWebContents() - ->GetPrimaryMainFrame(); - int process_id = main_frame->GetProcess()->GetID(); - int frame_routing_id = main_frame->GetRoutingID(); GURL url2(https_server_->GetURL("/title1.html")); TestDistillabilityObserver distillability_observer(initial_web_contents); @@ -377,6 +371,12 @@ // Navigate to the page ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url1)); + content::RenderFrameHost* main_frame = browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetPrimaryMainFrame(); + int process_id = main_frame->GetProcess()->GetID(); + int frame_routing_id = main_frame->GetRoutingID(); distillability_observer.WaitForResult(expected_result); DistillCurrentPageAndView(initial_web_contents);
diff --git a/chrome/browser/download/bubble/download_bubble_update_service.cc b/chrome/browser/download/bubble/download_bubble_update_service.cc index 13460309..a65918b 100644 --- a/chrome/browser/download/bubble/download_bubble_update_service.cc +++ b/chrome/browser/download/bubble/download_bubble_update_service.cc
@@ -49,13 +49,12 @@ template <typename Item> using SortedItems = DownloadBubbleUpdateService::SortedItems<Item>; -// Show 100 items by default. We will cache up to this many download items and -// up to this many offline items. -constexpr size_t kDefaultMaxNumItemsToShow = 100u; -// Cache a few more items than we will return from GetAllModelsToDisplay. This -// gives us some wiggle room and makes it more likely that we'll return enough -// items before backfilling. -constexpr size_t kDefaultExtraItemsToCache = 20u; +// Show up to 30 items in total by default. +constexpr size_t kDefaultMaxNumItemsToShow = 30u; +// Cache a few more items of each type than we will return from +// GetAllModelsToDisplay. This gives us some wiggle room and makes it more +// likely that we'll return enough items before backfilling. +constexpr size_t kDefaultExtraItemsToCache = 30u; // Amount of time to show an item in the bubble. Items older than this duration // ago will be pruned. constexpr base::TimeDelta kShowItemInBubbleDuration = base::Hours(24);
diff --git a/chrome/browser/enterprise/connectors/analysis/local_binary_upload_service.cc b/chrome/browser/enterprise/connectors/analysis/local_binary_upload_service.cc index 90e8202..f1b0390 100644 --- a/chrome/browser/enterprise/connectors/analysis/local_binary_upload_service.cc +++ b/chrome/browser/enterprise/connectors/analysis/local_binary_upload_service.cc
@@ -240,14 +240,6 @@ std::unique_ptr<Request> request) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - // If there have been too may consecutive failures accessing the agent, - // just fail the request immediately. Chrome will apply the default verdict. - if (retry_count_ >= kMaxRetryCount) { - DVLOG(1) << __func__ << ": aborting, too many errors"; - request->FinishRequest(Result::UPLOAD_FAILURE, ContentAnalysisResponse()); - return; - } - // Builds a request context to keep track of this request. This starts // a timer that will fire if no response is received from the agent within // the specified timeout. This timer remains active as the request moves @@ -714,7 +706,7 @@ if (!connection_retry_timer_.IsRunning()) { ++retry_count_; connection_retry_timer_.Start( - FROM_HERE, retry_count_ * base::Seconds(1), + FROM_HERE, retry_count_ * base::Milliseconds(100), base::BindOnce(&LocalBinaryUploadService::OnConnectionRetry, factory_.GetWeakPtr())); }
diff --git a/chrome/browser/enterprise/connectors/analysis/local_binary_upload_service.h b/chrome/browser/enterprise/connectors/analysis/local_binary_upload_service.h index f57ccf6..3d628876 100644 --- a/chrome/browser/enterprise/connectors/analysis/local_binary_upload_service.h +++ b/chrome/browser/enterprise/connectors/analysis/local_binary_upload_service.h
@@ -38,7 +38,7 @@ // The maximum number of reconnection retries chrome will attempt when an // error occurs with the agent communication. Once this is reached chrome // will no longer attempt to connect to the agent until it restarts. - static constexpr size_t kMaxRetryCount = 5; + static constexpr size_t kMaxRetryCount = 1; // The maximum amount of time chrome will wait for a verdict from the local // content analysis agent.
diff --git a/chrome/browser/enterprise/connectors/analysis/local_binary_upload_service_unittest.cc b/chrome/browser/enterprise/connectors/analysis/local_binary_upload_service_unittest.cc index 7ba351e..ce41fde8 100644 --- a/chrome/browser/enterprise/connectors/analysis/local_binary_upload_service_unittest.cc +++ b/chrome/browser/enterprise/connectors/analysis/local_binary_upload_service_unittest.cc
@@ -380,10 +380,21 @@ EXPECT_EQ(0u, lbus.GetActiveRequestCountForTesting()); EXPECT_EQ(0u, lbus.GetPendingRequestCountForTesting()); - // New requests should fail immediately. + // New requests should fail while agent is not running. result = BinaryUploadService::Result::UNKNOWN; lbus.MaybeUploadForDeepScanning(MakeRequest(config, &result, &response)); + + task_environment_.RunUntilIdle(); EXPECT_EQ(BinaryUploadService::Result::UPLOAD_FAILURE, result); + + // The next time the code tries to connect to a client it succeeds. + fake_sdk_manager_.SetClientSendStatus(0); + + // New requests should succeed now that agent is running. + result = BinaryUploadService::Result::UNKNOWN; + lbus.MaybeUploadForDeepScanning(MakeRequest(config, &result, &response)); + task_environment_.RunUntilIdle(); + EXPECT_EQ(BinaryUploadService::Result::SUCCESS, result); } TEST_F(LocalBinaryUploadServiceTest, CancelRequests) {
diff --git a/chrome/browser/extensions/api/metrics_private/metrics_apitest.cc b/chrome/browser/extensions/api/metrics_private/metrics_apitest.cc index f7e013d..80ab4b1 100644 --- a/chrome/browser/extensions/api/metrics_private/metrics_apitest.cc +++ b/chrome/browser/extensions/api/metrics_private/metrics_apitest.cc
@@ -7,11 +7,11 @@ #include <map> #include "base/metrics/field_trial.h" +#include "base/metrics/field_trial_params.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/statistics_recorder.h" #include "base/test/metrics/user_action_tester.h" #include "chrome/browser/extensions/extension_apitest.h" -#include "components/variations/variations_associated_data.h" #include "content/public/test/browser_test.h" namespace extensions { @@ -154,8 +154,8 @@ base::FieldTrialList::CreateFieldTrial("apitestfieldtrial2", "group1"); - ASSERT_TRUE(variations::AssociateVariationParams( - "apitestfieldtrial2", "group1", {{"a", "aa"}, {"b", "bb"}})); + ASSERT_TRUE(base::AssociateFieldTrialParams("apitestfieldtrial2", "group1", + {{"a", "aa"}, {"b", "bb"}})); ASSERT_TRUE(RunExtensionTest("metrics", {}, {.load_as_component = true})) << message_;
diff --git a/chrome/browser/extensions/data_deleter.cc b/chrome/browser/extensions/data_deleter.cc index 1b79c0a..a99d1f02 100644 --- a/chrome/browser/extensions/data_deleter.cc +++ b/chrome/browser/extensions/data_deleter.cc
@@ -106,7 +106,7 @@ GURL launch_web_url_origin; StoragePartition* partition = nullptr; - if (extensions::util::LegacyHasIsolatedStorage(extension)) { + if (extensions::util::HasIsolatedStorage(*extension, profile)) { has_isolated_storage = true; ++num_tasks; } else {
diff --git a/chrome/browser/extensions/extension_garbage_collector.cc b/chrome/browser/extensions/extension_garbage_collector.cc index 3a546bf..2e8b85c 100644 --- a/chrome/browser/extensions/extension_garbage_collector.cc +++ b/chrome/browser/extensions/extension_garbage_collector.cc
@@ -223,7 +223,7 @@ const ExtensionSet extensions = ExtensionRegistry::Get(context_)->GenerateInstalledExtensionsSet(); for (const auto& ext : extensions) { - if (extensions::util::LegacyHasIsolatedStorage(ext.get())) { + if (extensions::util::HasIsolatedStorage(*ext.get(), context_)) { active_paths.insert( util::GetStoragePartitionForExtensionId(ext->id(), context_) ->GetPath());
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc index 6528e43..5c42b52c 100644 --- a/chrome/browser/extensions/extension_service.cc +++ b/chrome/browser/extensions/extension_service.cc
@@ -1120,7 +1120,7 @@ // TODO(kalman): Convert ExtensionSpecialStoragePolicy to a // BrowserContextKeyedService and use ExtensionRegistryObserver. profile_->GetExtensionSpecialStoragePolicy()->GrantRightsForExtension( - extension.get()); + extension.get(), profile_); // TODO(kalman): This is broken. The crash reporter is process-wide so doesn't // work properly multi-profile. Besides which, it should be using @@ -1152,7 +1152,7 @@ // TODO(kalman): Convert ExtensionSpecialStoragePolicy to a // BrowserContextKeyedService and use ExtensionRegistryObserver. profile_->GetExtensionSpecialStoragePolicy()->RevokeRightsForExtension( - extension.get()); + extension.get(), profile_); #if BUILDFLAG(IS_CHROMEOS_ASH) // Revoke external file access for the extension from its file system context.
diff --git a/chrome/browser/extensions/extension_special_storage_policy.cc b/chrome/browser/extensions/extension_special_storage_policy.cc index e65bef40a..f0e9c248 100644 --- a/chrome/browser/extensions/extension_special_storage_policy.cc +++ b/chrome/browser/extensions/extension_special_storage_policy.cc
@@ -30,6 +30,7 @@ #include "components/content_settings/core/browser/cookie_settings.h" #include "components/content_settings/core/common/content_settings.h" #include "components/content_settings/core/common/content_settings_types.h" +#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/url_constants.h" @@ -213,7 +214,8 @@ } void ExtensionSpecialStoragePolicy::GrantRightsForExtension( - const extensions::Extension* extension) { + const extensions::Extension* extension, + content::BrowserContext* context) { base::AutoLock locker(lock_); DCHECK(extension); @@ -229,7 +231,7 @@ APIPermissionID::kUnlimitedStorage) || extension->permissions_data()->HasAPIPermission( APIPermissionID::kFileBrowserHandler) || - extensions::util::LegacyHasIsolatedStorage(extension) || + extensions::util::HasIsolatedStorage(*extension, context) || extension->is_app()) { if (NeedsProtection(extension) && protected_apps_.Add(extension)) { change_flags |= SpecialStoragePolicy::STORAGE_PROTECTED; @@ -246,7 +248,7 @@ file_handler_extensions_.Add(extension); } - if (extensions::util::LegacyHasIsolatedStorage(extension)) { + if (extensions::util::HasIsolatedStorage(*extension, context)) { isolated_extensions_.Add(extension); } } @@ -258,7 +260,8 @@ } void ExtensionSpecialStoragePolicy::RevokeRightsForExtension( - const extensions::Extension* extension) { + const extensions::Extension* extension, + content::BrowserContext* context) { base::AutoLock locker(lock_); DCHECK(extension); @@ -274,7 +277,7 @@ APIPermissionID::kUnlimitedStorage) || extension->permissions_data()->HasAPIPermission( APIPermissionID::kFileBrowserHandler) || - extensions::util::LegacyHasIsolatedStorage(extension) || + extensions::util::HasIsolatedStorage(*extension, context) || extension->is_app()) { if (NeedsProtection(extension) && protected_apps_.Remove(extension)) { change_flags |= SpecialStoragePolicy::STORAGE_PROTECTED; @@ -291,7 +294,7 @@ file_handler_extensions_.Remove(extension); } - if (extensions::util::LegacyHasIsolatedStorage(extension)) { + if (extensions::util::HasIsolatedStorage(*extension, context)) { isolated_extensions_.Remove(extension); } }
diff --git a/chrome/browser/extensions/extension_special_storage_policy.h b/chrome/browser/extensions/extension_special_storage_policy.h index e435d29..9b8632a 100644 --- a/chrome/browser/extensions/extension_special_storage_policy.h +++ b/chrome/browser/extensions/extension_special_storage_policy.h
@@ -17,6 +17,10 @@ #include "url/gurl.h" #include "url/origin.h" +namespace content { +class BrowserContext; +} + namespace content_settings { class CookieSettings; } @@ -43,8 +47,10 @@ bool IsStorageDurable(const GURL& origin) override; // Methods used by the ExtensionService to populate this class. - void GrantRightsForExtension(const extensions::Extension* extension); - void RevokeRightsForExtension(const extensions::Extension* extension); + void GrantRightsForExtension(const extensions::Extension* extension, + content::BrowserContext* context); + void RevokeRightsForExtension(const extensions::Extension* extension, + content::BrowserContext* context); void RevokeRightsForAllExtensions(); // Decides whether the storage for |extension|'s web extent needs protection.
diff --git a/chrome/browser/extensions/extension_special_storage_policy_unittest.cc b/chrome/browser/extensions/extension_special_storage_policy_unittest.cc index 7b6812d7..e98ff74 100644 --- a/chrome/browser/extensions/extension_special_storage_policy_unittest.cc +++ b/chrome/browser/extensions/extension_special_storage_policy_unittest.cc
@@ -202,8 +202,9 @@ } TEST_F(ExtensionSpecialStoragePolicyTest, AppWithProtectedStorage) { + TestingProfile profile; scoped_refptr<Extension> extension(CreateProtectedApp()); - policy_->GrantRightsForExtension(extension.get()); + policy_->GrantRightsForExtension(extension.get(), &profile); ExtensionSet protecting_extensions; protecting_extensions.Insert(extension); ExtensionSet empty_set; @@ -216,15 +217,16 @@ ExpectProtectedBy(protecting_extensions, GURL("https://bar.wildcards/")); ExpectProtectedBy(empty_set, GURL("http://not_listed/")); - policy_->RevokeRightsForExtension(extension.get()); + policy_->RevokeRightsForExtension(extension.get(), &profile); ExpectProtectedBy(empty_set, GURL("http://explicit/")); ExpectProtectedBy(empty_set, GURL("http://foo.wildcards/")); ExpectProtectedBy(empty_set, GURL("https://bar.wildcards/")); } TEST_F(ExtensionSpecialStoragePolicyTest, AppWithUnlimitedStorage) { + TestingProfile profile; scoped_refptr<Extension> extension(CreateUnlimitedApp()); - policy_->GrantRightsForExtension(extension.get()); + policy_->GrantRightsForExtension(extension.get(), &profile); ExtensionSet protecting_extensions; protecting_extensions.Insert(extension); ExtensionSet empty_set; @@ -242,7 +244,7 @@ EXPECT_TRUE(policy_->IsStorageUnlimited(GURL("https://bar.wildcards/"))); EXPECT_FALSE(policy_->IsStorageUnlimited(GURL("http://not_listed/"))); - policy_->RevokeRightsForExtension(extension.get()); + policy_->RevokeRightsForExtension(extension.get(), &profile); ExpectProtectedBy(empty_set, GURL("http://explicit/")); ExpectProtectedBy(empty_set, GURL("https://foo.wildcards/")); ExpectProtectedBy(empty_set, GURL("https://foo.wildcards/")); @@ -263,8 +265,9 @@ TEST_F(ExtensionSpecialStoragePolicyTest, ExplicitlyUnlimitedOriginsShouldNotInterferWithExtensions) { + TestingProfile profile; scoped_refptr<Extension> extension(CreateUnlimitedApp()); - policy_->GrantRightsForExtension(extension.get()); + policy_->GrantRightsForExtension(extension.get(), &profile); policy_->AddOriginWithUnlimitedStorage( url::Origin::Create(GURL("http://unlimited/"))); @@ -277,8 +280,9 @@ TEST_F(ExtensionSpecialStoragePolicyTest, HasIsolatedStorage) { const GURL kHttpUrl("http://foo"); const GURL kExtensionUrl("chrome-extension://bar"); + TestingProfile profile; scoped_refptr<Extension> app(CreateRegularApp()); - policy_->GrantRightsForExtension(app.get()); + policy_->GrantRightsForExtension(app.get(), &profile); EXPECT_FALSE(policy_->HasIsolatedStorage(kHttpUrl)); EXPECT_FALSE(policy_->HasIsolatedStorage(kExtensionUrl)); @@ -286,10 +290,11 @@ } TEST_F(ExtensionSpecialStoragePolicyTest, OverlappingApps) { + TestingProfile profile; scoped_refptr<Extension> protected_app(CreateProtectedApp()); scoped_refptr<Extension> unlimited_app(CreateUnlimitedApp()); - policy_->GrantRightsForExtension(protected_app.get()); - policy_->GrantRightsForExtension(unlimited_app.get()); + policy_->GrantRightsForExtension(protected_app.get(), &profile); + policy_->GrantRightsForExtension(unlimited_app.get(), &profile); ExtensionSet protecting_extensions; ExtensionSet empty_set; protecting_extensions.Insert(protected_app); @@ -307,7 +312,7 @@ EXPECT_TRUE(policy_->IsStorageUnlimited(GURL("https://bar.wildcards/"))); EXPECT_FALSE(policy_->IsStorageUnlimited(GURL("http://not_listed/"))); - policy_->RevokeRightsForExtension(unlimited_app.get()); + policy_->RevokeRightsForExtension(unlimited_app.get(), &profile); protecting_extensions.Remove(unlimited_app->id()); EXPECT_FALSE(policy_->IsStorageUnlimited(GURL("http://explicit/"))); EXPECT_FALSE(policy_->IsStorageUnlimited(GURL("https://foo.wildcards/"))); @@ -316,7 +321,7 @@ ExpectProtectedBy(protecting_extensions, GURL("http://foo.wildcards/")); ExpectProtectedBy(protecting_extensions, GURL("https://bar.wildcards/")); - policy_->RevokeRightsForExtension(protected_app.get()); + policy_->RevokeRightsForExtension(protected_app.get(), &profile); ExpectProtectedBy(empty_set, GURL("http://explicit/")); ExpectProtectedBy(empty_set, GURL("http://foo.wildcards/")); ExpectProtectedBy(empty_set, GURL("https://bar.wildcards/")); @@ -370,6 +375,7 @@ } TEST_F(ExtensionSpecialStoragePolicyTest, NotificationTest) { + TestingProfile profile; PolicyChangeObserver observer; policy_->AddObserver(&observer); @@ -389,14 +395,14 @@ for (size_t i = 0; i < std::size(apps); ++i) { SCOPED_TRACE(testing::Message() << "i: " << i); observer.ExpectGrant(apps[i]->id(), change_flags[i]); - policy_->GrantRightsForExtension(apps[i].get()); + policy_->GrantRightsForExtension(apps[i].get(), &profile); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(observer.IsCompleted()); } for (size_t i = 0; i < std::size(apps); ++i) { SCOPED_TRACE(testing::Message() << "i: " << i); - policy_->GrantRightsForExtension(apps[i].get()); + policy_->GrantRightsForExtension(apps[i].get(), &profile); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(observer.IsCompleted()); } @@ -404,14 +410,14 @@ for (size_t i = 0; i < std::size(apps); ++i) { SCOPED_TRACE(testing::Message() << "i: " << i); observer.ExpectRevoke(apps[i]->id(), change_flags[i]); - policy_->RevokeRightsForExtension(apps[i].get()); + policy_->RevokeRightsForExtension(apps[i].get(), &profile); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(observer.IsCompleted()); } for (size_t i = 0; i < std::size(apps); ++i) { SCOPED_TRACE(testing::Message() << "i: " << i); - policy_->RevokeRightsForExtension(apps[i].get()); + policy_->RevokeRightsForExtension(apps[i].get(), &profile); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(observer.IsCompleted()); }
diff --git a/chrome/browser/extensions/extension_util.cc b/chrome/browser/extensions/extension_util.cc index 7b4c98a..cc57da9 100644 --- a/chrome/browser/extensions/extension_util.cc +++ b/chrome/browser/extensions/extension_util.cc
@@ -91,11 +91,7 @@ } #endif - return LegacyHasIsolatedStorage(&extension); -} - -bool LegacyHasIsolatedStorage(const Extension* extension) { - return extension->is_platform_app(); + return extension.is_platform_app(); } void SetIsIncognitoEnabled(const std::string& extension_id,
diff --git a/chrome/browser/extensions/extension_util.h b/chrome/browser/extensions/extension_util.h index 397cca16..c706a7b 100644 --- a/chrome/browser/extensions/extension_util.h +++ b/chrome/browser/extensions/extension_util.h
@@ -36,11 +36,6 @@ bool HasIsolatedStorage(const Extension& extension, content::BrowserContext* context); -// Returns whether `extension` has isolated storage due to being a platform app. -// TODO(https://crbug.com/159932): Move all callers to HasIsolatedStorage, so -// that Chrome OS sign-in profile cases are handled as well. -bool LegacyHasIsolatedStorage(const Extension* extension); - // Sets whether |extension_id| can run in an incognito window. Reloads the // extension if it's enabled since this permission is applied at loading time // only. Note that an ExtensionService must exist.
diff --git a/chrome/browser/extensions/system_display/display_info_provider_chromeos.cc b/chrome/browser/extensions/system_display/display_info_provider_chromeos.cc index 428dc4b..5d5e8199 100644 --- a/chrome/browser/extensions/system_display/display_info_provider_chromeos.cc +++ b/chrome/browser/extensions/system_display/display_info_provider_chromeos.cc
@@ -15,7 +15,6 @@ #endif #include "base/functional/bind.h" -#include "base/strings/string_number_conversions.h" #include "chrome/browser/extensions/system_display/display_info_provider.h" #include "chrome/browser/extensions/system_display/display_info_provider_utils.h" #include "extensions/common/api/system_display.h" @@ -30,225 +29,6 @@ namespace { -int64_t GetDisplayId(const std::string& display_id_str) { - int64_t display_id; - if (!base::StringToInt64(display_id_str, &display_id)) { - display_id = display::kInvalidDisplayId; - } - return display_id; -} - -display::Display GetDisplayForId(const std::string& display_id_str) { - int64_t id = GetDisplayId(display_id_str); - display::Display display; - display::Screen::GetScreen()->GetDisplayWithDisplayId(id, &display); - return display; -} - -crosapi::mojom::DisplayLayoutPosition GetDisplayLayoutPosition( - system_display::LayoutPosition position) { - switch (position) { - case system_display::LAYOUT_POSITION_TOP: - return crosapi::mojom::DisplayLayoutPosition::kTop; - case system_display::LAYOUT_POSITION_RIGHT: - return crosapi::mojom::DisplayLayoutPosition::kRight; - case system_display::LAYOUT_POSITION_BOTTOM: - return crosapi::mojom::DisplayLayoutPosition::kBottom; - case system_display::LAYOUT_POSITION_LEFT: - case system_display::LAYOUT_POSITION_NONE: - return crosapi::mojom::DisplayLayoutPosition::kLeft; - } - NOTREACHED(); - return crosapi::mojom::DisplayLayoutPosition::kLeft; -} - -gfx::Insets GetInsets(const system_display::Insets& insets) { - return gfx::Insets::TLBR(insets.top, insets.left, insets.bottom, - insets.right); -} - -bool IsValidRotation(int rotation) { - return rotation == -1 || rotation == 0 || rotation == 90 || rotation == 180 || - rotation == 270; -} - -crosapi::mojom::DisplayRotationOptions GetMojomDisplayRotationOptions( - int rotation_value) { - DCHECK(IsValidRotation(rotation_value)); - - switch (rotation_value) { - case -1: - return crosapi::mojom::DisplayRotationOptions::kAutoRotate; - case 0: - return crosapi::mojom::DisplayRotationOptions::kZeroDegrees; - case 90: - return crosapi::mojom::DisplayRotationOptions::k90Degrees; - case 180: - return crosapi::mojom::DisplayRotationOptions::k180Degrees; - case 270: - return crosapi::mojom::DisplayRotationOptions::k270Degrees; - default: - NOTREACHED(); - return crosapi::mojom::DisplayRotationOptions::kZeroDegrees; - } -} - -int GetRotationFromMojomDisplayRotationInfo( - crosapi::mojom::DisplayRotationOptions rotation_options) { - switch (rotation_options) { - case crosapi::mojom::DisplayRotationOptions::kAutoRotate: - return -1; - case crosapi::mojom::DisplayRotationOptions::kZeroDegrees: - return 0; - case crosapi::mojom::DisplayRotationOptions::k90Degrees: - return 90; - case crosapi::mojom::DisplayRotationOptions::k180Degrees: - return 180; - case crosapi::mojom::DisplayRotationOptions::k270Degrees: - return 270; - } -} - -// Validates the DisplayProperties input. Does not perform any tests with -// DisplayManager dependencies. Returns an error string on failure or nullopt -// on success. -absl::optional<std::string> ValidateDisplayPropertiesInput( - const std::string& display_id_str, - const system_display::DisplayProperties& info) { - int64_t id = GetDisplayId(display_id_str); - if (id == display::kInvalidDisplayId) { - return "Invalid display id"; - } - - const display::Display& primary = - display::Screen::GetScreen()->GetPrimaryDisplay(); - bool is_primary = id == primary.id() || (info.is_primary && *info.is_primary); - - if (info.is_unified) { - if (!is_primary) { - return "Unified desktop mode can only be set for the primary display."; - } - // Setting isUnfied may change the display layout so no other properties - // should be set. - if (info.mirroring_source_id) { - return "Unified desktop mode can not be set with mirroringSourceId."; - } - if (info.bounds_origin_x || info.bounds_origin_y || info.rotation || - info.overscan || info.display_mode || info.display_zoom_factor) { - LOG(WARNING) - << "Unified mode set with other properties which will be ignored."; - } - return absl::nullopt; - } - - // If mirroring source parameter is specified, no other properties should be - // set the display list may change when mirroring is applied. - if (info.mirroring_source_id && - (info.is_primary || info.bounds_origin_x || info.bounds_origin_y || - info.rotation || info.overscan || info.display_mode || - info.display_zoom_factor)) { - return "No other parameter should be set with mirroringSourceId."; - } - - // Verify the rotation value is valid. - if (info.rotation && !IsValidRotation(*info.rotation)) { - return "Invalid rotation."; - } - - return absl::nullopt; -} - -system_display::DisplayMode GetDisplayModeFromMojo( - const crosapi::mojom::DisplayMode mode) { - system_display::DisplayMode result; - result.width = mode.size.width(); - result.height = mode.size.height(); - result.width_in_native_pixels = mode.size_in_native_pixels.width(); - result.height_in_native_pixels = mode.size_in_native_pixels.height(); - result.device_scale_factor = mode.device_scale_factor; - result.refresh_rate = mode.refresh_rate; - result.is_native = mode.is_native; - result.is_interlaced = mode.is_interlaced; - return result; -} - -system_display::DisplayUnitInfo GetDisplayUnitInfoFromMojo( - const crosapi::mojom::DisplayUnitInfo& mojo_info) { - system_display::DisplayUnitInfo info; - info.id = mojo_info.id; - info.name = mojo_info.name; - if (mojo_info.edid) { - info.edid.emplace(); - info.edid->manufacturer_id = mojo_info.edid->manufacturer_id; - info.edid->product_id = mojo_info.edid->product_id; - info.edid->year_of_manufacture = mojo_info.edid->year_of_manufacture; - } - info.is_primary = mojo_info.is_primary; - info.is_internal = mojo_info.is_internal; - info.is_enabled = mojo_info.is_enabled; - info.is_auto_rotation_allowed = mojo_info.is_auto_rotation_allowed; - info.dpi_x = mojo_info.dpi_x; - info.dpi_y = mojo_info.dpi_y; - info.rotation = - GetRotationFromMojomDisplayRotationInfo(mojo_info.rotation_options); - const gfx::Rect& bounds = mojo_info.bounds; - info.bounds.left = bounds.x(); - info.bounds.top = bounds.y(); - info.bounds.width = bounds.width(); - info.bounds.height = bounds.height(); - const gfx::Insets& overscan = mojo_info.overscan; - info.overscan.left = overscan.left(); - info.overscan.top = overscan.top(); - info.overscan.right = overscan.right(); - info.overscan.bottom = overscan.bottom(); - const gfx::Rect& work_area = mojo_info.work_area; - info.work_area.left = work_area.x(); - info.work_area.top = work_area.y(); - info.work_area.width = work_area.width(); - info.work_area.height = work_area.height(); - for (const crosapi::mojom::DisplayModePtr& mode : - mojo_info.available_display_modes) { - info.modes.emplace_back(GetDisplayModeFromMojo(*mode)); - } - if (!info.modes.empty()) { - int index = mojo_info.selected_display_mode_index; - if (index < 0 || index >= static_cast<int>(info.modes.size())) { - index = 0; - } - info.modes[index].is_selected = true; - } - info.has_touch_support = mojo_info.has_touch_support; - info.has_accelerometer_support = mojo_info.has_accelerometer_support; - info.available_display_zoom_factors = - mojo_info.available_display_zoom_factors; - info.display_zoom_factor = mojo_info.display_zoom_factor; - return info; -} - -crosapi::mojom::TouchCalibrationPairPtr GetTouchCalibrationPair( - const system_display::TouchCalibrationPair& pair) { - auto result = crosapi::mojom::TouchCalibrationPair::New(); - result->display_point = - gfx::Point(pair.display_point.x, pair.display_point.y); - result->touch_point = gfx::Point(pair.touch_point.x, pair.touch_point.y); - return result; -} - -void SetDisplayUnitInfoLayoutProperties( - const crosapi::mojom::DisplayLayoutInfo& layout, - system_display::DisplayUnitInfo* display) { - display->is_unified = - layout.layout_mode == crosapi::mojom::DisplayLayoutMode::kUnified; - if (layout.mirror_source_id) { - display->mirroring_source_id = *layout.mirror_source_id; - if (layout.mirror_destination_ids) { - for (const std::string& id : *layout.mirror_destination_ids) { - display->mirroring_destination_ids.push_back(id); - } - } - } -} - void RunResultCallback(DisplayInfoProvider::ErrorCallback callback, absl::optional<std::string> error) { if (error) {
diff --git a/chrome/browser/extensions/system_display/display_info_provider_utils.cc b/chrome/browser/extensions/system_display/display_info_provider_utils.cc index 23236c5..90b1d23 100644 --- a/chrome/browser/extensions/system_display/display_info_provider_utils.cc +++ b/chrome/browser/extensions/system_display/display_info_provider_utils.cc
@@ -4,7 +4,11 @@ #include "chrome/browser/extensions/system_display/display_info_provider_utils.h" -#include "extensions/common/api/system_display.h" +#include "base/strings/string_number_conversions.h" +#include "chromeos/crosapi/mojom/cros_display_config.mojom.h" +#include "ui/display/display.h" +#include "ui/display/screen.h" +#include "ui/display/types/display_constants.h" namespace extensions { @@ -46,4 +50,220 @@ std::move(callback).Run(std::move(result)); } +int64_t GetDisplayId(const std::string& display_id_str) { + int64_t display_id; + if (!base::StringToInt64(display_id_str, &display_id)) { + display_id = display::kInvalidDisplayId; + } + return display_id; +} + +display::Display GetDisplayForId(const std::string& display_id_str) { + int64_t id = GetDisplayId(display_id_str); + display::Display display; + display::Screen::GetScreen()->GetDisplayWithDisplayId(id, &display); + return display; +} + +crosapi::mojom::DisplayLayoutPosition GetDisplayLayoutPosition( + system_display::LayoutPosition position) { + switch (position) { + case system_display::LAYOUT_POSITION_TOP: + return crosapi::mojom::DisplayLayoutPosition::kTop; + case system_display::LAYOUT_POSITION_RIGHT: + return crosapi::mojom::DisplayLayoutPosition::kRight; + case system_display::LAYOUT_POSITION_BOTTOM: + return crosapi::mojom::DisplayLayoutPosition::kBottom; + case system_display::LAYOUT_POSITION_LEFT: + case system_display::LAYOUT_POSITION_NONE: + return crosapi::mojom::DisplayLayoutPosition::kLeft; + } + NOTREACHED(); + return crosapi::mojom::DisplayLayoutPosition::kLeft; +} + +gfx::Insets GetInsets(const system_display::Insets& insets) { + return gfx::Insets::TLBR(insets.top, insets.left, insets.bottom, + insets.right); +} + +bool IsValidRotation(int rotation) { + return rotation == -1 || rotation == 0 || rotation == 90 || rotation == 180 || + rotation == 270; +} + +crosapi::mojom::DisplayRotationOptions GetMojomDisplayRotationOptions( + int rotation_value) { + DCHECK(IsValidRotation(rotation_value)); + + switch (rotation_value) { + case -1: + return crosapi::mojom::DisplayRotationOptions::kAutoRotate; + case 0: + return crosapi::mojom::DisplayRotationOptions::kZeroDegrees; + case 90: + return crosapi::mojom::DisplayRotationOptions::k90Degrees; + case 180: + return crosapi::mojom::DisplayRotationOptions::k180Degrees; + case 270: + return crosapi::mojom::DisplayRotationOptions::k270Degrees; + default: + NOTREACHED(); + return crosapi::mojom::DisplayRotationOptions::kZeroDegrees; + } +} + +int GetRotationFromMojomDisplayRotationInfo( + crosapi::mojom::DisplayRotationOptions rotation_options) { + switch (rotation_options) { + case crosapi::mojom::DisplayRotationOptions::kAutoRotate: + return -1; + case crosapi::mojom::DisplayRotationOptions::kZeroDegrees: + return 0; + case crosapi::mojom::DisplayRotationOptions::k90Degrees: + return 90; + case crosapi::mojom::DisplayRotationOptions::k180Degrees: + return 180; + case crosapi::mojom::DisplayRotationOptions::k270Degrees: + return 270; + } +} + +absl::optional<std::string> ValidateDisplayPropertiesInput( + const std::string& display_id_str, + const system_display::DisplayProperties& info) { + int64_t id = GetDisplayId(display_id_str); + if (id == display::kInvalidDisplayId) { + return "Invalid display id"; + } + + const display::Display& primary = + display::Screen::GetScreen()->GetPrimaryDisplay(); + bool is_primary = id == primary.id() || (info.is_primary && *info.is_primary); + + if (info.is_unified) { + if (!is_primary) { + return "Unified desktop mode can only be set for the primary display."; + } + // Setting isUnfied may change the display layout so no other properties + // should be set. + if (info.mirroring_source_id) { + return "Unified desktop mode can not be set with mirroringSourceId."; + } + if (info.bounds_origin_x || info.bounds_origin_y || info.rotation || + info.overscan || info.display_mode || info.display_zoom_factor) { + LOG(WARNING) + << "Unified mode set with other properties which will be ignored."; + } + return absl::nullopt; + } + + // If mirroring source parameter is specified, no other properties should be + // set the display list may change when mirroring is applied. + if (info.mirroring_source_id && + (info.is_primary || info.bounds_origin_x || info.bounds_origin_y || + info.rotation || info.overscan || info.display_mode || + info.display_zoom_factor)) { + return "No other parameter should be set with mirroringSourceId."; + } + + // Verify the rotation value is valid. + if (info.rotation && !IsValidRotation(*info.rotation)) { + return "Invalid rotation."; + } + + return absl::nullopt; +} + +system_display::DisplayMode GetDisplayModeFromMojo( + const crosapi::mojom::DisplayMode mode) { + system_display::DisplayMode result; + result.width = mode.size.width(); + result.height = mode.size.height(); + result.width_in_native_pixels = mode.size_in_native_pixels.width(); + result.height_in_native_pixels = mode.size_in_native_pixels.height(); + result.device_scale_factor = mode.device_scale_factor; + result.refresh_rate = mode.refresh_rate; + result.is_native = mode.is_native; + result.is_interlaced = mode.is_interlaced; + return result; +} + +system_display::DisplayUnitInfo GetDisplayUnitInfoFromMojo( + const crosapi::mojom::DisplayUnitInfo& mojo_info) { + system_display::DisplayUnitInfo info; + info.id = mojo_info.id; + info.name = mojo_info.name; + if (mojo_info.edid) { + info.edid.emplace(); + info.edid->manufacturer_id = mojo_info.edid->manufacturer_id; + info.edid->product_id = mojo_info.edid->product_id; + info.edid->year_of_manufacture = mojo_info.edid->year_of_manufacture; + } + info.is_primary = mojo_info.is_primary; + info.is_internal = mojo_info.is_internal; + info.is_enabled = mojo_info.is_enabled; + info.is_auto_rotation_allowed = mojo_info.is_auto_rotation_allowed; + info.dpi_x = mojo_info.dpi_x; + info.dpi_y = mojo_info.dpi_y; + info.rotation = + GetRotationFromMojomDisplayRotationInfo(mojo_info.rotation_options); + const gfx::Rect& bounds = mojo_info.bounds; + info.bounds.left = bounds.x(); + info.bounds.top = bounds.y(); + info.bounds.width = bounds.width(); + info.bounds.height = bounds.height(); + const gfx::Insets& overscan = mojo_info.overscan; + info.overscan.left = overscan.left(); + info.overscan.top = overscan.top(); + info.overscan.right = overscan.right(); + info.overscan.bottom = overscan.bottom(); + const gfx::Rect& work_area = mojo_info.work_area; + info.work_area.left = work_area.x(); + info.work_area.top = work_area.y(); + info.work_area.width = work_area.width(); + info.work_area.height = work_area.height(); + for (const crosapi::mojom::DisplayModePtr& mode : + mojo_info.available_display_modes) { + info.modes.emplace_back(GetDisplayModeFromMojo(*mode)); + } + if (!info.modes.empty()) { + int index = mojo_info.selected_display_mode_index; + if (index < 0 || index >= static_cast<int>(info.modes.size())) { + index = 0; + } + info.modes[index].is_selected = true; + } + info.has_touch_support = mojo_info.has_touch_support; + info.has_accelerometer_support = mojo_info.has_accelerometer_support; + info.available_display_zoom_factors = + mojo_info.available_display_zoom_factors; + info.display_zoom_factor = mojo_info.display_zoom_factor; + return info; +} + +crosapi::mojom::TouchCalibrationPairPtr GetTouchCalibrationPair( + const system_display::TouchCalibrationPair& pair) { + auto result = crosapi::mojom::TouchCalibrationPair::New(); + result->display_point = + gfx::Point(pair.display_point.x, pair.display_point.y); + result->touch_point = gfx::Point(pair.touch_point.x, pair.touch_point.y); + return result; +} + +void SetDisplayUnitInfoLayoutProperties( + const crosapi::mojom::DisplayLayoutInfo& layout, + system_display::DisplayUnitInfo* display) { + display->is_unified = + layout.layout_mode == crosapi::mojom::DisplayLayoutMode::kUnified; + if (layout.mirror_source_id) { + display->mirroring_source_id = *layout.mirror_source_id; + if (layout.mirror_destination_ids) { + for (const std::string& id : *layout.mirror_destination_ids) { + display->mirroring_destination_ids.push_back(id); + } + } + } +} + } // namespace extensions
diff --git a/chrome/browser/extensions/system_display/display_info_provider_utils.h b/chrome/browser/extensions/system_display/display_info_provider_utils.h index 98055a3d..708c0f8 100644 --- a/chrome/browser/extensions/system_display/display_info_provider_utils.h +++ b/chrome/browser/extensions/system_display/display_info_provider_utils.h
@@ -5,19 +5,62 @@ #ifndef CHROME_BROWSER_EXTENSIONS_SYSTEM_DISPLAY_DISPLAY_INFO_PROVIDER_UTILS_H_ #define CHROME_BROWSER_EXTENSIONS_SYSTEM_DISPLAY_DISPLAY_INFO_PROVIDER_UTILS_H_ -#include "chromeos/crosapi/mojom/cros_display_config.mojom.h" +#include "chromeos/crosapi/mojom/cros_display_config.mojom-forward.h" #include "extensions/browser/api/system_display/display_info_provider.h" +#include "extensions/common/api/system_display.h" +#include "ui/gfx/geometry/insets.h" namespace extensions { // Callback function for CrosDisplayConfigController crosapi interface. -// Reused by both ash and lacros implementations of DisplayInfoProvider. // Converts input display layout |info| from crosapi to extension api type. // Passes converted array into a |callback|. void OnGetDisplayLayoutResult( base::OnceCallback<void(DisplayInfoProvider::DisplayLayoutList)> callback, crosapi::mojom::DisplayLayoutInfoPtr info); +// Converts display id string to number. +// Returns invalid id in case of error. +int64_t GetDisplayId(const std::string& display_id_str); + +// Returns a display object for if display id is found. +// Return empty display object otherwise. +display::Display GetDisplayForId(const std::string& display_id_str); + +// Converts display layout |position| from extension api to crosapi type. +crosapi::mojom::DisplayLayoutPosition GetDisplayLayoutPosition( + api::system_display::LayoutPosition position); + +// Converts system display |insets| to gfx type. +gfx::Insets GetInsets(const api::system_display::Insets& insets); + +// Converts int |rotation_value| to crosapi type. +crosapi::mojom::DisplayRotationOptions GetMojomDisplayRotationOptions( + int rotation_value); + +// Converts crosapi |rotation_options| to int. +int GetRotationFromMojomDisplayRotationInfo( + crosapi::mojom::DisplayRotationOptions rotation_options); + +// Validates the DisplayProperties input. Does not perform any tests with +// DisplayManager dependencies. Returns an error string on failure or nullopt +// on success. +absl::optional<std::string> ValidateDisplayPropertiesInput( + const std::string& display_id_str, + const api::system_display::DisplayProperties& info); + +// Converts display unit crosapi |mojo_info| to system display type. +api::system_display::DisplayUnitInfo GetDisplayUnitInfoFromMojo( + const crosapi::mojom::DisplayUnitInfo& mojo_info); + +// Converts system display calibration |pair| to crosapi type. +crosapi::mojom::TouchCalibrationPairPtr GetTouchCalibrationPair( + const api::system_display::TouchCalibrationPair& pair); + +void SetDisplayUnitInfoLayoutProperties( + const crosapi::mojom::DisplayLayoutInfo& layout, + api::system_display::DisplayUnitInfo* display); + } // namespace extensions #endif // CHROME_BROWSER_EXTENSIONS_SYSTEM_DISPLAY_DISPLAY_INFO_PROVIDER_UTILS_H_
diff --git a/chrome/browser/favicon/content_favicon_driver_browsertest.cc b/chrome/browser/favicon/content_favicon_driver_browsertest.cc index 7b5c86f0..e40e70b 100644 --- a/chrome/browser/favicon/content_favicon_driver_browsertest.cc +++ b/chrome/browser/favicon/content_favicon_driver_browsertest.cc
@@ -311,8 +311,7 @@ embedded_test_server()->GetURL("/favicon/page_with_favicon.html"); GURL icon_url = embedded_test_server()->GetURL("/favicon/icon.png"); GURL initial_url = embedded_test_server()->GetURL("/empty.html"); - EXPECT_CALL(observer, DidUpdateFaviconURL( - web_contents()->GetPrimaryMainFrame(), testing::_)); + EXPECT_CALL(observer, DidUpdateFaviconURL(testing::_, testing::_)); prerender_helper().NavigatePrimaryPage(initial_url); {
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/feedmanagement/FeedManagementMediator.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/feedmanagement/FeedManagementMediator.java index a8e4167..ecf1e59 100644 --- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/feedmanagement/FeedManagementMediator.java +++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/feedmanagement/FeedManagementMediator.java
@@ -14,7 +14,9 @@ import android.view.View.OnClickListener; import androidx.annotation.VisibleForTesting; +import androidx.browser.customtabs.CustomTabsClient; import androidx.browser.customtabs.CustomTabsIntent; +import androidx.browser.customtabs.CustomTabsSession; import org.chromium.base.Log; import org.chromium.base.compat.ApiHelperForM; @@ -22,6 +24,7 @@ import org.chromium.chrome.browser.feed.R; import org.chromium.chrome.browser.feed.StreamKind; import org.chromium.chrome.browser.feed.v2.FeedUserActionType; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.ui.modelutil.MVCListAdapter.ModelList; import org.chromium.ui.modelutil.ModelListAdapter; import org.chromium.ui.modelutil.PropertyModel; @@ -41,6 +44,8 @@ private final FollowManagementLauncher mFollowManagementLauncher; private final AutoplayManagementLauncher mAutoplayManagementLauncher; private final @StreamKind int mInitiatingStreamKind; + private CustomTabsClient mClient; + private CustomTabsSession mCustomTabsSession; /** * Interface to supply a method which can launch the FollowManagementActivity. @@ -103,25 +108,51 @@ // TODO(petewil): Borrowed these from code we can't link to. How do I keep them in sync? static final String TRUSTED_APPLICATION_CODE_EXTRA = "trusted_application_code_extra"; + // TODO(katzz): Replace with intent extras to be defined in AndroidX; + static final String EXTRA_ACTIVITY_INITIAL_WIDTH_PX = + "androidx.browser.customtabs.extra.INITIAL_ACTIVITY_WIDTH_PX"; + static final String EXTRA_ACTIVITY_INITIAL_HEIGHT_PX = + "androidx.browser.customtabs.extra.INITIAL_ACTIVITY_HEIGHT_PX"; + static final String EXTRA_ACTIVITY_SIDE_SHEET_BREAKPOINT_DP = + "androidx.browser.customtabs.extra.ACTIVITY_SIDE_SHEET_BREAKPOINT_DP"; // Launch a new activity in the same task with the given uri as a CCT. private void launchUriActivity(String uri) { CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); builder.setShowTitle(true); builder.setShareState(CustomTabsIntent.SHARE_STATE_ON); - Intent intent = builder.build().intent; - intent.setData(Uri.parse(uri)); - intent.setAction(Intent.ACTION_VIEW); - intent.setClassName(mContext, "org.chromium.chrome.browser.customtabs.CustomTabActivity"); + if (ChromeFeatureList.sCctResizableSideSheetDiscoverFeedSettings.isEnabled()) { + int displayHeight = mContext.getResources().getDisplayMetrics().heightPixels; + int displayWidth = mContext.getResources().getDisplayMetrics().widthPixels; + int initialHeight = Math.max(displayHeight, displayWidth); + int initialWidth = Math.max(displayHeight, displayWidth) / 2; + int breakPoint = (int) (Math.min(displayHeight, displayWidth) + / mContext.getResources().getDisplayMetrics().density + + 1); - // Do the things that createCustomTabActivityIntent does: - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // Needed for pre-N versions of android. - intent.putExtra(Browser.EXTRA_APPLICATION_ID, mContext.getPackageName()); - - // Adding trusted extras lets us know that the intent came from Chrome. - intent.setPackage(mContext.getPackageName()); - intent.putExtra(TRUSTED_APPLICATION_CODE_EXTRA, getAuthenticationToken()); - mContext.startActivity(intent); + CustomTabsIntent customTabsIntent = builder.build(); + customTabsIntent.intent.setPackage(mContext.getPackageName()); + // Adding trusted extras lets us know that the intent came from Chrome. + customTabsIntent.intent.putExtra( + TRUSTED_APPLICATION_CODE_EXTRA, getAuthenticationToken()); + customTabsIntent.intent.setData(Uri.parse(uri)); + customTabsIntent.intent.putExtra(EXTRA_ACTIVITY_INITIAL_HEIGHT_PX, initialHeight); + customTabsIntent.intent.putExtra(EXTRA_ACTIVITY_INITIAL_WIDTH_PX, initialWidth); + customTabsIntent.intent.putExtra(EXTRA_ACTIVITY_SIDE_SHEET_BREAKPOINT_DP, breakPoint); + customTabsIntent.launchUrl(mContext, Uri.parse(uri)); + } else { + Intent intent = builder.build().intent; + intent.setPackage(mContext.getPackageName()); + // Adding trusted extras lets us know that the intent came from Chrome. + intent.putExtra(TRUSTED_APPLICATION_CODE_EXTRA, getAuthenticationToken()); + intent.setData(Uri.parse(uri)); + intent.setAction(Intent.ACTION_VIEW); + intent.setClassName( + mContext, "org.chromium.chrome.browser.customtabs.CustomTabActivity"); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // Needed for pre-N versions of android. + intent.putExtra(Browser.EXTRA_APPLICATION_ID, mContext.getPackageName()); + mContext.startActivity(intent); + } // TODO(https://crbug.com/1195209): Record uma by calling ReportOtherUserAction // on the stream. }
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/feedmanagement/FeedManagementMediatorTest.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/feedmanagement/FeedManagementMediatorTest.java index 4d3cf83..70c418d 100644 --- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/feedmanagement/FeedManagementMediatorTest.java +++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/feedmanagement/FeedManagementMediatorTest.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.feed.feedmanagement; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; import static org.mockito.Mockito.verify; import android.app.Activity; @@ -27,6 +28,7 @@ import org.chromium.chrome.browser.feed.FeedServiceBridgeJni; import org.chromium.chrome.browser.feed.StreamKind; import org.chromium.chrome.browser.feed.v2.FeedUserActionType; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.ui.modelutil.MVCListAdapter.ModelList; /** @@ -67,7 +69,8 @@ } @Test - public void testHandleActivityClick() { + public void testHandleActivityClick_FlagDisabled() { + ChromeFeatureList.sCctResizableSideSheetDiscoverFeedSettings.setForTesting(false); // Act mFeedManagementMediator.handleActivityClick(null); @@ -75,12 +78,35 @@ Intent intent = mShadowActivity.peekNextStartedActivityForResult().intent; assertEquals( intent.getData(), Uri.parse("https://myactivity.google.com/myactivity?product=50")); + assertEquals( + 0, intent.getIntExtra(FeedManagementMediator.EXTRA_ACTIVITY_INITIAL_WIDTH_PX, 0)); + assertEquals( + 0, intent.getIntExtra(FeedManagementMediator.EXTRA_ACTIVITY_INITIAL_HEIGHT_PX, 0)); verify(mFeedServiceBridgeJniMock) .reportOtherUserAction(TEST_STREAM_KIND, FeedUserActionType.TAPPED_MANAGE_ACTIVITY); } @Test - public void testHandleInterestsClick() { + public void testHandleActivityClick_FlagEnabled() { + ChromeFeatureList.sCctResizableSideSheetDiscoverFeedSettings.setForTesting(true); + // Act + mFeedManagementMediator.handleActivityClick(null); + + // Assert + Intent intent = mShadowActivity.peekNextStartedActivityForResult().intent; + assertEquals( + intent.getData(), Uri.parse("https://myactivity.google.com/myactivity?product=50")); + assertNotEquals( + 0, intent.getIntExtra(FeedManagementMediator.EXTRA_ACTIVITY_INITIAL_WIDTH_PX, 0)); + assertNotEquals( + 0, intent.getIntExtra(FeedManagementMediator.EXTRA_ACTIVITY_INITIAL_HEIGHT_PX, 0)); + verify(mFeedServiceBridgeJniMock) + .reportOtherUserAction(TEST_STREAM_KIND, FeedUserActionType.TAPPED_MANAGE_ACTIVITY); + } + + @Test + public void testHandleInterestsClick_FlagDisabled() { + ChromeFeatureList.sCctResizableSideSheetDiscoverFeedSettings.setForTesting(false); // Act mFeedManagementMediator.handleInterestsClick(null); @@ -88,13 +114,37 @@ Intent intent = mShadowActivity.peekNextStartedActivityForResult().intent; assertEquals(intent.getData(), Uri.parse("https://www.google.com/preferences/interests/yourinterests?sh=n")); + assertEquals( + 0, intent.getIntExtra(FeedManagementMediator.EXTRA_ACTIVITY_INITIAL_WIDTH_PX, 0)); + assertEquals( + 0, intent.getIntExtra(FeedManagementMediator.EXTRA_ACTIVITY_INITIAL_HEIGHT_PX, 0)); verify(mFeedServiceBridgeJniMock) .reportOtherUserAction( TEST_STREAM_KIND, FeedUserActionType.TAPPED_MANAGE_INTERESTS); } @Test - public void testHandleHiddenClick() { + public void testHandleInterestsClick_FlagEnabled() { + ChromeFeatureList.sCctResizableSideSheetDiscoverFeedSettings.setForTesting(true); + // Act + mFeedManagementMediator.handleInterestsClick(null); + + // Assert + Intent intent = mShadowActivity.peekNextStartedActivityForResult().intent; + assertEquals(intent.getData(), + Uri.parse("https://www.google.com/preferences/interests/yourinterests?sh=n")); + assertNotEquals( + 0, intent.getIntExtra(FeedManagementMediator.EXTRA_ACTIVITY_INITIAL_WIDTH_PX, 0)); + assertNotEquals( + 0, intent.getIntExtra(FeedManagementMediator.EXTRA_ACTIVITY_INITIAL_HEIGHT_PX, 0)); + verify(mFeedServiceBridgeJniMock) + .reportOtherUserAction( + TEST_STREAM_KIND, FeedUserActionType.TAPPED_MANAGE_INTERESTS); + } + + @Test + public void testHandleHiddenClick_FlagDisabled() { + ChromeFeatureList.sCctResizableSideSheetDiscoverFeedSettings.setForTesting(false); // Act mFeedManagementMediator.handleHiddenClick(null); @@ -102,6 +152,29 @@ Intent intent = mShadowActivity.peekNextStartedActivityForResult().intent; assertEquals(intent.getData(), Uri.parse("https://www.google.com/preferences/interests/hidden?sh=n")); + assertEquals( + 0, intent.getIntExtra(FeedManagementMediator.EXTRA_ACTIVITY_INITIAL_WIDTH_PX, 0)); + assertEquals( + 0, intent.getIntExtra(FeedManagementMediator.EXTRA_ACTIVITY_INITIAL_HEIGHT_PX, 0)); + verify(mFeedServiceBridgeJniMock) + .reportOtherUserAction( + TEST_STREAM_KIND, FeedUserActionType.TAPPED_MANAGE_INTERESTS); + } + + @Test + public void testHandleHiddenClick_FlagEnabled() { + ChromeFeatureList.sCctResizableSideSheetDiscoverFeedSettings.setForTesting(true); + // Act + mFeedManagementMediator.handleHiddenClick(null); + + // Assert + Intent intent = mShadowActivity.peekNextStartedActivityForResult().intent; + assertEquals(intent.getData(), + Uri.parse("https://www.google.com/preferences/interests/hidden?sh=n")); + assertNotEquals( + 0, intent.getIntExtra(FeedManagementMediator.EXTRA_ACTIVITY_INITIAL_WIDTH_PX, 0)); + assertNotEquals( + 0, intent.getIntExtra(FeedManagementMediator.EXTRA_ACTIVITY_INITIAL_HEIGHT_PX, 0)); verify(mFeedServiceBridgeJniMock) .reportOtherUserAction( TEST_STREAM_KIND, FeedUserActionType.TAPPED_MANAGE_INTERESTS);
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 5625f91f8..58705666d 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -634,7 +634,7 @@ "vykochko@google.com", "autofill-squad-muc@google.com" ], - "expiry_milestone": 113 + "expiry_milestone": 120 }, { "name": "autofill-offer-to-save-card-with-same-last-four", @@ -993,6 +993,11 @@ "expiry_milestone": 121 }, { + "name": "cct-resizable-side-sheet-discover-feed-settings", + "owners": ["katzz", "kgrosu", "jinsukkim"], + "expiry_milestone": 130 + }, + { "name": "cct-resizable-side-sheet-for-third-parties", "owners": ["katzz", "kgrosu", "jinsukkim"], "expiry_milestone": 123 @@ -2476,7 +2481,7 @@ { "name": "enable-fullscreen-api", "owners": [ "ajuma", "joemerramos" ], - "expiry_milestone": 113 + "expiry_milestone": 120 }, { "name": "enable-future-v8-vm-features", @@ -2632,7 +2637,7 @@ { "name": "enable-isolated-sandboxed-iframes", "owners": [ "wjmaclean@chromium.org", "alexmos@chromium.org", "creis@chromium.org" ], - "expiry_milestone": 114 + "expiry_milestone": 122 }, { "name": "enable-isolated-web-app-dev-mode", @@ -2958,11 +2963,6 @@ "expiry_milestone": 116 }, { - "name": "enable-pointer-lock-options", - "owners": [ "eirage", "nzolghadr", "input-dev" ], - "expiry_milestone": 92 - }, - { "name": "enable-power-sounds", "owners": [ "afakhry", "bicioglu", "hongyulong", "nupurjain" ], "expiry_milestone": 123 @@ -3032,6 +3032,16 @@ "expiry_milestone": -1 }, { + "name": "enable-reading-list-account-storage", + "owners": [ "mmrashad", "mastiz", "myuu", "chrome-signin-team" ], + "expiry_milestone": 119 + }, + { + "name": "enable-reading-list-sign-in-promo", + "owners": [ "mmrashad", "mastiz", "myuu", "chrome-signin-team" ], + "expiry_milestone": 119 + }, + { "name": "enable-refine-data-source-reload-reporting", "owners": [ "sczs", "tinazwang" ], "expiry_milestone": 120 @@ -3216,7 +3226,7 @@ { "name": "enable-tab-groups-continuation", "owners": [ "ckitagawa", "fredmello", "memex-team@google.com" ], - "expiry_milestone": 114 + "expiry_milestone": 117 }, { "name": "enable-tab-groups-for-tablets", @@ -3241,7 +3251,7 @@ { "name": "enable-tailored-security-integration", "owners": ["joemerramos", "ajuma", "bling-flags@google.com"], - "expiry_milestone": 114 + "expiry_milestone": 120 }, { "name": "enable-tflite-language-detection", @@ -3664,6 +3674,11 @@ "expiry_milestone": 102 }, { + "name": "expose-out-of-process-video-decoding-to-lacros", + "owners": [ "pmolinalopez", "andrescj" ], + "expiry_milestone": 128 + }, + { "name": "extension-content-verification", "owners": [ "//extensions/OWNERS" ], "expiry_milestone": 86 @@ -4185,7 +4200,7 @@ { "name": "hardware-media-key-handling", "owners": [ "steimel", "media-dev" ], - "expiry_milestone": 113 + "expiry_milestone": 123 }, { "name": "heavy-ad-privacy-mitigations", @@ -6291,13 +6306,13 @@ }, { "name": "request-desktop-site-defaults", - "owners": [ "aishwaryarj", "twellington", "clank-app-team@google.com" ], - "expiry_milestone": 114 + "owners": [ "aishwaryarj@google.com", "skavuluru@google.com", "twellington", "clank-app-team@google.com" ], + "expiry_milestone": 116 }, { "name": "request-desktop-site-defaults-downgrade", - "owners": [ "aishwaryarj", "twellington", "clank-app-team@google.com" ], - "expiry_milestone": 114 + "owners": [ "aishwaryarj@google.com", "skavuluru@google.com", "twellington", "clank-app-team@google.com" ], + "expiry_milestone": 116 }, { "name": "request-desktop-site-defaults-logging", @@ -6316,13 +6331,13 @@ }, { "name": "request-desktop-site-per-site-iph", - "owners": [ "aishwaryarj@google.com", "twellington", "clank-app-team@google.com" ], - "expiry_milestone": 114 + "owners": [ "aishwaryarj@google.com", "skavuluru@google.com", "twellington", "clank-app-team@google.com" ], + "expiry_milestone": 116 }, { "name": "request-desktop-site-zoom", - "owners": [ "aishwaryarj@google.com", "twellington", "clank-app-team@google.com" ], - "expiry_milestone": 114 + "owners": [ "aishwaryarj@google.com", "skavuluru@google.com", "twellington", "clank-app-team@google.com" ], + "expiry_milestone": 116 }, { "name": "restore-session-from-cache", @@ -6495,6 +6510,11 @@ "expiry_milestone": 130 }, { + "name": "sf-symbols-follow-up", + "owners": [ "ewannpv", "gambard", "bling-flags@google.com" ], + "expiry_milestone": 118 + }, + { "name": "share-sheet-migration-android", "owners": [ "wenyufu" ], "expiry_milestone": 121 @@ -7258,6 +7278,11 @@ "expiry_milestone": 120 }, { + "name": "use-out-of-process-video-decoding", + "owners": [ "pmolinalopez", "andrescj" ], + "expiry_milestone": 128 + }, + { "name": "use-passthrough-command-decoder", "owners": [ "//third_party/angle/OWNERS" ], "expiry_milestone": 120 @@ -7275,7 +7300,7 @@ { "name": "use-sf-symbols-omnibox", "owners": [ "ewannpv", "gambard", "bling-flags@google.com" ], - "expiry_milestone": 114 + "expiry_milestone": 116 }, { "name": "use-sha1-server-handshakes", @@ -7492,17 +7517,17 @@ { "name": "webpage-alternative-text-zoom", "owners": [ "rkgibson@google.com", "bling-flags@google.com" ], - "expiry_milestone": 111 + "expiry_milestone": 120 }, { "name": "webpage-default-zoom-from-dynamic-type", "owners": [ "rkgibson@google.com", "bling-flags@google.com" ], - "expiry_milestone": 111 + "expiry_milestone": 120 }, { "name": "webpage-text-zoom-ipad", "owners": [ "rkgibson@google.com", "bling-flags@google.com" ], - "expiry_milestone": 111 + "expiry_milestone": 120 }, { "name": "webui-omnibox-popup", @@ -7510,6 +7535,11 @@ "expiry_milestone": 120 }, { + "name": "webui-system-font", + "owners": [ "dpapad", "johntlee" ], + "expiry_milestone": 120 + }, + { "name": "webui-tab-strip", "owners": [ "yuhengh",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 34332d9d..ee39d88 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -400,14 +400,6 @@ "When enabled, card product name (instead of issuer network) will be shown " "in Payments Autofill UI."; -const char kAutofillEnableCvcForVcnYellowPathName[] = - "Enable CVC Authentication in the yellow path of the VCN retrieval flow"; -const char kAutofillEnableCvcForVcnYellowPathDescription[] = - "When enabled, if the user encounters the yellow path (challenge path) in " - "the VCN retrieval flow and the server denotes that the card is eligible " - "for CVC authentication, CVC authentication will be offered as one of the " - "challenge options."; - const char kAutofillEnableNewCardArtAndNetworkImagesName[] = "Enable showing new card art and network images"; const char kAutofillEnableNewCardArtAndNetworkImagesDescription[] = @@ -2342,6 +2334,11 @@ const char kWebUIOmniboxPopupDescription[] = "If enabled, shows the omnibox suggestions popup in WebUI."; +const char kWebUiSystemFontName[] = "WebUI System font"; +const char kWebUiSystemFontDescription[] = + "If enabled, all WebUI surfaces will use the default UI font of the " + "underlying platform."; + const char kOmniboxMaxURLMatchesName[] = "Omnibox Max URL Matches"; const char kOmniboxMaxURLMatchesDescription[] = "The maximum number of URL matches to show, unless there are no " @@ -2598,12 +2595,6 @@ "When enabled, permissions grants with a durable session model will have " "an expiration date set."; -const char kPointerLockOptionsName[] = "Enables pointer lock options"; -const char kPointerLockOptionsDescription[] = - "Enables pointer lock unadjustedMovement. When unadjustedMovement is set " - "to true, pointer movements wil not be affected by the underlying platform " - "modications such as mouse accelaration."; - const char kPowerBookmarkBackendName[] = "Power bookmark backend"; const char kPowerBookmarkBackendDescription[] = "Enables storing additional metadata to support power bookmark features."; @@ -3626,6 +3617,10 @@ const char kCCTResizableSideSheetName[] = "Side sheet Custom Tabs"; const char kCCTResizableSideSheetDescription[] = "Enable side sheet Custom Tabs"; +const char kCCTResizableSideSheetDiscoverFeedSettingsName[] = + "Discover feed settings Partial Custom Tab"; +const char kCCTResizableSideSheetDiscoverFeedSettingsDescription[] = + "Enable discover feed settings Partial Custom Tabs"; const char kCCTResizableSideSheetForThirdPartiesName[] = "Side sheet Custom Tabs (third party)"; const char kCCTResizableSideSheetForThirdPartiesDescription[] = @@ -5616,6 +5611,12 @@ "Enable experimental or in-progress Switch Access features for improved " "text input"; +const char kExposeOutOfProcessVideoDecodingToLacrosName[] = + "Expose out-of-process video decoding (OOP-VD) to LaCrOS."; +const char kExposeOutOfProcessVideoDecodingToLacrosDescription[] = + "Accept media.stable.mojom.StableVideoDecoderFactory connection requests " + "from LaCrOS and host said factories in utility processes."; + const char kFileTransferEnterpriseConnectorName[] = "Enable Files Transfer Enterprise Connector."; const char kFileTransferEnterpriseConnectorDescription[] = @@ -6571,6 +6572,17 @@ "refresh needs to also be enabled."; #endif +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) +const char kUseOutOfProcessVideoDecodingName[] = + "Use out-of-process video decoding (OOP-VD)"; +const char kUseOutOfProcessVideoDecodingDescription[] = + "Start utility processes to do hardware video decoding. Note: on LaCrOS, " + "this task is delegated to ash-chrome by requesting a " + "media.stable.mojom.StableVideoDecoderFactory through the crosapi (so " + "chrome://flags#expose-out-of-process-video-decoding-to-lacros must be " + "enabled in ash-chrome)."; +#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) + #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) const char kWebShareName[] = "Web Share"; const char kWebShareDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 43aa66e..f51ad7b 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -232,9 +232,6 @@ extern const char kAutofillEnableCardProductNameName[]; extern const char kAutofillEnableCardProductNameDescription[]; -extern const char kAutofillEnableCvcForVcnYellowPathName[]; -extern const char kAutofillEnableCvcForVcnYellowPathDescription[]; - extern const char kAutofillEnableNewCardArtAndNetworkImagesName[]; extern const char kAutofillEnableNewCardArtAndNetworkImagesDescription[]; @@ -1316,6 +1313,9 @@ extern const char kWebUIOmniboxPopupName[]; extern const char kWebUIOmniboxPopupDescription[]; +extern const char kWebUiSystemFontName[]; +extern const char kWebUiSystemFontDescription[]; + extern const char kOmniboxMaxURLMatchesName[]; extern const char kOmniboxMaxURLMatchesDescription[]; @@ -1460,9 +1460,6 @@ extern const char kRecordPermissionExpirationTimestampsName[]; extern const char kRecordPermissionExpirationTimestampsDescription[]; -extern const char kPointerLockOptionsName[]; -extern const char kPointerLockOptionsDescription[]; - extern const char kPowerBookmarkBackendName[]; extern const char kPowerBookmarkBackendDescription[]; @@ -2077,6 +2074,8 @@ extern const char kCCTResizableForThirdPartiesDescription[]; extern const char kCCTResizableSideSheetName[]; extern const char kCCTResizableSideSheetDescription[]; +extern const char kCCTResizableSideSheetDiscoverFeedSettingsName[]; +extern const char kCCTResizableSideSheetDiscoverFeedSettingsDescription[]; extern const char kCCTResizableSideSheetForThirdPartiesName[]; extern const char kCCTResizableSideSheetForThirdPartiesDescription[]; @@ -3221,6 +3220,9 @@ extern const char kExperimentalAccessibilitySwitchAccessTextName[]; extern const char kExperimentalAccessibilitySwitchAccessTextDescription[]; +extern const char kExposeOutOfProcessVideoDecodingToLacrosName[]; +extern const char kExposeOutOfProcessVideoDecodingToLacrosDescription[]; + extern const char kFileTransferEnterpriseConnectorName[]; extern const char kFileTransferEnterpriseConnectorDescription[]; @@ -3834,6 +3836,11 @@ extern const char kLocalWebApprovalsDescription[]; #endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) +extern const char kUseOutOfProcessVideoDecodingName[]; +extern const char kUseOutOfProcessVideoDecodingDescription[]; +#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) + // Feature flags -------------------------------------------------------------- #if BUILDFLAG(CHROME_WIDE_ECHO_CANCELLATION)
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index a8eae33..f07baae 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -201,6 +201,7 @@ &kCCTResizable90MaximumHeight, &kCCTResizableForThirdParties, &kCCTResizableSideSheet, + &kCCTResizableSideSheetDiscoverFeedSettings, &kCCTResizableSideSheetForThirdParties, &kCCTRetainingStateInMemory, &kCCTResourcePrefetch, @@ -227,6 +228,7 @@ &kContextualSearchThinWebViewImplementation, &kDeferKeepScreenOnDuringGesture, &kDeferNotifyInMotion, + &kDelayTransitionsForAnimation, &kExperimentsForAgsa, &kExploreSites, &kFocusOmniboxInIncognitoTabIntents, @@ -608,6 +610,10 @@ "CCTResizableSideSheet", base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE(kCCTResizableSideSheetDiscoverFeedSettings, + "CCTResizableSideSheetDiscoverFeedSettings", + base::FEATURE_DISABLED_BY_DEFAULT); + BASE_FEATURE(kCCTResizableSideSheetForThirdParties, "CCTResizableSideSheetForThirdParties", base::FEATURE_DISABLED_BY_DEFAULT); @@ -720,6 +726,10 @@ "DeferNotifyInMotion", base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE(kDelayTransitionsForAnimation, + "DelayTransitionsForAnimation", + base::FEATURE_ENABLED_BY_DEFAULT); + BASE_FEATURE(kDownloadAutoResumptionThrottling, "DownloadAutoResumptionThrottling", base::FEATURE_ENABLED_BY_DEFAULT);
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h index 0215909..3e90bb1 100644 --- a/chrome/browser/flags/android/chrome_feature_list.h +++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -59,6 +59,7 @@ BASE_DECLARE_FEATURE(kCCTResizable90MaximumHeight); BASE_DECLARE_FEATURE(kCCTResizableForThirdParties); BASE_DECLARE_FEATURE(kCCTResizableSideSheet); +BASE_DECLARE_FEATURE(kCCTResizableSideSheetDiscoverFeedSettings); BASE_DECLARE_FEATURE(kCCTResizableSideSheetForThirdParties); BASE_DECLARE_FEATURE(kCCTResourcePrefetch); BASE_DECLARE_FEATURE(kCCTRetainingStateInMemory); @@ -86,6 +87,7 @@ BASE_DECLARE_FEATURE(kContextualSearchThinWebViewImplementation); BASE_DECLARE_FEATURE(kDeferKeepScreenOnDuringGesture); BASE_DECLARE_FEATURE(kDeferNotifyInMotion); +BASE_DECLARE_FEATURE(kDelayTransitionsForAnimation); BASE_DECLARE_FEATURE(kDontPrefetchLibraries); BASE_DECLARE_FEATURE(kDownloadAutoResumptionThrottling); BASE_DECLARE_FEATURE(kDownloadHomeForExternalApp);
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 23102c1..1167941 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
@@ -248,6 +248,8 @@ "CCTResizableAllowResizeByUserGesture"; public static final String CCT_RESIZABLE_FOR_THIRD_PARTIES = "CCTResizableForThirdParties"; public static final String CCT_RESIZABLE_SIDE_SHEET = "CCTResizableSideSheet"; + public static final String CCT_RESIZABLE_SIDE_SHEET_DISCOVER_FEED_SETTINGS = + "CCTResizableSideSheetDiscoverFeedSettings"; public static final String CCT_RESIZABLE_SIDE_SHEET_FOR_THIRD_PARTIES = "CCTResizableSideSheetForThirdParties"; public static final String CCT_RESOURCE_PREFETCH = "CCTResourcePrefetch"; @@ -296,6 +298,7 @@ public static final String DEFER_KEEP_SCREEN_ON_DURING_GESTURE = "DeferKeepScreenOnDuringGesture"; public static final String DEFER_NOTIFY_IN_MOTION = "DeferNotifyInMotion"; + public static final String DELAY_TRANSITIONS_FOR_ANIMATION = "DelayTransitionsForAnimation"; public static final String DETAILED_LANGUAGE_SETTINGS = "DetailedLanguageSettings"; public static final String DISCO_FEED_ENDPOINT = "DiscoFeedEndpoint"; public static final String DNS_OVER_HTTPS = "DnsOverHttps"; @@ -602,6 +605,8 @@ new CachedFlag(CCT_RESIZABLE_FOR_THIRD_PARTIES, true); public static final CachedFlag sCctResizableSideSheet = new CachedFlag(CCT_RESIZABLE_SIDE_SHEET, false); + public static final CachedFlag sCctResizableSideSheetDiscoverFeedSettings = + new CachedFlag(CCT_RESIZABLE_SIDE_SHEET_DISCOVER_FEED_SETTINGS, false); public static final CachedFlag sCctResizableSideSheetForThirdParties = new CachedFlag(CCT_RESIZABLE_SIDE_SHEET_FOR_THIRD_PARTIES, false); public static final CachedFlag sCctRetainableStateInMemory =
diff --git a/chrome/browser/heavy_ad_intervention/heavy_ad_helper_browsertest.cc b/chrome/browser/heavy_ad_intervention/heavy_ad_helper_browsertest.cc index 93b9c80..caeb2c2 100644 --- a/chrome/browser/heavy_ad_intervention/heavy_ad_helper_browsertest.cc +++ b/chrome/browser/heavy_ad_intervention/heavy_ad_helper_browsertest.cc
@@ -100,13 +100,7 @@ net::ERR_BLOCKED_BY_CLIENT); error_observer.Wait(); - // With error page isolation, the error page will be loaded in the error - // page process, therefore it will have a different RenderFrameHost - // instance. - if (content::SiteIsolationPolicy::IsErrorPageIsolationEnabled( - /* in_main_frame = */ false)) { - child = ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0); - } + child = ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0); EXPECT_TRUE(IsContentInDocument( child,
diff --git a/chrome/browser/history/history_browsertest.cc b/chrome/browser/history/history_browsertest.cc index bed215e..b5d6bf6 100644 --- a/chrome/browser/history/history_browsertest.cc +++ b/chrome/browser/history/history_browsertest.cc
@@ -543,11 +543,12 @@ ui_test_utils::GetTestUrl(base::FilePath().AppendASCII("History"), base::FilePath().AppendASCII("target.html")); - RenderFrameHostGrabber rfh_grabber( - browser()->tab_strip_model()->GetActiveWebContents(), initial_subframe); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_page)); - rfh_grabber.Wait(); - content::RenderFrameHost* frame = rfh_grabber.render_frame_host(); + content::RenderFrameHost* frame = ChildFrameAt(browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetPrimaryMainFrame(), + 0); ASSERT_TRUE(frame); ASSERT_TRUE(HistoryContainsURL(main_page)); ASSERT_FALSE(HistoryContainsURL(initial_subframe)); @@ -560,7 +561,11 @@ ASSERT_TRUE(HistoryContainsURL(manual_subframe)); // After navigation, the current RenderFrameHost may change. - frame = rfh_grabber.render_frame_host(); + frame = ChildFrameAt(browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetPrimaryMainFrame(), + 0); // Page-initiated location.replace subframe navigations should not show up in // history. std::string script = "location.replace('form.html')";
diff --git a/chrome/browser/history_clusters/BUILD.gn b/chrome/browser/history_clusters/BUILD.gn index 351d5e2..ea82994 100644 --- a/chrome/browser/history_clusters/BUILD.gn +++ b/chrome/browser/history_clusters/BUILD.gn
@@ -8,7 +8,6 @@ android_resources("java_resources") { sources = [ - "java/res/drawable/ic_journeys.xml", "java/res/layout/empty_text_view.xml", "java/res/layout/history_cluster.xml", "java/res/layout/history_cluster_visit.xml",
diff --git a/chrome/browser/lacros/desk_template_client_lacros.cc b/chrome/browser/lacros/desk_template_client_lacros.cc index 0d2870c..a80df2ff 100644 --- a/chrome/browser/lacros/desk_template_client_lacros.cc +++ b/chrome/browser/lacros/desk_template_client_lacros.cc
@@ -52,7 +52,7 @@ return false; } - if (range.GetMax() >= static_cast<uint32_t>(tab_strip_model->count())) { + if (range.GetMax() > static_cast<uint32_t>(tab_strip_model->count())) { LOG(WARNING) << "group_info: range max cannot be larger than count of tabs!"; return false; @@ -84,6 +84,10 @@ return; } + if (!browser_tab_model->SupportsTabGroups()) { + return; + } + const std::vector<int> tab_range = ConvertRangeToTabGroupIndices(group_info.tab_range); tab_groups::TabGroupId new_group_id = @@ -174,6 +178,7 @@ static_cast<ui::WindowShowState>(show_state); create_params.initial_bounds = bounds; create_params.restore_id = additional_state->restore_window_id; + create_params.creation_source = Browser::CreationSource::kDeskTemplate; Browser* browser = Browser::Create(create_params); for (size_t i = 0; i < additional_state->urls.size(); i++) { @@ -220,6 +225,7 @@ crosapi::mojom::DeskTemplateStatePtr state = crosapi::mojom::DeskTemplateState::New(); TabStripModel* tab_strip_model = browser->tab_strip_model(); + DCHECK(tab_strip_model); state->active_index = tab_strip_model->active_index(); state->first_non_pinned_index = tab_strip_model->IndexOfFirstNonPinnedTab();
diff --git a/chrome/browser/lacros/desk_template_client_lacros_browsertest.cc b/chrome/browser/lacros/desk_template_client_lacros_browsertest.cc index 5368bdc76..57400f6 100644 --- a/chrome/browser/lacros/desk_template_client_lacros_browsertest.cc +++ b/chrome/browser/lacros/desk_template_client_lacros_browsertest.cc
@@ -81,6 +81,8 @@ EXPECT_EQ(browser->create_params().type, Browser::Type::TYPE_NORMAL); } + EXPECT_EQ(browser->creation_source(), Browser::CreationSource::kDeskTemplate); + TabStripModel* browser_tab_model = browser->tab_strip_model(); EXPECT_TRUE(browser_tab_model); @@ -146,6 +148,24 @@ return state; } + // Returns a maximal `DeskTemplateStatePtr` mojom for testing where the tab + // group in question reaches to the end of the tab strip. This ensures that + // the browser launches with the entirety of the tab group intact. + crosapi::mojom::DeskTemplateStatePtr MakeTestMojomWithTabGroupAtEndOfStrip() { + crosapi::mojom::DeskTemplateStatePtr state = + MakeTestStateWithoutPinnedTabsOrTabGroup(); + + // Add in tab groups and pinned tabs. + state->first_non_pinned_index = 1; + state->groups = + std::vector<tab_groups::TabGroupInfo>({tab_groups::TabGroupInfo( + gfx::Range(2, 5), + tab_groups::TabGroupVisualData( + u"tab group one", tab_groups::TabGroupColorId::kGreen))}); + + return state; + } + // Returns a PWA `DeskTemplateStatePtr` mojom for testing app launches work in // lacros. crosapi::mojom::DeskTemplateStatePtr MakeAppTestMojom() { @@ -255,6 +275,39 @@ u"tab group one", tab_groups::TabGroupColorId::kGreen)); } + // Helper function that modifies the test's browser() object to match the + // representation produced in the `MakeTestMojomWithTabGroupAtEndOfStrip` + // function. This helps to ensure that the entirety of Tab Groups are captured + // properly. + void MakeTestBrowserWithTabGroupAtEndOfStrip() { + EXPECT_TRUE( + AddTabAtIndexToBrowser(browser(), 0, GURL(kChromeVersionUrl), + ui::PageTransition::PAGE_TRANSITION_LINK)); + EXPECT_TRUE( + AddTabAtIndexToBrowser(browser(), 2, GetGoogleTestURL(), + ui::PageTransition::PAGE_TRANSITION_LINK)); + EXPECT_TRUE( + AddTabAtIndexToBrowser(browser(), 3, GURL(kChromeVersionUrl), + ui::PageTransition::PAGE_TRANSITION_LINK)); + EXPECT_TRUE( + AddTabAtIndexToBrowser(browser(), 4, GURL(kChromeVersionUrl), + ui::PageTransition::PAGE_TRANSITION_LINK)); + + TabStripModel* strip_model = browser()->tab_strip_model(); + + // May not be necessary but guarantees that the correct tab is active. + strip_model->ActivateTabAt(0); + + // Assert we haven't moved the pinned tab. + EXPECT_EQ(0, strip_model->SetTabPinned(0, /*pinned=*/true)); + tab_groups::TabGroupId group_id_one = strip_model->AddToNewGroup({2, 3, 4}); + + TabGroupModel* group_model = strip_model->group_model(); + TabGroup* group_one = group_model->GetTabGroup(group_id_one); + group_one->SetVisualData(tab_groups::TabGroupVisualData( + u"tab group one", tab_groups::TabGroupColorId::kGreen)); + } + void MakeTestAppBrowser() { Profile* profile = ProfileManager::GetLastUsedProfileAllowedByPolicy(); @@ -334,6 +387,30 @@ } IN_PROC_BROWSER_TEST_F(DeskTemplateClientLacrosBrowserTest, + LaunchesBrowserWithTabGroupAtEndOfStripCorrectly) { + // State pointers don't supply a Clone operation. Therefore we will create + // two semantically identical states to test against. + crosapi::mojom::DeskTemplateStatePtr expected_state = + MakeTestMojomWithTabGroupAtEndOfStrip(); + crosapi::mojom::DeskTemplateStatePtr launch_parameters = + MakeTestMojomWithTabGroupAtEndOfStrip(); + gfx::Rect expected_bounds(0, 0, 256, 256); + + DeskTemplateClientLacros client; + + client.CreateBrowserWithRestoredData( + expected_bounds, ui::mojom::WindowShowState::SHOW_STATE_DEFAULT, + std::move(launch_parameters)); + + // Close default test browser, we will set browser to the browser created + // by the method under test. + CloseBrowserSynchronously(browser()); + SelectFirstBrowser(); + + AssertBrowserCreatedCorrectly(browser(), expected_state, expected_bounds); +} + +IN_PROC_BROWSER_TEST_F(DeskTemplateClientLacrosBrowserTest, LaunchesBrowserAppCorrectly) { // State pointers don't supply a Clone operation. Therefore we will create // two semantically identical states to test against. @@ -456,6 +533,36 @@ } IN_PROC_BROWSER_TEST_F(DeskTemplateClientLacrosBrowserTest, + CapturesBrowserWithTabGroupAtEndOfStripCorrectly) { + MakeTestBrowserWithTabGroupAtEndOfStrip(); + DeskTemplateClientLacros client; + crosapi::mojom::DeskTemplateClientAsyncWaiter waiter(&client); + std::string window_id = views::DesktopWindowTreeHostLacros::From( + browser()->window()->GetNativeWindow()->GetHost()) + ->platform_window() + ->GetWindowUniqueId(); + + uint32_t out_serial; + std::string out_window_id; + crosapi::mojom::DeskTemplateStatePtr out_state; + waiter.GetBrowserInformation(/*serial=*/0, window_id, &out_serial, + &out_window_id, &out_state); + + crosapi::mojom::DeskTemplateStatePtr test_mojom = + MakeTestMojomWithTabGroupAtEndOfStrip(); + EXPECT_EQ(out_state->urls, test_mojom->urls); + EXPECT_EQ(out_state->active_index, test_mojom->active_index); + EXPECT_EQ(out_state->first_non_pinned_index, + test_mojom->first_non_pinned_index); + ASSERT_TRUE(test_mojom->groups.has_value()); + EXPECT_TRUE(out_state->groups.has_value()); + + // We don't care about the order of tab groups. + EXPECT_THAT(out_state->groups.value(), + testing::UnorderedElementsAreArray(test_mojom->groups.value())); +} + +IN_PROC_BROWSER_TEST_F(DeskTemplateClientLacrosBrowserTest, CapturesBrowserWithoutPinnedTabsOrTabGroupsCorrectly) { MakeBrowserWithoutTabgroupsOrPinnedTabs(); DeskTemplateClientLacros client;
diff --git a/chrome/browser/lacros/net/network_change_manager_bridge.cc b/chrome/browser/lacros/net/network_change_manager_bridge.cc index 61c516cb..d608efe 100644 --- a/chrome/browser/lacros/net/network_change_manager_bridge.cc +++ b/chrome/browser/lacros/net/network_change_manager_bridge.cc
@@ -8,7 +8,7 @@ #include "chromeos/lacros/lacros_service.h" #include "content/public/browser/network_service_instance.h" #include "content/public/common/network_service_util.h" -#include "net/base/network_change_notifier_posix.h" +#include "net/base/network_change_notifier_passive.h" #include "services/network/public/mojom/network_service.mojom.h" // Check ConnectionType and ConnectionSubtype values are the same for @@ -64,7 +64,7 @@ STATIC_ASSERT_CONNECTION_TYPE(ConnectionSubtype::SUBTYPE_LAST); NetworkChangeManagerBridge::NetworkChangeManagerBridge() - : network_change_notifier_(static_cast<net::NetworkChangeNotifierPosix*>( + : network_change_notifier_(static_cast<net::NetworkChangeNotifierPassive*>( content::GetNetworkChangeNotifier())) { auto* lacros_service = chromeos::LacrosService::Get(); // If NetworkChange crosapi is not supported, fallback to use
diff --git a/chrome/browser/lacros/net/network_change_manager_bridge.h b/chrome/browser/lacros/net/network_change_manager_bridge.h index a891d6d..ccff9070 100644 --- a/chrome/browser/lacros/net/network_change_manager_bridge.h +++ b/chrome/browser/lacros/net/network_change_manager_bridge.h
@@ -12,7 +12,7 @@ #include "services/network/public/mojom/network_change_manager.mojom.h" namespace net { -class NetworkChangeNotifierPosix; +class NetworkChangeNotifierPassive; } // Passes NetworkChange status given from Ash to NetworkChangeNotifier in @@ -47,7 +47,7 @@ net::NetworkChangeNotifier::ConnectionSubtype connection_subtype_ = net::NetworkChangeNotifier::SUBTYPE_NONE; - const raw_ptr<net::NetworkChangeNotifierPosix> network_change_notifier_; + const raw_ptr<net::NetworkChangeNotifierPassive> network_change_notifier_; mojo::Remote<network::mojom::NetworkChangeManager> network_change_manager_; // Receives mojo messages from ash-chrome.
diff --git a/chrome/browser/lacros/sync/crosapi_session_sync_favicon_delegate.cc b/chrome/browser/lacros/sync/crosapi_session_sync_favicon_delegate.cc new file mode 100644 index 0000000..de712ee9 --- /dev/null +++ b/chrome/browser/lacros/sync/crosapi_session_sync_favicon_delegate.cc
@@ -0,0 +1,43 @@ +// 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/lacros/sync/crosapi_session_sync_favicon_delegate.h" + +#include "chromeos/crosapi/mojom/synced_session_client.mojom.h" +#include "components/favicon/core/history_ui_favicon_request_handler.h" +#include "components/favicon_base/favicon_types.h" +#include "url/gurl.h" + +CrosapiSessionSyncFaviconDelegate::CrosapiSessionSyncFaviconDelegate( + favicon::HistoryUiFaviconRequestHandler* favicon_request_handler) + : favicon_request_handler_(favicon_request_handler) {} + +CrosapiSessionSyncFaviconDelegate::~CrosapiSessionSyncFaviconDelegate() = + default; + +void CrosapiSessionSyncFaviconDelegate::GetFaviconImageForPageURL( + const GURL& url, + GetFaviconImageForPageURLCallback callback) { + if (!favicon_request_handler_) { + std::move(callback).Run(gfx::ImageSkia()); + return; + } + + favicon_request_handler_->GetFaviconImageForPageURL( + url, + base::BindOnce(&CrosapiSessionSyncFaviconDelegate::OnFaviconReady, + weak_ptr_factory_.GetWeakPtr(), std::move(callback)), + favicon::HistoryUiFaviconRequestOrigin::kRecentTabs); +} + +mojo::PendingRemote<crosapi::mojom::SyncedSessionClientFaviconDelegate> +CrosapiSessionSyncFaviconDelegate::CreateRemote() { + return receiver_.BindNewPipeAndPassRemote(); +} + +void CrosapiSessionSyncFaviconDelegate::OnFaviconReady( + GetFaviconImageForPageURLCallback callback, + const favicon_base::FaviconImageResult& favicon_image_result) { + std::move(callback).Run(favicon_image_result.image.AsImageSkia()); +}
diff --git a/chrome/browser/lacros/sync/crosapi_session_sync_favicon_delegate.h b/chrome/browser/lacros/sync/crosapi_session_sync_favicon_delegate.h new file mode 100644 index 0000000..62b9d62 --- /dev/null +++ b/chrome/browser/lacros/sync/crosapi_session_sync_favicon_delegate.h
@@ -0,0 +1,59 @@ +// 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_LACROS_SYNC_CROSAPI_SESSION_SYNC_FAVICON_DELEGATE_H_ +#define CHROME_BROWSER_LACROS_SYNC_CROSAPI_SESSION_SYNC_FAVICON_DELEGATE_H_ + +#include "base/memory/raw_ptr.h" +#include "base/memory/weak_ptr.h" +#include "chromeos/crosapi/mojom/synced_session_client.mojom.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "url/gurl.h" + +namespace favicon_base { +struct FaviconImageResult; +} // namespace favicon_base + +namespace favicon { +class HistoryUiFaviconRequestHandler; +} // namespace favicon + +// This class is responsible for fielding requests for favicons from Ash as part +// of the SyncedSessionClient API. +class CrosapiSessionSyncFaviconDelegate + : public crosapi::mojom::SyncedSessionClientFaviconDelegate { + public: + // |favicon_request_handler| can be null but must outlive |this| if provided. + explicit CrosapiSessionSyncFaviconDelegate( + favicon::HistoryUiFaviconRequestHandler* favicon_request_handler); + CrosapiSessionSyncFaviconDelegate(const CrosapiSessionSyncFaviconDelegate&) = + delete; + CrosapiSessionSyncFaviconDelegate& operator=( + const CrosapiSessionSyncFaviconDelegate&) = delete; + ~CrosapiSessionSyncFaviconDelegate() override; + + // crosapi::mojom::SyncedSessionClientFaviconDelegate: + void GetFaviconImageForPageURL( + const GURL& url, + GetFaviconImageForPageURLCallback callback) override; + + mojo::PendingRemote<crosapi::mojom::SyncedSessionClientFaviconDelegate> + CreateRemote(); + + private: + void OnFaviconReady( + GetFaviconImageForPageURLCallback callback, + const favicon_base::FaviconImageResult& favicon_image_result); + + base::raw_ptr<favicon::HistoryUiFaviconRequestHandler> + favicon_request_handler_; + mojo::Receiver<crosapi::mojom::SyncedSessionClientFaviconDelegate> receiver_{ + this}; + + base::WeakPtrFactory<CrosapiSessionSyncFaviconDelegate> weak_ptr_factory_{ + this}; +}; + +#endif // CHROME_BROWSER_LACROS_SYNC_CROSAPI_SESSION_SYNC_FAVICON_DELEGATE_H_
diff --git a/chrome/browser/lacros/sync/crosapi_session_sync_favicon_delegate_unittest.cc b/chrome/browser/lacros/sync/crosapi_session_sync_favicon_delegate_unittest.cc new file mode 100644 index 0000000..8ff1b08 --- /dev/null +++ b/chrome/browser/lacros/sync/crosapi_session_sync_favicon_delegate_unittest.cc
@@ -0,0 +1,102 @@ +// 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/lacros/sync/crosapi_session_sync_favicon_delegate.h" + +#include "base/test/bind.h" +#include "base/test/task_environment.h" +#include "base/test/test_future.h" +#include "components/favicon/core/history_ui_favicon_request_handler.h" +#include "components/favicon_base/favicon_types.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/favicon_size.h" +#include "ui/gfx/image/image_unittest_util.h" + +namespace { + +constexpr char kTestUrl[] = "www.google.com"; + +class FakeHistoryUiFaviconRequestHandler + : public favicon::HistoryUiFaviconRequestHandler { + public: + FakeHistoryUiFaviconRequestHandler() = default; + ~FakeHistoryUiFaviconRequestHandler() override = default; + + void GetRawFaviconForPageURL( + const GURL& page_url, + int desired_size_in_pixel, + favicon_base::FaviconRawBitmapCallback callback, + favicon::HistoryUiFaviconRequestOrigin request_origin_for_uma) override { + NOTIMPLEMENTED(); + } + + void GetFaviconImageForPageURL( + const GURL& page_url, + favicon_base::FaviconImageCallback callback, + favicon::HistoryUiFaviconRequestOrigin request_origin_for_uma) override { + favicon_base::FaviconImageResult result; + if (result_image_) { + result.image = *result_image_; + } + + std::move(callback).Run(std::move(result)); + } + + void SetResultImage(gfx::Image* image) { result_image_ = image; } + + private: + gfx::Image* result_image_ = nullptr; +}; + +gfx::Image GetTestImage() { + SkBitmap bitmap; + bitmap.allocN32Pixels(gfx::kFaviconSize, gfx::kFaviconSize); + bitmap.eraseColor(SK_ColorBLUE); + return gfx::Image::CreateFrom1xBitmap(bitmap); +} + +} // namespace + +class CrosapiSessionSyncFaviconDelegateTest : public testing::Test { + public: + void CreateFaviconDelegate( + FakeHistoryUiFaviconRequestHandler* favicon_request_handler) { + favicon_delegate_ = std::make_unique<CrosapiSessionSyncFaviconDelegate>( + favicon_request_handler); + } + + CrosapiSessionSyncFaviconDelegate* favicon_delegate() { + return favicon_delegate_.get(); + } + + private: + base::test::SingleThreadTaskEnvironment task_environment_; + + std::unique_ptr<CrosapiSessionSyncFaviconDelegate> favicon_delegate_; +}; + +TEST_F(CrosapiSessionSyncFaviconDelegateTest, + GetFaviconImageForPageURL_NoHandler) { + CreateFaviconDelegate(/*favicon_request_handler=*/nullptr); + base::test::TestFuture<const gfx::ImageSkia&> future; + favicon_delegate()->GetFaviconImageForPageURL(GURL(kTestUrl), + future.GetCallback()); + EXPECT_TRUE( + gfx::test::AreImagesEqual(gfx::Image(), gfx::Image(future.Get()))); +} + +TEST_F(CrosapiSessionSyncFaviconDelegateTest, + GetFaviconImageForPageURL_ImagesMatch) { + FakeHistoryUiFaviconRequestHandler favicon_request_handler; + CreateFaviconDelegate(&favicon_request_handler); + + gfx::Image expected_image = GetTestImage(); + favicon_request_handler.SetResultImage(&expected_image); + + base::test::TestFuture<const gfx::ImageSkia&> future; + favicon_delegate()->GetFaviconImageForPageURL(GURL(kTestUrl), + future.GetCallback()); + EXPECT_TRUE( + gfx::test::AreImagesEqual(expected_image, gfx::Image(future.Get()))); +}
diff --git a/chrome/browser/lacros/sync/crosapi_session_sync_notifier.cc b/chrome/browser/lacros/sync/crosapi_session_sync_notifier.cc index edb042ab..beb3109 100644 --- a/chrome/browser/lacros/sync/crosapi_session_sync_notifier.cc +++ b/chrome/browser/lacros/sync/crosapi_session_sync_notifier.cc
@@ -7,6 +7,7 @@ #include <utility> #include "base/functional/bind.h" +#include "chrome/browser/lacros/sync/crosapi_session_sync_favicon_delegate.h" #include "chromeos/lacros/lacros_service.h" #include "components/sync/driver/sync_user_settings.h" #include "components/sync_sessions/open_tabs_ui_delegate.h" @@ -98,10 +99,12 @@ sync_sessions::SessionSyncService* session_sync_service, mojo::PendingRemote<crosapi::mojom::SyncedSessionClient> synced_session_client, - syncer::SyncService* sync_service) + syncer::SyncService* sync_service, + favicon::HistoryUiFaviconRequestHandler* favicon_request_handler) : is_tab_sync_enabled_(IsTabSyncEnabled(sync_service)), session_sync_service_(session_sync_service), - synced_session_client_(std::move(synced_session_client)) { + synced_session_client_(std::move(synced_session_client)), + favicon_delegate_(favicon_request_handler) { if (synced_session_client_.version() >= static_cast<int>(crosapi::mojom::SyncedSessionClient:: kOnForeignSyncedPhoneSessionsUpdatedMinVersion)) { @@ -112,10 +115,21 @@ base::Unretained(this))); } - sync_service_observation_.Observe(sync_service); + if (synced_session_client_.version() >= + static_cast<int>(crosapi::mojom::SyncedSessionClient:: + kOnSessionSyncEnabledChangedMinVersion)) { + sync_service_observation_.Observe(sync_service); - // Broadcast the initial value for |is_tab_sync_enabled_|. - NotifySyncEnabledChanged(); + // Broadcast the initial value for |is_tab_sync_enabled_|. + NotifySyncEnabledChanged(); + } + + if (synced_session_client_.version() >= + static_cast<int>( + crosapi::mojom::SyncedSessionClient::kSetFaviconDelegateMinVersion)) { + synced_session_client_->SetFaviconDelegate( + favicon_delegate_.CreateRemote()); + } } CrosapiSessionSyncNotifier::~CrosapiSessionSyncNotifier() = default;
diff --git a/chrome/browser/lacros/sync/crosapi_session_sync_notifier.h b/chrome/browser/lacros/sync/crosapi_session_sync_notifier.h index 675e8169..74b9af74 100644 --- a/chrome/browser/lacros/sync/crosapi_session_sync_notifier.h +++ b/chrome/browser/lacros/sync/crosapi_session_sync_notifier.h
@@ -8,6 +8,7 @@ #include "base/callback_list.h" #include "base/memory/raw_ptr.h" #include "base/scoped_observation.h" +#include "chrome/browser/lacros/sync/crosapi_session_sync_favicon_delegate.h" #include "chromeos/crosapi/mojom/synced_session_client.mojom.h" #include "components/sync/driver/sync_service.h" #include "components/sync/driver/sync_service_observer.h" @@ -18,17 +19,23 @@ class SessionSyncService; } // namespace sync_sessions +namespace favicon { +class HistoryUiFaviconRequestHandler; +} // namespace favicon + // This class is responsible for sending browser window data to Ash upon changes // to foreign browser sessions. class CrosapiSessionSyncNotifier : public syncer::SyncServiceObserver { public: - // `session_sync_service` should not be null and should outlive `this`. - // `sync_service` should not be null and should outlive `this`. + // |session_sync_service| should not be null and should outlive |this|. + // |sync_service| should not be null and should outlive |this|. + // |favicon_request_handler| can be null but must outlive |this| if provided. CrosapiSessionSyncNotifier( sync_sessions::SessionSyncService* session_sync_service, mojo::PendingRemote<crosapi::mojom::SyncedSessionClient> synced_session_client, - syncer::SyncService* sync_service); + syncer::SyncService* sync_service, + favicon::HistoryUiFaviconRequestHandler* favicon_request_handler); CrosapiSessionSyncNotifier(const CrosapiSessionSyncNotifier&) = delete; CrosapiSessionSyncNotifier& operator=(const CrosapiSessionSyncNotifier&) = delete; @@ -47,6 +54,7 @@ base::CallbackListSubscription session_updated_subscription_; base::ScopedObservation<syncer::SyncService, syncer::SyncServiceObserver> sync_service_observation_{this}; + CrosapiSessionSyncFaviconDelegate favicon_delegate_; }; #endif // CHROME_BROWSER_LACROS_SYNC_CROSAPI_SESSION_SYNC_NOTIFIER_H_
diff --git a/chrome/browser/lacros/sync/crosapi_session_sync_notifier_unittest.cc b/chrome/browser/lacros/sync/crosapi_session_sync_notifier_unittest.cc index 24816b6..59d25714d 100644 --- a/chrome/browser/lacros/sync/crosapi_session_sync_notifier_unittest.cc +++ b/chrome/browser/lacros/sync/crosapi_session_sync_notifier_unittest.cc
@@ -130,7 +130,7 @@ std::make_unique<CrosapiSessionSyncNotifier>( &mock_session_sync_service_, fake_synced_session_client_ash_.CreateRemote(), - test_sync_service_.get()); + test_sync_service_.get(), /*favicon_request_handler=*/nullptr); } base::CallbackListSubscription SubscribeToForeignSessionsChanged(
diff --git a/chrome/browser/lacros/sync/sync_crosapi_manager_lacros.cc b/chrome/browser/lacros/sync/sync_crosapi_manager_lacros.cc index 109cf20f..182be675 100644 --- a/chrome/browser/lacros/sync/sync_crosapi_manager_lacros.cc +++ b/chrome/browser/lacros/sync/sync_crosapi_manager_lacros.cc
@@ -9,6 +9,7 @@ #include <utility> #include "base/feature_list.h" +#include "chrome/browser/favicon/history_ui_favicon_request_handler_factory.h" #include "chrome/browser/lacros/sync/crosapi_session_sync_notifier.h" #include "chrome/browser/lacros/sync/sync_explicit_passphrase_client_lacros.h" #include "chrome/browser/lacros/sync/sync_user_settings_client_lacros.h" @@ -101,6 +102,8 @@ return; } + DCHECK(!profile_); + profile_ = profile; auto* lacros_service = chromeos::LacrosService::Get(); auto* sync_service = SyncServiceFactory::GetForProfile(profile); if (!lacros_service || !sync_service) { @@ -110,7 +113,7 @@ DCHECK(!crosapi_session_sync_notifier_); profile->AddObserver(this); - MaybeCreateCrosapiSessionSyncNotifier(lacros_service, profile, sync_service); + MaybeCreateCrosapiSessionSyncNotifier(); DCHECK(!sync_explicit_passphrase_client_); sync_explicit_passphrase_client_ = @@ -122,6 +125,7 @@ } void SyncCrosapiManagerLacros::OnProfileWillBeDestroyed(Profile* profile) { + profile_ = nullptr; crosapi_session_sync_notifier_.reset(); profile->RemoveObserver(this); } @@ -133,50 +137,48 @@ sync_service->RemoveObserver(this); } -void SyncCrosapiManagerLacros::MaybeCreateCrosapiSessionSyncNotifier( - chromeos::LacrosService* lacros_service, - Profile* profile, - syncer::SyncService* sync_service) { +void SyncCrosapiManagerLacros::MaybeCreateCrosapiSessionSyncNotifier() { if (!base::FeatureList::IsEnabled(syncer::kChromeOSSyncedSessionSharing)) { return; } - if (chromeos::LacrosService::Get() - ->GetInterfaceVersion<crosapi::mojom::SyncService>() < + auto* lacros_service = chromeos::LacrosService::Get(); + if (lacros_service->GetInterfaceVersion<crosapi::mojom::SyncService>() < static_cast<int>( crosapi::mojom::SyncService::kCreateSyncedSessionClientMinVersion)) { return; } + lacros_service->GetRemote<crosapi::mojom::SyncService>() + ->CreateSyncedSessionClient( + base::BindOnce(&SyncCrosapiManagerLacros::OnCreateSyncedSessionClient, + weak_ptr_factory_.GetWeakPtr())); +} + +void SyncCrosapiManagerLacros::OnCreateSyncedSessionClient( + mojo::PendingRemote<crosapi::mojom::SyncedSessionClient> pending_remote) { + if (!pending_remote || !profile_) { + return; + } + + syncer::SyncService* sync_service = + SyncServiceFactory::GetForProfile(profile_); + if (!sync_service) { + return; + } + sync_sessions::SessionSyncService* session_sync_service = - SessionSyncServiceFactory::GetInstance()->GetForProfile(profile); + SessionSyncServiceFactory::GetInstance()->GetForProfile(profile_); if (!session_sync_service) { return; } - lacros_service->GetRemote<crosapi::mojom::SyncService>() - ->CreateSyncedSessionClient(base::BindOnce( - &SyncCrosapiManagerLacros::OnCreateSyncedSessionClient, - weak_ptr_factory_.GetWeakPtr(), session_sync_service, sync_service)); -} - -void SyncCrosapiManagerLacros::OnCreateSyncedSessionClient( - sync_sessions::SessionSyncService* session_sync_service, - syncer::SyncService* sync_service, - mojo::PendingRemote<crosapi::mojom::SyncedSessionClient> pending_remote) { - // TODO(b/260599791): Handle the potential case where the profile or these - // passed-in services may be invalid by the time we receive the remote. - if (!pending_remote) { - return; - } - - if (pending_remote.version() < - static_cast<int>(crosapi::mojom::SyncedSessionClient:: - kOnSessionSyncEnabledChangedMinVersion)) { - return; - } + favicon::HistoryUiFaviconRequestHandler* favicon_request_handler = + HistoryUiFaviconRequestHandlerFactory::GetInstance() + ->GetForBrowserContext(profile_); DCHECK(!crosapi_session_sync_notifier_); crosapi_session_sync_notifier_ = std::make_unique<CrosapiSessionSyncNotifier>( - session_sync_service, std::move(pending_remote), sync_service); + session_sync_service, std::move(pending_remote), sync_service, + favicon_request_handler); }
diff --git a/chrome/browser/lacros/sync/sync_crosapi_manager_lacros.h b/chrome/browser/lacros/sync/sync_crosapi_manager_lacros.h index e23286e..748f75ed 100644 --- a/chrome/browser/lacros/sync/sync_crosapi_manager_lacros.h +++ b/chrome/browser/lacros/sync/sync_crosapi_manager_lacros.h
@@ -7,29 +7,22 @@ #include <memory> +#include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_observer.h" #include "chromeos/crosapi/mojom/sync.mojom.h" #include "components/sync/driver/sync_service_observer.h" #include "mojo/public/cpp/bindings/pending_remote.h" -class Profile; class SyncExplicitPassphraseClientLacros; class SyncUserSettingsClientLacros; class CrosapiSessionSyncNotifier; -namespace chromeos { -class LacrosService; -} // namespace chromeos - namespace syncer { class SyncService; } // namespace syncer -namespace sync_sessions { -class SessionSyncService; -} // namespace sync_sessions - // Controls lifetime of sync-related Crosapi clients. class SyncCrosapiManagerLacros : public syncer::SyncServiceObserver, public ProfileObserver { @@ -54,15 +47,12 @@ // - Crosapi version used is not high enough to include the necessary updates // made. // - session sync service for the user's profile cannot be found. - void MaybeCreateCrosapiSessionSyncNotifier( - chromeos::LacrosService* lacros_service, - Profile* profile, - syncer::SyncService* sync_service); + void MaybeCreateCrosapiSessionSyncNotifier(); void OnCreateSyncedSessionClient( - sync_sessions::SessionSyncService* session_sync_service, - syncer::SyncService* sync_service, mojo::PendingRemote<crosapi::mojom::SyncedSessionClient> pending_remote); + base::raw_ptr<Profile> profile_ = nullptr; + // The objects below are created for main profile PostProfileInit() and // destroyed upon main profile SyncService shutdown. std::unique_ptr<SyncExplicitPassphraseClientLacros>
diff --git a/chrome/browser/lacros/web_app_provider_bridge_lacros.cc b/chrome/browser/lacros/web_app_provider_bridge_lacros.cc index 2225aa0..0df0a80 100644 --- a/chrome/browser/lacros/web_app_provider_bridge_lacros.cc +++ b/chrome/browser/lacros/web_app_provider_bridge_lacros.cc
@@ -101,6 +101,10 @@ install_info->theme_color = arc_install_info->theme_color; const SkBitmap& bitmap = *arc_install_info->icon.bitmap(); install_info->icon_bitmaps.any[bitmap.width()] = bitmap; + if (arc_install_info->additional_policy_ids) { + install_info->additional_policy_ids = + std::move(*arc_install_info->additional_policy_ids); + } provider->scheduler().InstallFromInfo( std::move(install_info),
diff --git a/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/AppLanguagePromoDialog.java b/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/AppLanguagePromoDialog.java index c5681903..bc562d2 100644 --- a/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/AppLanguagePromoDialog.java +++ b/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/AppLanguagePromoDialog.java
@@ -200,11 +200,14 @@ * Modify the LanguageItemAdapter to show the other languages in addition to the top * languages. Can only called once. The other languages can not be hidden once shown. */ + @SuppressWarnings("NotifyDataSetChanged") public void showOtherLanguages() { + // Do nothing if other languagers are already showing. + if (mShowOtherLanguages) return; mShowOtherLanguages = true; - notifyItemRemoved(mTopLanguages.size()); // Remove "More languages" item. - // Other languages plus a horizontal separator have been added. - notifyItemRangeInserted(mTopLanguages.size(), mOtherLanguages.size() + 1); + // Showing all other items adds a large amount of languages to the list, so we use + // DataSetChanged instead of more specific methods. + notifyDataSetChanged(); } /**
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 75a457ff..2b60ca4 100644 --- a/chrome/browser/media/webrtc/media_stream_devices_controller_browsertest.cc +++ b/chrome/browser/media/webrtc/media_stream_devices_controller_browsertest.cc
@@ -8,6 +8,7 @@ #include "base/functional/bind.h" #include "base/functional/callback.h" #include "base/metrics/field_trial.h" +#include "base/metrics/field_trial_params.h" #include "base/run_loop.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h" @@ -34,7 +35,6 @@ #include "components/permissions/request_type.h" #include "components/permissions/test/mock_permission_prompt_factory.h" #include "components/prefs/pref_service.h" -#include "components/variations/variations_associated_data.h" #include "content/public/browser/render_frame_host.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" @@ -997,7 +997,7 @@ params[permissions::PermissionUtil::GetPermissionString( ContentSettingsType::MEDIASTREAM_CAMERA)] = permissions::PermissionContextBase::kPermissionsKillSwitchBlockedValue; - variations::AssociateVariationParams( + base::AssociateFieldTrialParams( permissions::PermissionContextBase::kPermissionsKillSwitchFieldStudy, "TestGroup", params); base::FieldTrialList::CreateFieldTrial(
diff --git a/chrome/browser/metrics/chrome_browser_sampling_trials.cc b/chrome/browser/metrics/chrome_browser_sampling_trials.cc index c4cbc05..a9c2c6c 100644 --- a/chrome/browser/metrics/chrome_browser_sampling_trials.cc +++ b/chrome/browser/metrics/chrome_browser_sampling_trials.cc
@@ -6,11 +6,11 @@ #include "base/feature_list.h" #include "base/metrics/field_trial.h" +#include "base/metrics/field_trial_params.h" #include "base/strings/string_number_conversions.h" #include "chrome/browser/metrics/chrome_metrics_services_manager_client.h" #include "chrome/common/channel_info.h" #include "components/ukm/ukm_recorder_impl.h" -#include "components/variations/variations_associated_data.h" #include "components/version_info/channel.h" namespace metrics { @@ -36,7 +36,7 @@ base::FieldTrial* trial) { std::map<std::string, std::string> params = { {metrics::internal::kRateParamName, base::NumberToString(rate)}}; - variations::AssociateVariationParams(trial->trial_name(), group_name, params); + base::AssociateFieldTrialParams(trial->trial_name(), group_name, params); trial->AppendGroup(group_name, rate); } @@ -115,8 +115,7 @@ // Everybody (100%) should have a sampling configuration. std::map<std::string, std::string> params = { {"_default_sampling", base::NumberToString(default_sampling)}}; - variations::AssociateVariationParams(trial->trial_name(), sampled_group, - params); + base::AssociateFieldTrialParams(trial->trial_name(), sampled_group, params); trial->AppendGroup(sampled_group, 100); // Setup the feature.
diff --git a/chrome/browser/metrics/perf/perf_events_collector_unittest.cc b/chrome/browser/metrics/perf/perf_events_collector_unittest.cc index ceee20f..ec7069e 100644 --- a/chrome/browser/metrics/perf/perf_events_collector_unittest.cc +++ b/chrome/browser/metrics/perf/perf_events_collector_unittest.cc
@@ -15,6 +15,7 @@ #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/memory/ptr_util.h" +#include "base/metrics/field_trial_params.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" #include "base/system/sys_info.h" @@ -1241,8 +1242,8 @@ internal::GetDefaultCommandsForCpuModel( GetCPUIdentity(), base::SysInfo::HardwareModelName()); std::map<std::string, std::string> params; - ASSERT_TRUE(variations::AssociateVariationParams( - "ChromeOSWideProfilingCollection", "group_name", params)); + ASSERT_TRUE(base::AssociateFieldTrialParams("ChromeOSWideProfilingCollection", + "group_name", params)); ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( "ChromeOSWideProfilingCollection", "group_name")); @@ -1268,8 +1269,8 @@ std::make_pair("PerfCommand::default::4", "NaN-trailing-space ")); params.insert(std::make_pair("PerfCommand::default::5", "NaN x")); params.insert(std::make_pair("PerfCommand::default::6", "perf command")); - ASSERT_TRUE(variations::AssociateVariationParams( - "ChromeOSWideProfilingCollection", "group_name", params)); + ASSERT_TRUE(base::AssociateFieldTrialParams("ChromeOSWideProfilingCollection", + "group_name", params)); ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( "ChromeOSWideProfilingCollection", "group_name")); @@ -1295,8 +1296,8 @@ std::make_pair("PerfCommand::default::2", "25 perf record baz")); params.insert( std::make_pair("PerfCommand::another-cpu::0", "7 perf record bar")); - ASSERT_TRUE(variations::AssociateVariationParams( - "ChromeOSWideProfilingCollection", "group_name", params)); + ASSERT_TRUE(base::AssociateFieldTrialParams("ChromeOSWideProfilingCollection", + "group_name", params)); ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( "ChromeOSWideProfilingCollection", "group_name")); @@ -1320,8 +1321,8 @@ params.insert(std::make_pair("ResumeFromSuspend::MaxDelaySec", "10")); params.insert(std::make_pair("RestoreSession::SamplingFactor", "2")); params.insert(std::make_pair("RestoreSession::MaxDelaySec", "20")); - ASSERT_TRUE(variations::AssociateVariationParams( - "ChromeOSWideProfilingCollection", "group_name", params)); + ASSERT_TRUE(base::AssociateFieldTrialParams("ChromeOSWideProfilingCollection", + "group_name", params)); ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( "ChromeOSWideProfilingCollection", "group_name"));
diff --git a/chrome/browser/metrics/perf/profile_provider_unittest_main.cc b/chrome/browser/metrics/perf/profile_provider_unittest_main.cc index 0dd44f6..fe8af908 100644 --- a/chrome/browser/metrics/perf/profile_provider_unittest_main.cc +++ b/chrome/browser/metrics/perf/profile_provider_unittest_main.cc
@@ -10,6 +10,7 @@ #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" #include "base/metrics/field_trial.h" +#include "base/metrics/field_trial_params.h" #include "base/metrics/statistics_recorder.h" #include "base/run_loop.h" #include "base/synchronization/waitable_event.h" @@ -157,7 +158,7 @@ "PerfCommand::default::0", "50 -- record -a -e cycles -c 1000003")); field_trial_params.insert(std::make_pair( "PerfCommand::default::1", "50 -- record -a -e cycles -g -c 4000037")); - ASSERT_TRUE(variations::AssociateVariationParams( + ASSERT_TRUE(base::AssociateFieldTrialParams( "ChromeOSWideProfilingCollection", "group_name", field_trial_params)); field_trial_ = base::FieldTrialList::CreateFieldTrial( "ChromeOSWideProfilingCollection", "group_name");
diff --git a/chrome/browser/new_tab_page/customize_chrome/DEPS b/chrome/browser/new_tab_page/customize_chrome/DEPS new file mode 100644 index 0000000..ef5d311 --- /dev/null +++ b/chrome/browser/new_tab_page/customize_chrome/DEPS
@@ -0,0 +1,5 @@ +specific_include_rules = { + "customize_chrome_feature_promo_helper_unittest\.cc": [ + "+components/user_education/test" + ] +}
diff --git a/chrome/browser/new_tab_page/customize_chrome/customize_chrome_feature_promo_helper.cc b/chrome/browser/new_tab_page/customize_chrome/customize_chrome_feature_promo_helper.cc new file mode 100644 index 0000000..12cae22 --- /dev/null +++ b/chrome/browser/new_tab_page/customize_chrome/customize_chrome_feature_promo_helper.cc
@@ -0,0 +1,45 @@ +// 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/new_tab_page/customize_chrome/customize_chrome_feature_promo_helper.h" + +#include "chrome/browser/feature_engagement/tracker_factory.h" +#include "chrome/browser/ui/browser_window.h" +#include "components/feature_engagement/public/event_constants.h" +#include "components/feature_engagement/public/feature_constants.h" + +void CustomizeChromeFeaturePromoHelper::RecordCustomizeChromeFeatureUsage( + content::WebContents* web_contents) { + auto* tracker = feature_engagement::TrackerFactory::GetForBrowserContext( + web_contents->GetBrowserContext()); + if (tracker) { + tracker->NotifyEvent(feature_engagement::events::kCustomizeChromeOpened); + } +} + +void CustomizeChromeFeaturePromoHelper::MaybeShowCustomizeChromeFeaturePromo( + content::WebContents* web_contents) { + if (base::FeatureList::IsEnabled( + feature_engagement::kIPHDesktopCustomizeChromeFeature)) { + auto* browser_window = + BrowserWindow::FindBrowserWindowWithWebContents(web_contents); + if (browser_window) { + browser_window->MaybeShowFeaturePromo( + feature_engagement::kIPHDesktopCustomizeChromeFeature); + } + } +} + +void CustomizeChromeFeaturePromoHelper::CloseCustomizeChromeFeaturePromo( + content::WebContents* web_contents) { + if (base::FeatureList::IsEnabled( + feature_engagement::kIPHDesktopCustomizeChromeFeature)) { + auto* browser_window = + BrowserWindow::FindBrowserWindowWithWebContents(web_contents); + if (browser_window) { + browser_window->CloseFeaturePromo( + feature_engagement::kIPHDesktopCustomizeChromeFeature); + } + } +}
diff --git a/chrome/browser/new_tab_page/customize_chrome/customize_chrome_feature_promo_helper.h b/chrome/browser/new_tab_page/customize_chrome/customize_chrome_feature_promo_helper.h new file mode 100644 index 0000000..bb22911 --- /dev/null +++ b/chrome/browser/new_tab_page/customize_chrome/customize_chrome_feature_promo_helper.h
@@ -0,0 +1,22 @@ +// 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_NEW_TAB_PAGE_CUSTOMIZE_CHROME_CUSTOMIZE_CHROME_FEATURE_PROMO_HELPER_H_ +#define CHROME_BROWSER_NEW_TAB_PAGE_CUSTOMIZE_CHROME_CUSTOMIZE_CHROME_FEATURE_PROMO_HELPER_H_ + +#include "content/public/browser/web_contents_observer.h" + +class CustomizeChromeFeaturePromoHelper { + public: + virtual void RecordCustomizeChromeFeatureUsage( + content::WebContents* web_contents); + virtual void MaybeShowCustomizeChromeFeaturePromo( + content::WebContents* web_contents); + virtual void CloseCustomizeChromeFeaturePromo( + content::WebContents* web_contents); + + virtual ~CustomizeChromeFeaturePromoHelper() = default; +}; + +#endif // CHROME_BROWSER_NEW_TAB_PAGE_CUSTOMIZE_CHROME_CUSTOMIZE_CHROME_FEATURE_PROMO_HELPER_H_
diff --git a/chrome/browser/new_tab_page/customize_chrome/customize_chrome_feature_promo_helper_unittest.cc b/chrome/browser/new_tab_page/customize_chrome/customize_chrome_feature_promo_helper_unittest.cc new file mode 100644 index 0000000..a82ac4e6 --- /dev/null +++ b/chrome/browser/new_tab_page/customize_chrome/customize_chrome_feature_promo_helper_unittest.cc
@@ -0,0 +1,115 @@ +// 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/new_tab_page/customize_chrome/customize_chrome_feature_promo_helper.h" + +#include "chrome/browser/feature_engagement/tracker_factory.h" +#include "chrome/test/base/browser_with_test_window_test.h" +#include "chrome/test/base/test_browser_window.h" +#include "components/feature_engagement/public/event_constants.h" +#include "components/feature_engagement/public/feature_constants.h" +#include "components/feature_engagement/test/mock_tracker.h" +#include "components/feature_engagement/test/scoped_iph_feature_list.h" +#include "components/user_education/test/mock_feature_promo_controller.h" +#include "testing/gmock/include/gmock/gmock.h" + +class CustomizeChromeFeaturePromoHelperTest : public BrowserWithTestWindowTest { + protected: + CustomizeChromeFeaturePromoHelperTest() {} + + void SetUp() override { + BrowserWithTestWindowTest::SetUp(); + + iph_feature_list_.InitAndEnableFeatures( + {feature_engagement::kIPHDesktopCustomizeChromeFeature}); + + AddTab(browser(), GURL("chrome://newtab")); + tab_ = browser()->tab_strip_model()->GetActiveWebContents(); + + mock_tracker_ = + static_cast<testing::NiceMock<feature_engagement::test::MockTracker>*>( + feature_engagement::TrackerFactory::GetForBrowserContext( + tab_->GetBrowserContext())); + } + + std::unique_ptr<BrowserWindow> CreateBrowserWindow() override { + auto test_window = std::make_unique<TestBrowserWindow>(); + + // This test only supports one window. + DCHECK(!mock_promo_controller_); + + mock_promo_controller_ = + static_cast<user_education::test::MockFeaturePromoController*>( + test_window->SetFeaturePromoController( + std::make_unique< + user_education::test::MockFeaturePromoController>())); + return test_window; + } + + TestingProfile::TestingFactories GetTestingFactories() override { + TestingProfile::TestingFactories factories = { + {feature_engagement::TrackerFactory::GetInstance(), + base::BindRepeating( + CustomizeChromeFeaturePromoHelperTest::MakeTestTracker)}}; + return factories; + } + + content::WebContents* tab() { return tab_; } + user_education::test::MockFeaturePromoController* mock_promo_controller() { + return mock_promo_controller_; + } + feature_engagement::test::MockTracker* mock_tracker() { + return mock_tracker_; + } + + private: + feature_engagement::test::ScopedIphFeatureList iph_feature_list_; + raw_ptr<content::WebContents> tab_; + raw_ptr<testing::NiceMock<feature_engagement::test::MockTracker>> + mock_tracker_; + raw_ptr<user_education::test::MockFeaturePromoController> + mock_promo_controller_ = nullptr; + + static std::unique_ptr<KeyedService> MakeTestTracker( + content::BrowserContext* context) { + auto tracker = std::make_unique< + testing::NiceMock<feature_engagement::test::MockTracker>>(); + return tracker; + } +}; + +TEST_F(CustomizeChromeFeaturePromoHelperTest, + RecordCustomizeChromeFeatureUsage) { + EXPECT_CALL(*mock_tracker(), + NotifyEvent(feature_engagement::events::kCustomizeChromeOpened)) + .Times(1); + CustomizeChromeFeaturePromoHelper customize_chrome_feature_promo_helper; + customize_chrome_feature_promo_helper.RecordCustomizeChromeFeatureUsage( + tab()); +} + +TEST_F(CustomizeChromeFeaturePromoHelperTest, + MaybeShowCustomizeChromeFeaturePromoHelper) { + EXPECT_CALL( + *mock_promo_controller(), + MaybeShowPromo( + testing::Ref(feature_engagement::kIPHDesktopCustomizeChromeFeature), + testing::_, testing::_)) + .Times(1) + .WillOnce(testing::Return(true)); + CustomizeChromeFeaturePromoHelper customize_chrome_feature_promo_helper; + customize_chrome_feature_promo_helper.MaybeShowCustomizeChromeFeaturePromo( + tab()); +} + +TEST_F(CustomizeChromeFeaturePromoHelperTest, + CloseCustomizeChromeFeaturePromoHelper) { + EXPECT_CALL(*mock_promo_controller(), + EndPromo(testing::Ref( + feature_engagement::kIPHDesktopCustomizeChromeFeature))) + .Times(1) + .WillOnce(testing::Return(true)); + CustomizeChromeFeaturePromoHelper customize_chrome_feature_promo_helper; + customize_chrome_feature_promo_helper.CloseCustomizeChromeFeaturePromo(tab()); +}
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc index 78f8ca5..7880a10 100644 --- a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc +++ b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc
@@ -139,6 +139,12 @@ subresource_filter::SubresourceFilterBrowserTest::SetUp(); } + void SetUpCommandLine(base::CommandLine* command_line) override { + subresource_filter::SubresourceFilterBrowserTest::SetUpCommandLine( + command_line); + command_line->AppendSwitchASCII(switches::kForceDeviceScaleFactor, "1"); + } + void SetUpOnMainThread() override { SubresourceFilterBrowserTest::SetUpOnMainThread(); SetRulesetWithRules(
diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc index 61d30bf..8076ee1 100644 --- a/chrome/browser/password_manager/password_manager_browsertest.cc +++ b/chrome/browser/password_manager/password_manager_browsertest.cc
@@ -4835,6 +4835,7 @@ content::JsReplace("document.getElementById('normal').src = $1", form_url))); content::WaitForLoadStop(WebContents()); + iframe_normal = ChildFrameAt(WebContents()->GetPrimaryMainFrame(), 0); EXPECT_EQ("not found", content::EvalJs(iframe_normal, "window.parent.check_password(document);"));
diff --git a/chrome/browser/permissions/permission_request_manager_browsertest.cc b/chrome/browser/permissions/permission_request_manager_browsertest.cc index 906db80..ab6d693 100644 --- a/chrome/browser/permissions/permission_request_manager_browsertest.cc +++ b/chrome/browser/permissions/permission_request_manager_browsertest.cc
@@ -9,6 +9,7 @@ #include "base/command_line.h" #include "base/functional/bind.h" #include "base/metrics/field_trial.h" +#include "base/metrics/field_trial_params.h" #include "base/run_loop.h" #include "base/test/mock_callback.h" #include "base/test/scoped_feature_list.h" @@ -39,7 +40,6 @@ #include "components/permissions/test/mock_permission_prompt_factory.h" #include "components/permissions/test/mock_permission_request.h" #include "components/permissions/test/permission_request_observer.h" -#include "components/variations/variations_associated_data.h" #include "content/public/browser/permission_controller.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" @@ -143,9 +143,8 @@ std::map<std::string, std::string> params; params[permissions::PermissionUtil::GetPermissionString( content_settings_type)] = kPermissionsKillSwitchBlockedValue; - variations::AssociateVariationParams(kPermissionsKillSwitchFieldStudy, - kPermissionsKillSwitchTestGroup, - params); + base::AssociateFieldTrialParams(kPermissionsKillSwitchFieldStudy, + kPermissionsKillSwitchTestGroup, params); base::FieldTrialList::CreateFieldTrial(kPermissionsKillSwitchFieldStudy, kPermissionsKillSwitchTestGroup); }
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index 894b96b..915eafb 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -1341,9 +1341,6 @@ { key::kSecurityTokenSessionNotificationSeconds, prefs::kSecurityTokenSessionNotificationSeconds, base::Value::Type::INTEGER }, - { key::kDeviceArcDataSnapshotHours, - arc::prefs::kArcSnapshotHours, - base::Value::Type::DICT }, { key::kDeviceAllowMGSToStoreDisplayProperties, ash::prefs::kAllowMGSToStoreDisplayProperties, base::Value::Type::BOOLEAN },
diff --git a/chrome/browser/printing/print_backend_browsertest.cc b/chrome/browser/printing/print_backend_browsertest.cc index 5de5dbf..d10a186 100644 --- a/chrome/browser/printing/print_backend_browsertest.cc +++ b/chrome/browser/printing/print_backend_browsertest.cc
@@ -162,15 +162,62 @@ printer_name); } + // `PrintBackendServiceTestImpl` does a debug check on shutdown that there + // are no residual persistent printing contexts left in the service. For + // tests which are known to break this (either by design, for test simplicity + // or because a related change is only partly implemented), use this method + // to notify the service to not DCHECK on such a condition. + void SkipPersistentContextsCheckOnShutdown() { + print_backend_service_->SkipPersistentContextsCheckOnShutdown(); + } + // Common helpers to perform particular stages of printing a document. - mojom::ResultCode StartPrintingAndWait(const PrintSettings& print_settings) { - mojom::ResultCode result; + uint32_t EstablishPrintingContextAndWait() { + constexpr uint32_t kContextId = 7; +#if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) + constexpr uint32_t kParentWindowId = 8; +#endif + + GetPrintBackendService()->EstablishPrintingContext(kContextId +#if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) + , + kParentWindowId +#endif + ); + return kContextId; + } + + mojom::PrintSettingsResultPtr UpdatePrintSettingsAndWait( + uint32_t context_id, + const PrintSettings& print_settings) { + base::Value::Dict job_settings = + PrintSettingsToJobSettingsDebug(print_settings); + job_settings.Set(kSettingPrinterType, + static_cast<int>(mojom::PrinterType::kLocal)); // Safe to use base::Unretained(this) since waiting locally on the callback // forces a shorter lifetime than `this`. + mojom::PrintSettingsResultPtr settings; + GetPrintBackendService()->UpdatePrintSettings( + context_id, std::move(job_settings), + base::BindOnce(&PrintBackendBrowserTest::CapturePrintSettings, + base::Unretained(this), std::ref(settings))); + WaitUntilCallbackReceived(); + return settings; + } + + mojom::ResultCode StartPrintingAndWait(uint32_t context_id, + const PrintSettings& print_settings) { + UpdatePrintSettingsAndWait(context_id, print_settings); + + // Safe to use base::Unretained(this) since waiting locally on the callback + // forces a shorter lifetime than `this`. + mojom::ResultCode result; GetPrintBackendService()->StartPrinting( - kTestDocumentCookie, u"document name", - mojom::PrintTargetType::kDirectToDevice, print_settings, + context_id, kTestDocumentCookie, u"document name", +#if !BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) + /*settings=*/absl::nullopt, +#endif base::BindOnce(&PrintBackendBrowserTest::CaptureResult, base::Unretained(this), std::ref(result))); WaitUntilCallbackReceived(); @@ -496,13 +543,18 @@ AddDefaultPrinter(); SetPrinterNameForSubsequentContexts(kDefaultPrinterName); + // Isolated call has no corresponding cleanup of the printing context. + SkipPersistentContextsCheckOnShutdown(); + + const uint32_t context_id = EstablishPrintingContextAndWait(); + mojom::PrintSettingsResultPtr settings; // Safe to use base::Unretained(this) since waiting locally on the callback // forces a shorter lifetime than `this`. GetPrintBackendService()->UseDefaultSettings( - base::BindOnce(&PrintBackendBrowserTest::CapturePrintSettings, - base::Unretained(this), std::ref(settings))); + context_id, base::BindOnce(&PrintBackendBrowserTest::CapturePrintSettings, + base::Unretained(this), std::ref(settings))); WaitUntilCallbackReceived(); ASSERT_TRUE(settings->is_settings()); EXPECT_EQ(settings->get_settings().copies(), kPrintSettingsCopies); @@ -515,12 +567,17 @@ AddDefaultPrinter(); SetPrinterNameForSubsequentContexts(kDefaultPrinterName); + // Isolated call has no corresponding cleanup of the printing context. + SkipPersistentContextsCheckOnShutdown(); + + const uint32_t context_id = EstablishPrintingContextAndWait(); + mojom::PrintSettingsResultPtr settings; // Safe to use base::Unretained(this) since waiting locally on the callback // forces a shorter lifetime than `this`. GetPrintBackendService()->AskUserForSettings( - /*parent_window_id=*/8, + context_id, /*max_pages=*/1, /*has_selection=*/false, /*is_scripted=*/false, base::BindOnce(&PrintBackendBrowserTest::CapturePrintSettings, base::Unretained(this), std::ref(settings))); @@ -536,23 +593,17 @@ AddDefaultPrinter(); SetPrinterNameForSubsequentContexts(kDefaultPrinterName); - mojom::PrintSettingsResultPtr settings; + // Isolated call has no corresponding cleanup of the printing context. + SkipPersistentContextsCheckOnShutdown(); + + const uint32_t context_id = EstablishPrintingContextAndWait(); PrintSettings print_settings; print_settings.set_device_name(kDefaultPrinterName16); print_settings.set_dpi(kPrintSettingsOverrideDpi); - base::Value::Dict job_settings = - PrintSettingsToJobSettingsDebug(print_settings); - job_settings.Set(kSettingPrinterType, - static_cast<int>(mojom::PrinterType::kLocal)); - // Safe to use base::Unretained(this) since waiting locally on the callback - // forces a shorter lifetime than `this`. - GetPrintBackendService()->UpdatePrintSettings( - std::move(job_settings), - base::BindOnce(&PrintBackendBrowserTest::CapturePrintSettings, - base::Unretained(this), std::ref(settings))); - WaitUntilCallbackReceived(); + mojom::PrintSettingsResultPtr settings = + UpdatePrintSettingsAndWait(context_id, print_settings); ASSERT_TRUE(settings->is_settings()); EXPECT_EQ(settings->get_settings().copies(), kPrintSettingsCopies); EXPECT_EQ(settings->get_settings().dpi(), kPrintSettingsOverrideDpi); @@ -569,38 +620,25 @@ // Updating for an invalid printer should not return print settings. print_settings.set_device_name(kInvalidPrinterName16); - job_settings = PrintSettingsToJobSettingsDebug(print_settings); - job_settings.Set(kSettingPrinterType, - static_cast<int>(mojom::PrinterType::kLocal)); - GetPrintBackendService()->UpdatePrintSettings( - std::move(job_settings), - base::BindOnce(&PrintBackendBrowserTest::CapturePrintSettings, - base::Unretained(this), std::ref(settings))); - WaitUntilCallbackReceived(); + + settings = UpdatePrintSettingsAndWait(context_id, print_settings); ASSERT_TRUE(settings->is_result_code()); EXPECT_EQ(settings->get_result_code(), mojom::ResultCode::kFailed); } -IN_PROC_BROWSER_TEST_F(PrintBackendBrowserTest, StartPrintingValidPrinter) { +IN_PROC_BROWSER_TEST_F(PrintBackendBrowserTest, StartPrinting) { LaunchService(); AddDefaultPrinter(); SetPrinterNameForSubsequentContexts(kDefaultPrinterName); + const uint32_t context_id = EstablishPrintingContextAndWait(); + PrintSettings print_settings; print_settings.set_device_name(kDefaultPrinterName16); + ASSERT_TRUE(UpdatePrintSettingsAndWait(context_id, print_settings)); - EXPECT_EQ(StartPrintingAndWait(print_settings), mojom::ResultCode::kSuccess); -} - -IN_PROC_BROWSER_TEST_F(PrintBackendBrowserTest, StartPrintingInvalidPrinter) { - LaunchService(); - AddDefaultPrinter(); - SetPrinterNameForSubsequentContexts(kDefaultPrinterName); - - PrintSettings print_settings; - print_settings.set_device_name(kInvalidPrinterName16); - - EXPECT_EQ(StartPrintingAndWait(print_settings), mojom::ResultCode::kFailed); + EXPECT_EQ(StartPrintingAndWait(context_id, print_settings), + mojom::ResultCode::kSuccess); } #if BUILDFLAG(IS_WIN) @@ -609,10 +647,14 @@ AddDefaultPrinter(); SetPrinterNameForSubsequentContexts(kDefaultPrinterName); + const uint32_t context_id = EstablishPrintingContextAndWait(); + PrintSettings print_settings; print_settings.set_device_name(kDefaultPrinterName16); + ASSERT_TRUE(UpdatePrintSettingsAndWait(context_id, print_settings)); - EXPECT_EQ(StartPrintingAndWait(print_settings), mojom::ResultCode::kSuccess); + ASSERT_EQ(StartPrintingAndWait(context_id, print_settings), + mojom::ResultCode::kSuccess); absl::optional<mojom::ResultCode> result = RenderPageAndWait(); EXPECT_EQ(result, mojom::ResultCode::kSuccess); @@ -627,10 +669,14 @@ AddDefaultPrinter(); SetPrinterNameForSubsequentContexts(kDefaultPrinterName); + const uint32_t context_id = EstablishPrintingContextAndWait(); + PrintSettings print_settings; print_settings.set_device_name(kDefaultPrinterName16); + ASSERT_TRUE(UpdatePrintSettingsAndWait(context_id, print_settings)); - EXPECT_EQ(StartPrintingAndWait(print_settings), mojom::ResultCode::kSuccess); + ASSERT_EQ(StartPrintingAndWait(context_id, print_settings), + mojom::ResultCode::kSuccess); absl::optional<mojom::ResultCode> result = RenderDocumentAndWait(); EXPECT_EQ(result, mojom::ResultCode::kSuccess); @@ -642,10 +688,14 @@ AddDefaultPrinter(); SetPrinterNameForSubsequentContexts(kDefaultPrinterName); + const uint32_t context_id = EstablishPrintingContextAndWait(); + PrintSettings print_settings; print_settings.set_device_name(kDefaultPrinterName16); + ASSERT_TRUE(UpdatePrintSettingsAndWait(context_id, print_settings)); - EXPECT_EQ(StartPrintingAndWait(print_settings), mojom::ResultCode::kSuccess); + ASSERT_EQ(StartPrintingAndWait(context_id, print_settings), + mojom::ResultCode::kSuccess); // TODO(crbug.com/1008222) Include Windows coverage for RenderDocument() // path once XPS print pipeline is enabled. @@ -664,10 +714,14 @@ AddDefaultPrinter(); SetPrinterNameForSubsequentContexts(kDefaultPrinterName); + const uint32_t context_id = EstablishPrintingContextAndWait(); + PrintSettings print_settings; print_settings.set_device_name(kDefaultPrinterName16); + ASSERT_TRUE(UpdatePrintSettingsAndWait(context_id, print_settings)); - EXPECT_EQ(StartPrintingAndWait(print_settings), mojom::ResultCode::kSuccess); + EXPECT_EQ(StartPrintingAndWait(context_id, print_settings), + mojom::ResultCode::kSuccess); CancelAndWait(); }
diff --git a/chrome/browser/printing/print_backend_service_manager.cc b/chrome/browser/printing/print_backend_service_manager.cc index 2d4760b9..40e9ea2 100644 --- a/chrome/browser/printing/print_backend_service_manager.cc +++ b/chrome/browser/printing/print_backend_service_manager.cc
@@ -270,11 +270,16 @@ // due to an idle timeout. The client could be used for a system print // dialog and/or for printing a document. Either `kQueryWithUi` or // `kPrintDocument` would satisfy guaranteeing this persists for as long as - // could be needed. Associate this with the printing document client type, - // given that most cases would fall into this usage. + // could be needed. The particular use case that it is being used with can + // be deduced from the provided `printer_name`, since the printer cannot be + // known ahead of time for a system print dialog query, but must be known + // when printing a document. CallbackContext context; - auto& service = GetServiceAndCallbackContextForPrintDocumentClient( - client_id, printer_name, context); + auto& service = printer_name.empty() + ? GetServiceAndCallbackContextForQueryWithUiClient( + client_id, kEmptyPrinterName, context) + : GetServiceAndCallbackContextForPrintDocumentClient( + client_id, printer_name, context); LogCallToRemote("EstablishPrintingContext", context); ContextId context_id = ContextId(++last_context_id_); @@ -289,6 +294,7 @@ void PrintBackendServiceManager::UseDefaultSettings( ClientId client_id, + ContextId context_id, mojom::PrintBackendService::UseDefaultSettingsCallback callback) { // Even though this call does not require a UI, it is used exclusively as // part of preparation for system print. It is called immediately before a @@ -305,6 +311,7 @@ LogCallToRemote("UseDefaultSettings", context); service->UseDefaultSettings( + *context_id, base::BindOnce(&PrintBackendServiceManager::OnDidUseDefaultSettings, base::Unretained(this), std::move(context))); } @@ -312,7 +319,7 @@ #if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) void PrintBackendServiceManager::AskUserForSettings( ClientId client_id, - gfx::NativeView parent_view, + ContextId context_id, int max_pages, bool has_selection, bool is_scripted, @@ -327,23 +334,27 @@ LogCallToRemote("AskUserForSettings", context); service->AskUserForSettings( - NativeViewToUint(parent_view), max_pages, has_selection, is_scripted, + *context_id, max_pages, has_selection, is_scripted, base::BindOnce(&PrintBackendServiceManager::OnDidAskUserForSettings, base::Unretained(this), std::move(context))); } #endif // BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) void PrintBackendServiceManager::UpdatePrintSettings( - absl::optional<ClientId> client_id, + ClientId client_id, const std::string& printer_name, + ContextId context_id, base::Value::Dict job_settings, mojom::PrintBackendService::UpdatePrintSettingsCallback callback) { + // A blank `printer_name` indicates the destination is unknown, which occurs + // when initiating a system print dialog. When printing a document the + // destination must be known. CallbackContext context; - auto& service = - client_id.has_value() - ? GetServiceAndCallbackContextForQueryWithUiClient( - *client_id, printer_name, context) - : GetServiceAndCallbackContextForQuery(printer_name, context); + auto& service = printer_name.empty() + ? GetServiceAndCallbackContextForQueryWithUiClient( + client_id, printer_name, context) + : GetServiceAndCallbackContextForPrintDocumentClient( + client_id, printer_name, context); SaveCallback(GetRemoteSavedUpdatePrintSettingsCallbacks(context.is_sandboxed), context.remote_id, context.saved_callback_id, @@ -353,7 +364,7 @@ LogCallToRemote("UpdatePrintSettings", context); service->UpdatePrintSettings( - std::move(job_settings), + *context_id, std::move(job_settings), base::BindOnce(&PrintBackendServiceManager::OnDidUpdatePrintSettings, base::Unretained(this), std::move(context))); } @@ -361,10 +372,12 @@ void PrintBackendServiceManager::StartPrinting( ClientId client_id, const std::string& printer_name, + ContextId context_id, int document_cookie, const std::u16string& document_name, - mojom::PrintTargetType target_type, - const PrintSettings& settings, +#if !BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) + absl::optional<PrintSettings> settings, +#endif mojom::PrintBackendService::StartPrintingCallback callback) { CallbackContext context; auto& service = GetServiceAndCallbackContextForPrintDocumentClient( @@ -378,7 +391,10 @@ LogCallToRemote("StartPrinting", context); service->StartPrinting( - document_cookie, document_name, target_type, settings, + *context_id, document_cookie, document_name, +#if !BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) + settings, +#endif base::BindOnce(&PrintBackendServiceManager::OnDidStartPrinting, base::Unretained(this), std::move(context))); }
diff --git a/chrome/browser/printing/print_backend_service_manager.h b/chrome/browser/printing/print_backend_service_manager.h index 734ddd8..753a073 100644 --- a/chrome/browser/printing/print_backend_service_manager.h +++ b/chrome/browser/printing/print_backend_service_manager.h
@@ -145,41 +145,45 @@ ); void UseDefaultSettings( ClientId client_id, + ContextId context_id, mojom::PrintBackendService::UseDefaultSettingsCallback callback); #if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) void AskUserForSettings( ClientId client_id, - gfx::NativeView parent_view, + ContextId context_id, int max_pages, bool has_selection, bool is_scripted, mojom::PrintBackendService::AskUserForSettingsCallback callback); #endif - // `UpdatePrintSettings()` can be used in two different scenarios: - // - For Print Preview, where the desire is to use the appropriate - // service based on the `printer_name` indicated. - // - System printing, where a particular PrintBackendService instance - // is desired, and is selected based upon a ClientId. - // When `client_id` is null, then the `printer_name` will be used to select - // the service. Otherwise the `client_id` value will be used, similar to - // other methods related for supporting the system print dialog and for - // printing the document. - // TODO(crbug.com/1414968): Remove use of optional for `client_id` once - // this the callers are updated to take advantage of `UpdatePrintSettings()` - // no longer being needed for Print Preview queries after - // https://crrev.com/1117252. + // `UpdatePrintSettings()` can be used prior to initiating a system print + // dialog or right before starting to print a document. The first requires a + // `client_id` of `kQueryWithUi` type, while the latter requires a the ID to + // be of type `kPrintDocument`. + // The destination printer is still unknown when initiating a system print + // dialog, so `printer_name` will be empty in this case. The destination + // must be known when starting to print a document. `UpdatePrintSettings()` + // uses this insight to know what kind of client type is to be expected for + // the provided `client_id`. The function will CHECK if the `client_id` + // is not registered for the expected type. void UpdatePrintSettings( - absl::optional<ClientId> client_id, + ClientId client_id, const std::string& printer_name, + ContextId context_id, base::Value::Dict job_settings, mojom::PrintBackendService::UpdatePrintSettingsCallback callback); + // `StartPrinting()` initiates the printing of a document. The optional + // `settings` is used in the case where a system print dialog is invoked + // from in the browser, and this provides those settings for printing. void StartPrinting( ClientId client_id, const std::string& printer_name, + ContextId context_id, int document_cookie, const std::u16string& document_name, - mojom::PrintTargetType target_type, - const PrintSettings& settings, +#if !BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) + absl::optional<PrintSettings> settings, +#endif mojom::PrintBackendService::StartPrintingCallback callback); #if BUILDFLAG(IS_WIN) void RenderPrintedPage(
diff --git a/chrome/browser/printing/print_backend_service_test_impl.cc b/chrome/browser/printing/print_backend_service_test_impl.cc index 53df1ab..2aa81266 100644 --- a/chrome/browser/printing/print_backend_service_test_impl.cc +++ b/chrome/browser/printing/print_backend_service_test_impl.cc
@@ -71,8 +71,10 @@ test_print_backend_(std::move(backend)) {} PrintBackendServiceTestImpl::~PrintBackendServiceTestImpl() { - // Make sure that all persistent contexts have been properly cleaned up. - DCHECK(persistent_printing_contexts_.empty()); + if (!skip_dtor_persistent_contexts_check_) { + // Make sure that all persistent contexts have been properly cleaned up. + DCHECK(persistent_printing_contexts_.empty()); + } } void PrintBackendServiceTestImpl::Init( @@ -142,6 +144,7 @@ } void PrintBackendServiceTestImpl::UpdatePrintSettings( + uint32_t context_id, base::Value::Dict job_settings, mojom::PrintBackendService::UpdatePrintSettingsCallback callback) { if (terminate_receiver_) { @@ -149,8 +152,8 @@ return; } - PrintBackendServiceImpl::UpdatePrintSettings(std::move(job_settings), - std::move(callback)); + PrintBackendServiceImpl::UpdatePrintSettings( + context_id, std::move(job_settings), std::move(callback)); } #if BUILDFLAG(IS_WIN)
diff --git a/chrome/browser/printing/print_backend_service_test_impl.h b/chrome/browser/printing/print_backend_service_test_impl.h index addd06b..f10b3dd 100644 --- a/chrome/browser/printing/print_backend_service_test_impl.h +++ b/chrome/browser/printing/print_backend_service_test_impl.h
@@ -97,6 +97,7 @@ const std::string& printer_name, mojom::PrintBackendService::FetchCapabilitiesCallback callback) override; void UpdatePrintSettings( + uint32_t context_id, base::Value::Dict job_settings, mojom::PrintBackendService::UpdatePrintSettingsCallback callback) override; @@ -112,6 +113,13 @@ mojom::PrintBackendService::RenderPrintedPageCallback callback) override; #endif // BUILDFLAG(IS_WIN) + // Tests which will have a leftover printing context established in the + // service can use this to skip the destructor check that all contexts were + // cleaned up. + void SkipPersistentContextsCheckOnShutdown() { + skip_dtor_persistent_contexts_check_ = true; + } + // Cause the service to terminate on the next interaction it receives. Once // terminated no further Mojo calls will be possible since there will not be // a receiver to handle them. @@ -152,6 +160,9 @@ // denied errors. bool is_sandboxed_ = false; + // Marker for skipping check for empty persistent contexts at destruction. + bool skip_dtor_persistent_contexts_check_ = false; + // Marker to signal service should terminate on next interaction. bool terminate_receiver_ = false;
diff --git a/chrome/browser/printing/print_job_worker_oop.cc b/chrome/browser/printing/print_job_worker_oop.cc index c9576f1..632a59a 100644 --- a/chrome/browser/printing/print_job_worker_oop.cc +++ b/chrome/browser/printing/print_job_worker_oop.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/printing/print_job_worker_oop.h" +#include "base/check_op.h" +#include "base/functional/bind.h" #include "base/metrics/histogram_functions.h" #include "base/notreached.h" #include "base/strings/utf_string_conversions.h" @@ -15,9 +17,11 @@ #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/global_routing_id.h" +#include "printing/buildflags/buildflags.h" #include "printing/metafile.h" #include "printing/printed_document.h" #include "printing/printing_features.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #if BUILDFLAG(IS_WIN) #include "printing/printed_page_win.h" @@ -49,28 +53,32 @@ std::unique_ptr<PrintingContext::Delegate> printing_context_delegate, std::unique_ptr<PrintingContext> printing_context, absl::optional<PrintBackendServiceManager::ClientId> client_id, + absl::optional<PrintBackendServiceManager::ContextId> context_id, PrintJob* print_job, - mojom::PrintTargetType print_target_type) + bool print_from_system_dialog) : PrintJobWorkerOop(std::move(printing_context_delegate), std::move(printing_context), client_id, + context_id, print_job, - print_target_type, + print_from_system_dialog, /*simulate_spooling_memory_errors=*/false) {} PrintJobWorkerOop::PrintJobWorkerOop( std::unique_ptr<PrintingContext::Delegate> printing_context_delegate, std::unique_ptr<PrintingContext> printing_context, absl::optional<PrintBackendServiceManager::ClientId> client_id, + absl::optional<PrintBackendServiceManager::ContextId> context_id, PrintJob* print_job, - mojom::PrintTargetType print_target_type, + bool print_from_system_dialog, bool simulate_spooling_memory_errors) : PrintJobWorker(std::move(printing_context_delegate), std::move(printing_context), print_job), simulate_spooling_memory_errors_(simulate_spooling_memory_errors), service_manager_client_id_(client_id), - print_target_type_(print_target_type) {} + printing_context_id_(context_id), + print_from_system_dialog_(print_from_system_dialog) {} PrintJobWorkerOop::~PrintJobWorkerOop() { DCHECK(!service_manager_client_id_.has_value()); @@ -202,6 +210,7 @@ << document_oop_->cookie(); UnregisterServiceManagerClient(); + printing_context_id_.reset(); // Done with private document reference. document_oop_ = nullptr; @@ -317,11 +326,22 @@ PrintBackendServiceManager::GetInstance(); service_mgr.SetPrinterDriverFoundToRequireElevatedPrivilege(device_name_); +#if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) + if (print_from_system_dialog_) { + // Cannot print from process where system dialog was displayed. Another + // print attempt where dialog is used again will be required. + PRINTER_LOG(ERROR) << "Failure during system printing, unable to retry."; + return false; + } +#endif + // Failure from access-denied means we no longer need the prior client ID. UnregisterServiceManagerClient(); - // Retry the operation, which should now happen at a higher privilege - // level. + // Need to establish a new persistent printing context to use during + // printing. Then retry the operation, which should now happen at a higher + // privilege level. + SendEstablishPrintingContext(); SendStartPrinting(device_name_, document_name_); return true; } @@ -361,6 +381,29 @@ } } +void PrintJobWorkerOop::SendEstablishPrintingContext() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + DCHECK(features::kEnableOopPrintDriversJobPrint.Get()); + + PrintBackendServiceManager& service_mgr = + PrintBackendServiceManager::GetInstance(); + + // Register this worker as a printing client, if registration wasn't already + // performed earlier. + if (!service_manager_client_id_.has_value()) { + service_manager_client_id_ = + service_mgr.RegisterPrintDocumentClient(device_name_); + } + + printing_context_id_ = service_mgr.EstablishPrintingContext( + *service_manager_client_id_, device_name_ +#if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) + , + /*parent_view=*/nullptr +#endif + ); +} + void PrintJobWorkerOop::SendStartPrinting(const std::string& device_name, const std::u16string& document_name) { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -381,16 +424,23 @@ PrintBackendServiceManager& service_mgr = PrintBackendServiceManager::GetInstance(); - // Register this worker as a printing client, if registration wasn't already - // performed earlier. - if (!service_manager_client_id_.has_value()) { - service_manager_client_id_ = - service_mgr.RegisterPrintDocumentClient(device_name_); + if (!printing_context_id_.has_value()) { + // Need to establish a persistent printing context to use during printing. + SendEstablishPrintingContext(); } +#if !BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) + absl::optional<PrintSettings> settings; + if (print_from_system_dialog_) { + settings = document_oop_->settings(); + } +#endif service_mgr.StartPrinting( - *service_manager_client_id_, device_name_, document_cookie, - document_name_, print_target_type_, document_oop_->settings(), + *service_manager_client_id_, device_name, *printing_context_id_, + document_cookie, document_name_, +#if !BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) + settings, +#endif base::BindOnce(&PrintJobWorkerOop::OnDidStartPrinting, ui_weak_factory_.GetWeakPtr())); }
diff --git a/chrome/browser/printing/print_job_worker_oop.h b/chrome/browser/printing/print_job_worker_oop.h index bcf299a..e51d45f 100644 --- a/chrome/browser/printing/print_job_worker_oop.h +++ b/chrome/browser/printing/print_job_worker_oop.h
@@ -41,8 +41,9 @@ std::unique_ptr<PrintingContext::Delegate> printing_context_delegate, std::unique_ptr<PrintingContext> printing_context, absl::optional<PrintBackendServiceManager::ClientId> client_id, + absl::optional<PrintBackendServiceManager::ContextId> context_id, PrintJob* print_job, - mojom::PrintTargetType print_target_type); + bool print_from_system_dialog); PrintJobWorkerOop(const PrintJobWorkerOop&) = delete; PrintJobWorkerOop& operator=(const PrintJobWorkerOop&) = delete; ~PrintJobWorkerOop() override; @@ -56,8 +57,9 @@ std::unique_ptr<PrintingContext::Delegate> printing_context_delegate, std::unique_ptr<PrintingContext> printing_context, absl::optional<PrintBackendServiceManager::ClientId> client_id, + absl::optional<PrintBackendServiceManager::ContextId> context_id, PrintJob* print_job, - mojom::PrintTargetType print_target_type, + bool print_from_system_dialog, bool simulate_spooling_memory_errors); // Local callback wrappers for Print Backend Service mojom call. Virtual to @@ -91,6 +93,8 @@ // Initiate failure handling, including notification to the user. void NotifyFailure(mojom::ResultCode result); + // Mojo support to send messages from UI thread. + void SendEstablishPrintingContext(); void SendStartPrinting(const std::string& device_name, const std::u16string& document_name); #if BUILDFLAG(IS_WIN) @@ -113,6 +117,10 @@ absl::optional<PrintBackendServiceManager::ClientId> service_manager_client_id_; + // The printing context identifier related to this print job. + // Used only from UI thread. + absl::optional<PrintBackendServiceManager::ContextId> printing_context_id_; + // The device name used when printing via a service. Used only from the UI // thread. std::string device_name_; @@ -129,9 +137,8 @@ // to avoid any potential confusion between them. scoped_refptr<PrintedDocument> document_oop_; - // The type of target to print to. Used only from the UI thread. - mojom::PrintTargetType print_target_type_ = - mojom::PrintTargetType::kDirectToDevice; + // Indicates if the print job was initiated from the print system dialog. + const bool print_from_system_dialog_; #if BUILDFLAG(IS_WIN) // Number of pages that have completed printing.
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc index 9c9a56c2..7df5210 100644 --- a/chrome/browser/printing/print_view_manager_base.cc +++ b/chrome/browser/printing/print_view_manager_base.cc
@@ -241,6 +241,11 @@ std::move(callback)); std::unique_ptr<printing::PrinterQuery> printer_query = queue_->CreatePrinterQuery(rfh->GetGlobalId()); +#if BUILDFLAG(ENABLE_OOP_PRINTING) + if (query_with_ui_client_id_.has_value()) { + printer_query->SetClientId(*query_with_ui_client_id_); + } +#endif auto* printer_query_ptr = printer_query.get(); printer_query_ptr->SetSettings( std::move(job_settings),
diff --git a/chrome/browser/printing/printer_query_oop.cc b/chrome/browser/printing/printer_query_oop.cc index 2237b86..e07caaa 100644 --- a/chrome/browser/printing/printer_query_oop.cc +++ b/chrome/browser/printing/printer_query_oop.cc
@@ -7,33 +7,18 @@ #include <memory> #include <utility> +#include "base/check_op.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/printing/print_backend_service_manager.h" #include "chrome/browser/printing/print_job_worker_oop.h" #include "components/device_event_log/device_event_log.h" #include "content/public/browser/global_routing_id.h" #include "content/public/browser/web_contents.h" +#include "printing/buildflags/buildflags.h" #include "printing/printing_features.h" namespace printing { -namespace { - -mojom::PrintTargetType DeterminePrintTargetType( - const base::Value::Dict& job_settings) { -#if BUILDFLAG(IS_MAC) - if (job_settings.contains(kSettingOpenPDFInPreview)) { - return mojom::PrintTargetType::kExternalPreview; - } -#endif - if (job_settings.FindBool(kSettingShowSystemDialog).value_or(false)) { - return mojom::PrintTargetType::kSystemDialog; - } - return mojom::PrintTargetType::kDirectToDevice; -} - -} // namespace - PrinterQueryOop::PrinterQueryOop(content::GlobalRenderFrameHostId rfh_id) : PrinterQuery(rfh_id) {} @@ -125,6 +110,13 @@ void PrinterQueryOop::UseDefaultSettings(SettingsCallback callback) { #if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) + CHECK(query_with_ui_client_id_.has_value()); + + // Any settings selected from the system dialog could need to be retained + // for printing, so establish a printing context. + CHECK(!context_id_.has_value()); + SendEstablishPrintingContext(*query_with_ui_client_id_, + /*printer_name=*/std::string()); SendUseDefaultSettings(std::move(callback)); #else // `PrintingContextLinux::UseDefaultSettings()` is to be called prior to @@ -139,6 +131,10 @@ bool has_selection, bool is_scripted, SettingsCallback callback) { + // Save the print target type from the settings, since this will be needed + // later when printing is started. + print_from_system_dialog_ = true; + #if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) SendAskUserForSettings(document_page_count, has_selection, is_scripted, std::move(callback)); @@ -166,16 +162,47 @@ // Do not take a const reference, as `new_settings` will be modified below. std::string device_name = *new_settings.FindString(kSettingDeviceName); - // Save the print target type from the settings, since this will be needed + // Remember if this is from system print dialog, since this will be needed // later when printing is started. - print_target_type_ = DeterminePrintTargetType(new_settings); + print_from_system_dialog_ = + new_settings.FindBool(kSettingShowSystemDialog).value_or(false); - VLOG(1) << "Updating print settings via service for " << device_name; + // A device name is required for printing documents. If the device name is + // empty then this is for a system print dialog, for which a destination is + // not yet known. PrintBackendServiceManager& service_mgr = PrintBackendServiceManager::GetInstance(); + PrintBackendServiceManager::ClientId client_id; + std::string printer_name; + if (print_from_system_dialog_) { + CHECK(!print_document_client_id_.has_value()); + client_id = *query_with_ui_client_id_; +#if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) && BUILDFLAG(IS_WIN) + // `PrintingContextWin::UpdatePrintSettings()` is special because it can + // invoke `AskUserForSettings()` and cause a system dialog to be displayed. + // Running a dialog causes an exit to webpage-initiated fullscreen. + // http://crbug.com/728276 + content::WebContents* web_contents = GetWebContents(); + if (web_contents && web_contents->IsFullscreen()) { + web_contents->ExitFullscreen(true); + } +#endif + } else { + // Print the document from Print Preview. + CHECK(!query_with_ui_client_id_.has_value()); + CHECK(!print_document_client_id_.has_value()); + + print_document_client_id_ = + service_mgr.RegisterPrintDocumentClient(device_name); + client_id = *print_document_client_id_; + printer_name = device_name; + } + SendEstablishPrintingContext(client_id, printer_name); + + VLOG(1) << "Updating print settings via service for " << device_name; service_mgr.UpdatePrintSettings( - query_with_ui_client_id_, device_name, std::move(new_settings), + client_id, printer_name, *context_id_, std::move(new_settings), base::BindOnce(&PrinterQueryOop::OnDidUpdatePrintSettings, weak_factory_.GetWeakPtr(), device_name, std::move(callback))); @@ -200,17 +227,44 @@ result = mojom::ResultCode::kSuccess; printing_context()->ApplyPrintSettings(print_settings->get_settings()); - // Query work completed, next step will be to print. - // TODO(crbug.com/1414968): Registration for printing a document will - // need to be made before calling `UpdatePrintSettings()` once it requires - // a context ID. - print_document_client_id_ = - PrintBackendServiceManager::GetInstance().RegisterPrintDocumentClient( - device_name); + if (query_with_ui_client_id_.has_value()) { + // Use the same PrintBackendService for querying and printing, so that the + // same device context can be used with both. + CHECK(!print_document_client_id_.has_value()); + print_document_client_id_ = + PrintBackendServiceManager::GetInstance() + .RegisterPrintDocumentClientReusingClientRemote( + *query_with_ui_client_id_); + } } InvokeSettingsCallback(std::move(callback), result); } +void PrinterQueryOop::SendEstablishPrintingContext( + PrintBackendServiceManager::ClientId client_id, + const std::string& printer_name) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + DCHECK(features::kEnableOopPrintDriversJobPrint.Get()); + + DVLOG(1) << "Establishing printing context for system print"; + +#if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) + content::WebContents* web_contents = GetWebContents(); + gfx::NativeView parent_view = + web_contents ? web_contents->GetTopLevelNativeWindow() : nullptr; +#endif + + PrintBackendServiceManager& service_mgr = + PrintBackendServiceManager::GetInstance(); + + context_id_ = service_mgr.EstablishPrintingContext(client_id, printer_name +#if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) + , + parent_view +#endif + ); +} + void PrinterQueryOop::SendUseDefaultSettings(SettingsCallback callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK(features::kEnableOopPrintDriversJobPrint.Get()); @@ -220,7 +274,7 @@ PrintBackendServiceManager::GetInstance(); service_mgr.UseDefaultSettings( - *query_with_ui_client_id_, + *query_with_ui_client_id_, *context_id_, base::BindOnce(&PrinterQueryOop::OnDidUseDefaultSettings, weak_factory_.GetWeakPtr(), std::move(callback))); } @@ -238,10 +292,6 @@ return; } - // Save the print target type from the settings, since this will be needed - // later when printing is started. - print_target_type_ = mojom::PrintTargetType::kDirectToDevice; - content::WebContents* web_contents = GetWebContents(); // Running a dialog causes an exit to webpage-initiated fullscreen. @@ -250,13 +300,10 @@ web_contents->ExitFullscreen(true); } - gfx::NativeView parent_view = - web_contents ? web_contents->GetTopLevelNativeWindow() : nullptr; - PrintBackendServiceManager& service_mgr = PrintBackendServiceManager::GetInstance(); service_mgr.AskUserForSettings( - *query_with_ui_client_id_, parent_view, document_page_count, + *query_with_ui_client_id_, *context_id_, document_page_count, has_selection, is_scripted, base::BindOnce(&PrinterQueryOop::OnDidAskUserForSettings, weak_factory_.GetWeakPtr(), std::move(callback))); @@ -267,7 +314,8 @@ PrintJob* print_job) { return std::make_unique<PrintJobWorkerOop>( std::move(printing_context_delegate_), std::move(printing_context_), - print_document_client_id_, print_job, print_target_type_); + print_document_client_id_, context_id_, print_job, + print_from_system_dialog_); } } // namespace printing
diff --git a/chrome/browser/printing/printer_query_oop.h b/chrome/browser/printing/printer_query_oop.h index 2485f50..f387912 100644 --- a/chrome/browser/printing/printer_query_oop.h +++ b/chrome/browser/printing/printer_query_oop.h
@@ -61,6 +61,12 @@ SettingsCallback callback) override; // Mojo support to send messages from UI thread. + void SendEstablishPrintingContext( + PrintBackendServiceManager::ClientId client_id, + const std::string& printer_name); + void SendUpdatePrintSettings(const std::string& printer_name, + base::Value::Dict new_settings, + SettingsCallback callback); void SendUseDefaultSettings(SettingsCallback callback); #if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) void SendAskUserForSettings(uint32_t document_page_count, @@ -78,16 +84,19 @@ return print_document_client_id_; } - mojom::PrintTargetType print_target_type() const { - return print_target_type_; + bool print_from_system_dialog() const { return print_from_system_dialog_; } + + const absl::optional<PrintBackendServiceManager::ContextId>& context_id() + const { + return context_id_; } private: - mojom::PrintTargetType print_target_type_ = - mojom::PrintTargetType::kDirectToDevice; + bool print_from_system_dialog_ = false; absl::optional<PrintBackendServiceManager::ClientId> query_with_ui_client_id_; absl::optional<PrintBackendServiceManager::ClientId> print_document_client_id_; + absl::optional<PrintBackendServiceManager::ContextId> context_id_; base::WeakPtrFactory<PrinterQueryOop> weak_factory_{this}; };
diff --git a/chrome/browser/printing/system_access_process_print_browsertest.cc b/chrome/browser/printing/system_access_process_print_browsertest.cc index 14f2f71..c4927e6 100644 --- a/chrome/browser/printing/system_access_process_print_browsertest.cc +++ b/chrome/browser/printing/system_access_process_print_browsertest.cc
@@ -151,16 +151,18 @@ TestPrintJobWorkerOop( std::unique_ptr<PrintingContext::Delegate> printing_context_delegate, std::unique_ptr<PrintingContext> printing_context, - PrintBackendServiceManager::ClientId client_id, + absl::optional<PrintBackendServiceManager::ClientId> client_id, + absl::optional<PrintBackendServiceManager::ContextId> context_id, PrintJob* print_job, - mojom::PrintTargetType print_target_type, + bool print_from_system_dialog, bool simulate_spooling_memory_errors, TestPrintJobWorkerOop::PrintCallbacks* callbacks) : PrintJobWorkerOop(std::move(printing_context_delegate), std::move(printing_context), client_id, + context_id, print_job, - print_target_type, + print_from_system_dialog, simulate_spooling_memory_errors), callbacks_(callbacks) {} TestPrintJobWorkerOop(const TestPrintJobWorkerOop&) = delete; @@ -252,8 +254,9 @@ PrintJob* print_job) override { return std::make_unique<TestPrintJobWorkerOop>( std::move(printing_context_delegate_), std::move(printing_context_), - *print_document_client_id(), print_job, print_target_type(), - simulate_spooling_memory_errors_, callbacks_); + print_document_client_id(), context_id(), print_job, + print_from_system_dialog(), simulate_spooling_memory_errors_, + callbacks_); } bool simulate_spooling_memory_errors_; @@ -1300,14 +1303,6 @@ IN_PROC_BROWSER_TEST_P(SystemAccessProcessPrintBrowserTest, SystemPrintFromPrintPreview) { - // TODO(crbug.com/1393505) Enable OOP test coverage once underlying - // printing stack updates to support this scenario with out-of-process are - // in place. - if (GetParam() != PrintBackendFeatureVariation::kInBrowserProcess) { - GTEST_SKIP() << "Skipping test for out-of-process, which is known to crash " - "when transitioning to system print from print preview"; - } - AddPrinter("printer1"); SetPrinterNameForSubsequentContexts("printer1"); @@ -1340,22 +1335,59 @@ SetNumExpectedMessages(/*num=*/4); #endif // BUILDFLAG(IS_WIN) } else { - // TODO(crbug.com/1393505) Fill in expected events once the printing stack - // updates to support this scenario with out-of-process are in place. +#if BUILDFLAG(IS_WIN) + // Once the transition to system print is initiated, the expected events + // are: + // 1. A print job is started. + // 2. Rendering for 1 page of document of content. + // 3. Completes with document done. + // 4. Wait for the one print job to be destroyed, to ensure printing + // finished cleanly before completing the test. + SetNumExpectedMessages(/*num=*/4); +#else + // Once the transition to system print is initiated, the expected events + // are: + // 1. A print job is started. + // 2. Rendering for 1 page of document of content. + // 3. Completes with document done. + // 4. Wait until all processing for DidPrintDocument is known to have + // completed, to ensure printing finished cleanly before completing the + // test. + // 5. Wait for the one print job to be destroyed, to ensure printing + // finished cleanly before completing the test. + SetNumExpectedMessages(/*num=*/5); +#endif // BUILDFLAG(IS_WIN) } SystemPrintFromPreviewOnceReadyAndLoaded(/*wait_for_callback=*/true); -#if !BUILDFLAG(IS_WIN) if (GetParam() == PrintBackendFeatureVariation::kInBrowserProcess) { +#if !BUILDFLAG(IS_WIN) EXPECT_TRUE(did_get_settings_with_ui()); EXPECT_EQ(did_print_document_count(), 1); - } else { - // TODO(crbug.com/1393505) Fill in expectations once the printing stack - // updates to support this scenario with out-of-process are in place. - } #endif - ASSERT_EQ(*MakeUserModifiedPrintSettings("printer1"), - *document_print_settings()); + EXPECT_EQ(*MakeUserModifiedPrintSettings("printer1"), + *document_print_settings()); + } else { + EXPECT_EQ(start_printing_result(), mojom::ResultCode::kSuccess); +#if BUILDFLAG(IS_WIN) + // TODO(crbug.com/1008222) Include Windows coverage of + // RenderPrintedDocument() once XPS print pipeline is added. + EXPECT_EQ(render_printed_page_result(), mojom::ResultCode::kSuccess); + EXPECT_EQ(render_printed_page_count(), 1); +#else + EXPECT_EQ(render_printed_document_result(), mojom::ResultCode::kSuccess); +#endif + EXPECT_EQ(document_done_result(), mojom::ResultCode::kSuccess); +#if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) + EXPECT_EQ(*MakeUserModifiedPrintSettings("printer1"), + *document_print_settings()); +#else + // TODO(crbug.com/1414968): Update the expectation once system print + // settings are properly reflected at start of job print. + EXPECT_NE(*MakeUserModifiedPrintSettings("printer1"), + *document_print_settings()); +#endif + } EXPECT_EQ(error_dialog_shown_count(), 0u); EXPECT_EQ(print_job_destruction_count(), 1); } @@ -1408,11 +1440,14 @@ #if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) EXPECT_EQ(use_default_settings_result(), mojom::ResultCode::kSuccess); EXPECT_EQ(ask_user_for_settings_result(), mojom::ResultCode::kSuccess); -#endif - // TODO(crbug.com/1414968) Correct expectation once system print settings - // are properly reflected at start of job print. - ASSERT_NE(*MakeUserModifiedPrintSettings("printer1"), + EXPECT_EQ(*MakeUserModifiedPrintSettings("printer1"), *document_print_settings()); +#else + // TODO(crbug.com/1414968): Update the expectation once system print + // settings are properly reflected at start of job print. + EXPECT_NE(*MakeUserModifiedPrintSettings("printer1"), + *document_print_settings()); +#endif EXPECT_EQ(start_printing_result(), mojom::ResultCode::kSuccess); #if BUILDFLAG(IS_WIN) // TODO(crbug.com/1008222) Include Windows coverage of
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 546d2643..861a243 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
@@ -15,7 +15,6 @@ import static androidx.test.espresso.matcher.ViewMatchers.withText; import static org.hamcrest.CoreMatchers.not; -import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -34,7 +33,6 @@ import org.junit.After; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -42,10 +40,10 @@ import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; -import org.chromium.base.test.metrics.HistogramTestRule; import org.chromium.base.test.util.Batch; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Feature; +import org.chromium.base.test.util.HistogramWatcher; import org.chromium.base.test.util.UserActionTester; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; @@ -64,7 +62,6 @@ import org.chromium.components.embedder_support.util.UrlConstants; import org.chromium.components.sync.UserSelectableType; import org.chromium.components.user_prefs.UserPrefs; -import org.chromium.content_public.browser.test.NativeLibraryTestUtils; import java.util.HashSet; import java.util.Set; @@ -88,9 +85,6 @@ new ChromeTabbedActivityTestRule(); @Rule - public HistogramTestRule mHistogramTestRule = new HistogramTestRule(); - - @Rule public SettingsActivityTestRule<PrivacyGuideFragment> mSettingsActivityTestRule = new SettingsActivityTestRule<>(PrivacyGuideFragment.class); @@ -102,12 +96,6 @@ private UserActionTester mActionTester; - @BeforeClass - public static void setUpBeforeActivityLaunched() { - // Only needs to be loaded once and needs to be loaded before HistogramTestRule. - NativeLibraryTestUtils.loadNativeLibraryNoBrowserProcess(); - } - @Before public void setUp() { mActivityTestRule.startMainActivityOnBlankPage(); @@ -281,15 +269,12 @@ public void testWelcomeCard_nextNavigationHistogram() { launchPrivacyGuide(); - assertEquals(0, - mHistogramTestRule.getHistogramValueCount( - NEXT_NAVIGATION_HISTOGRAM, PrivacyGuideInteractions.WELCOME_NEXT_BUTTON)); + var histogram = HistogramWatcher.newSingleRecordWatcher( + NEXT_NAVIGATION_HISTOGRAM, PrivacyGuideInteractions.WELCOME_NEXT_BUTTON); navigateFromWelcomeToMSBBCard(); - assertEquals(1, - mHistogramTestRule.getHistogramValueCount( - NEXT_NAVIGATION_HISTOGRAM, PrivacyGuideInteractions.WELCOME_NEXT_BUTTON)); + histogram.assertExpected(); } @Test @@ -315,16 +300,13 @@ launchPrivacyGuide(); goToCompletionCard(); - assertEquals(0, - mHistogramTestRule.getHistogramValueCount(NEXT_NAVIGATION_HISTOGRAM, - PrivacyGuideInteractions.COMPLETION_NEXT_BUTTON)); + var histogram = HistogramWatcher.newSingleRecordWatcher( + NEXT_NAVIGATION_HISTOGRAM, PrivacyGuideInteractions.COMPLETION_NEXT_BUTTON); // Complete page -> EXIT onView(withText(R.string.done)).perform(click()); - assertEquals(1, - mHistogramTestRule.getHistogramValueCount(NEXT_NAVIGATION_HISTOGRAM, - PrivacyGuideInteractions.COMPLETION_NEXT_BUTTON)); + histogram.assertExpected(); } @Test @@ -372,15 +354,12 @@ launchPrivacyGuide(); goToCompletionCard(); - assertEquals(0, - mHistogramTestRule.getHistogramValueCount(ENTRY_EXIT_HISTOGRAM, - PrivacyGuideInteractions.PRIVACY_SANDBOX_COMPLETION_LINK)); + var histogram = HistogramWatcher.newSingleRecordWatcher( + ENTRY_EXIT_HISTOGRAM, PrivacyGuideInteractions.PRIVACY_SANDBOX_COMPLETION_LINK); onViewWaiting(withId(R.id.ps_button)).perform(click()); - assertEquals(1, - mHistogramTestRule.getHistogramValueCount(ENTRY_EXIT_HISTOGRAM, - PrivacyGuideInteractions.PRIVACY_SANDBOX_COMPLETION_LINK)); + histogram.assertExpected(); } @Test @@ -417,15 +396,12 @@ launchPrivacyGuide(); goToCompletionCard(); - assertEquals(0, - mHistogramTestRule.getHistogramValueCount( - ENTRY_EXIT_HISTOGRAM, PrivacyGuideInteractions.SWAA_COMPLETION_LINK)); + var histogram = HistogramWatcher.newSingleRecordWatcher( + ENTRY_EXIT_HISTOGRAM, PrivacyGuideInteractions.SWAA_COMPLETION_LINK); executeWhileCapturingIntents(() -> onViewWaiting(withId(R.id.waa_button)).perform(click())); - assertEquals(1, - mHistogramTestRule.getHistogramValueCount( - ENTRY_EXIT_HISTOGRAM, PrivacyGuideInteractions.SWAA_COMPLETION_LINK)); + histogram.assertExpected(); } @Test @@ -445,15 +421,12 @@ launchPrivacyGuide(); navigateFromWelcomeToMSBBCard(); - assertEquals(0, - mHistogramTestRule.getHistogramValueCount( - NEXT_NAVIGATION_HISTOGRAM, PrivacyGuideInteractions.MSBB_NEXT_BUTTON)); + var histogram = HistogramWatcher.newSingleRecordWatcher( + NEXT_NAVIGATION_HISTOGRAM, PrivacyGuideInteractions.MSBB_NEXT_BUTTON); navigateFromMSBBToHistorySyncCard(); - assertEquals(1, - mHistogramTestRule.getHistogramValueCount( - NEXT_NAVIGATION_HISTOGRAM, PrivacyGuideInteractions.MSBB_NEXT_BUTTON)); + histogram.assertExpected(); } @Test @@ -464,15 +437,12 @@ launchPrivacyGuide(); navigateFromWelcomeToMSBBCard(); - assertEquals(0, - mHistogramTestRule.getHistogramValueCount( - SETTINGS_STATES_HISTOGRAM, PrivacyGuideSettingsStates.MSBB_OFF_TO_OFF)); + var histogram = HistogramWatcher.newSingleRecordWatcher( + SETTINGS_STATES_HISTOGRAM, PrivacyGuideSettingsStates.MSBB_OFF_TO_OFF); navigateFromMSBBToHistorySyncCard(); - assertEquals(1, - mHistogramTestRule.getHistogramValueCount( - SETTINGS_STATES_HISTOGRAM, PrivacyGuideSettingsStates.MSBB_OFF_TO_OFF)); + histogram.assertExpected(); } @Test @@ -483,16 +453,13 @@ launchPrivacyGuide(); navigateFromWelcomeToMSBBCard(); - assertEquals(0, - mHistogramTestRule.getHistogramValueCount( - SETTINGS_STATES_HISTOGRAM, PrivacyGuideSettingsStates.MSBB_OFF_TO_ON)); + var histogram = HistogramWatcher.newSingleRecordWatcher( + SETTINGS_STATES_HISTOGRAM, PrivacyGuideSettingsStates.MSBB_OFF_TO_ON); onView(withId(R.id.msbb_switch)).perform(click()); navigateFromMSBBToHistorySyncCard(); - assertEquals(1, - mHistogramTestRule.getHistogramValueCount( - SETTINGS_STATES_HISTOGRAM, PrivacyGuideSettingsStates.MSBB_OFF_TO_ON)); + histogram.assertExpected(); } @Test @@ -503,16 +470,13 @@ launchPrivacyGuide(); navigateFromWelcomeToMSBBCard(); - assertEquals(0, - mHistogramTestRule.getHistogramValueCount( - SETTINGS_STATES_HISTOGRAM, PrivacyGuideSettingsStates.MSBB_ON_TO_OFF)); + var histogram = HistogramWatcher.newSingleRecordWatcher( + SETTINGS_STATES_HISTOGRAM, PrivacyGuideSettingsStates.MSBB_ON_TO_OFF); onView(withId(R.id.msbb_switch)).perform(click()); navigateFromMSBBToHistorySyncCard(); - assertEquals(1, - mHistogramTestRule.getHistogramValueCount( - SETTINGS_STATES_HISTOGRAM, PrivacyGuideSettingsStates.MSBB_ON_TO_OFF)); + histogram.assertExpected(); } @Test @@ -523,15 +487,12 @@ launchPrivacyGuide(); navigateFromWelcomeToMSBBCard(); - assertEquals(0, - mHistogramTestRule.getHistogramValueCount( - SETTINGS_STATES_HISTOGRAM, PrivacyGuideSettingsStates.MSBB_ON_TO_ON)); + var histogram = HistogramWatcher.newSingleRecordWatcher( + SETTINGS_STATES_HISTOGRAM, PrivacyGuideSettingsStates.MSBB_ON_TO_ON); navigateFromMSBBToHistorySyncCard(); - assertEquals(1, - mHistogramTestRule.getHistogramValueCount( - SETTINGS_STATES_HISTOGRAM, PrivacyGuideSettingsStates.MSBB_ON_TO_ON)); + histogram.assertExpected(); } @Test @@ -585,15 +546,12 @@ launchPrivacyGuide(); goToHistorySyncCard(); - assertEquals(0, - mHistogramTestRule.getHistogramValueCount(NEXT_NAVIGATION_HISTOGRAM, - PrivacyGuideInteractions.HISTORY_SYNC_NEXT_BUTTON)); + var histogram = HistogramWatcher.newSingleRecordWatcher( + NEXT_NAVIGATION_HISTOGRAM, PrivacyGuideInteractions.HISTORY_SYNC_NEXT_BUTTON); navigateFromHistorySyncToSBCard(); - assertEquals(1, - mHistogramTestRule.getHistogramValueCount(NEXT_NAVIGATION_HISTOGRAM, - PrivacyGuideInteractions.HISTORY_SYNC_NEXT_BUTTON)); + histogram.assertExpected(); } @Test @@ -604,15 +562,12 @@ launchPrivacyGuide(); goToHistorySyncCard(); - assertEquals(0, - mHistogramTestRule.getHistogramValueCount(SETTINGS_STATES_HISTOGRAM, - PrivacyGuideSettingsStates.HISTORY_SYNC_OFF_TO_OFF)); + var histogram = HistogramWatcher.newSingleRecordWatcher( + SETTINGS_STATES_HISTOGRAM, PrivacyGuideSettingsStates.HISTORY_SYNC_OFF_TO_OFF); navigateFromHistorySyncToSBCard(); - assertEquals(1, - mHistogramTestRule.getHistogramValueCount(SETTINGS_STATES_HISTOGRAM, - PrivacyGuideSettingsStates.HISTORY_SYNC_OFF_TO_OFF)); + histogram.assertExpected(); } @Test @@ -623,16 +578,13 @@ launchPrivacyGuide(); goToHistorySyncCard(); - assertEquals(0, - mHistogramTestRule.getHistogramValueCount(SETTINGS_STATES_HISTOGRAM, - PrivacyGuideSettingsStates.HISTORY_SYNC_OFF_TO_ON)); + var histogram = HistogramWatcher.newSingleRecordWatcher( + SETTINGS_STATES_HISTOGRAM, PrivacyGuideSettingsStates.HISTORY_SYNC_OFF_TO_ON); onView(withId(R.id.history_sync_switch)).perform(click()); navigateFromHistorySyncToSBCard(); - assertEquals(1, - mHistogramTestRule.getHistogramValueCount(SETTINGS_STATES_HISTOGRAM, - PrivacyGuideSettingsStates.HISTORY_SYNC_OFF_TO_ON)); + histogram.assertExpected(); } @Test @@ -643,16 +595,13 @@ launchPrivacyGuide(); goToHistorySyncCard(); - assertEquals(0, - mHistogramTestRule.getHistogramValueCount(SETTINGS_STATES_HISTOGRAM, - PrivacyGuideSettingsStates.HISTORY_SYNC_ON_TO_OFF)); + var histogram = HistogramWatcher.newSingleRecordWatcher( + SETTINGS_STATES_HISTOGRAM, PrivacyGuideSettingsStates.HISTORY_SYNC_ON_TO_OFF); onView(withId(R.id.history_sync_switch)).perform(click()); navigateFromHistorySyncToSBCard(); - assertEquals(1, - mHistogramTestRule.getHistogramValueCount(SETTINGS_STATES_HISTOGRAM, - PrivacyGuideSettingsStates.HISTORY_SYNC_ON_TO_OFF)); + histogram.assertExpected(); } @Test @@ -663,15 +612,12 @@ launchPrivacyGuide(); goToHistorySyncCard(); - assertEquals(0, - mHistogramTestRule.getHistogramValueCount(SETTINGS_STATES_HISTOGRAM, - PrivacyGuideSettingsStates.HISTORY_SYNC_ON_TO_ON)); + var histogram = HistogramWatcher.newSingleRecordWatcher( + SETTINGS_STATES_HISTOGRAM, PrivacyGuideSettingsStates.HISTORY_SYNC_ON_TO_ON); navigateFromHistorySyncToSBCard(); - assertEquals(1, - mHistogramTestRule.getHistogramValueCount(SETTINGS_STATES_HISTOGRAM, - PrivacyGuideSettingsStates.HISTORY_SYNC_ON_TO_ON)); + histogram.assertExpected(); } @Test @@ -724,15 +670,12 @@ launchPrivacyGuide(); goToSafeBrowsingCard(); - assertEquals(0, - mHistogramTestRule.getHistogramValueCount(NEXT_NAVIGATION_HISTOGRAM, - PrivacyGuideInteractions.SAFE_BROWSING_NEXT_BUTTON)); + var histogram = HistogramWatcher.newSingleRecordWatcher( + NEXT_NAVIGATION_HISTOGRAM, PrivacyGuideInteractions.SAFE_BROWSING_NEXT_BUTTON); navigateFromSBToCookiesCard(); - assertEquals(1, - mHistogramTestRule.getHistogramValueCount(NEXT_NAVIGATION_HISTOGRAM, - PrivacyGuideInteractions.SAFE_BROWSING_NEXT_BUTTON)); + histogram.assertExpected(); } @Test @@ -743,15 +686,12 @@ launchPrivacyGuide(); goToSafeBrowsingCard(); - assertEquals(0, - mHistogramTestRule.getHistogramValueCount(SETTINGS_STATES_HISTOGRAM, - PrivacyGuideSettingsStates.SAFE_BROWSING_STANDARD_TO_STANDARD)); + var histogram = HistogramWatcher.newSingleRecordWatcher(SETTINGS_STATES_HISTOGRAM, + PrivacyGuideSettingsStates.SAFE_BROWSING_STANDARD_TO_STANDARD); navigateFromSBToCookiesCard(); - assertEquals(1, - mHistogramTestRule.getHistogramValueCount(SETTINGS_STATES_HISTOGRAM, - PrivacyGuideSettingsStates.SAFE_BROWSING_STANDARD_TO_STANDARD)); + histogram.assertExpected(); } @Test @@ -762,16 +702,13 @@ launchPrivacyGuide(); goToSafeBrowsingCard(); - assertEquals(0, - mHistogramTestRule.getHistogramValueCount(SETTINGS_STATES_HISTOGRAM, - PrivacyGuideSettingsStates.SAFE_BROWSING_STANDARD_TO_ENHANCED)); + var histogram = HistogramWatcher.newSingleRecordWatcher(SETTINGS_STATES_HISTOGRAM, + PrivacyGuideSettingsStates.SAFE_BROWSING_STANDARD_TO_ENHANCED); onView(withId(R.id.enhanced_option)).perform(click()); navigateFromSBToCookiesCard(); - assertEquals(1, - mHistogramTestRule.getHistogramValueCount(SETTINGS_STATES_HISTOGRAM, - PrivacyGuideSettingsStates.SAFE_BROWSING_STANDARD_TO_ENHANCED)); + histogram.assertExpected(); } @Test @@ -782,15 +719,12 @@ launchPrivacyGuide(); goToSafeBrowsingCard(); - assertEquals(0, - mHistogramTestRule.getHistogramValueCount(SETTINGS_STATES_HISTOGRAM, - PrivacyGuideSettingsStates.SAFE_BROWSING_ENHANCED_TO_ENHANCED)); + var histogram = HistogramWatcher.newSingleRecordWatcher(SETTINGS_STATES_HISTOGRAM, + PrivacyGuideSettingsStates.SAFE_BROWSING_ENHANCED_TO_ENHANCED); navigateFromSBToCookiesCard(); - assertEquals(1, - mHistogramTestRule.getHistogramValueCount(SETTINGS_STATES_HISTOGRAM, - PrivacyGuideSettingsStates.SAFE_BROWSING_ENHANCED_TO_ENHANCED)); + histogram.assertExpected(); } @Test @@ -801,16 +735,13 @@ launchPrivacyGuide(); goToSafeBrowsingCard(); - assertEquals(0, - mHistogramTestRule.getHistogramValueCount(SETTINGS_STATES_HISTOGRAM, - PrivacyGuideSettingsStates.SAFE_BROWSING_ENHANCED_TO_STANDARD)); + var histogram = HistogramWatcher.newSingleRecordWatcher(SETTINGS_STATES_HISTOGRAM, + PrivacyGuideSettingsStates.SAFE_BROWSING_ENHANCED_TO_STANDARD); onView(withId(R.id.standard_option)).perform(click()); navigateFromSBToCookiesCard(); - assertEquals(1, - mHistogramTestRule.getHistogramValueCount(SETTINGS_STATES_HISTOGRAM, - PrivacyGuideSettingsStates.SAFE_BROWSING_ENHANCED_TO_STANDARD)); + histogram.assertExpected(); } @Test @@ -862,15 +793,12 @@ launchPrivacyGuide(); goToCookiesCard(); - assertEquals(0, - mHistogramTestRule.getHistogramValueCount( - NEXT_NAVIGATION_HISTOGRAM, PrivacyGuideInteractions.COOKIES_NEXT_BUTTON)); + var histogram = HistogramWatcher.newSingleRecordWatcher( + NEXT_NAVIGATION_HISTOGRAM, PrivacyGuideInteractions.COOKIES_NEXT_BUTTON); navigateFromCookiesToCompletionCard(); - assertEquals(1, - mHistogramTestRule.getHistogramValueCount( - NEXT_NAVIGATION_HISTOGRAM, PrivacyGuideInteractions.COOKIES_NEXT_BUTTON)); + histogram.assertExpected(); } @Test @@ -881,15 +809,12 @@ launchPrivacyGuide(); goToCookiesCard(); - assertEquals(0, - mHistogramTestRule.getHistogramValueCount(SETTINGS_STATES_HISTOGRAM, - PrivacyGuideSettingsStates.BLOCK3P_INCOGNITO_TO3P_INCOGNITO)); + var histogram = HistogramWatcher.newSingleRecordWatcher(SETTINGS_STATES_HISTOGRAM, + PrivacyGuideSettingsStates.BLOCK3P_INCOGNITO_TO3P_INCOGNITO); navigateFromCookiesToCompletionCard(); - assertEquals(1, - mHistogramTestRule.getHistogramValueCount(SETTINGS_STATES_HISTOGRAM, - PrivacyGuideSettingsStates.BLOCK3P_INCOGNITO_TO3P_INCOGNITO)); + histogram.assertExpected(); } @Test @@ -900,16 +825,13 @@ launchPrivacyGuide(); goToCookiesCard(); - assertEquals(0, - mHistogramTestRule.getHistogramValueCount(SETTINGS_STATES_HISTOGRAM, - PrivacyGuideSettingsStates.BLOCK3P_INCOGNITO_TO3P)); + var histogram = HistogramWatcher.newSingleRecordWatcher( + SETTINGS_STATES_HISTOGRAM, PrivacyGuideSettingsStates.BLOCK3P_INCOGNITO_TO3P); onView(withId(R.id.block_third_party)).perform(click()); navigateFromCookiesToCompletionCard(); - assertEquals(1, - mHistogramTestRule.getHistogramValueCount(SETTINGS_STATES_HISTOGRAM, - PrivacyGuideSettingsStates.BLOCK3P_INCOGNITO_TO3P)); + histogram.assertExpected(); } @Test @@ -920,16 +842,13 @@ launchPrivacyGuide(); goToCookiesCard(); - assertEquals(0, - mHistogramTestRule.getHistogramValueCount(SETTINGS_STATES_HISTOGRAM, - PrivacyGuideSettingsStates.BLOCK3P_TO3P_INCOGNITO)); + var histogram = HistogramWatcher.newSingleRecordWatcher( + SETTINGS_STATES_HISTOGRAM, PrivacyGuideSettingsStates.BLOCK3P_TO3P_INCOGNITO); onView(withId(R.id.block_third_party_incognito)).perform(click()); navigateFromCookiesToCompletionCard(); - assertEquals(1, - mHistogramTestRule.getHistogramValueCount(SETTINGS_STATES_HISTOGRAM, - PrivacyGuideSettingsStates.BLOCK3P_TO3P_INCOGNITO)); + histogram.assertExpected(); } @Test @@ -940,15 +859,12 @@ launchPrivacyGuide(); goToCookiesCard(); - assertEquals(0, - mHistogramTestRule.getHistogramValueCount( - SETTINGS_STATES_HISTOGRAM, PrivacyGuideSettingsStates.BLOCK3P_TO3P)); + var histogram = HistogramWatcher.newSingleRecordWatcher( + SETTINGS_STATES_HISTOGRAM, PrivacyGuideSettingsStates.BLOCK3P_TO3P); navigateFromCookiesToCompletionCard(); - assertEquals(1, - mHistogramTestRule.getHistogramValueCount( - SETTINGS_STATES_HISTOGRAM, PrivacyGuideSettingsStates.BLOCK3P_TO3P)); + histogram.assertExpected(); } @Test
diff --git a/chrome/browser/privacy_sandbox/android/javatests/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxDialogTest.java b/chrome/browser/privacy_sandbox/android/javatests/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxDialogTest.java index 774f7b7..1905813 100644 --- a/chrome/browser/privacy_sandbox/android/javatests/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxDialogTest.java +++ b/chrome/browser/privacy_sandbox/android/javatests/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxDialogTest.java
@@ -31,7 +31,6 @@ import org.hamcrest.Matcher; import org.junit.After; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; @@ -58,9 +57,7 @@ import org.chromium.chrome.test.util.browser.Features; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; import org.chromium.components.browser_ui.settings.SettingsLauncher; -import org.chromium.content_public.browser.test.NativeLibraryTestUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils; -import org.chromium.ui.test.util.DisableAnimationsTestRule; import org.chromium.ui.test.util.RenderTestRule; import java.io.IOException; @@ -71,9 +68,6 @@ @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) public final class PrivacySandboxDialogTest { @ClassRule - public static DisableAnimationsTestRule disableAnimationsRule = new DisableAnimationsTestRule(); - - @ClassRule public static final ChromeTabbedActivityTestRule sActivityTestRule = new ChromeTabbedActivityTestRule(); @@ -99,12 +93,6 @@ private Dialog mDialog; - @BeforeClass - public static void beforeClass() { - // Only needs to be loaded once and needs to be loaded before HistogramTestRule. - NativeLibraryTestUtils.loadNativeLibraryNoBrowserProcess(); - } - @Before public void setUp() { MockitoAnnotations.initMocks(this);
diff --git a/chrome/browser/privacy_sandbox/android/javatests/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxSettingsFragmentV3Test.java b/chrome/browser/privacy_sandbox/android/javatests/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxSettingsFragmentV3Test.java index da49df41..1400f35 100644 --- a/chrome/browser/privacy_sandbox/android/javatests/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxSettingsFragmentV3Test.java +++ b/chrome/browser/privacy_sandbox/android/javatests/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxSettingsFragmentV3Test.java
@@ -22,7 +22,6 @@ import static org.hamcrest.Matchers.hasItems; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.startsWith; -import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -40,16 +39,15 @@ import org.hamcrest.Matcher; import org.junit.After; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; -import org.chromium.base.test.metrics.HistogramTestRule; import org.chromium.base.test.util.Batch; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Feature; +import org.chromium.base.test.util.HistogramWatcher; import org.chromium.base.test.util.JniMocker; import org.chromium.base.test.util.PayloadCallbackHelper; import org.chromium.base.test.util.UserActionTester; @@ -61,7 +59,6 @@ import org.chromium.chrome.test.util.ChromeRenderTestRule; import org.chromium.chrome.test.util.browser.Features; import org.chromium.components.browser_ui.settings.SettingsFeatureList; -import org.chromium.content_public.browser.test.NativeLibraryTestUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.ui.test.util.RenderTestRule; import org.chromium.ui.test.util.ViewUtils; @@ -95,21 +92,12 @@ .build(); @Rule - public HistogramTestRule mHistogramTestRule = new HistogramTestRule(); - - @Rule public JniMocker mocker = new JniMocker(); private FakePrivacySandboxBridge mFakePrivacySandboxBridge; private UserActionTester mUserActionTester; - @BeforeClass - public static void beforeClass() { - // Only needs to be loaded once and needs to be loaded before HistogramTestRule. - NativeLibraryTestUtils.loadNativeLibraryNoBrowserProcess(); - } - @Before public void setUp() { mFakePrivacySandboxBridge = new FakePrivacySandboxBridge(); @@ -436,26 +424,25 @@ @Test @SmallTest public void testCreateActivityFromPrivacySettings() { + var histogram = HistogramWatcher.newSingleRecordWatcher( + REFERRER_HISTOGRAM, PrivacySandboxReferrer.PRIVACY_SETTINGS); + openPrivacySandboxSettings(); - assertEquals("Total histogram count wrong", 1, - mHistogramTestRule.getHistogramTotalCount(REFERRER_HISTOGRAM)); - assertEquals("Privacy referrer histogram count", 1, - mHistogramTestRule.getHistogramValueCount( - REFERRER_HISTOGRAM, PrivacySandboxReferrer.PRIVACY_SETTINGS)); + + histogram.assertExpected(); } @Test @SmallTest public void testCreateActivityFromCookiesSnackbar() { + var histogram = HistogramWatcher.newSingleRecordWatcher( + REFERRER_HISTOGRAM, PrivacySandboxReferrer.COOKIES_SNACKBAR); + Bundle fragmentArgs = new Bundle(); fragmentArgs.putInt(PrivacySandboxSettingsFragmentV3.PRIVACY_SANDBOX_REFERRER, PrivacySandboxReferrer.COOKIES_SNACKBAR); mSettingsActivityTestRule.startSettingsActivity(fragmentArgs); - assertEquals("Total histogram count", 1, - mHistogramTestRule.getHistogramTotalCount(REFERRER_HISTOGRAM)); - assertEquals("Cookies snackbar referrer histogram count wrong", 1, - mHistogramTestRule.getHistogramValueCount( - REFERRER_HISTOGRAM, PrivacySandboxReferrer.COOKIES_SNACKBAR)); + histogram.assertExpected(); } }
diff --git a/chrome/browser/push_messaging/push_messaging_browsertest.cc b/chrome/browser/push_messaging/push_messaging_browsertest.cc index fbd50c1..9f55f78 100644 --- a/chrome/browser/push_messaging/push_messaging_browsertest.cc +++ b/chrome/browser/push_messaging/push_messaging_browsertest.cc
@@ -1281,12 +1281,6 @@ // Check that we record this case in UMA. histogram_tester_.ExpectUniqueSample( - "PushMessaging.DeliveryStatus.FindServiceWorker", - 0 /* SERVICE_WORKER_OK */, 1); - histogram_tester_.ExpectUniqueSample( - "PushMessaging.DeliveryStatus.ServiceWorkerEvent", - 0 /* SERVICE_WORKER_OK */, 1); - histogram_tester_.ExpectUniqueSample( "PushMessaging.DeliveryStatus", static_cast<int>(blink::mojom::PushEventStatus::SUCCESS), 1); } @@ -1382,11 +1376,6 @@ // Check that we record this case in UMA. histogram_tester_.ExpectUniqueSample( - "PushMessaging.DeliveryStatus.FindServiceWorker", - 5 /* SERVICE_WORKER_ERROR_NOT_FOUND */, 1); - histogram_tester_.ExpectTotalCount( - "PushMessaging.DeliveryStatus.ServiceWorkerEvent", 0); - histogram_tester_.ExpectUniqueSample( "PushMessaging.DeliveryStatus", static_cast<int>(blink::mojom::PushEventStatus::NO_SERVICE_WORKER), 1); @@ -1434,10 +1423,6 @@ EXPECT_EQ("null", script_result); // Check that we record this case in UMA. - histogram_tester_.ExpectTotalCount( - "PushMessaging.DeliveryStatus.FindServiceWorker", 0); - histogram_tester_.ExpectTotalCount( - "PushMessaging.DeliveryStatus.ServiceWorkerEvent", 0); histogram_tester_.ExpectUniqueSample( "PushMessaging.DeliveryStatus", static_cast<int>(blink::mojom::PushEventStatus::UNKNOWN_APP_ID), 1); @@ -1485,10 +1470,6 @@ EXPECT_EQ("null", script_result); // Check that we record this case in UMA. - histogram_tester_.ExpectTotalCount( - "PushMessaging.DeliveryStatus.FindServiceWorker", 0); - histogram_tester_.ExpectTotalCount( - "PushMessaging.DeliveryStatus.ServiceWorkerEvent", 0); histogram_tester_.ExpectUniqueSample( "PushMessaging.DeliveryStatus", static_cast<int>(blink::mojom::PushEventStatus::PERMISSION_DENIED), 1); @@ -1769,10 +1750,6 @@ EXPECT_EQ("null", script_result); // Check that we record this case in UMA. - histogram_tester_.ExpectTotalCount( - "PushMessaging.DeliveryStatus.FindServiceWorker", 0); - histogram_tester_.ExpectTotalCount( - "PushMessaging.DeliveryStatus.ServiceWorkerEvent", 0); histogram_tester_.ExpectUniqueSample( "PushMessaging.DeliveryStatus", static_cast<int>( @@ -1837,12 +1814,6 @@ // Check that we record this case in UMA. histogram_tester_.ExpectUniqueSample( - "PushMessaging.DeliveryStatus.FindServiceWorker", - 0 /* SERVICE_WORKER_OK */, 1); - histogram_tester_.ExpectUniqueSample( - "PushMessaging.DeliveryStatus.ServiceWorkerEvent", - 0 /* SERVICE_WORKER_OK */, 1); - histogram_tester_.ExpectUniqueSample( "PushMessaging.DeliveryStatus", static_cast<int>(blink::mojom::PushEventStatus::SUCCESS), 1); }
diff --git a/chrome/browser/quick_delete/android/java/src/org/chromium/chrome/browser/quick_delete/QuickDeleteController.java b/chrome/browser/quick_delete/android/java/src/org/chromium/chrome/browser/quick_delete/QuickDeleteController.java index c5ad66e..98d04a6 100644 --- a/chrome/browser/quick_delete/android/java/src/org/chromium/chrome/browser/quick_delete/QuickDeleteController.java +++ b/chrome/browser/quick_delete/android/java/src/org/chromium/chrome/browser/quick_delete/QuickDeleteController.java
@@ -70,17 +70,17 @@ switch (dismissalCause) { case DialogDismissalCause.POSITIVE_BUTTON_CLICKED: QuickDeleteMetricsDelegate.recordHistogram( - QuickDeleteMetricsDelegate.PrivacyQuickDelete.DELETE_CLICKED); + QuickDeleteMetricsDelegate.QuickDeleteAction.DELETE_CLICKED); navigateToTabSwitcher(); showSnackbar(); break; case DialogDismissalCause.NEGATIVE_BUTTON_CLICKED: QuickDeleteMetricsDelegate.recordHistogram( - QuickDeleteMetricsDelegate.PrivacyQuickDelete.CANCEL_CLICKED); + QuickDeleteMetricsDelegate.QuickDeleteAction.CANCEL_CLICKED); break; default: QuickDeleteMetricsDelegate.recordHistogram( - QuickDeleteMetricsDelegate.PrivacyQuickDelete.DIALOG_DISMISSED_IMPLICITLY); + QuickDeleteMetricsDelegate.QuickDeleteAction.DIALOG_DISMISSED_IMPLICITLY); break; } }
diff --git a/chrome/browser/quick_delete/android/java/src/org/chromium/chrome/browser/quick_delete/QuickDeleteMetricsDelegate.java b/chrome/browser/quick_delete/android/java/src/org/chromium/chrome/browser/quick_delete/QuickDeleteMetricsDelegate.java index 65fafa9..dd710f2 100644 --- a/chrome/browser/quick_delete/android/java/src/org/chromium/chrome/browser/quick_delete/QuickDeleteMetricsDelegate.java +++ b/chrome/browser/quick_delete/android/java/src/org/chromium/chrome/browser/quick_delete/QuickDeleteMetricsDelegate.java
@@ -17,11 +17,11 @@ * These values are persisted to logs. Entries should not be renumbered and * numeric values should never be reused. * - * Must be kept in sync with the PrivacyQuickDelete in enums.xml. + * Must be kept in sync with the QuickDeleteAction in enums.xml. */ - @IntDef({PrivacyQuickDelete.MENU_ITEM_CLICKED, PrivacyQuickDelete.DELETE_CLICKED, - PrivacyQuickDelete.CANCEL_CLICKED, PrivacyQuickDelete.DIALOG_DISMISSED_IMPLICITLY}) - public @interface PrivacyQuickDelete { + @IntDef({QuickDeleteAction.MENU_ITEM_CLICKED, QuickDeleteAction.DELETE_CLICKED, + QuickDeleteAction.CANCEL_CLICKED, QuickDeleteAction.DIALOG_DISMISSED_IMPLICITLY}) + public @interface QuickDeleteAction { int MENU_ITEM_CLICKED = 0; int DELETE_CLICKED = 1; int CANCEL_CLICKED = 2; @@ -31,16 +31,15 @@ } /** - * A method to record the metrics of an action {@link PrivacyQuickDelete} related with - * QuickDelete. + * A method to record the metrics of a {@link QuickDeleteAction}. * - * @param privacyQuickDelete action taken related to QuickDelete. + * @param quickDeleteAction action taken related to QuickDelete. */ - public static void recordHistogram(@PrivacyQuickDelete int privacyQuickDelete) { + public static void recordHistogram(@QuickDeleteAction int quickDeleteAction) { RecordHistogram.recordEnumeratedHistogram( - "Privacy.QuickDelete", privacyQuickDelete, PrivacyQuickDelete.MAX_VALUE); + "Privacy.QuickDelete", quickDeleteAction, QuickDeleteAction.MAX_VALUE); - if (privacyQuickDelete == PrivacyQuickDelete.DELETE_CLICKED) { + if (quickDeleteAction == QuickDeleteAction.DELETE_CLICKED) { RecordHistogram.recordEnumeratedHistogram("Privacy.ClearBrowsingData.Action", ClearBrowsingDataAction.QUICK_DELETE_LAST15_MINUTES, ClearBrowsingDataAction.MAX_VALUE);
diff --git a/chrome/browser/quick_delete/android/javatests/src/org/chromium/chrome/browser/quick_delete/QuickDeleteControllerTest.java b/chrome/browser/quick_delete/android/javatests/src/org/chromium/chrome/browser/quick_delete/QuickDeleteControllerTest.java index 8a282f80..2f67668 100644 --- a/chrome/browser/quick_delete/android/javatests/src/org/chromium/chrome/browser/quick_delete/QuickDeleteControllerTest.java +++ b/chrome/browser/quick_delete/android/javatests/src/org/chromium/chrome/browser/quick_delete/QuickDeleteControllerTest.java
@@ -96,7 +96,7 @@ HistogramWatcher histogramWatcher = HistogramWatcher.newBuilder() .expectIntRecords("Privacy.QuickDelete", - QuickDeleteMetricsDelegate.PrivacyQuickDelete.DELETE_CLICKED, 1) + QuickDeleteMetricsDelegate.QuickDeleteAction.DELETE_CLICKED, 1) .build(); onViewWaiting(withId(R.id.positive_button)).perform(click()); @@ -128,7 +128,7 @@ HistogramWatcher histogramWatcher = HistogramWatcher.newBuilder() .expectIntRecords("Privacy.QuickDelete", - QuickDeleteMetricsDelegate.PrivacyQuickDelete.CANCEL_CLICKED, 1) + QuickDeleteMetricsDelegate.QuickDeleteAction.CANCEL_CLICKED, 1) .build(); onViewWaiting(withId(R.id.negative_button)).perform(click()); @@ -144,7 +144,7 @@ HistogramWatcher histogramWatcher = HistogramWatcher.newBuilder() .expectIntRecords("Privacy.QuickDelete", - QuickDeleteMetricsDelegate.PrivacyQuickDelete + QuickDeleteMetricsDelegate.QuickDeleteAction .DIALOG_DISMISSED_IMPLICITLY, 1) .build();
diff --git a/chrome/browser/quick_delete/android/junit/src/org/chromium/chrome/browser/quick_delete/QuickDeleteMetricsDelegateTest.java b/chrome/browser/quick_delete/android/junit/src/org/chromium/chrome/browser/quick_delete/QuickDeleteMetricsDelegateTest.java index ce00a140..9bd956f 100644 --- a/chrome/browser/quick_delete/android/junit/src/org/chromium/chrome/browser/quick_delete/QuickDeleteMetricsDelegateTest.java +++ b/chrome/browser/quick_delete/android/junit/src/org/chromium/chrome/browser/quick_delete/QuickDeleteMetricsDelegateTest.java
@@ -38,16 +38,16 @@ public List<ParameterSet> getParameters() { return Arrays.asList( new ParameterSet() - .value(QuickDeleteMetricsDelegate.PrivacyQuickDelete.MENU_ITEM_CLICKED) + .value(QuickDeleteMetricsDelegate.QuickDeleteAction.MENU_ITEM_CLICKED) .name("MenuItem"), new ParameterSet() - .value(QuickDeleteMetricsDelegate.PrivacyQuickDelete.DELETE_CLICKED) + .value(QuickDeleteMetricsDelegate.QuickDeleteAction.DELETE_CLICKED) .name("Delete"), new ParameterSet() - .value(QuickDeleteMetricsDelegate.PrivacyQuickDelete.CANCEL_CLICKED) + .value(QuickDeleteMetricsDelegate.QuickDeleteAction.CANCEL_CLICKED) .name("Cancel"), new ParameterSet() - .value(QuickDeleteMetricsDelegate.PrivacyQuickDelete + .value(QuickDeleteMetricsDelegate.QuickDeleteAction .DIALOG_DISMISSED_IMPLICITLY) .name("Dismissed")); } @@ -57,13 +57,13 @@ @SmallTest @UseMethodParameter(MethodParams.class) public void testRecordHistogram( - @QuickDeleteMetricsDelegate.PrivacyQuickDelete int mPrivacyQuickDeleteMetric) { + @QuickDeleteMetricsDelegate.QuickDeleteAction int quickDeleteAction) { HistogramWatcher histogramWatcher = HistogramWatcher.newBuilder() - .expectIntRecords("Privacy.QuickDelete", mPrivacyQuickDeleteMetric, 1) + .expectIntRecords("Privacy.QuickDelete", quickDeleteAction, 1) .build(); - QuickDeleteMetricsDelegate.recordHistogram(mPrivacyQuickDeleteMetric); + QuickDeleteMetricsDelegate.recordHistogram(quickDeleteAction); histogramWatcher.assertExpected(); } @@ -78,7 +78,7 @@ .build(); QuickDeleteMetricsDelegate.recordHistogram( - QuickDeleteMetricsDelegate.PrivacyQuickDelete.DELETE_CLICKED); + QuickDeleteMetricsDelegate.QuickDeleteAction.DELETE_CLICKED); histogramWatcher.assertExpected(); }
diff --git a/chrome/browser/recent_tabs/android/java/src/org/chromium/chrome/browser/recent_tabs/ForeignSessionHelper.java b/chrome/browser/recent_tabs/android/java/src/org/chromium/chrome/browser/recent_tabs/ForeignSessionHelper.java index 4e83f29..be58f08 100644 --- a/chrome/browser/recent_tabs/android/java/src/org/chromium/chrome/browser/recent_tabs/ForeignSessionHelper.java +++ b/chrome/browser/recent_tabs/android/java/src/org/chromium/chrome/browser/recent_tabs/ForeignSessionHelper.java
@@ -44,7 +44,7 @@ public final long modifiedTime; public final List<ForeignSessionWindow> windows = new ArrayList<ForeignSessionWindow>(); - private ForeignSession(String tag, String name, long modifiedTime) { + protected ForeignSession(String tag, String name, long modifiedTime) { this.tag = tag; this.name = name; this.modifiedTime = modifiedTime;
diff --git a/chrome/browser/recent_tabs/internal/BUILD.gn b/chrome/browser/recent_tabs/internal/BUILD.gn index c5785c2b..3a52c7d 100644 --- a/chrome/browser/recent_tabs/internal/BUILD.gn +++ b/chrome/browser/recent_tabs/internal/BUILD.gn
@@ -14,7 +14,11 @@ sources = [ "android/java/src/org/chromium/chrome/browser/recent_tabs/RestoreTabsControllerFactory.java", "android/java/src/org/chromium/chrome/browser/recent_tabs/RestoreTabsControllerImpl.java", + "android/java/src/org/chromium/chrome/browser/recent_tabs/RestoreTabsCoordinator.java", "android/java/src/org/chromium/chrome/browser/recent_tabs/RestoreTabsFeatureHelperImpl.java", + "android/java/src/org/chromium/chrome/browser/recent_tabs/RestoreTabsMediator.java", + "android/java/src/org/chromium/chrome/browser/recent_tabs/RestoreTabsProperties.java", + "android/java/src/org/chromium/chrome/browser/recent_tabs/ui/RestoreTabsPromoScreenCoordinator.java", ] deps = [ @@ -23,6 +27,8 @@ "//chrome/browser/profiles/android:java", "//chrome/browser/recent_tabs:java", "//components/feature_engagement/public:public_java", + "//third_party/androidx:androidx_annotation_annotation_java", + "//ui/android:ui_java", ] resources_package = "org.chromium.chrome.recent_tabs" } @@ -31,7 +37,10 @@ bypass_platform_checks = true testonly = true - sources = [ "android/java/src/org/chromium/chrome/browser/recent_tabs/RestoreTabsFeatureHelperUnitTest.java" ] + sources = [ + "android/java/src/org/chromium/chrome/browser/recent_tabs/RestoreTabsFeatureHelperUnitTest.java", + "android/java/src/org/chromium/chrome/browser/recent_tabs/RestoreTabsMediatorUnitTest.java", + ] deps = [ ":java", @@ -45,5 +54,6 @@ "//third_party/hamcrest:hamcrest_library_java", "//third_party/junit:junit", "//third_party/mockito:mockito_java", + "//ui/android:ui_java", ] }
diff --git a/chrome/browser/recent_tabs/internal/android/java/src/org/chromium/chrome/browser/recent_tabs/RestoreTabsControllerImpl.java b/chrome/browser/recent_tabs/internal/android/java/src/org/chromium/chrome/browser/recent_tabs/RestoreTabsControllerImpl.java index da51aa2..edc89d74 100644 --- a/chrome/browser/recent_tabs/internal/android/java/src/org/chromium/chrome/browser/recent_tabs/RestoreTabsControllerImpl.java +++ b/chrome/browser/recent_tabs/internal/android/java/src/org/chromium/chrome/browser/recent_tabs/RestoreTabsControllerImpl.java
@@ -4,18 +4,26 @@ package org.chromium.chrome.browser.recent_tabs; +import org.chromium.chrome.browser.profiles.Profile; + /** - * Controller for accessing an instance of the RestoreTabsFeatureHelper for the singleton factory - * instance. + * Controller for accessing helper functions for the singleton factory instance. */ public class RestoreTabsControllerImpl { private RestoreTabsFeatureHelper mHelper; + private RestoreTabsCoordinator mRestoreTabsCoordinator; public RestoreTabsControllerImpl() { mHelper = new RestoreTabsFeatureHelperImpl(); + mRestoreTabsCoordinator = new RestoreTabsCoordinator(); + mRestoreTabsCoordinator.initialize(); } public RestoreTabsFeatureHelper getFeatureHelper() { return mHelper; } + + public void showBottomSheet(Profile profile) { + mRestoreTabsCoordinator.showOptions(profile); + } } \ No newline at end of file
diff --git a/chrome/browser/recent_tabs/internal/android/java/src/org/chromium/chrome/browser/recent_tabs/RestoreTabsCoordinator.java b/chrome/browser/recent_tabs/internal/android/java/src/org/chromium/chrome/browser/recent_tabs/RestoreTabsCoordinator.java new file mode 100644 index 0000000..1e236db --- /dev/null +++ b/chrome/browser/recent_tabs/internal/android/java/src/org/chromium/chrome/browser/recent_tabs/RestoreTabsCoordinator.java
@@ -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. + +package org.chromium.chrome.browser.recent_tabs; + +import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.recent_tabs.ForeignSessionHelper.ForeignSession; +import org.chromium.ui.modelutil.PropertyModel; + +import java.util.List; + +/** + * Coordinator to manage the Restore Tabs on FRE feature. + */ +public class RestoreTabsCoordinator { + private RestoreTabsMediator mMediator = new RestoreTabsMediator(); + private PropertyModel mModel = RestoreTabsProperties.createDefaultModel(); + + public void initialize() { + mMediator.initialize(mModel); + } + + public void showOptions(Profile profile) { + ForeignSessionHelper foreignSessionHelper = new ForeignSessionHelper(profile); + List<ForeignSession> sessions = foreignSessionHelper.getForeignSessions(); + foreignSessionHelper.destroy(); + + mMediator.showOptions(sessions); + } +}
diff --git a/chrome/browser/recent_tabs/internal/android/java/src/org/chromium/chrome/browser/recent_tabs/RestoreTabsMediator.java b/chrome/browser/recent_tabs/internal/android/java/src/org/chromium/chrome/browser/recent_tabs/RestoreTabsMediator.java new file mode 100644 index 0000000..3481590b --- /dev/null +++ b/chrome/browser/recent_tabs/internal/android/java/src/org/chromium/chrome/browser/recent_tabs/RestoreTabsMediator.java
@@ -0,0 +1,70 @@ +// 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.recent_tabs; + +import org.chromium.chrome.browser.recent_tabs.ForeignSessionHelper.ForeignSession; +import org.chromium.chrome.browser.recent_tabs.ui.RestoreTabsPromoScreenCoordinator; +import org.chromium.ui.modelutil.PropertyModel; + +import java.util.List; + +/** + * Contains the logic to set the state of the model and react to events like clicks. + */ +public class RestoreTabsMediator { + private PropertyModel mModel; + + public void initialize(PropertyModel model) { + mModel = model; + mModel.set(RestoreTabsProperties.HOME_SCREEN_DELEGATE, createHomeScreenDelegate()); + } + + /** Returns an implementation the RestoreTabsPromoScreen.Delegate interface. */ + private RestoreTabsPromoScreenCoordinator.Delegate createHomeScreenDelegate() { + return new RestoreTabsPromoScreenCoordinator.Delegate() { + @Override + public void onShowDeviceList() { + setCurrentScreen(RestoreTabsProperties.ScreenType.DEVICE_SCREEN); + } + + @Override + public void onAllTabsChosen() { + mModel.set(RestoreTabsProperties.VISIBLE, false); + }; + + @Override + public void onReviewTabsChosen() { + setCurrentScreen(RestoreTabsProperties.ScreenType.REVIEW_TABS_SCREEN); + } + }; + } + + public void showOptions(List<ForeignSession> sessions) { + setDeviceListItems(sessions); + setCurrentScreen(mModel.get(RestoreTabsProperties.CURRENT_SCREEN)); + mModel.set(RestoreTabsProperties.VISIBLE, true); + } + + public void setDeviceListItems(List<ForeignSession> sessions) { + assert sessions != null && sessions.size() != 0; + + ForeignSession previousSelection = mModel.get(RestoreTabsProperties.SELECTED_DEVICE); + ForeignSession newSelection = sessions.get(0); + + setSelectedDeviceItem(newSelection); + } + + public void setSelectedDeviceItem(ForeignSession selectedSession) { + assert selectedSession != null; + mModel.set(RestoreTabsProperties.SELECTED_DEVICE, selectedSession); + } + + /** + * Selects the currently shown screen on the bottomsheet. + * @param screenType A {@link RestoreTabsProperties.ScreenType} that defines the screen to be + * shown. + */ + public void setCurrentScreen(int screenType) {} +}
diff --git a/chrome/browser/recent_tabs/internal/android/java/src/org/chromium/chrome/browser/recent_tabs/RestoreTabsMediatorUnitTest.java b/chrome/browser/recent_tabs/internal/android/java/src/org/chromium/chrome/browser/recent_tabs/RestoreTabsMediatorUnitTest.java new file mode 100644 index 0000000..675a36e5 --- /dev/null +++ b/chrome/browser/recent_tabs/internal/android/java/src/org/chromium/chrome/browser/recent_tabs/RestoreTabsMediatorUnitTest.java
@@ -0,0 +1,65 @@ +// 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.recent_tabs; + +import static org.hamcrest.Matchers.instanceOf; + +import static org.chromium.chrome.browser.recent_tabs.RestoreTabsProperties.CURRENT_SCREEN; +import static org.chromium.chrome.browser.recent_tabs.RestoreTabsProperties.HOME_SCREEN_DELEGATE; +import static org.chromium.chrome.browser.recent_tabs.RestoreTabsProperties.SELECTED_DEVICE; +import static org.chromium.chrome.browser.recent_tabs.RestoreTabsProperties.VISIBLE; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.chrome.browser.recent_tabs.ForeignSessionHelper.ForeignSession; +import org.chromium.chrome.browser.recent_tabs.ui.RestoreTabsPromoScreenCoordinator; +import org.chromium.ui.modelutil.PropertyModel; + +import java.util.ArrayList; +import java.util.List; + +/** Tests for RestoreTabsMediator. */ +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class RestoreTabsMediatorUnitTest { + private PropertyModel mModel = RestoreTabsProperties.createDefaultModel(); + private RestoreTabsMediator mMediator = new RestoreTabsMediator(); + + @Before + public void setUp() { + mMediator.initialize(mModel); + } + + @After + public void tearDown() { + mModel = null; + } + + @Test + public void testRestoreTabsMediator_createsValidDefaultModel() { + ForeignSession session = new ForeignSession("tag", "John's iPhone 6", 32L); + List<ForeignSession> testSessions = new ArrayList<>(); + testSessions.add(session); + + Assert.assertEquals(mModel.get(VISIBLE), false); + + mMediator.showOptions(testSessions); + + Assert.assertEquals(mModel.get(VISIBLE), true); + Assert.assertEquals( + mModel.get(CURRENT_SCREEN), RestoreTabsProperties.ScreenType.HOME_SCREEN); + Assert.assertEquals(mModel.get(SELECTED_DEVICE), testSessions.get(0)); + + Assert.assertNotNull(mModel.get(HOME_SCREEN_DELEGATE)); + Assert.assertThat(mModel.get(HOME_SCREEN_DELEGATE), + instanceOf(RestoreTabsPromoScreenCoordinator.Delegate.class)); + } +}
diff --git a/chrome/browser/recent_tabs/internal/android/java/src/org/chromium/chrome/browser/recent_tabs/RestoreTabsProperties.java b/chrome/browser/recent_tabs/internal/android/java/src/org/chromium/chrome/browser/recent_tabs/RestoreTabsProperties.java new file mode 100644 index 0000000..ada2b37 --- /dev/null +++ b/chrome/browser/recent_tabs/internal/android/java/src/org/chromium/chrome/browser/recent_tabs/RestoreTabsProperties.java
@@ -0,0 +1,59 @@ +// 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.recent_tabs; + +import androidx.annotation.IntDef; + +import org.chromium.chrome.browser.recent_tabs.ForeignSessionHelper.ForeignSession; +import org.chromium.chrome.browser.recent_tabs.ui.RestoreTabsPromoScreenCoordinator; +import org.chromium.ui.modelutil.PropertyKey; +import org.chromium.ui.modelutil.PropertyModel; +import org.chromium.ui.modelutil.PropertyModel.WritableBooleanPropertyKey; +import org.chromium.ui.modelutil.PropertyModel.WritableIntPropertyKey; +import org.chromium.ui.modelutil.PropertyModel.WritableObjectPropertyKey; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * State for the Restore Tabs promo UI. + */ +public class RestoreTabsProperties { + /** + * The different screens that can be shown on the sheet. + */ + @IntDef({ScreenType.HOME_SCREEN, ScreenType.DEVICE_SCREEN, ScreenType.REVIEW_TABS_SCREEN}) + @Retention(RetentionPolicy.SOURCE) + public @interface ScreenType { + int HOME_SCREEN = 0; + int DEVICE_SCREEN = 1; + int REVIEW_TABS_SCREEN = 2; + } + + /** Property that indicates the bottom sheet visibility. */ + public static final WritableBooleanPropertyKey VISIBLE = new WritableBooleanPropertyKey(); + + /** Indicates which ScreenType is currently displayed on the bottom sheet. */ + public static final WritableIntPropertyKey CURRENT_SCREEN = new WritableIntPropertyKey(); + + /** The chosen device for restoring tabs from. */ + public static final WritableObjectPropertyKey<ForeignSession> SELECTED_DEVICE = + new WritableObjectPropertyKey<>(); + + /** The delegate that handles actions on the home screen. */ + public static final WritableObjectPropertyKey<RestoreTabsPromoScreenCoordinator.Delegate> + HOME_SCREEN_DELEGATE = new WritableObjectPropertyKey<>(); + + public static PropertyModel createDefaultModel() { + return new PropertyModel.Builder(ALL_KEYS) + .with(VISIBLE, false) + .with(CURRENT_SCREEN, ScreenType.HOME_SCREEN) + .build(); + } + + /** All keys used for the restore tabs promo bottom sheet. */ + static final PropertyKey[] ALL_KEYS = + new PropertyKey[] {VISIBLE, CURRENT_SCREEN, SELECTED_DEVICE, HOME_SCREEN_DELEGATE}; +}
diff --git a/chrome/browser/recent_tabs/internal/android/java/src/org/chromium/chrome/browser/recent_tabs/ui/RestoreTabsPromoScreenCoordinator.java b/chrome/browser/recent_tabs/internal/android/java/src/org/chromium/chrome/browser/recent_tabs/ui/RestoreTabsPromoScreenCoordinator.java new file mode 100644 index 0000000..83d967f --- /dev/null +++ b/chrome/browser/recent_tabs/internal/android/java/src/org/chromium/chrome/browser/recent_tabs/ui/RestoreTabsPromoScreenCoordinator.java
@@ -0,0 +1,20 @@ +// 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.recent_tabs.ui; + +/** + * Coordinator for the home screen of the Restore Tabs on FRE promo. + */ +public class RestoreTabsPromoScreenCoordinator { + /** The delegate of the class. */ + public interface Delegate { + /** The user clicked on the selected device item. */ + void onShowDeviceList(); + /** The user clicked on restoring all tabs for the selected device. */ + void onAllTabsChosen(); + /** The user clicked on reviewing tabs for the selected device. */ + void onReviewTabsChosen(); + } +}
diff --git a/chrome/browser/referrer_policy_browsertest.cc b/chrome/browser/referrer_policy_browsertest.cc index 15745a18..f327c33 100644 --- a/chrome/browser/referrer_policy_browsertest.cc +++ b/chrome/browser/referrer_policy_browsertest.cc
@@ -686,11 +686,17 @@ title_watcher = std::make_unique<content::TitleWatcher>(tab, expected_title); EXPECT_TRUE(content::ExecuteScript(tab, "document.title = 'reset'")); EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle()); + frame = content::FrameMatchingPredicate( + tab->GetPrimaryPage(), + base::BindRepeating(&content::FrameIsChildOfMainFrame)); expected_title = u"loaded"; title_watcher = std::make_unique<content::TitleWatcher>(tab, expected_title); EXPECT_TRUE(content::ExecuteScript(frame, "location.reload()")); EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle()); + frame = content::FrameMatchingPredicate( + tab->GetPrimaryPage(), + base::BindRepeating(&content::FrameIsChildOfMainFrame)); // Verify that the full url of the iframe was used as referrer. EXPECT_TRUE(content::ExecuteScriptAndExtractString(
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc index 6ffc3f0..766d0ed 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -1767,7 +1767,8 @@ menu_model_.AddItem(GetSearchForImageIdc(), menu_string); - if (base::FeatureList::IsEnabled(lens::features::kEnableImageTranslate) && + if (base::FeatureList::IsEnabled(lens::features::kLensStandalone) && + base::FeatureList::IsEnabled(lens::features::kEnableImageTranslate) && provider && !provider->image_translate_url().empty() && provider->image_translate_url_ref().IsValid( service->search_terms_data())) {
diff --git a/chrome/browser/resource_coordinator/tab_manager_browsertest.cc b/chrome/browser/resource_coordinator/tab_manager_browsertest.cc index ba10fef3..e5705d9 100644 --- a/chrome/browser/resource_coordinator/tab_manager_browsertest.cc +++ b/chrome/browser/resource_coordinator/tab_manager_browsertest.cc
@@ -839,6 +839,7 @@ // Navigate the main frame (same site) again, wasDiscarded is not set anymore. ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url)); + main_frame = contents->GetPrimaryMainFrame(); EXPECT_TRUE(content::ExecuteScriptAndExtractBool( main_frame, kDiscardedStateJS, &discarded_mainframe_result)); EXPECT_FALSE(discarded_mainframe_result); @@ -847,6 +848,7 @@ content::TestNavigationObserver observer(contents); contents->GetController().GoBack(); observer.Wait(); + main_frame = contents->GetPrimaryMainFrame(); EXPECT_TRUE(content::ExecuteScriptAndExtractBool( main_frame, kDiscardedStateJS, &discarded_mainframe_result)); EXPECT_FALSE(discarded_mainframe_result);
diff --git a/chrome/browser/resources/app_home/app_item.html b/chrome/browser/resources/app_home/app_item.html index c84f3a8..6ba0787 100644 --- a/chrome/browser/resources/app_home/app_item.html +++ b/chrome/browser/resources/app_home/app_item.html
@@ -66,33 +66,6 @@ position: fixed; } -cr-action-menu { - /* Used to force dark mode */ - --cr-primary-text-color: var(--google-grey-200); - --cr-secondary-text-color: var(--google-grey-500); - - --cr-card-background-color: var(--google-grey-900-white-4-percent); - --cr-card-shadow-color-rgb: 0, 0, 0; - - --cr-checked-color: var(--google-blue-300); - --cr-focused-item-color: var(--google-grey-800); - --cr-form-field-label-color: var(--dark-secondary-color); - --cr-hairline-rgb: 255, 255, 255; - --cr-iph-anchor-highlight-color: rgba(var(--google-grey-100-rgb), 0.1); - --cr-link-color: var(--google-blue-300); - --cr-menu-background-color: var(--google-grey-900); - --cr-menu-background-focus-color: var(--google-grey-700); - --cr-menu-background-sheen: rgba(255, 255, 255, .06); - --cr-menu-shadow: rgba(0, 0, 0, .3) 0 1px 2px 0, - rgba(0, 0, 0, .15) 0 3px 6px 2px; - --cr-separator-color: rgba(255, 255, 255, .1); - --cr-title-text-color: var(--cr-primary-text-color); - --cr-toolbar-background-color: var(--google-grey-900-white-4-percent); - - --cr-hover-background-color: rgba(255, 255, 255, .1); - --cr-active-background-color: rgba(var(--google-grey-200-rgb), .16); - --cr-focus-outline-color: rgba(var(--google-blue-300-rgb), .4); -} </style> <div title="[[appInfo.name]]" aria-hidden="true">
diff --git a/chrome/browser/resources/nearby_share/shared/nearby_page_template.html b/chrome/browser/resources/nearby_share/shared/nearby_page_template.html index 42dae738..e18474e9 100644 --- a/chrome/browser/resources/nearby_share/shared/nearby_page_template.html +++ b/chrome/browser/resources/nearby_share/shared/nearby_page_template.html
@@ -1,4 +1,7 @@ <style include="cr-icons cr-shared-style"></style> +<if expr="chromeos_ash"> +<style include="cros-color-overrides"></style> +</if> <style> :host { --nearby-page-linear-gradient-color-start: var(--google-blue-50); @@ -13,6 +16,10 @@ } } + :host-context(body.jelly-enabled):host { + --nearby-page-linear-gradient-color-start: var(--cros-sys-highlight_shape); + } + #pageContainer { display: flex; flex-direction: column;
diff --git a/chrome/browser/resources/nearby_share/shared/nearby_page_template.ts b/chrome/browser/resources/nearby_share/shared/nearby_page_template.ts index 7831a52..7626144 100644 --- a/chrome/browser/resources/nearby_share/shared/nearby_page_template.ts +++ b/chrome/browser/resources/nearby_share/shared/nearby_page_template.ts
@@ -9,6 +9,10 @@ */ import 'chrome://resources/cr_elements/cr_shared_style.css.js'; +// <if expr='chromeos_ash'> +import 'chrome://resources/cr_elements/chromeos/cros_color_overrides.css.js'; + +// </if> import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
diff --git a/chrome/browser/resources/new_tab_page/app.ts b/chrome/browser/resources/new_tab_page/app.ts index 823db20..efdf61ba 100644 --- a/chrome/browser/resources/new_tab_page/app.ts +++ b/chrome/browser/resources/new_tab_page/app.ts
@@ -524,6 +524,7 @@ document.documentElement.setAttribute('lazy-loaded', String(true)); this.registerHelpBubble( CUSTOMIZE_CHROME_BUTTON_ELEMENT_ID, '#customizeButton', {fixed: true}); + this.pageHandler_.maybeShowCustomizeChromeFeaturePromo(); } private onOpenVoiceSearch_() {
diff --git a/chrome/browser/resources/new_tab_page/modules/cart/icons/BUILD.gn b/chrome/browser/resources/new_tab_page/modules/cart/icons/BUILD.gn index 78c9b0d..fdf8dea 100644 --- a/chrome/browser/resources/new_tab_page/modules/cart/icons/BUILD.gn +++ b/chrome/browser/resources/new_tab_page/modules/cart/icons/BUILD.gn
@@ -14,6 +14,7 @@ "cart_logo.svg", "consent_icon.svg", "consent_label.svg", + "shopping_cart.svg", ] input_files_base_dir = rebase_path(".", "//") resource_path_prefix = "modules/cart/icons"
diff --git a/chrome/browser/resources/new_tab_page/modules/cart/icons/shopping_cart.svg b/chrome/browser/resources/new_tab_page/modules/cart/icons/shopping_cart.svg new file mode 100644 index 0000000..4276636 --- /dev/null +++ b/chrome/browser/resources/new_tab_page/modules/cart/icons/shopping_cart.svg
@@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 96 960 960" fill="#041E49"><path d="M263.788 960Q234 960 213 938.788q-21-21.213-21-51Q192 858 213.212 837q21.213-21 51-21Q294 816 315 837.212q21 21.213 21 51Q336 918 314.788 939q-21.213 21-51 21Zm432 0Q666 960 645 938.788q-21-21.213-21-51Q624 858 645.212 837q21.213-21 51-21Q726 816 747 837.212q21 21.213 21 51Q768 918 746.788 939q-21.213 21-51 21ZM253 360l83 192h301l82-192H253Zm-31-72h570q14 0 20.5 11t1.5 23L702.627 579.855Q694 600 676.5 612 659 624 637 624H317l-42 72h493v72H276q-43 0-63.5-36.153Q192 695.695 213 660l52-90-131-306H48v-72h133l41 96Zm114 264h301-301Z"/></svg>
diff --git a/chrome/browser/resources/new_tab_page/modules/cart/module.html b/chrome/browser/resources/new_tab_page/modules/cart/module.html index aa9e8806..bdc5e49 100644 --- a/chrome/browser/resources/new_tab_page/modules/cart/module.html +++ b/chrome/browser/resources/new_tab_page/modules/cart/module.html
@@ -339,7 +339,8 @@ 'modulesCartLower')]]" show-info-button on-info-button-click="onInfoButtonClick_" show-dismiss-button on-dismiss-button-click="onDismissButtonClick_" - on-disable-button-click="onDisableButtonClick_"> + on-disable-button-click="onDisableButtonClick_" + icon-src="modules/cart/icons/shopping_cart.svg"> $i18n{modulesCartSentence} </ntp-module-header> <div id="moduleContent">
diff --git a/chrome/browser/resources/new_tab_page/modules/history_clusters/tile.html b/chrome/browser/resources/new_tab_page/modules/history_clusters/tile.html index a8cee28a..8824be2 100644 --- a/chrome/browser/resources/new_tab_page/modules/history_clusters/tile.html +++ b/chrome/browser/resources/new_tab_page/modules/history_clusters/tile.html
@@ -131,6 +131,10 @@ position: relative; } + #date { + min-width: max-content; + } + :host([large-format]) #label { max-width: 220px; }
diff --git a/chrome/browser/resources/password_manager/BUILD.gn b/chrome/browser/resources/password_manager/BUILD.gn index 250f6a0..f314a87cb 100644 --- a/chrome/browser/resources/password_manager/BUILD.gn +++ b/chrome/browser/resources/password_manager/BUILD.gn
@@ -19,7 +19,17 @@ "password_manager.html", ] if (is_chrome_branded) { - static_files += [ "chrome_branded_manifest.webmanifest" ] + static_files += [ + "chrome_branded_manifest.webmanifest", + "images/access_on_any_device_promo.svg", + "images/access_on_any_device_promo_dark.svg", + "images/password_checkup_promo.svg", + "images/password_checkup_promo_dark.svg", + "images/password_shortcut_promo.svg", + "images/password_shortcut_promo_dark.svg", + "images/passwords_on_web_promo.svg", + "images/passwords_on_web_promo_dark.svg", + ] } else { static_files += [ "manifest.webmanifest" ] } @@ -39,12 +49,17 @@ "password_manager_app.ts", "passwords_exporter.ts", "passwords_section.ts", + "prefs/extension_controlled_icon.ts", "prefs/pref_toggle_button.ts", "settings_section.ts", "side_bar.ts", "site_favicon.ts", "toolbar.ts", ] + if (is_chrome_branded) { + web_component_files += [ "promo_cards/promo_card.ts" ] + } + non_web_component_files = [ "password_manager.ts", "password_manager_proxy.ts", @@ -55,6 +70,7 @@ "show_password_mixin.ts", "sync_browser_proxy.ts", "user_utils_mixin.ts", + "promo_cards/promo_cards_browser_proxy.ts", ] # Files that are passed as input to css_to_wrapper().
diff --git a/chrome/browser/resources/password_manager/images/access_on_any_device_promo.svg b/chrome/browser/resources/password_manager/images/access_on_any_device_promo.svg new file mode 100644 index 0000000..baac06e --- /dev/null +++ b/chrome/browser/resources/password_manager/images/access_on_any_device_promo.svg
@@ -0,0 +1 @@ +<svg width="244" height="120" viewBox="0 0 244 120" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M120.5 114c24.348 0 44.967-15.966 51.958-38M120.5 5C98.424 5 79.413 18.126 70.847 37M133.5 6.56c16.362 4.004 29.826 15.396 36.653 30.44M106.5 112.185C91.318 108.161 78.735 97.749 71.804 84M162 59.5a41.31 41.31 0 0 0-7.29-23.5M79 59.5a41.306 41.306 0 0 1 6.5-22.309M142 95.004a41.64 41.64 0 0 0 17.336-20.843M131.5 99.526a41.548 41.548 0 0 1-11 1.474c-15.015 0-28.167-7.974-35.454-19.918M143 24.622A41.306 41.306 0 0 0 120.5 18a41.337 41.337 0 0 0-27.02 10" stroke="#E8EAED" stroke-width="1.376" stroke-linecap="round"/><path d="M113.298 62.08a5.16 5.16 0 0 1-4.463 2.58 5.168 5.168 0 0 1-5.161-5.161 5.168 5.168 0 0 1 5.161-5.161 5.165 5.165 0 0 1 4.463 2.58h6.593c-1.172-5.02-5.681-8.773-11.052-8.773-6.264 0-11.358 5.094-11.358 11.354 0 6.259 5.094 11.354 11.354 11.354 5.371 0 9.884-3.753 11.052-8.774h-6.589Z" fill="#4285F4"/><path d="M131.027 56.402h-11.354v6.194h11.354v-6.194Z" fill="#FBBC04"/><path d="M142.897 62.08v6.71h-4.129v-2.065a2.065 2.065 0 0 0-4.128 0v2.064h-4.129V62.08h12.386Z" fill="#34A853"/><path d="M142.897 56.402h-12.386v6.194h12.386v-6.194Z" fill="#188038"/><path d="M119.755 56.402h-6.792v.013a5.14 5.14 0 0 1 1.032 3.084 5.14 5.14 0 0 1-1.032 3.084v.013h6.792a11.317 11.317 0 0 0 0-6.194Z" fill="#EA4335"/><rect x="-.837" y=".497" width="40.447" height="28.146" rx="2.064" transform="scale(-1 1) rotate(-14.295 92.125 858.678)" fill="#F8F9FA" stroke="#9AA0A6" stroke-width="1.376"/><path d="m207.867 80.541-50.064-12.757a1.846 1.846 0 0 0 1.333 2.244l46.488 11.845a1.844 1.844 0 0 0 2.243-1.332Z" fill="#9AA0A6"/><circle cx=".486" cy=".486" r=".486" transform="scale(-1 1) rotate(-14.295 88.766 782.895)" fill="#BDC1C6"/><rect x="50.847" y="45.185" width="19.268" height="39.911" rx="2.064" transform="rotate(-15.469 50.847 45.185)" fill="#F8F9FA" stroke="#9AA0A6" stroke-width="1.376"/><circle cx="53.449" cy="46.897" r=".681" transform="rotate(-15.469 53.45 46.897)" fill="#BDC1C6"/><rect width="8.173" height="1.362" rx=".681" transform="scale(-1 1) rotate(15.469 -318.95 -232.975)" fill="#BDC1C6"/><rect width="5.108" height="5.108" rx="1.376" transform="scale(-1 1) rotate(-38.785 -1.404 147.802)" fill="#34A853"/><rect width="5.108" height="5.108" rx="1.376" transform="scale(-1 1) rotate(-7.486 794.066 945.13)" fill="#FBBC04"/><circle cx="137" cy="98" r="2" fill="#EA4335"/><circle cx="147.131" cy="27.993" r="1.916" transform="rotate(3.1 147.131 27.993)" fill="#FBBC04"/><circle cx="151.377" cy="31.819" r="1.916" transform="rotate(3.1 151.377 31.82)" fill="#4285F4"/><rect x="63.671" y="56.643" width="5.505" height="9.634" rx="2.753" transform="rotate(-.827 63.67 56.643)" fill="#4285F4"/><circle cx="66.992" cy="71.679" r="2.064" transform="rotate(-4.548 66.992 71.68)" fill="#FBBC04"/><circle cx="66.992" cy="51.322" r="2.064" transform="rotate(-4.548 66.992 51.322)" fill="#34A853"/><rect x="171.932" y="51.707" width="5.505" height="9.634" rx="2.753" transform="rotate(-2.454 171.932 51.707)" fill="#FBBC04"/><circle cx="173.409" cy="46.597" r="2.064" transform="rotate(13.015 173.409 46.597)" fill="#EA4335"/><circle cx="174.408" cy="66.207" r="2.064" transform="rotate(13.015 174.408 66.207)" fill="#E8EAED"/><circle cx="127.5" cy="5.5" r="2.5" fill="#4285F4"/></svg> \ No newline at end of file
diff --git a/chrome/browser/resources/password_manager/images/access_on_any_device_promo_dark.svg b/chrome/browser/resources/password_manager/images/access_on_any_device_promo_dark.svg new file mode 100644 index 0000000..0684ca1 --- /dev/null +++ b/chrome/browser/resources/password_manager/images/access_on_any_device_promo_dark.svg
@@ -0,0 +1 @@ +<svg width="248" height="120" viewBox="0 0 248 120" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M125.446 109c22.284 0 41.156-14.501 47.554-34.514M125.446 10C105.24 10 87.84 21.922 80 39.064m57.344-27.647c14.976 3.637 27.298 13.984 33.547 27.647m-58.259 68.288c-13.896-3.655-25.412-13.112-31.756-25.6M163 59.5a36.989 36.989 0 0 0-6.675-21.235M87 59.5c0-7.42 2.184-14.337 5.952-20.158m51.735 52.24c7.213-4.32 12.853-10.942 15.874-18.834m-25.489 22.92A38.516 38.516 0 0 1 125 97c-13.749 0-25.792-7.205-32.464-17.998m53.066-51.017C139.667 24.197 132.594 22 125 22c-9.449 0-18.093 3.404-24.741 9.036" stroke="#3C4043" stroke-width="1.5" stroke-linecap="round"/><path d="M118.783 61.879a4.71 4.71 0 0 1-4.074 2.355 4.718 4.718 0 0 1-4.712-4.71 4.718 4.718 0 0 1 4.712-4.712c1.737 0 3.256.95 4.074 2.355h6.019c-1.07-4.583-5.186-8.009-10.09-8.009-5.717 0-10.368 4.651-10.368 10.365s4.651 10.365 10.365 10.365c4.903 0 9.023-3.426 10.089-8.01h-6.015Z" fill="#4285F4"/><path d="M134.967 56.697h-10.364v5.654h10.364v-5.654Z" fill="#FBBC04"/><path d="M145.803 61.879v6.125h-3.769v-1.885a1.885 1.885 0 0 0-3.769 0v1.885h-3.769v-6.125h11.307Z" fill="#34A853"/><path d="M145.803 56.697h-11.307v5.654h11.307v-5.654Z" fill="#188038"/><path d="M124.678 56.697h-6.2v.012a4.69 4.69 0 0 1 .942 2.815 4.692 4.692 0 0 1-.942 2.816v.01h6.2a10.316 10.316 0 0 0 0-5.653Z" fill="#EA4335"/><rect x="-.912" y=".542" width="36.679" height="25.45" rx="2.003" transform="scale(-1 1) rotate(-14.295 97.192 846.604)" stroke="#9AA0A6" stroke-width="1.5"/><path d="m205.113 78.732-45.702-11.645a1.684 1.684 0 0 0 1.216 2.048l42.438 10.814a1.684 1.684 0 0 0 2.048-1.217Z" fill="#9AA0A6"/><rect x="61.923" y="46.54" width="17.345" height="36.191" rx="2.003" transform="rotate(-15.469 61.923 46.54)" stroke="#9AA0A6" stroke-width="1.5"/><rect width="7.461" height="1.244" rx=".622" transform="scale(-1 1) rotate(15.469 -318.01 -266.605)" fill="#9AA0A6"/><rect width="4.663" height="4.663" rx="1.376" transform="scale(-1 1) rotate(-38.785 -1.561 159.34)" fill="#81C995"/><rect width="4.663" height="4.663" rx="1.376" transform="scale(-1 1) rotate(-7.486 757.017 982.76)" fill="#FDD663"/><circle cx="140.5" cy="94.5" r="1.5" fill="#F28B82"/><circle cx="149.668" cy="30.763" r="1.749" transform="rotate(3.1 149.668 30.763)" fill="#FDD663"/><circle cx="153.544" cy="34.255" r="1.749" transform="rotate(3.1 153.544 34.255)" fill="#8AB4F8"/><rect x="73.48" y="56.916" width="5.025" height="8.794" rx="2.513" transform="rotate(-.827 73.48 56.916)" fill="#8AB4F8"/><circle cx="76.511" cy="70.643" r="1.885" transform="rotate(-4.548 76.511 70.643)" fill="#FDD663"/><circle cx="76.511" cy="52.059" r="1.885" transform="rotate(-4.548 76.511 52.06)" fill="#81C995"/><rect x="172.309" y="52.41" width="5.025" height="8.794" rx="2.513" transform="rotate(-2.454 172.309 52.41)" fill="#FDD663"/><circle cx="173.657" cy="47.747" r="1.885" transform="rotate(13.015 173.657 47.747)" fill="#F28B82"/><circle cx="174.569" cy="65.647" r="1.885" transform="rotate(13.015 174.569 65.647)" fill="#3C4043"/><circle cx="131.5" cy="10.5" r="2.5" fill="#8AB4F8"/></svg> \ No newline at end of file
diff --git a/chrome/browser/resources/password_manager/images/password_checkup_promo.svg b/chrome/browser/resources/password_manager/images/password_checkup_promo.svg new file mode 100644 index 0000000..48185ce --- /dev/null +++ b/chrome/browser/resources/password_manager/images/password_checkup_promo.svg
@@ -0,0 +1 @@ +<svg width="248" height="120" viewBox="0 0 248 120" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M141 21H89a4 4 0 0 0-4 4v82a4 4 0 0 0 4 4h52a4 4 0 0 0 4-4V25a4 4 0 0 0-4-4Z" fill="#BDC1C6"/><path d="M141 28H89v76h52V28Z" fill="#fff"/><path fill="#9AA0A6" d="M89 104h52v2H89z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M121 27V16a6 6 0 1 0-12 0v11h12Zm-3-11a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" fill="#1B6EF3"/><path d="M102 21h26a2.998 2.998 0 0 1 3 3v4H99v-4a3 3 0 0 1 3-3Z" fill="#1B6EF3"/><path d="M131 28H99v5h32v-5Z" fill="#7CACF8"/><circle cx="168.748" cy="36.634" r="4" transform="rotate(10 168.748 36.634)" fill="#FF8BCB"/><path fill="#FF8BCB" d="m164.809 35.94 7.878 1.39-.694 3.938-7.879-1.389z"/><path fill="#DADCE0" d="m164.113 39.879 7.878 1.39-1.736 9.847-7.878-1.389z"/><path fill="#FBBC04" d="m162.377 49.727 7.878 1.39-7.64 43.33-7.879-1.388z"/><path fill="#9AA0A6" d="m163.767 41.848 7.878 1.39-.173.984-7.879-1.39zm-.869 4.924 7.878 1.39-.173.984-7.879-1.39z"/><path d="m156.94 103.6-2.203-10.542 7.878 1.389-5.675 9.153Z" fill="#E8EAED"/><path d="m156.059 99.383.881 4.217 2.27-3.661-3.151-.556Z" fill="#80868B"/><path d="M136 73v7h-7v-7h7Zm2-2h-11v11h11V71Zm-2-28v7h-7v-7h7Zm2-2h-11v11h11V41Zm-2 17v7h-7v-7h7Zm2-2h-11v11h11V56Zm-2 32v7h-7v-7h7Zm2-2h-11v11h11V86Z" fill="#DADCE0"/><rect x="92" y="41" width="32" height="11" rx="5.5" fill="#DADCE0"/><circle cx="97.5" cy="46.5" r="2.5" fill="#1B6EF3"/><circle cx="118.5" cy="46.5" r="2.5" fill="#1B6EF3"/><circle cx="104.5" cy="46.5" r="2.5" fill="#1B6EF3"/><circle cx="111.5" cy="46.5" r="2.5" fill="#1B6EF3"/><rect x="92" y="56" width="32" height="11" rx="5.5" fill="#DADCE0"/><circle cx="97.5" cy="61.5" r="2.5" fill="#1B6EF3"/><circle cx="118.5" cy="61.5" r="2.5" fill="#1B6EF3"/><circle cx="104.5" cy="61.5" r="2.5" fill="#1B6EF3"/><circle cx="111.5" cy="61.5" r="2.5" fill="#1B6EF3"/><rect x="92" y="71" width="32" height="11" rx="5.5" fill="#DADCE0"/><circle cx="97.5" cy="76.5" r="2.5" fill="#1B6EF3"/><circle cx="118.5" cy="76.5" r="2.5" fill="#1B6EF3"/><circle cx="104.5" cy="76.5" r="2.5" fill="#1B6EF3"/><circle cx="111.5" cy="76.5" r="2.5" fill="#1B6EF3"/><rect x="92" y="86" width="32" height="11" rx="5.5" fill="#DADCE0"/><circle cx="97.5" cy="91.5" r="2.5" fill="#1B6EF3"/><circle cx="118.5" cy="91.5" r="2.5" fill="#1B6EF3"/><circle cx="104.5" cy="91.5" r="2.5" fill="#1B6EF3"/><circle cx="111.5" cy="91.5" r="2.5" fill="#1B6EF3"/><circle cx="58" cy="20" r="1" fill="#DADCE0"/><circle cx="62" cy="20" r="1" fill="#DADCE0"/><circle cx="50" cy="20" r="1" fill="#DADCE0"/><circle cx="54" cy="20" r="1" fill="#DADCE0"/><circle cx="66" cy="20" r="1" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 36 92)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 44 92)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 40 92)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 32 92)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 28 92)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 198 25)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 194 25)" fill="#DADCE0"/><circle cx="42" cy="24" r="1" fill="#DADCE0"/><circle cx="46" cy="24" r="1" fill="#DADCE0"/><circle cx="30" cy="24" r="1" fill="#DADCE0"/><circle cx="50" cy="24" r="1" fill="#DADCE0"/><circle cx="54" cy="24" r="1" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 206 25)" fill="#DADCE0"/><circle cx="38" cy="24" r="1" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 202 25)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 190 25)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 186 25)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 182 25)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 52 96)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 48 100)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 48 96)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 44 100)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 44 96)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 40 96)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 36 96)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 56 96)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 214 29)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 210 29)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 206 29)" fill="#DADCE0"/><circle cx="183" cy="107" r="1" fill="#DADCE0"/><circle cx="187" cy="107" r="1" fill="#DADCE0"/><circle cx="179" cy="103" r="1" fill="#DADCE0"/><circle cx="183" cy="103" r="1" fill="#DADCE0"/><circle cx="191" cy="107" r="1" fill="#DADCE0"/><circle cx="187" cy="103" r="1" fill="#DADCE0"/><circle cx="163" cy="107" r="1" fill="#DADCE0"/><circle cx="179" cy="107" r="1" fill="#DADCE0"/><circle cx="167" cy="107" r="1" fill="#DADCE0"/><circle cx="171" cy="107" r="1" fill="#DADCE0"/><circle cx="175" cy="107" r="1" fill="#DADCE0"/><circle cx="175" cy="103" r="1" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 218 29)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 202 29)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 198 29)" fill="#DADCE0"/><circle cx="37" cy="53" r="3" fill="#DADCE0"/><circle cx="45" cy="53" r="3" fill="#DADCE0"/><circle cx="53" cy="53" r="3" fill="#DADCE0"/><circle cx="21" cy="53" r="3" fill="#DADCE0"/><circle cx="199" cy="72" r="3" fill="#DADCE0"/><circle cx="207" cy="72" r="3" fill="#DADCE0"/><circle cx="215" cy="72" r="3" fill="#DADCE0"/><circle cx="231" cy="72" r="3" fill="#DADCE0"/></svg> \ No newline at end of file
diff --git a/chrome/browser/resources/password_manager/images/password_checkup_promo_dark.svg b/chrome/browser/resources/password_manager/images/password_checkup_promo_dark.svg new file mode 100644 index 0000000..c253dc19 --- /dev/null +++ b/chrome/browser/resources/password_manager/images/password_checkup_promo_dark.svg
@@ -0,0 +1 @@ +<svg width="248" height="120" viewBox="0 0 248 120" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M141 21H89a4 4 0 0 0-4 4v82a4 4 0 0 0 4 4h52a4 4 0 0 0 4-4V25a4 4 0 0 0-4-4Z" fill="#80868B"/><path d="M141 28H89v76h52V28Z" fill="#fff"/><path fill-rule="evenodd" clip-rule="evenodd" d="M121 27V16a6 6 0 1 0-12 0v11h12Zm-3-11a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" fill="#0B57D0"/><path d="M102 21h26a2.998 2.998 0 0 1 3 3v4H99v-4a3 3 0 0 1 3-3Z" fill="#0B57D0"/><path d="M131 28H99v5h32v-5Z" fill="#7CACF8"/><path d="M136 73v7h-7v-7h7Zm2-2h-11v11h11V71Zm-2-28v7h-7v-7h7Zm2-2h-11v11h11V41Zm-2 17v7h-7v-7h7Zm2-2h-11v11h11V56Zm-2 32v7h-7v-7h7Zm2-2h-11v11h11V86Z" fill="#DADCE0"/><rect x="92" y="41" width="32" height="11" rx="5.5" fill="#DADCE0"/><circle cx="97.5" cy="46.5" r="2.5" fill="#1B6EF3"/><circle cx="118.5" cy="46.5" r="2.5" fill="#1B6EF3"/><circle cx="104.5" cy="46.5" r="2.5" fill="#1B6EF3"/><circle cx="111.5" cy="46.5" r="2.5" fill="#1B6EF3"/><rect x="92" y="56" width="32" height="11" rx="5.5" fill="#DADCE0"/><circle cx="97.5" cy="61.5" r="2.5" fill="#1B6EF3"/><circle cx="118.5" cy="61.5" r="2.5" fill="#1B6EF3"/><circle cx="104.5" cy="61.5" r="2.5" fill="#1B6EF3"/><circle cx="111.5" cy="61.5" r="2.5" fill="#1B6EF3"/><rect x="92" y="71" width="32" height="11" rx="5.5" fill="#DADCE0"/><circle cx="97.5" cy="76.5" r="2.5" fill="#1B6EF3"/><circle cx="118.5" cy="76.5" r="2.5" fill="#1B6EF3"/><circle cx="104.5" cy="76.5" r="2.5" fill="#1B6EF3"/><circle cx="111.5" cy="76.5" r="2.5" fill="#1B6EF3"/><rect x="92" y="86" width="32" height="11" rx="5.5" fill="#DADCE0"/><circle cx="97.5" cy="91.5" r="2.5" fill="#1B6EF3"/><circle cx="118.5" cy="91.5" r="2.5" fill="#1B6EF3"/><circle cx="104.5" cy="91.5" r="2.5" fill="#1B6EF3"/><circle cx="111.5" cy="91.5" r="2.5" fill="#1B6EF3"/><circle cx="168.748" cy="36.634" r="4" transform="rotate(10 168.748 36.634)" fill="#FF8BCB"/><path fill="#FF8BCB" d="m164.809 35.94 7.878 1.39-.694 3.938-7.879-1.389z"/><path fill="#DADCE0" d="m164.113 39.879 7.878 1.39-1.736 9.847-7.878-1.389z"/><path fill="#FBBC04" d="m162.377 49.727 7.878 1.39-7.64 43.33-7.879-1.388z"/><path fill="#9AA0A6" d="m163.767 41.848 7.878 1.39-.173.984-7.879-1.39zm-.869 4.924 7.878 1.39-.173.984-7.879-1.39z"/><path d="m156.94 103.6-2.203-10.542 7.878 1.389-5.675 9.153Z" fill="#E8EAED"/><path d="m156.059 99.383.881 4.217 2.27-3.661-3.151-.556Z" fill="#80868B"/><circle cx="58" cy="20" r="1" fill="#5F6368"/><circle cx="62" cy="20" r="1" fill="#5F6368"/><circle cx="50" cy="20" r="1" fill="#5F6368"/><circle cx="54" cy="20" r="1" fill="#5F6368"/><circle cx="66" cy="20" r="1" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 36 92)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 44 92)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 40 92)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 32 92)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 28 92)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 198 25)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 194 25)" fill="#5F6368"/><circle cx="42" cy="24" r="1" fill="#5F6368"/><circle cx="46" cy="24" r="1" fill="#5F6368"/><circle cx="30" cy="24" r="1" fill="#5F6368"/><circle cx="50" cy="24" r="1" fill="#5F6368"/><circle cx="54" cy="24" r="1" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 206 25)" fill="#5F6368"/><circle cx="38" cy="24" r="1" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 202 25)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 190 25)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 186 25)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 182 25)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 52 96)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 48 100)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 48 96)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 44 100)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 44 96)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 40 96)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 36 96)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 56 96)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 214 29)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 210 29)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 206 29)" fill="#5F6368"/><circle cx="183" cy="107" r="1" fill="#5F6368"/><circle cx="187" cy="107" r="1" fill="#5F6368"/><circle cx="179" cy="103" r="1" fill="#5F6368"/><circle cx="183" cy="103" r="1" fill="#5F6368"/><circle cx="191" cy="107" r="1" fill="#5F6368"/><circle cx="187" cy="103" r="1" fill="#5F6368"/><circle cx="163" cy="107" r="1" fill="#5F6368"/><circle cx="179" cy="107" r="1" fill="#5F6368"/><circle cx="167" cy="107" r="1" fill="#5F6368"/><circle cx="171" cy="107" r="1" fill="#5F6368"/><circle cx="175" cy="107" r="1" fill="#5F6368"/><circle cx="175" cy="103" r="1" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 218 29)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 202 29)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 198 29)" fill="#5F6368"/><circle cx="37" cy="53" r="3" fill="#5F6368"/><circle cx="45" cy="53" r="3" fill="#5F6368"/><circle cx="53" cy="53" r="3" fill="#5F6368"/><circle cx="21" cy="53" r="3" fill="#5F6368"/><circle cx="199" cy="72" r="3" fill="#5F6368"/><circle cx="207" cy="72" r="3" fill="#5F6368"/><circle cx="215" cy="72" r="3" fill="#5F6368"/><circle cx="231" cy="72" r="3" fill="#5F6368"/></svg> \ No newline at end of file
diff --git a/chrome/browser/resources/password_manager/images/password_shortcut_promo.svg b/chrome/browser/resources/password_manager/images/password_shortcut_promo.svg new file mode 100644 index 0000000..e0b72636 --- /dev/null +++ b/chrome/browser/resources/password_manager/images/password_shortcut_promo.svg
@@ -0,0 +1 @@ +<svg width="248" height="120" viewBox="0 0 248 120" fill="none" xmlns="http://www.w3.org/2000/svg"><g filter="url(#a)"><circle cx="131" cy="61" r="46" fill="#fff"/></g><circle cx="58" cy="20" r="1" fill="#DADCE0"/><circle cx="62" cy="20" r="1" fill="#DADCE0"/><circle cx="50" cy="20" r="1" fill="#DADCE0"/><circle cx="54" cy="20" r="1" fill="#DADCE0"/><circle cx="66" cy="20" r="1" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 36 92)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 44 92)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 40 92)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 32 92)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 28 92)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 198 25)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 194 25)" fill="#DADCE0"/><circle cx="42" cy="24" r="1" fill="#DADCE0"/><circle cx="46" cy="24" r="1" fill="#DADCE0"/><circle cx="30" cy="24" r="1" fill="#DADCE0"/><circle cx="50" cy="24" r="1" fill="#DADCE0"/><circle cx="54" cy="24" r="1" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 206 25)" fill="#DADCE0"/><circle cx="38" cy="24" r="1" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 202 25)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 190 25)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 186 25)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 182 25)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 52 96)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 48 100)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 48 96)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 44 100)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 44 96)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 40 96)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 36 96)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 56 96)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 214 29)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 210 29)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 206 29)" fill="#DADCE0"/><circle cx="183" cy="107" r="1" fill="#DADCE0"/><circle cx="187" cy="107" r="1" fill="#DADCE0"/><circle cx="179" cy="103" r="1" fill="#DADCE0"/><circle cx="183" cy="103" r="1" fill="#DADCE0"/><circle cx="191" cy="107" r="1" fill="#DADCE0"/><circle cx="187" cy="103" r="1" fill="#DADCE0"/><circle cx="163" cy="107" r="1" fill="#DADCE0"/><circle cx="179" cy="107" r="1" fill="#DADCE0"/><circle cx="167" cy="107" r="1" fill="#DADCE0"/><circle cx="171" cy="107" r="1" fill="#DADCE0"/><circle cx="175" cy="107" r="1" fill="#DADCE0"/><circle cx="175" cy="103" r="1" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 218 29)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 202 29)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 198 29)" fill="#DADCE0"/><circle cx="37" cy="53" r="3" fill="#DADCE0"/><circle cx="45" cy="53" r="3" fill="#DADCE0"/><circle cx="53" cy="53" r="3" fill="#DADCE0"/><circle cx="21" cy="53" r="3" fill="#DADCE0"/><circle cx="199" cy="72" r="3" fill="#DADCE0"/><circle cx="207" cy="72" r="3" fill="#DADCE0"/><circle cx="215" cy="72" r="3" fill="#DADCE0"/><circle cx="231" cy="72" r="3" fill="#DADCE0"/><path d="M156.666 57.5h-14v7h14v-7Z" fill="#188038"/><path d="M118.167 73.833c-7.058 0-12.833-5.775-12.833-12.834 0-7.058 5.775-12.833 12.833-12.833 7.059 0 12.834 5.775 12.834 12.833 0 7.059-5.775 12.834-12.834 12.834Zm0-18.667c-3.208 0-5.833 2.625-5.833 5.833 0 3.209 2.625 5.834 5.833 5.834 3.209 0 5.834-2.625 5.834-5.834 0-3.208-2.625-5.833-5.834-5.833Z" fill="#4285F4"/><path d="M151.999 64.5h-9.333v7h4.667v-2.333a2.34 2.34 0 0 1 2.333-2.334 2.34 2.34 0 0 1 2.333 2.334V71.5h4.667v-7h-4.667Z" fill="#34A853"/><path d="M130.534 57.5h-7.7c.7.992 1.167 2.158 1.167 3.5s-.467 2.508-1.167 3.5h7.7c.292-1.108.467-2.275.467-3.5s-.175-2.392-.467-3.5Z" fill="#EA4335"/><path d="M142.667 57.5h-12.134c.292 1.108.467 2.275.467 3.5s-.175 2.392-.467 3.5h12.134v-7Z" fill="#FBBC04"/><defs><filter id="a" x="81" y="11" width="100" height="104" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/><feOffset dy="4"/><feGaussianBlur stdDeviation="2"/><feComposite in2="hardAlpha" operator="out"/><feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/><feBlend in2="BackgroundImageFix" result="effect1_dropShadow_16989_243392"/><feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/><feOffset/><feGaussianBlur stdDeviation="2"/><feComposite in2="hardAlpha" operator="out"/><feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/><feBlend in2="effect1_dropShadow_16989_243392" result="effect2_dropShadow_16989_243392"/><feBlend in="SourceGraphic" in2="effect2_dropShadow_16989_243392" result="shape"/></filter></defs></svg> \ No newline at end of file
diff --git a/chrome/browser/resources/password_manager/images/password_shortcut_promo_dark.svg b/chrome/browser/resources/password_manager/images/password_shortcut_promo_dark.svg new file mode 100644 index 0000000..a8366e2 --- /dev/null +++ b/chrome/browser/resources/password_manager/images/password_shortcut_promo_dark.svg
@@ -0,0 +1 @@ +<svg width="248" height="120" viewBox="0 0 248 120" fill="none" xmlns="http://www.w3.org/2000/svg"><g filter="url(#a)"><circle cx="124" cy="60" r="38" fill="#3C4043"/></g><circle cx="58" cy="20" r="1" fill="#5F6368"/><circle cx="62" cy="20" r="1" fill="#5F6368"/><circle cx="50" cy="20" r="1" fill="#5F6368"/><circle cx="54" cy="20" r="1" fill="#5F6368"/><circle cx="66" cy="20" r="1" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 36 92)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 44 92)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 40 92)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 32 92)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 28 92)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 198 25)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 194 25)" fill="#5F6368"/><circle cx="42" cy="24" r="1" fill="#5F6368"/><circle cx="46" cy="24" r="1" fill="#5F6368"/><circle cx="30" cy="24" r="1" fill="#5F6368"/><circle cx="50" cy="24" r="1" fill="#5F6368"/><circle cx="54" cy="24" r="1" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 206 25)" fill="#5F6368"/><circle cx="38" cy="24" r="1" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 202 25)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 190 25)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 186 25)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 182 25)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 52 96)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 48 100)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 48 96)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 44 100)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 44 96)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 40 96)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 36 96)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 56 96)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 214 29)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 210 29)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 206 29)" fill="#5F6368"/><circle cx="183" cy="107" r="1" fill="#5F6368"/><circle cx="187" cy="107" r="1" fill="#5F6368"/><circle cx="179" cy="103" r="1" fill="#5F6368"/><circle cx="183" cy="103" r="1" fill="#5F6368"/><circle cx="191" cy="107" r="1" fill="#5F6368"/><circle cx="187" cy="103" r="1" fill="#5F6368"/><circle cx="163" cy="107" r="1" fill="#5F6368"/><circle cx="179" cy="107" r="1" fill="#5F6368"/><circle cx="167" cy="107" r="1" fill="#5F6368"/><circle cx="171" cy="107" r="1" fill="#5F6368"/><circle cx="175" cy="107" r="1" fill="#5F6368"/><circle cx="175" cy="103" r="1" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 218 29)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 202 29)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 198 29)" fill="#5F6368"/><circle cx="37" cy="53" r="3" fill="#5F6368"/><circle cx="45" cy="53" r="3" fill="#5F6368"/><circle cx="53" cy="53" r="3" fill="#5F6368"/><circle cx="21" cy="53" r="3" fill="#5F6368"/><circle cx="199" cy="72" r="3" fill="#5F6368"/><circle cx="207" cy="72" r="3" fill="#5F6368"/><circle cx="215" cy="72" r="3" fill="#5F6368"/><circle cx="231" cy="72" r="3" fill="#5F6368"/><path d="M149.667 56.5h-14v7h14v-7Z" fill="#188038"/><path d="M111.166 72.833c-7.058 0-12.833-5.775-12.833-12.834 0-7.058 5.775-12.833 12.833-12.833 7.059 0 12.834 5.775 12.834 12.833 0 7.059-5.775 12.834-12.834 12.834Zm0-18.667c-3.208 0-5.833 2.625-5.833 5.833 0 3.209 2.625 5.834 5.833 5.834 3.209 0 5.834-2.625 5.834-5.834 0-3.208-2.625-5.833-5.834-5.833Z" fill="#4285F4"/><path d="M145 63.5h-9.333v7h4.667v-2.333a2.34 2.34 0 0 1 2.333-2.334A2.34 2.34 0 0 1 145 68.167V70.5h4.667v-7H145Z" fill="#34A853"/><path d="M123.533 56.5h-7.7c.7.992 1.167 2.158 1.167 3.5s-.467 2.508-1.167 3.5h7.7c.292-1.108.467-2.275.467-3.5s-.175-2.392-.467-3.5Z" fill="#EA4335"/><path d="M135.667 56.5h-12.134c.292 1.108.467 2.275.467 3.5s-.175 2.392-.467 3.5h12.134v-7Z" fill="#FBBC04"/><defs><filter id="a" x="82.696" y="18.696" width="82.609" height="85.913" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/><feOffset dy="3.304"/><feGaussianBlur stdDeviation="1.652"/><feComposite in2="hardAlpha" operator="out"/><feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/><feBlend in2="BackgroundImageFix" result="effect1_dropShadow_20032_274689"/><feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/><feOffset/><feGaussianBlur stdDeviation="1.652"/><feComposite in2="hardAlpha" operator="out"/><feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/><feBlend in2="effect1_dropShadow_20032_274689" result="effect2_dropShadow_20032_274689"/><feBlend in="SourceGraphic" in2="effect2_dropShadow_20032_274689" result="shape"/></filter></defs></svg> \ No newline at end of file
diff --git a/chrome/browser/resources/password_manager/images/passwords_on_web_promo.svg b/chrome/browser/resources/password_manager/images/passwords_on_web_promo.svg new file mode 100644 index 0000000..aeb2e2d4 --- /dev/null +++ b/chrome/browser/resources/password_manager/images/passwords_on_web_promo.svg
@@ -0,0 +1 @@ +<svg width="248" height="120" viewBox="0 0 248 120" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="58" cy="20" r="1" fill="#DADCE0"/><circle cx="62" cy="20" r="1" fill="#DADCE0"/><circle cx="50" cy="20" r="1" fill="#DADCE0"/><circle cx="54" cy="20" r="1" fill="#DADCE0"/><circle cx="66" cy="20" r="1" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 36 92)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 44 92)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 40 92)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 32 92)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 28 92)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 198 25)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 194 25)" fill="#DADCE0"/><circle cx="42" cy="24" r="1" fill="#DADCE0"/><circle cx="46" cy="24" r="1" fill="#DADCE0"/><circle cx="30" cy="24" r="1" fill="#DADCE0"/><circle cx="50" cy="24" r="1" fill="#DADCE0"/><circle cx="54" cy="24" r="1" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 206 25)" fill="#DADCE0"/><circle cx="38" cy="24" r="1" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 202 25)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 190 25)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 186 25)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 182 25)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 52 96)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 48 100)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 48 96)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 44 100)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 44 96)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 40 96)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 36 96)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 56 96)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 214 29)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 210 29)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 206 29)" fill="#DADCE0"/><circle cx="183" cy="107" r="1" fill="#DADCE0"/><circle cx="187" cy="107" r="1" fill="#DADCE0"/><circle cx="179" cy="103" r="1" fill="#DADCE0"/><circle cx="183" cy="103" r="1" fill="#DADCE0"/><circle cx="191" cy="107" r="1" fill="#DADCE0"/><circle cx="187" cy="103" r="1" fill="#DADCE0"/><circle cx="163" cy="107" r="1" fill="#DADCE0"/><circle cx="179" cy="107" r="1" fill="#DADCE0"/><circle cx="167" cy="107" r="1" fill="#DADCE0"/><circle cx="171" cy="107" r="1" fill="#DADCE0"/><circle cx="175" cy="107" r="1" fill="#DADCE0"/><circle cx="175" cy="103" r="1" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 218 29)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 202 29)" fill="#DADCE0"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 198 29)" fill="#DADCE0"/><circle cx="37" cy="53" r="3" fill="#DADCE0"/><circle cx="45" cy="53" r="3" fill="#DADCE0"/><circle cx="53" cy="53" r="3" fill="#DADCE0"/><circle cx="21" cy="53" r="3" fill="#DADCE0"/><circle cx="199" cy="72" r="3" fill="#DADCE0"/><circle cx="207" cy="72" r="3" fill="#DADCE0"/><circle cx="215" cy="72" r="3" fill="#DADCE0"/><circle cx="231" cy="72" r="3" fill="#DADCE0"/><path d="M168 54h-24v12h24V54Z" fill="#188038"/><path d="M102 82c-12.1 0-22-9.9-22-22s9.9-22 22-22 22 9.9 22 22-9.9 22-22 22Zm0-32c-5.5 0-10 4.5-10 10s4.5 10 10 10 10-4.5 10-10-4.5-10-10-10Z" fill="#4285F4"/><path d="M160 66h-16v12h8v-4c0-2.2 1.8-4 4-4s4 1.8 4 4v4h8V66h-8Z" fill="#34A853"/><path d="M123.2 54H110c1.2 1.7 2 3.7 2 6s-.8 4.3-2 6h13.2c.5-1.9.8-3.9.8-6s-.3-4.1-.8-6Z" fill="#EA4335"/><path d="M144 54h-20.8c.5 1.9.8 3.9.8 6s-.3 4.1-.8 6H144V54Z" fill="#FBBC04"/></svg> \ No newline at end of file
diff --git a/chrome/browser/resources/password_manager/images/passwords_on_web_promo_dark.svg b/chrome/browser/resources/password_manager/images/passwords_on_web_promo_dark.svg new file mode 100644 index 0000000..dccc0116 --- /dev/null +++ b/chrome/browser/resources/password_manager/images/passwords_on_web_promo_dark.svg
@@ -0,0 +1 @@ +<svg width="248" height="120" viewBox="0 0 248 120" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="58" cy="20" r="1" fill="#5F6368"/><circle cx="62" cy="20" r="1" fill="#5F6368"/><circle cx="50" cy="20" r="1" fill="#5F6368"/><circle cx="54" cy="20" r="1" fill="#5F6368"/><circle cx="66" cy="20" r="1" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 36 92)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 44 92)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 40 92)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 32 92)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 28 92)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 198 25)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 194 25)" fill="#5F6368"/><circle cx="42" cy="24" r="1" fill="#5F6368"/><circle cx="46" cy="24" r="1" fill="#5F6368"/><circle cx="30" cy="24" r="1" fill="#5F6368"/><circle cx="50" cy="24" r="1" fill="#5F6368"/><circle cx="54" cy="24" r="1" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 206 25)" fill="#5F6368"/><circle cx="38" cy="24" r="1" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 202 25)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 190 25)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 186 25)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 182 25)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 52 96)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 48 100)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 48 96)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 44 100)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 44 96)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 40 96)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 36 96)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 56 96)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 214 29)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 210 29)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 206 29)" fill="#5F6368"/><circle cx="183" cy="107" r="1" fill="#5F6368"/><circle cx="187" cy="107" r="1" fill="#5F6368"/><circle cx="179" cy="103" r="1" fill="#5F6368"/><circle cx="183" cy="103" r="1" fill="#5F6368"/><circle cx="191" cy="107" r="1" fill="#5F6368"/><circle cx="187" cy="103" r="1" fill="#5F6368"/><circle cx="163" cy="107" r="1" fill="#5F6368"/><circle cx="179" cy="107" r="1" fill="#5F6368"/><circle cx="167" cy="107" r="1" fill="#5F6368"/><circle cx="171" cy="107" r="1" fill="#5F6368"/><circle cx="175" cy="107" r="1" fill="#5F6368"/><circle cx="175" cy="103" r="1" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 218 29)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 202 29)" fill="#5F6368"/><circle cx="1" cy="1" r="1" transform="matrix(-1 0 0 1 198 29)" fill="#5F6368"/><circle cx="37" cy="53" r="3" fill="#5F6368"/><circle cx="45" cy="53" r="3" fill="#5F6368"/><circle cx="53" cy="53" r="3" fill="#5F6368"/><circle cx="21" cy="53" r="3" fill="#5F6368"/><circle cx="199" cy="72" r="3" fill="#5F6368"/><circle cx="207" cy="72" r="3" fill="#5F6368"/><circle cx="215" cy="72" r="3" fill="#5F6368"/><circle cx="231" cy="72" r="3" fill="#5F6368"/><path d="M153.334 56h-16v8h16v-8Z" fill="#188038"/><path d="M109.335 74.67c-8.067 0-14.667-6.6-14.667-14.667s6.6-14.667 14.667-14.667c8.066 0 14.666 6.6 14.666 14.667 0 8.066-6.6 14.666-14.666 14.666Zm0-21.334c-3.667 0-6.667 3-6.667 6.667 0 3.666 3 6.666 6.667 6.666 3.666 0 6.666-3 6.666-6.666 0-3.667-3-6.667-6.666-6.667Z" fill="#4285F4"/><path d="M148.001 64h-10.667v8h5.333v-2.667c0-1.466 1.2-2.666 2.667-2.666 1.467 0 2.667 1.2 2.667 2.666V72h5.333v-8h-5.333Z" fill="#34A853"/><path d="M123.466 56h-8.8c.8 1.133 1.333 2.467 1.333 4s-.533 2.867-1.333 4h8.8c.333-1.267.533-2.6.533-4s-.2-2.733-.533-4Z" fill="#EA4335"/><path d="M137.333 56h-13.866c.333 1.267.533 2.6.533 4s-.2 2.733-.533 4h13.866v-8Z" fill="#FBBC04"/></svg> \ No newline at end of file
diff --git a/chrome/browser/resources/password_manager/password_manager.ts b/chrome/browser/resources/password_manager/password_manager.ts index 792c5777..91daecb 100644 --- a/chrome/browser/resources/password_manager/password_manager.ts +++ b/chrome/browser/resources/password_manager/password_manager.ts
@@ -21,6 +21,7 @@ export {PasswordsSectionElement} from './passwords_section.js'; export {PrefToggleButtonElement} from './prefs/pref_toggle_button.js'; export {PrefsBrowserProxy, PrefsBrowserProxyImpl, PrefsChangedListener} from './prefs/prefs_browser_proxy.js'; +export {PromoCard, PromoCardsProxy, PromoCardsProxyImpl} from './promo_cards/promo_cards_browser_proxy.js'; export {CheckupSubpage, Page, Route, RouteObserverMixin, RouteObserverMixinInterface, Router, UrlParam} from './router.js'; export {SettingsSectionElement} from './settings_section.js'; export {PasswordManagerSideBarElement} from './side_bar.js';
diff --git a/chrome/browser/resources/password_manager/passwords_section.html b/chrome/browser/resources/password_manager/passwords_section.html index 273236a..08bae9b 100644 --- a/chrome/browser/resources/password_manager/passwords_section.html +++ b/chrome/browser/resources/password_manager/passwords_section.html
@@ -12,7 +12,19 @@ #passwords { margin-top: 20px; } + + promo-card { + margin-bottom: 24px; + margin-top: 24px; + } </style> +<if expr="_google_chrome"> +<template is="dom-if" if="[[promoCard_]]" restamp> + <promo-card id="promoCard" class="card" promo-card="[[promoCard_]]" + on-promo-closed="onPromoClosed_"> + </promo-card> +</template> +</if> <div id="header"> <h2 class="flex page-title">$i18n{passwords}</h2> <cr-button id="addPasswordButton" on-click="onAddPasswordClick_"
diff --git a/chrome/browser/resources/password_manager/passwords_section.ts b/chrome/browser/resources/password_manager/passwords_section.ts index 8c5c62f..f3363ba5 100644 --- a/chrome/browser/resources/password_manager/passwords_section.ts +++ b/chrome/browser/resources/password_manager/passwords_section.ts
@@ -10,6 +10,10 @@ import './dialogs/add_password_dialog.js'; import './dialogs/auth_timed_out_dialog.js'; import './user_utils_mixin.js'; +// <if expr="_google_chrome"> +import './promo_cards/promo_card.js'; +import './promo_cards/promo_cards_browser_proxy.js'; +// </if> import {getInstance as getAnnouncerInstance} from 'chrome://resources/cr_elements/cr_a11y_announcer/cr_a11y_announcer.js'; import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js'; @@ -22,10 +26,12 @@ import {PasswordManagerImpl} from './password_manager_proxy.js'; import {getTemplate} from './passwords_section.html.js'; +// <if expr="_google_chrome"> +import {PromoCard, PromoCardsProxyImpl} from './promo_cards/promo_cards_browser_proxy.js'; +// </if> import {Route, RouteObserverMixin, UrlParam} from './router.js'; import {UserUtilMixin} from './user_utils_mixin.js'; - export interface PasswordsSectionElement { $: { addPasswordButton: CrButtonElement, @@ -85,6 +91,12 @@ computed: 'computeShowMovePasswords_(isOptedInForAccountStorage, ' + 'numberOfPasswordsOnDevice_)', }, + // <if expr="_google_chrome"> + promoCard_: { + type: Object, + value: null, + }, + // </if> }; } @@ -94,6 +106,9 @@ private showAddPasswordDialog_: boolean; private showAuthTimedOutDialog_: boolean; private movePasswordsText_: string; + // <if expr="_google_chrome"> + private promoCard_: PromoCard|null; + // </if> private setSavedPasswordsListener_: ( (entries: chrome.passwordsPrivate.PasswordUiEntry[]) => void)|null = null; @@ -113,6 +128,10 @@ updateGroups(); PasswordManagerImpl.getInstance().addSavedPasswordListChangedListener( this.setSavedPasswordsListener_); + // <if expr="_google_chrome"> + PromoCardsProxyImpl.getInstance().getAvailablePromoCard().then( + promo => this.promoCard_ = promo); + // </if> this.authTimedOutListener_ = this.onAuthTimedOut_.bind(this); window.addEventListener('auth-timed-out', this.authTimedOutListener_); @@ -232,6 +251,12 @@ e.preventDefault(); // TODO(crbug.com/1420548): Show import passwords dialog. } + + // <if expr="_google_chrome"> + private onPromoClosed_() { + this.promoCard_ = null; + } + // </if> } declare global {
diff --git a/chrome/browser/resources/password_manager/prefs/extension_controlled_icon.html b/chrome/browser/resources/password_manager/prefs/extension_controlled_icon.html new file mode 100644 index 0000000..43b4ea4 --- /dev/null +++ b/chrome/browser/resources/password_manager/prefs/extension_controlled_icon.html
@@ -0,0 +1,14 @@ +<style> + :host { + align-items: center; + display: flex; + padding-inline-start: 36px; + } + + img { + /* Dimensions of the image are set in the URL. */ + margin-inline-end: 16px; + } +</style> +<img role="presentation" src="chrome://extension-icon/[[extensionId]]/20/1"> +<span>[[getLabel_(extensionName)]]</span>
diff --git a/chrome/browser/resources/password_manager/prefs/extension_controlled_icon.ts b/chrome/browser/resources/password_manager/prefs/extension_controlled_icon.ts new file mode 100644 index 0000000..e723528 --- /dev/null +++ b/chrome/browser/resources/password_manager/prefs/extension_controlled_icon.ts
@@ -0,0 +1,55 @@ +// 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. + +/** + * @fileoverview + * `extension-controlled-icon` is an icon that indicates that a given field is + * managed by an extension and therefore disabled for the user. It mimics the + * `extension_controlled_indicator` class that shows a similar indicator in the + * settings code. + */ +import '//resources/cr_elements/cr_button/cr_button.js'; + +import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; + +import {getTemplate} from './extension_controlled_icon.html.js'; + +const ExtensionControlledIconElementBase = I18nMixin(PolymerElement); + +export class ExtensionControlledIconElement extends + ExtensionControlledIconElementBase { + static get is() { + return 'extension-controlled-icon'; + } + + static get template() { + return getTemplate(); + } + + static get properties() { + return { + /** The ID of the extension controlling the associated field */ + extensionId: String, + /** The name of the extension controlling the associated field */ + extensionName: String, + }; + } + + extensionId: string; + extensionName: string; + + private getLabel_(): string { + return this.i18n('controlledByExtension', this.extensionName); + } +} + +declare global { + interface HTMLElementTagNameMap { + 'extension-controlled-icon': ExtensionControlledIconElement; + } +} + +customElements.define( + ExtensionControlledIconElement.is, ExtensionControlledIconElement);
diff --git a/chrome/browser/resources/password_manager/prefs/pref_toggle_button.html b/chrome/browser/resources/password_manager/prefs/pref_toggle_button.html index 2b4ef91..218a8a26 100644 --- a/chrome/browser/resources/password_manager/prefs/pref_toggle_button.html +++ b/chrome/browser/resources/password_manager/prefs/pref_toggle_button.html
@@ -29,9 +29,15 @@ </span> </div> </div> - <!-- TODO(crbug.com/1350947): Add policy pref indicator --> <cr-toggle id="control" checked="{{checked}}" + disabled="[[disabled]]" on-change="onClick_" aria-describedby="sub-label-text"> </cr-toggle> + <template is="dom-if" if="[[pref.extensionId]]"> + <extension-controlled-icon id="extensionIcon" + extension-id="[[pref.extensionId]]" + extension-name="[[pref.controlledByName]]"> + </extension-controlled-icon> + </template> </div>
diff --git a/chrome/browser/resources/password_manager/prefs/pref_toggle_button.ts b/chrome/browser/resources/password_manager/prefs/pref_toggle_button.ts index 404d67eb..93c4ca5 100644 --- a/chrome/browser/resources/password_manager/prefs/pref_toggle_button.ts +++ b/chrome/browser/resources/password_manager/prefs/pref_toggle_button.ts
@@ -11,6 +11,7 @@ import '//resources/cr_elements/cr_toggle/cr_toggle.js'; import '//resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js'; import './pref_mixin.js'; +import './extension_controlled_icon.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -51,6 +52,15 @@ }, /** + * Whether the control is disabled, for example due to an extension + * managing the preference. + */ + disabled: { + type: Boolean, + value: false, + }, + + /** * If true, do not automatically set the preference value on user click. * Confirm the change first then call either sendPrefChange or * resetToPrefValue accordingly. @@ -63,12 +73,16 @@ } static get observers() { - return ['prefValueChanged_(pref.value)']; + return [ + 'prefValueChanged_(pref.value)', + 'prefManagementChanged_(pref.extensionId)', + ]; } label: string; subLabel: string; checked: boolean; + disabled: boolean; changeRequiresValidation: boolean; override ready() { @@ -83,6 +97,9 @@ */ private onClick_(e: Event) { e.stopPropagation(); + if (this.disabled) { + return; + } if (this.changeRequiresValidation) { this.dispatchEvent(new CustomEvent( @@ -98,6 +115,10 @@ this.checked = prefValue; } + private prefManagementChanged_(extensionId: string|null) { + this.disabled = !!extensionId; + } + /** Update the pref to the current |checked| value. */ private updatePrefValue_() { this.setPrefValue(this.checked);
diff --git a/chrome/browser/resources/password_manager/promo_cards/promo_card.html b/chrome/browser/resources/password_manager/promo_cards/promo_card.html new file mode 100644 index 0000000..120519b5 --- /dev/null +++ b/chrome/browser/resources/password_manager/promo_cards/promo_card.html
@@ -0,0 +1,46 @@ +<style include="shared-style cr-shared-style"> + :host { + display: flex; + } + + #image { + height: 120px; + width: 248px; + } + + a[href] { + color: var(--cr-link-color); + text-decoration: none; + } + + #promoContent { + display: flex; + flex: 1; + flex-direction: column; + justify-content: center; + margin-inline-end: 6px; + margin-inline-start: 24px; + } + + #actionButton { + margin-top: 6px; + width: fit-content + } +</style> +<picture id="image"> + <source class="banner" srcset="./images/[[promoCard.id]]_dark.svg" + media="(prefers-color-scheme: dark)"> + <img class="banner" alt="" src="./images/[[promoCard.id]].svg"> +</picture> +<div id="promoContent"> + <span id="title" class="label">[[promoCard.title]]</span> + <div id="description" class="cr-secondary-text label" + inner-h-t-m-l="[[getDescription_(promoCard)]]"></div> + <cr-button id="actionButton" hidden="[[!promoCard.actionButtonText]]" + class="action-button" on-click="onActionButtonClick_"> + [[promoCard.actionButtonText]] + </cr-button> +</div> +<cr-icon-button id="closeButton" class="icon-clear no-overlap" + on-click="onCloseClick_"> +</cr-icon-button>
diff --git a/chrome/browser/resources/password_manager/promo_cards/promo_card.ts b/chrome/browser/resources/password_manager/promo_cards/promo_card.ts new file mode 100644 index 0000000..a34e41a6 --- /dev/null +++ b/chrome/browser/resources/password_manager/promo_cards/promo_card.ts
@@ -0,0 +1,94 @@ +// 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 'chrome://resources/cr_elements/cr_button/cr_button.js'; +import 'chrome://resources/cr_elements/cr_icons.css.js'; +import 'chrome://resources/cr_elements/cr_shared_style.css.js'; +import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js'; +import 'chrome://resources/cr_elements/cr_shared_vars.css.js'; + +import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js'; +import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js'; +import {assertNotReached} from 'chrome://resources/js/assert_ts.js'; +import {sanitizeInnerHtml} from 'chrome://resources/js/parse_html_subset.js'; +import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {PasswordManagerImpl} from '../password_manager_proxy.js'; +import {Page, Router, UrlParam} from '../router.js'; + +import {getTemplate} from './promo_card.html.js'; +import {PromoCard, PromoCardsProxyImpl} from './promo_cards_browser_proxy.js'; + +// WARNING: Keep synced with +// chrome/browser/ui/webui/password_manager/promo_cards_handler.cc. +enum PromoCardId { + CHECKUP = 'password_checkup_promo', + WEB_PASSWORD_MANAGER = 'passwords_on_web_promo', + SHORTCUT = 'password_shortcut_promo', + ACCESS_ON_ANY_DEVICE = 'access_on_any_device_promo', +} + +export interface PromoCardElement { + $: { + actionButton: CrButtonElement, + closeButton: CrIconButtonElement, + description: HTMLElement, + title: HTMLElement, + }; +} + +export class PromoCardElement extends PolymerElement { + static get is() { + return 'promo-card'; + } + + static get template() { + return getTemplate(); + } + + static get properties() { + return { + promoCard: Object, + }; + } + + promoCard: PromoCard; + + private getDescription_(): TrustedHTML { + return sanitizeInnerHtml(this.promoCard.description); + } + + private onActionButtonClick_() { + switch (this.promoCard.id) { + case PromoCardId.CHECKUP: + const params = new URLSearchParams(); + params.set(UrlParam.START_CHECK, 'true'); + Router.getInstance().navigateTo(Page.CHECKUP, null, params); + break; + case PromoCardId.SHORTCUT: + PasswordManagerImpl.getInstance().showAddShortcutDialog(); + break; + default: + assertNotReached(); + } + this.close_(); + } + + private onCloseClick_() { + PromoCardsProxyImpl.getInstance().recordPromoDismissed(this.promoCard.id); + this.close_(); + } + + private close_() { + this.dispatchEvent( + new CustomEvent('promo-closed', {bubbles: true, composed: true})); + } +} + +declare global { + interface HTMLElementTagNameMap { + 'promo-card': PromoCardElement; + } +} + +customElements.define(PromoCardElement.is, PromoCardElement);
diff --git a/chrome/browser/resources/password_manager/promo_cards/promo_cards_browser_proxy.ts b/chrome/browser/resources/password_manager/promo_cards/promo_cards_browser_proxy.ts new file mode 100644 index 0000000..b7eb2e1 --- /dev/null +++ b/chrome/browser/resources/password_manager/promo_cards/promo_cards_browser_proxy.ts
@@ -0,0 +1,45 @@ +// 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 {sendWithPromise} from 'chrome://resources/js/cr.js'; + +export interface PromoCard { + id: string; + title: string; + description: string; + actionButtonText?: string; +} + +export interface PromoCardsProxy { + /** + * Returns promo card to show, or null if there are no available promo cards. + */ + getAvailablePromoCard(): Promise<PromoCard|null>; + + /** + * Records dismissal of a promo card. This is important to determine whether + * promo should be shown in the future. + */ + recordPromoDismissed(id: string): void; +} + +export class PromoCardsProxyImpl implements PromoCardsProxy { + getAvailablePromoCard() { + return sendWithPromise('getAvailablePromoCard'); + } + + recordPromoDismissed(id: string) { + chrome.send('recordPromoDismissed', [id]); + } + + static getInstance(): PromoCardsProxy { + return instance || (instance = new PromoCardsProxyImpl()); + } + + static setInstance(obj: PromoCardsProxy) { + instance = obj; + } +} + +let instance: PromoCardsProxy|null = null;
diff --git a/chrome/browser/resources/password_manager/router.ts b/chrome/browser/resources/password_manager/router.ts index d0017bc..8f8d554 100644 --- a/chrome/browser/resources/password_manager/router.ts +++ b/chrome/browser/resources/password_manager/router.ts
@@ -46,22 +46,31 @@ details?: any; path(): string { + let path: string; switch (this.page) { case Page.PASSWORDS: case Page.CHECKUP: case Page.SETTINGS: - return '/' + this.page; + path = '/' + this.page; + break; case Page.PASSWORD_DETAILS: const group = this.details as chrome.passwordsPrivate.CredentialGroup; // When navigating from the passwords list details will be // |CredentialGroup|. In case of direct navigation details is string. const origin = group.name ? group.name : (this.details as string); assert(origin); - return '/' + Page.PASSWORDS + '/' + origin; + path = '/' + Page.PASSWORDS + '/' + origin; + break; case Page.CHECKUP_DETAILS: assert(this.details); - return '/' + Page.CHECKUP + '/' + this.details; + path = '/' + Page.CHECKUP + '/' + this.details; + break; } + const queryString = this.queryParameters.toString(); + if (queryString) { + path += '?' + queryString; + } + return path; } } @@ -102,8 +111,10 @@ /** * Navigates to a page and pushes a new history entry. */ - navigateTo(page: Page, details?: any) { - const newRoute = new Route(page, new URLSearchParams(), details); + navigateTo( + page: Page, details?: any, + params: URLSearchParams = new URLSearchParams()) { + const newRoute = new Route(page, params, details); if (this.currentRoute_.path() === newRoute.path()) { return; } @@ -123,15 +134,11 @@ * Notifies routeObservers_. */ updateRouterParams(params: URLSearchParams) { - let path: string = this.currentRoute_.path(); - const queryString = params.toString(); - if (queryString) { - path += '?' + queryString; - } - window.history.replaceState(window.history.state, '', path); - const oldRoute = this.currentRoute_; this.currentRoute_ = new Route(oldRoute.page, params, oldRoute.details); + + window.history.replaceState( + window.history.state, '', this.currentRoute_.path()); this.notifyObservers_(oldRoute); }
diff --git a/chrome/browser/resources/password_manager/toolbar.ts b/chrome/browser/resources/password_manager/toolbar.ts index 22525c17b..279bd8c 100644 --- a/chrome/browser/resources/password_manager/toolbar.ts +++ b/chrome/browser/resources/password_manager/toolbar.ts
@@ -55,7 +55,10 @@ if (event.detail) { newParams.set(UrlParam.SEARCH_TERM, event.detail); // Switch to passwords page, since search is supported only on passwords. - Router.getInstance().navigateTo(Page.PASSWORDS); + if (Router.getInstance().currentRoute.page !== Page.PASSWORDS) { + Router.getInstance().navigateTo(Page.PASSWORDS, null, newParams); + return; + } } Router.getInstance().updateRouterParams(newParams); }
diff --git a/chrome/browser/resources/settings/chromeos/device_page/audio.ts b/chrome/browser/resources/settings/chromeos/device_page/audio.ts index f1563f87..438b686 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/audio.ts +++ b/chrome/browser/resources/settings/chromeos/device_page/audio.ts
@@ -158,21 +158,11 @@ } protected onInputMuteClicked(): void { - // TODO(b/260277007): Remove condition when setInputMuted added to mojo - // definition. - if (!this.crosAudioConfig_.setInputMuted) { - return; - } this.crosAudioConfig_.setInputMuted(!this.isInputMuted_); } /** Handles updating active input device. */ protected onInputDeviceChanged(): void { - // TODO(b/260277007): Remove condition when setActiveDevice added to mojo - // definition. - if (!this.crosAudioConfig_.setActiveDevice) { - return; - } const inputDeviceSelect = this.shadowRoot!.querySelector<HTMLSelectElement>( '#audioInputDeviceDropdown'); assert(!!inputDeviceSelect); @@ -217,11 +207,6 @@ /** Handles updating active output device. */ protected onOutputDeviceChanged(): void { - // TODO(b/260277007): Remove condition when setActiveDevice added to mojo - // definition. - if (!this.crosAudioConfig_.setActiveDevice) { - return; - } const outputDeviceSelect = this.shadowRoot!.querySelector<HTMLSelectElement>( '#audioOutputDeviceDropdown'); @@ -231,11 +216,6 @@ /** Handles updating outputMuteState. */ protected onOutputMuteButtonClicked(): void { - // TODO(b/260277007): Remove condition when setOutputMuted added to mojo - // definition. - if (!this.crosAudioConfig_.setOutputMuted) { - return; - } this.crosAudioConfig_.setOutputMuted(!this.isOutputMuted_); }
diff --git a/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard_subsection.html b/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard_subsection.html index 7acc52a..40c2347 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard_subsection.html +++ b/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard_subsection.html
@@ -29,7 +29,8 @@ class="hr" id="blockMetaFunctionKeyRewritesButton" pref="{{blockMetaFunctionKeyRewritesPref}}" label="$i18n{keyboardBlockMetaFunctionKeyRewrites}" - sub-label="$i18n{keyboardBlockMetaFunctionKeyRewritesDescription}"> + sub-label="$i18n{keyboardBlockMetaFunctionKeyRewritesDescription}" + deep-link-focus-id$="[[Setting.kKeyboardBlockMetaFkeyRewrites]]"> </settings-toggle-button> </template> <template is="dom-if" if="[[!keyboard.isExternal]]" restamp> @@ -44,6 +45,7 @@ <cr-link-row id="remapKeyboardKeys" class="hr" on-click="onRemapKeyboardKeysTap" label="$i18n{remapKeyboardKeysRowLabel}" - sub-label$="[[remapKeyboardKeysSublabel]]"> + sub-label$="[[remapKeyboardKeysSublabel]]" + deep-link-focus-id$="[[Setting.kKeyboardRemapKeys]]"> </cr-link-row> </div>
diff --git a/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard_subsection.ts b/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard_subsection.ts index 1cad52e1..ded9afb 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard_subsection.ts +++ b/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard_subsection.ts
@@ -91,6 +91,7 @@ type: Object, value: () => new Set<Setting>([ Setting.kKeyboardFunctionKeys, + Setting.kKeyboardRemapKeys, ]), }, @@ -118,6 +119,10 @@ return; } + if (this.keyboard.isExternal) { + this.supportedSettingIds.add(Setting.kKeyboardBlockMetaFkeyRewrites); + } + // If multiple keyboards are available, focus on the first one. if (this.keyboardIndex === 0) { this.attemptDeepLink();
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/text_to_speech_page.html b/chrome/browser/resources/settings/chromeos/os_a11y_page/text_to_speech_page.html index 7db683c..ccb82ad 100644 --- a/chrome/browser/resources/settings/chromeos/os_a11y_page/text_to_speech_page.html +++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/text_to_speech_page.html
@@ -81,7 +81,7 @@ class="hr" hidden$="[[!showPdfOcrToggle_]]" pref="{{prefs.settings.a11y.pdf_ocr_always_active}}" label="$i18n{pdfOcrTitle}" - sub-label="$i18n{pdfOcrSubtitle}"> + sub-label="[[getPdfOcrToggleSublabel_(pdfOcrStatus_, pdfOcrProgress_)]]"> </settings-toggle-button> <cr-link-row id="ttsSubpageButton" class="hr"
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/text_to_speech_page.ts b/chrome/browser/resources/settings/chromeos/os_a11y_page/text_to_speech_page.ts index f2e5e9175..cf7a2ae 100644 --- a/chrome/browser/resources/settings/chromeos/os_a11y_page/text_to_speech_page.ts +++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/text_to_speech_page.ts
@@ -28,6 +28,18 @@ import {getTemplate} from './text_to_speech_page.html.js'; import {TextToSpeechPageBrowserProxy, TextToSpeechPageBrowserProxyImpl} from './text_to_speech_page_browser_proxy.js'; +/** + * Numerical values should not be changed because they must stay in sync with + * screen_ai::ScreenAIInstallState::State defined in screen_ai_install_state.h + */ +export enum ScreenAiInstallStatus { + NOT_DOWNLOADED = 0, + DOWNLOADING = 1, + FAILED = 2, + DOWNLOADED = 3, + READY = 4, +} + const SettingsTextToSpeechPageElementBase = DeepLinkingMixin(RouteOriginMixin( PrefsMixin(WebUiListenerMixin(I18nMixin(PolymerElement))))); @@ -72,6 +84,17 @@ }, /** + * |pdfOcrProgress_| stores the downloading progress in percentage of + * the ScreenAI library. + */ + pdfOcrProgress_: Number, + + /** + * |pdfOcrStatus_| stores the ScreenAI library install state. + */ + pdfOcrStatus_: ScreenAiInstallStatus, + + /** * Whether to show the toggle button for PDF OCR. */ showPdfOcrToggle_: { @@ -98,6 +121,8 @@ private isAccessibilityChromeVoxPageMigrationEnabled_: boolean; private isAccessibilitySelectToSpeakPageMigrationEnabled_: boolean; private route_: Route; + private pdfOcrProgress_: number; + private pdfOcrStatus_: ScreenAiInstallStatus; private showPdfOcrToggle_: boolean; private textToSpeechBrowserProxy_: TextToSpeechPageBrowserProxy; @@ -120,6 +145,18 @@ 'has-hardware-keyboard', (hasKeyboard: boolean) => this.set('hasKeyboard_', hasKeyboard)); this.deviceBrowserProxy_.initializeKeyboardWatcher(); + + if (loadTimeData.getBoolean('pdfOcrEnabled')) { + this.addWebUiListener( + 'pdf-ocr-state-changed', + (pdfOcrState: ScreenAiInstallStatus) => + this.onPdfOcrStateChanged_(pdfOcrState)); + this.addWebUiListener( + 'pdf-ocr-downloading-progress-changed', + (progress: number) => + this.onPdfOcrDownloadingProgressChanged_(progress)); + this.textToSpeechBrowserProxy_.pdfOcrSectionReady(); + } } override ready() { @@ -130,6 +167,34 @@ this.addFocusConfig(routes.MANAGE_TTS_SETTINGS, '#ttsSubpageButton'); } + private getPdfOcrToggleSublabel_(): string { + switch (this.pdfOcrStatus_) { + case ScreenAiInstallStatus.DOWNLOADING: + return this.pdfOcrProgress_ > 0 && this.pdfOcrProgress_ < 100 ? + this.i18n('pdfOcrDownloadProgressLabel', this.pdfOcrProgress_) : + this.i18n('pdfOcrDownloadingLabel'); + case ScreenAiInstallStatus.FAILED: + return this.i18n('pdfOcrDownloadErrorLabel'); + case ScreenAiInstallStatus.DOWNLOADED: + return this.i18n('pdfOcrDownloadCompleteLabel'); + case ScreenAiInstallStatus.READY: + // No subtitle update in this case + case ScreenAiInstallStatus.NOT_DOWNLOADED: + // No subtitle update in this case + default: + // This is a generic subtitle describing the feature. + return this.i18n('pdfOcrSubtitle'); + } + } + + private onPdfOcrStateChanged_(pdfOcrState: ScreenAiInstallStatus) { + this.pdfOcrStatus_ = pdfOcrState; + } + + private onPdfOcrDownloadingProgressChanged_(progress: number) { + this.pdfOcrProgress_ = progress; + } + /** * Note: Overrides RouteOriginMixin implementation */
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/text_to_speech_page_browser_proxy.ts b/chrome/browser/resources/settings/chromeos/os_a11y_page/text_to_speech_page_browser_proxy.ts index f4b5dac..2cc42aec 100644 --- a/chrome/browser/resources/settings/chromeos/os_a11y_page/text_to_speech_page_browser_proxy.ts +++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/text_to_speech_page_browser_proxy.ts
@@ -4,6 +4,12 @@ export interface TextToSpeechPageBrowserProxy { /** + * Request whether ScreenAIInstallState changed. Result is returned by the + * 'pdf-ocr-state-changed' WebUI listener event. + */ + pdfOcrSectionReady(): void; + + /** * Opens the options page for Chrome Vox. */ showChromeVoxSettings(): void; @@ -31,6 +37,10 @@ instance = obj; } + pdfOcrSectionReady(): void { + chrome.send('pdfOcrSectionReady'); + } + showChromeVoxSettings(): void { chrome.send('showChromeVoxSettings'); }
diff --git a/chrome/browser/safe_browsing/tailored_security/chrome_tailored_security_service.cc b/chrome/browser/safe_browsing/tailored_security/chrome_tailored_security_service.cc index 62aaebc..5d8c4c37 100644 --- a/chrome/browser/safe_browsing/tailored_security/chrome_tailored_security_service.cc +++ b/chrome/browser/safe_browsing/tailored_security/chrome_tailored_security_service.cc
@@ -12,6 +12,7 @@ #include "components/prefs/pref_service.h" #include "components/safe_browsing/core/browser/tailored_security_service/tailored_security_notification_result.h" #include "components/safe_browsing/core/browser/tailored_security_service/tailored_security_service_util.h" +#include "components/safe_browsing/core/common/features.h" #include "components/safe_browsing/core/common/safe_browsing_policy_handler.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" #include "components/signin/public/identity_manager/identity_manager.h" @@ -21,6 +22,8 @@ #if BUILDFLAG(IS_ANDROID) #include "chrome/browser/ui/android/tab_model/tab_model.h" #include "chrome/browser/ui/android/tab_model/tab_model_list.h" +#include "chrome/browser/ui/android/tab_model/tab_model_observer.h" +#include "components/safe_browsing/core/browser/tailored_security_service/tailored_security_service.h" #else #include "chrome/browser/safe_browsing/tailored_security/notification_handler_desktop.h" #include "chrome/browser/ui/browser.h" @@ -34,14 +37,16 @@ #if BUILDFLAG(IS_ANDROID) content::WebContents* GetWebContentsForProfile(Profile* profile) { for (const TabModel* tab_model : TabModelList::models()) { - if (tab_model->GetProfile() != profile) + if (tab_model->GetProfile() != profile) { continue; + } int tab_count = tab_model->GetTabCount(); for (int i = 0; i < tab_count; i++) { content::WebContents* web_contents = tab_model->GetWebContentsAt(i); - if (web_contents) + if (web_contents) { return web_contents; + } } } return nullptr; @@ -59,6 +64,12 @@ ChromeTailoredSecurityService::~ChromeTailoredSecurityService() { RemoveObserver(this); +#if BUILDFLAG(IS_ANDROID) + TabModelList::RemoveObserver(this); + if (observed_tab_model_) { + observed_tab_model_->RemoveObserver(this); + } +#endif } void ChromeTailoredSecurityService::OnSyncNotificationMessageRequest( @@ -66,6 +77,11 @@ #if BUILDFLAG(IS_ANDROID) content::WebContents* web_contents = GetWebContentsForProfile(profile_); if (!web_contents) { + if (base::FeatureList::IsEnabled( + safe_browsing::kTailoredSecurityObserverRetries)) { + AddTabModelListObserver(); + return; + } if (is_enabled) { RecordEnabledNotificationResult( TailoredSecurityNotificationResult::kNoWebContentsAvailable); @@ -78,7 +94,6 @@ is_enabled ? SafeBrowsingState::ENHANCED_PROTECTION : SafeBrowsingState::STANDARD_PROTECTION, /*is_esb_enabled_in_sync=*/is_enabled); - message_ = std::make_unique<TailoredSecurityConsentedModalAndroid>( web_contents, is_enabled, base::BindOnce(&ChromeTailoredSecurityService::MessageDismissed, @@ -110,6 +125,62 @@ } } +#if BUILDFLAG(IS_ANDROID) +void ChromeTailoredSecurityService::DidAddTab(TabAndroid* tab, + TabModel::TabLaunchType type) { + if (observed_tab_model_) { + observed_tab_model_->RemoveObserver(this); + observed_tab_model_ = nullptr; + } + + TailoredSecurityTimestampUpdateCallback(); +} + +void ChromeTailoredSecurityService::AddTabModelListObserver() { + TabModelList::AddObserver(this); +} + +void ChromeTailoredSecurityService::OnTabModelAdded() { + if (AddTabModelObserver()) { + TabModelList::RemoveObserver(this); + } +} + +void ChromeTailoredSecurityService::OnTabModelRemoved() { + if (!observed_tab_model_) { + return; + } + + for (const TabModel* remaining_model : TabModelList::models()) { + // We want to make sure our tab model is still not in the + // tab model list, because we don't want to delete it + // prematurely + if (observed_tab_model_ == remaining_model) { + return; + } + } + observed_tab_model_ = nullptr; +} + +bool ChromeTailoredSecurityService::AddTabModelObserver() { + for (TabModel* tab_model : TabModelList::models()) { + if (tab_model->GetProfile() != profile_) { + continue; + } + tab_model->AddObserver(this); + // Saving the tab_model so we can stop observing the tab + // model after we start a new tailored security logic sequence. + observed_tab_model_ = tab_model; + return true; + } + return false; +} + +void ChromeTailoredSecurityService::MessageDismissed() { + message_.reset(); +} +#endif + #if !BUILDFLAG(IS_ANDROID) void ChromeTailoredSecurityService::DisplayDesktopDialog( Browser* browser, @@ -122,12 +193,6 @@ } #endif -#if BUILDFLAG(IS_ANDROID) -void ChromeTailoredSecurityService::MessageDismissed() { - message_.reset(); -} -#endif - scoped_refptr<network::SharedURLLoaderFactory> ChromeTailoredSecurityService::GetURLLoaderFactory() { return profile_->GetDefaultStoragePartition()
diff --git a/chrome/browser/safe_browsing/tailored_security/chrome_tailored_security_service.h b/chrome/browser/safe_browsing/tailored_security/chrome_tailored_security_service.h index d1cbbea..eae03d6 100644 --- a/chrome/browser/safe_browsing/tailored_security/chrome_tailored_security_service.h +++ b/chrome/browser/safe_browsing/tailored_security/chrome_tailored_security_service.h
@@ -12,6 +12,8 @@ #if BUILDFLAG(IS_ANDROID) #include "chrome/browser/safe_browsing/tailored_security/consented_message_android.h" +#include "chrome/browser/ui/android/tab_model/tab_model_list_observer.h" +#include "chrome/browser/ui/android/tab_model/tab_model_observer.h" #else #include "chrome/browser/ui/views/safe_browsing/tailored_security_desktop_dialog_manager.h" #endif @@ -21,20 +23,34 @@ namespace safe_browsing { +#if BUILDFLAG(IS_ANDROID) class ChromeTailoredSecurityService : public TailoredSecurityService, - public TailoredSecurityServiceObserver { + public TailoredSecurityServiceObserver, + public TabModelObserver, + public TabModelListObserver +#else +class ChromeTailoredSecurityService : public TailoredSecurityService, + public TailoredSecurityServiceObserver +#endif +{ public: explicit ChromeTailoredSecurityService(Profile* profile); ~ChromeTailoredSecurityService() override; - // TailoredSecurityServiceObserver. void OnSyncNotificationMessageRequest(bool is_enabled) override; +#if BUILDFLAG(IS_ANDROID) + // TabModelObserver:: + void DidAddTab(TabAndroid* tab, TabModel::TabLaunchType type) override; + // TabModelListObserver:: + void OnTabModelAdded() override; + void OnTabModelRemoved() override; +#endif protected: #if !BUILDFLAG(IS_ANDROID) // Shows a dialog on the provided `browser`. If `show_enable_dialog` is - // true, display the enabled dialog; otherwise show the disabled dialog. This - // method is virtual to support testing. + // true, display the enabled dialog; otherwise show the disabled dialog. + // This method is virtual to support testing. virtual void DisplayDesktopDialog(Browser* browser, bool show_enable_dialog); #endif @@ -44,11 +60,16 @@ #if BUILDFLAG(IS_ANDROID) void MessageDismissed(); + void AddTabModelListObserver(); + bool AddTabModelObserver(); + // This tab model is used for the observer based retry mechanism. + // We can't depend on this being set as a tab can be deleted at + // any time. + raw_ptr<TabModel> observed_tab_model_ = nullptr; std::unique_ptr<TailoredSecurityConsentedModalAndroid> message_; #else TailoredSecurityDesktopDialogManager dialog_manager_; #endif - raw_ptr<Profile> profile_; };
diff --git a/chrome/browser/safe_browsing/tailored_security/chrome_tailored_security_service_android_unittest.cc b/chrome/browser/safe_browsing/tailored_security/chrome_tailored_security_service_android_unittest.cc new file mode 100644 index 0000000..917ac544 --- /dev/null +++ b/chrome/browser/safe_browsing/tailored_security/chrome_tailored_security_service_android_unittest.cc
@@ -0,0 +1,214 @@ +// 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/safe_browsing/tailored_security/chrome_tailored_security_service.h" + +#include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_feature_list.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/ui/android/tab_model/tab_model.h" +#include "chrome/browser/ui/android/tab_model/tab_model_list.h" +#include "chrome/browser/ui/android/tab_model/tab_model_observer.h" +#include "chrome/test/base/testing_browser_process.h" +#include "chrome/test/base/testing_profile.h" +#include "components/messages/android/mock_message_dispatcher_bridge.h" +#include "components/safe_browsing/core/browser/tailored_security_service/tailored_security_notification_result.h" +#include "components/safe_browsing/core/common/features.h" +#include "content/public/browser/web_contents.h" +#include "content/public/test/browser_task_environment.h" +#include "content/public/test/web_contents_tester.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +// Names for Tailored Security status to make the test cases clearer. +const bool kTailoredSecurityEnabled = true; + +namespace { +// Test implementation of ChromeTailoredSecurityService. +class TestChromeTailoredSecurityService + : public safe_browsing::ChromeTailoredSecurityService { + public: + explicit TestChromeTailoredSecurityService(Profile* profile) + : ChromeTailoredSecurityService(profile) {} + ~TestChromeTailoredSecurityService() override = default; + + // We are overriding this method because we don't want to test + // the calls to the History API + void TailoredSecurityTimestampUpdateCallback() override { + ChromeTailoredSecurityService::OnSyncNotificationMessageRequest( + kTailoredSecurityEnabled); + } +}; +} // namespace + +class ChromeTailoredSecurityServiceTest : public testing::Test { + public: + ChromeTailoredSecurityServiceTest() = default; + + TestingProfile* getProfile() { return &profile_; } + + void SetUp() override { + browser_process_ = TestingBrowserProcess::GetGlobal(); + chrome_tailored_security_service_ = + std::make_unique<TestChromeTailoredSecurityService>(&profile_); + // message_dispatcher_bridge_.SetMessagesEnabledForEmbedder(true); + messages::MessageDispatcherBridge::SetInstanceForTesting( + &message_dispatcher_bridge_); + } + + void TearDown() override { + // Remove all tabs so testing state doesn't get affected + for (TabModel* tab : TabModelList::models()) { + TabModelList::RemoveTabModel(tab); + } + messages::MessageDispatcherBridge::SetInstanceForTesting(nullptr); + chrome_tailored_security_service_->Shutdown(); + chrome_tailored_security_service_.reset(); + } + + TestChromeTailoredSecurityService* tailored_security_service() { + return chrome_tailored_security_service_.get(); + } + + protected: + content::BrowserTaskEnvironment task_environment_; + raw_ptr<TestingBrowserProcess> browser_process_; + TestingProfile profile_; + std::unique_ptr<TestChromeTailoredSecurityService> + chrome_tailored_security_service_; + base::HistogramTester histograms_; + messages::MockMessageDispatcherBridge message_dispatcher_bridge_; + base::test::ScopedFeatureList feature_list; +}; + +class TestTabModel : public TabModel { + public: + explicit TestTabModel(TestingProfile* profile) + : TabModel(profile, chrome::android::ActivityType::kCustomTab), + profile_(profile), + tab_count_() {} + + int GetTabCount() const override { return tab_count_; } + int GetActiveIndex() const override { return 0; } + void SetWebContents(content::WebContents* webcontents) { + web_contents_ = webcontents; + } + content::WebContents* GetWebContentsAt(int index) const override { + return web_contents_; + } + base::android::ScopedJavaLocalRef<jobject> GetJavaObject() const override { + return nullptr; + } + + void SetProfile(TestingProfile* profile) { profile_ = profile; } + + Profile* GetProfile() const override { return profile_; } + + void CreateTab(TabAndroid* parent, + content::WebContents* web_contents) override {} + void HandlePopupNavigation(TabAndroid* parent, + NavigateParams* params) override {} + content::WebContents* CreateNewTabForDevTools(const GURL& url) override { + return nullptr; + } + bool IsSessionRestoreInProgress() const override { return false; } + bool IsActiveModel() const override { return false; } + TabAndroid* GetTabAt(int index) const override { return nullptr; } + void SetActiveIndex(int index) override {} + void CloseTabAt(int index) override {} + void AddObserver(TabModelObserver* observer) override { + observer_ = observer; + } + void RemoveObserver(TabModelObserver* observer) override {} + + TabModelObserver* observer_; + TestingProfile* profile_; + // A fake value for the current number of tabs. + int tab_count_{0}; + content::WebContents* web_contents_; +}; + +TEST_F(ChromeTailoredSecurityServiceTest, + RetryDisabledWithNoTabsLogsNoWebContents) { + feature_list.InitAndDisableFeature( + safe_browsing::kTailoredSecurityObserverRetries); + + for (TabModel* tab : TabModelList::models()) { + TabModelList::RemoveTabModel(tab); + } + + EXPECT_EQ(TabModelList::models().size(), 0U); + + chrome_tailored_security_service_->OnSyncNotificationMessageRequest( + kTailoredSecurityEnabled); + histograms_.ExpectBucketCount( + "SafeBrowsing.TailoredSecurity.SyncPromptEnabledNotificationResult2", + TailoredSecurityNotificationResult::kNoWebContentsAvailable, 1); +} + +TEST_F(ChromeTailoredSecurityServiceTest, WhenATabIsAvailableShowsTheMessage) { + TestTabModel tab_model(getProfile()); + TabModelList::AddTabModel(&tab_model); + + std::unique_ptr<content::WebContents> web_contents( + content::WebContentsTester::CreateTestWebContents(getProfile(), nullptr)); + content::WebContents* raw_contents = web_contents.get(); + tab_model.SetWebContents(raw_contents); + tab_model.tab_count_ = 1; + + EXPECT_CALL(message_dispatcher_bridge_, EnqueueWindowScopedMessage); + chrome_tailored_security_service_->OnSyncNotificationMessageRequest( + kTailoredSecurityEnabled); + histograms_.ExpectBucketCount( + "SafeBrowsing.TailoredSecurity.SyncPromptEnabledNotificationResult2", + TailoredSecurityNotificationResult::kShown, 1); +} + +TEST_F(ChromeTailoredSecurityServiceTest, + RetryEnabledWithNoTabsDoesNotLogWebContents) { + feature_list.InitAndEnableFeature( + safe_browsing::kTailoredSecurityObserverRetries); + + EXPECT_EQ(TabModelList::models().size(), 0U); + + chrome_tailored_security_service_->OnSyncNotificationMessageRequest( + kTailoredSecurityEnabled); + histograms_.ExpectBucketCount( + "SafeBrowsing.TailoredSecurity.SyncPromptEnabledNotificationResult2", + TailoredSecurityNotificationResult::kNoWebContentsAvailable, 0); +} + +TEST_F(ChromeTailoredSecurityServiceTest, + RetryEnabledWithNoTabsThenCallOnSyncThenAddTabLogsThatMessageWasShown) { + feature_list.InitAndEnableFeature( + safe_browsing::kTailoredSecurityObserverRetries); + + // Call OnSync method while there are no tabs + EXPECT_EQ(TabModelList::models().size(), 0U); + tailored_security_service()->TailoredSecurityTimestampUpdateCallback(); + histograms_.ExpectBucketCount( + "SafeBrowsing.TailoredSecurity.SyncPromptEnabledNotificationResult2", + TailoredSecurityNotificationResult::kShown, 0); + + // Add a tab and set the web contents + TestTabModel tab_model(getProfile()); + TabModelList::AddTabModel(&tab_model); + + std::unique_ptr<content::WebContents> web_contents( + content::WebContentsTester::CreateTestWebContents(getProfile(), nullptr)); + content::WebContents* raw_contents = web_contents.get(); + tab_model.SetWebContents(raw_contents); + tab_model.tab_count_ = 1; + + EXPECT_CALL(message_dispatcher_bridge_, EnqueueWindowScopedMessage); + // Simulate observers being notified after a tab is added. + tab_model.observer_->DidAddTab(nullptr, TabModel::TabLaunchType::FROM_LINK); + + histograms_.ExpectBucketCount( + "SafeBrowsing.TailoredSecurity.SyncPromptEnabledNotificationResult2", + TailoredSecurityNotificationResult::kShown, 1); +} + +} // namespace
diff --git a/chrome/browser/search/search_unittest.cc b/chrome/browser/search/search_unittest.cc index 818b1d9a..73a5d57 100644 --- a/chrome/browser/search/search_unittest.cc +++ b/chrome/browser/search/search_unittest.cc
@@ -106,9 +106,9 @@ // Each test case represents a navigation to |start_url| followed by a // navigation to |end_url|. We will check whether each navigation lands in an // Instant process, and also whether the navigation from start to end re-uses - // the same SiteInstance (and hence the same RenderViewHost, etc.). + // the same SiteInstance, RenderViewHost, etc. // Note that we need to define this here because the flags needed to check - // content::CanSameSiteMainFrameNavigationsChangeSiteInstances() might not + // content::CanSameSiteMainFrameNavigationsChangeSiteInstances() etc might not // be set yet if we define this immediately (e.g. outside of the test class). const struct ProcessIsolationTestCase { const char* description; @@ -117,23 +117,21 @@ const char* end_url; bool end_in_instant_process; bool same_site_instance; + bool same_rvh; bool same_process; } kProcessIsolationTestCases[5] = { {"Remote NTP -> SRP", "https://foo.com/newtab", true, - "https://foo.com/url", false, false, false}, + "https://foo.com/url", false, false, false, false}, {"Remote NTP -> Regular", "https://foo.com/newtab", true, - "https://foo.com/other", false, false, false}, + "https://foo.com/other", false, false, false, false}, {"SRP -> SRP", "https://foo.com/url", false, "https://foo.com/url", false, - true, true}, - // Same-site (but not same URL) navigations might switch site instances - // but keep the same process when ProactivelySwapBrowsingInstance is - // enabled on same-site navigations. + true, !content::WillSameSiteNavigationsChangeRenderFrameHosts(), true}, {"SRP -> Regular", "https://foo.com/url", false, "https://foo.com/other", false, !content::CanSameSiteMainFrameNavigationsChangeSiteInstances(), - true}, + !content::CanSameSiteMainFrameNavigationsChangeSiteInstances(), true}, {"Regular -> SRP", "https://foo.com/other", false, "https://foo.com/url", false, !content::CanSameSiteMainFrameNavigationsChangeSiteInstances(), - true}, + !content::CanSameSiteMainFrameNavigationsChangeSiteInstances(), true}, }; // BrowserWithTestWindowTest: @@ -224,7 +222,7 @@ EXPECT_EQ(test.same_site_instance, start_site_instance.get() == contents->GetSiteInstance()) << test.description; - EXPECT_EQ(test.same_site_instance, + EXPECT_EQ(test.same_rvh, start_rvh == contents->GetPrimaryMainFrame()->GetRenderViewHost()) << test.description; EXPECT_EQ(test.same_process, @@ -263,7 +261,7 @@ EXPECT_EQ(test.same_site_instance, start_site_instance.get() == contents->GetSiteInstance()) << test.description; - EXPECT_EQ(test.same_site_instance, + EXPECT_EQ(test.same_rvh, start_rvh == contents->GetPrimaryMainFrame()->GetRenderViewHost()) << test.description; EXPECT_EQ(test.same_process,
diff --git a/chrome/browser/sessions/session_restore_browsertest.cc b/chrome/browser/sessions/session_restore_browsertest.cc index 884c4ecc..bb26b01 100644 --- a/chrome/browser/sessions/session_restore_browsertest.cc +++ b/chrome/browser/sessions/session_restore_browsertest.cc
@@ -2819,7 +2819,7 @@ content::ExecJs(old_tab, "window.open('about:blank', 'subframe');")); nav_observer.Wait(); } - EXPECT_EQ(subframe, ChildFrameAt(old_tab_main_frame.get(), 0)); + subframe = ChildFrameAt(old_tab_main_frame.get(), 0); EXPECT_EQ(GURL(url::kAboutBlankURL), subframe->GetLastCommittedURL()); EXPECT_EQ(a_origin, subframe->GetLastCommittedOrigin());
diff --git a/chrome/browser/sharing/sharing_ui_controller.cc b/chrome/browser/sharing/sharing_ui_controller.cc index 0104f3ca..dbc92b3 100644 --- a/chrome/browser/sharing/sharing_ui_controller.cc +++ b/chrome/browser/sharing/sharing_ui_controller.cc
@@ -62,7 +62,7 @@ case SharingSendMessageResult::kCommitTimeout: return l10n_util::GetStringFUTF16( IDS_BROWSER_SHARING_ERROR_DIALOG_TITLE_GENERIC_ERROR, - base::ToLowerASCII(GetContentType())); + GetContentType()); case SharingSendMessageResult::kSuccessful: case SharingSendMessageResult::kCancelled: @@ -74,7 +74,7 @@ case SharingSendMessageResult::kEncryptionError: return l10n_util::GetStringFUTF16( IDS_BROWSER_SHARING_ERROR_DIALOG_TITLE_INTERNAL_ERROR, - base::ToLowerASCII(GetContentType())); + GetContentType()); } }
diff --git a/chrome/browser/sharing/sharing_ui_controller.h b/chrome/browser/sharing/sharing_ui_controller.h index 9b9c0b67..31b0d30 100644 --- a/chrome/browser/sharing/sharing_ui_controller.h +++ b/chrome/browser/sharing/sharing_ui_controller.h
@@ -65,7 +65,9 @@ // Get the name of the feature to be used as a prefix for the metric name. virtual SharingFeatureName GetFeatureMetricsPrefix() const = 0; - // Describes the content type of shared data. + // Describes the content type of shared data. For most languages this + // will be lower case as it's intended to be put as a placeholder within + // a sentence. virtual std::u16string GetContentType() const = 0; // Returns the message to be shown in the body of error dialog based on // |send_result_|.
diff --git a/chrome/browser/tab/BUILD.gn b/chrome/browser/tab/BUILD.gn index 15317092..4acf4e8 100644 --- a/chrome/browser/tab/BUILD.gn +++ b/chrome/browser/tab/BUILD.gn
@@ -156,6 +156,7 @@ "java/src/org/chromium/chrome/browser/tab/TabAssociatedAppTest.java", "java/src/org/chromium/chrome/browser/tab/TabIdManagerTest.java", "java/src/org/chromium/chrome/browser/tab/TabStateAttributesTest.java", + "java/src/org/chromium/chrome/browser/tab/state/PriceDropMetricsLoggerTest.java", ] deps = [
diff --git a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/PriceDropMetricsLoggerTest.java b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/PriceDropMetricsLoggerTest.java new file mode 100644 index 0000000..c214ea1 --- /dev/null +++ b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/PriceDropMetricsLoggerTest.java
@@ -0,0 +1,163 @@ +// Copyright 2021 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.tab.state; + +import static org.mockito.Mockito.doReturn; + +import org.chromium.base.test.BaseRobolectricTestRunner; +import androidx.test.filters.SmallTest; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import org.chromium.base.test.util.HistogramWatcher; + +import java.util.concurrent.TimeUnit; + +/** + * Test relating to {@link PriceDropMetricsLogger} + */ +@RunWith(BaseRobolectricTestRunner.class) +public class PriceDropMetricsLoggerTest { + @Mock + private ShoppingPersistedTabData mShoppingPersistedTabData; + + private PriceDropMetricsLogger mPriceDropMetricsLogger; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + doReturn("offer-id").when(mShoppingPersistedTabData).getMainOfferId(); + doReturn(true).when(mShoppingPersistedTabData).hasPriceMicros(); + doReturn(true).when(mShoppingPersistedTabData).hasPreviousPriceMicros(); + mPriceDropMetricsLogger = new PriceDropMetricsLogger(mShoppingPersistedTabData); + } + + @SmallTest + @Test + public void testTabUsageStatus() { + Assert.assertEquals(PriceDropMetricsLogger.TabUsageStatus.ABANDONED, + PriceDropMetricsLogger.getTabUsageStatus(TimeUnit.DAYS.toMillis(100))); + Assert.assertEquals(PriceDropMetricsLogger.TabUsageStatus.ABANDONED, + PriceDropMetricsLogger.getTabUsageStatus(TimeUnit.DAYS.toMillis(90))); + Assert.assertEquals(PriceDropMetricsLogger.TabUsageStatus.STALE, + PriceDropMetricsLogger.getTabUsageStatus(TimeUnit.DAYS.toMillis(45))); + Assert.assertEquals(PriceDropMetricsLogger.TabUsageStatus.STALE, + PriceDropMetricsLogger.getTabUsageStatus(TimeUnit.DAYS.toMillis(1))); + Assert.assertEquals(PriceDropMetricsLogger.TabUsageStatus.ACTIVE, + PriceDropMetricsLogger.getTabUsageStatus(TimeUnit.HOURS.toMillis(12))); + } + + @SmallTest + @Test + public void testMetricsStaleTabNavigation() { + var histograms = + HistogramWatcher.newBuilder() + .expectAnyRecord( + "Commerce.PriceDrops.StaleTabNavigationComplete.IsProductDetailPage") + .expectAnyRecord( + "Commerce.PriceDrops.StaleTabNavigationComplete.ContainsPrice") + .expectAnyRecord( + "Commerce.PriceDrops.StaleTabNavigationComplete.ContainsPriceDrop") + .build(); + mPriceDropMetricsLogger.logPriceDropMetrics( + "NavigationComplete", TimeUnit.DAYS.toMillis(45)); + histograms.assertExpected(); + } + + @SmallTest + @Test + public void testMetrics2StaleTabEnterTabSwitcher() { + var histograms = + HistogramWatcher.newBuilder() + .expectAnyRecord( + "Commerce.PriceDrops.StaleTabEnterTabSwitcher.IsProductDetailPage") + .expectAnyRecord( + "Commerce.PriceDrops.StaleTabEnterTabSwitcher.ContainsPrice") + .expectAnyRecord( + "Commerce.PriceDrops.StaleTabEnterTabSwitcher.ContainsPriceDrop") + .build(); + mPriceDropMetricsLogger.logPriceDropMetrics("EnterTabSwitcher", TimeUnit.DAYS.toMillis(45)); + histograms.assertExpected(); + } + + @SmallTest + @Test + public void testMetricsActiveTabNavigationComplete() { + var histograms = + HistogramWatcher.newBuilder() + .expectAnyRecord( + "Commerce.PriceDrops.ActiveTabNavigationComplete.IsProductDetailPage") + .expectAnyRecord( + "Commerce.PriceDrops.ActiveTabNavigationComplete.ContainsPrice") + .expectAnyRecord( + "Commerce.PriceDrops.ActiveTabNavigationComplete.ContainsPriceDrop") + .build(); + mPriceDropMetricsLogger.logPriceDropMetrics( + "NavigationComplete", TimeUnit.HOURS.toMillis(12)); + histograms.assertExpected(); + } + + @SmallTest + @Test + public void testMetricsActiveTabEnterTabSwitcher() { + var histograms = + HistogramWatcher.newBuilder() + .expectAnyRecord( + "Commerce.PriceDrops.ActiveTabEnterTabSwitcher.IsProductDetailPage") + .expectAnyRecord( + "Commerce.PriceDrops.ActiveTabEnterTabSwitcher.ContainsPrice") + .expectAnyRecord( + "Commerce.PriceDrops.ActiveTabEnterTabSwitcher.ContainsPriceDrop") + .build(); + mPriceDropMetricsLogger.logPriceDropMetrics( + "EnterTabSwitcher", TimeUnit.HOURS.toMillis(12)); + histograms.assertExpected(); + } + + @SmallTest + @Test + public void testMetricsPriceNoPriceDrop() { + var histograms = + HistogramWatcher.newBuilder() + .expectAnyRecord( + "Commerce.PriceDrops.ActiveTabEnterTabSwitcher.IsProductDetailPage") + .expectAnyRecord( + "Commerce.PriceDrops.ActiveTabEnterTabSwitcher.ContainsPrice") + .expectAnyRecord( + "Commerce.PriceDrops.ActiveTabEnterTabSwitcher.ContainsPriceDrop") + .build(); + mPriceDropMetricsLogger.logPriceDropMetrics( + "EnterTabSwitcher", TimeUnit.HOURS.toMillis(12)); + histograms.assertExpected(); + } + + @SmallTest + @Test + public void testEmptyPriceDropResponse() { + doReturn(null).when(mShoppingPersistedTabData).getMainOfferId(); + doReturn(false).when(mShoppingPersistedTabData).hasPriceMicros(); + doReturn(false).when(mShoppingPersistedTabData).hasPreviousPriceMicros(); + var histograms = + HistogramWatcher.newBuilder() + .expectBooleanRecord( + "Commerce.PriceDrops.ActiveTabEnterTabSwitcher.IsProductDetailPage", + false) + .expectBooleanRecord( + "Commerce.PriceDrops.ActiveTabEnterTabSwitcher.ContainsPrice", + false) + .expectBooleanRecord( + "Commerce.PriceDrops.ActiveTabEnterTabSwitcher.ContainsPriceDrop", + false) + .build(); + mPriceDropMetricsLogger.logPriceDropMetrics( + "EnterTabSwitcher", TimeUnit.HOURS.toMillis(12)); + histograms.assertExpected(); + } +}
diff --git a/chrome/browser/tab_contents/view_source_browsertest.cc b/chrome/browser/tab_contents/view_source_browsertest.cc index 438886b..65bc6fa7 100644 --- a/chrome/browser/tab_contents/view_source_browsertest.cc +++ b/chrome/browser/tab_contents/view_source_browsertest.cc
@@ -545,6 +545,8 @@ EXPECT_TRUE(ExecuteScript(original_child_frame, "document.getElementById('form').submit();")); form_post_observer.Wait(); + original_child_frame = ChildFrameAt(original_contents, 0); + GURL target_url(embedded_test_server()->GetURL("b.com", "/echoall")); EXPECT_EQ(target_url, original_child_frame->GetLastCommittedURL());
diff --git a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillView.java b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillView.java index 76f264ba..af33ee7 100644 --- a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillView.java +++ b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillView.java
@@ -25,9 +25,6 @@ * Android Views. */ class TouchToFillView extends TouchToFillViewBase { - private final BottomSheetController mBottomSheetController; - private final RecyclerView mSheetItemListView; - private static class HorizontalDividerItemDecoration extends ItemDividerBase { HorizontalDividerItemDecoration(Context context) { super(context); @@ -76,17 +73,15 @@ super(bottomSheetController, (RelativeLayout) LayoutInflater.from(context).inflate( R.layout.touch_to_fill_sheet, null)); - mBottomSheetController = bottomSheetController; - mSheetItemListView = getItemList(); if (usesUnifiedPasswordManagerBranding()) { - mSheetItemListView.addItemDecoration(new HorizontalDividerItemDecoration(context)); + getSheetItemListView().addItemDecoration(new HorizontalDividerItemDecoration(context)); } } @Override public int getVerticalScrollOffset() { - return mSheetItemListView.computeVerticalScrollOffset(); + return getSheetItemListView().computeVerticalScrollOffset(); } @Override @@ -115,11 +110,6 @@ } @Override - protected RecyclerView getItemList() { - return getContentView().findViewById(R.id.sheet_item_list); - } - - @Override protected @Px int getConclusiveMarginHeightPx() { return getContentView().getResources().getDimensionPixelSize( usesUnifiedPasswordManagerBranding()
diff --git a/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewTest.java b/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewTest.java index 1a78cd61..acb6b6d5 100644 --- a/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewTest.java +++ b/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewTest.java
@@ -7,8 +7,10 @@ import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.verify; @@ -97,6 +99,7 @@ private PropertyModel mModel; private TouchToFillView mTouchToFillView; private BottomSheetController mBottomSheetController; + private BottomSheetTestSupport mSheetTestSupport; TouchToFillResourceProvider mResourceProvider; @Rule @@ -110,6 +113,7 @@ .getRootUiCoordinatorForTesting() .getBottomSheetController(); mResourceProvider = new TouchToFillResourceProviderImpl(); + mSheetTestSupport = new BottomSheetTestSupport(mBottomSheetController); TestThreadUtils.runOnUiThreadBlocking(() -> { mModel = TouchToFillProperties.createDefaultModel(mDismissHandler); mTouchToFillView = new TouchToFillView(getActivity(), mBottomSheetController); @@ -404,12 +408,10 @@ mModel.set(VISIBLE, true); }); BottomSheetTestSupport.waitForOpen(mBottomSheetController); - BottomSheetTestSupport sheetSupport = new BottomSheetTestSupport( - getActivity().getRootUiCoordinatorForTesting().getBottomSheetController()); // Swipe the sheet up to it's full state. TestThreadUtils.runOnUiThreadBlocking( - () -> { sheetSupport.setSheetState(SheetState.FULL, false); }); + () -> mSheetTestSupport.setSheetState(SheetState.FULL, false)); TextView manageButton = mTouchToFillView.getContentView().findViewById( R.id.touch_to_fill_sheet_manage_passwords); @@ -507,6 +509,30 @@ pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF); } + @Test + @MediumTest + public void testSheetScrollabilityDependsOnState() { + TestThreadUtils.runOnUiThreadBlocking(() -> { + mModel.get(SHEET_ITEMS).add(buildCredentialItem(ANA)); + mModel.set(VISIBLE, true); + }); + BottomSheetTestSupport.waitForOpen(mBottomSheetController); + + // The sheet should be expanded to half height and suppress scrolling. + RecyclerView recyclerView = mTouchToFillView.getSheetItemListView(); + assertTrue(recyclerView.isLayoutSuppressed()); + + // Expand the sheet to the full height and scrolling . + TestThreadUtils.runOnUiThreadBlocking( + () + -> mSheetTestSupport.setSheetState( + BottomSheetController.SheetState.FULL, false)); + BottomSheetTestSupport.waitForState( + mBottomSheetController, BottomSheetController.SheetState.FULL); + + assertFalse(recyclerView.isLayoutSuppressed()); + } + private ChromeActivity getActivity() { return mActivityTestRule.getActivity(); }
diff --git a/chrome/browser/touch_to_fill/common/android/BUILD.gn b/chrome/browser/touch_to_fill/common/android/BUILD.gn index 178e103..3b9307e 100644 --- a/chrome/browser/touch_to_fill/common/android/BUILD.gn +++ b/chrome/browser/touch_to_fill/common/android/BUILD.gn
@@ -22,6 +22,7 @@ deps = [ ":java_resources", "//base:base_java", + "//chrome/browser/autofill/android:bottom_sheet_utils_java", "//chrome/browser/tab:java", "//chrome/browser/tabmodel:java", "//chrome/browser/util:java",
diff --git a/chrome/browser/touch_to_fill/common/android/java/src/org/chromium/chrome/browser/touch_to_fill/common/TouchToFillViewBase.java b/chrome/browser/touch_to_fill/common/android/java/src/org/chromium/chrome/browser/touch_to_fill/common/TouchToFillViewBase.java index 84f1f4bd..8ce138de 100644 --- a/chrome/browser/touch_to_fill/common/android/java/src/org/chromium/chrome/browser/touch_to_fill/common/TouchToFillViewBase.java +++ b/chrome/browser/touch_to_fill/common/android/java/src/org/chromium/chrome/browser/touch_to_fill/common/TouchToFillViewBase.java
@@ -12,10 +12,12 @@ import androidx.annotation.Nullable; import androidx.annotation.Px; +import androidx.annotation.VisibleForTesting; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import org.chromium.base.Callback; +import org.chromium.chrome.browser.autofill.bottom_sheet_utils.DetailScreenScrollListener; import org.chromium.chrome.browser.util.ChromeAccessibilityUtil; import org.chromium.components.browser_ui.bottomsheet.BottomSheetContent; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; @@ -23,7 +25,6 @@ import org.chromium.components.browser_ui.bottomsheet.EmptyBottomSheetObserver; import org.chromium.ui.base.LocalizationUtils; import org.chromium.ui.base.ViewUtils; - /** * This is a base class for the Touch to Fill View classes. */ @@ -32,8 +33,9 @@ private final BottomSheetController mBottomSheetController; private final RelativeLayout mContentView; - private final RecyclerView mSheetItemListView; + private final DetailScreenScrollListener mScrollListener; private Callback<Integer> mDismissHandler; + private RecyclerView mSheetItemListView; private final BottomSheetObserver mBottomSheetObserver = new EmptyBottomSheetObserver() { @Override @@ -47,6 +49,16 @@ @Override public void onSheetStateChanged(int newState, int reason) { super.onSheetStateChanged(newState, reason); + if (newState == BottomSheetController.SheetState.FULL) { + // The list of items should be scrollable in full state. + mSheetItemListView.suppressLayout(false); + } else if (newState == BottomSheetController.SheetState.HALF + && mScrollListener.isScrolledToTop()) { + // The list of items should not be scrollable when the sheet transitions into half + // state if it's scrolled to the top. If the list is currently scrolled away from + // the top, it should stay scrolled in half state until the user scrolls to the top. + mSheetItemListView.suppressLayout(true); + } if (newState != BottomSheetController.SheetState.HIDDEN) return; // This is a fail-safe for cases where onSheetClosed isn't triggered. mDismissHandler.onResult(BottomSheetController.StateChangeReason.NONE); @@ -61,12 +73,6 @@ protected abstract View getHandlebar(); /** - * Used to access the list of suggestions to measure it. - * @return the {@link RecyclerView} containing the suggestions in the {@link BottomSheet}. - */ - protected abstract RecyclerView getItemList(); - - /** * Returns the margin between the last item in the scrollable list and the footer. * @return the margin size in pixels. */ @@ -94,7 +100,7 @@ BottomSheetController bottomSheetController, RelativeLayout contentView) { mBottomSheetController = bottomSheetController; mContentView = contentView; - mSheetItemListView = getItemList(); + mSheetItemListView = getContentView().findViewById(R.id.sheet_item_list); mSheetItemListView.setLayoutManager(new LinearLayoutManager( mSheetItemListView.getContext(), LinearLayoutManager.VERTICAL, false) { @@ -108,6 +114,9 @@ int layoutDirection = LocalizationUtils.isLayoutRtl() ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR; mContentView.setLayoutDirection(layoutDirection); + + mScrollListener = new DetailScreenScrollListener(mBottomSheetController); + mSheetItemListView.addOnScrollListener(mScrollListener); } @Override @@ -317,4 +326,9 @@ public void destroy() { mBottomSheetController.removeObserver(mBottomSheetObserver); } + + @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED) + public RecyclerView getSheetItemListView() { + return mSheetItemListView; + } }
diff --git a/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardControllerRobolectricTest.java b/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardControllerRobolectricTest.java index ff76dd6..e3cbab8 100644 --- a/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardControllerRobolectricTest.java +++ b/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardControllerRobolectricTest.java
@@ -27,6 +27,7 @@ import static org.chromium.chrome.browser.touch_to_fill.payments.TouchToFillCreditCardProperties.FooterProperties.SHOW_CREDIT_CARD_SETTINGS_CALLBACK; import static org.chromium.chrome.browser.touch_to_fill.payments.TouchToFillCreditCardProperties.ItemType.CREDIT_CARD; import static org.chromium.chrome.browser.touch_to_fill.payments.TouchToFillCreditCardProperties.ItemType.FILL_BUTTON; +import static org.chromium.chrome.browser.touch_to_fill.payments.TouchToFillCreditCardProperties.ItemType.FOOTER; import static org.chromium.chrome.browser.touch_to_fill.payments.TouchToFillCreditCardProperties.ItemType.HEADER; import static org.chromium.chrome.browser.touch_to_fill.payments.TouchToFillCreditCardProperties.SHEET_ITEMS; import static org.chromium.chrome.browser.touch_to_fill.payments.TouchToFillCreditCardProperties.VISIBLE; @@ -267,6 +268,32 @@ TOUCH_TO_FILL_OUTCOME_HISTOGRAM, TouchToFillCreditCardOutcome.DISMISS)); } + @Test + public void testScanNewCardClick() { + mCoordinator.showSheet(new CreditCard[] {VISA, MASTER_CARD}, true); + ModelList itemList = mTouchToFillCreditCardModel.get(SHEET_ITEMS); + getModelsOfType(itemList, FOOTER).get(0).get(SCAN_CREDIT_CARD_CALLBACK).run(); + + verify(mDelegateMock).scanCreditCard(); + } + + @Test + public void testManagePaymentMethodsClick() { + mCoordinator.showSheet(new CreditCard[] {VISA, MASTER_CARD}, false); + ModelList itemList = mTouchToFillCreditCardModel.get(SHEET_ITEMS); + getModelsOfType(itemList, FOOTER).get(0).get(SHOW_CREDIT_CARD_SETTINGS_CALLBACK).run(); + + verify(mDelegateMock).showCreditCardSettings(); + } + + @Test + public void testContinueButtonClick() { + mCoordinator.showSheet(new CreditCard[] {VISA}, false); + ModelList itemList = mTouchToFillCreditCardModel.get(SHEET_ITEMS); + getModelsOfType(itemList, FILL_BUTTON).get(0).get(ON_CLICK_ACTION).run(); + verify(mDelegateMock).suggestionSelected(VISA.getGUID(), VISA.getIsVirtual()); + } + private static List<PropertyModel> getModelsOfType(ModelList items, int type) { return StreamSupport.stream(items.spliterator(), false) .filter(item -> item.type == type)
diff --git a/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardCoordinator.java b/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardCoordinator.java index ae264a8..38e632a 100644 --- a/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardCoordinator.java +++ b/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardCoordinator.java
@@ -37,7 +37,6 @@ TouchToFillCreditCardComponent.Delegate delegate, BottomSheetFocusHelper bottomSheetFocusHelper) { mTouchToFillCreditCardModel = createModel(mMediator); - mMediator.initialize( context, delegate, mTouchToFillCreditCardModel, bottomSheetFocusHelper); setUpModelChangeProcessors(mTouchToFillCreditCardModel,
diff --git a/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardRenderTest.java b/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardRenderTest.java index 9b88f619..31013e2c 100644 --- a/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardRenderTest.java +++ b/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardRenderTest.java
@@ -263,4 +263,16 @@ mRenderTestRule.render(bottomSheetView, "touch_to_fill_credit_card_sheet_shows_local_and_server_and_virtual_cards"); } + + @Test + @MediumTest + @Feature({"RenderTest"}) + public void testScanNewCardButtonIsHidden() throws IOException { + runOnUiThreadBlocking(() -> { mCoordinator.showSheet(new CreditCard[] {VISA}, false); }); + BottomSheetTestSupport.waitForOpen(mBottomSheetController); + + View bottomSheetView = mActivityTestRule.getActivity().findViewById(R.id.bottom_sheet); + mRenderTestRule.render( + bottomSheetView, "touch_to_fill_credit_card_sheet_scan_credit_card_hidden"); + } }
diff --git a/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardView.java b/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardView.java index 1fa85e3..6cbc64d 100644 --- a/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardView.java +++ b/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardView.java
@@ -23,10 +23,6 @@ * but holds Android Views. */ class TouchToFillCreditCardView extends TouchToFillViewBase { - private final BottomSheetController mBottomSheetController; - private final RecyclerView mSheetItemListView; - private Runnable mScanCreditCardHandler; - private static class HorizontalDividerItemDecoration extends ItemDividerBase { HorizontalDividerItemDecoration(Context context) { super(context); @@ -71,15 +67,13 @@ super(bottomSheetController, (RelativeLayout) LayoutInflater.from(context).inflate( R.layout.touch_to_fill_sheet, null)); - mBottomSheetController = bottomSheetController; - mSheetItemListView = getItemList(); - mSheetItemListView.addItemDecoration(new HorizontalDividerItemDecoration(context)); + getSheetItemListView().addItemDecoration(new HorizontalDividerItemDecoration(context)); } @Override public int getVerticalScrollOffset() { - return mSheetItemListView.computeVerticalScrollOffset(); + return getSheetItemListView().computeVerticalScrollOffset(); } @Override @@ -108,11 +102,6 @@ } @Override - protected RecyclerView getItemList() { - return getContentView().findViewById(R.id.sheet_item_list); - } - - @Override protected int getConclusiveMarginHeightPx() { return getContentView().getResources().getDimensionPixelSize(R.dimen.ttf_sheet_padding); }
diff --git a/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardViewTest.java b/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardViewTest.java index 18a43d2..66ac114 100644 --- a/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardViewTest.java +++ b/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardViewTest.java
@@ -4,16 +4,10 @@ package org.chromium.chrome.browser.touch_to_fill.payments; -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.action.ViewActions.click; -import static androidx.test.espresso.assertion.ViewAssertions.matches; -import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; -import static androidx.test.espresso.matcher.ViewMatchers.withId; - import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.verify; +import static org.junit.Assert.assertTrue; import static org.chromium.base.test.util.CriteriaHelper.pollUiThread; import static org.chromium.chrome.browser.autofill.AutofillTestHelper.createLocalCreditCard; @@ -45,7 +39,6 @@ import org.chromium.base.test.util.DoNotBatch; import org.chromium.chrome.browser.autofill.PersonalDataManager.CreditCard; import org.chromium.chrome.browser.flags.ChromeSwitches; -import org.chromium.chrome.browser.touch_to_fill.common.BottomSheetFocusHelper; import org.chromium.chrome.browser.util.ChromeAccessibilityUtil; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; @@ -77,15 +70,10 @@ public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule(); @Mock - private TouchToFillCreditCardComponent.Delegate mDelegateMock; - @Mock private Callback<Integer> mDismissCallback; - @Mock - private BottomSheetFocusHelper mBottomSheetFocusHelper; private BottomSheetController mBottomSheetController; - private BottomSheetTestSupport mSheetSupport; - private TouchToFillCreditCardCoordinator mCoordinator; + private BottomSheetTestSupport mSheetTestSupport; private TouchToFillCreditCardView mTouchToFillCreditCardView; private PropertyModel mTouchToFillCreditCardModel; @@ -96,11 +84,8 @@ mBottomSheetController = mActivityTestRule.getActivity() .getRootUiCoordinatorForTesting() .getBottomSheetController(); - mSheetSupport = new BottomSheetTestSupport(mBottomSheetController); + mSheetTestSupport = new BottomSheetTestSupport(mBottomSheetController); runOnUiThreadBlocking(() -> { - mCoordinator = new TouchToFillCreditCardCoordinator(); - mCoordinator.initialize(mActivityTestRule.getActivity(), mBottomSheetController, - mDelegateMock, mBottomSheetFocusHelper); mTouchToFillCreditCardModel = new PropertyModel.Builder(TouchToFillCreditCardProperties.ALL_KEYS) .with(VISIBLE, false) @@ -170,55 +155,6 @@ @Test @MediumTest - public void testScanNewCardButtonIsHidden() { - runOnUiThreadBlocking( - () -> mCoordinator.showSheet(new CreditCard[] {VISA, MASTER_CARD}, false)); - BottomSheetTestSupport.waitForOpen(mBottomSheetController); - runOnUiThreadBlocking(() -> { mSheetSupport.setSheetState(SheetState.FULL, false); }); - - onView(withId(R.id.scan_new_card)).check(matches(not(isDisplayed()))); - } - - @Test - @MediumTest - public void testScanNewCardClick() { - runOnUiThreadBlocking( - () -> mCoordinator.showSheet(new CreditCard[] {VISA, MASTER_CARD}, true)); - BottomSheetTestSupport.waitForOpen(mBottomSheetController); - runOnUiThreadBlocking(() -> { mSheetSupport.setSheetState(SheetState.FULL, false); }); - - onView(withId(R.id.scan_new_card)).perform(click()); - - verify(mDelegateMock).scanCreditCard(); - } - - @Test - @MediumTest - public void testManagePaymentMethodsClick() { - runOnUiThreadBlocking( - () -> mCoordinator.showSheet(new CreditCard[] {VISA, MASTER_CARD}, true)); - BottomSheetTestSupport.waitForOpen(mBottomSheetController); - runOnUiThreadBlocking(() -> mSheetSupport.setSheetState(SheetState.FULL, false)); - - onView(withId(R.id.manage_payment_methods)).perform(click()); - - verify(mDelegateMock).showCreditCardSettings(); - } - - @Test - @MediumTest - public void testContinueButtonClick() { - runOnUiThreadBlocking(() -> mCoordinator.showSheet(new CreditCard[] {VISA}, true)); - BottomSheetTestSupport.waitForOpen(mBottomSheetController); - runOnUiThreadBlocking(() -> mSheetSupport.setSheetState(SheetState.FULL, false)); - - onView(withId(R.id.touch_to_fill_button_title)).perform(click()); - - verify(mDelegateMock).suggestionSelected(VISA.getGUID(), VISA.getIsVirtual()); - } - - @Test - @MediumTest public void testSheetStartsInFullHeightForAccessibility() { // Enabling the accessibility settings. runOnUiThreadBlocking(() -> { @@ -226,7 +162,11 @@ ChromeAccessibilityUtil.get().setTouchExplorationEnabledForTesting(true); }); - runOnUiThreadBlocking(() -> mCoordinator.showSheet(new CreditCard[] {VISA}, true)); + runOnUiThreadBlocking(() -> { + mTouchToFillCreditCardModel.get(SHEET_ITEMS) + .add(new ListItem(CREDIT_CARD, createCardModel(VISA))); + mTouchToFillCreditCardModel.set(VISIBLE, true); + }); BottomSheetTestSupport.waitForOpen(mBottomSheetController); // The sheet should be expanded to full height. @@ -242,13 +182,41 @@ @Test @MediumTest public void testSheetStartsInHalfHeightForAccessibilityDisabled() { - runOnUiThreadBlocking(() -> mCoordinator.showSheet(new CreditCard[] {VISA}, true)); + runOnUiThreadBlocking(() -> { + mTouchToFillCreditCardModel.get(SHEET_ITEMS) + .add(new ListItem(CREDIT_CARD, createCardModel(VISA))); + mTouchToFillCreditCardModel.set(VISIBLE, true); + }); BottomSheetTestSupport.waitForOpen(mBottomSheetController); // The sheet should be expanded to half height. pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF); } + @Test + @MediumTest + public void testSheetScrollabilityDependsOnState() { + runOnUiThreadBlocking(() -> { + mTouchToFillCreditCardModel.get(SHEET_ITEMS) + .add(new ListItem(CREDIT_CARD, createCardModel(VISA))); + mTouchToFillCreditCardModel.set(VISIBLE, true); + }); + BottomSheetTestSupport.waitForOpen(mBottomSheetController); + + // The sheet should be expanded to the half height and scrolling suppressed. + RecyclerView recyclerView = mTouchToFillCreditCardView.getSheetItemListView(); + assertTrue(recyclerView.isLayoutSuppressed()); + + // Expand the sheet to the full height and scrolling . + runOnUiThreadBlocking(() + -> mSheetTestSupport.setSheetState( + BottomSheetController.SheetState.FULL, false)); + BottomSheetTestSupport.waitForState( + mBottomSheetController, BottomSheetController.SheetState.FULL); + + assertFalse(recyclerView.isLayoutSuppressed()); + } + private RecyclerView getCreditCards() { return mTouchToFillCreditCardView.getContentView().findViewById(R.id.sheet_item_list); }
diff --git a/chrome/browser/touch_to_fill/payments/android/touch_to_fill_delegate_android_impl.cc b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_delegate_android_impl.cc index 3c6a6b80..4850cda 100644 --- a/chrome/browser/touch_to_fill/payments/android/touch_to_fill_delegate_android_impl.cc +++ b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_delegate_android_impl.cc
@@ -71,7 +71,7 @@ // Trigger only for complete forms (contining the fields for the card number // and the card expiration date). - if (!FormHasAllCreditCardFields(*form)) { + if (!FormHasAllEmtyCreditCardFields(*form)) { return {TriggerOutcome::kIncompleteForm, {}}; } // Trigger only if not shown before.
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 75458c8..63653ffe 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -3128,6 +3128,11 @@ "webui/settings/ash/os_settings_ui.h", "webui/settings/ash/parental_controls_handler.cc", "webui/settings/ash/parental_controls_handler.h", + + # TODO(crbug.com/1393069): Move to under `enable_screen_ai_service` when + # PDF OCR becomes available on windows, macOS, and linux. + "webui/settings/ash/pdf_ocr_handler.cc", + "webui/settings/ash/pdf_ocr_handler.h", "webui/settings/ash/people_section.cc", "webui/settings/ash/people_section.h", "webui/settings/ash/peripheral_data_access_handler.cc",
diff --git a/chrome/browser/ui/android/quickactionsearchwidget/BUILD.gn b/chrome/browser/ui/android/quickactionsearchwidget/BUILD.gn index db63880..dfa849b3 100644 --- a/chrome/browser/ui/android/quickactionsearchwidget/BUILD.gn +++ b/chrome/browser/ui/android/quickactionsearchwidget/BUILD.gn
@@ -54,7 +54,6 @@ sources = [ "java/res/drawable-nodpi/quick_action_search_widget_dino_preview.png", "java/res/drawable-nodpi/quick_action_search_widget_small_preview.png", - "java/res/drawable/ic_dino.xml", "java/res/drawable/quick_action_search_widget_background.xml", "java/res/drawable/quick_action_search_widget_dino_background.xml", "java/res/drawable/quick_action_search_widget_dino_content.xml",
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd index 21611d4..6404e11 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -4869,7 +4869,7 @@ </message> <!-- Sharing content types --> - <message name="IDS_BROWSER_SHARING_CONTENT_TYPE_TEXT" desc="The label used to describe that the content type being shared is a text."> + <message name="IDS_BROWSER_SHARING_CONTENT_TYPE_TEXT" desc="This will be used as a placeholder in the message 'Can't share [content type].' so it should be lower-case unless this is a language where nouns are upper case." meaning="text as placeholder"> text </message>
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_BROWSER_SHARING_CONTENT_TYPE_TEXT.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_BROWSER_SHARING_CONTENT_TYPE_TEXT.png.sha1 new file mode 100644 index 0000000..135af0d --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_BROWSER_SHARING_CONTENT_TYPE_TEXT.png.sha1
@@ -0,0 +1 @@ +8a35ef7feaed6fb5ab29fc7f80ac5982ceb48e5d
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ToolbarFeatures.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ToolbarFeatures.java index 70f44b2..c3c3f70 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ToolbarFeatures.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ToolbarFeatures.java
@@ -22,6 +22,8 @@ new MutableFlagWithSafeDefault(ChromeFeatureList.SUPPRESS_TOOLBAR_CAPTURES, false); private static final MutableFlagWithSafeDefault sRecordSuppressionMetrics = new MutableFlagWithSafeDefault(ChromeFeatureList.RECORD_SUPPRESSION_METRICS, true); + private static final MutableFlagWithSafeDefault sDelayTransitionsForAnimation = + new MutableFlagWithSafeDefault(ChromeFeatureList.DELAY_TRANSITIONS_FOR_ANIMATION, true); /** Private constructor to avoid instantiation. */ private ToolbarFeatures() {} @@ -43,6 +45,16 @@ } /** + * Returns whether the layout system will delay transitions between start/done hiding/showing + * for Android view animations or not. When this is delayed, the toolbar code will try to + * always draw itself from Android views during these transitions, to avoid letting the captured + * bitmap leak through during transitions. With suppression enabled, the captured bitmap is less + * reliable during these transitions. + */ + public static boolean shouldDelayTransitionsForAnimation() { + return sDelayTransitionsForAnimation.isEnabled(); + } + /** * Returns whether to record metrics from suppression experiment. This allows an arm of * suppression to run without the overhead from reporting any extra metrics in Java. Using a * feature instead of a param to utilize Java side caching.
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java index 471af534..749048e 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java
@@ -32,6 +32,7 @@ import org.chromium.base.lifetime.DestroyChecker; import org.chromium.base.lifetime.Destroyable; import org.chromium.chrome.browser.browser_controls.BrowserStateBrowserControlsVisibilityDelegate; +import org.chromium.chrome.browser.layouts.LayoutStateProvider; import org.chromium.chrome.browser.omnibox.LocationBar; import org.chromium.chrome.browser.omnibox.LocationBarCoordinator; import org.chromium.chrome.browser.omnibox.NewTabPageDelegate; @@ -877,4 +878,16 @@ shadow.setVisibility(isHairlineVisible ? VISIBLE : GONE); } } + + /** + * To be called indirectly by + * {@link LayoutStateProvider.LayoutStateObserver#onStartedHiding(int, boolean, boolean)}. + */ + public void onTransitionStart() {} + + /** + * To be called indirectly by + * {@link LayoutStateProvider.LayoutStateObserver#onFinishedShowing(int)}. + */ + public void onTransitionEnd() {} }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java index 4b47198..0bd8142 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java
@@ -271,6 +271,9 @@ private boolean mDropdownListScrolled; + // If we're in a layout transition, between startHiding to doneShowing. + private boolean mInLayoutTransition; + // The following are some properties used during animation. We use explicit property classes // to avoid the cost of reflection for each animation setup. @@ -798,6 +801,10 @@ return ChromeColors.getDefaultThemeColor(getContext(), false); } + // During transition we cannot rely on the background to be opaque yet, so keep full + // alpha until the transition is over. + int alpha = mInLayoutTransition ? 255 : Math.round(mUrlExpansionFraction * 255); + // When the NTP fake search box is visible, the background color should be // transparent. When the location bar reaches the top of the screen (i.e. location // bar is fully expanded), the background needs to change back to the default @@ -805,8 +812,7 @@ // between the transition, we set a translucent default toolbar color based on // the expansion progress of the toolbar. return androidx.core.graphics.ColorUtils.setAlphaComponent( - ChromeColors.getDefaultThemeColor(getContext(), false), - Math.round(mUrlExpansionFraction * 255)); + ChromeColors.getDefaultThemeColor(getContext(), false), alpha); case VisualState.NORMAL: return ChromeColors.getDefaultThemeColor(getContext(), false); case VisualState.INCOGNITO: @@ -1404,8 +1410,14 @@ * toolbar. */ private boolean shouldDrawLocationBar() { - return mLocationBarBackground != null - && (mTabSwitcherState == STATIC_TAB || mTextureCaptureMode); + if (ToolbarFeatures.shouldDelayTransitionsForAnimation()) { + // The location bar should have alpha or clip+translation when its not supposed to be + // shown. Needs to be drawn during transitions, such as entering/exiting tab switcher. + return mLocationBarBackground != null; + } else { + return mLocationBarBackground != null + && (mTabSwitcherState == STATIC_TAB || mTextureCaptureMode); + } } private boolean drawLocationBar(Canvas canvas, long drawingTime) { @@ -1413,7 +1425,6 @@ boolean clipped = false; if (shouldDrawLocationBar()) { canvas.save(); - if (shouldDrawLocationBarBackground()) { if (mActiveLocationBarBackground instanceof NtpSearchBoxDrawable) { ((NtpSearchBoxDrawable) mActiveLocationBarBackground) @@ -1806,6 +1817,12 @@ updateViewsForTabSwitcherMode(); } + if (ToolbarFeatures.shouldDelayTransitionsForAnimation()) { + // Since mTabSwitcherState has changed, we need to also check if mVisualState should + // change. + updateVisualsForLocationBarState(); + } + updateButtonsTranslationY(); if (DeviceClassManager.enableAccessibilityLayout(getContext())) { @@ -2743,4 +2760,17 @@ private int calculateOnFocusHeightIncrease() { return (int) (mBackgroundHeightIncreaseWhenFocus * mUrlFocusChangeFraction / 2); } + + @Override + public void onTransitionStart() { + setVisibility(View.VISIBLE); + mInLayoutTransition = true; + updateToolbarBackgroundFromState(mVisualState); + } + + @Override + public void onTransitionEnd() { + mInLayoutTransition = false; + updateToolbarBackgroundFromState(mVisualState); + } }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java index 467f64e8..b07f98c58 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java
@@ -806,4 +806,12 @@ public boolean isBrowsingModeToolbarVisible() { return mToolbarLayout.getVisibility() == View.VISIBLE; } + + public void onTransitionStart() { + mToolbarLayout.onTransitionStart(); + } + + public void onTransitionEnd() { + mToolbarLayout.onTransitionEnd(); + } }
diff --git a/chrome/browser/ui/ash/cast_config_controller_media_router.cc b/chrome/browser/ui/ash/cast_config_controller_media_router.cc index 4eed6a8..187a4973 100644 --- a/chrome/browser/ui/ash/cast_config_controller_media_router.cc +++ b/chrome/browser/ui/ash/cast_config_controller_media_router.cc
@@ -143,7 +143,13 @@ session_observation_.Observe(session_manager::SessionManager::Get()); } -CastConfigControllerMediaRouter::~CastConfigControllerMediaRouter() = default; +CastConfigControllerMediaRouter::~CastConfigControllerMediaRouter() { + StopObservingMirroringMediaControllerHosts(); +} + +void CastConfigControllerMediaRouter::OnFreezeInfoChanged() { + UpdateDevices(); +} // static void CastConfigControllerMediaRouter::SetMediaRouterForTest( @@ -164,11 +170,13 @@ return device_cache_.get(); } -void CastConfigControllerMediaRouter::AddObserver(Observer* observer) { +void CastConfigControllerMediaRouter::AddObserver( + CastConfigController::Observer* observer) { observers_.AddObserver(observer); } -void CastConfigControllerMediaRouter::RemoveObserver(Observer* observer) { +void CastConfigControllerMediaRouter::RemoveObserver( + CastConfigController::Observer* observer) { observers_.RemoveObserver(observer); } @@ -203,6 +211,97 @@ // Build the old-style SinkAndRoute set out of the MediaRouter // source/sink/route setup. We first map the existing sinks, and then we // update those sinks with activity information. + StopObservingMirroringMediaControllerHosts(); + UpdateDevices(); + + for (auto& device : devices_) { + if (device.route.id.size() > 0) { + media_router::MirroringMediaControllerHost* freeze_host = + GetMediaRouter()->GetMirroringMediaControllerHost(device.route.id); + if (freeze_host) { + freeze_host->AddObserver(this); + } + } + } +} + +const std::vector<ash::SinkAndRoute>& +CastConfigControllerMediaRouter::GetSinksAndRoutes() { + return devices_; +} + +void CastConfigControllerMediaRouter::CastToSink(const std::string& sink_id) { + if (GetMediaRouter()) { + // TODO(takumif): Pass in tab casting timeout. + GetMediaRouter()->CreateRoute( + media_router::MediaSource::ForUnchosenDesktop().id(), sink_id, + url::Origin::Create(GURL("http://cros-cast-origin/")), nullptr, + base::DoNothing(), base::TimeDelta(), false); + } +} + +void CastConfigControllerMediaRouter::StopCasting(const std::string& route_id) { + if (GetMediaRouter()) { + GetMediaRouter()->TerminateRoute(route_id); + } +} + +void CastConfigControllerMediaRouter::FreezeRoute(const std::string& route_id) { + if (!GetMediaRouter()) { + return; + } + media_router::MirroringMediaControllerHost* freeze_host = + GetMediaRouter()->GetMirroringMediaControllerHost(route_id); + if (!freeze_host) { + return; + } + freeze_host->Freeze(); +} + +void CastConfigControllerMediaRouter::UnfreezeRoute( + const std::string& route_id) { + if (!GetMediaRouter()) { + return; + } + media_router::MirroringMediaControllerHost* freeze_host = + GetMediaRouter()->GetMirroringMediaControllerHost(route_id); + if (!freeze_host) { + return; + } + freeze_host->Unfreeze(); +} + +void CastConfigControllerMediaRouter::OnUserProfileLoaded( + const AccountId& account_id) { + // The active profile has changed, which means that the media router has + // as well. Reset the device cache to ensure we are using up-to-date + // object instances. + device_cache_.reset(); + RequestDeviceRefresh(); +} + +bool CastConfigControllerMediaRouter::IsAccessCodeCastFreezeUiEnabled() { + Profile* profile = GetProfile(); + return profile && media_router::IsAccessCodeCastFreezeUiEnabled(profile); +} + +void CastConfigControllerMediaRouter:: + StopObservingMirroringMediaControllerHosts() { + for (const auto& device : devices_) { + auto route_id = device.route.id; + if (route_id.size() > 0) { + media_router::MirroringMediaControllerHost* mirroring_controller_host = + GetMediaRouter()->GetMirroringMediaControllerHost(route_id); + if (mirroring_controller_host) { + // It is safe to call RemoveObserver even if we are not observing a + // particular host. + mirroring_controller_host->RemoveObserver(this); + } + } + } +} + +void CastConfigControllerMediaRouter::UpdateDevices() { devices_.clear(); #if !defined(OFFICIAL_BUILD) @@ -223,12 +322,25 @@ } for (const media_router::MediaRoute& route : device_cache()->routes()) { + media_router::MirroringMediaControllerHost* freeze_host = + IsAccessCodeCastFreezeUiEnabled() + ? GetMediaRouter()->GetMirroringMediaControllerHost( + route.media_route_id()) + : nullptr; + for (ash::SinkAndRoute& device : devices_) { if (device.sink.id == route.media_sink_id()) { device.route.id = route.media_route_id(); device.route.title = route.description(); device.route.is_local_source = route.is_local(); + // Only set freeze info if the appropriate feature is enabled. Else, + // values default to false and freeze ui is not shown. + if (freeze_host) { + device.route.freeze_info.can_freeze = freeze_host->can_freeze(); + device.route.freeze_info.is_frozen = freeze_host->is_frozen(); + } + // Default to a tab/app capture. This will display the media router // description. This means we will properly support DIAL casts. device.route.content_source = @@ -244,35 +356,6 @@ observer.OnDevicesUpdated(devices_); } -const std::vector<ash::SinkAndRoute>& -CastConfigControllerMediaRouter::GetSinksAndRoutes() { - return devices_; -} - -void CastConfigControllerMediaRouter::CastToSink(const std::string& sink_id) { - if (GetMediaRouter()) { - // TODO(imcheng): Pass in tab casting timeout. - GetMediaRouter()->CreateRoute( - media_router::MediaSource::ForUnchosenDesktop().id(), sink_id, - url::Origin::Create(GURL("http://cros-cast-origin/")), nullptr, - base::DoNothing(), base::TimeDelta(), false); - } -} - -void CastConfigControllerMediaRouter::StopCasting(const std::string& route_id) { - if (GetMediaRouter()) - GetMediaRouter()->TerminateRoute(route_id); -} - -void CastConfigControllerMediaRouter::OnUserProfileLoaded( - const AccountId& account_id) { - // The active profile has changed, which means that the media router has - // as well. Reset the device cache to ensure we are using up-to-date - // object instances. - device_cache_.reset(); - RequestDeviceRefresh(); -} - #if !defined(OFFICIAL_BUILD) void CastConfigControllerMediaRouter::AddFakeCastDevices() { // Add enough devices that the UI menu will scroll.
diff --git a/chrome/browser/ui/ash/cast_config_controller_media_router.h b/chrome/browser/ui/ash/cast_config_controller_media_router.h index 74b7b11c..6749f515 100644 --- a/chrome/browser/ui/ash/cast_config_controller_media_router.h +++ b/chrome/browser/ui/ash/cast_config_controller_media_router.h
@@ -10,6 +10,7 @@ #include "ash/public/cpp/cast_config_controller.h" #include "base/observer_list.h" #include "base/scoped_observation.h" +#include "components/media_router/browser/mirroring_media_controller_host.h" #include "components/session_manager/core/session_manager.h" #include "components/session_manager/core/session_manager_observer.h" @@ -23,7 +24,8 @@ // A class which allows the ash tray to communicate with the media router. class CastConfigControllerMediaRouter : public ash::CastConfigController, - public session_manager::SessionManagerObserver { + public session_manager::SessionManagerObserver, + public media_router::MirroringMediaControllerHost::Observer { public: CastConfigControllerMediaRouter(); @@ -34,12 +36,15 @@ ~CastConfigControllerMediaRouter() override; + // media_router::MirroringMediaControllerHost::Observer: + void OnFreezeInfoChanged() override; + static void SetMediaRouterForTest(media_router::MediaRouter* media_router); private: // CastConfigController: - void AddObserver(Observer* observer) override; - void RemoveObserver(Observer* observer) override; + void AddObserver(CastConfigController::Observer* observer) override; + void RemoveObserver(CastConfigController::Observer* observer) override; bool HasMediaRouterForPrimaryProfile() const override; bool HasSinksAndRoutes() const override; bool HasActiveRoute() const override; @@ -48,10 +53,18 @@ const std::vector<ash::SinkAndRoute>& GetSinksAndRoutes() override; void CastToSink(const std::string& sink_id) override; void StopCasting(const std::string& route_id) override; + void FreezeRoute(const std::string& route_id) override; + void UnfreezeRoute(const std::string& route_id) override; // session_manager::SessionManagerObserver: void OnUserProfileLoaded(const AccountId& account_id) override; + bool IsAccessCodeCastFreezeUiEnabled(); + + void StopObservingMirroringMediaControllerHosts(); + + void UpdateDevices(); + #if !defined(OFFICIAL_BUILD) // Adds fake Cast devices for manual testing of the UI (for example, in the // linux-chromeos emulator). @@ -67,7 +80,7 @@ // Ash UI. std::vector<ash::SinkAndRoute> devices_; - base::ObserverList<Observer> observers_; + base::ObserverList<CastConfigController::Observer> observers_; base::ScopedObservation<session_manager::SessionManager, session_manager::SessionManagerObserver>
diff --git a/chrome/browser/ui/ash/desks/chrome_saved_desk_delegate.cc b/chrome/browser/ui/ash/desks/chrome_saved_desk_delegate.cc index 21dc7d3..932a9db 100644 --- a/chrome/browser/ui/ash/desks/chrome_saved_desk_delegate.cc +++ b/chrome/browser/ui/ash/desks/chrome_saved_desk_delegate.cc
@@ -265,13 +265,6 @@ } } - // Use app id from lacros if available. This will only be set for lacros - // app windows. - if (auto app_name = DesksClient::Get()->GetAppIdForLacrosWindow(window)) { - app_launch_info->app_name = *app_name; - app_launch_info->app_type_browser = true; - } - if (app_id != app_constants::kChromeAppId && app_id != app_constants::kLacrosAppId && (app_type == apps::AppType::kChromeApp || @@ -456,6 +449,10 @@ app_launch_info->urls = state->urls; app_launch_info->active_tab_index = state->active_index; app_launch_info->first_non_pinned_tab_index = state->first_non_pinned_index; + if (state->browser_app_name.has_value()) { + app_launch_info->app_name = state->browser_app_name.value(); + app_launch_info->app_type_browser = true; + } std::move(callback).Run(std::move(app_launch_info)); }
diff --git a/chrome/browser/ui/ash/desks/desks_client_browsertest.cc b/chrome/browser/ui/ash/desks/desks_client_browsertest.cc index ce6b8740..0ee840f 100644 --- a/chrome/browser/ui/ash/desks/desks_client_browsertest.cc +++ b/chrome/browser/ui/ash/desks/desks_client_browsertest.cc
@@ -124,6 +124,7 @@ constexpr int32_t kSettingsWindowId = 100; constexpr int32_t kHelpWindowId = 200; constexpr int32_t kLaunchedWindowIdBase = -1; +constexpr int32_t kTestWindowId = 300; constexpr char kExampleUrl1[] = "https://examples1.com"; constexpr char kExampleUrl2[] = "https://examples2.com"; @@ -138,6 +139,7 @@ "\"created_time_usec\": \"1633535632\",\"updated_time_usec\": " "\"1633535632\",\"desk\":{}}]"; constexpr char kTestTabGroupNameFormat[] = "test_tab_group_%u"; +constexpr char kTestAppName[] = "test_app_name"; Browser* FindBrowser(int32_t window_id) { for (auto* browser : *BrowserList::GetInstance()) { @@ -3000,6 +3002,76 @@ ash::WaitForOverviewExitAnimation(); } +// Tests that app browsers are captured correctly, coverage for launching +// lacros browsers can be found in +// c/b/lacros/desk_template_client_browsertest.cc This simply confirms that the +// chrome desk client handles apps correctly when converting the returned mojom +// from crosapi to app_launch_info. +IN_PROC_BROWSER_TEST_F(DesksTemplatesClientLacrosTest, + CapturesLacrosAppCorrectly) { + // Prevents test from running when running in a build without lacros. + if (!ash_starter_.HasLacrosArgument()) { + return; + } + + ASSERT_TRUE(crosapi::BrowserManager::Get()->IsRunning()); + + // Add our browser under test, this is the only way to launch an app + // via the BrowserManager. + crosapi::BrowserManager::Get()->CreateBrowserWithRestoredData( + {GURL(kExampleUrl1)}, {0, 0, 256, 256}, {}, + ui::WindowShowState::SHOW_STATE_DEFAULT, + /*active_tab_index=*/0, /*first_non_pinned_tab_index=*/0, kTestAppName, + kTestWindowId); + LacrosWindowWaiter waiter; + aura::Window::Windows launched_windows = waiter.Wait(/*expected_count=*/1u); + ASSERT_EQ(1u, launched_windows.size()); + + // Enter overview and save the current desk as a template. The current desk + // has one lacros app and the default browser. + ash::ToggleOverview(); + ash::WaitForOverviewEnterAnimation(); + ClickSaveDeskAsTemplateButton(); + + // Grab all entries to assert. + const std::vector<const ash::DeskTemplate*> all_entries = GetAllEntries(); + ASSERT_EQ(all_entries.size(), 1u); + + // Since we only have one template grab the first one. + const app_restore::RestoreData* desk_restore_data = + all_entries[0]->desk_restore_data(); + ASSERT_NE(desk_restore_data, nullptr); + + // Through an exhaustive process of trial and error we cannot retrieve our + // desired window through any other means than running a search for the app + // name in the mapping of window ID's to app launch info. There isn't a way, + // currently at least, within this test class or through the crosapi + // to close the default browser. We can't use the test's class' close browser + // method either as both have been tried and failed to successfully close the + // window. Furthermore obscuring the window from the capture logic doesn't + // seem to work in the testing logic either. Simply using the window ID the + // browser was launched with doesn't work either because the window ID is + // changed on capture. + const auto& app_id_to_launch_list = + desk_restore_data->app_id_to_launch_list(); + const auto& launch_list = + app_id_to_launch_list.at(app_constants::kLacrosAppId); + const app_restore::AppRestoreData* actual_app_data = nullptr; + + for (const auto& it : launch_list) { + if (it.second->app_name.has_value() && + it.second->app_name.value() == kTestAppName) { + actual_app_data = it.second.get(); + break; + } + } + ASSERT_NE(actual_app_data, nullptr); + + // Finally assert we set the relevant fields properly. + EXPECT_TRUE(actual_app_data->app_type_browser.has_value()); + EXPECT_TRUE(actual_app_data->app_type_browser.value()); +} + using SaveAndRecallBrowserTest = DesksClientTest; IN_PROC_BROWSER_TEST_F(SaveAndRecallBrowserTest,
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc index be84a6a..93132db 100644 --- a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc +++ b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc
@@ -57,6 +57,7 @@ #include "base/task/sequenced_task_runner.h" #include "base/task/single_thread_task_runner.h" #include "base/test/scoped_feature_list.h" +#include "base/test/test_future.h" #include "base/values.h" #include "build/build_config.h" #include "chrome/browser/apps/app_service/app_service_proxy.h" @@ -71,6 +72,7 @@ #include "chrome/browser/ash/app_list/arc/arc_app_utils.h" #include "chrome/browser/ash/app_list/arc/arc_default_app_list.h" #include "chrome/browser/ash/app_list/internal_app/internal_app_metadata.h" +#include "chrome/browser/ash/apps/apk_web_app_service.h" #include "chrome/browser/ash/arc/arc_util.h" #include "chrome/browser/ash/arc/session/arc_session_manager.h" #include "chrome/browser/ash/crosapi/browser_util.h" @@ -4685,21 +4687,60 @@ TEST_F(ChromeShelfControllerWithArcTest, ArcAppPinPolicy) { InitShelfControllerWithBrowser(); - arc::mojom::AppInfoPtr appinfo = - CreateAppInfo("Some App", "SomeActivity", "com.example.app"); - const std::string app_id = AddArcAppAndShortcut(*appinfo); - // Set policy, that makes pins ARC app. Unlike native extension, for ARC app - // package_name (not hash) specified as id. In this test we check that - // by hash we can determine that appropriate package was set by policy. + constexpr char kExampleArcPackageName[] = "com.example.app"; + + arc::mojom::AppInfoPtr appinfo = + CreateAppInfo("Some App", "SomeActivity", kExampleArcPackageName); + const std::string example_app_id = AddArcAppAndShortcut(*appinfo); + + // Sets up policy that pins this ARC app. Unlike native extensions, ARC apps + // are pinned by |package_name| rather than the actual |app_id|. base::Value::List policy_value; - AppendPrefValue(policy_value, appinfo->package_name); + AppendPrefValue(policy_value, kExampleArcPackageName); profile()->GetTestingPrefService()->SetManagedPref( prefs::kPolicyPinnedLauncherApps, base::Value(policy_value.Clone())); - EXPECT_TRUE(shelf_controller_->IsAppPinned(app_id)); + EXPECT_TRUE(shelf_controller_->IsAppPinned(example_app_id)); EXPECT_EQ(AppListControllerDelegate::PIN_FIXED, - GetPinnableForAppID(app_id, profile())); + GetPinnableForAppID(example_app_id, profile())); +} + +TEST_F(ChromeShelfControllerWithArcTest, ApkWebAppPinPolicy) { + InitShelfControllerWithBrowser(); + + constexpr char kMapsWebPackageName[] = "com.google.maps"; + + auto* service = ash::ApkWebAppService::Get(browser()->profile()); + ASSERT_TRUE(service); + service->SetArcAppListPrefsForTesting(arc_test_.arc_app_list_prefs()); + + base::test::TestFuture<const std::string&, const web_app::AppId&> future; + service->SetWebAppInstalledCallbackForTesting(future.GetCallback()); + + auto package = arc::mojom::ArcPackageInfo::New(kMapsWebPackageName, 1, 1, 1, + /*sync=*/true); + package->web_app_info = + arc::mojom::WebAppInfo::New("Google Maps", "https://www.google.com/maps/", + "https://www.google.com/", 1000000); + std::vector<arc::mojom::ArcPackageInfoPtr> packages; + packages.push_back(std::move(package)); + arc_test_.app_instance()->SendRefreshPackageList(std::move(packages)); + + auto [maps_package_name, maps_app_id] = future.Take(); + ASSERT_EQ(maps_package_name, kMapsWebPackageName); + + // Sets up policy that pins this apk-based Web App. Unlike regular Web Apps, + // Web Apps originating from apks are pinned by |package_name| rather than + // their |install_url|. + base::Value::List policy_value; + AppendPrefValue(policy_value, kMapsWebPackageName); + profile()->GetTestingPrefService()->SetManagedPref( + prefs::kPolicyPinnedLauncherApps, base::Value(policy_value.Clone())); + + EXPECT_TRUE(shelf_controller_->IsAppPinned(maps_app_id)); + EXPECT_EQ(AppListControllerDelegate::PIN_FIXED, + GetPinnableForAppID(maps_app_id, profile())); } TEST_F(ChromeShelfControllerWithArcTest, ArcManaged) {
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_interactive_uitest.cc b/chrome/browser/ui/autofill/autofill_popup_controller_interactive_uitest.cc index 7b68099..3c236f82 100644 --- a/chrome/browser/ui/autofill/autofill_popup_controller_interactive_uitest.cc +++ b/chrome/browser/ui/autofill/autofill_popup_controller_interactive_uitest.cc
@@ -39,20 +39,6 @@ void SetUpOnMainThread() override { web_contents()->Focus(); - autofill_driver_ = - ContentAutofillDriverFactory::FromWebContents(web_contents()) - ->DriverForFrame(main_rfh()); - auto autofill_external_delegate = - std::make_unique<TestAutofillExternalDelegate>( - &autofill_manager(), autofill_driver_, - /*call_parent_methods=*/true); - autofill_external_delegate_ = autofill_external_delegate.get(); - autofill_manager().SetExternalDelegateForTest( - std::move(autofill_external_delegate)); - - disable_animation_ = std::make_unique<ui::ScopedAnimationDurationScaleMode>( - ui::ScopedAnimationDurationScaleMode::ZERO_DURATION); - // The test cases mock the entire forms by directly calling // ContentAutofillDriver functions. Nonetheless we set up an HTTP server and // open an empty page. Otherwise, the FormData::url would be about:blank and @@ -73,6 +59,20 @@ embedded_test_server()->StartAcceptingConnections(); ASSERT_TRUE(ui_test_utils::NavigateToURL( browser(), embedded_test_server()->GetURL("/test.html"))); + + autofill_driver_ = + ContentAutofillDriverFactory::FromWebContents(web_contents()) + ->DriverForFrame(main_rfh()); + auto autofill_external_delegate = + std::make_unique<TestAutofillExternalDelegate>( + &autofill_manager(), autofill_driver_, + /*call_parent_methods=*/true); + autofill_external_delegate_ = autofill_external_delegate.get(); + autofill_manager().SetExternalDelegateForTest( + std::move(autofill_external_delegate)); + + disable_animation_ = std::make_unique<ui::ScopedAnimationDurationScaleMode>( + ui::ScopedAnimationDurationScaleMode::ZERO_DURATION); } void TearDownOnMainThread() override {
diff --git a/chrome/browser/ui/autofill/payments/card_unmask_authentication_selection_dialog_controller_impl.cc b/chrome/browser/ui/autofill/payments/card_unmask_authentication_selection_dialog_controller_impl.cc index 1e71995..feb0a8a 100644 --- a/chrome/browser/ui/autofill/payments/card_unmask_authentication_selection_dialog_controller_impl.cc +++ b/chrome/browser/ui/autofill/payments/card_unmask_authentication_selection_dialog_controller_impl.cc
@@ -54,10 +54,7 @@ return; CHECK(!challenge_options.empty()); - challenge_options_ = - base::FeatureList::IsEnabled(features::kAutofillEnableCvcForVcnYellowPath) - ? challenge_options - : std::vector<CardUnmaskChallengeOption>{challenge_options[0]}; + challenge_options_ = challenge_options; confirm_unmasking_method_callback_ = std::move(confirm_unmasking_method_callback);
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc index 0bba07ca..c81630f 100644 --- a/chrome/browser/ui/browser_commands.cc +++ b/chrome/browser/ui/browser_commands.cc
@@ -1381,6 +1381,10 @@ } void ManagePasswordsForPage(Browser* browser) { + browser->window()->CloseFeaturePromo( + feature_engagement::kIPHPasswordsManagementBubbleAfterSaveFeature); + browser->window()->CloseFeaturePromo( + feature_engagement::kIPHPasswordsManagementBubbleDuringSigninFeature); WebContents* web_contents = browser->tab_strip_model()->GetActiveWebContents(); ManagePasswordsUIController* controller =
diff --git a/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript.h b/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript.h index f824c8dd..b92a135 100644 --- a/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript.h +++ b/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript.h
@@ -11,13 +11,18 @@ @class BookmarkItemAppleScript; -// Represent a bookmark folder scriptable object in applescript. +// Represent a bookmark folder scriptable object in AppleScript. @interface BookmarkFolderAppleScript : BookmarkNodeAppleScript +// Returns an array of all the bookmark folders contained within this particular +// folder. +@property(readonly) NSArray<BookmarkFolderAppleScript*>* bookmarkFolders; + +// Returns an array of all the bookmark items contained within this particular +// folder. +@property(readonly) NSArray<BookmarkItemAppleScript*>* bookmarkItems; + // Bookmark folder manipulation methods. -// Returns an array of |BookmarkFolderAppleScript*| of all the bookmark folders -// contained within this particular folder. -@property(readonly) NSArray* bookmarkFolders; // Inserts a bookmark folder at the end. - (void)insertInBookmarkFolders:(BookmarkFolderAppleScript*)aBookmarkFolder; @@ -34,9 +39,6 @@ - (void)removeFromBookmarkFoldersAtIndex:(size_t)index; // Bookmark item manipulation methods. -// Returns an array of |BookmarkItemAppleScript*| of all the bookmark items -// contained within this particular folder. -@property(readonly) NSArray* bookmarkItems; // Inserts a bookmark item at the end. - (void)insertInBookmarkItems:(BookmarkItemAppleScript*)aBookmarkItem; @@ -52,18 +54,6 @@ // before calling directly. - (void)removeFromBookmarkItemsAtIndex:(size_t)index; -// Returns the position of a bookmark folder within the current bookmark folder -// which consists of bookmark folders as well as bookmark items. -// AppleScript makes sure that there is a bookmark folder before calling this -// method, make sure of that before calling directly. -- (size_t)calculatePositionOfBookmarkFolderAt:(size_t)index; - -// Returns the position of a bookmark item within the current bookmark folder -// which consists of bookmark folders as well as bookmark items. -// AppleScript makes sure that there is a bookmark item before calling this -// method, make sure of that before calling directly. -- (size_t)calculatePositionOfBookmarkItemAt:(size_t)index; - @end #endif // CHROME_BROWSER_UI_COCOA_APPLESCRIPT_BOOKMARK_FOLDER_APPLESCRIPT_H_
diff --git a/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript.mm b/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript.mm index 3d6c6b7..fe35685 100644 --- a/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript.mm +++ b/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript.mm
@@ -16,10 +16,69 @@ using bookmarks::BookmarkModel; using bookmarks::BookmarkNode; +// /!\ Warning +// +// The design of the AppleScript dictionary with regards to bookmarks is +// deficient. The ideal design would mirror the design of the actual bookmark +// system, where a bookmark element could be either a folder or an item, and +// bookmark folders could hold any number of them, in any order. +// +// However, that's not the design that is implemented. The current design is +// that bookmark folders and bookmark items are separate and unrelated things, +// and that bookmark folders have a list of bookmark folders they contain, as +// well as a list of bookmark items they contain. +// +// That is, there are _two separate lists_. +// +// Translating from the real bookmarks system, where the children of a folder +// are a list of intermingled folders and items, is easy: walk the list of +// children, and filter out the wrong kind. (See `-bookmarkFolders` and +// `-bookmarkItems`.) +// +// Translating _to_ the real bookmarks system cannot be done in the general +// case. There is no control over the mingling of folders and items, and there +// is only vague control over the ordering of items that share a type. +// +// All this is to explain the difference in terminology between "index" and +// "bookmark manager position". An "index" value is relative to the two separate +// child lists that exist from the AppleScript perspective. The "bookmark +// manager position" is relative to the true list of (both types of) children of +// a folder in the bookmarks system. +// +// Because AppleScript maintains no state, no translation ever needs to be done +// from positions to indexes. AppleScript keeps object identifiers, and if it +// ever needs to update the index, it will re-request the list and find the item +// again by matching its ID. +// +// However, when a script requests a folder or bookmark to be moved around or +// inserted, AppleScript will request a change in index. That index will need to +// be converted into a position in the real list of children of a folder, and +// that's what the `-bookmarkManagerPositionOf[Folder|Item]At:` methods are for. + +@interface BookmarkFolderAppleScript () + +// Does the actual insertion of a bookmark folder at an absolute position. +- (void)insertFolder:(BookmarkFolderAppleScript*)bookmarkFolder + atBookmarkManagerPosition:(size_t)position; + +// Does the actual insertion of a bookmark item at an absolute position. +- (void)insertItem:(BookmarkItemAppleScript*)bookmarkItem + atBookmarkManagerPosition:(size_t)position; + +// Returns the position of a bookmark folder within the current bookmark folder +// which consists of bookmark folders as well as bookmark items. +- (size_t)bookmarkManagerPositionOfFolderAt:(size_t)index; + +// Returns the position of a bookmark item within the current bookmark folder +// which consists of bookmark folders as well as bookmark items. +- (size_t)bookmarkManagerPositionOfItemAt:(size_t)index; + +@end + @implementation BookmarkFolderAppleScript -- (NSArray*)bookmarkFolders { - NSMutableArray* bookmarkFolders = +- (NSArray<BookmarkFolderAppleScript*>*)bookmarkFolders { + NSMutableArray<BookmarkFolderAppleScript*>* bookmarkFolders = [NSMutableArray arrayWithCapacity:self.bookmarkNode->children().size()]; for (const auto& node : self.bookmarkNode->children()) { @@ -37,64 +96,8 @@ return bookmarkFolders; } -- (void)insertInBookmarkFolders:(BookmarkFolderAppleScript*)aBookmarkFolder { - // This method gets called when a new bookmark folder is created so - // the container and property are set here. - [aBookmarkFolder setContainer:self - property:AppleScript::kBookmarkFoldersProperty]; - BookmarkModel* model = self.bookmarkModel; - if (!model) { - return; - } - - const BookmarkNode* node = - model->AddFolder(self.bookmarkNode, self.bookmarkNode->children().size(), - std::u16string()); - if (!node) { - AppleScript::SetError(AppleScript::Error::kCreateBookmarkFolder); - return; - } - - aBookmarkFolder.bookmarkNode = node; -} - -- (void)insertInBookmarkFolders:(BookmarkFolderAppleScript*)aBookmarkFolder - atIndex:(size_t)index { - // This method gets called when a new bookmark folder is created so - // the container and property are set here. - [aBookmarkFolder setContainer:self - property:AppleScript::kBookmarkFoldersProperty]; - size_t position = [self calculatePositionOfBookmarkFolderAt:index]; - - BookmarkModel* model = self.bookmarkModel; - if (!model) { - return; - } - - const BookmarkNode* node = - model->AddFolder(self.bookmarkNode, position, std::u16string()); - if (!node) { - AppleScript::SetError(AppleScript::Error::kCreateBookmarkFolder); - return; - } - - aBookmarkFolder.bookmarkNode = node; -} - -- (void)removeFromBookmarkFoldersAtIndex:(size_t)index { - size_t position = [self calculatePositionOfBookmarkFolderAt:index]; - - BookmarkModel* model = self.bookmarkModel; - if (!model) { - return; - } - - model->Remove(self.bookmarkNode->children()[position].get(), - bookmarks::metrics::BookmarkEditSource::kUser); -} - -- (NSArray*)bookmarkItems { - NSMutableArray* bookmarkItems = +- (NSArray<BookmarkItemAppleScript*>*)bookmarkItems { + NSMutableArray<BookmarkItemAppleScript*>* bookmarkItems = [NSMutableArray arrayWithCapacity:self.bookmarkNode->children().size()]; for (const auto& node : self.bookmarkNode->children()) { @@ -112,65 +115,41 @@ return bookmarkItems; } -- (void)insertInBookmarkItems:(BookmarkItemAppleScript*)aBookmarkItem { - // This method gets called when a new bookmark item is created so - // the container and property are set here. - [aBookmarkItem setContainer:self - property:AppleScript::kBookmarkItemsProperty]; +- (void)insertInBookmarkFolders:(BookmarkFolderAppleScript*)bookmarkFolder { + [self insertFolder:bookmarkFolder + atBookmarkManagerPosition:self.bookmarkNode->children().size()]; +} + +- (void)insertInBookmarkFolders:(BookmarkFolderAppleScript*)bookmarkFolder + atIndex:(size_t)index { + [self insertFolder:bookmarkFolder + atBookmarkManagerPosition:[self bookmarkManagerPositionOfFolderAt:index]]; +} + +- (void)insertFolder:(BookmarkFolderAppleScript*)bookmarkFolder + atBookmarkManagerPosition:(size_t)position { + [bookmarkFolder setContainer:self + property:AppleScript::kBookmarkFoldersProperty]; BookmarkModel* model = self.bookmarkModel; if (!model) { return; } - GURL url = GURL(base::SysNSStringToUTF8(aBookmarkItem.URL)); - if (!url.is_valid()) { - AppleScript::SetError(AppleScript::Error::kInvalidURL); - return; - } - - const BookmarkNode* node = - model->AddNewURL(self.bookmarkNode, self.bookmarkNode->children().size(), - std::u16string(), url); + const BookmarkNode* node = model->AddFolder( + self.bookmarkNode, position, + /*title=*/std::u16string(), /*meta_info=*/nullptr, + /*creation_time=*/absl::nullopt, bookmarkFolder.bookmarkGUID); if (!node) { - AppleScript::SetError(AppleScript::Error::kCreateBookmarkItem); + AppleScript::SetError(AppleScript::Error::kCreateBookmarkFolder); return; } - aBookmarkItem.bookmarkNode = node; + [bookmarkFolder didCreateBookmarkNode:node]; } -- (void)insertInBookmarkItems:(BookmarkItemAppleScript*)aBookmarkItem - atIndex:(size_t)index { - // This method gets called when a new bookmark item is created so - // the container and property are set here. - [aBookmarkItem setContainer:self - property:AppleScript::kBookmarkItemsProperty]; - size_t position = [self calculatePositionOfBookmarkItemAt:index]; - - BookmarkModel* model = self.bookmarkModel; - if (!model) { - return; - } - - GURL url(base::SysNSStringToUTF8(aBookmarkItem.URL)); - if (!url.is_valid()) { - AppleScript::SetError(AppleScript::Error::kInvalidURL); - return; - } - - const BookmarkNode* node = - model->AddNewURL(self.bookmarkNode, position, std::u16string(), url); - if (!node) { - AppleScript::SetError(AppleScript::Error::kCreateBookmarkItem); - return; - } - - aBookmarkItem.bookmarkNode = node; -} - -- (void)removeFromBookmarkItemsAtIndex:(size_t)index { - size_t position = [self calculatePositionOfBookmarkItemAt:index]; +- (void)removeFromBookmarkFoldersAtIndex:(size_t)index { + size_t position = [self bookmarkManagerPositionOfFolderAt:index]; BookmarkModel* model = self.bookmarkModel; if (!model) { @@ -181,8 +160,58 @@ bookmarks::metrics::BookmarkEditSource::kUser); } -- (size_t)calculatePositionOfBookmarkFolderAt:(size_t)index { - // Traverse through all the child nodes till the required node is found and +- (void)insertInBookmarkItems:(BookmarkItemAppleScript*)bookmarkItem { + [self insertItem:bookmarkItem + atBookmarkManagerPosition:self.bookmarkNode->children().size()]; +} + +- (void)insertInBookmarkItems:(BookmarkItemAppleScript*)bookmarkItem + atIndex:(size_t)index { + [self insertItem:bookmarkItem + atBookmarkManagerPosition:[self bookmarkManagerPositionOfItemAt:index]]; +} + +- (void)insertItem:(BookmarkItemAppleScript*)bookmarkItem + atBookmarkManagerPosition:(size_t)position { + [bookmarkItem setContainer:self property:AppleScript::kBookmarkItemsProperty]; + + BookmarkModel* model = self.bookmarkModel; + if (!model) { + return; + } + + GURL url(base::SysNSStringToUTF8(bookmarkItem.URL)); + if (!url.is_valid()) { + AppleScript::SetError(AppleScript::Error::kInvalidURL); + return; + } + + const BookmarkNode* node = model->AddURL( + self.bookmarkNode, position, /*title=*/std::u16string(), url, + /*meta_info=*/nullptr, /*creation_time=*/absl::nullopt, + bookmarkItem.bookmarkGUID, /*added_by_user=*/true); + if (!node) { + AppleScript::SetError(AppleScript::Error::kCreateBookmarkItem); + return; + } + + [bookmarkItem didCreateBookmarkNode:node]; +} + +- (void)removeFromBookmarkItemsAtIndex:(size_t)index { + size_t position = [self bookmarkManagerPositionOfItemAt:index]; + + BookmarkModel* model = self.bookmarkModel; + if (!model) { + return; + } + + model->Remove(self.bookmarkNode->children()[position].get(), + bookmarks::metrics::BookmarkEditSource::kUser); +} + +- (size_t)bookmarkManagerPositionOfFolderAt:(size_t)index { + // Traverse through all the child nodes until the required node is found and // return its position. // AppleScript is 1-based therefore index is incremented by 1. ++index; @@ -195,8 +224,8 @@ return count - 1; } -- (size_t)calculatePositionOfBookmarkItemAt:(size_t)index { - // Traverse through all the child nodes till the required node is found and +- (size_t)bookmarkManagerPositionOfItemAt:(size_t)index { + // Traverse through all the child nodes until the required node is found and // return its position. // AppleScript is 1-based therefore index is incremented by 1. ++index;
diff --git a/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript_browsertest.mm b/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript_browsertest.mm index b3cc0bc5..4d2e986 100644 --- a/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript_browsertest.mm +++ b/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript_browsertest.mm
@@ -137,12 +137,12 @@ EXPECT_NSEQ(unique_id.get(), bi.uniqueID); // Test to see no bookmark item is created when no/invalid URL is entered. - base::scoped_nsobject<FakeScriptCommand> fakeScriptCommand( + base::scoped_nsobject<FakeScriptCommand> fake_script_command( [[FakeScriptCommand alloc] init]); bookmark_item.reset([[BookmarkItemAppleScript alloc] init]); [bookmark_bar_ insertInBookmarkItems:bookmark_item]; EXPECT_EQ(static_cast<int>(Error::kInvalidURL), - fakeScriptCommand.get().scriptErrorNumber); + fake_script_command.get().scriptErrorNumber); } // Insert a new bookmark item at a particular position. @@ -171,12 +171,12 @@ EXPECT_NSEQ(unique_id, bi.uniqueID); // Test to see no bookmark item is created when no/invalid URL is entered. - base::scoped_nsobject<FakeScriptCommand> fakeScriptCommand( + base::scoped_nsobject<FakeScriptCommand> fake_script_command( [[FakeScriptCommand alloc] init]); bookmark_item.reset([[BookmarkItemAppleScript alloc] init]); [bookmark_bar_ insertInBookmarkItems:bookmark_item atIndex:1]; EXPECT_EQ(static_cast<int>(Error::kInvalidURL), - fakeScriptCommand.get().scriptErrorNumber); + fake_script_command.get().scriptErrorNumber); } // Delete bookmark items.
diff --git a/chrome/browser/ui/cocoa/applescript/bookmark_item_applescript.h b/chrome/browser/ui/cocoa/applescript/bookmark_item_applescript.h index 65a0933a..ed1c53b9 100644 --- a/chrome/browser/ui/cocoa/applescript/bookmark_item_applescript.h +++ b/chrome/browser/ui/cocoa/applescript/bookmark_item_applescript.h
@@ -12,12 +12,12 @@ // Represents a bookmark item scriptable object in applescript. @interface BookmarkItemAppleScript : BookmarkNodeAppleScript -// Assigns a node, sets its unique ID and also copies temporary values. -- (void)setBookmarkNode:(const bookmarks::BookmarkNode*)aBookmarkNode; - // Returns/sets the URL that the bookmark item holds. @property(copy) NSString* URL; +// Handles the bookkeeping for when a node is created. +- (void)didCreateBookmarkNode:(const bookmarks::BookmarkNode*)bookmarkNode; + @end #endif // CHROME_BROWSER_UI_COCOA_APPLESCRIPT_BOOKMARK_ITEM_APPLESCRIPT_H_
diff --git a/chrome/browser/ui/cocoa/applescript/bookmark_item_applescript.mm b/chrome/browser/ui/cocoa/applescript/bookmark_item_applescript.mm index e78f9e4..a6f6411 100644 --- a/chrome/browser/ui/cocoa/applescript/bookmark_item_applescript.mm +++ b/chrome/browser/ui/cocoa/applescript/bookmark_item_applescript.mm
@@ -41,8 +41,8 @@ [super dealloc]; } -- (void)setBookmarkNode:(const BookmarkNode*)aBookmarkNode { - super.bookmarkNode = aBookmarkNode; +- (void)didCreateBookmarkNode:(const bookmarks::BookmarkNode*)bookmarkNode { + [super didCreateBookmarkNode:bookmarkNode]; self.URL = self.tempURL; } @@ -54,35 +54,34 @@ return base::SysUTF8ToNSString(self.bookmarkNode->url().spec()); } -- (void)setURL:(NSString*)aURL { - GURL url(base::SysNSStringToUTF8(aURL)); +- (void)setURL:(NSString*)url { + // If a scripter sets a URL before the node is added, the URL is saved at a + // temporary location. + if (!self.bookmarkNode) { + self.tempURL = url; + return; + } + + GURL gurl(base::SysNSStringToUTF8(url)); + if (!gurl.is_valid()) { + AppleScript::SetError(AppleScript::Error::kInvalidURL); + return; + } AppController* appDelegate = base::mac::ObjCCastStrict<AppController>(NSApp.delegate); if (!chrome::mac::IsJavaScriptEnabledForProfile(appDelegate.lastProfile) && - url.SchemeIs(url::kJavaScriptScheme)) { + gurl.SchemeIs(url::kJavaScriptScheme)) { AppleScript::SetError(AppleScript::Error::kJavaScriptUnsupported); return; } - // If a scripter sets a URL before the node is added, the URL is saved at a - // temporary location. - if (!self.bookmarkNode) { - self.tempURL = aURL; - return; - } - BookmarkModel* model = self.bookmarkModel; if (!model) { return; } - if (!url.is_valid()) { - AppleScript::SetError(AppleScript::Error::kInvalidURL); - return; - } - - model->SetURL(self.bookmarkNode, url, + model->SetURL(self.bookmarkNode, gurl, bookmarks::metrics::BookmarkEditSource::kOther); }
diff --git a/chrome/browser/ui/cocoa/applescript/bookmark_node_applescript.h b/chrome/browser/ui/cocoa/applescript/bookmark_node_applescript.h index 60d3e29..240bedc 100644 --- a/chrome/browser/ui/cocoa/applescript/bookmark_node_applescript.h +++ b/chrome/browser/ui/cocoa/applescript/bookmark_node_applescript.h
@@ -7,6 +7,7 @@ #import <Foundation/Foundation.h> +#include "base/guid.h" #import "chrome/browser/ui/cocoa/applescript/element_applescript.h" namespace bookmarks { @@ -18,16 +19,8 @@ // bookmark item. @interface BookmarkNodeAppleScript : ElementAppleScript -// Does not actually create a folder/item but just sets its ID, the folder is -// created in insertInBookmarksFolder: in the corresponding bookmarks folder. -- (instancetype)init; - -// Does not make a folder/item but instead uses an existing one. -- (instancetype)initWithBookmarkNode: - (const bookmarks::BookmarkNode*)aBookmarkNode; - -// Assigns/gets a node, sets its unique ID and also copies temporary values. -@property(assign) const bookmarks::BookmarkNode* bookmarkNode; +// Gets the node. +@property(readonly) const bookmarks::BookmarkNode* bookmarkNode; // Get and Set title. @property(copy) NSString* title; @@ -39,6 +32,20 @@ // Returns the bookmark model of the browser, returns null if there is an error. @property(readonly) bookmarks::BookmarkModel* bookmarkModel; +// Returns the GUID of the bookmark node. +@property(readonly) base::GUID bookmarkGUID; + +// Does not actually create a folder/item but just sets its ID, the folder is +// created in insertInBookmarksFolder: in the corresponding bookmarks folder. +- (instancetype)init; + +// Does not make a folder/item but instead uses an existing one. +- (instancetype)initWithBookmarkNode: + (const bookmarks::BookmarkNode*)bookmarkNode; + +// Handles the bookkeeping for when a node is created. +- (void)didCreateBookmarkNode:(const bookmarks::BookmarkNode*)bookmarkNode; + @end #endif // CHROME_BROWSER_UI_COCOA_APPLESCRIPT_BOOKMARK_NODE_APPLESCRIPT_H_
diff --git a/chrome/browser/ui/cocoa/applescript/bookmark_node_applescript.mm b/chrome/browser/ui/cocoa/applescript/bookmark_node_applescript.mm index fd0b4d7..c04c694 100644 --- a/chrome/browser/ui/cocoa/applescript/bookmark_node_applescript.mm +++ b/chrome/browser/ui/cocoa/applescript/bookmark_node_applescript.mm
@@ -5,9 +5,10 @@ #import "chrome/browser/ui/cocoa/applescript/bookmark_node_applescript.h" #include "base/check.h" +#include "base/check_op.h" +#include "base/guid.h" #import "base/mac/foundation_util.h" #import "base/mac/scoped_nsobject.h" -#include "base/memory/raw_ptr.h" #include "base/strings/sys_string_conversions.h" #import "chrome/browser/app_controller_mac.h" #include "chrome/browser/bookmarks/bookmark_model_factory.h" @@ -16,6 +17,8 @@ #import "chrome/browser/ui/cocoa/applescript/bookmark_item_applescript.h" #import "chrome/browser/ui/cocoa/applescript/error_applescript.h" #include "components/bookmarks/browser/bookmark_model.h" +#include "components/bookmarks/browser/bookmark_node.h" +#include "components/bookmarks/browser/bookmark_utils.h" #import "components/bookmarks/common/bookmark_metrics.h" using bookmarks::BookmarkModel; @@ -32,81 +35,73 @@ @end @implementation BookmarkNodeAppleScript { - raw_ptr<const bookmarks::BookmarkNode> _bookmarkNode; // weak. + base::GUID _bookmarkGUID; } @synthesize tempTitle = _tempTitle; - (instancetype)init { if ((self = [super init])) { - BookmarkModel* model = self.bookmarkModel; - if (!model) { - [self release]; - return nil; - } - - self.uniqueID = [NSString stringWithFormat:@"%lld", model->next_node_id()]; + _bookmarkGUID = base::GUID::GenerateRandomV4(); + self.uniqueID = [NSString + stringWithFormat:@"%s", _bookmarkGUID.AsLowercaseString().c_str()]; self.tempTitle = @""; } return self; } +- (instancetype)initWithBookmarkNode:(const BookmarkNode*)bookmarkNode { + if (!bookmarkNode) { + [self release]; + return nil; + } + + if ((self = [super init])) { + _bookmarkGUID = bookmarkNode->guid(); + self.uniqueID = [NSString + stringWithFormat:@"%s", _bookmarkGUID.AsLowercaseString().c_str()]; + } + return self; +} + - (void)dealloc { [_tempTitle release]; [super dealloc]; } -- (instancetype)initWithBookmarkNode:(const BookmarkNode*)aBookmarkNode { - if (!aBookmarkNode) { - [self release]; - return nil; - } - - if ((self = [super init])) { - // It is safe to be weak, if a bookmark item/folder goes away - // (eg user deleting a folder) the AppleScript runtime calls - // bookmarkFolders/bookmarkItems in BookmarkFolderAppleScript - // and this particular bookmark item/folder is never returned. - _bookmarkNode = aBookmarkNode; - - self.uniqueID = [NSString stringWithFormat:@"%lld", aBookmarkNode->id()]; - } - return self; +- (base::GUID)bookmarkGUID { + return _bookmarkGUID; } -- (void)setBookmarkNode:(const BookmarkNode*)aBookmarkNode { - DCHECK(aBookmarkNode); - // It is safe to be weak, if a bookmark item/folder goes away - // (eg user deleting a folder) the AppleScript runtime calls - // bookmarkFolders/bookmarkItems in BookmarkFolderAppleScript - // and this particular bookmark item/folder is never returned. - _bookmarkNode = aBookmarkNode; +- (void)didCreateBookmarkNode:(const bookmarks::BookmarkNode*)bookmarkNode { + CHECK(bookmarkNode); + CHECK_EQ(bookmarkNode->guid(), _bookmarkGUID); - self.uniqueID = [NSString stringWithFormat:@"%lld", aBookmarkNode->id()]; - - [self setTitle:[self tempTitle]]; + self.title = self.tempTitle; } - (const bookmarks::BookmarkNode*)bookmarkNode { - return _bookmarkNode; + return bookmarks::GetBookmarkNodeByGUID(self.bookmarkModel, _bookmarkGUID); } - (NSString*)title { - if (!_bookmarkNode) { - return _tempTitle; + const BookmarkNode* bookmarkNode = self.bookmarkNode; + if (!bookmarkNode) { + return self.tempTitle; } - return base::SysUTF16ToNSString(_bookmarkNode->GetTitle()); + return base::SysUTF16ToNSString(bookmarkNode->GetTitle()); } -- (void)setTitle:(NSString*)aTitle { +- (void)setTitle:(NSString*)title { // If the scripter enters: // // make new bookmarks folder with properties {title:"foo"} // // the node has not yet been created so title is stored in the temp title. - if (!_bookmarkNode) { - self.tempTitle = aTitle; + const BookmarkNode* bookmarkNode = self.bookmarkNode; + if (!bookmarkNode) { + self.tempTitle = title; return; } @@ -115,13 +110,22 @@ return; } - model->SetTitle(_bookmarkNode, base::SysNSStringToUTF16(aTitle), + model->SetTitle(bookmarkNode, base::SysNSStringToUTF16(title), bookmarks::metrics::BookmarkEditSource::kOther); } - (NSNumber*)index { - const BookmarkNode* parent = _bookmarkNode->parent(); - size_t index = parent->GetIndexOf(_bookmarkNode).value(); + const BookmarkNode* bookmarkNode = self.bookmarkNode; + if (!bookmarkNode) { + return nil; + } + + const BookmarkNode* parent = bookmarkNode->parent(); + if (!parent) { + return nil; + } + + size_t index = parent->GetIndexOf(bookmarkNode).value(); // NOTE: AppleScript is 1-Based. return @(index + 1); }
diff --git a/chrome/browser/ui/startup/first_run_service_dice_statics.cc b/chrome/browser/ui/startup/first_run_service_dice_statics.cc index 15df80a..d2adb2e 100644 --- a/chrome/browser/ui/startup/first_run_service_dice_statics.cc +++ b/chrome/browser/ui/startup/first_run_service_dice_statics.cc
@@ -10,6 +10,7 @@ #include "base/feature_list.h" #include "base/logging.h" #include "base/metrics/field_trial.h" +#include "base/metrics/field_trial_params.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/first_run/first_run.h" #include "chrome/browser/metrics/chrome_metrics_service_accessor.h" @@ -129,8 +130,8 @@ : base::FeatureList::OVERRIDE_DISABLE_FEATURE; if (measurement_feature_state == base::FeatureList::OVERRIDE_ENABLE_FEATURE) { - variations::AssociateVariationParams( - kTrialName, group_name, {{kForYouFreStudyGroup.name, group_name}}); + base::AssociateFieldTrialParams(kTrialName, group_name, + {{kForYouFreStudyGroup.name, group_name}}); } feature_list->RegisterFieldTrialOverride(
diff --git a/chrome/browser/ui/views/autofill/payments/card_unmask_authentication_selection_dialog_browsertest.cc b/chrome/browser/ui/views/autofill/payments/card_unmask_authentication_selection_dialog_browsertest.cc index 2e1e34e..f57f0bd 100644 --- a/chrome/browser/ui/views/autofill/payments/card_unmask_authentication_selection_dialog_browsertest.cc +++ b/chrome/browser/ui/views/autofill/payments/card_unmask_authentication_selection_dialog_browsertest.cc
@@ -3,7 +3,6 @@ // found in the LICENSE file. #include "base/test/metrics/histogram_tester.h" -#include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "chrome/browser/ui/autofill/payments/card_unmask_authentication_selection_dialog_controller_impl.h" #include "chrome/browser/ui/browser.h" @@ -13,7 +12,6 @@ #include "chrome/test/base/ui_test_utils.h" #include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/browser/metrics/autofill_metrics.h" -#include "components/autofill/core/common/autofill_payments_features.h" #include "content/public/test/browser_test.h" namespace autofill { @@ -85,13 +83,10 @@ class CardUnmaskAuthenticationSelectionDialogBrowserTestNonParameterized : public CardUnmaskAuthenticationSelectionDialogBrowserTestBase { public: - CardUnmaskAuthenticationSelectionDialogBrowserTestNonParameterized() { - feature_list_.InitAndEnableFeature( - features::kAutofillEnableCvcForVcnYellowPath); - } - - private: - base::test::ScopedFeatureList feature_list_; + CardUnmaskAuthenticationSelectionDialogBrowserTestNonParameterized() = + default; + ~CardUnmaskAuthenticationSelectionDialogBrowserTestNonParameterized() + override = default; }; // Ensure accepting the CVC challenge option in the selection dialog is @@ -129,46 +124,31 @@ // Parameters of the // CardUnmaskAuthenticationSelectionDialogBrowserTestParameterized. using ChallengeOptionTypes = std::vector<CardUnmaskChallengeOptionType>; -using EnableCvcForVcnYellowPathIsEnabled = bool; // Parameterized version of // CardUnmaskAuthenticationSelectionDialogBrowserTestBase. Should be used to // test the overall functionality of the dialog, across all combinations of -// challenge options and flags related to the dialog. +// challenge options related to the dialog. class CardUnmaskAuthenticationSelectionDialogBrowserTestParameterized : public CardUnmaskAuthenticationSelectionDialogBrowserTestBase, - public testing::WithParamInterface< - std::tuple<ChallengeOptionTypes, - EnableCvcForVcnYellowPathIsEnabled>> { + public testing::WithParamInterface<ChallengeOptionTypes> { public: - CardUnmaskAuthenticationSelectionDialogBrowserTestParameterized() { - feature_list_.InitWithFeatureState( - /*feature=*/features::kAutofillEnableCvcForVcnYellowPath, - /*enabled=*/GetEnableCvcForVcnYellowPathIsEnabled()); - } + CardUnmaskAuthenticationSelectionDialogBrowserTestParameterized() = default; + ~CardUnmaskAuthenticationSelectionDialogBrowserTestParameterized() override = + default; - ChallengeOptionTypes GetChallengeOptionTypes() { - return std::get<0>(GetParam()); - } - - EnableCvcForVcnYellowPathIsEnabled GetEnableCvcForVcnYellowPathIsEnabled() { - return std::get<1>(GetParam()); - } - - private: - base::test::ScopedFeatureList feature_list_; + ChallengeOptionTypes GetChallengeOptionTypes() { return GetParam(); } }; INSTANTIATE_TEST_SUITE_P( , CardUnmaskAuthenticationSelectionDialogBrowserTestParameterized, - testing::Combine(testing::Values( - std::vector<CardUnmaskChallengeOptionType>{ - CardUnmaskChallengeOptionType::kSmsOtp}, - std::vector<CardUnmaskChallengeOptionType>{ - CardUnmaskChallengeOptionType::kSmsOtp, - CardUnmaskChallengeOptionType::kCvc}), - testing::Bool())); + testing::Values( + std::vector<CardUnmaskChallengeOptionType>{ + CardUnmaskChallengeOptionType::kSmsOtp}, + std::vector<CardUnmaskChallengeOptionType>{ + CardUnmaskChallengeOptionType::kSmsOtp, + CardUnmaskChallengeOptionType::kCvc})); // Ensures the UI can be shown. IN_PROC_BROWSER_TEST_P( @@ -181,13 +161,7 @@ EXPECT_THAT( histogram_tester.GetAllSamples( "Autofill.CardUnmaskAuthenticationSelectionDialog.Shown2"), - // If the CVC flag is on, then the count depends on the number of - // challenge options, i.e. `GetParam().size()`. If the CVC flag is - // off, it will always be 1. - base::BucketsAre(base::Bucket(GetEnableCvcForVcnYellowPathIsEnabled() - ? GetChallengeOptionTypes().size() - : 1, - 1))); + base::BucketsAre(base::Bucket(GetChallengeOptionTypes().size(), 1))); } // Ensures closing tab while dialog being visible is correctly handled. @@ -204,13 +178,7 @@ EXPECT_THAT( histogram_tester.GetAllSamples( "Autofill.CardUnmaskAuthenticationSelectionDialog.Shown2"), - // If the CVC flag is on, then the count depends on the number of - // challenge options, i.e. `GetParam().size()`. If the CVC flag is - // off, it will always be 1. - base::BucketsAre(base::Bucket(GetEnableCvcForVcnYellowPathIsEnabled() - ? GetChallengeOptionTypes().size() - : 1, - 1))); + base::BucketsAre(base::Bucket(GetChallengeOptionTypes().size(), 1))); histogram_tester.ExpectUniqueSample( "Autofill.CardUnmaskAuthenticationSelectionDialog.Result", AutofillMetrics::CardUnmaskAuthenticationSelectionDialogResultMetric:: @@ -232,13 +200,7 @@ EXPECT_THAT( histogram_tester.GetAllSamples( "Autofill.CardUnmaskAuthenticationSelectionDialog.Shown2"), - // If the CVC flag is on, then the count depends on the number of - // challenge options, i.e. `GetParam().size()`. If the CVC flag is - // off, it will always be 1. - base::BucketsAre(base::Bucket(GetEnableCvcForVcnYellowPathIsEnabled() - ? GetChallengeOptionTypes().size() - : 1, - 1))); + base::BucketsAre(base::Bucket(GetChallengeOptionTypes().size(), 1))); histogram_tester.ExpectUniqueSample( "Autofill.CardUnmaskAuthenticationSelectionDialog.Result", AutofillMetrics::CardUnmaskAuthenticationSelectionDialogResultMetric::
diff --git a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.cc b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.cc index fda00f2..d9d28bea 100644 --- a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.cc +++ b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.cc
@@ -400,7 +400,7 @@ SavedTabGroupUpdated(group_guid); } -void SavedTabGroupBar::OnWidgetClosing(views::Widget* widget) { +void SavedTabGroupBar::OnWidgetDestroying(views::Widget* widget) { widget_observation_.Reset(); overflow_menu_ = nullptr; bubble_delegate_ = nullptr;
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 31c9cb0..260d047b 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
@@ -81,7 +81,7 @@ const absl::optional<base::GUID>& tab_guid = absl::nullopt) override; // WidgetObserver - void OnWidgetClosing(views::Widget* widget) override; + void OnWidgetDestroying(views::Widget* widget) override; // Calculates what the visible width would be when a restriction on width is // placed on the bar.
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_details_view.cc b/chrome/browser/ui/views/passwords/manage_passwords_details_view.cc index f85fb7d..fea03eaf 100644 --- a/chrome/browser/ui/views/passwords/manage_passwords_details_view.cc +++ b/chrome/browser/ui/views/passwords/manage_passwords_details_view.cc
@@ -55,6 +55,20 @@ scw.WriteText(text); } +// Computes the margins of each row. This adjusts the left margin equal to the +// dialog left margin + the back button insets to make sure all icons are +// vertically aligned with the back button. +gfx::Insets ComputeRowMargins() { + ChromeLayoutProvider* layout_provider = ChromeLayoutProvider::Get(); + gfx::Insets margins = layout_provider->GetInsetsMetric(views::INSETS_DIALOG); + margins.set_top_bottom(0, 0); + margins.set_left( + margins.left() + + layout_provider->GetInsetsMetric(views::INSETS_VECTOR_IMAGE_BUTTON) + .left()); + return margins; +} + std::unique_ptr<views::View> CreateIconView( const gfx::VectorIcon& vector_icon) { // TODO(crbug.com/1408790): Double check if it should always be not accessible @@ -120,6 +134,7 @@ std::unique_ptr<views::View> detail_view) { auto row = std::make_unique<views::FlexLayoutView>(); row->SetCollapseMargins(true); + row->SetInteriorMargin(ComputeRowMargins()); row->SetDefault( views::kMarginsKey, gfx::Insets::VH(0, ChromeLayoutProvider::Get()->GetDistanceMetric( @@ -247,6 +262,7 @@ DCHECK(form.username_value.empty()); auto row = std::make_unique<views::FlexLayoutView>(); row->SetCollapseMargins(true); + row->SetInteriorMargin(ComputeRowMargins()); row->SetDefault( views::kMarginsKey, gfx::Insets::VH(0, ChromeLayoutProvider::Get()->GetDistanceMetric( @@ -282,6 +298,7 @@ raw_ptr<views::Label>* error_label) { auto row = std::make_unique<views::FlexLayoutView>(); row->SetCollapseMargins(true); + row->SetInteriorMargin(ComputeRowMargins()); row->SetDefault( views::kMarginsKey, gfx::Insets::VH(0, ChromeLayoutProvider::Get()->GetDistanceMetric( @@ -375,8 +392,7 @@ PasswordManagementBubbleInteractions:: kUsernameCopyButtonClicked)); AddChildView(CreateDetailsRowWithActionButton( - kAccountCircleIcon, std::move(username_label), - vector_icons::kContentCopyIcon, + kAccountCircleIcon, std::move(username_label), kCopyIcon, l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_UI_COPY_USERNAME), std::move(copy_username_button_callback), ManagePasswordsViewIDs::kCopyUsernameButton)); @@ -418,7 +434,7 @@ kKeyIcon, CreatePasswordLabelWithEyeIconView(std::move(password_label), on_activity_callback_), - vector_icons::kContentCopyIcon, + kCopyIcon, l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_UI_COPY_PASSWORD), std::move(copy_password_button_callback), ManagePasswordsViewIDs::kCopyPasswordButton));
diff --git a/chrome/browser/ui/views/tabs/tab_style_views.cc b/chrome/browser/ui/views/tabs/tab_style_views.cc index 55cd5bc..e222f8f 100644 --- a/chrome/browser/ui/views/tabs/tab_style_views.cc +++ b/chrome/browser/ui/views/tabs/tab_style_views.cc
@@ -31,6 +31,7 @@ #include "third_party/skia/include/core/SkScalar.h" #include "third_party/skia/include/pathops/SkPathOps.h" #include "ui/base/theme_provider.h" +#include "ui/base/ui_base_features.h" #include "ui/gfx/canvas.h" #include "ui/gfx/font_list.h" #include "ui/gfx/geometry/skia_conversions.h" @@ -48,6 +49,33 @@ // Exclude the lower right arc. constexpr ShapeModifier kNoLowerRightArc = 0x02; +void DrawHighlight(gfx::Canvas* canvas, + const SkPoint& p, + SkScalar radius, + SkColor color) { + // TODO(crbug/1308932): Remove FromColor and make all SkColor4f. + const SkColor4f colors[2] = { + SkColor4f::FromColor(color), + SkColor4f::FromColor(SkColorSetA(color, SK_AlphaTRANSPARENT))}; + cc::PaintFlags flags; + flags.setAntiAlias(true); + flags.setShader(cc::PaintShader::MakeRadialGradient( + p, radius, colors, nullptr, 2, SkTileMode::kClamp)); + canvas->sk_canvas()->drawRect( + SkRect::MakeXYWH(p.x() - radius, p.y() - radius, radius * 2, radius * 2), + flags); +} + +// Updates a target value, returning true if it changed. +template <class T> +bool UpdateValue(T* dest, const T& src) { + if (*dest == src) { + return false; + } + *dest = src; + return true; +} + // Tab style implementation for the GM2 refresh (Chrome 69). class GM2TabStyle : public TabStyleViews { public: @@ -55,6 +83,8 @@ GM2TabStyle(const GM2TabStyle&) = delete; GM2TabStyle& operator=(const GM2TabStyle&) = delete; + const Tab* tab() const { return tab_; } + protected: // TabStyle: SkPath GetPath( @@ -72,6 +102,9 @@ void ShowHover(ShowHoverStyle style) override; void HideHover(HideHoverStyle style) override; + // Painting helper functions: + virtual SkColor GetTabBackgroundColor(TabActive active) const; + private: // Gets the bounds for the leading and trailing separators for a tab. SeparatorBounds GetSeparatorBounds(float scale) const; @@ -118,8 +151,6 @@ bool ShouldPaintTabBackgroundColor(TabActive active, bool has_custom_background) const; - SkColor GetTabBackgroundColor(TabActive active) const; - // When selected, non-active, non-hovered tabs are adjacent to each other, // there are anti-aliasing artifacts in the overlapped lower arc region. This // returns how to modify the tab shape to eliminate the lower arcs on the @@ -156,32 +187,6 @@ std::unique_ptr<GlowHoverController> hover_controller_; }; -void DrawHighlight(gfx::Canvas* canvas, - const SkPoint& p, - SkScalar radius, - SkColor color) { - // TODO(crbug/1308932): Remove FromColor and make all SkColor4f. - const SkColor4f colors[2] = { - SkColor4f::FromColor(color), - SkColor4f::FromColor(SkColorSetA(color, SK_AlphaTRANSPARENT))}; - cc::PaintFlags flags; - flags.setAntiAlias(true); - flags.setShader(cc::PaintShader::MakeRadialGradient( - p, radius, colors, nullptr, 2, SkTileMode::kClamp)); - canvas->sk_canvas()->drawRect( - SkRect::MakeXYWH(p.x() - radius, p.y() - radius, radius * 2, radius * 2), - flags); -} - -// Updates a target value, returning true if it changed. -template <class T> -bool UpdateValue(T* dest, const T& src) { - if (*dest == src) - return false; - *dest = src; - return true; -} - // GM2TabStyle ----------------------------------------------------------------- GM2TabStyle::GM2TabStyle(Tab* tab) @@ -947,6 +952,31 @@ return aligned_bounds; } +class GM3TabStyle : public GM2TabStyle { + public: + explicit GM3TabStyle(Tab* tab); + SkColor GetTabBackgroundColor(TabActive active) const override; +}; + +GM3TabStyle::GM3TabStyle(Tab* tab) : GM2TabStyle(tab) {} + +SkColor GM3TabStyle::GetTabBackgroundColor(TabActive active) const { + const auto* cp = tab()->GetWidget()->GetColorProvider(); + DCHECK(cp); + if (!cp) { + return gfx::kPlaceholderColor; + } + + constexpr ChromeColorIds kColorIds[2][2] = { + {kColorTabBackgroundInactiveFrameInactive, + kColorTabBackgroundInactiveFrameActive}, + {kColorTabBackgroundActiveFrameInactive, + kColorTabBackgroundActiveFrameActive}}; + + return cp->GetColor(kColorIds[int(active == TabActive::kActive)][int( + tab()->controller()->ShouldPaintAsActiveFrame())]); +} + } // namespace // static @@ -997,6 +1027,10 @@ // static std::unique_ptr<TabStyleViews> TabStyleViews::CreateForTab(Tab* tab) { + // If refresh is turned on use GM3 styling. + if (features::IsChromeRefresh2023()) { + return std::make_unique<GM3TabStyle>(tab); + } return std::make_unique<GM2TabStyle>(tab); }
diff --git a/chrome/browser/ui/webui/chrome_webui_navigation_browsertest.cc b/chrome/browser/ui/webui/chrome_webui_navigation_browsertest.cc index 945753b3..6402e76 100644 --- a/chrome/browser/ui/webui/chrome_webui_navigation_browsertest.cc +++ b/chrome/browser/ui/webui/chrome_webui_navigation_browsertest.cc
@@ -43,8 +43,8 @@ DisallowEmbeddingChromeSchemeFromWebFrameBrowserCheck) { GURL main_frame_url(embedded_test_server()->GetURL("/title1.html")); auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); - auto* main_frame = web_contents->GetPrimaryMainFrame(); EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); + auto* main_frame = web_contents->GetPrimaryMainFrame(); // Add iframe but don't navigate it to a chrome:// URL yet. EXPECT_TRUE(content::ExecJs(main_frame, @@ -76,8 +76,8 @@ DisallowEmbeddingChromeUntrustedSchemeFromWebFrameBrowserCheck) { GURL main_frame_url(embedded_test_server()->GetURL("/title1.html")); auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); - auto* main_frame = web_contents->GetPrimaryMainFrame(); EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); + auto* main_frame = web_contents->GetPrimaryMainFrame(); // Add iframe but don't navigate it to a chrome-untrusted:// URL yet. EXPECT_TRUE(content::ExecJs(main_frame,
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page.mojom b/chrome/browser/ui/webui/new_tab_page/new_tab_page.mojom index e364b061..0a7ce1d 100644 --- a/chrome/browser/ui/webui/new_tab_page/new_tab_page.mojom +++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page.mojom
@@ -318,6 +318,8 @@ // Increment the number of times the user has opened the side panel // with the customize chrome button. IncrementCustomizeChromeButtonOpenCount(); + // Attempts to trigger in product help for customize chrome. + MaybeShowCustomizeChromeFeaturePromo(); // ======= METRICS ======= // Logs that the One Google Bar was added to the DOM / loaded in an iframe at
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc index 17d4dff..67826b3c 100644 --- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc +++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc
@@ -30,6 +30,7 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "chrome/browser/new_tab_page/customize_chrome/customize_chrome_feature_promo_helper.h" #include "chrome/browser/new_tab_page/modules/new_tab_page_modules.h" #include "chrome/browser/new_tab_page/promos/promo_service_factory.h" #include "chrome/browser/profiles/profile.h" @@ -460,6 +461,8 @@ ThemeService* theme_service, search_provider_logos::LogoService* logo_service, content::WebContents* web_contents, + std::unique_ptr<CustomizeChromeFeaturePromoHelper> + customize_chrome_feature_promo_helper, const base::Time& ntp_navigation_start_time, const std::vector<std::pair<const std::string, int>> module_id_names) : ntp_background_service_( @@ -470,6 +473,8 @@ theme_service_(theme_service), profile_(profile), web_contents_(web_contents), + customize_chrome_feature_promo_helper_( + std::move(customize_chrome_feature_promo_helper)), ntp_navigation_start_time_(ntp_navigation_start_time), module_id_names_(module_id_names), logger_(profile, @@ -484,6 +489,7 @@ CHECK(theme_service_); CHECK(promo_service_); CHECK(web_contents_); + CHECK(customize_chrome_feature_promo_helper_); ntp_background_service_->AddObserver(this); native_theme_observation_.Observe(ui::NativeTheme::GetInstanceForNativeUi()); theme_service_observation_.Observe(theme_service_.get()); @@ -873,6 +879,15 @@ CustomizeChromeTabHelper::FromWebContents(web_contents_); customize_chrome_tab_helper->SetCustomizeChromeSidePanelVisible(visible, section_enum); + + if (visible) { + // Record usage for customize chrome promo. + auto* tab = web_contents_.get(); + customize_chrome_feature_promo_helper_->RecordCustomizeChromeFeatureUsage( + tab); + customize_chrome_feature_promo_helper_->CloseCustomizeChromeFeaturePromo( + tab); + } } void NewTabPageHandler::IncrementCustomizeChromeButtonOpenCount() { @@ -885,6 +900,18 @@ 1); } +void NewTabPageHandler::MaybeShowCustomizeChromeFeaturePromo() { + CHECK(profile_); + CHECK(profile_->GetPrefs()); + const auto customize_chrome_button_open_count = + profile_->GetPrefs()->GetInteger( + prefs::kNtpCustomizeChromeButtonOpenCount); + if (customize_chrome_button_open_count == 0) { + customize_chrome_feature_promo_helper_ + ->MaybeShowCustomizeChromeFeaturePromo(web_contents_.get()); + } +} + void NewTabPageHandler::OnPromoDataUpdated() { if (promo_load_start_time_.has_value()) { base::TimeDelta duration = base::TimeTicks::Now() - *promo_load_start_time_;
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.h b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.h index e388d907..182721a3 100644 --- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.h +++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.h
@@ -14,6 +14,7 @@ #include "base/memory/weak_ptr.h" #include "base/scoped_observation.h" #include "base/time/time.h" +#include "chrome/browser/new_tab_page/customize_chrome/customize_chrome_feature_promo_helper.h" #include "chrome/browser/new_tab_page/promos/promo_service.h" #include "chrome/browser/new_tab_page/promos/promo_service_observer.h" #include "chrome/browser/search/background/ntp_background_service_observer.h" @@ -40,6 +41,7 @@ class NtpBackgroundService; class Profile; class NTPUserDataLogger; +class CustomizeChromeFeaturePromoHelper; namespace content { class WebContents; @@ -70,6 +72,8 @@ ThemeService* theme_service, search_provider_logos::LogoService* logo_service, content::WebContents* web_contents, + std::unique_ptr<CustomizeChromeFeaturePromoHelper> + customize_chrome_feature_promo_helper, const base::Time& ntp_navigation_start_time, const std::vector<std::pair<const std::string, int>> module_id_names); @@ -126,6 +130,7 @@ bool visible, new_tab_page::mojom::CustomizeChromeSection section) override; void IncrementCustomizeChromeButtonOpenCount() override; + void MaybeShowCustomizeChromeFeaturePromo() override; void OnAppRendered(double time) override; void OnOneGoogleBarRendered(double time) override; void OnPromoRendered(double time, @@ -208,6 +213,8 @@ raw_ptr<Profile> profile_; scoped_refptr<ui::SelectFileDialog> select_file_dialog_; raw_ptr<content::WebContents> web_contents_; + std::unique_ptr<CustomizeChromeFeaturePromoHelper> + customize_chrome_feature_promo_helper_; base::Time ntp_navigation_start_time_; const std::vector<std::pair<const std::string, int>> module_id_names_; NTPUserDataLogger logger_;
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler_unittest.cc b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler_unittest.cc index 34feeea..4a80c603 100644 --- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler_unittest.cc +++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler_unittest.cc
@@ -14,6 +14,7 @@ #include "base/test/metrics/histogram_tester.h" #include "base/test/mock_callback.h" #include "base/test/scoped_feature_list.h" +#include "chrome/browser/new_tab_page/customize_chrome/customize_chrome_feature_promo_helper.h" #include "chrome/browser/new_tab_page/promos/promo_data.h" #include "chrome/browser/new_tab_page/promos/promo_service.h" #include "chrome/browser/new_tab_page/promos/promo_service_factory.h" @@ -193,6 +194,25 @@ : CustomizeChromeTabHelper(web_contents) {} }; +class MockCustomizeChromeFeaturePromoHelper + : public CustomizeChromeFeaturePromoHelper { + public: + MOCK_METHOD(void, + RecordCustomizeChromeFeatureUsage, + (content::WebContents*), + (override)); + MOCK_METHOD(void, + MaybeShowCustomizeChromeFeaturePromo, + (content::WebContents*), + (override)); + MOCK_METHOD(void, + CloseCustomizeChromeFeaturePromo, + (content::WebContents*), + (override)); + + ~MockCustomizeChromeFeaturePromoHelper() override = default; +}; + std::unique_ptr<TestingProfile> MakeTestingProfile( scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) { TestingProfile::Builder profile_builder; @@ -222,6 +242,11 @@ mock_promo_service_(*static_cast<MockPromoService*>( PromoServiceFactory::GetForProfile(profile_.get()))), web_contents_(factory_.CreateWebContents(profile_.get())), + mock_customize_chrome_feature_promo_helper_( + new MockCustomizeChromeFeaturePromoHelper()), + mock_customize_chrome_feature_promo_helper_ptr_( + std::unique_ptr<MockCustomizeChromeFeaturePromoHelper>( + mock_customize_chrome_feature_promo_helper_)), mock_customize_chrome_tab_helper_( MockCustomizeChromeTabHelper::CreateForWebContents( web_contents_.get())) { @@ -258,7 +283,9 @@ mojo::PendingReceiver<new_tab_page::mojom::PageHandler>(), mock_page_.BindAndGetRemote(), profile_.get(), &mock_ntp_custom_background_service_, &mock_theme_service_, - &mock_logo_service_, web_contents_, base::Time::Now(), module_id_names); + &mock_logo_service_, web_contents_, + std::move(mock_customize_chrome_feature_promo_helper_ptr_), + base::Time::Now(), module_id_names); mock_page_.FlushForTesting(); EXPECT_EQ(handler_.get(), theme_service_observer_); EXPECT_EQ(handler_.get(), ntp_custom_background_service_observer_); @@ -312,6 +339,11 @@ const raw_ref<MockPromoService> mock_promo_service_; content::TestWebContentsFactory factory_; raw_ptr<content::WebContents> web_contents_; // Weak. Owned by factory_. + // Pointer to mock that will eventually be solely owned by the handler. + MockCustomizeChromeFeaturePromoHelper* + mock_customize_chrome_feature_promo_helper_; + std::unique_ptr<MockCustomizeChromeFeaturePromoHelper> + mock_customize_chrome_feature_promo_helper_ptr_; raw_ptr<MockCustomizeChromeTabHelper> mock_customize_chrome_tab_helper_; base::HistogramTester histogram_tester_; std::unique_ptr<NewTabPageHandler> handler_; @@ -1056,6 +1088,12 @@ .Times(1) .WillOnce(testing::DoAll(testing::SaveArg<0>(&visible), testing::SaveArg<1>(§ion))); + EXPECT_CALL(*mock_customize_chrome_feature_promo_helper_, + RecordCustomizeChromeFeatureUsage) + .Times(1); + EXPECT_CALL(*mock_customize_chrome_feature_promo_helper_, + CloseCustomizeChromeFeaturePromo) + .Times(1); handler_->SetCustomizeChromeSidePanelVisible( /*visible=*/true, @@ -1073,6 +1111,12 @@ .Times(1) .WillOnce(testing::DoAll(testing::SaveArg<0>(&visible), testing::SaveArg<1>(§ion))); + EXPECT_CALL(*mock_customize_chrome_feature_promo_helper_, + RecordCustomizeChromeFeatureUsage) + .Times(0); + EXPECT_CALL(*mock_customize_chrome_feature_promo_helper_, + CloseCustomizeChromeFeaturePromo) + .Times(0); handler_->SetCustomizeChromeSidePanelVisible( /*visible=*/false, new_tab_page::mojom::CustomizeChromeSection::kModules); @@ -1100,3 +1144,26 @@ mock_page_.FlushForTesting(); } + +TEST_F(NewTabPageHandlerTest, MaybeShowCustomizeChromeFeaturePromo) { + EXPECT_EQ(profile_->GetPrefs()->GetInteger( + prefs::kNtpCustomizeChromeButtonOpenCount), + 0); + EXPECT_CALL(*mock_customize_chrome_feature_promo_helper_, + MaybeShowCustomizeChromeFeaturePromo) + .Times(1); + + handler_->MaybeShowCustomizeChromeFeaturePromo(); + + handler_->IncrementCustomizeChromeButtonOpenCount(); + EXPECT_EQ(profile_->GetPrefs()->GetInteger( + prefs::kNtpCustomizeChromeButtonOpenCount), + 1); + EXPECT_CALL(*mock_customize_chrome_feature_promo_helper_, + MaybeShowCustomizeChromeFeaturePromo) + .Times(0); + + handler_->MaybeShowCustomizeChromeFeaturePromo(); + + mock_page_.FlushForTesting(); +}
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc index dba920e..03e70a2 100644 --- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc +++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
@@ -19,6 +19,7 @@ #include "chrome/browser/buildflags.h" #include "chrome/browser/cart/cart_handler.h" #include "chrome/browser/image_service/image_service_factory.h" +#include "chrome/browser/new_tab_page/customize_chrome/customize_chrome_feature_promo_helper.h" #include "chrome/browser/new_tab_page/modules/drive/drive_handler.h" #include "chrome/browser/new_tab_page/modules/feed/feed_handler.h" #include "chrome/browser/new_tab_page/modules/history_clusters/history_clusters.mojom.h" @@ -823,6 +824,7 @@ std::move(pending_page_handler), std::move(pending_page), profile_, ntp_custom_background_service_, theme_service_, LogoServiceFactory::GetForProfile(profile_), web_contents(), + std::make_unique<CustomizeChromeFeaturePromoHelper>(), navigation_start_time_, module_id_names_); }
diff --git a/chrome/browser/ui/webui/password_manager/password_manager_ui.cc b/chrome/browser/ui/webui/password_manager/password_manager_ui.cc index d789c52..6e08a4e 100644 --- a/chrome/browser/ui/webui/password_manager/password_manager_ui.cc +++ b/chrome/browser/ui/webui/password_manager/password_manager_ui.cc
@@ -101,6 +101,7 @@ IDS_PASSWORD_MANAGER_UI_NO_COMPROMISED_PASSWORDS}, {"compromisedPasswordsTitle", IDS_PASSWORD_MANAGER_UI_HAS_COMPROMISED_PASSWORDS}, + {"controlledByExtension", IDS_SETTINGS_CONTROLLED_BY_EXTENSION}, {"copyPassword", IDS_PASSWORD_MANAGER_UI_COPY_PASSWORD}, {"copyUsername", IDS_PASSWORD_MANAGER_UI_COPY_USERNAME}, {"deletePassword", IDS_DELETE},
diff --git a/chrome/browser/ui/webui/settings/ash/accessibility_section.cc b/chrome/browser/ui/webui/settings/ash/accessibility_section.cc index 5464cee3..5246114c 100644 --- a/chrome/browser/ui/webui/settings/ash/accessibility_section.cc +++ b/chrome/browser/ui/webui/settings/ash/accessibility_section.cc
@@ -22,6 +22,7 @@ #include "chrome/browser/speech/extension_api/tts_engine_extension_observer_chromeos.h" #include "chrome/browser/ui/webui/settings/accessibility_main_handler.h" #include "chrome/browser/ui/webui/settings/ash/accessibility_handler.h" +#include "chrome/browser/ui/webui/settings/ash/pdf_ocr_handler.h" #include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/ash/select_to_speak_handler.h" #include "chrome/browser/ui/webui/settings/ash/switch_access_handler.h" @@ -745,6 +746,10 @@ {"onScreenKeyboardLabel", IDS_SETTINGS_ON_SCREEN_KEYBOARD_LABEL}, {"optionsInMenuDescription", IDS_SETTINGS_OPTIONS_IN_MENU_DESCRIPTION}, {"optionsInMenuLabel", IDS_SETTINGS_OPTIONS_IN_MENU_LABEL}, + {"pdfOcrDownloadCompleteLabel", IDS_SETTINGS_PDF_OCR_DOWNLOAD_COMPLETE}, + {"pdfOcrDownloadErrorLabel", IDS_SETTINGS_PDF_OCR_DOWNLOAD_ERROR}, + {"pdfOcrDownloadProgressLabel", IDS_SETTINGS_PDF_OCR_DOWNLOAD_PROGRESS}, + {"pdfOcrDownloadingLabel", IDS_SETTINGS_PDF_OCR_DOWNLOADING}, {"pdfOcrSubtitle", IDS_SETTINGS_PDF_OCR_SUBTITLE}, {"pdfOcrTitle", IDS_SETTINGS_PDF_OCR_TITLE}, {"percentage", IDS_SETTINGS_PERCENTAGE}, @@ -1050,6 +1055,9 @@ std::make_unique<::settings::FontHandler>(profile())); web_ui->AddMessageHandler( std::make_unique<::settings::CaptionsHandler>(profile()->GetPrefs())); + if (base::FeatureList::IsEnabled(::features::kPdfOcr)) { + web_ui->AddMessageHandler(std::make_unique<::settings::PdfOcrHandler>()); + } } int AccessibilitySection::GetSectionNameMessageId() const {
diff --git a/chrome/browser/ui/webui/settings/ash/device_section.cc b/chrome/browser/ui/webui/settings/ash/device_section.cc index 3adcf78..4ed28a29 100644 --- a/chrome/browser/ui/webui/settings/ash/device_section.cc +++ b/chrome/browser/ui/webui/settings/ash/device_section.cc
@@ -197,6 +197,18 @@ mojom::SearchResultDefaultRank::kMedium, mojom::SearchResultType::kSetting, {.setting = mojom::Setting::kKeyboardFunctionKeys}}, + {IDS_OS_SETTINGS_TAG_KEYBOARD_BLOCK_META_FKEY_COMBO_REWRITES, + mojom::kPerDeviceKeyboardSubpagePath, + mojom::SearchResultIcon::kKeyboard, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSetting, + {.setting = mojom::Setting::kKeyboardBlockMetaFkeyRewrites}}, + {IDS_OS_SETTINGS_TAG_KEYBOARD_REMAP_KEYS, + mojom::kPerDeviceKeyboardSubpagePath, + mojom::SearchResultIcon::kKeyboard, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSetting, + {.setting = mojom::Setting::kKeyboardRemapKeys}}, }); return *tags; } @@ -1287,6 +1299,13 @@ mojom::SearchResultDefaultRank::kMedium, mojom::kPerDeviceKeyboardRemapKeysSubpagePath); + static constexpr mojom::Setting kPerDeviceKeyboardSettings[] = { + mojom::Setting::kKeyboardBlockMetaFkeyRewrites, + mojom::Setting::kKeyboardRemapKeys, + }; + RegisterNestedSettingBulk(mojom::Subpage::kPerDeviceKeyboard, + kPerDeviceKeyboardSettings, generator); + // Per-device Mouse. generator->RegisterTopLevelSubpage(IDS_SETTINGS_MOUSE_TITLE, mojom::Subpage::kPerDeviceMouse,
diff --git a/chrome/browser/ui/webui/settings/ash/device_section_unittest.cc b/chrome/browser/ui/webui/settings/ash/device_section_unittest.cc index 6668e07..b4ce8460 100644 --- a/chrome/browser/ui/webui/settings/ash/device_section_unittest.cc +++ b/chrome/browser/ui/webui/settings/ash/device_section_unittest.cc
@@ -21,6 +21,7 @@ namespace mojom { +using ::chromeos::settings::mojom::Setting; using ::chromeos::settings::mojom::Subpage; } // namespace mojom @@ -33,6 +34,8 @@ .subpage = mojom::Subpage::kKeyboard}; constexpr OsSettingsIdentifier kPerDeviceKeyboardOsSettingsId = { .subpage = mojom::Subpage::kPerDeviceKeyboard}; +constexpr OsSettingsIdentifier kKeyboardBlockMetaFkeyRewritesOsSettingsId = { + .setting = mojom::Setting::kKeyboardBlockMetaFkeyRewrites}; // Provides a correctly formatted result_id based on `SearchConcept` // configuration in `device_section.cc`. Based on private static function in @@ -43,6 +46,12 @@ return ss.str(); } +std::string GetSettingsSearchResultId(OsSettingsIdentifier id, int message_id) { + std::stringstream ss; + ss << id.setting << "," << message_id; + return ss.str(); +} + } // namespace // Test for the device settings page. @@ -119,7 +128,11 @@ std::string result_id = GetSubpageSearchResultId( kPerDeviceKeyboardOsSettingsId, IDS_OS_SETTINGS_TAG_KEYBOARD); + std::string switch_top_row_key_id = GetSettingsSearchResultId( + kKeyboardBlockMetaFkeyRewritesOsSettingsId, + IDS_OS_SETTINGS_TAG_KEYBOARD_BLOCK_META_FKEY_COMBO_REWRITES); EXPECT_TRUE(search_tag_registry()->GetTagMetadata(result_id)); + EXPECT_TRUE(search_tag_registry()->GetTagMetadata(switch_top_row_key_id)); } // Verify registry updated with regular settings search tags when flag is @@ -131,7 +144,11 @@ std::string result_id = GetSubpageSearchResultId( kKeyboardOsSettingsId, IDS_OS_SETTINGS_TAG_KEYBOARD); + std::string switch_top_row_key_id = GetSettingsSearchResultId( + kKeyboardBlockMetaFkeyRewritesOsSettingsId, + IDS_OS_SETTINGS_TAG_KEYBOARD_BLOCK_META_FKEY_COMBO_REWRITES); EXPECT_TRUE(search_tag_registry()->GetTagMetadata(result_id)); + EXPECT_FALSE(search_tag_registry()->GetTagMetadata(switch_top_row_key_id)); } } // namespace ash::settings
diff --git a/chrome/browser/ui/webui/settings/ash/pdf_ocr_handler.cc b/chrome/browser/ui/webui/settings/ash/pdf_ocr_handler.cc new file mode 100644 index 0000000..7920260 --- /dev/null +++ b/chrome/browser/ui/webui/settings/ash/pdf_ocr_handler.cc
@@ -0,0 +1,64 @@ +// 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 <string> + +#include "base/feature_list.h" +#include "chrome/browser/ui/webui/settings/ash/pdf_ocr_handler.h" +#include "chrome/grit/generated_resources.h" +#include "components/services/screen_ai/public/cpp/screen_ai_install_state.h" +#include "ui/accessibility/accessibility_features.h" +#include "ui/base/l10n/l10n_util.h" + +namespace { + +constexpr char kPdfOcrStateChangedEventName[] = "pdf-ocr-state-changed"; +constexpr char kPdfOcrDownloadingProgressChangedEventName[] = + "pdf-ocr-downloading-progress-changed"; + +} // namespace + +namespace settings { + +PdfOcrHandler::PdfOcrHandler() { + DCHECK(base::FeatureList::IsEnabled(features::kPdfOcr)); +} + +PdfOcrHandler::~PdfOcrHandler() { + screen_ai::ScreenAIInstallState::GetInstance()->RemoveObserver(this); +} + +void PdfOcrHandler::RegisterMessages() { + VLOG(2) << "Registering a UI handler for the PDF OCR toggle on Settings"; + web_ui()->RegisterMessageCallback( + "pdfOcrSectionReady", + base::BindRepeating(&PdfOcrHandler::HandlePdfOcrSectionReady, + base::Unretained(this))); +} + +void PdfOcrHandler::OnJavascriptAllowed() { + screen_ai::ScreenAIInstallState::GetInstance()->AddObserver(this); +} + +void PdfOcrHandler::OnJavascriptDisallowed() { + screen_ai::ScreenAIInstallState::GetInstance()->RemoveObserver(this); +} + +void PdfOcrHandler::HandlePdfOcrSectionReady(const base::Value::List& args) { + AllowJavascript(); +} + +void PdfOcrHandler::DownloadProgressChanged(double progress) { + const int progress_num = progress * 100; + VLOG(2) << "Downloading progress: " << progress_num << "%"; + FireWebUIListener(kPdfOcrDownloadingProgressChangedEventName, + base::Value(progress_num)); +} + +void PdfOcrHandler::StateChanged(screen_ai::ScreenAIInstallState::State state) { + base::Value state_value = base::Value(static_cast<int>(state)); + FireWebUIListener(kPdfOcrStateChangedEventName, state_value); +} + +} // namespace settings
diff --git a/chrome/browser/ui/webui/settings/ash/pdf_ocr_handler.h b/chrome/browser/ui/webui/settings/ash/pdf_ocr_handler.h new file mode 100644 index 0000000..ceb5009 --- /dev/null +++ b/chrome/browser/ui/webui/settings/ash/pdf_ocr_handler.h
@@ -0,0 +1,47 @@ +// 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_UI_WEBUI_SETTINGS_ASH_PDF_OCR_HANDLER_H_ +#define CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_PDF_OCR_HANDLER_H_ + +#include "base/memory/weak_ptr.h" +#include "base/scoped_observation.h" +#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" +#include "components/services/screen_ai/public/cpp/screen_ai_install_state.h" + +namespace settings { + +// Settings handler for the PDF OCR settings subpage +class PdfOcrHandler : public SettingsPageUIHandler, + public screen_ai::ScreenAIInstallState::Observer { + public: + PdfOcrHandler(); + + PdfOcrHandler(const PdfOcrHandler&) = delete; + PdfOcrHandler& operator=(const PdfOcrHandler&) = delete; + + ~PdfOcrHandler() override; + + // SettingsPageUIHandler: + void RegisterMessages() override; + void OnJavascriptAllowed() override; + void OnJavascriptDisallowed() override; + + // screen_ai::ScreenAIInstallState::Observer: + void DownloadProgressChanged(double progress) override; + void StateChanged(screen_ai::ScreenAIInstallState::State state) override; + + void HandlePdfOcrSectionReady(const base::Value::List& args); + + private: + base::ScopedObservation<screen_ai::ScreenAIInstallState, + screen_ai::ScreenAIInstallState::Observer> + component_ready_observer{this}; + + base::WeakPtrFactory<PdfOcrHandler> weak_factory_{this}; +}; + +} // namespace settings + +#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_PDF_OCR_HANDLER_H_
diff --git a/chrome/browser/ui/webui/settings/ash/pdf_ocr_handler_unittest.cc b/chrome/browser/ui/webui/settings/ash/pdf_ocr_handler_unittest.cc new file mode 100644 index 0000000..a52c8130 --- /dev/null +++ b/chrome/browser/ui/webui/settings/ash/pdf_ocr_handler_unittest.cc
@@ -0,0 +1,233 @@ +// 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/webui/settings/ash/pdf_ocr_handler.h" +#include <memory> + +#include "base/test/scoped_feature_list.h" +#include "chrome/test/base/testing_profile.h" +#include "components/services/screen_ai/public/cpp/screen_ai_install_state.h" +#include "content/public/browser/web_contents.h" +#include "content/public/test/browser_task_environment.h" +#include "content/public/test/test_web_ui.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/accessibility/accessibility_features.h" + +namespace settings { + +namespace { + +const char kPdfOcrDownloadingProgressChangedEventName[] = + "pdf-ocr-downloading-progress-changed"; +const char kPdfOcrStateChangedEventName[] = "pdf-ocr-state-changed"; +const char kPdfSectionReadyCallback[] = "pdfOcrSectionReady"; +const char kWebUIListenerCall[] = "cr.webUIListenerCallback"; + +class TestScreenAIInstallState : public screen_ai::ScreenAIInstallState { + public: + TestScreenAIInstallState() = default; + + TestScreenAIInstallState(const TestScreenAIInstallState&) = delete; + TestScreenAIInstallState& operator=(const TestScreenAIInstallState&) = delete; + + ~TestScreenAIInstallState() = default; +}; + +class TestPdfOcrHandler : public PdfOcrHandler { + public: + explicit TestPdfOcrHandler(TestScreenAIInstallState* screen_ai_install_state) + : test_screen_ai_install_state_(screen_ai_install_state) {} + + ~TestPdfOcrHandler() override { + test_screen_ai_install_state_->RemoveObserver(this); + } + + // Override this function to add an observer to the screen ai state created + // for testing. + void OnJavascriptAllowed() override { + test_screen_ai_install_state_->AddObserver(this); + } + + // Override this function to remove an observer from the screen ai state + // created for testing. + void OnJavascriptDisallowed() override { + test_screen_ai_install_state_->RemoveObserver(this); + } + + // Make public for testing. + using PdfOcrHandler::AllowJavascript; + using PdfOcrHandler::RegisterMessages; + using PdfOcrHandler::set_web_ui; + + private: + TestScreenAIInstallState* test_screen_ai_install_state_ = nullptr; +}; + +} // namespace + +class PdfOcrHandlerTest : public testing::Test { + public: + PdfOcrHandlerTest() : enable_pdf_ocr_({features::kPdfOcr}) {} + + PdfOcrHandlerTest(const PdfOcrHandlerTest&) = delete; + PdfOcrHandlerTest& operator=(const PdfOcrHandlerTest&) = delete; + + ~PdfOcrHandlerTest() override = default; + + // testing::Test: + void SetUp() override { + TestingProfile::Builder builder; + profile_ = builder.Build(); + web_contents_ = content::WebContents::Create( + content::WebContents::CreateParams(profile_.get())); + + test_web_ui_ = std::make_unique<content::TestWebUI>(); + test_web_ui_->set_web_contents(web_contents_.get()); + + test_screen_ai_install_state_ = + std::make_unique<TestScreenAIInstallState>(); + + handler_ = std::make_unique<TestPdfOcrHandler>( + test_screen_ai_install_state_.get()); + handler_->set_web_ui(test_web_ui_.get()); + handler_->RegisterMessages(); + handler_->AllowJavascript(); + ASSERT_TRUE(handler_->IsJavascriptAllowed()); + + base::Value::List empty_args; + test_web_ui()->HandleReceivedMessage(kPdfSectionReadyCallback, empty_args); + + // Run until idle so the handler picks up initial screen ai install state, + // which is screen_ai::ScreenAIInstallState::State::kNotDownloaded. + browser_task_environment_.RunUntilIdle(); + } + + void TearDown() override { handler_.reset(); } + + void ExpectCallToWebUI(const std::string& type, + const std::string& func_name, + const int expected_arg, + size_t call_count) { + EXPECT_EQ(test_web_ui()->call_data().size(), call_count); + // Get the last call data based on the given call_count value. + const content::TestWebUI::CallData& call_data = + *test_web_ui()->call_data()[call_count - 1]; + EXPECT_EQ(call_data.function_name(), type); + EXPECT_EQ(call_data.arg1()->GetString(), func_name); + EXPECT_EQ(call_data.arg2()->GetInt(), expected_arg); + } + + void SimulateSetDownloadProgress(double progress) { + test_screen_ai_install_state_->SetDownloadProgress(progress); + } + + void SimulateSetState(screen_ai::ScreenAIInstallState::State state) { + test_screen_ai_install_state_->SetState(state); + } + + content::TestWebUI* test_web_ui() const { return test_web_ui_.get(); } + TestPdfOcrHandler* handler() const { return handler_.get(); } + + protected: + base::test::ScopedFeatureList enable_pdf_ocr_; + content::BrowserTaskEnvironment browser_task_environment_; + + std::unique_ptr<TestingProfile> profile_; + std::unique_ptr<TestScreenAIInstallState> test_screen_ai_install_state_; + std::unique_ptr<content::TestWebUI> test_web_ui_; + std::unique_ptr<content::WebContents> web_contents_; + std::unique_ptr<TestPdfOcrHandler> handler_; +}; + +TEST_F(PdfOcrHandlerTest, MessageForDownloadingState) { + size_t call_data_count_before_call = test_web_ui()->call_data().size(); + + screen_ai::ScreenAIInstallState::State state = + screen_ai::ScreenAIInstallState::State::kDownloading; + SimulateSetState(state); + const int expected_state = static_cast<int>(state); + ExpectCallToWebUI(kWebUIListenerCall, kPdfOcrStateChangedEventName, + expected_state, + /*call_count=*/call_data_count_before_call + 1u); +} + +TEST_F(PdfOcrHandlerTest, UpdateMessageForDownloadingProgress) { + // State needs to be `kDownloading` before updating the download progress. + size_t call_data_count_before_call = test_web_ui()->call_data().size(); + + screen_ai::ScreenAIInstallState::State state = + screen_ai::ScreenAIInstallState::State::kDownloading; + SimulateSetState(state); + const int expected_state = static_cast<int>(state); + ExpectCallToWebUI(kWebUIListenerCall, kPdfOcrStateChangedEventName, + expected_state, + /*call_count=*/++call_data_count_before_call); + + const double progress = 0.3; + SimulateSetDownloadProgress(progress); + // `progress` is expected to be converted into percentage in a message. + const int expected_progress_in_percentage = progress * 100; + ExpectCallToWebUI(kWebUIListenerCall, + kPdfOcrDownloadingProgressChangedEventName, + expected_progress_in_percentage, + /*call_count=*/call_data_count_before_call + 1u); +} + +TEST_F(PdfOcrHandlerTest, MessageForDownloadedState) { + size_t call_data_count_before_call = test_web_ui()->call_data().size(); + + screen_ai::ScreenAIInstallState::State state = + screen_ai::ScreenAIInstallState::State::kDownloaded; + SimulateSetState(state); + const int expected_state = static_cast<int>(state); + ExpectCallToWebUI(kWebUIListenerCall, kPdfOcrStateChangedEventName, + expected_state, + /*call_count=*/call_data_count_before_call + 1u); +} + +TEST_F(PdfOcrHandlerTest, MessageForFailedState) { + size_t call_data_count_before_call = test_web_ui()->call_data().size(); + + screen_ai::ScreenAIInstallState::State state = + screen_ai::ScreenAIInstallState::State::kFailed; + SimulateSetState(state); + const int expected_state = static_cast<int>(state); + ExpectCallToWebUI(kWebUIListenerCall, kPdfOcrStateChangedEventName, + expected_state, + /*call_count=*/call_data_count_before_call + 1u); +} + +TEST_F(PdfOcrHandlerTest, MessageForReadyState) { + size_t call_data_count_before_call = test_web_ui()->call_data().size(); + + screen_ai::ScreenAIInstallState::State state = + screen_ai::ScreenAIInstallState::State::kReady; + SimulateSetState(state); + const int expected_state = static_cast<int>(state); + ExpectCallToWebUI(kWebUIListenerCall, kPdfOcrStateChangedEventName, + expected_state, + /*call_count=*/call_data_count_before_call + 1u); +} + +TEST_F(PdfOcrHandlerTest, MessageForNotDownloadedState) { + size_t call_data_count_before_call = test_web_ui()->call_data().size(); + + // Either `kReady` or `kFailed` needs to be set for testing `kNotDownloaded`. + screen_ai::ScreenAIInstallState::State state = + screen_ai::ScreenAIInstallState::State::kReady; + SimulateSetState(state); + int expected_state = static_cast<int>(state); + ExpectCallToWebUI(kWebUIListenerCall, kPdfOcrStateChangedEventName, + expected_state, + /*call_count=*/++call_data_count_before_call); + + state = screen_ai::ScreenAIInstallState::State::kNotDownloaded; + SimulateSetState(state); + expected_state = static_cast<int>(state); + ExpectCallToWebUI(kWebUIListenerCall, kPdfOcrStateChangedEventName, + expected_state, + /*call_count=*/call_data_count_before_call + 1u); +} + +} // namespace settings
diff --git a/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom b/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom index 810b586..c4f7185 100644 --- a/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom +++ b/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom
@@ -142,6 +142,8 @@ kTouchpadHapticFeedback = 438, kTouchpadHapticClickSensitivity = 439, kAdaptiveCharging = 440, + kKeyboardBlockMetaFkeyRewrites = 441, + kKeyboardRemapKeys = 442, // Personalization section. kOpenWallpaper = 500,
diff --git a/chrome/browser/ui/webui/settings/site_settings_helper.cc b/chrome/browser/ui/webui/settings/site_settings_helper.cc index 8703daa..85ecd3c 100644 --- a/chrome/browser/ui/webui/settings/site_settings_helper.cc +++ b/chrome/browser/ui/webui/settings/site_settings_helper.cc
@@ -31,12 +31,12 @@ #include "chrome/browser/serial/serial_chooser_context.h" #include "chrome/browser/serial/serial_chooser_context_factory.h" #include "chrome/browser/subresource_filter/subresource_filter_profile_context_factory.h" +#include "chrome/browser/ui/url_identity.h" #include "chrome/browser/usb/usb_chooser_context.h" #include "chrome/browser/usb/usb_chooser_context_factory.h" -#include "chrome/browser/web_applications/web_app_provider.h" -#include "chrome/browser/web_applications/web_app_utils.h" #include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" +#include "chrome/common/url_constants.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/content_settings/core/common/content_settings.h" #include "components/content_settings/core/common/content_settings_pattern.h" @@ -1041,17 +1041,13 @@ absl::optional<std::string> GetIsolatedWebAppName(Profile* profile, GURL origin) { - absl::optional<std::string> app_name; - if (auto* provider = web_app::WebAppProvider::GetForWebApps(profile)) { - if (absl::optional<web_app::AppId> app_id = - provider->registrar_unsafe().FindAppWithUrlInScope(origin)) { - if (!provider->registrar_unsafe().IsIsolated(*app_id)) { - return app_name; - } - app_name = provider->registrar_unsafe().GetAppShortName(*app_id); - } + if (!origin.SchemeIs(chrome::kIsolatedAppScheme)) { + return absl::nullopt; } - return app_name; + auto identity = UrlIdentity::CreateFromUrl( + profile, origin, + /*allowed_types=*/{UrlIdentity::Type::kIsolatedWebApp}, /*options=*/{}); + return base::UTF16ToUTF8(identity.name); } absl::optional<std::string> GetExtensionDisplayName(Profile* profile,
diff --git a/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc b/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc index a5cf9dc..7e2b23e3 100644 --- a/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc +++ b/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc
@@ -1642,6 +1642,14 @@ } #endif // BUIDLFLAG(IS_CHROMEOS_ASH) + for (const auto& [source, external_config] : + web_app.management_to_external_config_map()) { + if (!external_config.additional_policy_ids.empty()) { + base::ranges::copy(external_config.additional_policy_ids, + std::back_inserter(policy_ids)); + } + } + if (!registrar().HasExternalAppWithInstallSource( app_id, ExternalInstallSource::kExternalPolicy)) { return policy_ids;
diff --git a/chrome/browser/web_applications/manifest_update_manager.cc b/chrome/browser/web_applications/manifest_update_manager.cc index e0a0789..c8f5119c 100644 --- a/chrome/browser/web_applications/manifest_update_manager.cc +++ b/chrome/browser/web_applications/manifest_update_manager.cc
@@ -269,7 +269,8 @@ return; } - if (!contents) { + if (!contents || contents->IsBeingDestroyed() || + !contents->GetBrowserContext()) { update_stages_.erase(app_id); NotifyResult(url, app_id, ManifestUpdateResult::kWebContentsDestroyed); return; @@ -287,8 +288,7 @@ DCHECK(install_info.has_value()); - Profile* profile = - Profile::FromBrowserContext(contents.get()->GetBrowserContext()); + Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); auto keep_alive = std::make_unique<ScopedKeepAlive>( KeepAliveOrigin::APP_MANIFEST_UPDATE, KeepAliveRestartOption::DISABLED); std::unique_ptr<ScopedProfileKeepAlive> profile_keep_alive;
diff --git a/chrome/browser/web_applications/proto/web_app.proto b/chrome/browser/web_applications/proto/web_app.proto index 523d2434..d585303 100644 --- a/chrome/browser/web_applications/proto/web_app.proto +++ b/chrome/browser/web_applications/proto/web_app.proto
@@ -127,12 +127,20 @@ ONEDRIVEINTEGRATION = 10; } +// This stores data per-external-WebAppManagement::Type, as each installation +// manager can have different installation configurations for the same web app. message ManagementToExternalConfigInfo { optional WebAppManagementProto management = 1; // The collection of install_urls per web_app per WebAppManagement::Type. repeated string install_urls = 2; // Stores whether the app is a placeholder app or not. optional bool is_placeholder = 3; + // A list of additional terms to use when matching this app against + // identifiers in admin policies (for shelf pinning, default file handlers, + // etc) per web_app per WebAppManagement::Type. + // Note that list is not meant to be an exhaustive enumeration of all possible + // policy_ids but rather just a supplement for tricky cases. + repeated string additional_policy_ids = 4; } // Contains information specific to Isolated Web Apps.
diff --git a/chrome/browser/web_applications/test/web_app_test_utils.cc b/chrome/browser/web_applications/test/web_app_test_utils.cc index 5342deb..264c765 100644 --- a/chrome/browser/web_applications/test/web_app_test_utils.cc +++ b/chrome/browser/web_applications/test/web_app_test_utils.cc
@@ -769,13 +769,23 @@ if (type == WebAppManagement::kSync) continue; base::flat_set<GURL> install_urls; + base::flat_set<std::string> additional_policy_ids; WebApp::ExternalManagementConfig config; - if (random.next_bool()) + if (random.next_bool()) { install_urls.emplace(base_url.Resolve("installer1_" + seed_str + "/")); - if (random.next_bool()) + } + if (random.next_bool()) { install_urls.emplace(base_url.Resolve("installer2_" + seed_str + "/")); + } + if (random.next_bool()) { + additional_policy_ids.emplace("policy_id_1_" + seed_str); + } + if (random.next_bool()) { + additional_policy_ids.emplace("policy_id_2_" + seed_str); + } config.is_placeholder = random.next_bool(); - config.install_urls = install_urls; + config.install_urls = std::move(install_urls); + config.additional_policy_ids = std::move(additional_policy_ids); management_to_external_config.insert_or_assign(type, std::move(config)); }
diff --git a/chrome/browser/web_applications/web_app.cc b/chrome/browser/web_applications/web_app.cc index fb6fc8e..d80bd12 100644 --- a/chrome/browser/web_applications/web_app.cc +++ b/chrome/browser/web_applications/web_app.cc
@@ -588,6 +588,15 @@ management_to_external_config_map_[type].install_urls.emplace(install_url); } +void WebApp::AddPolicyIdToManagementExternalConfigMap( + WebAppManagement::Type type, + const std::string& policy_id) { + DCHECK_NE(type, WebAppManagement::Type::kSync); + DCHECK(!policy_id.empty()); + management_to_external_config_map_[type].additional_policy_ids.emplace( + policy_id); +} + void WebApp::AddExternalSourceInformation(WebAppManagement::Type type, GURL install_url, bool is_placeholder) { @@ -666,10 +675,15 @@ base::Value::Dict WebApp::ExternalManagementConfig::AsDebugValue() const { base::Value::Dict root; base::Value::List urls; - for (auto it : install_urls) { - urls.Append(it.spec()); + for (const auto& install_url : install_urls) { + urls.Append(install_url.spec()); + } + base::Value::List policy_ids; + for (const auto& policy_id : additional_policy_ids) { + policy_ids.Append(policy_id); } root.Set("install_urls", std::move(urls)); + root.Set("additional_policy_ids", std::move(policy_ids)); root.Set("is_placeholder", is_placeholder); return root; } @@ -1101,8 +1115,12 @@ bool operator==(const WebApp::ExternalManagementConfig& management_config1, const WebApp::ExternalManagementConfig& management_config2) { - return management_config1.install_urls == management_config2.install_urls && - management_config1.is_placeholder == management_config2.is_placeholder; + return std::tie(management_config1.install_urls, + management_config1.is_placeholder, + management_config1.additional_policy_ids) == + std::tie(management_config2.install_urls, + management_config2.is_placeholder, + management_config2.additional_policy_ids); } bool operator!=(const WebApp::ExternalManagementConfig& management_config1,
diff --git a/chrome/browser/web_applications/web_app.h b/chrome/browser/web_applications/web_app.h index 5f71e330..e9c4c06c 100644 --- a/chrome/browser/web_applications/web_app.h +++ b/chrome/browser/web_applications/web_app.h
@@ -292,6 +292,13 @@ bool is_placeholder = false; base::flat_set<GURL> install_urls; + + // A list of additional terms to use when matching this app against + // identifiers in admin policies (for shelf pinning, default file handlers, + // etc). + // Note that list is not meant to be an exhaustive enumeration of all + // possible policy_ids but rather just a supplement for tricky cases. + base::flat_set<std::string> additional_policy_ids; }; using ExternalConfigMap = @@ -428,10 +435,15 @@ bool is_placeholder); // This adds an install_url per management type (source) for the - // WebAppManagementToInstallURLsMap. + // ExternalConfigMap. void AddInstallURLToManagementExternalConfigMap(WebAppManagement::Type type, GURL install_url); + // This adds a policy_id per management type (source) for the + // ExternalConfigMap. + void AddPolicyIdToManagementExternalConfigMap(WebAppManagement::Type type, + const std::string& policy_id); + // Encapsulate the addition of install_url and is_placeholder information // for cases where both need to be added. void AddExternalSourceInformation(WebAppManagement::Type source_type,
diff --git a/chrome/browser/web_applications/web_app_database.cc b/chrome/browser/web_applications/web_app_database.cc index 1953b679..baf4dd28 100644 --- a/chrome/browser/web_applications/web_app_database.cc +++ b/chrome/browser/web_applications/web_app_database.cc
@@ -734,16 +734,21 @@ } if (!web_app.management_to_external_config_map().empty()) { - for (const auto& entry : web_app.management_to_external_config_map()) { + for (const auto& [source, external_config] : + web_app.management_to_external_config_map()) { ManagementToExternalConfigInfo* management_config_proto = local_data->add_management_to_external_config_info(); - management_config_proto->set_management( - WebAppManagementToProto(entry.first)); - management_config_proto->set_is_placeholder(entry.second.is_placeholder); - for (const auto& url : entry.second.install_urls) { + management_config_proto->set_management(WebAppManagementToProto(source)); + management_config_proto->set_is_placeholder( + external_config.is_placeholder); + for (const auto& url : external_config.install_urls) { DCHECK(url.is_valid()); management_config_proto->add_install_urls(url.spec()); } + for (const auto& policy_id : external_config.additional_policy_ids) { + DCHECK(!policy_id.empty()); + management_config_proto->add_additional_policy_ids(policy_id); + } } } @@ -1411,8 +1416,18 @@ } install_urls.emplace(install_url); } + base::flat_set<std::string> additional_policy_ids; + for (const auto& policy_id : management_proto.additional_policy_ids()) { + if (policy_id.empty()) { + DLOG(ERROR) << "WebApp proto empty policy_id"; + return nullptr; + } + additional_policy_ids.emplace(policy_id); + } + config.is_placeholder = management_proto.is_placeholder(); - config.install_urls = install_urls; + config.install_urls = std::move(install_urls); + config.additional_policy_ids = std::move(additional_policy_ids); management_to_external_config.insert_or_assign( ProtoToWebAppManagement(management_proto.management()), std::move(config));
diff --git a/chrome/browser/web_applications/web_app_install_finalizer.cc b/chrome/browser/web_applications/web_app_install_finalizer.cc index e987b76..70054ac 100644 --- a/chrome/browser/web_applications/web_app_install_finalizer.cc +++ b/chrome/browser/web_applications/web_app_install_finalizer.cc
@@ -207,9 +207,9 @@ web_app->SetIsFromSyncAndPendingInstallation(false); web_app->SetLatestInstallSource(options.install_surface); - WriteExternalConfigMapInfo(*web_app, options.source, - web_app_info.is_placeholder, - web_app_info.install_url); + WriteExternalConfigMapInfo( + *web_app, options.source, web_app_info.is_placeholder, + web_app_info.install_url, web_app_info.additional_policy_ids); if (!options.locally_installed) { DCHECK(!(options.add_to_applications_menu || options.add_to_desktop || @@ -649,7 +649,8 @@ WebApp& web_app, WebAppManagement::Type source, bool is_placeholder, - GURL install_url) { + GURL install_url, + const std::vector<std::string>& additional_policy_ids) { DCHECK(!(source == WebAppManagement::Type::kSync && is_placeholder)); if (source != WebAppManagement::Type::kSync) { web_app.AddPlaceholderInfoToManagementExternalConfigMap(source, @@ -657,6 +658,11 @@ if (install_url.is_valid()) { web_app.AddInstallURLToManagementExternalConfigMap(source, install_url); } + if (!additional_policy_ids.empty()) { + for (const auto& policy_id : additional_policy_ids) { + web_app.AddPolicyIdToManagementExternalConfigMap(source, policy_id); + } + } } }
diff --git a/chrome/browser/web_applications/web_app_install_finalizer.h b/chrome/browser/web_applications/web_app_install_finalizer.h index 5c1af28b..88615d3 100644 --- a/chrome/browser/web_applications/web_app_install_finalizer.h +++ b/chrome/browser/web_applications/web_app_install_finalizer.h
@@ -159,10 +159,12 @@ const WebAppRegistrar& GetWebAppRegistrar() const; // Writes external config data to the web_app DB, mapped per source. - void WriteExternalConfigMapInfo(WebApp& web_app, - WebAppManagement::Type source, - bool is_placeholder, - GURL install_url); + void WriteExternalConfigMapInfo( + WebApp& web_app, + WebAppManagement::Type source, + bool is_placeholder, + GURL install_url, + const std::vector<std::string>& additional_policy_ids); // Used to schedule a WebAppUninstallCommand. The |external_install_source| // field is only required for external app uninstalls to verify OS
diff --git a/chrome/browser/web_applications/web_app_install_info.h b/chrome/browser/web_applications/web_app_install_info.h index 4715751..4a7b93c 100644 --- a/chrome/browser/web_applications/web_app_install_info.h +++ b/chrome/browser/web_applications/web_app_install_info.h
@@ -345,6 +345,13 @@ // API. absl::optional<web_app::AppId> parent_app_id; + // A list of additional terms to use when matching this app against + // identifiers in admin policies (for shelf pinning, default file handlers, + // etc). + // Note that list is not meant to be an exhaustive enumeration of all possible + // policy_ids but rather just a supplement for tricky cases. + std::vector<std::string> additional_policy_ids; + private: // Used this method in Clone() method. Use Clone() to deep copy explicitly. WebAppInstallInfo(const WebAppInstallInfo& other);
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index 55ea1a5..665b72b 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1679666352-893ba2ab29e001a8d06b83384c21756ff421c3af.profdata +chrome-mac-arm-main-1679680693-d693694c85959104915ecf5cb194386a47140e9b.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 19d15ee0..26158140 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1679659147-c3ab80a26c54eb22ce593cc45a8426014bfb6518.profdata +chrome-win64-main-1679680693-06d47d930b07d390341ca29eb35a7a52ff62ce7e.profdata
diff --git a/chrome/common/extensions/api/file_system_provider_capabilities/file_system_provider_capabilities_handler.cc b/chrome/common/extensions/api/file_system_provider_capabilities/file_system_provider_capabilities_handler.cc index fce6c6d8..ee53ef3 100644 --- a/chrome/common/extensions/api/file_system_provider_capabilities/file_system_provider_capabilities_handler.cc +++ b/chrome/common/extensions/api/file_system_provider_capabilities/file_system_provider_capabilities_handler.cc
@@ -79,7 +79,7 @@ api::manifest_types::FileSystemProviderCapabilities idl_capabilities; if (!api::manifest_types::FileSystemProviderCapabilities::Populate( - *section, idl_capabilities, error)) { + *section, idl_capabilities, *error)) { return false; }
diff --git a/chrome/common/extensions/api/omnibox/omnibox_handler.cc b/chrome/common/extensions/api/omnibox/omnibox_handler.cc index e39d4d2..ac224e8 100644 --- a/chrome/common/extensions/api/omnibox/omnibox_handler.cc +++ b/chrome/common/extensions/api/omnibox/omnibox_handler.cc
@@ -36,7 +36,7 @@ bool OmniboxHandler::Parse(Extension* extension, std::u16string* error) { ManifestKeys manifest_keys; if (!ManifestKeys::ParseFromDictionary( - extension->manifest()->available_values(), manifest_keys, error)) { + extension->manifest()->available_values(), manifest_keys, *error)) { return false; }
diff --git a/chrome/common/extensions/api/side_panel/side_panel_info.cc b/chrome/common/extensions/api/side_panel/side_panel_info.cc index 0beb975..4dad1f52 100644 --- a/chrome/common/extensions/api/side_panel/side_panel_info.cc +++ b/chrome/common/extensions/api/side_panel/side_panel_info.cc
@@ -27,7 +27,7 @@ std::u16string* error) { SidePanelManifestKeys manifest_keys; if (!SidePanelManifestKeys::ParseFromDictionary( - extension.manifest()->available_values(), manifest_keys, error)) { + extension.manifest()->available_values(), manifest_keys, *error)) { return nullptr; } auto info = std::make_unique<SidePanelInfo>();
diff --git a/chrome/common/extensions/chrome_manifest_url_handlers.cc b/chrome/common/extensions/chrome_manifest_url_handlers.cc index 0d031ad..4623c1a5 100644 --- a/chrome/common/extensions/chrome_manifest_url_handlers.cc +++ b/chrome/common/extensions/chrome_manifest_url_handlers.cc
@@ -90,7 +90,7 @@ bool URLOverridesHandler::Parse(Extension* extension, std::u16string* error) { ChromeUrlOverridesKeys manifest_keys; if (!ChromeUrlOverridesKeys::ParseFromDictionary( - extension->manifest()->available_values(), manifest_keys, error)) { + extension->manifest()->available_values(), manifest_keys, *error)) { return false; }
diff --git a/chrome/credential_provider/test/test_credential.h b/chrome/credential_provider/test/test_credential.h index 6acaffe..349d3f9 100644 --- a/chrome/credential_provider/test/test_credential.h +++ b/chrome/credential_provider/test/test_credential.h
@@ -220,7 +220,7 @@ bool CTestCredentialBase<T>::IsAuthenticationResultsEmpty() { auto& results = this->get_authentication_results(); - return !results || (results->is_dict() && results->DictEmpty()); + return !results || (results->is_dict() && results->GetDict().empty()); } template <class T>
diff --git a/chrome/services/printing/print_backend_service_impl.cc b/chrome/services/printing/print_backend_service_impl.cc index a0a033fa..3d34fa6 100644 --- a/chrome/services/printing/print_backend_service_impl.cc +++ b/chrome/services/printing/print_backend_service_impl.cc
@@ -103,21 +103,6 @@ return task_runner; } -#if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) -void OnDidAskUserForSettings( - std::unique_ptr<PrintingContext> context, - mojom::PrintBackendService::AskUserForSettingsCallback callback, - mojom::ResultCode result) { - if (result != mojom::ResultCode::kSuccess) { - DLOG(ERROR) << "Did not get user settings, error: " << result; - std::move(callback).Run(mojom::PrintSettingsResult::NewResultCode(result)); - return; - } - std::move(callback).Run(mojom::PrintSettingsResult::NewSettings( - *context->TakeAndResetSettings())); -} -#endif // BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) - std::unique_ptr<Metafile> CreateMetafile(mojom::MetafileDataType data_type) { switch (data_type) { case mojom::MetafileDataType::kPDF: @@ -172,12 +157,12 @@ // a worker task runner. class DocumentContainer { public: - DocumentContainer(PrintingContext::Delegate* context_delegate, - scoped_refptr<PrintedDocument> document, - mojom::PrintTargetType target_type) - : context_delegate_(context_delegate), - document_(document), - target_type_(target_type) {} + DocumentContainer(std::unique_ptr<PrintingContext::Delegate> context_delegate, + std::unique_ptr<PrintingContext> context, + scoped_refptr<PrintedDocument> document) + : context_delegate_(std::move(context_delegate)), + context_(std::move(context)), + document_(document) {} ~DocumentContainer() = default; @@ -200,14 +185,10 @@ void DoCancel(); private: - raw_ptr<PrintingContext::Delegate> context_delegate_; - scoped_refptr<PrintedDocument> document_; - - // `context` is not initialized until the document is ready for printing. + std::unique_ptr<PrintingContext::Delegate> context_delegate_; std::unique_ptr<PrintingContext> context_; - // Parameter required for the delayed call to `UpdatePrinterSettings()`. - mojom::PrintTargetType target_type_; + scoped_refptr<PrintedDocument> document_; // Ensure all interactions for this document are issued from the same runner. SEQUENCE_CHECKER(sequence_checker_); @@ -218,36 +199,7 @@ DVLOG(1) << "Start printing for document " << document_->cookie(); - // Create a printing context that will work with this document for the - // duration of the print job. - context_ = - PrintingContext::Create(context_delegate_, /*skip_system_calls=*/false); - - // With out-of-process printing the printer settings no longer get updated - // from `PrintingContext::UpdatePrintSettings()`, so we need to apply that - // now to our new context. - // TODO(crbug.com/1245679) Replumb `mojom::PrintTargetType` into - // `PrintingContext::UpdatePrinterSettings()`. - PrintingContext::PrinterSettings printer_settings { -#if BUILDFLAG(IS_MAC) - .external_preview = - target_type_ == mojom::PrintTargetType::kExternalPreview, -#endif - .show_system_dialog = target_type_ == mojom::PrintTargetType::kSystemDialog, -#if BUILDFLAG(IS_WIN) - .page_count = 0, -#endif - }; - context_->ApplyPrintSettings(document_->settings()); - mojom::ResultCode result = context_->UpdatePrinterSettings(printer_settings); - if (result != mojom::ResultCode::kSuccess) { - DLOG(ERROR) << "Failure updating printer settings for document " - << document_->cookie() << ", error: " << result; - context_->Cancel(); - return result; - } - - result = context_->NewDocument(document_->name()); + mojom::ResultCode result = context_->NewDocument(document_->name()); if (result != mojom::ResultCode::kSuccess) { DLOG(ERROR) << "Failure initializing new document " << document_->cookie() << ", error: " << result; @@ -481,7 +433,6 @@ #endif // BUILDFLAG(IS_WIN) ) { locale_ = locale; - context_delegate_.SetAppLocale(locale); #if BUILDFLAG(IS_WIN) if (remote.is_valid()) xml_parser_remote_.Bind(std::move(remote)); @@ -659,14 +610,15 @@ } void PrintBackendServiceImpl::UseDefaultSettings( + uint32_t context_id, mojom::PrintBackendService::UseDefaultSettingsCallback callback) { - // Use a one-time `PrintingContext` to get the print settings. - std::unique_ptr<PrintingContext> context = - PrintingContext::Create(&context_delegate_, /*skip_system_calls=*/false); - mojom::ResultCode result = context.get()->UseDefaultSettings(); + PrintingContext* context = GetPrintingContext(context_id); + CHECK(context) << "No context found for id " << context_id; + mojom::ResultCode result = context->UseDefaultSettings(); if (result != mojom::ResultCode::kSuccess) { DLOG(ERROR) << "Failure getting default settings of default printer, " << "error: " << result; + persistent_printing_contexts_.erase(context_id); std::move(callback).Run(mojom::PrintSettingsResult::NewResultCode(result)); return; } @@ -676,34 +628,25 @@ #if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) void PrintBackendServiceImpl::AskUserForSettings( - uint32_t parent_window_id, + uint32_t context_id, int max_pages, bool has_selection, bool is_scripted, mojom::PrintBackendService::AskUserForSettingsCallback callback) { - // Provide the window which owns the print dialog. On Windows the call to - // `AskUserForSettings()` is a blocking call. Additionally, the browser - // process is to have logic to avoid even making a concurrent call to the - // service. That means there is no concern here about a possible concurrent - // call overwriting the parent window ID of `context_delegate_`. - // TODO(crbug.com/809738) When updating for Linux, add extra protection to - // guarantee that the parent window ID cannot be overwritten by a concurrent - // system print request. - context_delegate_.SetParentWindow(parent_window_id); - - // Use a one-time `PrintingContext` to ask for the print settings. - // We do not yet know which device (if any) will be selected. - std::unique_ptr<PrintingContext> context = - PrintingContext::Create(&context_delegate_, /*skip_system_calls=*/false); - PrintingContext* context_ptr = context.get(); - context_ptr->AskUserForSettings( + // Safe to use `base::Unretained(this)` because `this` outlives the async + // call and callback. The entire service process goes away when `this` + // lifetime expires. + PrintingContext* context = GetPrintingContext(context_id); + CHECK(context) << "No context found for id " << context_id; + context->AskUserForSettings( max_pages, has_selection, is_scripted, - base::BindOnce(&OnDidAskUserForSettings, std::move(context), - std::move(callback))); + base::BindOnce(&PrintBackendServiceImpl::OnDidAskUserForSettings, + base::Unretained(this), context_id, std::move(callback))); } #endif // BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) void PrintBackendServiceImpl::UpdatePrintSettings( + uint32_t context_id, base::Value::Dict job_settings, mojom::PrintBackendService::UpdatePrintSettingsCallback callback) { DCHECK(print_backend_); @@ -727,12 +670,8 @@ } #endif // BUILDFLAG(IS_LINUX) && BUILDFLAG(USE_CUPS) - // Use a one-time `PrintingContext` to do the update to print settings. - // Intentionally do not cache this context here since the process model does - // not guarantee that we will return to this same process when - // `StartPrinting()` might be called. - std::unique_ptr<PrintingContext> context = - PrintingContext::Create(&context_delegate_, /*skip_system_calls=*/false); + PrintingContext* context = GetPrintingContext(context_id); + CHECK(context) << "No context found for id " << context_id; mojom::ResultCode result = context->UpdatePrintSettings(std::move(job_settings)); @@ -741,15 +680,17 @@ return; } - std::move(callback).Run(mojom::PrintSettingsResult::NewSettings( - *context->TakeAndResetSettings())); + std::move(callback).Run( + mojom::PrintSettingsResult::NewSettings(context->settings())); } void PrintBackendServiceImpl::StartPrinting( + uint32_t context_id, int document_cookie, const std::u16string& document_name, - mojom::PrintTargetType target_type, - const PrintSettings& settings, +#if !BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) + const absl::optional<PrintSettings>& settings, +#endif mojom::PrintBackendService::StartPrintingCallback callback) { #if BUILDFLAG(IS_CHROMEOS) && BUILDFLAG(USE_CUPS) CupsConnectionPool* connection_pool = CupsConnectionPool::GetInstance(); @@ -767,14 +708,30 @@ } #endif + // This job takes ownership of this printing context and associates it with + // the document. + auto item = persistent_printing_contexts_.find(context_id); + CHECK(item != persistent_printing_contexts_.end()) + << "No context found for id " << context_id; + std::unique_ptr<ContextContainer> context_container = std::move(item->second); + persistent_printing_contexts_.erase(item); + +#if !BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) + if (settings) { + // Apply the settings from the in-browser system dialog to the context. + context_container->context->ApplyPrintSettings(*settings); + } +#endif + // Save all the document settings for use through the print job, until the // time that this document can complete printing. Track the order of // received documents with position in `documents_`. auto document = base::MakeRefCounted<PrintedDocument>( - std::make_unique<PrintSettings>(settings), document_name, - document_cookie); + std::make_unique<PrintSettings>(context_container->context->settings()), + document_name, document_cookie); base::SequenceBound<DocumentContainer> document_container( - GetPrintingTaskRunner(), &context_delegate_, document, target_type); + GetPrintingTaskRunner(), std::move(context_container->delegate), + std::move(context_container->context), document); documents_.push_back(std::make_unique<DocumentHelper>( document_cookie, std::move(document_container), std::move(callback))); DocumentHelper& document_helper = *documents_.back(); @@ -858,6 +815,24 @@ std::move(callback))); } +#if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) +void PrintBackendServiceImpl::OnDidAskUserForSettings( + uint32_t context_id, + mojom::PrintBackendService::AskUserForSettingsCallback callback, + mojom::ResultCode result) { + auto* context = GetPrintingContext(context_id); + DCHECK(context); + if (result != mojom::ResultCode::kSuccess) { + DLOG(ERROR) << "Did not get user settings, error: " << result; + persistent_printing_contexts_.erase(context_id); + std::move(callback).Run(mojom::PrintSettingsResult::NewResultCode(result)); + return; + } + std::move(callback).Run(mojom::PrintSettingsResult::NewSettings( + *context->TakeAndResetSettings())); +} +#endif // BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) + void PrintBackendServiceImpl::OnDidStartPrintingReadyDocument( DocumentHelper& document_helper, mojom::ResultCode result) { @@ -895,6 +870,16 @@ return context_delegate; } +PrintingContext* PrintBackendServiceImpl::GetPrintingContext( + uint32_t context_id) { + DCHECK_CALLED_ON_VALID_SEQUENCE(main_sequence_checker_); + auto item = persistent_printing_contexts_.find(context_id); + if (item == persistent_printing_contexts_.end()) { + return nullptr; + } + return item->second->context.get(); +} + PrintBackendServiceImpl::DocumentHelper* PrintBackendServiceImpl::GetDocumentHelper(int document_cookie) { DCHECK_CALLED_ON_VALID_SEQUENCE(main_sequence_checker_);
diff --git a/chrome/services/printing/print_backend_service_impl.h b/chrome/services/printing/print_backend_service_impl.h index 8f46953..de21509 100644 --- a/chrome/services/printing/print_backend_service_impl.h +++ b/chrome/services/printing/print_backend_service_impl.h
@@ -165,24 +165,28 @@ #endif ) override; void UseDefaultSettings( + uint32_t context_id, mojom::PrintBackendService::UseDefaultSettingsCallback callback) override; #if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) void AskUserForSettings( - uint32_t parent_window_id, + uint32_t context_id, int max_pages, bool has_selection, bool is_scripted, mojom::PrintBackendService::AskUserForSettingsCallback callback) override; #endif void UpdatePrintSettings( + uint32_t context_id, base::Value::Dict job_settings, mojom::PrintBackendService::UpdatePrintSettingsCallback callback) override; void StartPrinting( + uint32_t context_id, int document_cookie, const std::u16string& document_name, - mojom::PrintTargetType target_type, - const PrintSettings& settings, +#if !BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) + const absl::optional<PrintSettings>& settings, +#endif mojom::PrintBackendService::StartPrintingCallback callback) override; #if BUILDFLAG(IS_WIN) void RenderPrintedPage( @@ -209,6 +213,12 @@ mojom::PrintBackendService::CancelCallback callback) override; // Callbacks from worker functions. +#if BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) + void OnDidAskUserForSettings( + uint32_t context_id, + mojom::PrintBackendService::AskUserForSettingsCallback callback, + mojom::ResultCode result); +#endif void OnDidStartPrintingReadyDocument(DocumentHelper& document_helper, mojom::ResultCode result); void OnDidDocumentDone( @@ -220,6 +230,7 @@ // Utility helpers. std::unique_ptr<PrintingContextDelegate> CreatePrintingContextDelegate(); + PrintingContext* GetPrintingContext(uint32_t context_id); DocumentHelper* GetDocumentHelper(int document_cookie); void RemoveDocumentHelper(DocumentHelper& document_helper); @@ -241,14 +252,11 @@ scoped_refptr<PrintBackend> print_backend_; - // Map from a context ID to a printing device context. + // Map from a context ID to a printing device context. Accessed only from + // the main thread. base::flat_map<uint32_t, std::unique_ptr<ContextContainer>> persistent_printing_contexts_; - // TODO(crbug.com/1414968): Delete this once callers switch to complete - // local contexts or using `persistent_printing_contexts_`. - PrintingContextDelegate context_delegate_; - // Want all callbacks and document helper sequence manipulations to be made // from main thread, not a thread runner. SEQUENCE_CHECKER(main_sequence_checker_);
diff --git a/chrome/services/printing/public/mojom/print_backend_service.mojom b/chrome/services/printing/public/mojom/print_backend_service.mojom index 2c46ea7..e119ff0 100644 --- a/chrome/services/printing/public/mojom/print_backend_service.mojom +++ b/chrome/services/printing/public/mojom/print_backend_service.mojom
@@ -58,14 +58,6 @@ ResultCode result_code; }; -// The type of printing interface to target. -enum PrintTargetType { - kDirectToDevice, - kSystemDialog, - [EnableIf=is_mac] - kExternalPreview, -}; - // Hosts the PrintBackendService but does so without sandboxing the service - // this is required if print drivers need UI access or cannot otherwise // operate in the normal sandbox. There is a 1:1 relationship and `service` @@ -140,15 +132,17 @@ uint32 parent_window_id); // Generates a print settings object based upon the default settings for the - // default printer. - UseDefaultSettings() + // default printer. `context_id` must be for a context previously created + // by a call to `EstablishPrintingContext()`. + UseDefaultSettings(uint32 context_id) => (PrintSettingsResult settings); // Generates a print settings object from user-selected options via a system - // print dialog. The `parent_window_id` parameter specifies an ID which is - // cross-process safe to represent the native window which owns the modal - // print dialog used for prompting the user. Other parameters are the same - // as used in `PrintingContext::AskUserForSettings()`. + // print dialog. `context_id` must be for a context previously created by a + // call to `EstablishPrintingContext()`. + // The previously established context has the necessary parent window ID for + // displaying a system dialog. Other parameters are the same as used in + // `PrintingContext::AskUserForSettings()`. // Currently only supported on Windows: // - It is impossible for macOS `//ui` code to display a system print // dialog from a service utility process that is modal to a window in the @@ -162,27 +156,43 @@ // - Platforms other than those identified above do not support a system // print dialog. [EnableIf=enable_oop_basic_print_dialog] - AskUserForSettings(uint32 parent_window_id, + AskUserForSettings(uint32 context_id, int32 max_pages, bool has_selection, bool is_scripted) => (PrintSettingsResult settings); - // Generates a print settings object based upon the job settings used with - // the device settings. The driver to be used is expected to be identified - // in the `job_settings` map by an entry with key - // `printing::kSettingDeviceName`. - UpdatePrintSettings(mojo_base.mojom.DictionaryValue job_settings) + // Updates the indicated printing context based upon the job settings used + // with the device settings. The driver to be used is expected to be + // identified in the `job_settings` map by an entry with key + // `printing::kSettingDeviceName`. `context_id` must be for a context + // previously created by a call to `EstablishPrintingContext()`. The updated + // print settings remain in the context for use when a system dialog is + // initiated and/or printing of a document is started. + UpdatePrintSettings(uint32 context_id, + mojo_base.mojom.DictionaryValue job_settings) => (PrintSettingsResult settings); // Submit the document identified by `document_cookie` to be printed. + // A printing context must already have been setup previously with a call to + // `EstablishPrintingContext()`. + // This call to `StartPrinting()` will take ownership of the indicated + // context and automatically free it once the print job has completed (either + // with success or via a cancel after failure). // Starting the device initialization may be delayed if it needs to wait for // prior print jobs to complete before a connection to the system to become // available. - StartPrinting(int32 document_cookie, + // For platforms which do not support an out-of-process system print dialog, + // when doing system print the settings are specified from the system dialog + // that is invoked from the browser process. The settings are collected from + // that and then are provided at start of printing via `settings`. This is + // optional since such settings are not necessary when printing from Print + // Preview, where the print settings are provided via `UpdatePrintSettings()`. + StartPrinting(uint32 context_id, + int32 document_cookie, mojo_base.mojom.String16 document_name, - PrintTargetType target_type, - PrintSettings settings) + [EnableIfNot=enable_oop_basic_print_dialog] + PrintSettings? settings) => (ResultCode result_code); // Render the indicated page as part of print job for `document_cookie`.
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index dbbd673..3b4885b 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -4292,6 +4292,7 @@ } if (enable_assistant_integration_tests) { sources += [ + "../browser/ash/app_list/launcher_search_iph_browsertest.cc", "../browser/ui/ash/assistant/assistant_browsertest.cc", "../browser/ui/ash/assistant/assistant_test_mixin.cc", "../browser/ui/ash/assistant/assistant_test_mixin.h", @@ -4337,7 +4338,6 @@ "//ash/components/arc:arc_metrics_constants", "//ash/components/arc:arc_test_support", "//ash/components/arc:prefs", - "//ash/components/arc/enterprise", "//ash/components/arc/session:arc_base_enums", "//ash/constants:constants", "//ash/keyboard/ui:test_support", @@ -7291,6 +7291,7 @@ sources += [ # NTP is in native code on Android. "../browser/new_tab_page/chrome_colors/chrome_colors_service_unittest.cc", + "../browser/new_tab_page/customize_chrome/customize_chrome_feature_promo_helper_unittest.cc", "../browser/new_tab_page/modules/drive/drive_service_unittest.cc", "../browser/new_tab_page/modules/feed/feed_handler_unittest.cc", "../browser/new_tab_page/modules/history_clusters/history_clusters_page_handler_unittest.cc", @@ -7825,6 +7826,7 @@ "../browser/lacros/net/network_settings_translation_unittest.cc", "../browser/lacros/prefs_ash_observer_unittest.cc", "../browser/lacros/remote_apps/remote_apps_proxy_lacros_unittest.cc", + "../browser/lacros/sync/crosapi_session_sync_favicon_delegate_unittest.cc", "../browser/lacros/sync/crosapi_session_sync_notifier_unittest.cc", "../browser/lacros/sync/sync_explicit_passphrase_client_lacros_unittest.cc", "../browser/lacros/sync/sync_user_settings_client_lacros_unittest.cc", @@ -8607,6 +8609,7 @@ sources += [ "../browser/component_updater/real_time_url_checks_allowlist_component_installer_unittest.cc", "../browser/safe_browsing/android/password_reuse_controller_android_unittest.cc", + "../browser/safe_browsing/tailored_security/chrome_tailored_security_service_android_unittest.cc", "../browser/safe_browsing/telemetry/android/android_telemetry_service_unittest.cc", ]
diff --git a/chrome/test/chromedriver/performance_logger_unittest.cc b/chrome/test/chromedriver/performance_logger_unittest.cc index a35876d4..2e99c1d 100644 --- a/chrome/test/chromedriver/performance_logger_unittest.cc +++ b/chrome/test/chromedriver/performance_logger_unittest.cc
@@ -76,6 +76,11 @@ listener_ = listener; } + void RemoveListener(DevToolsEventListener* listener) override { + CHECK(listener_ = listener); + listener_ = nullptr; + } + const std::string& GetId() override { return id_; } private: @@ -207,6 +212,7 @@ ASSERT_EQ(2u, log.GetEntries().size()); ValidateLogEntry(log.GetEntries()[0].get(), "webview-1", "Network.gaga"); ValidateLogEntry(log.GetEntries()[1].get(), "webview-1", "Page.ulala"); + client.RemoveListener(&logger); } TEST(PerformanceLogger, TwoWebViews) { @@ -234,6 +240,8 @@ ASSERT_EQ(2u, log.GetEntries().size()); ValidateLogEntry(log.GetEntries()[0].get(), "webview-1", "Page.gaga1"); ValidateLogEntry(log.GetEntries()[1].get(), "webview-2", "Network.gaga2"); + client1.RemoveListener(&logger); + client2.RemoveListener(&logger); } TEST(PerformanceLogger, PerfLoggingPrefs) { @@ -253,6 +261,7 @@ DevToolsCommand* cmd; ASSERT_FALSE(client.PopSentCommand(&cmd)); + client.RemoveListener(&logger); } namespace { @@ -315,6 +324,7 @@ ExpectCommand(&client, "Tracing.end"); ExpectCommand(&client, "Tracing.start"); // Tracing should re-start. ASSERT_FALSE(client.PopSentCommand(&cmd)); + client.RemoveListener(&logger); } TEST(PerformanceLogger, RecordTraceEvents) { @@ -345,6 +355,7 @@ ValidateLogEntry(log.GetEntries()[1].get(), DevToolsClientImpl::kBrowserwideDevToolsClientId, "Tracing.dataCollected", event2); + client.RemoveListener(&logger); } TEST(PerformanceLogger, ShouldRequestTraceEvents) { @@ -366,6 +377,7 @@ // Trace events should always be dumped for GetLog command. ASSERT_EQ(kOk, logger.BeforeCommand("GetLog").code()); EXPECT_TRUE(client.events_handled()); + client.RemoveListener(&logger); } TEST(PerformanceLogger, WarnWhenTraceBufferFull) { @@ -398,4 +410,5 @@ message->FindDictByDottedPath("message.params"); ASSERT_TRUE(actual_params); EXPECT_TRUE(actual_params->contains("error")); + client.RemoveListener(&logger); }
diff --git a/chrome/test/data/web_apps/sample_web_app.json b/chrome/test/data/web_apps/sample_web_app.json index 8686fd0..c9675024 100644 --- a/chrome/test/data/web_apps/sample_web_app.json +++ b/chrome/test/data/web_apps/sample_web_app.json
@@ -5,20 +5,19 @@ "allowed_launch_protocols": [ "web+test_1234_0" ], "always_show_toolbar_in_fullscreen": false, "app_service_icon_url": "chrome://app-icon/eajjdjobhihlgobdfaehiiheinneagde/32", - "app_size_in_bytes": "2353265476", + "app_size_in_bytes": "1505422652", "background_color": "rgba(77,188,194,0.9686274509803922)", "capture_links": "kNone", "current_os_integration_states": { "file_handling": [ ], "protocols_handled": { - "web+test0": "https://example.com/scope1234/start12340", - "web+test1": "https://example.com/scope1234/start12341" + "web+test0": "https://example.com/scope1234/start12340" }, - "run_on_os_login": "minimized", + "run_on_os_login": "not_run", "shortcut_descriptions": { "description": "Description1234", "icon_size_to_timestamp_map": { - "32": "1970-02-18 08:29:15.376 UTC" + "32": "1970-02-04 17:47:46.335 UTC" }, "title": "Name1234" }, @@ -30,7 +29,7 @@ }, "dark_mode_background_color": "none", "dark_mode_theme_color": "rgba(34,214,187,1)", - "data_size_in_bytes": "3216637306", + "data_size_in_bytes": "1449447663", "description": "Description1234", "disallowed_launch_protocols": [ "web+disallowed_1234_0", "web+disallowed_1234_1", "web+disallowed_1234_2", "web+disallowed_1234_3", "web+disallowed_1234_4", "web+disallowed_1234_5" ], "display_mode": "fullscreen", @@ -166,7 +165,7 @@ "is_uninstalling": false, "isolation_data": { "isolated_web_app_location": { - "dev_mode_bundle": { + "installed_bundle": { "path": "1234" } } @@ -181,16 +180,19 @@ "lock_screen_start_url": "https://example.com/scope1234/lock_screen_start_url3022990271", "management_type_to_external_configuration_map": { "Default": { + "additional_policy_ids": [ "policy_id_1_1234", "policy_id_2_1234" ], + "install_urls": [ "https://example.com/installer1_1234/" ], + "is_placeholder": false + }, + "SubApp": { + "additional_policy_ids": [ ], "install_urls": [ ], "is_placeholder": true }, - "SubApp": { - "install_urls": [ "https://example.com/installer2_1234/" ], - "is_placeholder": true - }, "WebAppStore": { + "additional_policy_ids": [ "policy_id_1_1234" ], "install_urls": [ "https://example.com/installer1_1234/", "https://example.com/installer2_1234/" ], - "is_placeholder": true + "is_placeholder": false } }, "manifest_icons": [ ],
diff --git a/chrome/test/data/webui/chromeos/os_feedback_ui/OWNERS b/chrome/test/data/webui/chromeos/os_feedback_ui/OWNERS new file mode 100644 index 0000000..feaac8d --- /dev/null +++ b/chrome/test/data/webui/chromeos/os_feedback_ui/OWNERS
@@ -0,0 +1,7 @@ +# Primary OWNERS +xiangdongkong@google.com + +# Backup OWNERS +gavinwill@chromium.org +jimmyxgong@chromium.org +zentaro@chromium.org
diff --git a/chrome/test/data/webui/mojo/mojo_js_interface_broker_browsertest.cc b/chrome/test/data/webui/mojo/mojo_js_interface_broker_browsertest.cc index 44618698..4ad3dab 100644 --- a/chrome/test/data/webui/mojo/mojo_js_interface_broker_browsertest.cc +++ b/chrome/test/data/webui/mojo/mojo_js_interface_broker_browsertest.cc
@@ -397,6 +397,7 @@ content::TestNavigationObserver observer(web_contents, 1); EXPECT_TRUE(content::ExecuteScript(bar_frame, "location.reload()")); observer.Wait(); + bar_frame = ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0); EXPECT_EQ("bar", EvalStatement("(async () => {" " let barRemote = window.Bar.getRemote();"
diff --git a/chrome/test/data/webui/new_tab_page/app_test.ts b/chrome/test/data/webui/new_tab_page/app_test.ts index 9d4f183..ecba5b4 100644 --- a/chrome/test/data/webui/new_tab_page/app_test.ts +++ b/chrome/test/data/webui/new_tab_page/app_test.ts
@@ -823,6 +823,11 @@ }); }); + test('customize chrome in product help might show on startup'), () => { + assertEquals( + 1, handler.getCallCount('maybeShowCustomizeChromeFeaturePromo')); + }; + test('clicking customize button opens side panel', () => { // Act. $$<HTMLElement>(app, '#customizeButton')!.click();
diff --git a/chrome/test/data/webui/password_manager/BUILD.gn b/chrome/test/data/webui/password_manager/BUILD.gn index 3c2c6a027..28cff12 100644 --- a/chrome/test/data/webui/password_manager/BUILD.gn +++ b/chrome/test/data/webui/password_manager/BUILD.gn
@@ -25,8 +25,12 @@ "site_favicon_test.ts", "test_password_manager_proxy.ts", "test_prefs_browser_proxy.ts", + "test_promo_cards_browser_proxy.ts", "test_util.ts", ] + if (is_chrome_branded) { + files += [ "promo_cards_test.ts" ] + } ts_definitions = [ "//tools/typescript/definitions/passwords_private.d.ts",
diff --git a/chrome/test/data/webui/password_manager/password_manager_app_test.ts b/chrome/test/data/webui/password_manager/password_manager_app_test.ts index e848a73..23299be 100644 --- a/chrome/test/data/webui/password_manager/password_manager_app_test.ts +++ b/chrome/test/data/webui/password_manager/password_manager_app_test.ts
@@ -124,8 +124,7 @@ test('Search navigates to Passwords and updates URL parameters', function() { const query = new URLSearchParams(); query.set(UrlParam.START_CHECK, 'true'); - Router.getInstance().navigateTo(Page.CHECKUP); - Router.getInstance().updateRouterParams(query); + Router.getInstance().navigateTo(Page.CHECKUP, null, query); app.$.toolbar.$.mainToolbar.getSearchField().setValue('hello');
diff --git a/chrome/test/data/webui/password_manager/password_manager_browsertest.js b/chrome/test/data/webui/password_manager/password_manager_browsertest.js index 2a0b7a9..a16b39e 100644 --- a/chrome/test/data/webui/password_manager/password_manager_browsertest.js +++ b/chrome/test/data/webui/password_manager/password_manager_browsertest.js
@@ -9,6 +9,7 @@ GEN_INCLUDE(['//chrome/test/data/webui/polymer_browser_test_base.js']); GEN('#include "build/build_config.h"') +GEN('#include "build/branding_buildflags.h"'); GEN('#include "components/password_manager/core/common/password_manager_features.h"'); GEN('#include "content/public/test/browser_test.h"'); @@ -39,6 +40,9 @@ ['SiteFavicon', 'site_favicon_test.js'], ].forEach(test => registerTest(...test)); +GEN('#if BUILDFLAG(GOOGLE_CHROME_BRANDING)'); +registerTest('PromoCards', 'promo_cards_test.js'); +GEN('#endif'); function registerTest(testName, module, caseName) { const className = `PasswordManagerUI${testName}Test`;
diff --git a/chrome/test/data/webui/password_manager/password_manager_routing_test.ts b/chrome/test/data/webui/password_manager/password_manager_routing_test.ts index 67bc96a2..9ff4560 100644 --- a/chrome/test/data/webui/password_manager/password_manager_routing_test.ts +++ b/chrome/test/data/webui/password_manager/password_manager_routing_test.ts
@@ -82,4 +82,13 @@ assertEquals(Page.CHECKUP_DETAILS, router.currentRoute.page); assertEquals(CheckupSubpage.WEAK, router.currentRoute.details); }); + + test('navigate to with URLSearchParams', function() { + const newParams = new URLSearchParams(); + newParams.set(UrlParam.START_CHECK, 'true'); + Router.getInstance().navigateTo(Page.CHECKUP, null, newParams); + + assertEquals(newParams, Router.getInstance().currentRoute.queryParameters); + assertEquals(newParams, testElement.newRoute!.queryParameters); + }); });
diff --git a/chrome/test/data/webui/password_manager/promo_cards_test.ts b/chrome/test/data/webui/password_manager/promo_cards_test.ts new file mode 100644 index 0000000..db10df4e --- /dev/null +++ b/chrome/test/data/webui/password_manager/promo_cards_test.ts
@@ -0,0 +1,130 @@ +// 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 'chrome://password-manager/password_manager.js'; + +import {Page, PasswordManagerImpl, PasswordsSectionElement, PromoCardsProxyImpl, Router, UrlParam} from 'chrome://password-manager/password_manager.js'; +import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; +import {flushTasks} from 'chrome://webui-test/polymer_test_util.js'; +import {isVisible} from 'chrome://webui-test/test_util.js'; + +import {TestPasswordManagerProxy} from './test_password_manager_proxy.js'; +import {TestPromoCardsProxy} from './test_promo_cards_browser_proxy.js'; + +suite('PasswordsSectionTest', function() { + let passwordManager: TestPasswordManagerProxy; + let promoCardsProxy: TestPromoCardsProxy; + + async function createPasswordsSection(): Promise<PasswordsSectionElement> { + const section: PasswordsSectionElement = + document.createElement('passwords-section'); + document.body.appendChild(section); + await passwordManager.whenCalled('getCredentialGroups'); + await flushTasks(); + + return section; + } + + setup(function() { + document.body.innerHTML = window.trustedTypes!.emptyHTML; + passwordManager = new TestPasswordManagerProxy(); + PasswordManagerImpl.setInstance(passwordManager); + promoCardsProxy = new TestPromoCardsProxy(); + PromoCardsProxyImpl.setInstance(promoCardsProxy); + Router.getInstance().updateRouterParams(new URLSearchParams()); + return flushTasks(); + }); + + test('promo card shown', async function() { + promoCardsProxy.promo = { + id: 'test_promo', + title: 'Hello there', + description: 'This is a promo card.', + }; + + const section = await createPasswordsSection(); + let promoCardElement = section.shadowRoot!.querySelector('promo-card'); + + // Verify promo card is shown. + assertTrue(!!promoCardElement); + assertEquals( + promoCardsProxy.promo!.title, + promoCardElement.$.title.textContent!.trim()); + assertEquals( + promoCardsProxy.promo!.description, + promoCardElement.$.description.textContent!.trim()); + assertFalse(isVisible(promoCardElement.$.actionButton)); + const shownImage = promoCardElement.shadowRoot!.querySelector('img'); + assertTrue(!!shownImage); + assertEquals( + 'chrome://password-manager/images/test_promo.svg', shownImage.src); + + // Click close button. + promoCardElement.$.closeButton.click(); + assertEquals( + promoCardsProxy.promo?.id, + await promoCardsProxy.whenCalled('recordPromoDismissed')); + await flushTasks(); + + // Verify that the promo card is hidden. + promoCardElement = section.shadowRoot!.querySelector('promo-card'); + assertFalse(!!promoCardElement); + }); + + test('password checkup promo', async function() { + promoCardsProxy.promo = { + id: 'password_checkup_promo', + title: 'Checkup promo', + description: 'Checkup promo description.', + actionButtonText: 'Start check', + }; + + const section = await createPasswordsSection(); + let promoCardElement = section.shadowRoot!.querySelector('promo-card'); + + // Verify promo card is shown. + assertTrue(!!promoCardElement); + assertTrue(isVisible(promoCardElement.$.actionButton)); + + // Click action button button and verify we navigated to checkup page and + // started password checkup. + promoCardElement.$.actionButton.click(); + assertEquals(Page.CHECKUP, Router.getInstance().currentRoute.page); + assertEquals( + 'true', + String(Router.getInstance().currentRoute.queryParameters.get( + UrlParam.START_CHECK))); + await flushTasks(); + + // Verify that the promo card is hidden. + promoCardElement = section.shadowRoot!.querySelector('promo-card'); + assertFalse(!!promoCardElement); + }); + + test('shortcut promo', async function() { + promoCardsProxy.promo = { + id: 'password_shortcut_promo', + title: 'Shortcut promo', + description: 'Shortcut promo description.', + actionButtonText: 'Add shortcut', + }; + + const section = await createPasswordsSection(); + let promoCardElement = section.shadowRoot!.querySelector('promo-card'); + + // Verify promo card is shown. + assertTrue(!!promoCardElement); + assertTrue(isVisible(promoCardElement.$.actionButton)); + + // Click action button button and verify we navigated to checkup page and + // started password checkup. + promoCardElement.$.actionButton.click(); + await passwordManager.whenCalled('showAddShortcutDialog'); + await flushTasks(); + + // Verify that the promo card is hidden. + promoCardElement = section.shadowRoot!.querySelector('promo-card'); + assertFalse(!!promoCardElement); + }); +});
diff --git a/chrome/test/data/webui/password_manager/settings_section_test.ts b/chrome/test/data/webui/password_manager/settings_section_test.ts index ee90eda..fd1dad7c3 100644 --- a/chrome/test/data/webui/password_manager/settings_section_test.ts +++ b/chrome/test/data/webui/password_manager/settings_section_test.ts
@@ -82,6 +82,50 @@ assertFalse(value); }); + test('extension control disables toggle', async function() { + const enableServicePref = + await prefsProxy.getPref('credentials_enable_service'); + enableServicePref.extensionId = 'test'; + enableServicePref.controlledByName = 'test extension'; + + const settings = document.createElement('settings-section'); + document.body.appendChild(settings); + await prefsProxy.whenCalled('getPref'); + + assertTrue(settings.$.passwordToggle.checked); + settings.$.passwordToggle.click(); + assertTrue(settings.$.passwordToggle.checked); + + const postPref = await prefsProxy.getPref('credentials_enable_service'); + assertTrue(postPref.value); + }); + + test('extension control includes icon', async function() { + const enableServicePref = + await prefsProxy.getPref('credentials_enable_service'); + enableServicePref.extensionId = 'test'; + enableServicePref.controlledByName = 'test extension'; + + const settings = document.createElement('settings-section'); + document.body.appendChild(settings); + await prefsProxy.whenCalled('getPref'); + + assertTrue(settings.$.passwordToggle.checked); + assertTrue(!!settings.$.passwordToggle.shadowRoot!.querySelector( + '#extensionIcon')); + }); + + test('no extension control icon by default', async function() { + const settings = document.createElement('settings-section'); + document.body.appendChild(settings); + await prefsProxy.whenCalled('getPref'); + + assertTrue(settings.$.passwordToggle.checked); + settings.$.passwordToggle.click(); + assertFalse(!!settings.$.passwordToggle.shadowRoot!.querySelector( + '#extensionIcon')); + }); + test('pref updated externally', async function() { const settings = document.createElement('settings-section'); document.body.appendChild(settings);
diff --git a/chrome/test/data/webui/password_manager/test_promo_cards_browser_proxy.ts b/chrome/test/data/webui/password_manager/test_promo_cards_browser_proxy.ts new file mode 100644 index 0000000..3916a132 --- /dev/null +++ b/chrome/test/data/webui/password_manager/test_promo_cards_browser_proxy.ts
@@ -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. + +/** @fileoverview Test implementation of PromoCardsProxy. */ + +import {PromoCard, PromoCardsProxy} from 'chrome://password-manager/password_manager.js'; +import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js'; + +/** + * Test implementation + */ +export class TestPromoCardsProxy extends TestBrowserProxy implements + PromoCardsProxy { + promo: PromoCard|null; + + constructor() { + super([ + 'getAvailablePromoCard', + 'recordPromoDismissed', + ]); + + this.promo = null; + } + + getAvailablePromoCard() { + this.methodCalled('getAvailablePromoCard'); + return Promise.resolve(this.promo); + } + + recordPromoDismissed(id: string) { + this.methodCalled('recordPromoDismissed', id); + } +}
diff --git a/chrome/test/data/webui/settings/chromeos/os_a11y_page/text_to_speech_page_tests.ts b/chrome/test/data/webui/settings/chromeos/os_a11y_page/text_to_speech_page_tests.ts index 28e1813..f5a0f54 100644 --- a/chrome/test/data/webui/settings/chromeos/os_a11y_page/text_to_speech_page_tests.ts +++ b/chrome/test/data/webui/settings/chromeos/os_a11y_page/text_to_speech_page_tests.ts
@@ -93,7 +93,9 @@ test( 'pdf ocr pref enabled when both pdf ocr and screen reader enabled', async function() { - loadTimeData.overrideValues({pdfOcrEnabled: true}); + // `features::kPdfOcr` is enabled in os_settings_v3_browsertest.js + assertTrue(loadTimeData.getBoolean('pdfOcrEnabled')); + await initPage(); // Simulate enabling the ChromeVox. page.hasScreenReader = true;
diff --git a/chrome/test/data/webui/settings/chromeos/os_a11y_page_tests.js b/chrome/test/data/webui/settings/chromeos/os_a11y_page_tests.js index 69e35e11..d45f6af8 100644 --- a/chrome/test/data/webui/settings/chromeos/os_a11y_page_tests.js +++ b/chrome/test/data/webui/settings/chromeos/os_a11y_page_tests.js
@@ -72,7 +72,8 @@ test('Checking pdf ocr toggle visibility in the TTS page', async () => { // Need to have this test here as the screen reader state is passed from // the os-settings-a11y-page to the settings-text-to-speech-page. - loadTimeData.overrideValues({pdfOcrEnabled: true}); + // `features::kPdfOcr` is enabled in os_settings_v3_browsertest.js + assertTrue(loadTimeData.getBoolean('pdfOcrEnabled')); Router.getInstance().navigateTo(routes.A11Y_TEXT_TO_SPEECH); flush();
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js index a52a8c8df..7304a94 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js
@@ -200,7 +200,11 @@ mocha.run(); }); -[['AccessibilityPage', 'os_a11y_page_tests.js'], +[[ + 'AccessibilityPage', + 'os_a11y_page_tests.js', + {enabled: ['features::kPdfOcr']}, + ], ['AboutPage', 'os_about_page_tests.js'], ['ApnDetailDialog', 'apn_detail_dialog_tests.js'], [ @@ -387,6 +391,7 @@ [ 'OsA11yPageTextToSpeechPage', 'os_a11y_page/text_to_speech_page_tests.js', + {enabled: ['features::kPdfOcr']}, ], [ 'OsA11yPageTextToSpeechSubpage',
diff --git a/chrome/test/data/webui/settings/chromeos/per_device_keyboard_subsection_test.js b/chrome/test/data/webui/settings/chromeos/per_device_keyboard_subsection_test.js index 7c1a2b78..e3f28ff 100644 --- a/chrome/test/data/webui/settings/chromeos/per_device_keyboard_subsection_test.js +++ b/chrome/test/data/webui/settings/chromeos/per_device_keyboard_subsection_test.js
@@ -11,6 +11,7 @@ import {isVisible} from 'chrome://webui-test/test_util.js'; const KEYBOARD_FUNCTION_KEYS_SETTING_ID = 411; +const KEYBOARD_SWITCH_TOP_ROW_KEYS_SETTING_ID = 441; suite('PerDeviceKeyboardSubsection', function() { /** @@ -263,18 +264,33 @@ '#externalTopRowAreFunctionKeysButton'); subsection.keyboardIndex = 0; // Enter the page from auto repeat search tag. - const url = new URLSearchParams( + const searchAutoRepeatUrl = new URLSearchParams( 'search=keyboard&settingId=' + encodeURIComponent(KEYBOARD_FUNCTION_KEYS_SETTING_ID)); await Router.getInstance().navigateTo( routes.PER_DEVICE_KEYBOARD, - /* dynamicParams= */ url, /* removeSearch= */ true); + /* dynamicParams= */ searchAutoRepeatUrl, /* removeSearch= */ true); await waitAfterNextRender(topRowAreFunctionKeysToggle); assertTrue(!!topRowAreFunctionKeysToggle); assertEquals( subsection.shadowRoot.activeElement, topRowAreFunctionKeysToggle); + + const switchTopRowKeysButton = subsection.shadowRoot.querySelector( + '#blockMetaFunctionKeyRewritesButton'); + const searchSwitchTopRowKeysUrl = new URLSearchParams( + 'search=switch+top&settingId=' + + encodeURIComponent(KEYBOARD_SWITCH_TOP_ROW_KEYS_SETTING_ID)); + + await Router.getInstance().navigateTo( + routes.PER_DEVICE_KEYBOARD, + /* dynamicParams= */ searchSwitchTopRowKeysUrl, + /* removeSearch= */ true); + + await waitAfterNextRender(switchTopRowKeysButton); + assertTrue(!!switchTopRowKeysButton); + assertEquals(subsection.shadowRoot.activeElement, switchTopRowKeysButton); }); /** @@ -298,5 +314,20 @@ assertTrue(!!topRowAreFunctionKeysToggle); assertFalse(!!subsection.shadowRoot.activeElement); + + const switchTopRowKeysButton = subsection.shadowRoot.querySelector( + '#blockMetaFunctionKeyRewritesButton'); + const searchSwitchTopRowKeysUrl = new URLSearchParams( + 'search=switch+top&settingId=' + + encodeURIComponent(KEYBOARD_SWITCH_TOP_ROW_KEYS_SETTING_ID)); + + await Router.getInstance().navigateTo( + routes.PER_DEVICE_KEYBOARD, + /* dynamicParams= */ searchSwitchTopRowKeysUrl, + /* removeSearch= */ true); + + await flushTasks(); + assertTrue(!!switchTopRowKeysButton); + assertFalse(!!subsection.shadowRoot.activeElement); }); });
diff --git a/chrome/test/interaction/README.md b/chrome/test/interaction/README.md index 9196856..7137056 100644 --- a/chrome/test/interaction/README.md +++ b/chrome/test/interaction/README.md
@@ -1,12 +1,17 @@ # Interactive Testing API: "Kombucha" +**[go/kombucha-api](goto.google.com/kombucha-api)** + **Kombucha** is a group of powerful test mix-ins that let you easily and concisely write interactive tests. -The current API version is 1.55. All future 1.x versions are guaranteed to +The current API version is 2.0. All future 2.x versions are guaranteed to either be backwards-compatible with existing tests, or the authors will update the API calls for you. +This page provides technical documentation. For a cookbook/FAQ/troubleshooting +guide, see our [Kombucha Playbook](goto.google.com/kombucha-playbook). + [TOC] ## Getting Started
diff --git a/chrome/updater/app/app_uninstall.cc b/chrome/updater/app/app_uninstall.cc index 2e85b41..2b60664 100644 --- a/chrome/updater/app/app_uninstall.cc +++ b/chrome/updater/app/app_uninstall.cc
@@ -22,11 +22,15 @@ #include "build/build_config.h" #include "chrome/updater/app/app.h" #include "chrome/updater/app/app_utils.h" +#include "chrome/updater/configurator.h" #include "chrome/updater/constants.h" +#include "chrome/updater/external_constants.h" #include "chrome/updater/lock.h" #include "chrome/updater/persisted_data.h" #include "chrome/updater/prefs.h" +#include "chrome/updater/updater_version.h" #include "chrome/updater/util/util.h" +#include "components/update_client/update_client.h" #include "third_party/abseil-cpp/absl/types/optional.h" #if BUILDFLAG(IS_WIN) @@ -87,12 +91,16 @@ void Uninitialize() override; void FirstTaskRun() override; - void UninstallAll(); + void UninstallAll(int reason); - // Inter-process lock taken by AppInstall, AppUninstall, and AppUpdate. + // Inter-process lock taken by AppInstall, AppUninstall, and AppUpdate. May + // be null if the setup lock wasn't acquired. std::unique_ptr<ScopedLock> setup_lock_; + // These may be null if the global prefs lock wasn't acquired. scoped_refptr<GlobalPrefs> global_prefs_; + scoped_refptr<PersistedData> persisted_data_; + scoped_refptr<Configurator> config_; }; void AppUninstall::Initialize() { @@ -100,22 +108,50 @@ ScopedLock::Create(kSetupMutex, updater_scope(), kWaitForSetupLock); global_prefs_ = CreateGlobalPrefs(updater_scope()); + + if (global_prefs_) { + persisted_data_ = base::MakeRefCounted<PersistedData>( + updater_scope(), global_prefs_->GetPrefService()); + config_ = base::MakeRefCounted<Configurator>(global_prefs_, + CreateExternalConstants()); + } } void AppUninstall::Uninitialize() { global_prefs_ = nullptr; } -void AppUninstall::UninstallAll() { - base::ThreadPool::PostTaskAndReplyWithResult( - FROM_HERE, {base::MayBlock()}, +void AppUninstall::UninstallAll(int reason) { + update_client::CrxComponent uninstall_data; + uninstall_data.ap = persisted_data_->GetAP(kUpdaterAppId); + uninstall_data.app_id = kUpdaterAppId; + uninstall_data.brand = persisted_data_->GetBrandCode(kUpdaterAppId); + uninstall_data.requires_network_encryption = false; + uninstall_data.version = persisted_data_->GetProductVersion(kUpdaterAppId); + if (!uninstall_data.version.IsValid()) { + // In cases where there is no version in persisted data, fall back to the + // currently-running version of the updater. + uninstall_data.version = base::Version(kUpdaterVersion); + } + update_client::UpdateClientFactory(config_)->SendUninstallPing( + uninstall_data, reason, base::BindOnce( - [](UpdaterScope scope) { - UninstallOtherVersions(scope); - return Uninstall(scope); + [](base::OnceCallback<void(int)> shutdown, UpdaterScope scope, + update_client::Error uninstall_ping_error) { + VLOG_IF(1, uninstall_ping_error != update_client::Error::NONE) + << "Uninstall ping failed: " + << static_cast<int>(uninstall_ping_error); + base::ThreadPool::PostTaskAndReplyWithResult( + FROM_HERE, {base::MayBlock()}, + base::BindOnce( + [](UpdaterScope scope) { + UninstallOtherVersions(scope); + return Uninstall(scope); + }, + scope), + std::move(shutdown)); }, - updater_scope()), - base::BindOnce(&AppUninstall::Shutdown, this)); + base::BindOnce(&AppUninstall::Shutdown, this), updater_scope())); } void AppUninstall::FirstTaskRun() { @@ -141,19 +177,19 @@ base::CommandLine::ForCurrentProcess(); if (command_line->HasSwitch(kUninstallSwitch)) { - UninstallAll(); + UninstallAll(kUninstallPingReasonUninstalled); return; } if (command_line->HasSwitch(kUninstallIfUnusedSwitch)) { - auto persisted_data = base::MakeRefCounted<PersistedData>( - updater_scope(), global_prefs_->GetPrefService()); - const bool should_uninstall = ShouldUninstall( - persisted_data->GetAppIds(), global_prefs_->CountServerStarts(), - persisted_data->GetHadApps()); + const bool had_apps = persisted_data_->GetHadApps(); + const bool should_uninstall = + ShouldUninstall(persisted_data_->GetAppIds(), + global_prefs_->CountServerStarts(), had_apps); VLOG(1) << "ShouldUninstall returned: " << should_uninstall; if (should_uninstall) { - UninstallAll(); + UninstallAll(had_apps ? kUninstallPingReasonNoAppsRemain + : kUninstallPingReasonNeverHadApps); } else { base::SequencedTaskRunner::GetCurrentDefault()->PostTask( FROM_HERE, base::BindOnce(&AppUninstall::Shutdown, this, 0));
diff --git a/chrome/updater/constants.h b/chrome/updater/constants.h index 9d6968ff..f720d4e0 100644 --- a/chrome/updater/constants.h +++ b/chrome/updater/constants.h
@@ -444,6 +444,8 @@ inline constexpr int kUninstallPingReasonUninstalled = 0; inline constexpr int kUninstallPingReasonUserNotAnOwner = 1; +inline constexpr int kUninstallPingReasonNoAppsRemain = 2; +inline constexpr int kUninstallPingReasonNeverHadApps = 3; // The file downloaded to a temporary location could not be moved. inline constexpr int kErrorFailedToMoveDownloadedFile = 5;
diff --git a/chrome/updater/mac/BUILD.gn b/chrome/updater/mac/BUILD.gn index 44381a9..37d5f665 100644 --- a/chrome/updater/mac/BUILD.gn +++ b/chrome/updater/mac/BUILD.gn
@@ -52,7 +52,7 @@ "//chrome/updater:constants_prod", ] public_deps = [ - ":ksadmin", + ":ksadmin_copy", ":ksadmin_link", ] } @@ -77,7 +77,10 @@ if (is_asan) { deps += [ ":keystone_agent_bundle_resource_executable_test_asan_dylib" ] } - public_deps = [ ":ksadmin_test_copy" ] + public_deps = [ + ":ksadmin_test_copy", + ":ksadmin_test_link", + ] } source_set("privileged_helper_sources") { @@ -331,7 +334,7 @@ } executable("ksadmin") { - output_dir = "$root_out_dir/${updater_product_full_name}.app/Contents/Helpers/$keystone_app_name.bundle/Contents/Helpers" + output_name = "ksadmin" sources = [ "keystone/ksadmin_main.cc" ] deps = [ @@ -348,8 +351,14 @@ } } +copy("ksadmin_copy") { + sources = [ "$root_out_dir/ksadmin" ] + outputs = [ "$root_out_dir/${updater_product_full_name}.app/Contents/Helpers/$keystone_app_name.bundle/Contents/Helpers/ksadmin" ] + deps = [ ":ksadmin" ] +} + executable("ksadmin_test") { - output_dir = "$root_gen_dir" + output_name = "ksadmin_test" sources = [ "keystone/ksadmin_main.cc" ] deps = [ @@ -367,7 +376,7 @@ } copy("ksadmin_test_copy") { - sources = [ "${root_gen_dir}/ksadmin_test" ] + sources = [ "$root_out_dir/ksadmin_test" ] outputs = [ "$root_out_dir/${updater_product_full_name}_test.app/Contents/Helpers/$keystone_app_name.bundle/Contents/Helpers/ksadmin" ] deps = [ ":ksadmin_test" ] } @@ -402,6 +411,12 @@ deps = [ ":ksadmin" ] } +symlink("ksadmin_test_link") { + source = "$root_out_dir/${updater_product_full_name}_test.app/Contents/Helpers/$keystone_app_name.bundle/Contents/Helpers/ksadmin" + output = "$root_out_dir/${updater_product_full_name}_test.app/Contents/Helpers/$keystone_app_name.bundle/Contents/MacOS/ksadmin" + deps = [ ":ksadmin_test" ] +} + mac_app_bundle("keystone_agent_bundle") { info_plist = "keystone/Info.plist" sources = [ "keystone/agent_main.cc" ] @@ -586,6 +601,7 @@ "$root_build_dir/${updater_product_full_name}_test.app/Contents/Helpers/$keystone_app_name.bundle/Contents/MacOS/$keystone_app_name", "$root_build_dir/${updater_product_full_name}_test.app/Contents/Helpers/$keystone_app_name.bundle/Contents/Helpers/ksinstall", "$root_build_dir/${updater_product_full_name}_test.app/Contents/Helpers/$keystone_app_name.bundle/Contents/Helpers/ksadmin", + "$root_build_dir/${updater_product_full_name}_test.app/Contents/Helpers/$keystone_app_name.bundle/Contents/MacOS/ksadmin", "$root_build_dir/${updater_product_full_name}_test.app/Contents/Helpers/$keystone_app_name.bundle/Contents/Resources/${keystone_app_name}Agent.app/Contents/MacOS/${keystone_app_name}Agent", "$root_build_dir/${updater_product_full_name}_test.app/Contents/Helpers/$keystone_app_name.bundle/Contents/Resources/${keystone_app_name}Agent.app/Contents/Info.plist", "$root_build_dir/${updater_product_full_name}_test.app/Contents/Helpers/$keystone_app_name.bundle/Contents/Info.plist",
diff --git a/chrome/updater/mac/keystone/ksadmin_unittest.cc b/chrome/updater/mac/keystone/ksadmin_unittest.cc index 2d23bf9..0cdd482 100644 --- a/chrome/updater/mac/keystone/ksadmin_unittest.cc +++ b/chrome/updater/mac/keystone/ksadmin_unittest.cc
@@ -14,7 +14,6 @@ #include "base/process/launch.h" #include "base/process/process.h" #include "base/strings/strcat.h" -#include "chrome/updater/updater_branding.h" #include "chrome/updater/updater_version.h" #include "testing/gtest/include/gtest/gtest.h" @@ -27,14 +26,7 @@ int RunKSAdmin(std::string* std_out, const std::vector<std::string>& args) { base::FilePath out_dir; EXPECT_TRUE(base::PathService::Get(base::DIR_EXE, &out_dir)); - base::CommandLine command( - out_dir.Append(base::StrCat({PRODUCT_FULLNAME_STRING, ".app"})) - .Append(FILE_PATH_LITERAL("Contents")) - .Append(FILE_PATH_LITERAL("Helpers")) - .Append(FILE_PATH_LITERAL(KEYSTONE_NAME ".bundle")) - .Append(FILE_PATH_LITERAL("Contents")) - .Append(FILE_PATH_LITERAL("Helpers")) - .Append(FILE_PATH_LITERAL("ksadmin"))); + base::CommandLine command(out_dir.Append(FILE_PATH_LITERAL("ksadmin"))); for (const auto& arg : args) { command.AppendSwitch(arg); }
diff --git a/chrome/updater/test/integration_test_commands.h b/chrome/updater/test/integration_test_commands.h index 6df6637..e5e1c72d 100644 --- a/chrome/updater/test/integration_test_commands.h +++ b/chrome/updater/test/integration_test_commands.h
@@ -41,6 +41,7 @@ virtual void ExpectActive(const std::string& app_id) const = 0; virtual void ExpectNotActive(const std::string& app_id) const = 0; virtual void ExpectSelfUpdateSequence(ScopedServer* test_server) const = 0; + virtual void ExpectUninstallPing(ScopedServer* test_server) const = 0; virtual void ExpectUpdateCheckSequence( ScopedServer* test_server, const std::string& app_id,
diff --git a/chrome/updater/test/integration_test_commands_system.cc b/chrome/updater/test/integration_test_commands_system.cc index f8176c0..6e8bd35 100644 --- a/chrome/updater/test/integration_test_commands_system.cc +++ b/chrome/updater/test/integration_test_commands_system.cc
@@ -97,6 +97,10 @@ updater::test::ExpectSelfUpdateSequence(updater_scope_, test_server); } + void ExpectUninstallPing(ScopedServer* test_server) const override { + updater::test::ExpectUninstallPing(updater_scope_, test_server); + } + void ExpectUpdateCheckSequence( ScopedServer* test_server, const std::string& app_id,
diff --git a/chrome/updater/test/integration_test_commands_user.cc b/chrome/updater/test/integration_test_commands_user.cc index 23344bd7..d33d9abe 100644 --- a/chrome/updater/test/integration_test_commands_user.cc +++ b/chrome/updater/test/integration_test_commands_user.cc
@@ -77,6 +77,10 @@ updater::test::SetGroupPolicies(values); } + void ExpectUninstallPing(ScopedServer* test_server) const override { + updater::test::ExpectUninstallPing(updater_scope_, test_server); + } + void ExpectUpdateCheckSequence( ScopedServer* test_server, const std::string& app_id,
diff --git a/chrome/updater/test/integration_tests.cc b/chrome/updater/test/integration_tests.cc index ab77a46f..92b612b8 100644 --- a/chrome/updater/test/integration_tests.cc +++ b/chrome/updater/test/integration_tests.cc
@@ -335,6 +335,10 @@ from_version, to_version); } + void ExpectUninstallPing(ScopedServer* test_server) { + test_commands_->ExpectUninstallPing(test_server); + } + void ExpectUpdateSequence(ScopedServer* test_server, const std::string& app_id, const std::string& install_data_index, @@ -511,6 +515,7 @@ ASSERT_TRUE(WaitForUpdaterExit()); ASSERT_NO_FATAL_FAILURE(ExpectVersionActive(kUpdaterVersion)); + ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(&test_server)); ASSERT_NO_FATAL_FAILURE(Uninstall()); } @@ -527,6 +532,7 @@ ASSERT_TRUE(WaitForUpdaterExit()); ASSERT_NO_FATAL_FAILURE(ExpectAppVersion(kUpdaterAppId, next_version)); + ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(&test_server)); ASSERT_NO_FATAL_FAILURE(Uninstall()); } @@ -543,6 +549,7 @@ ASSERT_TRUE(WaitForUpdaterExit()); ASSERT_NO_FATAL_FAILURE(ExpectAppVersion(kUpdaterAppId, next_version)); + ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(&test_server)); ASSERT_NO_FATAL_FAILURE(Uninstall()); } @@ -583,6 +590,7 @@ ASSERT_NO_FATAL_FAILURE(ExpectNotActive("test1")); ASSERT_NO_FATAL_FAILURE(ExpectNotActive("test2")); + ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(&test_server)); ASSERT_NO_FATAL_FAILURE(Uninstall()); } @@ -621,6 +629,7 @@ base::Version("0.1"), base::Version("1"))); ASSERT_NO_FATAL_FAILURE(CheckForUpdate(kAppId)); + ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(&test_server)); ASSERT_NO_FATAL_FAILURE(Uninstall()); } @@ -648,6 +657,7 @@ ASSERT_NO_FATAL_FAILURE(ExpectLastChecked()); ASSERT_NO_FATAL_FAILURE(ExpectLastStarted()); + ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(&test_server)); ASSERT_NO_FATAL_FAILURE(Uninstall()); } @@ -665,6 +675,7 @@ ASSERT_NO_FATAL_FAILURE(ExpectAppVersion(kAppId, v1)); + ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(&test_server)); ASSERT_NO_FATAL_FAILURE(Uninstall()); } @@ -681,6 +692,7 @@ ASSERT_TRUE(WaitForUpdaterExit()); ASSERT_NO_FATAL_FAILURE(ExpectAppVersion(kAppId, v1)); + ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(&test_server)); ASSERT_NO_FATAL_FAILURE(Uninstall()); } @@ -708,6 +720,7 @@ ASSERT_TRUE(WaitForUpdaterExit()); ASSERT_NO_FATAL_FAILURE(ExpectAppVersion(kAppId, v1)); + ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(&test_server)); ASSERT_NO_FATAL_FAILURE(Uninstall()); } #endif // BUILDFLAG(IS_WIN) @@ -721,6 +734,7 @@ ASSERT_NO_FATAL_FAILURE(RunWake(0)); ASSERT_NO_FATAL_FAILURE(RunWake(0)); + ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(&test_server)); ASSERT_NO_FATAL_FAILURE(Uninstall()); } @@ -733,6 +747,7 @@ ASSERT_NO_FATAL_FAILURE(ExpectNoUpdateSequence(&test_server, kUpdaterAppId)); ASSERT_NO_FATAL_FAILURE(UpdateAll()); + ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(&test_server)); ASSERT_NO_FATAL_FAILURE(Uninstall()); } @@ -778,6 +793,7 @@ ASSERT_NO_FATAL_FAILURE(ExpectLegacyPolicyStatusSucceeds()); + ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(&test_server)); ASSERT_NO_FATAL_FAILURE(Uninstall()); } @@ -911,6 +927,7 @@ ASSERT_TRUE(WaitForUpdaterExit()); ASSERT_NO_FATAL_FAILURE(ExpectVersionActive(kUpdaterVersion)); + ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(&test_server)); ASSERT_NO_FATAL_FAILURE(Uninstall()); } @@ -938,6 +955,7 @@ ASSERT_NO_FATAL_FAILURE(ExpectVersionActive(kUpdaterVersion)); + ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(&test_server)); ASSERT_NO_FATAL_FAILURE(SetServerStarts(24)); ASSERT_NO_FATAL_FAILURE(RunWake(0)); ASSERT_TRUE(WaitForUpdaterExit()); @@ -1015,6 +1033,7 @@ response); ASSERT_NO_FATAL_FAILURE(CallServiceUpdate( app_id, "", UpdateService::PolicySameVersionUpdate::kNotAllowed)); + ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(&test_server)); ASSERT_NO_FATAL_FAILURE(Uninstall()); } @@ -1056,6 +1075,7 @@ CallServiceUpdate(app_id, install_data_index, UpdateService::PolicySameVersionUpdate::kAllowed)); + ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(&test_server)); ASSERT_NO_FATAL_FAILURE(Uninstall()); } @@ -1118,6 +1138,7 @@ } void TearDown() override { + ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(test_server_.get())); ASSERT_NO_FATAL_FAILURE(Uninstall()); IntegrationTest::TearDown();
diff --git a/chrome/updater/test/integration_tests_impl.cc b/chrome/updater/test/integration_tests_impl.cc index c485564..5fc5015 100644 --- a/chrome/updater/test/integration_tests_impl.cc +++ b/chrome/updater/test/integration_tests_impl.cc
@@ -636,6 +636,13 @@ return true; } +void ExpectUninstallPing(UpdaterScope scope, ScopedServer* test_server) { + test_server->ExpectOnce( + {base::BindRepeating(RequestMatcherRegex, R"(.*"eventtype":4.*)"), + GetScopePredicate(scope)}, + ")]}'\n"); +} + void ExpectSelfUpdateSequence(UpdaterScope scope, ScopedServer* test_server) { base::FilePath test_data_path; ASSERT_TRUE(base::PathService::Get(base::DIR_EXE, &test_data_path));
diff --git a/chrome/updater/test/integration_tests_impl.h b/chrome/updater/test/integration_tests_impl.h index 0d8744bf..fd8d75b1c 100644 --- a/chrome/updater/test/integration_tests_impl.h +++ b/chrome/updater/test/integration_tests_impl.h
@@ -223,6 +223,8 @@ void ExpectSelfUpdateSequence(UpdaterScope scope, ScopedServer* test_server); +void ExpectUninstallPing(UpdaterScope scope, ScopedServer* test_server); + void ExpectUpdateCheckSequence(UpdaterScope scope, ScopedServer* test_server, const std::string& app_id,
diff --git a/chrome/updater/test/integration_tests_win.cc b/chrome/updater/test/integration_tests_win.cc index 98f8e1f6..3428259 100644 --- a/chrome/updater/test/integration_tests_win.cc +++ b/chrome/updater/test/integration_tests_win.cc
@@ -647,11 +647,11 @@ // dir, because it is useful for tests to be able to run it to clean the // system even if installation has failed or the installed binaries have // already been removed. - base::FilePath path = - GetSetupExecutablePath().DirName().Append(GetExecutableRelativePath()); + base::FilePath path = GetSetupExecutablePath().DirName().Append( + FILE_PATH_LITERAL("updater_test.exe")); ASSERT_FALSE(path.empty()); base::CommandLine command_line(path); - command_line.AppendSwitch("uninstall"); + command_line.AppendSwitch(kUninstallSwitch); int exit_code = -1; Run(scope, command_line, &exit_code);
diff --git a/chrome/updater/util/win_util.h b/chrome/updater/util/win_util.h index 92844c7..4eb71fc 100644 --- a/chrome/updater/util/win_util.h +++ b/chrome/updater/util/win_util.h
@@ -24,7 +24,6 @@ #include "base/types/expected.h" #include "base/win/atl.h" #include "base/win/scoped_handle.h" -#include "base/win/win_util.h" #include "base/win/windows_types.h" #include "chrome/updater/updater_scope.h" #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/chromeos/ash/components/audio/cros_audio_config_impl.cc b/chromeos/ash/components/audio/cros_audio_config_impl.cc index e732704d..9374296 100644 --- a/chromeos/ash/components/audio/cros_audio_config_impl.cc +++ b/chromeos/ash/components/audio/cros_audio_config_impl.cc
@@ -16,7 +16,6 @@ namespace { constexpr int kDefaultInternalMicId = 0; -constexpr char kStubInternalMicDisplayName[] = "Internal Mic"; constexpr base::TimeDelta kMetricsDelayTimerInterval = base::Seconds(2); // Histogram names. @@ -42,8 +41,6 @@ AudioDevice internal_mic; internal_mic.id = kDefaultInternalMicId; internal_mic.is_input = true; - // TODO(b/260277007): Replace with lookup for localized device name. - internal_mic.display_name = kStubInternalMicDisplayName; internal_mic.stable_device_id_version = 2; internal_mic.type = AudioDeviceType::kInternalMic; internal_mic.active = false;
diff --git a/chromeos/ash/components/audio/cros_audio_config_impl_unittest.cc b/chromeos/ash/components/audio/cros_audio_config_impl_unittest.cc index 22f37294..a37e0ae 100644 --- a/chromeos/ash/components/audio/cros_audio_config_impl_unittest.cc +++ b/chromeos/ash/components/audio/cros_audio_config_impl_unittest.cc
@@ -949,8 +949,7 @@ fake_observer->last_audio_system_properties_.value() ->input_devices[1] .Clone(); - const std::string expected_display_name = "Internal Mic"; - EXPECT_EQ(expected_display_name, internal_mic->display_name); + EXPECT_EQ(mojom::AudioDeviceType::kInternalMic, internal_mic->device_type); EXPECT_FALSE(internal_mic->is_active); SimulateSetActiveDevice(kInternalMicFrontId); @@ -961,7 +960,7 @@ internal_mic = fake_observer->last_audio_system_properties_.value() ->input_devices[1] .Clone(); - EXPECT_EQ(expected_display_name, internal_mic->display_name); + EXPECT_EQ(mojom::AudioDeviceType::kInternalMic, internal_mic->device_type); EXPECT_TRUE(internal_mic->is_active); // Verify rear device ID will also set internal mic to active. @@ -974,7 +973,7 @@ internal_mic = fake_observer->last_audio_system_properties_.value() ->input_devices[1] .Clone(); - EXPECT_EQ(expected_display_name, internal_mic->display_name); + EXPECT_EQ(mojom::AudioDeviceType::kInternalMic, internal_mic->device_type); EXPECT_TRUE(internal_mic->is_active); }
diff --git a/chromeos/ash/components/dbus/shill/README.md b/chromeos/ash/components/dbus/shill/README.md index 366d83c..f9db152 100644 --- a/chromeos/ash/components/dbus/shill/README.md +++ b/chromeos/ash/components/dbus/shill/README.md
@@ -1,11 +1,11 @@ # Overview -The Shill D-Bus client is a critical component of the Chrome OS network stack -that facilitates communication between applications and system components with -Shill via D-Bus. This client provides a high-level API that enables interaction +The Shill D-Bus clients are a critical component of the Chrome OS network stack +that facilitate communication between applications and system components with +Shill via D-Bus. These clients provide a high-level API that enables interaction with the following Shill services: * [Shill manager service](#shill-manager-client) * Shill device service -* Shill IPconfig service +* [Shill IPconfig service](#shill-ipconfig-client) * Shill profile service * Shill service service @@ -62,4 +62,24 @@ setting fake responses. For example, `SetInteractiveDelay` sets the fake interactive delay for the following shill response for testing purposes, while `SetSimulateConfigurationResult` sets the following `ConfigureService` call to -succeed, fail or timeout. \ No newline at end of file +succeed, fail or timeout. + +## Shill IPConfig client +The [ShillIPConfigClient](https://source.chromium.org/chromium/chromium/src/+/main:chromeos/ash/components/dbus/shill/shill_ipconfig_client.h;drc=ad947e92bd398452f42173e7a39ed7ab2e4ad094) +class provides an interface for interacting with the Shill IPConfig interface +which is the top-level singleton exposed by Shill that provides Layer 3 +configuration. It enables Chrome to: +* Get, set, clear, or observe changes to IPConfig properties +* Remove IPConfig entries + +For detailed documentation on the Shill IPConfig DBus API, please refer to +[ipconfig-api.txt](https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform2/shill/doc/ipconfig-api.txt;drc=9a98a2fb4b28a8e3c32d7eafb39395ccbc730538). + +All Shill methods must be called from the origin thread that initializes the +DBusThreadManager instance. Most methods that make Shill IPConfig calls pass +a callback that is invoked when the method finishes. + +Additionally, ShillIPConfigClient provides a +[test interface](https://source.chromium.org/chromium/chromium/src/+/main:chromeos/ash/components/dbus/shill/shill_ipconfig_client.h;l=32-40;drc=ad947e92bd398452f42173e7a39ed7ab2e4ad094) +that allows you to add fake IPConfig entries for ChromeOS unit testing +purposes. This interface is implemented in the [FakeShillIPConfigClient](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:chromeos/ash/components/dbus/shill/fake_shill_ipconfig_client.h;drc=ad947e92bd398452f42173e7a39ed7ab2e4ad094). \ No newline at end of file
diff --git a/chromeos/ash/components/network/network_state_handler.cc b/chromeos/ash/components/network/network_state_handler.cc index 3c9ddc86..b3717b64 100644 --- a/chromeos/ash/components/network/network_state_handler.cc +++ b/chromeos/ash/components/network/network_state_handler.cc
@@ -1729,7 +1729,6 @@ case ManagedState::MANAGED_TYPE_NETWORK: AddOrRemoveStubCellularNetworks(); SortNetworkList(); - UpdateNetworkStats(); NotifyIfActiveNetworksChanged(); NotifyNetworkListChanged(); UpdateBlockedCellularNetworks(); @@ -1806,25 +1805,6 @@ network_list_sorted_ = true; } -void NetworkStateHandler::UpdateNetworkStats() { - size_t shared = 0, unshared = 0, visible = 0; - for (ManagedStateList::iterator iter = network_list_.begin(); - iter != network_list_.end(); ++iter) { - const NetworkState* network = (*iter)->AsNetworkState(); - if (network->visible()) - ++visible; - if (network->IsInProfile()) { - if (network->IsPrivate()) - ++unshared; - else - ++shared; - } - } - base::UmaHistogramCounts100("Networks.Visible", visible); - base::UmaHistogramCounts100("Networks.RememberedShared", shared); - base::UmaHistogramCounts100("Networks.RememberedUnshared", unshared); -} - void NetworkStateHandler::DefaultNetworkServiceChanged( const std::string& service_path) { // Shill uses '/' for empty service path values; check explicitly for that.
diff --git a/chromeos/ash/components/network/network_state_handler.h b/chromeos/ash/components/network/network_state_handler.h index 74f90ac..430dd937 100644 --- a/chromeos/ash/components/network/network_state_handler.h +++ b/chromeos/ash/components/network/network_state_handler.h
@@ -591,9 +591,6 @@ // * Hidden (wifi) networks void SortNetworkList(); - // Updates UMA stats. Called once after all requested networks are updated. - void UpdateNetworkStats(); - // NetworkState specific method for UpdateManagedStateProperties which // notifies observers. void UpdateNetworkStateProperties(NetworkState* network,
diff --git a/chromeos/ash/components/phonehub/browser_tabs_metadata_fetcher.h b/chromeos/ash/components/phonehub/browser_tabs_metadata_fetcher.h index 44b565b7..9ad2f08c9 100644 --- a/chromeos/ash/components/phonehub/browser_tabs_metadata_fetcher.h +++ b/chromeos/ash/components/phonehub/browser_tabs_metadata_fetcher.h
@@ -15,9 +15,12 @@ struct SyncedSession; } // namespace sync_sessions +class SyncedSessionClientAsh; + namespace ash { struct ForeignSyncedSessionAsh; +class SyncedSessionClientAsh; namespace phonehub { @@ -43,6 +46,7 @@ base::OnceCallback<void(BrowserTabsMetadataResponse)> callback) = 0; virtual void FetchForeignSyncedPhoneSessionMetadata( const ForeignSyncedSessionAsh& session, + SyncedSessionClientAsh* synced_session_client_ash, base::OnceCallback<void(BrowserTabsMetadataResponse)> callback) = 0; protected:
diff --git a/chromeos/ash/components/phonehub/fake_browser_tabs_metadata_fetcher.cc b/chromeos/ash/components/phonehub/fake_browser_tabs_metadata_fetcher.cc index 8fed9b0..7650b17 100644 --- a/chromeos/ash/components/phonehub/fake_browser_tabs_metadata_fetcher.cc +++ b/chromeos/ash/components/phonehub/fake_browser_tabs_metadata_fetcher.cc
@@ -21,6 +21,7 @@ void FakeBrowserTabsMetadataFetcher::FetchForeignSyncedPhoneSessionMetadata( const ash::ForeignSyncedSessionAsh& session, + SyncedSessionClientAsh* synced_session_client_ash, base::OnceCallback<void(BrowserTabsMetadataResponse)> callback) { foreign_synced_session_ = &session; callback_ = std::move(callback);
diff --git a/chromeos/ash/components/phonehub/fake_browser_tabs_metadata_fetcher.h b/chromeos/ash/components/phonehub/fake_browser_tabs_metadata_fetcher.h index 162903df..16d1481 100644 --- a/chromeos/ash/components/phonehub/fake_browser_tabs_metadata_fetcher.h +++ b/chromeos/ash/components/phonehub/fake_browser_tabs_metadata_fetcher.h
@@ -24,6 +24,7 @@ base::OnceCallback<void(BrowserTabsMetadataResponse)> callback) override; void FetchForeignSyncedPhoneSessionMetadata( const ForeignSyncedSessionAsh& session, + SyncedSessionClientAsh* synced_session_client_ash, base::OnceCallback<void(BrowserTabsMetadataResponse)> callback) override; void RespondToCurrentFetchAttempt(
diff --git a/chromeos/ash/components/proximity_auth/screenlock_bridge.cc b/chromeos/ash/components/proximity_auth/screenlock_bridge.cc index eabe158..2733149 100644 --- a/chromeos/ash/components/proximity_auth/screenlock_bridge.cc +++ b/chromeos/ash/components/proximity_auth/screenlock_bridge.cc
@@ -74,9 +74,6 @@ if (!aria_label_.empty()) result.Set("ariaLabel", aria_label_); - if (hardlock_on_click_) - result.Set("hardlockOnClick", true); - return result; } @@ -97,10 +94,6 @@ aria_label_ = aria_label; } -void ScreenlockBridge::UserPodCustomIconInfo::SetHardlockOnClick() { - hardlock_on_click_ = true; -} - std::string ScreenlockBridge::UserPodCustomIconInfo::GetIDString() const { return GetIdForIcon(icon_); }
diff --git a/chromeos/ash/components/proximity_auth/screenlock_bridge.h b/chromeos/ash/components/proximity_auth/screenlock_bridge.h index c784633..6852916 100644 --- a/chromeos/ash/components/proximity_auth/screenlock_bridge.h +++ b/chromeos/ash/components/proximity_auth/screenlock_bridge.h
@@ -66,10 +66,6 @@ // provided, then the tooltip will be used. void SetAriaLabel(const std::u16string& aria_label); - // If hardlock on click is set, clicking the icon in the screenlock will - // go to state where password is required for unlock. - void SetHardlockOnClick(); - std::string GetIDString() const; UserPodCustomIcon icon() const { return icon_; } @@ -80,8 +76,6 @@ const std::u16string aria_label() const { return aria_label_; } - bool hardlock_on_click() const { return hardlock_on_click_; } - private: UserPodCustomIcon icon_; @@ -89,8 +83,6 @@ bool autoshow_tooltip_ = false; std::u16string aria_label_; - - bool hardlock_on_click_ = false; }; class LockHandler {
diff --git a/chromeos/crosapi/mojom/synced_session_client.mojom b/chromeos/crosapi/mojom/synced_session_client.mojom index 4a768d0..72558f8 100644 --- a/chromeos/crosapi/mojom/synced_session_client.mojom +++ b/chromeos/crosapi/mojom/synced_session_client.mojom
@@ -6,6 +6,7 @@ import "mojo/public/mojom/base/string16.mojom"; import "mojo/public/mojom/base/time.mojom"; +import "ui/gfx/image/mojom/image.mojom"; import "url/mojom/url.mojom"; // Contains information regarding a Chrome tab for sync. @@ -32,6 +33,15 @@ array<SyncedSessionWindow> windows@2; }; +// Used by ash-chrome to request favicons for SyncedSessionTabs. +[Stable] +interface SyncedSessionClientFaviconDelegate { + // Request a favicon for the given page URL. Responds with an empty image + // if the favicon is not found. + GetFaviconImageForPageURL@0(url.mojom.Url page_url) + => (gfx.mojom.ImageSkia? image); +}; + // Defines an API for updating synced foreign sessions. [Stable] interface SyncedSessionClient { @@ -44,4 +54,10 @@ // the first update is received. [MinVersion=1] OnSessionSyncEnabledChanged@1(bool enabled); + + // Called by Lacros to register a delegate which Ash can use to request + // favicons. + [MinVersion=2] + SetFaviconDelegate@2( + pending_remote<SyncedSessionClientFaviconDelegate> delegate); };
diff --git a/chromeos/crosapi/mojom/web_app_types.mojom b/chromeos/crosapi/mojom/web_app_types.mojom index 55271d19..baf34e5 100644 --- a/chromeos/crosapi/mojom/web_app_types.mojom +++ b/chromeos/crosapi/mojom/web_app_types.mojom
@@ -59,4 +59,5 @@ url.mojom.Url scope@2; skia.mojom.SkColor? theme_color@3; gfx.mojom.ImageSkia icon@4; + [MinVersion=1] array<string>? additional_policy_ids@5; };
diff --git a/chromeos/ui/vector_icons/unfloat_button.icon b/chromeos/ui/vector_icons/unfloat_button.icon index 7140b80..afc006be 100644 --- a/chromeos/ui/vector_icons/unfloat_button.icon +++ b/chromeos/ui/vector_icons/unfloat_button.icon
@@ -2,31 +2,58 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -CANVAS_DIMENSIONS, 20, -MOVE_TO, 14, 6, -R_H_LINE_TO, -2, +CANVAS_DIMENSIONS, 24, +MOVE_TO, 1, 12, +V_LINE_TO, 1, +H_LINE_TO, 12, V_LINE_TO, 4, -R_H_LINE_TO, 2, -R_ARC_TO, 2, 2, 0, 0, 1, 2, 2, -R_V_LINE_TO, 8, -R_ARC_TO, 2, 2, 0, 0, 1, -2, 2, -H_LINE_TO, 6, -R_ARC_TO, 2, 2, 0, 0, 1, -2, -2, -R_V_LINE_TO, -2, -R_H_LINE_TO, 2, -R_V_LINE_TO, 2, -R_H_LINE_TO, 8, -V_LINE_TO, 6, +H_LINE_TO, 6.12f, +LINE_TO, 14.06f, 11.94f, +LINE_TO, 11.94f, 14.06f, +LINE_TO, 4, 6.12f, +V_LINE_TO, 12, +H_LINE_TO, 1, CLOSE, NEW_PATH, -MOVE_TO, 6, 10, -V_LINE_TO, 7.41f, -R_LINE_TO, 4.27f, 4.27f, -R_LINE_TO, 1.41f, -1.41f, -LINE_TO, 7.41f, 6, -H_LINE_TO, 10, +MOVE_TO, 1, 15, +V_LINE_TO, 22, +CUBIC_TO, 1, 22.55f, 1.45f, 23, 2, 23, +H_LINE_TO, 22, +CUBIC_TO, 22.55f, 23, 23, 22.55f, 23, 22, +V_LINE_TO, 2, +CUBIC_TO, 23, 1.45f, 22.55f, 1, 22, 1, +H_LINE_TO, 15, V_LINE_TO, 4, +H_LINE_TO, 20, +V_LINE_TO, 20, H_LINE_TO, 4, -R_V_LINE_TO, 6, -R_H_LINE_TO, 2, +V_LINE_TO, 15, +H_LINE_TO, 1, +CLOSE + +CANVAS_DIMENSIONS, 12, +NEW_PATH, +MOVE_TO, 8, 3, +H_LINE_TO, 9, +V_LINE_TO, 9, +H_LINE_TO, 3, +V_LINE_TO, 8, +H_LINE_TO, 1, +V_LINE_TO, 11, +H_LINE_TO, 11, +V_LINE_TO, 1, +H_LINE_TO, 8, +V_LINE_TO, 3, +CLOSE, +NEW_PATH, +MOVE_TO, 3, 4.41f, +V_LINE_TO, 6, +H_LINE_TO, 1, +V_LINE_TO, 1, +H_LINE_TO, 6, +V_LINE_TO, 3, +H_LINE_TO, 4.41f, +LINE_TO, 6.71f, 5.29f, +LINE_TO, 5.29f, 6.71f, +LINE_TO, 3, 4.41f, CLOSE \ No newline at end of file
diff --git a/chromeos/utils/pdf_conversion.cc b/chromeos/utils/pdf_conversion.cc index 0f413b3..3b807bd 100644 --- a/chromeos/utils/pdf_conversion.cc +++ b/chromeos/utils/pdf_conversion.cc
@@ -31,7 +31,7 @@ const sk_sp<SkData>& image_data, bool rotate, absl::optional<int> dpi) { - const sk_sp<SkImage> image = SkImage::MakeFromEncoded(image_data); + const sk_sp<SkImage> image = SkImages::DeferredFromEncodedData(image_data); if (!image) { LOG(ERROR) << "Unable to generate image from encoded image data."; return false;
diff --git a/components/autofill/android/java/src/org/chromium/components/autofill/AutofillDropdownAdapter.java b/components/autofill/android/java/src/org/chromium/components/autofill/AutofillDropdownAdapter.java index e5f6833..5687ca8b 100644 --- a/components/autofill/android/java/src/org/chromium/components/autofill/AutofillDropdownAdapter.java +++ b/components/autofill/android/java/src/org/chromium/components/autofill/AutofillDropdownAdapter.java
@@ -5,7 +5,6 @@ package org.chromium.components.autofill; import android.content.Context; -import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.Typeface; import android.text.TextUtils; @@ -20,7 +19,6 @@ import android.widget.TextView; import androidx.annotation.Nullable; -import androidx.appcompat.content.res.AppCompatResources; import androidx.core.view.MarginLayoutParamsCompat; import androidx.core.view.ViewCompat; @@ -232,30 +230,12 @@ */ @Nullable private ImageView populateIconView(ImageView iconView, DropdownItem item) { - // If neither the iconId nor the customIcon are provided, return null as we have nothing to - // display for the item. - if (item.getIconId() == DropdownItem.NO_ICON && item.getCustomIcon() == null) { + // If there is no icon, remove the icon view. + if (item.getIconDrawable() == null) { iconView.setVisibility(View.GONE); return null; } - // If a customIcon is provided we prefer to use it over the iconId of the item. - if (item.getCustomIcon() != null) { - // TODO(crbug.com/1381189): We need to scale the bitmap because we show custom icons to - // highlight certain credit card features (like virtual cards), which are available in a - // fixed size. In future, if we show only the card art for all cards, there is no need - // to scale the bitmap as we can directly fetch the icon in the required size. - // Scale the bitmap to match the dimensions of the default resources used for other - // items. - Bitmap scaledBitmap = Bitmap.createScaledBitmap(item.getCustomIcon(), - mContext.getResources().getDimensionPixelSize( - R.dimen.autofill_dropdown_icon_width), - mContext.getResources().getDimensionPixelSize( - R.dimen.autofill_dropdown_icon_height), - true); - iconView.setImageBitmap(scaledBitmap); - } else { - iconView.setImageDrawable(AppCompatResources.getDrawable(mContext, item.getIconId())); - } + iconView.setImageDrawable(item.getIconDrawable()); iconView.setVisibility(View.VISIBLE); // TODO(crbug.com/874077): Add accessible text for this icon. return iconView;
diff --git a/components/autofill/android/java/src/org/chromium/components/autofill/AutofillSuggestion.java b/components/autofill/android/java/src/org/chromium/components/autofill/AutofillSuggestion.java index ca3cac41..c7a32f5 100644 --- a/components/autofill/android/java/src/org/chromium/components/autofill/AutofillSuggestion.java +++ b/components/autofill/android/java/src/org/chromium/components/autofill/AutofillSuggestion.java
@@ -4,7 +4,8 @@ package org.chromium.components.autofill; -import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; import android.text.TextUtils; import androidx.annotation.Nullable; @@ -38,7 +39,7 @@ @Nullable private final GURL mCustomIconUrl; @Nullable - private final Bitmap mCustomIcon; + private final Drawable mIconDrawable; /** * Constructs a Autofill suggestion container. @@ -67,7 +68,7 @@ boolean isBoldLabel, @Nullable String featureForIPH) { this(label, /* secondaryLabel= */ null, sublabel, /* secondarySublabel= */ null, itemTag, iconId, isIconAtStart, suggestionId, isDeletable, isMultilineLabel, isBoldLabel, - featureForIPH, /* customIconUrl= */ null, /* customIcon= */ null); + featureForIPH, /* customIconUrl= */ null, /* iconDrawable= */ null); } @VisibleForTesting @@ -75,7 +76,7 @@ @Nullable String secondarySublabel, @Nullable String itemTag, int iconId, boolean isIconAtStart, int suggestionId, boolean isDeletable, boolean isMultilineLabel, boolean isBoldLabel, @Nullable String featureForIPH, @Nullable GURL customIconUrl, - @Nullable Bitmap customIcon) { + @Nullable Drawable iconDrawable) { mLabel = label; mSecondaryLabel = secondaryLabel; mSublabel = sublabel; @@ -89,7 +90,7 @@ mIsBoldLabel = isBoldLabel; mFeatureForIPH = featureForIPH; mCustomIconUrl = customIconUrl; - mCustomIcon = customIcon; + mIconDrawable = iconDrawable; } @Override @@ -159,8 +160,8 @@ @Override @Nullable - public Bitmap getCustomIcon() { - return mCustomIcon; + public Drawable getIconDrawable() { + return mIconDrawable; } public int getSuggestionId() { @@ -203,8 +204,7 @@ && this.mIsBoldLabel == other.mIsBoldLabel && Objects.equals(this.mFeatureForIPH, other.mFeatureForIPH) && Objects.equals(this.mCustomIconUrl, other.mCustomIconUrl) - && (this.mCustomIcon == null ? other.mCustomIcon == null - : this.mCustomIcon.sameAs(other.mCustomIcon)); + && areIconsEqual(this.mIconDrawable, other.mIconDrawable); } public Builder toBuilder() { @@ -222,7 +222,7 @@ .setIsBoldLabel(mIsBoldLabel) .setFeatureForIPH(mFeatureForIPH) .setCustomIconUrl(mCustomIconUrl) - .setCustomIcon(mCustomIcon); + .setIconDrawable(mIconDrawable); } /** @@ -231,7 +231,7 @@ public static final class Builder { private int mIconId; private GURL mCustomIconUrl; - private Bitmap mCustomIcon; + private Drawable mIconDrawable; private boolean mIsBoldLabel; private boolean mIsIconAtStart; private boolean mIsDeletable; @@ -254,8 +254,8 @@ return this; } - public Builder setCustomIcon(Bitmap customIcon) { - this.mCustomIcon = customIcon; + public Builder setIconDrawable(Drawable iconDrawable) { + this.mIconDrawable = iconDrawable; return this; } @@ -320,7 +320,26 @@ : "The AutofillSuggestion sublabel can be empty but never null."; return new AutofillSuggestion(mLabel, mSecondaryLabel, mSubLabel, mSecondarySubLabel, mItemTag, mIconId, mIsIconAtStart, mSuggestionId, mIsDeletable, - mIsMultiLineLabel, mIsBoldLabel, mFeatureForIPH, mCustomIconUrl, mCustomIcon); + mIsMultiLineLabel, mIsBoldLabel, mFeatureForIPH, mCustomIconUrl, mIconDrawable); } } + + public static boolean areIconsEqual( + @Nullable Drawable iconDrawable1, @Nullable Drawable iconDrawable2) { + if (iconDrawable1 == null) { + return iconDrawable2 == null; + } + // If the icons are custom Bitmap images. + if (iconDrawable1 instanceof BitmapDrawable) { + if (iconDrawable2 instanceof BitmapDrawable) { + return ((BitmapDrawable) iconDrawable1) + .getBitmap() + .sameAs(((BitmapDrawable) iconDrawable2).getBitmap()); + } + return false; + } + // Icons with {@code iconId} which are fetched from resources are already checked for + // equality. + return true; + } }
diff --git a/components/autofill/core/browser/autofill_save_update_address_profile_delegate_ios.h b/components/autofill/core/browser/autofill_save_update_address_profile_delegate_ios.h index 4ab3476..f4c4b9ac 100644 --- a/components/autofill/core/browser/autofill_save_update_address_profile_delegate_ios.h +++ b/components/autofill/core/browser/autofill_save_update_address_profile_delegate_ios.h
@@ -92,6 +92,10 @@ bool IsMigrationToAccount() const { return is_migration_to_account_; } + absl::optional<std::u16string> SyncingUserEmail() const { + return syncing_user_email_; + } + #if defined(UNIT_TEST) // Getter for |user_decision_|. Used for the testing purposes. AutofillClient::SaveAddressProfileOfferUserDecision user_decision() const {
diff --git a/components/autofill/core/browser/autofill_test_utils.cc b/components/autofill/core/browser/autofill_test_utils.cc index 27a6477b..c337de1 100644 --- a/components/autofill/core/browser/autofill_test_utils.cc +++ b/components/autofill/core/browser/autofill_test_utils.cc
@@ -462,14 +462,6 @@ return profile; } -AutofillProfile GetFullValidProfileForChina() { - AutofillProfile profile(base::GenerateGUID(), kEmptyOrigin); - SetProfileInfo(&profile, "John", "H.", "Doe", "johndoe@google.cn", "Google", - "100 Century Avenue", "", "赫章县", "毕节地区", "贵州省", - "200120", "CN", "+86-21-6133-7666"); - return profile; -} - AutofillProfile GetFullProfile() { AutofillProfile profile(base::GenerateGUID(), kEmptyOrigin); SetProfileInfo(&profile, "John", "H.", "Doe", "johndoe@hades.com",
diff --git a/components/autofill/core/browser/autofill_test_utils.h b/components/autofill/core/browser/autofill_test_utils.h index fec6eb6..7c36fab 100644 --- a/components/autofill/core/browser/autofill_test_utils.h +++ b/components/autofill/core/browser/autofill_test_utils.h
@@ -270,9 +270,6 @@ // Returns a full profile with valid info according to rules for Canada. AutofillProfile GetFullValidProfileForCanada(); -// Returns a full profile with valid info according to rules for China. -AutofillProfile GetFullValidProfileForChina(); - // Returns a profile full of dummy info. AutofillProfile GetFullProfile();
diff --git a/components/autofill/core/browser/browser_autofill_manager.cc b/components/autofill/core/browser/browser_autofill_manager.cc index 3814a077..a192432 100644 --- a/components/autofill/core/browser/browser_autofill_manager.cc +++ b/components/autofill/core/browser/browser_autofill_manager.cc
@@ -3478,12 +3478,19 @@ return false; } - auto is_text_field = [](const std::unique_ptr<AutofillField>& field) { - return field->IsTextInputElement(); - }; + // Return true if the field is a visible text input field which has predicted + // types from heuristics or the server. + auto is_focusable_predicted_text_field = + [](const std::unique_ptr<AutofillField>& field) { + return field->IsTextInputElement() && field->IsFocusable() && + ((field->server_type() != NO_SERVER_DATA && + field->server_type() != UNKNOWN_TYPE) || + field->heuristic_type() != UNKNOWN_TYPE || + field->html_type() != HtmlFieldType::kUnspecified); + }; - size_t num_text_fields = - base::ranges::count_if(form_structure.fields(), is_text_field); + size_t num_text_fields = base::ranges::count_if( + form_structure.fields(), is_focusable_predicted_text_field); if (num_text_fields == 0) { return false; } @@ -3492,7 +3499,8 @@ // "search" in its name/id/placeholder, the function return false and the form // is not recorded into UKM. The form is considered a search box. if (num_text_fields == 1) { - auto it = base::ranges::find_if(form_structure.fields(), is_text_field); + auto it = base::ranges::find_if(form_structure.fields(), + is_focusable_predicted_text_field); if (base::ToLowerASCII((*it)->placeholder).find(u"search") != std::string::npos || base::ToLowerASCII((*it)->name).find(u"search") != std::string::npos ||
diff --git a/components/autofill/core/browser/browser_autofill_manager.h b/components/autofill/core/browser/browser_autofill_manager.h index fa27bb59..f08d647 100644 --- a/components/autofill/core/browser/browser_autofill_manager.h +++ b/components/autofill/core/browser/browser_autofill_manager.h
@@ -722,7 +722,8 @@ // Returns whether the form is considered parseable and meets a couple of // other requirements which makes uploading UKM data worthwhile. E.g. the - // form should not be a search form. + // form should not be a search form, the forms should have at least one + // focusable input field with a type from heuristics or the server. bool ShouldUploadUkm(const FormStructure& form_structure); // Delegates to perform external processing (display, selection) on
diff --git a/components/autofill/core/browser/form_types.cc b/components/autofill/core/browser/form_types.cc index 8418c77d..bb6cf31e 100644 --- a/components/autofill/core/browser/form_types.cc +++ b/components/autofill/core/browser/form_types.cc
@@ -6,6 +6,7 @@ #include "base/containers/contains.h" #include "components/autofill/core/browser/field_types.h" #include "components/autofill/core/browser/form_structure.h" +#include "components/autofill/core/common/autofill_util.h" namespace autofill { @@ -58,16 +59,18 @@ return base::Contains(kExpirationDateTypes, field->Type().GetStorableType()); } -bool FormHasAllCreditCardFields(const FormStructure& form_structure) { +bool FormHasAllEmtyCreditCardFields(const FormStructure& form_structure) { bool has_card_number_field = base::ranges::any_of( form_structure, [](const std::unique_ptr<AutofillField>& autofill_field) { return autofill_field->Type().GetStorableType() == - ServerFieldType::CREDIT_CARD_NUMBER; + ServerFieldType::CREDIT_CARD_NUMBER && + SanitizedFieldIsEmpty(autofill_field->value); }); bool has_expiration_date_field = base::ranges::any_of( form_structure, [](const std::unique_ptr<AutofillField>& autofill_field) { - return FieldHasExpirationDateType(autofill_field.get()); + return FieldHasExpirationDateType(autofill_field.get()) && + SanitizedFieldIsEmpty(autofill_field->value); }); return has_card_number_field && has_expiration_date_field;
diff --git a/components/autofill/core/browser/form_types.h b/components/autofill/core/browser/form_types.h index a5b89d42..da954e4 100644 --- a/components/autofill/core/browser/form_types.h +++ b/components/autofill/core/browser/form_types.h
@@ -21,7 +21,7 @@ // Returns true if the form contains fields that represent the card number and // the card expiration date. -bool FormHasAllCreditCardFields(const FormStructure& form_structure); +bool FormHasAllEmtyCreditCardFields(const FormStructure& form_structure); FormType FieldTypeGroupToFormType(FieldTypeGroup field_type_group);
diff --git a/components/autofill/core/browser/form_types_unittest.cc b/components/autofill/core/browser/form_types_unittest.cc index ff7e51d07..69827d3 100644 --- a/components/autofill/core/browser/form_types_unittest.cc +++ b/components/autofill/core/browser/form_types_unittest.cc
@@ -8,33 +8,57 @@ #include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/browser/field_types.h" #include "components/autofill/core/browser/form_structure_test_api.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" namespace autofill { -class FormTypesTest : public testing::Test { +using autofill::ServerFieldType; +using std::string; + +struct FormTypesTestCase { + std::vector<ServerFieldType> field_types; + std::vector<std::u16string> field_values; + bool expected_result; +}; + +autofill::FormFieldData CreateFieldWithValue(std::u16string value) { + FormFieldData field; + field.value = value; + return field; +} + +class FormTypesTest : public testing::TestWithParam<FormTypesTestCase> { private: test::AutofillUnitTestEnvironment autofill_test_environment_; }; -TEST_F(FormTypesTest, FormHasAllCreditCardFieldsReturnsTrue) { +TEST_P(FormTypesTest, FormHasFillableCreditCardFields) { + FormTypesTestCase test_case = GetParam(); + FormData form; - form.fields.resize(3); + for (const auto& value : test_case.field_values) { + form.fields.emplace_back(CreateFieldWithValue(value)); + } FormStructure form_structure(form); - FormStructureTestApi(&form_structure) - .SetFieldTypes({CREDIT_CARD_NUMBER, CREDIT_CARD_EXP_MONTH, - CREDIT_CARD_EXP_2_DIGIT_YEAR}); + FormStructureTestApi(&form_structure).SetFieldTypes(test_case.field_types); - EXPECT_TRUE(FormHasAllCreditCardFields(form_structure)); + EXPECT_THAT(FormHasAllEmtyCreditCardFields(form_structure), + testing::Eq(test_case.expected_result)); } -TEST_F(FormTypesTest, FormHasAllCreditCardFieldsReturnsFalse) { - FormData incomplete_form; - incomplete_form.fields.resize(1); - FormStructure form_structure(incomplete_form); - FormStructureTestApi(&form_structure).SetFieldTypes({CREDIT_CARD_NUMBER}); - - EXPECT_FALSE(FormHasAllCreditCardFields(form_structure)); -} +INSTANTIATE_TEST_SUITE_P( + All, + FormTypesTest, + testing::Values( + FormTypesTestCase{{CREDIT_CARD_NUMBER, CREDIT_CARD_EXP_MONTH, + CREDIT_CARD_EXP_2_DIGIT_YEAR}, + {u"", u"", u""}, + true}, + FormTypesTestCase{{CREDIT_CARD_NUMBER}, {u""}, false}, + FormTypesTestCase{{CREDIT_CARD_NUMBER, CREDIT_CARD_EXP_MONTH, + CREDIT_CARD_EXP_2_DIGIT_YEAR}, + {u"411111111111", u"", u""}, + false})); } // namespace autofill
diff --git a/components/autofill/core/browser/iban_manager.cc b/components/autofill/core/browser/iban_manager.cc index 4c99507d..77d1465 100644 --- a/components/autofill/core/browser/iban_manager.cc +++ b/components/autofill/core/browser/iban_manager.cc
@@ -14,10 +14,8 @@ namespace autofill { -IBANManager::IBANManager(PersonalDataManager* personal_data_manager, - bool is_off_the_record) - : personal_data_manager_(personal_data_manager), - is_off_the_record_(is_off_the_record) {} +IBANManager::IBANManager(PersonalDataManager* personal_data_manager) + : personal_data_manager_(personal_data_manager) {} IBANManager::~IBANManager() = default; @@ -45,7 +43,7 @@ } } - if (!is_off_the_record_ && personal_data_manager_) { + if (personal_data_manager_) { std::vector<IBAN*> ibans = personal_data_manager_->GetLocalIBANs(); if (!ibans.empty()) { // Rank the IBANs by ranking score (see AutoFillDataModel for details).
diff --git a/components/autofill/core/browser/iban_manager.h b/components/autofill/core/browser/iban_manager.h index 6fb76efbb..a1e86fd 100644 --- a/components/autofill/core/browser/iban_manager.h +++ b/components/autofill/core/browser/iban_manager.h
@@ -27,12 +27,10 @@ public KeyedService, public AutofillSubject { public: - // Initializes the instance with the given parameters. |personal_data_manager| + // Initializes the instance with the given parameters. `personal_data_manager` // is a profile-scope data manager used to retrieve IBAN data from the - // local autofill table. |is_off_the_record| indicates whether the user is - // currently operating in an off-the-record context (i.e. incognito). - explicit IBANManager(PersonalDataManager* personal_data_manager, - bool is_off_the_record); + // local autofill table. + explicit IBANManager(PersonalDataManager* personal_data_manager); IBANManager(const IBANManager&) = delete; IBANManager& operator=(const IBANManager&) = delete; @@ -57,13 +55,6 @@ base::WeakPtr<IBANManager> GetWeakPtr(); -#if defined(UNIT_TEST) - // Assign types to the fields for the testing purposes. - void SetOffTheRecordForTesting(bool is_off_the_record) { - is_off_the_record_ = is_off_the_record; - } -#endif - private: // Sends suggestions for |ibans| to the |query_handler|'s handler for display // in the associated Autofill popup. @@ -73,8 +64,6 @@ raw_ptr<PersonalDataManager, DanglingUntriaged> personal_data_manager_ = nullptr; - bool is_off_the_record_ = false; - base::WeakPtrFactory<IBANManager> weak_ptr_factory_{this}; };
diff --git a/components/autofill/core/browser/iban_manager_unittest.cc b/components/autofill/core/browser/iban_manager_unittest.cc index 3c6b92901..010aee72 100644 --- a/components/autofill/core/browser/iban_manager_unittest.cc +++ b/components/autofill/core/browser/iban_manager_unittest.cc
@@ -65,8 +65,7 @@ class IBANManagerTest : public testing::Test { protected: - IBANManagerTest() - : iban_manager_(&personal_data_manager_, /*is_off_the_record=*/false) {} + IBANManagerTest() : iban_manager_(&personal_data_manager_) {} void SetUp() override { if (ui::ResourceBundle::HasSharedInstance()) { @@ -313,23 +312,6 @@ /*context=*/context)); } -TEST_F(IBANManagerTest, DoesNotShowIBANsForOffTheRecord) { - SetUpIBAN(kIbanValue_0, kNickname_0); - iban_manager_.SetOffTheRecordForTesting(true); - AutofillField test_field; - SuggestionsContext context = GetIbanFocusedSuggestionsContext(test_field); - - // Setting up mock to verify that suggestions returning is not triggered if - // the user is off the record. - EXPECT_CALL(suggestions_handler_, OnSuggestionsReturned).Times(0); - - // Simulate request for suggestions. - EXPECT_FALSE(iban_manager_.OnGetSingleFieldSuggestions( - AutoselectFirstSuggestion(false), test_field, autofill_client_, - suggestions_handler_.GetWeakPtr(), - /*context=*/context)); -} - TEST_F(IBANManagerTest, DoesNotShowIBANsForBlockedWebsite) { SetUpIBAN(kIbanValue_0, kNickname_0); AutofillField test_field;
diff --git a/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc b/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc index 8d761d0..213872b 100644 --- a/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc +++ b/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc
@@ -8686,7 +8686,7 @@ EXPECT_EQ(0u, entries.size()); auto form_entries = test_ukm_recorder_->GetEntriesByName(UkmFormSummaryType::kEntryName); - ASSERT_EQ(0u, form_entries.size()); + EXPECT_EQ(0u, form_entries.size()); } // Test that we do not record FieldInfo/FormSummary UKM metrics for forms @@ -8709,7 +8709,7 @@ EXPECT_EQ(0u, entries.size()); auto form_entries = test_ukm_recorder_->GetEntriesByName(UkmFormSummaryType::kEntryName); - ASSERT_EQ(0u, form_entries.size()); + EXPECT_EQ(0u, form_entries.size()); } // Tests that the forms with only <input type="checkbox"> fields are not @@ -8745,17 +8745,15 @@ EXPECT_EQ(0u, entries.size()); auto form_entries = test_ukm_recorder_->GetEntriesByName(UkmFormSummaryType::kEntryName); - ASSERT_EQ(0u, form_entries.size()); + EXPECT_EQ(0u, form_entries.size()); } -// Tests that the forms with <input type="checkbox"> fields and a text field are -// recorded in UkmFieldInfo metrics. -TEST_F(AutofillMetricsFromLogEventsTest, - AutofillFieldInfoMetricsRecordOnCheckBoxWithTextField) { - base::TimeTicks now = AutofillTickClock::NowTicks(); - TestAutofillTickClock test_clock; - test_clock.SetNowTicks(now); - +// Tests that the forms with <input type="checkbox"> fields and a text field +// which does not get a type from heuristics or the server are not recorded in +// UkmFieldInfo metrics. +TEST_F( + AutofillMetricsFromLogEventsTest, + AutofillFieldInfoMetricsNotRecordOnCheckBoxWithTextFieldWithUnknownType) { FormData form; form.url = GURL("http://www.foo.com/"); @@ -8791,6 +8789,64 @@ form.fields.push_back(field); SeeForm(form); + SubmitForm(form); + autofill_manager().Reset(); + + // This form only has one non-checkable field, so the local heuristics are + // not executed. + auto entries = + test_ukm_recorder_->GetEntriesByName(UkmFieldInfoType::kEntryName); + EXPECT_EQ(0u, entries.size()); + auto form_entries = + test_ukm_recorder_->GetEntriesByName(UkmFormSummaryType::kEntryName); + EXPECT_EQ(0u, form_entries.size()); +} + +// Tests that the forms with <input type="checkbox"> fields and two text field +// which have predicted types are recorded in UkmFieldInfo metrics. +TEST_F(AutofillMetricsFromLogEventsTest, + AutofillFieldInfoMetricsRecordOnCheckBoxWithTextField) { + base::TimeTicks now = AutofillTickClock::NowTicks(); + TestAutofillTickClock test_clock; + test_clock.SetNowTicks(now); + + FormData form; + form.url = GURL("http://www.foo.com/"); + + // Start with two input text fields. + FormFieldData field; + field.label = u"First Name"; + field.name = u"firstname"; + field.form_control_type = "text"; + field.unique_renderer_id = test::MakeFieldRendererId(); + form.fields.push_back(field); + + field.label = u"Last Name"; + field.name = u"lastname"; + field.form_control_type = "text"; + field.unique_renderer_id = test::MakeFieldRendererId(); + form.fields.push_back(field); + + // Two checkable radio buttons. + field.label = u"female"; + field.name = u"female"; + field.form_control_type = "radio"; + field.check_status = FormFieldData::CheckStatus::kCheckableButUnchecked; + field.unique_renderer_id = test::MakeFieldRendererId(); + form.fields.push_back(field); + + field.label = u"male"; + field.name = u"male"; + field.form_control_type = "radio"; + field.check_status = FormFieldData::CheckStatus::kCheckableButUnchecked; + field.unique_renderer_id = test::MakeFieldRendererId(); + form.fields.push_back(field); + + // The two text fields have predicted types. + std::vector<ServerFieldType> field_types = {NAME_FIRST, NAME_LAST, + UNKNOWN_TYPE, UNKNOWN_TYPE}; + autofill_manager().AddSeenForm(form, field_types); + SeeForm(form); base::TimeTicks parse_time = autofill_manager() .form_structures() .begin() @@ -8800,9 +8856,6 @@ SubmitForm(form); autofill_manager().Reset(); - // Record Autofill2.FieldInfo UKM event at autofill manager reset. - // This form only has one non-checkable field, so the local heuristics are - // not executed. auto entries = test_ukm_recorder_->GetEntriesByName(UkmFieldInfoType::kEntryName); ASSERT_EQ(4u, entries.size()); @@ -8820,7 +8873,7 @@ {UFIT::kWasFocusedName, false}, {UFIT::kIsFocusableName, true}, {UFIT::kUserTypedIntoFieldName, false}, - {UFIT::kOverallTypeName, UNKNOWN_TYPE}, + {UFIT::kOverallTypeName, field_types[i]}, {UFIT::kSectionIdName, 1}, {UFIT::kTypeChangedByRationalizationName, false}, }; @@ -8837,7 +8890,7 @@ ASSERT_EQ(1u, form_entries.size()); using UFST = UkmFormSummaryType; const auto* const form_entry = form_entries[0]; - AutofillMetrics::FormEventSet form_events = {}; + AutofillMetrics::FormEventSet form_events = {FORM_EVENT_DID_PARSE_FORM}; std::map<std::string, int64_t> expected = { {UFST::kFormSessionIdentifierName, AutofillMetrics::FormGlobalIdToHash64Bit(form.global_id())},
diff --git a/components/autofill/core/browser/mock_iban_manager.cc b/components/autofill/core/browser/mock_iban_manager.cc index 9c13f62d..217dbf0 100644 --- a/components/autofill/core/browser/mock_iban_manager.cc +++ b/components/autofill/core/browser/mock_iban_manager.cc
@@ -7,7 +7,7 @@ namespace autofill { MockIBANManager::MockIBANManager(PersonalDataManager* personal_data_manager) - : IBANManager(personal_data_manager, /*is_off_the_record=*/false) {} + : IBANManager(personal_data_manager) {} MockIBANManager::~MockIBANManager() = default;
diff --git a/components/autofill/core/browser/payments/payments_client_unittest.cc b/components/autofill/core/browser/payments/payments_client_unittest.cc index ab59537..114a9ea 100644 --- a/components/autofill/core/browser/payments/payments_client_unittest.cc +++ b/components/autofill/core/browser/payments/payments_client_unittest.cc
@@ -774,50 +774,7 @@ EXPECT_EQ(AutofillClient::PaymentsRpcResult::kPermanentFailure, result_); } -TEST_F(PaymentsClientTest, VirtualCardRiskBasedYellowPathResponse_CvcFlagOff) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndDisableFeature( - features::kAutofillEnableCvcForVcnYellowPath); - StartUnmasking(CardUnmaskOptions().with_virtual_card_risk_based()); - IssueOAuthToken(); - ReturnResponse( - net::HTTP_OK, - "{ \"fido_request_options\": { \"challenge\": \"fake_fido_challenge\" }, " - "\"context_token\": \"fake_context_token\", \"idv_challenge_options\": " - "[{ \"sms_otp_challenge_option\": { \"challenge_id\": " - "\"fake_challenge_id_1\", \"masked_phone_number\": \"(***)-***-1234\" } " - "}, { \"sms_otp_challenge_option\": { \"challenge_id\": " - "\"fake_challenge_id_2\", \"masked_phone_number\": \"(***)-***-5678\" } " - "}, { \"cvc_challenge_option\": { \"challenge_id\": " - "\"fake_challenge_id_3\", \"cvc_length\": 3, \"cvc_position\": " - "\"CVC_POSITION_BACK\"}}]}"); - - // Ensure that it's not treated as failure when no pan is returned. - EXPECT_EQ(AutofillClient::PaymentsRpcResult::kSuccess, result_); - EXPECT_EQ("fake_context_token", unmask_response_details_->context_token); - // Verify the FIDO request challenge is correctly parsed. - EXPECT_EQ( - "fake_fido_challenge", - *unmask_response_details_->fido_request_options->FindString("challenge")); - // Verify the two idv challenge options are both sms challenge and fields can - // be correctly parsed. - ASSERT_EQ(2u, unmask_response_details_->card_unmask_challenge_options.size()); - const CardUnmaskChallengeOption& challenge_option_1 = - unmask_response_details_->card_unmask_challenge_options[0]; - EXPECT_EQ(CardUnmaskChallengeOptionType::kSmsOtp, challenge_option_1.type); - EXPECT_EQ("fake_challenge_id_1", challenge_option_1.id.value()); - EXPECT_EQ(u"(***)-***-1234", challenge_option_1.challenge_info); - const CardUnmaskChallengeOption& challenge_option_2 = - unmask_response_details_->card_unmask_challenge_options[1]; - EXPECT_EQ(CardUnmaskChallengeOptionType::kSmsOtp, challenge_option_2.type); - EXPECT_EQ("fake_challenge_id_2", challenge_option_2.id.value()); - EXPECT_EQ(u"(***)-***-5678", challenge_option_2.challenge_info); -} - -TEST_F(PaymentsClientTest, VirtualCardRiskBasedYellowPathResponse_CvcFlagOn) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - features::kAutofillEnableCvcForVcnYellowPath); +TEST_F(PaymentsClientTest, VirtualCardRiskBasedYellowPathResponse) { StartUnmasking(CardUnmaskOptions().with_virtual_card_risk_based()); IssueOAuthToken(); ReturnResponse(
diff --git a/components/autofill/core/browser/payments/payments_requests/unmask_card_request.cc b/components/autofill/core/browser/payments/payments_requests/unmask_card_request.cc index de77113..1d7fc8a 100644 --- a/components/autofill/core/browser/payments/payments_requests/unmask_card_request.cc +++ b/components/autofill/core/browser/payments/payments_requests/unmask_card_request.cc
@@ -142,9 +142,7 @@ // Check if it's a CVC challenge option, and if it is, set // `defined_challenge_option` to the defined challenge option found, parse the // challenge option, and return it. - else if (base::FeatureList::IsEnabled( - features::kAutofillEnableCvcForVcnYellowPath) && - (defined_challenge_option = + else if ((defined_challenge_option = challenge_option.FindDict("cvc_challenge_option"))) { ParseAsCvcChallengeOption(defined_challenge_option, &parsed_challenge_option);
diff --git a/components/autofill/core/browser/payments/payments_requests/unmask_card_request_unittest.cc b/components/autofill/core/browser/payments/payments_requests/unmask_card_request_unittest.cc index 7f4deec9..92afe35c 100644 --- a/components/autofill/core/browser/payments/payments_requests/unmask_card_request_unittest.cc +++ b/components/autofill/core/browser/payments/payments_requests/unmask_card_request_unittest.cc
@@ -8,7 +8,6 @@ #include "base/functional/callback_helpers.h" #include "base/json/json_reader.h" -#include "base/test/scoped_feature_list.h" #include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/browser/payments/card_unmask_challenge_option.h" #include "testing/gtest/include/gtest/gtest.h" @@ -116,71 +115,60 @@ TEST_P(VirtualCardUnmaskCardRequestTest, ChallengeOptionsReturned_ParseResponse) { - base::test::ScopedFeatureList feature_list; - for (bool enable_cvc_challenge_option : {true, false}) { - feature_list.Reset(); - feature_list.InitWithFeatureState( - features::kAutofillEnableCvcForVcnYellowPath, - /*enabled=*/enable_cvc_challenge_option); + absl::optional<base::Value> response = base::JSONReader::Read( + "{ \"fido_request_options\": { \"challenge\": " + "\"fake_fido_challenge\" }, \"context_token\": \"fake_context_token\", " + "\"idv_challenge_options\": [{ \"sms_otp_challenge_option\": " + "{ \"challenge_id\": \"fake_challenge_id_1\", \"masked_phone_number\": " + "\"(***)-***-1234\" } }, { \"sms_otp_challenge_option\": { " + "\"challenge_id\": \"fake_challenge_id_2\", \"masked_phone_number\": " + "\"(***)-***-5678\" } }, { \"cvc_challenge_option\": { " + "\"challenge_id\": \"fake_challenge_id_3\", \"cvc_length\": 3, " + "\"cvc_position\": \"CVC_POSITION_BACK\"}}, { " + "\"cvc_challenge_option\":{ \"challenge_id\": \"fake_challenge_id_4\", " + "\"cvc_length\": 4, \"cvc_position\": \"CVC_POSITION_FRONT\"}}]}"); + ASSERT_TRUE(response.has_value()); + GetRequest()->ParseResponse(response->GetDict()); - absl::optional<base::Value> response = base::JSONReader::Read( - "{ \"fido_request_options\": { \"challenge\": " - "\"fake_fido_challenge\" }, \"context_token\": \"fake_context_token\", " - "\"idv_challenge_options\": [{ \"sms_otp_challenge_option\": " - "{ \"challenge_id\": \"fake_challenge_id_1\", \"masked_phone_number\": " - "\"(***)-***-1234\" } }, { \"sms_otp_challenge_option\": { " - "\"challenge_id\": \"fake_challenge_id_2\", \"masked_phone_number\": " - "\"(***)-***-5678\" } }, { \"cvc_challenge_option\": { " - "\"challenge_id\": \"fake_challenge_id_3\", \"cvc_length\": 3, " - "\"cvc_position\": \"CVC_POSITION_BACK\"}}, { " - "\"cvc_challenge_option\":{ \"challenge_id\": \"fake_challenge_id_4\", " - "\"cvc_length\": 4, \"cvc_position\": \"CVC_POSITION_FRONT\"}}]}"); - ASSERT_TRUE(response.has_value()); - GetRequest()->ParseResponse(response->GetDict()); + const PaymentsClient::UnmaskResponseDetails& response_details = + GetParsedResponse(); + EXPECT_EQ("fake_context_token", response_details.context_token); + // Verify the FIDO request challenge is correctly parsed. + EXPECT_EQ("fake_fido_challenge", + *response_details.fido_request_options->FindString("challenge")); + // Verify the three challenge options are two sms challenge options and one + // cvc challenge option, and fields can be correctly parsed. + ASSERT_EQ(4u, response_details.card_unmask_challenge_options.size()); - const PaymentsClient::UnmaskResponseDetails& response_details = - GetParsedResponse(); - EXPECT_EQ("fake_context_token", response_details.context_token); - // Verify the FIDO request challenge is correctly parsed. - EXPECT_EQ("fake_fido_challenge", - *response_details.fido_request_options->FindString("challenge")); - // Verify the three challenge options are two sms challenge options and one - // cvc challenge option, and fields can be correctly parsed. - ASSERT_EQ(enable_cvc_challenge_option ? 4u : 2u, - response_details.card_unmask_challenge_options.size()); + const CardUnmaskChallengeOption& challenge_option_1 = + response_details.card_unmask_challenge_options[0]; + EXPECT_EQ(CardUnmaskChallengeOptionType::kSmsOtp, challenge_option_1.type); + EXPECT_EQ("fake_challenge_id_1", challenge_option_1.id.value()); + EXPECT_EQ(u"(***)-***-1234", challenge_option_1.challenge_info); - const CardUnmaskChallengeOption& challenge_option_1 = - response_details.card_unmask_challenge_options[0]; - EXPECT_EQ(CardUnmaskChallengeOptionType::kSmsOtp, challenge_option_1.type); - EXPECT_EQ("fake_challenge_id_1", challenge_option_1.id.value()); - EXPECT_EQ(u"(***)-***-1234", challenge_option_1.challenge_info); + const CardUnmaskChallengeOption& challenge_option_2 = + response_details.card_unmask_challenge_options[1]; + EXPECT_EQ(CardUnmaskChallengeOptionType::kSmsOtp, challenge_option_2.type); + EXPECT_EQ("fake_challenge_id_2", challenge_option_2.id.value()); + EXPECT_EQ(u"(***)-***-5678", challenge_option_2.challenge_info); - const CardUnmaskChallengeOption& challenge_option_2 = - response_details.card_unmask_challenge_options[1]; - EXPECT_EQ(CardUnmaskChallengeOptionType::kSmsOtp, challenge_option_2.type); - EXPECT_EQ("fake_challenge_id_2", challenge_option_2.id.value()); - EXPECT_EQ(u"(***)-***-5678", challenge_option_2.challenge_info); + const CardUnmaskChallengeOption& challenge_option_3 = + response_details.card_unmask_challenge_options[2]; + EXPECT_EQ(CardUnmaskChallengeOptionType::kCvc, challenge_option_3.type); + EXPECT_EQ("fake_challenge_id_3", challenge_option_3.id.value()); + EXPECT_EQ(challenge_option_3.challenge_info, + u"This is the 3-digit code on the back of your card"); + EXPECT_EQ(3u, challenge_option_3.challenge_input_length); + EXPECT_EQ(CvcPosition::kBackOfCard, challenge_option_3.cvc_position); - if (enable_cvc_challenge_option) { - const CardUnmaskChallengeOption& challenge_option_3 = - response_details.card_unmask_challenge_options[2]; - EXPECT_EQ(CardUnmaskChallengeOptionType::kCvc, challenge_option_3.type); - EXPECT_EQ("fake_challenge_id_3", challenge_option_3.id.value()); - EXPECT_EQ(challenge_option_3.challenge_info, - u"This is the 3-digit code on the back of your card"); - EXPECT_EQ(3u, challenge_option_3.challenge_input_length); - EXPECT_EQ(CvcPosition::kBackOfCard, challenge_option_3.cvc_position); - - const CardUnmaskChallengeOption& challenge_option_4 = - response_details.card_unmask_challenge_options[3]; - EXPECT_EQ(CardUnmaskChallengeOptionType::kCvc, challenge_option_4.type); - EXPECT_EQ("fake_challenge_id_4", challenge_option_4.id.value()); - EXPECT_EQ(challenge_option_4.challenge_info, - u"This is the 4-digit code on the front of your card"); - EXPECT_EQ(4u, challenge_option_4.challenge_input_length); - EXPECT_EQ(CvcPosition::kFrontOfCard, challenge_option_4.cvc_position); - } - } + const CardUnmaskChallengeOption& challenge_option_4 = + response_details.card_unmask_challenge_options[3]; + EXPECT_EQ(CardUnmaskChallengeOptionType::kCvc, challenge_option_4.type); + EXPECT_EQ("fake_challenge_id_4", challenge_option_4.id.value()); + EXPECT_EQ(challenge_option_4.challenge_info, + u"This is the 4-digit code on the front of your card"); + EXPECT_EQ(4u, challenge_option_4.challenge_input_length); + EXPECT_EQ(CvcPosition::kFrontOfCard, challenge_option_4.cvc_position); } TEST_P(VirtualCardUnmaskCardRequestTest, IsRetryableFailure) {
diff --git a/components/autofill/core/common/autofill_payments_features.cc b/components/autofill/core/common/autofill_payments_features.cc index d50fcbe..8034d15 100644 --- a/components/autofill/core/common/autofill_payments_features.cc +++ b/components/autofill/core/common/autofill_payments_features.cc
@@ -47,14 +47,6 @@ "AutofillEnableCardProductName", base::FEATURE_DISABLED_BY_DEFAULT); -// When enabled, if the user encounters the yellow path (challenge path) in the -// VCN retrieval flow and the server denotes that the card is eligible for CVC -// authentication, CVC authentication will be offered as one of the challenge -// options. -BASE_FEATURE(kAutofillEnableCvcForVcnYellowPath, - "AutofillEnableCvcForVcnYellowPath", - base::FEATURE_ENABLED_BY_DEFAULT); - // When enabled, user's will see network card art images and network icons which // are larger, having a white border, and don't have the standard grey overlay // applied to them.
diff --git a/components/autofill/core/common/autofill_payments_features.h b/components/autofill/core/common/autofill_payments_features.h index 5bfa0c27..fcd0597 100644 --- a/components/autofill/core/common/autofill_payments_features.h +++ b/components/autofill/core/common/autofill_payments_features.h
@@ -17,7 +17,6 @@ BASE_DECLARE_FEATURE(kAutofillAutoTriggerManualFallbackForCards); BASE_DECLARE_FEATURE(kAutofillEnableCardArtImage); BASE_DECLARE_FEATURE(kAutofillEnableCardProductName); -BASE_DECLARE_FEATURE(kAutofillEnableCvcForVcnYellowPath); BASE_DECLARE_FEATURE(kAutofillEnableFIDOProgressDialog); BASE_DECLARE_FEATURE(kAutofillEnableIbanClientSideUrlFiltering); BASE_DECLARE_FEATURE(kAutofillEnableManualFallbackForVirtualCards);
diff --git a/components/autofill_strings.grdp b/components/autofill_strings.grdp index a84c0fb..f1f3a7e 100644 --- a/components/autofill_strings.grdp +++ b/components/autofill_strings.grdp
@@ -405,6 +405,9 @@ <message name="IDS_IOS_AUTOFILL_SAVE_ADDRESS_IN_ACCOUNT_MESSAGE_SUBTITLE" desc="Subtitle shown in the messages UI view when a new profile is asked to be saved in the Google Account"> In your Google Account, <ph name="USER_EMAIL">$1<ex>janedoe@google.com</ex></ph> </message> + <message name="IDS_IOS_AUTOFILL_SAVE_ADDRESS_IN_ACCOUNT_FOOTER" desc="Footer text shown in the save modal for saving a new address profile or migrating it in the Google Account"> + You can use saved addresses across Google products. This address will be saved in your Google Account, <ph name="USER_EMAIL">$1<ex>janedoe@google.com</ex></ph>. + </message> </if> <!-- Used on Desktop: --> <if expr="not is_android and not is_ios">
diff --git a/components/autofill_strings_grdp/IDS_IOS_AUTOFILL_SAVE_ADDRESS_IN_ACCOUNT_FOOTER.png.sha1 b/components/autofill_strings_grdp/IDS_IOS_AUTOFILL_SAVE_ADDRESS_IN_ACCOUNT_FOOTER.png.sha1 new file mode 100644 index 0000000..23c6750 --- /dev/null +++ b/components/autofill_strings_grdp/IDS_IOS_AUTOFILL_SAVE_ADDRESS_IN_ACCOUNT_FOOTER.png.sha1
@@ -0,0 +1 @@ +b5bdbc72502999bfc483ed014ebbf2c1417e6071 \ No newline at end of file
diff --git a/components/browser_ui/styles/android/BUILD.gn b/components/browser_ui/styles/android/BUILD.gn index c5fd4be..de7d1572 100644 --- a/components/browser_ui/styles/android/BUILD.gn +++ b/components/browser_ui/styles/android/BUILD.gn
@@ -163,6 +163,7 @@ "java/res/drawable/ic_data_personalization_20dp.xml", "java/res/drawable/ic_data_viz_grey.xml", "java/res/drawable/ic_desktop_windows.xml", + "java/res/drawable/ic_dino.xml", "java/res/drawable/ic_dns_24dp.xml", "java/res/drawable/ic_done_blue.xml", "java/res/drawable/ic_drive_document_24dp.xml", @@ -180,6 +181,7 @@ "java/res/drawable/ic_history_24dp.xml", "java/res/drawable/ic_info_outline_grey_16dp.xml", "java/res/drawable/ic_info_outline_grey_24dp.xml", + "java/res/drawable/ic_journeys.xml", "java/res/drawable/ic_lightbulb_24dp.xml", "java/res/drawable/ic_link_24dp.xml", "java/res/drawable/ic_mic_off_white_24dp.xml", @@ -229,6 +231,16 @@ "java/res/values/styles.xml", "java/res/values/themes.xml", "java/res/values/values.xml", + "java/res_chromium/drawable-hdpi/fre_product_logo.png", + "java/res_chromium/drawable-hdpi/product_logo_name.png", + "java/res_chromium/drawable-mdpi/fre_product_logo.png", + "java/res_chromium/drawable-mdpi/product_logo_name.png", + "java/res_chromium/drawable-xhdpi/fre_product_logo.png", + "java/res_chromium/drawable-xhdpi/product_logo_name.png", + "java/res_chromium/drawable-xxhdpi/fre_product_logo.png", + "java/res_chromium/drawable-xxhdpi/product_logo_name.png", + "java/res_chromium/drawable-xxxhdpi/fre_product_logo.png", + "java/res_chromium/drawable-xxxhdpi/product_logo_name.png", ] if (enable_arcore) { @@ -240,3 +252,20 @@ "//ui/android:ui_java_resources", ] } + +# Overrides icon / name defined in chrome_app_java_resources. +android_resources("chrome_public_apk_resources") { + resource_overlay = true + sources = [ + "java/res_chromium/drawable-hdpi/fre_product_logo.png", + "java/res_chromium/drawable-hdpi/product_logo_name.png", + "java/res_chromium/drawable-mdpi/fre_product_logo.png", + "java/res_chromium/drawable-mdpi/product_logo_name.png", + "java/res_chromium/drawable-xhdpi/fre_product_logo.png", + "java/res_chromium/drawable-xhdpi/product_logo_name.png", + "java/res_chromium/drawable-xxhdpi/fre_product_logo.png", + "java/res_chromium/drawable-xxhdpi/product_logo_name.png", + "java/res_chromium/drawable-xxxhdpi/fre_product_logo.png", + "java/res_chromium/drawable-xxxhdpi/product_logo_name.png", + ] +}
diff --git a/chrome/browser/ui/android/quickactionsearchwidget/java/res/drawable/ic_dino.xml b/components/browser_ui/styles/android/java/res/drawable/ic_dino.xml similarity index 100% rename from chrome/browser/ui/android/quickactionsearchwidget/java/res/drawable/ic_dino.xml rename to components/browser_ui/styles/android/java/res/drawable/ic_dino.xml
diff --git a/chrome/browser/history_clusters/java/res/drawable/ic_journeys.xml b/components/browser_ui/styles/android/java/res/drawable/ic_journeys.xml similarity index 100% rename from chrome/browser/history_clusters/java/res/drawable/ic_journeys.xml rename to components/browser_ui/styles/android/java/res/drawable/ic_journeys.xml
diff --git a/chrome/android/java/res_chromium/OWNERS b/components/browser_ui/styles/android/java/res_chromium/OWNERS similarity index 100% rename from chrome/android/java/res_chromium/OWNERS rename to components/browser_ui/styles/android/java/res_chromium/OWNERS
diff --git a/chrome/android/java/res_chromium/drawable-hdpi/fre_product_logo.png b/components/browser_ui/styles/android/java/res_chromium/drawable-hdpi/fre_product_logo.png similarity index 100% rename from chrome/android/java/res_chromium/drawable-hdpi/fre_product_logo.png rename to components/browser_ui/styles/android/java/res_chromium/drawable-hdpi/fre_product_logo.png Binary files differ
diff --git a/chrome/android/java/res_chromium/drawable-hdpi/product_logo_name.png b/components/browser_ui/styles/android/java/res_chromium/drawable-hdpi/product_logo_name.png similarity index 100% rename from chrome/android/java/res_chromium/drawable-hdpi/product_logo_name.png rename to components/browser_ui/styles/android/java/res_chromium/drawable-hdpi/product_logo_name.png Binary files differ
diff --git a/chrome/android/java/res_chromium/drawable-mdpi/fre_product_logo.png b/components/browser_ui/styles/android/java/res_chromium/drawable-mdpi/fre_product_logo.png similarity index 100% rename from chrome/android/java/res_chromium/drawable-mdpi/fre_product_logo.png rename to components/browser_ui/styles/android/java/res_chromium/drawable-mdpi/fre_product_logo.png Binary files differ
diff --git a/chrome/android/java/res_chromium/drawable-mdpi/product_logo_name.png b/components/browser_ui/styles/android/java/res_chromium/drawable-mdpi/product_logo_name.png similarity index 100% rename from chrome/android/java/res_chromium/drawable-mdpi/product_logo_name.png rename to components/browser_ui/styles/android/java/res_chromium/drawable-mdpi/product_logo_name.png Binary files differ
diff --git a/chrome/android/java/res_chromium/drawable-xhdpi/fre_product_logo.png b/components/browser_ui/styles/android/java/res_chromium/drawable-xhdpi/fre_product_logo.png similarity index 100% rename from chrome/android/java/res_chromium/drawable-xhdpi/fre_product_logo.png rename to components/browser_ui/styles/android/java/res_chromium/drawable-xhdpi/fre_product_logo.png Binary files differ
diff --git a/chrome/android/java/res_chromium/drawable-xhdpi/product_logo_name.png b/components/browser_ui/styles/android/java/res_chromium/drawable-xhdpi/product_logo_name.png similarity index 100% rename from chrome/android/java/res_chromium/drawable-xhdpi/product_logo_name.png rename to components/browser_ui/styles/android/java/res_chromium/drawable-xhdpi/product_logo_name.png Binary files differ
diff --git a/chrome/android/java/res_chromium/drawable-xxhdpi/fre_product_logo.png b/components/browser_ui/styles/android/java/res_chromium/drawable-xxhdpi/fre_product_logo.png similarity index 100% rename from chrome/android/java/res_chromium/drawable-xxhdpi/fre_product_logo.png rename to components/browser_ui/styles/android/java/res_chromium/drawable-xxhdpi/fre_product_logo.png Binary files differ
diff --git a/chrome/android/java/res_chromium/drawable-xxhdpi/product_logo_name.png b/components/browser_ui/styles/android/java/res_chromium/drawable-xxhdpi/product_logo_name.png similarity index 100% rename from chrome/android/java/res_chromium/drawable-xxhdpi/product_logo_name.png rename to components/browser_ui/styles/android/java/res_chromium/drawable-xxhdpi/product_logo_name.png Binary files differ
diff --git a/chrome/android/java/res_chromium/drawable-xxxhdpi/fre_product_logo.png b/components/browser_ui/styles/android/java/res_chromium/drawable-xxxhdpi/fre_product_logo.png similarity index 100% rename from chrome/android/java/res_chromium/drawable-xxxhdpi/fre_product_logo.png rename to components/browser_ui/styles/android/java/res_chromium/drawable-xxxhdpi/fre_product_logo.png Binary files differ
diff --git a/chrome/android/java/res_chromium/drawable-xxxhdpi/product_logo_name.png b/components/browser_ui/styles/android/java/res_chromium/drawable-xxxhdpi/product_logo_name.png similarity index 100% rename from chrome/android/java/res_chromium/drawable-xxxhdpi/product_logo_name.png rename to components/browser_ui/styles/android/java/res_chromium/drawable-xxxhdpi/product_logo_name.png Binary files differ
diff --git a/components/feature_engagement/public/event_constants.cc b/components/feature_engagement/public/event_constants.cc index bf5cda90..f9f6825b 100644 --- a/components/feature_engagement/public/event_constants.cc +++ b/components/feature_engagement/public/event_constants.cc
@@ -19,6 +19,7 @@ const char kReadingListItemAdded[] = "reading_list_item_added"; const char kReadingListMenuOpened[] = "reading_list_menu_opened"; const char kBookmarkStarMenuOpened[] = "bookmark_star_menu_opened"; +const char kCustomizeChromeOpened[] = "customize_chrome_opened"; const char kReopenTabConditionsMet[] = "reopen_tab_conditions_met"; const char kTabReopened[] = "tab_reopened";
diff --git a/components/feature_engagement/public/event_constants.h b/components/feature_engagement/public/event_constants.h index 8f91b8e1..7e632d14 100644 --- a/components/feature_engagement/public/event_constants.h +++ b/components/feature_engagement/public/event_constants.h
@@ -29,6 +29,8 @@ extern const char kReadingListMenuOpened[]; // Bookmark star button was clicked opening the menu. extern const char kBookmarkStarMenuOpened[]; +// Customize chrome was opened. +extern const char kCustomizeChromeOpened[]; // All conditions for reopen closed tab IPH were met. Since this IPH needs to // track user events (opening/closing tabs, focusing the omnibox, etc) on the
diff --git a/components/feature_engagement/public/feature_constants.cc b/components/feature_engagement/public/feature_constants.cc index b7b8227..47f25ca 100644 --- a/components/feature_engagement/public/feature_constants.cc +++ b/components/feature_engagement/public/feature_constants.cc
@@ -46,10 +46,10 @@ base::FEATURE_ENABLED_BY_DEFAULT); BASE_FEATURE(kIPHHighEfficiencyInfoModeFeature, "IPH_HighEfficiencyInfoMode", - base::FEATURE_ENABLED_BY_DEFAULT); + base::FEATURE_DISABLED_BY_DEFAULT); BASE_FEATURE(kIPHHighEfficiencyModeFeature, "IPH_HighEfficiencyMode", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); BASE_FEATURE(kIPHLiveCaptionFeature, "IPH_LiveCaption", base::FEATURE_ENABLED_BY_DEFAULT); @@ -484,6 +484,9 @@ BASE_FEATURE(kIPHGoogleOneOfferNotificationFeature, "IPH_GoogleOneOfferNotification", base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE(kIPHLauncherSearchHelpUiFeature, + "IPH_LauncherSearchHelpUi", + base::FEATURE_DISABLED_BY_DEFAULT); #endif } // namespace feature_engagement
diff --git a/components/feature_engagement/public/feature_constants.h b/components/feature_engagement/public/feature_constants.h index 66d82bb..5220270 100644 --- a/components/feature_engagement/public/feature_constants.h +++ b/components/feature_engagement/public/feature_constants.h
@@ -202,6 +202,7 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) BASE_DECLARE_FEATURE(kIPHGoogleOneOfferNotificationFeature); +BASE_DECLARE_FEATURE(kIPHLauncherSearchHelpUiFeature); #endif } // namespace feature_engagement
diff --git a/components/feature_engagement/public/feature_list.cc b/components/feature_engagement/public/feature_list.cc index 35e8306..94bdf019 100644 --- a/components/feature_engagement/public/feature_list.cc +++ b/components/feature_engagement/public/feature_list.cc
@@ -179,6 +179,7 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) &kIPHGoogleOneOfferNotificationFeature, + &kIPHLauncherSearchHelpUiFeature, #endif // BUILDFLAG(IS_CHROMEOS_ASH) }; } // namespace
diff --git a/components/feature_engagement/public/feature_list.h b/components/feature_engagement/public/feature_list.h index 259379b..abcfcc3 100644 --- a/components/feature_engagement/public/feature_list.h +++ b/components/feature_engagement/public/feature_list.h
@@ -312,6 +312,8 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) DEFINE_VARIATION_PARAM(kIPHGoogleOneOfferNotificationFeature, "IPH_GoogleOneOfferNotification"); +DEFINE_VARIATION_PARAM(kIPHLauncherSearchHelpUiFeature, + "IPH_LauncherSearchHelpUi"); #endif // BUILDFLAG(IS_CHROMEOS_ASH) } // namespace @@ -475,6 +477,7 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) VARIATION_ENTRY(kIPHGoogleOneOfferNotificationFeature), + VARIATION_ENTRY(kIPHLauncherSearchHelpUiFeature), #endif // BUILDFLAG(IS_CHROMEOS_ASH) };
diff --git a/components/flags_ui/flags_state.cc b/components/flags_ui/flags_state.cc index 3c27e21d..48f65200 100644 --- a/components/flags_ui/flags_state.cc +++ b/components/flags_ui/flags_state.cc
@@ -15,6 +15,7 @@ #include "base/functional/callback.h" #include "base/logging.h" #include "base/metrics/field_trial.h" +#include "base/metrics/field_trial_params.h" #include "base/stl_util.h" #include "base/strings/strcat.h" #include "base/strings/string_piece.h" @@ -128,7 +129,7 @@ const std::string& feature_trial_name, const std::map<std::string, std::string>& feature_variation_params, const std::string& trial_group) { - bool success = variations::AssociateVariationParams( + bool success = base::AssociateFieldTrialParams( feature_trial_name, trial_group, feature_variation_params); if (!success) return nullptr;
diff --git a/components/lens/lens_metrics.cc b/components/lens/lens_metrics.cc index 7104a59..43c302907 100644 --- a/components/lens/lens_metrics.cc +++ b/components/lens/lens_metrics.cc
@@ -8,6 +8,14 @@ namespace lens { +void RecordCameraOpen(CameraOpenEntryPoint entry_point) { + base::UmaHistogramEnumeration(kSearchCameraOpenHistogramName, entry_point); +} + +void RecordCameraResult(CameraResult result) { + base::UmaHistogramEnumeration(kSearchCameraResultHistogramName, result); +} + void RecordAmbientSearchQuery(AmbientSearchEntryPoint entry_point) { base::UmaHistogramEnumeration(kAmbientSearchQueryHistogramName, entry_point); }
diff --git a/components/lens/lens_metrics.h b/components/lens/lens_metrics.h index ee36cdd9..6ef79f4 100644 --- a/components/lens/lens_metrics.h +++ b/components/lens/lens_metrics.h
@@ -10,6 +10,13 @@ // Histogram for recording ambient search queries. constexpr char kAmbientSearchQueryHistogramName[] = "Search.Ambient.Query"; +// Histogram for recording camera open events. +constexpr char kSearchCameraOpenHistogramName[] = "Search.Image.Camera.Open"; + +// Histogram for recording camera result events. +constexpr char kSearchCameraResultHistogramName[] = + "Search.Image.Camera.Result"; + // Histogram for recording the capture result of Lens Region Search. See enum // below for types of results. constexpr char kLensRegionSearchCaptureResultHistogramName[] = @@ -24,6 +31,27 @@ constexpr char kLensRegionSearchRegionAspectRatioHistogramName[] = "Search.RegionSearch.Lens.RegionAspectRatio"; +// Needs to be kept in sync with CameraOpenEntryPoint enum in +// tools/metrics/histograms/enums.xml. +enum class CameraOpenEntryPoint { + OMNIBOX = 0, + NEW_TAB_PAGE = 1, + WIDGET = 2, + TASKS_SURFACE = 3, + KEYBOARD = 4, + kMaxValue = KEYBOARD +}; + +// Needs to be kept in sync with CameraResult enum in +// tools/metrics/histograms/enums.xml. +enum class CameraResult { + SUCCESS_CAMERA = 0, + SUCCESS_GALLERY_IMAGE = 1, + SUCCESS_QR_CODE = 2, + DISMISSED = 3, + kMaxValue = DISMISSED +}; + // Needs to be kept in sync with AmbientSearchEntryPoint enum in // tools/metrics/histograms/enums.xml. enum class AmbientSearchEntryPoint { @@ -71,6 +99,12 @@ // Record an ambient search query along with the entry point that initiated. extern void RecordAmbientSearchQuery(AmbientSearchEntryPoint entry_point); +// Record a camera open event with the entry point. +extern void RecordCameraOpen(CameraOpenEntryPoint entry_point); + +// Record a camera result. +extern void RecordCameraResult(CameraResult result); + } // namespace lens #endif // COMPONENTS_LENS_LENS_METRICS_H_
diff --git a/components/network_session_configurator/browser/network_session_configurator_unittest.cc b/components/network_session_configurator/browser/network_session_configurator_unittest.cc index f876910..190d6b1 100644 --- a/components/network_session_configurator/browser/network_session_configurator_unittest.cc +++ b/components/network_session_configurator/browser/network_session_configurator_unittest.cc
@@ -11,6 +11,7 @@ #include "base/command_line.h" #include "base/containers/contains.h" #include "base/metrics/field_trial.h" +#include "base/metrics/field_trial_params.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "components/network_session_configurator/common/network_features.h" @@ -121,8 +122,7 @@ TEST_F(NetworkSessionConfiguratorTest, Http2FieldTrialDisable) { std::map<std::string, std::string> field_trial_params; field_trial_params["http2_enabled"] = "false"; - variations::AssociateVariationParams("HTTP2", "Experiment", - field_trial_params); + base::AssociateFieldTrialParams("HTTP2", "Experiment", field_trial_params); base::FieldTrialList::CreateFieldTrial("HTTP2", "Experiment"); ParseFieldTrials(); @@ -133,7 +133,7 @@ TEST_F(NetworkSessionConfiguratorTest, DisableQuicFromFieldTrialGroup) { std::map<std::string, std::string> field_trial_params; field_trial_params["enable_quic"] = "false"; - variations::AssociateVariationParams("QUIC", "Disabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Disabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Disabled"); ParseFieldTrials(); @@ -144,7 +144,7 @@ TEST_F(NetworkSessionConfiguratorTest, EnableQuicFromParams) { std::map<std::string, std::string> field_trial_params; field_trial_params["enable_quic"] = "true"; - variations::AssociateVariationParams("QUIC", "UseQuic", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "UseQuic", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "UseQuic"); ParseFieldTrials(); @@ -159,8 +159,8 @@ field_trial_params["channel"] = "T"; field_trial_params["epoch"] = "90001234"; // Epoch in the far future. field_trial_params["quic_version"] = quic::ParsedQuicVersionToString(version); - variations::AssociateVariationParams("QUIC", "ValidQuicParams", - field_trial_params); + base::AssociateFieldTrialParams("QUIC", "ValidQuicParams", + field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "ValidQuicParams"); ParseFieldTrials(); @@ -178,8 +178,8 @@ field_trial_params["enable_quic"] = "true"; // These params are missing channel and epoch. field_trial_params["quic_version"] = quic::ParsedQuicVersionToString(version); - variations::AssociateVariationParams("QUIC", "InvalidQuicParams", - field_trial_params); + base::AssociateFieldTrialParams("QUIC", "InvalidQuicParams", + field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "InvalidQuicParams"); ParseFieldTrials(); @@ -204,7 +204,7 @@ TEST_F(NetworkSessionConfiguratorTest, EnableQuicProxiesForHttpsUrls) { std::map<std::string, std::string> field_trial_params; field_trial_params["enable_quic_proxies_for_https_urls"] = "true"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -215,7 +215,7 @@ TEST_F(NetworkSessionConfiguratorTest, DisableRetryWithoutAltSvcOnQuicErrors) { std::map<std::string, std::string> field_trial_params; field_trial_params["retry_without_alt_svc_on_quic_errors"] = "false"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -227,7 +227,7 @@ QuicCloseSessionsOnIpChangeFromFieldTrialParams) { std::map<std::string, std::string> field_trial_params; field_trial_params["close_sessions_on_ip_change"] = "true"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -239,7 +239,7 @@ QuicGoAwaySessionsOnIpChangeFromFieldTrialParams) { std::map<std::string, std::string> field_trial_params; field_trial_params["goaway_sessions_on_ip_change"] = "true"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -251,7 +251,7 @@ QuicRetransmittableOnWireTimeoutMillisecondsFieldTrialParams) { std::map<std::string, std::string> field_trial_params; field_trial_params["retransmittable_on_wire_timeout_milliseconds"] = "1000"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -265,7 +265,7 @@ std::map<std::string, std::string> field_trial_params; field_trial_params["initial_delay_for_broken_alternative_service_seconds"] = "5"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -279,7 +279,7 @@ TEST_F(NetworkSessionConfiguratorTest, ExponentialBackOffOnInitialDelay) { std::map<std::string, std::string> field_trial_params; field_trial_params["exponential_backoff_on_initial_delay"] = "true"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -292,7 +292,7 @@ DisableExponentialBackOffOnInitialDelay) { std::map<std::string, std::string> field_trial_params; field_trial_params["exponential_backoff_on_initial_delay"] = "false"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -304,7 +304,7 @@ TEST_F(NetworkSessionConfiguratorTest, DelayMainJobWithAvailableSpdySession) { std::map<std::string, std::string> field_trial_params; field_trial_params["delay_main_job_with_available_spdy_session"] = "true"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -316,7 +316,7 @@ NotDelayMainJobWithAvailableSpdySession) { std::map<std::string, std::string> field_trial_params; field_trial_params["delay_main_job_with_available_spdy_session"] = "false"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -328,7 +328,7 @@ QuicIdleConnectionTimeoutSecondsFieldTrialParams) { std::map<std::string, std::string> field_trial_params; field_trial_params["idle_connection_timeout_seconds"] = "300"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -340,7 +340,7 @@ NegativeQuicReducedPingTimeoutSecondsFieldTrialParams) { std::map<std::string, std::string> field_trial_params; field_trial_params["reduced_ping_timeout_seconds"] = "-5"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); EXPECT_EQ(base::Seconds(quic::kPingTimeoutSecs), @@ -351,7 +351,7 @@ LargeQuicReducedPingTimeoutSecondsFieldTrialParams) { std::map<std::string, std::string> field_trial_params; field_trial_params["reduced_ping_timeout_seconds"] = "50"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); EXPECT_EQ(base::Seconds(quic::kPingTimeoutSecs), @@ -362,7 +362,7 @@ QuicReducedPingTimeoutSecondsFieldTrialParams) { std::map<std::string, std::string> field_trial_params; field_trial_params["reduced_ping_timeout_seconds"] = "10"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); EXPECT_EQ(base::Seconds(10), quic_params_.reduced_ping_timeout); @@ -372,7 +372,7 @@ QuicMaxTimeBeforeCryptoHandshakeSeconds) { std::map<std::string, std::string> field_trial_params; field_trial_params["max_time_before_crypto_handshake_seconds"] = "7"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); EXPECT_EQ(base::Seconds(7), quic_params_.max_time_before_crypto_handshake); @@ -382,7 +382,7 @@ NegativeQuicMaxTimeBeforeCryptoHandshakeSeconds) { std::map<std::string, std::string> field_trial_params; field_trial_params["max_time_before_crypto_handshake_seconds"] = "-1"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); EXPECT_EQ(base::Seconds(quic::kMaxTimeForCryptoHandshakeSecs), @@ -393,7 +393,7 @@ QuicMaxIdleTimeBeforeCryptoHandshakeSeconds) { std::map<std::string, std::string> field_trial_params; field_trial_params["max_idle_time_before_crypto_handshake_seconds"] = "11"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); EXPECT_EQ(base::Seconds(11), @@ -404,7 +404,7 @@ NegativeQuicMaxIdleTimeBeforeCryptoHandshakeSeconds) { std::map<std::string, std::string> field_trial_params; field_trial_params["max_idle_time_before_crypto_handshake_seconds"] = "-1"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); EXPECT_EQ(base::Seconds(quic::kInitialIdleTimeoutSecs), @@ -414,7 +414,7 @@ TEST_F(NetworkSessionConfiguratorTest, EnableServerPushCancellation) { std::map<std::string, std::string> field_trial_params; field_trial_params["enable_server_push_cancellation"] = "true"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -425,7 +425,7 @@ TEST_F(NetworkSessionConfiguratorTest, QuicEstimateInitialRtt) { std::map<std::string, std::string> field_trial_params; field_trial_params["estimate_initial_rtt"] = "true"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -437,7 +437,7 @@ QuicMigrateSessionsOnNetworkChangeV2FromFieldTrialParams) { std::map<std::string, std::string> field_trial_params; field_trial_params["migrate_sessions_on_network_change_v2"] = "true"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -449,7 +449,7 @@ QuicMigrateSessionsEarlyV2FromFieldTrialParams) { std::map<std::string, std::string> field_trial_params; field_trial_params["migrate_sessions_early_v2"] = "true"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -461,7 +461,7 @@ QuicRetryOnAlternateNetworkBeforeHandshakeFromFieldTrialParams) { std::map<std::string, std::string> field_trial_params; field_trial_params["retry_on_alternate_network_before_handshake"] = "true"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -474,7 +474,7 @@ std::map<std::string, std::string> field_trial_params; field_trial_params["migrate_idle_sessions"] = "true"; field_trial_params["idle_session_migration_period_seconds"] = "15"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -487,7 +487,7 @@ QuicMaxTimeOnNonDefaultNetworkFromFieldTrialParams) { std::map<std::string, std::string> field_trial_params; field_trial_params["max_time_on_non_default_network_seconds"] = "10"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -501,7 +501,7 @@ std::map<std::string, std::string> field_trial_params; field_trial_params["max_migrations_to_non_default_network_on_write_error"] = "3"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -516,7 +516,7 @@ std::map<std::string, std::string> field_trial_params; field_trial_params ["max_migrations_to_non_default_network_on_path_degrading"] = "4"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -529,7 +529,7 @@ DisableQuicAllowPortMigrationFromFieldTrialParams) { std::map<std::string, std::string> field_trial_params; field_trial_params["allow_port_migration"] = "false"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -541,7 +541,7 @@ QuicDisableTlsZeroRttFromFieldTrialParams) { std::map<std::string, std::string> field_trial_params; field_trial_params["disable_tls_zero_rtt"] = "true"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -553,7 +553,7 @@ QuicDisableGQuicZeroRttFromFieldTrialParams) { std::map<std::string, std::string> field_trial_params; field_trial_params["disable_gquic_zero_rtt"] = "true"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -564,7 +564,7 @@ TEST_F(NetworkSessionConfiguratorTest, PacketLengthFromFieldTrialParams) { std::map<std::string, std::string> field_trial_params; field_trial_params["max_packet_length"] = "1450"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -576,7 +576,7 @@ quic::ParsedQuicVersion version = net::DefaultSupportedQuicVersions().front(); std::map<std::string, std::string> field_trial_params; field_trial_params["quic_version"] = quic::ParsedQuicVersionToString(version); - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -589,7 +589,7 @@ QuicConnectionOptionsFromFieldTrialParams) { std::map<std::string, std::string> field_trial_params; field_trial_params["connection_options"] = "TIME,TBBR,REJ"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -605,7 +605,7 @@ QuicClientConnectionOptionsFromFieldTrialParams) { std::map<std::string, std::string> field_trial_params; field_trial_params["client_connection_options"] = "TBBR,1RTT"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -619,7 +619,7 @@ TEST_F(NetworkSessionConfiguratorTest, QuicHostAllowlist) { std::map<std::string, std::string> field_trial_params; field_trial_params["host_whitelist"] = "www.example.org, www.example.com"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -632,7 +632,7 @@ TEST_F(NetworkSessionConfiguratorTest, QuicHostAllowlistEmpty) { std::map<std::string, std::string> field_trial_params; field_trial_params["host_whitelist"] = ""; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -647,7 +647,7 @@ field_trial_params["set_quic_flags"] = "FLAGS_quic_reloadable_flag_quic_testonly_default_false=true," "FLAGS_quic_restart_flag_quic_testonly_default_true=false"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -659,7 +659,7 @@ TEST_F(NetworkSessionConfiguratorTest, Http2SettingsFromFieldTrialParams) { std::map<std::string, std::string> field_trial_params; field_trial_params["http2_settings"] = "7:1234,25:5678"; - variations::AssociateVariationParams("HTTP2", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("HTTP2", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("HTTP2", "Enabled"); ParseFieldTrials(); @@ -839,7 +839,7 @@ TEST_F(NetworkSessionConfiguratorTest, Http2GreaseSettingsFromFieldTrial) { std::map<std::string, std::string> field_trial_params; field_trial_params["http2_grease_settings"] = "true"; - variations::AssociateVariationParams("HTTP2", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("HTTP2", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("HTTP2", "Enabled"); ParseFieldTrials(); @@ -854,7 +854,7 @@ std::map<std::string, std::string> field_trial_params; field_trial_params["http2_grease_settings"] = "true"; - variations::AssociateVariationParams("HTTP2", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("HTTP2", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("HTTP2", "Enabled"); ParseCommandLineAndFieldTrials(command_line); @@ -876,7 +876,7 @@ TEST_F(NetworkSessionConfiguratorTest, Http2GreaseFrameTypeFromFieldTrial) { std::map<std::string, std::string> field_trial_params; field_trial_params["http2_grease_frame_type"] = "true"; - variations::AssociateVariationParams("HTTP2", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("HTTP2", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("HTTP2", "Enabled"); ParseFieldTrials(); @@ -890,7 +890,7 @@ Http2EndStreamWithDataFrameFromFieldTrial) { std::map<std::string, std::string> field_trial_params; field_trial_params["http2_end_stream_with_data_frame"] = "true"; - variations::AssociateVariationParams("HTTP2", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("HTTP2", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("HTTP2", "Enabled"); ParseFieldTrials(); @@ -902,7 +902,7 @@ QuicInitialRttForHandshakeFromFieldTrailParams) { std::map<std::string, std::string> field_trial_params; field_trial_params["initial_rtt_for_handshake_milliseconds"] = "500"; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); @@ -969,7 +969,7 @@ quic::QuicVersionToString(version_.transport_version); std::map<std::string, std::string> field_trial_params; field_trial_params["quic_version"] = quic_versions; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); quic::ParsedQuicVersionVector expected_versions = {version_}; @@ -988,7 +988,7 @@ quic::ParsedQuicVersionToString(version_); std::map<std::string, std::string> field_trial_params; field_trial_params["quic_version"] = quic_versions; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); quic::ParsedQuicVersionVector expected_versions = {version_}; @@ -1005,7 +1005,7 @@ std::string quic_versions = quic::ParsedQuicVersionToString(version_); std::map<std::string, std::string> field_trial_params; field_trial_params["quic_version"] = quic_versions; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); EXPECT_EQ(net::DefaultSupportedQuicVersions(), @@ -1026,7 +1026,7 @@ quic::ParsedQuicVersionToString(good_version); std::map<std::string, std::string> field_trial_params; field_trial_params["quic_version"] = quic_versions; - variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::AssociateFieldTrialParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); quic::ParsedQuicVersionVector expected_versions = {good_version};
diff --git a/components/omnibox/browser/autocomplete_result_unittest.cc b/components/omnibox/browser/autocomplete_result_unittest.cc index 545c1cab..820eaf8a 100644 --- a/components/omnibox/browser/autocomplete_result_unittest.cc +++ b/components/omnibox/browser/autocomplete_result_unittest.cc
@@ -1086,7 +1086,7 @@ std::map<std::string, std::string> params; params[std::string(OmniboxFieldTrial::kDemoteByTypeRule) + ":3:*"] = "1:50,7:100,2:0"; // 3 == HOME_PAGE - ASSERT_TRUE(variations::AssociateVariationParams( + ASSERT_TRUE(base::AssociateFieldTrialParams( OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params)); } base::FieldTrialList::CreateFieldTrial( @@ -1248,7 +1248,7 @@ { std::map<std::string, std::string> params; params[std::string(OmniboxFieldTrial::kDemoteByTypeRule) + ":*:*"] = "2:50"; - ASSERT_TRUE(variations::AssociateVariationParams( + ASSERT_TRUE(base::AssociateFieldTrialParams( OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params)); } base::FieldTrialList::CreateFieldTrial(
diff --git a/components/omnibox/browser/keyword_provider_unittest.cc b/components/omnibox/browser/keyword_provider_unittest.cc index 0ef9bfa..2aa4ac3 100644 --- a/components/omnibox/browser/keyword_provider_unittest.cc +++ b/components/omnibox/browser/keyword_provider_unittest.cc
@@ -12,6 +12,7 @@ #include "base/command_line.h" #include "base/metrics/field_trial.h" +#include "base/metrics/field_trial_params.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/test/task_environment.h" @@ -264,7 +265,7 @@ { std::map<std::string, std::string> params; params[OmniboxFieldTrial::kKeywordRequiresRegistryRule] = "false"; - ASSERT_TRUE(variations::AssociateVariationParams( + ASSERT_TRUE(base::AssociateFieldTrialParams( OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params)); } base::FieldTrialList::CreateFieldTrial(
diff --git a/components/omnibox/browser/omnibox_field_trial_unittest.cc b/components/omnibox/browser/omnibox_field_trial_unittest.cc index b638ce2..49e103a0 100644 --- a/components/omnibox/browser/omnibox_field_trial_unittest.cc +++ b/components/omnibox/browser/omnibox_field_trial_unittest.cc
@@ -118,7 +118,7 @@ OmniboxFieldTrial::kSuggestPollingDelayMsRule)] = polling_delay_ms_rule_value; } - ASSERT_TRUE(variations::AssociateVariationParams( + ASSERT_TRUE(base::AssociateFieldTrialParams( OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params)); base::FieldTrialList::CreateFieldTrial( OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A"); @@ -139,7 +139,7 @@ SCOPED_TRACE("Valid field trial, missing param."); ResetFieldTrialList(); std::map<std::string, std::string> params; - ASSERT_TRUE(variations::AssociateVariationParams( + ASSERT_TRUE(base::AssociateFieldTrialParams( OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params)); base::FieldTrialList::CreateFieldTrial( OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A"); @@ -151,7 +151,7 @@ ResetFieldTrialList(); std::map<std::string, std::string> params; params[std::string(OmniboxFieldTrial::kDisableProvidersRule)] = ""; - ASSERT_TRUE(variations::AssociateVariationParams( + ASSERT_TRUE(base::AssociateFieldTrialParams( OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params)); base::FieldTrialList::CreateFieldTrial( OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A"); @@ -163,7 +163,7 @@ ResetFieldTrialList(); std::map<std::string, std::string> params; params[std::string(OmniboxFieldTrial::kDisableProvidersRule)] = "aaa"; - ASSERT_TRUE(variations::AssociateVariationParams( + ASSERT_TRUE(base::AssociateFieldTrialParams( OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params)); base::FieldTrialList::CreateFieldTrial( OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A"); @@ -175,7 +175,7 @@ ResetFieldTrialList(); std::map<std::string, std::string> params; params[std::string(OmniboxFieldTrial::kDisableProvidersRule)] = "12321"; - ASSERT_TRUE(variations::AssociateVariationParams( + ASSERT_TRUE(base::AssociateFieldTrialParams( OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params)); base::FieldTrialList::CreateFieldTrial( OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A"); @@ -191,7 +191,7 @@ params[std::string(OmniboxFieldTrial::kDemoteByTypeRule) + ":3:*"] = "5:100"; params[std::string(OmniboxFieldTrial::kDemoteByTypeRule) + ":*:*"] = "1:25"; - ASSERT_TRUE(variations::AssociateVariationParams( + ASSERT_TRUE(base::AssociateFieldTrialParams( OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params)); } base::FieldTrialList::CreateFieldTrial( @@ -268,7 +268,7 @@ params["rule4:4:0"] = "rule4-4-0-value"; // OTHER // Add a malformed rule to make sure it doesn't screw things up. params["unrecognized"] = "unrecognized-value"; - ASSERT_TRUE(variations::AssociateVariationParams( + ASSERT_TRUE(base::AssociateFieldTrialParams( OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params)); } @@ -371,7 +371,7 @@ params[std::string( OmniboxFieldTrial::kHUPNewScoringVisitedCountScoreBucketsParam)] = "5:300,0:200"; - ASSERT_TRUE(variations::AssociateVariationParams( + ASSERT_TRUE(base::AssociateFieldTrialParams( OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params)); } base::FieldTrialList::CreateFieldTrial( @@ -405,7 +405,7 @@ "1"; params[OmniboxFieldTrial::kHUPNewScoringTypedCountScoreBucketsParam] = "0.1:100,0.5:500,1.0:1000"; - ASSERT_TRUE(variations::AssociateVariationParams( + ASSERT_TRUE(base::AssociateFieldTrialParams( OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params)); } base::FieldTrialList::CreateFieldTrial(
diff --git a/components/paint_preview/common/serialized_recording_unittest.cc b/components/paint_preview/common/serialized_recording_unittest.cc index a5bb29c..2e379a2 100644 --- a/components/paint_preview/common/serialized_recording_unittest.cc +++ b/components/paint_preview/common/serialized_recording_unittest.cc
@@ -92,7 +92,7 @@ paint.setStyle(SkPaint::kFill_Style); paint.setColor(SK_ColorRED); canvas->drawRect(sk_bounds, paint); - canvas->drawImage(SkImage::MakeFromBitmap(bitmap), 0, 0); + canvas->drawImage(SkImages::RasterFromBitmap(bitmap), 0, 0); return recorder.finishRecordingAsPicture(); }
diff --git a/components/paint_preview/renderer/paint_preview_recorder_utils.cc b/components/paint_preview/renderer/paint_preview_recorder_utils.cc index ebab63b1..76f3d28 100644 --- a/components/paint_preview/renderer/paint_preview_recorder_utils.cc +++ b/components/paint_preview/renderer/paint_preview_recorder_utils.cc
@@ -43,7 +43,7 @@ } // Make immutable to skip an extra copy. bitmap.setImmutable(); - sk_image = SkImage::MakeFromBitmap(bitmap); + sk_image = SkImages::RasterFromBitmap(bitmap); } return cc::PaintImageBuilder::WithDefault() .set_id(cc::PaintImage::GetNextId())
diff --git a/components/paint_preview/renderer/paint_preview_recorder_utils_unittest.cc b/components/paint_preview/renderer/paint_preview_recorder_utils_unittest.cc index d6d91030..4e08de9 100644 --- a/components/paint_preview/renderer/paint_preview_recorder_utils_unittest.cc +++ b/components/paint_preview/renderer/paint_preview_recorder_utils_unittest.cc
@@ -378,7 +378,7 @@ .set_id(cc::PaintImage::GetNextId()) .set_texture_backing( sk_sp<FakeTextureBacking>( - new FakeTextureBacking(SkImage::MakeFromBitmap(bitmap))), + new FakeTextureBacking(SkImages::RasterFromBitmap(bitmap))), cc::PaintImage::GetNextContentId()) .TakePaintImage(); canvas->drawImage(paint_image, 0U, 0U); @@ -405,9 +405,9 @@ bitmap.allocN32Pixels(dimensions.width(), dimensions.height()); SkCanvas sk_canvas(bitmap); sk_canvas.drawColor(SkColors::kRed); - auto sk_image = SkImage::MakeFromBitmap(bitmap); + auto sk_image = SkImages::RasterFromBitmap(bitmap); auto data = sk_image->encodeToData(); - auto lazy_sk_image = SkImage::MakeFromEncoded(data); + auto lazy_sk_image = SkImages::DeferredFromEncodedData(data); ASSERT_TRUE(lazy_sk_image->isLazyGenerated()); cc::PaintImage paint_image = cc::PaintImageBuilder::WithDefault()
diff --git a/components/password_manager/core/browser/form_parsing/form_parser.cc b/components/password_manager/core/browser/form_parsing/form_parser.cc index 988c5a4..c0dca29 100644 --- a/components/password_manager/core/browser/form_parsing/form_parser.cc +++ b/components/password_manager/core/browser/form_parsing/form_parser.cc
@@ -577,18 +577,23 @@ } // Filters the available passwords from |processed_fields| using these rules: -// (1) Passwords with Interactability below |best_interactability| are removed. -// (2) If |mode| == |kSaving|, passwords with empty values are removed. -// (3) Passwords for which IsLikelyPassword returns false are removed. -// (4) Field parsed as username is removed. -// If applying rules (1)-(3) results in a non-empty vector of password fields, -// that vector is returned. Otherwise, only rules (1) and (2) are applied and -// the result returned (even if it is empty). +// (0): Filter out all input fields which type is not password. +// (1) If |mode| == |kFilling|, credit card fields are ignored even for +// fallback. +// (2) Passwords with Interactability below |best_interactability| are removed. +// (3) If |mode| == |kSaving|, passwords with empty values are removed. +// (4) Passwords for which IsLikelyPassword returns false are removed. +// (5) The field parsed as username is removed. +// If applying filters (0)-(1) results in an empty vector, the vector is +// returned. +// If applying filters (0)-(5) results in a non-empty vector of password fields, +// that vector is returned. Otherwise, roll back to the result after applying +// (0)-(3) and return it (with |is_fallback=true|) even if the result is empty. // Neither of the following output parameters may be null: -// |readonly_status| will be updated according to the processing of the parsed +// - |readonly_status| will be updated according to the processing of the parsed // fields. -// |is_fallback| is set to true if the filtering rule (3) was not used to -// obtain the result. +// - |is_fallback| is set to true if applying all filters removes all fields and +// the method rolls back to the result after (0)-(3). std::vector<const FormFieldData*> GetRelevantPasswords( const std::vector<ProcessedField>& processed_fields, FormDataParser::Mode mode, @@ -599,13 +604,27 @@ DCHECK(readonly_status); DCHECK(is_fallback); - // Step 0: filter out all non-password fields. + // Step 0: filter out all input fields which type is not password. std::vector<const ProcessedField*> passwords; passwords.reserve(processed_fields.size()); for (const ProcessedField& processed_field : processed_fields) { if (processed_field.is_password) passwords.push_back(&processed_field); } + // Step 1: filter out credit card fields (e.g. CVC). In the filling mode, + // don't keep CC fields even for fallback filling and let non-password + // Autofill handle these fields. Fallback saving is fine because saving UIs of + // Autofill and the password manager are not mutually exclusive. + if (mode == FormDataParser::Mode::kFilling) { + base::EraseIf(passwords, [](const ProcessedField* processed_field) { + // TODO(crbug/1425423): This code does not use |StringMatchesCVC| because + // the underlying regex has a high false positive rate, i.e. matches many + // real password fields. Reconsider this once the regex becomes better. + return processed_field->server_hints_credit_card_field || + processed_field->autocomplete_flag == + AutocompleteFlag::kCreditCardField; + }); + } if (passwords.empty()) return std::vector<const FormFieldData*>(); @@ -614,20 +633,20 @@ const size_t all_passwords_seen = passwords.size(); size_t ignored_readonly = 0; - // Step 1: apply filter criterion (1). + // Step 2: apply filter criterion (2). base::EraseIf( passwords, [best_interactability](const ProcessedField* processed_field) { return !MatchesInteractability(*processed_field, best_interactability); }); if (mode == FormDataParser::Mode::kSaving) { - // Step 2: apply filter criterion (2). + // Step 3: apply filter criterion (3). base::EraseIf(passwords, [](const ProcessedField* processed_field) { return GetFieldValue(*processed_field->field).empty(); }); } - // Step 3: apply filter criterion (3). Keep the current content of + // Step 4: apply filter criterion (4). Keep the current content of // |passwords| though, in case it is needed for fallback. std::vector<const ProcessedField*> filtered; filtered.reserve(passwords.size()); @@ -637,7 +656,7 @@ return IsLikelyPassword(*processed_field, &ignored_readonly); }); - // Step 4: remove the field parsed as username, if needed. + // Step 5: remove the field parsed as username, if needed. if (username && username->IsPasswordInputElement()) { base::EraseIf(filtered, [username](const ProcessedField* processed_field) { return processed_field->field->unique_renderer_id ==
diff --git a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc index d478bf68..280520f1 100644 --- a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc +++ b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc
@@ -1027,10 +1027,10 @@ "Simple form, all fields are credit-card-related", .fields = { - {.role = ElementRole::USERNAME, + {.role_saving = ElementRole::USERNAME, .autocomplete_attribute = "cc-name", .form_control_type = "text"}, - {.role = ElementRole::CURRENT_PASSWORD, + {.role_saving = ElementRole::CURRENT_PASSWORD, .autocomplete_attribute = "cc-any-string", .form_control_type = "password"}, }, @@ -1793,8 +1793,9 @@ "Server hints: CREDIT_CARD_VERIFICATION_CODE on only password.", .fields = { - {.role = ElementRole::USERNAME, .form_control_type = "text"}, - {.role = ElementRole::CURRENT_PASSWORD, + {.role_saving = ElementRole::USERNAME, + .form_control_type = "text"}, + {.role_saving = ElementRole::CURRENT_PASSWORD, .form_control_type = "password", .prediction = {.type = autofill::CREDIT_CARD_VERIFICATION_CODE}}, @@ -1880,8 +1881,9 @@ .description_for_logging = "Server hints: CREDIT_CARD_NUMBER.", .fields = { - {.role = ElementRole::USERNAME, .form_control_type = "text"}, - {.role = ElementRole::CURRENT_PASSWORD, + {.role_saving = ElementRole::USERNAME, + .form_control_type = "text"}, + {.role_saving = ElementRole::CURRENT_PASSWORD, .form_control_type = "password", .prediction = {.type = autofill::CREDIT_CARD_NUMBER}}, }, @@ -1909,11 +1911,11 @@ "date are both password fields.", .fields = { - {.role = ElementRole::USERNAME, + {.role_saving = ElementRole::USERNAME, .name = u"cardholder", .form_control_type = "text", .prediction = {.type = autofill::CREDIT_CARD_NAME_FULL}}, - {.role = ElementRole::CURRENT_PASSWORD, + {.role_saving = ElementRole::CURRENT_PASSWORD, .name = u"ccnumber", .form_control_type = "password", .prediction = {.type = autofill::CREDIT_CARD_NUMBER}}, @@ -1921,7 +1923,7 @@ .form_control_type = "text", .prediction = {.type = autofill::CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR}}, - {.role = ElementRole::NEW_PASSWORD, + {.role_saving = ElementRole::NEW_PASSWORD, .name = u"cvc", .form_control_type = "password", .prediction = {.type = @@ -1956,7 +1958,7 @@ }, { .description_for_logging = "Create a fallback for the only password" - "field being an SSN/OTP field", + " field being an SSN/OTP field.", .fields = { {.role = ElementRole::USERNAME, @@ -1997,7 +1999,7 @@ }, { .description_for_logging = "Create a fallback for the only password" - "field being an SSN/OTP field", + " field being an SSN/OTP field.", .fields = { {.role = ElementRole::USERNAME,
diff --git a/components/password_manager/core/browser/password_manager_unittest.cc b/components/password_manager/core/browser/password_manager_unittest.cc index 019446f5..a650580 100644 --- a/components/password_manager/core/browser/password_manager_unittest.cc +++ b/components/password_manager/core/browser/password_manager_unittest.cc
@@ -3334,14 +3334,21 @@ PasswordForm saved_match(MakeSimpleForm()); store_->AddLogin(saved_match); - PasswordForm credit_card_form(MakeSimpleCreditCardForm()); - credit_card_form.only_for_fallback = true; + PasswordForm non_password_form(MakeSimpleForm()); + non_password_form.username_value = u"+1 650 000 000"; // Phone number. + non_password_form.form_data.fields[0].value = + non_password_form.username_value; + non_password_form.password_value = u"379 390"; // One time SMS code. + non_password_form.form_data.fields[1].value = + non_password_form.password_value; + non_password_form.form_data.fields[1].id_attribute = u"one-time-code"; + non_password_form.only_for_fallback = true; PasswordFormFillData form_data; EXPECT_CALL(driver_, SetPasswordFillData) .WillRepeatedly(SaveArg<0>(&form_data)); - manager()->OnPasswordFormsParsed(&driver_, {credit_card_form.form_data}); + manager()->OnPasswordFormsParsed(&driver_, {non_password_form.form_data}); task_environment_.RunUntilIdle(); // Check that manual filling fallback available. @@ -3355,6 +3362,44 @@ // Check that saving fallback is available. std::unique_ptr<PasswordFormManagerForUI> form_manager_to_save; + EXPECT_CALL(client_, ShowManualFallbackForSavingPtr(_, _, _)) + .WillOnce(WithArg<0>(SaveToScopedPtr(&form_manager_to_save))); + manager()->OnInformAboutUserInput(&driver_, non_password_form.form_data); + ASSERT_TRUE(form_manager_to_save); + EXPECT_THAT(form_manager_to_save->GetPendingCredentials(), + FormMatches(non_password_form)); + + // Check that no automatic save prompt is shown. + OnPasswordFormSubmitted(non_password_form.form_data); + EXPECT_CALL(client_, PromptUserToSaveOrUpdatePasswordPtr(_)).Times(0); + manager()->DidNavigateMainFrame(true); + manager()->OnPasswordFormsRendered(&driver_, {}); + task_environment_.RunUntilIdle(); +} + +// Check that on a credit card form, there is no password filling (can be +// overwritten with a server override, but it is not tested in this test). For +// saving, only the fallback is available. +TEST_P(PasswordManagerTest, FillingAndSavingFallbacksOnCreditCardForm) { + PasswordFormManager::set_wait_for_server_predictions_for_filling(false); + EXPECT_CALL(client_, IsSavingAndFillingEnabled(_)) + .WillRepeatedly(Return(true)); + + PasswordForm saved_match(MakeSimpleForm()); + store_->AddLogin(saved_match); + PasswordForm credit_card_form(MakeSimpleCreditCardForm()); + credit_card_form.only_for_fallback = true; + + PasswordFormFillData form_data; + // No filling fallback in order to let non-password Autofill to handle the + // form. + EXPECT_CALL(driver_, SetPasswordFillData).Times(0); + + manager()->OnPasswordFormsParsed(&driver_, {credit_card_form.form_data}); + task_environment_.RunUntilIdle(); + + // Check that saving fallback is available. + std::unique_ptr<PasswordFormManagerForUI> form_manager_to_save; EXPECT_CALL(client_, ShowManualFallbackForSavingPtr(_, false, false)) .WillOnce(WithArg<0>(SaveToScopedPtr(&form_manager_to_save))); manager()->OnInformAboutUserInput(&driver_, credit_card_form.form_data);
diff --git a/components/payments/content/android/java/src/org/chromium/components/payments/AndroidPaymentApp.java b/components/payments/content/android/java/src/org/chromium/components/payments/AndroidPaymentApp.java index e70358c8..9756b5e 100644 --- a/components/payments/content/android/java/src/org/chromium/components/payments/AndroidPaymentApp.java +++ b/components/payments/content/android/java/src/org/chromium/components/payments/AndroidPaymentApp.java
@@ -261,9 +261,8 @@ /*packageName=*/mPackageName, /*serviceName=*/mIsReadyToPayServiceName, removeUrlScheme(origin), removeUrlScheme(iframeOrigin), certificateChain, WebPaymentIntentHelperTypeConverter.fromMojoPaymentMethodDataMap(methodDataMap), - /*clearIdFields=*/ - !PaymentFeatureList.isEnabled( - PaymentFeatureList.ADD_IDENTITY_IN_CAN_MAKE_PAYMENT_EVENT)); + // TODO(crbug.com/1290492): Re-enable clearing of identity for IS_READY_TO_PAY + /*clearIdFields=*/false); if (mBypassIsReadyToPayServiceInTest) { respondToIsReadyToPayQuery(true); return;
diff --git a/components/pdf/renderer/pdf_accessibility_tree.cc b/components/pdf/renderer/pdf_accessibility_tree.cc index a4dc241..2131bb3 100644 --- a/components/pdf/renderer/pdf_accessibility_tree.cc +++ b/components/pdf/renderer/pdf_accessibility_tree.cc
@@ -424,6 +424,29 @@ VLOG(2) << "Creating an OCR status node."; return node_ptr; } + +std::unique_ptr<gfx::Transform> MakeTransformForImage( + const chrome_pdf::AccessibilityImageInfo& image) { + // Nodes created with OCR results from the image will be misaligned on screen + // if `image_screen_size` is different from `image_pixel_size`. To address + // this misalignment issue, an additional transform needs to be created. This + // transform will be applied to a leaf node pointing to a child tree that + // contains nodes created from OCR results. Once it's applied to that node, + // this transform will be applied to all nodes within the child tree. + const gfx::RectF& image_screen_size = image.bounds; + const gfx::RectF image_pixel_size = + gfx::RectF(image.image_data.width(), image.image_data.height()); + CHECK(!image_pixel_size.IsEmpty()); + + auto transform = std::make_unique<gfx::Transform>(); + float width_scale_factor = + image_screen_size.width() / image_pixel_size.width(); + float height_scale_factor = + image_screen_size.height() / image_pixel_size.height(); + transform->Scale(width_scale_factor, height_scale_factor); + + return transform; +} #endif // BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) ax::mojom::Role GetRoleForButtonType(chrome_pdf::ButtonType button_type) { @@ -1188,7 +1211,7 @@ ocr_service_->ScheduleImageProcessing( images_[i], base::BindOnce(&PdfAccessibilityTree::OnOcrDataReceived, pdf_accessibility_tree_, image_node->id, - images_[i].bounds, para_node->id)); + images_[i], para_node->id)); } #endif } @@ -1874,7 +1897,7 @@ #if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) void PdfAccessibilityTree::OnOcrDataReceived( const ui::AXNodeID& image_node_id, - const gfx::RectF& image_bounds, + const chrome_pdf::AccessibilityImageInfo& image, const ui::AXNodeID& parent_node_id, const ui::AXTreeID& child_tree_id) { // TODO(accessibility): Following the convensions in this file, this method @@ -1900,6 +1923,7 @@ VLOG(1) << "OCR data received: " << child_tree_id.ToString(); + const gfx::RectF& image_bounds = image.bounds; DCHECK_NE(image_node_id, ui::kInvalidAXNodeID); DCHECK_NE(parent_node_id, ui::kInvalidAXNodeID); DCHECK(!image_bounds.IsEmpty()); @@ -1924,6 +1948,11 @@ // page_node->AddBoolAttribute(ax::mojom::BoolAttribute::kIsAutoGenerated, // true); page_node->relative_bounds.bounds = image_bounds; + // Create a Transform to position OCR results on PDF. Without this transform, + // nodes created from OCR results will have misaligned bounding boxes. This + // transform will be applied to all nodes within a child tree pointed by + // `child_tree_id`. + page_node->relative_bounds.transform = MakeTransformForImage(image); page_node->AddChildTreeId(child_tree_id); int num_erased = base::EraseIf(nodes_, [&image_node_id](const auto& node) {
diff --git a/components/pdf/renderer/pdf_accessibility_tree.h b/components/pdf/renderer/pdf_accessibility_tree.h index d6fcba3..2f854b62 100644 --- a/components/pdf/renderer/pdf_accessibility_tree.h +++ b/components/pdf/renderer/pdf_accessibility_tree.h
@@ -32,6 +32,7 @@ struct AccessibilityActionData; struct AccessibilityCharInfo; struct AccessibilityDocInfo; +struct AccessibilityImageInfo; struct AccessibilityPageInfo; struct AccessibilityPageObjects; struct AccessibilityTextRunInfo; @@ -131,7 +132,7 @@ // adds a page node hosting a child tree containing the page contents which // will later be provided by the OCR Service. void OnOcrDataReceived(const ui::AXNodeID& image_node_id, - const gfx::RectF& image_bounds, + const chrome_pdf::AccessibilityImageInfo& image, const ui::AXNodeID& parent_node_id, const ui::AXTreeID& child_tree_id);
diff --git a/components/performance_manager/features.cc b/components/performance_manager/features.cc index dc9e4078..70fb925 100644 --- a/components/performance_manager/features.cc +++ b/components/performance_manager/features.cc
@@ -39,7 +39,7 @@ &kHighEfficiencyModeAvailable, "time_before_discard", base::Hours(2)}; const base::FeatureParam<bool> kHighEfficiencyModeDefaultState{ - &kHighEfficiencyModeAvailable, "default_state", true}; + &kHighEfficiencyModeAvailable, "default_state", false}; // 10 tabs is the 70th percentile of tab counts based on UMA data. const base::FeatureParam<int> kHighEfficiencyModePromoTabCountThreshold{
diff --git a/components/policy/proto/chrome_device_policy.proto b/components/policy/proto/chrome_device_policy.proto index 6dfb9950..e50c207 100644 --- a/components/policy/proto/chrome_device_policy.proto +++ b/components/policy/proto/chrome_device_policy.proto
@@ -1714,10 +1714,10 @@ // Setting that controls whether ARC data snapshotting is enabled for the device // and time intervals of updating ARC data snapshot. -message DeviceArcDataSnapshotHoursProto { +message OBSOLETE_DeviceArcDataSnapshotHoursProto { // This is a JSON string, for details see // "DeviceArcDataSnapshotHours" in policy_template.json - optional string arc_data_snapshot_hours = 1; + optional string OBSOLETE_arc_data_snapshot_hours = 1 [deprecated = true]; } // Setting that controls whether system-wide trace collection using the Perfetto @@ -1948,7 +1948,8 @@ optional UsbDetachableAllowlistProto usb_detachable_allowlist = 113; optional DeviceFamilyLinkAccountsAllowedProto family_link_accounts_allowed = 114; - optional DeviceArcDataSnapshotHoursProto arc_data_snapshot_hours = 115; + optional OBSOLETE_DeviceArcDataSnapshotHoursProto arc_data_snapshot_hours = + 115 [deprecated = true]; optional BooleanPolicyProto device_allow_mgs_to_store_display_properties = 116; optional DeviceSystemWideTracingEnabledProto
diff --git a/components/policy/resources/templates/device_policy_proto_map.yaml b/components/policy/resources/templates/device_policy_proto_map.yaml index 4d74d045..4320b69 100644 --- a/components/policy/resources/templates/device_policy_proto_map.yaml +++ b/components/policy/resources/templates/device_policy_proto_map.yaml
@@ -15,7 +15,6 @@ DeviceAllowNewUsers: allow_new_users.allow_new_users DeviceAllowRedeemChromeOsRegistrationOffers: allow_redeem_offers.allow_redeem_offers DeviceAllowedBluetoothServices: device_allowed_bluetooth_services.allowlist -DeviceArcDataSnapshotHours: arc_data_snapshot_hours.arc_data_snapshot_hours DeviceAuthDataCacheLifetime: device_auth_data_cache_lifetime.lifetime_hours DeviceAutoUpdateDisabled: auto_update_settings.update_disabled DeviceAutoUpdateP2PEnabled: auto_update_settings.p2p_enabled
diff --git a/components/policy/resources/templates/policy_definitions/Arc/DeviceArcDataSnapshotHours.yaml b/components/policy/resources/templates/policy_definitions/Arc/DeviceArcDataSnapshotHours.yaml index 5a484a4..c3476ada 100644 --- a/components/policy/resources/templates/policy_definitions/Arc/DeviceArcDataSnapshotHours.yaml +++ b/components/policy/resources/templates/policy_definitions/Arc/DeviceArcDataSnapshotHours.yaml
@@ -9,6 +9,7 @@ update process. Note: a device is blocked for usage during the ARC data snapshot update process.' device_only: true +deprecated: true example_value: intervals: - end: @@ -40,6 +41,6 @@ type: string type: object supported_on: -- chrome_os:88- +- chrome_os:88-113 tags: [] type: dict
diff --git a/components/policy/test/data/policy_test_cases.json b/components/policy/test/data/policy_test_cases.json index d152902..e30dc63 100644 --- a/components/policy/test/data/policy_test_cases.json +++ b/components/policy/test/data/policy_test_cases.json
@@ -16322,45 +16322,7 @@ ] }, "DeviceArcDataSnapshotHours": { - "os": [ - "chromeos_ash" - ], - "policy_pref_mapping_tests": [ - { - "policies": { - "DeviceArcDataSnapshotHours": { - "intervals": [ - { - "start": { - "day_of_week": 1, - "time": 1284000 - }, - "end": { - "day_of_week": 1, - "time": 21720000 - } - }, - { - "start": { - "day_of_week": 2, - "time": 1284000 - }, - "end": { - "day_of_week": 2, - "time": 21720000 - } - } - ], - "timezone": "GMT" - } - }, - "prefs": { - "arc.snapshot_hours": { - "location": "local_state" - } - } - } - ] + "reason_for_missing_test": "Policy was removed" }, "DeviceBorealisAllowed": { "reason_for_missing_test": "Policy was removed"
diff --git a/components/safe_browsing/android/remote_database_manager_unittest.cc b/components/safe_browsing/android/remote_database_manager_unittest.cc index 8c71c31..09da9639 100644 --- a/components/safe_browsing/android/remote_database_manager_unittest.cc +++ b/components/safe_browsing/android/remote_database_manager_unittest.cc
@@ -8,6 +8,7 @@ #include <memory> #include "base/metrics/field_trial.h" +#include "base/metrics/field_trial_params.h" #include "base/run_loop.h" #include "base/test/metrics/histogram_tester.h" #include "base/time/time.h" @@ -60,8 +61,8 @@ if (!types_to_check_val.empty()) params["types_to_check"] = types_to_check_val; - ASSERT_TRUE(variations::AssociateVariationParams(experiment_name, - group_name, params)); + ASSERT_TRUE( + base::AssociateFieldTrialParams(experiment_name, group_name, params)); } content::BrowserTaskEnvironment task_environment_;
diff --git a/components/safe_browsing/core/browser/tailored_security_service/tailored_security_service.h b/components/safe_browsing/core/browser/tailored_security_service/tailored_security_service.h index c550336..bab8e04 100644 --- a/components/safe_browsing/core/browser/tailored_security_service/tailored_security_service.h +++ b/components/safe_browsing/core/browser/tailored_security_service/tailored_security_service.h
@@ -111,6 +111,9 @@ void Shutdown() override; protected: + // Callback when the `kAccountTailoredSecurityUpdateTimestamp` is updated + virtual void TailoredSecurityTimestampUpdateCallback(); + // This function is pulled out for testing purposes. Caller takes ownership of // the new Request. virtual std::unique_ptr<Request> CreateRequest( @@ -155,9 +158,6 @@ GetURLLoaderFactory() = 0; private: - // Callback when the `kAccountTailoredSecurityUpdateTimestamp` is updated - void TailoredSecurityTimestampUpdateCallback(); - // Stores pointer to IdentityManager instance. It must outlive the // TailoredSecurityService and can be null during tests. raw_ptr<signin::IdentityManager> identity_manager_;
diff --git a/components/services/storage/shared_storage/shared_storage_database.cc b/components/services/storage/shared_storage/shared_storage_database.cc index 4bf4e74..9f7a74c8 100644 --- a/components/services/storage/shared_storage/shared_storage_database.cc +++ b/components/services/storage/shared_storage/shared_storage_database.cc
@@ -22,6 +22,7 @@ #include "components/services/storage/shared_storage/shared_storage_database_migrations.h" #include "components/services/storage/shared_storage/shared_storage_options.h" #include "mojo/public/cpp/bindings/remote.h" +#include "sql/database.h" #include "sql/error_delegate_util.h" #include "sql/statement.h" #include "sql/transaction.h" @@ -225,7 +226,7 @@ if (!is_filebacked()) return true; - return base::DeleteFile(db_path_); + return sql::Database::Delete(db_path_); } void SharedStorageDatabase::TrimMemory() { @@ -1567,7 +1568,7 @@ if (is_filebacked()) { int64_t file_size = 0L; - if (GetFileSize(db_path_, &file_size)) { + if (base::GetFileSize(db_path_, &file_size)) { int64_t file_size_kb = file_size / 1024; base::UmaHistogramCounts10M( "Storage.SharedStorage.Database.FileBacked.FileSize.KB",
diff --git a/components/sync/test/fake_synced_session_client_ash.cc b/components/sync/test/fake_synced_session_client_ash.cc index adfc52c..1d64e1b 100644 --- a/components/sync/test/fake_synced_session_client_ash.cc +++ b/components/sync/test/fake_synced_session_client_ash.cc
@@ -54,6 +54,10 @@ is_session_sync_enabled_ = enabled; } +void FakeSyncedSessionClientAsh::SetFaviconDelegate( + mojo::PendingRemote<crosapi::mojom::SyncedSessionClientFaviconDelegate> + delegate) {} + void FakeSyncedSessionClientAsh::FlushMojoForTesting() { receivers_.FlushForTesting(); }
diff --git a/components/sync/test/fake_synced_session_client_ash.h b/components/sync/test/fake_synced_session_client_ash.h index 604dbd11..16345f50 100644 --- a/components/sync/test/fake_synced_session_client_ash.h +++ b/components/sync/test/fake_synced_session_client_ash.h
@@ -11,7 +11,6 @@ #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver_set.h" -#include "mojo/public/cpp/bindings/remote_set.h" namespace syncer { @@ -25,6 +24,9 @@ void OnForeignSyncedPhoneSessionsUpdated( std::vector<crosapi::mojom::SyncedSessionPtr> sessions) override; void OnSessionSyncEnabledChanged(bool enabled) override; + void SetFaviconDelegate( + mojo::PendingRemote<crosapi::mojom::SyncedSessionClientFaviconDelegate> + delegate) override; void SetOnForeignSyncedPhoneSessionsUpdatedCallback( base::RepeatingClosure callback);
diff --git a/components/update_client/background_downloader_win.cc b/components/update_client/background_downloader_win.cc index 8bccbad0..2d9749b 100644 --- a/components/update_client/background_downloader_win.cc +++ b/components/update_client/background_downloader_win.cc
@@ -577,8 +577,6 @@ const int error_to_report = SUCCEEDED(error) ? 0 : error; - CHECK(static_cast<bool>(error_to_report) == !base::PathExists(response_)); - DownloadMetrics download_metrics; download_metrics.url = url(); download_metrics.downloader = DownloadMetrics::kBits;
diff --git a/components/user_manager/BUILD.gn b/components/user_manager/BUILD.gn index 100bf99f..5dd2aa39 100644 --- a/components/user_manager/BUILD.gn +++ b/components/user_manager/BUILD.gn
@@ -32,6 +32,8 @@ if (is_chromeos_ash) { sources += [ "common_types.h", + "include_exclude_account_id_filter.cc", + "include_exclude_account_id_filter.h", "known_user.cc", "known_user.h", "remove_user_delegate.h", @@ -77,6 +79,7 @@ source_set("unit_tests") { testonly = true sources = [ + "include_exclude_account_id_filter_unittest.cc", "known_user_unittest.cc", "user_unittest.cc", ]
diff --git a/components/user_manager/fake_user_manager.cc b/components/user_manager/fake_user_manager.cc index 37e2fb9..cd0cab59 100644 --- a/components/user_manager/fake_user_manager.cc +++ b/components/user_manager/fake_user_manager.cc
@@ -176,8 +176,9 @@ } } - if (!active_user_ && AreEphemeralUsersEnabled()) + if (!active_user_ && IsEphemeralAccountId(account_id)) { RegularUserLoggedInAsEphemeral(account_id, USER_TYPE_REGULAR); + } } User* FakeUserManager::GetActiveUserInternal() const { @@ -345,12 +346,13 @@ return true; } -bool FakeUserManager::AreEphemeralUsersEnabled() const { - return GetEphemeralUsersEnabled(); +bool FakeUserManager::IsEphemeralAccountId(const AccountId& account_id) const { + return GetEphemeralModeConfig().IsAccountIdIncluded(account_id); } -void FakeUserManager::SetEphemeralUsersEnabled(bool enabled) { - UserManagerBase::SetEphemeralUsersEnabled(enabled); +void FakeUserManager::SetEphemeralModeConfig( + EphemeralModeConfig ephemeral_mode_config) { + UserManagerBase::SetEphemeralModeConfig(std::move(ephemeral_mode_config)); } const std::string& FakeUserManager::GetApplicationLocale() const {
diff --git a/components/user_manager/fake_user_manager.h b/components/user_manager/fake_user_manager.h index ef09f551..addddb5 100644 --- a/components/user_manager/fake_user_manager.h +++ b/components/user_manager/fake_user_manager.h
@@ -133,7 +133,7 @@ bool IsGuestSessionAllowed() const override; bool IsGaiaUserAllowed(const User& user) const override; bool IsUserAllowed(const User& user) const override; - bool AreEphemeralUsersEnabled() const override; + bool IsEphemeralAccountId(const AccountId& account_id) const override; void UpdateLoginState(const User* active_user, const User* primary_user, bool is_current_user_owner) const override; @@ -150,7 +150,9 @@ bool IsValidDefaultUserImageId(int image_index) const override; // UserManagerBase overrides: - void SetEphemeralUsersEnabled(bool enabled) override; + void SetEphemeralModeConfig( + EphemeralModeConfig ephemeral_mode_config) override; + const std::string& GetApplicationLocale() const override; PrefService* GetLocalState() const override; bool IsEnterpriseManaged() const override;
diff --git a/components/user_manager/include_exclude_account_id_filter.cc b/components/user_manager/include_exclude_account_id_filter.cc new file mode 100644 index 0000000..cb7d0fd --- /dev/null +++ b/components/user_manager/include_exclude_account_id_filter.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/user_manager/include_exclude_account_id_filter.h" + +#include <vector> + +#include "base/check.h" +#include "base/containers/flat_set.h" +#include "components/account_id/account_id.h" + +namespace user_manager { + +namespace { + +bool AreSetsMutuallyExclusive(const base::flat_set<AccountId>& set1, + const base::flat_set<AccountId>& set2) { + for (const auto& item : set1) { + if (set2.count(item) > 0) { + return false; + } + } + return true; +} + +} // namespace + +IncludeExcludeAccountIdFilter::IncludeExcludeAccountIdFilter() = default; + +IncludeExcludeAccountIdFilter::IncludeExcludeAccountIdFilter( + bool included_by_default, + std::vector<AccountId> include_list, + std::vector<AccountId> exclude_list) + : included_by_default_(included_by_default), + include_set_(include_list.begin(), include_list.end()), + exclude_set_(exclude_list.begin(), exclude_list.end()) { + DCHECK(AreSetsMutuallyExclusive(include_set_, exclude_set_)); +} + +IncludeExcludeAccountIdFilter::IncludeExcludeAccountIdFilter( + IncludeExcludeAccountIdFilter&& other) = default; + +IncludeExcludeAccountIdFilter& IncludeExcludeAccountIdFilter::operator=( + IncludeExcludeAccountIdFilter&& other) = default; + +IncludeExcludeAccountIdFilter::~IncludeExcludeAccountIdFilter() = default; + +bool IncludeExcludeAccountIdFilter::IsAccountIdIncluded( + const AccountId& item) const { + if (include_set_.count(item) > 0) { + return true; + } + + if (exclude_set_.count(item) > 0) { + return false; + } + + return included_by_default_; +} + +} // namespace user_manager
diff --git a/components/user_manager/include_exclude_account_id_filter.h b/components/user_manager/include_exclude_account_id_filter.h new file mode 100644 index 0000000..88cb9b2 --- /dev/null +++ b/components/user_manager/include_exclude_account_id_filter.h
@@ -0,0 +1,59 @@ +// 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_USER_MANAGER_INCLUDE_EXCLUDE_ACCOUNT_ID_FILTER_H_ +#define COMPONENTS_USER_MANAGER_INCLUDE_EXCLUDE_ACCOUNT_ID_FILTER_H_ + +#include <vector> + +#include "base/containers/flat_set.h" +#include "components/account_id/account_id.h" +#include "components/user_manager/user_manager_export.h" + +namespace user_manager { + +// IncludeExcludeAccountIdFilter is a data structure which helps to identify +// whether `AccountId` is included or excluded from some set (e.g. set of +// ephemeral accounts). +// +// It holds include set, exclude set and a boolean flag which indicates +// whether item is included by default if not present neither in include set +// nor in exclude set. +// +// For example, every account is ephemeral or not, so we can have a set of +// ephemeral accounts and appropriate IncludeExcludeAccountIdFilter if we +// provide next things: +// 1. list of accounts that are ephemeral (include_list) +// 2. list of accounts that are non-ephemeral (exclude_list) +// 3. boolean flag (included_by_default) which configures whether we consider +// account ephemeral (included to the set) if account is neither present in +// include nor in exclude lists. +class USER_MANAGER_EXPORT IncludeExcludeAccountIdFilter { + public: + IncludeExcludeAccountIdFilter(); + IncludeExcludeAccountIdFilter(bool included_by_default, + std::vector<AccountId> include_list, + std::vector<AccountId> exclude_list); + + IncludeExcludeAccountIdFilter(IncludeExcludeAccountIdFilter&& other); + IncludeExcludeAccountIdFilter& operator=( + IncludeExcludeAccountIdFilter&& other); + + ~IncludeExcludeAccountIdFilter(); + + // Returns whether |item| is included by following next rules: + // 1. Returns true if |item| is present in |include_set_|; + // 2. Returns false if |item| is present in |exclude_set_|; + // 3. Returns value of |included_by_default_|. + bool IsAccountIdIncluded(const AccountId& item) const; + + private: + bool included_by_default_ = false; + base::flat_set<AccountId> include_set_; + base::flat_set<AccountId> exclude_set_; +}; + +} // namespace user_manager + +#endif // COMPONENTS_USER_MANAGER_INCLUDE_EXCLUDE_ACCOUNT_ID_FILTER_H_
diff --git a/components/user_manager/include_exclude_account_id_filter_unittest.cc b/components/user_manager/include_exclude_account_id_filter_unittest.cc new file mode 100644 index 0000000..b28b6a4 --- /dev/null +++ b/components/user_manager/include_exclude_account_id_filter_unittest.cc
@@ -0,0 +1,75 @@ +// 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/user_manager/include_exclude_account_id_filter.h" + +#include <string> +#include <vector> + +#include "components/account_id/account_id.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace user_manager { + +namespace { + +constexpr char kIncludedItem1[] = "included_item1"; +constexpr char kIncludedItem2[] = "included_item2"; + +constexpr char kExcludedItem1[] = "excluded_item1"; +constexpr char kExcludedItem2[] = "excluded_item2"; + +constexpr char kNonListedItem[] = "non_listed_item"; + +IncludeExcludeAccountIdFilter CreateIncludeExcludeAccountIdFilter( + bool included_by_default) { + return IncludeExcludeAccountIdFilter( + included_by_default, + {AccountId::FromUserEmail(kIncludedItem1), + AccountId::FromUserEmail(kIncludedItem2)}, + {AccountId::FromUserEmail(kExcludedItem1), + AccountId::FromUserEmail(kExcludedItem2)}); +} + +} // namespace + +TEST(IncludeExcludeAccountIdFilterTest, DefaultConstructor) { + const IncludeExcludeAccountIdFilter filter; + EXPECT_FALSE( + filter.IsAccountIdIncluded(AccountId::FromUserEmail(kNonListedItem))); +} + +TEST(IncludeExcludeAccountIdFilterTest, IncludedByDefault) { + const auto filter = CreateIncludeExcludeAccountIdFilter(true); + EXPECT_TRUE( + filter.IsAccountIdIncluded(AccountId::FromUserEmail(kNonListedItem))); + + EXPECT_TRUE( + filter.IsAccountIdIncluded(AccountId::FromUserEmail(kIncludedItem1))); + EXPECT_TRUE( + filter.IsAccountIdIncluded(AccountId::FromUserEmail(kIncludedItem2))); + + EXPECT_FALSE( + filter.IsAccountIdIncluded(AccountId::FromUserEmail(kExcludedItem1))); + EXPECT_FALSE( + filter.IsAccountIdIncluded(AccountId::FromUserEmail(kExcludedItem2))); +} + +TEST(IncludeExcludeAccountIdFilterTest, ExcludedByDefault) { + const auto filter = CreateIncludeExcludeAccountIdFilter(false); + EXPECT_FALSE( + filter.IsAccountIdIncluded(AccountId::FromUserEmail(kNonListedItem))); + + EXPECT_TRUE( + filter.IsAccountIdIncluded(AccountId::FromUserEmail(kIncludedItem1))); + EXPECT_TRUE( + filter.IsAccountIdIncluded(AccountId::FromUserEmail(kIncludedItem2))); + + EXPECT_FALSE( + filter.IsAccountIdIncluded(AccountId::FromUserEmail(kExcludedItem1))); + EXPECT_FALSE( + filter.IsAccountIdIncluded(AccountId::FromUserEmail(kExcludedItem2))); +} + +} // namespace user_manager
diff --git a/components/user_manager/user_manager.h b/components/user_manager/user_manager.h index b09e27d..0d69ec3b 100644 --- a/components/user_manager/user_manager.h +++ b/components/user_manager/user_manager.h
@@ -9,6 +9,7 @@ #include "base/functional/callback_forward.h" #include "base/scoped_observation_traits.h" +#include "components/user_manager/include_exclude_account_id_filter.h" #include "components/user_manager/user.h" #include "components/user_manager/user_manager_export.h" #include "components/user_manager/user_type.h" @@ -42,6 +43,8 @@ // * Find/modify users, store user meta-data such as display name/email. class USER_MANAGER_EXPORT UserManager { public: + using EphemeralModeConfig = IncludeExcludeAccountIdFilter; + // Interface that observers of UserManager must implement in order // to receive notification when local state preferences is changed class Observer { @@ -392,8 +395,14 @@ virtual bool IsUserAllowed(const User& user) const = 0; // Returns true if trusted device policies have successfully been retrieved - // and ephemeral users are enabled. - virtual bool AreEphemeralUsersEnabled() const = 0; + // and `account_id` is ephemeral by policies. + // + // NOTE: this function does not handle neither device owner account nor + // explicitly-ephemeral accounts like MGS separately. This function gives an + // answer whether `account_id` is ephemeral by policies. + // + // TODO(b:275059758): Add logic to handle owner ID separately. + virtual bool IsEphemeralAccountId(const AccountId& account_id) const = 0; // Returns "Local State" PrefService instance. virtual PrefService* GetLocalState() const = 0;
diff --git a/components/user_manager/user_manager_base.cc b/components/user_manager/user_manager_base.cc index e8762849..cd97667 100644 --- a/components/user_manager/user_manager_base.cc +++ b/components/user_manager/user_manager_base.cc
@@ -229,7 +229,7 @@ case USER_TYPE_CHILD: // fallthrough case USER_TYPE_ACTIVE_DIRECTORY: if (account_id != GetOwnerAccountId() && !user && - (AreEphemeralUsersEnabled() || browser_restart)) { + (IsEphemeralAccountId(account_id) || browser_restart)) { RegularUserLoggedInAsEphemeral(account_id, user_type); } else { RegularUserLoggedIn(account_id, user_type); @@ -661,8 +661,8 @@ return true; } - // Otherwise, if ephemeral_users policy is enabled, it is ephemeral. - return AreEphemeralUsersEnabled(); + // Otherwise, check ephemeral policies. + return IsEphemeralAccountId(user->GetAccountId()); } bool UserManagerBase::IsCurrentUserOwner() const { @@ -773,7 +773,7 @@ // enabled. // - or - // b) The browser is restarting after a crash. - return AreEphemeralUsersEnabled() || HasBrowserRestarted(); + return IsEphemeralAccountId(account_id) || HasBrowserRestarted(); } bool UserManagerBase::IsUserCryptohomeDataEphemeral( @@ -792,7 +792,7 @@ return true; // Ephemeral users. - if (AreEphemeralUsersEnabled() && user && + if (IsEphemeralAccountId(account_id) && user && user->GetType() == USER_TYPE_REGULAR && FindUserInList(account_id) == nullptr) { return true; @@ -902,12 +902,14 @@ return true; } -bool UserManagerBase::GetEphemeralUsersEnabled() const { - return ephemeral_users_enabled_; +const UserManagerBase::EphemeralModeConfig& +UserManagerBase::GetEphemeralModeConfig() const { + return ephemeral_mode_config_; } -void UserManagerBase::SetEphemeralUsersEnabled(bool enabled) { - ephemeral_users_enabled_ = enabled; +void UserManagerBase::SetEphemeralModeConfig( + EphemeralModeConfig ephemeral_mode_config) { + ephemeral_mode_config_ = std::move(ephemeral_mode_config); } void UserManagerBase::SetIsCurrentUserNew(bool is_new) {
diff --git a/components/user_manager/user_manager_base.h b/components/user_manager/user_manager_base.h index 444ab52..5027a23 100644 --- a/components/user_manager/user_manager_base.h +++ b/components/user_manager/user_manager_base.h
@@ -283,8 +283,9 @@ // Getters/setters for private members. - virtual bool GetEphemeralUsersEnabled() const; - virtual void SetEphemeralUsersEnabled(bool enabled); + const EphemeralModeConfig& GetEphemeralModeConfig() const; + virtual void SetEphemeralModeConfig( + EphemeralModeConfig ephemeral_mode_config); virtual void SetOwnerId(const AccountId& owner_account_id); @@ -382,10 +383,11 @@ // to |false|. bool is_current_user_ephemeral_regular_user_ = false; - // Cached flag indicating whether the ephemeral user policy is enabled. - // Defaults to |false| if the value has not been read from trusted device - // policy yet. - bool ephemeral_users_enabled_ = false; + // Cached `EphemeralModeConfig` created from trusted device policies. + // + // If the value has not been read from trusted device policy yet, then all + // users considered as non-ephemeral. + EphemeralModeConfig ephemeral_mode_config_; // Cached name of device owner. Defaults to empty if the value has not // been read from trusted device policy yet.
diff --git a/components/variations/variations_associated_data.cc b/components/variations/variations_associated_data.cc index 1dfda64..136e422 100644 --- a/components/variations/variations_associated_data.cc +++ b/components/variations/variations_associated_data.cc
@@ -151,13 +151,6 @@ return GroupMapAccessor::GetInstance()->GetID(key, active_group); } -bool AssociateVariationParams( - const std::string& trial_name, - const std::string& group_name, - const std::map<std::string, std::string>& params) { - return base::AssociateFieldTrialParams(trial_name, group_name, params); -} - // Functions below are exposed for testing explicitly behind this namespace. // They simply wrap existing functions in this file. namespace testing {
diff --git a/components/variations/variations_associated_data.h b/components/variations/variations_associated_data.h index d5e04ae2..fecad31d 100644 --- a/components/variations/variations_associated_data.h +++ b/components/variations/variations_associated_data.h
@@ -20,7 +20,7 @@ // IDs. These APIs are meant to extend the base::FieldTrial APIs to offer extra // functionality that is not offered by the simpler base::FieldTrial APIs. // -// The AssociateGoogleVariationID and AssociateVariationParams functions are +// The AssociateGoogleVariationID function is // generally meant to be called by the VariationsService based on server-side // variation configs, but may also be used for client-only field trials by // invoking them directly after appending all the groups to a FieldTrial. @@ -120,12 +120,6 @@ VariationID GetGoogleVariationIDFromHashes(IDCollectionKey key, const ActiveGroupId& active_group); -// Deprecated. Use base::AssociateFieldTrialParams() instead. -COMPONENT_EXPORT(VARIATIONS) -bool AssociateVariationParams(const std::string& trial_name, - const std::string& group_name, - const std::map<std::string, std::string>& params); - // Expose some functions for testing. namespace testing {
diff --git a/components/variations/variations_params_manager.cc b/components/variations/variations_params_manager.cc index a553c424..976b51e 100644 --- a/components/variations/variations_params_manager.cc +++ b/components/variations/variations_params_manager.cc
@@ -10,6 +10,7 @@ #include "base/base_switches.h" #include "base/feature_list.h" #include "base/metrics/field_trial.h" +#include "base/metrics/field_trial_params.h" #include "base/test/scoped_feature_list.h" #include "components/variations/field_trial_config/field_trial_util.h" #include "components/variations/variations_associated_data.h" @@ -26,7 +27,7 @@ const std::string& trial_name, const std::string& trial_group_name, const std::map<std::string, std::string>& param_values) { - AssociateVariationParams(trial_name, trial_group_name, param_values); + base::AssociateFieldTrialParams(trial_name, trial_group_name, param_values); return base::FieldTrialList::CreateFieldTrial(trial_name, trial_group_name); }
diff --git a/components/variations/variations_seed_processor.cc b/components/variations/variations_seed_processor.cc index 31f9949b..ac30d7ab 100644 --- a/components/variations/variations_seed_processor.cc +++ b/components/variations/variations_seed_processor.cc
@@ -12,6 +12,7 @@ #include "base/command_line.h" #include "base/feature_list.h" #include "base/metrics/field_trial.h" +#include "base/metrics/field_trial_params.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/strings/utf_string_conversions.h" @@ -40,7 +41,7 @@ params[experiment.param(i).name()] = experiment.param(i).value(); } if (!params.empty()) - AssociateVariationParams(study.name(), experiment.name(), params); + base::AssociateFieldTrialParams(study.name(), experiment.name(), params); } // Returns the IDCollectionKey with which |experiment| should be associated.
diff --git a/components/variations/variations_seed_simulator_unittest.cc b/components/variations/variations_seed_simulator_unittest.cc index 5158f486..35d3af1 100644 --- a/components/variations/variations_seed_simulator_unittest.cc +++ b/components/variations/variations_seed_simulator_unittest.cc
@@ -8,6 +8,7 @@ #include <map> +#include "base/metrics/field_trial_params.h" #include "base/strings/stringprintf.h" #include "components/variations/client_filterable_state.h" #include "components/variations/processed_study.h" @@ -28,7 +29,7 @@ const std::map<std::string, std::string>* params) { base::FieldTrialList::CreateFieldTrial(trial_name, group_name); if (params != nullptr) - AssociateVariationParams(trial_name, group_name, *params); + base::AssociateFieldTrialParams(trial_name, group_name, *params); base::FieldTrialList::FindFullName(trial_name); }
diff --git a/components/viz/common/gpu/context_cache_controller_unittest.cc b/components/viz/common/gpu/context_cache_controller_unittest.cc index 459678a..e42340d 100644 --- a/components/viz/common/gpu/context_cache_controller_unittest.cc +++ b/components/viz/common/gpu/context_cache_controller_unittest.cc
@@ -181,7 +181,7 @@ auto image_info = SkImageInfo::MakeN32Premul(200, 200); std::vector<uint8_t> image_data(image_info.computeMinByteSize()); SkPixmap pixmap(image_info, image_data.data(), image_info.minRowBytes()); - auto image = SkImage::MakeRasterCopy(pixmap); + auto image = SkImages::RasterFromPixmapCopy(pixmap); auto image_gpu = image->makeTextureImage(gr_context); gr_context->flushAndSubmit(); }
diff --git a/components/viz/service/display/display_resource_provider_software.cc b/components/viz/service/display/display_resource_provider_software.cc index 6ca80fb..06c28de 100644 --- a/components/viz/service/display/display_resource_provider_software.cc +++ b/components/viz/service/display/display_resource_provider_software.cc
@@ -9,6 +9,7 @@ #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" namespace viz { @@ -148,7 +149,7 @@ resource_provider->PopulateSkBitmapWithResource(&sk_bitmap, resource, alpha_type); sk_bitmap.setImmutable(); - sk_image_ = SkImage::MakeFromBitmap(sk_bitmap); + sk_image_ = SkImages::RasterFromBitmap(sk_bitmap); resource_provider_->resource_sk_images_[resource_id] = sk_image_; }
diff --git a/components/viz/service/display/display_scheduler.cc b/components/viz/service/display/display_scheduler.cc index 6f85763..f70d170 100644 --- a/components/viz/service/display/display_scheduler.cc +++ b/components/viz/service/display/display_scheduler.cc
@@ -472,11 +472,9 @@ return; } - begin_frame_deadline_timer_.Start( - FROM_HERE, desired_deadline, begin_frame_deadline_closure_, - deadline_mode == BeginFrameDeadlineMode::kLate - ? base::subtle::DelayPolicy::kFlexibleNoSooner - : base::subtle::DelayPolicy::kPrecise); + begin_frame_deadline_timer_.Start(FROM_HERE, desired_deadline, + begin_frame_deadline_closure_, + base::subtle::DelayPolicy::kPrecise); TRACE_EVENT2("viz", "Using new deadline", "deadline_mode", deadline_mode, "desired_deadline", desired_deadline); }
diff --git a/components/viz/service/display/software_renderer.cc b/components/viz/service/display/software_renderer.cc index a7ac5300..0b27e46 100644 --- a/components/viz/service/display/software_renderer.cc +++ b/components/viz/service/display/software_renderer.cc
@@ -37,6 +37,7 @@ #include "skia/ext/opacity_filter_canvas.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkColor.h" +#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkImageFilter.h" #include "third_party/skia/include/core/SkMatrix.h" #include "third_party/skia/include/core/SkPath.h" @@ -853,7 +854,7 @@ if (filter_clip.IsEmpty()) return nullptr; // Crop the source image to the backdrop_filter_bounds. - sk_sp<SkImage> cropped_image = SkImage::MakeFromBitmap(backdrop_bitmap); + sk_sp<SkImage> cropped_image = SkImages::RasterFromBitmap(backdrop_bitmap); cropped_image = cropped_image->makeSubset(RectToSkIRect(filter_clip), nullptr); cropped_image->asLegacyBitmap(&backdrop_bitmap); @@ -913,7 +914,7 @@ canvas.drawImageRect(filtered_image, src_rect, dst_rect, SkSamplingOptions(), &paint, SkCanvas::kStrict_SrcRectConstraint); - return SkImage::MakeFromBitmap(bitmap)->makeShader( + return SkImages::RasterFromBitmap(bitmap)->makeShader( content_tile_mode, content_tile_mode, SkSamplingOptions(), &filter_backdrop_transform); }
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 a31e60b..df376b2e 100644 --- a/components/viz/service/display_embedder/skia_output_device_dcomp.cc +++ b/components/viz/service/display_embedder/skia_output_device_dcomp.cc
@@ -409,6 +409,7 @@ DCHECK(presenter_); DCHECK(presenter_->SupportsGpuVSync()); + capabilities_.supports_post_sub_buffer = true; capabilities_.supports_delegated_ink = presenter_->SupportsDelegatedInk(); capabilities_.pending_swap_params.max_pending_swaps = 1; capabilities_.renderer_allocates_images = true;
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.cc b/components/viz/service/display_embedder/skia_output_surface_impl.cc index 01ff2ccd..b3c9eb6b 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl.cc
@@ -46,8 +46,10 @@ #include "gpu/vulkan/buildflags.h" #include "skia/buildflags.h" #include "skia/ext/legacy_display_globals.h" +#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkPromiseImageTexture.h" #include "third_party/skia/include/gpu/GrYUVABackendTextures.h" +#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h" #include "ui/base/ui_base_features.h" #include "ui/gfx/color_space.h" #include "ui/gfx/geometry/skia_conversions.h" @@ -454,7 +456,7 @@ image_context->mailbox_holder().texture_target, image_context->ycbcr_info()); FulfillForPlane* fulfill = new FulfillForPlane(impl); - auto image = SkImage::MakePromiseTexture( + auto image = SkImages::PromiseTextureFrom( gr_context_thread_safe_, backend_format, gfx::SizeToSkISize(image_context->size()), GrMipMapped::kNo, image_context->origin(), color_type, image_context->alpha_type(), @@ -483,7 +485,7 @@ GrYUVABackendTextureInfo yuva_backend_info( yuva_info, formats.data(), GrMipmapped::kNo, kTopLeft_GrSurfaceOrigin); - auto image = SkImage::MakePromiseYUVATexture( + auto image = SkImages::PromiseTextureFromYUVA( gr_context_thread_safe_, yuva_backend_info, image_context->color_space(), Fulfill, CleanUp, fulfills); DCHECK(image); @@ -538,7 +540,7 @@ GrYUVABackendTextureInfo yuva_backend_info( yuva_info, formats, GrMipmapped::kNo, kTopLeft_GrSurfaceOrigin); - auto image = SkImage::MakePromiseYUVATexture( + auto image = SkImages::PromiseTextureFromYUVA( gr_context_thread_safe_, yuva_backend_info, std::move(image_color_space), Fulfill, CleanUp, fulfills); DCHECK(image); @@ -793,7 +795,7 @@ si_format, /*plane_index=*/0, GL_TEXTURE_2D, /*ycbcr_info=*/absl::nullopt); FulfillForPlane* fulfill = new FulfillForPlane(image_context.get()); - auto image = SkImage::MakePromiseTexture( + auto image = SkImages::PromiseTextureFrom( gr_context_thread_safe_, backend_format, gfx::SizeToSkISize(image_context->size()), mipmap ? GrMipMapped::kYes : GrMipMapped::kNo, image_context->origin(),
diff --git a/components/viz/test/fake_skia_output_surface.cc b/components/viz/test/fake_skia_output_surface.cc index 529691f..86183f52 100644 --- a/components/viz/test/fake_skia_output_surface.cc +++ b/components/viz/test/fake_skia_output_surface.cc
@@ -24,10 +24,12 @@ #include "gpu/command_buffer/common/swap_buffers_complete_params.h" #include "gpu/command_buffer/service/shared_image/shared_image_format_utils.h" #include "third_party/khronos/GLES2/gl2ext.h" +#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkPixelRef.h" #include "third_party/skia/include/gpu/GpuTypes.h" #include "third_party/skia/include/gpu/GrBackendSurface.h" #include "third_party/skia/include/gpu/GrDirectContext.h" +#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h" #include "third_party/skia/include/gpu/gl/GrGLTypes.h" #include "ui/gfx/gpu_fence_handle.h" #include "ui/gfx/presentation_feedback.h" @@ -130,10 +132,10 @@ auto sk_color_type = ToClosestSkColorType(true /* gpu_compositing */, image_context->format()); image_context->SetImage( - SkImage::MakeFromTexture(gr_context(), backend_texture, - kTopLeft_GrSurfaceOrigin, sk_color_type, - image_context->alpha_type(), - image_context->color_space()), + SkImages::BorrowTextureFrom(gr_context(), backend_texture, + kTopLeft_GrSurfaceOrigin, sk_color_type, + image_context->alpha_type(), + image_context->color_space()), {backend_texture.getBackendFormat()}); }
diff --git a/content/app/android/content_jni_onload.cc b/content/app/android/content_jni_onload.cc index 0a9801d..895cf44 100644 --- a/content/app/android/content_jni_onload.cc +++ b/content/app/android/content_jni_onload.cc
@@ -9,9 +9,9 @@ #include "base/android/base_jni_onload.h" #include "base/android/jni_android.h" #include "base/android/library_loader/library_loader_hooks.h" -#include "base/functional/bind.h" +#include "base/i18n/icu_util.h" +#include "base/trace_event/trace_event.h" #include "content/app/android/library_loader_hooks.h" -#include "content/public/app/content_main.h" namespace content { namespace android { @@ -21,6 +21,13 @@ return false; base::android::SetLibraryLoadedHook(&content::LibraryLoaded); + +#if ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE + // Initialize ICU early so that it can be used by JNI calls before + // ContentMain() is called. + TRACE_EVENT0("startup", "InitializeICU"); + CHECK(base::i18n::InitializeICU()); +#endif return true; }
diff --git a/content/app/content_main_runner_impl.cc b/content/app/content_main_runner_impl.cc index 0846656e..a6458f1 100644 --- a/content/app/content_main_runner_impl.cc +++ b/content/app/content_main_runner_impl.cc
@@ -941,26 +941,10 @@ RegisterPathProvider(); -#if BUILDFLAG(IS_ANDROID) && (ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE) - if (process_type.empty()) { - TRACE_EVENT0("startup", "InitializeICU"); - // In browser process load ICU data files from disk. - if (!base::i18n::InitializeICU()) { - return TerminateForFatalInitializationError(); - } - } else { - // In child process map ICU data files loaded by browser process. - int icu_data_fd = g_fds->MaybeGet(kAndroidICUDataDescriptor); - if (icu_data_fd == -1) { - return TerminateForFatalInitializationError(); - } - auto icu_data_region = g_fds->GetRegion(kAndroidICUDataDescriptor); - if (!base::i18n::InitializeICUWithFileDescriptor(icu_data_fd, - icu_data_region)) { - return TerminateForFatalInitializationError(); - } - } -#else +// On Android, InitializeICU() is called from content_jni_onload.cc +// so that it is available before Content::main() is called. +// https://crbug.com/1418738 +#if !BUILDFLAG(IS_ANDROID) if (!base::i18n::InitializeICU()) return TerminateForFatalInitializationError(); #endif // BUILDFLAG(IS_ANDROID) && (ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE)
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc index eb448a10..94fff05c 100644 --- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -1868,7 +1868,7 @@ } // TODO(crbug.com/1307316): failing on Linux bots and flaky on Fuchsia bots. -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_FUCHSIA) +#if BUILDFLAG(IS_FUCHSIA) #define MAYBE_AccessibilityFigcaption DISABLED_AccessibilityFigcaption #else #define MAYBE_AccessibilityFigcaption AccessibilityFigcaption
diff --git a/content/browser/aggregation_service/aggregatable_report.cc b/content/browser/aggregation_service/aggregatable_report.cc index 40e45e0..ddad396 100644 --- a/content/browser/aggregation_service/aggregatable_report.cc +++ b/content/browser/aggregation_service/aggregatable_report.cc
@@ -27,6 +27,7 @@ #include "base/time/time.h" #include "base/values.h" #include "components/aggregation_service/aggregation_service.mojom.h" +#include "components/aggregation_service/parsing_utils.h" #include "components/cbor/values.h" #include "components/cbor/writer.h" #include "content/browser/aggregation_service/aggregation_service_features.h" @@ -701,10 +702,13 @@ AggregatableReport::AggregatableReport( std::vector<AggregationServicePayload> payloads, std::string shared_info, - absl::optional<uint64_t> debug_key) + absl::optional<uint64_t> debug_key, + ::aggregation_service::mojom::AggregationCoordinator + aggregation_coordinator) : payloads_(std::move(payloads)), shared_info_(std::move(shared_info)), - debug_key_(debug_key) {} + debug_key_(debug_key), + aggregation_coordinator_(aggregation_coordinator) {} AggregatableReport::AggregatableReport(const AggregatableReport& other) = default; @@ -796,9 +800,10 @@ std::move(debug_cleartext_payload)); } - return AggregatableReport(std::move(encrypted_payloads), - std::move(encoded_shared_info), - report_request.debug_key()); + return AggregatableReport( + std::move(encrypted_payloads), std::move(encoded_shared_info), + report_request.debug_key(), + report_request.payload_contents().aggregation_coordinator); } base::Value::Dict AggregatableReport::GetAsJson() const { @@ -830,6 +835,10 @@ value.Set("debug_key", base::NumberToString(debug_key_.value())); } + value.Set("aggregation_coordinator_identifier", + ::aggregation_service::SerializeAggregationCoordinator( + aggregation_coordinator_)); + return value; }
diff --git a/content/browser/aggregation_service/aggregatable_report.h b/content/browser/aggregation_service/aggregatable_report.h index d477f06..5d36d32 100644 --- a/content/browser/aggregation_service/aggregatable_report.h +++ b/content/browser/aggregation_service/aggregatable_report.h
@@ -61,8 +61,6 @@ std::vector<blink::mojom::AggregatableReportHistogramContribution> contributions; blink::mojom::AggregationServiceMode aggregation_mode; - - // Does not affect the unencrypted payload, but is used for encryption. ::aggregation_service::mojom::AggregationCoordinator aggregation_coordinator; }; @@ -189,7 +187,9 @@ AggregatableReport(std::vector<AggregationServicePayload> payloads, std::string shared_info, - absl::optional<uint64_t> debug_key); + absl::optional<uint64_t> debug_key, + ::aggregation_service::mojom::AggregationCoordinator + aggregation_coordinator); AggregatableReport(const AggregatableReport& other); AggregatableReport& operator=(const AggregatableReport& other); AggregatableReport(AggregatableReport&& other); @@ -201,6 +201,10 @@ } const std::string& shared_info() const { return shared_info_; } absl::optional<uint64_t> debug_key() const { return debug_key_; } + ::aggregation_service::mojom::AggregationCoordinator aggregation_coordinator() + const { + return aggregation_coordinator_; + } // Returns the JSON representation of this report of the form // { @@ -261,6 +265,8 @@ // Should only be set if the debug mode is enabled (but can still be empty). // Used as part of the temporary debugging mechanism. absl::optional<uint64_t> debug_key_; + + ::aggregation_service::mojom::AggregationCoordinator aggregation_coordinator_; }; // Represents a request for an AggregatableReport. Contains all the data
diff --git a/content/browser/aggregation_service/aggregatable_report_unittest.cc b/content/browser/aggregation_service/aggregatable_report_unittest.cc index 6728ccb..b3788d88 100644 --- a/content/browser/aggregation_service/aggregatable_report_unittest.cc +++ b/content/browser/aggregation_service/aggregatable_report_unittest.cc
@@ -35,6 +35,11 @@ namespace content { +namespace { + +using AggregationCoordinator = + ::aggregation_service::mojom::AggregationCoordinator; + testing::AssertionResult CborMapContainsKeyAndType( const cbor::Value::MapValue& map, const std::string& key, @@ -406,13 +411,15 @@ /*debug_cleartext_payload=*/absl::nullopt); AggregatableReport report(std::move(payloads), "example_shared_info", - /*debug_key=*/absl::nullopt); + /*debug_key=*/absl::nullopt, + AggregationCoordinator::kDefault); std::string report_json_string; base::JSONWriter::Write(base::Value(report.GetAsJson()), &report_json_string); const char kExpectedJsonString[] = R"({)" + R"("aggregation_coordinator_identifier":"aws-cloud",)" R"("aggregation_service_payloads":[)" R"({"key_id":"key_1","payload":"ABCD1234"})" R"(],)" @@ -431,13 +438,15 @@ /*debug_cleartext_payload=*/absl::nullopt); AggregatableReport report(std::move(payloads), "example_shared_info", - /*debug_key=*/absl::nullopt); + /*debug_key=*/absl::nullopt, + AggregationCoordinator::kDefault); std::string report_json_string; base::JSONWriter::Write(base::Value(report.GetAsJson()), &report_json_string); const char kExpectedJsonString[] = R"({)" + R"("aggregation_coordinator_identifier":"aws-cloud",)" R"("aggregation_service_payloads":[)" R"({"key_id":"key_1","payload":"ABCD1234"},)" R"({"key_id":"key_2","payload":"EFGH5678"})" @@ -454,19 +463,22 @@ /*debug_cleartext_payload=*/kEFGH5678AsBytes); AggregatableReport report(std::move(payloads), "example_shared_info", - /*debug_key=*/absl::nullopt); + /*debug_key=*/absl::nullopt, + AggregationCoordinator::kDefault); std::string report_json_string; base::JSONWriter::Write(base::Value(report.GetAsJson()), &report_json_string); - const char kExpectedJsonString[] = R"({)" - R"("aggregation_service_payloads":[{)" - R"("debug_cleartext_payload":"EFGH5678",)" - R"("key_id":"key_1",)" - R"("payload":"ABCD1234")" - R"(}],)" - R"("shared_info":"example_shared_info")" - R"(})"; + const char kExpectedJsonString[] = + R"({)" + R"("aggregation_coordinator_identifier":"aws-cloud",)" + R"("aggregation_service_payloads":[{)" + R"("debug_cleartext_payload":"EFGH5678",)" + R"("key_id":"key_1",)" + R"("payload":"ABCD1234")" + R"(}],)" + R"("shared_info":"example_shared_info")" + R"(})"; EXPECT_EQ(report_json_string, kExpectedJsonString); } @@ -477,20 +489,23 @@ /*debug_cleartext_payload=*/kEFGH5678AsBytes); AggregatableReport report(std::move(payloads), "example_shared_info", - /*debug_key=*/1234); + /*debug_key=*/1234, + AggregationCoordinator::kDefault); std::string report_json_string; base::JSONWriter::Write(base::Value(report.GetAsJson()), &report_json_string); - const char kExpectedJsonString[] = R"({)" - R"("aggregation_service_payloads":[{)" - R"("debug_cleartext_payload":"EFGH5678",)" - R"("key_id":"key_1",)" - R"("payload":"ABCD1234")" - R"(}],)" - R"("debug_key":"1234",)" - R"("shared_info":"example_shared_info")" - R"(})"; + const char kExpectedJsonString[] = + R"({)" + R"("aggregation_coordinator_identifier":"aws-cloud",)" + R"("aggregation_service_payloads":[{)" + R"("debug_cleartext_payload":"EFGH5678",)" + R"("key_id":"key_1",)" + R"("payload":"ABCD1234")" + R"(}],)" + R"("debug_key":"1234",)" + R"("shared_info":"example_shared_info")" + R"(})"; EXPECT_EQ(report_json_string, kExpectedJsonString); } @@ -641,14 +656,17 @@ TEST(AggregatableReportTest, EmptyPayloads) { AggregatableReport report(/*payloads=*/{}, "example_shared_info", - /*debug_key=*/absl::nullopt); + /*debug_key=*/absl::nullopt, + AggregationCoordinator::kDefault); std::string report_json_string; base::JSONWriter::Write(base::Value(report.GetAsJson()), &report_json_string); - const char kExpectedJsonString[] = R"({)" - R"("shared_info":"example_shared_info")" - R"(})"; + const char kExpectedJsonString[] = + R"({)" + R"("aggregation_coordinator_identifier":"aws-cloud",)" + R"("shared_info":"example_shared_info")" + R"(})"; EXPECT_EQ(report_json_string, kExpectedJsonString); } @@ -676,7 +694,7 @@ {blink::mojom::AggregatableReportHistogramContribution( /*bucket=*/123, /*value=*/456)}, blink::mojom::AggregationServiceMode::kDefault, - ::aggregation_service::mojom::AggregationCoordinator::kDefault), + AggregationCoordinator::kDefault), AggregatableReportSharedInfo( base::Time::FromJavaTime(1652984901234), base::GUID::ParseLowercase( @@ -719,7 +737,7 @@ {blink::mojom::AggregatableReportHistogramContribution( /*bucket=*/123, /*value=*/456)}, blink::mojom::AggregationServiceMode::kDefault, - ::aggregation_service::mojom::AggregationCoordinator::kDefault), + AggregationCoordinator::kDefault), AggregatableReportSharedInfo( base::Time::FromJavaTime(1652984901234), base::GUID::ParseLowercase( @@ -779,4 +797,5 @@ } } +} // namespace } // namespace content
diff --git a/content/browser/aggregation_service/aggregation_service_impl_unittest.cc b/content/browser/aggregation_service/aggregation_service_impl_unittest.cc index 1029c05..45f569e 100644 --- a/content/browser/aggregation_service/aggregation_service_impl_unittest.cc +++ b/content/browser/aggregation_service/aggregation_service_impl_unittest.cc
@@ -61,8 +61,10 @@ payloads.emplace_back(/*payload=*/kABCD1234AsBytes, /*key_id=*/"key_1", /*debug_cleartext_payload=*/absl::nullopt); - return AggregatableReport(std::move(payloads), "example_shared_info", - /*debug_key=*/absl::nullopt); + return AggregatableReport( + std::move(payloads), "example_shared_info", + /*debug_key=*/absl::nullopt, + ::aggregation_service::mojom::AggregationCoordinator::kDefault); } } // namespace
diff --git a/content/browser/aggregation_service/aggregation_service_internals_handler_impl.cc b/content/browser/aggregation_service/aggregation_service_internals_handler_impl.cc index f06f0ab..2ebab48 100644 --- a/content/browser/aggregation_service/aggregation_service_internals_handler_impl.cc +++ b/content/browser/aggregation_service/aggregation_service_internals_handler_impl.cc
@@ -56,7 +56,8 @@ } else { report_body = AggregatableReport( /*payloads=*/{}, request.shared_info().SerializeAsJson(), - request.debug_key()) + request.debug_key(), + request.payload_contents().aggregation_coordinator) .GetAsJson(); constexpr char kAggregationServicePayloadsKey[] =
diff --git a/content/browser/aggregation_service/aggregation_service_test_utils.cc b/content/browser/aggregation_service/aggregation_service_test_utils.cc index 3895dc2..39dbdd4 100644 --- a/content/browser/aggregation_service/aggregation_service_test_utils.cc +++ b/content/browser/aggregation_service/aggregation_service_test_utils.cc
@@ -273,7 +273,8 @@ } return AggregatableReport(std::move(payloads), report.shared_info(), - report.debug_key()); + report.debug_key(), + report.aggregation_coordinator()); } TestHpkeKey GenerateKey(std::string key_id) {
diff --git a/content/browser/android/synchronous_compositor_host.cc b/content/browser/android/synchronous_compositor_host.cc index a634959f..69219fb 100644 --- a/content/browser/android/synchronous_compositor_host.cc +++ b/content/browser/android/synchronous_compositor_host.cc
@@ -437,9 +437,9 @@ auto mark_bool = [](const void* pixels, void* context) { *static_cast<bool*>(context) = true; }; - image = SkImage::MakeFromRaster(pixmap, mark_bool, &pixels_released); + image = SkImages::RasterFromPixmap(pixmap, mark_bool, &pixels_released); } else { - image = SkImage::MakeRasterCopy(pixmap); + image = SkImages::RasterFromPixmapCopy(pixmap); } canvas->drawImage(image, 0, 0); canvas->restore();
diff --git a/content/browser/attribution_reporting/attribution_interop_runner.cc b/content/browser/attribution_reporting/attribution_interop_runner.cc index 66b841a3..74d13cb 100644 --- a/content/browser/attribution_reporting/attribution_interop_runner.cc +++ b/content/browser/attribution_reporting/attribution_interop_runner.cc
@@ -103,6 +103,9 @@ report_body.Remove("aggregation_service_payloads"); report_body.Remove("source_registration_time"); + // The aggregation coordinator may be platform specific. + report_body.Remove("aggregation_coordinator_identifier"); + base::Value::List list; for (const auto& contribution : aggregatable_data.contributions) { base::Value::Dict dict;
diff --git a/content/browser/attribution_reporting/attribution_manager_impl_unittest.cc b/content/browser/attribution_reporting/attribution_manager_impl_unittest.cc index 171d375..9205c76 100644 --- a/content/browser/attribution_reporting/attribution_manager_impl_unittest.cc +++ b/content/browser/attribution_reporting/attribution_manager_impl_unittest.cc
@@ -33,6 +33,7 @@ #include "base/values.h" #include "build/build_config.h" #include "build/buildflag.h" +#include "components/aggregation_service/aggregation_service.mojom.h" #include "components/attribution_reporting/suitable_origin.h" #include "content/browser/aggregation_service/aggregatable_report.h" #include "content/browser/aggregation_service/aggregation_service.h" @@ -160,8 +161,10 @@ /*api_version=*/"", /*api_identifier=*/"attribution-reporting"); - return AggregatableReport(std::move(payloads), shared_info.SerializeAsJson(), - /*debug_key=*/absl::nullopt); + return AggregatableReport( + std::move(payloads), shared_info.SerializeAsJson(), + /*debug_key=*/absl::nullopt, + ::aggregation_service::mojom::AggregationCoordinator::kDefault); } // Time after impression that a conversion can first be sent. See
diff --git a/content/browser/child_process_launcher_helper_android.cc b/content/browser/child_process_launcher_helper_android.cc index 64e05bfc..0a5bf246 100644 --- a/content/browser/child_process_launcher_helper_android.cc +++ b/content/browser/child_process_launcher_helper_android.cc
@@ -68,12 +68,6 @@ child_process_id(), mojo_channel_->remote_endpoint(), file_data_->files_to_preload, GetProcessType(), command_line()); -#if ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE - base::MemoryMappedFile::Region icu_region; - int fd = base::i18n::GetIcuDataFileHandle(&icu_region); - files_to_register->ShareWithRegion(kAndroidICUDataDescriptor, fd, icu_region); -#endif // ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE - return files_to_register; }
diff --git a/content/browser/child_process_security_policy_impl.cc b/content/browser/child_process_security_policy_impl.cc index 2cc2e8e..b8c8ab4 100644 --- a/content/browser/child_process_security_policy_impl.cc +++ b/content/browser/child_process_security_policy_impl.cc
@@ -1317,19 +1317,14 @@ } bool ChildProcessSecurityPolicyImpl::CanReadRequestBody( - SiteInstance* site_instance, + RenderProcessHost* process, const scoped_refptr<network::ResourceRequestBody>& body) { - DCHECK(site_instance); + CHECK(process); DCHECK_CURRENTLY_ON(BrowserThread::UI); - int child_id = site_instance->GetProcess()->GetID(); - - StoragePartition* storage_partition = - site_instance->GetBrowserContext()->GetStoragePartition(site_instance); - const storage::FileSystemContext* file_system_context = - storage_partition->GetFileSystemContext(); - - return CanReadRequestBody(child_id, file_system_context, body); + return CanReadRequestBody( + process->GetID(), process->GetStoragePartition()->GetFileSystemContext(), + body); } bool ChildProcessSecurityPolicyImpl::CanCreateReadWriteFile(
diff --git a/content/browser/child_process_security_policy_impl.h b/content/browser/child_process_security_policy_impl.h index 9709516..4bd4afd 100644 --- a/content/browser/child_process_security_policy_impl.h +++ b/content/browser/child_process_security_policy_impl.h
@@ -337,11 +337,10 @@ const storage::FileSystemContext* file_system_context, const scoped_refptr<network::ResourceRequestBody>& body); - // Validate that the renderer process for |site_instance| is allowed to access - // data in the POST body specified by |body|. Has to be called on the UI - // thread. + // Validate that `process` is allowed to access data in the POST body + // specified by |body|. Has to be called on the UI thread. bool CanReadRequestBody( - SiteInstance* site_instance, + RenderProcessHost* process, const scoped_refptr<network::ResourceRequestBody>& body); // Pseudo schemes are treated differently than other schemes because they
diff --git a/content/browser/pointer_lock_browsertest.cc b/content/browser/pointer_lock_browsertest.cc index 8710fdab..73a8bf1 100644 --- a/content/browser/pointer_lock_browsertest.cc +++ b/content/browser/pointer_lock_browsertest.cc
@@ -144,16 +144,6 @@ MockPointerLockWebContentsDelegate web_contents_delegate_; }; -class PointerLockBrowserTestWithOptions : public PointerLockBrowserTest { - public: - PointerLockBrowserTestWithOptions() { - feature_list_.InitAndEnableFeature(features::kPointerLockOptions); - } - - private: - base::test::ScopedFeatureList feature_list_; -}; - namespace { class PointerLockHelper { public: @@ -720,7 +710,7 @@ EXPECT_TRUE(ExecJs(shell(), "", EXECUTE_SCRIPT_NO_USER_GESTURE)); } -IN_PROC_BROWSER_TEST_F(PointerLockBrowserTestWithOptions, +IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockRequestUnadjustedMovement) { GURL main_url(embedded_test_server()->GetURL( "a.com", "/cross_site_iframe_factory.html?a(b)")); @@ -782,8 +772,7 @@ #if defined(USE_AURA) // Flaky on all platforms http://crbug.com/1198612. -IN_PROC_BROWSER_TEST_F(PointerLockBrowserTestWithOptions, - DISABLED_UnadjustedMovement) { +IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, DISABLED_UnadjustedMovement) { GURL main_url(embedded_test_server()->GetURL( "a.com", "/cross_site_iframe_factory.html?a(b)")); EXPECT_TRUE(NavigateToURL(shell(), main_url)); @@ -865,7 +854,7 @@ // options inside a Child view gets piped to the proper places and gives // the proper unsupported error(this option is only supported on Windows // This was prompted by this bug: https://crbug.com/1062702 -IN_PROC_BROWSER_TEST_F(PointerLockBrowserTestWithOptions, +IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, MAYBE_ChangeUnadjustedMovementFailure) { GURL main_url(embedded_test_server()->GetURL( "a.com", "/cross_site_iframe_factory.html?a(b)")); @@ -913,7 +902,7 @@ // options inside a Child view gets piped to the proper places and updates // the option(this option is only supported on Windows). // This was prompted by this bug: https://crbug.com/1062702 -IN_PROC_BROWSER_TEST_F(PointerLockBrowserTestWithOptions, +IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, ChangeUnadjustedMovementSuccess) { GURL main_url(embedded_test_server()->GetURL( "a.com", "/cross_site_iframe_factory.html?a(b)"));
diff --git a/content/browser/push_messaging/push_messaging_router.cc b/content/browser/push_messaging/push_messaging_router.cc index 59d7ac3..f0b4ccd4 100644 --- a/content/browser/push_messaging/push_messaging_router.cc +++ b/content/browser/push_messaging/push_messaging_router.cc
@@ -51,10 +51,6 @@ scoped_refptr<ServiceWorkerRegistration> service_worker_registration) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (event_type == ServiceWorkerMetrics::EventType::PUSH) { - UMA_HISTOGRAM_ENUMERATION("PushMessaging.DeliveryStatus.FindServiceWorker", - service_worker_status); - } if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) { std::move(callback).Run(nullptr /* service_worker_version */, nullptr /* devtools_context */, @@ -191,8 +187,6 @@ PushEventCallback deliver_message_callback, blink::ServiceWorkerStatusCode service_worker_status) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - UMA_HISTOGRAM_ENUMERATION("PushMessaging.DeliveryStatus.ServiceWorkerEvent", - service_worker_status); blink::mojom::PushEventStatus push_event_status = blink::mojom::PushEventStatus::SERVICE_WORKER_ERROR; std::string status_description;
diff --git a/content/browser/renderer_host/frame_tree.cc b/content/browser/renderer_host/frame_tree.cc index db819ce..7ba0435 100644 --- a/content/browser/renderer_host/frame_tree.cc +++ b/content/browser/renderer_host/frame_tree.cc
@@ -546,15 +546,15 @@ } } - // Check whether we're in an inner delegate and |site_instance| corresponds - // to the outer delegate. Subframe proxies aren't needed if this is the - // case. - bool is_site_instance_for_outer_delegate = false; + // Check whether we're in an inner delegate and the group |site_instance| is + // in corresponds to the outer delegate. Subframe proxies aren't needed if + // this is the case. + bool is_site_instance_group_for_outer_delegate = false; RenderFrameProxyHost* outer_delegate_proxy = root()->render_manager()->GetProxyToOuterDelegate(); if (outer_delegate_proxy) { - is_site_instance_for_outer_delegate = - (site_instance == outer_delegate_proxy->GetSiteInstance()); + is_site_instance_group_for_outer_delegate = + (site_instance->group() == outer_delegate_proxy->site_instance_group()); } // Proxies are created in the FrameTree in response to a node navigating to a @@ -592,11 +592,12 @@ } // Do not create proxies for subframes in the outer delegate's - // SiteInstance, since there is no need to expose these subframes to the - // outer delegate. See also comments in CreateProxiesForChildFrame() and - // https://crbug.com/1013553. - if (!node->IsMainFrame() && is_site_instance_for_outer_delegate) + // SiteInstanceGroup, since there is no need to expose these subframes to + // the outer delegate. See also comments in CreateProxiesForChildFrame() + // and https://crbug.com/1013553. + if (!node->IsMainFrame() && is_site_instance_group_for_outer_delegate) { continue; + } // If |node| is the FrameTreeNode being navigated, we use // |browsing_context_state| (as BrowsingContextState might change for
diff --git a/content/browser/renderer_host/ipc_utils.cc b/content/browser/renderer_host/ipc_utils.cc index aa8a0028..bc5b3e4 100644 --- a/content/browser/renderer_host/ipc_utils.cc +++ b/content/browser/renderer_host/ipc_utils.cc
@@ -124,17 +124,16 @@ } bool VerifyOpenURLParams(RenderFrameHostImpl* current_rfh, - SiteInstance* site_instance, + RenderProcessHost* process, const blink::mojom::OpenURLParamsPtr& params, GURL* out_validated_url, scoped_refptr<network::SharedURLLoaderFactory>* out_blob_url_loader_factory) { DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK(current_rfh); - DCHECK(site_instance); + DCHECK(process); DCHECK(out_validated_url); DCHECK(out_blob_url_loader_factory); - RenderProcessHost* process = site_instance->GetProcess(); int process_id = process->GetID(); // Verify |params.url| and populate |out_validated_url|. @@ -148,14 +147,12 @@ if (params->blob_url_token.is_valid()) { *out_blob_url_loader_factory = ChromeBlobStorageContext::URLLoaderFactoryForToken( - site_instance->GetBrowserContext()->GetStoragePartition( - site_instance), - std::move(params->blob_url_token)); + process->GetStoragePartition(), std::move(params->blob_url_token)); } // Verify |params.post_body|. auto* policy = ChildProcessSecurityPolicyImpl::GetInstance(); - if (!policy->CanReadRequestBody(site_instance, params->post_body)) { + if (!policy->CanReadRequestBody(process, params->post_body)) { bad_message::ReceivedBadMessage(process, bad_message::ILLEGAL_UPLOAD_PARAMS); return false; @@ -205,7 +202,7 @@ // Verify |post_data|. auto* policy = ChildProcessSecurityPolicyImpl::GetInstance(); - if (!policy->CanReadRequestBody(site_instance, common_params->post_data)) { + if (!policy->CanReadRequestBody(process, common_params->post_data)) { bad_message::ReceivedBadMessage(process, bad_message::ILLEGAL_UPLOAD_PARAMS); return false;
diff --git a/content/browser/renderer_host/ipc_utils.h b/content/browser/renderer_host/ipc_utils.h index a6021b1..3e742edd3 100644 --- a/content/browser/renderer_host/ipc_utils.h +++ b/content/browser/renderer_host/ipc_utils.h
@@ -29,19 +29,17 @@ bool VerifyDownloadUrlParams(SiteInstance* site_instance, const blink::mojom::DownloadURLParams& params); -// Verifies that |params| are valid and can be accessed by the renderer process -// associated with |site_instance|. |current_rfh| represents the current frame -// on which OpenURL is being called +// Verifies that |params| are valid and can be accessed by |process|. +// |current_rfh| represents the current frame on which OpenURL is being called // // Returns true if the |params| are valid. As a side-effect of the verification // |out_validated_url| and |out_blob_url_loader_factory| will be populated. // -// Terminates the renderer the process associated with |site_instance| and -// returns false if the |params| are invalid. +// Terminates |process| and returns false if the |params| are invalid. // // This function has to be called on the UI thread. bool VerifyOpenURLParams(RenderFrameHostImpl* current_rfh, - SiteInstance* site_instance, + RenderProcessHost* process, const blink::mojom::OpenURLParamsPtr& params, GURL* out_validated_url, scoped_refptr<network::SharedURLLoaderFactory>*
diff --git a/content/browser/renderer_host/media/media_stream_manager.cc b/content/browser/renderer_host/media/media_stream_manager.cc index f5a66a61..82f812a 100644 --- a/content/browser/renderer_host/media/media_stream_manager.cc +++ b/content/browser/renderer_host/media/media_stream_manager.cc
@@ -2602,7 +2602,7 @@ request->SetState(video_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); } - if (ShouldUseFakeUIProxy(request->video_type())) { + if (ShouldUseFakeUIProxy(*request)) { request->ui_proxy = MakeFakeUIProxy(label, enumeration, request); } else if (!request->ui_proxy) { request->ui_proxy = MediaStreamUIProxy::Create(); @@ -4479,17 +4479,17 @@ } bool MediaStreamManager::ShouldUseFakeUIProxy( - MediaStreamType stream_type) const { + const DeviceRequest& request) const { if (!fake_ui_factory_) { return false; } if (use_fake_ui_only_for_camera_and_microphone_) { - return stream_type == MediaStreamType::DEVICE_AUDIO_CAPTURE || - stream_type == MediaStreamType::DEVICE_VIDEO_CAPTURE; + return request.audio_type() == MediaStreamType::DEVICE_AUDIO_CAPTURE || + request.video_type() == MediaStreamType::DEVICE_VIDEO_CAPTURE; } - return stream_type != MediaStreamType::GUM_DESKTOP_VIDEO_CAPTURE || + return request.video_type() != MediaStreamType::GUM_DESKTOP_VIDEO_CAPTURE || use_fake_ui_for_gum_desktop_capture_; }
diff --git a/content/browser/renderer_host/media/media_stream_manager.h b/content/browser/renderer_host/media/media_stream_manager.h index 1816f7e..cb03bf5 100644 --- a/content/browser/renderer_host/media/media_stream_manager.h +++ b/content/browser/renderer_host/media/media_stream_manager.h
@@ -747,7 +747,7 @@ const blink::mojom::StreamDevicesSet& new_stream_devices_set, DeviceRequest& request); - bool ShouldUseFakeUIProxy(blink::mojom::MediaStreamType stream_type) const; + bool ShouldUseFakeUIProxy(const DeviceRequest& request) const; std::unique_ptr<MediaStreamUIProxy> MakeFakeUIProxy( const std::string& label,
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index 246c29c..e8d27c6 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -7430,7 +7430,7 @@ // Verify and unpack the Mojo payload. GURL validated_url; scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory; - if (!VerifyOpenURLParams(this, GetSiteInstance(), params, &validated_url, + if (!VerifyOpenURLParams(this, GetProcess(), params, &validated_url, &blob_url_loader_factory)) { return; }
diff --git a/content/browser/renderer_host/render_frame_proxy_host.cc b/content/browser/renderer_host/render_frame_proxy_host.cc index e0d7be45..3383cb0a 100644 --- a/content/browser/renderer_host/render_frame_proxy_host.cc +++ b/content/browser/renderer_host/render_frame_proxy_host.cc
@@ -673,8 +673,8 @@ scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory; RenderFrameHostImpl* current_rfh = frame_tree_node_->current_frame_host(); - if (!VerifyOpenURLParams(current_rfh, GetSiteInstance(), params, - &validated_url, &blob_url_loader_factory)) { + if (!VerifyOpenURLParams(current_rfh, GetProcess(), params, &validated_url, + &blob_url_loader_factory)) { return; }
diff --git a/content/browser/tracing/background_tracing_active_scenario.cc b/content/browser/tracing/background_tracing_active_scenario.cc index b5a6657..8bc04c4 100644 --- a/content/browser/tracing/background_tracing_active_scenario.cc +++ b/content/browser/tracing/background_tracing_active_scenario.cc
@@ -467,18 +467,6 @@ return true; } -base::Value::Dict BackgroundTracingActiveScenario::GenerateMetadataDict() { - base::Value::Dict metadata_dict; - metadata_dict.Set("config", config_->ToDict()); - metadata_dict.Set("scenario_name", config_->scenario_name()); - - if (last_triggered_rule_) { - metadata_dict.Set("last_triggered_rule", last_triggered_rule_->ToDict()); - } - - return metadata_dict; -} - void BackgroundTracingActiveScenario::GenerateMetadataProto( perfetto::protos::pbzero::ChromeMetadataPacket* metadata) { if (!last_triggered_rule_) {
diff --git a/content/browser/tracing/background_tracing_active_scenario.h b/content/browser/tracing/background_tracing_active_scenario.h index be11758..6659ef6 100644 --- a/content/browser/tracing/background_tracing_active_scenario.h +++ b/content/browser/tracing/background_tracing_active_scenario.h
@@ -42,7 +42,6 @@ void AbortScenario(); CONTENT_EXPORT const BackgroundTracingConfigImpl* GetConfig() const; - base::Value::Dict GenerateMetadataDict(); void GenerateMetadataProto( perfetto::protos::pbzero::ChromeMetadataPacket* metadata); State state() const { return scenario_state_; }
diff --git a/content/browser/tracing/background_tracing_manager_impl.cc b/content/browser/tracing/background_tracing_manager_impl.cc index ff94579..e89747c 100644 --- a/content/browser/tracing/background_tracing_manager_impl.cc +++ b/content/browser/tracing/background_tracing_manager_impl.cc
@@ -96,9 +96,6 @@ void BackgroundTracingManagerImpl::AddMetadataGeneratorFunction() { auto* metadata_source = tracing::TraceEventMetadataSource::GetInstance(); metadata_source->AddGeneratorFunction( - base::BindRepeating(&BackgroundTracingManagerImpl::GenerateMetadataDict, - base::Unretained(this))); - metadata_source->AddGeneratorFunction( base::BindRepeating(&BackgroundTracingManagerImpl::GenerateMetadataProto, base::Unretained(this))); } @@ -382,14 +379,6 @@ is_crash_scenario)); } -absl::optional<base::Value::Dict> -BackgroundTracingManagerImpl::GenerateMetadataDict() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (!active_scenario_) - return absl::nullopt; - return active_scenario_->GenerateMetadataDict(); -} - void BackgroundTracingManagerImpl::GenerateMetadataProto( perfetto::protos::pbzero::ChromeMetadataPacket* metadata, bool privacy_filtering_enabled) {
diff --git a/content/browser/tracing/background_tracing_manager_impl.h b/content/browser/tracing/background_tracing_manager_impl.h index 6bb8cfc..2a6eb07 100644 --- a/content/browser/tracing/background_tracing_manager_impl.h +++ b/content/browser/tracing/background_tracing_manager_impl.h
@@ -20,10 +20,6 @@ #include "services/tracing/public/mojom/background_tracing_agent.mojom.h" #include "third_party/abseil-cpp/absl/types/optional.h" -namespace base { -class Value; -} // namespace base - namespace tracing::mojom { class BackgroundTracingAgent; class BackgroundTracingAgentProvider; @@ -137,7 +133,6 @@ BackgroundTracingManagerImpl(); ~BackgroundTracingManagerImpl() override; - absl::optional<base::Value::Dict> GenerateMetadataDict(); void GenerateMetadataProto( perfetto::protos::pbzero::ChromeMetadataPacket* metadata, bool privacy_filtering_enabled);
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index 614d25b..881a680 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -270,7 +270,6 @@ raw_ref(features::kWindowsScrollingPersonality)}, {wf::EnablePeriodicBackgroundSync, raw_ref(features::kPeriodicBackgroundSync)}, - {wf::EnablePointerLockOptions, raw_ref(features::kPointerLockOptions)}, {wf::EnablePushMessagingSubscriptionChange, raw_ref(features::kPushSubscriptionChangeEvent)}, {wf::EnableRestrictGamepadAccess,
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/input/OngoingGestureTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/OngoingGestureTest.java index 5763036..99f2e04 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/input/OngoingGestureTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/input/OngoingGestureTest.java
@@ -8,16 +8,13 @@ import androidx.test.filters.SmallTest; -import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; -import org.chromium.base.test.metrics.HistogramTestRule; import org.chromium.base.test.util.Batch; +import org.chromium.base.test.util.HistogramWatcher; import org.chromium.blink.mojom.HandwritingGestureResult; import org.chromium.content_public.browser.test.ContentJUnit4ClassRunner; -import org.chromium.content_public.browser.test.NativeLibraryTestUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils; /** @@ -30,15 +27,6 @@ private static final String GESTURE_RESULT_HISTOGRAM = "InputMethod.StylusHandwriting.GestureResult"; - @Rule - public HistogramTestRule mHistogramTester = new HistogramTestRule(); - - @BeforeClass - public static void setUpClass() { - // Needed for HistogramTestRule. - NativeLibraryTestUtils.loadNativeLibraryNoBrowserProcess(); - } - @Test @SmallTest public void testGestureRequestsHaveIncreasingIDs() { @@ -55,12 +43,12 @@ @SmallTest public void testGestureRequestLogsUnknownWithNullExecutor() { TestThreadUtils.runOnUiThreadBlocking(() -> { + var histogram = HistogramWatcher.newSingleRecordWatcher( + GESTURE_RESULT_HISTOGRAM, HandwritingGestureResult.UNKNOWN); OngoingGesture request = new OngoingGesture( new org.chromium.blink.mojom.StylusWritingGestureData(), null, (value) -> {}); request.onGestureHandled(HandwritingGestureResult.SUCCESS); - assertEquals(1, - mHistogramTester.getHistogramValueCount( - GESTURE_RESULT_HISTOGRAM, HandwritingGestureResult.UNKNOWN)); + histogram.assertExpected(); }); } @@ -68,12 +56,12 @@ @SmallTest public void testGestureRequestLogsUnknownWithNullIntConsumer() { TestThreadUtils.runOnUiThreadBlocking(() -> { + var histogram = HistogramWatcher.newSingleRecordWatcher( + GESTURE_RESULT_HISTOGRAM, HandwritingGestureResult.UNKNOWN); OngoingGesture request = new OngoingGesture( new org.chromium.blink.mojom.StylusWritingGestureData(), (command) -> {}, null); request.onGestureHandled(HandwritingGestureResult.FAILED); - assertEquals(1, - mHistogramTester.getHistogramValueCount( - GESTURE_RESULT_HISTOGRAM, HandwritingGestureResult.UNKNOWN)); + histogram.assertExpected(); }); } @@ -84,20 +72,21 @@ OngoingGesture request = new OngoingGesture(new org.chromium.blink.mojom.StylusWritingGestureData(), (command) -> {}, (value) -> {}); + + var histogram = HistogramWatcher.newSingleRecordWatcher( + GESTURE_RESULT_HISTOGRAM, HandwritingGestureResult.SUCCESS); request.onGestureHandled(HandwritingGestureResult.SUCCESS); - assertEquals(1, - mHistogramTester.getHistogramValueCount( - GESTURE_RESULT_HISTOGRAM, HandwritingGestureResult.SUCCESS)); + histogram.assertExpected(); + histogram = HistogramWatcher.newSingleRecordWatcher( + GESTURE_RESULT_HISTOGRAM, HandwritingGestureResult.FAILED); request.onGestureHandled(HandwritingGestureResult.FAILED); - assertEquals(1, - mHistogramTester.getHistogramValueCount( - GESTURE_RESULT_HISTOGRAM, HandwritingGestureResult.FAILED)); + histogram.assertExpected(); + histogram = HistogramWatcher.newSingleRecordWatcher( + GESTURE_RESULT_HISTOGRAM, HandwritingGestureResult.FALLBACK); request.onGestureHandled(HandwritingGestureResult.FALLBACK); - assertEquals(1, - mHistogramTester.getHistogramValueCount( - GESTURE_RESULT_HISTOGRAM, HandwritingGestureResult.FALLBACK)); + histogram.assertExpected(); }); } }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/input/StylusGestureHandlerTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/StylusGestureHandlerTest.java index a1530069..7d27c970 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/input/StylusGestureHandlerTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/input/StylusGestureHandlerTest.java
@@ -12,24 +12,21 @@ import android.graphics.RectF; import android.view.inputmethod.InputConnection; -import androidx.core.os.BuildCompat; import androidx.test.filters.MediumTest; -import org.junit.Assume; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; -import org.chromium.base.test.metrics.HistogramTestRule; import org.chromium.base.test.util.Batch; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.CriteriaHelper; +import org.chromium.base.test.util.HistogramWatcher; +import org.chromium.base.test.util.MinAndroidSdkLevel; import org.chromium.blink.mojom.StylusWritingGestureAction; import org.chromium.blink.mojom.StylusWritingGestureData; import org.chromium.content_public.browser.test.ContentJUnit4ClassRunner; -import org.chromium.content_public.browser.test.NativeLibraryTestUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.gfx.mojom.Rect; @@ -45,13 +42,11 @@ @RunWith(ContentJUnit4ClassRunner.class) @Batch(Batch.PER_CLASS) @CommandLineFlags.Add({"enable-features=StylusRichGestures"}) +@MinAndroidSdkLevel(34) public class StylusGestureHandlerTest { @Rule public ImeActivityTestRule mRule = new ImeActivityTestRule(); - @Rule - public HistogramTestRule mHistogramTester = new HistogramTestRule(); - private static final String TARGET_PACKAGE = "android.view.inputmethod."; private static final String FALLBACK_TEXT = "this gesture failed"; private static final String GESTURE_TYPE_HISTOGRAM = "InputMethod.StylusHandwriting.Gesture"; @@ -59,15 +54,8 @@ private InputConnection mWrappedInputConnection; private StylusWritingGestureData mLastGestureData; - @BeforeClass - public static void setUpClass() { - // Needed for HistogramTestRule. - NativeLibraryTestUtils.loadNativeLibraryNoBrowserProcess(); - } - @Before public void setUp() throws Exception { - Assume.assumeTrue("Skipping U+ test on older OS version", BuildCompat.isAtLeastU()); mRule.setUpForUrl(ImeActivityTestRule.INPUT_FORM_HTML); mWrappedInputConnection = StylusGestureHandler.maybeProxyInputConnection(mRule.getInputConnection(), @@ -85,6 +73,8 @@ public void testSelectGesture() throws ClassNotFoundException, InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException { + var histogram = HistogramWatcher.newSingleRecordWatcher( + GESTURE_TYPE_HISTOGRAM, StylusGestureHandler.UmaGestureType.SELECT); Class builderClass = getBuilderForClass(Class.forName(TARGET_PACKAGE + "SelectGesture")); Map<String, Method> builderMethods = getMethodsForClass(builderClass); Object builder = builderClass.newInstance(); @@ -114,9 +104,7 @@ assertMojoRectsAreEqual(createMojoRect(10, 5, 0, 0), mLastGestureData.endRect); assertEquals(FALLBACK_TEXT, toJavaString(mLastGestureData.textAlternative)); assertNull(mLastGestureData.textToInsert); - assertEquals(1, - mHistogramTester.getHistogramValueCount( - GESTURE_TYPE_HISTOGRAM, StylusGestureHandler.UmaGestureType.SELECT)); + histogram.assertExpected(); } @Test @@ -124,6 +112,8 @@ public void testInsertGesture() throws ClassNotFoundException, InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException { + var histogram = HistogramWatcher.newSingleRecordWatcher( + GESTURE_TYPE_HISTOGRAM, StylusGestureHandler.UmaGestureType.INSERT); Class builderClass = getBuilderForClass(Class.forName(TARGET_PACKAGE + "InsertGesture")); Map<String, Method> builderMethods = getMethodsForClass(builderClass); Object builder = builderClass.newInstance(); @@ -152,9 +142,7 @@ assertNull(mLastGestureData.endRect); assertEquals(FALLBACK_TEXT, toJavaString(mLastGestureData.textAlternative)); assertEquals("Foo", toJavaString(mLastGestureData.textToInsert)); - assertEquals(1, - mHistogramTester.getHistogramValueCount( - GESTURE_TYPE_HISTOGRAM, StylusGestureHandler.UmaGestureType.INSERT)); + histogram.assertExpected(); } @Test @@ -162,6 +150,8 @@ public void testDeleteGesture() throws ClassNotFoundException, InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException { + var histogram = HistogramWatcher.newSingleRecordWatcher( + GESTURE_TYPE_HISTOGRAM, StylusGestureHandler.UmaGestureType.DELETE); Class builderClass = getBuilderForClass(Class.forName(TARGET_PACKAGE + "DeleteGesture")); Map<String, Method> builderMethods = getMethodsForClass(builderClass); Object builder = builderClass.newInstance(); @@ -190,9 +180,7 @@ assertMojoRectsAreEqual(createMojoRect(10, 5, 0, 0), mLastGestureData.endRect); assertEquals(FALLBACK_TEXT, toJavaString(mLastGestureData.textAlternative)); assertNull(mLastGestureData.textToInsert); - assertEquals(1, - mHistogramTester.getHistogramValueCount( - GESTURE_TYPE_HISTOGRAM, StylusGestureHandler.UmaGestureType.DELETE)); + histogram.assertExpected(); } @Test @@ -200,6 +188,8 @@ public void testRemoveSpaceGesture() throws ClassNotFoundException, InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException { + var histogram = HistogramWatcher.newSingleRecordWatcher( + GESTURE_TYPE_HISTOGRAM, StylusGestureHandler.UmaGestureType.REMOVE_SPACE); Class builderClass = getBuilderForClass(Class.forName(TARGET_PACKAGE + "RemoveSpaceGesture")); Map<String, Method> builderMethods = getMethodsForClass(builderClass); @@ -228,9 +218,7 @@ assertMojoRectsAreEqual(createMojoRect(105, 30, 0, 0), mLastGestureData.endRect); assertEquals(FALLBACK_TEXT, toJavaString(mLastGestureData.textAlternative)); assertNull(mLastGestureData.textToInsert); - assertEquals(1, - mHistogramTester.getHistogramValueCount( - GESTURE_TYPE_HISTOGRAM, StylusGestureHandler.UmaGestureType.REMOVE_SPACE)); + histogram.assertExpected(); } @Test @@ -238,6 +226,8 @@ public void testJoinOrSplitGesture() throws ClassNotFoundException, InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException { + var histogram = HistogramWatcher.newSingleRecordWatcher( + GESTURE_TYPE_HISTOGRAM, StylusGestureHandler.UmaGestureType.JOIN_OR_SPLIT); Class builderClass = getBuilderForClass(Class.forName(TARGET_PACKAGE + "JoinOrSplitGesture")); Map<String, Method> builderMethods = getMethodsForClass(builderClass); @@ -266,9 +256,7 @@ assertNull(mLastGestureData.endRect); assertEquals(FALLBACK_TEXT, toJavaString(mLastGestureData.textAlternative)); assertNull(mLastGestureData.textToInsert); - assertEquals(1, - mHistogramTester.getHistogramValueCount( - GESTURE_TYPE_HISTOGRAM, StylusGestureHandler.UmaGestureType.JOIN_OR_SPLIT)); + histogram.assertExpected(); } @Test @@ -276,6 +264,8 @@ public void testSelectRangeGesture() throws ClassNotFoundException, InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException { + var histogram = HistogramWatcher.newSingleRecordWatcher( + GESTURE_TYPE_HISTOGRAM, StylusGestureHandler.UmaGestureType.SELECT_RANGE); Class builderClass = getBuilderForClass(Class.forName(TARGET_PACKAGE + "SelectRangeGesture")); Map<String, Method> builderMethods = getMethodsForClass(builderClass); @@ -306,9 +296,7 @@ assertMojoRectsAreEqual(createMojoRect(0, 100, 70, 100), mLastGestureData.endRect); assertEquals(FALLBACK_TEXT, toJavaString(mLastGestureData.textAlternative)); assertNull(mLastGestureData.textToInsert); - assertEquals(1, - mHistogramTester.getHistogramValueCount( - GESTURE_TYPE_HISTOGRAM, StylusGestureHandler.UmaGestureType.SELECT_RANGE)); + histogram.assertExpected(); } @Test @@ -316,6 +304,8 @@ public void testDeleteRangeGesture() throws ClassNotFoundException, InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException { + var histogram = HistogramWatcher.newSingleRecordWatcher( + GESTURE_TYPE_HISTOGRAM, StylusGestureHandler.UmaGestureType.DELETE_RANGE); Class builderClass = getBuilderForClass(Class.forName(TARGET_PACKAGE + "DeleteRangeGesture")); Map<String, Method> builderMethods = getMethodsForClass(builderClass); @@ -347,9 +337,7 @@ assertMojoRectsAreEqual(createMojoRect(0, 100, 70, 100), mLastGestureData.endRect); assertEquals(FALLBACK_TEXT, toJavaString(mLastGestureData.textAlternative)); assertNull(mLastGestureData.textToInsert); - assertEquals(1, - mHistogramTester.getHistogramValueCount( - GESTURE_TYPE_HISTOGRAM, StylusGestureHandler.UmaGestureType.DELETE_RANGE)); + histogram.assertExpected(); } private static Map<String, Method> getMethodsForClass(Class<?> className) {
diff --git a/content/public/common/content_descriptors.h b/content/public/common/content_descriptors.h index 9a3d192..4ecb004 100644 --- a/content/public/common/content_descriptors.h +++ b/content/public/common/content_descriptors.h
@@ -17,7 +17,6 @@ #if BUILDFLAG(IS_ANDROID) kAndroidPropertyDescriptor, - kAndroidICUDataDescriptor, #endif // Reserves 100 to 199 for dynamically generated IDs.
diff --git a/content/public/test/network_connection_change_simulator.cc b/content/public/test/network_connection_change_simulator.cc index b3b40b0b..192a22d 100644 --- a/content/public/test/network_connection_change_simulator.cc +++ b/content/public/test/network_connection_change_simulator.cc
@@ -17,7 +17,7 @@ #include "services/network/public/mojom/network_service_test.mojom.h" #if BUILDFLAG(IS_CHROMEOS) -#include "net/base/network_change_notifier_posix.h" +#include "net/base/network_change_notifier_passive.h" #endif namespace content { @@ -39,8 +39,8 @@ // Manually set the connection type since ChromeOS's NetworkChangeNotifier // implementation relies on some other class controlling it (normally // NetworkChangeManagerClient), which isn't used on content/. - net::NetworkChangeNotifierPosix* network_change_notifier = - static_cast<net::NetworkChangeNotifierPosix*>( + net::NetworkChangeNotifierPassive* network_change_notifier = + static_cast<net::NetworkChangeNotifierPassive*>( content::GetNetworkChangeNotifier()); network_change_notifier->OnConnectionChanged( net::NetworkChangeNotifier::CONNECTION_ETHERNET);
diff --git a/content/public/test/test_utils.cc b/content/public/test/test_utils.cc index 27fc26c6..f4d29b1 100644 --- a/content/public/test/test_utils.cc +++ b/content/public/test/test_utils.cc
@@ -29,6 +29,7 @@ #include "content/browser/site_info.h" #include "content/browser/site_instance_impl.h" #include "content/common/content_navigation_policy.h" +#include "content/common/features.h" #include "content/public/browser/browser_child_process_host_iterator.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -241,6 +242,10 @@ CanSameSiteMainFrameNavigationsChangeSiteInstances(); } +bool WillSameSiteNavigationsChangeRenderFrameHosts() { + return ShouldCreateNewHostForAllFrames(); +} + bool CanSameSiteMainFrameNavigationsChangeSiteInstances() { return IsProactivelySwapBrowsingInstanceOnSameSiteNavigationEnabled() || IsBackForwardCacheEnabled();
diff --git a/content/public/test/test_utils.h b/content/public/test/test_utils.h index 930d30d..a2fa59f 100644 --- a/content/public/test/test_utils.h +++ b/content/public/test/test_utils.h
@@ -120,9 +120,20 @@ // Whether same-site navigations might result in a change of RenderFrameHosts - // this will happen when ProactivelySwapBrowsingInstance, RenderDocument or -// back-forward cache is enabled on same-site main frame navigations. +// back-forward cache is enabled on same-site main frame navigations. Note that +// not even if this returns true, not all same-site main frame navigations will +// result in a change of RenderFrameHosts, e.g. if RenderDocument is disabled +// but BFCache is enabled, this will return true but only same-site navigations +// from pages that are BFCache-eligible will result in a RenderFrameHost change. bool CanSameSiteMainFrameNavigationsChangeRenderFrameHosts(); +// Whether same-site navigations will always result in a change of +// RenderFrameHosts, which will happen when RenderDocument is enabled. Different +// from `CanSameSiteMainFrameNavigationsChangeRenderFrameHosts()`, this means +// all same-site navigations will trigger a RenderFrameHost change, instead of +// only a subset that satisfies some conditions, e.g. BFCache eligibilty. +bool WillSameSiteNavigationsChangeRenderFrameHosts(); + // Whether same-site navigations might result in a change of SiteInstances - // this will happen when ProactivelySwapBrowsingInstance or back-forward cache // is enabled on same-site main frame navigations.
diff --git a/content/renderer/pepper/pepper_graphics_2d_host.cc b/content/renderer/pepper/pepper_graphics_2d_host.cc index d74f5aec..2c6a701d1 100644 --- a/content/renderer/pepper/pepper_graphics_2d_host.cc +++ b/content/renderer/pepper/pepper_graphics_2d_host.cc
@@ -745,8 +745,8 @@ if (!shared_bitmap) { viz::SharedBitmapId id = viz::SharedBitmap::GenerateId(); base::MappedReadOnlyRegion shm = - viz::bitmap_allocation::AllocateSharedBitmap(pixel_image_size, - viz::RGBA_8888); + viz::bitmap_allocation::AllocateSharedBitmap( + pixel_image_size, viz::SinglePlaneFormat::kRGBA_8888); shared_bitmap = base::MakeRefCounted<cc::CrossThreadSharedBitmap>( id, std::move(shm), pixel_image_size, viz::SinglePlaneFormat::kRGBA_8888);
diff --git a/content/test/data/accessibility/html/figcaption-expected-android-external.txt b/content/test/data/accessibility/html/figcaption-expected-android-external.txt index f5f1a87..92904c3 100644 --- a/content/test/data/accessibility/html/figcaption-expected-android-external.txt +++ b/content/test/data/accessibility/html/figcaption-expected-android-external.txt
@@ -1,4 +1,7 @@ WebView focusable focused scrollable actions:[CLEAR_FOCUS, AX_FOCUS] bundle:[chromeRole="rootWebArea", hasImage="true"] ++View actions:[AX_FOCUS] bundle:[chromeRole="figure", hasImage="true", roleDescription="graphic"] ++++Image text:"This is a green box." actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="image", hasImage="true", roleDescription="graphic", targetUrl="file:///storage/emulated/0/chromium_tests_root/content/test/data/accessibility/html/greenbox.png"] -++++View text:"Fig.1 - A green Box" actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="figcaption"] \ No newline at end of file +++++View text:"Fig.1 - A green Box" actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="figcaption"] +++View actions:[AX_FOCUS] bundle:[chromeRole="figure", hasImage="true", roleDescription="graphic"] +++++Image text:"This is a blue box." actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="image", hasImage="true", roleDescription="graphic", targetUrl="file:///storage/emulated/0/chromium_tests_root/content/test/data/accessibility/html/greenbox.png"] +++++View text:"Fig.2 - A blue Box" actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="figcaption"]
diff --git a/content/test/data/accessibility/html/figcaption-expected-android.txt b/content/test/data/accessibility/html/figcaption-expected-android.txt index d0bd255..5a967f64 100644 --- a/content/test/data/accessibility/html/figcaption-expected-android.txt +++ b/content/test/data/accessibility/html/figcaption-expected-android.txt
@@ -1,4 +1,7 @@ android.webkit.WebView focusable focused scrollable ++android.view.View role_description='graphic' ++++android.widget.Image role_description='graphic' name='This is a green box.' -++++android.view.View name='Fig.1 - A green Box' \ No newline at end of file +++++android.view.View name='Fig.1 - A green Box' +++android.view.View role_description='graphic' +++++android.widget.Image role_description='graphic' name='This is a blue box.' +++++android.view.View name='Fig.2 - A blue Box'
diff --git a/content/test/data/accessibility/html/figcaption-expected-auralinux.txt b/content/test/data/accessibility/html/figcaption-expected-auralinux.txt index 04268c5c..c40b2c1f 100644 --- a/content/test/data/accessibility/html/figcaption-expected-auralinux.txt +++ b/content/test/data/accessibility/html/figcaption-expected-auralinux.txt
@@ -3,3 +3,7 @@ ++++[image] name='This is a green box.' ++++[caption] details-for ++++++[static] name='Fig.1 - A green Box' +++[panel] +++++[image] name='This is a blue box.' +++++[caption] +++++++[static] name='Fig.2 - A blue Box' \ No newline at end of file
diff --git a/content/test/data/accessibility/html/figcaption-expected-blink.txt b/content/test/data/accessibility/html/figcaption-expected-blink.txt index 0b0efd7..20dab35a 100644 --- a/content/test/data/accessibility/html/figcaption-expected-blink.txt +++ b/content/test/data/accessibility/html/figcaption-expected-blink.txt
@@ -6,3 +6,8 @@ ++++++++figcaption ++++++++++staticText name='Fig.1 - A green Box' ++++++++++++inlineTextBox name='Fig.1 - A green Box' +++++++figure +++++++++image name='This is a blue box.' +++++++++figcaption +++++++++++staticText name='Fig.2 - A blue Box' +++++++++++++inlineTextBox name='Fig.2 - A blue Box'
diff --git a/content/test/data/accessibility/html/figcaption-expected-mac.txt b/content/test/data/accessibility/html/figcaption-expected-mac.txt index cd791c8e..7484417 100644 --- a/content/test/data/accessibility/html/figcaption-expected-mac.txt +++ b/content/test/data/accessibility/html/figcaption-expected-mac.txt
@@ -3,3 +3,7 @@ ++++AXImage AXDescription='This is a green box.' ++++AXGroup ++++++AXStaticText AXValue='Fig.1 - A green Box' +++AXGroup +++++AXImage AXDescription='This is a blue box.' +++++AXGroup +++++++AXStaticText AXValue='Fig.2 - A blue Box' \ No newline at end of file
diff --git a/content/test/data/accessibility/html/figcaption-expected-uia-win.txt b/content/test/data/accessibility/html/figcaption-expected-uia-win.txt index 4db01e2..b496700 100644 --- a/content/test/data/accessibility/html/figcaption-expected-uia-win.txt +++ b/content/test/data/accessibility/html/figcaption-expected-uia-win.txt
@@ -3,3 +3,7 @@ ++++Image Name='This is a green box.' ++++Text IsControlElement=false ++++++Text Name='Fig.1 - A green Box' +++Group +++++Image Name='This is a blue box.' +++++Text IsControlElement=false +++++++Text Name='Fig.2 - A blue Box' \ No newline at end of file
diff --git a/content/test/data/accessibility/html/figcaption-expected-win.txt b/content/test/data/accessibility/html/figcaption-expected-win.txt index d1c4dbfe..fed71f5 100644 --- a/content/test/data/accessibility/html/figcaption-expected-win.txt +++ b/content/test/data/accessibility/html/figcaption-expected-win.txt
@@ -3,3 +3,7 @@ ++++ROLE_SYSTEM_GRAPHIC name='This is a green box.' READONLY ++++IA2_ROLE_CAPTION ++++++ROLE_SYSTEM_STATICTEXT name='Fig.1 - A green Box' +++ROLE_SYSTEM_GROUPING +++++ROLE_SYSTEM_GRAPHIC name='This is a blue box.' READONLY +++++IA2_ROLE_CAPTION +++++++ROLE_SYSTEM_STATICTEXT name='Fig.2 - A blue Box' \ No newline at end of file
diff --git a/content/test/data/accessibility/html/figcaption.html b/content/test/data/accessibility/html/figcaption.html index 5de4ed8..ccbcab7d 100644 --- a/content/test/data/accessibility/html/figcaption.html +++ b/content/test/data/accessibility/html/figcaption.html
@@ -8,5 +8,11 @@ <img src="greenbox.png" alt="This is a green box."> <figcaption>Fig.1 - A green Box</figcaption> </figure> + +<!-- aria-details="" prevents automatic computation of details relation --> +<figure aria-details=""> + <img src="greenbox.png" alt="This is a blue box."> + <figcaption>Fig.2 - A blue Box</figcaption> +</figure> </body> </html>
diff --git a/content/test/data/accessibility/html/popover-api-expected-auralinux.txt b/content/test/data/accessibility/html/popover-api-expected-auralinux.txt index 75e6c5d2..24d16dc 100644 --- a/content/test/data/accessibility/html/popover-api-expected-auralinux.txt +++ b/content/test/data/accessibility/html/popover-api-expected-auralinux.txt
@@ -16,6 +16,7 @@ ++[paragraph] ++++[static] name='Showing/visible popovers below' ++[push button] name='Button pointing to showing popover' expanded details details-roles:popover +++[push button] name='w/o details' expanded ++[entry] selectable-text ++[static] name='Tel input pointing to showing popover ' ++[push button] name='Show button pointing to nested popover' expanded details details-roles:popover @@ -30,4 +31,4 @@ ++[static] name='Url input pointing to showing manual ' ++[push button] name='Hide button pointing to showing manual (should NOT add aria-details)' ++[panel] details-for -++++[static] name='Manual (showing)' +++++[static] name='Manual (showing)' \ No newline at end of file
diff --git a/content/test/data/accessibility/html/popover-api-expected-blink.txt b/content/test/data/accessibility/html/popover-api-expected-blink.txt index 02f00d643..5c7d03c 100644 --- a/content/test/data/accessibility/html/popover-api-expected-blink.txt +++ b/content/test/data/accessibility/html/popover-api-expected-blink.txt
@@ -56,6 +56,9 @@ ++++++button expanded name='Button pointing to showing popover' detailsIds=group ++++++++staticText name='Button pointing to showing popover' ++++++++++inlineTextBox name='Button pointing to showing popover' +++++++button expanded name='w/o details' +++++++++staticText name='w/o details' +++++++++++inlineTextBox name='w/o details' ++++++textField ++++++++genericContainer ++++++staticText name='Tel input pointing to showing popover '
diff --git a/content/test/data/accessibility/html/popover-api-expected-mac.txt b/content/test/data/accessibility/html/popover-api-expected-mac.txt index 6ae8ecb2..ba10740c 100644 --- a/content/test/data/accessibility/html/popover-api-expected-mac.txt +++ b/content/test/data/accessibility/html/popover-api-expected-mac.txt
@@ -16,6 +16,7 @@ ++AXGroup ++++AXStaticText AXValue='Showing/visible popovers below' ++AXButton AXExpanded=1 AXTitle='Button pointing to showing popover' +++AXButton AXExpanded=1 AXTitle='w/o details' ++AXTextField ++AXStaticText AXValue='Tel input pointing to showing popover ' ++AXButton AXExpanded=1 AXTitle='Show button pointing to nested popover' @@ -30,4 +31,4 @@ ++AXStaticText AXValue='Url input pointing to showing manual ' ++AXButton AXTitle='Hide button pointing to showing manual (should NOT add aria-details)' ++AXGroup AXSubrole=AXApplicationGroup -++++AXStaticText AXValue='Manual (showing)' +++++AXStaticText AXValue='Manual (showing)' \ No newline at end of file
diff --git a/content/test/data/accessibility/html/popover-api-expected-uia-win.txt b/content/test/data/accessibility/html/popover-api-expected-uia-win.txt index bcef3e7..fbf1378 100644 --- a/content/test/data/accessibility/html/popover-api-expected-uia-win.txt +++ b/content/test/data/accessibility/html/popover-api-expected-uia-win.txt
@@ -16,6 +16,7 @@ ++Group IsControlElement=false ++++Text Name='Showing/visible popovers below' ++Button Name='Button pointing to showing popover' ExpandCollapse.ExpandCollapseState='Expanded' +++Button Name='w/o details' ExpandCollapse.ExpandCollapseState='Expanded' ++Edit ++Text Name='Tel input pointing to showing popover ' ++Button Name='Show button pointing to nested popover' ExpandCollapse.ExpandCollapseState='Expanded'
diff --git a/content/test/data/accessibility/html/popover-api-expected-win.txt b/content/test/data/accessibility/html/popover-api-expected-win.txt index b6a1ba7..ce6c985 100644 --- a/content/test/data/accessibility/html/popover-api-expected-win.txt +++ b/content/test/data/accessibility/html/popover-api-expected-win.txt
@@ -16,6 +16,7 @@ ++IA2_ROLE_PARAGRAPH ++++ROLE_SYSTEM_STATICTEXT name='Showing/visible popovers below' ++ROLE_SYSTEM_PUSHBUTTON name='Button pointing to showing popover' EXPANDED FOCUSABLE details-roles:popover +++ROLE_SYSTEM_PUSHBUTTON name='w/o details' EXPANDED FOCUSABLE ++ROLE_SYSTEM_TEXT FOCUSABLE ++ROLE_SYSTEM_STATICTEXT name='Tel input pointing to showing popover ' ++ROLE_SYSTEM_PUSHBUTTON name='Show button pointing to nested popover' EXPANDED FOCUSABLE details-roles:popover
diff --git a/content/test/data/accessibility/html/popover-api.html b/content/test/data/accessibility/html/popover-api.html index 748768f..e9a7fda 100644 --- a/content/test/data/accessibility/html/popover-api.html +++ b/content/test/data/accessibility/html/popover-api.html
@@ -32,6 +32,7 @@ <p> Showing/visible popovers below </p> <button popovertarget=popover2>Button pointing to showing popover</button> +<button popovertarget=popover2 aria-details="">w/o details</button> <input type=tel popovertarget=popover2>Tel input pointing to showing popover</button> <button popovertarget=popover3 popovertargetaction=show>Show button pointing to nested popover</button> <input type=url popovertarget=popover3 popovertargetaction=show>Url input pointing to nested popover</button>
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_1.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_1.json index 5b624e0..a208801b 100644 --- a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_1.json +++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_1.json
@@ -1,4 +1,5 @@ { + "aggregation_coordinator_identifier": "aws-cloud", "aggregation_service_payloads": [ { "debug_cleartext_payload": "omRkYXRhgaJldmFsdWVEAAAAAmZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAWlvcGVyYXRpb25paGlzdG9ncmFt", "key_id": "example_id",
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_2.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_2.json index a1dbb336..0b72cf65 100644 --- a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_2.json +++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_2.json
@@ -1,4 +1,5 @@ { + "aggregation_coordinator_identifier": "aws-cloud", "aggregation_service_payloads": [ { "key_id": "example_id", "payload": "dCYizN7JKoWWZDpuozgMKeByzoe/IpsVMhelP8l2pmad+TDXg2ozkr7wTGtrnzzV9QO6IpC1HD1fE4zmVK887kGj3yKKFDffRtB61g5DwMwW9ZrBJYvYP5doz4JV/R5QKwpgM5gmvAEa+PXT1R7h"
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_3.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_3.json index fe2f3da5..ce5200d 100644 --- a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_3.json +++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_3.json
@@ -1,4 +1,5 @@ { + "aggregation_coordinator_identifier": "aws-cloud", "aggregation_service_payloads": [ { "debug_cleartext_payload": "omRkYXRhgqJldmFsdWVEAAAAAmZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAaJldmFsdWVEAAAABGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAA2lvcGVyYXRpb25paGlzdG9ncmFt", "key_id": "example_id", @@ -8,4 +9,3 @@ "source_debug_key": "123", "trigger_debug_key": "456" } - \ No newline at end of file
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_4.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_4.json index ecaf02f..e2d4fa9 100644 --- a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_4.json +++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_4.json
@@ -1,4 +1,5 @@ { + "aggregation_coordinator_identifier": "aws-cloud", "aggregation_service_payloads": [ { "key_id": "example_id", "payload": "LiavspqLWGHPnexW5xtuLXVMb2oNNBrrhULpOrBR4TGKnKCxL9qdKTyqzSJlkztvG8lDG2eQnxMwRl0lwKu4T157wwYHLpt0VxWBArFUeNh18QP5WihW7z3+UYkNQN3PJ7ddwoDe60X5UiQ6fxdUKT7F0mOIb/bAjKYKvUd8QukUBCvxTLdGmrWj22+OR239nRAO"
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_5.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_5.json index beee9df..c54da2b 100644 --- a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_5.json +++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_5.json
@@ -1,4 +1,5 @@ { + "aggregation_coordinator_identifier": "aws-cloud", "aggregation_service_payloads": [ { "debug_cleartext_payload": "omRkYXRhgaJldmFsdWVEAAAD6GZidWNrZXRQ/////////////////////2lvcGVyYXRpb25paGlzdG9ncmFt", "key_id": "example_id", @@ -7,4 +8,4 @@ "shared_info": "{\"api\":\"attribution-reporting\",\"attribution_destination\":\"https://conversion.test\",\"debug_mode\":\"enabled\",\"report_id\":\"21abd97f-73e8-4b88-9389-a9fee6abda5e\",\"reporting_origin\":\"https://report.test\",\"scheduled_report_time\":\"1234486600\",\"source_registration_time\":\"1234483200\",\"version\":\"0.1\"}", "source_debug_key": "123", "trigger_debug_key": "456" -} +}
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_6.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_6.json index 520fed7..b1bcd92 100644 --- a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_6.json +++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_6.json
@@ -1,7 +1,8 @@ { + "aggregation_coordinator_identifier": "aws-cloud", "aggregation_service_payloads": [ { "key_id": "example_id", "payload": "IQuLGiKuR9tcUrq3nWuJ7Qy6VrtQSKNDUgflzyuIkT1R6kagnjxsYVMhrw3j9euUQaSlK9jYfg070Z+GMIGYjRwsVUGnCbmTROH30zrB1ar2hupppnvl0Hz2Xkbv9ZjoVCmuV97RuQP506JqYyj7" } ], "shared_info": "{\"api\":\"attribution-reporting\",\"attribution_destination\":\"https://conversion.test\",\"report_id\":\"21abd97f-73e8-4b88-9389-a9fee6abda5e\",\"reporting_origin\":\"https://report.test\",\"scheduled_report_time\":\"1234486600\",\"source_registration_time\":\"1234483200\",\"version\":\"0.1\"}" -} +}
diff --git a/content/test/render_document_feature.cc b/content/test/render_document_feature.cc index d5c0c377..da0423c 100644 --- a/content/test/render_document_feature.cc +++ b/content/test/render_document_feature.cc
@@ -39,8 +39,12 @@ if (render_document_level == GetRenderDocumentLevelName(RenderDocumentLevel::kCrashedFrame)) { return "RDCrashedFrame"; + } else if (render_document_level == + GetRenderDocumentLevelName(RenderDocumentLevel::kSubframe)) { + return "RDSubframe"; + } else { + return "RDAllFrames"; } - return "RDSubframe"; } } // namespace content
diff --git a/content/web_test/renderer/test_plugin.cc b/content/web_test/renderer/test_plugin.cc index 680a0731..027526d 100644 --- a/content/web_test/renderer/test_plugin.cc +++ b/content/web_test/renderer/test_plugin.cc
@@ -278,8 +278,8 @@ } else { viz::SharedBitmapId id = viz::SharedBitmap::GenerateId(); base::MappedReadOnlyRegion shm = - viz::bitmap_allocation::AllocateSharedBitmap(gfx::Rect(rect_).size(), - viz::RGBA_8888); + viz::bitmap_allocation::AllocateSharedBitmap( + gfx::Rect(rect_).size(), viz::SinglePlaneFormat::kRGBA_8888); shared_bitmap_ = base::MakeRefCounted<cc::CrossThreadSharedBitmap>( id, std::move(shm), gfx::Rect(rect_).size(), viz::SinglePlaneFormat::kRGBA_8888);
diff --git a/device/vr/android/arcore/arcore_impl.cc b/device/vr/android/arcore/arcore_impl.cc index ec1dee2..b64e86378f 100644 --- a/device/vr/android/arcore/arcore_impl.cc +++ b/device/vr/android/arcore/arcore_impl.cc
@@ -844,7 +844,7 @@ kOpaque_SkAlphaType), SkBitmap::kZeroPixels_AllocFlag); SkCanvas gray_canvas(canvas_bitmap); - sk_sp<SkImage> src_image = SkImage::MakeFromBitmap(src_bitmap); + sk_sp<SkImage> src_image = SkImages::RasterFromBitmap(src_bitmap); gray_canvas.drawImage(src_image, 0, 0); SkPixmap gray_pixmap; if (!gray_canvas.peekPixels(&gray_pixmap)) {
diff --git a/docs/android_isolated_splits.md b/docs/android_isolated_splits.md index 56ddff6..806ee47 100644 --- a/docs/android_isolated_splits.md +++ b/docs/android_isolated_splits.md
@@ -102,8 +102,8 @@ ### Conflicting ClassLoaders -Missing synchronization can cause the parent ClassLoader of split contexts to -be different from the Application's ClassLoader. This manifests as odd-looking +Tracked by [b/172602571], sometimes a split's parent ClassLoader is different +from the Application's ClassLoader. This manifests as odd-looking `ClassCastExceptions` where `"TypeA cannot be cast to TypeA"` (since the two `TypeAs` are from different ClassLoaders). @@ -180,6 +180,26 @@ [crbug/1298496]: https://bugs.chromium.org/p/chromium/issues/detail?id=1298496 [Application Zygote]: https://developer.android.com/reference/android/app/ZygotePreload +### AppComponentFactory does not Hook Split ClassLoaders + +`AppComponentFactory#instantiateClassLoader()` is meant to allow apps to hook +`ClassLoader` creation. The hook is called for the base split, but not for other +isolated splits. Tracked by [b/265583114]. There is no work-around. + +[b/265583114]: https://issuetracker.google.com/265583114 + +### Incorrect Handling of Shared Libraries + +Tracked by [b/265589431]. If an APK split has `<uses-library>` in its manifest, +the classloader for the split is meant to have that library added to it by the +framework. However, Android does not add the library to the classpath when a +split is dynamically installed, but instead adds it to the classpath of the base +split's classloader upon subsequent app launches. + +**Work-around:** + +In progress: https://bugs.chromium.org/p/chromium/issues/detail?id=1066842#c34 + ## Other Quirks & Subtleties ### System Image APKs @@ -326,6 +346,17 @@ [proguard.py]: https://source.chromium.org/search?q=symbol:_DeDupeInputJars%20f:proguard.py&ss=chromium [b/225876019]: https://issuetracker.google.com/225876019 +### Metadata in Splits + +Metadata is queried on a per-app basis (not a per-split basis). E.g.: + +```java +ApplicationInfo ai = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA); +Bundle b = ai.metaData; +``` + +This bundle contains merged values from all fully-installed apk splits. + ## Other Resources * [go/isolated-splits-dev-guide] (Googlers only).
diff --git a/docs/dangling_ptr_guide.md b/docs/dangling_ptr_guide.md index 93c53cf..39314e92b 100644 --- a/docs/dangling_ptr_guide.md +++ b/docs/dangling_ptr_guide.md
@@ -174,11 +174,11 @@ Q. Gee, this is a raw pointer. Does destroying it actually do anything? -A. Yes. On some platforms raw_ptr<T> is a synonym for T*, but on many platforms -(more every day) raw_ptr<T> is the interface to PartitionAlloc’s BackupRefPtr -(BRP) Use-after-Free (UaF) protection mechanism. Destroying the pointer thus -actually performs internal bookkeeping and may also null the pointer on -destruction to trap use-after-destruct errors. +A. Yes. On some platforms `raw_ptr<T>` is a synonym for `T*`, but on many +platforms (more every day) `raw_ptr<T>` is the interface to PartitionAlloc’s +BackupRefPtr (BRP) Use-after-Free (UaF) protection mechanism. Destroying the +pointer thus actually performs internal bookkeeping and may also null +the pointer on destruction to trap use-after-destruct errors. Q. So BRP mitigates these dangling pointers. What's the problem with just keeping them if they are not used? @@ -187,7 +187,7 @@ remaining, the object must be quarantined and overwritten with a “zapped” pattern as opposed to being simply freed. This costs cycles and memory pressure. Even worse, it is still possible that the raw_ptr is converted to -T* and used with the zap value, or even used after the quarantine is +`T*` and used with the zap value, or even used after the quarantine is gone. Hence we are inventing mechanisms for finding dangling pointers so we may remove the ones we know about. BRP will then make it harder to write exploits with the ones we don’t know about in the wild.
diff --git a/docs/flag_guarding_guidelines.md b/docs/flag_guarding_guidelines.md index 930dc45e..44197a6 100644 --- a/docs/flag_guarding_guidelines.md +++ b/docs/flag_guarding_guidelines.md
@@ -71,3 +71,6 @@ Google to launch and monitor the experiment. * Otherwise it should be guarded minimally by an enabled-by-default base::Feature flag, which can be remotely disabled by a server configuration. + * For code in blink, this can be as simple as using a +[Runtime Enabled Feature](/third_party/blink/renderer/platform/RuntimeEnabledFeatures.md), +which has long been common-practice for new or changed APIs.
diff --git a/docs/webui_build_configuration.md b/docs/webui_build_configuration.md index 2ee7ccb..cd74ad8 100644 --- a/docs/webui_build_configuration.md +++ b/docs/webui_build_configuration.md
@@ -515,6 +515,7 @@ grd_resource_path_prefix: See |resource_path_prefix| in generate_grd(). Optional parameter. html_to_wrapper_template: See |template| in html_to_wrapper(). +html_to_wrapper_scheme: See |scheme| in html_to_wrapper(). extra_grdp_deps: List of external generate_grd() targets that generate .grdp files. These will be included in the final generated resources.grd file. Optional parameter.
diff --git a/extensions/browser/api/declarative_net_request/declarative_net_request_api.cc b/extensions/browser/api/declarative_net_request/declarative_net_request_api.cc index 6698b04..6add55d0 100644 --- a/extensions/browser/api/declarative_net_request/declarative_net_request_api.cc +++ b/extensions/browser/api/declarative_net_request/declarative_net_request_api.cc
@@ -84,7 +84,7 @@ using Params = dnr_api::UpdateDynamicRules::Params; std::u16string error; - absl::optional<Params> params = Params::Create(args(), &error); + absl::optional<Params> params = Params::Create(args(), error); EXTENSION_FUNCTION_VALIDATE(params); EXTENSION_FUNCTION_VALIDATE(error.empty()); @@ -134,7 +134,7 @@ using Params = dnr_api::GetDynamicRules::Params; std::u16string error; - absl::optional<Params> params = Params::Create(args(), &error); + absl::optional<Params> params = Params::Create(args(), error); EXTENSION_FUNCTION_VALIDATE(params); EXTENSION_FUNCTION_VALIDATE(error.empty()); @@ -190,7 +190,7 @@ using Params = dnr_api::UpdateSessionRules::Params; std::u16string error; - absl::optional<Params> params = Params::Create(args(), &error); + absl::optional<Params> params = Params::Create(args(), error); EXTENSION_FUNCTION_VALIDATE(params); EXTENSION_FUNCTION_VALIDATE(error.empty()); @@ -237,7 +237,7 @@ using Params = dnr_api::GetSessionRules::Params; std::u16string error; - absl::optional<Params> params = Params::Create(args(), &error); + absl::optional<Params> params = Params::Create(args(), error); EXTENSION_FUNCTION_VALIDATE(params); EXTENSION_FUNCTION_VALIDATE(error.empty()); @@ -267,7 +267,7 @@ using DNRManifestData = declarative_net_request::DNRManifestData; std::u16string error; - absl::optional<Params> params = Params::Create(args(), &error); + absl::optional<Params> params = Params::Create(args(), error); EXTENSION_FUNCTION_VALIDATE(params); EXTENSION_FUNCTION_VALIDATE(error.empty()); @@ -379,7 +379,7 @@ DeclarativeNetRequestPrefsHelper::RuleIdsToUpdate; std::u16string error; - absl::optional<Params> params = Params::Create(args(), &error); + absl::optional<Params> params = Params::Create(args(), error); EXTENSION_FUNCTION_VALIDATE(params); EXTENSION_FUNCTION_VALIDATE(error.empty()); @@ -433,7 +433,7 @@ using DNRManifestData = declarative_net_request::DNRManifestData; std::u16string error; - absl::optional<Params> params = Params::Create(args(), &error); + absl::optional<Params> params = Params::Create(args(), error); EXTENSION_FUNCTION_VALIDATE(params); EXTENSION_FUNCTION_VALIDATE(error.empty()); @@ -482,7 +482,7 @@ using Params = dnr_api::GetMatchedRules::Params; std::u16string error; - absl::optional<Params> params = Params::Create(args(), &error); + absl::optional<Params> params = Params::Create(args(), error); EXTENSION_FUNCTION_VALIDATE(params); EXTENSION_FUNCTION_VALIDATE(error.empty()); @@ -555,7 +555,7 @@ using Params = dnr_api::SetExtensionActionOptions::Params; std::u16string error; - absl::optional<Params> params = Params::Create(args(), &error); + absl::optional<Params> params = Params::Create(args(), error); EXTENSION_FUNCTION_VALIDATE(params); EXTENSION_FUNCTION_VALIDATE(error.empty()); @@ -624,7 +624,7 @@ using Params = dnr_api::IsRegexSupported::Params; std::u16string error; - absl::optional<Params> params = Params::Create(args(), &error); + absl::optional<Params> params = Params::Create(args(), error); EXTENSION_FUNCTION_VALIDATE(params); EXTENSION_FUNCTION_VALIDATE(error.empty()); @@ -714,7 +714,7 @@ using Params = dnr_api::TestMatchOutcome::Params; std::u16string error; - absl::optional<Params> params = Params::Create(args(), &error); + absl::optional<Params> params = Params::Create(args(), error); EXTENSION_FUNCTION_VALIDATE(params); EXTENSION_FUNCTION_VALIDATE(error.empty());
diff --git a/extensions/browser/api/declarative_net_request/file_backed_ruleset_source.cc b/extensions/browser/api/declarative_net_request/file_backed_ruleset_source.cc index 39ed29c6..dafb23c0 100644 --- a/extensions/browser/api/declarative_net_request/file_backed_ruleset_source.cc +++ b/extensions/browser/api/declarative_net_request/file_backed_ruleset_source.cc
@@ -105,7 +105,7 @@ dnr_api::Rule parsed_rule; std::u16string parse_error; - if (dnr_api::Rule::Populate(rules_list[i], parsed_rule, &parse_error)) { + if (dnr_api::Rule::Populate(rules_list[i], parsed_rule, parse_error)) { DCHECK(parse_error.empty()); if (result.rules.size() == rule_limit) { result.rule_parse_warnings.push_back(
diff --git a/extensions/browser/api/declarative_net_request/file_sequence_helper_unittest.cc b/extensions/browser/api/declarative_net_request/file_sequence_helper_unittest.cc index aab90ab..d05057f 100644 --- a/extensions/browser/api/declarative_net_request/file_sequence_helper_unittest.cc +++ b/extensions/browser/api/declarative_net_request/file_sequence_helper_unittest.cc
@@ -38,7 +38,7 @@ api::declarative_net_request::Rule result; std::u16string error; EXPECT_TRUE(api::declarative_net_request::Rule::Populate(rule.ToValue(), - result, &error)) + result, error)) << error; EXPECT_TRUE(error.empty()) << error; return result;
diff --git a/extensions/browser/api/declarative_net_request/filter_list_converter/converter.cc b/extensions/browser/api/declarative_net_request/filter_list_converter/converter.cc index da4ac8e..8676855 100644 --- a/extensions/browser/api/declarative_net_request/filter_list_converter/converter.cc +++ b/extensions/browser/api/declarative_net_request/filter_list_converter/converter.cc
@@ -77,7 +77,7 @@ // Sanity check that we can parse this rule. std::u16string err; dnr_api::Rule rule; - CHECK(dnr_api::Rule::Populate(json_rule_, rule, &err) && err.empty()) + CHECK(dnr_api::Rule::Populate(json_rule_, rule, err) && err.empty()) << "Converted rule can't be parsed " << json_rule_; IndexedRule indexed_rule;
diff --git a/extensions/browser/api/declarative_net_request/indexed_rule_fuzzer.cc b/extensions/browser/api/declarative_net_request/indexed_rule_fuzzer.cc index 8742da4..fda7c75 100644 --- a/extensions/browser/api/declarative_net_request/indexed_rule_fuzzer.cc +++ b/extensions/browser/api/declarative_net_request/indexed_rule_fuzzer.cc
@@ -32,7 +32,7 @@ if (!value || !value->is_dict()) return 0; std::u16string error; - absl::optional<Rule> rule = Rule::FromValue(value->GetDict(), &error); + absl::optional<Rule> rule = Rule::FromValue(value->GetDict(), error); if (!rule) { CHECK(!error.empty()); return 0;
diff --git a/extensions/browser/api/declarative_net_request/rules_monitor_service.cc b/extensions/browser/api/declarative_net_request/rules_monitor_service.cc index 8629c7b..2094e71 100644 --- a/extensions/browser/api/declarative_net_request/rules_monitor_service.cc +++ b/extensions/browser/api/declarative_net_request/rules_monitor_service.cc
@@ -385,7 +385,7 @@ std::vector<api::declarative_net_request::Rule> result; std::u16string error; bool populate_result = json_schema_compiler::util::PopulateArrayFromList( - GetSessionRulesValue(extension_id), result, &error); + GetSessionRulesValue(extension_id), result, error); DCHECK(populate_result); DCHECK(error.empty()); return result;
diff --git a/extensions/common/api/declarative_net_request/dnr_manifest_handler.cc b/extensions/common/api/declarative_net_request/dnr_manifest_handler.cc index 4fc6a6d1f..cbda4bcab 100644 --- a/extensions/common/api/declarative_net_request/dnr_manifest_handler.cc +++ b/extensions/common/api/declarative_net_request/dnr_manifest_handler.cc
@@ -49,7 +49,7 @@ dnr_api::ManifestKeys manifest_keys; if (!dnr_api::ManifestKeys::ParseFromDictionary( - extension->manifest()->available_values(), manifest_keys, error)) { + extension->manifest()->available_values(), manifest_keys, *error)) { return false; } std::vector<dnr_api::Ruleset> rulesets =
diff --git a/extensions/common/image_util.cc b/extensions/common/image_util.cc index 302362a..220c7ce 100644 --- a/extensions/common/image_util.cc +++ b/extensions/common/image_util.cc
@@ -139,7 +139,7 @@ } rendered_icon->eraseColor(background_color); SkCanvas offscreen(*rendered_icon, SkSurfaceProps{}); - offscreen.drawImage(SkImage::MakeFromBitmap(icon), 0, 0); + offscreen.drawImage(SkImages::RasterFromBitmap(icon), 0, 0); offscreen.drawColor(background_color, SkBlendMode::kDifference); return true;
diff --git a/extensions/common/manifest_handlers/content_scripts_handler.cc b/extensions/common/manifest_handlers/content_scripts_handler.cc index 32a7a50..eb7ad0d 100644 --- a/extensions/common/manifest_handlers/content_scripts_handler.cc +++ b/extensions/common/manifest_handlers/content_scripts_handler.cc
@@ -222,7 +222,7 @@ bool ContentScriptsHandler::Parse(Extension* extension, std::u16string* error) { ContentScriptsKeys manifest_keys; if (!ContentScriptsKeys::ParseFromDictionary( - extension->manifest()->available_values(), manifest_keys, error)) { + extension->manifest()->available_values(), manifest_keys, *error)) { return false; }
diff --git a/extensions/common/manifest_handlers/cross_origin_isolation_info.cc b/extensions/common/manifest_handlers/cross_origin_isolation_info.cc index 394a6e5b..212d3af 100644 --- a/extensions/common/manifest_handlers/cross_origin_isolation_info.cc +++ b/extensions/common/manifest_handlers/cross_origin_isolation_info.cc
@@ -45,7 +45,7 @@ std::u16string* error) { COIManifestKeys manifest_keys; if (!COIManifestKeys::ParseFromDictionary( - extension->manifest()->available_values(), manifest_keys, error)) { + extension->manifest()->available_values(), manifest_keys, *error)) { return false; }
diff --git a/extensions/common/manifest_handlers/incognito_info.cc b/extensions/common/manifest_handlers/incognito_info.cc index 028a5cf2c..1a986c9 100644 --- a/extensions/common/manifest_handlers/incognito_info.cc +++ b/extensions/common/manifest_handlers/incognito_info.cc
@@ -38,7 +38,7 @@ bool IncognitoHandler::Parse(Extension* extension, std::u16string* error) { IncognitoManifestKeys manifest_keys; if (!IncognitoManifestKeys::ParseFromDictionary( - extension->manifest()->available_values(), manifest_keys, error)) { + extension->manifest()->available_values(), manifest_keys, *error)) { return false; }
diff --git a/extensions/common/manifest_handlers/oauth2_manifest_handler.cc b/extensions/common/manifest_handlers/oauth2_manifest_handler.cc index b7bb8e9..a6077930a6 100644 --- a/extensions/common/manifest_handlers/oauth2_manifest_handler.cc +++ b/extensions/common/manifest_handlers/oauth2_manifest_handler.cc
@@ -43,7 +43,7 @@ bool OAuth2ManifestHandler::Parse(Extension* extension, std::u16string* error) { OAuth2ManifestKeys manifest_keys; if (!OAuth2ManifestKeys::ParseFromDictionary( - extension->manifest()->available_values(), manifest_keys, error)) { + extension->manifest()->available_values(), manifest_keys, *error)) { return false; }
diff --git a/extensions/common/manifest_handlers/requirements_info.cc b/extensions/common/manifest_handlers/requirements_info.cc index 4fc812a..48ce137 100644 --- a/extensions/common/manifest_handlers/requirements_info.cc +++ b/extensions/common/manifest_handlers/requirements_info.cc
@@ -49,7 +49,7 @@ bool RequirementsHandler::Parse(Extension* extension, std::u16string* error) { ManifestKeys manifest_keys; if (!ManifestKeys::ParseFromDictionary( - extension->manifest()->available_values(), manifest_keys, error)) { + extension->manifest()->available_values(), manifest_keys, *error)) { return false; }
diff --git a/extensions/common/manifest_handlers/shared_module_info.cc b/extensions/common/manifest_handlers/shared_module_info.cc index 96ee077..9722ac0 100644 --- a/extensions/common/manifest_handlers/shared_module_info.cc +++ b/extensions/common/manifest_handlers/shared_module_info.cc
@@ -132,7 +132,7 @@ bool SharedModuleHandler::Parse(Extension* extension, std::u16string* error) { ManifestKeys manifest_keys; if (!ManifestKeys::ParseFromDictionary( - extension->manifest()->available_values(), manifest_keys, error)) { + extension->manifest()->available_values(), manifest_keys, *error)) { return false; }
diff --git a/extensions/common/manifest_handlers/web_accessible_resources_info.cc b/extensions/common/manifest_handlers/web_accessible_resources_info.cc index 1d9cf29..2ae61a8 100644 --- a/extensions/common/manifest_handlers/web_accessible_resources_info.cc +++ b/extensions/common/manifest_handlers/web_accessible_resources_info.cc
@@ -55,7 +55,7 @@ std::u16string* error) { WebAccessibleResourcesMv2ManifestKeys manifest_keys; if (!WebAccessibleResourcesMv2ManifestKeys::ParseFromDictionary( - extension.manifest()->available_values(), manifest_keys, error)) { + extension.manifest()->available_values(), manifest_keys, *error)) { return nullptr; } @@ -92,7 +92,7 @@ WebAccessibleResourcesManifestKeys manifest_keys; if (!WebAccessibleResourcesManifestKeys::ParseFromDictionary( - extension.manifest()->available_values(), manifest_keys, error)) { + extension.manifest()->available_values(), manifest_keys, *error)) { return nullptr; }
diff --git a/extensions/common/manifest_handlers/web_file_handlers_info.cc b/extensions/common/manifest_handlers/web_file_handlers_info.cc index c759a23..56d24d6 100644 --- a/extensions/common/manifest_handlers/web_file_handlers_info.cc +++ b/extensions/common/manifest_handlers/web_file_handlers_info.cc
@@ -26,7 +26,7 @@ std::u16string* error) { FileHandlersManifestKeys manifest_keys; if (!FileHandlersManifestKeys::ParseFromDictionary( - extension.manifest()->available_values(), manifest_keys, error)) { + extension.manifest()->available_values(), manifest_keys, *error)) { return nullptr; } @@ -122,7 +122,7 @@ // Make the temporary `accept` permanent by assigning to `file_handler`. api::file_handlers::FileHandler::Accept::Populate( - accept, file_handler.accept, error); + accept, file_handler.accept, *error); // `icon` is an optional array of dictionaries. if (manifest_file_handler.icons.has_value()) {
diff --git a/extensions/shell/browser/shell_desktop_controller_aura.cc b/extensions/shell/browser/shell_desktop_controller_aura.cc index 9a0a70f..0601bb64e 100644 --- a/extensions/shell/browser/shell_desktop_controller_aura.cc +++ b/extensions/shell/browser/shell_desktop_controller_aura.cc
@@ -76,9 +76,9 @@ // wm::NativeCursorManager overrides. void SetDisplay(const display::Display& display, wm::NativeCursorManagerDelegate* delegate) override { - if (cursor_loader_.SetDisplayData(display.panel_rotation(), - display.device_scale_factor())) + if (cursor_loader_.SetDisplay(display)) { SetCursor(delegate->GetCursor(), delegate); + } } void SetCursor(gfx::NativeCursor cursor,
diff --git a/gpu/command_buffer/service/copy_shared_image_helper.cc b/gpu/command_buffer/service/copy_shared_image_helper.cc index eb6d6c0..1c8e3e9 100644 --- a/gpu/command_buffer/service/copy_shared_image_helper.cc +++ b/gpu/command_buffer/service/copy_shared_image_helper.cc
@@ -19,13 +19,16 @@ #include "skia/ext/rgba_to_yuva.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkColorSpace.h" +#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkPromiseImageTexture.h" +#include "third_party/skia/include/core/SkRect.h" #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/core/SkYUVAInfo.h" #include "third_party/skia/include/gpu/GrBackendSemaphore.h" #include "third_party/skia/include/gpu/GrBackendSurface.h" #include "third_party/skia/include/gpu/GrDirectContext.h" #include "third_party/skia/include/gpu/GrYUVABackendTextures.h" +#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h" namespace gpu { @@ -33,6 +36,48 @@ namespace { +SkColorType GetCompatibleSurfaceColorType(GrGLenum format) { + switch (format) { + case GL_RGBA8: + return kRGBA_8888_SkColorType; + case GL_RGB565: + return kRGB_565_SkColorType; + case GL_RGBA16F: + return kRGBA_F16_SkColorType; + case GL_RGB8: + return kRGB_888x_SkColorType; + case GL_RGB10_A2: + return kRGBA_1010102_SkColorType; + case GL_RGBA4: + return kARGB_4444_SkColorType; + case GL_SRGB8_ALPHA8: + return kRGBA_8888_SkColorType; + default: + NOTREACHED(); + return kUnknown_SkColorType; + } +} + +GrGLenum GetSurfaceColorFormat(GrGLenum format, GrGLenum type) { + if (format == GL_RGBA) { + if (type == GL_UNSIGNED_BYTE) { + return GL_RGBA8; + } + if (type == GL_UNSIGNED_SHORT_4_4_4_4) { + return GL_RGBA4; + } + } + if (format == GL_RGB) { + if (type == GL_UNSIGNED_BYTE) { + return GL_RGB8; + } + if (type == GL_UNSIGNED_SHORT_5_6_5) { + return GL_RGB565; + } + } + return format; +} + // Return true if all of `sk_yuv_color_space`, `sk_plane_config`, // `sk_subsampling`, `rgba_image, `num_yuva_images`, and `yuva_images` were // successfully populated. Return false on error. If this returns false, some @@ -430,7 +475,7 @@ src_yuv_color_space); GrYUVABackendTextures yuva_backend_textures(yuva_info, yuva_textures.data(), kTopLeft_GrSurfaceOrigin); - auto result_image = SkImage::MakeFromYUVATextures( + auto result_image = SkImages::TextureFromYUVATextures( shared_context_state_->gr_context(), yuva_backend_textures, src_rgb_color_space); if (!result_image) { @@ -551,12 +596,12 @@ // In some cases (e.g android video that is promoted to overlay) we can't // create representation of the valid mailbox. To avoid problems with - // uncleared destination later later, we do clear destination rect with black + // uncleared destination later, we do clear destination rect with black // color. if (!source_shared_image) { auto* canvas = dest_scoped_access->surface()->getCanvas(); - SkAutoCanvasRestore autoRestore(canvas, true /* do_save */); + SkAutoCanvasRestore autoRestore(canvas, /*doSave=*/true); canvas->clipRect(gfx::RectToSkRect(dest_rect)); canvas->clear(SkColors::kBlack); @@ -584,30 +629,30 @@ std::unique_ptr<SkiaImageRepresentation::ScopedReadAccess> source_scoped_access = source_shared_image->BeginScopedReadAccess( &begin_semaphores, &end_semaphores); - if (!begin_semaphores.empty()) { bool ret = dest_scoped_access->surface()->wait( begin_semaphores.size(), begin_semaphores.data(), /*deleteSemaphoresAfterWait=*/false); DCHECK(ret); } - - base::expected<void, GLError> result = base::ok(); if (!source_scoped_access) { - result = base::unexpected<GLError>( - GLError(GL_INVALID_VALUE, "glCopySubTexture", - "Source shared image is not accessable")); // We still need to flush surface for begin semaphores above. FlushSurface(dest_scoped_access.get()); - } else { - auto source_image = source_scoped_access->CreateSkImage( - shared_context_state_->gr_context()); - if (!source_image) { - result = base::unexpected<GLError>( - GLError(GL_INVALID_VALUE, "glCopySubTexture", - "Couldn't create SkImage from source shared image.")); - } + SubmitIfNecessary(std::move(end_semaphores), shared_context_state_, + is_drdc_enabled_); + return base::unexpected<GLError>( + GLError(GL_INVALID_VALUE, "glCopySubTexture", + "Source shared image is not accessable")); + } + base::expected<void, GLError> result = base::ok(); + auto source_image = + source_scoped_access->CreateSkImage(shared_context_state_->gr_context()); + if (!source_image) { + result = base::unexpected<GLError>( + GLError(GL_INVALID_VALUE, "glCopySubTexture", + "Couldn't create SkImage from source shared image.")); + } else { // Skia will flip the image if the surface origins do not match. DCHECK_EQ(unpack_flip_y, source_shared_image->surface_origin() != dest_shared_image->surface_origin()); @@ -652,26 +697,160 @@ skia::BlitRGBAToYUVA(source_image.get(), yuva_sk_surfaces, yuva_info); } - FlushSurface(dest_scoped_access.get()); - auto source_format = source_shared_image->format(); - if (auto end_state = source_scoped_access->TakeEndState()) { - // Only one texture for external sampler case in source shared image. - const int num_planes = source_format.PrefersExternalSampler() - ? 1 - : source_format.NumberOfPlanes(); - for (int plane_index = 0; plane_index < num_planes; plane_index++) { - shared_context_state_->gr_context()->setBackendTextureState( - source_scoped_access->promise_image_texture(plane_index) - ->backendTexture(), - *end_state); - } - } - if (!dest_shared_image->IsCleared()) { dest_shared_image->SetClearedRect(new_cleared_rect); } } + FlushSurface(dest_scoped_access.get()); + if (auto end_state = source_scoped_access->TakeEndState()) { + const int num_planes = + static_cast<int>(source_shared_image->NumPlanesExpected()); + for (int plane_index = 0; plane_index < num_planes; plane_index++) { + shared_context_state_->gr_context()->setBackendTextureState( + source_scoped_access->promise_image_texture(plane_index) + ->backendTexture(), + *end_state); + } + } + + SubmitIfNecessary(std::move(end_semaphores), shared_context_state_, + is_drdc_enabled_); + return result; +} + +base::expected<void, GLError> CopySharedImageHelper::CopySharedImageToGLTexture( + GLuint dest_texture_id, + GLenum target, + GLuint internal_format, + GLenum type, + GLint src_x, + GLint src_y, + GLsizei width, + GLsizei height, + GLboolean flip_y, + const volatile GLbyte* src_mailbox) { + Mailbox source_mailbox = Mailbox::FromVolatile( + reinterpret_cast<const volatile Mailbox*>(src_mailbox)[0]); + DLOG_IF(ERROR, !source_mailbox.Verify()) + << "CopySharedImageToGLTexture was passed an invalid mailbox"; + + CHECK_NE(dest_texture_id, 0u); + CHECK(shared_context_state_->GrContextIsGL()); + GrGLTextureInfo texture_info; + texture_info.fID = dest_texture_id; + texture_info.fTarget = target; + // Get the surface color format similar to that in VideoFrameYUVConverter. + texture_info.fFormat = GetSurfaceColorFormat(internal_format, type); + GrBackendTexture backend_texture(width, height, GrMipMapped::kNo, + texture_info); + + auto dest_color_space = SkColorSpace::MakeSRGB(); + sk_sp<SkSurface> dest_surface = SkSurface::MakeFromBackendTexture( + shared_context_state_->gr_context(), backend_texture, + flip_y ? GrSurfaceOrigin::kBottomLeft_GrSurfaceOrigin + : GrSurfaceOrigin::kTopLeft_GrSurfaceOrigin, + /*sampleCnt=*/1, GetCompatibleSurfaceColorType(texture_info.fFormat), + dest_color_space, nullptr); + if (!dest_surface) { + return base::unexpected<GLError>( + GLError(GL_INVALID_VALUE, "glCopySharedImageToTexture", + "Cannot create destination surface")); + } + + // `dest_rect` always starts from (0, 0). + SkRect dest_rect = + SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)); + auto source_shared_image = representation_factory_->ProduceSkia( + source_mailbox, + scoped_refptr<gpu::SharedContextState>(shared_context_state_)); + + // In some cases (e.g android video that is promoted to overlay) we can't + // create representation of the valid mailbox. To avoid problems with + // uncleared destination later, we do clear destination rect with black + // color. + if (!source_shared_image) { + auto* canvas = dest_surface->getCanvas(); + + SkAutoCanvasRestore autoRestore(canvas, /*doSave=*/true); + canvas->clipRect(dest_rect); + canvas->clear(SkColors::kBlack); + + dest_surface->flush(); + SubmitIfNecessary({}, shared_context_state_, is_drdc_enabled_); + + // Note, that we still generate error for the client to indicate there was + // problem. + return base::unexpected<GLError>(GLError(GL_INVALID_VALUE, + "glCopySharedImageToTexture", + "unknown source image mailbox.")); + } + + gfx::Size source_size = source_shared_image->size(); + gfx::Rect source_rect(src_x, src_y, width, height); + if (!gfx::Rect(source_size).Contains(source_rect)) { + return base::unexpected<GLError>(GLError(GL_INVALID_VALUE, + "glCopySharedImageToTexture", + "source texture bad dimensions.")); + } + + std::vector<GrBackendSemaphore> begin_semaphores; + std::vector<GrBackendSemaphore> end_semaphores; + std::unique_ptr<SkiaImageRepresentation::ScopedReadAccess> + source_scoped_access = source_shared_image->BeginScopedReadAccess( + &begin_semaphores, &end_semaphores); + if (!begin_semaphores.empty()) { + bool ret = + dest_surface->wait(begin_semaphores.size(), begin_semaphores.data(), + /*deleteSemaphoresAfterWait=*/false); + DCHECK(ret); + } + if (!source_scoped_access) { + // We still need to flush surface for begin semaphores above. + dest_surface->flush(); + SubmitIfNecessary(std::move(end_semaphores), shared_context_state_, + is_drdc_enabled_); + + return base::unexpected<GLError>( + GLError(GL_INVALID_VALUE, "glCopySharedImageToTexture", + "Source shared image is not accessable")); + } + + base::expected<void, GLError> result = base::ok(); + auto source_image = + source_scoped_access->CreateSkImage(shared_context_state_->gr_context()); + if (!source_image) { + result = base::unexpected<GLError>( + GLError(GL_INVALID_VALUE, "glCopySharedImageToTexture", + "Couldn't create SkImage from source shared image.")); + } else { + auto* canvas = dest_surface->getCanvas(); + SkPaint paint; + paint.setBlendMode(SkBlendMode::kSrc); + + // Reinterpret the source image as being in the destination color space, + // to disable color conversion. + auto source_image_reinterpreted = source_image; + if (canvas->imageInfo().colorSpace()) { + source_image_reinterpreted = source_image->reinterpretColorSpace( + canvas->imageInfo().refColorSpace()); + } + canvas->drawImageRect( + source_image_reinterpreted, gfx::RectToSkRect(source_rect), dest_rect, + SkSamplingOptions(), &paint, SkCanvas::kStrict_SrcRectConstraint); + } + + dest_surface->flush(); + if (auto end_state = source_scoped_access->TakeEndState()) { + const int num_planes = + static_cast<int>(source_shared_image->NumPlanesExpected()); + for (int plane_index = 0; plane_index < num_planes; plane_index++) { + shared_context_state_->gr_context()->setBackendTextureState( + source_scoped_access->promise_image_texture(plane_index) + ->backendTexture(), + *end_state); + } + } SubmitIfNecessary(std::move(end_semaphores), shared_context_state_, is_drdc_enabled_); return result;
diff --git a/gpu/command_buffer/service/copy_shared_image_helper.h b/gpu/command_buffer/service/copy_shared_image_helper.h index 89adf755..afdd1ae 100644 --- a/gpu/command_buffer/service/copy_shared_image_helper.h +++ b/gpu/command_buffer/service/copy_shared_image_helper.h
@@ -56,6 +56,18 @@ GLsizei height, GLboolean unpack_flip_y, const volatile GLbyte* mailboxes); + // Only used by passthrough decoder. + base::expected<void, GLError> CopySharedImageToGLTexture( + GLuint texture_service_id, + GLenum target, + GLuint internal_format, + GLenum type, + GLint src_x, + GLint src_y, + GLsizei width, + GLsizei height, + GLboolean flip_y, + const volatile GLbyte* src_mailbox); base::expected<void, GLError> ReadPixels( GLint src_x, GLint src_y,
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc index e7e66ab..c23cd37 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
@@ -5195,7 +5195,36 @@ GLsizei height, GLboolean flip_y, const volatile GLbyte* src_mailbox) { - NOTIMPLEMENTED_LOG_ONCE(); + if (!lazy_context_) { + lazy_context_ = LazySharedContextState::Create(this); + if (!lazy_context_) { + return error::kNoError; + } + } + ScopedPixelLocalStorageDeactivate scoped_pls_deactivate(this); + ui::ScopedMakeCurrent smc(lazy_context_->shared_context_state()->context(), + lazy_context_->shared_context_state()->surface()); + + if (GLenumToTextureTarget(target) == TextureTarget::kUnkown) { + InsertError(GL_INVALID_VALUE, "Invalid texture target"); + return error::kNoError; + } + + GLuint gl_texture_service_id = GetTextureServiceID( + api(), texture, resources_, /*create_if_missing=*/false); + if (gl_texture_service_id == 0) { + InsertError(GL_INVALID_OPERATION, "Cannot get texture service id"); + return error::kNoError; + } + + CopySharedImageHelper helper(group_->shared_image_representation_factory(), + lazy_context_->shared_context_state()); + auto result = helper.CopySharedImageToGLTexture( + gl_texture_service_id, target, internal_format, type, src_x, src_y, width, + height, flip_y, src_mailbox); + if (!result.has_value()) { + InsertError(result.error().gl_error, result.error().msg); + } return error::kNoError; }
diff --git a/gpu/command_buffer/service/gr_cache_controller_unittest.cc b/gpu/command_buffer/service/gr_cache_controller_unittest.cc index e4c8ddab..cfbbfca 100644 --- a/gpu/command_buffer/service/gr_cache_controller_unittest.cc +++ b/gpu/command_buffer/service/gr_cache_controller_unittest.cc
@@ -74,7 +74,7 @@ SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10); ASSERT_TRUE(bm.tryAllocPixels(info)); sk_sp<SkImage> uploaded = - SkImage::MakeFromBitmap(bm)->makeTextureImage(gr_context()); + SkImages::RasterFromBitmap(bm)->makeTextureImage(gr_context()); ASSERT_TRUE(uploaded); } EXPECT_GT(gr_context()->getResourceCachePurgeableBytes(), 0u); @@ -96,7 +96,7 @@ SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10); ASSERT_TRUE(bm.tryAllocPixels(info)); sk_sp<SkImage> uploaded = - SkImage::MakeFromBitmap(bm)->makeTextureImage(gr_context()); + SkImages::RasterFromBitmap(bm)->makeTextureImage(gr_context()); ASSERT_TRUE(uploaded); } EXPECT_GT(gr_context()->getResourceCachePurgeableBytes(), 0u);
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 aedb586..f5518be 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
@@ -34,6 +34,7 @@ #include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkPromiseImageTexture.h" #include "third_party/skia/include/core/SkSurface.h" +#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/skia_conversions.h" #include "ui/gfx/gpu_memory_buffer.h" @@ -483,7 +484,7 @@ EXPECT_EQ(size.height(), backend_texture.height()); // Create an Sk Image from GrBackendTexture. - auto sk_image = SkImage::MakeFromTexture( + auto sk_image = SkImages::BorrowTextureFrom( gr_context(), backend_texture, kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kOpaque_SkAlphaType, nullptr); @@ -2277,7 +2278,7 @@ GrBackendTexture backend_texture = dest_surface->getBackendTexture( SkSurface::kFlushWrite_BackendHandleAccess); - auto dst_image = SkImage::MakeFromTexture( + auto dst_image = SkImages::BorrowTextureFrom( context_state_->gr_context(), backend_texture, kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, alpha_type, nullptr); ASSERT_TRUE(dst_image);
diff --git a/gpu/command_buffer/service/shared_image/egl_image_backing_factory_unittest.cc b/gpu/command_buffer/service/shared_image/egl_image_backing_factory_unittest.cc index fd01b6a..32efa0f 100644 --- a/gpu/command_buffer/service/shared_image/egl_image_backing_factory_unittest.cc +++ b/gpu/command_buffer/service/shared_image/egl_image_backing_factory_unittest.cc
@@ -29,9 +29,11 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkPromiseImageTexture.h" #include "third_party/skia/include/gpu/GrBackendSemaphore.h" #include "third_party/skia/include/gpu/GrBackendSurface.h" +#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h" #include "ui/gfx/buffer_format_util.h" #include "ui/gfx/color_space.h" #include "ui/gl/buffer_format_utils.h" @@ -175,7 +177,7 @@ EXPECT_EQ(size.height(), backend_texture.height()); // Create an Sk Image from GrBackendTexture. - auto sk_image = SkImage::MakeFromTexture( + auto sk_image = SkImages::BorrowTextureFrom( context_state_->gr_context(), backend_texture, kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kOpaque_SkAlphaType, nullptr);
diff --git a/gpu/command_buffer/service/shared_image/external_vk_image_backing_factory_unittest.cc b/gpu/command_buffer/service/shared_image/external_vk_image_backing_factory_unittest.cc index 25841dac..e2d97d4 100644 --- a/gpu/command_buffer/service/shared_image/external_vk_image_backing_factory_unittest.cc +++ b/gpu/command_buffer/service/shared_image/external_vk_image_backing_factory_unittest.cc
@@ -30,6 +30,7 @@ #include "third_party/skia/include/core/SkPromiseImageTexture.h" #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/gpu/GrBackendSemaphore.h" +#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h" #include "ui/gl/buildflags.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_surface.h" @@ -245,7 +246,7 @@ EXPECT_EQ(size.height(), backend_texture.height()); // Create an Sk Image from GrBackendTexture. - auto sk_image = SkImage::MakeFromTexture( + auto sk_image = SkImages::BorrowTextureFrom( gr_context(), backend_texture, kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kOpaque_SkAlphaType, nullptr); EXPECT_TRUE(sk_image);
diff --git a/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory_unittest.cc b/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory_unittest.cc index c4cb8d73..2073a52 100644 --- a/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory_unittest.cc +++ b/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory_unittest.cc
@@ -28,6 +28,7 @@ #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/gpu/GrBackendSemaphore.h" #include "third_party/skia/include/gpu/GrBackendSurface.h" +#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h" #include "ui/gl/buildflags.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_surface.h" @@ -124,7 +125,7 @@ EXPECT_EQ(size.height(), backend_texture.height()); // Create an Sk Image from GrBackendTexture. - auto sk_image = SkImage::MakeFromTexture( + auto sk_image = SkImages::BorrowTextureFrom( gr_context(), backend_texture, kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kOpaque_SkAlphaType, nullptr);
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 7846620..7a49807 100644 --- a/gpu/command_buffer/service/shared_image/shared_image_representation.cc +++ b/gpu/command_buffer/service/shared_image/shared_image_representation.cc
@@ -12,10 +12,12 @@ #include "gpu/command_buffer/service/shared_image/shared_image_format_utils.h" #include "gpu/command_buffer/service/texture_manager.h" #include "third_party/skia/include/core/SkColorSpace.h" +#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkPromiseImageTexture.h" #include "third_party/skia/include/gpu/GrBackendSurfaceMutableState.h" #include "third_party/skia/include/gpu/GrDirectContext.h" #include "third_party/skia/include/gpu/GrYUVABackendTextures.h" +#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h" #include "ui/gl/gl_fence.h" namespace gpu { @@ -283,7 +285,7 @@ auto alpha_type = representation()->alpha_type(); auto color_type = viz::ToClosestSkColorType(/*gpu_compositing=*/true, format); - return SkImage::MakeFromTexture( + return SkImages::BorrowTextureFrom( context, promise_image_texture()->backendTexture(), surface_origin, color_type, alpha_type, sk_color_space, texture_release_proc, release_context); @@ -307,9 +309,9 @@ ToSkYUVASubsampling(format), yuv_color_space); GrYUVABackendTextures yuva_backend_textures(yuva_info, yuva_textures.data(), surface_origin); - return SkImage::MakeFromYUVATextures(context, yuva_backend_textures, - sk_color_space, texture_release_proc, - release_context); + return SkImages::TextureFromYUVATextures( + context, yuva_backend_textures, sk_color_space, texture_release_proc, + release_context); } } @@ -325,7 +327,7 @@ auto alpha_type = SkAlphaType::kOpaque_SkAlphaType; auto color_type = viz::ToClosestSkColorType(/*gpu_compositing=*/true, format, plane_index); - return SkImage::MakeFromTexture( + return SkImages::BorrowTextureFrom( context, promise_image_texture(plane_index)->backendTexture(), surface_origin, color_type, alpha_type, /*sk_color_space=*/nullptr); }
diff --git a/gpu/command_buffer/service/shared_image/test_utils.cc b/gpu/command_buffer/service/shared_image/test_utils.cc index 7e152ab..800f1ce 100644 --- a/gpu/command_buffer/service/shared_image/test_utils.cc +++ b/gpu/command_buffer/service/shared_image/test_utils.cc
@@ -9,8 +9,10 @@ #include "gpu/command_buffer/service/shared_image/shared_image_factory.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/core/SkColorSpace.h" +#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkPromiseImageTexture.h" #include "third_party/skia/include/gpu/GrBackendSemaphore.h" +#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h" #include "ui/gfx/geometry/size.h" namespace gpu { @@ -41,7 +43,7 @@ EXPECT_EQ(size.height(), backend_texture.height()); // Create an Sk Image from GrBackendTexture. - auto sk_image = SkImage::MakeFromTexture( + auto sk_image = SkImages::BorrowTextureFrom( context_state->gr_context(), promise_texture->backendTexture(), kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kOpaque_SkAlphaType, nullptr);
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 4555f39f..bbeba3e 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
@@ -24,8 +24,10 @@ #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkColorType.h" +#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkPromiseImageTexture.h" #include "third_party/skia/include/gpu/GrBackendSemaphore.h" +#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_share_group.h" #include "ui/gl/gl_surface.h" @@ -226,7 +228,7 @@ // Readback via Skia API and verify it's the same pixels that were uploaded. SkColorType color_type = ToClosestSkColorType(true, format, plane); - auto sk_image = SkImage::MakeFromTexture( + auto sk_image = SkImages::BorrowTextureFrom( context_state_->gr_context(), promise_texture->backendTexture(), kSurfaceOrigin, color_type, kAlphaType, nullptr); ASSERT_TRUE(sk_image);
diff --git a/gpu/command_buffer/service/skia_utils.h b/gpu/command_buffer/service/skia_utils.h index 43e638f..09ca7d98 100644 --- a/gpu/command_buffer/service/skia_utils.h +++ b/gpu/command_buffer/service/skia_utils.h
@@ -26,6 +26,8 @@ typedef unsigned int GLuint; class GrBackendTexture; +class GrContextThreadSafeProxy; +class SkImage; namespace gfx { class Size;
diff --git "a/infra/config/generated/builders/ci/Linux Builder \050reclient compare\051/properties.json" "b/infra/config/generated/builders/ci/Linux Builder \050reclient compare\051/properties.json" index e0c12d2..fee13b9 100644 --- "a/infra/config/generated/builders/ci/Linux Builder \050reclient compare\051/properties.json" +++ "b/infra/config/generated/builders/ci/Linux Builder \050reclient compare\051/properties.json"
@@ -41,12 +41,14 @@ } }, "$build/reclient": { + "bootstrap_env": { + "RBE_compression_threshold": "4000000" + }, "ensure_verified": true, "instance": "rbe-chromium-trusted-test", "metrics_project": "chromium-reclient-metrics", "rewrapper_env": { - "RBE_compare": "true", - "RBE_compression_threshold": "4000000" + "RBE_compare": "true" } }, "$recipe_engine/resultdb/test_presentation": {
diff --git "a/infra/config/generated/builders/ci/Mac Builder \050reclient compare\051/properties.json" "b/infra/config/generated/builders/ci/Mac Builder \050reclient compare\051/properties.json" index 2024a5e3..e858b6c9 100644 --- "a/infra/config/generated/builders/ci/Mac Builder \050reclient compare\051/properties.json" +++ "b/infra/config/generated/builders/ci/Mac Builder \050reclient compare\051/properties.json"
@@ -42,12 +42,14 @@ } }, "$build/reclient": { + "bootstrap_env": { + "RBE_compression_threshold": "4000000" + }, "ensure_verified": true, "instance": "rbe-chromium-trusted-test", "metrics_project": "chromium-reclient-metrics", "rewrapper_env": { - "RBE_compare": "true", - "RBE_compression_threshold": "4000000" + "RBE_compare": "true" }, "scandeps_server": true },
diff --git "a/infra/config/generated/builders/ci/Mac Builder \050reclient\051/properties.json" "b/infra/config/generated/builders/ci/Mac Builder \050reclient\051/properties.json" index 946fc15..0ecc08e 100644 --- "a/infra/config/generated/builders/ci/Mac Builder \050reclient\051/properties.json" +++ "b/infra/config/generated/builders/ci/Mac Builder \050reclient\051/properties.json"
@@ -42,11 +42,11 @@ } }, "$build/reclient": { - "instance": "rbe-chromium-trusted-test", - "metrics_project": "chromium-reclient-metrics", - "rewrapper_env": { + "bootstrap_env": { "RBE_compression_threshold": "4000000" }, + "instance": "rbe-chromium-trusted-test", + "metrics_project": "chromium-reclient-metrics", "scandeps_server": true }, "$recipe_engine/resultdb/test_presentation": {
diff --git "a/infra/config/generated/builders/ci/Win x64 Builder \050reclient compare\051/properties.json" "b/infra/config/generated/builders/ci/Win x64 Builder \050reclient compare\051/properties.json" index c2e261d..48039dd 100644 --- "a/infra/config/generated/builders/ci/Win x64 Builder \050reclient compare\051/properties.json" +++ "b/infra/config/generated/builders/ci/Win x64 Builder \050reclient compare\051/properties.json"
@@ -41,12 +41,14 @@ } }, "$build/reclient": { + "bootstrap_env": { + "RBE_compression_threshold": "4000000" + }, "ensure_verified": true, "instance": "rbe-chromium-trusted-test", "metrics_project": "chromium-reclient-metrics", "rewrapper_env": { - "RBE_compare": "true", - "RBE_compression_threshold": "4000000" + "RBE_compare": "true" } }, "$recipe_engine/resultdb/test_presentation": {
diff --git "a/infra/config/generated/builders/ci/Win x64 Builder \050reclient\051/properties.json" "b/infra/config/generated/builders/ci/Win x64 Builder \050reclient\051/properties.json" index fd5ef1db..6899cc32 100644 --- "a/infra/config/generated/builders/ci/Win x64 Builder \050reclient\051/properties.json" +++ "b/infra/config/generated/builders/ci/Win x64 Builder \050reclient\051/properties.json"
@@ -42,11 +42,11 @@ } }, "$build/reclient": { - "instance": "rbe-chromium-trusted-test", - "metrics_project": "chromium-reclient-metrics", - "rewrapper_env": { + "bootstrap_env": { "RBE_compression_threshold": "4000000" - } + }, + "instance": "rbe-chromium-trusted-test", + "metrics_project": "chromium-reclient-metrics" }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [],
diff --git a/infra/config/generated/cq-builders.md b/infra/config/generated/cq-builders.md index c778102..3a2a915 100644 --- a/infra/config/generated/cq-builders.md +++ b/infra/config/generated/cq-builders.md
@@ -20,6 +20,8 @@ ### chrome * [linux-chromeos-compile-chrome](https://ci.chromium.org/p/chrome/builders/try/linux-chromeos-compile-chrome) ([definition](https://source.corp.google.com/search?q=+file:/try/.*\.star$+""linux-chromeos-compile-chrome"")) +* [win-branded-compile-rel](https://ci.chromium.org/p/chrome/builders/try/win-branded-compile-rel) ([definition](https://source.corp.google.com/search?q=+file:/try/.*\.star$+""win-branded-compile-rel"")) + ### chromium * [android-12-x64-rel](https://ci.chromium.org/p/chromium/builders/try/android-12-x64-rel) ([definition](https://cs.chromium.org/search?q=+file:/try/.*\.star$+""android-12-x64-rel"")) @@ -538,9 +540,6 @@ Location filters: * [`//third_party/nearby/README.chromium`](https://cs.chromium.org/search?q=+file:third_party/nearby/README.chromium) -* [win-branded-compile-rel](https://ci.chromium.org/p/chrome/builders/try/win-branded-compile-rel) ([definition](https://source.corp.google.com/search?q=+file:/try/.*\.star$+""win-branded-compile-rel"")) - * Experiment percentage: 100.0 - ### chromium * [linux-1mbu-compile-fyi-rel](https://ci.chromium.org/p/chromium/builders/try/linux-1mbu-compile-fyi-rel) ([definition](https://cs.chromium.org/search?q=+file:/try/.*\.star$+""linux-1mbu-compile-fyi-rel"")) * Experiment percentage: 5.0
diff --git a/infra/config/generated/cq-usage/default.cfg b/infra/config/generated/cq-usage/default.cfg index cb0ffc7..e9763a4 100644 --- a/infra/config/generated/cq-usage/default.cfg +++ b/infra/config/generated/cq-usage/default.cfg
@@ -19,6 +19,9 @@ name: "chrome/try/linux-chromeos-compile-chrome" } builders { + name: "chrome/try/win-branded-compile-rel" + } + builders { name: "chromium/try/android-12-x64-rel" } builders {
diff --git a/infra/config/generated/cq-usage/full.cfg b/infra/config/generated/cq-usage/full.cfg index c07be489..c94f2c7 100644 --- a/infra/config/generated/cq-usage/full.cfg +++ b/infra/config/generated/cq-usage/full.cfg
@@ -39,6 +39,21 @@ } } builders { + name: "chrome/try/win-branded-compile-rel" + location_filters { + gerrit_host_regexp: ".*" + gerrit_project_regexp: ".*" + path_regexp: "docs/.+" + exclude: true + } + location_filters { + gerrit_host_regexp: ".*" + gerrit_project_regexp: ".*" + path_regexp: "infra/config/.+" + exclude: true + } + } + builders { name: "chromium/try/3pp-linux-amd64-packager" location_filters { gerrit_host_regexp: ".*"
diff --git a/infra/config/generated/luci/commit-queue.cfg b/infra/config/generated/luci/commit-queue.cfg index 5627621..ef15462 100644 --- a/infra/config/generated/luci/commit-queue.cfg +++ b/infra/config/generated/luci/commit-queue.cfg
@@ -272,7 +272,6 @@ builders { name: "chrome/try/win-branded-compile-rel" result_visibility: COMMENT_LEVEL_RESTRICTED - experiment_percentage: 100 location_filters { gerrit_host_regexp: ".*" gerrit_project_regexp: ".*"
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg index 4fe6534f..de9f8527 100644 --- a/infra/config/generated/luci/cr-buildbucket.cfg +++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -3550,7 +3550,7 @@ ' "RBE_ip_reset_min_delay": "-1s"' ' },' ' "cache_silo": "Comparison Android - cache siloed",' - ' "instance": "rbe-chromium-trusted",' + ' "instance": "rbe-chromium-trusted-test",' ' "jobs": 250,' ' "metrics_project": "chromium-reclient-metrics"' ' },' @@ -3634,7 +3634,7 @@ ' "RBE_ip_reset_min_delay": "-1s"' ' },' ' "cache_silo": "Comparison Android (reproxy cache) - cache siloed",' - ' "instance": "rbe-chromium-trusted",' + ' "instance": "rbe-chromium-trusted-test",' ' "jobs": 250,' ' "metrics_project": "chromium-reclient-metrics"' ' },' @@ -3802,7 +3802,7 @@ ' "RBE_ip_reset_min_delay": "-1s"' ' },' ' "cache_silo": "Comparison Linux - cache siloed",' - ' "instance": "rbe-chromium-trusted",' + ' "instance": "rbe-chromium-trusted-test",' ' "jobs": 250,' ' "metrics_project": "chromium-reclient-metrics"' ' },' @@ -4303,7 +4303,7 @@ ' "RBE_ip_reset_min_delay": "-1s"' ' },' ' "cache_silo": "Comparison Simple Chrome - cache siloed",' - ' "instance": "rbe-chromium-trusted",' + ' "instance": "rbe-chromium-trusted-test",' ' "jobs": 250,' ' "metrics_project": "chromium-reclient-metrics"' ' },' @@ -4470,7 +4470,7 @@ ' "RBE_ip_reset_min_delay": "-1s"' ' },' ' "cache_silo": "Comparison Windows 8 cores - cache siloed",' - ' "instance": "rbe-chromium-trusted",' + ' "instance": "rbe-chromium-trusted-test",' ' "jobs": 80,' ' "metrics_project": "chromium-reclient-metrics"' ' },' @@ -4553,7 +4553,7 @@ ' "RBE_ip_reset_min_delay": "-1s"' ' },' ' "cache_silo": "Comparison Windows - cache siloed",' - ' "instance": "rbe-chromium-trusted",' + ' "instance": "rbe-chromium-trusted-test",' ' "jobs": 250,' ' "metrics_project": "chromium-reclient-metrics"' ' },'
diff --git a/infra/config/subprojects/chrome/try.star b/infra/config/subprojects/chrome/try.star index bae99e6d..eb9c6d8 100644 --- a/infra/config/subprojects/chrome/try.star +++ b/infra/config/subprojects/chrome/try.star
@@ -67,10 +67,7 @@ chrome_internal_verifier( builder = "win-branded-compile-rel", - tryjob = try_.job( - # TODO(crbug.com/1259887): Promote out of experimental. - experiment_percentage = 100, - ), + tryjob = try_.job(), ) ### Optional builders ###
diff --git a/infra/config/subprojects/chromium/ci/chromium.fyi.star b/infra/config/subprojects/chromium/ci/chromium.fyi.star index 65775b0..96370e9c 100644 --- a/infra/config/subprojects/chromium/ci/chromium.fyi.star +++ b/infra/config/subprojects/chromium/ci/chromium.fyi.star
@@ -1167,6 +1167,7 @@ "RBE_deps_cache_mode": "reproxy", }, reclient_cache_silo = "Comparison Android - cache siloed", + reclient_instance = reclient.instance.TEST_TRUSTED, ) ci.builder( @@ -1191,6 +1192,7 @@ "RBE_deps_cache_mode": "reproxy", }, reclient_cache_silo = "Comparison Android (reproxy cache) - cache siloed", + reclient_instance = reclient.instance.TEST_TRUSTED, ) ci.builder( @@ -1208,6 +1210,7 @@ "RBE_deps_cache_mode": "reproxy", }, reclient_cache_silo = "Comparison Linux - cache siloed", + reclient_instance = reclient.instance.TEST_TRUSTED, ) fyi_mac_builder( @@ -1288,6 +1291,7 @@ "RBE_deps_cache_mode": "reproxy", }, reclient_cache_silo = "Comparison Windows 8 cores - cache siloed", + reclient_instance = reclient.instance.TEST_TRUSTED, reclient_jobs = 80, ) @@ -1309,6 +1313,7 @@ "RBE_deps_cache_mode": "reproxy", }, reclient_cache_silo = "Comparison Windows - cache siloed", + reclient_instance = reclient.instance.TEST_TRUSTED, ) ci.builder( @@ -1327,6 +1332,7 @@ "RBE_deps_cache_mode": "reproxy", }, reclient_cache_silo = "Comparison Simple Chrome - cache siloed", + reclient_instance = reclient.instance.TEST_TRUSTED, ) fyi_mac_builder( @@ -1671,12 +1677,14 @@ short_name = "re", ), execution_timeout = 14 * time.hour, + reclient_bootstrap_env = { + "RBE_compression_threshold": "4000000", + }, reclient_ensure_verified = True, reclient_instance = reclient.instance.TEST_TRUSTED, reclient_jobs = None, reclient_rewrapper_env = { "RBE_compare": "true", - "RBE_compression_threshold": "4000000", }, ) @@ -1705,11 +1713,11 @@ category = "win", short_name = "re", ), - reclient_instance = reclient.instance.TEST_TRUSTED, - reclient_jobs = None, - reclient_rewrapper_env = { + reclient_bootstrap_env = { "RBE_compression_threshold": "4000000", }, + reclient_instance = reclient.instance.TEST_TRUSTED, + reclient_jobs = None, ) ci.builder( @@ -1734,12 +1742,14 @@ category = "win", short_name = "re", ), + reclient_bootstrap_env = { + "RBE_compression_threshold": "4000000", + }, reclient_ensure_verified = True, reclient_instance = reclient.instance.TEST_TRUSTED, reclient_jobs = None, reclient_rewrapper_env = { "RBE_compare": "true", - "RBE_compression_threshold": "4000000", }, ) @@ -1768,11 +1778,11 @@ category = "mac", short_name = "re", ), - reclient_instance = reclient.instance.TEST_TRUSTED, - reclient_jobs = None, - reclient_rewrapper_env = { + reclient_bootstrap_env = { "RBE_compression_threshold": "4000000", }, + reclient_instance = reclient.instance.TEST_TRUSTED, + reclient_jobs = None, ) fyi_mac_builder( @@ -1801,12 +1811,14 @@ short_name = "cmp", ), execution_timeout = 14 * time.hour, + reclient_bootstrap_env = { + "RBE_compression_threshold": "4000000", + }, reclient_ensure_verified = True, reclient_instance = reclient.instance.TEST_TRUSTED, reclient_jobs = None, reclient_rewrapper_env = { "RBE_compare": "true", - "RBE_compression_threshold": "4000000", }, )
diff --git a/ios/chrome/app/BUILD.gn b/ios/chrome/app/BUILD.gn index 43fd03f..173041c4 100644 --- a/ios/chrome/app/BUILD.gn +++ b/ios/chrome/app/BUILD.gn
@@ -481,6 +481,7 @@ "//ios/chrome/browser/omaha", "//ios/chrome/browser/passwords", "//ios/chrome/browser/paths", + "//ios/chrome/browser/promos_manager:factory", "//ios/chrome/browser/push_notification:push_notification_service", "//ios/chrome/browser/reading_list", "//ios/chrome/browser/screenshot",
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm index bf79442..c6fe2b0 100644 --- a/ios/chrome/app/main_controller.mm +++ b/ios/chrome/app/main_controller.mm
@@ -90,6 +90,7 @@ #import "ios/chrome/browser/omaha/omaha_service.h" #import "ios/chrome/browser/passwords/password_manager_util_ios.h" #import "ios/chrome/browser/paths/paths.h" +#import "ios/chrome/browser/promos_manager/promos_manager_factory.h" #import "ios/chrome/browser/screenshot/screenshot_metrics_recorder.h" #import "ios/chrome/browser/search_engines/extension_search_engine_data_updater.h" #import "ios/chrome/browser/search_engines/search_engines_util.h" @@ -498,15 +499,16 @@ [NSURLCache setSharedURLCache:[EmptyNSURLCache emptyNSURLCache]]; + ChromeBrowserState* browserState = self.appState.mainBrowserState; + DCHECK(browserState); [self.appState - addAgent:[[PostRestoreAppAgent alloc] - initWithPromosManager:GetApplicationContext() - ->GetPromosManager() - authenticationService:AuthenticationServiceFactory:: - GetForBrowserState( - self.appState.mainBrowserState) - localState:GetApplicationContext() - ->GetLocalState()]]; + addAgent: + [[PostRestoreAppAgent alloc] + initWithPromosManager:PromosManagerFactory::GetForBrowserState( + browserState) + authenticationService:AuthenticationServiceFactory:: + GetForBrowserState(browserState) + localState:GetApplicationContext()->GetLocalState()]]; } // This initialization must happen before any windows are created.
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index f62ca4b2..f1d5d96 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -551,6 +551,43 @@ <message name="IDS_IOS_BOTTOM_TOOLBAR_IPH_PROMOTION_TEXT" desc="Text for the Bottom Toolbar Tip in-product help promotion, explaining that the bottom toolbar can be used to focus the Search Bar, instead of having to reach to the top toolbar. [iOS only]"> Search bar is now easier to reach </message> + <message name="IDS_IOS_BRING_ANDROID_TABS_CANCEL_BUTTON" desc="Button to dismiss the 'Bring Android Tabs' prompt. [iOS only]"> + Cancel + </message> + <message name="IDS_IOS_BRING_ANDROID_TABS_PROMPT_OPEN_TABS_BUTTON" desc="Button to open on the current device all the Android switcher's recently active tabs from Android. [iOS only]"> + {count, plural, + =1 {Open the tab} + other {Open {count} tabs}} + </message> + <message name="IDS_IOS_BRING_ANDROID_TABS_PROMPT_REVIEW_TABS_BUTTON_BOTTOM_MESSAGE" desc="Button shown on the prompt (bottom message version) for Android switchers to bring up a table of the user's recently active tabs from Android. [iOS only]"> + {count, plural, + =1 {Review the tab} + other {Review all tabs}} + </message> + <message name="IDS_IOS_BRING_ANDROID_TABS_PROMPT_REVIEW_TABS_BUTTON_CONFIRMATION_ALERT" desc="Button shown on the prompt (confirmation alert version) for Android switchers to bring up a table of the user's recently active tabs from Android. [iOS only]"> + {count, plural, + =1 {Review the tab...} + other {Review all tabs...}} + </message> + <message name="IDS_IOS_BRING_ANDROID_TABS_PROMPT_SUBTITLE" desc="Subtitle of the 'Bring Android Tabs' prompt shown to Android switchers to review their recently active tabs from Android. [iOS only]"> + {count, plural, + =1 {Get your {count} recently active tab from your other device on this iPhone} + other {Get your {count} recently active tabs from your other device on this iPhone}} + </message> + <message name="IDS_IOS_BRING_ANDROID_TABS_PROMPT_TITLE" desc="Title of the 'Bring Android Tabs' prompt shown to Android switchers to review their recently active tabs from Android. [iOS only]"> + {count, plural, + =1 {Pick up the tab you left off from Android?} + other {Pick up the tabs you left off from Android?}} + </message> + <message name="IDS_IOS_BRING_ANDROID_TABS_REVIEW_TABLE_OPEN_BUTTON" desc="Button to open selected tabs imported from Android. [iOS only]"> + {count, plural, + =0 {Open {count} tab} + =1 {Open {count} tab} + other {Open {count} tabs}} + </message> + <message name="IDS_IOS_BRING_ANDROID_TABS_REVIEW_TABLE_TITLE" desc="Title of the table that shows a list of recently active tabs from Android for the Android switcher to review and open. [iOS only]"> + Tabs from Android + </message> <message name="IDS_IOS_CALENDARS_USAGE_DESCRIPTION" desc="Specifies the reason for accessing the user's calendar while the app is in use [Length: unlimited] [iOS only]."> This will be used to create events in your Apple Calendar from Chrome and Google Lens. </message> @@ -1220,6 +1257,23 @@ <message name="IDS_IOS_INACTIVE_TABS_BUTTON_SUBTITLE" desc="Subtitle of the button in the Tab Grid that opens the grid of Inactive Tabs."> Tabs not used for <ph name="THRESHOLD">$1<ex>14</ex></ph> days </message> + <message name="IDS_IOS_INACTIVE_TABS_CLOSE_ALL_BUTTON" desc="Title of the Close All Inactive button in the grid of Inactive Tabs."> + Close All Inactive + </message> + <message name="IDS_IOS_INACTIVE_TABS_CLOSE_ALL_CONFIRMATION" desc="Title of the confirmation dialog that offers to close all inactive tabs. COUNT refers to the number of inactive tabs present. According to its value, the string goes from singular to plural."> + {COUNT, plural, + =1 {Close {COUNT} Inactive Tab?} + other {Close {COUNT} Inactive Tabs?}} + </message> + <message name="IDS_IOS_INACTIVE_TABS_CLOSE_ALL_CONFIRMATION_MANY" desc="Title of the confirmation dialog that offers to close all inactive tabs. This is used instead of IDS_IOS_INACTIVE_TABS_CLOSE_ALL_CONFIRMATION when there are more than 99 inactive tabs present."> + Close 99+ Inactive Tabs? + </message> + <message name="IDS_IOS_INACTIVE_TABS_CLOSE_ALL_CONFIRMATION_MESSAGE" desc="Message of the confimation dialog when the user wants to close all tabs in the grid of Inactive Tabs."> + You can always get them back in history. + </message> + <message name="IDS_IOS_INACTIVE_TABS_CLOSE_ALL_CONFIRMATION_OPTION" desc="Title of the action that will close all tabs in the grid of Inactive Tabs."> + Close All + </message> <message name="IDS_IOS_INCOGNITO_INTERSTITIAL_LEARN_MORE_HINT" desc="Accessibility hint for the 'Learn more' button in the incognito NTP [iOS only]"> Learn more about Incognito mode </message> @@ -2373,10 +2427,10 @@ <message name="IDS_IOS_SNACKBAR_MESSAGE_UNPINNED_TAB" desc="The iOS snackbar message when a tab has been unpinned. [iOS only]"> Tab Unpinned </message> - <message name="IDS_IOS_SNACKBAR_MESSAGE_ICOGNITO_DISABLED" desc="The material toast message when incogonito mode is disabled by policy [iOS only]."> + <message name="IDS_IOS_SNACKBAR_MESSAGE_INCOGNITO_DISABLED" desc="The material toast message when incogonito mode is disabled by policy [iOS only]."> Your organization turned off Incognito mode </message> - <message name="IDS_IOS_SNACKBAR_MESSAGE_ICOGNITO_FORCED" desc="The material toast message when incogonito mode is forced by policy [iOS only]."> + <message name="IDS_IOS_SNACKBAR_MESSAGE_INCOGNITO_FORCED" desc="The material toast message when incogonito mode is forced by policy [iOS only]."> Your organization requires Incognito mode </message> <message name="IDS_IOS_TOOLS_MENU_CELL_NEW_FEATURE_BADGE" desc="Title and accessibility label of the badge displayed on a tools menu item when it represents a new feature [Length: 20em]" meaning="A badge with this title is displayed informing the user that this feature that is new to them.">
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_BRING_ANDROID_TABS_CANCEL_BUTTON.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_BRING_ANDROID_TABS_CANCEL_BUTTON.png.sha1 new file mode 100644 index 0000000..312fc9e --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_BRING_ANDROID_TABS_CANCEL_BUTTON.png.sha1
@@ -0,0 +1 @@ +8568378f9e373df816ad9d8a711ba89d42af85a4 \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_BRING_ANDROID_TABS_PROMPT_OPEN_TABS_BUTTON.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_BRING_ANDROID_TABS_PROMPT_OPEN_TABS_BUTTON.png.sha1 new file mode 100644 index 0000000..312fc9e --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_BRING_ANDROID_TABS_PROMPT_OPEN_TABS_BUTTON.png.sha1
@@ -0,0 +1 @@ +8568378f9e373df816ad9d8a711ba89d42af85a4 \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_BRING_ANDROID_TABS_PROMPT_REVIEW_TABS_BUTTON_BOTTOM_MESSAGE.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_BRING_ANDROID_TABS_PROMPT_REVIEW_TABS_BUTTON_BOTTOM_MESSAGE.png.sha1 new file mode 100644 index 0000000..312fc9e --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_BRING_ANDROID_TABS_PROMPT_REVIEW_TABS_BUTTON_BOTTOM_MESSAGE.png.sha1
@@ -0,0 +1 @@ +8568378f9e373df816ad9d8a711ba89d42af85a4 \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_BRING_ANDROID_TABS_PROMPT_REVIEW_TABS_BUTTON_CONFIRMATION_ALERT.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_BRING_ANDROID_TABS_PROMPT_REVIEW_TABS_BUTTON_CONFIRMATION_ALERT.png.sha1 new file mode 100644 index 0000000..937f619 --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_BRING_ANDROID_TABS_PROMPT_REVIEW_TABS_BUTTON_CONFIRMATION_ALERT.png.sha1
@@ -0,0 +1 @@ +ccab4c49805f230a0db791ae9ecadd1f31ad4a8c \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_BRING_ANDROID_TABS_PROMPT_SUBTITLE.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_BRING_ANDROID_TABS_PROMPT_SUBTITLE.png.sha1 new file mode 100644 index 0000000..312fc9e --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_BRING_ANDROID_TABS_PROMPT_SUBTITLE.png.sha1
@@ -0,0 +1 @@ +8568378f9e373df816ad9d8a711ba89d42af85a4 \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_BRING_ANDROID_TABS_PROMPT_TITLE.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_BRING_ANDROID_TABS_PROMPT_TITLE.png.sha1 new file mode 100644 index 0000000..312fc9e --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_BRING_ANDROID_TABS_PROMPT_TITLE.png.sha1
@@ -0,0 +1 @@ +8568378f9e373df816ad9d8a711ba89d42af85a4 \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_BRING_ANDROID_TABS_REVIEW_TABLE_OPEN_BUTTON.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_BRING_ANDROID_TABS_REVIEW_TABLE_OPEN_BUTTON.png.sha1 new file mode 100644 index 0000000..93b6135d --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_BRING_ANDROID_TABS_REVIEW_TABLE_OPEN_BUTTON.png.sha1
@@ -0,0 +1 @@ +cd2dde030097cd27b8a8c3818813ea4c56c052cc \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_BRING_ANDROID_TABS_REVIEW_TABLE_TITLE.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_BRING_ANDROID_TABS_REVIEW_TABLE_TITLE.png.sha1 new file mode 100644 index 0000000..93b6135d --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_BRING_ANDROID_TABS_REVIEW_TABLE_TITLE.png.sha1
@@ -0,0 +1 @@ +cd2dde030097cd27b8a8c3818813ea4c56c052cc \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_INACTIVE_TABS_CLOSE_ALL_BUTTON.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_INACTIVE_TABS_CLOSE_ALL_BUTTON.png.sha1 new file mode 100644 index 0000000..ae8d1425 --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_INACTIVE_TABS_CLOSE_ALL_BUTTON.png.sha1
@@ -0,0 +1 @@ +e487782b6a5563cc1b78037b8ee4cfe7ffbc60a3 \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_INACTIVE_TABS_CLOSE_ALL_CONFIRMATION.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_INACTIVE_TABS_CLOSE_ALL_CONFIRMATION.png.sha1 new file mode 100644 index 0000000..6763708 --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_INACTIVE_TABS_CLOSE_ALL_CONFIRMATION.png.sha1
@@ -0,0 +1 @@ +831151de4dcccd1654420c0267933b361d60dc0e \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_INACTIVE_TABS_CLOSE_ALL_CONFIRMATION_MANY.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_INACTIVE_TABS_CLOSE_ALL_CONFIRMATION_MANY.png.sha1 new file mode 100644 index 0000000..6763708 --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_INACTIVE_TABS_CLOSE_ALL_CONFIRMATION_MANY.png.sha1
@@ -0,0 +1 @@ +831151de4dcccd1654420c0267933b361d60dc0e \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_INACTIVE_TABS_CLOSE_ALL_CONFIRMATION_MESSAGE.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_INACTIVE_TABS_CLOSE_ALL_CONFIRMATION_MESSAGE.png.sha1 new file mode 100644 index 0000000..6763708 --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_INACTIVE_TABS_CLOSE_ALL_CONFIRMATION_MESSAGE.png.sha1
@@ -0,0 +1 @@ +831151de4dcccd1654420c0267933b361d60dc0e \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_INACTIVE_TABS_CLOSE_ALL_CONFIRMATION_OPTION.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_INACTIVE_TABS_CLOSE_ALL_CONFIRMATION_OPTION.png.sha1 new file mode 100644 index 0000000..6763708 --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_INACTIVE_TABS_CLOSE_ALL_CONFIRMATION_OPTION.png.sha1
@@ -0,0 +1 @@ +831151de4dcccd1654420c0267933b361d60dc0e \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SNACKBAR_MESSAGE_ICOGNITO_DISABLED.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SNACKBAR_MESSAGE_INCOGNITO_DISABLED.png.sha1 similarity index 100% rename from ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SNACKBAR_MESSAGE_ICOGNITO_DISABLED.png.sha1 rename to ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SNACKBAR_MESSAGE_INCOGNITO_DISABLED.png.sha1
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SNACKBAR_MESSAGE_ICOGNITO_FORCED.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SNACKBAR_MESSAGE_INCOGNITO_FORCED.png.sha1 similarity index 100% rename from ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SNACKBAR_MESSAGE_ICOGNITO_FORCED.png.sha1 rename to ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SNACKBAR_MESSAGE_INCOGNITO_FORCED.png.sha1
diff --git a/ios/chrome/browser/application_context/BUILD.gn b/ios/chrome/browser/application_context/BUILD.gn index fae6a087..150b880 100644 --- a/ios/chrome/browser/application_context/BUILD.gn +++ b/ios/chrome/browser/application_context/BUILD.gn
@@ -52,8 +52,6 @@ "//ios/chrome/browser/prefs", "//ios/chrome/browser/prefs:browser_prefs", "//ios/chrome/browser/prefs:pref_names", - "//ios/chrome/browser/promos_manager:features", - "//ios/chrome/browser/promos_manager:internal", "//ios/chrome/browser/push_notification:push_notification_service", "//ios/chrome/browser/segmentation_platform", "//ios/chrome/browser/update_client",
diff --git a/ios/chrome/browser/application_context/application_context.h b/ios/chrome/browser/application_context/application_context.h index dfbaf565..aa272ed 100644 --- a/ios/chrome/browser/application_context/application_context.h +++ b/ios/chrome/browser/application_context/application_context.h
@@ -66,7 +66,6 @@ class ApplicationContext; class BrowserPolicyConnectorIOS; -class PromosManager; class IOSChromeIOThread; class PrefService; class PushNotificationService; @@ -164,9 +163,6 @@ // system. May be null if policy is not enabled. virtual BrowserPolicyConnectorIOS* GetBrowserPolicyConnector() = 0; - // Gets the Fullscreen Promos Manager. - virtual PromosManager* GetPromosManager() = 0; - // Returns the SingleSignOnService instance used by this application. virtual id<SingleSignOnService> GetSSOService() = 0;
diff --git a/ios/chrome/browser/application_context/application_context_impl.h b/ios/chrome/browser/application_context/application_context_impl.h index 842c60b..3a5f4a0 100644 --- a/ios/chrome/browser/application_context/application_context_impl.h +++ b/ios/chrome/browser/application_context/application_context_impl.h
@@ -38,6 +38,9 @@ // Called before the browser threads are created. void PreCreateThreads(); + // Called after the browser threads are created. + void PostCreateThreads(); + // Called after the threads have been created but before the message loops // starts running. Allows the ApplicationContext to do any initialization // that requres all threads running. @@ -76,7 +79,6 @@ SafeBrowsingService* GetSafeBrowsingService() override; network::NetworkConnectionTracker* GetNetworkConnectionTracker() override; BrowserPolicyConnectorIOS* GetBrowserPolicyConnector() override; - PromosManager* GetPromosManager() override; id<SingleSignOnService> GetSSOService() override; SystemIdentityManager* GetSystemIdentityManager() override; segmentation_platform::OTRWebStateObserver* @@ -105,9 +107,6 @@ // service, the policy connector must live outside the keyed services. std::unique_ptr<BrowserPolicyConnectorIOS> browser_policy_connector_; - // Promos Manager which coordinates the display of app-wide promos. - std::unique_ptr<PromosManager> promos_manager_; - std::unique_ptr<PrefService> local_state_; std::unique_ptr<net_log::NetExportFileWriter> net_export_file_writer_; std::unique_ptr<network_time::NetworkTimeTracker> network_time_tracker_;
diff --git a/ios/chrome/browser/application_context/application_context_impl.mm b/ios/chrome/browser/application_context/application_context_impl.mm index 00bbda7..43a5f4e88 100644 --- a/ios/chrome/browser/application_context/application_context_impl.mm +++ b/ios/chrome/browser/application_context/application_context_impl.mm
@@ -58,8 +58,6 @@ #import "ios/chrome/browser/prefs/browser_prefs.h" #import "ios/chrome/browser/prefs/ios_chrome_pref_service_factory.h" #import "ios/chrome/browser/prefs/pref_names.h" -#import "ios/chrome/browser/promos_manager/features.h" -#import "ios/chrome/browser/promos_manager/promos_manager_impl.h" #import "ios/chrome/browser/push_notification/push_notification_service.h" #import "ios/chrome/browser/segmentation_platform/otr_web_state_observer.h" #import "ios/chrome/browser/update_client/ios_chrome_update_query_params_delegate.h" @@ -145,6 +143,12 @@ new IOSChromeIOThread(GetLocalState(), GetNetLog())); } +void ApplicationContextImpl::PostCreateThreads() { + web::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&IOSChromeIOThread::InitOnIO, + base::Unretained(ios_chrome_io_thread_.get()))); +} + void ApplicationContextImpl::PreMainMessageLoopRun() { DCHECK(thread_checker_.CalledOnValidThread()); @@ -481,15 +485,6 @@ return browser_policy_connector_.get(); } -PromosManager* ApplicationContextImpl::GetPromosManager() { - DCHECK(thread_checker_.CalledOnValidThread()); - if (!promos_manager_) { - promos_manager_ = std::make_unique<PromosManagerImpl>( - GetLocalState(), base::DefaultClock::GetInstance()); - } - return promos_manager_.get(); -} - id<SingleSignOnService> ApplicationContextImpl::GetSSOService() { DCHECK(thread_checker_.CalledOnValidThread()); if (!single_sign_on_service_) {
diff --git a/ios/chrome/browser/bring_android_tabs/BUILD.gn b/ios/chrome/browser/bring_android_tabs/BUILD.gn new file mode 100644 index 0000000..a368a553 --- /dev/null +++ b/ios/chrome/browser/bring_android_tabs/BUILD.gn
@@ -0,0 +1,51 @@ +# 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. + +source_set("bring_android_tabs") { + configs += [ "//build/config/compiler:enable_arc" ] + sources = [ + "bring_android_tabs_to_ios_service.h", + "bring_android_tabs_to_ios_service.mm", + "bring_android_tabs_to_ios_service_factory.h", + "bring_android_tabs_to_ios_service_factory.mm", + ] + deps = [ + ":features", + ":metrics", + "//base", + "//components/keyed_service/core", + "//components/keyed_service/ios", + "//components/pref_registry", + "//components/prefs", + "//components/segmentation_platform/embedder/default_model", + "//components/segmentation_platform/public", + "//components/sync/driver", + "//components/sync_device_info", + "//ios/chrome/browser/browser_state", + "//ios/chrome/browser/first_run", + "//ios/chrome/browser/flags:system_flags", + "//ios/chrome/browser/prefs:pref_names", + "//ios/chrome/browser/segmentation_platform", + "//ios/chrome/browser/sync", + "//ios/chrome/browser/synced_sessions", + ] +} + +source_set("features") { + configs += [ "//build/config/compiler:enable_arc" ] + sources = [ + "features.h", + "features.mm", + ] + deps = [ "//base" ] +} + +source_set("metrics") { + configs += [ "//build/config/compiler:enable_arc" ] + sources = [ + "metrics.h", + "metrics.mm", + ] + deps = [ "//base" ] +}
diff --git a/ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service.h b/ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service.h new file mode 100644 index 0000000..186fd67 --- /dev/null +++ b/ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service.h
@@ -0,0 +1,96 @@ +// 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 IOS_CHROME_BROWSER_BRING_ANDROID_TABS_BRING_ANDROID_TABS_TO_IOS_SERVICE_H_ +#define IOS_CHROME_BROWSER_BRING_ANDROID_TABS_BRING_ANDROID_TABS_TO_IOS_SERVICE_H_ + +#import <memory> +#import <vector> + +#import "components/keyed_service/core/keyed_service.h" + +class PrefService; + +namespace segmentation_platform { +class DeviceSwitcherResultDispatcher; +} // namespace segmentation_platform + +namespace syncer { +class SyncService; +} // namespace syncer + +namespace sync_sessions { +class SessionSyncService; +} // namespace sync_sessions + +namespace synced_sessions { +struct DistantTab; +class SyncedSessions; +} // namespace synced_sessions + +// Class that manages the life cycle of the "Bring tabs from Android" +// experience. +class BringAndroidTabsToIOSService : public KeyedService { + public: + explicit BringAndroidTabsToIOSService( + segmentation_platform::DeviceSwitcherResultDispatcher* dispatcher, + syncer::SyncService* sync_service, + sync_sessions::SessionSyncService* session_sync_service, + PrefService* browser_state_prefs); + + BringAndroidTabsToIOSService(const BringAndroidTabsToIOSService&) = delete; + BringAndroidTabsToIOSService& operator=(const BringAndroidTabsToIOSService&) = + delete; + + ~BringAndroidTabsToIOSService() override; + + // Loads the list of recent tabs brought from the user's last Android device + // into the service on demand. Could be called repeatedly to retrieve updated + // results. + void LoadTabs(); + + // Returns the number of recent tabs / the tab at the given index. + // `GetNumberOfAndroidTabs() > 0` could be used to determine whether the + // prompt should be shown or not. + // + // NOTE: Both method MUST be called after `LoadTabs()` is called; the + // returned values would be computed from the last call to `LoadTabs`. + virtual size_t GetNumberOfAndroidTabs() const; + virtual synced_sessions::DistantTab* GetTabAtIndex(size_t index) const; + + // Called when the Bring Android Tabs Prompt has been displayed. + virtual void OnBringAndroidTabsPromptDisplayed(); + + // Called when the user interacts with the Bring Android Tabs prompt. + virtual void OnUserInteractWithBringAndroidTabsPrompt(); + + private: + // Returns true if the prompt has been shown before invocation, and should not + // show again. + bool PromptShownAndShouldNotShowAgain() const; + // Loads the list of synced sessions and saves the positions of Android + // Switcher Tabs. Logs attempt status metric on UMA. + void LoadSyncedSessionsAndComputeTabPositions(); + + // Service dependencies. + segmentation_platform::DeviceSwitcherResultDispatcher* const + device_switcher_result_dispatcher_; + syncer::SyncService* const sync_service_; + sync_sessions::SessionSyncService* session_sync_service_; + PrefService* const browser_state_prefs_; + // Flag that marks whether `LoadTabs` has been invoked. + bool load_tabs_invoked_ = false; + + // Prompt is displayed in the current browsing session. + bool prompt_shown_current_session_ = false; + // The user has interacted with the prompt in the current browsing session. + bool prompt_interacted_ = false; + // All synced sessions. + std::unique_ptr<synced_sessions::SyncedSessions> synced_sessions_; + // Positions of recent tabs from the user's last Android device in + // `synced_sessions_`. + std::vector<std::tuple<size_t, size_t>> position_of_tabs_in_synced_sessions_; +}; + +#endif // IOS_CHROME_BROWSER_BRING_ANDROID_TABS_BRING_ANDROID_TABS_TO_IOS_SERVICE_H_
diff --git a/ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service.mm b/ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service.mm new file mode 100644 index 0000000..a8963ec --- /dev/null +++ b/ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service.mm
@@ -0,0 +1,228 @@ +// 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/bring_android_tabs/bring_android_tabs_to_ios_service.h" + +#import <string> + +#import "base/containers/contains.h" +#import "base/files/file.h" +#import "base/files/file_path.h" +#import "base/files/file_util.h" +#import "base/metrics/histogram_functions.h" +#import "base/time/time.h" +#import "components/prefs/pref_service.h" +#import "components/segmentation_platform/embedder/default_model/device_switcher_model.h" +#import "components/segmentation_platform/embedder/default_model/device_switcher_result_dispatcher.h" +#import "components/segmentation_platform/public/result.h" +#import "components/sync/base/sync_prefs.h" +#import "components/sync/driver/sync_service.h" +#import "components/sync/driver/sync_user_settings.h" +#import "components/sync_device_info/device_info.h" +#import "components/sync_sessions/session_sync_service.h" +#import "ios/chrome/browser/bring_android_tabs/features.h" +#import "ios/chrome/browser/bring_android_tabs/metrics.h" +#import "ios/chrome/browser/browser_state/chrome_browser_state.h" +#import "ios/chrome/browser/first_run/first_run.h" +#import "ios/chrome/browser/flags/system_flags.h" +#import "ios/chrome/browser/prefs/pref_names.h" +#import "ios/chrome/browser/synced_sessions/distant_session.h" +#import "ios/chrome/browser/synced_sessions/distant_tab.h" +#import "ios/chrome/browser/synced_sessions/synced_sessions.h" +#import "ui/base/device_form_factor.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace { + +using ::bring_android_tabs::kPromptAttemptStatusHistogramName; +using ::bring_android_tabs::PromptAttemptStatus; + +// The length of time from now in which the tabs will be brought over. +const base::TimeDelta kTimeRangeOfTabsImported = base::Days(14); + +// Logs `status` on UMA. +void RecordPromptAttemptStatus(PromptAttemptStatus status) { + base::UmaHistogramEnumeration(kPromptAttemptStatusHistogramName, status); +} + +// Returns true if the user is eligible for the Bring Android Tabs prompt. Logs +// attempt status metric on UMA if the user is NOT eligible. +bool UserEligibleForAndroidSwitcherPrompt() { + bool first_run = FirstRun::IsChromeFirstRun() || + experimental_flags::AlwaysDisplayFirstRun(); + if (!first_run) { + // Check the time of first run. + absl::optional<base::File::Info> info = FirstRun::GetSentinelInfo(); + if (info.has_value()) { + base::Time first_run_time = info.value().creation_time; + bool first_run_over_7_days_ago = + base::Time::Now() - first_run_time > base::Days(7); + if (first_run_over_7_days_ago) { + return false; + } + } + } + if (GetBringYourOwnTabsPromptType() == + BringYourOwnTabsPromptType::kDisabled) { + return false; + } + return ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_PHONE; +} + +// Returns true if the user is segmented as an Android switcher, either by +// the segmentation platform or by using the forced device switcher flag. If the +// user is NOT enrolled in sync or not identified as an Android switcher, this +// method logs so on histogram. +bool UserIsAndroidSwitcher( + segmentation_platform::DeviceSwitcherResultDispatcher* dispatcher) { + bool device_switcher_forced = + experimental_flags::GetSegmentForForcedDeviceSwitcherExperience() == + segmentation_platform::DeviceSwitcherModel::kAndroidPhoneLabel; + if (device_switcher_forced) { + return true; + } + + segmentation_platform::ClassificationResult result = + dispatcher->GetCachedClassificationResult(); + if (result.status != segmentation_platform::PredictionStatus::kSucceeded) { + RecordPromptAttemptStatus(PromptAttemptStatus::kSegmentationIncomplete); + return false; + } + + if (base::Contains( + result.ordered_labels, + segmentation_platform::DeviceSwitcherModel::kIosPhoneChromeLabel)) { + RecordPromptAttemptStatus(PromptAttemptStatus::kNotAndroidSwitcher); + return false; + } + + if (result.ordered_labels[0] == + segmentation_platform::DeviceSwitcherModel::kNotSyncedLabel) { + RecordPromptAttemptStatus(PromptAttemptStatus::kSyncDisabled); + } + + if (result.ordered_labels[0] != + segmentation_platform::DeviceSwitcherModel::kAndroidPhoneLabel) { + RecordPromptAttemptStatus(PromptAttemptStatus::kNotAndroidSwitcher); + return false; + } + return true; +} + +} // namespace + +BringAndroidTabsToIOSService::BringAndroidTabsToIOSService( + segmentation_platform::DeviceSwitcherResultDispatcher* dispatcher, + syncer::SyncService* sync_service, + sync_sessions::SessionSyncService* session_sync_service, + PrefService* browser_state_prefs) + : device_switcher_result_dispatcher_(dispatcher), + sync_service_(sync_service), + session_sync_service_(session_sync_service), + browser_state_prefs_(browser_state_prefs) { + DCHECK(device_switcher_result_dispatcher_); + DCHECK(sync_service_); + DCHECK(session_sync_service_); + DCHECK(browser_state_prefs_); +} + +BringAndroidTabsToIOSService::~BringAndroidTabsToIOSService() {} + +void BringAndroidTabsToIOSService::LoadTabs() { + load_tabs_invoked_ = true; + // Early return for users who should never see the prompt in the current + // session. In case the user is previously eligible for the prompt but not + // anymore, clear the tabs. + if (!UserEligibleForAndroidSwitcherPrompt() || + PromptShownAndShouldNotShowAgain()) { + synced_sessions_.reset(); + position_of_tabs_in_synced_sessions_.clear(); + return; + } + // Tabs already loaded. In this case, the user is guaranteed to be an Android + // switcher, so we can skip the check to `UserIsAndroidSwitcher` and return + // early. + if (!position_of_tabs_in_synced_sessions_.empty()) { + return; + } + // If the tabs are empty, it's possible that the tabs aren't loaded because + // the last invocation to `LoadTabs()` happens before the user enrolls in + // sync. Try again. + if (UserIsAndroidSwitcher(device_switcher_result_dispatcher_)) { + LoadSyncedSessionsAndComputeTabPositions(); + } +} + +size_t BringAndroidTabsToIOSService::GetNumberOfAndroidTabs() const { + DCHECK(load_tabs_invoked_); + return position_of_tabs_in_synced_sessions_.size(); +} + +synced_sessions::DistantTab* BringAndroidTabsToIOSService::GetTabAtIndex( + size_t index) const { + DCHECK_LT(index, position_of_tabs_in_synced_sessions_.size()); + std::tuple<size_t, size_t> indices = + position_of_tabs_in_synced_sessions_[index]; + size_t session_idx = std::get<0>(indices); + size_t tab_idx = std::get<1>(indices); + return synced_sessions_->GetSession(session_idx)->tabs[tab_idx].get(); +} + +void BringAndroidTabsToIOSService::OnBringAndroidTabsPromptDisplayed() { + browser_state_prefs_->SetBoolean(prefs::kIosBringAndroidTabsPromptDisplayed, + true); + prompt_shown_current_session_ = true; +} + +void BringAndroidTabsToIOSService::OnUserInteractWithBringAndroidTabsPrompt() { + prompt_interacted_ = true; +} + +bool BringAndroidTabsToIOSService::PromptShownAndShouldNotShowAgain() const { + bool shown_before = browser_state_prefs_->GetBoolean( + prefs::kIosBringAndroidTabsPromptDisplayed); + bool should_not_show_again = + prompt_interacted_ || (shown_before && !prompt_shown_current_session_); + if (should_not_show_again) { + RecordPromptAttemptStatus(PromptAttemptStatus::kPromptShownAndDismissed); + } + return should_not_show_again; +} + +void BringAndroidTabsToIOSService::LoadSyncedSessionsAndComputeTabPositions() { + bool tab_sync_disabled = + !sync_service_ || + !sync_service_->GetUserSettings()->GetSelectedTypes().Has( + syncer::UserSelectableType::kTabs); + if (tab_sync_disabled) { + RecordPromptAttemptStatus(PromptAttemptStatus::kTabSyncDisabled); + return; + } + + synced_sessions_ = + std::make_unique<synced_sessions::SyncedSessions>(session_sync_service_); + size_t session_count = synced_sessions_->GetSessionCount(); + for (size_t session_idx = 0; session_idx < session_count; session_idx++) { + // Only tabs from an Android phone device within the last + // `kTimeRangeOfTabsImported` are considered Android tabs. + const synced_sessions::DistantSession* session = + synced_sessions_->GetSession(session_idx); + if (session->form_factor != syncer::DeviceInfo::FormFactor::kPhone || + session->modified_time < base::Time::Now() - kTimeRangeOfTabsImported) { + continue; + } + size_t tab_size = session->tabs.size(); + for (size_t tab_idx = 0; tab_idx < tab_size; tab_idx++) { + std::tuple<size_t, size_t> indices = {session_idx, tab_idx}; + position_of_tabs_in_synced_sessions_.push_back(indices); + } + } + PromptAttemptStatus status = position_of_tabs_in_synced_sessions_.empty() + ? PromptAttemptStatus::kNoActiveTabs + : PromptAttemptStatus::kSuccess; + RecordPromptAttemptStatus(status); +}
diff --git a/ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service_factory.h b/ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service_factory.h new file mode 100644 index 0000000..a235666 --- /dev/null +++ b/ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service_factory.h
@@ -0,0 +1,47 @@ +// 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 IOS_CHROME_BROWSER_BRING_ANDROID_TABS_BRING_ANDROID_TABS_TO_IOS_SERVICE_FACTORY_H_ +#define IOS_CHROME_BROWSER_BRING_ANDROID_TABS_BRING_ANDROID_TABS_TO_IOS_SERVICE_FACTORY_H_ + +#import "base/no_destructor.h" +#import "components/keyed_service/ios/browser_state_keyed_service_factory.h" + +class ChromeBrowserState; +class BringAndroidTabsToIOSService; + +// Singleton that owns all BringAndroidTabsToIOSService and associates them with +// ChromeBrowserState. +// +// Note that as the "Bring Android Tabs" feature does not apply in incognito +// mode, the factory should only create and store services for regular browser +// states. +class BringAndroidTabsToIOSServiceFactory + : public BrowserStateKeyedServiceFactory { + public: + static BringAndroidTabsToIOSService* GetForBrowserState( + ChromeBrowserState* browser_state); + static BringAndroidTabsToIOSService* GetForBrowserStateIfExists( + ChromeBrowserState* browser_state); + static BringAndroidTabsToIOSServiceFactory* GetInstance(); + + BringAndroidTabsToIOSServiceFactory( + const BringAndroidTabsToIOSServiceFactory&) = delete; + BringAndroidTabsToIOSServiceFactory& operator=( + const BringAndroidTabsToIOSServiceFactory&) = delete; + + private: + friend class base::NoDestructor<BringAndroidTabsToIOSServiceFactory>; + + BringAndroidTabsToIOSServiceFactory(); + ~BringAndroidTabsToIOSServiceFactory() override; + + // BrowserStateKeyedServiceFactory implementation. + void RegisterBrowserStatePrefs( + user_prefs::PrefRegistrySyncable* registry) override; + std::unique_ptr<KeyedService> BuildServiceInstanceFor( + web::BrowserState* context) const override; +}; + +#endif // IOS_CHROME_BROWSER_BRING_ANDROID_TABS_BRING_ANDROID_TABS_TO_IOS_SERVICE_FACTORY_H_
diff --git a/ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service_factory.mm b/ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service_factory.mm new file mode 100644 index 0000000..d1ea638e --- /dev/null +++ b/ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service_factory.mm
@@ -0,0 +1,77 @@ +// 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/bring_android_tabs/bring_android_tabs_to_ios_service_factory.h" + +#import "components/keyed_service/ios/browser_state_dependency_manager.h" +#import "components/pref_registry/pref_registry_syncable.h" +#import "components/segmentation_platform/embedder/default_model/device_switcher_result_dispatcher.h" +#import "ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service.h" +#import "ios/chrome/browser/browser_state/chrome_browser_state.h" +#import "ios/chrome/browser/first_run/first_run.h" +#import "ios/chrome/browser/prefs/pref_names.h" +#import "ios/chrome/browser/segmentation_platform/segmentation_platform_service_factory.h" +#import "ios/chrome/browser/sync/session_sync_service_factory.h" +#import "ios/chrome/browser/sync/sync_service_factory.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +// static +BringAndroidTabsToIOSService* +BringAndroidTabsToIOSServiceFactory::GetForBrowserState( + ChromeBrowserState* browser_state) { + DCHECK(!browser_state->IsOffTheRecord()); + return static_cast<BringAndroidTabsToIOSService*>( + GetInstance()->GetServiceForBrowserState(browser_state, true)); +} + +// static +BringAndroidTabsToIOSService* +BringAndroidTabsToIOSServiceFactory::GetForBrowserStateIfExists( + ChromeBrowserState* browser_state) { + return static_cast<BringAndroidTabsToIOSService*>( + GetInstance()->GetServiceForBrowserState(browser_state, false)); +} + +// static +BringAndroidTabsToIOSServiceFactory* +BringAndroidTabsToIOSServiceFactory::GetInstance() { + static base::NoDestructor<BringAndroidTabsToIOSServiceFactory> instance; + return instance.get(); +} + +BringAndroidTabsToIOSServiceFactory::BringAndroidTabsToIOSServiceFactory() + : BrowserStateKeyedServiceFactory( + "BringAndroidTabsToIOSService", + BrowserStateDependencyManager::GetInstance()) {} + +BringAndroidTabsToIOSServiceFactory::~BringAndroidTabsToIOSServiceFactory() { + DependsOn( + segmentation_platform::SegmentationPlatformServiceFactory::GetInstance()); + DependsOn(SyncServiceFactory::GetInstance()); + DependsOn(SessionSyncServiceFactory::GetInstance()); +} + +void BringAndroidTabsToIOSServiceFactory::RegisterBrowserStatePrefs( + user_prefs::PrefRegistrySyncable* registry) { + registry->RegisterBooleanPref(prefs::kIosBringAndroidTabsPromptDisplayed, + false); +} + +std::unique_ptr<KeyedService> +BringAndroidTabsToIOSServiceFactory::BuildServiceInstanceFor( + web::BrowserState* context) const { + ChromeBrowserState* browser_state = + ChromeBrowserState::FromBrowserState(context); + PrefService* browser_state_prefs = + browser_state ? browser_state->GetPrefs() : nullptr; + return std::make_unique<BringAndroidTabsToIOSService>( + segmentation_platform::SegmentationPlatformServiceFactory:: + GetDispatcherForBrowserState(browser_state), + SyncServiceFactory::GetForBrowserState(browser_state), + SessionSyncServiceFactory::GetForBrowserState(browser_state), + browser_state_prefs); +}
diff --git a/ios/chrome/browser/bring_android_tabs/features.h b/ios/chrome/browser/bring_android_tabs/features.h new file mode 100644 index 0000000..98cf5a6 --- /dev/null +++ b/ios/chrome/browser/bring_android_tabs/features.h
@@ -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. + +#ifndef IOS_CHROME_BROWSER_BRING_ANDROID_TABS_FEATURES_H_ +#define IOS_CHROME_BROWSER_BRING_ANDROID_TABS_FEATURES_H_ + +#import "base/feature_list.h" + +// Feature flag to turn on the prompt that brings the user's Android tabs to iOS +// Chrome. +BASE_DECLARE_FEATURE(kBringYourOwnTabsIOS); + +// Enum for "Bring Your Own Tabs" experiment groups. +enum class BringYourOwnTabsPromptType { + // "Bring Your Own Tabs" enabled with half sheet modal prompt. + kHalfSheet = 0, + // "Bring Your Own Tabs" enabled with bottom message prompt. + kBottomMessage, + // "Bring Your Own Tabs" not enabled. + kDisabled, +}; + +// Feature param name that specifies the prompt type. +extern const char kBringYourOwnTabsIOSParam[]; + +// Returns the current BringYourOwnTabsPromptType according to the feature flag +// and experiment "BringYourOwnTabsIOS". +BringYourOwnTabsPromptType GetBringYourOwnTabsPromptType(); + +#endif // IOS_CHROME_BROWSER_BRING_ANDROID_TABS_FEATURES_H_
diff --git a/ios/chrome/browser/bring_android_tabs/features.mm b/ios/chrome/browser/bring_android_tabs/features.mm new file mode 100644 index 0000000..ab2e9ab --- /dev/null +++ b/ios/chrome/browser/bring_android_tabs/features.mm
@@ -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. + +#import "ios/chrome/browser/bring_android_tabs/features.h" + +#import "base/metrics/field_trial_params.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +BASE_FEATURE(kBringYourOwnTabsIOS, + "BringYourOwnTabsIOS", + base::FEATURE_DISABLED_BY_DEFAULT); + +const char kBringYourOwnTabsIOSParam[] = "bottom-message"; + +BringYourOwnTabsPromptType GetBringYourOwnTabsPromptType() { + if (base::FeatureList::IsEnabled(kBringYourOwnTabsIOS)) { + bool showBottomMessagePrompt = base::GetFieldTrialParamByFeatureAsBool( + kBringYourOwnTabsIOS, kBringYourOwnTabsIOSParam, false); + return showBottomMessagePrompt ? BringYourOwnTabsPromptType::kBottomMessage + : BringYourOwnTabsPromptType::kHalfSheet; + } + return BringYourOwnTabsPromptType::kDisabled; +}
diff --git a/ios/chrome/browser/ui/recent_tabs/bring_android_tabs/bring_android_tabs_metrics.h b/ios/chrome/browser/bring_android_tabs/metrics.h similarity index 86% rename from ios/chrome/browser/ui/recent_tabs/bring_android_tabs/bring_android_tabs_metrics.h rename to ios/chrome/browser/bring_android_tabs/metrics.h index 15bdb37..a01a5d6 100644 --- a/ios/chrome/browser/ui/recent_tabs/bring_android_tabs/bring_android_tabs_metrics.h +++ b/ios/chrome/browser/bring_android_tabs/metrics.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_CHROME_BROWSER_UI_RECENT_TABS_BRING_ANDROID_TABS_BRING_ANDROID_TABS_METRICS_H_ -#define IOS_CHROME_BROWSER_UI_RECENT_TABS_BRING_ANDROID_TABS_BRING_ANDROID_TABS_METRICS_H_ +#ifndef IOS_CHROME_BROWSER_BRING_ANDROID_TABS_METRICS_H_ +#define IOS_CHROME_BROWSER_BRING_ANDROID_TABS_METRICS_H_ namespace bring_android_tabs { @@ -62,4 +62,4 @@ } // namespace bring_android_tabs -#endif // IOS_CHROME_BROWSER_UI_RECENT_TABS_BRING_ANDROID_TABS_BRING_ANDROID_TABS_METRICS_H_ +#endif // IOS_CHROME_BROWSER_BRING_ANDROID_TABS_METRICS_H_
diff --git a/ios/chrome/browser/ui/recent_tabs/bring_android_tabs/bring_android_tabs_metrics.mm b/ios/chrome/browser/bring_android_tabs/metrics.mm similarity index 89% rename from ios/chrome/browser/ui/recent_tabs/bring_android_tabs/bring_android_tabs_metrics.mm rename to ios/chrome/browser/bring_android_tabs/metrics.mm index 4d285d2..dcc212a3 100644 --- a/ios/chrome/browser/ui/recent_tabs/bring_android_tabs/bring_android_tabs_metrics.mm +++ b/ios/chrome/browser/bring_android_tabs/metrics.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/ui/recent_tabs/bring_android_tabs/bring_android_tabs_metrics.h" +#import "ios/chrome/browser/bring_android_tabs/metrics.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support."
diff --git a/ios/chrome/browser/browser_state/BUILD.gn b/ios/chrome/browser/browser_state/BUILD.gn index e92ae519..02ae7cc 100644 --- a/ios/chrome/browser/browser_state/BUILD.gn +++ b/ios/chrome/browser/browser_state/BUILD.gn
@@ -117,6 +117,7 @@ "//ios/chrome/browser/autocomplete", "//ios/chrome/browser/autofill", "//ios/chrome/browser/bookmarks", + "//ios/chrome/browser/bring_android_tabs", "//ios/chrome/browser/browser_state_metrics", "//ios/chrome/browser/browsing_data", "//ios/chrome/browser/commerce:shopping_service", @@ -149,6 +150,7 @@ "//ios/chrome/browser/prefs", "//ios/chrome/browser/prefs:browser_prefs", "//ios/chrome/browser/prefs:pref_names", + "//ios/chrome/browser/promos_manager:factory", "//ios/chrome/browser/push_notification:push_notification_browser_state_service_factory", "//ios/chrome/browser/reading_list", "//ios/chrome/browser/safe_browsing",
diff --git a/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm b/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm index a765a92..ad48811 100644 --- a/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm +++ b/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm
@@ -12,6 +12,7 @@ #import "ios/chrome/browser/bookmarks/account_bookmark_model_factory.h" #import "ios/chrome/browser/bookmarks/local_or_syncable_bookmark_model_factory.h" #import "ios/chrome/browser/bookmarks/managed_bookmark_service_factory.h" +#import "ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service_factory.h" #import "ios/chrome/browser/browsing_data/browsing_data_remover_factory.h" #import "ios/chrome/browser/commerce/shopping_service_factory.h" #import "ios/chrome/browser/consent_auditor/consent_auditor_factory.h" @@ -47,6 +48,7 @@ #import "ios/chrome/browser/passwords/ios_chrome_password_store_factory.h" #import "ios/chrome/browser/policy/cloud/user_policy_signin_service_factory.h" #import "ios/chrome/browser/policy_url_blocking/policy_url_blocking_service.h" +#import "ios/chrome/browser/promos_manager/promos_manager_factory.h" #import "ios/chrome/browser/push_notification/push_notification_browser_state_service_factory.h" #import "ios/chrome/browser/reading_list/reading_list_model_factory.h" #import "ios/chrome/browser/safe_browsing/chrome_password_protection_service_factory.h" @@ -177,6 +179,8 @@ PolicyBlocklistServiceFactory::GetInstance(); TrustedVaultClientBackendFactory::GetInstance(); TextClassifierModelServiceFactory::GetInstance(); + PromosManagerFactory::GetInstance(); + BringAndroidTabsToIOSServiceFactory::GetInstance(); #if BUILDFLAG(IOS_CREDENTIAL_PROVIDER_ENABLED) CredentialProviderServiceFactory::GetInstance();
diff --git a/ios/chrome/browser/flags/BUILD.gn b/ios/chrome/browser/flags/BUILD.gn index 36092efd..be3405b 100644 --- a/ios/chrome/browser/flags/BUILD.gn +++ b/ios/chrome/browser/flags/BUILD.gn
@@ -38,6 +38,7 @@ "//components/payments/core", "//components/policy:generated", "//components/policy/core/common:common_constants", + "//components/reading_list/features:flags", "//components/safe_browsing/core/common", "//components/search_provider_logos", "//components/security_state/core", @@ -53,6 +54,7 @@ "//components/variations", "//ios/chrome/app:background_mode_buildflags", "//ios/chrome/app/strings", + "//ios/chrome/browser/bring_android_tabs:features", "//ios/chrome/browser/browsing_data:feature_flags", "//ios/chrome/browser/crash_report", "//ios/chrome/browser/credential_provider_promo:features",
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index 84c5c8d..bc78b0a 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -52,6 +52,7 @@ #import "components/policy/core/common/features.h" #import "components/policy/core/common/policy_loader_ios_constants.h" #import "components/policy/policy_constants.h" +#import "components/reading_list/features/reading_list_switches.h" #import "components/safe_browsing/core/common/features.h" #import "components/send_tab_to_self/features.h" #import "components/shared_highlighting/core/common/shared_highlighting_features.h" @@ -65,6 +66,7 @@ #import "components/translate/core/browser/translate_prefs.h" #import "components/translate/core/common/translate_util.h" #import "ios/chrome/app/background_mode_buildflags.h" +#import "ios/chrome/browser/bring_android_tabs/features.h" #import "ios/chrome/browser/browsing_data/browsing_data_features.h" #import "ios/chrome/browser/crash_report/features.h" #import "ios/chrome/browser/credential_provider_promo/features.h" @@ -1489,6 +1491,21 @@ flag_descriptions::kIOSBrowserEditMenuMetricsName, flag_descriptions::kIOSBrowserEditMenuMetricsDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(kIOSBrowserEditMenuMetrics)}, + {"sf-symbols-follow-up", flag_descriptions::kSFSymbolsFollowupName, + flag_descriptions::kSFSymbolsFollowupDescription, flags_ui::kOsIos, + FEATURE_VALUE_TYPE(kSFSymbolsFollowup)}, + {"enable-reading-list-account-storage", + flag_descriptions::kEnableReadingListAccountStorageName, + flag_descriptions::kEnableReadingListAccountStorageDescription, + flags_ui::kOsIos, + FEATURE_VALUE_TYPE( + reading_list::switches::kReadingListEnableDualReadingListModel)}, + {"enable-reading-list-sign-in-promo", + flag_descriptions::kEnableReadingListSignInPromoName, + flag_descriptions::kEnableReadingListSignInPromoDescription, + flags_ui::kOsIos, + FEATURE_VALUE_TYPE(reading_list::switches:: + kReadingListEnableSyncTransportModeUponSignIn)}, }; bool SkipConditionalFeatureEntry(const flags_ui::FeatureEntry& entry) {
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc index 8e916b6..310dab1c 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -385,6 +385,16 @@ "Allows users to pin tabs." "#enable-pinned-tabs should also be enabled."; +const char kEnableReadingListAccountStorageName[] = + "Enable Reading List Account Storage"; +const char kEnableReadingListAccountStorageDescription[] = + "Enable the reading list account storage."; + +const char kEnableReadingListSignInPromoName[] = + "Enable Reading List Sign-in promo"; +const char kEnableReadingListSignInPromoDescription[] = + "Enable the sign-in promo view in the reading list screen."; + const char kEnableRefineDataSourceReloadReportingName[] = "Enable Refine Data Source Reload Reporting"; const char kEnableRefineDataSourceReloadReportingDescription[] = @@ -993,6 +1003,9 @@ "when Google is the selected search engine, accessible from the omnibox or " "popup menu."; +const char kSFSymbolsFollowupName[] = "SF Symbol follow up"; +const char kSFSymbolsFollowupDescription[] = "Change the + button."; + const char kTabGridRecencySortName[] = "Change TabGrid sorting"; const char kTabGridRecencySortDescription[] = "When enabled, the tabs in the Tab Grid are sorted differently.";
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h index d4f7ef6..5462591 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -339,6 +339,15 @@ extern const char kEnablePinnedTabsIpadName[]; extern const char kEnablePinnedTabsIpadDescription[]; +// Title and description for the flag to enable the account storage. +extern const char kEnableReadingListAccountStorageName[]; +extern const char kEnableReadingListAccountStorageDescription[]; + +// Title and description for the flag to enable the sign-in promo in the reading +// list screen. +extern const char kEnableReadingListSignInPromoName[]; +extern const char kEnableReadingListSignInPromoDescription[]; + // Title and description for the flag to enable refining data source reload // reporting when having a very short attention log. extern const char kEnableRefineDataSourceReloadReportingName[]; @@ -861,6 +870,10 @@ extern const char kEnableLensInOmniboxCopiedImageName[]; extern const char kEnableLensInOmniboxCopiedImageDescription[]; +// Title and description for the flag to enable the follow up of the SF Symbols. +extern const char kSFSymbolsFollowupName[]; +extern const char kSFSymbolsFollowupDescription[]; + // Title and description for the flag to sort the tab by recency in the TabGrid. extern const char kTabGridRecencySortName[]; extern const char kTabGridRecencySortDescription[];
diff --git a/ios/chrome/browser/optimization_guide/optimization_guide_service_factory_unittest.mm b/ios/chrome/browser/optimization_guide/optimization_guide_service_factory_unittest.mm index 4d8333e..b2699721 100644 --- a/ios/chrome/browser/optimization_guide/optimization_guide_service_factory_unittest.mm +++ b/ios/chrome/browser/optimization_guide/optimization_guide_service_factory_unittest.mm
@@ -55,7 +55,7 @@ browser_state_.get())); } -TEST_F(OptimizationGuideServiceFactoryTest, CheckIncogitoServiceNotNull) { +TEST_F(OptimizationGuideServiceFactoryTest, CheckIncognitoServiceNotNull) { EXPECT_NE(nullptr, OptimizationGuideServiceFactory::GetForBrowserState( browser_state_->GetOffTheRecordChromeBrowserState())); }
diff --git a/ios/chrome/browser/overlays/public/infobar_modal/save_address_profile_infobar_modal_overlay_request_config.h b/ios/chrome/browser/overlays/public/infobar_modal/save_address_profile_infobar_modal_overlay_request_config.h index 320d4ce..896e055 100644 --- a/ios/chrome/browser/overlays/public/infobar_modal/save_address_profile_infobar_modal_overlay_request_config.h +++ b/ios/chrome/browser/overlays/public/infobar_modal/save_address_profile_infobar_modal_overlay_request_config.h
@@ -54,6 +54,12 @@ return current_address_profile_saved_; } + bool is_migration_to_account() const { return is_migration_to_account_; } + + absl::optional<std::u16string> syncing_user_email() const { + return syncing_user_email_; + } + private: OVERLAY_USER_DATA_SETUP(SaveAddressProfileModalRequestConfig); explicit SaveAddressProfileModalRequestConfig(InfoBarIOS* infobar); @@ -85,6 +91,12 @@ // True if the address profile is saved. bool current_address_profile_saved_ = false; + + // Denotes that the profile will be saved to Google Account. + bool is_migration_to_account_ = false; + + // Denotes the email address of the syncing account. + absl::optional<std::u16string> syncing_user_email_; }; } // namespace autofill_address_profile_infobar_overlays
diff --git a/ios/chrome/browser/overlays/public/infobar_modal/save_address_profile_infobar_modal_overlay_request_config.mm b/ios/chrome/browser/overlays/public/infobar_modal/save_address_profile_infobar_modal_overlay_request_config.mm index eb4bdc0..bec4d7e 100644 --- a/ios/chrome/browser/overlays/public/infobar_modal/save_address_profile_infobar_modal_overlay_request_config.mm +++ b/ios/chrome/browser/overlays/public/infobar_modal/save_address_profile_infobar_modal_overlay_request_config.mm
@@ -40,6 +40,8 @@ } current_address_profile_saved_ = infobar->accepted(); + is_migration_to_account_ = delegate->IsMigrationToAccount(); + syncing_user_email_ = delegate->SyncingUserEmail(); } SaveAddressProfileModalRequestConfig::~SaveAddressProfileModalRequestConfig() =
diff --git a/ios/chrome/browser/prefs/browser_prefs.mm b/ios/chrome/browser/prefs/browser_prefs.mm index e9fc1df..720d0c19 100644 --- a/ios/chrome/browser/prefs/browser_prefs.mm +++ b/ios/chrome/browser/prefs/browser_prefs.mm
@@ -416,11 +416,6 @@ // Register pref used to determine if the Price Tracking UI has been shown. registry->RegisterBooleanPref(prefs::kPriceNotificationsHasBeenShown, false); - - // Register pref used to determine if the Bring Android Tabs prompt has been - // shown. - registry->RegisterBooleanPref(prefs::kIosBringAndroidTabsPromptDisplayed, - false); } // This method should be periodically pruned of year+ old migrations.
diff --git a/ios/chrome/browser/promos_manager/BUILD.gn b/ios/chrome/browser/promos_manager/BUILD.gn index b99f8f1..7f54ac5 100644 --- a/ios/chrome/browser/promos_manager/BUILD.gn +++ b/ios/chrome/browser/promos_manager/BUILD.gn
@@ -17,11 +17,29 @@ ":constants", ":features", ":types", + "//components/keyed_service/core", "//components/prefs", "//ios/chrome/browser/prefs:pref_names", ] } +source_set("factory") { + sources = [ + "promos_manager_factory.h", + "promos_manager_factory.mm", + ] + frameworks = [ "Foundation.framework" ] + configs += [ "//build/config/compiler:enable_arc" ] + deps = [ + ":internal", + ":promos_manager", + "//components/keyed_service/core", + "//components/keyed_service/ios", + "//ios/chrome/browser/application_context", + "//ios/chrome/browser/browser_state", + ] +} + source_set("internal") { sources = [ "promos_manager_impl.h",
diff --git a/ios/chrome/browser/promos_manager/promos_manager.h b/ios/chrome/browser/promos_manager/promos_manager.h index 70b131e..bff1ab1 100644 --- a/ios/chrome/browser/promos_manager/promos_manager.h +++ b/ios/chrome/browser/promos_manager/promos_manager.h
@@ -12,6 +12,7 @@ #import "base/containers/flat_set.h" #import "base/containers/small_map.h" #import "base/time/time.h" +#import "components/keyed_service/core/keyed_service.h" #import "ios/chrome/browser/promos_manager/promo_config.h" #import "third_party/abseil-cpp/absl/types/optional.h" @@ -45,10 +46,9 @@ // 1. RegisterPromoForSingleDisplay // 2. RegisterPromoForContinuousDisplay // 3. DeregisterPromo -class PromosManager { +class PromosManager : public KeyedService { public: PromosManager(); - virtual ~PromosManager(); #pragma mark - Public-facing APIs
diff --git a/ios/chrome/browser/promos_manager/promos_manager.mm b/ios/chrome/browser/promos_manager/promos_manager.mm index 47ba07d..a597f819 100644 --- a/ios/chrome/browser/promos_manager/promos_manager.mm +++ b/ios/chrome/browser/promos_manager/promos_manager.mm
@@ -11,7 +11,6 @@ #pragma mark - Constructor/Destructor PromosManager::PromosManager() {} -PromosManager::~PromosManager() {} #pragma mark - Internal APIs
diff --git a/ios/chrome/browser/promos_manager/promos_manager_factory.h b/ios/chrome/browser/promos_manager/promos_manager_factory.h new file mode 100644 index 0000000..68660ebb --- /dev/null +++ b/ios/chrome/browser/promos_manager/promos_manager_factory.h
@@ -0,0 +1,38 @@ +// 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 IOS_CHROME_BROWSER_PROMOS_MANAGER_PROMOS_MANAGER_FACTORY_H_ +#define IOS_CHROME_BROWSER_PROMOS_MANAGER_PROMOS_MANAGER_FACTORY_H_ + +#include "base/no_destructor.h" +#include "components/keyed_service/ios/browser_state_keyed_service_factory.h" + +class ChromeBrowserState; +class PromosManager; + +// Singleton that owns all PromosManagers and associates them with +// ChromeBrowserState. +class PromosManagerFactory : public BrowserStateKeyedServiceFactory { + public: + static PromosManager* GetForBrowserState(ChromeBrowserState* browser_state); + + static PromosManagerFactory* GetInstance(); + + PromosManagerFactory(const PromosManagerFactory&) = delete; + PromosManagerFactory& operator=(const PromosManagerFactory&) = delete; + + private: + friend class base::NoDestructor<PromosManagerFactory>; + + PromosManagerFactory(); + ~PromosManagerFactory() override; + + // BrowserStateKeyedServiceFactory implementation. + std::unique_ptr<KeyedService> BuildServiceInstanceFor( + web::BrowserState* context) const override; + web::BrowserState* GetBrowserStateToUse( + web::BrowserState* state) const override; +}; + +#endif // IOS_CHROME_BROWSER_PROMOS_MANAGER_PROMOS_MANAGER_FACTORY_H_
diff --git a/ios/chrome/browser/promos_manager/promos_manager_factory.mm b/ios/chrome/browser/promos_manager/promos_manager_factory.mm new file mode 100644 index 0000000..b01f674f --- /dev/null +++ b/ios/chrome/browser/promos_manager/promos_manager_factory.mm
@@ -0,0 +1,53 @@ +// 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/promos_manager/promos_manager_factory.h" + +#import "base/no_destructor.h" +#import "base/time/default_clock.h" +#import "components/keyed_service/core/service_access_type.h" +#import "components/keyed_service/ios/browser_state_dependency_manager.h" +#import "ios/chrome/browser/application_context/application_context.h" +#import "ios/chrome/browser/browser_state/browser_state_otr_helper.h" +#import "ios/chrome/browser/browser_state/chrome_browser_state.h" +#import "ios/chrome/browser/promos_manager/promos_manager.h" +#import "ios/chrome/browser/promos_manager/promos_manager_impl.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +// static +PromosManager* PromosManagerFactory::GetForBrowserState( + ChromeBrowserState* browser_state) { + return static_cast<PromosManager*>( + GetInstance()->GetServiceForBrowserState(browser_state, true)); +} + +// static +PromosManagerFactory* PromosManagerFactory::GetInstance() { + static base::NoDestructor<PromosManagerFactory> instance; + return instance.get(); +} + +PromosManagerFactory::PromosManagerFactory() + : BrowserStateKeyedServiceFactory( + "PromosManagerFactory", + BrowserStateDependencyManager::GetInstance()) {} + +PromosManagerFactory::~PromosManagerFactory() = default; + +std::unique_ptr<KeyedService> PromosManagerFactory::BuildServiceInstanceFor( + web::BrowserState* context) const { + auto promos_manager = std::make_unique<PromosManagerImpl>( + GetApplicationContext()->GetLocalState(), + base::DefaultClock::GetInstance()); + promos_manager->Init(); + return promos_manager; +} + +web::BrowserState* PromosManagerFactory::GetBrowserStateToUse( + web::BrowserState* context) const { + return GetBrowserStateRedirectedInIncognito(context); +}
diff --git a/ios/chrome/browser/shared/public/commands/BUILD.gn b/ios/chrome/browser/shared/public/commands/BUILD.gn index 1e84892..6f109f0 100644 --- a/ios/chrome/browser/shared/public/commands/BUILD.gn +++ b/ios/chrome/browser/shared/public/commands/BUILD.gn
@@ -11,6 +11,7 @@ "bookmark_add_command.h", "bookmark_add_command.mm", "bookmarks_commands.h", + "bring_android_tabs_commands.h", "browser_commands.h", "browser_coordinator_commands.h", "browsing_data_commands.h",
diff --git a/ios/chrome/browser/shared/public/commands/activity_service_commands.h b/ios/chrome/browser/shared/public/commands/activity_service_commands.h index f73b64f..229717a 100644 --- a/ios/chrome/browser/shared/public/commands/activity_service_commands.h +++ b/ios/chrome/browser/shared/public/commands/activity_service_commands.h
@@ -9,6 +9,11 @@ @protocol ActivityServiceCommands <NSObject> +// Stops the existing SharingCoordinator and creates a new one. This is used +// when a sharing coordinator is already started, but the user taps again on the +// share button. +- (void)stopAndStartSharingCoordinator; + // Shows the share sheet for the current page. - (void)sharePage;
diff --git a/ios/chrome/browser/shared/public/commands/bring_android_tabs_commands.h b/ios/chrome/browser/shared/public/commands/bring_android_tabs_commands.h new file mode 100644 index 0000000..f923433 --- /dev/null +++ b/ios/chrome/browser/shared/public/commands/bring_android_tabs_commands.h
@@ -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. + +#ifndef IOS_CHROME_BROWSER_SHARED_PUBLIC_COMMANDS_BRING_ANDROID_TABS_COMMANDS_H_ +#define IOS_CHROME_BROWSER_SHARED_PUBLIC_COMMANDS_BRING_ANDROID_TABS_COMMANDS_H_ + +// Protocol for commands that manages the presentation cycle of the Bring +// Android Tabs, both the prompt and the review tabs list. +@protocol BringAndroidTabsCommands + +// Display the Bring Android Tabs prompt in the UI hierarchy. +- (void)displayBringAndroidTabsPrompt; + +// Remove the Bring Android Tabs prompt from the UI hierarchy and bring up the +// modal used to review the list of tabs. +- (void)reviewAllBringAndroidTabs; + +// Remove the Bring Android Tabs prompt from the UI hierarchy and end the user +// journey for Bring Android Tabs. +- (void)dismissBringAndroidTabsPrompt; + +@end + +#endif // IOS_CHROME_BROWSER_SHARED_PUBLIC_COMMANDS_BRING_ANDROID_TABS_COMMANDS_H_
diff --git a/ios/chrome/browser/shared/public/features/features.cc b/ios/chrome/browser/shared/public/features/features.cc index 23d16716..10da751 100644 --- a/ios/chrome/browser/shared/public/features/features.cc +++ b/ios/chrome/browser/shared/public/features/features.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 "ios/chrome/browser/shared/public/features/features.h" +#import "ios/chrome/browser/shared/public/features/features.h" BASE_FEATURE(kDefaultBrowserBlueDotPromo, "DefaultBrowserBlueDotPromo", @@ -132,6 +132,10 @@ "UseSFSymbolsInOmnibox", base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE(kSFSymbolsFollowup, + "SFSymbolsFollowup", + base::FEATURE_DISABLED_BY_DEFAULT); + BASE_FEATURE(kCalendarExperienceKit, "CalendarExperienceKit", base::FEATURE_ENABLED_BY_DEFAULT); @@ -197,22 +201,6 @@ kAddToHomeScreen, kAddToHomeScreenDisableIncognitoParam, false); } -BASE_FEATURE(kBringYourOwnTabsIOS, - "BringYourOwnTabsIOS", - base::FEATURE_DISABLED_BY_DEFAULT); - -const char kBringYourOwnTabsIOSParam[] = "bottom-message"; - -BringYourOwnTabsPromptType GetBringYourOwnTabsPromptType() { - if (base::FeatureList::IsEnabled(kBringYourOwnTabsIOS)) { - bool showBottomMessagePrompt = base::GetFieldTrialParamByFeatureAsBool( - kBringYourOwnTabsIOS, kBringYourOwnTabsIOSParam, false); - return showBottomMessagePrompt ? BringYourOwnTabsPromptType::kBottomMessage - : BringYourOwnTabsPromptType::kHalfSheet; - } - return BringYourOwnTabsPromptType::kDisabled; -} - BASE_FEATURE(kNewNTPOmniboxLayout, "kNewNTPOmniboxLayout", base::FEATURE_DISABLED_BY_DEFAULT);
diff --git a/ios/chrome/browser/shared/public/features/features.h b/ios/chrome/browser/shared/public/features/features.h index 8115325b..7a96abc 100644 --- a/ios/chrome/browser/shared/public/features/features.h +++ b/ios/chrome/browser/shared/public/features/features.h
@@ -110,6 +110,9 @@ // Feature flag to switch images to SFSymbols in the omnibox when enabled. BASE_DECLARE_FEATURE(kUseSFSymbolsInOmnibox); +// Feature flag for the follow up of the SF Symbols. +BASE_DECLARE_FEATURE(kSFSymbolsFollowup); + // Feature flag to enable Calendar event in experience kit. BASE_DECLARE_FEATURE(kCalendarExperienceKit); @@ -162,26 +165,6 @@ // Feature flag to enable the new layout of the NTP omnibox. BASE_DECLARE_FEATURE(kNewNTPOmniboxLayout); -// Feature flag to turn on the prompt that brings the user's Android tabs to iOS -// Chrome. -BASE_DECLARE_FEATURE(kBringYourOwnTabsIOS); - -// Enum for "Bring Your Own Tabs" experiment groups (control/experiment) and its -// param. -enum class BringYourOwnTabsPromptType { - // "Bring Your Own Tabs" enabled with half sheet modal prompt. - kHalfSheet = 0, - // "Bring Your Own Tabs" enabled with bottom message prompt. - kBottomMessage, - // "Bring Your Own Tabs" not enabled. - kDisabled, -}; -extern const char kBringYourOwnTabsIOSParam[]; - -// Returns the current BringYourOwnTabsPromptType according to the feature flag -// and experiment "BringYourOwnTabsIOS". -BringYourOwnTabsPromptType GetBringYourOwnTabsPromptType(); - // Whether the email is shown in the snackbar indicating that a new bookmark // or reading list item is added. BASE_DECLARE_FEATURE(kEnableEmailInBookmarksReadingListSnackbar);
diff --git a/ios/chrome/browser/shared/ui/table_view/cells/table_view_url_item.mm b/ios/chrome/browser/shared/ui/table_view/cells/table_view_url_item.mm index 09cbc7f..bd32eada 100644 --- a/ios/chrome/browser/shared/ui/table_view/cells/table_view_url_item.mm +++ b/ios/chrome/browser/shared/ui/table_view/cells/table_view_url_item.mm
@@ -179,6 +179,8 @@ [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote]; _thirdRowLabel.adjustsFontForContentSizeCategory = YES; _thirdRowLabel.textColor = [UIColor colorNamed:kTextSecondaryColor]; + _thirdRowLabel.numberOfLines = 0; + _thirdRowLabel.lineBreakMode = NSLineBreakByWordWrapping; _thirdRowLabel.hidden = YES; _metadataLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote];
diff --git a/ios/chrome/browser/signin/constants.h b/ios/chrome/browser/signin/constants.h index 3f8c9b2..765044a 100644 --- a/ios/chrome/browser/signin/constants.h +++ b/ios/chrome/browser/signin/constants.h
@@ -31,10 +31,17 @@ // Enum is used to represent the action to be taken by the authentication once // the user is successfully signed in. -typedef enum { - POST_SIGNIN_ACTION_NONE, - POST_SIGNIN_ACTION_COMMIT_SYNC, -} PostSignInAction; +enum class PostSignInAction { + // No post action after sign-in. + kNone, + // Starts sign-in flow for a sync consent. + // The owner of `AuthenticationFlow` still needs to: + // * Record the sync dialog strings. + // * Grand the sync consent in AuthenticationService. + // * Record the first setup complete. + // Related crbug.com/1254359. + kCommitSync, +}; // Enum for identity avatar size. See GetSizeForIdentityAvatarSize() to convert // the enum value to point.
diff --git a/ios/chrome/browser/synced_sessions/distant_session.h b/ios/chrome/browser/synced_sessions/distant_session.h index 0dad5c70..1516e48e 100644 --- a/ios/chrome/browser/synced_sessions/distant_session.h +++ b/ios/chrome/browser/synced_sessions/distant_session.h
@@ -8,7 +8,6 @@ #import <string> #import "components/sync_device_info/device_info.h" -#import "ios/chrome/browser/synced_sessions/distant_tab.h" namespace base { class Time; @@ -22,6 +21,8 @@ namespace synced_sessions { +struct DistantTab; + // Data holder that contains the data of the distant sessions and their tabs to // show in the UI. struct DistantSession { @@ -49,7 +50,7 @@ // Time the session is last modified. base::Time modified_time; // A list of tabs opened in this session. - DistantTabVector tabs; + std::vector<std::unique_ptr<DistantTab>> tabs; // The form factor of the device in which the session is created. syncer::DeviceInfo::FormFactor form_factor; };
diff --git a/ios/chrome/browser/synced_sessions/distant_session.mm b/ios/chrome/browser/synced_sessions/distant_session.mm index 067a2a6b..3b4e34f2 100644 --- a/ios/chrome/browser/synced_sessions/distant_session.mm +++ b/ios/chrome/browser/synced_sessions/distant_session.mm
@@ -8,6 +8,7 @@ #import "components/sync_sessions/open_tabs_ui_delegate.h" #import "components/sync_sessions/session_sync_service.h" #import "components/sync_sessions/synced_session.h" +#import "ios/chrome/browser/synced_sessions/distant_tab.h" #import "ios/chrome/browser/synced_sessions/synced_sessions.h" #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/chrome/browser/synced_sessions/distant_tab.h b/ios/chrome/browser/synced_sessions/distant_tab.h index 845ac9a..5caff35 100644 --- a/ios/chrome/browser/synced_sessions/distant_tab.h +++ b/ios/chrome/browser/synced_sessions/distant_tab.h
@@ -35,9 +35,6 @@ size_t hashOfUserVisibleProperties(); }; -// A list of DistantTab objects. -using DistantTabVector = std::vector<std::unique_ptr<DistantTab>>; - // Data holder that contains a set of distant tabs to show in the UI. struct DistantTabsSet { DistantTabsSet();
diff --git a/ios/chrome/browser/ui/authentication/authentication_flow.mm b/ios/chrome/browser/ui/authentication/authentication_flow.mm index 7f98eb27..69e39b0b 100644 --- a/ios/chrome/browser/ui/authentication/authentication_flow.mm +++ b/ios/chrome/browser/ui/authentication/authentication_flow.mm
@@ -219,8 +219,8 @@ return CHECK_MERGE_CASE; case CHECK_MERGE_CASE: // If the user enabled Sync, expect the data clearing strategy to be set. - DCHECK(self.postSignInAction == POST_SIGNIN_ACTION_NONE || - (self.postSignInAction == POST_SIGNIN_ACTION_COMMIT_SYNC && + DCHECK(self.postSignInAction == PostSignInAction::kNone || + (self.postSignInAction == PostSignInAction::kCommitSync && self.localDataClearingStrategy != SHOULD_CLEAR_DATA_USER_CHOICE)); if (_shouldShowManagedConfirmation) return SHOW_MANAGED_CONFIRMATION; @@ -245,9 +245,9 @@ return SIGN_IN; case SIGN_IN: switch (self.postSignInAction) { - case POST_SIGNIN_ACTION_COMMIT_SYNC: + case PostSignInAction::kCommitSync: return COMMIT_SYNC; - case POST_SIGNIN_ACTION_NONE: + case PostSignInAction::kNone: return COMPLETE_WITH_SUCCESS; } case COMMIT_SYNC: @@ -380,10 +380,10 @@ return; } switch (self.postSignInAction) { - case POST_SIGNIN_ACTION_COMMIT_SYNC: + case PostSignInAction::kCommitSync: [self checkMergeCaseForUnsupervisedAccounts]; break; - case POST_SIGNIN_ACTION_NONE: + case PostSignInAction::kNone: [self continueSignin]; break; } @@ -456,9 +456,10 @@ bool isManagedAccount = _identityToSignInHostedDomain.length > 0; signin_metrics::RecordSigninAccountType(signin::ConsentLevel::kSignin, isManagedAccount); - if (self.postSignInAction == POST_SIGNIN_ACTION_COMMIT_SYNC) + if (self.postSignInAction == PostSignInAction::kCommitSync) { signin_metrics::RecordSigninAccountType(signin::ConsentLevel::kSync, isManagedAccount); + } } if (_signInCompletion) { // Make sure the completion callback is always called after @@ -531,7 +532,7 @@ DCHECK_EQ(FETCH_MANAGED_STATUS, _state); _shouldShowManagedConfirmation = [hostedDomain length] > 0 && - (self.postSignInAction == POST_SIGNIN_ACTION_COMMIT_SYNC); + (self.postSignInAction == PostSignInAction::kCommitSync); _identityToSignInHostedDomain = hostedDomain; _shouldFetchUserPolicy = YES; [self continueSignin];
diff --git a/ios/chrome/browser/ui/authentication/authentication_flow_unittest.mm b/ios/chrome/browser/ui/authentication/authentication_flow_unittest.mm index 996d96f..b5a2e89 100644 --- a/ios/chrome/browser/ui/authentication/authentication_flow_unittest.mm +++ b/ios/chrome/browser/ui/authentication/authentication_flow_unittest.mm
@@ -161,7 +161,7 @@ // Tests a Sign In of a normal account on the same profile with Sync // consent granted. TEST_F(AuthenticationFlowTest, TestSignInSimple) { - CreateAuthenticationFlow(POST_SIGNIN_ACTION_COMMIT_SYNC, identity1_); + CreateAuthenticationFlow(PostSignInAction::kCommitSync, identity1_); [[[performer_ expect] andDo:^(NSInvocation*) { [authentication_flow_ didFetchManagedStatus:nil]; @@ -189,7 +189,7 @@ // Tests that starting sync while the user is already signed in only. TEST_F(AuthenticationFlowTest, TestAlreadySignedIn) { - CreateAuthenticationFlow(POST_SIGNIN_ACTION_COMMIT_SYNC, identity1_); + CreateAuthenticationFlow(PostSignInAction::kCommitSync, identity1_); [[[performer_ expect] andDo:^(NSInvocation*) { [authentication_flow_ didFetchManagedStatus:nil]; @@ -220,7 +220,7 @@ // already signed in account, and asking the user whether data should be cleared // or merged. TEST_F(AuthenticationFlowTest, TestSignOutUserChoice) { - CreateAuthenticationFlow(POST_SIGNIN_ACTION_COMMIT_SYNC, identity1_); + CreateAuthenticationFlow(PostSignInAction::kCommitSync, identity1_); [[[performer_ expect] andDo:^(NSInvocation*) { [authentication_flow_ didFetchManagedStatus:nil]; @@ -264,7 +264,7 @@ // Tests the cancelling of a Sign In. TEST_F(AuthenticationFlowTest, TestCancel) { - CreateAuthenticationFlow(POST_SIGNIN_ACTION_COMMIT_SYNC, identity1_); + CreateAuthenticationFlow(PostSignInAction::kCommitSync, identity1_); [[[performer_ expect] andDo:^(NSInvocation*) { [authentication_flow_ didFetchManagedStatus:nil]; @@ -292,7 +292,7 @@ // Tests the fetch managed status failure case. TEST_F(AuthenticationFlowTest, TestFailFetchManagedStatus) { - CreateAuthenticationFlow(POST_SIGNIN_ACTION_COMMIT_SYNC, identity1_); + CreateAuthenticationFlow(PostSignInAction::kCommitSync, identity1_); NSError* error = [NSError errorWithDomain:@"foo" code:0 userInfo:nil]; [[[performer_ expect] andDo:^(NSInvocation*) { @@ -319,7 +319,7 @@ // Tests the managed sign in confirmation dialog is shown when signing in to // a managed identity. TEST_F(AuthenticationFlowTest, TestShowManagedConfirmation) { - CreateAuthenticationFlow(POST_SIGNIN_ACTION_COMMIT_SYNC, managed_identity_); + CreateAuthenticationFlow(PostSignInAction::kCommitSync, managed_identity_); [[[performer_ expect] andDo:^(NSInvocation*) { [authentication_flow_ didFetchManagedStatus:@"foo.com"]; @@ -353,7 +353,7 @@ // Tests sign-in only with a managed account. The managed account confirmation // dialog should not be shown. TEST_F(AuthenticationFlowTest, TestShowNoManagedConfirmationForSigninOnly) { - CreateAuthenticationFlow(POST_SIGNIN_ACTION_NONE, managed_identity_); + CreateAuthenticationFlow(PostSignInAction::kNone, managed_identity_); [[[performer_ expect] andDo:^(NSInvocation*) { [authentication_flow_ didFetchManagedStatus:@"foo.com"]; @@ -373,7 +373,7 @@ // Tests sign-in only with a managed account, and then starts sync. The managed // account confirmation dialog should be shown only in sync. TEST_F(AuthenticationFlowTest, TestSyncAfterSigninAndSync) { - CreateAuthenticationFlow(POST_SIGNIN_ACTION_COMMIT_SYNC, managed_identity_); + CreateAuthenticationFlow(PostSignInAction::kCommitSync, managed_identity_); [[[performer_ expect] andDo:^(NSInvocation*) { [authentication_flow_ didFetchManagedStatus:@"foo.com"]; @@ -411,7 +411,7 @@ base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitWithFeatures({policy::kUserPolicy}, {}); - CreateAuthenticationFlow(POST_SIGNIN_ACTION_COMMIT_SYNC, managed_identity_); + CreateAuthenticationFlow(PostSignInAction::kCommitSync, managed_identity_); [[[performer_ expect] andDo:^(NSInvocation*) { [authentication_flow_ didFetchManagedStatus:@"foo.com"]; @@ -461,7 +461,7 @@ base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitWithFeatures({policy::kUserPolicy}, {}); - CreateAuthenticationFlow(POST_SIGNIN_ACTION_COMMIT_SYNC, managed_identity_); + CreateAuthenticationFlow(PostSignInAction::kCommitSync, managed_identity_); [[[performer_ expect] andDo:^(NSInvocation*) { [authentication_flow_ didFetchManagedStatus:@"foo.com"]; @@ -508,7 +508,7 @@ base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitWithFeatures({policy::kUserPolicy}, {}); - CreateAuthenticationFlow(POST_SIGNIN_ACTION_COMMIT_SYNC, managed_identity_); + CreateAuthenticationFlow(PostSignInAction::kCommitSync, managed_identity_); [[[performer_ expect] andDo:^(NSInvocation*) { [authentication_flow_ didFetchManagedStatus:@"foo.com"];
diff --git a/ios/chrome/browser/ui/authentication/signin/consistency_promo_signin/consistency_promo_signin_coordinator.mm b/ios/chrome/browser/ui/authentication/signin/consistency_promo_signin/consistency_promo_signin_coordinator.mm index d3105e5..0f8f6f00 100644 --- a/ios/chrome/browser/ui/authentication/signin/consistency_promo_signin/consistency_promo_signin_coordinator.mm +++ b/ios/chrome/browser/ui/authentication/signin/consistency_promo_signin/consistency_promo_signin_coordinator.mm
@@ -265,7 +265,7 @@ AuthenticationFlow* authenticationFlow = [[AuthenticationFlow alloc] initWithBrowser:self.browser identity:self.selectedIdentity - postSignInAction:POST_SIGNIN_ACTION_NONE + postSignInAction:PostSignInAction::kNone presentingViewController:self.navigationController]; authenticationFlow.dispatcher = HandlerForProtocol( self.browser->GetCommandDispatcher(), BrowsingDataCommands);
diff --git a/ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_coordinator.mm b/ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_coordinator.mm index ede3ff6..497a2f0 100644 --- a/ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_coordinator.mm +++ b/ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_coordinator.mm
@@ -549,8 +549,8 @@ DCHECK(self.unifiedConsentCoordinator.selectedIdentity); PostSignInAction postSignInAction = self.userSigninMediatorGetSettingsLinkWasTapped - ? POST_SIGNIN_ACTION_NONE - : POST_SIGNIN_ACTION_COMMIT_SYNC; + ? PostSignInAction::kNone + : PostSignInAction::kCommitSync; AuthenticationFlow* authenticationFlow = [[AuthenticationFlow alloc] initWithBrowser:self.browser identity:self.unifiedConsentCoordinator.selectedIdentity
diff --git a/ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_mediator_unittest.mm b/ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_mediator_unittest.mm index 33b738c..d9bf5fd 100644 --- a/ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_mediator_unittest.mm +++ b/ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_mediator_unittest.mm
@@ -130,7 +130,7 @@ NSLog(@" signInIdentity "); authentication_service()->SignIn(identity_); }); - if (postSignInAction == POST_SIGNIN_ACTION_COMMIT_SYNC) { + if (postSignInAction == PostSignInAction::kCommitSync) { OCMExpect( [performer_mock_ shouldHandleMergeCaseForIdentity:identity_ @@ -293,8 +293,8 @@ // Tests a successful authentication for a given identity. TEST_F(UserSigninMediatorTest, AuthenticateWithIdentitySuccess) { - CreateAuthenticationFlow(POST_SIGNIN_ACTION_COMMIT_SYNC); - SetPerformerSigninExpectations(POST_SIGNIN_ACTION_COMMIT_SYNC); + CreateAuthenticationFlow(PostSignInAction::kCommitSync); + SetPerformerSigninExpectations(PostSignInAction::kCommitSync); // Retrieving coordinator data for the mediator delegate. OCMExpect( @@ -321,8 +321,8 @@ // Tests authenticating the identity when the settings link has been tapped. TEST_F(UserSigninMediatorTest, AuthenticateWithSettingsLinkTapped) { - CreateAuthenticationFlow(POST_SIGNIN_ACTION_COMMIT_SYNC); - SetPerformerSigninExpectations(POST_SIGNIN_ACTION_COMMIT_SYNC); + CreateAuthenticationFlow(PostSignInAction::kCommitSync); + SetPerformerSigninExpectations(PostSignInAction::kCommitSync); OCMExpect( [mediator_delegate_mock_ userSigninMediatorGetSettingsLinkWasTapped]) @@ -343,7 +343,7 @@ // Tests authentication failure for a given identity. TEST_F(UserSigninMediatorTest, AuthenticateWithIdentityError) { - CreateAuthenticationFlow(POST_SIGNIN_ACTION_COMMIT_SYNC); + CreateAuthenticationFlow(PostSignInAction::kCommitSync); SetPerformerFailureExpectations(); OCMExpect( @@ -417,7 +417,7 @@ // authentication is in progress. TEST_F(UserSigninMediatorTest, CancelAndDismissAuthenticationInProgressWithAnimation) { - CreateAuthenticationFlow(POST_SIGNIN_ACTION_COMMIT_SYNC); + CreateAuthenticationFlow(PostSignInAction::kCommitSync); SetPerformerCancelAndDismissExpectations(/*animated=*/YES); OCMExpect( @@ -446,7 +446,7 @@ // authentication is in progress. TEST_F(UserSigninMediatorTest, CancelAndDismissAuthenticationInProgressWithoutAnimation) { - CreateAuthenticationFlow(POST_SIGNIN_ACTION_COMMIT_SYNC); + CreateAuthenticationFlow(PostSignInAction::kCommitSync); SetPerformerCancelAndDismissExpectations(/*animated=*/NO); OCMExpect( @@ -474,8 +474,8 @@ // Tests a user sign-in operation cancel and dismiss without animation when // authentication is in progress. TEST_F(UserSigninMediatorTest, CancelSyncAndStaySignin) { - CreateAuthenticationFlow(POST_SIGNIN_ACTION_COMMIT_SYNC); - SetPerformerSigninExpectations(POST_SIGNIN_ACTION_COMMIT_SYNC); + CreateAuthenticationFlow(PostSignInAction::kCommitSync); + SetPerformerSigninExpectations(PostSignInAction::kCommitSync); OCMExpect( [mediator_delegate_mock_ userSigninMediatorGetSettingsLinkWasTapped]) @@ -518,9 +518,9 @@ authentication_service()->SignIn(identity2); // Opens the settings link with identity 1. - CreateAuthenticationFlow(POST_SIGNIN_ACTION_NONE); + CreateAuthenticationFlow(PostSignInAction::kNone); SetPerformerSignoutExpectations(); - SetPerformerSigninExpectations(POST_SIGNIN_ACTION_NONE); + SetPerformerSigninExpectations(PostSignInAction::kNone); OCMExpect( [mediator_delegate_mock_ userSigninMediatorGetSettingsLinkWasTapped]) .andReturn(YES); @@ -570,9 +570,9 @@ authentication_service()->SignIn(identity2); // Opens the settings link with identity 1. - CreateAuthenticationFlow(POST_SIGNIN_ACTION_NONE); + CreateAuthenticationFlow(PostSignInAction::kNone); SetPerformerSignoutExpectations(); - SetPerformerSigninExpectations(POST_SIGNIN_ACTION_NONE); + SetPerformerSigninExpectations(PostSignInAction::kNone); OCMExpect( [mediator_delegate_mock_ userSigninMediatorGetSettingsLinkWasTapped])
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 97451c16..197dacbb7 100644 --- a/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm +++ b/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm
@@ -639,7 +639,7 @@ // received yet. Let's update the promo identity. [self identityListChanged]; } - DCHECK(self.identity); + DCHECK(self.identity) << base::SysNSStringToUTF8([self description]); return [[SigninPromoViewConfigurator alloc] initWithSigninPromoViewMode:SigninPromoViewModeSyncWithPrimaryAccount userEmail:self.identity.userEmail @@ -667,7 +667,7 @@ } - (void)signinPromoViewIsVisible { - DCHECK(!self.invalidOrClosed); + DCHECK(!self.invalidOrClosed) << base::SysNSStringToUTF8([self description]); if (self.signinPromoViewVisible) { return; } @@ -711,7 +711,7 @@ } - (void)signinPromoViewIsHidden { - DCHECK(!self.invalidOrClosed); + DCHECK(!self.invalidOrClosed) << base::SysNSStringToUTF8([self description]); self.signinPromoViewVisible = NO; } @@ -746,7 +746,8 @@ if (self.authService->HasPrimaryIdentity(signin::ConsentLevel::kSignin)) { return self.authService->GetPrimaryIdentity(signin::ConsentLevel::kSignin); } - DCHECK(self.accountManagerService); + DCHECK(self.accountManagerService) + << base::SysNSStringToUTF8([self description]); return self.accountManagerService->GetDefaultIdentity(); } @@ -789,7 +790,8 @@ // before the sign-in button is pressed, if the current access point supports // it. - (void)sendImpressionsTillSigninButtonsHistogram { - DCHECK(!self.invalidClosedOrNeverVisible); + DCHECK(!self.invalidClosedOrNeverVisible) + << base::SysNSStringToUTF8([self description]); const char* displayedCountPreferenceKey = DisplayedCountPreferenceKey(self.accessPoint); if (!displayedCountPreferenceKey) @@ -807,8 +809,9 @@ return; } DCHECK_EQ(ios::SigninPromoViewState::UsedAtLeastOnce, - self.signinPromoViewState); - DCHECK(self.signinInProgress); + self.signinPromoViewState) + << base::SysNSStringToUTF8([self description]); + DCHECK(self.signinInProgress) << base::SysNSStringToUTF8([self description]); self.signinInProgress = NO; } @@ -848,7 +851,7 @@ // Triggers the primary action when `signInOnly` is at YES: starts sign-in flow. - (void)primaryActionForSignInOnly { - DCHECK(self.signInOnly); + DCHECK(self.signInOnly) << base::SysNSStringToUTF8([self description]); signin_metrics::RecordSigninUserActionForAccessPoint(self.accessPoint); self.signinPromoViewState = ios::SigninPromoViewState::UsedAtLeastOnce; self.signinInProgress = YES; @@ -858,7 +861,7 @@ // Triggers the secondary action when `signInOnly` is at YES: starts the // add account dialog. - (void)secondaryActionForSignInOnly { - DCHECK(self.signInOnly); + DCHECK(self.signInOnly) << base::SysNSStringToUTF8([self description]); signin_metrics::RecordSigninUserActionForAccessPoint(self.accessPoint); self.signinPromoViewState = ios::SigninPromoViewState::UsedAtLeastOnce; self.signinInProgress = YES; @@ -875,7 +878,7 @@ _authenticationFlow = [[AuthenticationFlow alloc] initWithBrowser:_browser identity:self.identity - postSignInAction:POST_SIGNIN_ACTION_NONE + postSignInAction:PostSignInAction::kNone presentingViewController:_baseViewController]; __weak id<SigninPromoViewConsumer> weakConsumer = self.consumer; [_authenticationFlow startSignInWithCompletion:^(BOOL success) { @@ -887,7 +890,8 @@ - (void)startAddAccountForSignInOnly { DCHECK(!_signinCoordinator) - << base::SysNSStringToUTF8([_signinCoordinator description]); + << base::SysNSStringToUTF8([_signinCoordinator description]) << " " + << base::SysNSStringToUTF8([self description]); self.signinPromoViewState = ios::SigninPromoViewState::UsedAtLeastOnce; self.signinInProgress = YES; _signinCoordinator = [SigninCoordinator @@ -904,7 +908,7 @@ - (void)addAccountDoneWithResult:(SigninCoordinatorResult)result info:(SigninCompletionInfo*)info { - DCHECK(_signinCoordinator); + DCHECK(_signinCoordinator) << base::SysNSStringToUTF8([self description]); _signinCoordinator = nil; switch (result) { case SigninCoordinatorResultSuccess: @@ -920,7 +924,8 @@ // Changes the promo view state, and records the metrics. - (void)signinPromoViewIsRemoved { - DCHECK_NE(ios::SigninPromoViewState::Invalid, self.signinPromoViewState); + DCHECK_NE(ios::SigninPromoViewState::Invalid, self.signinPromoViewState) + << base::SysNSStringToUTF8([self description]); BOOL wasNeverVisible = self.signinPromoViewState == ios::SigninPromoViewState::NeverVisible; BOOL wasUnused = @@ -969,13 +974,15 @@ - (void)signinPromoViewDidTapSigninWithNewAccount: (SigninPromoView*)signinPromoView { - DCHECK(!self.identity); + DCHECK(!self.identity) << base::SysNSStringToUTF8([self description]); // The promo on top of the feed is only logged as visible when most of it can // be seen, so it can be used without `self.signinPromoViewVisible`. DCHECK(self.signinPromoViewVisible || self.accessPoint == - signin_metrics::AccessPoint::ACCESS_POINT_NTP_FEED_TOP_PROMO); - DCHECK(!self.invalidClosedOrNeverVisible); + signin_metrics::AccessPoint::ACCESS_POINT_NTP_FEED_TOP_PROMO) + << base::SysNSStringToUTF8([self description]); + DCHECK(!self.invalidClosedOrNeverVisible) + << base::SysNSStringToUTF8([self description]); [self sendImpressionsTillSigninButtonsHistogram]; // On iOS, the promo does not have a button to add and account when there is // already an account on the device. That flow goes through the NOT_DEFAULT @@ -992,9 +999,11 @@ - (void)signinPromoViewDidTapSigninWithDefaultAccount: (SigninPromoView*)signinPromoView { - DCHECK(self.identity); - DCHECK(self.signinPromoViewVisible); - DCHECK(!self.invalidClosedOrNeverVisible); + DCHECK(self.identity) << base::SysNSStringToUTF8([self description]); + DCHECK(self.signinPromoViewVisible) + << base::SysNSStringToUTF8([self description]); + DCHECK(!self.invalidClosedOrNeverVisible) + << base::SysNSStringToUTF8([self description]); [self sendImpressionsTillSigninButtonsHistogram]; if (self.signInOnly) { [self primaryActionForSignInOnly]; @@ -1007,9 +1016,11 @@ - (void)signinPromoViewDidTapSigninWithOtherAccount: (SigninPromoView*)signinPromoView { - DCHECK(self.identity); - DCHECK(self.signinPromoViewVisible); - DCHECK(!self.invalidClosedOrNeverVisible); + DCHECK(self.identity) << base::SysNSStringToUTF8([self description]); + DCHECK(self.signinPromoViewVisible) + << base::SysNSStringToUTF8([self description]); + DCHECK(!self.invalidClosedOrNeverVisible) + << base::SysNSStringToUTF8([self description]); [self sendImpressionsTillSigninButtonsHistogram]; signin_metrics::RecordSigninUserActionForAccessPoint(self.accessPoint); if (self.signInOnly) { @@ -1022,16 +1033,19 @@ } - (void)signinPromoViewCloseButtonWasTapped:(SigninPromoView*)view { - DCHECK(!self.invalidClosedOrNeverVisible); + DCHECK(!self.invalidClosedOrNeverVisible) + << base::SysNSStringToUTF8([self description]); // The promo on top of the feed is only logged as visible when most of it can // be seen, so it can be dismissed without `self.signinPromoViewVisible`. DCHECK(self.signinPromoViewVisible || self.accessPoint == - signin_metrics::AccessPoint::ACCESS_POINT_NTP_FEED_TOP_PROMO); + signin_metrics::AccessPoint::ACCESS_POINT_NTP_FEED_TOP_PROMO) + << base::SysNSStringToUTF8([self description]); self.signinPromoViewState = ios::SigninPromoViewState::Closed; const char* alreadySeenSigninViewPreferenceKey = AlreadySeenSigninViewPreferenceKey(self.accessPoint); - DCHECK(alreadySeenSigninViewPreferenceKey); + DCHECK(alreadySeenSigninViewPreferenceKey) + << base::SysNSStringToUTF8([self description]); self.prefService->SetBoolean(alreadySeenSigninViewPreferenceKey, true); const char* displayedCountPreferenceKey = DisplayedCountPreferenceKey(self.accessPoint); @@ -1054,12 +1068,13 @@ // `_identityChooserCoordinator.delegate` was set to nil before calling this // method since `identityChooserCoordinatorDidTapOnAddAccount:` or // `identityChooserCoordinator:didSelectIdentity:` have been called before. - NOTREACHED(); + NOTREACHED() << base::SysNSStringToUTF8([self description]); } - (void)identityChooserCoordinatorDidTapOnAddAccount: (IdentityChooserCoordinator*)coordinator { - DCHECK_EQ(coordinator, _identityChooserCoordinator); + DCHECK_EQ(coordinator, _identityChooserCoordinator) + << base::SysNSStringToUTF8([self description]); _identityChooserCoordinator.delegate = nil; [_identityChooserCoordinator stop]; _identityChooserCoordinator = nil; @@ -1068,7 +1083,8 @@ - (void)identityChooserCoordinator:(IdentityChooserCoordinator*)coordinator didSelectIdentity:(id<SystemIdentity>)identity { - DCHECK_EQ(coordinator, _identityChooserCoordinator); + DCHECK_EQ(coordinator, _identityChooserCoordinator) + << base::SysNSStringToUTF8([self description]); _identityChooserCoordinator.delegate = nil; [_identityChooserCoordinator stop]; _identityChooserCoordinator = nil; @@ -1082,4 +1098,17 @@ [self startSignInOnlyFlow]; } +#pragma mark - NSObject + +- (NSString*)description { + return [NSString + stringWithFormat:@"<%@: %p, identity: %p, signinPromoViewState: %d, " + @"signinInProgress: %d, accessPoint: %d, " + @"signinPromoViewVisible: %d, invalidOrClosed %d>", + self.class.description, self, self.identity, + self.signinPromoViewState, self.signinInProgress, + self.accessPoint, self.signinPromoViewVisible, + self.invalidOrClosed]; +} + @end
diff --git a/ios/chrome/browser/ui/authentication/tangible_sync/tangible_sync_coordinator.mm b/ios/chrome/browser/ui/authentication/tangible_sync/tangible_sync_coordinator.mm index 0894ea5..c367728 100644 --- a/ios/chrome/browser/ui/authentication/tangible_sync/tangible_sync_coordinator.mm +++ b/ios/chrome/browser/ui/authentication/tangible_sync/tangible_sync_coordinator.mm
@@ -195,8 +195,8 @@ ->GetPrimaryIdentity(signin::ConsentLevel::kSignin); PostSignInAction postSignInAction = advancedSettings - ? POST_SIGNIN_ACTION_NONE - : POST_SIGNIN_ACTION_COMMIT_SYNC; + ? PostSignInAction::kNone + : PostSignInAction::kCommitSync; AuthenticationFlow* authenticationFlow = [[AuthenticationFlow alloc] initWithBrowser:self.browser identity:identity
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm b/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm index 4e71ea5..0b29685 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm
@@ -400,9 +400,9 @@ assertWithMatcher:grey_notVisible()]; } -// Tests that the Password View Controller is not present when presenting UI. -// TODO(crbug.com/1350323): Test is flaky. -- (void)DISABLED_testPasswordControllerPauses { +// Tests that the Password View Controller is still present after tapping the +// search bar. +- (void)testPasswordControllerWhileSearching { // Bring up the keyboard. [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()] performAction:TapWebElementWithId(kFormElementUsername)]; @@ -411,22 +411,29 @@ [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()] performAction:grey_tap()]; - // Tap the "Manage Passwords..." action. - [[EarlGrey selectElementWithMatcher:ManualFallbackManagePasswordsMatcher()] + // Tap the "Select Password..." action. + [[EarlGrey selectElementWithMatcher:ManualFallbackOtherPasswordsMatcher()] performAction:grey_tap()]; + // Acknowledge concerns using other passwords on a website. + [[EarlGrey selectElementWithMatcher:ConfirmUsingOtherPasswordButton()] + performAction:grey_tap()]; + + // Verify the use other passwords opened. + [[EarlGrey + selectElementWithMatcher:ManualFallbackOtherPasswordsDismissMatcher()] + assertWithMatcher:grey_sufficientlyVisible()]; + // Tap the password search. - [[EarlGrey selectElementWithMatcher:SettingsPasswordSearchMatcher()] + [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordSearchBarMatcher()] performAction:grey_tap()]; - // Verify keyboard is shown without the password controller. + // Verify keyboard is shown and that the password controller is still present + // in the background. GREYAssertTrue([EarlGrey isKeyboardShownWithError:nil], @"Keyboard Should be Shown"); [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()] - assertWithMatcher:grey_notVisible()]; - - [[EarlGrey selectElementWithMatcher:SettingsPasswordMatcher()] - performAction:grey_tap()]; + assertWithMatcher:grey_minimumVisiblePercent(0.6)]; } // Tests that the Password View Controller is dismissed when tapping the
diff --git a/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm b/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm index c20332d..6fea0abf 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm
@@ -131,6 +131,16 @@ [BookmarkEarlGrey verifyBookmarksWithTitle:@"my bookmark" expectedCount:1]; } +// Regression test for crbug.com/1426259. +// Tests that there is no crash when opening from incognito tab. +- (void)testOpeningBookmarksInIncognitoMode { + [ChromeEarlGrey openNewIncognitoTab]; + + [BookmarkEarlGrey setupStandardBookmarks]; + [BookmarkEarlGreyUI openBookmarks]; + [BookmarkEarlGreyUI openMobileBookmarks]; +} + // Tests that changes to the parent folder from the Single Bookmark Editor // are saved to the bookmark only when saving the results. - (void)testMoveDoesSaveOnSave {
diff --git a/ios/chrome/browser/ui/bring_android_tabs/BUILD.gn b/ios/chrome/browser/ui/bring_android_tabs/BUILD.gn new file mode 100644 index 0000000..6299bf2 --- /dev/null +++ b/ios/chrome/browser/ui/bring_android_tabs/BUILD.gn
@@ -0,0 +1,59 @@ +# 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. + +source_set("bring_android_tabs") { + configs += [ "//build/config/compiler:enable_arc" ] + sources = [ + "bring_android_tabs_prompt_coordinator.h", + "bring_android_tabs_prompt_coordinator.mm", + "bring_android_tabs_prompt_mediator.h", + "bring_android_tabs_prompt_mediator.mm", + ] + deps = [ + ":bring_android_tabs_ui", + "//base", + "//ios/chrome/browser/bring_android_tabs", + "//ios/chrome/browser/bring_android_tabs:features", + "//ios/chrome/browser/bring_android_tabs:metrics", + "//ios/chrome/browser/main:public", + "//ios/chrome/browser/shared/coordinator/chrome_coordinator", + "//ios/chrome/browser/shared/public/commands", + "//ios/chrome/browser/synced_sessions", + "//ios/chrome/browser/url_loading", + "//ios/chrome/browser/url_loading:url_loading_params_header", + ] +} + +source_set("bring_android_tabs_ui") { + sources = [ "bring_android_tabs_prompt_view_controller_delegate.h" ] + deps = [ + "//base", + "//ios/chrome/browser/shared/public/commands", + ] +} + +source_set("unit_tests") { + configs += [ "//build/config/compiler:enable_arc" ] + testonly = true + sources = [ "bring_android_tabs_prompt_mediator_unittest.mm" ] + deps = [ + ":bring_android_tabs", + "//base/test:test_support", + "//components/prefs", + "//components/segmentation_platform/embedder/default_model", + "//components/segmentation_platform/public", + "//ios/chrome/browser/bring_android_tabs", + "//ios/chrome/browser/bring_android_tabs:metrics", + "//ios/chrome/browser/browser_state:test_support", + "//ios/chrome/browser/main:test_support", + "//ios/chrome/browser/segmentation_platform", + "//ios/chrome/browser/sync", + "//ios/chrome/browser/synced_sessions", + "//ios/chrome/browser/url_loading", + "//ios/chrome/browser/url_loading:test_support", + "//ios/chrome/test:test_support", + "//ios/web/public/test", + "//testing/gtest:gtest", + ] +}
diff --git a/ios/chrome/browser/ui/bring_android_tabs/bring_android_tabs_prompt_coordinator.h b/ios/chrome/browser/ui/bring_android_tabs/bring_android_tabs_prompt_coordinator.h new file mode 100644 index 0000000..fe22df79 --- /dev/null +++ b/ios/chrome/browser/ui/bring_android_tabs/bring_android_tabs_prompt_coordinator.h
@@ -0,0 +1,21 @@ +// 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 IOS_CHROME_BROWSER_UI_BRING_ANDROID_TABS_BRING_ANDROID_TABS_PROMPT_COORDINATOR_H_ +#define IOS_CHROME_BROWSER_UI_BRING_ANDROID_TABS_BRING_ANDROID_TABS_PROMPT_COORDINATOR_H_ + +#import "ios/chrome/browser/shared/coordinator/chrome_coordinator/chrome_coordinator.h" + +#import <UIKit/UIKit.h> + +// Coordinator that manages the "Bring Android Tabs" prompt presentation and +// interaction. +@interface BringAndroidTabsPromptCoordinator : ChromeCoordinator + +// View controller for the prompt. +@property(nonatomic, strong) UIViewController* viewController; + +@end + +#endif // IOS_CHROME_BROWSER_UI_BRING_ANDROID_TABS_BRING_ANDROID_TABS_PROMPT_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/bring_android_tabs/bring_android_tabs_prompt_coordinator.mm b/ios/chrome/browser/ui/bring_android_tabs/bring_android_tabs_prompt_coordinator.mm new file mode 100644 index 0000000..b651e2d --- /dev/null +++ b/ios/chrome/browser/ui/bring_android_tabs/bring_android_tabs_prompt_coordinator.mm
@@ -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. + +#import "ios/chrome/browser/ui/bring_android_tabs/bring_android_tabs_prompt_coordinator.h" + +#import "base/check_op.h" +#import "ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service.h" +#import "ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service_factory.h" +#import "ios/chrome/browser/main/browser.h" +#import "ios/chrome/browser/shared/public/commands/bring_android_tabs_commands.h" +#import "ios/chrome/browser/ui/bring_android_tabs/bring_android_tabs_prompt_mediator.h" +#import "ios/chrome/browser/url_loading/url_loading_browser_agent.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@implementation BringAndroidTabsPromptCoordinator { + // Mediator that updates Chromium model objects; serves as a delegate to the + // view controller. + BringAndroidTabsPromptMediator* _mediator; +} + +- (void)start { + BringAndroidTabsToIOSService* service = + BringAndroidTabsToIOSServiceFactory::GetForBrowserStateIfExists( + self.browser->GetBrowserState()); + _mediator = [[BringAndroidTabsPromptMediator alloc] + initWithBringAndroidTabsService:service + URLLoader:UrlLoadingBrowserAgent::FromBrowser( + self.browser)]; + + // TODO(crbug.com/1418117): Create view controller for the prompts. + /*self.viewController = [UIViewController + initWithNumber:static_cast<int>(service->GetNumberOfAndroidTabs()) + delegate:_mediator + commandHandler:HandlerForProtocol(self.browser->GetCommandDispatcher(), + BringAndroidTabsCommands)];*/ +} + +- (void)stop { + // The view controller should have already dismissed itself using the + // Bring Android Commands handler. + DCHECK(self.viewController); + DCHECK(self.viewController.beingDismissed || + self.viewController.parentViewController == nil); + self.viewController = nil; + // Remove the mediator. + DCHECK(_mediator); + _mediator = nil; +} + +@end
diff --git a/ios/chrome/browser/ui/bring_android_tabs/bring_android_tabs_prompt_mediator.h b/ios/chrome/browser/ui/bring_android_tabs/bring_android_tabs_prompt_mediator.h new file mode 100644 index 0000000..d453327 --- /dev/null +++ b/ios/chrome/browser/ui/bring_android_tabs/bring_android_tabs_prompt_mediator.h
@@ -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. + +#ifndef IOS_CHROME_BROWSER_UI_BRING_ANDROID_TABS_BRING_ANDROID_TABS_PROMPT_MEDIATOR_H_ +#define IOS_CHROME_BROWSER_UI_BRING_ANDROID_TABS_BRING_ANDROID_TABS_PROMPT_MEDIATOR_H_ + +#import "ios/chrome/browser/ui/bring_android_tabs/bring_android_tabs_prompt_view_controller_delegate.h" + +#import <Foundation/Foundation.h> + +class BringAndroidTabsToIOSService; +class UrlLoadingBrowserAgent; + +// Mediator for "Bring Android Tabs" prompt that manages model interactions. +@interface BringAndroidTabsPromptMediator + : NSObject <BringAndroidTabsPromptViewControllerDelegate> + +// Designated initializer of the mediator, with `tabs` as a list of active tabs +// on the user's previous Android device to be brought to the current iOS +// device. +- (instancetype) + initWithBringAndroidTabsService:(BringAndroidTabsToIOSService*)service + URLLoader:(UrlLoadingBrowserAgent*)URLLoader + NS_DESIGNATED_INITIALIZER; + +- (instancetype)init NS_UNAVAILABLE; + +@end + +#endif // IOS_CHROME_BROWSER_UI_BRING_ANDROID_TABS_BRING_ANDROID_TABS_PROMPT_MEDIATOR_H_
diff --git a/ios/chrome/browser/ui/bring_android_tabs/bring_android_tabs_prompt_mediator.mm b/ios/chrome/browser/ui/bring_android_tabs/bring_android_tabs_prompt_mediator.mm new file mode 100644 index 0000000..5e60d58 --- /dev/null +++ b/ios/chrome/browser/ui/bring_android_tabs/bring_android_tabs_prompt_mediator.mm
@@ -0,0 +1,77 @@ +// 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/ui/bring_android_tabs/bring_android_tabs_prompt_mediator.h" + +#import "base/metrics/histogram_functions.h" +#import "ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service.h" +#import "ios/chrome/browser/bring_android_tabs/metrics.h" +#import "ios/chrome/browser/synced_sessions/synced_sessions_util.h" +#import "ios/chrome/browser/url_loading/url_loading_browser_agent.h" +#import "ios/chrome/browser/url_loading/url_loading_params.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@implementation BringAndroidTabsPromptMediator { + // Keyed service to retrieve active tabs from Android. + BringAndroidTabsToIOSService* _bringAndroidTabsService; + // URL loader to open tabs when needed. + UrlLoadingBrowserAgent* _URLLoader; + // Number of tabs active tabs from Android brought over. + size_t _tabCount; +} + +- (instancetype) + initWithBringAndroidTabsService:(BringAndroidTabsToIOSService*)service + URLLoader:(UrlLoadingBrowserAgent*)URLLoader { + DCHECK(service != nil); + self = [super init]; + if (self) { + _bringAndroidTabsService = service; + _URLLoader = URLLoader; + _tabCount = service->GetNumberOfAndroidTabs(); + } + return self; +} + +#pragma mark - BringAndroidTabsPromptViewControllerDelegate + +- (void)bringAndroidTabsPromptViewControllerDidShow { + base::UmaHistogramCounts1000(bring_android_tabs::kTabCountHistogramName, + _tabCount); + _bringAndroidTabsService->OnBringAndroidTabsPromptDisplayed(); +} + +- (void)bringAndroidTabsPromptViewControllerDidTapOpenAllButton { + [self onPromptDisappear:bring_android_tabs::PromptActionType::kOpenTabs]; + for (size_t idx = 0; idx < _tabCount; idx++) { + OpenDistantTabInBackground(_bringAndroidTabsService->GetTabAtIndex(idx), NO, + _URLLoader, UrlLoadStrategy::NORMAL); + } +} + +- (void)bringAndroidTabsPromptViewControllerDidTapReviewButton { + [self onPromptDisappear:bring_android_tabs::PromptActionType::kReviewTabs]; +} + +- (void)bringAndroidTabsPromptViewControllerDidDismiss:(BOOL)swiped { + [self onPromptDisappear: + swiped ? bring_android_tabs::PromptActionType::kSwipeToDismiss + : bring_android_tabs::PromptActionType::kCancel]; +} + +#pragma mark - Private + +// Helper method that takes the user's interaction with the prompt as +// `actionType` and logs a respective metric and notifies Chromium that the +// prompt has disappeared. +- (void)onPromptDisappear:(bring_android_tabs::PromptActionType)actionType { + base::UmaHistogramEnumeration(bring_android_tabs::kPromptActionHistogramName, + actionType); + _bringAndroidTabsService->OnUserInteractWithBringAndroidTabsPrompt(); +} + +@end
diff --git a/ios/chrome/browser/ui/bring_android_tabs/bring_android_tabs_prompt_mediator_unittest.mm b/ios/chrome/browser/ui/bring_android_tabs/bring_android_tabs_prompt_mediator_unittest.mm new file mode 100644 index 0000000..15d3b3f --- /dev/null +++ b/ios/chrome/browser/ui/bring_android_tabs/bring_android_tabs_prompt_mediator_unittest.mm
@@ -0,0 +1,184 @@ +// 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/ui/bring_android_tabs/bring_android_tabs_prompt_mediator.h" + +#import "base/test/metrics/histogram_tester.h" +#import "components/segmentation_platform/embedder/default_model/device_switcher_result_dispatcher.h" +#import "ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service.h" +#import "ios/chrome/browser/bring_android_tabs/metrics.h" +#import "ios/chrome/browser/browser_state/test_chrome_browser_state.h" +#import "ios/chrome/browser/main/test_browser.h" +#import "ios/chrome/browser/segmentation_platform/segmentation_platform_service_factory.h" +#import "ios/chrome/browser/sync/session_sync_service_factory.h" +#import "ios/chrome/browser/sync/sync_service_factory.h" +#import "ios/chrome/browser/synced_sessions/distant_tab.h" +#import "ios/chrome/browser/url_loading/fake_url_loading_browser_agent.h" +#import "ios/chrome/browser/url_loading/url_loading_notifier_browser_agent.h" +#import "ios/web/public/test/web_task_environment.h" +#import "testing/platform_test.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +// A fake BringAndroidTabsToIOSService for testing purpose, with permanently one +// tab. +class FakeServiceWithOneTab : public BringAndroidTabsToIOSService { + public: + FakeServiceWithOneTab( + std::unique_ptr<synced_sessions::DistantTab> tab, + segmentation_platform::DeviceSwitcherResultDispatcher* dispatcher, + syncer::SyncService* sync_service, + sync_sessions::SessionSyncService* session_sync_service, + PrefService* browser_state_prefs) + : BringAndroidTabsToIOSService(dispatcher, + sync_service, + session_sync_service, + browser_state_prefs), + tab_(std::move(tab)) {} + size_t GetNumberOfAndroidTabs() const override { return 1; } + synced_sessions::DistantTab* GetTabAtIndex(size_t index) const override { + return tab_.get(); + } + void OnBringAndroidTabsPromptDisplayed() override { displayed_ = true; } + void OnUserInteractWithBringAndroidTabsPrompt() override { + interacted_ = true; + } + + bool displayed() { return displayed_; } + bool interacted() { return interacted_; } + + private: + std::unique_ptr<synced_sessions::DistantTab> tab_; + bool displayed_ = false; + bool interacted_ = false; +}; + +// Test fixture for BringAndroidTabsPromptMediator. +class BringAndroidTabsPromptMediatorTest : public PlatformTest { + public: + BringAndroidTabsPromptMediatorTest() : PlatformTest() { + // Environment setup. + TestChromeBrowserState::Builder builder; + builder.AddTestingFactory( + segmentation_platform::SegmentationPlatformServiceFactory:: + GetInstance(), + segmentation_platform::SegmentationPlatformServiceFactory:: + GetDefaultFactory()); + browser_state_ = builder.Build(); + browser_ = std::make_unique<TestBrowser>(browser_state_.get()); + UrlLoadingNotifierBrowserAgent::CreateForBrowser(browser_.get()); + FakeUrlLoadingBrowserAgent::InjectForBrowser(browser_.get()); + url_loader_ = FakeUrlLoadingBrowserAgent::FromUrlLoadingBrowserAgent( + UrlLoadingBrowserAgent::FromBrowser(browser_.get())); + + // Create a tab in the mock BringAndroidTabsToIOS service. + std::unique_ptr<synced_sessions::DistantTab> tab = + std::make_unique<synced_sessions::DistantTab>(); + tab->virtual_url = kTestUrl; + // Create the BringAndroidTabsToIOSService. + segmentation_platform::DeviceSwitcherResultDispatcher* dispatcher = + segmentation_platform::SegmentationPlatformServiceFactory:: + GetDispatcherForBrowserState(browser_state_.get()); + syncer::SyncService* sync_service = + SyncServiceFactory::GetForBrowserState(browser_state_.get()); + sync_sessions::SessionSyncService* session_sync_service = + SessionSyncServiceFactory::GetForBrowserState(browser_state_.get()); + PrefService* prefs = browser_state_->GetPrefs(); + fake_bring_android_tabs_service_ = new FakeServiceWithOneTab( + std::move(tab), dispatcher, sync_service, session_sync_service, prefs); + + // Create the mediator. + mediator_ = [[BringAndroidTabsPromptMediator alloc] + initWithBringAndroidTabsService:fake_bring_android_tabs_service_ + URLLoader:url_loader_]; + } + // Property accessors. + id<BringAndroidTabsPromptViewControllerDelegate> delegate() { + return mediator_; + } + FakeServiceWithOneTab* bring_android_tabs_service() { + return fake_bring_android_tabs_service_; + } + web::NavigationManager::WebLoadParams last_loaded_url_params() { + return url_loader_->last_params.web_params; + } + + const GURL kTestUrl = GURL("http://chromium.org"); + + private: + // Environment mocks. + web::WebTaskEnvironment task_environment_; + FakeUrlLoadingBrowserAgent* url_loader_; + FakeServiceWithOneTab* fake_bring_android_tabs_service_; + // Mediator dependencies. + std::unique_ptr<TestChromeBrowserState> browser_state_; + std::unique_ptr<Browser> browser_; + BringAndroidTabsPromptMediator* mediator_; +}; + +// Tests that when the prompt is displayed, the mediator logs histogram and +// updates the profile pref accordingly. +TEST_F(BringAndroidTabsPromptMediatorTest, ShowPrompt) { + base::HistogramTester histogram_tester; + [delegate() bringAndroidTabsPromptViewControllerDidShow]; + histogram_tester.ExpectUniqueSample( + bring_android_tabs::kTabCountHistogramName, 1, 1); + EXPECT_TRUE(bring_android_tabs_service()->displayed()); + EXPECT_FALSE(bring_android_tabs_service()->interacted()); +} + +// Tests when the prompt is displayed and the user taps "open tabs", the +// mediator logs histogram, opens tabs on request, and that the prompt display +// is recorded. +TEST_F(BringAndroidTabsPromptMediatorTest, OpenTabs) { + base::HistogramTester histogram_tester; + [delegate() bringAndroidTabsPromptViewControllerDidShow]; + [delegate() bringAndroidTabsPromptViewControllerDidTapOpenAllButton]; + histogram_tester.ExpectUniqueSample( + bring_android_tabs::kPromptActionHistogramName, + bring_android_tabs::PromptActionType::kOpenTabs, 1); + EXPECT_EQ(kTestUrl, last_loaded_url_params().url); + EXPECT_TRUE( + ui::PageTransitionCoreTypeIs(ui::PAGE_TRANSITION_AUTO_BOOKMARK, + last_loaded_url_params().transition_type)); + EXPECT_TRUE(bring_android_tabs_service()->interacted()); +} + +// Tests that mediator logs histogram when the user taps "reviews tabs", and the +// interaction is recorded so that it would not be displayed again. +TEST_F(BringAndroidTabsPromptMediatorTest, ReviewTabs) { + base::HistogramTester histogram_tester; + [delegate() bringAndroidTabsPromptViewControllerDidShow]; + [delegate() bringAndroidTabsPromptViewControllerDidTapReviewButton]; + histogram_tester.ExpectUniqueSample( + bring_android_tabs::kPromptActionHistogramName, + bring_android_tabs::PromptActionType::kReviewTabs, 1); + EXPECT_TRUE(bring_android_tabs_service()->interacted()); +} + +// Tests that mediator logs histogram when the user closes the prompt, and the +// interaction is recorded so that it would not be displayed again. +TEST_F(BringAndroidTabsPromptMediatorTest, TapCloseButton) { + base::HistogramTester histogram_tester; + [delegate() bringAndroidTabsPromptViewControllerDidShow]; + [delegate() bringAndroidTabsPromptViewControllerDidDismiss:NO]; + histogram_tester.ExpectUniqueSample( + bring_android_tabs::kPromptActionHistogramName, + bring_android_tabs::PromptActionType::kCancel, 1); + EXPECT_TRUE(bring_android_tabs_service()->interacted()); +} + +// Tests that mediator logs histogram when the user swipes the prompt down, and +// the interaction is recorded so that it would not be displayed again. +TEST_F(BringAndroidTabsPromptMediatorTest, SwipeToDismiss) { + base::HistogramTester histogram_tester; + [delegate() bringAndroidTabsPromptViewControllerDidShow]; + [delegate() bringAndroidTabsPromptViewControllerDidDismiss:YES]; + histogram_tester.ExpectUniqueSample( + bring_android_tabs::kPromptActionHistogramName, + bring_android_tabs::PromptActionType::kSwipeToDismiss, 1); + EXPECT_TRUE(bring_android_tabs_service()->interacted()); +}
diff --git a/ios/chrome/browser/ui/bring_android_tabs/bring_android_tabs_prompt_view_controller_delegate.h b/ios/chrome/browser/ui/bring_android_tabs/bring_android_tabs_prompt_view_controller_delegate.h new file mode 100644 index 0000000..4923beb --- /dev/null +++ b/ios/chrome/browser/ui/bring_android_tabs/bring_android_tabs_prompt_view_controller_delegate.h
@@ -0,0 +1,28 @@ +// 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 IOS_CHROME_BROWSER_UI_BRING_ANDROID_TABS_BRING_ANDROID_TABS_PROMPT_VIEW_CONTROLLER_DELEGATE_H_ +#define IOS_CHROME_BROWSER_UI_BRING_ANDROID_TABS_BRING_ANDROID_TABS_PROMPT_VIEW_CONTROLLER_DELEGATE_H_ + +#import <Foundation/Foundation.h> + +// Delegate object that handles Chromium model updates according to user action. +@protocol BringAndroidTabsPromptViewControllerDelegate + +// Called when prompt is visible. +- (void)bringAndroidTabsPromptViewControllerDidShow; + +// User has tapped "open all tabs" button. +- (void)bringAndroidTabsPromptViewControllerDidTapOpenAllButton; + +// User has tapped "review" button. +- (void)bringAndroidTabsPromptViewControllerDidTapReviewButton; + +// User has dismissed the prompt. If the dismissal is done using a modal swipe, +// the parameter `swiped` is YES. +- (void)bringAndroidTabsPromptViewControllerDidDismiss:(BOOL)swiped; + +@end + +#endif // IOS_CHROME_BROWSER_UI_BRING_ANDROID_TABS_BRING_ANDROID_TABS_PROMPT_VIEW_CONTROLLER_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm index c994b81..85a5883 100644 --- a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm +++ b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
@@ -1298,7 +1298,7 @@ #pragma mark - ActivityServiceCommands -- (void)sharePage { +- (void)stopAndStartSharingCoordinator { SharingParams* params = [[SharingParams alloc] initWithScenario:SharingScenario::TabShareButton]; @@ -1312,6 +1312,8 @@ anchor = positioner.barButtonItem; } + [self.sharingCoordinator stop]; + self.sharingCoordinator = nil; self.sharingCoordinator = [[SharingCoordinator alloc] initWithBaseViewController:self.viewController browser:self.browser @@ -1319,9 +1321,19 @@ originView:positioner.sourceView originRect:positioner.sourceRect anchor:anchor]; + self.sharingCoordinator.activityHandler = + HandlerForProtocol(self.dispatcher, ActivityServiceCommands); [self.sharingCoordinator start]; } +- (void)sharePage { + if (!self.sharingCoordinator) { + [self stopAndStartSharingCoordinator]; + } else { + [self.sharingCoordinator cancelIfNecessaryAndCreateNewCoordinator]; + } +} + - (void)shareChromeApp { GURL URL = GURL(kChromeAppStoreUrl); NSString* title =
diff --git a/ios/chrome/browser/ui/content_suggestions/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/BUILD.gn index a5d394a..679923f 100644 --- a/ios/chrome/browser/ui/content_suggestions/BUILD.gn +++ b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
@@ -77,6 +77,7 @@ "//ios/chrome/browser/ntp_tiles", "//ios/chrome/browser/policy:policy_util", "//ios/chrome/browser/prefs:pref_names", + "//ios/chrome/browser/promos_manager:factory", "//ios/chrome/browser/reading_list", "//ios/chrome/browser/search_engines", "//ios/chrome/browser/shared/coordinator/chrome_coordinator", @@ -191,6 +192,7 @@ "//ios/chrome/browser/ui/content_suggestions/identifier", "//ios/chrome/browser/ui/elements", "//ios/chrome/browser/ui/icons:symbols", + "//ios/chrome/browser/ui/lens:lens_availability", "//ios/chrome/browser/ui/lens:lens_entrypoint", "//ios/chrome/browser/ui/ntp", "//ios/chrome/browser/ui/ntp:logo", @@ -282,6 +284,7 @@ "//ios/chrome/browser/main:public", "//ios/chrome/browser/main:test_support", "//ios/chrome/browser/ntp", + "//ios/chrome/browser/promos_manager:test_support", "//ios/chrome/browser/reading_list", "//ios/chrome/browser/reading_list:test_support", "//ios/chrome/browser/search_engines",
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm index 12586ea..d243b594 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm
@@ -26,6 +26,7 @@ #import "ios/chrome/browser/ntp_tiles/ios_most_visited_sites_factory.h" #import "ios/chrome/browser/policy/policy_util.h" #import "ios/chrome/browser/prefs/pref_names.h" +#import "ios/chrome/browser/promos_manager/promos_manager_factory.h" #import "ios/chrome/browser/reading_list/reading_list_model_factory.h" #import "ios/chrome/browser/shared/public/commands/application_commands.h" #import "ios/chrome/browser/shared/public/commands/browser_coordinator_commands.h" @@ -138,6 +139,8 @@ ReadingListModel* readingListModel = ReadingListModelFactory::GetForBrowserState( self.browser->GetBrowserState()); + PromosManager* promosManager = + PromosManagerFactory::GetForBrowserState(self.browser->GetBrowserState()); BOOL isGoogleDefaultSearchProvider = [self.ntpDelegate isGoogleDefaultSearchEngine]; @@ -151,6 +154,7 @@ isGoogleDefaultSearchProvider:isGoogleDefaultSearchProvider browser:self.browser]; self.contentSuggestionsMediator.feedDelegate = self.feedDelegate; + self.contentSuggestionsMediator.promosManager = promosManager; // TODO(crbug.com/1045047): Use HandlerForProtocol after commands protocol // clean up. self.contentSuggestionsMediator.dispatcher =
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view.mm index 357a253..3d139b78 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view.mm
@@ -19,6 +19,7 @@ #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_feature.h" #import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h" #import "ios/chrome/browser/ui/elements/extended_touch_target_button.h" +#import "ios/chrome/browser/ui/lens/lens_availability.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_delegate.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_header_constants.h" #import "ios/chrome/browser/ui/omnibox/omnibox_constants.h" @@ -269,9 +270,9 @@ UIButton* endButton = self.voiceSearchButton; // Lens. - const BOOL lensEnabled = ios::provider::IsLensSupported() && - base::FeatureList::IsEnabled(kEnableLensInNTP); - const BOOL useLens = lensEnabled && self.isGoogleDefaultSearchEngine; + const BOOL useLens = + lens_availability::CheckAndLogAvailabilityForLensEntryPoint( + LensEntrypoint::NewTabPage, self.isGoogleDefaultSearchEngine); if (useLens) { self.lensButton = [ExtendedTouchTargetButton buttonWithType:UIButtonTypeSystem];
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.h index b1ecd17..8d8bd4a06 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.h +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.h
@@ -34,6 +34,7 @@ @protocol FeedDelegate; class GURL; class LargeIconCache; +class PromosManager; class ReadingListModel; @protocol SnackbarCommands; class WebStateList; @@ -83,6 +84,9 @@ // The web state associated with this NTP. @property(nonatomic, assign) web::WebState* webState; +// The promos manager to alert if the user uses What's New. +@property(nonatomic, assign) PromosManager* promosManager; + // Disconnects the mediator. - (void)disconnect;
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm index 414575ff..bc837fb 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm
@@ -337,7 +337,7 @@ [self.dispatcher showHistory]; break; case NTPCollectionShortcutTypeWhatsNew: - SetWhatsNewUsed(); + SetWhatsNewUsed(self.promosManager); base::RecordAction(base::UserMetricsAction("MobileNTPShowWhatsNew")); [self.dispatcher showWhatsNew]; break;
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator_unittest.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator_unittest.mm index 80881a4f3..da999d1 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator_unittest.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator_unittest.mm
@@ -20,6 +20,7 @@ #import "ios/chrome/browser/main/browser.h" #import "ios/chrome/browser/main/test_browser.h" #import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h" +#import "ios/chrome/browser/promos_manager/mock_promos_manager.h" #import "ios/chrome/browser/reading_list/reading_list_model_factory.h" #import "ios/chrome/browser/reading_list/reading_list_test_utils.h" #import "ios/chrome/browser/search_engines/template_url_service_factory.h" @@ -110,6 +111,9 @@ mediator_.webStateList = browser_.get()->GetWebStateList(); mediator_.webState = fake_web_state_.get(); + promos_manager_ = std::make_unique<MockPromosManager>(); + mediator_.promosManager = promos_manager_.get(); + StartSurfaceRecentTabBrowserAgent::CreateForBrowser(browser_.get()); UrlLoadingNotifierBrowserAgent::CreateForBrowser(browser_.get()); FakeUrlLoadingBrowserAgent::InjectForBrowser(browser_.get()); @@ -140,6 +144,7 @@ id dispatcher_; id consumer_; std::unique_ptr<favicon::LargeIconServiceImpl> large_icon_service_; + std::unique_ptr<MockPromosManager> promos_manager_; ContentSuggestionsMediator* mediator_; FakeUrlLoadingBrowserAgent* url_loader_; std::unique_ptr<base::HistogramTester> histogram_tester_;
diff --git a/ios/chrome/browser/ui/context_menu/context_menu_configuration_provider.mm b/ios/chrome/browser/ui/context_menu/context_menu_configuration_provider.mm index 5a650f3..859afe8f 100644 --- a/ios/chrome/browser/ui/context_menu/context_menu_configuration_provider.mm +++ b/ios/chrome/browser/ui/context_menu/context_menu_configuration_provider.mm
@@ -6,7 +6,6 @@ #import "base/ios/ios_util.h" #import "base/metrics/histogram_functions.h" -#import "base/metrics/histogram_macros.h" #import "base/metrics/user_metrics.h" #import "components/prefs/pref_service.h" #import "components/search_engines/template_url_service.h" @@ -258,13 +257,10 @@ ios::TemplateURLServiceFactory::GetForBrowserState( self.browser->GetBrowserState()); - const BOOL lensEnabled = - ios::provider::IsLensSupported() && - base::FeatureList::IsEnabled(kUseLensToSearchForImage); const BOOL useLens = - lensEnabled && search_engines::SupportsSearchImageWithLens(service) && - ui::GetDeviceFormFactor() != ui::DEVICE_FORM_FACTOR_TABLET; - + lens_availability::CheckAndLogAvailabilityForLensEntryPoint( + LensEntrypoint::ContextMenu, + search_engines::SupportsSearchImageWithLens(service)); if (useLens) { UIAction* searchImageWithLensAction = [actionFactory actionToSearchImageUsingLensWithBlock:^{ @@ -273,14 +269,6 @@ referrer:referrer]; }]; [menuElements addObject:searchImageWithLensAction]; - UMA_HISTOGRAM_ENUMERATION(kIOSLensSupportStatusHistogram, - LensSupportStatus::LensSearchSupported); - } else if (ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET) { - UMA_HISTOGRAM_ENUMERATION(kIOSLensSupportStatusHistogram, - LensSupportStatus::DeviceFormFactorTablet); - } else { - UMA_HISTOGRAM_ENUMERATION(kIOSLensSupportStatusHistogram, - LensSupportStatus::NonGoogleSearchEngine); } if (!useLens && search_engines::SupportsSearchByImage(service)) {
diff --git a/ios/chrome/browser/ui/credential_provider_promo/BUILD.gn b/ios/chrome/browser/ui/credential_provider_promo/BUILD.gn index 05dca1d..733577e 100644 --- a/ios/chrome/browser/ui/credential_provider_promo/BUILD.gn +++ b/ios/chrome/browser/ui/credential_provider_promo/BUILD.gn
@@ -29,6 +29,7 @@ "//ios/chrome/browser/main:public", "//ios/chrome/browser/prefs:pref_names", "//ios/chrome/browser/promos_manager", + "//ios/chrome/browser/promos_manager:factory", "//ios/chrome/browser/promos_manager:features", "//ios/chrome/browser/promos_manager:types", "//ios/chrome/browser/shared/coordinator/chrome_coordinator",
diff --git a/ios/chrome/browser/ui/credential_provider_promo/credential_provider_promo_coordinator.mm b/ios/chrome/browser/ui/credential_provider_promo/credential_provider_promo_coordinator.mm index 46f156f7..01b81d0 100644 --- a/ios/chrome/browser/ui/credential_provider_promo/credential_provider_promo_coordinator.mm +++ b/ios/chrome/browser/ui/credential_provider_promo/credential_provider_promo_coordinator.mm
@@ -9,6 +9,7 @@ #import "ios/chrome/browser/browser_state/chrome_browser_state.h" #import "ios/chrome/browser/main/browser.h" #import "ios/chrome/browser/prefs/pref_names.h" +#import "ios/chrome/browser/promos_manager/promos_manager_factory.h" #import "ios/chrome/browser/shared/public/commands/command_dispatcher.h" #import "ios/chrome/browser/shared/public/commands/credential_provider_promo_commands.h" #import "ios/chrome/browser/shared/public/commands/promos_manager_commands.h" @@ -57,8 +58,10 @@ [self.browser->GetCommandDispatcher() startDispatchingToTarget:self forProtocol:@protocol(CredentialProviderPromoCommands)]; + PromosManager* promosManager = + PromosManagerFactory::GetForBrowserState(self.browser->GetBrowserState()); self.mediator = [[CredentialProviderPromoMediator alloc] - initWithPromosManager:GetApplicationContext()->GetPromosManager() + initWithPromosManager:promosManager prefService:self.browser->GetBrowserState()->GetPrefs()]; }
diff --git a/ios/chrome/browser/ui/first_run/signin/signin_screen_coordinator.mm b/ios/chrome/browser/ui/first_run/signin/signin_screen_coordinator.mm index 1aed17c..3fa5f76 100644 --- a/ios/chrome/browser/ui/first_run/signin/signin_screen_coordinator.mm +++ b/ios/chrome/browser/ui/first_run/signin/signin_screen_coordinator.mm
@@ -175,7 +175,7 @@ AuthenticationFlow* authenticationFlow = [[AuthenticationFlow alloc] initWithBrowser:self.browser identity:self.mediator.selectedIdentity - postSignInAction:POST_SIGNIN_ACTION_NONE + postSignInAction:PostSignInAction::kNone presentingViewController:self.viewController]; authenticationFlow.dispatcher = HandlerForProtocol( self.browser->GetCommandDispatcher(), BrowsingDataCommands);
diff --git a/ios/chrome/browser/ui/icons/BUILD.gn b/ios/chrome/browser/ui/icons/BUILD.gn index 8198ceb..19f627e 100644 --- a/ios/chrome/browser/ui/icons/BUILD.gn +++ b/ios/chrome/browser/ui/icons/BUILD.gn
@@ -73,6 +73,7 @@ "//ios/chrome/browser/ui/icons/resources:laptopcomputer_and_phone", "//ios/chrome/browser/ui/icons/resources:legacy_cloud_and_arrow_up", "//ios/chrome/browser/ui/icons/resources:legacy_cloud_slash", + "//ios/chrome/browser/ui/icons/resources:legacy_plus_circle_fill", "//ios/chrome/browser/ui/icons/resources:line_downtrend", "//ios/chrome/browser/ui/icons/resources:location", "//ios/chrome/browser/ui/icons/resources:location.fill", @@ -91,6 +92,7 @@ "//ios/chrome/browser/ui/icons/resources:tab_grid_new_tab_floating_button_incognito_ios14", "//ios/chrome/browser/ui/icons/resources:tab_grid_new_tab_floating_button_ios14", "//ios/chrome/browser/ui/icons/resources:translate", + "//ios/chrome/browser/ui/icons/resources:tuner", "//ios/chrome/common/ui/colors", ios_branded_icons, ]
diff --git a/ios/chrome/browser/ui/icons/resources/BUILD.gn b/ios/chrome/browser/ui/icons/resources/BUILD.gn index a430f42..3d53af7 100644 --- a/ios/chrome/browser/ui/icons/resources/BUILD.gn +++ b/ios/chrome/browser/ui/icons/resources/BUILD.gn
@@ -126,6 +126,13 @@ ] } +symbolset("legacy_plus_circle_fill") { + sources = [ + "legacy_plus_circle_fill.symbolset/Contents.json", + "legacy_plus_circle_fill.symbolset/legacy.plus.circle.fill.cr.svg", + ] +} + imageset("plus_circle_fill_ios14") { sources = [ "plus_circle_fill_ios14.imageset/Contents.json", @@ -273,3 +280,10 @@ "chrome_product.symbolset/chrome.product.cr.svg", ] } + +symbolset("tuner") { + sources = [ + "tuner.symbolset/Contents.json", + "tuner.symbolset/tuner.cr.svg", + ] +}
diff --git a/ios/chrome/browser/ui/icons/resources/legacy_plus_circle_fill.symbolset/Contents.json b/ios/chrome/browser/ui/icons/resources/legacy_plus_circle_fill.symbolset/Contents.json new file mode 100644 index 0000000..46317b1d --- /dev/null +++ b/ios/chrome/browser/ui/icons/resources/legacy_plus_circle_fill.symbolset/Contents.json
@@ -0,0 +1,12 @@ +{ + "info": { + "author": "xcode", + "version": 1 + }, + "symbols": [ + { + "filename": "legacy.plus.circle.fill.cr.svg", + "idiom": "universal" + } + ] +}
diff --git a/ios/chrome/browser/ui/icons/resources/legacy_plus_circle_fill.symbolset/legacy.plus.circle.fill.cr.svg b/ios/chrome/browser/ui/icons/resources/legacy_plus_circle_fill.symbolset/legacy.plus.circle.fill.cr.svg new file mode 100644 index 0000000..d3feeab --- /dev/null +++ b/ios/chrome/browser/ui/icons/resources/legacy_plus_circle_fill.symbolset/legacy.plus.circle.fill.cr.svg
@@ -0,0 +1,194 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!--Generator: Apple Native CoreSVG 175--> +<!DOCTYPE svg +PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="3300" height="2200"> + <!--glyph: "", point size: 100.0, font version: "17.3d3e1", template writer version: "65.1"--> + <style>.hierarchical-0:secondary {fill:#4D4D4D} +.hierarchical-1:primary {fill:#212121} + +.SFSymbolsPreview212121 {fill:#212121;opacity:1.0} +.SFSymbolsPreview4D4D4D {fill:#4D4D4D;opacity:1.0} +</style> + <g id="Notes"> + <rect height="2200" id="artboard" style="fill:white;opacity:1" width="3300" x="0" y="0"/> + <line style="fill:none;stroke:black;opacity:1;stroke-width:0.5;" x1="263" x2="3036" y1="292" y2="292"/> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;font-weight:bold;" transform="matrix(1 0 0 1 263 322)">Weight/Scale Variations</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:middle;" transform="matrix(1 0 0 1 559.711 322)">Ultralight</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:middle;" transform="matrix(1 0 0 1 856.422 322)">Thin</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:middle;" transform="matrix(1 0 0 1 1153.13 322)">Light</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:middle;" transform="matrix(1 0 0 1 1449.84 322)">Regular</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:middle;" transform="matrix(1 0 0 1 1746.56 322)">Medium</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:middle;" transform="matrix(1 0 0 1 2043.27 322)">Semibold</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:middle;" transform="matrix(1 0 0 1 2339.98 322)">Bold</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:middle;" transform="matrix(1 0 0 1 2636.69 322)">Heavy</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:middle;" transform="matrix(1 0 0 1 2933.4 322)">Black</text> + <line style="fill:none;stroke:black;opacity:1;stroke-width:0.5;" x1="263" x2="3036" y1="1903" y2="1903"/> + <g transform="matrix(1 0 0 1 263 1933)"> + <path d="M9.24805 0.830078Q10.8691 0.830078 12.2949 0.214844Q13.7207-0.400391 14.8096-1.49414Q15.8984-2.58789 16.5186-4.01367Q17.1387-5.43945 17.1387-7.05078Q17.1387-8.66211 16.5186-10.0879Q15.8984-11.5137 14.8047-12.6074Q13.7109-13.7012 12.2852-14.3164Q10.8594-14.9316 9.23828-14.9316Q7.62695-14.9316 6.20117-14.3164Q4.77539-13.7012 3.69141-12.6074Q2.60742-11.5137 1.9873-10.0879Q1.36719-8.66211 1.36719-7.05078Q1.36719-5.43945 1.9873-4.01367Q2.60742-2.58789 3.69629-1.49414Q4.78516-0.400391 6.21094 0.214844Q7.63672 0.830078 9.24805 0.830078ZM9.24805-0.654297Q7.91992-0.654297 6.7627-1.14746Q5.60547-1.64062 4.73145-2.51953Q3.85742-3.39844 3.36426-4.56055Q2.87109-5.72266 2.87109-7.05078Q2.87109-8.37891 3.35938-9.54102Q3.84766-10.7031 4.72168-11.582Q5.5957-12.4609 6.75293-12.9541Q7.91016-13.4473 9.23828-13.4473Q10.5762-13.4473 11.7334-12.9541Q12.8906-12.4609 13.7695-11.582Q14.6484-10.7031 15.1465-9.54102Q15.6445-8.37891 15.6445-7.05078Q15.6445-5.72266 15.1514-4.56055Q14.6582-3.39844 13.7842-2.51953Q12.9102-1.64062 11.748-1.14746Q10.5859-0.654297 9.24805-0.654297ZM5.6543-7.05078Q5.6543-6.72852 5.85938-6.52832Q6.06445-6.32812 6.40625-6.32812L8.51562-6.32812L8.51562-4.20898Q8.51562-3.88672 8.71094-3.67676Q8.90625-3.4668 9.23828-3.4668Q9.56055-3.4668 9.77051-3.67676Q9.98047-3.88672 9.98047-4.20898L9.98047-6.32812L12.0898-6.32812Q12.4219-6.32812 12.627-6.52832Q12.832-6.72852 12.832-7.05078Q12.832-7.38281 12.627-7.58789Q12.4219-7.79297 12.0898-7.79297L9.98047-7.79297L9.98047-9.90234Q9.98047-10.2344 9.77051-10.4443Q9.56055-10.6543 9.23828-10.6543Q8.90625-10.6543 8.71094-10.4443Q8.51562-10.2344 8.51562-9.90234L8.51562-7.79297L6.40625-7.79297Q6.06445-7.79297 5.85938-7.58789Q5.6543-7.38281 5.6543-7.05078Z"/> + </g> + <g transform="matrix(1 0 0 1 281.867 1933)"> + <path d="M11.709 2.91016Q13.75 2.91016 15.5518 2.12891Q17.3535 1.34766 18.7305-0.0292969Q20.1074-1.40625 20.8887-3.20801Q21.6699-5.00977 21.6699-7.05078Q21.6699-9.0918 20.8887-10.8936Q20.1074-12.6953 18.7305-14.0723Q17.3535-15.4492 15.5469-16.2305Q13.7402-17.0117 11.6992-17.0117Q9.6582-17.0117 7.85645-16.2305Q6.05469-15.4492 4.68262-14.0723Q3.31055-12.6953 2.5293-10.8936Q1.74805-9.0918 1.74805-7.05078Q1.74805-5.00977 2.5293-3.20801Q3.31055-1.40625 4.6875-0.0292969Q6.06445 1.34766 7.86621 2.12891Q9.66797 2.91016 11.709 2.91016ZM11.709 1.25Q9.98047 1.25 8.47656 0.605469Q6.97266-0.0390625 5.83496-1.17676Q4.69727-2.31445 4.05762-3.81836Q3.41797-5.32227 3.41797-7.05078Q3.41797-8.7793 4.05762-10.2832Q4.69727-11.7871 5.83008-12.9297Q6.96289-14.0723 8.4668-14.7119Q9.9707-15.3516 11.6992-15.3516Q13.4277-15.3516 14.9316-14.7119Q16.4355-14.0723 17.5781-12.9297Q18.7207-11.7871 19.3652-10.2832Q20.0098-8.7793 20.0098-7.05078Q20.0098-5.32227 19.3701-3.81836Q18.7305-2.31445 17.5928-1.17676Q16.4551-0.0390625 14.9463 0.605469Q13.4375 1.25 11.709 1.25ZM7.17773-7.05078Q7.17773-6.69922 7.41211-6.47461Q7.64648-6.25 8.01758-6.25L10.8887-6.25L10.8887-3.36914Q10.8887-2.99805 11.1133-2.76855Q11.3379-2.53906 11.6895-2.53906Q12.0605-2.53906 12.29-2.76855Q12.5195-2.99805 12.5195-3.36914L12.5195-6.25L15.4004-6.25Q15.7715-6.25 16.001-6.47461Q16.2305-6.69922 16.2305-7.05078Q16.2305-7.42188 16.001-7.65137Q15.7715-7.88086 15.4004-7.88086L12.5195-7.88086L12.5195-10.752Q12.5195-11.1328 12.29-11.3623Q12.0605-11.5918 11.6895-11.5918Q11.3379-11.5918 11.1133-11.3574Q10.8887-11.123 10.8887-10.752L10.8887-7.88086L8.01758-7.88086Q7.63672-7.88086 7.40723-7.65137Q7.17773-7.42188 7.17773-7.05078Z"/> + </g> + <g transform="matrix(1 0 0 1 305.646 1933)"> + <path d="M14.9707 5.66406Q17.0605 5.66406 18.96 5.01465Q20.8594 4.36523 22.4512 3.19336Q24.043 2.02148 25.2197 0.429688Q26.3965-1.16211 27.0459-3.06641Q27.6953-4.9707 27.6953-7.05078Q27.6953-9.14062 27.0459-11.04Q26.3965-12.9395 25.2197-14.5312Q24.043-16.123 22.4512-17.2998Q20.8594-18.4766 18.9551-19.126Q17.0508-19.7754 14.9609-19.7754Q12.8711-19.7754 10.9717-19.126Q9.07227-18.4766 7.48535-17.2998Q5.89844-16.123 4.72168-14.5312Q3.54492-12.9395 2.90039-11.04Q2.25586-9.14062 2.25586-7.05078Q2.25586-4.9707 2.90527-3.06641Q3.55469-1.16211 4.72656 0.429688Q5.89844 2.02148 7.49023 3.19336Q9.08203 4.36523 10.9814 5.01465Q12.8809 5.66406 14.9707 5.66406ZM14.9707 3.84766Q13.1641 3.84766 11.5283 3.2959Q9.89258 2.74414 8.53516 1.74805Q7.17773 0.751953 6.17676-0.610352Q5.17578-1.97266 4.62891-3.6084Q4.08203-5.24414 4.08203-7.05078Q4.08203-8.86719 4.62891-10.5029Q5.17578-12.1387 6.17188-13.501Q7.16797-14.8633 8.52539-15.8594Q9.88281-16.8555 11.5186-17.4023Q13.1543-17.9492 14.9609-17.9492Q16.7773-17.9492 18.4131-17.4023Q20.0488-16.8555 21.4111-15.8594Q22.7734-14.8633 23.7695-13.501Q24.7656-12.1387 25.3174-10.5029Q25.8691-8.86719 25.8691-7.05078Q25.8789-5.24414 25.332-3.6084Q24.7852-1.97266 23.7842-0.610352Q22.7832 0.751953 21.4209 1.74805Q20.0586 2.74414 18.4229 3.2959Q16.7871 3.84766 14.9707 3.84766ZM9.19922-7.05078Q9.19922-6.66992 9.45801-6.4209Q9.7168-6.17188 10.1172-6.17188L14.0625-6.17188L14.0625-2.2168Q14.0625-1.81641 14.3115-1.55762Q14.5605-1.29883 14.9512-1.29883Q15.3516-1.29883 15.6104-1.55273Q15.8691-1.80664 15.8691-2.2168L15.8691-6.17188L19.8242-6.17188Q20.2246-6.17188 20.4785-6.4209Q20.7324-6.66992 20.7324-7.05078Q20.7324-7.46094 20.4785-7.71484Q20.2246-7.96875 19.8242-7.96875L15.8691-7.96875L15.8691-11.9141Q15.8691-12.3242 15.6104-12.583Q15.3516-12.8418 14.9512-12.8418Q14.5605-12.8418 14.3115-12.583Q14.0625-12.3242 14.0625-11.9141L14.0625-7.96875L10.1172-7.96875Q9.70703-7.96875 9.45312-7.71484Q9.19922-7.46094 9.19922-7.05078Z"/> + </g> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;font-weight:bold;" transform="matrix(1 0 0 1 263 1953)">Design Variations</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 263 1971)">Symbols are supported in up to nine weights and three scales.</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 263 1989)">For optimal layout with text and other symbols, vertically align</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 263 2007)">symbols with the adjacent text.</text> + <line style="fill:none;stroke:#00AEEF;stroke-width:0.5;opacity:1.0;" x1="776" x2="776" y1="1919" y2="1933"/> + <g transform="matrix(1 0 0 1 776 1933)"> + <path d="M3.31055 0.15625Q3.70117 0.15625 3.91602-0.00976562Q4.13086-0.175781 4.26758-0.585938L5.52734-4.0332L11.2891-4.0332L12.5488-0.585938Q12.6855-0.175781 12.9004-0.00976562Q13.1152 0.15625 13.4961 0.15625Q13.8867 0.15625 14.1162-0.0585938Q14.3457-0.273438 14.3457-0.644531Q14.3457-0.869141 14.2383-1.17188L9.6582-13.3691Q9.48242-13.8184 9.17969-14.043Q8.87695-14.2676 8.4082-14.2676Q7.5-14.2676 7.17773-13.3789L2.59766-1.16211Q2.49023-0.859375 2.49023-0.634766Q2.49023-0.263672 2.70996-0.0537109Q2.92969 0.15625 3.31055 0.15625ZM6.00586-5.51758L8.37891-12.0898L8.42773-12.0898L10.8008-5.51758Z"/> + </g> + <line style="fill:none;stroke:#00AEEF;stroke-width:0.5;opacity:1.0;" x1="793.197" x2="793.197" y1="1919" y2="1933"/> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;font-weight:bold;" transform="matrix(1 0 0 1 776 1953)">Margins</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 776 1971)">Leading and trailing margins on the left and right side of each symbol</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 776 1989)">can be adjusted by modifying the x-location of the margin guidelines.</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 776 2007)">Modifications are automatically applied proportionally to all</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 776 2025)">scales and weights.</text> + <g transform="matrix(1 0 0 1 1289 1933)"> + <path d="M2.8418 1.86523L4.54102 3.57422Q5.18555 4.22852 5.90332 4.17969Q6.62109 4.13086 7.31445 3.35938L18.0078-8.42773L17.041-9.4043L6.42578 2.27539Q6.16211 2.57812 5.89355 2.61719Q5.625 2.65625 5.27344 2.30469L4.10156 1.14258Q3.75 0.791016 3.79395 0.522461Q3.83789 0.253906 4.14062-0.0195312L15.6152-10.8203L14.6387-11.7871L3.04688-0.898438Q2.30469-0.214844 2.25098 0.498047Q2.19727 1.21094 2.8418 1.86523ZM9.25781-16.3281Q8.94531-16.0254 8.90625-15.6348Q8.86719-15.2441 9.04297-14.9512Q9.21875-14.6777 9.55566-14.541Q9.89258-14.4043 10.3809-14.5215Q11.4746-14.7754 12.5977-14.7314Q13.7207-14.6875 14.7949-13.9844L14.209-12.5293Q13.9551-11.9043 14.0674-11.4404Q14.1797-10.9766 14.5801-10.5664L16.875-8.25195Q17.2363-7.88086 17.5781-7.82227Q17.9199-7.76367 18.3398-7.8418L19.4043-8.03711L20.0684-7.36328L20.0293-6.80664Q20-6.43555 20.1221-6.12305Q20.2441-5.81055 20.6055-5.44922L21.3672-4.70703Q21.7285-4.3457 22.1533-4.33105Q22.5781-4.31641 22.9297-4.66797L25.8398-7.58789Q26.1914-7.93945 26.1816-8.35449Q26.1719-8.76953 25.8105-9.13086L25.0391-9.89258Q24.6875-10.2539 24.3799-10.3857Q24.0723-10.5176 23.7109-10.4883L23.1348-10.4395L22.4902-11.0742L22.7344-12.1973Q22.832-12.6172 22.6953-12.9834Q22.5586-13.3496 22.1191-13.7891L19.9219-15.9766Q18.6719-17.2168 17.2607-17.8369Q15.8496-18.457 14.4189-18.4814Q12.9883-18.5059 11.665-17.959Q10.3418-17.4121 9.25781-16.3281ZM10.752-15.957Q11.6602-16.6211 12.7002-16.9043Q13.7402-17.1875 14.8047-17.085Q15.8691-16.9824 16.8701-16.5137Q17.8711-16.0449 18.7012-15.2051L21.1328-12.793Q21.3086-12.6172 21.3525-12.4512Q21.3965-12.2852 21.3379-12.0312L21.0156-10.5469L22.5195-9.0625L23.5059-9.12109Q23.6914-9.13086 23.7891-9.09668Q23.8867-9.0625 24.0332-8.91602L24.6094-8.33984L22.168-5.89844L21.5918-6.47461Q21.4453-6.62109 21.4062-6.71875Q21.3672-6.81641 21.377-7.01172L21.4453-7.98828L19.9512-9.47266L18.4277-9.21875Q18.1836-9.16992 18.042-9.2041Q17.9004-9.23828 17.7148-9.41406L15.7129-11.416Q15.5176-11.5918 15.4932-11.7529Q15.4688-11.9141 15.5859-12.1875L16.4648-14.2773Q15.293-15.3711 13.8281-15.791Q12.3633-16.2109 10.8398-15.7617Q10.7227-15.7324 10.6885-15.8057Q10.6543-15.8789 10.752-15.957Z"/> + </g> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;font-weight:bold;" transform="matrix(1 0 0 1 1289 1953)">Exporting</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 1289 1971)">Symbols should be outlined when exporting to ensure the</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 1289 1989)">design is preserved when submitting to Xcode.</text> + <text id="template-version" style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:end;" transform="matrix(1 0 0 1 3036 1933)">Template v.3.0</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:end;" transform="matrix(1 0 0 1 3036 1951)">Requires Xcode 13 or greater</text> + <text id="descriptive-name" style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:end;" transform="matrix(1 0 0 1 3036 1969)">Generated from plus.circle.fill.cr</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:end;" transform="matrix(1 0 0 1 3036 1987)">Typeset at 100 points</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 263 726)">Small</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 263 1156)">Medium</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 263 1586)">Large</text> + </g> + <g id="Guides"> + <g id="H-reference" style="fill:#27AAE1;stroke:none;" transform="matrix(1 0 0 1 339 696)"> + <path d="M0.993347 0L3.6377 0L29.3282-67.1326L30.0301-67.1326L30.0301-70.459L28.1227-70.459ZM11.6882-24.4797L46.9818-24.4797L46.2311-26.7288L12.4382-26.7288ZM55.1193 0L57.7637 0L30.6381-70.459L29.4327-70.459L29.4327-67.1326Z"/> + </g> + <line id="Baseline-S" style="fill:none;stroke:#27AAE1;opacity:1;stroke-width:0.5;" x1="263" x2="3036" y1="696" y2="696"/> + <line id="Capline-S" style="fill:none;stroke:#27AAE1;opacity:1;stroke-width:0.5;" x1="263" x2="3036" y1="625.541" y2="625.541"/> + <g id="H-reference" style="fill:#27AAE1;stroke:none;" transform="matrix(1 0 0 1 339 1126)"> + <path d="M0.993347 0L3.6377 0L29.3282-67.1326L30.0301-67.1326L30.0301-70.459L28.1227-70.459ZM11.6882-24.4797L46.9818-24.4797L46.2311-26.7288L12.4382-26.7288ZM55.1193 0L57.7637 0L30.6381-70.459L29.4327-70.459L29.4327-67.1326Z"/> + </g> + <line id="Baseline-M" style="fill:none;stroke:#27AAE1;opacity:1;stroke-width:0.5;" x1="263" x2="3036" y1="1126" y2="1126"/> + <line id="Capline-M" style="fill:none;stroke:#27AAE1;opacity:1;stroke-width:0.5;" x1="263" x2="3036" y1="1055.54" y2="1055.54"/> + <g id="H-reference" style="fill:#27AAE1;stroke:none;" transform="matrix(1 0 0 1 339 1556)"> + <path d="M0.993347 0L3.6377 0L29.3282-67.1326L30.0301-67.1326L30.0301-70.459L28.1227-70.459ZM11.6882-24.4797L46.9818-24.4797L46.2311-26.7288L12.4382-26.7288ZM55.1193 0L57.7637 0L30.6381-70.459L29.4327-70.459L29.4327-67.1326Z"/> + </g> + <line id="Baseline-L" style="fill:none;stroke:#27AAE1;opacity:1;stroke-width:0.5;" x1="263" x2="3036" y1="1556" y2="1556"/> + <line id="Capline-L" style="fill:none;stroke:#27AAE1;opacity:1;stroke-width:0.5;" x1="263" x2="3036" y1="1485.54" y2="1485.54"/> + <line id="left-margin-Regular-M" style="fill:none;stroke:#FF3B30;stroke-width:0.5;opacity:1.0;" x1="1374.84" x2="1374.84" y1="1030.78" y2="1150.12"/> + <line id="right-margin-Regular-M" style="fill:none;stroke:#FF3B30;stroke-width:0.5;opacity:1.0;" x1="1524.84" x2="1524.84" y1="1030.78" y2="1150.12"/> + </g> + <g id="Symbols"> + <g id="Black-L" transform="matrix(1 0 0 1 2843.4 1556)"> + <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M124.7 47.29C113.85 52 102.26 54.35 89.96 54.35C77.65 54.35 66.07 52 55.21 47.29C44.35 42.65 34.78 36.17 26.47 27.86C18.23 19.56 11.76 9.97 7.05-0.89C2.35-11.75 0-23.34 0-35.65C0-47.96 2.35-59.55 7.05-70.41C11.76-81.27 18.23-90.83 26.47-99.08C34.78-107.38 44.33-113.89 55.12-118.59C65.98-123.3 77.56-125.65 89.87-125.65C102.24-125.65 113.85-123.3 124.7-118.59C135.56-113.89 145.14-107.38 153.44-99.08C161.74-90.83 168.24-81.27 172.95-70.41C177.65-59.55 180-47.96 180-35.65C180-23.34 177.65-11.75 172.95-0.89C168.24 9.97 161.74 19.56 153.44 27.86C145.14 36.17 135.56 42.65 124.7 47.29Z"/> + <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M79.34-7.83C79.34-1.75 84.26 3.17 90.34 3.17C96.42 3.17 101.34-1.75 101.34-7.83L101.34-24.67L118.17-24.67C124.25-24.67 129.17-29.59 129.17-35.67C129.17-41.74 124.25-46.67 118.17-46.67L101.34-46.67L101.34-63.5C101.34-69.58 96.42-74.5 90.34-74.5C84.26-74.5 79.34-69.58 79.34-63.5L79.34-46.67L62.5-46.67C56.43-46.67 51.5-41.74 51.5-35.67C51.5-29.59 56.43-24.67 62.5-24.67L79.34-24.67L79.34-7.83Z"/> + </g> + <g id="Heavy-L" transform="matrix(1 0 0 1 2545.69 1556)"> + <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M126.09 48.26C115.11 53.02 103.4 55.4 90.96 55.4C78.51 55.4 66.8 53.02 55.82 48.26C44.85 43.57 35.16 37.02 26.77 28.62C18.43 20.22 11.89 10.53 7.13-0.45C2.38-11.43 0-23.15 0-35.6C0-48.05 2.38-59.77 7.13-70.75C11.89-81.73 18.43-91.39 26.77-99.73C35.16-108.13 44.82-114.71 55.74-119.46C66.71-124.22 78.42-126.6 90.87-126.6C103.37-126.6 115.11-124.22 126.09-119.46C137.07-114.71 146.75-108.13 155.14-99.73C163.54-91.39 170.11-81.73 174.87-70.75C179.62-59.77 182-48.05 182-35.6C182-23.15 179.62-11.43 174.87-0.45C170.11 10.53 163.54 20.22 155.14 28.62C146.75 37.02 137.07 43.57 126.09 48.26Z"/> + <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M81.84-7.83C81.84-2.58 86.09 1.67 91.34 1.67C96.59 1.67 100.84-2.58 100.84-7.83L100.84-26.17L119.17-26.17C124.42-26.17 128.67-30.42 128.67-35.67C128.67-40.91 124.42-45.17 119.17-45.17L100.84-45.17L100.84-63.5C100.84-68.75 96.59-73 91.34-73C86.09-73 81.84-68.75 81.84-63.5L81.84-45.17L63.5-45.17C58.25-45.17 54-40.91 54-35.67C54-30.42 58.25-26.17 63.5-26.17L81.84-26.17L81.84-7.83Z"/> + </g> + <g id="Bold-L" transform="matrix(1 0 0 1 2249.98 1556)"> + <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M124.7 47.74C113.85 52.45 102.26 54.8 89.96 54.8C77.65 54.8 66.07 52.45 55.21 47.74C44.35 43.1 34.78 36.62 26.47 28.31C18.23 20.01 11.76 10.42 7.05-0.44C2.35-11.3 0-22.89 0-35.2C0-47.51 2.35-59.1 7.05-69.96C11.76-80.83 18.23-90.38 26.47-98.63C34.78-106.93 44.33-113.44 55.12-118.14C65.98-122.85 77.56-125.2 89.87-125.2C102.24-125.2 113.85-122.85 124.7-118.14C135.56-113.44 145.14-106.93 153.44-98.63C161.74-90.38 168.24-80.83 172.95-69.96C177.65-59.1 180-47.51 180-35.2C180-22.89 177.65-11.3 172.95-0.44C168.24 10.42 161.74 20.01 153.44 28.31C145.14 36.62 135.56 43.1 124.7 47.74Z"/> + <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M81.99-7.33C81.99-2.91 85.57 0.67 89.99 0.67C94.41 0.67 97.99-2.91 97.99-7.33L97.99-27.17L117.82-27.17C122.24-27.17 125.82-30.75 125.82-35.17C125.82-39.59 122.24-43.17 117.82-43.17L97.99-43.17L97.99-63C97.99-67.42 94.41-71 89.99-71C85.57-71 81.99-67.42 81.99-63L81.99-43.17L62.15-43.17C57.73-43.17 54.15-39.59 54.15-35.17C54.15-30.75 57.73-27.17 62.15-27.17L81.99-27.17L81.99-7.33Z"/> + </g> + <g id="Semibold-L" transform="matrix(1 0 0 1 1953.27 1556)"> + <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M124.7 47.44C113.85 52.15 102.26 54.5 89.96 54.5C77.65 54.5 66.07 52.15 55.21 47.44C44.35 42.8 34.78 36.32 26.47 28.01C18.23 19.71 11.76 10.12 7.05-0.74C2.35-11.6 0-23.19 0-35.5C0-47.81 2.35-59.4 7.05-70.26C11.76-81.12 18.23-90.68 26.47-98.93C34.78-107.23 44.33-113.74 55.12-118.44C65.98-123.15 77.56-125.5 89.87-125.5C102.24-125.5 113.85-123.15 124.7-118.44C135.56-113.74 145.14-107.23 153.44-98.93C161.74-90.68 168.24-81.12 172.95-70.26C177.65-59.4 180-47.81 180-35.5C180-23.19 177.65-11.6 172.95-0.74C168.24 10.12 161.74 19.71 153.44 28.01C145.14 36.32 135.56 42.8 124.7 47.44Z"/> + <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M83.34-7.63C83.34-4.04 86.25-1.13 89.84-1.13C93.43-1.13 96.34-4.04 96.34-7.63L96.34-28.97L117.67-28.97C121.26-28.97 124.17-31.88 124.17-35.47C124.17-39.06 121.26-41.97 117.67-41.97L96.34-41.97L96.34-63.3C96.34-66.89 93.43-69.8 89.84-69.8C86.25-69.8 83.34-66.89 83.34-63.3L83.34-41.97L62-41.97C58.41-41.97 55.5-39.06 55.5-35.47C55.5-31.88 58.41-28.97 62-28.97L83.34-28.97L83.34-7.63Z"/> + </g> + <g id="Medium-L" transform="matrix(1 0 0 1 1656.56 1556)"> + <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M124.7 47.44C113.85 52.15 102.26 54.5 89.96 54.5C77.65 54.5 66.07 52.15 55.21 47.44C44.35 42.8 34.78 36.32 26.47 28.01C18.23 19.71 11.76 10.12 7.05-0.74C2.35-11.6 0-23.19 0-35.5C0-47.81 2.35-59.4 7.05-70.26C11.76-81.12 18.23-90.68 26.47-98.93C34.78-107.23 44.33-113.74 55.12-118.44C65.98-123.15 77.56-125.5 89.87-125.5C102.24-125.5 113.85-123.15 124.7-118.44C135.56-113.74 145.14-107.23 153.44-98.93C161.74-90.68 168.24-81.12 172.95-70.26C177.65-59.4 180-47.81 180-35.5C180-23.19 177.65-11.6 172.95-0.74C168.24 10.12 161.74 19.71 153.44 28.01C145.14 36.32 135.56 42.8 124.7 47.44Z"/> + <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M84.34-7.63C84.34-4.43 86.94-1.83 90.14-1.83C93.34-1.83 95.94-4.43 95.94-7.63L95.94-29.67L117.97-29.67C121.17-29.67 123.77-32.26 123.77-35.47C123.77-38.67 121.17-41.27 117.97-41.27L95.94-41.27L95.94-63.3C95.94-66.5 93.34-69.1 90.14-69.1C86.94-69.1 84.34-66.5 84.34-63.3L84.34-41.27L62.3-41.27C59.1-41.27 56.5-38.67 56.5-35.47C56.5-32.26 59.1-29.67 62.3-29.67L84.34-29.67L84.34-7.63Z"/> + </g> + <g id="Regular-L" transform="matrix(1 0 0 1 1359.84 1556)"> + <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M124.7 47.74C113.85 52.45 102.26 54.8 89.96 54.8C77.65 54.8 66.07 52.45 55.21 47.74C44.35 43.1 34.77 36.62 26.47 28.31C18.23 20.01 11.76 10.43 7.05-0.44C2.35-11.3 0-22.89 0-35.2C0-47.51 2.35-59.1 7.05-69.96C11.76-80.82 18.23-90.38 26.47-98.63C34.77-106.93 44.32-113.44 55.12-118.14C65.98-122.85 77.56-125.2 89.87-125.2C102.23-125.2 113.85-122.85 124.7-118.14C135.56-113.44 145.14-106.93 153.44-98.63C161.74-90.38 168.24-80.82 172.95-69.96C177.65-59.1 180-47.51 180-35.2C180-22.89 177.65-11.3 172.95-0.44C168.24 10.43 161.74 20.01 153.44 28.31C145.14 36.62 135.56 43.1 124.7 47.74Z"/> + <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M85.34-7.38C85.34-4.7 87.51-2.53 90.19-2.53C92.87-2.53 95.04-4.7 95.04-7.38L95.04-30.15L117.67-30.15C120.35-30.15 122.52-32.32 122.52-35C122.52-37.68 120.35-39.85 117.67-39.85L95.04-39.85L95.04-63.05C95.04-65.73 92.87-67.9 90.19-67.9C87.51-67.9 85.34-65.73 85.34-63.05L85.34-39.85L62-39.85C59.32-39.85 57.15-37.68 57.15-35C57.15-32.32 59.32-30.15 62-30.15L85.34-30.15L85.34-7.38Z"/> + </g> + <g id="Light-L" transform="matrix(1 0 0 1 1063.13 1556)"> + <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M124.7 46.94C113.85 51.65 102.26 54 89.96 54C77.65 54 66.07 51.65 55.21 46.94C44.35 42.3 34.78 35.82 26.47 27.51C18.23 19.21 11.76 9.62 7.05-1.24C2.35-12.1 0-23.69 0-36C0-48.31 2.35-59.9 7.05-70.76C11.76-81.62 18.23-91.18 26.47-99.43C34.78-107.73 44.33-114.24 55.12-118.94C65.98-123.65 77.56-126 89.87-126C102.24-126 113.85-123.65 124.7-118.94C135.56-114.24 145.14-107.73 153.44-99.43C161.74-91.18 168.24-81.62 172.95-70.76C177.65-59.9 180-48.31 180-36C180-23.69 177.65-12.1 172.95-1.24C168.24 9.62 161.74 19.21 153.44 27.51C145.14 35.82 135.56 42.3 124.7 46.94Z"/> + <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M86.84-8.03C86.84-6.21 88.32-4.73 90.14-4.73C91.96-4.73 93.44-6.21 93.44-8.03L93.44-32.57L117.97-32.57C119.79-32.57 121.27-34.05 121.27-35.87C121.27-37.69 119.79-39.17 117.97-39.17L93.44-39.17L93.44-63.7C93.44-65.52 91.96-67 90.14-67C88.32-67 86.84-65.52 86.84-63.7L86.84-39.17L62.3-39.17C60.48-39.17 59-37.69 59-35.87C59-34.05 60.48-32.57 62.3-32.57L86.84-32.57L86.84-8.03Z"/> + </g> + <g id="Thin-L" transform="matrix(1 0 0 1 766.422 1556)"> + <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M124.702 45.34C113.846 50.05 102.264 52.4 89.956 52.4C77.649 52.4 66.067 50.05 55.21 45.34C44.354 40.7 34.775 34.22 26.473 25.91C18.229 17.61 11.756 8.02 7.054-2.84C2.351-13.7 0-25.29 0-37.6C0-49.91 2.351-61.5 7.054-72.36C11.756-83.22 18.229-92.78 26.473-101.03C34.775-109.33 44.325-115.84 55.123-120.54C65.98-125.25 77.562-127.6 89.869-127.6C102.235-127.6 113.846-125.25 124.702-120.54C135.559-115.84 145.138-109.33 153.44-101.03C161.742-92.78 168.244-83.22 172.946-72.36C177.649-61.5 180-49.91 180-37.6C180-25.29 177.649-13.7 172.946-2.84C168.244 8.02 161.742 17.61 153.44 25.91C145.138 34.22 135.559 40.7 124.702 45.34Z"/> + <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M87.64-9.78C87.64-8.68 88.535-7.78 89.64-7.78C90.744-7.78 91.64-8.68 91.64-9.78L91.64-35.62L117.47-35.62C118.574-35.62 119.47-36.51 119.47-37.62C119.47-38.72 118.574-39.62 117.47-39.62L91.64-39.62L91.64-65.45C91.64-66.56 90.744-67.45 89.64-67.45C88.535-67.45 87.64-66.56 87.64-65.45L87.64-39.62L61.8-39.62C60.695-39.62 59.8-38.72 59.8-37.62C59.8-36.51 60.695-35.62 61.8-35.62L87.64-35.62L87.64-9.78Z"/> + </g> + <g id="Ultralight-L" transform="matrix(1 0 0 1 469.711 1556)"> + <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M124.702 47.94C113.846 52.65 102.264 55 89.956 55C77.649 55 66.067 52.65 55.21 47.94C44.354 43.3 34.775 36.82 26.473 28.51C18.229 20.21 11.756 10.62 7.054-0.24C2.351-11.1 0-22.69 0-35C0-47.31 2.351-58.9 7.054-69.76C11.756-80.62 18.229-90.18 26.473-98.43C34.775-106.73 44.325-113.24 55.123-117.94C65.98-122.65 77.562-125 89.869-125C102.235-125 113.846-122.65 124.702-117.94C135.559-113.24 145.138-106.73 153.44-98.43C161.742-90.18 168.244-80.62 172.946-69.76C177.649-58.9 180-47.31 180-35C180-22.69 177.649-11.1 172.946-0.24C168.244 10.62 161.742 20.21 153.44 28.51C145.138 36.82 135.559 43.3 124.702 47.94Z"/> + <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M88.875-7.46C88.875-6.84 89.379-6.33 90-6.33C90.621-6.33 91.125-6.84 91.125-7.46L91.125-34.17L117.83-34.17C118.451-34.17 118.955-34.68 118.955-35.3C118.955-35.92 118.451-36.42 117.83-36.42L91.125-36.42L91.125-63.13C91.125-63.75 90.621-64.25 90-64.25C89.379-64.25 88.875-63.75 88.875-63.13L88.875-36.42L62.16-36.42C61.539-36.42 61.035-35.92 61.035-35.3C61.035-34.68 61.539-34.17 62.16-34.17L88.875-34.17L88.875-7.46Z"/> + </g> + <g id="Black-M" transform="matrix(1 0 0 1 2858.4 1126)"> + <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M103.92 34.32C94.87 38.24 85.22 40.2 74.96 40.2C64.71 40.2 55.06 38.24 46.01 34.32C36.96 30.45 28.98 25.05 22.06 18.13C15.19 11.21 9.8 3.22 5.88-5.83C1.96-14.88 0-24.54 0-34.8C0-45.06 1.96-54.72 5.88-63.77C9.8-72.82 15.19-80.78 22.06-87.65C28.98-94.58 36.94-100 45.94-103.92C54.98-107.84 64.63-109.8 74.89-109.8C85.2-109.8 94.87-107.84 103.92-103.92C112.97-100 120.95-94.58 127.87-87.65C134.78-80.78 140.2-72.82 144.12-63.77C148.04-54.72 150-45.06 150-34.8C150-24.54 148.04-14.88 144.12-5.83C140.2 3.22 134.78 11.21 127.87 18.13C120.95 25.05 112.97 30.45 103.92 34.32Z"/> + <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M65.5-6.96C65.5-1.71 69.75 2.54 75 2.54C80.25 2.54 84.5-1.71 84.5-6.96L84.5-25.3L102.83-25.3C108.08-25.3 112.33-29.55 112.33-34.8C112.33-40.05 108.08-44.3 102.83-44.3L84.5-44.3L84.5-62.63C84.5-67.88 80.25-72.13 75-72.13C69.75-72.13 65.5-67.88 65.5-62.63L65.5-44.3L47.16-44.3C41.91-44.3 37.66-40.05 37.66-34.8C37.66-29.55 41.91-25.3 47.16-25.3L65.5-25.3L65.5-6.96Z"/> + </g> + <g id="Heavy-M" transform="matrix(1 0 0 1 2561.69 1126)"> + <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M103.92 34.32C94.87 38.24 85.22 40.2 74.96 40.2C64.71 40.2 55.06 38.24 46.01 34.32C36.96 30.45 28.98 25.05 22.06 18.13C15.19 11.21 9.8 3.22 5.88-5.83C1.96-14.88 0-24.54 0-34.8C0-45.06 1.96-54.72 5.88-63.77C9.8-72.82 15.19-80.78 22.06-87.65C28.98-94.58 36.94-100 45.94-103.92C54.98-107.84 64.63-109.8 74.89-109.8C85.2-109.8 94.87-107.84 103.92-103.92C112.97-100 120.95-94.58 127.87-87.65C134.78-80.78 140.2-72.82 144.12-63.77C148.04-54.72 150-45.06 150-34.8C150-24.54 148.04-14.88 144.12-5.83C140.2 3.22 134.78 11.21 127.87 18.13C120.95 25.05 112.97 30.45 103.92 34.32Z"/> + <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M66.5-6.96C66.5-2.27 70.31 1.54 75 1.54C79.69 1.54 83.5-2.27 83.5-6.96L83.5-26.3L102.83-26.3C107.52-26.3 111.33-30.1 111.33-34.8C111.33-39.49 107.52-43.3 102.83-43.3L83.5-43.3L83.5-62.63C83.5-67.33 79.69-71.13 75-71.13C70.31-71.13 66.5-67.33 66.5-62.63L66.5-43.3L47.16-43.3C42.47-43.3 38.66-39.49 38.66-34.8C38.66-30.1 42.47-26.3 47.16-26.3L66.5-26.3L66.5-6.96Z"/> + </g> + <g id="Bold-M" transform="matrix(1 0 0 1 2264.98 1126)"> + <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M103.92 34.32C94.87 38.24 85.22 40.2 74.96 40.2C64.71 40.2 55.06 38.24 46.01 34.32C36.96 30.45 28.98 25.05 22.06 18.13C15.19 11.21 9.8 3.22 5.88-5.83C1.96-14.88 0-24.54 0-34.8C0-45.06 1.96-54.72 5.88-63.77C9.8-72.82 15.19-80.78 22.06-87.65C28.98-94.58 36.94-100 45.94-103.92C54.98-107.84 64.63-109.8 74.89-109.8C85.2-109.8 94.87-107.84 103.92-103.92C112.97-100 120.95-94.58 127.87-87.65C134.78-80.78 140.2-72.82 144.12-63.77C148.04-54.72 150-45.06 150-34.8C150-24.54 148.04-14.88 144.12-5.83C140.2 3.22 134.78 11.21 127.87 18.13C120.95 25.05 112.97 30.45 103.92 34.32Z"/> + <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M68-6.96C68-3.09 71.13 0.04 75 0.04C78.87 0.04 82-3.09 82-6.96L82-27.8L102.83-27.8C106.7-27.8 109.83-30.93 109.83-34.8C109.83-38.66 106.7-41.8 102.83-41.8L82-41.8L82-62.63C82-66.5 78.87-69.63 75-69.63C71.13-69.63 68-66.5 68-62.63L68-41.8L47.16-41.8C43.29-41.8 40.16-38.66 40.16-34.8C40.16-30.93 43.29-27.8 47.16-27.8L68-27.8L68-6.96Z"/> + </g> + <g id="Semibold-M" transform="matrix(1 0 0 1 1968.27 1126)"> + <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M103.92 34.32C94.87 38.24 85.22 40.2 74.96 40.2C64.71 40.2 55.06 38.24 46.01 34.32C36.96 30.45 28.98 25.05 22.06 18.13C15.19 11.21 9.8 3.22 5.88-5.83C1.96-14.88 0-24.54 0-34.8C0-45.06 1.96-54.72 5.88-63.77C9.8-72.82 15.19-80.78 22.06-87.65C28.98-94.58 36.94-100 45.94-103.92C54.98-107.84 64.63-109.8 74.89-109.8C85.2-109.8 94.87-107.84 103.92-103.92C112.97-100 120.95-94.58 127.87-87.65C134.78-80.78 140.2-72.82 144.12-63.77C148.04-54.72 150-45.06 150-34.8C150-24.54 148.04-14.88 144.12-5.83C140.2 3.22 134.78 11.21 127.87 18.13C120.95 25.05 112.97 30.45 103.92 34.32Z"/> + <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M69-6.96C69-3.65 71.69-0.96 75-0.96C78.31-0.96 81-3.65 81-6.96L81-28.8L102.83-28.8C106.14-28.8 108.83-31.49 108.83-34.8C108.83-38.11 106.14-40.8 102.83-40.8L81-40.8L81-62.63C81-65.94 78.31-68.63 75-68.63C71.69-68.63 69-65.94 69-62.63L69-40.8L47.16-40.8C43.85-40.8 41.16-38.11 41.16-34.8C41.16-31.49 43.85-28.8 47.16-28.8L69-28.8L69-6.96Z"/> + </g> + <g id="Medium-M" transform="matrix(1 0 0 1 1671.56 1126)"> + <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M103.92 34.32C94.87 38.24 85.22 40.2 74.96 40.2C64.71 40.2 55.06 38.24 46.01 34.32C36.96 30.45 28.98 25.05 22.06 18.13C15.19 11.21 9.8 3.22 5.88-5.83C1.96-14.88 0-24.54 0-34.8C0-45.06 1.96-54.72 5.88-63.77C9.8-72.82 15.19-80.78 22.06-87.65C28.98-94.58 36.94-100 45.94-103.92C54.98-107.84 64.63-109.8 74.89-109.8C85.2-109.8 94.87-107.84 103.92-103.92C112.97-100 120.95-94.58 127.87-87.65C134.78-80.78 140.2-72.82 144.12-63.77C148.04-54.72 150-45.06 150-34.8C150-24.54 148.04-14.88 144.12-5.83C140.2 3.22 134.78 11.21 127.87 18.13C120.95 25.05 112.97 30.45 103.92 34.32Z"/> + <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M69.7-6.96C69.7-4.03 72.07-1.66 75-1.66C77.93-1.66 80.3-4.03 80.3-6.96L80.3-29.5L102.83-29.5C105.76-29.5 108.13-31.87 108.13-34.8C108.13-37.73 105.76-40.1 102.83-40.1L80.3-40.1L80.3-62.63C80.3-65.56 77.93-67.93 75-67.93C72.07-67.93 69.7-65.56 69.7-62.63L69.7-40.1L47.16-40.1C44.23-40.1 41.86-37.73 41.86-34.8C41.86-31.87 44.23-29.5 47.16-29.5L69.7-29.5L69.7-6.96Z"/> + </g> + <g id="Regular-M" transform="matrix(1 0 0 1 1374.84 1126)"> + <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M103.92 33.82C94.87 37.74 85.22 39.7 74.96 39.7C64.71 39.7 55.06 37.74 46.01 33.82C36.96 29.95 28.98 24.55 22.06 17.63C15.19 10.71 9.8 2.72 5.88-6.33C1.96-15.38 0-25.04 0-35.3C0-45.56 1.96-55.22 5.88-64.27C9.8-73.32 15.19-81.28 22.06-88.15C28.98-95.08 36.94-100.5 45.94-104.42C54.98-108.34 64.63-110.3 74.89-110.3C85.2-110.3 94.87-108.34 103.92-104.42C112.97-100.5 120.95-95.08 127.87-88.15C134.78-81.28 140.2-73.32 144.12-64.27C148.04-55.22 150-45.56 150-35.3C150-25.04 148.04-15.38 144.12-6.33C140.2 2.72 134.78 10.71 127.87 17.63C120.95 24.55 112.97 29.95 103.92 33.82Z"/> + <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M70.65-7.46C70.65-5.06 72.6-3.11 75-3.11C77.4-3.11 79.35-5.06 79.35-7.46L79.35-30.95L102.83-30.95C105.23-30.95 107.18-32.9 107.18-35.3C107.18-37.7 105.23-39.65 102.83-39.65L79.35-39.65L79.35-63.13C79.35-65.54 77.4-67.48 75-67.48C72.6-67.48 70.65-65.54 70.65-63.13L70.65-39.65L47.16-39.65C44.76-39.65 42.81-37.7 42.81-35.3C42.81-32.9 44.76-30.95 47.16-30.95L70.65-30.95L70.65-7.46Z"/> + </g> + <g id="Light-M" transform="matrix(1 0 0 1 1078.13 1126)"> + <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M103.92 34.32C94.87 38.24 85.22 40.2 74.96 40.2C64.71 40.2 55.06 38.24 46.01 34.32C36.96 30.45 28.98 25.05 22.06 18.13C15.19 11.21 9.8 3.22 5.88-5.83C1.96-14.88 0-24.54 0-34.8C0-45.06 1.96-54.72 5.88-63.77C9.8-72.82 15.19-80.78 22.06-87.65C28.98-94.58 36.94-100 45.94-103.92C54.98-107.84 64.63-109.8 74.89-109.8C85.2-109.8 94.87-107.84 103.92-103.92C112.97-100 120.95-94.58 127.87-87.65C134.78-80.78 140.2-72.82 144.12-63.77C148.04-54.72 150-45.06 150-34.8C150-24.54 148.04-14.88 144.12-5.83C140.2 3.22 134.78 11.21 127.87 18.13C120.95 25.05 112.97 30.45 103.92 34.32Z"/> + <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M71.7-6.96C71.7-5.14 73.18-3.66 75-3.66C76.82-3.66 78.3-5.14 78.3-6.96L78.3-31.5L102.83-31.5C104.65-31.5 106.13-32.98 106.13-34.8C106.13-36.62 104.65-38.1 102.83-38.1L78.3-38.1L78.3-62.63C78.3-64.46 76.82-65.93 75-65.93C73.18-65.93 71.7-64.46 71.7-62.63L71.7-38.1L47.16-38.1C45.34-38.1 43.86-36.62 43.86-34.8C43.86-32.98 45.34-31.5 47.16-31.5L71.7-31.5L71.7-6.96Z"/> + </g> + <g id="Thin-M" transform="matrix(1 0 0 1 781.422 1126)"> + <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M103.919 34.32C94.872 38.24 85.221 40.2 74.964 40.2C64.708 40.2 55.056 38.24 46.009 34.32C36.962 30.45 28.98 25.05 22.061 18.13C15.192 11.21 9.797 3.22 5.878-5.83C1.96-14.88 0-24.54 0-34.8C0-45.06 1.96-54.71 5.878-63.77C9.797-72.82 15.192-80.78 22.061-87.65C28.98-94.57 36.938-100 45.937-103.92C54.983-107.84 64.635-109.8 74.892-109.8C85.196-109.8 94.872-107.84 103.919-103.92C112.966-100 120.949-94.57 127.867-87.65C134.785-80.78 140.204-72.82 144.122-63.77C148.041-54.71 150-45.06 150-34.8C150-24.54 148.041-14.88 144.122-5.83C140.204 3.22 134.785 11.21 127.867 18.13C120.949 25.05 112.966 30.45 103.919 34.32Z"/> + <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M73.201-6.96C73.201-5.96 74.006-5.16 75.001-5.16C75.995-5.16 76.801-5.96 76.801-6.96L76.801-33L102.831-33C103.825-33 104.631-33.8 104.631-34.8C104.631-35.79 103.825-36.6 102.831-36.6L76.801-36.6L76.801-62.63C76.801-63.62 75.995-64.43 75.001-64.43C74.006-64.43 73.201-63.62 73.201-62.63L73.201-36.6L47.161-36.6C46.167-36.6 45.361-35.79 45.361-34.8C45.361-33.8 46.167-33 47.161-33L73.201-33L73.201-6.96Z"/> + </g> + <g id="Ultralight-M" transform="matrix(1 0 0 1 484.711 1126)"> + <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M103.919 34.32C94.872 38.24 85.22 40.2 74.964 40.2C64.707 40.2 55.056 38.24 46.009 34.32C36.962 30.45 28.979 25.05 22.061 18.13C15.191 11.21 9.797 3.22 5.878-5.83C1.959-14.88 0-24.54 0-34.8C0-45.06 1.959-54.72 5.878-63.77C9.797-72.82 15.191-80.78 22.061-87.65C28.979-94.58 36.938-100 45.936-103.92C54.983-107.84 64.635-109.8 74.891-109.8C85.196-109.8 94.872-107.84 103.919-103.92C112.966-100 120.948-94.58 127.866-87.65C134.785-80.78 140.203-72.82 144.122-63.77C148.041-54.72 150-45.06 150-34.8C150-24.54 148.041-14.88 144.122-5.83C140.203 3.22 134.785 11.21 127.866 18.13C120.948 25.05 112.966 30.45 103.919 34.32Z"/> + <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M73.875-6.96C73.875-6.34 74.379-5.83 75-5.83C75.621-5.83 76.125-6.34 76.125-6.96L76.125-33.67L102.83-33.67C103.451-33.67 103.955-34.18 103.955-34.8C103.955-35.42 103.451-35.92 102.83-35.92L76.125-35.92L76.125-62.63C76.125-63.25 75.621-63.75 75-63.75C74.379-63.75 73.875-63.25 73.875-62.63L73.875-35.92L47.16-35.92C46.539-35.92 46.035-35.42 46.035-34.8C46.035-34.18 46.539-33.67 47.16-33.67L73.875-33.67L73.875-6.96Z"/> + </g> + <g id="Black-S" transform="matrix(1 0 0 1 2879.4 696)"> + <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M74.82 13.967C68.31 16.79 61.36 18.201 53.97 18.201C46.59 18.201 39.64 16.79 33.13 13.967C26.61 11.179 20.87 7.293 15.88 2.31C10.94-2.674 7.05-8.424 4.23-14.941C1.41-21.458 0-28.411 0-35.799C0-43.187 1.41-50.14 4.23-56.657C7.05-63.173 10.94-68.906 15.88-73.855C20.87-78.839 26.6-82.742 33.07-85.565C39.59-88.387 46.54-89.799 53.92-89.799C61.34-89.799 68.31-88.387 74.82-85.565C81.34-82.742 87.08-78.839 92.06-73.855C97.05-68.906 100.95-63.173 103.77-56.657C106.59-50.14 108-43.187 108-35.799C108-28.411 106.59-21.458 103.77-14.941C100.95-8.424 97.05-2.674 92.06 2.31C87.08 7.293 81.34 11.179 74.82 13.967Z"/> + <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M44.84-7.83C44.84-2.583 49.09 1.67 54.34 1.67C59.59 1.67 63.84-2.583 63.84-7.83L63.84-26.168L82.17-26.168C87.42-26.168 91.67-30.421 91.67-35.668C91.67-40.915 87.42-45.168 82.17-45.168L63.84-45.168L63.84-63.5C63.84-68.747 59.59-73 54.34-73C49.09-73 44.84-68.747 44.84-63.5L44.84-45.168L26.5-45.168C21.25-45.168 17-40.915 17-35.668C17-30.421 21.25-26.168 26.5-26.168L44.84-26.168L44.84-7.83Z"/> + </g> + <g id="Heavy-S" transform="matrix(1 0 0 1 2582.69 696)"> + <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M74.82 13.967C68.31 16.79 61.36 18.201 53.97 18.201C46.59 18.201 39.64 16.79 33.13 13.967C26.61 11.179 20.87 7.293 15.88 2.31C10.94-2.674 7.05-8.424 4.23-14.941C1.41-21.458 0-28.411 0-35.799C0-43.187 1.41-50.14 4.23-56.657C7.05-63.173 10.94-68.906 15.88-73.855C20.87-78.839 26.6-82.742 33.07-85.565C39.59-88.387 46.54-89.799 53.92-89.799C61.34-89.799 68.31-88.387 74.82-85.565C81.34-82.742 87.08-78.839 92.06-73.855C97.05-68.906 100.95-63.173 103.77-56.657C106.59-50.14 108-43.187 108-35.799C108-28.411 106.59-21.458 103.77-14.941C100.95-8.424 97.05-2.674 92.06 2.31C87.08 7.293 81.34 11.179 74.82 13.967Z"/> + <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M45.34-8.33C45.34-3.636 49.15 0.17 53.84 0.17C58.53 0.17 62.34-3.636 62.34-8.33L62.34-27.668L81.67-27.668C86.36-27.668 90.17-31.473 90.17-36.168C90.17-40.862 86.36-44.668 81.67-44.668L62.34-44.668L62.34-64C62.34-68.694 58.53-72.5 53.84-72.5C49.15-72.5 45.34-68.694 45.34-64L45.34-44.668L26-44.668C21.31-44.668 17.5-40.862 17.5-36.168C17.5-31.473 21.31-27.668 26-27.668L45.34-27.668L45.34-8.33Z"/> + </g> + <g id="Bold-S" transform="matrix(1 0 0 1 2285.98 696)"> + <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M74.82 13.967C68.31 16.79 61.36 18.201 53.97 18.201C46.59 18.201 39.64 16.79 33.13 13.967C26.61 11.179 20.87 7.293 15.88 2.31C10.94-2.674 7.05-8.424 4.23-14.941C1.41-21.458 0-28.411 0-35.799C0-43.187 1.41-50.14 4.23-56.657C7.05-63.173 10.94-68.906 15.88-73.855C20.87-78.839 26.6-82.742 33.07-85.565C39.59-88.387 46.54-89.799 53.92-89.799C61.34-89.799 68.31-88.387 74.82-85.565C81.34-82.742 87.08-78.839 92.06-73.855C97.05-68.906 100.95-63.173 103.77-56.657C106.59-50.14 108-43.187 108-35.799C108-28.411 106.59-21.458 103.77-14.941C100.95-8.424 97.05-2.674 92.06 2.31C87.08 7.293 81.34 11.179 74.82 13.967Z"/> + <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M46.84-8.33C46.84-4.464 49.97-1.33 53.84-1.33C57.71-1.33 60.84-4.464 60.84-8.33L60.84-29.168L81.67-29.168C85.54-29.168 88.67-32.302 88.67-36.168C88.67-40.034 85.54-43.168 81.67-43.168L60.84-43.168L60.84-64C60.84-67.866 57.71-71 53.84-71C49.97-71 46.84-67.866 46.84-64L46.84-43.168L26-43.168C22.13-43.168 19-40.034 19-36.168C19-32.302 22.13-29.168 26-29.168L46.84-29.168L46.84-8.33Z"/> + </g> + <g id="Semibold-S" transform="matrix(1 0 0 1 1989.27 696)"> + <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M74.82 13.967C68.31 16.79 61.36 18.201 53.97 18.201C46.59 18.201 39.64 16.79 33.13 13.967C26.61 11.179 20.87 7.293 15.88 2.31C10.94-2.674 7.05-8.424 4.23-14.941C1.41-21.458 0-28.411 0-35.799C0-43.187 1.41-50.14 4.23-56.657C7.05-63.173 10.94-68.906 15.88-73.855C20.87-78.839 26.6-82.742 33.07-85.565C39.59-88.387 46.54-89.799 53.92-89.799C61.34-89.799 68.31-88.387 74.82-85.565C81.34-82.742 87.08-78.839 92.06-73.855C97.05-68.906 100.95-63.173 103.77-56.657C106.59-50.14 108-43.187 108-35.799C108-28.411 106.59-21.458 103.77-14.941C100.95-8.424 97.05-2.674 92.06 2.31C87.08 7.293 81.34 11.179 74.82 13.967Z"/> + <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M47.84-8.33C47.84-5.016 50.53-2.33 53.84-2.33C57.15-2.33 59.84-5.016 59.84-8.33L59.84-30.168L81.67-30.168C84.98-30.168 87.67-32.854 87.67-36.168C87.67-39.482 84.98-42.168 81.67-42.168L59.84-42.168L59.84-64C59.84-67.314 57.15-70 53.84-70C50.53-70 47.84-67.314 47.84-64L47.84-42.168L26-42.168C22.69-42.168 20-39.482 20-36.168C20-32.854 22.69-30.168 26-30.168L47.84-30.168L47.84-8.33Z"/> + </g> + <g id="Medium-S" transform="matrix(1 0 0 1 1692.56 696)"> + <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M74.82 13.967C68.31 16.79 61.36 18.201 53.97 18.201C46.59 18.201 39.64 16.79 33.13 13.967C26.61 11.179 20.87 7.293 15.88 2.31C10.94-2.674 7.05-8.424 4.23-14.941C1.41-21.458 0-28.411 0-35.799C0-43.187 1.41-50.14 4.23-56.657C7.05-63.173 10.94-68.906 15.88-73.855C20.87-78.839 26.6-82.742 33.07-85.565C39.59-88.387 46.54-89.799 53.92-89.799C61.34-89.799 68.31-88.387 74.82-85.565C81.34-82.742 87.08-78.839 92.06-73.855C97.05-68.906 100.95-63.173 103.77-56.657C106.59-50.14 108-43.187 108-35.799C108-28.411 106.59-21.458 103.77-14.941C100.95-8.424 97.05-2.674 92.06 2.31C87.08 7.293 81.34 11.179 74.82 13.967Z"/> + <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M48.84-8.03C48.84-5.103 51.21-2.73 54.14-2.73C57.07-2.73 59.44-5.103 59.44-8.03L59.44-30.568L81.97-30.568C84.9-30.568 87.27-32.941 87.27-35.868C87.27-38.795 84.9-41.168 81.97-41.168L59.44-41.168L59.44-63.7C59.44-66.627 57.07-69 54.14-69C51.21-69 48.84-66.627 48.84-63.7L48.84-41.168L26.3-41.168C23.37-41.168 21-38.795 21-35.868C21-32.941 23.37-30.568 26.3-30.568L48.84-30.568L48.84-8.03Z"/> + </g> + <g id="Regular-S" transform="matrix(1 0 0 1 1395.84 696)"> + <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M74.82 13.965C68.31 16.788 61.36 18.199 53.97 18.199C46.59 18.199 39.64 16.788 33.13 13.965C26.61 11.177 20.87 7.291 15.88 2.308C10.94-2.676 7.05-8.426 4.23-14.943C1.41-21.46 0-28.413 0-35.801C0-43.189 1.41-50.142 4.23-56.658C7.05-63.175 10.94-68.908 15.88-73.857C20.87-78.84 26.6-82.744 33.07-85.567C39.59-88.389 46.54-89.801 53.92-89.801C61.34-89.801 68.31-88.389 74.82-85.567C81.34-82.744 87.08-78.84 92.06-73.857C97.04-68.908 100.95-63.175 103.77-56.658C106.59-50.142 108-43.189 108-35.801C108-28.413 106.59-21.46 103.77-14.943C100.95-8.426 97.04-2.676 92.06 2.308C87.08 7.291 81.34 11.177 74.82 13.965Z"/> + <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M49.84-7.98C49.84-5.578 51.79-3.63 54.19-3.63C56.59-3.63 58.54-5.578 58.54-7.98L58.54-31.468L82.02-31.468C84.42-31.468 86.37-33.415 86.37-35.818C86.37-38.22 84.42-40.168 82.02-40.168L58.54-40.168L58.54-63.65C58.54-66.052 56.59-68 54.19-68C51.79-68 49.84-66.052 49.84-63.65L49.84-40.168L26.35-40.168C23.95-40.168 22-38.22 22-35.818C22-33.415 23.95-31.468 26.35-31.468L49.84-31.468L49.84-7.98Z"/> + </g> + <g id="Light-S" transform="matrix(1 0 0 1 1099.13 696)"> + <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M74.82 13.967C68.31 16.79 61.36 18.201 53.97 18.201C46.59 18.201 39.64 16.79 33.13 13.967C26.61 11.179 20.87 7.293 15.88 2.31C10.94-2.674 7.05-8.424 4.23-14.941C1.41-21.458 0-28.411 0-35.799C0-43.187 1.41-50.14 4.23-56.657C7.05-63.173 10.94-68.906 15.88-73.855C20.87-78.839 26.6-82.742 33.07-85.565C39.59-88.387 46.54-89.799 53.92-89.799C61.34-89.799 68.31-88.387 74.82-85.565C81.34-82.742 87.08-78.839 92.06-73.855C97.05-68.906 100.95-63.173 103.77-56.657C106.59-50.14 108-43.187 108-35.799C108-28.411 106.59-21.458 103.77-14.941C100.95-8.424 97.05-2.674 92.06 2.31C87.08 7.293 81.34 11.179 74.82 13.967Z"/> + <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M50.84-8.03C50.84-6.207 52.32-4.73 54.14-4.73C55.96-4.73 57.44-6.207 57.44-8.03L57.44-32.568L81.97-32.568C83.79-32.568 85.27-34.045 85.27-35.868C85.27-37.69 83.79-39.168 81.97-39.168L57.44-39.168L57.44-63.7C57.44-65.523 55.96-67 54.14-67C52.32-67 50.84-65.523 50.84-63.7L50.84-39.168L26.3-39.168C24.48-39.168 23-37.69 23-35.868C23-34.045 24.48-32.568 26.3-32.568L50.84-32.568L50.84-8.03Z"/> + </g> + <g id="Thin-S" transform="matrix(1 0 0 1 802.422 696)"> + <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M74.821 13.967C68.308 16.79 61.358 18.201 53.974 18.201C46.589 18.201 39.64 16.79 33.126 13.967C26.612 11.179 20.865 7.293 15.884 2.31C10.938-2.674 7.054-8.424 4.232-14.941C1.411-21.458 0-28.411 0-35.799C0-43.187 1.411-50.14 4.232-56.657C7.054-63.173 10.938-68.906 15.884-73.855C20.865-78.839 26.595-82.742 33.074-85.565C39.588-88.387 46.537-89.799 53.922-89.799C61.341-89.799 68.308-88.387 74.821-85.565C81.335-82.742 87.083-78.839 92.064-73.855C97.045-68.906 100.946-63.173 103.768-56.657C106.589-50.14 108-43.187 108-35.799C108-28.411 106.589-21.458 103.768-14.941C100.946-8.424 97.045-2.674 92.064 2.31C87.083 7.293 81.335 11.179 74.821 13.967Z"/> + <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M52.04-8.331C52.04-7.337 52.846-6.531 53.84-6.531C54.834-6.531 55.64-7.337 55.64-8.331L55.64-34.369L81.67-34.369C82.664-34.369 83.47-35.175 83.47-36.169C83.47-37.163 82.664-37.969 81.67-37.969L55.64-37.969L55.64-64.001C55.64-64.995 54.834-65.801 53.84-65.801C52.846-65.801 52.04-64.995 52.04-64.001L52.04-37.969L26-37.969C25.006-37.969 24.2-37.163 24.2-36.169C24.2-35.175 25.006-34.369 26-34.369L52.04-34.369L52.04-8.331Z"/> + </g> + <g id="Ultralight-S" transform="matrix(1 0 0 1 505.711 696)"> + <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M74.821 13.967C68.308 16.79 61.358 18.201 53.974 18.201C46.589 18.201 39.64 16.79 33.126 13.967C26.612 11.179 20.865 7.293 15.884 2.31C10.938-2.674 7.054-8.424 4.232-14.941C1.411-21.458 0-28.411 0-35.799C0-43.187 1.411-50.14 4.232-56.657C7.054-63.173 10.938-68.906 15.884-73.855C20.865-78.839 26.595-82.742 33.074-85.565C39.588-88.387 46.537-89.799 53.922-89.799C61.341-89.799 68.308-88.387 74.821-85.565C81.335-82.742 87.083-78.839 92.064-73.855C97.045-68.906 100.946-63.173 103.768-56.657C106.589-50.14 108-43.187 108-35.799C108-28.411 106.589-21.458 103.768-14.941C100.946-8.424 97.045-2.674 92.064 2.31C87.083 7.293 81.335 11.179 74.821 13.967Z"/> + <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M52.84-8.205C52.84-7.584 53.344-7.08 53.965-7.08C54.586-7.08 55.09-7.584 55.09-8.205L55.09-34.918L81.795-34.918C82.416-34.918 82.92-35.422 82.92-36.043C82.92-36.664 82.416-37.168 81.795-37.168L55.09-37.168L55.09-63.875C55.09-64.496 54.586-65 53.965-65C53.344-65 52.84-64.496 52.84-63.875L52.84-37.168L26.125-37.168C25.504-37.168 25-36.664 25-36.043C25-35.422 25.504-34.918 26.125-34.918L52.84-34.918L52.84-8.205Z"/> + </g> + </g> +</svg>
diff --git a/ios/chrome/browser/ui/icons/resources/plus_circle_fill.symbolset/plus.circle.fill.cr.svg b/ios/chrome/browser/ui/icons/resources/plus_circle_fill.symbolset/plus.circle.fill.cr.svg index d3feeab..4df07d3e 100644 --- a/ios/chrome/browser/ui/icons/resources/plus_circle_fill.symbolset/plus.circle.fill.cr.svg +++ b/ios/chrome/browser/ui/icons/resources/plus_circle_fill.symbolset/plus.circle.fill.cr.svg
@@ -1,15 +1,18 @@ <?xml version="1.0" encoding="UTF-8"?> -<!--Generator: Apple Native CoreSVG 175--> +<!--Generator: Apple Native CoreSVG 175.5--> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="3300" height="2200"> - <!--glyph: "", point size: 100.0, font version: "17.3d3e1", template writer version: "65.1"--> - <style>.hierarchical-0:secondary {fill:#4D4D4D} + <!--glyph: "", point size: 100.0, font version: "18.0d12e2", template writer version: "101"--> + <style>.multicolor-0:tintColor {fill:#007AFF} +.multicolor-1:tintColor {fill:#007AFF;opacity:0.0;-sfsymbols-clear-behind:true} + +.hierarchical-0:secondary {fill:#4D4D4D} .hierarchical-1:primary {fill:#212121} -.SFSymbolsPreview212121 {fill:#212121;opacity:1.0} -.SFSymbolsPreview4D4D4D {fill:#4D4D4D;opacity:1.0} +.SFSymbolsPreview007AFF {fill:#007AFF;opacity:1.0} +.SFSymbolsPreviewFFFFFF {fill:#FFFFFF;opacity:1.0} </style> <g id="Notes"> <rect height="2200" id="artboard" style="fill:white;opacity:1" width="3300" x="0" y="0"/> @@ -26,13 +29,13 @@ <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:middle;" transform="matrix(1 0 0 1 2933.4 322)">Black</text> <line style="fill:none;stroke:black;opacity:1;stroke-width:0.5;" x1="263" x2="3036" y1="1903" y2="1903"/> <g transform="matrix(1 0 0 1 263 1933)"> - <path d="M9.24805 0.830078Q10.8691 0.830078 12.2949 0.214844Q13.7207-0.400391 14.8096-1.49414Q15.8984-2.58789 16.5186-4.01367Q17.1387-5.43945 17.1387-7.05078Q17.1387-8.66211 16.5186-10.0879Q15.8984-11.5137 14.8047-12.6074Q13.7109-13.7012 12.2852-14.3164Q10.8594-14.9316 9.23828-14.9316Q7.62695-14.9316 6.20117-14.3164Q4.77539-13.7012 3.69141-12.6074Q2.60742-11.5137 1.9873-10.0879Q1.36719-8.66211 1.36719-7.05078Q1.36719-5.43945 1.9873-4.01367Q2.60742-2.58789 3.69629-1.49414Q4.78516-0.400391 6.21094 0.214844Q7.63672 0.830078 9.24805 0.830078ZM9.24805-0.654297Q7.91992-0.654297 6.7627-1.14746Q5.60547-1.64062 4.73145-2.51953Q3.85742-3.39844 3.36426-4.56055Q2.87109-5.72266 2.87109-7.05078Q2.87109-8.37891 3.35938-9.54102Q3.84766-10.7031 4.72168-11.582Q5.5957-12.4609 6.75293-12.9541Q7.91016-13.4473 9.23828-13.4473Q10.5762-13.4473 11.7334-12.9541Q12.8906-12.4609 13.7695-11.582Q14.6484-10.7031 15.1465-9.54102Q15.6445-8.37891 15.6445-7.05078Q15.6445-5.72266 15.1514-4.56055Q14.6582-3.39844 13.7842-2.51953Q12.9102-1.64062 11.748-1.14746Q10.5859-0.654297 9.24805-0.654297ZM5.6543-7.05078Q5.6543-6.72852 5.85938-6.52832Q6.06445-6.32812 6.40625-6.32812L8.51562-6.32812L8.51562-4.20898Q8.51562-3.88672 8.71094-3.67676Q8.90625-3.4668 9.23828-3.4668Q9.56055-3.4668 9.77051-3.67676Q9.98047-3.88672 9.98047-4.20898L9.98047-6.32812L12.0898-6.32812Q12.4219-6.32812 12.627-6.52832Q12.832-6.72852 12.832-7.05078Q12.832-7.38281 12.627-7.58789Q12.4219-7.79297 12.0898-7.79297L9.98047-7.79297L9.98047-9.90234Q9.98047-10.2344 9.77051-10.4443Q9.56055-10.6543 9.23828-10.6543Q8.90625-10.6543 8.71094-10.4443Q8.51562-10.2344 8.51562-9.90234L8.51562-7.79297L6.40625-7.79297Q6.06445-7.79297 5.85938-7.58789Q5.6543-7.38281 5.6543-7.05078Z"/> + <path d="M9.24805 0.830078C13.5547 0.830078 17.1387-2.74414 17.1387-7.05078C17.1387-11.3574 13.5449-14.9316 9.23828-14.9316C4.94141-14.9316 1.36719-11.3574 1.36719-7.05078C1.36719-2.74414 4.95117 0.830078 9.24805 0.830078ZM9.24805-0.654297C5.70312-0.654297 2.87109-3.49609 2.87109-7.05078C2.87109-10.6055 5.69336-13.4473 9.23828-13.4473C12.793-13.4473 15.6445-10.6055 15.6445-7.05078C15.6445-3.49609 12.8027-0.654297 9.24805-0.654297ZM5.6543-7.05078C5.6543-6.62109 5.95703-6.32812 6.40625-6.32812L8.50586-6.32812L8.50586-4.20898C8.50586-3.76953 8.79883-3.4668 9.22852-3.4668C9.67773-3.4668 9.9707-3.76953 9.9707-4.20898L9.9707-6.32812L12.0898-6.32812C12.5293-6.32812 12.832-6.62109 12.832-7.05078C12.832-7.49023 12.5293-7.79297 12.0898-7.79297L9.9707-7.79297L9.9707-9.90234C9.9707-10.3516 9.67773-10.6543 9.22852-10.6543C8.79883-10.6543 8.50586-10.3516 8.50586-9.90234L8.50586-7.79297L6.40625-7.79297C5.95703-7.79297 5.6543-7.49023 5.6543-7.05078Z"/> </g> <g transform="matrix(1 0 0 1 281.867 1933)"> - <path d="M11.709 2.91016Q13.75 2.91016 15.5518 2.12891Q17.3535 1.34766 18.7305-0.0292969Q20.1074-1.40625 20.8887-3.20801Q21.6699-5.00977 21.6699-7.05078Q21.6699-9.0918 20.8887-10.8936Q20.1074-12.6953 18.7305-14.0723Q17.3535-15.4492 15.5469-16.2305Q13.7402-17.0117 11.6992-17.0117Q9.6582-17.0117 7.85645-16.2305Q6.05469-15.4492 4.68262-14.0723Q3.31055-12.6953 2.5293-10.8936Q1.74805-9.0918 1.74805-7.05078Q1.74805-5.00977 2.5293-3.20801Q3.31055-1.40625 4.6875-0.0292969Q6.06445 1.34766 7.86621 2.12891Q9.66797 2.91016 11.709 2.91016ZM11.709 1.25Q9.98047 1.25 8.47656 0.605469Q6.97266-0.0390625 5.83496-1.17676Q4.69727-2.31445 4.05762-3.81836Q3.41797-5.32227 3.41797-7.05078Q3.41797-8.7793 4.05762-10.2832Q4.69727-11.7871 5.83008-12.9297Q6.96289-14.0723 8.4668-14.7119Q9.9707-15.3516 11.6992-15.3516Q13.4277-15.3516 14.9316-14.7119Q16.4355-14.0723 17.5781-12.9297Q18.7207-11.7871 19.3652-10.2832Q20.0098-8.7793 20.0098-7.05078Q20.0098-5.32227 19.3701-3.81836Q18.7305-2.31445 17.5928-1.17676Q16.4551-0.0390625 14.9463 0.605469Q13.4375 1.25 11.709 1.25ZM7.17773-7.05078Q7.17773-6.69922 7.41211-6.47461Q7.64648-6.25 8.01758-6.25L10.8887-6.25L10.8887-3.36914Q10.8887-2.99805 11.1133-2.76855Q11.3379-2.53906 11.6895-2.53906Q12.0605-2.53906 12.29-2.76855Q12.5195-2.99805 12.5195-3.36914L12.5195-6.25L15.4004-6.25Q15.7715-6.25 16.001-6.47461Q16.2305-6.69922 16.2305-7.05078Q16.2305-7.42188 16.001-7.65137Q15.7715-7.88086 15.4004-7.88086L12.5195-7.88086L12.5195-10.752Q12.5195-11.1328 12.29-11.3623Q12.0605-11.5918 11.6895-11.5918Q11.3379-11.5918 11.1133-11.3574Q10.8887-11.123 10.8887-10.752L10.8887-7.88086L8.01758-7.88086Q7.63672-7.88086 7.40723-7.65137Q7.17773-7.42188 7.17773-7.05078Z"/> + <path d="M11.709 2.91016C17.1582 2.91016 21.6699-1.61133 21.6699-7.05078C21.6699-12.5 17.1484-17.0117 11.6992-17.0117C6.25977-17.0117 1.74805-12.5 1.74805-7.05078C1.74805-1.61133 6.26953 2.91016 11.709 2.91016ZM11.709 1.25C7.09961 1.25 3.41797-2.44141 3.41797-7.05078C3.41797-11.6602 7.08984-15.3516 11.6992-15.3516C16.3086-15.3516 20.0098-11.6602 20.0098-7.05078C20.0098-2.44141 16.3184 1.25 11.709 1.25ZM7.17773-7.05078C7.17773-6.57227 7.50977-6.25 8.00781-6.25L10.8789-6.25L10.8789-3.36914C10.8789-2.88086 11.2109-2.53906 11.6895-2.53906C12.1777-2.53906 12.5195-2.87109 12.5195-3.36914L12.5195-6.25L15.4004-6.25C15.8887-6.25 16.2305-6.57227 16.2305-7.05078C16.2305-7.53906 15.8887-7.88086 15.4004-7.88086L12.5195-7.88086L12.5195-10.752C12.5195-11.25 12.1777-11.5918 11.6895-11.5918C11.2109-11.5918 10.8789-11.25 10.8789-10.752L10.8789-7.88086L8.00781-7.88086C7.50977-7.88086 7.17773-7.53906 7.17773-7.05078Z"/> </g> <g transform="matrix(1 0 0 1 305.646 1933)"> - <path d="M14.9707 5.66406Q17.0605 5.66406 18.96 5.01465Q20.8594 4.36523 22.4512 3.19336Q24.043 2.02148 25.2197 0.429688Q26.3965-1.16211 27.0459-3.06641Q27.6953-4.9707 27.6953-7.05078Q27.6953-9.14062 27.0459-11.04Q26.3965-12.9395 25.2197-14.5312Q24.043-16.123 22.4512-17.2998Q20.8594-18.4766 18.9551-19.126Q17.0508-19.7754 14.9609-19.7754Q12.8711-19.7754 10.9717-19.126Q9.07227-18.4766 7.48535-17.2998Q5.89844-16.123 4.72168-14.5312Q3.54492-12.9395 2.90039-11.04Q2.25586-9.14062 2.25586-7.05078Q2.25586-4.9707 2.90527-3.06641Q3.55469-1.16211 4.72656 0.429688Q5.89844 2.02148 7.49023 3.19336Q9.08203 4.36523 10.9814 5.01465Q12.8809 5.66406 14.9707 5.66406ZM14.9707 3.84766Q13.1641 3.84766 11.5283 3.2959Q9.89258 2.74414 8.53516 1.74805Q7.17773 0.751953 6.17676-0.610352Q5.17578-1.97266 4.62891-3.6084Q4.08203-5.24414 4.08203-7.05078Q4.08203-8.86719 4.62891-10.5029Q5.17578-12.1387 6.17188-13.501Q7.16797-14.8633 8.52539-15.8594Q9.88281-16.8555 11.5186-17.4023Q13.1543-17.9492 14.9609-17.9492Q16.7773-17.9492 18.4131-17.4023Q20.0488-16.8555 21.4111-15.8594Q22.7734-14.8633 23.7695-13.501Q24.7656-12.1387 25.3174-10.5029Q25.8691-8.86719 25.8691-7.05078Q25.8789-5.24414 25.332-3.6084Q24.7852-1.97266 23.7842-0.610352Q22.7832 0.751953 21.4209 1.74805Q20.0586 2.74414 18.4229 3.2959Q16.7871 3.84766 14.9707 3.84766ZM9.19922-7.05078Q9.19922-6.66992 9.45801-6.4209Q9.7168-6.17188 10.1172-6.17188L14.0625-6.17188L14.0625-2.2168Q14.0625-1.81641 14.3115-1.55762Q14.5605-1.29883 14.9512-1.29883Q15.3516-1.29883 15.6104-1.55273Q15.8691-1.80664 15.8691-2.2168L15.8691-6.17188L19.8242-6.17188Q20.2246-6.17188 20.4785-6.4209Q20.7324-6.66992 20.7324-7.05078Q20.7324-7.46094 20.4785-7.71484Q20.2246-7.96875 19.8242-7.96875L15.8691-7.96875L15.8691-11.9141Q15.8691-12.3242 15.6104-12.583Q15.3516-12.8418 14.9512-12.8418Q14.5605-12.8418 14.3115-12.583Q14.0625-12.3242 14.0625-11.9141L14.0625-7.96875L10.1172-7.96875Q9.70703-7.96875 9.45312-7.71484Q9.19922-7.46094 9.19922-7.05078Z"/> + <path d="M14.9707 5.66406C21.9336 5.66406 27.6953-0.0976562 27.6953-7.05078C27.6953-14.0137 21.9238-19.7754 14.9609-19.7754C8.00781-19.7754 2.25586-14.0137 2.25586-7.05078C2.25586-0.0976562 8.01758 5.66406 14.9707 5.66406ZM14.9707 3.84766C8.93555 3.84766 4.08203-1.01562 4.08203-7.05078C4.08203-13.0957 8.92578-17.9492 14.9609-17.9492C21.0059-17.9492 25.8691-13.0957 25.8691-7.05078C25.8691-1.01562 21.0156 3.84766 14.9707 3.84766ZM9.19922-7.05078C9.19922-6.5332 9.57031-6.17188 10.1172-6.17188L14.0625-6.17188L14.0625-2.2168C14.0625-1.67969 14.4336-1.29883 14.9512-1.29883C15.4883-1.29883 15.8594-1.66992 15.8594-2.2168L15.8594-6.17188L19.8145-6.17188C20.3516-6.17188 20.7324-6.5332 20.7324-7.05078C20.7324-7.59766 20.3613-7.96875 19.8145-7.96875L15.8594-7.96875L15.8594-11.9141C15.8594-12.4609 15.4883-12.8418 14.9512-12.8418C14.4336-12.8418 14.0625-12.4609 14.0625-11.9141L14.0625-7.96875L10.1172-7.96875C9.57031-7.96875 9.19922-7.59766 9.19922-7.05078Z"/> </g> <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;font-weight:bold;" transform="matrix(1 0 0 1 263 1953)">Design Variations</text> <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 263 1971)">Symbols are supported in up to nine weights and three scales.</text> @@ -40,7 +43,7 @@ <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 263 2007)">symbols with the adjacent text.</text> <line style="fill:none;stroke:#00AEEF;stroke-width:0.5;opacity:1.0;" x1="776" x2="776" y1="1919" y2="1933"/> <g transform="matrix(1 0 0 1 776 1933)"> - <path d="M3.31055 0.15625Q3.70117 0.15625 3.91602-0.00976562Q4.13086-0.175781 4.26758-0.585938L5.52734-4.0332L11.2891-4.0332L12.5488-0.585938Q12.6855-0.175781 12.9004-0.00976562Q13.1152 0.15625 13.4961 0.15625Q13.8867 0.15625 14.1162-0.0585938Q14.3457-0.273438 14.3457-0.644531Q14.3457-0.869141 14.2383-1.17188L9.6582-13.3691Q9.48242-13.8184 9.17969-14.043Q8.87695-14.2676 8.4082-14.2676Q7.5-14.2676 7.17773-13.3789L2.59766-1.16211Q2.49023-0.859375 2.49023-0.634766Q2.49023-0.263672 2.70996-0.0537109Q2.92969 0.15625 3.31055 0.15625ZM6.00586-5.51758L8.37891-12.0898L8.42773-12.0898L10.8008-5.51758Z"/> + <path d="M3.31055 0.15625C3.82812 0.15625 4.08203-0.0390625 4.26758-0.585938L5.52734-4.0332L11.2891-4.0332L12.5488-0.585938C12.7344-0.0390625 12.9883 0.15625 13.4961 0.15625C14.0137 0.15625 14.3457-0.15625 14.3457-0.644531C14.3457-0.810547 14.3164-0.966797 14.2383-1.17188L9.6582-13.3691C9.43359-13.9648 9.0332-14.2676 8.4082-14.2676C7.80273-14.2676 7.39258-13.9746 7.17773-13.3789L2.59766-1.16211C2.51953-0.957031 2.49023-0.800781 2.49023-0.634766C2.49023-0.146484 2.80273 0.15625 3.31055 0.15625ZM6.00586-5.51758L8.37891-12.0898L8.42773-12.0898L10.8008-5.51758Z"/> </g> <line style="fill:none;stroke:#00AEEF;stroke-width:0.5;opacity:1.0;" x1="793.197" x2="793.197" y1="1919" y2="1933"/> <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;font-weight:bold;" transform="matrix(1 0 0 1 776 1953)">Margins</text> @@ -49,14 +52,14 @@ <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 776 2007)">Modifications are automatically applied proportionally to all</text> <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 776 2025)">scales and weights.</text> <g transform="matrix(1 0 0 1 1289 1933)"> - <path d="M2.8418 1.86523L4.54102 3.57422Q5.18555 4.22852 5.90332 4.17969Q6.62109 4.13086 7.31445 3.35938L18.0078-8.42773L17.041-9.4043L6.42578 2.27539Q6.16211 2.57812 5.89355 2.61719Q5.625 2.65625 5.27344 2.30469L4.10156 1.14258Q3.75 0.791016 3.79395 0.522461Q3.83789 0.253906 4.14062-0.0195312L15.6152-10.8203L14.6387-11.7871L3.04688-0.898438Q2.30469-0.214844 2.25098 0.498047Q2.19727 1.21094 2.8418 1.86523ZM9.25781-16.3281Q8.94531-16.0254 8.90625-15.6348Q8.86719-15.2441 9.04297-14.9512Q9.21875-14.6777 9.55566-14.541Q9.89258-14.4043 10.3809-14.5215Q11.4746-14.7754 12.5977-14.7314Q13.7207-14.6875 14.7949-13.9844L14.209-12.5293Q13.9551-11.9043 14.0674-11.4404Q14.1797-10.9766 14.5801-10.5664L16.875-8.25195Q17.2363-7.88086 17.5781-7.82227Q17.9199-7.76367 18.3398-7.8418L19.4043-8.03711L20.0684-7.36328L20.0293-6.80664Q20-6.43555 20.1221-6.12305Q20.2441-5.81055 20.6055-5.44922L21.3672-4.70703Q21.7285-4.3457 22.1533-4.33105Q22.5781-4.31641 22.9297-4.66797L25.8398-7.58789Q26.1914-7.93945 26.1816-8.35449Q26.1719-8.76953 25.8105-9.13086L25.0391-9.89258Q24.6875-10.2539 24.3799-10.3857Q24.0723-10.5176 23.7109-10.4883L23.1348-10.4395L22.4902-11.0742L22.7344-12.1973Q22.832-12.6172 22.6953-12.9834Q22.5586-13.3496 22.1191-13.7891L19.9219-15.9766Q18.6719-17.2168 17.2607-17.8369Q15.8496-18.457 14.4189-18.4814Q12.9883-18.5059 11.665-17.959Q10.3418-17.4121 9.25781-16.3281ZM10.752-15.957Q11.6602-16.6211 12.7002-16.9043Q13.7402-17.1875 14.8047-17.085Q15.8691-16.9824 16.8701-16.5137Q17.8711-16.0449 18.7012-15.2051L21.1328-12.793Q21.3086-12.6172 21.3525-12.4512Q21.3965-12.2852 21.3379-12.0312L21.0156-10.5469L22.5195-9.0625L23.5059-9.12109Q23.6914-9.13086 23.7891-9.09668Q23.8867-9.0625 24.0332-8.91602L24.6094-8.33984L22.168-5.89844L21.5918-6.47461Q21.4453-6.62109 21.4062-6.71875Q21.3672-6.81641 21.377-7.01172L21.4453-7.98828L19.9512-9.47266L18.4277-9.21875Q18.1836-9.16992 18.042-9.2041Q17.9004-9.23828 17.7148-9.41406L15.7129-11.416Q15.5176-11.5918 15.4932-11.7529Q15.4688-11.9141 15.5859-12.1875L16.4648-14.2773Q15.293-15.3711 13.8281-15.791Q12.3633-16.2109 10.8398-15.7617Q10.7227-15.7324 10.6885-15.8057Q10.6543-15.8789 10.752-15.957Z"/> + <path d="M2.8418 1.86523L4.54102 3.57422C5.40039 4.44336 6.38672 4.38477 7.31445 3.35938L18.0078-8.42773L17.041-9.4043L6.42578 2.27539C6.07422 2.67578 5.74219 2.77344 5.27344 2.30469L4.10156 1.14258C3.63281 0.683594 3.74023 0.341797 4.14062-0.0195312L15.6152-10.8203L14.6387-11.7871L3.04688-0.898438C2.06055 0.0195312 1.98242 0.996094 2.8418 1.86523ZM9.25781-16.3281C8.83789-15.918 8.80859-15.3418 9.04297-14.9512C9.27734-14.5898 9.73633-14.3555 10.3809-14.5215C11.8457-14.8633 13.3691-14.9219 14.7949-13.9844L14.209-12.5293C13.8672-11.6992 14.043-11.1133 14.5801-10.5664L16.875-8.25195C17.3633-7.76367 17.7734-7.74414 18.3398-7.8418L19.4043-8.03711L20.0684-7.36328L20.0293-6.80664C19.9902-6.30859 20.1172-5.92773 20.6055-5.44922L21.3672-4.70703C21.8457-4.22852 22.4609-4.19922 22.9297-4.66797L25.8398-7.58789C26.3086-8.05664 26.2891-8.65234 25.8105-9.13086L25.0391-9.89258C24.5605-10.3711 24.1895-10.5273 23.7109-10.4883L23.1348-10.4395L22.4902-11.0742L22.7344-12.1973C22.8613-12.7637 22.7051-13.2031 22.1191-13.7891L19.9219-15.9766C16.582-19.2969 12.1484-19.2188 9.25781-16.3281ZM10.752-15.957C13.1836-17.7344 16.4746-17.4316 18.7012-15.2051L21.1328-12.793C21.3672-12.5586 21.4062-12.373 21.3379-12.0312L21.0156-10.5469L22.5195-9.0625L23.5059-9.12109C23.7598-9.13086 23.8379-9.11133 24.0332-8.91602L24.6094-8.33984L22.168-5.89844L21.5918-6.47461C21.3965-6.66992 21.3672-6.74805 21.377-7.01172L21.4453-7.98828L19.9512-9.47266L18.4277-9.21875C18.1055-9.15039 17.959-9.17969 17.7148-9.41406L15.7129-11.416C15.459-11.6504 15.4297-11.8164 15.5859-12.1875L16.4648-14.2773C14.9023-15.7324 12.8711-16.3574 10.8398-15.7617C10.6836-15.7227 10.625-15.8496 10.752-15.957Z"/> </g> <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;font-weight:bold;" transform="matrix(1 0 0 1 1289 1953)">Exporting</text> <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 1289 1971)">Symbols should be outlined when exporting to ensure the</text> <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 1289 1989)">design is preserved when submitting to Xcode.</text> <text id="template-version" style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:end;" transform="matrix(1 0 0 1 3036 1933)">Template v.3.0</text> <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:end;" transform="matrix(1 0 0 1 3036 1951)">Requires Xcode 13 or greater</text> - <text id="descriptive-name" style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:end;" transform="matrix(1 0 0 1 3036 1969)">Generated from plus.circle.fill.cr</text> + <text id="descriptive-name" style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:end;" transform="matrix(1 0 0 1 3036 1969)">Generated from plus.circle.fill.alt.cr</text> <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:end;" transform="matrix(1 0 0 1 3036 1987)">Typeset at 100 points</text> <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 263 726)">Small</text> <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 263 1156)">Medium</text> @@ -64,131 +67,131 @@ </g> <g id="Guides"> <g id="H-reference" style="fill:#27AAE1;stroke:none;" transform="matrix(1 0 0 1 339 696)"> - <path d="M0.993347 0L3.6377 0L29.3282-67.1326L30.0301-67.1326L30.0301-70.459L28.1227-70.459ZM11.6882-24.4797L46.9818-24.4797L46.2311-26.7288L12.4382-26.7288ZM55.1193 0L57.7637 0L30.6381-70.459L29.4327-70.459L29.4327-67.1326Z"/> + <path d="M0.993654 0L3.63775 0L29.3281-67.1323L30.0303-67.1323L30.0303-70.459L28.1226-70.459ZM11.6885-24.4799L46.9815-24.4799L46.2315-26.7285L12.4385-26.7285ZM55.1196 0L57.7637 0L30.6382-70.459L29.4326-70.459L29.4326-67.1323Z"/> </g> <line id="Baseline-S" style="fill:none;stroke:#27AAE1;opacity:1;stroke-width:0.5;" x1="263" x2="3036" y1="696" y2="696"/> <line id="Capline-S" style="fill:none;stroke:#27AAE1;opacity:1;stroke-width:0.5;" x1="263" x2="3036" y1="625.541" y2="625.541"/> <g id="H-reference" style="fill:#27AAE1;stroke:none;" transform="matrix(1 0 0 1 339 1126)"> - <path d="M0.993347 0L3.6377 0L29.3282-67.1326L30.0301-67.1326L30.0301-70.459L28.1227-70.459ZM11.6882-24.4797L46.9818-24.4797L46.2311-26.7288L12.4382-26.7288ZM55.1193 0L57.7637 0L30.6381-70.459L29.4327-70.459L29.4327-67.1326Z"/> + <path d="M0.993654 0L3.63775 0L29.3281-67.1323L30.0303-67.1323L30.0303-70.459L28.1226-70.459ZM11.6885-24.4799L46.9815-24.4799L46.2315-26.7285L12.4385-26.7285ZM55.1196 0L57.7637 0L30.6382-70.459L29.4326-70.459L29.4326-67.1323Z"/> </g> <line id="Baseline-M" style="fill:none;stroke:#27AAE1;opacity:1;stroke-width:0.5;" x1="263" x2="3036" y1="1126" y2="1126"/> <line id="Capline-M" style="fill:none;stroke:#27AAE1;opacity:1;stroke-width:0.5;" x1="263" x2="3036" y1="1055.54" y2="1055.54"/> <g id="H-reference" style="fill:#27AAE1;stroke:none;" transform="matrix(1 0 0 1 339 1556)"> - <path d="M0.993347 0L3.6377 0L29.3282-67.1326L30.0301-67.1326L30.0301-70.459L28.1227-70.459ZM11.6882-24.4797L46.9818-24.4797L46.2311-26.7288L12.4382-26.7288ZM55.1193 0L57.7637 0L30.6381-70.459L29.4327-70.459L29.4327-67.1326Z"/> + <path d="M0.993654 0L3.63775 0L29.3281-67.1323L30.0303-67.1323L30.0303-70.459L28.1226-70.459ZM11.6885-24.4799L46.9815-24.4799L46.2315-26.7285L12.4385-26.7285ZM55.1196 0L57.7637 0L30.6382-70.459L29.4326-70.459L29.4326-67.1323Z"/> </g> <line id="Baseline-L" style="fill:none;stroke:#27AAE1;opacity:1;stroke-width:0.5;" x1="263" x2="3036" y1="1556" y2="1556"/> <line id="Capline-L" style="fill:none;stroke:#27AAE1;opacity:1;stroke-width:0.5;" x1="263" x2="3036" y1="1485.54" y2="1485.54"/> - <line id="left-margin-Regular-M" style="fill:none;stroke:#FF3B30;stroke-width:0.5;opacity:1.0;" x1="1374.84" x2="1374.84" y1="1030.78" y2="1150.12"/> - <line id="right-margin-Regular-M" style="fill:none;stroke:#FF3B30;stroke-width:0.5;opacity:1.0;" x1="1524.84" x2="1524.84" y1="1030.78" y2="1150.12"/> + <line id="left-margin-Regular-M" style="fill:none;stroke:#FF3B30;stroke-width:0.5;opacity:1.0;" x1="1374.84" x2="1374.84" y1="1030.79" y2="1150.12"/> + <line id="right-margin-Regular-M" style="fill:none;stroke:#FF3B30;stroke-width:0.5;opacity:1.0;" x1="1524.84" x2="1524.84" y1="1030.79" y2="1150.12"/> </g> <g id="Symbols"> <g id="Black-L" transform="matrix(1 0 0 1 2843.4 1556)"> - <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M124.7 47.29C113.85 52 102.26 54.35 89.96 54.35C77.65 54.35 66.07 52 55.21 47.29C44.35 42.65 34.78 36.17 26.47 27.86C18.23 19.56 11.76 9.97 7.05-0.89C2.35-11.75 0-23.34 0-35.65C0-47.96 2.35-59.55 7.05-70.41C11.76-81.27 18.23-90.83 26.47-99.08C34.78-107.38 44.33-113.89 55.12-118.59C65.98-123.3 77.56-125.65 89.87-125.65C102.24-125.65 113.85-123.3 124.7-118.59C135.56-113.89 145.14-107.38 153.44-99.08C161.74-90.83 168.24-81.27 172.95-70.41C177.65-59.55 180-47.96 180-35.65C180-23.34 177.65-11.75 172.95-0.89C168.24 9.97 161.74 19.56 153.44 27.86C145.14 36.17 135.56 42.65 124.7 47.29Z"/> - <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M79.34-7.83C79.34-1.75 84.26 3.17 90.34 3.17C96.42 3.17 101.34-1.75 101.34-7.83L101.34-24.67L118.17-24.67C124.25-24.67 129.17-29.59 129.17-35.67C129.17-41.74 124.25-46.67 118.17-46.67L101.34-46.67L101.34-63.5C101.34-69.58 96.42-74.5 90.34-74.5C84.26-74.5 79.34-69.58 79.34-63.5L79.34-46.67L62.5-46.67C56.43-46.67 51.5-41.74 51.5-35.67C51.5-29.59 56.43-24.67 62.5-24.67L79.34-24.67L79.34-7.83Z"/> + <path class="multicolor-0:tintColor hierarchical-0:secondary SFSymbolsPreview007AFF" d="M124.7 47.29C113.85 52 102.26 54.35 89.96 54.35C77.65 54.35 66.07 52 55.21 47.29C44.35 42.65 34.78 36.17 26.47 27.86C18.23 19.56 11.76 9.97 7.05-0.89C2.35-11.75 0-23.34 0-35.65C0-47.96 2.35-59.55 7.05-70.41C11.76-81.27 18.23-90.83 26.47-99.08C34.78-107.38 44.33-113.89 55.12-118.59C65.98-123.3 77.56-125.65 89.87-125.65C102.24-125.65 113.85-123.3 124.7-118.59C135.56-113.89 145.14-107.38 153.44-99.08C161.74-90.83 168.24-81.27 172.95-70.41C177.65-59.55 180-47.96 180-35.65C180-23.34 177.65-11.75 172.95-0.89C168.24 9.97 161.74 19.56 153.44 27.86C145.14 36.17 135.56 42.65 124.7 47.29Z"/> + <path class="multicolor-1:tintColor hierarchical-1:primary SFSymbolsPreviewFFFFFF" d="M79.34-0.83C79.34 5.25 84.26 10.17 90.34 10.17C96.42 10.17 101.34 5.25 101.34-0.83L101.34-24.67L125.17-24.67C131.25-24.67 136.17-29.59 136.17-35.67C136.17-41.74 131.25-46.67 125.17-46.67L101.34-46.67L101.34-70.5C101.34-76.58 96.42-81.5 90.34-81.5C84.26-81.5 79.34-76.58 79.34-70.5L79.34-46.67L55.5-46.67C49.43-46.67 44.5-41.74 44.5-35.67C44.5-29.59 49.43-24.67 55.5-24.67L79.34-24.67L79.34-0.83Z"/> </g> <g id="Heavy-L" transform="matrix(1 0 0 1 2545.69 1556)"> - <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M126.09 48.26C115.11 53.02 103.4 55.4 90.96 55.4C78.51 55.4 66.8 53.02 55.82 48.26C44.85 43.57 35.16 37.02 26.77 28.62C18.43 20.22 11.89 10.53 7.13-0.45C2.38-11.43 0-23.15 0-35.6C0-48.05 2.38-59.77 7.13-70.75C11.89-81.73 18.43-91.39 26.77-99.73C35.16-108.13 44.82-114.71 55.74-119.46C66.71-124.22 78.42-126.6 90.87-126.6C103.37-126.6 115.11-124.22 126.09-119.46C137.07-114.71 146.75-108.13 155.14-99.73C163.54-91.39 170.11-81.73 174.87-70.75C179.62-59.77 182-48.05 182-35.6C182-23.15 179.62-11.43 174.87-0.45C170.11 10.53 163.54 20.22 155.14 28.62C146.75 37.02 137.07 43.57 126.09 48.26Z"/> - <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M81.84-7.83C81.84-2.58 86.09 1.67 91.34 1.67C96.59 1.67 100.84-2.58 100.84-7.83L100.84-26.17L119.17-26.17C124.42-26.17 128.67-30.42 128.67-35.67C128.67-40.91 124.42-45.17 119.17-45.17L100.84-45.17L100.84-63.5C100.84-68.75 96.59-73 91.34-73C86.09-73 81.84-68.75 81.84-63.5L81.84-45.17L63.5-45.17C58.25-45.17 54-40.91 54-35.67C54-30.42 58.25-26.17 63.5-26.17L81.84-26.17L81.84-7.83Z"/> + <path class="multicolor-0:tintColor hierarchical-0:secondary SFSymbolsPreview007AFF" d="M126.09 48.26C115.11 53.02 103.4 55.4 90.96 55.4C78.51 55.4 66.8 53.02 55.82 48.26C44.85 43.57 35.16 37.02 26.77 28.62C18.43 20.22 11.89 10.53 7.13-0.45C2.38-11.43 0-23.15 0-35.6C0-48.05 2.38-59.77 7.13-70.75C11.89-81.73 18.43-91.39 26.77-99.73C35.16-108.13 44.82-114.71 55.74-119.46C66.71-124.22 78.42-126.6 90.87-126.6C103.37-126.6 115.11-124.22 126.09-119.46C137.07-114.71 146.75-108.13 155.14-99.73C163.54-91.39 170.11-81.73 174.87-70.75C179.62-59.77 182-48.05 182-35.6C182-23.15 179.62-11.43 174.87-0.45C170.11 10.53 163.54 20.22 155.14 28.62C146.75 37.02 137.07 43.57 126.09 48.26Z"/> + <path class="multicolor-1:tintColor hierarchical-1:primary SFSymbolsPreviewFFFFFF" d="M81.84-0.83C81.84 4.42 86.09 8.67 91.34 8.67C96.59 8.67 100.84 4.42 100.84-0.83L100.84-26.17L126.17-26.17C131.42-26.17 135.67-30.42 135.67-35.67C135.67-40.91 131.42-45.17 126.17-45.17L100.84-45.17L100.84-70.5C100.84-75.75 96.59-80 91.34-80C86.09-80 81.84-75.75 81.84-70.5L81.84-45.17L56.5-45.17C51.25-45.17 47-40.91 47-35.67C47-30.42 51.25-26.17 56.5-26.17L81.84-26.17L81.84-0.83Z"/> </g> <g id="Bold-L" transform="matrix(1 0 0 1 2249.98 1556)"> - <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M124.7 47.74C113.85 52.45 102.26 54.8 89.96 54.8C77.65 54.8 66.07 52.45 55.21 47.74C44.35 43.1 34.78 36.62 26.47 28.31C18.23 20.01 11.76 10.42 7.05-0.44C2.35-11.3 0-22.89 0-35.2C0-47.51 2.35-59.1 7.05-69.96C11.76-80.83 18.23-90.38 26.47-98.63C34.78-106.93 44.33-113.44 55.12-118.14C65.98-122.85 77.56-125.2 89.87-125.2C102.24-125.2 113.85-122.85 124.7-118.14C135.56-113.44 145.14-106.93 153.44-98.63C161.74-90.38 168.24-80.83 172.95-69.96C177.65-59.1 180-47.51 180-35.2C180-22.89 177.65-11.3 172.95-0.44C168.24 10.42 161.74 20.01 153.44 28.31C145.14 36.62 135.56 43.1 124.7 47.74Z"/> - <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M81.99-7.33C81.99-2.91 85.57 0.67 89.99 0.67C94.41 0.67 97.99-2.91 97.99-7.33L97.99-27.17L117.82-27.17C122.24-27.17 125.82-30.75 125.82-35.17C125.82-39.59 122.24-43.17 117.82-43.17L97.99-43.17L97.99-63C97.99-67.42 94.41-71 89.99-71C85.57-71 81.99-67.42 81.99-63L81.99-43.17L62.15-43.17C57.73-43.17 54.15-39.59 54.15-35.17C54.15-30.75 57.73-27.17 62.15-27.17L81.99-27.17L81.99-7.33Z"/> + <path class="multicolor-0:tintColor hierarchical-0:secondary SFSymbolsPreview007AFF" d="M124.7 47.74C113.85 52.45 102.26 54.8 89.96 54.8C77.65 54.8 66.07 52.45 55.21 47.74C44.35 43.1 34.78 36.62 26.47 28.31C18.23 20.01 11.76 10.42 7.05-0.44C2.35-11.3 0-22.89 0-35.2C0-47.51 2.35-59.1 7.05-69.96C11.76-80.83 18.23-90.38 26.47-98.63C34.78-106.93 44.33-113.44 55.12-118.14C65.98-122.85 77.56-125.2 89.87-125.2C102.24-125.2 113.85-122.85 124.7-118.14C135.56-113.44 145.14-106.93 153.44-98.63C161.74-90.38 168.24-80.83 172.95-69.96C177.65-59.1 180-47.51 180-35.2C180-22.89 177.65-11.3 172.95-0.44C168.24 10.42 161.74 20.01 153.44 28.31C145.14 36.62 135.56 43.1 124.7 47.74Z"/> + <path class="multicolor-1:tintColor hierarchical-1:primary SFSymbolsPreviewFFFFFF" d="M81.99-0.33C81.99 4.09 85.57 7.67 89.99 7.67C94.41 7.67 97.99 4.09 97.99-0.33L97.99-27.17L124.82-27.17C129.24-27.17 132.82-30.75 132.82-35.17C132.82-39.59 129.24-43.17 124.82-43.17L97.99-43.17L97.99-70C97.99-74.42 94.41-78 89.99-78C85.57-78 81.99-74.42 81.99-70L81.99-43.17L55.15-43.17C50.73-43.17 47.15-39.59 47.15-35.17C47.15-30.75 50.73-27.17 55.15-27.17L81.99-27.17L81.99-0.33Z"/> </g> <g id="Semibold-L" transform="matrix(1 0 0 1 1953.27 1556)"> - <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M124.7 47.44C113.85 52.15 102.26 54.5 89.96 54.5C77.65 54.5 66.07 52.15 55.21 47.44C44.35 42.8 34.78 36.32 26.47 28.01C18.23 19.71 11.76 10.12 7.05-0.74C2.35-11.6 0-23.19 0-35.5C0-47.81 2.35-59.4 7.05-70.26C11.76-81.12 18.23-90.68 26.47-98.93C34.78-107.23 44.33-113.74 55.12-118.44C65.98-123.15 77.56-125.5 89.87-125.5C102.24-125.5 113.85-123.15 124.7-118.44C135.56-113.74 145.14-107.23 153.44-98.93C161.74-90.68 168.24-81.12 172.95-70.26C177.65-59.4 180-47.81 180-35.5C180-23.19 177.65-11.6 172.95-0.74C168.24 10.12 161.74 19.71 153.44 28.01C145.14 36.32 135.56 42.8 124.7 47.44Z"/> - <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M83.34-7.63C83.34-4.04 86.25-1.13 89.84-1.13C93.43-1.13 96.34-4.04 96.34-7.63L96.34-28.97L117.67-28.97C121.26-28.97 124.17-31.88 124.17-35.47C124.17-39.06 121.26-41.97 117.67-41.97L96.34-41.97L96.34-63.3C96.34-66.89 93.43-69.8 89.84-69.8C86.25-69.8 83.34-66.89 83.34-63.3L83.34-41.97L62-41.97C58.41-41.97 55.5-39.06 55.5-35.47C55.5-31.88 58.41-28.97 62-28.97L83.34-28.97L83.34-7.63Z"/> + <path class="multicolor-0:tintColor hierarchical-0:secondary SFSymbolsPreview007AFF" d="M124.7 47.44C113.85 52.15 102.26 54.5 89.96 54.5C77.65 54.5 66.07 52.15 55.21 47.44C44.35 42.8 34.78 36.32 26.47 28.01C18.23 19.71 11.76 10.12 7.05-0.74C2.35-11.6 0-23.19 0-35.5C0-47.81 2.35-59.4 7.05-70.26C11.76-81.12 18.23-90.68 26.47-98.93C34.78-107.23 44.33-113.74 55.12-118.44C65.98-123.15 77.56-125.5 89.87-125.5C102.24-125.5 113.85-123.15 124.7-118.44C135.56-113.74 145.14-107.23 153.44-98.93C161.74-90.68 168.24-81.12 172.95-70.26C177.65-59.4 180-47.81 180-35.5C180-23.19 177.65-11.6 172.95-0.74C168.24 10.12 161.74 19.71 153.44 28.01C145.14 36.32 135.56 42.8 124.7 47.44Z"/> + <path class="multicolor-1:tintColor hierarchical-1:primary SFSymbolsPreviewFFFFFF" d="M83.34-0.63C83.34 2.96 86.25 5.87 89.84 5.87C93.43 5.87 96.34 2.96 96.34-0.63L96.34-28.97L124.67-28.97C128.26-28.97 131.17-31.88 131.17-35.47C131.17-39.06 128.26-41.97 124.67-41.97L96.34-41.97L96.34-70.3C96.34-73.89 93.43-76.8 89.84-76.8C86.25-76.8 83.34-73.89 83.34-70.3L83.34-41.97L55-41.97C51.41-41.97 48.5-39.06 48.5-35.47C48.5-31.88 51.41-28.97 55-28.97L83.34-28.97L83.34-0.63Z"/> </g> <g id="Medium-L" transform="matrix(1 0 0 1 1656.56 1556)"> - <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M124.7 47.44C113.85 52.15 102.26 54.5 89.96 54.5C77.65 54.5 66.07 52.15 55.21 47.44C44.35 42.8 34.78 36.32 26.47 28.01C18.23 19.71 11.76 10.12 7.05-0.74C2.35-11.6 0-23.19 0-35.5C0-47.81 2.35-59.4 7.05-70.26C11.76-81.12 18.23-90.68 26.47-98.93C34.78-107.23 44.33-113.74 55.12-118.44C65.98-123.15 77.56-125.5 89.87-125.5C102.24-125.5 113.85-123.15 124.7-118.44C135.56-113.74 145.14-107.23 153.44-98.93C161.74-90.68 168.24-81.12 172.95-70.26C177.65-59.4 180-47.81 180-35.5C180-23.19 177.65-11.6 172.95-0.74C168.24 10.12 161.74 19.71 153.44 28.01C145.14 36.32 135.56 42.8 124.7 47.44Z"/> - <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M84.34-7.63C84.34-4.43 86.94-1.83 90.14-1.83C93.34-1.83 95.94-4.43 95.94-7.63L95.94-29.67L117.97-29.67C121.17-29.67 123.77-32.26 123.77-35.47C123.77-38.67 121.17-41.27 117.97-41.27L95.94-41.27L95.94-63.3C95.94-66.5 93.34-69.1 90.14-69.1C86.94-69.1 84.34-66.5 84.34-63.3L84.34-41.27L62.3-41.27C59.1-41.27 56.5-38.67 56.5-35.47C56.5-32.26 59.1-29.67 62.3-29.67L84.34-29.67L84.34-7.63Z"/> + <path class="multicolor-0:tintColor hierarchical-0:secondary SFSymbolsPreview007AFF" d="M124.7 47.44C113.85 52.15 102.26 54.5 89.96 54.5C77.65 54.5 66.07 52.15 55.21 47.44C44.35 42.8 34.78 36.32 26.47 28.01C18.23 19.71 11.76 10.12 7.05-0.74C2.35-11.6 0-23.19 0-35.5C0-47.81 2.35-59.4 7.05-70.26C11.76-81.12 18.23-90.68 26.47-98.93C34.78-107.23 44.33-113.74 55.12-118.44C65.98-123.15 77.56-125.5 89.87-125.5C102.24-125.5 113.85-123.15 124.7-118.44C135.56-113.74 145.14-107.23 153.44-98.93C161.74-90.68 168.24-81.12 172.95-70.26C177.65-59.4 180-47.81 180-35.5C180-23.19 177.65-11.6 172.95-0.74C168.24 10.12 161.74 19.71 153.44 28.01C145.14 36.32 135.56 42.8 124.7 47.44Z"/> + <path class="multicolor-1:tintColor hierarchical-1:primary SFSymbolsPreviewFFFFFF" d="M84.34-0.63C84.34 2.57 86.94 5.17 90.14 5.17C93.34 5.17 95.94 2.57 95.94-0.63L95.94-29.67L124.97-29.67C128.17-29.67 130.77-32.26 130.77-35.47C130.77-38.67 128.17-41.27 124.97-41.27L95.94-41.27L95.94-70.3C95.94-73.5 93.34-76.1 90.14-76.1C86.94-76.1 84.34-73.5 84.34-70.3L84.34-41.27L55.3-41.27C52.1-41.27 49.5-38.67 49.5-35.47C49.5-32.26 52.1-29.67 55.3-29.67L84.34-29.67L84.34-0.63Z"/> </g> <g id="Regular-L" transform="matrix(1 0 0 1 1359.84 1556)"> - <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M124.7 47.74C113.85 52.45 102.26 54.8 89.96 54.8C77.65 54.8 66.07 52.45 55.21 47.74C44.35 43.1 34.77 36.62 26.47 28.31C18.23 20.01 11.76 10.43 7.05-0.44C2.35-11.3 0-22.89 0-35.2C0-47.51 2.35-59.1 7.05-69.96C11.76-80.82 18.23-90.38 26.47-98.63C34.77-106.93 44.32-113.44 55.12-118.14C65.98-122.85 77.56-125.2 89.87-125.2C102.23-125.2 113.85-122.85 124.7-118.14C135.56-113.44 145.14-106.93 153.44-98.63C161.74-90.38 168.24-80.82 172.95-69.96C177.65-59.1 180-47.51 180-35.2C180-22.89 177.65-11.3 172.95-0.44C168.24 10.43 161.74 20.01 153.44 28.31C145.14 36.62 135.56 43.1 124.7 47.74Z"/> - <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M85.34-7.38C85.34-4.7 87.51-2.53 90.19-2.53C92.87-2.53 95.04-4.7 95.04-7.38L95.04-30.15L117.67-30.15C120.35-30.15 122.52-32.32 122.52-35C122.52-37.68 120.35-39.85 117.67-39.85L95.04-39.85L95.04-63.05C95.04-65.73 92.87-67.9 90.19-67.9C87.51-67.9 85.34-65.73 85.34-63.05L85.34-39.85L62-39.85C59.32-39.85 57.15-37.68 57.15-35C57.15-32.32 59.32-30.15 62-30.15L85.34-30.15L85.34-7.38Z"/> + <path class="multicolor-0:tintColor hierarchical-0:secondary SFSymbolsPreview007AFF" d="M124.7 47.74C113.85 52.45 102.26 54.8 89.96 54.8C77.65 54.8 66.07 52.45 55.21 47.74C44.35 43.1 34.77 36.62 26.47 28.31C18.23 20.01 11.76 10.43 7.05-0.44C2.35-11.3 0-22.89 0-35.2C0-47.51 2.35-59.1 7.05-69.96C11.76-80.82 18.23-90.38 26.47-98.63C34.77-106.93 44.32-113.44 55.12-118.14C65.98-122.85 77.56-125.2 89.87-125.2C102.23-125.2 113.85-122.85 124.7-118.14C135.56-113.44 145.14-106.93 153.44-98.63C161.74-90.38 168.24-80.82 172.95-69.96C177.65-59.1 180-47.51 180-35.2C180-22.89 177.65-11.3 172.95-0.44C168.24 10.43 161.74 20.01 153.44 28.31C145.14 36.62 135.56 43.1 124.7 47.74Z"/> + <path class="multicolor-1:tintColor hierarchical-1:primary SFSymbolsPreviewFFFFFF" d="M85.34-0.38C85.34 2.3 87.51 4.47 90.19 4.47C92.87 4.47 95.04 2.3 95.04-0.38L95.04-30.15L124.67-30.15C127.35-30.15 129.52-32.32 129.52-35C129.52-37.68 127.35-39.85 124.67-39.85L95.04-39.85L95.04-70.05C95.04-72.73 92.87-74.9 90.19-74.9C87.51-74.9 85.34-72.73 85.34-70.05L85.34-39.85L55-39.85C52.32-39.85 50.15-37.68 50.15-35C50.15-32.32 52.32-30.15 55-30.15L85.34-30.15L85.34-0.38Z"/> </g> <g id="Light-L" transform="matrix(1 0 0 1 1063.13 1556)"> - <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M124.7 46.94C113.85 51.65 102.26 54 89.96 54C77.65 54 66.07 51.65 55.21 46.94C44.35 42.3 34.78 35.82 26.47 27.51C18.23 19.21 11.76 9.62 7.05-1.24C2.35-12.1 0-23.69 0-36C0-48.31 2.35-59.9 7.05-70.76C11.76-81.62 18.23-91.18 26.47-99.43C34.78-107.73 44.33-114.24 55.12-118.94C65.98-123.65 77.56-126 89.87-126C102.24-126 113.85-123.65 124.7-118.94C135.56-114.24 145.14-107.73 153.44-99.43C161.74-91.18 168.24-81.62 172.95-70.76C177.65-59.9 180-48.31 180-36C180-23.69 177.65-12.1 172.95-1.24C168.24 9.62 161.74 19.21 153.44 27.51C145.14 35.82 135.56 42.3 124.7 46.94Z"/> - <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M86.84-8.03C86.84-6.21 88.32-4.73 90.14-4.73C91.96-4.73 93.44-6.21 93.44-8.03L93.44-32.57L117.97-32.57C119.79-32.57 121.27-34.05 121.27-35.87C121.27-37.69 119.79-39.17 117.97-39.17L93.44-39.17L93.44-63.7C93.44-65.52 91.96-67 90.14-67C88.32-67 86.84-65.52 86.84-63.7L86.84-39.17L62.3-39.17C60.48-39.17 59-37.69 59-35.87C59-34.05 60.48-32.57 62.3-32.57L86.84-32.57L86.84-8.03Z"/> + <path class="multicolor-0:tintColor hierarchical-0:secondary SFSymbolsPreview007AFF" d="M124.7 46.94C113.85 51.65 102.26 54 89.96 54C77.65 54 66.07 51.65 55.21 46.94C44.35 42.3 34.78 35.82 26.47 27.51C18.23 19.21 11.76 9.62 7.05-1.24C2.35-12.1 0-23.69 0-36C0-48.31 2.35-59.9 7.05-70.76C11.76-81.62 18.23-91.18 26.47-99.43C34.78-107.73 44.33-114.24 55.12-118.94C65.98-123.65 77.56-126 89.87-126C102.24-126 113.85-123.65 124.7-118.94C135.56-114.24 145.14-107.73 153.44-99.43C161.74-91.18 168.24-81.62 172.95-70.76C177.65-59.9 180-48.31 180-36C180-23.69 177.65-12.1 172.95-1.24C168.24 9.62 161.74 19.21 153.44 27.51C145.14 35.82 135.56 42.3 124.7 46.94Z"/> + <path class="multicolor-1:tintColor hierarchical-1:primary SFSymbolsPreviewFFFFFF" d="M86.84-1.03C86.84 0.79 88.32 2.27 90.14 2.27C91.96 2.27 93.44 0.79 93.44-1.03L93.44-32.57L124.97-32.57C126.79-32.57 128.27-34.05 128.27-35.87C128.27-37.69 126.79-39.17 124.97-39.17L93.44-39.17L93.44-70.7C93.44-72.52 91.96-74 90.14-74C88.32-74 86.84-72.52 86.84-70.7L86.84-39.17L55.3-39.17C53.48-39.17 52-37.69 52-35.87C52-34.05 53.48-32.57 55.3-32.57L86.84-32.57L86.84-1.03Z"/> </g> <g id="Thin-L" transform="matrix(1 0 0 1 766.422 1556)"> - <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M124.702 45.34C113.846 50.05 102.264 52.4 89.956 52.4C77.649 52.4 66.067 50.05 55.21 45.34C44.354 40.7 34.775 34.22 26.473 25.91C18.229 17.61 11.756 8.02 7.054-2.84C2.351-13.7 0-25.29 0-37.6C0-49.91 2.351-61.5 7.054-72.36C11.756-83.22 18.229-92.78 26.473-101.03C34.775-109.33 44.325-115.84 55.123-120.54C65.98-125.25 77.562-127.6 89.869-127.6C102.235-127.6 113.846-125.25 124.702-120.54C135.559-115.84 145.138-109.33 153.44-101.03C161.742-92.78 168.244-83.22 172.946-72.36C177.649-61.5 180-49.91 180-37.6C180-25.29 177.649-13.7 172.946-2.84C168.244 8.02 161.742 17.61 153.44 25.91C145.138 34.22 135.559 40.7 124.702 45.34Z"/> - <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M87.64-9.78C87.64-8.68 88.535-7.78 89.64-7.78C90.744-7.78 91.64-8.68 91.64-9.78L91.64-35.62L117.47-35.62C118.574-35.62 119.47-36.51 119.47-37.62C119.47-38.72 118.574-39.62 117.47-39.62L91.64-39.62L91.64-65.45C91.64-66.56 90.744-67.45 89.64-67.45C88.535-67.45 87.64-66.56 87.64-65.45L87.64-39.62L61.8-39.62C60.695-39.62 59.8-38.72 59.8-37.62C59.8-36.51 60.695-35.62 61.8-35.62L87.64-35.62L87.64-9.78Z"/> + <path class="multicolor-0:tintColor hierarchical-0:secondary SFSymbolsPreview007AFF" d="M124.702 45.34C113.846 50.05 102.264 52.4 89.956 52.4C77.649 52.4 66.067 50.05 55.21 45.34C44.354 40.7 34.775 34.22 26.473 25.91C18.229 17.61 11.756 8.02 7.054-2.84C2.351-13.7 0-25.29 0-37.6C0-49.91 2.351-61.5 7.054-72.36C11.756-83.22 18.229-92.78 26.473-101.03C34.775-109.33 44.325-115.84 55.123-120.54C65.98-125.25 77.562-127.6 89.869-127.6C102.235-127.6 113.846-125.25 124.702-120.54C135.559-115.84 145.138-109.33 153.44-101.03C161.742-92.78 168.244-83.22 172.946-72.36C177.649-61.5 180-49.91 180-37.6C180-25.29 177.649-13.7 172.946-2.84C168.244 8.02 161.742 17.61 153.44 25.91C145.138 34.22 135.559 40.7 124.702 45.34Z"/> + <path class="multicolor-1:tintColor hierarchical-1:primary SFSymbolsPreviewFFFFFF" d="M87.64-2.78C87.64-1.68 88.535-0.78 89.64-0.78C90.744-0.78 91.64-1.68 91.64-2.78L91.64-35.62L124.47-35.62C125.574-35.62 126.47-36.51 126.47-37.62C126.47-38.72 125.574-39.62 124.47-39.62L91.64-39.62L91.64-72.45C91.64-73.56 90.744-74.45 89.64-74.45C88.535-74.45 87.64-73.56 87.64-72.45L87.64-39.62L54.8-39.62C53.695-39.62 52.8-38.72 52.8-37.62C52.8-36.51 53.695-35.62 54.8-35.62L87.64-35.62L87.64-2.78Z"/> </g> <g id="Ultralight-L" transform="matrix(1 0 0 1 469.711 1556)"> - <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M124.702 47.94C113.846 52.65 102.264 55 89.956 55C77.649 55 66.067 52.65 55.21 47.94C44.354 43.3 34.775 36.82 26.473 28.51C18.229 20.21 11.756 10.62 7.054-0.24C2.351-11.1 0-22.69 0-35C0-47.31 2.351-58.9 7.054-69.76C11.756-80.62 18.229-90.18 26.473-98.43C34.775-106.73 44.325-113.24 55.123-117.94C65.98-122.65 77.562-125 89.869-125C102.235-125 113.846-122.65 124.702-117.94C135.559-113.24 145.138-106.73 153.44-98.43C161.742-90.18 168.244-80.62 172.946-69.76C177.649-58.9 180-47.31 180-35C180-22.69 177.649-11.1 172.946-0.24C168.244 10.62 161.742 20.21 153.44 28.51C145.138 36.82 135.559 43.3 124.702 47.94Z"/> - <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M88.875-7.46C88.875-6.84 89.379-6.33 90-6.33C90.621-6.33 91.125-6.84 91.125-7.46L91.125-34.17L117.83-34.17C118.451-34.17 118.955-34.68 118.955-35.3C118.955-35.92 118.451-36.42 117.83-36.42L91.125-36.42L91.125-63.13C91.125-63.75 90.621-64.25 90-64.25C89.379-64.25 88.875-63.75 88.875-63.13L88.875-36.42L62.16-36.42C61.539-36.42 61.035-35.92 61.035-35.3C61.035-34.68 61.539-34.17 62.16-34.17L88.875-34.17L88.875-7.46Z"/> + <path class="multicolor-0:tintColor hierarchical-0:secondary SFSymbolsPreview007AFF" d="M124.702 47.94C113.846 52.65 102.264 55 89.956 55C77.649 55 66.067 52.65 55.21 47.94C44.354 43.3 34.775 36.82 26.473 28.51C18.229 20.21 11.756 10.62 7.054-0.24C2.351-11.1 0-22.69 0-35C0-47.31 2.351-58.9 7.054-69.76C11.756-80.62 18.229-90.18 26.473-98.43C34.775-106.73 44.325-113.24 55.123-117.94C65.98-122.65 77.562-125 89.869-125C102.235-125 113.846-122.65 124.702-117.94C135.559-113.24 145.138-106.73 153.44-98.43C161.742-90.18 168.244-80.62 172.946-69.76C177.649-58.9 180-47.31 180-35C180-22.69 177.649-11.1 172.946-0.24C168.244 10.62 161.742 20.21 153.44 28.51C145.138 36.82 135.559 43.3 124.702 47.94Z"/> + <path class="multicolor-1:tintColor hierarchical-1:primary SFSymbolsPreviewFFFFFF" d="M88.875-0.46C88.875 0.16 89.379 0.67 90 0.67C90.621 0.67 91.125 0.16 91.125-0.46L91.125-34.17L124.83-34.17C125.451-34.17 125.955-34.68 125.955-35.3C125.955-35.92 125.451-36.42 124.83-36.42L91.125-36.42L91.125-70.13C91.125-70.75 90.621-71.25 90-71.25C89.379-71.25 88.875-70.75 88.875-70.13L88.875-36.42L55.16-36.42C54.539-36.42 54.035-35.92 54.035-35.3C54.035-34.68 54.539-34.17 55.16-34.17L88.875-34.17L88.875-0.46Z"/> </g> <g id="Black-M" transform="matrix(1 0 0 1 2858.4 1126)"> - <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M103.92 34.32C94.87 38.24 85.22 40.2 74.96 40.2C64.71 40.2 55.06 38.24 46.01 34.32C36.96 30.45 28.98 25.05 22.06 18.13C15.19 11.21 9.8 3.22 5.88-5.83C1.96-14.88 0-24.54 0-34.8C0-45.06 1.96-54.72 5.88-63.77C9.8-72.82 15.19-80.78 22.06-87.65C28.98-94.58 36.94-100 45.94-103.92C54.98-107.84 64.63-109.8 74.89-109.8C85.2-109.8 94.87-107.84 103.92-103.92C112.97-100 120.95-94.58 127.87-87.65C134.78-80.78 140.2-72.82 144.12-63.77C148.04-54.72 150-45.06 150-34.8C150-24.54 148.04-14.88 144.12-5.83C140.2 3.22 134.78 11.21 127.87 18.13C120.95 25.05 112.97 30.45 103.92 34.32Z"/> - <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M65.5-6.96C65.5-1.71 69.75 2.54 75 2.54C80.25 2.54 84.5-1.71 84.5-6.96L84.5-25.3L102.83-25.3C108.08-25.3 112.33-29.55 112.33-34.8C112.33-40.05 108.08-44.3 102.83-44.3L84.5-44.3L84.5-62.63C84.5-67.88 80.25-72.13 75-72.13C69.75-72.13 65.5-67.88 65.5-62.63L65.5-44.3L47.16-44.3C41.91-44.3 37.66-40.05 37.66-34.8C37.66-29.55 41.91-25.3 47.16-25.3L65.5-25.3L65.5-6.96Z"/> + <path class="multicolor-0:tintColor hierarchical-0:secondary SFSymbolsPreview007AFF" d="M103.92 34.32C94.87 38.24 85.22 40.2 74.96 40.2C64.71 40.2 55.06 38.24 46.01 34.32C36.96 30.45 28.98 25.05 22.06 18.13C15.19 11.21 9.8 3.22 5.88-5.83C1.96-14.88 0-24.54 0-34.8C0-45.06 1.96-54.72 5.88-63.77C9.8-72.82 15.19-80.78 22.06-87.65C28.98-94.58 36.94-100 45.94-103.92C54.98-107.84 64.63-109.8 74.89-109.8C85.2-109.8 94.87-107.84 103.92-103.92C112.97-100 120.95-94.58 127.87-87.65C134.78-80.78 140.2-72.82 144.12-63.77C148.04-54.72 150-45.06 150-34.8C150-24.54 148.04-14.88 144.12-5.83C140.2 3.22 134.78 11.21 127.87 18.13C120.95 25.05 112.97 30.45 103.92 34.32Z"/> + <path class="multicolor-1:tintColor hierarchical-1:primary SFSymbolsPreviewFFFFFF" d="M65.5-1.96C65.5 3.29 69.75 7.54 75 7.54C80.25 7.54 84.5 3.29 84.5-1.96L84.5-25.3L107.83-25.3C113.08-25.3 117.33-29.55 117.33-34.8C117.33-40.05 113.08-44.3 107.83-44.3L84.5-44.3L84.5-67.63C84.5-72.88 80.25-77.13 75-77.13C69.75-77.13 65.5-72.88 65.5-67.63L65.5-44.3L42.16-44.3C36.91-44.3 32.66-40.05 32.66-34.8C32.66-29.55 36.91-25.3 42.16-25.3L65.5-25.3L65.5-1.96Z"/> </g> <g id="Heavy-M" transform="matrix(1 0 0 1 2561.69 1126)"> - <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M103.92 34.32C94.87 38.24 85.22 40.2 74.96 40.2C64.71 40.2 55.06 38.24 46.01 34.32C36.96 30.45 28.98 25.05 22.06 18.13C15.19 11.21 9.8 3.22 5.88-5.83C1.96-14.88 0-24.54 0-34.8C0-45.06 1.96-54.72 5.88-63.77C9.8-72.82 15.19-80.78 22.06-87.65C28.98-94.58 36.94-100 45.94-103.92C54.98-107.84 64.63-109.8 74.89-109.8C85.2-109.8 94.87-107.84 103.92-103.92C112.97-100 120.95-94.58 127.87-87.65C134.78-80.78 140.2-72.82 144.12-63.77C148.04-54.72 150-45.06 150-34.8C150-24.54 148.04-14.88 144.12-5.83C140.2 3.22 134.78 11.21 127.87 18.13C120.95 25.05 112.97 30.45 103.92 34.32Z"/> - <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M66.5-6.96C66.5-2.27 70.31 1.54 75 1.54C79.69 1.54 83.5-2.27 83.5-6.96L83.5-26.3L102.83-26.3C107.52-26.3 111.33-30.1 111.33-34.8C111.33-39.49 107.52-43.3 102.83-43.3L83.5-43.3L83.5-62.63C83.5-67.33 79.69-71.13 75-71.13C70.31-71.13 66.5-67.33 66.5-62.63L66.5-43.3L47.16-43.3C42.47-43.3 38.66-39.49 38.66-34.8C38.66-30.1 42.47-26.3 47.16-26.3L66.5-26.3L66.5-6.96Z"/> + <path class="multicolor-0:tintColor hierarchical-0:secondary SFSymbolsPreview007AFF" d="M103.92 34.32C94.87 38.24 85.22 40.2 74.96 40.2C64.71 40.2 55.06 38.24 46.01 34.32C36.96 30.45 28.98 25.05 22.06 18.13C15.19 11.21 9.8 3.22 5.88-5.83C1.96-14.88 0-24.54 0-34.8C0-45.06 1.96-54.72 5.88-63.77C9.8-72.82 15.19-80.78 22.06-87.65C28.98-94.58 36.94-100 45.94-103.92C54.98-107.84 64.63-109.8 74.89-109.8C85.2-109.8 94.87-107.84 103.92-103.92C112.97-100 120.95-94.58 127.87-87.65C134.78-80.78 140.2-72.82 144.12-63.77C148.04-54.72 150-45.06 150-34.8C150-24.54 148.04-14.88 144.12-5.83C140.2 3.22 134.78 11.21 127.87 18.13C120.95 25.05 112.97 30.45 103.92 34.32Z"/> + <path class="multicolor-1:tintColor hierarchical-1:primary SFSymbolsPreviewFFFFFF" d="M66.5-1.96C66.5 2.73 70.31 6.54 75 6.54C79.69 6.54 83.5 2.73 83.5-1.96L83.5-26.3L107.83-26.3C112.52-26.3 116.33-30.1 116.33-34.8C116.33-39.49 112.52-43.3 107.83-43.3L83.5-43.3L83.5-67.63C83.5-72.33 79.69-76.13 75-76.13C70.31-76.13 66.5-72.33 66.5-67.63L66.5-43.3L42.16-43.3C37.47-43.3 33.66-39.49 33.66-34.8C33.66-30.1 37.47-26.3 42.16-26.3L66.5-26.3L66.5-1.96Z"/> </g> <g id="Bold-M" transform="matrix(1 0 0 1 2264.98 1126)"> - <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M103.92 34.32C94.87 38.24 85.22 40.2 74.96 40.2C64.71 40.2 55.06 38.24 46.01 34.32C36.96 30.45 28.98 25.05 22.06 18.13C15.19 11.21 9.8 3.22 5.88-5.83C1.96-14.88 0-24.54 0-34.8C0-45.06 1.96-54.72 5.88-63.77C9.8-72.82 15.19-80.78 22.06-87.65C28.98-94.58 36.94-100 45.94-103.92C54.98-107.84 64.63-109.8 74.89-109.8C85.2-109.8 94.87-107.84 103.92-103.92C112.97-100 120.95-94.58 127.87-87.65C134.78-80.78 140.2-72.82 144.12-63.77C148.04-54.72 150-45.06 150-34.8C150-24.54 148.04-14.88 144.12-5.83C140.2 3.22 134.78 11.21 127.87 18.13C120.95 25.05 112.97 30.45 103.92 34.32Z"/> - <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M68-6.96C68-3.09 71.13 0.04 75 0.04C78.87 0.04 82-3.09 82-6.96L82-27.8L102.83-27.8C106.7-27.8 109.83-30.93 109.83-34.8C109.83-38.66 106.7-41.8 102.83-41.8L82-41.8L82-62.63C82-66.5 78.87-69.63 75-69.63C71.13-69.63 68-66.5 68-62.63L68-41.8L47.16-41.8C43.29-41.8 40.16-38.66 40.16-34.8C40.16-30.93 43.29-27.8 47.16-27.8L68-27.8L68-6.96Z"/> + <path class="multicolor-0:tintColor hierarchical-0:secondary SFSymbolsPreview007AFF" d="M103.92 34.32C94.87 38.24 85.22 40.2 74.96 40.2C64.71 40.2 55.06 38.24 46.01 34.32C36.96 30.45 28.98 25.05 22.06 18.13C15.19 11.21 9.8 3.22 5.88-5.83C1.96-14.88 0-24.54 0-34.8C0-45.06 1.96-54.72 5.88-63.77C9.8-72.82 15.19-80.78 22.06-87.65C28.98-94.58 36.94-100 45.94-103.92C54.98-107.84 64.63-109.8 74.89-109.8C85.2-109.8 94.87-107.84 103.92-103.92C112.97-100 120.95-94.58 127.87-87.65C134.78-80.78 140.2-72.82 144.12-63.77C148.04-54.72 150-45.06 150-34.8C150-24.54 148.04-14.88 144.12-5.83C140.2 3.22 134.78 11.21 127.87 18.13C120.95 25.05 112.97 30.45 103.92 34.32Z"/> + <path class="multicolor-1:tintColor hierarchical-1:primary SFSymbolsPreviewFFFFFF" d="M68-1.96C68 1.91 71.13 5.04 75 5.04C78.87 5.04 82 1.91 82-1.96L82-27.8L107.83-27.8C111.7-27.8 114.83-30.93 114.83-34.8C114.83-38.66 111.7-41.8 107.83-41.8L82-41.8L82-67.63C82-71.5 78.87-74.63 75-74.63C71.13-74.63 68-71.5 68-67.63L68-41.8L42.16-41.8C38.29-41.8 35.16-38.66 35.16-34.8C35.16-30.93 38.29-27.8 42.16-27.8L68-27.8L68-1.96Z"/> </g> <g id="Semibold-M" transform="matrix(1 0 0 1 1968.27 1126)"> - <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M103.92 34.32C94.87 38.24 85.22 40.2 74.96 40.2C64.71 40.2 55.06 38.24 46.01 34.32C36.96 30.45 28.98 25.05 22.06 18.13C15.19 11.21 9.8 3.22 5.88-5.83C1.96-14.88 0-24.54 0-34.8C0-45.06 1.96-54.72 5.88-63.77C9.8-72.82 15.19-80.78 22.06-87.65C28.98-94.58 36.94-100 45.94-103.92C54.98-107.84 64.63-109.8 74.89-109.8C85.2-109.8 94.87-107.84 103.92-103.92C112.97-100 120.95-94.58 127.87-87.65C134.78-80.78 140.2-72.82 144.12-63.77C148.04-54.72 150-45.06 150-34.8C150-24.54 148.04-14.88 144.12-5.83C140.2 3.22 134.78 11.21 127.87 18.13C120.95 25.05 112.97 30.45 103.92 34.32Z"/> - <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M69-6.96C69-3.65 71.69-0.96 75-0.96C78.31-0.96 81-3.65 81-6.96L81-28.8L102.83-28.8C106.14-28.8 108.83-31.49 108.83-34.8C108.83-38.11 106.14-40.8 102.83-40.8L81-40.8L81-62.63C81-65.94 78.31-68.63 75-68.63C71.69-68.63 69-65.94 69-62.63L69-40.8L47.16-40.8C43.85-40.8 41.16-38.11 41.16-34.8C41.16-31.49 43.85-28.8 47.16-28.8L69-28.8L69-6.96Z"/> + <path class="multicolor-0:tintColor hierarchical-0:secondary SFSymbolsPreview007AFF" d="M103.92 34.32C94.87 38.24 85.22 40.2 74.96 40.2C64.71 40.2 55.06 38.24 46.01 34.32C36.96 30.45 28.98 25.05 22.06 18.13C15.19 11.21 9.8 3.22 5.88-5.83C1.96-14.88 0-24.54 0-34.8C0-45.06 1.96-54.72 5.88-63.77C9.8-72.82 15.19-80.78 22.06-87.65C28.98-94.58 36.94-100 45.94-103.92C54.98-107.84 64.63-109.8 74.89-109.8C85.2-109.8 94.87-107.84 103.92-103.92C112.97-100 120.95-94.58 127.87-87.65C134.78-80.78 140.2-72.82 144.12-63.77C148.04-54.72 150-45.06 150-34.8C150-24.54 148.04-14.88 144.12-5.83C140.2 3.22 134.78 11.21 127.87 18.13C120.95 25.05 112.97 30.45 103.92 34.32Z"/> + <path class="multicolor-1:tintColor hierarchical-1:primary SFSymbolsPreviewFFFFFF" d="M69-1.96C69 1.35 71.69 4.04 75 4.04C78.31 4.04 81 1.35 81-1.96L81-28.8L107.83-28.8C111.14-28.8 113.83-31.49 113.83-34.8C113.83-38.11 111.14-40.8 107.83-40.8L81-40.8L81-67.63C81-70.94 78.31-73.63 75-73.63C71.69-73.63 69-70.94 69-67.63L69-40.8L42.16-40.8C38.85-40.8 36.16-38.11 36.16-34.8C36.16-31.49 38.85-28.8 42.16-28.8L69-28.8L69-1.96Z"/> </g> <g id="Medium-M" transform="matrix(1 0 0 1 1671.56 1126)"> - <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M103.92 34.32C94.87 38.24 85.22 40.2 74.96 40.2C64.71 40.2 55.06 38.24 46.01 34.32C36.96 30.45 28.98 25.05 22.06 18.13C15.19 11.21 9.8 3.22 5.88-5.83C1.96-14.88 0-24.54 0-34.8C0-45.06 1.96-54.72 5.88-63.77C9.8-72.82 15.19-80.78 22.06-87.65C28.98-94.58 36.94-100 45.94-103.92C54.98-107.84 64.63-109.8 74.89-109.8C85.2-109.8 94.87-107.84 103.92-103.92C112.97-100 120.95-94.58 127.87-87.65C134.78-80.78 140.2-72.82 144.12-63.77C148.04-54.72 150-45.06 150-34.8C150-24.54 148.04-14.88 144.12-5.83C140.2 3.22 134.78 11.21 127.87 18.13C120.95 25.05 112.97 30.45 103.92 34.32Z"/> - <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M69.7-6.96C69.7-4.03 72.07-1.66 75-1.66C77.93-1.66 80.3-4.03 80.3-6.96L80.3-29.5L102.83-29.5C105.76-29.5 108.13-31.87 108.13-34.8C108.13-37.73 105.76-40.1 102.83-40.1L80.3-40.1L80.3-62.63C80.3-65.56 77.93-67.93 75-67.93C72.07-67.93 69.7-65.56 69.7-62.63L69.7-40.1L47.16-40.1C44.23-40.1 41.86-37.73 41.86-34.8C41.86-31.87 44.23-29.5 47.16-29.5L69.7-29.5L69.7-6.96Z"/> + <path class="multicolor-0:tintColor hierarchical-0:secondary SFSymbolsPreview007AFF" d="M103.92 34.32C94.87 38.24 85.22 40.2 74.96 40.2C64.71 40.2 55.06 38.24 46.01 34.32C36.96 30.45 28.98 25.05 22.06 18.13C15.19 11.21 9.8 3.22 5.88-5.83C1.96-14.88 0-24.54 0-34.8C0-45.06 1.96-54.72 5.88-63.77C9.8-72.82 15.19-80.78 22.06-87.65C28.98-94.58 36.94-100 45.94-103.92C54.98-107.84 64.63-109.8 74.89-109.8C85.2-109.8 94.87-107.84 103.92-103.92C112.97-100 120.95-94.58 127.87-87.65C134.78-80.78 140.2-72.82 144.12-63.77C148.04-54.72 150-45.06 150-34.8C150-24.54 148.04-14.88 144.12-5.83C140.2 3.22 134.78 11.21 127.87 18.13C120.95 25.05 112.97 30.45 103.92 34.32Z"/> + <path class="multicolor-1:tintColor hierarchical-1:primary SFSymbolsPreviewFFFFFF" d="M69.7-1.96C69.7 0.97 72.07 3.34 75 3.34C77.93 3.34 80.3 0.97 80.3-1.96L80.3-29.5L107.83-29.5C110.76-29.5 113.13-31.87 113.13-34.8C113.13-37.73 110.76-40.1 107.83-40.1L80.3-40.1L80.3-67.63C80.3-70.56 77.93-72.93 75-72.93C72.07-72.93 69.7-70.56 69.7-67.63L69.7-40.1L42.16-40.1C39.23-40.1 36.86-37.73 36.86-34.8C36.86-31.87 39.23-29.5 42.16-29.5L69.7-29.5L69.7-1.96Z"/> </g> <g id="Regular-M" transform="matrix(1 0 0 1 1374.84 1126)"> - <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M103.92 33.82C94.87 37.74 85.22 39.7 74.96 39.7C64.71 39.7 55.06 37.74 46.01 33.82C36.96 29.95 28.98 24.55 22.06 17.63C15.19 10.71 9.8 2.72 5.88-6.33C1.96-15.38 0-25.04 0-35.3C0-45.56 1.96-55.22 5.88-64.27C9.8-73.32 15.19-81.28 22.06-88.15C28.98-95.08 36.94-100.5 45.94-104.42C54.98-108.34 64.63-110.3 74.89-110.3C85.2-110.3 94.87-108.34 103.92-104.42C112.97-100.5 120.95-95.08 127.87-88.15C134.78-81.28 140.2-73.32 144.12-64.27C148.04-55.22 150-45.56 150-35.3C150-25.04 148.04-15.38 144.12-6.33C140.2 2.72 134.78 10.71 127.87 17.63C120.95 24.55 112.97 29.95 103.92 33.82Z"/> - <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M70.65-7.46C70.65-5.06 72.6-3.11 75-3.11C77.4-3.11 79.35-5.06 79.35-7.46L79.35-30.95L102.83-30.95C105.23-30.95 107.18-32.9 107.18-35.3C107.18-37.7 105.23-39.65 102.83-39.65L79.35-39.65L79.35-63.13C79.35-65.54 77.4-67.48 75-67.48C72.6-67.48 70.65-65.54 70.65-63.13L70.65-39.65L47.16-39.65C44.76-39.65 42.81-37.7 42.81-35.3C42.81-32.9 44.76-30.95 47.16-30.95L70.65-30.95L70.65-7.46Z"/> + <path class="multicolor-0:tintColor hierarchical-0:secondary SFSymbolsPreview007AFF" d="M103.92 33.82C94.87 37.74 85.22 39.7 74.96 39.7C64.71 39.7 55.06 37.74 46.01 33.82C36.96 29.95 28.98 24.55 22.06 17.63C15.19 10.71 9.8 2.72 5.88-6.33C1.96-15.38 0-25.04 0-35.3C0-45.56 1.96-55.22 5.88-64.27C9.8-73.32 15.19-81.28 22.06-88.15C28.98-95.08 36.94-100.5 45.94-104.42C54.98-108.34 64.63-110.3 74.89-110.3C85.2-110.3 94.87-108.34 103.92-104.42C112.97-100.5 120.95-95.08 127.87-88.15C134.78-81.28 140.2-73.32 144.12-64.27C148.04-55.22 150-45.56 150-35.3C150-25.04 148.04-15.38 144.12-6.33C140.2 2.72 134.78 10.71 127.87 17.63C120.95 24.55 112.97 29.95 103.92 33.82Z"/> + <path class="multicolor-1:tintColor hierarchical-1:primary SFSymbolsPreviewFFFFFF" d="M70.65-2.46C70.65-0.06 72.6 1.89 75 1.89C77.4 1.89 79.35-0.06 79.35-2.46L79.35-30.95L107.83-30.95C110.23-30.95 112.18-32.9 112.18-35.3C112.18-37.7 110.23-39.65 107.83-39.65L79.35-39.65L79.35-68.13C79.35-70.54 77.4-72.48 75-72.48C72.6-72.48 70.65-70.54 70.65-68.13L70.65-39.65L42.16-39.65C39.76-39.65 37.81-37.7 37.81-35.3C37.81-32.9 39.76-30.95 42.16-30.95L70.65-30.95L70.65-2.46Z"/> </g> <g id="Light-M" transform="matrix(1 0 0 1 1078.13 1126)"> - <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M103.92 34.32C94.87 38.24 85.22 40.2 74.96 40.2C64.71 40.2 55.06 38.24 46.01 34.32C36.96 30.45 28.98 25.05 22.06 18.13C15.19 11.21 9.8 3.22 5.88-5.83C1.96-14.88 0-24.54 0-34.8C0-45.06 1.96-54.72 5.88-63.77C9.8-72.82 15.19-80.78 22.06-87.65C28.98-94.58 36.94-100 45.94-103.92C54.98-107.84 64.63-109.8 74.89-109.8C85.2-109.8 94.87-107.84 103.92-103.92C112.97-100 120.95-94.58 127.87-87.65C134.78-80.78 140.2-72.82 144.12-63.77C148.04-54.72 150-45.06 150-34.8C150-24.54 148.04-14.88 144.12-5.83C140.2 3.22 134.78 11.21 127.87 18.13C120.95 25.05 112.97 30.45 103.92 34.32Z"/> - <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M71.7-6.96C71.7-5.14 73.18-3.66 75-3.66C76.82-3.66 78.3-5.14 78.3-6.96L78.3-31.5L102.83-31.5C104.65-31.5 106.13-32.98 106.13-34.8C106.13-36.62 104.65-38.1 102.83-38.1L78.3-38.1L78.3-62.63C78.3-64.46 76.82-65.93 75-65.93C73.18-65.93 71.7-64.46 71.7-62.63L71.7-38.1L47.16-38.1C45.34-38.1 43.86-36.62 43.86-34.8C43.86-32.98 45.34-31.5 47.16-31.5L71.7-31.5L71.7-6.96Z"/> + <path class="multicolor-0:tintColor hierarchical-0:secondary SFSymbolsPreview007AFF" d="M103.92 34.32C94.87 38.24 85.22 40.2 74.96 40.2C64.71 40.2 55.06 38.24 46.01 34.32C36.96 30.45 28.98 25.05 22.06 18.13C15.19 11.21 9.8 3.22 5.88-5.83C1.96-14.88 0-24.54 0-34.8C0-45.06 1.96-54.72 5.88-63.77C9.8-72.82 15.19-80.78 22.06-87.65C28.98-94.58 36.94-100 45.94-103.92C54.98-107.84 64.63-109.8 74.89-109.8C85.2-109.8 94.87-107.84 103.92-103.92C112.97-100 120.95-94.58 127.87-87.65C134.78-80.78 140.2-72.82 144.12-63.77C148.04-54.72 150-45.06 150-34.8C150-24.54 148.04-14.88 144.12-5.83C140.2 3.22 134.78 11.21 127.87 18.13C120.95 25.05 112.97 30.45 103.92 34.32Z"/> + <path class="multicolor-1:tintColor hierarchical-1:primary SFSymbolsPreviewFFFFFF" d="M71.7-1.96C71.7-0.14 73.18 1.34 75 1.34C76.82 1.34 78.3-0.14 78.3-1.96L78.3-31.5L107.83-31.5C109.65-31.5 111.13-32.98 111.13-34.8C111.13-36.62 109.65-38.1 107.83-38.1L78.3-38.1L78.3-67.63C78.3-69.46 76.82-70.93 75-70.93C73.18-70.93 71.7-69.46 71.7-67.63L71.7-38.1L42.16-38.1C40.34-38.1 38.86-36.62 38.86-34.8C38.86-32.98 40.34-31.5 42.16-31.5L71.7-31.5L71.7-1.96Z"/> </g> <g id="Thin-M" transform="matrix(1 0 0 1 781.422 1126)"> - <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M103.919 34.32C94.872 38.24 85.221 40.2 74.964 40.2C64.708 40.2 55.056 38.24 46.009 34.32C36.962 30.45 28.98 25.05 22.061 18.13C15.192 11.21 9.797 3.22 5.878-5.83C1.96-14.88 0-24.54 0-34.8C0-45.06 1.96-54.71 5.878-63.77C9.797-72.82 15.192-80.78 22.061-87.65C28.98-94.57 36.938-100 45.937-103.92C54.983-107.84 64.635-109.8 74.892-109.8C85.196-109.8 94.872-107.84 103.919-103.92C112.966-100 120.949-94.57 127.867-87.65C134.785-80.78 140.204-72.82 144.122-63.77C148.041-54.71 150-45.06 150-34.8C150-24.54 148.041-14.88 144.122-5.83C140.204 3.22 134.785 11.21 127.867 18.13C120.949 25.05 112.966 30.45 103.919 34.32Z"/> - <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M73.201-6.96C73.201-5.96 74.006-5.16 75.001-5.16C75.995-5.16 76.801-5.96 76.801-6.96L76.801-33L102.831-33C103.825-33 104.631-33.8 104.631-34.8C104.631-35.79 103.825-36.6 102.831-36.6L76.801-36.6L76.801-62.63C76.801-63.62 75.995-64.43 75.001-64.43C74.006-64.43 73.201-63.62 73.201-62.63L73.201-36.6L47.161-36.6C46.167-36.6 45.361-35.79 45.361-34.8C45.361-33.8 46.167-33 47.161-33L73.201-33L73.201-6.96Z"/> + <path class="multicolor-0:tintColor hierarchical-0:secondary SFSymbolsPreview007AFF" d="M103.919 34.32C94.872 38.24 85.221 40.2 74.964 40.2C64.708 40.2 55.056 38.24 46.009 34.32C36.962 30.45 28.98 25.05 22.061 18.13C15.192 11.21 9.797 3.22 5.878-5.83C1.96-14.88 0-24.54 0-34.8C0-45.06 1.96-54.71 5.878-63.77C9.797-72.82 15.192-80.78 22.061-87.65C28.98-94.57 36.938-100 45.937-103.92C54.983-107.84 64.635-109.8 74.892-109.8C85.196-109.8 94.872-107.84 103.919-103.92C112.966-100 120.949-94.57 127.867-87.65C134.785-80.78 140.204-72.82 144.122-63.77C148.041-54.71 150-45.06 150-34.8C150-24.54 148.041-14.88 144.122-5.83C140.204 3.22 134.785 11.21 127.867 18.13C120.949 25.05 112.966 30.45 103.919 34.32Z"/> + <path class="multicolor-1:tintColor hierarchical-1:primary SFSymbolsPreviewFFFFFF" d="M73.201-1.96C73.201-0.96 74.006-0.16 75.001-0.16C75.995-0.16 76.801-0.96 76.801-1.96L76.801-33L107.831-33C108.825-33 109.631-33.8 109.631-34.8C109.631-35.79 108.825-36.6 107.831-36.6L76.801-36.6L76.801-67.63C76.801-68.62 75.995-69.43 75.001-69.43C74.006-69.43 73.201-68.62 73.201-67.63L73.201-36.6L42.161-36.6C41.167-36.6 40.361-35.79 40.361-34.8C40.361-33.8 41.167-33 42.161-33L73.201-33L73.201-1.96Z"/> </g> <g id="Ultralight-M" transform="matrix(1 0 0 1 484.711 1126)"> - <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M103.919 34.32C94.872 38.24 85.22 40.2 74.964 40.2C64.707 40.2 55.056 38.24 46.009 34.32C36.962 30.45 28.979 25.05 22.061 18.13C15.191 11.21 9.797 3.22 5.878-5.83C1.959-14.88 0-24.54 0-34.8C0-45.06 1.959-54.72 5.878-63.77C9.797-72.82 15.191-80.78 22.061-87.65C28.979-94.58 36.938-100 45.936-103.92C54.983-107.84 64.635-109.8 74.891-109.8C85.196-109.8 94.872-107.84 103.919-103.92C112.966-100 120.948-94.58 127.866-87.65C134.785-80.78 140.203-72.82 144.122-63.77C148.041-54.72 150-45.06 150-34.8C150-24.54 148.041-14.88 144.122-5.83C140.203 3.22 134.785 11.21 127.866 18.13C120.948 25.05 112.966 30.45 103.919 34.32Z"/> - <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M73.875-6.96C73.875-6.34 74.379-5.83 75-5.83C75.621-5.83 76.125-6.34 76.125-6.96L76.125-33.67L102.83-33.67C103.451-33.67 103.955-34.18 103.955-34.8C103.955-35.42 103.451-35.92 102.83-35.92L76.125-35.92L76.125-62.63C76.125-63.25 75.621-63.75 75-63.75C74.379-63.75 73.875-63.25 73.875-62.63L73.875-35.92L47.16-35.92C46.539-35.92 46.035-35.42 46.035-34.8C46.035-34.18 46.539-33.67 47.16-33.67L73.875-33.67L73.875-6.96Z"/> + <path class="multicolor-0:tintColor hierarchical-0:secondary SFSymbolsPreview007AFF" d="M103.919 34.32C94.872 38.24 85.22 40.2 74.964 40.2C64.707 40.2 55.056 38.24 46.009 34.32C36.962 30.45 28.979 25.05 22.061 18.13C15.191 11.21 9.797 3.22 5.878-5.83C1.959-14.88 0-24.54 0-34.8C0-45.06 1.959-54.72 5.878-63.77C9.797-72.82 15.191-80.78 22.061-87.65C28.979-94.58 36.938-100 45.936-103.92C54.983-107.84 64.635-109.8 74.891-109.8C85.196-109.8 94.872-107.84 103.919-103.92C112.966-100 120.948-94.58 127.866-87.65C134.785-80.78 140.203-72.82 144.122-63.77C148.041-54.72 150-45.06 150-34.8C150-24.54 148.041-14.88 144.122-5.83C140.203 3.22 134.785 11.21 127.866 18.13C120.948 25.05 112.966 30.45 103.919 34.32Z"/> + <path class="multicolor-1:tintColor hierarchical-1:primary SFSymbolsPreviewFFFFFF" d="M73.875-1.96C73.875-1.34 74.379-0.83 75-0.83C75.621-0.83 76.125-1.34 76.125-1.96L76.125-33.67L107.83-33.67C108.451-33.67 108.955-34.18 108.955-34.8C108.955-35.42 108.451-35.92 107.83-35.92L76.125-35.92L76.125-67.63C76.125-68.25 75.621-68.75 75-68.75C74.379-68.75 73.875-68.25 73.875-67.63L73.875-35.92L42.16-35.92C41.539-35.92 41.035-35.42 41.035-34.8C41.035-34.18 41.539-33.67 42.16-33.67L73.875-33.67L73.875-1.96Z"/> </g> <g id="Black-S" transform="matrix(1 0 0 1 2879.4 696)"> - <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M74.82 13.967C68.31 16.79 61.36 18.201 53.97 18.201C46.59 18.201 39.64 16.79 33.13 13.967C26.61 11.179 20.87 7.293 15.88 2.31C10.94-2.674 7.05-8.424 4.23-14.941C1.41-21.458 0-28.411 0-35.799C0-43.187 1.41-50.14 4.23-56.657C7.05-63.173 10.94-68.906 15.88-73.855C20.87-78.839 26.6-82.742 33.07-85.565C39.59-88.387 46.54-89.799 53.92-89.799C61.34-89.799 68.31-88.387 74.82-85.565C81.34-82.742 87.08-78.839 92.06-73.855C97.05-68.906 100.95-63.173 103.77-56.657C106.59-50.14 108-43.187 108-35.799C108-28.411 106.59-21.458 103.77-14.941C100.95-8.424 97.05-2.674 92.06 2.31C87.08 7.293 81.34 11.179 74.82 13.967Z"/> - <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M44.84-7.83C44.84-2.583 49.09 1.67 54.34 1.67C59.59 1.67 63.84-2.583 63.84-7.83L63.84-26.168L82.17-26.168C87.42-26.168 91.67-30.421 91.67-35.668C91.67-40.915 87.42-45.168 82.17-45.168L63.84-45.168L63.84-63.5C63.84-68.747 59.59-73 54.34-73C49.09-73 44.84-68.747 44.84-63.5L44.84-45.168L26.5-45.168C21.25-45.168 17-40.915 17-35.668C17-30.421 21.25-26.168 26.5-26.168L44.84-26.168L44.84-7.83Z"/> + <path class="multicolor-0:tintColor hierarchical-0:secondary SFSymbolsPreview007AFF" d="M74.82 13.967C68.31 16.79 61.36 18.201 53.97 18.201C46.59 18.201 39.64 16.79 33.13 13.967C26.61 11.179 20.87 7.293 15.88 2.31C10.94-2.674 7.05-8.424 4.23-14.941C1.41-21.458 0-28.411 0-35.799C0-43.187 1.41-50.14 4.23-56.657C7.05-63.173 10.94-68.906 15.88-73.855C20.87-78.839 26.6-82.742 33.07-85.565C39.59-88.387 46.54-89.799 53.92-89.799C61.34-89.799 68.31-88.387 74.82-85.565C81.34-82.742 87.08-78.839 92.06-73.855C97.05-68.906 100.95-63.173 103.77-56.657C106.59-50.14 108-43.187 108-35.799C108-28.411 106.59-21.458 103.77-14.941C100.95-8.424 97.05-2.674 92.06 2.31C87.08 7.293 81.34 11.179 74.82 13.967Z"/> + <path class="multicolor-1:tintColor hierarchical-1:primary SFSymbolsPreviewFFFFFF" d="M44.84-7.83C44.84-2.583 49.09 1.67 54.34 1.67C59.59 1.67 63.84-2.583 63.84-7.83L63.84-26.168L82.17-26.168C87.42-26.168 91.67-30.421 91.67-35.668C91.67-40.915 87.42-45.168 82.17-45.168L63.84-45.168L63.84-63.5C63.84-68.747 59.59-73 54.34-73C49.09-73 44.84-68.747 44.84-63.5L44.84-45.168L26.5-45.168C21.25-45.168 17-40.915 17-35.668C17-30.421 21.25-26.168 26.5-26.168L44.84-26.168L44.84-7.83Z"/> </g> <g id="Heavy-S" transform="matrix(1 0 0 1 2582.69 696)"> - <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M74.82 13.967C68.31 16.79 61.36 18.201 53.97 18.201C46.59 18.201 39.64 16.79 33.13 13.967C26.61 11.179 20.87 7.293 15.88 2.31C10.94-2.674 7.05-8.424 4.23-14.941C1.41-21.458 0-28.411 0-35.799C0-43.187 1.41-50.14 4.23-56.657C7.05-63.173 10.94-68.906 15.88-73.855C20.87-78.839 26.6-82.742 33.07-85.565C39.59-88.387 46.54-89.799 53.92-89.799C61.34-89.799 68.31-88.387 74.82-85.565C81.34-82.742 87.08-78.839 92.06-73.855C97.05-68.906 100.95-63.173 103.77-56.657C106.59-50.14 108-43.187 108-35.799C108-28.411 106.59-21.458 103.77-14.941C100.95-8.424 97.05-2.674 92.06 2.31C87.08 7.293 81.34 11.179 74.82 13.967Z"/> - <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M45.34-8.33C45.34-3.636 49.15 0.17 53.84 0.17C58.53 0.17 62.34-3.636 62.34-8.33L62.34-27.668L81.67-27.668C86.36-27.668 90.17-31.473 90.17-36.168C90.17-40.862 86.36-44.668 81.67-44.668L62.34-44.668L62.34-64C62.34-68.694 58.53-72.5 53.84-72.5C49.15-72.5 45.34-68.694 45.34-64L45.34-44.668L26-44.668C21.31-44.668 17.5-40.862 17.5-36.168C17.5-31.473 21.31-27.668 26-27.668L45.34-27.668L45.34-8.33Z"/> + <path class="multicolor-0:tintColor hierarchical-0:secondary SFSymbolsPreview007AFF" d="M74.82 13.967C68.31 16.79 61.36 18.201 53.97 18.201C46.59 18.201 39.64 16.79 33.13 13.967C26.61 11.179 20.87 7.293 15.88 2.31C10.94-2.674 7.05-8.424 4.23-14.941C1.41-21.458 0-28.411 0-35.799C0-43.187 1.41-50.14 4.23-56.657C7.05-63.173 10.94-68.906 15.88-73.855C20.87-78.839 26.6-82.742 33.07-85.565C39.59-88.387 46.54-89.799 53.92-89.799C61.34-89.799 68.31-88.387 74.82-85.565C81.34-82.742 87.08-78.839 92.06-73.855C97.05-68.906 100.95-63.173 103.77-56.657C106.59-50.14 108-43.187 108-35.799C108-28.411 106.59-21.458 103.77-14.941C100.95-8.424 97.05-2.674 92.06 2.31C87.08 7.293 81.34 11.179 74.82 13.967Z"/> + <path class="multicolor-1:tintColor hierarchical-1:primary SFSymbolsPreviewFFFFFF" d="M45.34-8.33C45.34-3.636 49.15 0.17 53.84 0.17C58.53 0.17 62.34-3.636 62.34-8.33L62.34-27.668L81.67-27.668C86.36-27.668 90.17-31.473 90.17-36.168C90.17-40.862 86.36-44.668 81.67-44.668L62.34-44.668L62.34-64C62.34-68.694 58.53-72.5 53.84-72.5C49.15-72.5 45.34-68.694 45.34-64L45.34-44.668L26-44.668C21.31-44.668 17.5-40.862 17.5-36.168C17.5-31.473 21.31-27.668 26-27.668L45.34-27.668L45.34-8.33Z"/> </g> <g id="Bold-S" transform="matrix(1 0 0 1 2285.98 696)"> - <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M74.82 13.967C68.31 16.79 61.36 18.201 53.97 18.201C46.59 18.201 39.64 16.79 33.13 13.967C26.61 11.179 20.87 7.293 15.88 2.31C10.94-2.674 7.05-8.424 4.23-14.941C1.41-21.458 0-28.411 0-35.799C0-43.187 1.41-50.14 4.23-56.657C7.05-63.173 10.94-68.906 15.88-73.855C20.87-78.839 26.6-82.742 33.07-85.565C39.59-88.387 46.54-89.799 53.92-89.799C61.34-89.799 68.31-88.387 74.82-85.565C81.34-82.742 87.08-78.839 92.06-73.855C97.05-68.906 100.95-63.173 103.77-56.657C106.59-50.14 108-43.187 108-35.799C108-28.411 106.59-21.458 103.77-14.941C100.95-8.424 97.05-2.674 92.06 2.31C87.08 7.293 81.34 11.179 74.82 13.967Z"/> - <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M46.84-8.33C46.84-4.464 49.97-1.33 53.84-1.33C57.71-1.33 60.84-4.464 60.84-8.33L60.84-29.168L81.67-29.168C85.54-29.168 88.67-32.302 88.67-36.168C88.67-40.034 85.54-43.168 81.67-43.168L60.84-43.168L60.84-64C60.84-67.866 57.71-71 53.84-71C49.97-71 46.84-67.866 46.84-64L46.84-43.168L26-43.168C22.13-43.168 19-40.034 19-36.168C19-32.302 22.13-29.168 26-29.168L46.84-29.168L46.84-8.33Z"/> + <path class="multicolor-0:tintColor hierarchical-0:secondary SFSymbolsPreview007AFF" d="M74.82 13.967C68.31 16.79 61.36 18.201 53.97 18.201C46.59 18.201 39.64 16.79 33.13 13.967C26.61 11.179 20.87 7.293 15.88 2.31C10.94-2.674 7.05-8.424 4.23-14.941C1.41-21.458 0-28.411 0-35.799C0-43.187 1.41-50.14 4.23-56.657C7.05-63.173 10.94-68.906 15.88-73.855C20.87-78.839 26.6-82.742 33.07-85.565C39.59-88.387 46.54-89.799 53.92-89.799C61.34-89.799 68.31-88.387 74.82-85.565C81.34-82.742 87.08-78.839 92.06-73.855C97.05-68.906 100.95-63.173 103.77-56.657C106.59-50.14 108-43.187 108-35.799C108-28.411 106.59-21.458 103.77-14.941C100.95-8.424 97.05-2.674 92.06 2.31C87.08 7.293 81.34 11.179 74.82 13.967Z"/> + <path class="multicolor-1:tintColor hierarchical-1:primary SFSymbolsPreviewFFFFFF" d="M46.84-8.33C46.84-4.464 49.97-1.33 53.84-1.33C57.71-1.33 60.84-4.464 60.84-8.33L60.84-29.168L81.67-29.168C85.54-29.168 88.67-32.302 88.67-36.168C88.67-40.034 85.54-43.168 81.67-43.168L60.84-43.168L60.84-64C60.84-67.866 57.71-71 53.84-71C49.97-71 46.84-67.866 46.84-64L46.84-43.168L26-43.168C22.13-43.168 19-40.034 19-36.168C19-32.302 22.13-29.168 26-29.168L46.84-29.168L46.84-8.33Z"/> </g> <g id="Semibold-S" transform="matrix(1 0 0 1 1989.27 696)"> - <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M74.82 13.967C68.31 16.79 61.36 18.201 53.97 18.201C46.59 18.201 39.64 16.79 33.13 13.967C26.61 11.179 20.87 7.293 15.88 2.31C10.94-2.674 7.05-8.424 4.23-14.941C1.41-21.458 0-28.411 0-35.799C0-43.187 1.41-50.14 4.23-56.657C7.05-63.173 10.94-68.906 15.88-73.855C20.87-78.839 26.6-82.742 33.07-85.565C39.59-88.387 46.54-89.799 53.92-89.799C61.34-89.799 68.31-88.387 74.82-85.565C81.34-82.742 87.08-78.839 92.06-73.855C97.05-68.906 100.95-63.173 103.77-56.657C106.59-50.14 108-43.187 108-35.799C108-28.411 106.59-21.458 103.77-14.941C100.95-8.424 97.05-2.674 92.06 2.31C87.08 7.293 81.34 11.179 74.82 13.967Z"/> - <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M47.84-8.33C47.84-5.016 50.53-2.33 53.84-2.33C57.15-2.33 59.84-5.016 59.84-8.33L59.84-30.168L81.67-30.168C84.98-30.168 87.67-32.854 87.67-36.168C87.67-39.482 84.98-42.168 81.67-42.168L59.84-42.168L59.84-64C59.84-67.314 57.15-70 53.84-70C50.53-70 47.84-67.314 47.84-64L47.84-42.168L26-42.168C22.69-42.168 20-39.482 20-36.168C20-32.854 22.69-30.168 26-30.168L47.84-30.168L47.84-8.33Z"/> + <path class="multicolor-0:tintColor hierarchical-0:secondary SFSymbolsPreview007AFF" d="M74.82 13.967C68.31 16.79 61.36 18.201 53.97 18.201C46.59 18.201 39.64 16.79 33.13 13.967C26.61 11.179 20.87 7.293 15.88 2.31C10.94-2.674 7.05-8.424 4.23-14.941C1.41-21.458 0-28.411 0-35.799C0-43.187 1.41-50.14 4.23-56.657C7.05-63.173 10.94-68.906 15.88-73.855C20.87-78.839 26.6-82.742 33.07-85.565C39.59-88.387 46.54-89.799 53.92-89.799C61.34-89.799 68.31-88.387 74.82-85.565C81.34-82.742 87.08-78.839 92.06-73.855C97.05-68.906 100.95-63.173 103.77-56.657C106.59-50.14 108-43.187 108-35.799C108-28.411 106.59-21.458 103.77-14.941C100.95-8.424 97.05-2.674 92.06 2.31C87.08 7.293 81.34 11.179 74.82 13.967Z"/> + <path class="multicolor-1:tintColor hierarchical-1:primary SFSymbolsPreviewFFFFFF" d="M47.84-8.33C47.84-5.016 50.53-2.33 53.84-2.33C57.15-2.33 59.84-5.016 59.84-8.33L59.84-30.168L81.67-30.168C84.98-30.168 87.67-32.854 87.67-36.168C87.67-39.482 84.98-42.168 81.67-42.168L59.84-42.168L59.84-64C59.84-67.314 57.15-70 53.84-70C50.53-70 47.84-67.314 47.84-64L47.84-42.168L26-42.168C22.69-42.168 20-39.482 20-36.168C20-32.854 22.69-30.168 26-30.168L47.84-30.168L47.84-8.33Z"/> </g> <g id="Medium-S" transform="matrix(1 0 0 1 1692.56 696)"> - <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M74.82 13.967C68.31 16.79 61.36 18.201 53.97 18.201C46.59 18.201 39.64 16.79 33.13 13.967C26.61 11.179 20.87 7.293 15.88 2.31C10.94-2.674 7.05-8.424 4.23-14.941C1.41-21.458 0-28.411 0-35.799C0-43.187 1.41-50.14 4.23-56.657C7.05-63.173 10.94-68.906 15.88-73.855C20.87-78.839 26.6-82.742 33.07-85.565C39.59-88.387 46.54-89.799 53.92-89.799C61.34-89.799 68.31-88.387 74.82-85.565C81.34-82.742 87.08-78.839 92.06-73.855C97.05-68.906 100.95-63.173 103.77-56.657C106.59-50.14 108-43.187 108-35.799C108-28.411 106.59-21.458 103.77-14.941C100.95-8.424 97.05-2.674 92.06 2.31C87.08 7.293 81.34 11.179 74.82 13.967Z"/> - <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M48.84-8.03C48.84-5.103 51.21-2.73 54.14-2.73C57.07-2.73 59.44-5.103 59.44-8.03L59.44-30.568L81.97-30.568C84.9-30.568 87.27-32.941 87.27-35.868C87.27-38.795 84.9-41.168 81.97-41.168L59.44-41.168L59.44-63.7C59.44-66.627 57.07-69 54.14-69C51.21-69 48.84-66.627 48.84-63.7L48.84-41.168L26.3-41.168C23.37-41.168 21-38.795 21-35.868C21-32.941 23.37-30.568 26.3-30.568L48.84-30.568L48.84-8.03Z"/> + <path class="multicolor-0:tintColor hierarchical-0:secondary SFSymbolsPreview007AFF" d="M74.82 13.967C68.31 16.79 61.36 18.201 53.97 18.201C46.59 18.201 39.64 16.79 33.13 13.967C26.61 11.179 20.87 7.293 15.88 2.31C10.94-2.674 7.05-8.424 4.23-14.941C1.41-21.458 0-28.411 0-35.799C0-43.187 1.41-50.14 4.23-56.657C7.05-63.173 10.94-68.906 15.88-73.855C20.87-78.839 26.6-82.742 33.07-85.565C39.59-88.387 46.54-89.799 53.92-89.799C61.34-89.799 68.31-88.387 74.82-85.565C81.34-82.742 87.08-78.839 92.06-73.855C97.05-68.906 100.95-63.173 103.77-56.657C106.59-50.14 108-43.187 108-35.799C108-28.411 106.59-21.458 103.77-14.941C100.95-8.424 97.05-2.674 92.06 2.31C87.08 7.293 81.34 11.179 74.82 13.967Z"/> + <path class="multicolor-1:tintColor hierarchical-1:primary SFSymbolsPreviewFFFFFF" d="M48.84-8.03C48.84-5.103 51.21-2.73 54.14-2.73C57.07-2.73 59.44-5.103 59.44-8.03L59.44-30.568L81.97-30.568C84.9-30.568 87.27-32.941 87.27-35.868C87.27-38.795 84.9-41.168 81.97-41.168L59.44-41.168L59.44-63.7C59.44-66.627 57.07-69 54.14-69C51.21-69 48.84-66.627 48.84-63.7L48.84-41.168L26.3-41.168C23.37-41.168 21-38.795 21-35.868C21-32.941 23.37-30.568 26.3-30.568L48.84-30.568L48.84-8.03Z"/> </g> <g id="Regular-S" transform="matrix(1 0 0 1 1395.84 696)"> - <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M74.82 13.965C68.31 16.788 61.36 18.199 53.97 18.199C46.59 18.199 39.64 16.788 33.13 13.965C26.61 11.177 20.87 7.291 15.88 2.308C10.94-2.676 7.05-8.426 4.23-14.943C1.41-21.46 0-28.413 0-35.801C0-43.189 1.41-50.142 4.23-56.658C7.05-63.175 10.94-68.908 15.88-73.857C20.87-78.84 26.6-82.744 33.07-85.567C39.59-88.389 46.54-89.801 53.92-89.801C61.34-89.801 68.31-88.389 74.82-85.567C81.34-82.744 87.08-78.84 92.06-73.857C97.04-68.908 100.95-63.175 103.77-56.658C106.59-50.142 108-43.189 108-35.801C108-28.413 106.59-21.46 103.77-14.943C100.95-8.426 97.04-2.676 92.06 2.308C87.08 7.291 81.34 11.177 74.82 13.965Z"/> - <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M49.84-7.98C49.84-5.578 51.79-3.63 54.19-3.63C56.59-3.63 58.54-5.578 58.54-7.98L58.54-31.468L82.02-31.468C84.42-31.468 86.37-33.415 86.37-35.818C86.37-38.22 84.42-40.168 82.02-40.168L58.54-40.168L58.54-63.65C58.54-66.052 56.59-68 54.19-68C51.79-68 49.84-66.052 49.84-63.65L49.84-40.168L26.35-40.168C23.95-40.168 22-38.22 22-35.818C22-33.415 23.95-31.468 26.35-31.468L49.84-31.468L49.84-7.98Z"/> + <path class="multicolor-0:tintColor hierarchical-0:secondary SFSymbolsPreview007AFF" d="M74.82 13.965C68.31 16.788 61.36 18.199 53.97 18.199C46.59 18.199 39.64 16.788 33.13 13.965C26.61 11.177 20.87 7.291 15.88 2.308C10.94-2.676 7.05-8.426 4.23-14.943C1.41-21.46 0-28.413 0-35.801C0-43.189 1.41-50.142 4.23-56.658C7.05-63.175 10.94-68.908 15.88-73.857C20.87-78.84 26.6-82.744 33.07-85.567C39.59-88.389 46.54-89.801 53.92-89.801C61.34-89.801 68.31-88.389 74.82-85.567C81.34-82.744 87.08-78.84 92.06-73.857C97.04-68.908 100.95-63.175 103.77-56.658C106.59-50.142 108-43.189 108-35.801C108-28.413 106.59-21.46 103.77-14.943C100.95-8.426 97.04-2.676 92.06 2.308C87.08 7.291 81.34 11.177 74.82 13.965Z"/> + <path class="multicolor-1:tintColor hierarchical-1:primary SFSymbolsPreviewFFFFFF" d="M49.84-7.98C49.84-5.578 51.79-3.63 54.19-3.63C56.59-3.63 58.54-5.578 58.54-7.98L58.54-31.468L82.02-31.468C84.42-31.468 86.37-33.415 86.37-35.818C86.37-38.22 84.42-40.168 82.02-40.168L58.54-40.168L58.54-63.65C58.54-66.052 56.59-68 54.19-68C51.79-68 49.84-66.052 49.84-63.65L49.84-40.168L26.35-40.168C23.95-40.168 22-38.22 22-35.818C22-33.415 23.95-31.468 26.35-31.468L49.84-31.468L49.84-7.98Z"/> </g> <g id="Light-S" transform="matrix(1 0 0 1 1099.13 696)"> - <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M74.82 13.967C68.31 16.79 61.36 18.201 53.97 18.201C46.59 18.201 39.64 16.79 33.13 13.967C26.61 11.179 20.87 7.293 15.88 2.31C10.94-2.674 7.05-8.424 4.23-14.941C1.41-21.458 0-28.411 0-35.799C0-43.187 1.41-50.14 4.23-56.657C7.05-63.173 10.94-68.906 15.88-73.855C20.87-78.839 26.6-82.742 33.07-85.565C39.59-88.387 46.54-89.799 53.92-89.799C61.34-89.799 68.31-88.387 74.82-85.565C81.34-82.742 87.08-78.839 92.06-73.855C97.05-68.906 100.95-63.173 103.77-56.657C106.59-50.14 108-43.187 108-35.799C108-28.411 106.59-21.458 103.77-14.941C100.95-8.424 97.05-2.674 92.06 2.31C87.08 7.293 81.34 11.179 74.82 13.967Z"/> - <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M50.84-8.03C50.84-6.207 52.32-4.73 54.14-4.73C55.96-4.73 57.44-6.207 57.44-8.03L57.44-32.568L81.97-32.568C83.79-32.568 85.27-34.045 85.27-35.868C85.27-37.69 83.79-39.168 81.97-39.168L57.44-39.168L57.44-63.7C57.44-65.523 55.96-67 54.14-67C52.32-67 50.84-65.523 50.84-63.7L50.84-39.168L26.3-39.168C24.48-39.168 23-37.69 23-35.868C23-34.045 24.48-32.568 26.3-32.568L50.84-32.568L50.84-8.03Z"/> + <path class="multicolor-0:tintColor hierarchical-0:secondary SFSymbolsPreview007AFF" d="M74.82 13.967C68.31 16.79 61.36 18.201 53.97 18.201C46.59 18.201 39.64 16.79 33.13 13.967C26.61 11.179 20.87 7.293 15.88 2.31C10.94-2.674 7.05-8.424 4.23-14.941C1.41-21.458 0-28.411 0-35.799C0-43.187 1.41-50.14 4.23-56.657C7.05-63.173 10.94-68.906 15.88-73.855C20.87-78.839 26.6-82.742 33.07-85.565C39.59-88.387 46.54-89.799 53.92-89.799C61.34-89.799 68.31-88.387 74.82-85.565C81.34-82.742 87.08-78.839 92.06-73.855C97.05-68.906 100.95-63.173 103.77-56.657C106.59-50.14 108-43.187 108-35.799C108-28.411 106.59-21.458 103.77-14.941C100.95-8.424 97.05-2.674 92.06 2.31C87.08 7.293 81.34 11.179 74.82 13.967Z"/> + <path class="multicolor-1:tintColor hierarchical-1:primary SFSymbolsPreviewFFFFFF" d="M50.84-8.03C50.84-6.207 52.32-4.73 54.14-4.73C55.96-4.73 57.44-6.207 57.44-8.03L57.44-32.568L81.97-32.568C83.79-32.568 85.27-34.045 85.27-35.868C85.27-37.69 83.79-39.168 81.97-39.168L57.44-39.168L57.44-63.7C57.44-65.523 55.96-67 54.14-67C52.32-67 50.84-65.523 50.84-63.7L50.84-39.168L26.3-39.168C24.48-39.168 23-37.69 23-35.868C23-34.045 24.48-32.568 26.3-32.568L50.84-32.568L50.84-8.03Z"/> </g> <g id="Thin-S" transform="matrix(1 0 0 1 802.422 696)"> - <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M74.821 13.967C68.308 16.79 61.358 18.201 53.974 18.201C46.589 18.201 39.64 16.79 33.126 13.967C26.612 11.179 20.865 7.293 15.884 2.31C10.938-2.674 7.054-8.424 4.232-14.941C1.411-21.458 0-28.411 0-35.799C0-43.187 1.411-50.14 4.232-56.657C7.054-63.173 10.938-68.906 15.884-73.855C20.865-78.839 26.595-82.742 33.074-85.565C39.588-88.387 46.537-89.799 53.922-89.799C61.341-89.799 68.308-88.387 74.821-85.565C81.335-82.742 87.083-78.839 92.064-73.855C97.045-68.906 100.946-63.173 103.768-56.657C106.589-50.14 108-43.187 108-35.799C108-28.411 106.589-21.458 103.768-14.941C100.946-8.424 97.045-2.674 92.064 2.31C87.083 7.293 81.335 11.179 74.821 13.967Z"/> - <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M52.04-8.331C52.04-7.337 52.846-6.531 53.84-6.531C54.834-6.531 55.64-7.337 55.64-8.331L55.64-34.369L81.67-34.369C82.664-34.369 83.47-35.175 83.47-36.169C83.47-37.163 82.664-37.969 81.67-37.969L55.64-37.969L55.64-64.001C55.64-64.995 54.834-65.801 53.84-65.801C52.846-65.801 52.04-64.995 52.04-64.001L52.04-37.969L26-37.969C25.006-37.969 24.2-37.163 24.2-36.169C24.2-35.175 25.006-34.369 26-34.369L52.04-34.369L52.04-8.331Z"/> + <path class="multicolor-0:tintColor hierarchical-0:secondary SFSymbolsPreview007AFF" d="M74.821 13.967C68.308 16.79 61.358 18.201 53.974 18.201C46.589 18.201 39.64 16.79 33.126 13.967C26.612 11.179 20.865 7.293 15.884 2.31C10.938-2.674 7.054-8.424 4.232-14.941C1.411-21.458 0-28.411 0-35.799C0-43.187 1.411-50.14 4.232-56.657C7.054-63.173 10.938-68.906 15.884-73.855C20.865-78.839 26.595-82.742 33.074-85.565C39.588-88.387 46.537-89.799 53.922-89.799C61.341-89.799 68.308-88.387 74.821-85.565C81.335-82.742 87.083-78.839 92.064-73.855C97.045-68.906 100.946-63.173 103.768-56.657C106.589-50.14 108-43.187 108-35.799C108-28.411 106.589-21.458 103.768-14.941C100.946-8.424 97.045-2.674 92.064 2.31C87.083 7.293 81.335 11.179 74.821 13.967Z"/> + <path class="multicolor-1:tintColor hierarchical-1:primary SFSymbolsPreviewFFFFFF" d="M52.04-8.331C52.04-7.337 52.846-6.531 53.84-6.531C54.834-6.531 55.64-7.337 55.64-8.331L55.64-34.369L81.67-34.369C82.664-34.369 83.47-35.175 83.47-36.169C83.47-37.163 82.664-37.969 81.67-37.969L55.64-37.969L55.64-64.001C55.64-64.995 54.834-65.801 53.84-65.801C52.846-65.801 52.04-64.995 52.04-64.001L52.04-37.969L26-37.969C25.006-37.969 24.2-37.163 24.2-36.169C24.2-35.175 25.006-34.369 26-34.369L52.04-34.369L52.04-8.331Z"/> </g> <g id="Ultralight-S" transform="matrix(1 0 0 1 505.711 696)"> - <path class="hierarchical-0:secondary SFSymbolsPreview4D4D4D" d="M74.821 13.967C68.308 16.79 61.358 18.201 53.974 18.201C46.589 18.201 39.64 16.79 33.126 13.967C26.612 11.179 20.865 7.293 15.884 2.31C10.938-2.674 7.054-8.424 4.232-14.941C1.411-21.458 0-28.411 0-35.799C0-43.187 1.411-50.14 4.232-56.657C7.054-63.173 10.938-68.906 15.884-73.855C20.865-78.839 26.595-82.742 33.074-85.565C39.588-88.387 46.537-89.799 53.922-89.799C61.341-89.799 68.308-88.387 74.821-85.565C81.335-82.742 87.083-78.839 92.064-73.855C97.045-68.906 100.946-63.173 103.768-56.657C106.589-50.14 108-43.187 108-35.799C108-28.411 106.589-21.458 103.768-14.941C100.946-8.424 97.045-2.674 92.064 2.31C87.083 7.293 81.335 11.179 74.821 13.967Z"/> - <path class="hierarchical-1:primary SFSymbolsPreview212121" d="M52.84-8.205C52.84-7.584 53.344-7.08 53.965-7.08C54.586-7.08 55.09-7.584 55.09-8.205L55.09-34.918L81.795-34.918C82.416-34.918 82.92-35.422 82.92-36.043C82.92-36.664 82.416-37.168 81.795-37.168L55.09-37.168L55.09-63.875C55.09-64.496 54.586-65 53.965-65C53.344-65 52.84-64.496 52.84-63.875L52.84-37.168L26.125-37.168C25.504-37.168 25-36.664 25-36.043C25-35.422 25.504-34.918 26.125-34.918L52.84-34.918L52.84-8.205Z"/> + <path class="multicolor-0:tintColor hierarchical-0:secondary SFSymbolsPreview007AFF" d="M74.821 13.967C68.308 16.79 61.358 18.201 53.974 18.201C46.589 18.201 39.64 16.79 33.126 13.967C26.612 11.179 20.865 7.293 15.884 2.31C10.938-2.674 7.054-8.424 4.232-14.941C1.411-21.458 0-28.411 0-35.799C0-43.187 1.411-50.14 4.232-56.657C7.054-63.173 10.938-68.906 15.884-73.855C20.865-78.839 26.595-82.742 33.074-85.565C39.588-88.387 46.537-89.799 53.922-89.799C61.341-89.799 68.308-88.387 74.821-85.565C81.335-82.742 87.083-78.839 92.064-73.855C97.045-68.906 100.946-63.173 103.768-56.657C106.589-50.14 108-43.187 108-35.799C108-28.411 106.589-21.458 103.768-14.941C100.946-8.424 97.045-2.674 92.064 2.31C87.083 7.293 81.335 11.179 74.821 13.967Z"/> + <path class="multicolor-1:tintColor hierarchical-1:primary SFSymbolsPreviewFFFFFF" d="M52.84-8.205C52.84-7.584 53.344-7.08 53.965-7.08C54.586-7.08 55.09-7.584 55.09-8.205L55.09-34.918L81.795-34.918C82.416-34.918 82.92-35.422 82.92-36.043C82.92-36.664 82.416-37.168 81.795-37.168L55.09-37.168L55.09-63.875C55.09-64.496 54.586-65 53.965-65C53.344-65 52.84-64.496 52.84-63.875L52.84-37.168L26.125-37.168C25.504-37.168 25-36.664 25-36.043C25-35.422 25.504-34.918 26.125-34.918L52.84-34.918L52.84-8.205Z"/> </g> </g> </svg>
diff --git a/ios/chrome/browser/ui/icons/resources/tuner.symbolset/Contents.json b/ios/chrome/browser/ui/icons/resources/tuner.symbolset/Contents.json new file mode 100644 index 0000000..7e069bb --- /dev/null +++ b/ios/chrome/browser/ui/icons/resources/tuner.symbolset/Contents.json
@@ -0,0 +1,12 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "symbols" : [ + { + "filename" : "tuner.cr.svg", + "idiom" : "universal" + } + ] +}
diff --git a/ios/chrome/browser/ui/icons/resources/tuner.symbolset/tuner.cr.svg b/ios/chrome/browser/ui/icons/resources/tuner.symbolset/tuner.cr.svg new file mode 100644 index 0000000..d47d139 --- /dev/null +++ b/ios/chrome/browser/ui/icons/resources/tuner.symbolset/tuner.cr.svg
@@ -0,0 +1,161 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!--Generator: Apple Native CoreSVG 175.5--> +<!DOCTYPE svg +PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="3300" height="2200"> + <!--glyph: "", point size: 100.0, font version: "18.0d12e2", template writer version: "101"--> + <g id="Notes"> + <rect height="2200" id="artboard" style="fill:white;opacity:1" width="3300" x="0" y="0"/> + <line style="fill:none;stroke:black;opacity:1;stroke-width:0.5;" x1="263" x2="3036" y1="292" y2="292"/> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;font-weight:bold;" transform="matrix(1 0 0 1 263 322)">Weight/Scale Variations</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:middle;" transform="matrix(1 0 0 1 559.711 322)">Ultralight</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:middle;" transform="matrix(1 0 0 1 856.422 322)">Thin</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:middle;" transform="matrix(1 0 0 1 1153.13 322)">Light</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:middle;" transform="matrix(1 0 0 1 1449.84 322)">Regular</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:middle;" transform="matrix(1 0 0 1 1746.56 322)">Medium</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:middle;" transform="matrix(1 0 0 1 2043.27 322)">Semibold</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:middle;" transform="matrix(1 0 0 1 2339.98 322)">Bold</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:middle;" transform="matrix(1 0 0 1 2636.69 322)">Heavy</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:middle;" transform="matrix(1 0 0 1 2933.4 322)">Black</text> + <line style="fill:none;stroke:black;opacity:1;stroke-width:0.5;" x1="263" x2="3036" y1="1903" y2="1903"/> + <g transform="matrix(1 0 0 1 263 1933)"> + <path d="M9.24805 0.830078C13.5547 0.830078 17.1387-2.74414 17.1387-7.05078C17.1387-11.3574 13.5449-14.9316 9.23828-14.9316C4.94141-14.9316 1.36719-11.3574 1.36719-7.05078C1.36719-2.74414 4.95117 0.830078 9.24805 0.830078ZM9.24805-0.654297C5.70312-0.654297 2.87109-3.49609 2.87109-7.05078C2.87109-10.6055 5.69336-13.4473 9.23828-13.4473C12.793-13.4473 15.6445-10.6055 15.6445-7.05078C15.6445-3.49609 12.8027-0.654297 9.24805-0.654297ZM5.6543-7.05078C5.6543-6.62109 5.95703-6.32812 6.40625-6.32812L8.50586-6.32812L8.50586-4.20898C8.50586-3.76953 8.79883-3.4668 9.22852-3.4668C9.67773-3.4668 9.9707-3.76953 9.9707-4.20898L9.9707-6.32812L12.0898-6.32812C12.5293-6.32812 12.832-6.62109 12.832-7.05078C12.832-7.49023 12.5293-7.79297 12.0898-7.79297L9.9707-7.79297L9.9707-9.90234C9.9707-10.3516 9.67773-10.6543 9.22852-10.6543C8.79883-10.6543 8.50586-10.3516 8.50586-9.90234L8.50586-7.79297L6.40625-7.79297C5.95703-7.79297 5.6543-7.49023 5.6543-7.05078Z"/> + </g> + <g transform="matrix(1 0 0 1 281.867 1933)"> + <path d="M11.709 2.91016C17.1582 2.91016 21.6699-1.61133 21.6699-7.05078C21.6699-12.5 17.1484-17.0117 11.6992-17.0117C6.25977-17.0117 1.74805-12.5 1.74805-7.05078C1.74805-1.61133 6.26953 2.91016 11.709 2.91016ZM11.709 1.25C7.09961 1.25 3.41797-2.44141 3.41797-7.05078C3.41797-11.6602 7.08984-15.3516 11.6992-15.3516C16.3086-15.3516 20.0098-11.6602 20.0098-7.05078C20.0098-2.44141 16.3184 1.25 11.709 1.25ZM7.17773-7.05078C7.17773-6.57227 7.50977-6.25 8.00781-6.25L10.8789-6.25L10.8789-3.36914C10.8789-2.88086 11.2109-2.53906 11.6895-2.53906C12.1777-2.53906 12.5195-2.87109 12.5195-3.36914L12.5195-6.25L15.4004-6.25C15.8887-6.25 16.2305-6.57227 16.2305-7.05078C16.2305-7.53906 15.8887-7.88086 15.4004-7.88086L12.5195-7.88086L12.5195-10.752C12.5195-11.25 12.1777-11.5918 11.6895-11.5918C11.2109-11.5918 10.8789-11.25 10.8789-10.752L10.8789-7.88086L8.00781-7.88086C7.50977-7.88086 7.17773-7.53906 7.17773-7.05078Z"/> + </g> + <g transform="matrix(1 0 0 1 305.646 1933)"> + <path d="M14.9707 5.66406C21.9336 5.66406 27.6953-0.0976562 27.6953-7.05078C27.6953-14.0137 21.9238-19.7754 14.9609-19.7754C8.00781-19.7754 2.25586-14.0137 2.25586-7.05078C2.25586-0.0976562 8.01758 5.66406 14.9707 5.66406ZM14.9707 3.84766C8.93555 3.84766 4.08203-1.01562 4.08203-7.05078C4.08203-13.0957 8.92578-17.9492 14.9609-17.9492C21.0059-17.9492 25.8691-13.0957 25.8691-7.05078C25.8691-1.01562 21.0156 3.84766 14.9707 3.84766ZM9.19922-7.05078C9.19922-6.5332 9.57031-6.17188 10.1172-6.17188L14.0625-6.17188L14.0625-2.2168C14.0625-1.67969 14.4336-1.29883 14.9512-1.29883C15.4883-1.29883 15.8594-1.66992 15.8594-2.2168L15.8594-6.17188L19.8145-6.17188C20.3516-6.17188 20.7324-6.5332 20.7324-7.05078C20.7324-7.59766 20.3613-7.96875 19.8145-7.96875L15.8594-7.96875L15.8594-11.9141C15.8594-12.4609 15.4883-12.8418 14.9512-12.8418C14.4336-12.8418 14.0625-12.4609 14.0625-11.9141L14.0625-7.96875L10.1172-7.96875C9.57031-7.96875 9.19922-7.59766 9.19922-7.05078Z"/> + </g> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;font-weight:bold;" transform="matrix(1 0 0 1 263 1953)">Design Variations</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 263 1971)">Symbols are supported in up to nine weights and three scales.</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 263 1989)">For optimal layout with text and other symbols, vertically align</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 263 2007)">symbols with the adjacent text.</text> + <line style="fill:none;stroke:#00AEEF;stroke-width:0.5;opacity:1.0;" x1="776" x2="776" y1="1919" y2="1933"/> + <g transform="matrix(1 0 0 1 776 1933)"> + <path d="M3.31055 0.15625C3.82812 0.15625 4.08203-0.0390625 4.26758-0.585938L5.52734-4.0332L11.2891-4.0332L12.5488-0.585938C12.7344-0.0390625 12.9883 0.15625 13.4961 0.15625C14.0137 0.15625 14.3457-0.15625 14.3457-0.644531C14.3457-0.810547 14.3164-0.966797 14.2383-1.17188L9.6582-13.3691C9.43359-13.9648 9.0332-14.2676 8.4082-14.2676C7.80273-14.2676 7.39258-13.9746 7.17773-13.3789L2.59766-1.16211C2.51953-0.957031 2.49023-0.800781 2.49023-0.634766C2.49023-0.146484 2.80273 0.15625 3.31055 0.15625ZM6.00586-5.51758L8.37891-12.0898L8.42773-12.0898L10.8008-5.51758Z"/> + </g> + <line style="fill:none;stroke:#00AEEF;stroke-width:0.5;opacity:1.0;" x1="793.197" x2="793.197" y1="1919" y2="1933"/> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;font-weight:bold;" transform="matrix(1 0 0 1 776 1953)">Margins</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 776 1971)">Leading and trailing margins on the left and right side of each symbol</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 776 1989)">can be adjusted by modifying the x-location of the margin guidelines.</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 776 2007)">Modifications are automatically applied proportionally to all</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 776 2025)">scales and weights.</text> + <g transform="matrix(1 0 0 1 1289 1933)"> + <path d="M2.8418 1.86523L4.54102 3.57422C5.40039 4.44336 6.38672 4.38477 7.31445 3.35938L18.0078-8.42773L17.041-9.4043L6.42578 2.27539C6.07422 2.67578 5.74219 2.77344 5.27344 2.30469L4.10156 1.14258C3.63281 0.683594 3.74023 0.341797 4.14062-0.0195312L15.6152-10.8203L14.6387-11.7871L3.04688-0.898438C2.06055 0.0195312 1.98242 0.996094 2.8418 1.86523ZM9.25781-16.3281C8.83789-15.918 8.80859-15.3418 9.04297-14.9512C9.27734-14.5898 9.73633-14.3555 10.3809-14.5215C11.8457-14.8633 13.3691-14.9219 14.7949-13.9844L14.209-12.5293C13.8672-11.6992 14.043-11.1133 14.5801-10.5664L16.875-8.25195C17.3633-7.76367 17.7734-7.74414 18.3398-7.8418L19.4043-8.03711L20.0684-7.36328L20.0293-6.80664C19.9902-6.30859 20.1172-5.92773 20.6055-5.44922L21.3672-4.70703C21.8457-4.22852 22.4609-4.19922 22.9297-4.66797L25.8398-7.58789C26.3086-8.05664 26.2891-8.65234 25.8105-9.13086L25.0391-9.89258C24.5605-10.3711 24.1895-10.5273 23.7109-10.4883L23.1348-10.4395L22.4902-11.0742L22.7344-12.1973C22.8613-12.7637 22.7051-13.2031 22.1191-13.7891L19.9219-15.9766C16.582-19.2969 12.1484-19.2188 9.25781-16.3281ZM10.752-15.957C13.1836-17.7344 16.4746-17.4316 18.7012-15.2051L21.1328-12.793C21.3672-12.5586 21.4062-12.373 21.3379-12.0312L21.0156-10.5469L22.5195-9.0625L23.5059-9.12109C23.7598-9.13086 23.8379-9.11133 24.0332-8.91602L24.6094-8.33984L22.168-5.89844L21.5918-6.47461C21.3965-6.66992 21.3672-6.74805 21.377-7.01172L21.4453-7.98828L19.9512-9.47266L18.4277-9.21875C18.1055-9.15039 17.959-9.17969 17.7148-9.41406L15.7129-11.416C15.459-11.6504 15.4297-11.8164 15.5859-12.1875L16.4648-14.2773C14.9023-15.7324 12.8711-16.3574 10.8398-15.7617C10.6836-15.7227 10.625-15.8496 10.752-15.957Z"/> + </g> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;font-weight:bold;" transform="matrix(1 0 0 1 1289 1953)">Exporting</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 1289 1971)">Symbols should be outlined when exporting to ensure the</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 1289 1989)">design is preserved when submitting to Xcode.</text> + <text id="template-version" style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:end;" transform="matrix(1 0 0 1 3036 1933)">Template v.2.0</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:end;" transform="matrix(1 0 0 1 3036 1951)">Requires Xcode 12 or greater</text> + <text id="descriptive-name" style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:end;" transform="matrix(1 0 0 1 3036 1969)">Generated from tuner.cr</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;text-anchor:end;" transform="matrix(1 0 0 1 3036 1987)">Typeset at 100 points</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 263 726)">Small</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 263 1156)">Medium</text> + <text style="stroke:none;fill:black;font-family:sans-serif;font-size:13;" transform="matrix(1 0 0 1 263 1586)">Large</text> + </g> + <g id="Guides"> + <g id="H-reference" style="fill:#27AAE1;stroke:none;" transform="matrix(1 0 0 1 339 696)"> + <path d="M0.993654 0L3.63775 0L29.3281-67.1323L30.0303-67.1323L30.0303-70.459L28.1226-70.459ZM11.6885-24.4799L46.9815-24.4799L46.2315-26.7285L12.4385-26.7285ZM55.1196 0L57.7637 0L30.6382-70.459L29.4326-70.459L29.4326-67.1323Z"/> + </g> + <line id="Baseline-S" style="fill:none;stroke:#27AAE1;opacity:1;stroke-width:0.5;" x1="263" x2="3036" y1="696" y2="696"/> + <line id="Capline-S" style="fill:none;stroke:#27AAE1;opacity:1;stroke-width:0.5;" x1="263" x2="3036" y1="625.541" y2="625.541"/> + <g id="H-reference" style="fill:#27AAE1;stroke:none;" transform="matrix(1 0 0 1 339 1126)"> + <path d="M0.993654 0L3.63775 0L29.3281-67.1323L30.0303-67.1323L30.0303-70.459L28.1226-70.459ZM11.6885-24.4799L46.9815-24.4799L46.2315-26.7285L12.4385-26.7285ZM55.1196 0L57.7637 0L30.6382-70.459L29.4326-70.459L29.4326-67.1323Z"/> + </g> + <line id="Baseline-M" style="fill:none;stroke:#27AAE1;opacity:1;stroke-width:0.5;" x1="263" x2="3036" y1="1126" y2="1126"/> + <line id="Capline-M" style="fill:none;stroke:#27AAE1;opacity:1;stroke-width:0.5;" x1="263" x2="3036" y1="1055.54" y2="1055.54"/> + <g id="H-reference" style="fill:#27AAE1;stroke:none;" transform="matrix(1 0 0 1 339 1556)"> + <path d="M0.993654 0L3.63775 0L29.3281-67.1323L30.0303-67.1323L30.0303-70.459L28.1226-70.459ZM11.6885-24.4799L46.9815-24.4799L46.2315-26.7285L12.4385-26.7285ZM55.1196 0L57.7637 0L30.6382-70.459L29.4326-70.459L29.4326-67.1323Z"/> + </g> + <line id="Baseline-L" style="fill:none;stroke:#27AAE1;opacity:1;stroke-width:0.5;" x1="263" x2="3036" y1="1556" y2="1556"/> + <line id="Capline-L" style="fill:none;stroke:#27AAE1;opacity:1;stroke-width:0.5;" x1="263" x2="3036" y1="1485.54" y2="1485.54"/> + <line id="left-margin" style="fill:none;stroke:#00AEEF;stroke-width:0.5;opacity:1.0;" x1="1385.73" x2="1385.73" y1="1030.79" y2="1150.12"/> + <line id="right-margin" style="fill:none;stroke:#00AEEF;stroke-width:0.5;opacity:1.0;" x1="1513.96" x2="1513.96" y1="1030.79" y2="1150.12"/> + </g> + <g id="Symbols"> + <g id="Black-L" transform="matrix(1 0 0 1 2853.39 1556)"> + <path d="M82.07-71.05C82.07-68.66 82.29-66.32 82.71-64.05L20.97-64.05C17.1-64.05 13.97-67.18 13.97-71.05C13.97-74.91 17.1-78.05 20.97-78.05L82.71-78.05C82.29-75.78 82.07-73.44 82.07-71.05ZM76.87 0.85C76.87-1.54 76.65-3.88 76.23-6.15L137.97-6.15C141.84-6.15 144.97-3.01 144.97 0.85C144.97 4.72 141.84 7.85 137.97 7.85L76.23 7.85C76.65 5.58 76.87 3.24 76.87 0.85ZM120.42-99C135.86-99 148.37-86.49 148.37-71.05C148.37-55.61 135.86-43.1 120.42-43.1C104.98-43.1 92.47-55.61 92.47-71.05C92.47-86.49 104.98-99 120.42-99ZM120.42-85C112.72-85 106.47-78.75 106.47-71.05C106.47-63.35 112.72-57.1 120.42-57.1C128.12-57.1 134.37-63.35 134.37-71.05C134.37-78.75 128.12-85 120.42-85ZM38.52-27.1C53.96-27.1 66.47-14.59 66.47 0.85C66.47 16.28 53.96 28.8 38.52 28.8C23.08 28.8 10.57 16.28 10.57 0.85C10.57-14.59 23.08-27.1 38.52-27.1ZM38.52-13.1C30.82-13.1 24.57-6.86 24.57 0.85C24.57 8.55 30.82 14.8 38.52 14.8C46.22 14.8 52.47 8.55 52.47 0.85C52.47-6.86 46.22-13.1 38.52-13.1Z"/> + </g> + <g id="Heavy-L" transform="matrix(1 0 0 1 2556.67 1556)"> + <path d="M82.07-71.05C82.07-68.83 82.26-66.66 82.62-64.55L20.97-64.55C17.38-64.55 14.47-67.46 14.47-71.05C14.47-74.64 17.38-77.55 20.97-77.55L82.62-77.55C82.26-75.43 82.07-73.26 82.07-71.05ZM76.87 0.85C76.87-1.36 76.68-3.54 76.32-5.65L137.97-5.65C141.56-5.65 144.47-2.74 144.47 0.85C144.47 4.44 141.56 7.35 137.97 7.35L76.32 7.35C76.68 5.24 76.87 3.07 76.87 0.85ZM120.42-99C135.86-99 148.37-86.49 148.37-71.05C148.37-55.61 135.86-43.1 120.42-43.1C104.98-43.1 92.47-55.61 92.47-71.05C92.47-86.49 104.98-99 120.42-99ZM120.42-86C112.16-86 105.47-79.31 105.47-71.05C105.47-62.79 112.16-56.1 120.42-56.1C128.68-56.1 135.37-62.79 135.37-71.05C135.37-79.31 128.68-86 120.42-86ZM38.52-27.1C53.96-27.1 66.47-14.59 66.47 0.85C66.47 16.28 53.96 28.8 38.52 28.8C23.08 28.8 10.57 16.28 10.57 0.85C10.57-14.59 23.08-27.1 38.52-27.1ZM38.52-14.1C30.26-14.1 23.57-7.41 23.57 0.85C23.57 9.11 30.26 15.8 38.52 15.8C46.78 15.8 53.47 9.11 53.47 0.85C53.47-7.41 46.78-14.1 38.52-14.1Z"/> + </g> + <g id="Bold-L" transform="matrix(1 0 0 1 2259.96 1556)"> + <path d="M82.07-70.05C82.07-68.01 82.23-66 82.54-64.05L20.97-64.05C17.66-64.05 14.97-66.73 14.97-70.05C14.97-73.36 17.66-76.05 20.97-76.05L82.54-76.05C82.23-74.09 82.07-72.09 82.07-70.05ZM76.87-0.15C76.87-2.19 76.71-4.19 76.4-6.15L137.97-6.15C141.28-6.15 143.97-3.46 143.97-0.15C143.97 3.17 141.28 5.85 137.97 5.85L76.4 5.85C76.71 3.9 76.87 1.89 76.87-0.15ZM120.42-98C135.86-98 148.37-85.49 148.37-70.05C148.37-54.61 135.86-42.1 120.42-42.1C104.98-42.1 92.47-54.61 92.47-70.05C92.47-85.49 104.98-98 120.42-98ZM120.42-86C111.61-86 104.47-78.86 104.47-70.05C104.47-61.24 111.61-54.1 120.42-54.1C129.23-54.1 136.37-61.24 136.37-70.05C136.37-78.86 129.23-86 120.42-86ZM38.52-28.1C53.96-28.1 66.47-15.59 66.47-0.15C66.47 15.28 53.96 27.8 38.52 27.8C23.08 27.8 10.57 15.28 10.57-0.15C10.57-15.59 23.08-28.1 38.52-28.1ZM38.52-16.1C29.71-16.1 22.57-8.96 22.57-0.15C22.57 8.66 29.71 15.8 38.52 15.8C47.33 15.8 54.47 8.66 54.47-0.15C54.47-8.96 47.33-16.1 38.52-16.1Z"/> + </g> + <g id="Semibold-L" transform="matrix(1 0 0 1 1963.25 1556)"> + <path d="M82.07-70.05C82.07-68.18 82.2-66.34 82.46-64.55L20.97-64.55C17.93-64.55 15.47-67.01 15.47-70.05C15.47-73.08 17.93-75.55 20.97-75.55L82.46-75.55C82.2-73.75 82.07-71.91 82.07-70.05ZM76.87-0.15C76.87-2.02 76.74-3.85 76.48-5.65L137.97-5.65C141.01-5.65 143.47-3.19 143.47-0.15C143.47 2.89 141.01 5.35 137.97 5.35L76.48 5.35C76.74 3.56 76.87 1.72 76.87-0.15ZM120.42-98C135.86-98 148.37-85.49 148.37-70.05C148.37-54.61 135.86-42.1 120.42-42.1C104.98-42.1 92.47-54.61 92.47-70.05C92.47-85.49 104.98-98 120.42-98ZM120.42-87C111.06-87 103.47-79.41 103.47-70.05C103.47-60.69 111.06-53.1 120.42-53.1C129.78-53.1 137.37-60.69 137.37-70.05C137.37-79.41 129.78-87 120.42-87ZM38.52-28.1C53.96-28.1 66.47-15.59 66.47-0.15C66.47 15.28 53.96 27.8 38.52 27.8C23.08 27.8 10.57 15.28 10.57-0.15C10.57-15.59 23.08-28.1 38.52-28.1ZM38.52-17.1C29.16-17.1 21.57-9.51 21.57-0.15C21.57 9.21 29.16 16.8 38.52 16.8C47.88 16.8 55.47 9.21 55.47-0.15C55.47-9.51 47.88-17.1 38.52-17.1Z"/> + </g> + <g id="Medium-L" transform="matrix(1 0 0 1 1666.54 1556)"> + <path d="M82.07-69.05C82.07-67.35 82.18-65.68 82.39-64.05L20.97-64.05C18.21-64.05 15.97-66.29 15.97-69.05C15.97-71.81 18.21-74.05 20.97-74.05L82.39-74.05C82.18-72.41 82.07-70.74 82.07-69.05ZM76.87-0.15C76.87 1.55 76.76 3.22 76.55 4.85L137.97 4.85C140.73 4.85 142.97 2.61 142.97-0.15C142.97-2.91 140.73-5.15 137.97-5.15L76.55-5.15C76.76-3.51 76.87-1.84 76.87-0.15ZM120.42-97C135.86-97 148.37-84.49 148.37-69.05C148.37-53.61 135.86-41.1 120.42-41.1C104.98-41.1 92.47-53.61 92.47-69.05C92.47-84.49 104.98-97 120.42-97ZM120.42-87C110.51-87 102.47-78.96 102.47-69.05C102.47-59.14 110.51-51.1 120.42-51.1C130.33-51.1 138.37-59.14 138.37-69.05C138.37-78.96 130.33-87 120.42-87ZM38.52-28.1C53.96-28.1 66.47-15.59 66.47-0.15C66.47 15.28 53.96 27.8 38.52 27.8C23.08 27.8 10.57 15.28 10.57-0.15C10.57-15.59 23.08-28.1 38.52-28.1ZM38.52-18.1C28.61-18.1 20.57-10.07 20.57-0.15C20.57 9.76 28.61 17.8 38.52 17.8C48.43 17.8 56.47 9.76 56.47-0.15C56.47-10.07 48.43-18.1 38.52-18.1Z"/> + </g> + <g id="Regular-L" transform="matrix(1 0 0 1 1369.83 1556)"> + <path d="M82.07-70.04C82.07-68.52 82.16-67.02 82.33-65.54L20.97-65.54C18.48-65.54 16.47-67.55 16.47-70.04C16.47-72.52 18.48-74.54 20.97-74.54L82.33-74.54C82.16-73.06 82.07-71.56 82.07-70.04ZM76.87-1.14C76.87 0.38 76.78 1.88 76.61 3.36L137.97 3.36C140.46 3.36 142.47 1.34 142.47-1.14C142.47-3.63 140.46-5.64 137.97-5.64L76.61-5.64C76.78-4.16 76.87-2.66 76.87-1.14ZM120.42-97.99C135.86-97.99 148.37-85.48 148.37-70.04C148.37-54.61 135.86-42.09 120.42-42.09C104.98-42.09 92.47-54.61 92.47-70.04C92.47-85.48 104.98-97.99 120.42-97.99ZM120.42-88.99C109.95-88.99 101.47-80.51 101.47-70.04C101.47-59.58 109.95-51.09 120.42-51.09C130.89-51.09 139.37-59.58 139.37-70.04C139.37-80.51 130.89-88.99 120.42-88.99ZM38.52-29.09C53.96-29.09 66.47-16.58 66.47-1.14C66.47 14.29 53.96 26.81 38.52 26.81C23.08 26.81 10.57 14.29 10.57-1.14C10.57-16.58 23.08-29.09 38.52-29.09ZM38.52-20.09C28.05-20.09 19.57-11.61 19.57-1.14C19.57 9.32 28.05 17.81 38.52 17.81C48.99 17.81 57.47 9.32 57.47-1.14C57.47-11.61 48.99-20.09 38.52-20.09Z"/> + </g> + <g id="Light-L" transform="matrix(1 0 0 1 1073.12 1556)"> + <path d="M82.07-69.04C82.07-67.69 82.14-66.35 82.28-65.04L20.97-65.04C18.76-65.04 16.97-66.83 16.97-69.04C16.97-71.25 18.76-73.04 20.97-73.04L82.28-73.04C82.14-71.72 82.07-70.39 82.07-69.04ZM76.87-0.14C76.87 1.21 76.8 2.54 76.66 3.86L137.97 3.86C140.18 3.86 141.97 2.07 141.97-0.14C141.97-2.35 140.18-4.14 137.97-4.14L76.66-4.14C76.8-2.83 76.87-1.49 76.87-0.14ZM120.42-96.99C135.86-96.99 148.37-84.48 148.37-69.04C148.37-53.61 135.86-41.09 120.42-41.09C104.98-41.09 92.47-53.61 92.47-69.04C92.47-84.48 104.98-96.99 120.42-96.99ZM120.42-88.99C109.4-88.99 100.47-80.06 100.47-69.04C100.47-58.02 109.4-49.09 120.42-49.09C131.44-49.09 140.37-58.02 140.37-69.04C140.37-80.06 131.44-88.99 120.42-88.99ZM38.52-28.09C53.96-28.09 66.47-15.58 66.47-0.14C66.47 15.29 53.96 27.81 38.52 27.81C23.08 27.81 10.57 15.29 10.57-0.14C10.57-15.58 23.08-28.09 38.52-28.09ZM38.52-20.09C27.5-20.09 18.57-11.16 18.57-0.14C18.57 10.87 27.5 19.81 38.52 19.81C49.54 19.81 58.47 10.87 58.47-0.14C58.47-11.16 49.54-20.09 38.52-20.09Z"/> + </g> + <g id="Thin-L" transform="matrix(1 0 0 1 776.407 1556)"> + <path d="M82.07-70.05C82.07-69.04 82.109-68.04 82.186-67.05L20.969-67.05C19.313-67.05 17.969-68.39 17.969-70.05C17.969-71.7 19.313-73.05 20.969-73.05L82.186-73.05C82.109-72.06 82.07-71.06 82.07-70.05ZM76.87-1.15C76.87-0.14 76.831 0.86 76.755 1.85L137.97 1.85C139.627 1.85 140.97 0.51 140.97-1.15C140.97-2.81 139.627-4.15 137.97-4.15L76.755-4.15C76.831-3.16 76.87-2.16 76.87-1.15ZM120.42-98C135.856-98 148.37-85.49 148.37-70.05C148.37-54.61 135.856-42.1 120.42-42.1C104.984-42.1 92.47-54.61 92.47-70.05C92.47-85.49 104.984-98 120.42-98ZM120.42-92C108.297-92 98.47-82.17 98.47-70.05C98.47-57.93 108.297-48.1 120.42-48.1C132.543-48.1 142.37-57.93 142.37-70.05C142.37-82.17 132.543-92 120.42-92ZM38.52-29.1C53.956-29.1 66.47-16.59 66.47-1.15C66.47 14.28 53.956 26.8 38.52 26.8C23.084 26.8 10.57 14.28 10.57-1.15C10.57-16.59 23.084-29.1 38.52-29.1ZM38.52-23.1C26.397-23.1 16.57-13.27 16.57-1.15C16.57 10.97 26.397 20.8 38.52 20.8C50.643 20.8 60.47 10.97 60.47-1.15C60.47-13.27 50.643-23.1 38.52-23.1Z"/> + </g> + <g id="Ultralight-L" transform="matrix(1 0 0 1 479.696 1556)"> + <path d="M82.07-70.04C82.07-69.37 82.087-68.7 82.121-68.04L20.969-68.04C19.865-68.04 18.969-68.93 18.969-70.04C18.969-71.14 19.865-72.04 20.969-72.04L82.121-72.04C82.087-71.38 82.07-70.71 82.07-70.04ZM76.87-1.14C76.87-0.47 76.853 0.2 76.819 0.86L137.969 0.86C139.074 0.86 139.969-0.04 139.969-1.14C139.969-2.25 139.074-3.14 137.969-3.14L76.819-3.14C76.853-2.48 76.87-1.81 76.87-1.14ZM120.42-97.99C135.856-97.99 148.37-85.48 148.37-70.04C148.37-54.61 135.856-42.09 120.42-42.09C104.984-42.09 92.47-54.61 92.47-70.04C92.47-85.48 104.984-97.99 120.42-97.99ZM120.42-93.99C107.193-93.99 96.47-83.27 96.47-70.04C96.47-56.81 107.193-46.09 120.42-46.09C133.647-46.09 144.37-56.81 144.37-70.04C144.37-83.27 133.647-93.99 120.42-93.99ZM38.52-29.09C53.956-29.09 66.47-16.58 66.47-1.14C66.47 14.29 53.956 26.81 38.52 26.81C23.084 26.81 10.57 14.29 10.57-1.14C10.57-16.58 23.084-29.09 38.52-29.09ZM38.52-25.09C25.293-25.09 14.57-14.37 14.57-1.14C14.57 12.08 25.293 22.81 38.52 22.81C51.747 22.81 62.47 12.08 62.47-1.14C62.47-14.37 51.747-25.09 38.52-25.09Z"/> + </g> + <g id="Black-M" transform="matrix(1 0 0 1 2869.29 1126)"> + <path d="M65.57-63.5C65.57-61.27 65.82-59.09 66.29-57L18.57-57C14.98-57 12.07-59.91 12.07-63.5C12.07-67.09 14.98-70 18.57-70L66.29-70C65.82-67.91 65.57-65.73 65.57-63.5ZM61.57-6.5C61.57-8.73 61.32-10.91 60.85-13L108.57-13C112.16-13 115.07-10.09 115.07-6.5C115.07-2.91 112.16 0 108.57 0L60.85 0C61.32-2.09 61.57-4.27 61.57-6.5ZM95.07-85C106.94-85 116.57-75.37 116.57-63.5C116.57-51.63 106.94-42 95.07-42C83.2-42 73.57-51.63 73.57-63.5C73.57-75.37 83.2-85 95.07-85ZM95.07-72C90.38-72 86.57-68.19 86.57-63.5C86.57-58.81 90.38-55 95.07-55C99.76-55 103.57-58.81 103.57-63.5C103.57-68.19 99.76-72 95.07-72ZM32.07-28C43.94-28 53.57-18.37 53.57-6.5C53.57 5.37 43.94 15 32.07 15C20.2 15 10.57 5.37 10.57-6.5C10.57-18.37 20.2-28 32.07-28ZM32.07-15C27.38-15 23.57-11.19 23.57-6.5C23.57-1.81 27.38 2 32.07 2C36.76 2 40.57-1.81 40.57-6.5C40.57-11.19 36.76-15 32.07-15Z"/> + </g> + <g id="Heavy-M" transform="matrix(1 0 0 1 2572.57 1126)"> + <path d="M65.57-63.49C65.57-61.44 65.78-59.43 66.18-57.49L18.57-57.49C15.26-57.49 12.57-60.18 12.57-63.49C12.57-66.81 15.26-69.49 18.57-69.49L66.18-69.49C65.78-67.55 65.57-65.55 65.57-63.49ZM61.57-6.49C61.57-8.55 61.36-10.55 60.96-12.49L108.57-12.49C111.88-12.49 114.57-9.81 114.57-6.49C114.57-3.18 111.88-0.49 108.57-0.49L60.96-0.49C61.36-2.43 61.57-4.44 61.57-6.49ZM95.07-84.99C106.94-84.99 116.57-75.37 116.57-63.49C116.57-51.62 106.94-41.99 95.07-41.99C83.2-41.99 73.57-51.62 73.57-63.49C73.57-75.37 83.2-84.99 95.07-84.99ZM95.07-72.99C89.82-72.99 85.57-68.74 85.57-63.49C85.57-58.25 89.82-53.99 95.07-53.99C100.32-53.99 104.57-58.25 104.57-63.49C104.57-68.74 100.32-72.99 95.07-72.99ZM32.07-27.99C43.94-27.99 53.57-18.37 53.57-6.49C53.57 5.38 43.94 15.01 32.07 15.01C20.2 15.01 10.57 5.38 10.57-6.49C10.57-18.37 20.2-27.99 32.07-27.99ZM32.07-15.99C26.82-15.99 22.57-11.74 22.57-6.49C22.57-1.25 26.82 3.01 32.07 3.01C37.32 3.01 41.57-1.25 41.57-6.49C41.57-11.74 37.32-15.99 32.07-15.99Z"/> + </g> + <g id="Bold-M" transform="matrix(1 0 0 1 2275.86 1126)"> + <path d="M65.57-62.49C65.57-60.61 65.75-58.77 66.08-56.99L18.57-56.99C15.53-56.99 13.07-59.45 13.07-62.49C13.07-65.53 15.53-67.99 18.57-67.99L66.08-67.99C65.75-66.21 65.57-64.37 65.57-62.49ZM108.57-12.99C111.61-12.99 114.07-10.53 114.07-7.49C114.07-4.45 111.61-1.99 108.57-1.99L61.06-1.99C61.39-3.77 61.57-5.61 61.57-7.49C61.57-9.37 61.39-11.21 61.06-12.99L108.57-12.99ZM95.07-83.99C106.94-83.99 116.57-74.37 116.57-62.49C116.57-50.62 106.94-40.99 95.07-40.99C83.2-40.99 73.57-50.62 73.57-62.49C73.57-74.37 83.2-83.99 95.07-83.99ZM95.07-72.99C89.27-72.99 84.57-68.29 84.57-62.49C84.57-56.69 89.27-51.99 95.07-51.99C100.87-51.99 105.57-56.69 105.57-62.49C105.57-68.29 100.87-72.99 95.07-72.99ZM32.07-28.99C43.94-28.99 53.57-19.37 53.57-7.49C53.57 4.38 43.94 14.01 32.07 14.01C20.2 14.01 10.57 4.38 10.57-7.49C10.57-19.37 20.2-28.99 32.07-28.99ZM32.07-17.99C26.27-17.99 21.57-13.29 21.57-7.49C21.57-1.69 26.27 3.01 32.07 3.01C37.87 3.01 42.57-1.69 42.57-7.49C42.57-13.29 37.87-17.99 32.07-17.99Z"/> + </g> + <g id="Semibold-M" transform="matrix(1 0 0 1 1979.15 1126)"> + <path d="M65.57-62.5C65.57-60.8 65.71-59.13 65.99-57.5L18.57-57.5C15.81-57.5 13.57-59.74 13.57-62.5C13.57-65.26 15.81-67.5 18.57-67.5L65.99-67.5C65.71-65.87 65.57-64.2 65.57-62.5ZM61.57-7.5C61.57-9.2 61.43-10.87 61.15-12.5L108.57-12.5C111.33-12.5 113.57-10.26 113.57-7.5C113.57-4.74 111.33-2.5 108.57-2.5L61.15-2.5C61.43-4.13 61.57-5.8 61.57-7.5ZM95.07-84C106.94-84 116.57-74.37 116.57-62.5C116.57-50.63 106.94-41 95.07-41C83.2-41 73.57-50.63 73.57-62.5C73.57-74.37 83.2-84 95.07-84ZM95.07-74C88.72-74 83.57-68.85 83.57-62.5C83.57-56.15 88.72-51 95.07-51C101.42-51 106.57-56.15 106.57-62.5C106.57-68.85 101.42-74 95.07-74ZM32.07-29C43.94-29 53.57-19.37 53.57-7.5C53.57 4.37 43.94 14 32.07 14C20.2 14 10.57 4.37 10.57-7.5C10.57-19.37 20.2-29 32.07-29ZM32.07-19C25.72-19 20.57-13.85 20.57-7.5C20.57-1.15 25.72 4 32.07 4C38.42 4 43.57-1.15 43.57-7.5C43.57-13.85 38.42-19 32.07-19Z"/> + </g> + <g id="Medium-M" transform="matrix(1 0 0 1 1682.44 1126)"> + <path d="M65.57-61.5C65.57-59.97 65.69-58.47 65.91-57L18.57-57C16.08-57 14.07-59.01 14.07-61.5C14.07-63.99 16.08-66 18.57-66L65.91-66C65.69-64.53 65.57-63.03 65.57-61.5ZM61.57-8.5C61.57-10.03 61.45-11.53 61.23-13L108.57-13C111.06-13 113.07-10.99 113.07-8.5C113.07-6.01 111.06-4 108.57-4L61.23-4C61.45-5.47 61.57-6.97 61.57-8.5ZM95.07-83C106.94-83 116.57-73.37 116.57-61.5C116.57-49.63 106.94-40 95.07-40C83.2-40 73.57-49.63 73.57-61.5C73.57-73.37 83.2-83 95.07-83ZM95.07-74C88.17-74 82.57-68.4 82.57-61.5C82.57-54.6 88.17-49 95.07-49C101.97-49 107.57-54.6 107.57-61.5C107.57-68.4 101.97-74 95.07-74ZM32.07-30C43.94-30 53.57-20.37 53.57-8.5C53.57 3.37 43.94 13 32.07 13C20.2 13 10.57 3.37 10.57-8.5C10.57-20.37 20.2-30 32.07-30ZM32.07-21C25.17-21 19.57-15.4 19.57-8.5C19.57-1.6 25.17 4 32.07 4C38.97 4 44.57-1.6 44.57-8.5C44.57-15.4 38.97-21 32.07-21Z"/> + </g> + <g id="Regular-M" transform="matrix(1 0 0 1 1385.73 1126)"> + <path d="M65.57-61.5C65.57-60.14 65.66-58.81 65.84-57.5L18.57-57.5C16.36-57.5 14.57-59.29 14.57-61.5C14.57-63.71 16.36-65.5 18.57-65.5L65.84-65.5C65.66-64.19 65.57-62.86 65.57-61.5ZM61.57-8.5C61.57-7.14 61.48-5.81 61.3-4.5L108.57-4.5C110.78-4.5 112.57-6.29 112.57-8.5C112.57-10.71 110.78-12.5 108.57-12.5L61.3-12.5C61.48-11.19 61.57-9.86 61.57-8.5ZM95.07-83C106.94-83 116.57-73.37 116.57-61.5C116.57-49.63 106.94-40 95.07-40C83.2-40 73.57-49.63 73.57-61.5C73.57-73.37 83.2-83 95.07-83ZM95.07-75C87.61-75 81.57-68.96 81.57-61.5C81.57-54.04 87.61-48 95.07-48C102.53-48 108.57-54.04 108.57-61.5C108.57-68.96 102.53-75 95.07-75ZM32.07-30C43.94-30 53.57-20.37 53.57-8.5C53.57 3.37 43.94 13 32.07 13C20.2 13 10.57 3.37 10.57-8.5C10.57-20.37 20.2-30 32.07-30ZM32.07-22C24.61-22 18.57-15.96 18.57-8.5C18.57-1.04 24.61 5 32.07 5C39.53 5 45.57-1.04 45.57-8.5C45.57-15.96 39.53-22 32.07-22Z"/> + </g> + <g id="Light-M" transform="matrix(1 0 0 1 1089.02 1126)"> + <path d="M65.57-61.5C65.57-60.32 65.64-59.15 65.78-58L18.57-58C16.64-58 15.07-59.57 15.07-61.5C15.07-63.43 16.64-65 18.57-65L65.78-65C65.64-63.85 65.57-62.68 65.57-61.5ZM61.57-9.5C61.57-8.32 61.5-7.15 61.36-6L108.57-6C110.5-6 112.07-7.57 112.07-9.5C112.07-11.43 110.5-13 108.57-13L61.36-13C61.5-11.85 61.57-10.68 61.57-9.5ZM95.07-83C106.94-83 116.57-73.37 116.57-61.5C116.57-49.63 106.94-40 95.07-40C83.2-40 73.57-49.63 73.57-61.5C73.57-73.37 83.2-83 95.07-83ZM95.07-76C87.06-76 80.57-69.51 80.57-61.5C80.57-53.49 87.06-47 95.07-47C103.08-47 109.57-53.49 109.57-61.5C109.57-69.51 103.08-76 95.07-76ZM32.07-31C43.94-31 53.57-21.37 53.57-9.5C53.57 2.37 43.94 12 32.07 12C20.2 12 10.57 2.37 10.57-9.5C10.57-21.37 20.2-31 32.07-31ZM32.07-24C24.06-24 17.57-17.51 17.57-9.5C17.57-1.49 24.06 5 32.07 5C40.08 5 46.57-1.49 46.57-9.5C46.57-17.51 40.08-24 32.07-24Z"/> + </g> + <g id="Thin-M" transform="matrix(1 0 0 1 792.307 1126)"> + <path d="M65.57-61.5C65.57-60.66 65.605-59.82 65.674-59L18.57-59C17.189-59 16.07-60.12 16.07-61.5C16.07-62.88 17.189-64 18.57-64L65.674-64C65.605-63.18 65.57-62.34 65.57-61.5ZM61.57-9.5C61.57-8.66 61.535-7.82 61.466-7L108.57-7C109.951-7 111.07-8.12 111.07-9.5C111.07-10.88 109.951-12 108.57-12L61.466-12C61.535-11.18 61.57-10.34 61.57-9.5ZM95.07-83C106.944-83 116.57-73.37 116.57-61.5C116.57-49.63 106.944-40 95.07-40C83.196-40 73.57-49.63 73.57-61.5C73.57-73.37 83.196-83 95.07-83ZM95.07-78C85.957-78 78.57-70.61 78.57-61.5C78.57-52.39 85.957-45 95.07-45C104.183-45 111.57-52.39 111.57-61.5C111.57-70.61 104.183-78 95.07-78ZM32.07-31C43.944-31 53.57-21.37 53.57-9.5C53.57 2.37 43.944 12 32.07 12C20.196 12 10.57 2.37 10.57-9.5C10.57-21.37 20.196-31 32.07-31ZM32.07-26C22.957-26 15.57-18.61 15.57-9.5C15.57-0.39 22.957 7 32.07 7C41.183 7 48.57-0.39 48.57-9.5C48.57-18.61 41.183-26 32.07-26Z"/> + </g> + <g id="Ultralight-M" transform="matrix(1 0 0 1 495.596 1126)"> + <path d="M65.57-62.49C65.57-61.99 65.582-61.49 65.607-60.99L18.57-60.99C17.741-60.99 17.07-61.66 17.07-62.49C17.07-63.32 17.741-63.99 18.57-63.99L65.607-63.99C65.582-63.5 65.57-63 65.57-62.49ZM61.57-10.49C61.57-9.99 61.558-9.49 61.533-8.99L108.57-8.99C109.399-8.99 110.07-9.66 110.07-10.49C110.07-11.32 109.399-11.99 108.57-11.99L61.533-11.99C61.558-11.5 61.57-11 61.57-10.49ZM95.07-83.99C106.944-83.99 116.57-74.37 116.57-62.49C116.57-50.62 106.944-40.99 95.07-40.99C83.196-40.99 73.57-50.62 73.57-62.49C73.57-74.37 83.196-83.99 95.07-83.99ZM95.07-80.99C84.853-80.99 76.57-72.71 76.57-62.49C76.57-52.27 84.853-43.99 95.07-43.99C105.287-43.99 113.57-52.27 113.57-62.49C113.57-72.71 105.287-80.99 95.07-80.99ZM32.07-31.99C43.944-31.99 53.57-22.37 53.57-10.49C53.57 1.38 43.944 11.01 32.07 11.01C20.196 11.01 10.57 1.38 10.57-10.49C10.57-22.37 20.196-31.99 32.07-31.99ZM32.07-28.99C21.853-28.99 13.57-20.71 13.57-10.49C13.57-0.27 21.853 8.01 32.07 8.01C42.287 8.01 50.57-0.27 50.57-10.49C50.57-20.71 42.287-28.99 32.07-28.99Z"/> + </g> + <g id="Black-S" transform="matrix(1 0 0 1 2878.79 696)"> + <path d="M55.71-57.352C55.71-55.281 55.97-53.27 56.46-51.352L17.14-51.352C13.82-51.352 11.14-54.038 11.14-57.352C11.14-60.665 13.82-63.352 17.14-63.352L56.46-63.352C55.97-61.433 55.71-59.423 55.71-57.352ZM52.43-13.852C52.43-15.923 52.17-17.933 51.68-19.852L91-19.852C94.32-19.852 97-17.165 97-13.852C97-10.538 94.32-7.852 91-7.852L51.68-7.852C52.17-9.77 52.43-11.781 52.43-13.852ZM80.07-75C89.73-75 97.57-67.165 97.57-57.5C97.57-47.835 89.73-40 80.07-40C70.41-40 62.57-47.835 62.57-57.5C62.57-67.165 70.41-75 80.07-75ZM80.07-63C77.03-63 74.57-60.538 74.57-57.5C74.57-54.462 77.03-52 80.07-52C83.11-52 85.57-54.462 85.57-57.5C85.57-60.538 83.11-63 80.07-63ZM28.07-31C37.73-31 45.57-23.165 45.57-13.5C45.57-3.835 37.73 4 28.07 4C18.41 4 10.57-3.835 10.57-13.5C10.57-23.165 18.41-31 28.07-31ZM28.07-19C25.03-19 22.57-16.538 22.57-13.5C22.57-10.462 25.03-8 28.07-8C31.11-8 33.57-10.462 33.57-13.5C33.57-16.538 31.11-19 28.07-19Z"/> + </g> + <g id="Heavy-S" transform="matrix(1 0 0 1 2582.07 696)"> + <path d="M55.71-57.344C55.71-55.452 55.93-53.611 56.34-51.844L17.14-51.844C14.1-51.844 11.64-54.306 11.64-57.344C11.64-60.381 14.1-62.844 17.14-62.844L56.34-62.844C55.93-61.077 55.71-59.236 55.71-57.344ZM52.43-13.844C52.43-15.736 52.21-17.577 51.8-19.344L91-19.344C94.04-19.344 96.5-16.881 96.5-13.844C96.5-10.806 94.04-8.344 91-8.344L51.8-8.344C52.21-10.111 52.43-11.952 52.43-13.844ZM80.07-74.992C89.73-74.992 97.57-67.157 97.57-57.492C97.57-47.827 89.73-39.992 80.07-39.992C70.41-39.992 62.57-47.827 62.57-57.492C62.57-67.157 70.41-74.992 80.07-74.992ZM80.07-63.992C76.48-63.992 73.57-61.082 73.57-57.492C73.57-53.902 76.48-50.992 80.07-50.992C83.66-50.992 86.57-53.902 86.57-57.492C86.57-61.082 83.66-63.992 80.07-63.992ZM28.07-30.992C37.73-30.992 45.57-23.157 45.57-13.492C45.57-3.827 37.73 4.008 28.07 4.008C18.41 4.008 10.57-3.827 10.57-13.492C10.57-23.157 18.41-30.992 28.07-30.992ZM28.07-19.992C24.48-19.992 21.57-17.082 21.57-13.492C21.57-9.902 24.48-6.992 28.07-6.992C31.66-6.992 34.57-9.902 34.57-13.492C34.57-17.082 31.66-19.992 28.07-19.992Z"/> + </g> + <g id="Bold-S" transform="matrix(1 0 0 1 2285.36 696)"> + <path d="M55.71-57.352C55.71-55.637 55.89-53.965 56.23-52.352L17.14-52.352C14.37-52.352 12.14-54.59 12.14-57.352C12.14-60.113 14.37-62.352 17.14-62.352L56.23-62.352C55.89-60.738 55.71-59.066 55.71-57.352ZM52.43-13.852C52.43-15.566 52.25-17.238 51.91-18.852L91-18.852C93.76-18.852 96-16.613 96-13.852C96-11.09 93.76-8.852 91-8.852L51.91-8.852C52.25-10.465 52.43-12.137 52.43-13.852ZM80.07-75C89.73-75 97.57-67.165 97.57-57.5C97.57-47.835 89.73-40 80.07-40C70.41-40 62.57-47.835 62.57-57.5C62.57-67.165 70.41-75 80.07-75ZM80.07-65C75.93-65 72.57-61.642 72.57-57.5C72.57-53.358 75.93-50 80.07-50C84.21-50 87.57-53.358 87.57-57.5C87.57-61.642 84.21-65 80.07-65ZM28.07-31C37.73-31 45.57-23.165 45.57-13.5C45.57-3.835 37.73 4 28.07 4C18.41 4 10.57-3.835 10.57-13.5C10.57-23.165 18.41-31 28.07-31ZM28.07-21C23.93-21 20.57-17.642 20.57-13.5C20.57-9.358 23.93-6 28.07-6C32.21-6 35.57-9.358 35.57-13.5C35.57-17.642 32.21-21 28.07-21Z"/> + </g> + <g id="Semibold-S" transform="matrix(1 0 0 1 1988.65 696)"> + <path d="M55.71-57.352C55.71-55.814 55.85-54.31 56.13-52.852L17.14-52.852C14.65-52.852 12.64-54.866 12.64-57.352C12.64-59.837 14.65-61.852 17.14-61.852L56.13-61.852C55.85-60.393 55.71-58.889 55.71-57.352ZM52.43-13.852C52.43-15.389 52.28-16.893 52.01-18.352L91-18.352C93.49-18.352 95.5-16.337 95.5-13.852C95.5-11.366 93.49-9.352 91-9.352L52.01-9.352C52.28-10.81 52.43-12.314 52.43-13.852ZM80.07-75C89.73-75 97.57-67.165 97.57-57.5C97.57-47.835 89.73-40 80.07-40C70.41-40 62.57-47.835 62.57-57.5C62.57-67.165 70.41-75 80.07-75ZM80.07-66C75.38-66 71.57-62.194 71.57-57.5C71.57-52.806 75.38-49 80.07-49C84.76-49 88.57-52.806 88.57-57.5C88.57-62.194 84.76-66 80.07-66ZM28.07-31C37.73-31 45.57-23.165 45.57-13.5C45.57-3.835 37.73 4 28.07 4C18.41 4 10.57-3.835 10.57-13.5C10.57-23.165 18.41-31 28.07-31ZM28.07-22C23.38-22 19.57-18.194 19.57-13.5C19.57-8.806 23.38-5 28.07-5C32.76-5 36.57-8.806 36.57-13.5C36.57-18.194 32.76-22 28.07-22Z"/> + </g> + <g id="Medium-S" transform="matrix(1 0 0 1 1691.94 696)"> + <path d="M55.71-56.352C55.71-54.989 55.82-53.653 56.04-52.352L17.14-52.352C14.93-52.352 13.14-54.142 13.14-56.352C13.14-58.561 14.93-60.352 17.14-60.352L56.04-60.352C55.82-59.05 55.71-57.714 55.71-56.352ZM52.43-12.852C52.43-14.214 52.32-15.55 52.1-16.852L91-16.852C93.21-16.852 95-15.061 95-12.852C95-10.642 93.21-8.852 91-8.852L52.1-8.852C52.32-10.153 52.43-11.489 52.43-12.852ZM80.07-74C89.73-74 97.57-66.165 97.57-56.5C97.57-46.835 89.73-39 80.07-39C70.41-39 62.57-46.835 62.57-56.5C62.57-66.165 70.41-74 80.07-74ZM80.07-66C74.82-66 70.57-61.747 70.57-56.5C70.57-51.253 74.82-47 80.07-47C85.32-47 89.57-51.253 89.57-56.5C89.57-61.747 85.32-66 80.07-66ZM28.07-30C37.73-30 45.57-22.165 45.57-12.5C45.57-2.835 37.73 5 28.07 5C18.41 5 10.57-2.835 10.57-12.5C10.57-22.165 18.41-30 28.07-30ZM28.07-22C22.82-22 18.57-17.747 18.57-12.5C18.57-7.253 22.82-3 28.07-3C33.32-3 37.57-7.253 37.57-12.5C37.57-17.747 33.32-22 28.07-22Z"/> + </g> + <g id="Regular-S" transform="matrix(1 0 0 1 1395.23 696)"> + <path d="M55.71-57.344C55.71-56.155 55.8-54.987 55.96-53.844L17.14-53.844C15.2-53.844 13.64-55.411 13.64-57.344C13.64-59.277 15.2-60.844 17.14-60.844L55.96-60.844C55.8-59.701 55.71-58.532 55.71-57.344ZM52.43-13.844C52.43-15.032 52.34-16.201 52.18-17.344L91-17.344C92.94-17.344 94.5-15.777 94.5-13.844C94.5-11.911 92.94-10.344 91-10.344L52.18-10.344C52.34-11.487 52.43-12.655 52.43-13.844ZM80.07-74.992C89.73-74.992 97.57-67.157 97.57-57.492C97.57-47.827 89.73-39.992 80.07-39.992C70.41-39.992 62.57-47.827 62.57-57.492C62.57-67.157 70.41-74.992 80.07-74.992ZM80.07-67.992C74.27-67.992 69.57-63.291 69.57-57.492C69.57-51.693 74.27-46.992 80.07-46.992C85.87-46.992 90.57-51.693 90.57-57.492C90.57-63.291 85.87-67.992 80.07-67.992ZM28.07-30.992C37.73-30.992 45.57-23.157 45.57-13.492C45.57-3.827 37.73 4.008 28.07 4.008C18.41 4.008 10.57-3.827 10.57-13.492C10.57-23.157 18.41-30.992 28.07-30.992ZM28.07-23.992C22.27-23.992 17.57-19.291 17.57-13.492C17.57-7.693 22.27-2.992 28.07-2.992C33.87-2.992 38.57-7.693 38.57-13.492C38.57-19.291 33.87-23.992 28.07-23.992Z"/> + </g> + <g id="Light-S" transform="matrix(1 0 0 1 1098.52 696)"> + <path d="M55.71-56.352C55.71-55.336 55.77-54.335 55.9-53.352L17.14-53.352C15.48-53.352 14.14-54.695 14.14-56.352C14.14-58.008 15.48-59.352 17.14-59.352L55.9-59.352C55.77-58.369 55.71-57.367 55.71-56.352ZM52.43-12.852C52.43-11.836 52.37-10.835 52.24-9.852L91-9.852C92.66-9.852 94-11.195 94-12.852C94-14.508 92.66-15.852 91-15.852L52.24-15.852C52.37-14.869 52.43-13.867 52.43-12.852ZM80.07-74C89.74-74 97.57-66.165 97.57-56.5C97.57-46.835 89.74-39 80.07-39C70.41-39 62.57-46.835 62.57-56.5C62.57-66.165 70.41-74 80.07-74ZM80.07-68C73.72-68 68.57-62.851 68.57-56.5C68.57-50.149 73.72-45 80.07-45C86.42-45 91.57-50.149 91.57-56.5C91.57-62.851 86.42-68 80.07-68ZM28.07-30C37.74-30 45.57-22.165 45.57-12.5C45.57-2.835 37.74 5 28.07 5C18.41 5 10.57-2.835 10.57-12.5C10.57-22.165 18.41-30 28.07-30ZM28.07-24C21.72-24 16.57-18.851 16.57-12.5C16.57-6.149 21.72-1 28.07-1C34.42-1 39.57-6.149 39.57-12.5C39.57-18.851 34.42-24 28.07-24Z"/> + </g> + <g id="Thin-S" transform="matrix(1 0 0 1 801.807 696)"> + <path d="M55.711-56.352C55.711-55.678 55.739-55.011 55.793-54.352L17.135-54.352C16.031-54.352 15.135-55.247 15.135-56.352C15.135-57.456 16.031-58.352 17.135-58.352L55.793-58.352C55.739-57.692 55.711-57.025 55.711-56.352ZM52.428-12.852C52.428-12.178 52.401-11.511 52.347-10.852L91.003-10.852C92.108-10.852 93.003-11.747 93.003-12.852C93.003-13.956 92.108-14.852 91.003-14.852L52.347-14.852C52.401-14.192 52.428-13.525 52.428-12.852ZM80.07-74C89.735-74 97.57-66.165 97.57-56.5C97.57-46.835 89.735-39 80.07-39C70.405-39 62.57-46.835 62.57-56.5C62.57-66.165 70.405-74 80.07-74ZM80.07-70C72.614-70 66.57-63.956 66.57-56.5C66.57-49.044 72.614-43 80.07-43C87.526-43 93.57-49.044 93.57-56.5C93.57-63.956 87.526-70 80.07-70ZM28.07-30C37.735-30 45.57-22.165 45.57-12.5C45.57-2.835 37.735 5 28.07 5C18.405 5 10.57-2.835 10.57-12.5C10.57-22.165 18.405-30 28.07-30ZM28.07-26C20.614-26 14.57-19.956 14.57-12.5C14.57-5.044 20.614 1 28.07 1C35.526 1 41.57-5.044 41.57-12.5C41.57-19.956 35.526-26 28.07-26Z"/> + </g> + <g id="Ultralight-S" transform="matrix(1 0 0 1 505.096 696)"> + <path d="M55.711-56.352C55.711-55.848 55.727-55.348 55.757-54.852L17.135-54.852C16.307-54.852 15.635-55.523 15.635-56.352C15.635-57.18 16.307-57.852 17.135-57.852L55.757-57.852C55.727-57.355 55.711-56.855 55.711-56.352ZM52.429-12.852C52.429-12.348 52.413-11.848 52.383-11.352L91.004-11.352C91.832-11.352 92.504-12.023 92.504-12.852C92.504-13.68 91.832-14.352 91.004-14.352L52.383-14.352C52.413-13.855 52.429-13.355 52.429-12.852ZM80.07-74C89.735-74 97.57-66.165 97.57-56.5C97.57-46.835 89.735-39 80.07-39C70.405-39 62.57-46.835 62.57-56.5C62.57-66.165 70.405-74 80.07-74ZM80.07-71C72.062-71 65.57-64.508 65.57-56.5C65.57-48.492 72.062-42 80.07-42C88.078-42 94.57-48.492 94.57-56.5C94.57-64.508 88.078-71 80.07-71ZM28.07-30C37.735-30 45.57-22.165 45.57-12.5C45.57-2.835 37.735 5 28.07 5C18.405 5 10.57-2.835 10.57-12.5C10.57-22.165 18.405-30 28.07-30ZM28.07-27C20.062-27 13.57-20.508 13.57-12.5C13.57-4.492 20.062 2 28.07 2C36.078 2 42.57-4.492 42.57-12.5C42.57-20.508 36.078-27 28.07-27Z"/> + </g> + </g> +</svg>
diff --git a/ios/chrome/browser/ui/icons/symbol_names.h b/ios/chrome/browser/ui/icons/symbol_names.h index 6126670..cef6d62 100644 --- a/ios/chrome/browser/ui/icons/symbol_names.h +++ b/ios/chrome/browser/ui/icons/symbol_names.h
@@ -30,7 +30,6 @@ extern NSString* const kCameraSymbol; extern NSString* const kCameraFillSymbol; extern NSString* const kPasswordManagerSymbol; -extern NSString* const kPlusCircleFillSymbol; extern NSString* const kPopupBadgeMinusSymbol; extern NSString* const kPhotoBadgePlusSymbol; extern NSString* const kPhotoBadgeMagnifyingglassSymbol; @@ -50,11 +49,13 @@ extern NSString* const kCloudAndArrowUpSymbol; extern NSString* const kDinoSymbol; extern NSString* const kChromeProductSymbol; +extern NSString* const kTunerSymbol; // Custom symbol names which can be configured with a color palette. iOS 15+ // only. extern NSString* const kIncognitoCircleFillSymbol; -extern NSString* const kNewTabSymbol; +extern NSString* const kPlusCircleFillSymbol; +extern NSString* const kLegacyPlusCircleFillSymbol; // Custom symbol to replace "palette" symbols on iOS 14. Cannot be used with a // palette.
diff --git a/ios/chrome/browser/ui/icons/symbol_names.mm b/ios/chrome/browser/ui/icons/symbol_names.mm index 0c583cb..4e796977 100644 --- a/ios/chrome/browser/ui/icons/symbol_names.mm +++ b/ios/chrome/browser/ui/icons/symbol_names.mm
@@ -24,7 +24,6 @@ NSString* const kCameraSymbol = @"camera"; NSString* const kCameraFillSymbol = @"camera_fill"; NSString* const kPasswordManagerSymbol = @"password_manager"; -NSString* const kPlusCircleFillSymbol = @"plus_circle_fill"; NSString* const kPopupBadgeMinusSymbol = @"popup_badge_minus"; NSString* const kPhotoBadgePlusSymbol = @"photo_badge_plus"; NSString* const kPhotoBadgeMagnifyingglassSymbol = @@ -47,10 +46,12 @@ NSString* const kCloudAndArrowUpSymbol = @"cloud_and_arrow_up"; NSString* const kDinoSymbol = @"dino"; NSString* const kChromeProductSymbol = @"chrome_product"; +NSString* const kTunerSymbol = @"tuner"; // Custom symbol names which can be configured with a color palette. NSString* const kIncognitoCircleFillSymbol = @"incognito_circle_fill"; -NSString* const kNewTabSymbol = @"plus_circle_fill"; +NSString* const kPlusCircleFillSymbol = @"plus_circle_fill"; +NSString* const kLegacyPlusCircleFillSymbol = @"legacy_plus_circle_fill"; // Default symbol names. NSString* const kSyncEnabledSymbol = @"arrow.triangle.2.circlepath";
diff --git a/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_save_address_profile_modal_consumer.h b/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_save_address_profile_modal_consumer.h index 55dd9d9c..9a55740 100644 --- a/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_save_address_profile_modal_consumer.h +++ b/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_save_address_profile_modal_consumer.h
@@ -16,6 +16,8 @@ NSString* kIsUpdateModalPrefKey = @"IsUpdateModalPrefKey"; NSString* kProfileDataDiffKey = @"ProfileDataDiffKey"; NSString* kUpdateModalDescriptionKey = @"UpdateModalDescriptionKey"; +NSString* kSyncingUserEmailKey = @"SyncingUserEmailKey"; +NSString* kIsMigrationToAccountKey = @"IsMigrationToAccountKey"; } // namespace // Consumer for model to push configurations to the SaveAddressProfile UI.
diff --git a/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_save_address_profile_table_view_controller.mm b/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_save_address_profile_table_view_controller.mm index 8cb1a35..f36d3f7 100644 --- a/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_save_address_profile_table_view_controller.mm +++ b/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_save_address_profile_table_view_controller.mm
@@ -8,6 +8,7 @@ #import "base/mac/foundation_util.h" #import "base/metrics/user_metrics.h" #import "base/metrics/user_metrics_action.h" +#import "base/strings/sys_string_conversions.h" #import "components/autofill/core/common/autofill_features.h" #import "components/strings/grit/components_strings.h" #import "ios/chrome/browser/infobars/infobar_metrics_recorder.h" @@ -54,6 +55,7 @@ ItemTypeUpdateEmailOld, ItemTypeUpdatePhoneOld, ItemTypeAddressProfileSaveUpdateButton, + ItemTypeFooter }; const CGFloat kSymbolSize = 16; @@ -82,6 +84,10 @@ @property(nonatomic, copy) NSDictionary* profileDataDiff; // Description of the update modal. @property(nonatomic, copy) NSString* updateModalDescription; +// Stores the user email for the currently syncing account. +@property(nonatomic, copy) NSString* syncingUserEmail; +// If YES, denotes that the profile will be added to the Google Account. +@property(nonatomic, assign) BOOL isMigrationToAccount; @end @@ -248,6 +254,8 @@ self.isUpdateModal = [prefs[kIsUpdateModalPrefKey] boolValue]; self.profileDataDiff = prefs[kProfileDataDiffKey]; self.updateModalDescription = prefs[kUpdateModalDescriptionKey]; + self.isMigrationToAccount = [prefs[kIsMigrationToAccountKey] boolValue]; + self.syncingUserEmail = prefs[kSyncingUserEmailKey]; [self.tableView reloadData]; } @@ -381,8 +389,14 @@ lastAddedItem = phoneItem; } + if (self.isMigrationToAccount) { + DCHECK([self.syncingUserEmail length] > 0); + [model addItem:[self footerItem] + toSectionWithIdentifier:SectionIdentifierSaveModalFields]; + } + // Remove the separator after the last field. - lastAddedItem.useCustomSeparator = NO; + lastAddedItem.useCustomSeparator = self.isMigrationToAccount; [model addItem:[self saveUpdateButton] toSectionWithIdentifier:SectionIdentifierSaveModalFields]; @@ -534,4 +548,16 @@ return detailItem; } +- (TableViewTextItem*)footerItem { + // TODO(crbug.com/1407666): Align the text with the icon of the other fields. + TableViewTextItem* item = + [[TableViewTextItem alloc] initWithType:ItemTypeFooter]; + item.text = + l10n_util::GetNSStringF(IDS_IOS_AUTOFILL_SAVE_ADDRESS_IN_ACCOUNT_FOOTER, + base::SysNSStringToUTF16(self.syncingUserEmail)); + item.textFont = [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote]; + item.textColor = [UIColor colorNamed:kTextSecondaryColor]; + return item; +} + @end
diff --git a/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_save_address_profile_table_view_controller_unittest.mm b/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_save_address_profile_table_view_controller_unittest.mm index a059b036..a3a2191d 100644 --- a/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_save_address_profile_table_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_save_address_profile_table_view_controller_unittest.mm
@@ -38,7 +38,22 @@ kCurrentAddressProfileSavedPrefKey : @(false), kIsUpdateModalPrefKey : @(false), kProfileDataDiffKey : @{}, - kUpdateModalDescriptionKey : @"" + kUpdateModalDescriptionKey : @"", + }; + return prefs; + } + + NSDictionary* GetDataForSaveInAccountModal() { + NSDictionary* prefs = @{ + kAddressPrefKey : @"Test Envelope Address", + kPhonePrefKey : @"Test Phone Number", + kEmailPrefKey : @"Test Email Address", + kCurrentAddressProfileSavedPrefKey : @(false), + kIsUpdateModalPrefKey : @(false), + kProfileDataDiffKey : @{}, + kUpdateModalDescriptionKey : @"", + kSyncingUserEmailKey : @"test@gmail.com", + kIsMigrationToAccountKey : @(true) }; return prefs; } @@ -93,3 +108,20 @@ EXPECT_EQ(1, NumberOfSections()); EXPECT_EQ(6, NumberOfItemsInSection(0)); } + +// Tests that the save address profile modal has been initialized for saving the +// profile to Google Account. +TEST_F(InfobarSaveAddressProfileTableViewControllerTest, + TestSaveInAccountModalInitialization) { + CreateController(); + CheckController(); + InfobarSaveAddressProfileTableViewController* save_view_controller = + base::mac::ObjCCastStrict<InfobarSaveAddressProfileTableViewController>( + controller()); + [save_view_controller + setupModalViewControllerWithPrefs:GetDataForSaveInAccountModal()]; + [save_view_controller loadModel]; + + EXPECT_EQ(1, NumberOfSections()); + EXPECT_EQ(5, NumberOfItemsInSection(0)); +}
diff --git a/ios/chrome/browser/ui/lens/BUILD.gn b/ios/chrome/browser/ui/lens/BUILD.gn index 13e0c5a..6beb6ed 100644 --- a/ios/chrome/browser/ui/lens/BUILD.gn +++ b/ios/chrome/browser/ui/lens/BUILD.gn
@@ -13,6 +13,7 @@ deps = [ ":lens_entrypoint", "//base", + "//components/lens", "//ios/chrome/browser/application_context", "//ios/chrome/browser/browser_state:browser_state", "//ios/chrome/browser/main:public", @@ -35,7 +36,13 @@ "lens_availability.h", "lens_availability.mm", ] - deps = [] + deps = [ + ":lens_entrypoint", + "//base", + "//ios/chrome/browser/shared/public/features:features", + "//ios/public/provider/chrome/browser/lens:lens_api", + "//ui/base", + ] } source_set("lens_entrypoint") {
diff --git a/ios/chrome/browser/ui/lens/DEPS b/ios/chrome/browser/ui/lens/DEPS new file mode 100644 index 0000000..b76d1ca --- /dev/null +++ b/ios/chrome/browser/ui/lens/DEPS
@@ -0,0 +1,3 @@ +include_rules = [ + "+components/lens/lens_metrics.h", +]
diff --git a/ios/chrome/browser/ui/lens/lens_availability.h b/ios/chrome/browser/ui/lens/lens_availability.h index 56fb7eb..f0d03ea 100644 --- a/ios/chrome/browser/ui/lens/lens_availability.h +++ b/ios/chrome/browser/ui/lens/lens_availability.h
@@ -5,6 +5,8 @@ #ifndef IOS_CHROME_BROWSER_UI_LENS_LENS_AVAILABILITY_H_ #define IOS_CHROME_BROWSER_UI_LENS_LENS_AVAILABILITY_H_ +#import "ios/chrome/browser/ui/lens/lens_entrypoint.h" + // Enum representing the possible Lens avaiability statuses on iOS. // Current values should not be renumbered. Please keep in sync with // "IOSLensSupportStatus" in src/tools/metrics/histograms/enums.xml. @@ -12,9 +14,26 @@ LensSearchSupported = 0, NonGoogleSearchEngine = 1, DeviceFormFactorTablet = 2, - kMaxValue = DeviceFormFactorTablet, + DisabledByFlag = 3, + ProviderUnsupported = 4, + kMaxValue = ProviderUnsupported, }; -extern const char kIOSLensSupportStatusHistogram[]; +// Histogram name for the support status of the context menu entrypoint. +extern const char kIOSLensContextMenuSupportStatusHistogramName[]; + +// Histogram name for the support status of the keyboard entrypoint. +extern const char kIOSLensKeyboardSupportStatusHistogramName[]; + +// Histogram name for the support status of the new tab page entrypoint. +extern const char kIOSLensNewTabPageSupportStatusHistogramName[]; + +namespace lens_availability { +// Checks for and performs UMA logging for the availability of the given +// Lens entry point and search engine default provider. +bool CheckAndLogAvailabilityForLensEntryPoint( + LensEntrypoint entry_point, + bool is_google_default_search_engine); +} // namespace lens_availability #endif // IOS_CHROME_BROWSER_UI_LENS_LENS_AVAILABILITY_H_
diff --git a/ios/chrome/browser/ui/lens/lens_availability.mm b/ios/chrome/browser/ui/lens/lens_availability.mm index 30f3c78..33402c60 100644 --- a/ios/chrome/browser/ui/lens/lens_availability.mm +++ b/ios/chrome/browser/ui/lens/lens_availability.mm
@@ -4,9 +4,78 @@ #import "ios/chrome/browser/ui/lens/lens_availability.h" +#import "base/metrics/histogram_functions.h" +#import "base/notreached.h" +#import "ios/chrome/browser/shared/public/features/features.h" +#import "ios/public/provider/chrome/browser/lens/lens_api.h" +#import "ui/base/device_form_factor.h" + #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif -const char kIOSLensSupportStatusHistogram[] = +const char kIOSLensContextMenuSupportStatusHistogramName[] = "Mobile.ContextMenu.LensSupportStatus"; +const char kIOSLensKeyboardSupportStatusHistogramName[] = + "Mobile.Keyboard.LensSupportStatus"; +const char kIOSLensNewTabPageSupportStatusHistogramName[] = + "Mobile.NewTabPage.LensSupportStatus"; + +namespace lens_availability { +bool CheckAndLogAvailabilityForLensEntryPoint( + LensEntrypoint entry_point, + BOOL is_google_default_search_engine) { + // Check if the feature is enabled for the entry point. Starts at + // YES to account for removing flags for launched features. + BOOL flag_enabled = YES; + const char* availability_metric_name = nullptr; + + switch (entry_point) { + case LensEntrypoint::ContextMenu: + if (!base::FeatureList::IsEnabled(kUseLensToSearchForImage)) { + flag_enabled = NO; + } + availability_metric_name = kIOSLensContextMenuSupportStatusHistogramName; + break; + case LensEntrypoint::Keyboard: + if (!base::FeatureList::IsEnabled(kEnableLensInKeyboard)) { + flag_enabled = NO; + } + availability_metric_name = kIOSLensKeyboardSupportStatusHistogramName; + break; + case LensEntrypoint::NewTabPage: + if (!base::FeatureList::IsEnabled(kEnableLensInNTP)) { + flag_enabled = NO; + } + availability_metric_name = kIOSLensNewTabPageSupportStatusHistogramName; + break; + case LensEntrypoint::HomeScreenWidget: + if (!base::FeatureList::IsEnabled(kEnableLensInHomeScreenWidget)) { + flag_enabled = NO; + } + // Home screen widget cannot log availailability. + break; + default: + NOTREACHED() << "Unsupported Lens Entry Point."; + } + + LensSupportStatus lens_support_status; + if (!ios::provider::IsLensSupported()) { + lens_support_status = LensSupportStatus::ProviderUnsupported; + } else if (!flag_enabled) { + lens_support_status = LensSupportStatus::DisabledByFlag; + } else if (!is_google_default_search_engine) { + lens_support_status = LensSupportStatus::NonGoogleSearchEngine; + } else if (ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET) { + lens_support_status = LensSupportStatus::DeviceFormFactorTablet; + } else { + lens_support_status = LensSupportStatus::LensSearchSupported; + } + if (availability_metric_name) { + base::UmaHistogramEnumeration(availability_metric_name, + lens_support_status); + } + + return lens_support_status == LensSupportStatus::LensSearchSupported; +} +} // namespace lens_availability
diff --git a/ios/chrome/browser/ui/lens/lens_coordinator.mm b/ios/chrome/browser/ui/lens/lens_coordinator.mm index de03670..c32ac0e 100644 --- a/ios/chrome/browser/ui/lens/lens_coordinator.mm +++ b/ios/chrome/browser/ui/lens/lens_coordinator.mm
@@ -5,6 +5,7 @@ #import "ios/chrome/browser/ui/lens/lens_coordinator.h" #import "base/strings/sys_string_conversions.h" +#import "components/lens/lens_metrics.h" #import "ios/chrome/browser/application_context/application_context.h" #import "ios/chrome/browser/browser_state/chrome_browser_state.h" #import "ios/chrome/browser/main/browser.h" @@ -37,6 +38,8 @@ #error "This file requires ARC support." #endif +using lens::CameraOpenEntryPoint; + @interface LensCoordinator () <ChromeLensControllerDelegate, LensCommands, CRWWebStateObserver, @@ -218,6 +221,21 @@ [self.baseViewController presentViewController:viewController animated:YES completion:nil]; + + switch (entrypoint) { + case LensEntrypoint::HomeScreenWidget: + RecordCameraOpen(CameraOpenEntryPoint::WIDGET); + break; + case LensEntrypoint::NewTabPage: + RecordCameraOpen(CameraOpenEntryPoint::NEW_TAB_PAGE); + break; + case LensEntrypoint::Keyboard: + RecordCameraOpen(CameraOpenEntryPoint::KEYBOARD); + break; + default: + // Do not record the camera open histogram for other entry points. + break; + } } #pragma mark - ChromeLensControllerDelegate
diff --git a/ios/chrome/browser/ui/main/BUILD.gn b/ios/chrome/browser/ui/main/BUILD.gn index 0a3e9c57..97d4607 100644 --- a/ios/chrome/browser/ui/main/BUILD.gn +++ b/ios/chrome/browser/ui/main/BUILD.gn
@@ -179,6 +179,7 @@ "//ios/chrome/browser/policy", "//ios/chrome/browser/policy:policy_util", "//ios/chrome/browser/prefs:pref_names", + "//ios/chrome/browser/promos_manager:factory", "//ios/chrome/browser/promos_manager:features", "//ios/chrome/browser/screenshot", "//ios/chrome/browser/sessions:scene_util", @@ -212,7 +213,6 @@ "//ios/chrome/browser/ui/ntp:feature_flags", "//ios/chrome/browser/ui/policy:user_policy_scene_agent", "//ios/chrome/browser/ui/promos_manager:promos_manager_scene_agent", - "//ios/chrome/browser/ui/recent_tabs/bring_android_tabs:util", "//ios/chrome/browser/ui/scoped_ui_blocker", "//ios/chrome/browser/ui/settings:settings_root", "//ios/chrome/browser/ui/settings/sync",
diff --git a/ios/chrome/browser/ui/main/scene_controller.mm b/ios/chrome/browser/ui/main/scene_controller.mm index 3dea3c5..a9b3b16 100644 --- a/ios/chrome/browser/ui/main/scene_controller.mm +++ b/ios/chrome/browser/ui/main/scene_controller.mm
@@ -67,6 +67,7 @@ #import "ios/chrome/browser/policy/policy_watcher_browser_agent_observer_bridge.h" #import "ios/chrome/browser/prefs/pref_names.h" #import "ios/chrome/browser/promos_manager/features.h" +#import "ios/chrome/browser/promos_manager/promos_manager_factory.h" #import "ios/chrome/browser/screenshot/screenshot_delegate.h" #import "ios/chrome/browser/sessions/session_saving_scene_agent.h" #import "ios/chrome/browser/sessions/session_service_ios.h" @@ -956,28 +957,25 @@ addAgent:[[PromosManagerSceneAgent alloc] initWithCommandDispatcher:mainCommandDispatcher]]; - if (IsAppStoreRatingEnabled()) { - [self.sceneState - addAgent:[[AppStoreRatingSceneAgent alloc] - initWithPromosManager:GetApplicationContext() - ->GetPromosManager()]]; - } + PromosManager* promosManager = + PromosManagerFactory::GetForBrowserState(browserState); + + if (IsAppStoreRatingEnabled()) { + [self.sceneState addAgent:[[AppStoreRatingSceneAgent alloc] + initWithPromosManager:promosManager]]; + } if (IsWhatsNewEnabled()) { - [self.sceneState - addAgent:[[WhatsNewSceneAgent alloc] - initWithPromosManager:GetApplicationContext() - ->GetPromosManager()]]; + [self.sceneState addAgent:[[WhatsNewSceneAgent alloc] + initWithPromosManager:promosManager]]; } // Do not gate by feature flag so it can run for enabled -> disabled // scenarios. [self.sceneState addAgent:[[CredentialProviderPromoSceneAgent alloc] - initWithPromosManager:GetApplicationContext() - ->GetPromosManager() - prefService:self.sceneState.appState - .mainBrowserState->GetPrefs()]]; + initWithPromosManager:promosManager + prefService:browserState->GetPrefs()]]; } // Determines the mode (normal or incognito) the initial UI should be in. @@ -1305,8 +1303,8 @@ NSString* text = inIncognitoMode - ? l10n_util::GetNSString(IDS_IOS_SNACKBAR_MESSAGE_ICOGNITO_FORCED) - : l10n_util::GetNSString(IDS_IOS_SNACKBAR_MESSAGE_ICOGNITO_DISABLED); + ? l10n_util::GetNSString(IDS_IOS_SNACKBAR_MESSAGE_INCOGNITO_FORCED) + : l10n_util::GetNSString(IDS_IOS_SNACKBAR_MESSAGE_INCOGNITO_DISABLED); MDCSnackbarMessage* message = [MDCSnackbarMessage messageWithText:text]; message.action = action;
diff --git a/ios/chrome/browser/ui/menu/browser_action_factory.mm b/ios/chrome/browser/ui/menu/browser_action_factory.mm index ad448e40..7b5d16d 100644 --- a/ios/chrome/browser/ui/menu/browser_action_factory.mm +++ b/ios/chrome/browser/ui/menu/browser_action_factory.mm
@@ -292,7 +292,7 @@ IDS_IOS_TOOLS_MENU_NEW_INCOGNITO_SEARCH) image:CustomSymbolWithPointSize(kIncognitoSymbol, kSymbolActionPointSize) - type:MenuActionType::StartNewIcognitoSearch + type:MenuActionType::StartNewIncognitoSearch block:^{ OpenNewTabCommand* command = [OpenNewTabCommand commandWithIncognito:YES];
diff --git a/ios/chrome/browser/ui/menu/menu_action_type.h b/ios/chrome/browser/ui/menu/menu_action_type.h index 6c44f0b..ecc55fa 100644 --- a/ios/chrome/browser/ui/menu/menu_action_type.h +++ b/ios/chrome/browser/ui/menu/menu_action_type.h
@@ -44,7 +44,7 @@ ShowQRScanner = 32, StartVoiceSearch = 33, StartNewSearch = 34, - StartNewIcognitoSearch = 35, + StartNewIncognitoSearch = 35, SearchCopiedImage = 36, VisitCopiedLink = 37, SearchCopiedText = 38,
diff --git a/ios/chrome/browser/ui/omnibox/keyboard_assist/BUILD.gn b/ios/chrome/browser/ui/omnibox/keyboard_assist/BUILD.gn index 8a9b02a..0338c8c2 100644 --- a/ios/chrome/browser/ui/omnibox/keyboard_assist/BUILD.gn +++ b/ios/chrome/browser/ui/omnibox/keyboard_assist/BUILD.gn
@@ -33,6 +33,7 @@ "//ios/chrome/browser/shared/public/features", "//ios/chrome/browser/shared/ui/util", "//ios/chrome/browser/shared/ui/util:util_swift", + "//ios/chrome/browser/ui/lens:lens_availability", "//ios/chrome/browser/ui/lens:lens_entrypoint", "//ios/chrome/browser/ui/location_bar:constants", "//ios/chrome/browser/ui/omnibox:features",
diff --git a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views.mm b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views.mm index f080f3f..ef128d7c 100644 --- a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views.mm +++ b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views.mm
@@ -32,11 +32,11 @@ textField.inputAssistantItem.leadingBarButtonGroups = @[]; textField.inputAssistantItem.trailingBarButtonGroups = @[]; OmniboxKeyboardAccessoryView* keyboardAccessoryView = - [[OmniboxKeyboardAccessoryView alloc] - initWithButtons:buttonTitles - delegate:delegate - pasteTarget:textField - templateURLService:templateURLService]; + [[OmniboxKeyboardAccessoryView alloc] initWithButtons:buttonTitles + delegate:delegate + pasteTarget:textField + templateURLService:templateURLService + textField:textField]; [keyboardAccessoryView setAutoresizingMask:UIViewAutoresizingFlexibleWidth]; [textField setInputAccessoryView:keyboardAccessoryView]; return keyboardAccessoryView;
diff --git a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.h b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.h index f77de95..01416bf 100644 --- a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.h +++ b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.h
@@ -23,6 +23,7 @@ delegate:(id<OmniboxAssistiveKeyboardDelegate>)delegate pasteTarget:(id<UIPasteConfigurationSupporting>)pasteTarget templateURLService:(TemplateURLService*)templateURLService + textField:(UITextField*)textField NS_DESIGNATED_INITIALIZER; - (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE;
diff --git a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.mm b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.mm index 769a577..d621c38eb 100644 --- a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.mm +++ b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.mm
@@ -11,6 +11,8 @@ #import "ios/chrome/browser/search_engines/search_engines_util.h" #import "ios/chrome/browser/shared/public/features/features.h" #import "ios/chrome/browser/shared/ui/util/rtl_geometry.h" +#import "ios/chrome/browser/ui/lens/lens_availability.h" +#import "ios/chrome/browser/ui/lens/lens_entrypoint.h" #import "ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views.h" #import "ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views_utils.h" #import "ios/chrome/common/button_configuration_util.h" @@ -34,6 +36,9 @@ // The search stack view that is displayed by this view. @property(nonatomic, weak) UIStackView* searchStackView; +// The text field that this view is an accessory to. +@property(nonatomic, weak) UITextField* textField; + // Called when a keyboard shortcut button is pressed. - (void)keyboardButtonPressed:(NSString*)title; // Creates a button shortcut for `title`. @@ -51,13 +56,15 @@ - (instancetype)initWithButtons:(NSArray<NSString*>*)buttonTitles delegate:(id<OmniboxAssistiveKeyboardDelegate>)delegate pasteTarget:(id<UIPasteConfigurationSupporting>)pasteTarget - templateURLService:(TemplateURLService*)templateURLService { + templateURLService:(TemplateURLService*)templateURLService + textField:(UITextField*)textField { self = [super initWithFrame:CGRectZero inputViewStyle:UIInputViewStyleKeyboard]; if (self) { _buttonTitles = buttonTitles; _delegate = delegate; _pasteTarget = pasteTarget; + _textField = textField; self.translatesAutoresizingMaskIntoConstraints = NO; self.allowsSelfSizing = YES; self.templateURLService = templateURLService; @@ -189,6 +196,17 @@ [_delegate keyPressed:[button currentTitle]]; } +- (void)didMoveToWindow { + [super didMoveToWindow]; + if (!self.window || ![self.textField isFirstResponder]) { + return; + } + // Log the Lens support status when the keyboard is opened. + lens_availability::CheckAndLogAvailabilityForLensEntryPoint( + LensEntrypoint::Keyboard, + [self isGoogleSearchEngine:self.templateURLService]); +} + #pragma mark - Setters - (void)setTemplateURLService:(TemplateURLService*)templateURLService {
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.mm index cd41c71..f021f9b 100644 --- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.mm +++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.mm
@@ -168,7 +168,7 @@ - (void)loadView { // TODO(crbug.com/1365374): Check why largeIconService not available in - // icognito. + // incognito. if (self.largeIconService) { _carouselAttributeProvider = [[FaviconAttributesProvider alloc] initWithFaviconSize:kMaxTileFaviconSize
diff --git a/ios/chrome/browser/ui/open_in/open_in_controller.mm b/ios/chrome/browser/ui/open_in/open_in_controller.mm index e28da613c..0f11362 100644 --- a/ios/chrome/browser/ui/open_in/open_in_controller.mm +++ b/ios/chrome/browser/ui/open_in/open_in_controller.mm
@@ -513,14 +513,16 @@ if (@available(iOS 14.5, *)) { if (IsOpenInDownloadWithWKDownload()) { - [self.download cancelDownload]; + __weak __typeof(self) weakSelf = self; + [self.download cancelDownload:^() { + [weakSelf removeOverlayedView]; + if (ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET) { + [weakSelf hideOpenInToolbar]; + } + }]; + _downloadCanceled = YES; } } - - [self removeOverlayedView]; - if (ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET) - [self hideOpenInToolbar]; - _downloadCanceled = YES; } - (void)removeOverlayedView {
diff --git a/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_mediator.mm b/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_mediator.mm index 5a27945..069b070b 100644 --- a/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_mediator.mm +++ b/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_mediator.mm
@@ -62,7 +62,11 @@ kIsUpdateModalPrefKey : @(config->IsUpdateModal()), kProfileDataDiffKey : config->profile_diff(), kUpdateModalDescriptionKey : - base::SysUTF16ToNSString(config->update_modal_description()) + base::SysUTF16ToNSString(config->update_modal_description()), + kIsMigrationToAccountKey : @(config->is_migration_to_account()), + kSyncingUserEmailKey : config->syncing_user_email() + ? base::SysUTF16ToNSString(config->syncing_user_email().value()) + : @"" }; [_consumer setupModalViewControllerWithPrefs:prefs];
diff --git a/ios/chrome/browser/ui/popup_menu/BUILD.gn b/ios/chrome/browser/ui/popup_menu/BUILD.gn index 3fc7e77..af1d05d3 100644 --- a/ios/chrome/browser/ui/popup_menu/BUILD.gn +++ b/ios/chrome/browser/ui/popup_menu/BUILD.gn
@@ -71,6 +71,7 @@ "//ios/chrome/browser/overlays/public/web_content_area", "//ios/chrome/browser/policy", "//ios/chrome/browser/policy:policy_util", + "//ios/chrome/browser/promos_manager:factory", "//ios/chrome/browser/reading_list", "//ios/chrome/browser/search_engines", "//ios/chrome/browser/search_engines:search_engines_util",
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.h b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.h index ca116ba..f6799ad9 100644 --- a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.h +++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.h
@@ -35,6 +35,7 @@ @protocol PopupMenuCommands; @protocol PriceNotificationsCommands; class PrefService; +class PromosManager; @protocol FindInPageCommands; @protocol TextZoomCommands; class WebNavigationBrowserAgent; @@ -107,6 +108,9 @@ // The Sync Service that provides the status of Sync. @property(nonatomic, assign) syncer::SyncService* syncService; +// The Promos Manager to alert if the user uses What's New. +@property(nonatomic, assign) PromosManager* promosManager; + // Updates the pin state of the tab corresponding to the given `webState` in // `webStateList`. + (void)setTabPinned:(BOOL)pinned
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm index e78548ba..c1e5d65f 100644 --- a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm +++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm
@@ -607,7 +607,7 @@ self.siteInfoDestination = [self createOverflowMenuDestination:IDS_IOS_TOOLS_MENU_SITE_INFORMATION destination:overflow_menu::Destination::SiteInfo - symbolName:kInfoCircleSymbol + symbolName:kToolsMenuSiteInformation systemSymbol:YES accessibilityID:kToolsMenuSiteInformation handler:^{ @@ -1661,7 +1661,7 @@ // Dismisses the menu and opens What's New. - (void)openWhatsNew { if (!WasWhatsNewUsed()) { - SetWhatsNewUsed(); + SetWhatsNewUsed(self.promosManager); } if (self.engagementTracker) {
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm index f5798bb..1918fd1 100644 --- a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm +++ b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm
@@ -22,6 +22,7 @@ #import "ios/chrome/browser/main/browser.h" #import "ios/chrome/browser/ntp/features.h" #import "ios/chrome/browser/overlays/public/overlay_presenter.h" +#import "ios/chrome/browser/promos_manager/promos_manager_factory.h" #import "ios/chrome/browser/reading_list/reading_list_model_factory.h" #import "ios/chrome/browser/search_engines/template_url_service_factory.h" #import "ios/chrome/browser/shared/public/commands/bookmarks_commands.h" @@ -264,6 +265,9 @@ self.overflowMenuMediator.syncService = SyncServiceFactory::GetForBrowserState( self.browser->GetBrowserState()); + self.overflowMenuMediator.promosManager = + PromosManagerFactory::GetForBrowserState( + self.browser->GetBrowserState()); if (IsWebChannelsEnabled()) { self.overflowMenuMediator.followBrowserAgent =
diff --git a/ios/chrome/browser/ui/promos_manager/BUILD.gn b/ios/chrome/browser/ui/promos_manager/BUILD.gn index f0d8e2b..d5ddf878 100644 --- a/ios/chrome/browser/ui/promos_manager/BUILD.gn +++ b/ios/chrome/browser/ui/promos_manager/BUILD.gn
@@ -55,6 +55,7 @@ "//base", "//ios/chrome/app:tests_hook", "//ios/chrome/browser/promos_manager", + "//ios/chrome/browser/promos_manager:factory", "//ios/chrome/browser/promos_manager:types", "//ios/chrome/browser/shared/coordinator/chrome_coordinator", "//third_party/abseil-cpp:absl",
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 0fbada0..6b0f25f 100644 --- a/ios/chrome/browser/ui/promos_manager/promos_manager_coordinator.mm +++ b/ios/chrome/browser/ui/promos_manager/promos_manager_coordinator.mm
@@ -19,6 +19,7 @@ #import "ios/chrome/browser/main/browser.h" #import "ios/chrome/browser/promos_manager/promo_config.h" #import "ios/chrome/browser/promos_manager/promos_manager.h" +#import "ios/chrome/browser/promos_manager/promos_manager_factory.h" #import "ios/chrome/browser/shared/public/commands/command_dispatcher.h" #import "ios/chrome/browser/shared/public/commands/credential_provider_promo_commands.h" #import "ios/chrome/browser/shared/public/commands/promos_manager_commands.h" @@ -109,8 +110,10 @@ if (promosExist) { // Don't create PromosManagerMediator unless promos exist that are // registered with PromosManagerCoordinator via `registerPromos`. + PromosManager* promosManager = + PromosManagerFactory::GetForBrowserState(browser->GetBrowserState()); _mediator = [[PromosManagerMediator alloc] - initWithPromosManager:GetApplicationContext()->GetPromosManager() + initWithPromosManager:promosManager promoImpressionLimits:[self promoImpressionLimits]]; } } @@ -504,7 +507,9 @@ // WhatsNewPromoHandler promo below: if (IsWhatsNewEnabled()) { _displayHandlerPromos[promos_manager::Promo::WhatsNew] = - [[WhatsNewPromoDisplayHandler alloc] init]; + [[WhatsNewPromoDisplayHandler alloc] + initWithPromosManager:PromosManagerFactory::GetForBrowserState( + self.browser->GetBrowserState())]; } // CredentialProvider Promo handler
diff --git a/ios/chrome/browser/ui/recent_tabs/bring_android_tabs/BUILD.gn b/ios/chrome/browser/ui/recent_tabs/bring_android_tabs/BUILD.gn deleted file mode 100644 index fd0be4d..0000000 --- a/ios/chrome/browser/ui/recent_tabs/bring_android_tabs/BUILD.gn +++ /dev/null
@@ -1,35 +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. - -source_set("metrics") { - configs += [ "//build/config/compiler:enable_arc" ] - sources = [ - "bring_android_tabs_metrics.h", - "bring_android_tabs_metrics.mm", - ] - deps = [ "//base" ] -} - -source_set("util") { - configs += [ "//build/config/compiler:enable_arc" ] - sources = [ - "bring_android_tabs_util.h", - "bring_android_tabs_util.mm", - ] - deps = [ - ":metrics", - "//base", - "//components/prefs", - "//components/segmentation_platform/embedder/default_model", - "//components/segmentation_platform/public", - "//ios/chrome/browser/browser_state", - "//ios/chrome/browser/flags:system_flags", - "//ios/chrome/browser/prefs:pref_names", - "//ios/chrome/browser/segmentation_platform", - "//ios/chrome/browser/shared/public/features", - "//ios/chrome/browser/sync", - "//ios/chrome/browser/synced_sessions", - "//ios/chrome/browser/ui/first_run:utils", - ] -}
diff --git a/ios/chrome/browser/ui/recent_tabs/bring_android_tabs/bring_android_tabs_util.h b/ios/chrome/browser/ui/recent_tabs/bring_android_tabs/bring_android_tabs_util.h deleted file mode 100644 index 0623629..0000000 --- a/ios/chrome/browser/ui/recent_tabs/bring_android_tabs/bring_android_tabs_util.h +++ /dev/null
@@ -1,26 +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. - -#ifndef IOS_CHROME_BROWSER_UI_RECENT_TABS_BRING_ANDROID_TABS_BRING_ANDROID_TABS_UTIL_H_ -#define IOS_CHROME_BROWSER_UI_RECENT_TABS_BRING_ANDROID_TABS_BRING_ANDROID_TABS_UTIL_H_ - -#include "ios/chrome/browser/synced_sessions/distant_tab.h" - -class ChromeBrowserState; -class PrefService; - -// Returns a list of the user's recent tabs if they meet all the prerequisites -// to be shown the Bring Android Tabs prompt. Returns an empty list in all other -// cases. -synced_sessions::DistantTabVector PromptTabsForAndroidSwitcher( - ChromeBrowserState* browser_state); - -// Called when the Bring Android Tabs Prompt has been displayed. -// Takes browser state prefs as input. -void OnBringAndroidTabsPromptDisplayed(PrefService* user_prefs); - -// Called when the user interacts with the Bring Android Tabs prompt. -void OnUserInteractWithBringAndroidTabsPrompt(); - -#endif // IOS_CHROME_BROWSER_UI_RECENT_TABS_BRING_ANDROID_TABS_BRING_ANDROID_TABS_UTIL_H_
diff --git a/ios/chrome/browser/ui/recent_tabs/bring_android_tabs/bring_android_tabs_util.mm b/ios/chrome/browser/ui/recent_tabs/bring_android_tabs/bring_android_tabs_util.mm deleted file mode 100644 index 02ea8f5a..0000000 --- a/ios/chrome/browser/ui/recent_tabs/bring_android_tabs/bring_android_tabs_util.mm +++ /dev/null
@@ -1,189 +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 "ios/chrome/browser/ui/recent_tabs/bring_android_tabs/bring_android_tabs_util.h" - -#import <string> - -#import "base/containers/contains.h" -#import "base/files/file.h" -#import "base/metrics/histogram_functions.h" -#import "components/prefs/pref_service.h" -#import "components/segmentation_platform/embedder/default_model/device_switcher_model.h" -#import "components/segmentation_platform/embedder/default_model/device_switcher_result_dispatcher.h" -#import "components/segmentation_platform/public/field_trial_register.h" -#import "components/segmentation_platform/public/result.h" -#import "components/sync/base/sync_prefs.h" -#import "components/sync/driver/sync_service.h" -#import "components/sync/driver/sync_user_settings.h" -#import "components/sync_sessions/session_sync_service.h" -#import "ios/chrome/browser/browser_state/chrome_browser_state.h" -#import "ios/chrome/browser/flags/system_flags.h" -#import "ios/chrome/browser/prefs/pref_names.h" -#import "ios/chrome/browser/segmentation_platform/segmentation_platform_service_factory.h" -#import "ios/chrome/browser/shared/public/features/features.h" -#import "ios/chrome/browser/sync/session_sync_service_factory.h" -#import "ios/chrome/browser/sync/sync_service_factory.h" -#import "ios/chrome/browser/synced_sessions/distant_session.h" -#import "ios/chrome/browser/synced_sessions/distant_tab.h" -#import "ios/chrome/browser/synced_sessions/synced_sessions.h" -#import "ios/chrome/browser/ui/first_run/first_run_util.h" -#import "ios/chrome/browser/ui/recent_tabs/bring_android_tabs/bring_android_tabs_metrics.h" -#import "ui/base/device_form_factor.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace { - -bool prompt_shown_current_session = false; -bool prompt_interacted = false; - -// Returns true if the user is segmented as an Android switcher, either by -// the segmentation platform or by using the forced device switcher flag. -bool UserIsAndroidSwitcher(ChromeBrowserState* browser_state) { - bool device_switcher_forced = - experimental_flags::GetSegmentForForcedDeviceSwitcherExperience() == - segmentation_platform::DeviceSwitcherModel::kAndroidPhoneLabel; - if (device_switcher_forced) { - return true; - } - - segmentation_platform::DeviceSwitcherResultDispatcher* dispatcher = - segmentation_platform::SegmentationPlatformServiceFactory:: - GetDispatcherForBrowserState(browser_state); - - segmentation_platform::ClassificationResult result = - dispatcher->GetCachedClassificationResult(); - if (result.status != segmentation_platform::PredictionStatus::kSucceeded) { - base::UmaHistogramEnumeration( - bring_android_tabs::kPromptAttemptStatusHistogramName, - bring_android_tabs::PromptAttemptStatus::kSegmentationIncomplete); - return false; - } - - if (base::Contains( - result.ordered_labels, - segmentation_platform::DeviceSwitcherModel::kIosPhoneChromeLabel)) { - base::UmaHistogramEnumeration( - bring_android_tabs::kPromptAttemptStatusHistogramName, - bring_android_tabs::PromptAttemptStatus::kNotAndroidSwitcher); - return false; - } - - if (result.ordered_labels[0] == - segmentation_platform::DeviceSwitcherModel::kNotSyncedLabel) { - base::UmaHistogramEnumeration( - bring_android_tabs::kPromptAttemptStatusHistogramName, - bring_android_tabs::PromptAttemptStatus::kSyncDisabled); - } - - if (result.ordered_labels[0] != - segmentation_platform::DeviceSwitcherModel::kAndroidPhoneLabel) { - base::UmaHistogramEnumeration( - bring_android_tabs::kPromptAttemptStatusHistogramName, - bring_android_tabs::PromptAttemptStatus::kNotAndroidSwitcher); - return false; - } - return true; -} - -// Returns true if the user is eligible for the Bring Android Tabs prompt. -bool UserEligibleForAndroidSwitcherPrompt(ChromeBrowserState* browser_state) { - absl::optional<base::Time> first_run_time = GetFirstRunTime(); - bool first_run_over_7_days_ago = - first_run_time.has_value() && - (base::Time::Now() - first_run_time.value()) > base::Days(7); - if (!ShouldPresentFirstRunExperience() && first_run_over_7_days_ago) { - return false; - } - - if (GetBringYourOwnTabsPromptType() == - BringYourOwnTabsPromptType::kDisabled) { - return false; - } - - if (ui::GetDeviceFormFactor() != ui::DEVICE_FORM_FACTOR_PHONE) { - return false; - } - - bool prompt_shown = browser_state->GetPrefs()->GetBoolean( - prefs::kIosBringAndroidTabsPromptDisplayed); - if (prompt_interacted || (prompt_shown && !prompt_shown_current_session)) { - base::UmaHistogramEnumeration( - bring_android_tabs::kPromptAttemptStatusHistogramName, - bring_android_tabs::PromptAttemptStatus::kPromptShownAndDismissed); - return false; - } - - return UserIsAndroidSwitcher(browser_state); -} - -// Returns the set of DistantTabs for an android switcher. -synced_sessions::DistantTabVector AndroidSwitcherTabs( - ChromeBrowserState* browser_state) { - syncer::SyncService* sync_service = - SyncServiceFactory::GetForBrowserState(browser_state); - bool tab_sync_disabled = - !sync_service || !sync_service->GetUserSettings()->GetSelectedTypes().Has( - syncer::UserSelectableType::kTabs); - if (tab_sync_disabled) { - base::UmaHistogramEnumeration( - bring_android_tabs::kPromptAttemptStatusHistogramName, - bring_android_tabs::PromptAttemptStatus::kTabSyncDisabled); - return synced_sessions::DistantTabVector(); - } - - sync_sessions::SessionSyncService* session_sync_service = - SessionSyncServiceFactory::GetForBrowserState(browser_state); - auto synced_sessions = - std::make_unique<synced_sessions::SyncedSessions>(session_sync_service); - synced_sessions::DistantTabVector android_tabs; - - for (size_t s = 0; s < synced_sessions->GetSessionCount(); s++) { - const synced_sessions::DistantSession* session = - synced_sessions->GetSession(s); - for (auto const& tab : session->tabs) { - std::unique_ptr<synced_sessions::DistantTab> tab_copy = - std::make_unique<synced_sessions::DistantTab>(); - tab_copy->session_tag = tab->session_tag; - tab_copy->tab_id = tab->tab_id; - tab_copy->title = tab->title; - tab_copy->virtual_url = tab->virtual_url; - android_tabs.push_back(std::move(tab_copy)); - } - } - - return android_tabs; -} - -} // namespace - -synced_sessions::DistantTabVector PromptTabsForAndroidSwitcher( - ChromeBrowserState* browser_state) { - if (!UserEligibleForAndroidSwitcherPrompt(browser_state)) { - return synced_sessions::DistantTabVector(); - } - synced_sessions::DistantTabVector tabs = AndroidSwitcherTabs(browser_state); - if (tabs.empty()) { - base::UmaHistogramEnumeration( - bring_android_tabs::kPromptAttemptStatusHistogramName, - bring_android_tabs::PromptAttemptStatus::kNoActiveTabs); - } else { - base::UmaHistogramEnumeration( - bring_android_tabs::kPromptAttemptStatusHistogramName, - bring_android_tabs::PromptAttemptStatus::kSuccess); - } - return tabs; -} - -void OnBringAndroidTabsPromptDisplayed(PrefService* user_prefs) { - user_prefs->SetBoolean(prefs::kIosBringAndroidTabsPromptDisplayed, true); - prompt_shown_current_session = true; -} - -void OnUserInteractWithPrompt() { - prompt_interacted = true; -}
diff --git a/ios/chrome/browser/ui/settings/privacy/privacy_table_view_controller.mm b/ios/chrome/browser/ui/settings/privacy/privacy_table_view_controller.mm index 30f35d0d9..5b32bf7b 100644 --- a/ios/chrome/browser/ui/settings/privacy/privacy_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/privacy/privacy_table_view_controller.mm
@@ -582,7 +582,7 @@ - (void)didTapIncognitoReauthDisabledInfoButton:(UIButton*)buttonView { NSString* popoverMessage = IsIncognitoModeDisabled(_browserState->GetPrefs()) - ? l10n_util::GetNSString(IDS_IOS_SNACKBAR_MESSAGE_ICOGNITO_DISABLED) + ? l10n_util::GetNSString(IDS_IOS_SNACKBAR_MESSAGE_INCOGNITO_DISABLED) : l10n_util::GetNSString( IDS_IOS_INCOGNITO_REAUTH_SET_UP_PASSCODE_HINT); InfoPopoverViewController* popover = @@ -600,8 +600,8 @@ - (void)didTapIncognitoInterstitialDisabledInfoButton:(UIButton*)buttonView { NSString* popoverMessage = IsIncognitoModeDisabled(_browserState->GetPrefs()) - ? l10n_util::GetNSString(IDS_IOS_SNACKBAR_MESSAGE_ICOGNITO_DISABLED) - : l10n_util::GetNSString(IDS_IOS_SNACKBAR_MESSAGE_ICOGNITO_FORCED); + ? l10n_util::GetNSString(IDS_IOS_SNACKBAR_MESSAGE_INCOGNITO_DISABLED) + : l10n_util::GetNSString(IDS_IOS_SNACKBAR_MESSAGE_INCOGNITO_FORCED); EnterpriseInfoPopoverViewController* popover = [[EnterpriseInfoPopoverViewController alloc] initWithMessage:popoverMessage
diff --git a/ios/chrome/browser/ui/sharing/sharing_coordinator.h b/ios/chrome/browser/ui/sharing/sharing_coordinator.h index 0c728cf..ac23523 100644 --- a/ios/chrome/browser/ui/sharing/sharing_coordinator.h +++ b/ios/chrome/browser/ui/sharing/sharing_coordinator.h
@@ -9,6 +9,7 @@ #import "ios/chrome/browser/shared/coordinator/chrome_coordinator/chrome_coordinator.h" +@protocol ActivityServiceCommands; @class SharingParams; class Browser; @@ -50,6 +51,16 @@ - (instancetype)init NS_UNAVAILABLE; - (instancetype)initWithBaseViewController:(UIViewController*)viewController browser:(Browser*)browser NS_UNAVAILABLE; + +// Activity Handler. +// Adding this to be able to tell the BrowserCoordinator to start a new +// coordinator after stopping this one. +@property(nonatomic, weak) id<ActivityServiceCommands> activityHandler; + +// If there is a download currently happening, this cancels it and triggers a +// new coordinator to be created. +- (void)cancelIfNecessaryAndCreateNewCoordinator; + @end #endif // IOS_CHROME_BROWSER_UI_SHARING_SHARING_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/sharing/sharing_coordinator.mm b/ios/chrome/browser/ui/sharing/sharing_coordinator.mm index 6180697..80445a7 100644 --- a/ios/chrome/browser/ui/sharing/sharing_coordinator.mm +++ b/ios/chrome/browser/ui/sharing/sharing_coordinator.mm
@@ -15,6 +15,7 @@ #import "base/threading/scoped_blocking_call.h" #import "ios/chrome/browser/main/browser.h" #import "ios/chrome/browser/open_in/open_in_tab_helper.h" +#import "ios/chrome/browser/shared/public/commands/activity_service_commands.h" #import "ios/chrome/browser/shared/public/commands/command_dispatcher.h" #import "ios/chrome/browser/shared/public/commands/qr_generation_commands.h" #import "ios/chrome/browser/shared/public/commands/share_download_overlay_commands.h" @@ -128,6 +129,12 @@ // YES if the file download was canceled. @property(nonatomic, assign) BOOL isDownloadCanceled; +// YES if the file download is in the process of cancelling. +@property(nonatomic, assign) BOOL isCancelling; + +// YES if this coordinator should be restarted. +@property(nonatomic, assign) BOOL shouldRestartCoordinator; + // Command dispatcher. @property(nonatomic, strong) CommandDispatcher* dispatcher; @@ -190,6 +197,26 @@ return self; } +// The behaviour is predictable: the coordinator will be stopped, either right +// now or delayed (in -cancelDownload method). If we are already in the process +// of cancelling a download, do not call this again. +- (void)cancelIfNecessaryAndCreateNewCoordinator { + // Download has been cancelled or currently not download (so no overlay). + if (self.isDownloadCanceled || !self.overlay) { + // Stop the coordinator now. + [self stopAndStartNewCoordinator]; + } else if (!self.isCancelling) { + // Delay stopping the coordinator after the download has been cancelled. + self.shouldRestartCoordinator = YES; + [self cancelDownload]; + } +} + +// Stop this coordinator and start a new one. +- (void)stopAndStartNewCoordinator { + [self.activityHandler stopAndStartSharingCoordinator]; +} + #pragma mark - ChromeCoordinator - (void)start { @@ -374,14 +401,13 @@ // Removes downloaded file at `self.filePath`. - (void)removeFile { if ([[NSFileManager defaultManager] fileExistsAtPath:self.filePath]) { - __weak SharingCoordinator* weakSelf = self; + NSString* tempFilePath = self.filePath; base::ThreadPool::PostTask( FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, base::BindOnce(^{ NSError* error = nil; - if (![[NSFileManager defaultManager] - removeItemAtPath:weakSelf.filePath - error:&error]) { + if (![[NSFileManager defaultManager] removeItemAtPath:tempFilePath + error:&error]) { DLOG(ERROR) << "Failed to remove file: " << base::SysNSStringToUTF8([error description]); } @@ -415,10 +441,19 @@ #pragma mark - ShareDownloadOverlayCommands - (void)cancelDownload { - self.isDownloadCanceled = YES; [self stopDisplayDownloadOverlay]; if (@available(iOS 14.5, *)) { - [self.download cancelDownload]; + self.isCancelling = YES; + __weak SharingCoordinator* weakSelf = self; + [self.download cancelDownload:^() { + weakSelf.isDownloadCanceled = YES; + weakSelf.isCancelling = NO; + if (weakSelf.shouldRestartCoordinator) { + // Self will be destroyed after this call so it should not be used + // anymore. + [weakSelf stopAndStartNewCoordinator]; + } + }]; } UMA_HISTOGRAM_ENUMERATION(kOpenInDownloadHistogram, OpenInDownloadResult::kCanceled);
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn b/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn index 89ed382..0bc758a9 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn
@@ -29,6 +29,7 @@ "//components/strings", "//ios/chrome/app/strings", "//ios/chrome/browser/bookmarks", + "//ios/chrome/browser/bring_android_tabs", "//ios/chrome/browser/browser_state", "//ios/chrome/browser/commerce:commerce", "//ios/chrome/browser/drag_and_drop", @@ -55,6 +56,7 @@ "//ios/chrome/browser/ui/alert_coordinator", "//ios/chrome/browser/ui/bookmarks", "//ios/chrome/browser/ui/bookmarks/editor", + "//ios/chrome/browser/ui/bring_android_tabs", "//ios/chrome/browser/ui/commerce:price_card", "//ios/chrome/browser/ui/default_promo", "//ios/chrome/browser/ui/gestures",
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm index 02c40d2..4da435e 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm
@@ -397,17 +397,18 @@ [self.selectedEditingItemIDs removeAllObjects]; [self.selectedSharableEditingItemIDs removeAllObjects]; - // After transition from other modes to the normal mode, the - // selection border doesn't show around the selection item. The - // collection view needs to be updated with the selected item again - // for it to appear correctly. + // After transition from other modes to the normal mode, the selection + // border doesn't show around the selected item, because reloading + // operations like `reloadSections` loose the selected items. The + // collection view needs to be updated with the selected item again for it + // to appear correctly. [self deselectAllCollectionViewItemsAnimated:NO]; [self selectCollectionViewItemWithID:self.selectedItemID animated:NO scrollPosition:UICollectionViewScrollPositionNone]; [self updateFractionVisibleOfLastItem]; - } - self.searchText = nil; + } + self.searchText = nil; } - (void)setSearchText:(NSString*)searchText { @@ -1406,7 +1407,19 @@ // The header should appear or disappear. Reload the section. NSIndexSet* openTabsSection = [NSIndexSet indexSetWithIndex:kOpenTabsSectionIndex]; - [self.collectionView reloadSections:openTabsSection]; + // Prevent the animation, as it leads to a jarrying effect when closing all + // inactive tabs: the inactive tabs view controller gets popped, and the + // underlying regular Tab Grid moves tabs up. + // Note: this could be revisited when supporting iPad, as the user could + // have closed all inactive tabs in a different window. + [UIView performWithoutAnimation:^{ + [self.collectionView reloadSections:openTabsSection]; + }]; + // Make sure to restore the selection. `reloadSections` cleared it. + // https://developer.apple.com/forums/thread/656529 + [self selectCollectionViewItemWithID:self.selectedItemID + animated:NO + scrollPosition:UICollectionViewScrollPositionNone]; } else { // The header just needs to be updated with the new count. NSIndexPath* indexPath =
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/BUILD.gn b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/BUILD.gn index eae2eb84..b3ec8c6 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/BUILD.gn +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/BUILD.gn
@@ -16,10 +16,12 @@ ":inactive_tabs_ui", "//base", "//components/favicon/ios", + "//ios/chrome/app/strings", "//ios/chrome/browser/main:public", "//ios/chrome/browser/shared/coordinator/chrome_coordinator", "//ios/chrome/browser/snapshots", "//ios/chrome/browser/tabs/inactive_tabs:features", + "//ios/chrome/browser/ui/alert_coordinator", "//ios/chrome/browser/ui/tab_switcher", "//ios/chrome/browser/ui/tab_switcher:tab_utils", "//ios/chrome/browser/ui/tab_switcher/tab_grid/grid:grid_ui", @@ -41,6 +43,7 @@ "//ios/chrome/browser/tabs/inactive_tabs:features", "//ios/chrome/browser/ui/tab_switcher/tab_grid:tab_grid_ui_constants", "//ios/chrome/browser/ui/tab_switcher/tab_grid/grid:grid_ui", + "//ios/chrome/common/ui/colors", "//ui/base", ] }
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_button_mediator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_button_mediator.mm index 131fbacf..f2842af8 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_button_mediator.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_button_mediator.mm
@@ -86,6 +86,10 @@ didDetachWebState:(web::WebState*)webState atIndex:(int)atIndex { DCHECK_EQ(_webStateList, webStateList); + if (_webStateList->IsBatchInProgress()) { + // Consumer will be updated at the end of the batch. + return; + } [_consumer advertizeInactiveTabsWithCount:_webStateList->count()]; } @@ -113,11 +117,12 @@ } - (void)webStateListWillBeginBatchOperation:(WebStateList*)webStateList { - NOTREACHED(); + // No-op. This is called when all inactive tabs are closed at once. } - (void)webStateListBatchOperationEnded:(WebStateList*)webStateList { - NOTREACHED(); + DCHECK_EQ(_webStateList, webStateList); + [_consumer advertizeInactiveTabsWithCount:_webStateList->count()]; } - (void)webStateListDestroyed:(WebStateList*)webStateList {
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_coordinator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_coordinator.mm index db49a24..e1dca09 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_coordinator.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_coordinator.mm
@@ -7,13 +7,17 @@ #import <UIKit/UIKit.h> #import "base/notreached.h" +#import "base/strings/sys_string_conversions.h" #import "ios/chrome/browser/main/browser.h" #import "ios/chrome/browser/snapshots/snapshot_browser_agent.h" #import "ios/chrome/browser/tabs/inactive_tabs/features.h" +#import "ios/chrome/browser/ui/alert_coordinator/action_sheet_coordinator.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_mediator.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_view_controller.h" #import "ios/chrome/browser/web_state_list/web_state_list.h" +#import "ios/chrome/grit/ios_strings.h" +#import "ui/base/l10n/l10n_util.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -203,4 +207,49 @@ [self.delegate inactiveTabsCoordinatorDidFinish:self]; } +- (void)inactiveTabsViewController: + (InactiveTabsViewController*)inactiveTabsViewController + didTapCloseAllInactiveBarButtonItem:(UIBarButtonItem*)barButtonItem { + NSInteger numberOfTabs = [self.mediator numberOfItems]; + DCHECK_GT(numberOfTabs, 0); + + NSString* title; + if (numberOfTabs > 99) { + title = l10n_util::GetNSString( + IDS_IOS_INACTIVE_TABS_CLOSE_ALL_CONFIRMATION_MANY); + } else { + title = base::SysUTF16ToNSString(l10n_util::GetPluralStringFUTF16( + IDS_IOS_INACTIVE_TABS_CLOSE_ALL_CONFIRMATION, numberOfTabs)); + } + NSString* message = l10n_util::GetNSString( + IDS_IOS_INACTIVE_TABS_CLOSE_ALL_CONFIRMATION_MESSAGE); + + ActionSheetCoordinator* actionSheetCoordinator = + [[ActionSheetCoordinator alloc] + initWithBaseViewController:self.baseViewController + browser:self.browser + title:title + message:message + barButtonItem:barButtonItem]; + + __weak __typeof(self) weakSelf = self; + NSString* closeAllActionTitle = l10n_util::GetNSString( + IDS_IOS_INACTIVE_TABS_CLOSE_ALL_CONFIRMATION_OPTION); + [actionSheetCoordinator addItemWithTitle:closeAllActionTitle + action:^{ + [weakSelf closeAllInactiveTabs]; + } + style:UIAlertActionStyleDestructive]; + + [actionSheetCoordinator start]; +} + +#pragma mark - Private + +// Called when the user confirmed wanting to close all inactive tabs. +- (void)closeAllInactiveTabs { + [self.delegate inactiveTabsCoordinatorDidFinish:self]; + [self.mediator shutdownAndCloseAllItems]; +} + @end
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_mediator.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_mediator.h index 76c81858..ab9bfbe 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_mediator.h +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_mediator.h
@@ -24,9 +24,18 @@ NS_DESIGNATED_INITIALIZER; - (instancetype)init NS_UNAVAILABLE; +// Returns the number of items pushed to the consumer. +- (NSInteger)numberOfItems; + // Tells the receiver to close the item with the `itemID` identifier. - (void)closeItemWithID:(NSString*)itemID; +// Tells the receiver to stop observing the list and pushing updates to its +// consumer, and to close all items of the web state list (the consumer will +// disappear, there is no need to empty it explicitly). +// Note: this mediator is then no longer useful and should be disposed of. +- (void)shutdownAndCloseAllItems; + @end #endif // IOS_CHROME_BROWSER_UI_TAB_SWITCHER_TAB_GRID_INACTIVE_TABS_INACTIVE_TABS_MEDIATOR_H_
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_mediator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_mediator.mm index 2d819a6..55e933c 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_mediator.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_mediator.mm
@@ -20,6 +20,7 @@ #import "ios/chrome/browser/web_state_list/web_state_list_observer_bridge.h" #import "ios/web/public/web_state.h" #import "ios/web/public/web_state_observer_bridge.h" +#import "ui/base/device_form_factor.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -52,6 +53,24 @@ return items; } +// Observes all web states from the list with the scoped web state observer. +void AddWebStateObservations( + ScopedWebStateObservation* scoped_web_state_observation, + WebStateList* web_state_list) { + for (int i = 0; i < web_state_list->count(); i++) { + web::WebState* web_state = web_state_list->GetWebStateAt(i); + scoped_web_state_observation->AddObservation(web_state); + } +} + +// Pushes tab items created from the web state list to the consumer. They are +// sorted by recency (see `CreateItemsOrderedByRecency`). +void PopulateConsumerItems(id<TabCollectionConsumer> consumer, + WebStateList* web_state_list) { + [consumer populateItems:CreateItemsOrderedByRecency(web_state_list) + selectedItemID:nil]; +} + } // namespace @interface InactiveTabsMediator () <CRWWebStateObserver, @@ -101,14 +120,10 @@ std::make_unique<web::WebStateObserverBridge>(self); _scopedWebStateObservation = std::make_unique<ScopedWebStateObservation>( _webStateObserverBridge.get()); - for (int i = 0; i < _webStateList->count(); i++) { - web::WebState* webState = _webStateList->GetWebStateAt(i); - _scopedWebStateObservation->AddObservation(webState); - } + AddWebStateObservations(_scopedWebStateObservation.get(), _webStateList); // Push the tabs to the consumer. - [_consumer populateItems:CreateItemsOrderedByRecency(_webStateList) - selectedItemID:nil]; + PopulateConsumerItems(_consumer, _webStateList); // TODO(crbug.com/1421321): The snapshot cache never returns snapshots. // Investigate why. @@ -124,6 +139,10 @@ [_snapshotCache removeObserver:self]; } +- (NSInteger)numberOfItems { + return _webStateList->count(); +} + - (void)closeItemWithID:(NSString*)itemID { // TODO(crbug.com/1418021): Add metrics when the user closes an inactive tab. int index = GetTabIndex(_webStateList, WebStateSearchCriteria{ @@ -134,6 +153,20 @@ } } +- (void)shutdownAndCloseAllItems { + _consumer = nil; + _scopedWebStateObservation->RemoveAllObservations(); + _scopedWebStateObservation.reset(); + _scopedWebStateListObservation.reset(); + [_snapshotCache removeObserver:self]; + _appearanceCache = nil; + + // TODO(crbug.com/1418021): Add metrics when the user closes all inactive + // tabs. + _webStateList->CloseAllWebStates(WebStateList::CLOSE_USER_ACTION); + _webStateList = nullptr; +} + #pragma mark - CRWWebStateObserver - (void)webStateDidStartLoading:(web::WebState*)webState { @@ -245,7 +278,21 @@ didInsertWebState:(web::WebState*)webState atIndex:(int)index activating:(BOOL)activating { - NOTREACHED(); + // Insertions are only supported for iPad multiwindow support when changing + // the user settings for Inactive Tabs (i.e. when picking a longer inactivity + // threshold). + DCHECK_EQ(ui::GetDeviceFormFactor(), ui::DEVICE_FORM_FACTOR_TABLET); + DCHECK_EQ(_webStateList, webStateList); + if (_webStateList->IsBatchInProgress()) { + // Updates are handled in the batch operation observer methods. + return; + } + + [_consumer insertItem:GetTabSwitcherItem(webState) + atIndex:index + selectedItemID:nil]; + + _scopedWebStateObservation->AddObservation(webState); } - (void)webStateList:(WebStateList*)webStateList @@ -266,7 +313,10 @@ willDetachWebState:(web::WebState*)webState atIndex:(int)index { DCHECK_EQ(_webStateList, webStateList); - DCHECK(!webStateList->IsBatchInProgress()); + if (_webStateList->IsBatchInProgress()) { + // Updates are handled in the batch operation observer methods. + return; + } [_consumer removeItemWithID:webState->GetStableIdentifier() selectedItemID:nil]; @@ -302,11 +352,15 @@ } - (void)webStateListWillBeginBatchOperation:(WebStateList*)webStateList { - NOTREACHED(); + DCHECK_EQ(_webStateList, webStateList); + _scopedWebStateObservation->RemoveAllObservations(); } - (void)webStateListBatchOperationEnded:(WebStateList*)webStateList { - NOTREACHED(); + DCHECK_EQ(_webStateList, webStateList); + + AddWebStateObservations(_scopedWebStateObservation.get(), _webStateList); + PopulateConsumerItems(_consumer, _webStateList); } - (void)webStateListDestroyed:(WebStateList*)webStateList {
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_view_controller.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_view_controller.h index 5ca2064..6c95ef1 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_view_controller.h +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_view_controller.h
@@ -18,6 +18,11 @@ - (void)inactiveTabsViewControllerDidTapBackButton: (InactiveTabsViewController*)inactiveTabsViewController; +// Invoked when the button to close all inactive tabs is tapped. +- (void)inactiveTabsViewController: + (InactiveTabsViewController*)inactiveTabsViewController + didTapCloseAllInactiveBarButtonItem:(UIBarButtonItem*)barButtonItem; + @end // Displays the list of inactive tabs.
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_view_controller.mm index 7da265a..6f58fea 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_view_controller.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_view_controller.mm
@@ -7,6 +7,7 @@ #import "ios/chrome/browser/tabs/inactive_tabs/features.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_constants.h" +#import "ios/chrome/common/ui/colors/semantic_color_names.h" #import "ios/chrome/grit/ios_strings.h" #import "ui/base/l10n/l10n_util_mac.h" @@ -19,6 +20,12 @@ // The embedded navigation bar. @property(nonatomic, readonly) UINavigationBar* navigationBar; +// The embedded bottom toolbar bar. +@property(nonatomic, readonly) UIToolbar* bottomBar; + +// The Close All Inactive button. +@property(nonatomic, readonly) UIBarButtonItem* closeAllInactiveButton; + @end @implementation InactiveTabsViewController @@ -58,6 +65,33 @@ _navigationBar.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:_navigationBar]; + // Add the bottom toolbar with the Close All Inactive button. + NSString* buttonTitle = + l10n_util::GetNSString(IDS_IOS_INACTIVE_TABS_CLOSE_ALL_BUTTON); + __weak __typeof(self) weakSelf = self; + UIAction* closeAllInactiveAction = + [UIAction actionWithTitle:buttonTitle + image:nil + identifier:nil + handler:^(UIAction* action) { + [weakSelf didTapCloseAllInactive]; + }]; + _closeAllInactiveButton = + [[UIBarButtonItem alloc] initWithPrimaryAction:closeAllInactiveAction]; + _closeAllInactiveButton.accessibilityIdentifier = kInactiveTabGridIdentifier; + + _bottomBar = [[UIToolbar alloc] init]; + _bottomBar.barStyle = UIBarStyleBlack; + _bottomBar.translucent = YES; + _bottomBar.tintColor = [UIColor colorNamed:kRed500Color]; + UIBarButtonItem* flexibleSpace = [[UIBarButtonItem alloc] + initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace + target:nil + action:nil]; + _bottomBar.items = @[ flexibleSpace, _closeAllInactiveButton, flexibleSpace ]; + _bottomBar.translatesAutoresizingMaskIntoConstraints = NO; + [self.view addSubview:_bottomBar]; + [NSLayoutConstraint activateConstraints:@[ [gridView.topAnchor constraintEqualToAnchor:self.view.topAnchor], [gridView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor], @@ -69,13 +103,22 @@ constraintEqualToAnchor:self.view.leadingAnchor], [_navigationBar.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor], + [_bottomBar.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor], + [_bottomBar.trailingAnchor + constraintEqualToAnchor:self.view.trailingAnchor], + [_bottomBar.bottomAnchor + constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor], ]]; } - (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; + CGFloat topInset = + CGRectGetMaxY(_navigationBar.frame) - CGRectGetMinY(self.view.bounds); + CGFloat bottomInset = + CGRectGetMaxY(self.view.bounds) - CGRectGetMinY(_bottomBar.frame); _gridViewController.gridView.contentInset = - UIEdgeInsetsMake(CGRectGetMaxY(_navigationBar.frame), 0, 0, 0); + UIEdgeInsetsMake(topInset, 0, bottomInset, 0); } #pragma mark - UIBarPositioningDelegate @@ -94,4 +137,12 @@ return NO; } +#pragma mark - Private + +// Called when the user tapped the Close All Inactive button. +- (void)didTapCloseAllInactive { + [self.delegate inactiveTabsViewController:self + didTapCloseAllInactiveBarButtonItem:self.closeAllInactiveButton]; +} + @end
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_bottom_toolbar.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_bottom_toolbar.mm index 156ba1f4..9c19a80a 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_bottom_toolbar.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_bottom_toolbar.mm
@@ -5,6 +5,7 @@ #import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_bottom_toolbar.h" #import "base/strings/sys_string_conversions.h" +#import "ios/chrome/browser/shared/public/features/features.h" #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h" #import "ios/chrome/browser/ui/icons/symbols.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.h" @@ -335,8 +336,13 @@ // When a11y font size is used, long press on UIBarButtonItem will show a // built-in a11y modal panel with image and title if set. The size is not // taken into account. - _newTabButtonItem.image = - CustomSymbolWithPointSize(kPlusCircleFillSymbol, 0); + if (base::FeatureList::IsEnabled(kSFSymbolsFollowup)) { + _newTabButtonItem.image = + CustomSymbolWithPointSize(kPlusCircleFillSymbol, 0); + } else { + _newTabButtonItem.image = + CustomSymbolWithPointSize(kLegacyPlusCircleFillSymbol, 0); + } } else { UIImage* regularImage = [UIImage imageNamed:@"tab_grid_new_tab_floating_button_ios14"];
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_constants.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_constants.h index 309343ac..f01628d 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_constants.h +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_constants.h
@@ -28,6 +28,7 @@ extern NSString* const kRegularTabGridIdentifier; extern NSString* const kIncognitoTabGridIdentifier; extern NSString* const kInactiveTabGridIdentifier; +extern NSString* const kInactiveTabGridCloseAllButtonIdentifier; extern NSString* const kTabGridEditButtonIdentifier; extern NSString* const kTabGridEditCloseTabsButtonIdentifier;
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_constants.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_constants.mm index a7d2119..c8cd9ef 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_constants.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_constants.mm
@@ -40,6 +40,8 @@ NSString* const kRegularTabGridIdentifier = @"kRegularTabGridIdentifier"; NSString* const kIncognitoTabGridIdentifier = @"kIncognitoTabGridIdentifier"; NSString* const kInactiveTabGridIdentifier = @"kInactiveTabGridIdentifier"; +NSString* const kInactiveTabGridCloseAllButtonIdentifier = + @"kInactiveTabGridCloseAllButtonIdentifier"; NSString* const kTabGridEditButtonIdentifier = @"kTabGridEditButtonIdentifier"; NSString* const kTabGridEditCloseTabsButtonIdentifier =
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm index 87eb634..5f074b36 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm
@@ -15,6 +15,8 @@ #import "components/search_engines/template_url_service.h" #import "components/strings/grit/components_strings.h" #import "ios/chrome/browser/bookmarks/local_or_syncable_bookmark_model_factory.h" +#import "ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service.h" +#import "ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service_factory.h" #import "ios/chrome/browser/browser_state/chrome_browser_state.h" #import "ios/chrome/browser/main/browser.h" #import "ios/chrome/browser/main/browser_util.h" @@ -24,6 +26,7 @@ #import "ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h" #import "ios/chrome/browser/shared/public/commands/application_commands.h" #import "ios/chrome/browser/shared/public/commands/bookmarks_commands.h" +#import "ios/chrome/browser/shared/public/commands/bring_android_tabs_commands.h" #import "ios/chrome/browser/shared/public/commands/browser_commands.h" #import "ios/chrome/browser/shared/public/commands/browsing_data_commands.h" #import "ios/chrome/browser/shared/public/commands/command_dispatcher.h" @@ -40,6 +43,7 @@ #import "ios/chrome/browser/tabs/inactive_tabs/features.h" #import "ios/chrome/browser/ui/alert_coordinator/action_sheet_coordinator.h" #import "ios/chrome/browser/ui/bookmarks/bookmarks_coordinator.h" +#import "ios/chrome/browser/ui/bring_android_tabs/bring_android_tabs_prompt_coordinator.h" #import "ios/chrome/browser/ui/commerce/price_card/price_card_mediator.h" #import "ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_scheduler.h" #import "ios/chrome/browser/ui/gestures/view_controller_trait_collection_observer.h" @@ -86,7 +90,8 @@ #error "This file requires ARC support." #endif -@interface TabGridCoordinator () <RecentTabsPresentationDelegate, +@interface TabGridCoordinator () <BringAndroidTabsCommands, + RecentTabsPresentationDelegate, HistoryPresentationDelegate, InactiveTabsCoordinatorDelegate, SceneStateObserver, @@ -107,6 +112,10 @@ // The coordinator that shows the bookmarking UI after the user taps the Add // to Bookmarks button. BookmarksCoordinator* _bookmarksCoordinator; + + // The coordinator that manages the "Bring Android Tabs" prompt for Android + // switchers. + BringAndroidTabsPromptCoordinator* _bringAndroidTabsPromptCoordinator; } // Browser that contain tabs from the main pane (i.e. non-incognito). @@ -379,6 +388,13 @@ [DefaultBrowserSceneAgent agentFromScene:sceneState]; [agent.nonModalScheduler logTabGridEntered]; + // Store the currentActivePage at this point in code, to be potentially used + // during execution of the dispatched block to get the transition from Browser + // to Tab Grid. That is because in some instances the active page might change + // before the block gets executed, for example when closing the last tab in + // incognito (crbug.com/1136882). + TabGridPage currentActivePage = self.baseViewController.activePage; + // If a BVC is currently being presented, dismiss it. This will trigger any // necessary animations. if (self.bvcContainer) { @@ -386,12 +402,6 @@ // This is done with a dispatch to make sure that the view isn't added to // the view hierarchy right away, as it is not the expectations of the // API. - // Store the currentActivePage at this point in code, to be used during - // execution of the dispatched block to get the transition from Browser to - // Tab Grid. That is because in some instances the active page might change - // before the block gets executed, for example when closing the last tab in - // incognito (crbug.com/1136882). - TabGridPage currentActivePage = self.baseViewController.activePage; dispatch_async(dispatch_get_main_queue(), ^{ self.transitionHandler = [[TabGridTransitionHandler alloc] initWithLayoutProvider:self.baseViewController]; @@ -414,6 +424,23 @@ }); } + // Show "Bring Android Tabs" prompt if the user is an Android switcher and has + // open tabs from their previous Android device. + // Note: if the coordinator is already created, the prompt should have already + // been displayed, therefore we should not need to display it again. + if (currentActivePage == TabGridPageRegularTabs && + !_bringAndroidTabsPromptCoordinator) { + BringAndroidTabsToIOSService* bringAndroidTabsService = + BringAndroidTabsToIOSServiceFactory::GetForBrowserStateIfExists( + self.regularBrowser->GetBrowserState()); + if (bringAndroidTabsService != nil) { + bringAndroidTabsService->LoadTabs(); + if (bringAndroidTabsService->GetNumberOfAndroidTabs() > 0) { + [self displayBringAndroidTabsPrompt]; + } + } + } + // Record when the tab switcher is presented. self.tabGridEnterTime = base::TimeTicks::Now(); base::RecordAction(base::UserMetricsAction("MobileTabGridEntered")); @@ -840,6 +867,10 @@ self.snackbarCoordinator = nil; [self.incognitoSnackbarCoordinator stop]; self.incognitoSnackbarCoordinator = nil; + + self.baseViewController.bringAndroidTabsPromptViewController = nil; + [_bringAndroidTabsPromptCoordinator stop]; + _bringAndroidTabsPromptCoordinator = nil; } #pragma mark - TabPresentationDelegate @@ -1306,6 +1337,47 @@ } } +#pragma mark - BringAndroidTabsCommands + +- (void)displayBringAndroidTabsPrompt { + if (!_bringAndroidTabsPromptCoordinator) { + _bringAndroidTabsPromptCoordinator = + [[BringAndroidTabsPromptCoordinator alloc] + initWithBaseViewController:self.baseViewController + browser:self.regularBrowser]; + } + [_bringAndroidTabsPromptCoordinator start]; + self.baseViewController.bringAndroidTabsPromptViewController = + _bringAndroidTabsPromptCoordinator.viewController; +} + +- (void)reviewAllBringAndroidTabs { + [self onUserInteractionWithBringAndroidTabsPrompt:YES]; +} + +- (void)dismissBringAndroidTabsPrompt { + [self onUserInteractionWithBringAndroidTabsPrompt:NO]; +} + +// Helper method to handle BringAndroidTabsCommands. +- (void)onUserInteractionWithBringAndroidTabsPrompt:(BOOL)reviewTabs { + DCHECK(_bringAndroidTabsPromptCoordinator); + DCHECK_EQ(self.baseViewController.bringAndroidTabsPromptViewController, + _bringAndroidTabsPromptCoordinator.viewController); + self.baseViewController.bringAndroidTabsPromptViewController = nil; + if (reviewTabs) { + // TODO(crbug.com/1418120): Open the review Android tabs table. + } else { + // The user journey to bring recent tabs on Android to iOS has finished. + // Reload the service to update/clear the tabs. + BringAndroidTabsToIOSServiceFactory::GetForBrowserStateIfExists( + self.regularBrowser->GetBrowserState()) + ->LoadTabs(); + } + [_bringAndroidTabsPromptCoordinator stop]; + _bringAndroidTabsPromptCoordinator = nil; +} + #pragma mark - SnackbarCoordinatorDelegate - (CGFloat)bottomOffsetForCurrentlyPresentedView {
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_new_tab_button.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_new_tab_button.mm index d0cf404b..de97a0e1 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_new_tab_button.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_new_tab_button.mm
@@ -6,6 +6,7 @@ #import "base/check.h" #import "base/notreached.h" +#import "ios/chrome/browser/shared/public/features/features.h" #import "ios/chrome/browser/ui/icons/symbols.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_constants.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" @@ -43,7 +44,12 @@ self = [super initWithFrame:CGRectZero]; if (self) { CGFloat symbolSize = largeSize ? kLargeSymbolSize : kSmallSymbolSize; - _symbol = CustomSymbolWithPointSize(kPlusCircleFillSymbol, symbolSize); + if (base::FeatureList::IsEnabled(kSFSymbolsFollowup)) { + _symbol = CustomSymbolWithPointSize(kPlusCircleFillSymbol, symbolSize); + } else { + _symbol = + CustomSymbolWithPointSize(kLegacyPlusCircleFillSymbol, symbolSize); + } [self setImage:_symbol forState:UIControlStateNormal]; self.pointerInteractionEnabled = YES; self.pointerStyleProvider = CreateLiftEffectCirclePointerStyleProvider();
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.h index a1c291c..472da50 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.h +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.h
@@ -177,6 +177,12 @@ @property(nonatomic, weak) id<TabContextMenuProvider> incognitoTabsContextMenuProvider; +// The view controller for the "Bring Android Tabs" prompt for Android +// switchers. Note that setting this value immediately adds it to the view +// hierarchy. +@property(nonatomic, strong) + UIViewController* bringAndroidTabsPromptViewController; + // The layout guide center to use to refer to the bottom toolbar. @property(nonatomic, strong) LayoutGuideCenter* layoutGuideCenter;
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.mm index ecb6910..1ae5648 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.mm
@@ -724,6 +724,13 @@ [_reauthAgent addObserver:self]; } +- (void)setBringAndroidTabsPromptViewController: + (UIViewController*)viewController { + _bringAndroidTabsPromptViewController = viewController; + // TODO(crbug.com/1418117): Move around other UI components in the regular tab + // grid accordingly, and add/remove `viewController` to the view hierarchy. +} + #pragma mark - TabGridPaging - (void)setActivePage:(TabGridPage)activePage { @@ -801,7 +808,7 @@ completion(completeds[0], finisheds[0]); }; - // Each LayoutSwitcher method calls regular and icognito grid controller's + // Each LayoutSwitcher method calls regular and incognito grid controller's // corresponding method. Thus, attaching the completion to only one of the // grid view controllers should suffice. [regularViewController willTransitionToLayout:nextState
diff --git a/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.mm b/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.mm index b3cb449..83f2c34b 100644 --- a/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.mm +++ b/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.mm
@@ -168,8 +168,11 @@ - (ToolbarButton*)openNewTabButton { ToolbarButton* newTabButton; if (@available(iOS 15, *)) { + NSString* symbolName = base::FeatureList::IsEnabled(kSFSymbolsFollowup) + ? kPlusCircleFillSymbol + : kLegacyPlusCircleFillSymbol; UIImage* image = SymbolWithPalette( - CustomSymbolWithPointSize(kNewTabSymbol, kSymbolToolbarPointSize), @[ + CustomSymbolWithPointSize(symbolName, kSymbolToolbarPointSize), @[ [UIColor colorNamed:kGrey600Color], [self.toolbarConfiguration locationBarBackgroundColorWithVisibility:1] ]);
diff --git a/ios/chrome/browser/ui/whats_new/promo/whats_new_promo_display_handler.h b/ios/chrome/browser/ui/whats_new/promo/whats_new_promo_display_handler.h index ca2c56e..de09dbac4 100644 --- a/ios/chrome/browser/ui/whats_new/promo/whats_new_promo_display_handler.h +++ b/ios/chrome/browser/ui/whats_new/promo/whats_new_promo_display_handler.h
@@ -7,10 +7,18 @@ #import "ios/chrome/browser/ui/promos_manager/standard_promo_display_handler.h" +class PromosManager; + // Handler for displaying What's New. This handler is called by the Promos // Manager once on the 6th day or 6th launch after the FRE. @interface WhatsNewPromoDisplayHandler : NSObject <StandardPromoDisplayHandler> +- (instancetype)init NS_UNAVAILABLE; + +// Promos Manager to alert if the user uses What's New. +- (instancetype)initWithPromosManager:(PromosManager*)promosManager + NS_DESIGNATED_INITIALIZER; + #pragma mark - PromoProtocol // PromosManagerCommands handler.
diff --git a/ios/chrome/browser/ui/whats_new/promo/whats_new_promo_display_handler.mm b/ios/chrome/browser/ui/whats_new/promo/whats_new_promo_display_handler.mm index cd34bb3..c13a7b2 100644 --- a/ios/chrome/browser/ui/whats_new/promo/whats_new_promo_display_handler.mm +++ b/ios/chrome/browser/ui/whats_new/promo/whats_new_promo_display_handler.mm
@@ -15,10 +15,20 @@ #error "This file requires ARC support." #endif -@implementation WhatsNewPromoDisplayHandler +@implementation WhatsNewPromoDisplayHandler { + // Promos Manager to alert if the user uses What's New. + PromosManager* _promosManager; +} #pragma mark - StandardPromoDisplayHandler +- (instancetype)initWithPromosManager:(PromosManager*)promosManager { + if (self = [super init]) { + _promosManager = promosManager; + } + return self; +} + - (void)handleDisplay { // Don't show the promo if What's New has been previously open. if (WasWhatsNewUsed()) { @@ -26,7 +36,7 @@ } DCHECK(self.handler); - SetWhatsNewUsed(); + SetWhatsNewUsed(_promosManager); [self.handler showWhatsNewPromo]; }
diff --git a/ios/chrome/browser/ui/whats_new/whats_new_util.h b/ios/chrome/browser/ui/whats_new/whats_new_util.h index 13c8072..bb64c2f 100644 --- a/ios/chrome/browser/ui/whats_new/whats_new_util.h +++ b/ios/chrome/browser/ui/whats_new/whats_new_util.h
@@ -7,6 +7,8 @@ #import <Foundation/Foundation.h> +class PromosManager; + // Key to store whether the What's New promo has been register. extern NSString* const kWhatsNewPromoRegistrationKey; @@ -25,7 +27,7 @@ bool WasWhatsNewUsed(); // Set that What's New was used in the overflow menu. -void SetWhatsNewUsed(); +void SetWhatsNewUsed(PromosManager* promosManager); // Returns whether What's New is enabled. bool IsWhatsNewEnabled();
diff --git a/ios/chrome/browser/ui/whats_new/whats_new_util.mm b/ios/chrome/browser/ui/whats_new/whats_new_util.mm index 2031497..78bf9226 100644 --- a/ios/chrome/browser/ui/whats_new/whats_new_util.mm +++ b/ios/chrome/browser/ui/whats_new/whats_new_util.mm
@@ -78,15 +78,13 @@ [[NSUserDefaults standardUserDefaults] boolForKey:kWhatsNewUsageEntryKey]; } -void SetWhatsNewUsed() { +void SetWhatsNewUsed(PromosManager* promosManager) { if (WasWhatsNewUsed()) { return; } // Deregister What's New promo. - PromosManager* promosManager = GetApplicationContext()->GetPromosManager(); DCHECK(promosManager); - promosManager->DeregisterPromo(promos_manager::Promo::WhatsNew); [[NSUserDefaults standardUserDefaults] setBool:YES
diff --git a/ios/chrome/browser/web/chrome_main_parts.h b/ios/chrome/browser/web/chrome_main_parts.h index 7160e00..fe076060 100644 --- a/ios/chrome/browser/web/chrome_main_parts.h +++ b/ios/chrome/browser/web/chrome_main_parts.h
@@ -29,6 +29,7 @@ // web::WebMainParts implementation. void PreCreateMainMessageLoop() override; void PreCreateThreads() override; + void PostCreateThreads() override; void PreMainMessageLoopRun() override; void PostMainMessageLoopRun() override; void PostDestroyThreads() override;
diff --git a/ios/chrome/browser/web/chrome_main_parts.mm b/ios/chrome/browser/web/chrome_main_parts.mm index 386c1f1..b3aecc6 100644 --- a/ios/chrome/browser/web/chrome_main_parts.mm +++ b/ios/chrome/browser/web/chrome_main_parts.mm
@@ -267,6 +267,10 @@ application_context_->PreCreateThreads(); } +void IOSChromeMainParts::PostCreateThreads() { + application_context_->PostCreateThreads(); +} + void IOSChromeMainParts::PreMainMessageLoopRun() { application_context_->PreMainMessageLoopRun(); @@ -360,12 +364,6 @@ safe_browsing_service->Initialize(last_used_browser_state->GetPrefs(), user_data_path, safe_browsing_metrics_collector); - - // Ensure the Fullscren Promos Manager is initialized. - PromosManager* promos_manager = application_context_->GetPromosManager(); - if (promos_manager) { - promos_manager->Init(); - } } void IOSChromeMainParts::PostMainMessageLoopRun() {
diff --git a/ios/chrome/common/ui/util/text_view_util.mm b/ios/chrome/common/ui/util/text_view_util.mm index d198792..f276f28 100644 --- a/ios/chrome/common/ui/util/text_view_util.mm +++ b/ios/chrome/common/ui/util/text_view_util.mm
@@ -8,14 +8,6 @@ #error "This file requires ARC support." #endif -#if !defined(__IPHONE_16_0) || __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_16_0 -@interface UITextView (TextKit) -// Forward declare iOS 16 `+textViewUsingTextLayoutManager` on iOS 15 SDK -// builds. -+ (instancetype)textViewUsingTextLayoutManager:(BOOL)usingTextLayoutManager; -@end -#endif - // TODO(crbug.com/1335912): On iOS 16, EG is unable to tap links in // TextKit2-based UITextViews. Fall back to TextKit1 until this issue // is resolved.
diff --git a/ios/chrome/test/BUILD.gn b/ios/chrome/test/BUILD.gn index 844607e..a1d30ef 100644 --- a/ios/chrome/test/BUILD.gn +++ b/ios/chrome/test/BUILD.gn
@@ -291,6 +291,7 @@ "//ios/chrome/browser/ui/bookmarks/cells:unit_tests", "//ios/chrome/browser/ui/bookmarks/editor:unit_tests", "//ios/chrome/browser/ui/bookmarks/home:unit_tests", + "//ios/chrome/browser/ui/bring_android_tabs:unit_tests", "//ios/chrome/browser/ui/broadcaster:unit_tests", "//ios/chrome/browser/ui/browser_container:unit_tests", "//ios/chrome/browser/ui/browser_view:unit_tests",
diff --git a/ios/chrome/test/app/signin_test_util.mm b/ios/chrome/test/app/signin_test_util.mm index 53e5b9e..1115b24 100644 --- a/ios/chrome/test/app/signin_test_util.mm +++ b/ios/chrome/test/app/signin_test_util.mm
@@ -138,7 +138,7 @@ __block AuthenticationFlow* authenticationFlow = [[AuthenticationFlow alloc] initWithBrowser:browser identity:identity - postSignInAction:POST_SIGNIN_ACTION_NONE + postSignInAction:PostSignInAction::kNone presentingViewController:viewController]; authenticationFlow.dispatcher = (id<BrowsingDataCommands>)GetMainController(); [authenticationFlow startSignInWithCompletion:^(BOOL success) {
diff --git a/ios/chrome/test/testing_application_context.h b/ios/chrome/test/testing_application_context.h index b53573c..0f2ee00c 100644 --- a/ios/chrome/test/testing_application_context.h +++ b/ios/chrome/test/testing_application_context.h
@@ -69,7 +69,6 @@ SafeBrowsingService* GetSafeBrowsingService() override; network::NetworkConnectionTracker* GetNetworkConnectionTracker() override; BrowserPolicyConnectorIOS* GetBrowserPolicyConnector() override; - PromosManager* GetPromosManager() override; id<SingleSignOnService> GetSSOService() override; SystemIdentityManager* GetSystemIdentityManager() override; segmentation_platform::OTRWebStateObserver*
diff --git a/ios/chrome/test/testing_application_context.mm b/ios/chrome/test/testing_application_context.mm index 8df2055..d4d9346f 100644 --- a/ios/chrome/test/testing_application_context.mm +++ b/ios/chrome/test/testing_application_context.mm
@@ -223,14 +223,6 @@ return browser_policy_connector_.get(); } -PromosManager* TestingApplicationContext::GetPromosManager() { - DCHECK(thread_checker_.CalledOnValidThread()); - - promos_manager_ = std::make_unique<MockPromosManager>(); - - return promos_manager_.get(); -} - id<SingleSignOnService> TestingApplicationContext::GetSSOService() { DCHECK(thread_checker_.CalledOnValidThread()); if (!single_sign_on_service_) {
diff --git a/ios/components/io_thread/ios_io_thread.h b/ios/components/io_thread/ios_io_thread.h index 58da2386..b8403ae 100644 --- a/ios/components/io_thread/ios_io_thread.h +++ b/ios/components/io_thread/ios_io_thread.h
@@ -93,6 +93,9 @@ ~IOSIOThread() override; + // Initialize the IO thread with blocking allowed. + void InitOnIO(); + // Can only be called on the IO thread. Globals* globals();
diff --git a/ios/components/io_thread/ios_io_thread.mm b/ios/components/io_thread/ios_io_thread.mm index 3e82eb6b..48002cf 100644 --- a/ios/components/io_thread/ios_io_thread.mm +++ b/ios/components/io_thread/ios_io_thread.mm
@@ -21,6 +21,7 @@ #import "base/strings/string_util.h" #import "base/task/single_thread_task_runner.h" #import "base/threading/thread.h" +#import "base/threading/thread_restrictions.h" #import "base/time/time.h" #import "base/trace_event/trace_event.h" #import "components/network_session_configurator/browser/network_session_configurator.h" @@ -184,6 +185,13 @@ return globals_; } +void IOSIOThread::InitOnIO() { + DCHECK_CURRENTLY_ON(web::WebThread::IO); + // Allow blocking calls while initializing the IO thread. + base::ScopedAllowBlocking allow_blocking_for_init; + Init(); +} + void IOSIOThread::SetGlobalsForTesting(Globals* globals) { DCHECK_CURRENTLY_ON(web::WebThread::IO); DCHECK(!globals || !globals_);
diff --git a/ios/web/content/init/ios_browser_main_parts.h b/ios/web/content/init/ios_browser_main_parts.h index c21d4bf..adc9b1e 100644 --- a/ios/web/content/init/ios_browser_main_parts.h +++ b/ios/web/content/init/ios_browser_main_parts.h
@@ -29,6 +29,7 @@ void PreCreateMainMessageLoop() override; void PostCreateMainMessageLoop() override; int PreCreateThreads() override; + void PostCreateThreads() override; int PreMainMessageLoopRun() override; private:
diff --git a/ios/web/content/init/ios_browser_main_parts.mm b/ios/web/content/init/ios_browser_main_parts.mm index ee285fa..f938aba 100644 --- a/ios/web/content/init/ios_browser_main_parts.mm +++ b/ios/web/content/init/ios_browser_main_parts.mm
@@ -32,10 +32,16 @@ void IOSBrowserMainParts::PostCreateMainMessageLoop() { parts_->PostCreateMainMessageLoop(); } + int IOSBrowserMainParts::PreCreateThreads() { parts_->PreCreateThreads(); return 0; } + +void IOSBrowserMainParts::PostCreateThreads() { + parts_->PostCreateThreads(); +} + int IOSBrowserMainParts::PreMainMessageLoopRun() { parts_->PreMainMessageLoopRun(); return 0;
diff --git a/ios/web/download/crw_web_view_download.mm b/ios/web/download/crw_web_view_download.mm index 31ed7dc..b4fe3b9 100644 --- a/ios/web/download/crw_web_view_download.mm +++ b/ios/web/download/crw_web_view_download.mm
@@ -6,6 +6,8 @@ #import <WebKit/WebKit.h> +#import "base/ios/block_types.h" + #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif @@ -45,8 +47,11 @@ }]; } -- (void)cancelDownload API_AVAILABLE(ios(14.5)) { - [self.download cancel:^(NSData* resumeData){ +- (void)cancelDownload:(ProceduralBlock)completion API_AVAILABLE(ios(14.5)) { + [self.download cancel:^(NSData* resumeData) { + if (completion) { + completion(); + } }]; }
diff --git a/ios/web/init/web_main_loop.h b/ios/web/init/web_main_loop.h index 336bf62..ec23e550 100644 --- a/ios/web/init/web_main_loop.h +++ b/ios/web/init/web_main_loop.h
@@ -49,6 +49,9 @@ // Creates all secondary threads. int CreateThreads(); + // Called after creating the threads + int PostCreateThreads(); + // Called right after the web threads have been started. int WebThreadsStarted();
diff --git a/ios/web/init/web_main_loop.mm b/ios/web/init/web_main_loop.mm index d456625..b7f1648 100644 --- a/ios/web/init/web_main_loop.mm +++ b/ios/web/init/web_main_loop.mm
@@ -96,6 +96,11 @@ if (result > 0) return; + result = PostCreateThreads(); + if (result > 0) { + return; + } + result = WebThreadsStarted(); if (result > 0) return; @@ -120,6 +125,13 @@ return result_code_; } +int WebMainLoop::PostCreateThreads() { + if (parts_) { + parts_->PostCreateThreads(); + } + return result_code_; +} + int WebMainLoop::CreateThreads() { ios_global_state::StartThreadPool();
diff --git a/ios/web/public/download/crw_web_view_download.h b/ios/web/public/download/crw_web_view_download.h index d9e41aea..5f7d87f 100644 --- a/ios/web/public/download/crw_web_view_download.h +++ b/ios/web/public/download/crw_web_view_download.h
@@ -6,12 +6,13 @@ #define IOS_WEB_PUBLIC_DOWNLOAD_CRW_WEB_VIEW_DOWNLOAD_H_ #import <Foundation/Foundation.h> +#import "base/ios/block_types.h" // Provides API for managing a web view download. @protocol CRWWebViewDownload <NSObject> -// Cancels the download. -- (void)cancelDownload API_AVAILABLE(ios(14.5)); +// Cancels the download with a completion block. +- (void)cancelDownload:(ProceduralBlock)completion API_AVAILABLE(ios(14.5)); @end
diff --git a/ios/web/public/init/web_main_parts.h b/ios/web/public/init/web_main_parts.h index 8a4b0f2..e505370 100644 --- a/ios/web/public/init/web_main_parts.h +++ b/ios/web/public/init/web_main_parts.h
@@ -77,6 +77,7 @@ virtual void PreCreateMainMessageLoop() {} virtual void PostCreateMainMessageLoop() {} virtual void PreCreateThreads() {} + virtual void PostCreateThreads() {} virtual void PreMainMessageLoopRun() {} virtual void PostMainMessageLoopRun() {} virtual void PostDestroyThreads() {}
diff --git a/ios/web/web_sub_thread.cc b/ios/web/web_sub_thread.cc index 2f615f27..e6065509 100644 --- a/ios/web/web_sub_thread.cc +++ b/ios/web/web_sub_thread.cc
@@ -43,12 +43,6 @@ DCHECK(!web_thread_); web_thread_.reset(new WebThreadImpl(identifier_, task_runner())); - - // Unretained(this) is safe as `this` outlives its underlying thread. - task_runner()->PostTask( - FROM_HERE, - base::BindOnce(&WebSubThread::CompleteInitializationOnWebThread, - Unretained(this))); } void WebSubThread::AllowBlockingForTesting() { @@ -91,16 +85,6 @@ web_thread_.reset(); } -void WebSubThread::CompleteInitializationOnWebThread() { - DCHECK_CALLED_ON_VALID_THREAD(web_thread_checker_); - - if (identifier_ == WebThread::IO && g_io_thread_delegate) { - // Allow blocking calls while initializing the IO thread. - base::ScopedAllowBlocking allow_blocking_for_init; - g_io_thread_delegate->Init(); - } -} - void WebSubThread::UIThreadRun(base::RunLoop* run_loop) { Thread::Run(run_loop); // Inhibit tail calls of Run and inhibit code folding.
diff --git a/ios/web/web_sub_thread.h b/ios/web/web_sub_thread.h index c30f9501..a5999b4 100644 --- a/ios/web/web_sub_thread.h +++ b/ios/web/web_sub_thread.h
@@ -45,10 +45,6 @@ void CleanUp() override; private: - // Second Init() phase that must happen on this thread but can only happen - // after it's promoted to a WebThread in `RegisterAsWebThread()`. - void CompleteInitializationOnWebThread(); - // These methods merely forwards to Thread::Run() but are useful to identify // which WebThread this represents in stack traces. void UIThreadRun(base::RunLoop* run_loop);
diff --git a/ios/web_view/internal/app/application_context.h b/ios/web_view/internal/app/application_context.h index 44f9572f..3e6ec94 100644 --- a/ios/web_view/internal/app/application_context.h +++ b/ios/web_view/internal/app/application_context.h
@@ -74,6 +74,10 @@ // called from web::WebMainParts::PreCreateThreads. void PreCreateThreads(); + // Called after the browser threads are created. It is expected this will be + // called from web::WebMainParts::PostCreateThreads. + void PostCreateThreads(); + // Saves application context state if |local_state_| exists. This should be // called during shutdown to save application state. void SaveState();
diff --git a/ios/web_view/internal/app/application_context.mm b/ios/web_view/internal/app/application_context.mm index b47dac1d..9676762 100644 --- a/ios/web_view/internal/app/application_context.mm +++ b/ios/web_view/internal/app/application_context.mm
@@ -72,6 +72,13 @@ std::make_unique<WebViewIOThread>(GetLocalState(), GetNetLog()); } +void ApplicationContext::PostCreateThreads() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + web::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&WebViewIOThread::InitOnIO, + base::Unretained(web_view_io_thread_.get()))); +} + void ApplicationContext::SaveState() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (local_state_) {
diff --git a/ios/web_view/internal/web_view_web_main_parts.h b/ios/web_view/internal/web_view_web_main_parts.h index f14e24f..7b4cc53 100644 --- a/ios/web_view/internal/web_view_web_main_parts.h +++ b/ios/web_view/internal/web_view_web_main_parts.h
@@ -24,6 +24,7 @@ // web::WebMainParts implementation. void PreCreateMainMessageLoop() override; void PreCreateThreads() override; + void PostCreateThreads() override; void PreMainMessageLoopRun() override; void PostMainMessageLoopRun() override; void PostDestroyThreads() override;
diff --git a/ios/web_view/internal/web_view_web_main_parts.mm b/ios/web_view/internal/web_view_web_main_parts.mm index 03284c6..6a7479ee 100644 --- a/ios/web_view/internal/web_view_web_main_parts.mm +++ b/ios/web_view/internal/web_view_web_main_parts.mm
@@ -86,6 +86,10 @@ base::FeatureList::SetInstance(std::move(feature_list)); } +void WebViewWebMainParts::PostCreateThreads() { + ApplicationContext::GetInstance()->PostCreateThreads(); +} + void WebViewWebMainParts::PreMainMessageLoopRun() { WebViewTranslateService::GetInstance()->Initialize();
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index 1583582..443c602b 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -1212,6 +1212,14 @@ base::FEATURE_DISABLED_BY_DEFAULT); #endif +#if BUILDFLAG(IS_CHROMEOS_ASH) +// Expose the out-of-process video decoding feature from ash-chrome to +// lacros-chrome through the crosapi. +const base::Feature MEDIA_EXPORT kExposeOutOfProcessVideoDecodingToLacros{ + "ExposeOutOfProcessVideoDecodingToLacros", + base::FEATURE_ENABLED_BY_DEFAULT}; +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) // Spawn utility processes to perform hardware decode acceleration instead of // using the GPU process.
diff --git a/media/base/media_switches.h b/media/base/media_switches.h index 0480182..54c7c0d 100644 --- a/media/base/media_switches.h +++ b/media/base/media_switches.h
@@ -396,6 +396,10 @@ kAllowClearDolbyVisionInMseWhenPlatformEncryptedDvEnabled); #endif +#if BUILDFLAG(IS_CHROMEOS_ASH) +MEDIA_EXPORT BASE_DECLARE_FEATURE(kExposeOutOfProcessVideoDecodingToLacros); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) MEDIA_EXPORT BASE_DECLARE_FEATURE(kUseOutOfProcessVideoDecoding); #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
diff --git a/media/base/video_util.cc b/media/base/video_util.cc index 0d8e3d8..5b83802 100644 --- a/media/base/video_util.cc +++ b/media/base/video_util.cc
@@ -31,6 +31,7 @@ #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/core/SkYUVAPixmaps.h" #include "third_party/skia/include/gpu/GrDirectContext.h" +#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h" #include "third_party/skia/include/gpu/gl/GrGLTypes.h" #include "ui/gfx/gpu_memory_buffer.h" @@ -154,13 +155,13 @@ gl_texture_info.fFormat = texture_format; GrBackendTexture texture(width, height, GrMipMapped::kNo, gl_texture_info); - auto image = - SkImage::MakeFromTexture(gr_context, texture, - src_frame.metadata().texture_origin_is_top_left - ? kTopLeft_GrSurfaceOrigin - : kBottomLeft_GrSurfaceOrigin, - sk_color_type, sk_alpha_type, - /*colorSpace=*/nullptr); + auto image = SkImages::BorrowTextureFrom( + gr_context, texture, + src_frame.metadata().texture_origin_is_top_left + ? kTopLeft_GrSurfaceOrigin + : kBottomLeft_GrSurfaceOrigin, + sk_color_type, sk_alpha_type, + /*colorSpace=*/nullptr); if (!image) { DLOG(ERROR) << "Can't create SkImage from texture plane " << src_plane; return false;
diff --git a/media/gpu/sandbox/hardware_video_decoding_sandbox_hook_linux.cc b/media/gpu/sandbox/hardware_video_decoding_sandbox_hook_linux.cc index a8d938b..def6c04 100644 --- a/media/gpu/sandbox/hardware_video_decoding_sandbox_hook_linux.cc +++ b/media/gpu/sandbox/hardware_video_decoding_sandbox_hook_linux.cc
@@ -77,7 +77,7 @@ /*read_write=*/false); #endif // BUILDFLAG(IS_CHROMEOS_ASH) #if BUILDFLAG(USE_VAAPI) - VaapiWrapper::PreSandboxInitialization(); + VaapiWrapper::PreSandboxInitialization(/*allow_disabling_global_lock=*/true); return true; #else NOTREACHED(); @@ -106,7 +106,7 @@ } #if BUILDFLAG(USE_VAAPI) - VaapiWrapper::PreSandboxInitialization(); + VaapiWrapper::PreSandboxInitialization(/*allow_disabling_global_lock=*/true); return true; #else NOTREACHED();
diff --git a/media/gpu/sandbox/hardware_video_encoding_sandbox_hook_linux.cc b/media/gpu/sandbox/hardware_video_encoding_sandbox_hook_linux.cc index 80f6fa0c..13efa43 100644 --- a/media/gpu/sandbox/hardware_video_encoding_sandbox_hook_linux.cc +++ b/media/gpu/sandbox/hardware_video_encoding_sandbox_hook_linux.cc
@@ -108,7 +108,7 @@ // of VA-API/V4L2. That means that bots like linux-chromeos-rel would end up // reaching this presandbox hook. #if BUILDFLAG(USE_VAAPI) - VaapiWrapper::PreSandboxInitialization(); + VaapiWrapper::PreSandboxInitialization(/*allow_disabling_global_lock=*/true); if (options.use_amd_specific_policies) { const char* radeonsi_lib = "/usr/lib64/dri/radeonsi_dri.so";
diff --git a/media/gpu/vaapi/vaapi_wrapper.cc b/media/gpu/vaapi/vaapi_wrapper.cc index efa9a8a..7028f93 100644 --- a/media/gpu/vaapi/vaapi_wrapper.cc +++ b/media/gpu/vaapi/vaapi_wrapper.cc
@@ -250,6 +250,10 @@ } bool UseGlobalVaapiLock(media::VAImplementation implementation_type) { + if (!media::VaapiWrapper::allow_disabling_global_lock_) { + return true; + } + // Only iHD and Mesa Gallium are known to be thread safe at the moment. // * Mesa Gallium: b/144877595 // * iHD: crbug.com/1123429. @@ -3097,7 +3101,12 @@ } // static -void VaapiWrapper::PreSandboxInitialization() { +bool VaapiWrapper::allow_disabling_global_lock_ = false; + +// static +void VaapiWrapper::PreSandboxInitialization(bool allow_disabling_global_lock) { + allow_disabling_global_lock_ = allow_disabling_global_lock; + VADisplayState::PreSandboxInitialization(); const std::string va_suffix(std::to_string(VA_MAJOR_VERSION + 1));
diff --git a/media/gpu/vaapi/vaapi_wrapper.h b/media/gpu/vaapi/vaapi_wrapper.h index a1afcf0..44d8528 100644 --- a/media/gpu/vaapi/vaapi_wrapper.h +++ b/media/gpu/vaapi/vaapi_wrapper.h
@@ -123,6 +123,11 @@ class MEDIA_GPU_EXPORT VaapiWrapper : public base::RefCountedThreadSafe<VaapiWrapper> { public: + // Whether it's okay or not to try to disable the VA-API global lock on the + // current process. This is intended to be set only once during process + // start-up. + static bool allow_disabling_global_lock_; + enum CodecMode { kDecode, #if BUILDFLAG(IS_CHROMEOS_ASH) @@ -533,7 +538,8 @@ ); // Initialize static data before sandbox is enabled. - static void PreSandboxInitialization(); + static void PreSandboxInitialization( + bool allow_disabling_global_lock = false); // vaDestroySurfaces() a vector or a single VASurfaceID. virtual void DestroySurfaces(std::vector<VASurfaceID> va_surfaces);
diff --git a/media/renderers/paint_canvas_video_renderer.cc b/media/renderers/paint_canvas_video_renderer.cc index e98b838..9d0348691 100644 --- a/media/renderers/paint_canvas_video_renderer.cc +++ b/media/renderers/paint_canvas_video_renderer.cc
@@ -44,6 +44,7 @@ #include "third_party/skia/include/core/SkImageInfo.h" #include "third_party/skia/include/gpu/GrBackendSurface.h" #include "third_party/skia/include/gpu/GrDirectContext.h" +#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h" #include "third_party/skia/include/gpu/gl/GrGLTypes.h" #include "ui/gfx/geometry/rect_f.h" #include "ui/gfx/geometry/skia_conversions.h" @@ -203,7 +204,7 @@ texture_info.fFormat = GL_RGBA8_OES; GrBackendTexture backend_texture(size.width(), size.height(), GrMipMapped::kNo, texture_info); - return SkImage::MakeFromAdoptedTexture( + return SkImages::AdoptTextureFrom( raster_context_provider->GrContext(), backend_texture, texture_origin_is_top_left ? kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin, @@ -911,8 +912,8 @@ DLOG(ERROR) << "VideoTextureBacking::GetSkImageViaReadback failed."; return nullptr; } - return SkImage::MakeRasterData(sk_image_info_, std::move(image_pixels), - sk_image_info_.minRowBytes()); + return SkImages::RasterFromData(sk_image_info_, std::move(image_pixels), + sk_image_info_.minRowBytes()); } bool readPixels(const SkImageInfo& dst_info,
diff --git a/media/renderers/video_frame_rgba_to_yuva_converter.cc b/media/renderers/video_frame_rgba_to_yuva_converter.cc index ac92ad23..bf937a8 100644 --- a/media/renderers/video_frame_rgba_to_yuva_converter.cc +++ b/media/renderers/video_frame_rgba_to_yuva_converter.cc
@@ -20,6 +20,7 @@ #include "third_party/skia/include/core/SkColorSpace.h" #include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/gpu/GrDirectContext.h" +#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h" #include "ui/gfx/gpu_memory_buffer.h" namespace { @@ -67,7 +68,7 @@ SkColorType color_type = viz::ResourceFormatToClosestSkColorType( /*gpu_compositing=*/true, format); - sk_sp<SkImage> sk_image = SkImage::MakeFromTexture( + sk_sp<SkImage> sk_image = SkImages::BorrowTextureFrom( gr_context, backend_texture, surface_origin, color_type, kOpaque_SkAlphaType, color_space.ToSkColorSpace()); if (!sk_image) {
diff --git a/media/renderers/video_frame_yuv_mailboxes_holder.cc b/media/renderers/video_frame_yuv_mailboxes_holder.cc index 42728f6..955b7221 100644 --- a/media/renderers/video_frame_yuv_mailboxes_holder.cc +++ b/media/renderers/video_frame_yuv_mailboxes_holder.cc
@@ -19,6 +19,7 @@ #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/core/SkYUVAPixmaps.h" #include "third_party/skia/include/gpu/GrDirectContext.h" +#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h" #include "third_party/skia/include/gpu/gl/GrGLTypes.h" namespace media { @@ -199,8 +200,8 @@ : video_frame->ColorSpace().GetAsFullRangeRGB().ToSkColorSpace(); DCHECK(yuva_backend_textures.isValid()); - auto result = SkImage::MakeFromYUVATextures(gr_context, yuva_backend_textures, - rgb_color_space); + auto result = SkImages::TextureFromYUVATextures( + gr_context, yuva_backend_textures, rgb_color_space); DCHECK(result); return result; }
diff --git a/net/BUILD.gn b/net/BUILD.gn index 61a6559b..9fe07359 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -1347,8 +1347,8 @@ if (is_android || is_chromeos) { sources += [ - "base/network_change_notifier_posix.cc", - "base/network_change_notifier_posix.h", + "base/network_change_notifier_passive.cc", + "base/network_change_notifier_passive.h", ] } @@ -2902,7 +2902,7 @@ } if (is_android || is_chromeos_ash) { - sources += [ "base/network_change_notifier_posix_unittest.cc" ] + sources += [ "base/network_change_notifier_passive_unittest.cc" ] } if (enable_reporting) {
diff --git a/net/base/network_change_notifier.cc b/net/base/network_change_notifier.cc index 4398b17..2153c72 100644 --- a/net/base/network_change_notifier.cc +++ b/net/base/network_change_notifier.cc
@@ -38,7 +38,7 @@ #elif BUILDFLAG(IS_APPLE) #include "net/base/network_change_notifier_mac.h" #elif BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) -#include "net/base/network_change_notifier_posix.h" +#include "net/base/network_change_notifier_passive.h" #elif BUILDFLAG(IS_FUCHSIA) #include "net/base/network_change_notifier_fuchsia.h" #endif @@ -311,14 +311,14 @@ network_change_notifier->WatchForAddressChange(); return network_change_notifier; #elif BUILDFLAG(IS_ANDROID) - // Fallback to use NetworkChangeNotifierPosix if NetworkChangeNotifierFactory - // is not set. Currently used for tests and when running network - // service in a separate process. - return std::make_unique<NetworkChangeNotifierPosix>(initial_type, - initial_subtype); + // Fallback to use NetworkChangeNotifierPassive if + // NetworkChangeNotifierFactory is not set. Currently used for tests and when + // running network service in a separate process. + return std::make_unique<NetworkChangeNotifierPassive>(initial_type, + initial_subtype); #elif BUILDFLAG(IS_CHROMEOS) - return std::make_unique<NetworkChangeNotifierPosix>(initial_type, - initial_subtype); + return std::make_unique<NetworkChangeNotifierPassive>(initial_type, + initial_subtype); #elif BUILDFLAG(IS_LINUX) return std::make_unique<NetworkChangeNotifierLinux>( std::unordered_set<std::string>());
diff --git a/net/base/network_change_notifier_posix.cc b/net/base/network_change_notifier_passive.cc similarity index 76% rename from net/base/network_change_notifier_posix.cc rename to net/base/network_change_notifier_passive.cc index 2267ca6ba..b9038cc 100644 --- a/net/base/network_change_notifier_posix.cc +++ b/net/base/network_change_notifier_passive.cc
@@ -9,7 +9,7 @@ #include "base/task/task_traits.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" -#include "net/base/network_change_notifier_posix.h" +#include "net/base/network_change_notifier_passive.h" #include "net/dns/dns_config_service_posix.h" #include "net/dns/system_dns_config_change_notifier.h" @@ -19,38 +19,38 @@ namespace net { -NetworkChangeNotifierPosix::NetworkChangeNotifierPosix( +NetworkChangeNotifierPassive::NetworkChangeNotifierPassive( NetworkChangeNotifier::ConnectionType initial_connection_type, NetworkChangeNotifier::ConnectionSubtype initial_connection_subtype) - : NetworkChangeNotifierPosix(initial_connection_type, - initial_connection_subtype, - /*system_dns_config_notifier=*/nullptr) {} + : NetworkChangeNotifierPassive(initial_connection_type, + initial_connection_subtype, + /*system_dns_config_notifier=*/nullptr) {} -NetworkChangeNotifierPosix::NetworkChangeNotifierPosix( +NetworkChangeNotifierPassive::NetworkChangeNotifierPassive( NetworkChangeNotifier::ConnectionType initial_connection_type, NetworkChangeNotifier::ConnectionSubtype initial_connection_subtype, SystemDnsConfigChangeNotifier* system_dns_config_notifier) - : NetworkChangeNotifier(NetworkChangeCalculatorParamsPosix(), + : NetworkChangeNotifier(NetworkChangeCalculatorParamsPassive(), system_dns_config_notifier), connection_type_(initial_connection_type), max_bandwidth_mbps_( NetworkChangeNotifier::GetMaxBandwidthMbpsForConnectionSubtype( initial_connection_subtype)) {} -NetworkChangeNotifierPosix::~NetworkChangeNotifierPosix() { +NetworkChangeNotifierPassive::~NetworkChangeNotifierPassive() { ClearGlobalPointer(); } -void NetworkChangeNotifierPosix::OnDNSChanged() { +void NetworkChangeNotifierPassive::OnDNSChanged() { GetCurrentSystemDnsConfigNotifier()->RefreshConfig(); } -void NetworkChangeNotifierPosix::OnIPAddressChanged() { +void NetworkChangeNotifierPassive::OnIPAddressChanged() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); NetworkChangeNotifier::NotifyObserversOfIPAddressChange(); } -void NetworkChangeNotifierPosix::OnConnectionChanged( +void NetworkChangeNotifierPassive::OnConnectionChanged( NetworkChangeNotifier::ConnectionType connection_type) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); { @@ -60,7 +60,7 @@ NetworkChangeNotifier::NotifyObserversOfConnectionTypeChange(); } -void NetworkChangeNotifierPosix::OnConnectionSubtypeChanged( +void NetworkChangeNotifierPassive::OnConnectionSubtypeChanged( NetworkChangeNotifier::ConnectionType connection_type, NetworkChangeNotifier::ConnectionSubtype connection_subtype) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -75,12 +75,12 @@ } NetworkChangeNotifier::ConnectionType -NetworkChangeNotifierPosix::GetCurrentConnectionType() const { +NetworkChangeNotifierPassive::GetCurrentConnectionType() const { base::AutoLock scoped_lock(lock_); return connection_type_; } -void NetworkChangeNotifierPosix::GetCurrentMaxBandwidthAndConnectionType( +void NetworkChangeNotifierPassive::GetCurrentMaxBandwidthAndConnectionType( double* max_bandwidth_mbps, ConnectionType* connection_type) const { base::AutoLock scoped_lock(lock_); @@ -90,7 +90,7 @@ // static NetworkChangeNotifier::NetworkChangeCalculatorParams -NetworkChangeNotifierPosix::NetworkChangeCalculatorParamsPosix() { +NetworkChangeNotifierPassive::NetworkChangeCalculatorParamsPassive() { NetworkChangeCalculatorParams params; #if BUILDFLAG(IS_CHROMEOS) // Delay values arrived at by simple experimentation and adjusted so as to
diff --git a/net/base/network_change_notifier_posix.h b/net/base/network_change_notifier_passive.h similarity index 73% rename from net/base/network_change_notifier_posix.h rename to net/base/network_change_notifier_passive.h index 92e1c76..5f2fbc0 100644 --- a/net/base/network_change_notifier_posix.h +++ b/net/base/network_change_notifier_passive.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 NET_BASE_NETWORK_CHANGE_NOTIFIER_POSIX_H_ -#define NET_BASE_NETWORK_CHANGE_NOTIFIER_POSIX_H_ +#ifndef NET_BASE_NETWORK_CHANGE_NOTIFIER_PASSIVE_H_ +#define NET_BASE_NETWORK_CHANGE_NOTIFIER_PASSIVE_H_ #include "base/gtest_prod_util.h" #include "base/memory/scoped_refptr.h" @@ -18,18 +18,18 @@ namespace net { // A NetworkChangeNotifier that needs to be told about network changes by some -// other object. This class can't directly listen for network changes because on -// ChromeOS and Android only objects running in the browser process can listen -// for network state changes. -class NET_EXPORT NetworkChangeNotifierPosix : public NetworkChangeNotifier { +// other object. This is useful on platforms like ChromeOS and Android where +// only objects running in the browser process can listen for network state +// changes, but other processes want to add observers for network state. +class NET_EXPORT NetworkChangeNotifierPassive : public NetworkChangeNotifier { public: - NetworkChangeNotifierPosix( + NetworkChangeNotifierPassive( NetworkChangeNotifier::ConnectionType initial_connection_type, NetworkChangeNotifier::ConnectionSubtype initial_connection_subtype); - NetworkChangeNotifierPosix(const NetworkChangeNotifierPosix&) = delete; - NetworkChangeNotifierPosix& operator=(const NetworkChangeNotifierPosix&) = + NetworkChangeNotifierPassive(const NetworkChangeNotifierPassive&) = delete; + NetworkChangeNotifierPassive& operator=(const NetworkChangeNotifierPassive&) = delete; - ~NetworkChangeNotifierPosix() override; + ~NetworkChangeNotifierPassive() override; // These methods are used to notify this object that a network property has // changed. These must be called from the thread that owns this object. @@ -50,12 +50,12 @@ ConnectionType* connection_type) const override; private: - friend class NetworkChangeNotifierPosixTest; + friend class NetworkChangeNotifierPassiveTest; // For testing purposes, allows specifying a SystemDnsConfigChangeNotifier. // If |system_dns_config_notifier| is nullptr, NetworkChangeNotifier create a // global one. - NetworkChangeNotifierPosix( + NetworkChangeNotifierPassive( NetworkChangeNotifier::ConnectionType initial_connection_type, NetworkChangeNotifier::ConnectionSubtype initial_connection_subtype, SystemDnsConfigChangeNotifier* system_dns_config_notifier); @@ -63,7 +63,7 @@ // Calculates parameters used for network change notifier online/offline // signals. static NetworkChangeNotifier::NetworkChangeCalculatorParams - NetworkChangeCalculatorParamsPosix(); + NetworkChangeCalculatorParamsPassive(); THREAD_CHECKER(thread_checker_); @@ -75,4 +75,4 @@ } // namespace net -#endif // NET_BASE_NETWORK_CHANGE_NOTIFIER_POSIX_H_ +#endif // NET_BASE_NETWORK_CHANGE_NOTIFIER_PASSIVE_H_
diff --git a/net/base/network_change_notifier_posix_unittest.cc b/net/base/network_change_notifier_passive_unittest.cc similarity index 88% rename from net/base/network_change_notifier_posix_unittest.cc rename to net/base/network_change_notifier_passive_unittest.cc index 747fcdf3..c8bfe82e 100644 --- a/net/base/network_change_notifier_posix_unittest.cc +++ b/net/base/network_change_notifier_passive_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/base/network_change_notifier_posix.h" +#include "net/base/network_change_notifier_passive.h" #include <utility> @@ -20,16 +20,16 @@ namespace net { -class NetworkChangeNotifierPosixTest : public testing::Test { +class NetworkChangeNotifierPassiveTest : public testing::Test { public: - NetworkChangeNotifierPosixTest() + NetworkChangeNotifierPassiveTest() : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME) { // Create a SystemDnsConfigChangeNotifier instead of letting // NetworkChangeNotifier create a global one, otherwise the global one will // hold a TaskRunner handle to |task_environment_| and crash if any // subsequent tests use it. dns_config_notifier_ = std::make_unique<SystemDnsConfigChangeNotifier>(); - notifier_ = base::WrapUnique(new NetworkChangeNotifierPosix( + notifier_ = base::WrapUnique(new NetworkChangeNotifierPassive( NetworkChangeNotifier::CONNECTION_UNKNOWN, NetworkChangeNotifier::SUBTYPE_UNKNOWN, dns_config_notifier_.get())); auto dns_config_service = std::make_unique<TestDnsConfigService>(); @@ -42,14 +42,14 @@ task_environment_.FastForwardUntilNoTasksRemain(); } - NetworkChangeNotifierPosix* notifier() { return notifier_.get(); } + NetworkChangeNotifierPassive* notifier() { return notifier_.get(); } TestDnsConfigService* dns_config_service() { return dns_config_service_; } private: base::test::TaskEnvironment task_environment_; net::NetworkChangeNotifier::DisableForTest mock_notifier_disabler_; std::unique_ptr<SystemDnsConfigChangeNotifier> dns_config_notifier_; - std::unique_ptr<NetworkChangeNotifierPosix> notifier_; + std::unique_ptr<NetworkChangeNotifierPassive> notifier_; raw_ptr<TestDnsConfigService> dns_config_service_; }; @@ -58,7 +58,7 @@ MOCK_METHOD0(OnIPAddressChanged, void()); }; -TEST_F(NetworkChangeNotifierPosixTest, OnIPAddressChanged) { +TEST_F(NetworkChangeNotifierPassiveTest, OnIPAddressChanged) { testing::StrictMock<MockIPAddressObserver> observer; NetworkChangeNotifier::AddIPAddressObserver(&observer); @@ -75,7 +75,7 @@ MOCK_METHOD1(OnNetworkChanged, void(NetworkChangeNotifier::ConnectionType)); }; -TEST_F(NetworkChangeNotifierPosixTest, OnNetworkChanged) { +TEST_F(NetworkChangeNotifierPassiveTest, OnNetworkChanged) { testing::StrictMock<MockNetworkChangeObserver> observer; NetworkChangeNotifier::AddNetworkChangeObserver(&observer); @@ -95,7 +95,7 @@ void(double, NetworkChangeNotifier::ConnectionType)); }; -TEST_F(NetworkChangeNotifierPosixTest, OnMaxBandwidthChanged) { +TEST_F(NetworkChangeNotifierPassiveTest, OnMaxBandwidthChanged) { testing::StrictMock<MockMaxBandwidthObserver> observer; NetworkChangeNotifier::AddMaxBandwidthObserver(&observer); @@ -118,7 +118,7 @@ int dns_changes_ = 0; }; -TEST_F(NetworkChangeNotifierPosixTest, OnDNSChanged) { +TEST_F(NetworkChangeNotifierPassiveTest, OnDNSChanged) { TestDnsObserver observer; NetworkChangeNotifier::AddDNSObserver(&observer);
diff --git a/net/disk_cache/simple/simple_file_tracker.cc b/net/disk_cache/simple/simple_file_tracker.cc index b0ceeaf..faf5e67f 100644 --- a/net/disk_cache/simple/simple_file_tracker.cc +++ b/net/disk_cache/simple/simple_file_tracker.cc
@@ -331,8 +331,10 @@ } SimpleFileTracker::FileHandle::~FileHandle() { - if (entry_) - file_tracker_->Release(entry_, subfile_); + file_ = nullptr; + if (entry_) { + file_tracker_->Release(entry_.ExtractAsDangling(), subfile_); + } } SimpleFileTracker::FileHandle& SimpleFileTracker::FileHandle::operator=(
diff --git a/net/quic/quic_chromium_client_session.cc b/net/quic/quic_chromium_client_session.cc index 0a3a15f5..892877d 100644 --- a/net/quic/quic_chromium_client_session.cc +++ b/net/quic/quic_chromium_client_session.cc
@@ -3115,6 +3115,32 @@ std::move(probing_reader)); } +void QuicChromiumClientSession::MigrateToMultiPortPath( + std::unique_ptr<quic::QuicPathValidationContext> context) { + DCHECK_NE(nullptr, context); + auto* chrome_context = + static_cast<QuicChromiumPathValidationContext*>(context.get()); + std::unique_ptr<QuicChromiumPacketWriter> owned_writer = + chrome_context->ReleaseWriter(); + // Remove |this| as the old packet writer's delegate. Write error on old + // writers will be ignored. + // Set |this| to listen on socket write events on the packet writer + // that was used for probing. + static_cast<QuicChromiumPacketWriter*>(connection()->writer()) + ->set_delegate(nullptr); + owned_writer->set_delegate(this); + + if (!MigrateToSocket( + chrome_context->self_address(), chrome_context->peer_address(), + chrome_context->ReleaseSocket(), chrome_context->ReleaseReader(), + std::move(owned_writer))) { + LogMigrateToSocketStatus(false); + return; + } + LogMigrateToSocketStatus(true); + num_migrations_++; +} + void QuicChromiumClientSession::StartProbing( ProbingCallback probing_callback, handles::NetworkHandle network,
diff --git a/net/quic/quic_chromium_client_session.h b/net/quic/quic_chromium_client_session.h index 604b5e3..e3cba1b 100644 --- a/net/quic/quic_chromium_client_session.h +++ b/net/quic/quic_chromium_client_session.h
@@ -748,6 +748,8 @@ void OnKeyUpdate(quic::KeyUpdateReason reason) override; std::unique_ptr<quic::QuicPathValidationContext> CreateContextForMultiPortPath() override; + void MigrateToMultiPortPath( + std::unique_ptr<quic::QuicPathValidationContext> context) override; // QuicChromiumPacketReader::Visitor methods: bool OnReadError(int result, const DatagramClientSocket* socket) override;
diff --git a/net/quic/quic_stream_factory_test.cc b/net/quic/quic_stream_factory_test.cc index 39863c4..24bd300 100644 --- a/net/quic/quic_stream_factory_test.cc +++ b/net/quic/quic_stream_factory_test.cc
@@ -5082,7 +5082,7 @@ EXPECT_TRUE(quic_data2.AllWriteDataConsumed()); } -TEST_P(QuicStreamFactoryTest, MultiPortSession) { +TEST_P(QuicStreamFactoryTest, MultiPortSessionWithMigration) { SetIetfConnectionMigrationFlagsAndConnectionOptions(); // Turning on MPQC will implicitly turn on port migration. quic_params_->client_connection_options.push_back(quic::kMPQC); @@ -5097,27 +5097,12 @@ QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get()); MockQuicData quic_data1(version_); + quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1)); quic_data1.AddWrite( SYNCHRONOUS, ConstructGetRequestPacket( 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true)); - quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause - quic_data1.AddRead( - ASYNC, - ConstructOkResponsePacket( - 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false)); - quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - quic_data1.AddWrite( - SYNCHRONOUS, - client_maker_.MakeAckAndDataPacket( - 4, /*include_version=*/false, GetQpackDecoderStreamId(), - /*largest_received=*/2, /*smallest_received=*/1, /*fin=*/false, - StreamCancellationQpackDecoderInstruction(0))); - quic_data1.AddWrite( - SYNCHRONOUS, client_maker_.MakeRstPacket( - 5, false, GetNthClientInitiatedBidirectionalStreamId(0), - quic::QUIC_STREAM_CANCELLED)); quic_data1.AddSocketDataToFactory(socket_factory_.get()); // Set up the second socket data provider that is used for multi-port @@ -5133,8 +5118,29 @@ // Connectivity probe to receive from the server. quic_data2.AddRead(ASYNC, server_maker_.MakeConnectivityProbingPacket(1, false)); + quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause + quic_data2.AddRead( + ASYNC, + ConstructOkResponsePacket( + 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false)); + quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause + quic_data2.AddWrite( + ASYNC, client_maker_.MakeAckAndPingPacket(4, /*include_version=*/false, + /*largest_received=*/2, + /*smallest_received=*/1)); + quic_data2.AddWrite( + SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket( + 5, /*include_version=*/false, /*sequence_number=*/0u)); + quic_data2.AddRead(ASYNC, server_maker_.MakeAckPacket(3, 5, 1)); + quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read + quic_data2.AddWrite(ASYNC, client_maker_.MakeDataPacket( + 6, GetQpackDecoderStreamId(), true, false, + StreamCancellationQpackDecoderInstruction(0))); + quic_data2.AddWrite( + ASYNC, client_maker_.MakeRstPacket( + 7, false, GetNthClientInitiatedBidirectionalStreamId(0), + quic::QUIC_STREAM_CANCELLED)); - quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); quic_data2.AddSocketDataToFactory(socket_factory_.get()); // Create request and QuicHttpStream. @@ -5180,27 +5186,49 @@ HttpRequestHeaders request_headers; EXPECT_EQ(OK, stream->SendRequest(request_headers, &response, callback_.callback())); + // Disable connection migration on the request streams. + // This should have no effect for port migration. + QuicChromiumClientStream* chrome_stream = + static_cast<QuicChromiumClientStream*>( + quic::test::QuicSessionPeer::GetStream( + session, GetNthClientInitiatedBidirectionalStreamId(0))); + EXPECT_TRUE(chrome_stream); + chrome_stream->DisableConnectionMigrationToCellularNetwork(); // Resume quic data and a connectivity probe response will be read on the new - // socket. + // socket. This makes the multi-port path ready to migrate. quic_data2.Resume(); - // The response is received on the default path. - quic_data1.Resume(); - // Response headers are received over the new port. + EXPECT_EQ(0u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get())); + + // Cause the connection to report path degrading to the session. + // Session will start migrate to multi-port path immediately. + session->connection()->OnPathDegradingDetected(); + base::RunLoop().RunUntilIdle(); + // The connection should still be degrading because no new packets are + // received from the new path. + EXPECT_EQ(1u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get())); + + // The response is received on the new path. + quic_data2.Resume(); EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback())); EXPECT_EQ(200, response.headers->response_code()); + task_runner->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session)); EXPECT_TRUE(HasActiveSession(scheme_host_port_)); EXPECT_EQ(1u, session->GetNumActiveStreams()); - // The periodic probing is handled and tested in quiche. - EXPECT_TRUE(quic::test::QuicConnectionPeer::GetMultiPortProbingAlarm( - session->connection()) - ->IsSet()); + // Receives an ack from the server, this will be considered forward progress. + quic_data2.Resume(); + task_runner->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(0u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get())); stream.reset(); + task_runner->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); EXPECT_TRUE(quic_data1.AllReadDataConsumed()); EXPECT_TRUE(quic_data1.AllWriteDataConsumed()); EXPECT_TRUE(quic_data2.AllReadDataConsumed());
diff --git a/net/server/http_connection.cc b/net/server/http_connection.cc index 0fee0cc..351ef23 100644 --- a/net/server/http_connection.cc +++ b/net/server/http_connection.cc
@@ -160,7 +160,7 @@ HttpConnection::~HttpConnection() = default; void HttpConnection::SetWebSocket(std::unique_ptr<WebSocket> web_socket) { - DCHECK(!web_socket_); + DCHECK(!web_socket_ || !web_socket); web_socket_ = std::move(web_socket); }
diff --git a/net/server/http_server.cc b/net/server/http_server.cc index 75d6bb41..6629c381 100644 --- a/net/server/http_server.cc +++ b/net/server/http_server.cc
@@ -144,6 +144,7 @@ std::unique_ptr<HttpConnection> connection = std::move(it->second); id_to_connection_.erase(it); delegate_->OnClose(connection_id); + connection->SetWebSocket(nullptr); // The call stack might have callbacks which still have the pointer of // connection. Instead of referencing connection with ID all the time,
diff --git a/pdf/pdfium/pdfium_page_unittest.cc b/pdf/pdfium/pdfium_page_unittest.cc index 1397167a..be31270e5 100644 --- a/pdf/pdfium/pdfium_page_unittest.cc +++ b/pdf/pdfium/pdfium_page_unittest.cc
@@ -874,7 +874,7 @@ ASSERT_GT(stride, 0); ASSERT_EQ(image_info.minRowBytes(), static_cast<size_t>(stride)); std::vector<uint8_t> data = thumbnail.TakeData(); - sk_sp<SkImage> image = SkImage::MakeRasterCopy( + sk_sp<SkImage> image = SkImages::RasterFromPixmapCopy( SkPixmap(image_info, data.data(), image_info.minRowBytes())); ASSERT_TRUE(image);
diff --git a/printing/printing_context.cc b/printing/printing_context.cc index 3a9e75c..a6ce93f 100644 --- a/printing/printing_context.cc +++ b/printing/printing_context.cc
@@ -203,6 +203,17 @@ void PrintingContext::ApplyPrintSettings(const PrintSettings& settings) { *settings_ = settings; + +#if !BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) + if (skip_system_calls()) { + return; + } + + // TODO(crbug.com/1414968): System print dialog settings from the browser + // require platform-specific handling to be applied to device context. + NOTIMPLEMENTED() + << "Apply system dialog settings to device context not supported yet"; +#endif } } // namespace printing
diff --git a/printing/test_printing_context.cc b/printing/test_printing_context.cc index c966cf13..f5f281a41 100644 --- a/printing/test_printing_context.cc +++ b/printing/test_printing_context.cc
@@ -146,11 +146,6 @@ DCHECK(!printer_settings.external_preview) << "Not implemented"; #endif - // Windows is special case where system dialog can be shown from here. -#if !BUILDFLAG(IS_WIN) - DCHECK(!printer_settings.show_system_dialog) << "Not implemented"; -#endif - // The printer name is to be embedded in the printing context's existing // settings. const std::string& device_name = base::UTF16ToUTF8(settings_->device_name());
diff --git a/sandbox/policy/features.cc b/sandbox/policy/features.cc index 860a5e5..c169415 100644 --- a/sandbox/policy/features.cc +++ b/sandbox/policy/features.cc
@@ -47,11 +47,10 @@ base::FEATURE_ENABLED_BY_DEFAULT); // Emergency "off switch" for removal of direct system font access from -// sandboxed processes. -// Enabled until https://crbug.com/1425413 is resolved. +// web renderer processes. BASE_FEATURE(kWinSboxAllowSystemFonts, "WinSboxAllowSystemFonts", - base::FEATURE_ENABLED_BY_DEFAULT); + base::FEATURE_DISABLED_BY_DEFAULT); #endif // BUILDFLAG(IS_WIN) #if BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/services/device/geolocation/wifi_data_provider_chromeos.cc b/services/device/geolocation/wifi_data_provider_chromeos.cc index eae9cf3..e04ec58 100644 --- a/services/device/geolocation/wifi_data_provider_chromeos.cc +++ b/services/device/geolocation/wifi_data_provider_chromeos.cc
@@ -10,6 +10,7 @@ #include "base/functional/bind.h" #include "base/logging.h" +#include "base/ranges/algorithm.h" #include "base/strings/utf_string_conversions.h" #include "base/task/sequenced_task_runner.h" #include "chromeos/ash/components/network/geolocation_handler.h" @@ -28,6 +29,10 @@ const int kTwoNoChangePollingIntervalMilliseconds = 10 * 60 * 1000; // 10 mins const int kNoWifiPollingIntervalMilliseconds = 20 * 1000; // 20s +// The mobile location service (MLS) imposes a hard-coded limit on the number of +// access points that can be used to generate a position estimate. +constexpr size_t kApUseLimit = 20; + // Returns the Wi-Fi access point data from ChromeOS, or `nullopt` if the // NetworkHandler is not started or failed to acquire fresh data. absl::optional<WifiData> GetWifiData() { @@ -53,6 +58,16 @@ if (age_ms > kTwoNoChangePollingIntervalMilliseconds * 2) { return absl::nullopt; } + + // Sort AP sightings by age, most recent first. + base::ranges::sort(access_points, base::ranges::greater(), + &ash::WifiAccessPoint::timestamp); + + // Truncate to kApUseLimit. + if (access_points.size() > kApUseLimit) { + access_points.resize(kApUseLimit); + } + WifiData wifi_data; for (const auto& access_point : access_points) { AccessPointData ap_data;
diff --git a/services/network/network_change_manager.cc b/services/network/network_change_manager.cc index 87f4ea7..0cdd27c3 100644 --- a/services/network/network_change_manager.cc +++ b/services/network/network_change_manager.cc
@@ -12,7 +12,7 @@ #include "build/chromeos_buildflags.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "net/base/network_change_notifier.h" -#include "net/base/network_change_notifier_posix.h" +#include "net/base/network_change_notifier_passive.h" namespace network { @@ -62,8 +62,8 @@ if (!network_change_notifier_) return; - net::NetworkChangeNotifierPosix* notifier = - static_cast<net::NetworkChangeNotifierPosix*>( + net::NetworkChangeNotifierPassive* notifier = + static_cast<net::NetworkChangeNotifierPassive*>( network_change_notifier_.get()); if (dns_changed) notifier->OnDNSChanged();
diff --git a/services/network/network_service.cc b/services/network/network_service.cc index a5df705..e51487d 100644 --- a/services/network/network_service.cc +++ b/services/network/network_service.cc
@@ -40,7 +40,6 @@ #include "net/base/features.h" #include "net/base/logging_network_change_observer.h" #include "net/base/network_change_notifier.h" -#include "net/base/network_change_notifier_posix.h" #include "net/base/port_util.h" #include "net/cert/cert_database.h" #include "net/cert/ct_log_response_parser.h"
diff --git a/services/tracing/perfetto/privacy_filtered_fields-inl.h b/services/tracing/perfetto/privacy_filtered_fields-inl.h index 62b40cf2..b98a344 100644 --- a/services/tracing/perfetto/privacy_filtered_fields-inl.h +++ b/services/tracing/perfetto/privacy_filtered_fields-inl.h
@@ -639,7 +639,7 @@ constexpr MessageInfo kCounterDescriptor = {kCounterDescriptorIndices, nullptr}; // Proto Message: TrackDescriptor -constexpr int kTrackDescriptorIndices[] = {1, 3, 4, 5, 6, 7, 8, -1}; +constexpr int kTrackDescriptorIndices[] = {1, 3, 4, 5, 6, 7, 8, 9, -1}; constexpr MessageInfo const* kTrackDescriptorComplexMessages[] = { nullptr, &kProcessDescriptor, @@ -647,7 +647,8 @@ nullptr, &kChromeProcessDescriptor, &kChromeThreadDescriptor, - &kCounterDescriptor}; + &kCounterDescriptor, + nullptr}; constexpr MessageInfo kTrackDescriptor = {kTrackDescriptorIndices, kTrackDescriptorComplexMessages};
diff --git a/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.cc b/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.cc index bdbc564..5ee9bf9 100644 --- a/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.cc +++ b/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.cc
@@ -346,6 +346,11 @@ track_descriptor->set_uuid(thread_track.uuid); DCHECK(thread_track.parent_uuid); track_descriptor->set_parent_uuid(thread_track.parent_uuid); + // Instructs Trace Processor not to merge track events and system events + // track for this thread. + // TODO(kraskevich): Figure out how to do this for the Perfetto SDK + // version. + track_descriptor->set_disallow_merging_with_system_tracks(true); ThreadDescriptor* thread = track_descriptor->set_thread(); thread->set_pid(process_id_); thread->set_tid(trace_event->thread_id()); @@ -702,6 +707,10 @@ track_descriptor->set_uuid(thread_track.uuid); DCHECK(thread_track.parent_uuid); track_descriptor->set_parent_uuid(thread_track.parent_uuid); + // Instructs Trace Processor not to merge track events and system events + // track for this thread. + // TODO(kraskevich): Figure out how to do this for the Perfetto SDK version. + track_descriptor->set_disallow_merging_with_system_tracks(true); ThreadDescriptor* thread = track_descriptor->set_thread(); thread->set_pid(process_id_);
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h index 859ab50..7f6770c 100644 --- a/skia/config/SkUserConfig.h +++ b/skia/config/SkUserConfig.h
@@ -214,9 +214,6 @@ // Temporarily insulate Chrome pixel tests from Skia LOD bias change on GPU. #define SK_USE_LEGACY_MIPMAP_LOD_BIAS -// Temporarily insulate Chrome pixel tests from Skia luminance changes in RP. -#define SK_USE_LEGACY_RP_LUMINANCE - // Max. verb count for paths rendered by the edge-AA tessellating path renderer. #define GR_AA_TESSELLATOR_MAX_VERB_COUNT 100
diff --git a/testing/buildbot/chromium.fuchsia.fyi.json b/testing/buildbot/chromium.fuchsia.fyi.json index 2419717..b173536c 100644 --- a/testing/buildbot/chromium.fuchsia.fyi.json +++ b/testing/buildbot/chromium.fuchsia.fyi.json
@@ -3682,7 +3682,7 @@ { "kvm": "1", "machine_type": "e2-standard-2", - "os": "Ubuntu-18.04", + "os": "Ubuntu-20.04", "pool": "chromium.tests.fuchsia" } ], @@ -3705,7 +3705,7 @@ { "kvm": "1", "machine_type": "e2-standard-2", - "os": "Ubuntu-18.04", + "os": "Ubuntu-20.04", "pool": "chromium.tests.fuchsia" } ], @@ -3728,7 +3728,7 @@ { "kvm": "1", "machine_type": "e2-standard-2", - "os": "Ubuntu-18.04", + "os": "Ubuntu-20.04", "pool": "chromium.tests.fuchsia" } ], @@ -3751,7 +3751,7 @@ { "kvm": "1", "machine_type": "e2-standard-2", - "os": "Ubuntu-18.04", + "os": "Ubuntu-20.04", "pool": "chromium.tests.fuchsia" } ], @@ -3774,7 +3774,7 @@ { "kvm": "1", "machine_type": "e2-standard-2", - "os": "Ubuntu-18.04", + "os": "Ubuntu-20.04", "pool": "chromium.tests.fuchsia" } ], @@ -3798,7 +3798,7 @@ { "kvm": "1", "machine_type": "e2-standard-2", - "os": "Ubuntu-18.04", + "os": "Ubuntu-20.04", "pool": "chromium.tests.fuchsia" } ], @@ -3821,7 +3821,7 @@ { "kvm": "1", "machine_type": "e2-standard-2", - "os": "Ubuntu-18.04", + "os": "Ubuntu-20.04", "pool": "chromium.tests.fuchsia" } ],
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 66e4d9c..f2d0a942 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -33914,7 +33914,7 @@ "--platform", "iPhone 6s", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -33928,7 +33928,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "absl_hardening_tests iPhone 6s 14.4", + "name": "absl_hardening_tests iPhone 6s 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -33954,14 +33954,14 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://third_party/abseil-cpp:absl_hardening_tests/", - "variant_id": "iPhone 6s 14.4" + "variant_id": "iPhone 6s 14.5" }, { "args": [ @@ -34346,7 +34346,7 @@ "--platform", "iPhone 6s", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -34360,7 +34360,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "boringssl_crypto_tests iPhone 6s 14.4", + "name": "boringssl_crypto_tests iPhone 6s 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -34386,14 +34386,14 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://third_party/boringssl:boringssl_crypto_tests/", - "variant_id": "iPhone 6s 14.4" + "variant_id": "iPhone 6s 14.5" }, { "args": [ @@ -34508,7 +34508,7 @@ "--platform", "iPhone 6s", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -34522,7 +34522,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "boringssl_ssl_tests iPhone 6s 14.4", + "name": "boringssl_ssl_tests iPhone 6s 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -34548,14 +34548,14 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://third_party/boringssl:boringssl_ssl_tests/", - "variant_id": "iPhone 6s 14.4" + "variant_id": "iPhone 6s 14.5" }, { "args": [ @@ -34940,7 +34940,7 @@ "--platform", "iPhone 6s", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -34954,7 +34954,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "crashpad_tests iPhone 6s 14.4", + "name": "crashpad_tests iPhone 6s 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -34980,14 +34980,14 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://third_party/crashpad/crashpad:crashpad_tests/", - "variant_id": "iPhone 6s 14.4" + "variant_id": "iPhone 6s 14.5" }, { "args": [ @@ -35102,7 +35102,7 @@ "--platform", "iPhone 6s", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -35116,7 +35116,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "crypto_unittests iPhone 6s 14.4", + "name": "crypto_unittests iPhone 6s 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -35142,14 +35142,14 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://crypto:crypto_unittests/", - "variant_id": "iPhone 6s 14.4" + "variant_id": "iPhone 6s 14.5" }, { "args": [ @@ -35534,7 +35534,7 @@ "--platform", "iPhone 6s", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -35548,7 +35548,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "google_apis_unittests iPhone 6s 14.4", + "name": "google_apis_unittests iPhone 6s 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -35574,14 +35574,14 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://google_apis:google_apis_unittests/", - "variant_id": "iPhone 6s 14.4" + "variant_id": "iPhone 6s 14.5" }, { "args": [ @@ -35753,7 +35753,7 @@ "--platform", "iPad Air 2", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -35770,7 +35770,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_bookmarks_eg2tests_module iPad Air 2 14.4", + "name": "ios_chrome_bookmarks_eg2tests_module iPad Air 2 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -35796,14 +35796,14 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/", - "variant_id": "iPad Air 2 14.4" + "variant_id": "iPad Air 2 14.5" }, { "args": [ @@ -35981,7 +35981,7 @@ "--platform", "iPhone 7", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -35998,7 +35998,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_bookmarks_eg2tests_module iPhone 7 14.4", + "name": "ios_chrome_bookmarks_eg2tests_module iPhone 7 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -36024,14 +36024,14 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/", - "variant_id": "iPhone 7 14.4" + "variant_id": "iPhone 7 14.5" }, { "args": [ @@ -36152,7 +36152,7 @@ "--platform", "iPhone X", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -36169,7 +36169,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_bookmarks_eg2tests_module iPhone X 14.4", + "name": "ios_chrome_bookmarks_eg2tests_module iPhone X 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -36195,14 +36195,14 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/", - "variant_id": "iPhone X 14.4" + "variant_id": "iPhone X 14.5" }, { "args": [ @@ -36381,7 +36381,7 @@ "--platform", "iPad Air 2", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -36398,7 +36398,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_integration_eg2tests_module iPad Air 2 14.4", + "name": "ios_chrome_integration_eg2tests_module iPad Air 2 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -36424,15 +36424,15 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", "shards": 8 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_integration_eg2tests_module/", - "variant_id": "iPad Air 2 14.4" + "variant_id": "iPad Air 2 14.5" }, { "args": [ @@ -36613,7 +36613,7 @@ "--platform", "iPhone 7", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -36630,7 +36630,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_integration_eg2tests_module iPhone 7 14.4", + "name": "ios_chrome_integration_eg2tests_module iPhone 7 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -36656,15 +36656,15 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", "shards": 8 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_integration_eg2tests_module/", - "variant_id": "iPhone 7 14.4" + "variant_id": "iPhone 7 14.5" }, { "args": [ @@ -36787,7 +36787,7 @@ "--platform", "iPhone X", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -36804,7 +36804,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_integration_eg2tests_module iPhone X 14.4", + "name": "ios_chrome_integration_eg2tests_module iPhone X 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -36830,15 +36830,15 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", "shards": 8 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_integration_eg2tests_module/", - "variant_id": "iPhone X 14.4" + "variant_id": "iPhone X 14.5" }, { "args": [ @@ -37019,7 +37019,7 @@ "--platform", "iPad Air 2", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -37036,7 +37036,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_settings_eg2tests_module iPad Air 2 14.4", + "name": "ios_chrome_settings_eg2tests_module iPad Air 2 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -37062,15 +37062,15 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", "shards": 3 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/", - "variant_id": "iPad Air 2 14.4" + "variant_id": "iPad Air 2 14.5" }, { "args": [ @@ -37251,7 +37251,7 @@ "--platform", "iPhone 7", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -37268,7 +37268,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_settings_eg2tests_module iPhone 7 14.4", + "name": "ios_chrome_settings_eg2tests_module iPhone 7 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -37294,15 +37294,15 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", "shards": 3 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/", - "variant_id": "iPhone 7 14.4" + "variant_id": "iPhone 7 14.5" }, { "args": [ @@ -37425,7 +37425,7 @@ "--platform", "iPhone X", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -37442,7 +37442,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_settings_eg2tests_module iPhone X 14.4", + "name": "ios_chrome_settings_eg2tests_module iPhone X 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -37468,15 +37468,15 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", "shards": 3 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/", - "variant_id": "iPhone X 14.4" + "variant_id": "iPhone X 14.5" }, { "args": [ @@ -37657,7 +37657,7 @@ "--platform", "iPad Air 2", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -37674,7 +37674,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_signin_eg2tests_module iPad Air 2 14.4", + "name": "ios_chrome_signin_eg2tests_module iPad Air 2 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -37700,15 +37700,15 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", "shards": 6 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_signin_eg2tests_module/", - "variant_id": "iPad Air 2 14.4" + "variant_id": "iPad Air 2 14.5" }, { "args": [ @@ -37889,7 +37889,7 @@ "--platform", "iPhone 7", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -37906,7 +37906,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_signin_eg2tests_module iPhone 7 14.4", + "name": "ios_chrome_signin_eg2tests_module iPhone 7 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -37932,15 +37932,15 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", "shards": 6 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_signin_eg2tests_module/", - "variant_id": "iPhone 7 14.4" + "variant_id": "iPhone 7 14.5" }, { "args": [ @@ -38063,7 +38063,7 @@ "--platform", "iPhone X", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -38080,7 +38080,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_signin_eg2tests_module iPhone X 14.4", + "name": "ios_chrome_signin_eg2tests_module iPhone X 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -38106,15 +38106,15 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", "shards": 6 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_signin_eg2tests_module/", - "variant_id": "iPhone X 14.4" + "variant_id": "iPhone X 14.5" }, { "args": [ @@ -38294,7 +38294,7 @@ "--platform", "iPad Air 2", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -38311,7 +38311,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_smoke_eg2tests_module iPad Air 2 14.4", + "name": "ios_chrome_smoke_eg2tests_module iPad Air 2 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -38337,14 +38337,14 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/", - "variant_id": "iPad Air 2 14.4" + "variant_id": "iPad Air 2 14.5" }, { "args": [ @@ -38522,7 +38522,7 @@ "--platform", "iPhone 7", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -38539,7 +38539,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_smoke_eg2tests_module iPhone 7 14.4", + "name": "ios_chrome_smoke_eg2tests_module iPhone 7 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -38565,14 +38565,14 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/", - "variant_id": "iPhone 7 14.4" + "variant_id": "iPhone 7 14.5" }, { "args": [ @@ -38693,7 +38693,7 @@ "--platform", "iPhone X", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -38710,7 +38710,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_smoke_eg2tests_module iPhone X 14.4", + "name": "ios_chrome_smoke_eg2tests_module iPhone X 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -38736,14 +38736,14 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/", - "variant_id": "iPhone X 14.4" + "variant_id": "iPhone X 14.5" }, { "args": [ @@ -38922,7 +38922,7 @@ "--platform", "iPad Air 2", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -38939,7 +38939,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_ui_eg2tests_module iPad Air 2 14.4", + "name": "ios_chrome_ui_eg2tests_module iPad Air 2 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -38965,15 +38965,15 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", "shards": 12 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_ui_eg2tests_module/", - "variant_id": "iPad Air 2 14.4" + "variant_id": "iPad Air 2 14.5" }, { "args": [ @@ -39154,7 +39154,7 @@ "--platform", "iPhone 7", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -39171,7 +39171,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_ui_eg2tests_module iPhone 7 14.4", + "name": "ios_chrome_ui_eg2tests_module iPhone 7 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -39197,15 +39197,15 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", "shards": 12 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_ui_eg2tests_module/", - "variant_id": "iPhone 7 14.4" + "variant_id": "iPhone 7 14.5" }, { "args": [ @@ -39328,7 +39328,7 @@ "--platform", "iPhone X", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -39345,7 +39345,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_ui_eg2tests_module iPhone X 14.4", + "name": "ios_chrome_ui_eg2tests_module iPhone X 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -39371,15 +39371,15 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", "shards": 12 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_ui_eg2tests_module/", - "variant_id": "iPhone X 14.4" + "variant_id": "iPhone X 14.5" }, { "args": [ @@ -39830,7 +39830,7 @@ "--platform", "iPad Air 2", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -39847,7 +39847,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_web_eg2tests_module iPad Air 2 14.4", + "name": "ios_chrome_web_eg2tests_module iPad Air 2 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -39873,15 +39873,15 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", "shards": 2 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/", - "variant_id": "iPad Air 2 14.4" + "variant_id": "iPad Air 2 14.5" }, { "args": [ @@ -40062,7 +40062,7 @@ "--platform", "iPhone 7", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -40079,7 +40079,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_web_eg2tests_module iPhone 7 14.4", + "name": "ios_chrome_web_eg2tests_module iPhone 7 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -40105,15 +40105,15 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", "shards": 2 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/", - "variant_id": "iPhone 7 14.4" + "variant_id": "iPhone 7 14.5" }, { "args": [ @@ -40236,7 +40236,7 @@ "--platform", "iPhone X", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -40253,7 +40253,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_web_eg2tests_module iPhone X 14.4", + "name": "ios_chrome_web_eg2tests_module iPhone X 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -40279,15 +40279,15 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", "shards": 2 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/", - "variant_id": "iPhone X 14.4" + "variant_id": "iPhone X 14.5" }, { "args": [ @@ -40410,7 +40410,7 @@ "--platform", "iPhone 6s", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -40424,7 +40424,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_components_unittests iPhone 6s 14.4", + "name": "ios_components_unittests iPhone 6s 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -40450,14 +40450,14 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://ios/components:ios_components_unittests/", - "variant_id": "iPhone 6s 14.4" + "variant_id": "iPhone 6s 14.5" }, { "args": [ @@ -40572,7 +40572,7 @@ "--platform", "iPhone 6s", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -40587,7 +40587,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_crash_xcuitests_module iPhone 6s 14.4", + "name": "ios_crash_xcuitests_module iPhone 6s 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -40613,14 +40613,14 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://third_party/crashpad/crashpad/test/ios:ios_crash_xcuitests_module/", - "variant_id": "iPhone 6s 14.4" + "variant_id": "iPhone 6s 14.5" }, { "args": [ @@ -40737,7 +40737,7 @@ "--platform", "iPhone 6s", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -40751,7 +40751,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_net_unittests iPhone 6s 14.4", + "name": "ios_net_unittests iPhone 6s 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -40777,15 +40777,15 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", "shards": 3 }, "test_id_prefix": "ninja://ios/net:ios_net_unittests/", - "variant_id": "iPhone 6s 14.4" + "variant_id": "iPhone 6s 14.5" }, { "args": [ @@ -40902,7 +40902,7 @@ "--platform", "iPhone 6s", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -40916,7 +40916,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_remoting_unittests iPhone 6s 14.4", + "name": "ios_remoting_unittests iPhone 6s 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -40942,14 +40942,14 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://remoting/ios:ios_remoting_unittests/", - "variant_id": "iPhone 6s 14.4" + "variant_id": "iPhone 6s 14.5" }, { "args": [ @@ -41121,7 +41121,7 @@ "--platform", "iPad Air 2", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -41138,7 +41138,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_showcase_eg2tests_module iPad Air 2 14.4", + "name": "ios_showcase_eg2tests_module iPad Air 2 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -41164,14 +41164,14 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/", - "variant_id": "iPad Air 2 14.4" + "variant_id": "iPad Air 2 14.5" }, { "args": [ @@ -41349,7 +41349,7 @@ "--platform", "iPhone 7", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -41366,7 +41366,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_showcase_eg2tests_module iPhone 7 14.4", + "name": "ios_showcase_eg2tests_module iPhone 7 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -41392,14 +41392,14 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/", - "variant_id": "iPhone 7 14.4" + "variant_id": "iPhone 7 14.5" }, { "args": [ @@ -41520,7 +41520,7 @@ "--platform", "iPhone X", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -41537,7 +41537,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_showcase_eg2tests_module iPhone X 14.4", + "name": "ios_showcase_eg2tests_module iPhone X 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -41563,14 +41563,14 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/", - "variant_id": "iPhone X 14.4" + "variant_id": "iPhone X 14.5" }, { "args": [ @@ -41801,7 +41801,7 @@ "--platform", "iPhone 6s", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -41815,7 +41815,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_testing_unittests iPhone 6s 14.4", + "name": "ios_testing_unittests iPhone 6s 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -41841,14 +41841,14 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://ios/testing:ios_testing_unittests/", - "variant_id": "iPhone 6s 14.4" + "variant_id": "iPhone 6s 14.5" }, { "args": [ @@ -42290,7 +42290,7 @@ "--platform", "iPad Air 2", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -42307,7 +42307,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_web_shell_eg2tests_module iPad Air 2 14.4", + "name": "ios_web_shell_eg2tests_module iPad Air 2 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -42333,14 +42333,14 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://ios/web/shell/test:ios_web_shell_eg2tests_module/", - "variant_id": "iPad Air 2 14.4" + "variant_id": "iPad Air 2 14.5" }, { "args": [ @@ -42518,7 +42518,7 @@ "--platform", "iPhone 7", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -42535,7 +42535,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_web_shell_eg2tests_module iPhone 7 14.4", + "name": "ios_web_shell_eg2tests_module iPhone 7 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -42561,14 +42561,14 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://ios/web/shell/test:ios_web_shell_eg2tests_module/", - "variant_id": "iPhone 7 14.4" + "variant_id": "iPhone 7 14.5" }, { "args": [ @@ -42689,7 +42689,7 @@ "--platform", "iPhone X", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -42706,7 +42706,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_web_shell_eg2tests_module iPhone X 14.4", + "name": "ios_web_shell_eg2tests_module iPhone X 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -42732,14 +42732,14 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://ios/web/shell/test:ios_web_shell_eg2tests_module/", - "variant_id": "iPhone X 14.4" + "variant_id": "iPhone X 14.5" }, { "args": [ @@ -43670,7 +43670,7 @@ "--platform", "iPhone 6s", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -43684,7 +43684,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "net_unittests iPhone 6s 14.4", + "name": "net_unittests iPhone 6s 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -43710,14 +43710,14 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://net:net_unittests/", - "variant_id": "iPhone 6s 14.4" + "variant_id": "iPhone 6s 14.5" }, { "args": [ @@ -43832,7 +43832,7 @@ "--platform", "iPhone 6s", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -43846,7 +43846,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "services_unittests iPhone 6s 14.4", + "name": "services_unittests iPhone 6s 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -43872,14 +43872,14 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://services:services_unittests/", - "variant_id": "iPhone 6s 14.4" + "variant_id": "iPhone 6s 14.5" }, { "args": [ @@ -44264,7 +44264,7 @@ "--platform", "iPhone 6s", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -44278,7 +44278,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "sql_unittests iPhone 6s 14.4", + "name": "sql_unittests iPhone 6s 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -44304,14 +44304,14 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://sql:sql_unittests/", - "variant_id": "iPhone 6s 14.4" + "variant_id": "iPhone 6s 14.5" }, { "args": [ @@ -44696,7 +44696,7 @@ "--platform", "iPhone 6s", "--version", - "14.4", + "14.5", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", @@ -44710,7 +44710,7 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "url_unittests iPhone 6s 14.4", + "name": "url_unittests iPhone 6s 14.5", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -44736,14 +44736,14 @@ "path": "Xcode.app" }, { - "name": "runtime_ios_14_4", - "path": "Runtime-ios-14.4" + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://url:url_unittests/", - "variant_id": "iPhone 6s 14.4" + "variant_id": "iPhone 6s 14.5" }, { "args": [
diff --git a/testing/buildbot/mixins.pyl b/testing/buildbot/mixins.pyl index c3d950b..77b7890 100644 --- a/testing/buildbot/mixins.pyl +++ b/testing/buildbot/mixins.pyl
@@ -606,18 +606,6 @@ ], }, }, - 'ios_runtime_cache_14_4': { - '$mixin_append': { - 'swarming': { - 'named_caches': [ - { - 'name': 'runtime_ios_14_4', - 'path': 'Runtime-ios-14.4', - }, - ], - }, - }, - }, 'ios_runtime_cache_14_5': { '$mixin_append': { 'swarming': {
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 9f877d2..0e3e6752 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -7043,7 +7043,7 @@ 'variants': [ 'SIM_IPHONE_8_16_2', 'SIM_IPHONE_6S_15_5', - 'SIM_IPHONE_6S_14_4', + 'SIM_IPHONE_6S_14_5', ], }, 'ios_crash_xcuitests': { @@ -7051,7 +7051,7 @@ 'variants': [ 'SIM_IPHONE_X_16_2', 'SIM_IPHONE_6S_15_5', - 'SIM_IPHONE_6S_14_4', + 'SIM_IPHONE_6S_14_5', ] }, 'ios_eg2_tests': { @@ -7063,9 +7063,9 @@ 'SIM_IPHONE_7_15_5', 'SIM_IPAD_AIR_2_15_5', 'SIM_IPHONE_X_15_5', - 'SIM_IPHONE_7_14_4', - 'SIM_IPAD_AIR_2_14_4', - 'SIM_IPHONE_X_14_4', + 'SIM_IPHONE_7_14_5', + 'SIM_IPAD_AIR_2_14_5', + 'SIM_IPHONE_X_14_5', 'SIM_IPAD_PRO_3RD_GEN_15_5', 'SIM_IPAD_PRO_3RD_GEN_16_2', ] @@ -7079,9 +7079,9 @@ 'SIM_IPHONE_7_15_5', 'SIM_IPAD_AIR_2_15_5', 'SIM_IPHONE_X_15_5', - 'SIM_IPHONE_7_14_4', - 'SIM_IPAD_AIR_2_14_4', - 'SIM_IPHONE_X_14_4', + 'SIM_IPHONE_7_14_5', + 'SIM_IPAD_AIR_2_14_5', + 'SIM_IPHONE_X_14_5', 'SIM_IPAD_PRO_3RD_GEN_15_5', 'SIM_IPAD_PRO_3RD_GEN_16_2', ]
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index 7004ca09..c05548b8 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -127,18 +127,6 @@ 'ios_runtime_cache_14_5', ], }, - 'SIM_IPAD_AIR_2_14_4': { - 'args': [ - '--platform', - 'iPad Air 2', - '--version', - '14.4' - ], - 'identifier': 'iPad Air 2 14.4', - 'mixins': [ - 'ios_runtime_cache_14_4', - ], - }, 'SIM_IPAD_AIR_2_15_5': { 'args': [ '--platform', @@ -234,18 +222,6 @@ 'ios_runtime_cache_16_2', ], }, - 'SIM_IPHONE_6S_14_4': { - 'args': [ - '--platform', - 'iPhone 6s', - '--version', - '14.4', - ], - 'identifier': 'iPhone 6s 14.4', - 'mixins': [ - 'ios_runtime_cache_14_4', - ], - }, 'SIM_IPHONE_6S_14_5': { 'args': [ '--platform', @@ -294,18 +270,6 @@ 'ios_runtime_cache_15_5', ], }, - 'SIM_IPHONE_7_14_4': { - 'args': [ - '--platform', - 'iPhone 7', - '--version', - '14.4', - ], - 'identifier': 'iPhone 7 14.4', - 'mixins': [ - 'ios_runtime_cache_14_4', - ], - }, 'SIM_IPHONE_7_14_5': { 'args': [ '--platform', @@ -390,18 +354,6 @@ 'ios_runtime_cache_16_2', ], }, - 'SIM_IPHONE_X_14_4': { - 'args': [ - '--platform', - 'iPhone X', - '--version', - '14.4', - ], - 'identifier': 'iPhone X 14.4', - 'mixins': [ - 'ios_runtime_cache_14_4', - ], - }, 'SIM_IPHONE_X_14_5': { 'args': [ '--platform',
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 9fb7e88fa..2a573c2 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -2814,7 +2814,7 @@ 'os_type': 'fuchsia', 'mixins': [ 'fuchsia-persistent-emulator', - 'linux-bionic', + 'linux-focal', ], 'swarming': { 'dimension_sets': [
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 39162bb..8174cde 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -4644,28 +4644,6 @@ ] } ], - "ElementSuperRareData": [ - { - "platforms": [ - "android", - "chromeos", - "chromeos_lacros", - "fuchsia", - "ios", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "ElementSuperRareData" - ] - } - ] - } - ], "EmitHistogramsEarlier": [ { "platforms": [ @@ -8054,6 +8032,21 @@ ] } ], + "MojoIpczMac": [ + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "Enabled_1", + "enable_features": [ + "MojoIpcz" + ] + } + ] + } + ], "MoreAggressiveSolidColorDetection": [ { "platforms": [ @@ -8527,6 +8520,59 @@ ] } ], + "OmniboxUISimplificationDesktop": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_40px_RowHeight_SuggestIconBackgrounds_Non_Entities_Only", + "params": { + "OmniboxRichSuggestionVerticalMargin": "6", + "OmniboxSquareSuggestIconAnswers": "true", + "OmniboxSquareSuggestIconEntities": "false", + "OmniboxSquareSuggestIconIcons": "true" + }, + "enable_features": [ + "OmniboxSquareIcons", + "OmniboxUniformRowHeight" + ] + }, + { + "name": "Enabled_36px_RowHeight", + "params": { + "OmniboxRichSuggestionVerticalMargin": "4" + }, + "enable_features": [ + "OmniboxUniformRowHeight" + ], + "disable_features": [ + "OmniboxSquareIcons" + ] + }, + { + "name": "Enabled_40px_RowHeight_SuggestIconBackgrounds_13pct_Shrinkage", + "params": { + "OmniboxRichSuggestionVerticalMargin": "6", + "OmniboxSquareSuggestIconAnswers": "true", + "OmniboxSquareSuggestIconEntities": "true", + "OmniboxSquareSuggestIconEntitiesScale": "0.8722", + "OmniboxSquareSuggestIconIcons": "true" + }, + "enable_features": [ + "OmniboxSquareIcons", + "OmniboxUniformRowHeight" + ] + } + ] + } + ], "OmniboxZeroSuggestPrefetchingWithInMemoryCaching": [ { "platforms": [ @@ -9548,33 +9594,34 @@ ], "experiments": [ { - "name": "EnabledMemorySaverDefaultOn_20221107", + "name": "Enabled_OptIn", "params": { "IPH_BatterySaverMode_availability": "any", "IPH_BatterySaverMode_event_trigger": "name:battery_saver_info_triggered;comparator:<3;window:360;storage:360", "IPH_BatterySaverMode_event_used": "name:battery_saver_info_shown;comparator:==0;window:7;storage:360", "IPH_BatterySaverMode_session_rate": "==0", - "IPH_HighEfficiencyInfoMode_availability": "any", - "IPH_HighEfficiencyInfoMode_event_trigger": "name:high_efficiency_info_trigger;comparator:<3;window:360;storage:360", - "IPH_HighEfficiencyInfoMode_event_used": "name:high_efficiency_info_shown;comparator:==0;window:7;storage:360", - "IPH_HighEfficiencyInfoMode_session_rate": "==0", + "IPH_HighEfficiencyMode_availability": "any", + "IPH_HighEfficiencyMode_event_1": "name:high_efficiency_prompt_in_trigger;comparator:<3;window:360;storage:360", + "IPH_HighEfficiencyMode_event_trigger": "name:high_efficiency_prompt_in_trigger;comparator:<1;window:1;storage:360", + "IPH_HighEfficiencyMode_event_used": "name:high_efficiency_prompt_in_used;comparator:==0;window:360;storage:360", + "IPH_HighEfficiencyMode_session_rate": "any", "IPH_PerformanceNewBadge_availability": "any", "IPH_PerformanceNewBadge_event_trigger": "name:performance_new_badge_shown;comparator:<20;window:360;storage:360", "IPH_PerformanceNewBadge_event_used": "name:performance_activated;comparator:<3;window:360;storage:360", "IPH_PerformanceNewBadge_session_rate": "any", "IPH_PerformanceNewBadge_session_rate_impact": "none", - "default_state": "true" + "default_state": "false" }, "enable_features": [ "BatterySaverModeAvailable", "HighEfficiencyModeAvailable", "IPH_BatterySaverMode", - "IPH_HighEfficiencyInfoMode", + "IPH_HighEfficiencyMode", "IPH_PerformanceNewBadge", "PageTimelineMonitor" ], "disable_features": [ - "IPH_HighEfficiencyMode" + "IPH_HighEfficiencyInfoMode" ] } ]
diff --git a/third_party/blink/public/common/fenced_frame/redacted_fenced_frame_config.h b/third_party/blink/public/common/fenced_frame/redacted_fenced_frame_config.h index ac59b31..1a0c9b88 100644 --- a/third_party/blink/public/common/fenced_frame/redacted_fenced_frame_config.h +++ b/third_party/blink/public/common/fenced_frame/redacted_fenced_frame_config.h
@@ -8,12 +8,12 @@ #ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_FENCED_FRAME_REDACTED_FENCED_FRAME_CONFIG_H_ #define THIRD_PARTY_BLINK_PUBLIC_COMMON_FENCED_FRAME_REDACTED_FENCED_FRAME_CONFIG_H_ -#include "base/containers/flat_map.h" -#include "base/functional/callback_forward.h" -#include "base/memory/raw_ptr.h" +#include <string> +#include <utility> +#include <vector> + #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/common/common_export.h" -#include "third_party/blink/public/mojom/fenced_frame/fenced_frame.mojom.h" #include "third_party/blink/public/mojom/fenced_frame/fenced_frame_config.mojom-forward.h" #include "ui/gfx/geometry/size.h" #include "url/gurl.h"
diff --git a/third_party/blink/public/common/input/web_gesture_event.h b/third_party/blink/public/common/input/web_gesture_event.h index 16a5540f3..889e607 100644 --- a/third_party/blink/public/common/input/web_gesture_event.h +++ b/third_party/blink/public/common/input/web_gesture_event.h
@@ -107,14 +107,14 @@ // True if this event is generated from a mousewheel or scrollbar. // Synthetic GSB(s) are ignored by the blink::ElasticOverscrollController. bool synthetic; - // If true, this event has been hit tested by the main thread and the - // result is stored in scrollable_area_element_id. Used only in scroll - // unification when the event is sent back the the compositor for a - // second time after the main thread hit test is complete. - bool main_thread_hit_tested; // If true, this event will be used for cursor control instead of // scrolling. the entire scroll sequence will be used for cursor control. bool cursor_control; + // If nonzero, this event has been hit tested by the main thread and the + // result is stored in scrollable_area_element_id. Used only in scroll + // unification when the event is sent back the the compositor for a + // second time after the main thread hit test is complete. + uint32_t main_thread_hit_tested_reasons; } scroll_begin; struct {
diff --git a/third_party/blink/public/web/web_ax_object.h b/third_party/blink/public/web/web_ax_object.h index d893b16..4016362 100644 --- a/third_party/blink/public/web/web_ax_object.h +++ b/third_party/blink/public/web/web_ax_object.h
@@ -110,25 +110,15 @@ int ImageDataNodeId() const; ax::mojom::CheckedState CheckedState() const; - bool IsCheckable() const; bool IsClickable() const; - bool IsControl() const; bool IsFocused() const; - bool IsLineBreakingObject() const; - bool IsLinked() const; bool IsModal() const; - // Returns true if this object is an input element of a text field type, such - // as type="text" or type="tel", or a textarea. - bool IsAtomicTextField() const; bool IsOffScreen() const; bool IsSelectedOptionActive() const; bool IsVisited() const; - WebString AccessKey() const; bool CanSetValueAttribute() const; - // Deprecated. - void ColorValue(int& r, int& g, int& b) const; unsigned ColorValue() const; WebAXObject AriaActiveDescendant() const; WebString AutoComplete() const; @@ -136,7 +126,6 @@ bool IsEditable() const; bool AriaOwns(WebVector<WebAXObject>& owns_elements) const; bool CanvasHasFallbackContent() const; - WebAXObject ErrorMessage() const; ax::mojom::InvalidState InvalidState() const; int HeadingLevel() const; int HierarchicalLevel() const; @@ -192,7 +181,6 @@ bool LiveRegionAtomic() const; WebString LiveRegionRelevant() const; WebString LiveRegionStatus() const; - bool ContainerLiveRegionAtomic() const; bool SupportsRangeValue() const; bool ValueForRange(float* out_value) const;
diff --git a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc index e999197..07f5b29 100644 --- a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc +++ b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
@@ -1095,20 +1095,6 @@ AdjustAnchorQueryStyles(builder); - if (!HasFullNGFragmentationSupport()) { - // When establishing a block fragmentation context for LayoutNG, we require - // that everything fragmentable inside can be laid out by NG natively, since - // NG and legacy layout cannot cooperate within the same fragmentation - // context. And vice versa (everything inside a legacy fragmentation context - // needs to be legacy objects, in order to be fragmentable). Set a flag, so - // that we can quickly determine whether we need to check that an element is - // compatible with the block fragmentation implementation being used. - if (builder.SpecifiesColumns() || - (element && element->GetDocument().Printing())) { - builder.SetInsideFragmentationContextWithNondeterministicEngine(true); - } - } - if (element && element->HasCustomStyleCallbacks()) { element->AdjustStyle(base::PassKey<StyleAdjuster>(), builder); }
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc index b83f3442..8b07b57 100644 --- a/third_party/blink/renderer/core/css/style_engine.cc +++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -3861,25 +3861,6 @@ parent_for_detached_subtree_ = nullptr; } -void StyleEngine::ReportUseOfLegacyLayoutWithContainerQueries() { - DCHECK(!HasFullNGFragmentationSupport()); - - // Only report once. - if (legacy_layout_query_container_) { - return; - } - - legacy_layout_query_container_ = true; - - ConsoleMessage* console_message = MakeGarbageCollected<ConsoleMessage>( - mojom::blink::ConsoleMessageSource::kRendering, - mojom::blink::ConsoleMessageLevel::kWarning, - String::Format( - "Using container queries or units with printing, or in combination " - "with tables inside multicol will not work correctly.")); - GetDocument().AddConsoleMessage(console_message); -} - bool StyleEngine::AllowSkipStyleRecalcForScope() const { if (InContainerQueryStyleRecalc()) { return true;
diff --git a/third_party/blink/renderer/core/css/style_engine.h b/third_party/blink/renderer/core/css/style_engine.h index 2b3eaed..eeb1ca0b 100644 --- a/third_party/blink/renderer/core/css/style_engine.h +++ b/third_party/blink/renderer/core/css/style_engine.h
@@ -659,10 +659,6 @@ return active_user_style_sheets_; } - // Report a warning to the console that we are combining legacy layout and - // container queries. - void ReportUseOfLegacyLayoutWithContainerQueries(); - private: // FontSelectorClient implementation. void FontsNeedUpdate(FontSelector*, FontInvalidationReason) override; @@ -896,10 +892,6 @@ // Set to true if we are allowed to skip recalc for a size container subtree. bool allow_skip_style_recalc_{false}; - // Set to true if we have detected an element which is a size query container - // rendered in legacy layout. - bool legacy_layout_query_container_{false}; - // See enum ViewportUnitFlag. unsigned viewport_unit_dirty_flags_{0}; @@ -1020,12 +1012,6 @@ fill_or_clip_path_uri_value_cache_; }; -// Helper function for checking if we need to handle legacy fragmentation cases -// for container queries. -inline bool HasFullNGFragmentationSupport() { - return RuntimeEnabledFeatures::LayoutNGPrintingEnabled(); -} - void PossiblyScheduleNthPseudoInvalidations(Node& node); } // namespace blink
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index 6b6f586..d815499 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -403,6 +403,7 @@ class IntrinsicSizeResizeObserverDelegate : public ResizeObserver::Delegate { public: void OnResize(const HeapVector<Member<ResizeObserverEntry>>& entries) final; + ResizeObserver::DeliveryTime Delivery() const final; }; // Returns true if any of <object> ancestors don't start loading or are loading @@ -620,6 +621,11 @@ } } +ResizeObserver::DeliveryTime IntrinsicSizeResizeObserverDelegate::Delivery() + const { + return ResizeObserver::DeliveryTime::kBeforeOthers; +} + void Document::UnassociatedListedElementsList::MarkDirty() { dirty_ = true; list_.clear();
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index 14a0442..a9f0eb2 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -421,22 +421,6 @@ return false; } -bool CalculateStyleShouldForceLegacyLayout(const Element& element, - const ComputedStyle& style) { - Document& document = element.GetDocument(); - - if (style.DisplayTypeRequiresLayoutNG()) { - return false; - } - - if (document.Printing() && element == document.documentElement() && - !RuntimeEnabledFeatures::LayoutNGPrintingEnabled()) { - return true; - } - - return false; -} - bool HasLeftwardDirection(const Element& element) { auto* style = element.GetComputedStyle(); if (!style) { @@ -612,15 +596,6 @@ if (!NGBlockNode::CanUseNewLayout(*box)) { return false; } - // Out-of-flow positioned replaced elements take the legacy path for layout - // if the container for positioning is a legacy object. That is the case for - // LayoutView, which is a legacy object but does not otherwise force - // legacy layout objects. - if (!RuntimeEnabledFeatures::LayoutNGPrintingEnabled() && - layout_object.IsOutOfFlowPositioned() && - layout_object.IsLayoutReplaced()) { - return false; - } return true; } @@ -2926,11 +2901,6 @@ ? LegacyLayout::kForce : LegacyLayout::kAuto; - if (legacy == LegacyLayout::kForce && - style->IsContainerForSizeContainerQueries()) { - style_engine.ReportUseOfLegacyLayoutWithContainerQueries(); - } - LayoutTreeBuilderForElement builder(*this, context, style, legacy); builder.CreateLayoutObject(); @@ -3537,17 +3507,6 @@ if (!new_style.IsContainerForSizeContainerQueries()) { return nullptr; } - if (LayoutObject* layout_object = element.GetLayoutObject()) { - if (layout_object->ForceLegacyLayout()) { - element.GetDocument() - .GetStyleEngine() - .ReportUseOfLegacyLayoutWithContainerQueries(); - } - } - } - if (!RuntimeEnabledFeatures::LayoutNGPrintingEnabled() && - element.GetDocument().Printing()) { - return nullptr; } // If we're switching to display:contents, any existing results cached on // ContainerQueryEvaluator are no longer valid, since any style recalc @@ -5731,6 +5690,7 @@ EnsureElementRareData().SetAffectedByMultipleHas(); } +// TODO(1229581): Remove this function. bool Element::UpdateForceLegacyLayout(const ComputedStyle& new_style, const ComputedStyle* old_style) { // ::first-letter may cause structure discrepancies between DOM and layout @@ -5746,8 +5706,7 @@ } bool needs_reattach = false; bool old_force = old_style && ShouldForceLegacyLayout(); - SetStyleShouldForceLegacyLayout( - CalculateStyleShouldForceLegacyLayout(*this, new_style)); + SetStyleShouldForceLegacyLayout(false); if (ShouldForceLegacyLayout()) { if (!old_force) { if (const LayoutObject* layout_object = GetLayoutObject()) { @@ -5820,9 +5779,6 @@ if (container_recalc_root == ancestor) { DCHECK(found_fc) << "A size query container is always a formatting context"; - GetDocument() - .GetStyleEngine() - .ReportUseOfLegacyLayoutWithContainerQueries(); break; } } @@ -5887,12 +5843,6 @@ needs_reattach = true; } - if (legacy_root == container_recalc_root) { - GetDocument() - .GetStyleEngine() - .ReportUseOfLegacyLayoutWithContainerQueries(); - } - return needs_reattach; } @@ -7395,24 +7345,10 @@ "is no frame or that frame has no page."); } - if (RuntimeEnabledFeatures::PointerLockOptionsEnabled( - GetExecutionContext())) { if (exception_state.HadException()) { resolver->Reject(exception_state); } return promise.AsScriptValue(); - } - - // The current spec for PointerLock does not have any language about throwing - // exceptions. Therefore to be spec compliant we must clear all exceptions. - // When behind our experimental flag however, we will throw exceptions which - // should be caught as a promise rejection. - exception_state.ClearException(); - - // Detach the resolver, since we are not using it, to prepare it for garbage - // collection. - resolver->Detach(); - return ScriptValue(); } SpellcheckAttributeState Element::GetSpellcheckAttributeState() const {
diff --git a/third_party/blink/renderer/core/dom/element.idl b/third_party/blink/renderer/core/dom/element.idl index bd05a1a..3ec2e25d 100644 --- a/third_party/blink/renderer/core/dom/element.idl +++ b/third_party/blink/renderer/core/dom/element.idl
@@ -109,7 +109,7 @@ // Pointer Lock // https://w3c.github.io/pointerlock/#extensions-to-the-element-interface - // This function returns void unless the Runtime Enabled Feature |PointerLockOptions| is enabled then it returns Promise<void>. + // https://github.com/w3c/pointerlock/pull/49 [MeasureAs=ElementRequestPointerLock, CallWith=ScriptState, RaisesException] any requestPointerLock(optional PointerLockOptions options = {}); // CSSOM View Module
diff --git a/third_party/blink/renderer/core/dom/pointer_lock_options.idl b/third_party/blink/renderer/core/dom/pointer_lock_options.idl index e166732..426a548d 100644 --- a/third_party/blink/renderer/core/dom/pointer_lock_options.idl +++ b/third_party/blink/renderer/core/dom/pointer_lock_options.idl
@@ -1,3 +1,4 @@ +// https://github.com/w3c/pointerlock/pull/49 dictionary PointerLockOptions { - [RuntimeEnabled=PointerLockOptions]boolean unadjustedMovement = false; + boolean unadjustedMovement = false; };
diff --git a/third_party/blink/renderer/core/frame/child_frame_compositing_helper.cc b/third_party/blink/renderer/core/frame/child_frame_compositing_helper.cc index 951c843e..632bc8d 100644 --- a/third_party/blink/renderer/core/frame/child_frame_compositing_helper.cc +++ b/third_party/blink/renderer/core/frame/child_frame_compositing_helper.cc
@@ -112,7 +112,7 @@ auto image = cc::PaintImageBuilder::WithDefault() .set_id(cc::PaintImage::GetNextId()) - .set_image(SkImage::MakeFromBitmap(*sad_bitmap), + .set_image(SkImages::RasterFromBitmap(*sad_bitmap), cc::PaintImage::GetNextContentId()) .TakePaintImage(); display_list->push<cc::DrawImageOp>(image, x, y);
diff --git a/third_party/blink/renderer/core/frame/web_frame_test.cc b/third_party/blink/renderer/core/frame/web_frame_test.cc index 25ff4a45..777ca8b 100644 --- a/third_party/blink/renderer/core/frame/web_frame_test.cc +++ b/third_party/blink/renderer/core/frame/web_frame_test.cc
@@ -302,12 +302,6 @@ user_gesture); } -const char* ViewBackgroundLayerName() { - return RuntimeEnabledFeatures::LayoutNGPrintingEnabled() - ? "Scrolling background of LayoutNGView #document" - : "Scrolling background of LayoutView #document"; -} - } // namespace const int kTouchPointPadding = 32; @@ -6794,7 +6788,8 @@ static int LayerIdFromNode(const cc::Layer* root_layer, blink::Node* node) { Vector<const cc::Layer*> layers; if (node->IsDocumentNode()) { - layers = CcLayersByName(root_layer, ViewBackgroundLayerName()); + layers = CcLayersByName(root_layer, + "Scrolling background of LayoutNGView #document"); } else { DCHECK(node->IsElementNode()); layers = CcLayersByDOMElementId(root_layer, @@ -8869,7 +8864,9 @@ EXPECT_TRUE(document->IsXrOverlay()); const cc::Layer* root_layer = layer_tree_host->root_layer(); - EXPECT_EQ(1u, CcLayersByName(root_layer, ViewBackgroundLayerName()).size()); + EXPECT_EQ(1u, CcLayersByName(root_layer, + "Scrolling background of LayoutNGView #document") + .size()); EXPECT_EQ(1u, CcLayersByDOMElementId(root_layer, "other").size()); // The overlay is not composited when it's not in full screen. EXPECT_EQ(0u, CcLayersByDOMElementId(root_layer, "overlay").size()); @@ -8881,7 +8878,9 @@ EXPECT_TRUE(!layer_tree_host->background_color().isOpaque()); root_layer = layer_tree_host->root_layer(); - EXPECT_EQ(0u, CcLayersByName(root_layer, ViewBackgroundLayerName()).size()); + EXPECT_EQ(0u, CcLayersByName(root_layer, + "Scrolling background of LayoutNGView #document") + .size()); EXPECT_EQ(0u, CcLayersByDOMElementId(root_layer, "other").size()); EXPECT_EQ(1u, CcLayersByDOMElementId(root_layer, "overlay").size()); EXPECT_EQ(1u, CcLayersByDOMElementId(root_layer, "inner").size()); @@ -8893,7 +8892,9 @@ document->SetIsXrOverlay(false, overlay); root_layer = layer_tree_host->root_layer(); - EXPECT_EQ(1u, CcLayersByName(root_layer, ViewBackgroundLayerName()).size()); + EXPECT_EQ(1u, CcLayersByName(root_layer, + "Scrolling background of LayoutNGView #document") + .size()); EXPECT_EQ(1u, CcLayersByDOMElementId(root_layer, "other").size()); // The overlay is not composited when it's not in full screen. EXPECT_EQ(0u, CcLayersByDOMElementId(root_layer, "overlay").size());
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc index ed11fcd..f0229fbc 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc +++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
@@ -3497,7 +3497,10 @@ if (injected_type == WebInputEvent::Type::kGestureScrollBegin) { gesture_event->data.scroll_begin.scrollable_area_element_id = scrollable_area_element_id.GetInternalValue(); - gesture_event->data.scroll_begin.main_thread_hit_tested = true; + gesture_event->data.scroll_begin.main_thread_hit_tested_reasons = + device == WebGestureDevice::kScrollbar + ? cc::MainThreadScrollingReason::kScrollbarScrolling + : cc::MainThreadScrollingReason::kFailedHitTest; } // Notifies TestWebFrameWidget of the injected event. Does nothing outside
diff --git a/third_party/blink/renderer/core/html/resources/html.css b/third_party/blink/renderer/core/html/resources/html.css index 53d6669c9b..d111f83 100644 --- a/third_party/blink/renderer/core/html/resources/html.css +++ b/third_party/blink/renderer/core/html/resources/html.css
@@ -408,7 +408,10 @@ } /* Form controls don't go vertical. */ -input, textarea, select, button { +input, textarea, select { + writing-mode: horizontal-tb !important; +} +button:not(::-internal-selectmenu-button) { writing-mode: horizontal-tb !important; }
diff --git a/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc b/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc index 8486ca2..58b912d 100644 --- a/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc +++ b/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc
@@ -46,6 +46,7 @@ #include "third_party/blink/renderer/platform/wtf/cross_thread_copier_std.h" #include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h" #include "third_party/skia/include/core/SkCanvas.h" +#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkImageInfo.h" #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/core/SkSwizzle.h" @@ -340,8 +341,8 @@ resized_pixmap.setColorSpace(GetSkImageInfo(image).refColorSpace()); auto resized_sk_image = - SkImage::MakeRasterData(resized_pixmap.info(), std::move(image_pixels), - resized_pixmap.rowBytes()); + SkImages::RasterFromData(resized_pixmap.info(), std::move(image_pixels), + resized_pixmap.rowBytes()); if (!resized_sk_image) return nullptr; return UnacceleratedStaticBitmapImage::Create( @@ -593,7 +594,7 @@ paint_image = PaintImageBuilder::WithDefault() .set_id(paint_image.stable_id()) - .set_image(SkImage::MakeFromBitmap(bitmap), + .set_image(SkImages::RasterFromBitmap(bitmap), paint_image.GetContentIdForFrame(0u)) .TakePaintImage(); } @@ -693,7 +694,7 @@ ImageBitmap::ImageBitmap(const SkPixmap& pixmap, bool is_image_bitmap_origin_clean, ImageOrientationEnum image_orientation) { - sk_sp<SkImage> raster_copy = SkImage::MakeRasterCopy(pixmap); + sk_sp<SkImage> raster_copy = SkImages::RasterFromPixmapCopy(pixmap); if (!raster_copy) return; image_ = UnacceleratedStaticBitmapImage::Create(std::move(raster_copy));
diff --git a/third_party/blink/renderer/core/inspector/inspector_audits_agent.cc b/third_party/blink/renderer/core/inspector/inspector_audits_agent.cc index 1e68324..2ddfcf37 100644 --- a/third_party/blink/renderer/core/inspector/inspector_audits_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_audits_agent.cc
@@ -20,6 +20,7 @@ #include "third_party/blink/renderer/platform/graphics/image_data_buffer.h" #include "third_party/blink/renderer/platform/wtf/text/base64.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" +#include "third_party/skia/include/core/SkImage.h" #include "ui/gfx/geometry/size.h" namespace blink { @@ -55,7 +56,7 @@ Vector<unsigned char> pixel_storage( base::checked_cast<wtf_size_t>(info.computeByteSize(row_bytes))); SkPixmap pixmap(info, pixel_storage.data(), row_bytes); - sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap); + sk_sp<SkImage> image = SkImages::RasterFromBitmap(bitmap); if (!image || !image->readPixels(pixmap, 0, 0)) return false;
diff --git a/third_party/blink/renderer/core/inspector/inspector_highlight.cc b/third_party/blink/renderer/core/inspector/inspector_highlight.cc index 65f225b..b37ce0e 100644 --- a/third_party/blink/renderer/core/inspector/inspector_highlight.cc +++ b/third_party/blink/renderer/core/inspector/inspector_highlight.cc
@@ -2077,23 +2077,22 @@ view->ConvertToRootFrame(layout_object->AbsoluteBoundingBoxRect()); auto* model_object = DynamicTo<LayoutBoxModelObject>(layout_object); - *model = - protocol::DOM::BoxModel::create() - .setContent(BuildArrayForQuad(content)) - .setPadding(BuildArrayForQuad(padding)) - .setBorder(BuildArrayForQuad(border)) - .setMargin(BuildArrayForQuad(margin)) - .setWidth(model_object ? AdjustForAbsoluteZoom::AdjustInt( - model_object->PixelSnappedOffsetWidth( - model_object->OffsetParent()), - model_object) - : bounding_box.width()) - .setHeight(model_object ? AdjustForAbsoluteZoom::AdjustInt( - model_object->PixelSnappedOffsetHeight( - model_object->OffsetParent()), - model_object) - : bounding_box.height()) - .build(); + *model = protocol::DOM::BoxModel::create() + .setContent(BuildArrayForQuad(content)) + .setPadding(BuildArrayForQuad(padding)) + .setBorder(BuildArrayForQuad(border)) + .setMargin(BuildArrayForQuad(margin)) + .setWidth(model_object + ? AdjustForAbsoluteZoom::AdjustLayoutUnit( + model_object->OffsetWidth(), *model_object) + .Round() + : bounding_box.width()) + .setHeight(model_object + ? AdjustForAbsoluteZoom::AdjustLayoutUnit( + model_object->OffsetHeight(), *model_object) + .Round() + : bounding_box.height()) + .build(); Shape::DisplayPaths paths; gfx::QuadF bounds_quad;
diff --git a/third_party/blink/renderer/core/layout/layout_block_flow.cc b/third_party/blink/renderer/core/layout/layout_block_flow.cc index dd63265..2eb7b288 100644 --- a/third_party/blink/renderer/core/layout/layout_block_flow.cc +++ b/third_party/blink/renderer/core/layout/layout_block_flow.cc
@@ -351,20 +351,12 @@ !StyleRef().InitialLetter().IsNormal(); } +// TODO(1229581): Remove this function. bool LayoutBlockFlow::IsSelfCollapsingBlock() const { NOT_DESTROYED(); - if (NeedsLayout()) { - // Sometimes we don't lay out objects in DOM order (column spanners being - // one such relevant type of object right here). As long as the object in - // question establishes a new formatting context, that's nothing to worry - // about, though. - DCHECK(CreatesNewFormattingContext()); - return false; - } - DCHECK(!RuntimeEnabledFeatures::LayoutNGPrintingEnabled()); - if (!IsLayoutNGObject()) - DCHECK_EQ(!is_self_collapsing_, !CheckIfIsSelfCollapsingBlock()); - return is_self_collapsing_; + DCHECK(NeedsLayout()); + DCHECK(CreatesNewFormattingContext()); + return false; } bool LayoutBlockFlow::CheckIfIsSelfCollapsingBlock() const {
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc index 6b8fd6c4..4ed1c5c 100644 --- a/third_party/blink/renderer/core/layout/layout_box.cc +++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -1194,16 +1194,6 @@ return ClientHeight(); } -int LayoutBox::PixelSnappedOffsetWidth(const Element*) const { - NOT_DESTROYED(); - return SnapSizeToPixel(OffsetWidth(), Location().X() + ClientLeft()); -} - -int LayoutBox::PixelSnappedOffsetHeight(const Element*) const { - NOT_DESTROYED(); - return SnapSizeToPixel(OffsetHeight(), Location().Y() + ClientTop()); -} - bool LayoutBox::UsesOverlayScrollbars() const { NOT_DESTROYED(); if (StyleRef().HasCustomScrollbarStyle())
diff --git a/third_party/blink/renderer/core/layout/layout_box.h b/third_party/blink/renderer/core/layout/layout_box.h index ddcc891..47a1195 100644 --- a/third_party/blink/renderer/core/layout/layout_box.h +++ b/third_party/blink/renderer/core/layout/layout_box.h
@@ -595,8 +595,7 @@ LayoutRect NoOverflowRect() const; LayoutRect LayoutOverflowRect() const { NOT_DESTROYED(); - DCHECK(!RuntimeEnabledFeatures::LayoutNGPrintingEnabled() || - !IsLayoutMultiColumnSet()); + DCHECK(!IsLayoutMultiColumnSet()); return LayoutOverflowIsSet() ? overflow_->layout_overflow->LayoutOverflowRect() : NoOverflowRect(); @@ -808,10 +807,6 @@ return Size().Height(); } - // TODO(crbug.com/962299): This is incorrect in some cases. - int PixelSnappedOffsetWidth(const Element*) const final; - int PixelSnappedOffsetHeight(const Element*) const final; - bool UsesOverlayScrollbars() const; // Clamps the left scrollbar size so it is not wider than the content box. @@ -1449,12 +1444,11 @@ return StyleRef().IsHorizontalWritingMode() ? IntrinsicSize().Height() : IntrinsicSize().Width(); } + // TODO(1229581): Remove this function, and intrinsic_content_logical_height_. virtual LayoutUnit IntrinsicContentLogicalHeight() const { NOT_DESTROYED(); - DCHECK(!RuntimeEnabledFeatures::LayoutNGPrintingEnabled()); - return HasOverrideIntrinsicContentLogicalHeight() - ? OverrideIntrinsicContentLogicalHeight() - : intrinsic_content_logical_height_; + NOTREACHED(); + return LayoutUnit(); } // Whether or not the element shrinks to its intrinsic width (rather than
diff --git a/third_party/blink/renderer/core/layout/layout_box_model_object.cc b/third_party/blink/renderer/core/layout/layout_box_model_object.cc index fe1e816a..16b46f7 100644 --- a/third_party/blink/renderer/core/layout/layout_box_model_object.cc +++ b/third_party/blink/renderer/core/layout/layout_box_model_object.cc
@@ -1124,17 +1124,6 @@ return AdjustedPositionRelativeTo(PhysicalOffset(), parent).top; } -int LayoutBoxModelObject::PixelSnappedOffsetWidth(const Element* parent) const { - NOT_DESTROYED(); - return SnapSizeToPixel(OffsetWidth(), OffsetLeft(parent)); -} - -int LayoutBoxModelObject::PixelSnappedOffsetHeight( - const Element* parent) const { - NOT_DESTROYED(); - return SnapSizeToPixel(OffsetHeight(), OffsetTop(parent)); -} - LayoutUnit LayoutBoxModelObject::ComputedCSSPadding( const Length& padding) const { NOT_DESTROYED();
diff --git a/third_party/blink/renderer/core/layout/layout_box_model_object.h b/third_party/blink/renderer/core/layout/layout_box_model_object.h index 7d2b003..5ff6b21 100644 --- a/third_party/blink/renderer/core/layout/layout_box_model_object.h +++ b/third_party/blink/renderer/core/layout/layout_box_model_object.h
@@ -178,8 +178,6 @@ NOT_DESTROYED(); return RoundToInt(OffsetTop(parent)); } - virtual int PixelSnappedOffsetWidth(const Element*) const; - virtual int PixelSnappedOffsetHeight(const Element*) const; bool HasSelfPaintingLayer() const; PaintLayer* Layer() const {
diff --git a/third_party/blink/renderer/core/layout/layout_object_factory.cc b/third_party/blink/renderer/core/layout/layout_object_factory.cc index 3bcadcd..46815815 100644 --- a/third_party/blink/renderer/core/layout/layout_object_factory.cc +++ b/third_party/blink/renderer/core/layout/layout_object_factory.cc
@@ -143,8 +143,6 @@ LayoutView* LayoutObjectFactory::CreateView(Document& document, const ComputedStyle& style) { - if (!RuntimeEnabledFeatures::LayoutNGPrintingEnabled()) - return MakeGarbageCollected<LayoutView>(&document); return MakeGarbageCollected<LayoutNGView>(&document); } @@ -190,14 +188,7 @@ const ComputedStyle* parent_style = parent->GetComputedStyle(); if (legacy == LegacyLayout::kForce) { - // A table inside an inline element with specified columns may end up - // marking a list-item ancestor with a size container-type for forced legacy - // without re-attaching it during interleaved style recalc. Enforce - // legacy/ng consistency between list-item and marker. - DCHECK(!RuntimeEnabledFeatures::LayoutNGPrintingEnabled()); - DCHECK(parent->GetLayoutObject()); - if (parent->GetLayoutObject()->IsLayoutNGObject()) - legacy = LegacyLayout::kAuto; + NOTREACHED(); } bool is_inside = parent_style->ListStylePosition() == EListStylePosition::kInside ||
diff --git a/third_party/blink/renderer/core/layout/layout_view.cc b/third_party/blink/renderer/core/layout/layout_view.cc index 458f092..2894c3d 100644 --- a/third_party/blink/renderer/core/layout/layout_view.cc +++ b/third_party/blink/renderer/core/layout/layout_view.cc
@@ -345,12 +345,9 @@ NOT_DESTROYED(); if (!GetDocument().Printing()) { page_size_ = PhysicalSize(); - named_pages_mapper_ = nullptr; } if (PageLogicalHeight() && ShouldUsePrintingLayout()) { - if (!RuntimeEnabledFeatures::LayoutNGPrintingEnabled()) - named_pages_mapper_ = std::make_unique<NamedPagesMapper>(); intrinsic_logical_widths_ = LogicalWidth(); if (!fragmentation_context_) { fragmentation_context_ = @@ -381,15 +378,6 @@ LayoutBlockFlow::UpdateLayout(); - if (named_pages_mapper_) { - // If a start page name got propagated all the way up to the root, that will - // be the name for the first page. Usually we insert names into the mapper - // as part of inserting forced breaks, but in this case there'll be no - // break, since we're at the first page. - if (const AtomicString first_page_name = StartPageName()) - named_pages_mapper_->NameFirstPage(first_page_name); - } - #if DCHECK_IS_ON() CheckLayoutState(); #endif @@ -811,12 +799,6 @@ #undef RETURN_SCROLLBAR_MODE } -AtomicString LayoutView::NamedPageAtIndex(wtf_size_t page_index) const { - if (named_pages_mapper_) - return named_pages_mapper_->NamedPageAtIndex(page_index); - return AtomicString(); -} - PhysicalRect LayoutView::DocumentRect() const { NOT_DESTROYED(); return FlipForWritingMode(LayoutOverflowRect());
diff --git a/third_party/blink/renderer/core/layout/layout_view.h b/third_party/blink/renderer/core/layout/layout_view.h index d42993c..ececee0 100644 --- a/third_party/blink/renderer/core/layout/layout_view.h +++ b/third_party/blink/renderer/core/layout/layout_view.h
@@ -210,15 +210,14 @@ page_size_ = size; } - virtual AtomicString NamedPageAtIndex(wtf_size_t page_index) const; + // TODO(1229581): Make non-virtual. + virtual AtomicString NamedPageAtIndex(wtf_size_t page_index) const = 0; + // TODO(1229581): Remove this function, and the NamedPagesMapper class. NamedPagesMapper* GetNamedPagesMapper() const { NOT_DESTROYED(); - - // NamedPagesMapper is deprecated. - DCHECK(!RuntimeEnabledFeatures::LayoutNGPrintingEnabled()); - - return named_pages_mapper_.get(); + NOTREACHED(); + return nullptr; } PhysicalRect DocumentRect() const; @@ -397,7 +396,6 @@ LayoutState* layout_state_; Member<ViewFragmentationContext> fragmentation_context_; - std::unique_ptr<NamedPagesMapper> named_pages_mapper_; scoped_refptr<IntervalArena> interval_arena_; Member<LayoutQuote> layout_quote_head_;
diff --git a/third_party/blink/renderer/core/layout/layout_view_test.cc b/third_party/blink/renderer/core/layout/layout_view_test.cc index 8b65d34c..57ee745 100644 --- a/third_party/blink/renderer/core/layout/layout_view_test.cc +++ b/third_party/blink/renderer/core/layout/layout_view_test.cc
@@ -115,16 +115,9 @@ EXPECT_EQ(view->NamedPageAtIndex(7), AtomicString()); EXPECT_EQ(view->NamedPageAtIndex(8), "yksi"); - if (RuntimeEnabledFeatures::LayoutNGPrintingEnabled()) { - // LayoutNGPrinting doesn't provide a name for pages that don't exist. - EXPECT_EQ(view->NamedPageAtIndex(9), AtomicString()); - EXPECT_EQ(view->NamedPageAtIndex(100), AtomicString()); - } else { - // The legacy API, on the other hand, has no clue about how many pages we - // have, so it will just return the last page name, for good measure. - EXPECT_EQ(view->NamedPageAtIndex(9), "yksi"); - EXPECT_EQ(view->NamedPageAtIndex(100), "yksi"); - } + // We don't provide a name for pages that don't exist. + EXPECT_EQ(view->NamedPageAtIndex(9), AtomicString()); + EXPECT_EQ(view->NamedPageAtIndex(100), AtomicString()); } TEST_F(LayoutViewTest, NamedPagesAbsPos) {
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_view.cc b/third_party/blink/renderer/core/layout/ng/layout_ng_view.cc index 0a8f0eda2..5844dedb 100644 --- a/third_party/blink/renderer/core/layout/ng/layout_ng_view.cc +++ b/third_party/blink/renderer/core/layout/ng/layout_ng_view.cc
@@ -66,9 +66,6 @@ } AtomicString LayoutNGView::NamedPageAtIndex(wtf_size_t page_index) const { - // If LayoutNGView is enabled, but not LayoutNGPrinting, fall back to legacy. - if (!RuntimeEnabledFeatures::LayoutNGPrintingEnabled()) - return LayoutView::NamedPageAtIndex(page_index); if (!PhysicalFragmentCount()) return AtomicString(); DCHECK_EQ(PhysicalFragmentCount(), 1u);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc index 0b03490b..584429e 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
@@ -194,7 +194,6 @@ else if (GetFlowThread(box) && style.SpecifiesColumns()) { CreateAlgorithmAndRun<NGColumnLayoutAlgorithm>(params, callback); } else if (UNLIKELY(!box.Parent() && params.node.IsPaginatedRoot())) { - DCHECK(RuntimeEnabledFeatures::LayoutNGPrintingEnabled()); CreateAlgorithmAndRun<NGPageLayoutAlgorithm>(params, callback); } else { CreateAlgorithmAndRun<NGBlockLayoutAlgorithm>(params, callback);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment_test.cc b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment_test.cc index 4a195c8..bb6245e 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment_test.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment_test.cc
@@ -18,10 +18,6 @@ return NGPhysicalFragment::DumpFragmentTree( *GetDocument().GetLayoutView(), NGPhysicalFragment::DumpAll, target); } - - static bool IsNGViewEnabled() { - return RuntimeEnabledFeatures::LayoutNGPrintingEnabled(); - } }; TEST_F(NGPhysicalFragmentTest, DumpFragmentTreeBasic) { @@ -29,24 +25,13 @@ <div id="block"></div> )HTML"); String dump = DumpAll(); - if (IsNGViewEnabled()) { - String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. + String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. Box (out-of-flow-positioned block-flow)(self paint) offset:unplaced size:800x600 LayoutNGView #document Box (block-flow-root block-flow)(self paint) offset:0,0 size:800x8 LayoutNGBlockFlow HTML Box (block-flow) offset:8,8 size:784x0 LayoutNGBlockFlow BODY Box (block-flow) offset:0,0 size:784x0 LayoutNGBlockFlow DIV id='block' )DUMP"; - EXPECT_EQ(expectation, dump); - } else { - String expectation = - R"DUMP(.:: LayoutNG Physical Fragment Tree at legacy root LayoutView #document ::. - (NG fragment root inside fragment-less or legacy subtree:) - Box (block-flow-root block-flow)(self paint) offset:unplaced size:800x8 LayoutNGBlockFlow HTML - Box (block-flow) offset:8,8 size:784x0 LayoutNGBlockFlow BODY - Box (block-flow) offset:0,0 size:784x0 LayoutNGBlockFlow DIV id='block' -)DUMP"; - EXPECT_EQ(expectation, dump); - } + EXPECT_EQ(expectation, dump); } // LayoutView is the containing block of an absolutely positioned descendant. @@ -56,25 +41,13 @@ )HTML"); String dump = DumpAll(); - if (IsNGViewEnabled()) { - String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. + String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. Box (out-of-flow-positioned block-flow)(self paint) offset:unplaced size:800x600 LayoutNGView #document Box (block-flow-root block-flow)(self paint) offset:0,0 size:800x8 LayoutNGBlockFlow HTML Box (block-flow) offset:8,8 size:784x0 LayoutNGBlockFlow BODY Box (out-of-flow-positioned block-flow)(self paint) offset:8,8 size:0x0 LayoutNGBlockFlow (positioned) DIV id='abs' )DUMP"; - EXPECT_EQ(expectation, dump); - } else { - String expectation = - R"DUMP(.:: LayoutNG Physical Fragment Tree at legacy root LayoutView #document ::. - (NG fragment root inside fragment-less or legacy subtree:) - Box (out-of-flow-positioned block-flow)(self paint) offset:unplaced size:0x0 LayoutNGBlockFlow (positioned) DIV id='abs' - (NG fragment root inside fragment-less or legacy subtree:) - Box (block-flow-root block-flow)(self paint) offset:unplaced size:800x8 LayoutNGBlockFlow HTML - Box (block-flow) offset:8,8 size:784x0 LayoutNGBlockFlow BODY -)DUMP"; - EXPECT_EQ(expectation, dump); - } + EXPECT_EQ(expectation, dump); } // An NG object is the containing block of an absolutely positioned descendant. @@ -86,26 +59,14 @@ )HTML"); String dump = DumpAll(); - if (IsNGViewEnabled()) { - String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. + String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. Box (out-of-flow-positioned block-flow)(self paint) offset:unplaced size:800x600 LayoutNGView #document Box (block-flow-root block-flow)(self paint) offset:0,0 size:800x8 LayoutNGBlockFlow HTML Box (block-flow) offset:8,8 size:784x0 LayoutNGBlockFlow BODY Box (block-flow)(self paint) offset:0,0 size:784x0 LayoutNGBlockFlow (relative positioned) DIV id='rel' Box (out-of-flow-positioned block-flow)(self paint) offset:10,20 size:0x0 LayoutNGBlockFlow (positioned) DIV id='abs' )DUMP"; - EXPECT_EQ(expectation, dump); - } else { - String expectation = - R"DUMP(.:: LayoutNG Physical Fragment Tree at legacy root LayoutView #document ::. - (NG fragment root inside fragment-less or legacy subtree:) - Box (block-flow-root block-flow)(self paint) offset:unplaced size:800x8 LayoutNGBlockFlow HTML - Box (block-flow) offset:8,8 size:784x0 LayoutNGBlockFlow BODY - Box (block-flow)(self paint) offset:0,0 size:784x0 LayoutNGBlockFlow (relative positioned) DIV id='rel' - Box (out-of-flow-positioned block-flow)(self paint) offset:10,20 size:0x0 LayoutNGBlockFlow (positioned) DIV id='abs' -)DUMP"; - EXPECT_EQ(expectation, dump); - } + EXPECT_EQ(expectation, dump); } // A legacy grid with another legacy grid inside, and some NG objects, too. @@ -124,8 +85,7 @@ )HTML"); String dump = DumpAll(); - if (IsNGViewEnabled()) { - String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. + String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. Box (out-of-flow-positioned block-flow)(self paint) offset:unplaced size:800x600 LayoutNGView #document Box (block-flow-root block-flow)(self paint) offset:0,0 size:800x16 LayoutNGBlockFlow HTML Box (block-flow) offset:8,8 size:784x0 LayoutNGBlockFlow BODY @@ -136,22 +96,7 @@ Box (block-flow-root block-flow) offset:0,0 size:784x0 LayoutNGBlockFlow DIV id='block-container-item' Box (block-flow) offset:0,0 size:784x0 LayoutNGBlockFlow DIV id='bar' )DUMP"; - EXPECT_EQ(expectation, dump); - } else { - String expectation = - R"DUMP(.:: LayoutNG Physical Fragment Tree at legacy root LayoutView #document ::. - (NG fragment root inside fragment-less or legacy subtree:) - Box (block-flow-root block-flow)(self paint) offset:unplaced size:800x16 LayoutNGBlockFlow HTML - Box (block-flow) offset:8,8 size:784x0 LayoutNGBlockFlow BODY - Box (block-flow-root) offset:0,0 size:784x0 LayoutNGGrid DIV id='outer-grid' - Box (block-flow-root) offset:0,0 size:784x0 LayoutNGGrid DIV id='grid-as-item' - Box (block-flow-root block-flow) offset:0,0 size:784x0 LayoutNGBlockFlow DIV id='inner-grid-item' - Box (block-flow) offset:0,0 size:784x0 LayoutNGBlockFlow DIV id='foo' - Box (block-flow-root block-flow) offset:0,0 size:784x0 LayoutNGBlockFlow DIV id='block-container-item' - Box (block-flow) offset:0,0 size:784x0 LayoutNGBlockFlow DIV id='bar' -)DUMP"; - EXPECT_EQ(expectation, dump); - } + EXPECT_EQ(expectation, dump); } TEST_F(NGPhysicalFragmentTest, DumpFragmentTreeWithTargetInsideColumn) { @@ -170,8 +115,7 @@ box.GetPhysicalFragment(1); String dump = DumpAll(second_child_fragment); - if (IsNGViewEnabled()) { - String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. + String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. Box (out-of-flow-positioned block-flow)(self paint) offset:unplaced size:800x600 LayoutNGView #document Box (block-flow-root block-flow)(self paint) offset:0,0 size:800x66 LayoutNGBlockFlow HTML Box (block-flow) offset:8,8 size:784x50 LayoutNGBlockFlow BODY @@ -183,23 +127,7 @@ Box (column block-flow) offset:523.313,0 size:260.656x50 Box (block-flow) offset:0,0 size:260.656x50 LayoutNGBlockFlow DIV id='child' )DUMP"; - EXPECT_EQ(expectation, dump); - } else { - String expectation = - R"DUMP(.:: LayoutNG Physical Fragment Tree at legacy root LayoutView #document ::. - (NG fragment root inside fragment-less or legacy subtree:) - Box (block-flow-root block-flow)(self paint) offset:unplaced size:800x66 LayoutNGBlockFlow HTML - Box (block-flow) offset:8,8 size:784x50 LayoutNGBlockFlow BODY - Box (block-flow-root block-flow) offset:0,0 size:784x50 LayoutNGBlockFlow DIV id='multicol' - Box (column block-flow) offset:0,0 size:260.656x50 - Box (block-flow) offset:0,0 size:260.656x50 LayoutNGBlockFlow DIV id='child' - Box (column block-flow) offset:261.656,0 size:260.656x50 -* Box (block-flow) offset:0,0 size:260.656x50 LayoutNGBlockFlow DIV id='child' - Box (column block-flow) offset:523.313,0 size:260.656x50 - Box (block-flow) offset:0,0 size:260.656x50 LayoutNGBlockFlow DIV id='child' -)DUMP"; - EXPECT_EQ(expectation, dump); - } + EXPECT_EQ(expectation, dump); } } // namespace blink
diff --git a/third_party/blink/renderer/core/messaging/blink_transferable_message.cc b/third_party/blink/renderer/core/messaging/blink_transferable_message.cc index 04c8c61..aef9c9c1 100644 --- a/third_party/blink/renderer/core/messaging/blink_transferable_message.cc +++ b/third_party/blink/renderer/core/messaging/blink_transferable_message.cc
@@ -13,6 +13,7 @@ #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h" #include "third_party/blink/renderer/platform/blob/blob_data.h" #include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h" +#include "third_party/skia/include/core/SkImage.h" namespace blink { @@ -115,7 +116,7 @@ scoped_refptr<StaticBitmapImage> ToStaticBitmapImage( const SkBitmap& sk_bitmap) { - sk_sp<SkImage> image = SkImage::MakeFromBitmap(sk_bitmap); + sk_sp<SkImage> image = SkImages::RasterFromBitmap(sk_bitmap); if (!image) return nullptr;
diff --git a/third_party/blink/renderer/core/navigation_api/navigate_event.cc b/third_party/blink/renderer/core/navigation_api/navigate_event.cc index 28328b6d..5c9771a 100644 --- a/third_party/blink/renderer/core/navigation_api/navigate_event.cc +++ b/third_party/blink/renderer/core/navigation_api/navigate_event.cc
@@ -5,11 +5,9 @@ #include "third_party/blink/renderer/core/navigation_api/navigate_event.h" #include "third_party/blink/public/mojom/devtools/console_message.mojom-shared.h" -#include "third_party/blink/renderer/bindings/core/v8/script_function.h" #include "third_party/blink/renderer/bindings/core/v8/v8_navigate_event_init.h" #include "third_party/blink/renderer/bindings/core/v8/v8_navigation_intercept_handler.h" #include "third_party/blink/renderer/bindings/core/v8/v8_navigation_intercept_options.h" -#include "third_party/blink/renderer/core/accessibility/ax_object_cache.h" #include "third_party/blink/renderer/core/dom/abort_signal.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/dom/element.h" @@ -26,25 +24,6 @@ namespace blink { -enum class ResolveType { kFulfill, kReject }; -class NavigateEvent::Reaction final : public ScriptFunction::Callable { - public: - Reaction(NavigateEvent* navigate_event, ResolveType resolve_type) - : navigate_event_(navigate_event), resolve_type_(resolve_type) {} - void Trace(Visitor* visitor) const final { - ScriptFunction::Callable::Trace(visitor); - visitor->Trace(navigate_event_); - } - ScriptValue Call(ScriptState*, ScriptValue value) final { - navigate_event_->ReactDone(value, resolve_type_ == ResolveType::kFulfill); - return ScriptValue(); - } - - private: - Member<NavigateEvent> navigate_event_; - ResolveType resolve_type_; -}; - NavigateEvent::NavigateEvent(ExecutionContext* context, const AtomicString& type, NavigateEventInit* init) @@ -186,77 +165,22 @@ } } -void NavigateEvent::React(ScriptState* script_state) { +ScriptPromise NavigateEvent::GetReactionPromiseAll(ScriptState* script_state) { CHECK(navigation_action_handlers_list_.empty()); - - ScriptPromise promise; if (!navigation_action_promises_list_.empty()) { - promise = - ScriptPromise::All(script_state, navigation_action_promises_list_); - } else { - // There is a subtle timing difference between the fast-path for zero - // promises and the path for 1+ promises, in both spec and implementation. - // In most uses of ScriptPromise::All / the Web IDL spec's "wait for all", - // this does not matter. However for us there are so many events and promise - // handlers firing around the same time (navigatesuccess, committed promise, - // finished promise, ...) that the difference is pretty easily observable by - // web developers and web platform tests. So, let's make sure we always go - // down the 1+ promises path. - promise = ScriptPromise::All( - script_state, HeapVector<ScriptPromise>( - {ScriptPromise::CastUndefined(script_state)})); + return ScriptPromise::All(script_state, navigation_action_promises_list_); } - - promise.Then(MakeGarbageCollected<ScriptFunction>( - script_state, - MakeGarbageCollected<Reaction>(this, ResolveType::kFulfill)), - MakeGarbageCollected<ScriptFunction>( - script_state, - MakeGarbageCollected<Reaction>(this, ResolveType::kReject))); - - if (HasNavigationActions() && DomWindow()) { - if (AXObjectCache* cache = - DomWindow()->document()->ExistingAXObjectCache()) { - cache->HandleLoadStart(DomWindow()->document()); - } - } -} - -void NavigateEvent::ReactDone(ScriptValue value, bool did_fulfill) { - CHECK_NE(intercept_state_, InterceptState::kIntercepted); - CHECK_NE(intercept_state_, InterceptState::kFinished); - if (signal_->aborted()) { - return; - } - - LocalDOMWindow* window = DomWindow(); - CHECK_EQ(this, window->navigation()->ongoing_navigate_event_); - window->navigation()->ongoing_navigate_event_ = nullptr; - - if (intercept_state_ != InterceptState::kNone) { - PotentiallyResetTheFocus(); - if (did_fulfill) { - PotentiallyProcessScrollBehavior(); - } - intercept_state_ = InterceptState::kFinished; - } - - if (did_fulfill) { - window->navigation()->DidFinishOngoingNavigation(); - } else { - window->navigation()->DidFailOngoingNavigation(value); - } - - if (HasNavigationActions()) { - if (LocalFrame* frame = window->GetFrame()) { - frame->Loader().DidFinishNavigation( - did_fulfill ? FrameLoader::NavigationFinishState::kSuccess - : FrameLoader::NavigationFinishState::kFailure); - } - if (AXObjectCache* cache = window->document()->ExistingAXObjectCache()) { - cache->HandleLoadComplete(window->document()); - } - } + // There is a subtle timing difference between the fast-path for zero + // promises and the path for 1+ promises, in both spec and implementation. + // In most uses of ScriptPromise::All / the Web IDL spec's "wait for all", + // this does not matter. However for us there are so many events and promise + // handlers firing around the same time (navigatesuccess, committed promise, + // finished promise, ...) that the difference is pretty easily observable by + // web developers and web platform tests. So, let's make sure we always go + // down the 1+ promises path. + return ScriptPromise::All( + script_state, + HeapVector<ScriptPromise>({ScriptPromise::CastUndefined(script_state)})); } void NavigateEvent::FinalizeNavigationActionPromisesList() { @@ -333,6 +257,19 @@ ProcessScrollBehavior(); } +void NavigateEvent::Finish(bool did_fulfill) { + CHECK_NE(intercept_state_, InterceptState::kIntercepted); + CHECK_NE(intercept_state_, InterceptState::kFinished); + if (intercept_state_ == InterceptState::kNone) { + return; + } + PotentiallyResetTheFocus(); + if (did_fulfill) { + PotentiallyProcessScrollBehavior(); + } + intercept_state_ = InterceptState::kFinished; +} + void NavigateEvent::PotentiallyProcessScrollBehavior() { CHECK(intercept_state_ == InterceptState::kCommitted || intercept_state_ == InterceptState::kScrolled);
diff --git a/third_party/blink/renderer/core/navigation_api/navigate_event.h b/third_party/blink/renderer/core/navigation_api/navigate_event.h index 9534696..de983aea 100644 --- a/third_party/blink/renderer/core/navigation_api/navigate_event.h +++ b/third_party/blink/renderer/core/navigation_api/navigate_event.h
@@ -64,10 +64,12 @@ void intercept(NavigationInterceptOptions*, ExceptionState&); void DoCommit(); - void React(ScriptState* script_state); void scroll(ExceptionState&); + void Finish(bool did_fulfill); + + ScriptPromise GetReactionPromiseAll(ScriptState*); bool HasNavigationActions() const { return intercept_state_ != InterceptState::kNone; } @@ -86,9 +88,6 @@ void PotentiallyProcessScrollBehavior(); void ProcessScrollBehavior(); - class Reaction; - void ReactDone(ScriptValue, bool did_fulfill); - String navigation_type_; Member<NavigationDestination> destination_; bool can_intercept_;
diff --git a/third_party/blink/renderer/core/navigation_api/navigation_api.cc b/third_party/blink/renderer/core/navigation_api/navigation_api.cc index 6e1074ed..24d52bd 100644 --- a/third_party/blink/renderer/core/navigation_api/navigation_api.cc +++ b/third_party/blink/renderer/core/navigation_api/navigation_api.cc
@@ -10,6 +10,7 @@ #include "third_party/blink/public/mojom/frame/frame.mojom-blink.h" #include "third_party/blink/public/web/web_frame_load_type.h" #include "third_party/blink/renderer/bindings/core/v8/capture_source_location.h" +#include "third_party/blink/renderer/bindings/core/v8/script_function.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" @@ -21,6 +22,7 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_navigation_result.h" #include "third_party/blink/renderer/bindings/core/v8/v8_navigation_transition.h" #include "third_party/blink/renderer/bindings/core/v8/v8_navigation_update_current_entry_options.h" +#include "third_party/blink/renderer/core/accessibility/ax_object_cache.h" #include "third_party/blink/renderer/core/dom/abort_signal.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/event_target_names.h" @@ -46,6 +48,72 @@ namespace blink { +class NavigateReaction final : public ScriptFunction::Callable { + public: + enum class ResolveType { kFulfill, kReject }; + static void React(ScriptState* script_state, NavigateEvent* navigate_event) { + navigate_event->GetReactionPromiseAll(script_state) + .Then(MakeGarbageCollected<ScriptFunction>( + script_state, MakeGarbageCollected<NavigateReaction>( + navigate_event, ResolveType::kFulfill)), + MakeGarbageCollected<ScriptFunction>( + script_state, MakeGarbageCollected<NavigateReaction>( + navigate_event, ResolveType::kReject))); + + if (navigate_event->HasNavigationActions()) { + auto* window = LocalDOMWindow::From(script_state); + CHECK(window); + if (AXObjectCache* cache = window->document()->ExistingAXObjectCache()) + cache->HandleLoadStart(window->document()); + } + } + + NavigateReaction(NavigateEvent* navigate_event, ResolveType resolve_type) + : navigate_event_(navigate_event), resolve_type_(resolve_type) {} + + void Trace(Visitor* visitor) const final { + ScriptFunction::Callable::Trace(visitor); + visitor->Trace(navigate_event_); + } + + ScriptValue Call(ScriptState* script_state, ScriptValue value) final { + auto* window = LocalDOMWindow::From(script_state); + CHECK(window); + if (navigate_event_->signal()->aborted()) { + return ScriptValue(); + } + + NavigationApi* navigation_api = window->navigation(); + navigation_api->ongoing_navigate_event_ = nullptr; + + navigate_event_->Finish(resolve_type_ == ResolveType::kFulfill); + + if (resolve_type_ == ResolveType::kFulfill) { + navigation_api->DidFinishOngoingNavigation(); + } else { + navigation_api->DidFailOngoingNavigation(value); + } + + if (navigate_event_->HasNavigationActions()) { + if (LocalFrame* frame = window->GetFrame()) { + frame->Loader().DidFinishNavigation( + resolve_type_ == ResolveType::kFulfill + ? FrameLoader::NavigationFinishState::kSuccess + : FrameLoader::NavigationFinishState::kFailure); + } + if (AXObjectCache* cache = window->document()->ExistingAXObjectCache()) { + cache->HandleLoadComplete(window->document()); + } + } + + return ScriptValue(); + } + + private: + Member<NavigateEvent> navigate_event_; + ResolveType resolve_type_; +}; + template <typename... DOMExceptionArgs> NavigationResult* EarlyErrorResult(ScriptState* script_state, DOMExceptionArgs&&... args) { @@ -785,7 +853,7 @@ if (navigate_event->HasNavigationActions() || params->event_type != NavigateEventType::kCrossDocument) { - navigate_event->React(script_state); + NavigateReaction::React(script_state, navigate_event); } // Note: we cannot clean up ongoing_navigation_ for cross-document
diff --git a/third_party/blink/renderer/core/navigation_api/navigation_api.h b/third_party/blink/renderer/core/navigation_api/navigation_api.h index 60abf44..09bd88f 100644 --- a/third_party/blink/renderer/core/navigation_api/navigation_api.h +++ b/third_party/blink/renderer/core/navigation_api/navigation_api.h
@@ -132,7 +132,7 @@ void Trace(Visitor*) const final; private: - friend class NavigateEvent; + friend class NavigateReaction; NavigationHistoryEntry* GetEntryForRestore( const mojom::blink::NavigationApiHistoryEntryPtr&); void PopulateKeySet();
diff --git a/third_party/blink/renderer/core/page/drag_image_test.cc b/third_party/blink/renderer/core/page/drag_image_test.cc index cde58334..d10c77e 100644 --- a/third_party/blink/renderer/core/page/drag_image_test.cc +++ b/third_party/blink/renderer/core/page/drag_image_test.cc
@@ -166,7 +166,7 @@ test_bitmap.eraseArea(SkIRect::MakeXYWH(1, 1, 1, 1), 0xFFFFFFFF); scoped_refptr<TestImage> test_image = - TestImage::Create(SkImage::MakeFromBitmap(test_bitmap)); + TestImage::Create(SkImages::RasterFromBitmap(test_bitmap)); std::unique_ptr<DragImage> drag_image = DragImage::Create( test_image.get(), kRespectImageOrientation, kInterpolationNone); ASSERT_TRUE(drag_image);
diff --git a/third_party/blink/renderer/core/page/pointer_lock_controller.cc b/third_party/blink/renderer/core/page/pointer_lock_controller.cc index 2a4fbd7..30b9edf 100644 --- a/third_party/blink/renderer/core/page/pointer_lock_controller.cc +++ b/third_party/blink/renderer/core/page/pointer_lock_controller.cc
@@ -211,7 +211,7 @@ return; } DOMException* exception = ConvertResultToException(result); - RejectIfPromiseEnabled(resolver, exception); + resolver->Reject(exception); } void PointerLockController::ProcessResult( @@ -263,15 +263,6 @@ } } -void PointerLockController::RejectIfPromiseEnabled( - ScriptPromiseResolver* resolver, - DOMException* exception) { - if (RuntimeEnabledFeatures::PointerLockOptionsEnabled( - resolver->GetExecutionContext())) { - resolver->Reject(exception); - } -} - void PointerLockController::ExitPointerLock() { Document* pointer_lock_document = element_ ? &element_->GetDocument()
diff --git a/third_party/blink/renderer/core/page/pointer_lock_controller.h b/third_party/blink/renderer/core/page/pointer_lock_controller.h index 361f477..89b879e2 100644 --- a/third_party/blink/renderer/core/page/pointer_lock_controller.h +++ b/third_party/blink/renderer/core/page/pointer_lock_controller.h
@@ -108,8 +108,6 @@ mojom::blink::PointerLockResult result); static DOMException* ConvertResultToException( mojom::blink::PointerLockResult result); - static void RejectIfPromiseEnabled(ScriptPromiseResolver* resolver, - DOMException* exception); Member<Page> page_; bool lock_pending_;
diff --git a/third_party/blink/renderer/core/page/print_context_test.cc b/third_party/blink/renderer/core/page/print_context_test.cc index 5f97f0b..e6c7d3c9 100644 --- a/third_party/blink/renderer/core/page/print_context_test.cc +++ b/third_party/blink/renderer/core/page/print_context_test.cc
@@ -272,11 +272,7 @@ canvas.RecordedOperations(); ASSERT_EQ(1u, operations.size()); EXPECT_EQ(MockPageContextCanvas::kDrawRect, operations[0].type); - // Block-in-inline behaves differently in LayoutNG. - if (RuntimeEnabledFeatures::LayoutNGPrintingEnabled()) - EXPECT_SKRECT_EQ(0, 50, 555, 30, operations[0].rect); - else - EXPECT_SKRECT_EQ(0, 50, 133, 30, operations[0].rect); + EXPECT_SKRECT_EQ(0, 50, 555, 30, operations[0].rect); } TEST_P(PrintContextTest, LinkTargetUnderInInlines) {
diff --git a/third_party/blink/renderer/core/page/scrolling/scroll_metrics_test.cc b/third_party/blink/renderer/core/page/scrolling/scroll_metrics_test.cc index c9ccc4f..38459f34 100644 --- a/third_party/blink/renderer/core/page/scrolling/scroll_metrics_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/scroll_metrics_test.cc
@@ -147,7 +147,8 @@ if (base::FeatureList::IsEnabled(::features::kScrollUnification)) { // cc reports the below reasons because #box is not composited. EXPECT_TOUCH_BUCKET( - BucketIndex(cc::MainThreadScrollingReason::kFailedHitTest), 1); + BucketIndex(cc::MainThreadScrollingReason::kNonFastScrollableRegion), + 1); EXPECT_TOUCH_BUCKET( BucketIndex(cc::MainThreadScrollingReason::kNotOpaqueForTextAndLCDText), 1); @@ -183,7 +184,8 @@ if (base::FeatureList::IsEnabled(::features::kScrollUnification)) { // cc reports the below reasons because #box is not composited. EXPECT_WHEEL_BUCKET( - BucketIndex(cc::MainThreadScrollingReason::kFailedHitTest), 1); + BucketIndex(cc::MainThreadScrollingReason::kNonFastScrollableRegion), + 1); EXPECT_WHEEL_BUCKET( BucketIndex(cc::MainThreadScrollingReason::kNotOpaqueForTextAndLCDText), 1); @@ -231,7 +233,8 @@ if (base::FeatureList::IsEnabled(::features::kScrollUnification)) { // cc reports the below reasons because #box is not composited. EXPECT_WHEEL_BUCKET( - BucketIndex(cc::MainThreadScrollingReason::kFailedHitTest), 1); + BucketIndex(cc::MainThreadScrollingReason::kNonFastScrollableRegion), + 1); EXPECT_WHEEL_BUCKET( BucketIndex(cc::MainThreadScrollingReason::kNotOpaqueForTextAndLCDText), 1); @@ -293,7 +296,8 @@ if (base::FeatureList::IsEnabled(::features::kScrollUnification)) { // cc reports the below reasons because #box is not composited. EXPECT_WHEEL_BUCKET( - BucketIndex(cc::MainThreadScrollingReason::kFailedHitTest), 1); + BucketIndex(cc::MainThreadScrollingReason::kNonFastScrollableRegion), + 1); EXPECT_WHEEL_BUCKET( BucketIndex(cc::MainThreadScrollingReason::kNotOpaqueForTextAndLCDText), 1); @@ -330,13 +334,14 @@ if (base::FeatureList::IsEnabled(::features::kScrollUnification)) { // The overflow: hidden element is still a non-fast scroll region, so cc // reports the following for the second scroll: - // kFailedHitTest + // kNonFastScrollableRegion // kScrollingOnMainForAnyReason // // Since #box is overflow: hidden, the hit test returns the viewport, and // so we do not log kNoScrollingLayer again. EXPECT_WHEEL_BUCKET( - BucketIndex(cc::MainThreadScrollingReason::kFailedHitTest), 1); + BucketIndex(cc::MainThreadScrollingReason::kNonFastScrollableRegion), + 1); EXPECT_WHEEL_BUCKET( cc::MainThreadScrollingReason::kScrollingOnMainForAnyReason, 1); EXPECT_WHEEL_TOTAL(2);
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_test.cc b/third_party/blink/renderer/core/paint/compositing/compositing_test.cc index 5fbd1de9..00f5a79 100644 --- a/third_party/blink/renderer/core/paint/compositing/compositing_test.cc +++ b/third_party/blink/renderer/core/paint/compositing/compositing_test.cc
@@ -39,16 +39,6 @@ namespace blink { -namespace { - -const char* ViewLayerName() { - return RuntimeEnabledFeatures::LayoutNGPrintingEnabled() - ? "LayoutNGView #document" - : "LayoutView #document"; -} - -} // namespace - #define EXPECT_SKCOLOR4F_NEAR(expected, actual, error) \ do { \ EXPECT_NEAR(expected.fR, actual.fR, error); \ @@ -475,7 +465,7 @@ // The root layer and root scrolling contents layer get background_color by // blending the CSS background-color of the <html> element with // LocalFrameView::BaseBackgroundColor(), which is white by default. - auto* layer = CcLayersByName(RootCcLayer(), ViewLayerName())[0]; + auto* layer = CcLayersByName(RootCcLayer(), "LayoutNGView #document")[0]; SkColor4f expected_color = SkColor4f::FromColor(SkColorSetRGB(10, 20, 30)); EXPECT_EQ(layer->background_color(), SkColors::kTransparent); auto* scrollable_area = GetLocalFrameView()->LayoutViewport(); @@ -537,7 +527,7 @@ // background is painted into the root graphics layer, the root scrolling // contents layer should not checkerboard, so its background color should be // transparent. - auto* layer = CcLayersByName(RootCcLayer(), ViewLayerName())[0]; + auto* layer = CcLayersByName(RootCcLayer(), "LayoutNGView #document")[0]; EXPECT_EQ(layer->background_color(), SkColors::kWhite); auto* scrollable_area = GetLocalFrameView()->LayoutViewport(); layer = ScrollingContentsCcLayerByScrollElementId(
diff --git a/third_party/blink/renderer/core/paint/timing/text_paint_timing_detector_test.cc b/third_party/blink/renderer/core/paint/timing/text_paint_timing_detector_test.cc index dafd3cbe..2e9b003 100644 --- a/third_party/blink/renderer/core/paint/timing/text_paint_timing_detector_test.cc +++ b/third_party/blink/renderer/core/paint/timing/text_paint_timing_detector_test.cc
@@ -284,18 +284,9 @@ CheckSizeOfTextQueuedForPaintTimeAfterUpdateLifecyclePhases(1u); } -#if BUILDFLAG(IS_IOS) -// TODO(crbug.com/1141478) -#define MAYBE_LargestTextPaint_TraceEvent_Candidate \ - DISABLED_LargestTextPaint_TraceEvent_Candidate -#else -#define MAYBE_LargestTextPaint_TraceEvent_Candidate \ - LargestTextPaint_TraceEvent_Candidate -#endif // BUILDFLAG(IS_IOS) -TEST_F(TextPaintTimingDetectorTest, - MAYBE_LargestTextPaint_TraceEvent_Candidate) { +TEST_F(TextPaintTimingDetectorTest, LargestTextPaint_TraceEvent_Candidate) { using trace_analyzer::Query; - trace_analyzer::Start("*"); + trace_analyzer::Start("loading"); { SetBodyInnerHTML(R"HTML( )HTML"); @@ -339,7 +330,7 @@ TEST_F(TextPaintTimingDetectorTest, LargestTextPaint_TraceEvent_Candidate_Frame) { using trace_analyzer::Query; - trace_analyzer::Start("*"); + trace_analyzer::Start("loading"); { GetDocument().SetBaseURLOverride(KURL("http://test.com")); SetBodyInnerHTML(R"HTML(
diff --git a/third_party/blink/renderer/core/resize_observer/resize_observer.h b/third_party/blink/renderer/core/resize_observer/resize_observer.h index 3af6267..466e28e 100644 --- a/third_party/blink/renderer/core/resize_observer/resize_observer.h +++ b/third_party/blink/renderer/core/resize_observer/resize_observer.h
@@ -34,6 +34,11 @@ DEFINE_WRAPPERTYPEINFO(); public: + enum class DeliveryTime { + kInsertionOrder, + kBeforeOthers, + }; + // This delegate is an internal (non-web-exposed) version of ResizeCallback. class Delegate : public GarbageCollected<Delegate> { public: @@ -41,6 +46,9 @@ virtual void OnResize( const HeapVector<Member<ResizeObserverEntry>>& entries) = 0; virtual void Trace(Visitor* visitor) const {} + virtual DeliveryTime Delivery() const { + return DeliveryTime::kInsertionOrder; + } }; static ResizeObserver* Create(ScriptState*, V8ResizeObserverCallback*); @@ -69,6 +77,10 @@ void Trace(Visitor*) const override; + DeliveryTime Delivery() const { + return delegate_ ? delegate_->Delivery() : DeliveryTime::kInsertionOrder; + } + private: void observeInternal(Element* target, ResizeObserverBoxOptions box_option);
diff --git a/third_party/blink/renderer/core/resize_observer/resize_observer_controller.cc b/third_party/blink/renderer/core/resize_observer/resize_observer_controller.cc index 2f679fb..5b8073c 100644 --- a/third_party/blink/renderer/core/resize_observer/resize_observer_controller.cc +++ b/third_party/blink/renderer/core/resize_observer/resize_observer_controller.cc
@@ -30,7 +30,14 @@ ResizeObserverController::ResizeObserverController() : Supplement(nullptr) {} void ResizeObserverController::AddObserver(ResizeObserver& observer) { - observers_.insert(&observer); + switch (observer.Delivery()) { + case ResizeObserver::DeliveryTime::kInsertionOrder: + observers_.insert(&observer); + break; + case ResizeObserver::DeliveryTime::kBeforeOthers: + observers_.PrependOrMoveToFirst(&observer); + break; + } } size_t ResizeObserverController::GatherObservations() {
diff --git a/third_party/blink/renderer/core/style/computed_style.cc b/third_party/blink/renderer/core/style/computed_style.cc index 7aa6c01..d348afa 100644 --- a/third_party/blink/renderer/core/style/computed_style.cc +++ b/third_party/blink/renderer/core/style/computed_style.cc
@@ -2469,8 +2469,6 @@ bool ComputedStyle::CanMatchSizeContainerQueries(const Element& element) const { return IsContainerForSizeContainerQueries() && !element.ShouldForceLegacyLayout() && - (RuntimeEnabledFeatures::LayoutNGPrintingEnabled() || - !element.GetDocument().Printing()) && (!element.IsSVGElement() || To<SVGElement>(element).IsOutermostSVGSVGElement()); }
diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h index f0210bce..0a98265f 100644 --- a/third_party/blink/renderer/core/style/computed_style.h +++ b/third_party/blink/renderer/core/style/computed_style.h
@@ -980,13 +980,8 @@ } // Column utility functions. - static bool SpecifiesColumns(bool has_auto_column_count, - bool has_auto_column_width) { - return !has_auto_column_count || !has_auto_column_width; - } bool SpecifiesColumns() const { - return ComputedStyle::SpecifiesColumns(HasAutoColumnCount(), - HasAutoColumnWidth()); + return !HasAutoColumnCount() || !HasAutoColumnWidth(); } bool ColumnRuleIsTransparent() const { return !ColumnRuleColor() @@ -2977,10 +2972,6 @@ SetColumnWidthInternal(0); } - bool SpecifiesColumns() const { - return ComputedStyle::SpecifiesColumns(HasAutoColumnCount(), - HasAutoColumnWidth()); - } // contain bool ShouldApplyAnyContainment(const Element& element) const { unsigned effective_containment = ComputedStyle::EffectiveContainment(
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc index 96958b66..600634a 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -145,6 +145,7 @@ #include "third_party/blink/renderer/platform/text/text_direction.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" +#include "third_party/skia/include/core/SkImage.h" #include "ui/accessibility/ax_common.h" #include "ui/accessibility/ax_role_properties.h" #include "ui/events/keycodes/dom/dom_code.h" @@ -2628,8 +2629,9 @@ Vector<char> pixel_storage( base::checked_cast<wtf_size_t>(info.computeByteSize(row_bytes))); SkPixmap pixmap(info, pixel_storage.data(), row_bytes); - if (!SkImage::MakeFromBitmap(bitmap)->readPixels(pixmap, 0, 0)) + if (!SkImages::RasterFromBitmap(bitmap)->readPixels(pixmap, 0, 0)) { return String(); + } // Encode as a PNG and return as a data url. std::unique_ptr<ImageDataBuffer> buffer = ImageDataBuffer::Create(pixmap);
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc index 0bd20c1..0f1a33a 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -1765,16 +1765,6 @@ DCHECK_NE(node_data->role, ax::mojom::blink::Role::kUnknown); DCHECK_NE(node_data->role, ax::mojom::blink::Role::kNone); - if (node_data->role == ax::mojom::blink::Role::kFigure) { - AXObject* fig_caption = GetChildFigcaption(); - if (fig_caption) { - std::vector<int32_t> ids; - ids.push_back(GetChildFigcaption()->AXObjectID()); - node_data->AddIntListAttribute( - ax::mojom::blink::IntListAttribute::kDetailsIds, ids); - } - } - if (IsA<Document>(GetNode())) { if (!IsLoaded()) { node_data->AddBoolAttribute(ax::mojom::blink::BoolAttribute::kBusy, true); @@ -2269,16 +2259,7 @@ } } - // See if we need to add aria-details for a popover invoker. - if (!node_data->HasIntListAttribute( - ax::mojom::blink::IntListAttribute::kDetailsIds)) { - if (AXObject* popover = GetTargetPopoverForInvoker()) { - node_data->AddIntListAttribute( - ax::mojom::blink::IntListAttribute::kDetailsIds, - {static_cast<int32_t>(popover->AXObjectID())}); - } - } - + SerializeComputedDetailsRelation(node_data); // Try to get an aria-controls listbox for an <input role="combobox">. if (!node_data->HasIntListAttribute( ax::mojom::blink::IntListAttribute::kControlsIds)) { @@ -2302,10 +2283,42 @@ } } +void AXObject::SerializeComputedDetailsRelation( + ui::AXNodeData* node_data) const { + // aria-details was used -- it may have set a relation, unless the attribute + // value did not point to valid elements (e.g aria-details=""). Whether it + // actually set the relation or not, the author's intent in using the + // aria-details attribute is understood to mean that no automatic relation + // should be set. + if (HasAttribute(html_names::kAriaDetailsAttr)) { + return; + } + + // Add details relation to <figure>, pointing at <figcaption>. + if (node_data->role == ax::mojom::blink::Role::kFigure) { + AXObject* fig_caption = GetChildFigcaption(); + if (fig_caption) { + std::vector<int32_t> ids; + ids.push_back(GetChildFigcaption()->AXObjectID()); + node_data->AddIntListAttribute( + ax::mojom::blink::IntListAttribute::kDetailsIds, ids); + return; + } + } + + // Add aria-details for a popover invoker. + // TODO(https://crbug.com/1426607) Support this for non-plain hint popovers. + if (AXObject* popover = GetTargetPopoverForInvoker()) { + node_data->AddIntListAttribute( + ax::mojom::blink::IntListAttribute::kDetailsIds, + {static_cast<int32_t>(popover->AXObjectID())}); + } +} + // Popover invoking elements should have details relationships with their // target popover, when that popover is a) open, and b) not the next element // in the DOM (depth first search order). -AXObject* AXObject::GetTargetPopoverForInvoker() { +AXObject* AXObject::GetTargetPopoverForInvoker() const { auto* form_element = DynamicTo<HTMLFormControlElement>(GetElement()); if (!form_element) { return nullptr;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.h b/third_party/blink/renderer/modules/accessibility/ax_object.h index d92e8dd3..f059721 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.h +++ b/third_party/blink/renderer/modules/accessibility/ax_object.h
@@ -784,7 +784,7 @@ virtual ax::mojom::blink::IsPopup IsPopup() const; // Heuristic to get the target popover for an invoking element. - AXObject* GetTargetPopoverForInvoker(); + AXObject* GetTargetPopoverForInvoker() const; // Heuristic to get the listbox for an <input role="combobox">. AXObject* GetControlsListboxForTextfieldCombobox(); @@ -1448,6 +1448,7 @@ void SerializeTableAttributes(ui::AXNodeData* node_data); void SerializeUnignoredAttributes(ui::AXNodeData* node_data, ui::AXMode accessibility_mode); + void SerializeComputedDetailsRelation(ui::AXNodeData* node_data) const; // Serialization implemented in specific subclasses. virtual void SerializeMarkerAttributes(ui::AXNodeData* node_data) const;
diff --git a/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.cc b/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.cc index faef34c65..ffde9a8e 100644 --- a/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.cc +++ b/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.cc
@@ -52,7 +52,7 @@ SkBitmap black_bitmap; if (black_bitmap.tryAllocN32Pixels(width, height)) { black_bitmap.eraseARGB(0, 0, 0, 0); - auto image = SkImage::MakeFromBitmap(black_bitmap); + auto image = SkImages::RasterFromBitmap(black_bitmap); if (image) { image_layer_bridge_->SetImage( UnacceleratedStaticBitmapImage::Create(image));
diff --git a/third_party/blink/renderer/modules/exported/web_ax_object.cc b/third_party/blink/renderer/modules/exported/web_ax_object.cc index c8216fdf..741e9a8 100644 --- a/third_party/blink/renderer/modules/exported/web_ax_object.cc +++ b/third_party/blink/renderer/modules/exported/web_ax_object.cc
@@ -279,13 +279,6 @@ action != ax::mojom::blink::DefaultActionVerb::kClickAncestor; } -bool WebAXObject::IsControl() const { - if (IsDetached()) - return false; - - return private_->IsControl(); -} - bool WebAXObject::IsFocused() const { if (IsDetached()) return false; @@ -293,20 +286,6 @@ return private_->IsFocused(); } -bool WebAXObject::IsLineBreakingObject() const { - if (IsDetached()) - return false; - - return private_->IsLineBreakingObject(); -} - -bool WebAXObject::IsLinked() const { - if (IsDetached()) - return false; - - return private_->IsLinked(); -} - bool WebAXObject::IsModal() const { if (IsDetached()) return false; @@ -314,13 +293,6 @@ return private_->IsModal(); } -bool WebAXObject::IsAtomicTextField() const { - if (IsDetached()) - return false; - - return private_->IsAtomicTextField(); -} - bool WebAXObject::IsOffScreen() const { if (IsDetached()) return false; @@ -342,24 +314,6 @@ return private_->IsVisited(); } -WebString WebAXObject::AccessKey() const { - if (IsDetached()) - return WebString(); - - return WebString(private_->AccessKey()); -} - -// Deprecated. -void WebAXObject::ColorValue(int& r, int& g, int& b) const { - if (IsDetached()) - return; - - unsigned color = private_->ColorValue(); - r = (color >> 16) & 0xFF; - g = (color >> 8) & 0xFF; - b = color & 0xFF; -} - unsigned WebAXObject::ColorValue() const { if (IsDetached()) return 0; @@ -375,13 +329,6 @@ return WebAXObject(private_->ActiveDescendant()); } -WebAXObject WebAXObject::ErrorMessage() const { - if (IsDetached()) - return WebAXObject(); - - return WebAXObject(private_->ErrorMessage()); -} - bool WebAXObject::IsEditable() const { if (IsDetached()) return false; @@ -410,13 +357,6 @@ return private_->LiveRegionStatus(); } -bool WebAXObject::ContainerLiveRegionAtomic() const { - if (IsDetached()) - return false; - - return private_->ContainerLiveRegionAtomic(); -} - bool WebAXObject::AriaOwns(WebVector<WebAXObject>& owns_elements) const { // aria-owns rearranges the accessibility tree rather than just // exposing an attribute.
diff --git a/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler_unittest.cc b/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler_unittest.cc index 88529d8..1891b628 100644 --- a/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler_unittest.cc +++ b/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler_unittest.cc
@@ -106,7 +106,7 @@ testBitmap.allocPixels(info); testBitmap.eraseARGB(opaque ? 255 : kTestAlphaValue, 30, 60, 200); return UnacceleratedStaticBitmapImage::Create( - SkImage::MakeFromBitmap(testBitmap)); + SkImages::RasterFromBitmap(testBitmap)); } void OnVerifyDeliveredFrame(
diff --git a/third_party/blink/renderer/modules/webcodecs/image_decoder_core.cc b/third_party/blink/renderer/modules/webcodecs/image_decoder_core.cc index c63bf10..3e7e716 100644 --- a/third_party/blink/renderer/modules/webcodecs/image_decoder_core.cc +++ b/third_party/blink/renderer/modules/webcodecs/image_decoder_core.cc
@@ -16,6 +16,7 @@ #include "third_party/blink/renderer/platform/image-decoders/segment_reader.h" #include "third_party/blink/renderer/platform/wtf/shared_buffer.h" #include "third_party/skia/include/core/SkColorSpace.h" +#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkYUVAPixmaps.h" namespace blink { @@ -213,7 +214,7 @@ // Prefer FinalizePixelsAndGetImage() since that will mark the underlying // bitmap as immutable, which allows copies to be avoided. auto sk_image = is_complete ? image->FinalizePixelsAndGetImage() - : SkImage::MakeFromBitmap(image->Bitmap()); + : SkImages::RasterFromBitmap(image->Bitmap()); if (!sk_image) { NOTREACHED() << "Failed to retrieve SkImage for decoded image."; result->status = Status::kDecodeError;
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc index 7c7320ae..f7dee2d 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc +++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
@@ -134,6 +134,7 @@ #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" #include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h" +#include "third_party/skia/include/core/SkImage.h" #include "ui/gfx/geometry/size.h" // Populates parameters from texImage2D except for border, width, height, and @@ -5632,7 +5633,7 @@ } auto pixmap = pixels->GetSkPixmap(); - auto image = SkImage::MakeFromRaster(pixmap, nullptr, nullptr); + auto image = SkImages::RasterFromPixmap(pixmap, nullptr, nullptr); TexImageSkImage(params, std::move(image), /*image_has_flip_y=*/false); }
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc index 2276b1d..91150d4 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc
@@ -27,6 +27,7 @@ #include "third_party/blink/renderer/platform/graphics/gpu/webgpu_texture_alpha_clearer.h" #include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h" #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" +#include "third_party/skia/include/core/SkImage.h" namespace blink { @@ -267,7 +268,7 @@ return MakeGarbageCollected<ImageBitmap>( UnacceleratedStaticBitmapImage::Create( - SkImage::MakeFromBitmap(black_bitmap))); + SkImages::RasterFromBitmap(black_bitmap))); }; // If the canvas configuration is invalid, WebGPU requires that we give a
diff --git a/third_party/blink/renderer/platform/RuntimeEnabledFeatures.md b/third_party/blink/renderer/platform/RuntimeEnabledFeatures.md index cbeea40..742578b 100644 --- a/third_party/blink/renderer/platform/RuntimeEnabledFeatures.md +++ b/third_party/blink/renderer/platform/RuntimeEnabledFeatures.md
@@ -1,6 +1,6 @@ # Runtime Enabled Features ## Overview -Runtime flags enable Blink developers the ability to control access Chromium users have to new features they implement. Features that are hidden behind a runtime flag are known as Runtime Enabled Features. It is a requirement of the Blink Launch Process to implement new web exposed features behind a runtime flag until an Intent To Ship has been approved. +Runtime flags enable Blink developers the ability to control access Chromium users have to new features they implement. Features that are hidden behind a runtime flag are known as Runtime Enabled Features. It is a requirement of the Blink Launch Process to implement new web exposed features behind a runtime flag until an Intent To Ship has been approved. Additionally, all changes with non-trivial compatibility risk [should be guarded](/docs/flag_guarding_guidelines.md) by a Runtime Enabled Feature (or other base::Feature) so that they can be disabled quickly. ## Adding A Runtime Enabled Feature Runtime Enabled Features are defined in runtime_enabled_features.json5 in alphabetical order. Add your feature's flag to [runtime_enabled_features.json5] and the rest will be generated for you automatically. @@ -240,4 +240,4 @@ [virtual/stable]: <https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/web_tests/VirtualTestSuites;drc=9878f26d52d32871ed1c085444196e5453909eec;l=112> [content/child/runtime_features.cc]: <https://source.chromium.org/chromium/chromium/src/+/main:content/child/runtime_features.cc> [initialize blink features]: <https://chromium.googlesource.com/chromium/src/+/main/docs/initialize_blink_features.md> -[controlled by chromium feature]: <https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/platform/runtime_enabled_features.json5;drc=70bddadf50a14254072cf7ca0bcf83e4331a7d4f;l=833> \ No newline at end of file +[controlled by chromium feature]: <https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/platform/runtime_enabled_features.json5;drc=70bddadf50a14254072cf7ca0bcf83e4331a7d4f;l=833>
diff --git a/third_party/blink/renderer/platform/exported/platform.cc b/third_party/blink/renderer/platform/exported/platform.cc index 62c782ac..eddf6b4 100644 --- a/third_party/blink/renderer/platform/exported/platform.cc +++ b/third_party/blink/renderer/platform/exported/platform.cc
@@ -194,6 +194,8 @@ DCHECK(!did_initialize_blink_); WTF::Partitions::Initialize(); WTF::Initialize(); + ProcessHeap::Init(); + ThreadState::AttachMainThread(); did_initialize_blink_ = true; } @@ -221,9 +223,8 @@ DCHECK(did_initialize_blink_); MainThread::SetMainThread(std::move(main_thread)); - ProcessHeap::Init(); - - ThreadState* thread_state = ThreadState::AttachMainThread(); + ThreadState* thread_state = ThreadState::Current(); + CHECK(thread_state->IsMainThread()); new BlinkGCMemoryDumpProvider( thread_state, base::SingleThreadTaskRunner::GetCurrentDefault(), BlinkGCMemoryDumpProvider::HeapType::kBlinkMainThread);
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 77d7bf9..49850c20 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
@@ -27,6 +27,7 @@ #include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h" #include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/gpu/GrDirectContext.h" +#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h" namespace blink { @@ -339,7 +340,7 @@ release_ctx->texture_id = shared_context_texture_id; release_ctx->context_provider_wrapper = context_provider_wrapper; - sk_sp<SkImage> sk_image = SkImage::MakeFromTexture( + sk_sp<SkImage> sk_image = SkImages::BorrowTextureFrom( shared_gr_context, backend_texture, origin, sk_image_info_.colorType(), sk_image_info_.alphaType(), sk_image_info_.refColorSpace(), &ReleaseTexture, release_ctx);
diff --git a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc index 67cff9d..0758b93 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc
@@ -216,7 +216,7 @@ base::TimeTicks before = base::TimeTicks::Now(); // Note: not discarding the encoded image. - auto image = SkImage::MakeFromEncoded(encoded_)->makeRasterImage(); + auto image = SkImages::DeferredFromEncodedData(encoded_)->makeRasterImage(); base::TimeTicks after = base::TimeTicks::Now(); UMA_HISTOGRAM_TIMES( "Blink.Canvas.2DLayerBridge.Compression.DecompressionTime",
diff --git a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc index 741d976c..a5dfb2d 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc
@@ -74,6 +74,7 @@ #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" #include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h" +#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/gpu/GrDirectContext.h" #include "third_party/skia/include/gpu/gl/GrGLTypes.h" @@ -163,7 +164,7 @@ SkBitmap bitmap; bitmap.allocPixelsFlags(SkImageInfo::MakeN32Premul(10, 10), SkBitmap::kZeroPixels_AllocFlag); - sk_sp<SkImage> sk_image = SkImage::MakeFromBitmap(bitmap); + sk_sp<SkImage> sk_image = SkImages::RasterFromBitmap(bitmap); return cc::DecodedDrawImage( sk_image, nullptr, SkSize::Make(0, 0), SkSize::Make(1, 1), cc::PaintFlags::FilterQuality::kLow, !budget_exceeded_);
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource.cc b/third_party/blink/renderer/platform/graphics/canvas_resource.cc index 98ee5df..ad61f0e6 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_resource.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_resource.cc
@@ -39,6 +39,7 @@ #include "third_party/blink/renderer/platform/wtf/cross_thread_copier_gpu.h" #include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h" #include "third_party/blink/renderer/platform/wtf/functional.h" +#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/gpu/GrDirectContext.h" #include "ui/gfx/buffer_format_util.h" #include "ui/gfx/color_space.h" @@ -260,8 +261,8 @@ size_(info.width(), info.height()) { // Software compositing lazily uses RGBA_8888 as the resource format // everywhere but the content is expected to be rendered in N32 format. - base::MappedReadOnlyRegion shm = - viz::bitmap_allocation::AllocateSharedBitmap(Size(), viz::RGBA_8888); + base::MappedReadOnlyRegion shm = viz::bitmap_allocation::AllocateSharedBitmap( + Size(), viz::SinglePlaneFormat::kRGBA_8888); if (!shm.IsValid()) return; @@ -301,7 +302,7 @@ SkPixmap pixmap(image_info, shared_mapping_.memory(), image_info.minRowBytes()); AddRef(); - sk_sp<SkImage> sk_image = SkImage::MakeFromRaster( + sk_sp<SkImage> sk_image = SkImages::RasterFromPixmap( pixmap, [](const void*, SkImage::ReleaseContext resource_to_unref) { static_cast<CanvasResourceSharedBitmap*>(resource_to_unref)->Release(); @@ -644,7 +645,7 @@ SkPixmap pixmap(CreateSkImageInfo(), gpu_memory_buffer_->memory(0), gpu_memory_buffer_->stride(0)); - auto sk_image = SkImage::MakeRasterCopy(pixmap); + auto sk_image = SkImages::RasterFromPixmapCopy(pixmap); gpu_memory_buffer_->Unmap(); return sk_image ? UnacceleratedStaticBitmapImage::Create(sk_image) : nullptr;
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc index bab4a22..364ef1a 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
@@ -383,8 +383,8 @@ // the same composited layer. const auto& previous_sibling = pending_layers_[layer_index - 1]; if (previous_sibling.DrawsContent() && - !previous_sibling.CanMerge(layer, *upcast_state, - lcd_text_preference_)) { + !previous_sibling.CanMergeWithDecompositedBlendMode(layer, + *upcast_state)) { return false; } }
diff --git a/third_party/blink/renderer/platform/graphics/compositing/pending_layer.cc b/third_party/blink/renderer/platform/graphics/compositing/pending_layer.cc index 45cd03aa..25cd700 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/pending_layer.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/pending_layer.cc
@@ -78,6 +78,7 @@ draws_content_ = false; } } + rect_known_to_be_opaque_.Intersect(bounds_); if (IsCompositedScrollHitTest(first_chunk)) { compositing_type_ = kScrollHitTestLayer; @@ -116,14 +117,23 @@ } gfx::RectF PendingLayer::MapRectKnownToBeOpaque( - const PropertyTreeState& new_state) const { - if (rect_known_to_be_opaque_.IsEmpty()) + const PropertyTreeState& new_state, + const FloatClipRect& mapped_layer_bounds) const { + if (!mapped_layer_bounds.IsTight()) { return gfx::RectF(); - + } + if (rect_known_to_be_opaque_.IsEmpty()) { + return gfx::RectF(); + } + if (rect_known_to_be_opaque_ == bounds_) { + return mapped_layer_bounds.Rect(); + } FloatClipRect float_clip_rect(rect_known_to_be_opaque_); GeometryMapper::LocalToAncestorVisualRect(GetPropertyTreeState(), new_state, float_clip_rect); - return float_clip_rect.IsTight() ? float_clip_rect.Rect() : gfx::RectF(); + float_clip_rect.Rect().Intersect(mapped_layer_bounds.Rect()); + DCHECK(float_clip_rect.IsTight()); + return float_clip_rect.Rect(); } std::unique_ptr<JSONObject> PendingLayer::ToJSON() const { @@ -164,9 +174,11 @@ FloatClipRect float_clip_rect(bounds_); GeometryMapper::LocalToAncestorVisualRect(GetPropertyTreeState(), new_state, float_clip_rect); + // The order of the following two statements is important because + // MapRectKnownToBeOpaque() needs to know the original bounds_. + rect_known_to_be_opaque_ = MapRectKnownToBeOpaque(new_state, float_clip_rect); bounds_ = float_clip_rect.Rect(); - rect_known_to_be_opaque_ = MapRectKnownToBeOpaque(new_state); property_tree_state_ = new_state; is_solid_color_ = false; } @@ -192,20 +204,13 @@ // merged_area - (home_area + guest_area) <= kMergeSparsityAreaTolerance static constexpr float kMergeSparsityAreaTolerance = 10000; -bool PendingLayer::MergeInternal(const PendingLayer& guest, - const PropertyTreeState& guest_state, - LCDTextPreference lcd_text_preference, - bool dry_run) { - DCHECK_EQ(&Chunks().GetPaintArtifact(), &guest.Chunks().GetPaintArtifact()); - if (ChunkRequiresOwnLayer() || guest.ChunkRequiresOwnLayer()) +bool PendingLayer::Merge(const PendingLayer& guest, + LCDTextPreference lcd_text_preference) { + absl::optional<PropertyTreeState> merged_state = + CanUpcastWith(guest, guest.GetPropertyTreeState()); + if (!merged_state) { return false; - if (&GetPropertyTreeState().Effect() != &guest_state.Effect()) - return false; - - const absl::optional<PropertyTreeState>& merged_state = - GetPropertyTreeState().CanUpcastWith(guest_state); - if (!merged_state) - return false; + } const absl::optional<gfx::RectF>& merged_visibility_limit = GeometryMapper::VisibilityLimit(*merged_state); @@ -218,92 +223,121 @@ if (!guest.has_decomposited_blend_mode_ && merged_visibility_limit && *merged_visibility_limit == bounds_ && merged_state == property_tree_state_ && - rect_known_to_be_opaque_.Contains(bounds_)) { - if (!dry_run) { - chunks_.Merge(guest.Chunks()); - draws_content_ |= guest.draws_content_; - text_known_to_be_on_opaque_background_ = true; - has_text_ |= guest.has_text_; - is_solid_color_ = false; - change_of_decomposited_transforms_ = - std::max(ChangeOfDecompositedTransforms(), - guest.ChangeOfDecompositedTransforms()); - } + rect_known_to_be_opaque_ == bounds_) { + chunks_.Merge(guest.Chunks()); + draws_content_ |= guest.draws_content_; + text_known_to_be_on_opaque_background_ = true; + has_text_ |= guest.has_text_; + is_solid_color_ = false; + change_of_decomposited_transforms_ = + std::max(ChangeOfDecompositedTransforms(), + guest.ChangeOfDecompositedTransforms()); return true; } FloatClipRect new_home_bounds(bounds_); GeometryMapper::LocalToAncestorVisualRect(GetPropertyTreeState(), *merged_state, new_home_bounds); - if (merged_visibility_limit) + if (merged_visibility_limit) { new_home_bounds.Rect().Intersect(*merged_visibility_limit); - + } FloatClipRect new_guest_bounds(guest.bounds_); - GeometryMapper::LocalToAncestorVisualRect(guest_state, *merged_state, - new_guest_bounds); - if (merged_visibility_limit) + GeometryMapper::LocalToAncestorVisualRect(guest.GetPropertyTreeState(), + *merged_state, new_guest_bounds); + if (merged_visibility_limit) { new_guest_bounds.Rect().Intersect(*merged_visibility_limit); + } gfx::RectF merged_bounds = gfx::UnionRects(new_home_bounds.Rect(), new_guest_bounds.Rect()); - float sum_area = new_home_bounds.Rect().size().GetArea() + - new_guest_bounds.Rect().size().GetArea(); - if (merged_bounds.size().GetArea() - sum_area > kMergeSparsityAreaTolerance) - return false; - // The guest's blend mode may make the merged layer not opaque. + // If guest.has_decomposited_blend_mode_ is true, this function must merge + // unconditionally and return because the decomposited blend mode requires + // the merge. See PaintArtifactCompositor::DecompositeEffect(). + // Also in the case, the conditions returning false below are unlikely to + // apply because + // - the src and dest layers are unlikely to be far away (sparse), + // - the blend mode may make the merged layer not opaque, + // - LCD text will be disabled with exotic blend mode. gfx::RectF merged_rect_known_to_be_opaque; bool merged_text_known_to_be_on_opaque_background = false; if (!guest.has_decomposited_blend_mode_) { - merged_rect_known_to_be_opaque = - gfx::MaximumCoveredRect(MapRectKnownToBeOpaque(*merged_state), - guest.MapRectKnownToBeOpaque(*merged_state)); + float sum_area = new_home_bounds.Rect().size().GetArea() + + new_guest_bounds.Rect().size().GetArea(); + if (merged_bounds.size().GetArea() - sum_area > + kMergeSparsityAreaTolerance) { + return false; + } + + gfx::RectF home_rect_known_to_be_opaque = + MapRectKnownToBeOpaque(*merged_state, new_home_bounds); + gfx::RectF guest_rect_known_to_be_opaque = + guest.MapRectKnownToBeOpaque(*merged_state, new_guest_bounds); + merged_rect_known_to_be_opaque = gfx::MaximumCoveredRect( + home_rect_known_to_be_opaque, guest_rect_known_to_be_opaque); merged_text_known_to_be_on_opaque_background = text_known_to_be_on_opaque_background_; if (text_known_to_be_on_opaque_background_ != guest.text_known_to_be_on_opaque_background_) { if (!text_known_to_be_on_opaque_background_) { - if (merged_rect_known_to_be_opaque.Contains(new_home_bounds.Rect())) + if (merged_rect_known_to_be_opaque.Contains(new_home_bounds.Rect())) { merged_text_known_to_be_on_opaque_background = true; + } } else if (!guest.text_known_to_be_on_opaque_background_) { - if (!merged_rect_known_to_be_opaque.Contains(new_guest_bounds.Rect())) + if (!merged_rect_known_to_be_opaque.Contains(new_guest_bounds.Rect())) { merged_text_known_to_be_on_opaque_background = false; + } } } - // This is in the 'if' block because if guest.has_decomposited_blend_mode_ - // is true, we'll lose LCD text anyway due to the exotic blend mode - // regardless of whether it's decomposited. if (lcd_text_preference == LCDTextPreference::kStronglyPreferred && !merged_text_known_to_be_on_opaque_background) { - if (has_text_ && text_known_to_be_on_opaque_background_) + if (has_text_ && text_known_to_be_on_opaque_background_) { return false; - if (guest.has_text_ && guest.text_known_to_be_on_opaque_background_) + } + if (guest.has_text_ && guest.text_known_to_be_on_opaque_background_) { return false; + } } } - if (!dry_run) { - chunks_.Merge(guest.Chunks()); - bounds_ = merged_bounds; - property_tree_state_ = *merged_state; - draws_content_ |= guest.draws_content_; - rect_known_to_be_opaque_ = merged_rect_known_to_be_opaque; - text_known_to_be_on_opaque_background_ = - merged_text_known_to_be_on_opaque_background; - has_text_ |= guest.has_text_; - is_solid_color_ = false; - change_of_decomposited_transforms_ = - std::max(ChangeOfDecompositedTransforms(), - guest.ChangeOfDecompositedTransforms()); - // GeometryMapper::LocalToAncestorVisualRect can introduce floating-point - // error to the bounds. Integral bounds are important for reducing - // blurriness (see: PendingLayer::LayerOffset) so preserve that here. - PreserveNearIntegralBounds(bounds_); - PreserveNearIntegralBounds(rect_known_to_be_opaque_); - } + chunks_.Merge(guest.Chunks()); + bounds_ = merged_bounds; + property_tree_state_ = *merged_state; + draws_content_ |= guest.draws_content_; + rect_known_to_be_opaque_ = merged_rect_known_to_be_opaque; + text_known_to_be_on_opaque_background_ = + merged_text_known_to_be_on_opaque_background; + has_text_ |= guest.has_text_; + is_solid_color_ = false; + change_of_decomposited_transforms_ = std::max( + ChangeOfDecompositedTransforms(), guest.ChangeOfDecompositedTransforms()); + // GeometryMapper::LocalToAncestorVisualRect can introduce floating-point + // error to the bounds. Integral bounds are important for reducing + // blurriness (see: PendingLayer::LayerOffset) so preserve that here. + PreserveNearIntegralBounds(bounds_); + PreserveNearIntegralBounds(rect_known_to_be_opaque_); return true; } +absl::optional<PropertyTreeState> PendingLayer::CanUpcastWith( + const PendingLayer& guest, + const PropertyTreeState& guest_state) const { + DCHECK_EQ(&Chunks().GetPaintArtifact(), &guest.Chunks().GetPaintArtifact()); + if (ChunkRequiresOwnLayer() || guest.ChunkRequiresOwnLayer()) { + return absl::nullopt; + } + if (&GetPropertyTreeState().Effect() != &guest_state.Effect()) { + return absl::nullopt; + } + return GetPropertyTreeState().CanUpcastWith(guest_state); +} + +bool PendingLayer::CanMergeWithDecompositedBlendMode( + const PendingLayer& guest, + const PropertyTreeState& upcast_state) const { + return CanUpcastWith(guest, upcast_state).has_value(); +} + const TransformPaintPropertyNode& PendingLayer::ScrollTranslationForScrollHitTestLayer() const { DCHECK_EQ(GetCompositingType(), kScrollHitTestLayer);
diff --git a/third_party/blink/renderer/platform/graphics/compositing/pending_layer.h b/third_party/blink/renderer/platform/graphics/compositing/pending_layer.h index 3f349a5..302daef 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/pending_layer.h +++ b/third_party/blink/renderer/platform/graphics/compositing/pending_layer.h
@@ -74,22 +74,13 @@ // Returns whether the merge is successful. bool Merge( const PendingLayer& guest, - LCDTextPreference lcd_text_preference = LCDTextPreference::kIgnored) { - return MergeInternal(guest, - guest.property_tree_state_.GetPropertyTreeState(), - lcd_text_preference, /*dry_run*/ false); - } + LCDTextPreference lcd_text_preference = LCDTextPreference::kIgnored); - // Returns true if |guest| can be merged into |this|. - // |guest_state| is for cases where we want to check if we can merge |guest| - // if it has |guest_state| in the future (which may be different from its - // current state). - bool CanMerge(const PendingLayer& guest, - const PropertyTreeState& guest_state, - LCDTextPreference lcd_text_preference) const { - return const_cast<PendingLayer*>(this)->MergeInternal( - guest, guest_state, lcd_text_preference, /*dry_run*/ true); - } + // Returns true if `guest` that could be upcasted with decomposited blend + // mode can be merged into `this`. + bool CanMergeWithDecompositedBlendMode( + const PendingLayer& guest, + const PropertyTreeState& upcast_state) const; // Mutate this layer's property tree state to a more general (shallower) // state, thus the name "upcast". The concrete effect of this is to @@ -166,11 +157,15 @@ bool IsSolidColor() const { return is_solid_color_; } private: - gfx::RectF MapRectKnownToBeOpaque(const PropertyTreeState&) const; - bool MergeInternal(const PendingLayer& guest, - const PropertyTreeState& guest_state, - LCDTextPreference, - bool dry_run); + // Checks basic merge-ability with `guest` and calls + // PropertyTreeState::CanUpcastWith(). + absl::optional<PropertyTreeState> CanUpcastWith( + const PendingLayer& guest, + const PropertyTreeState& guest_state) const; + + gfx::RectF MapRectKnownToBeOpaque( + const PropertyTreeState& new_state, + const FloatClipRect& mapped_layer_bounds) const; bool PropertyTreeStateChanged(const PendingLayer* old_pending_layer) const;
diff --git a/third_party/blink/renderer/platform/graphics/compositing/pending_layer_test.cc b/third_party/blink/renderer/platform/graphics/compositing/pending_layer_test.cc index 5acea4ef..682a874 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/pending_layer_test.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/pending_layer_test.cc
@@ -492,7 +492,7 @@ PendingLayer layer_b(artifact, artifact->PaintChunks()[1]); ASSERT_TRUE(layer_a.Merge(layer_b, GetLCDTextPreference())); EXPECT_EQ(gfx::RectF(175, 175, 100, 100), layer_a.BoundsForTesting()); - EXPECT_EQ(gfx::RectF(100, 100, 210, 210), layer_a.RectKnownToBeOpaque()); + EXPECT_EQ(gfx::RectF(175, 175, 100, 100), layer_a.RectKnownToBeOpaque()); EXPECT_TRUE(layer_a.TextKnownToBeOnOpaqueBackground()); }
diff --git a/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test_wo_platform.cc b/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test_wo_platform.cc index 1c1752f..4aaeb7b 100644 --- a/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test_wo_platform.cc +++ b/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test_wo_platform.cc
@@ -19,9 +19,10 @@ namespace { sk_sp<SkImage> CreateFrameAtIndex(DeferredImageDecoder* decoder, size_t index) { - return SkImage::MakeFromGenerator(std::make_unique<SkiaPaintImageGenerator>( - decoder->CreateGenerator(), index, - cc::PaintImage::kDefaultGeneratorClientId)); + return SkImages::DeferredFromGenerator( + std::make_unique<SkiaPaintImageGenerator>( + decoder->CreateGenerator(), index, + cc::PaintImage::kDefaultGeneratorClientId)); } } // namespace
diff --git a/third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.cc b/third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.cc index e586dd8..63bb2fa 100644 --- a/third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.cc +++ b/third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.cc
@@ -30,6 +30,7 @@ #include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_record.h" #include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h" +#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/effects/SkColorMatrixFilter.h" #include "third_party/skia/include/effects/SkTableColorFilter.h" #include "ui/gfx/geometry/skia_conversions.h" @@ -132,7 +133,7 @@ canvas.drawPicture(std::move(mask_record)); PaintImage image = PaintImageBuilder::WithDefault() .set_id(PaintImage::GetNextId()) - .set_image(SkImage::MakeFromBitmap(bitmap), + .set_image(SkImages::RasterFromBitmap(bitmap), PaintImage::GetNextContentId()) .TakePaintImage();
diff --git a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc index 99de392d..9171b1b 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc
@@ -69,6 +69,7 @@ #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/wtf/functional.h" +#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkPixmap.h" #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/gpu/gl/GrGLTypes.h" @@ -383,8 +384,8 @@ const viz::SharedBitmapId id = viz::SharedBitmap::GenerateId(); const viz::SharedImageFormat format = viz::SinglePlaneFormat::kRGBA_8888; - base::MappedReadOnlyRegion shm = viz::bitmap_allocation::AllocateSharedBitmap( - size_, format.resource_format()); + base::MappedReadOnlyRegion shm = + viz::bitmap_allocation::AllocateSharedBitmap(size_, format); auto bitmap = base::MakeRefCounted<cc::CrossThreadSharedBitmap>( id, std::move(shm), size_, format); RegisteredBitmap registered = { @@ -464,7 +465,7 @@ if (!bitmap.tryAllocN32Pixels(size_.width(), size_.height())) return nullptr; ReadFramebufferIntoBitmapPixels(static_cast<uint8_t*>(bitmap.getPixels())); - auto sk_image = SkImage::MakeFromBitmap(bitmap); + auto sk_image = SkImages::RasterFromBitmap(bitmap); bool origin_top_left = flip_y ? opengl_flip_y_extension_ : !opengl_flip_y_extension_; @@ -698,7 +699,7 @@ if (!black_bitmap.tryAllocN32Pixels(size_.width(), size_.height())) return nullptr; black_bitmap.eraseARGB(0, 0, 0, 0); - sk_sp<SkImage> black_image = SkImage::MakeFromBitmap(black_bitmap); + sk_sp<SkImage> black_image = SkImages::RasterFromBitmap(black_bitmap); if (!black_image) return nullptr; return UnacceleratedStaticBitmapImage::Create(black_image);
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 a9250c1f..8066d26f 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
@@ -282,8 +282,8 @@ // There are no bitmaps to recycle so allocate a new one. viz::SharedBitmapId id = viz::SharedBitmap::GenerateId(); - base::MappedReadOnlyRegion shm = viz::bitmap_allocation::AllocateSharedBitmap( - size, format.resource_format()); + base::MappedReadOnlyRegion shm = + viz::bitmap_allocation::AllocateSharedBitmap(size, format); RegisteredBitmap registered; registered.bitmap = base::MakeRefCounted<cc::CrossThreadSharedBitmap>(
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc b/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc index d1090ee..faaf6bf 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc
@@ -3809,7 +3809,7 @@ // TODO(fmalita): Partial frames are not supported currently: only fully // decoded frames make it through. We could potentially relax this and - // use SkImage::MakeFromBitmap(bitmap) to make a copy. + // use SkImages::RasterFromBitmap(bitmap) to make a copy. skia_image = frame->FinalizePixelsAndGetImage(); } }
diff --git a/third_party/blink/renderer/platform/graphics/image_data_buffer.cc b/third_party/blink/renderer/platform/graphics/image_data_buffer.cc index 0e7963a..16875cc 100644 --- a/third_party/blink/renderer/platform/graphics/image_data_buffer.cc +++ b/third_party/blink/renderer/platform/graphics/image_data_buffer.cc
@@ -42,6 +42,7 @@ #include "third_party/blink/renderer/platform/wtf/text/base64.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/vector.h" +#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/core/SkSwizzle.h" #include "third_party/skia/include/encode/SkJpegEncoder.h" @@ -94,7 +95,7 @@ return; } MSAN_CHECK_MEM_IS_INITIALIZED(pixmap_.addr(), pixmap_.computeByteSize()); - retained_image_ = SkImage::MakeRasterData(info, std::move(data), rowBytes); + retained_image_ = SkImages::RasterFromData(info, std::move(data), rowBytes); } else { retained_image_ = paint_image.GetSwSkImage(); if (!retained_image_->peekPixels(&pixmap_))
diff --git a/third_party/blink/renderer/platform/graphics/mailbox_texture_backing.cc b/third_party/blink/renderer/platform/graphics/mailbox_texture_backing.cc index a885fe1..f8c5177e 100644 --- a/third_party/blink/renderer/platform/graphics/mailbox_texture_backing.cc +++ b/third_party/blink/renderer/platform/graphics/mailbox_texture_backing.cc
@@ -8,6 +8,7 @@ #include "third_party/blink/renderer/platform/graphics/mailbox_ref.h" #include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h" #include "third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_wrapper.h" +#include "third_party/skia/include/core/SkImage.h" namespace blink { @@ -76,8 +77,8 @@ static_cast<GLuint>(sk_image_info_.minRowBytes()), 0, 0, /*plane_index=*/0, writable_pixels); - return SkImage::MakeRasterData(sk_image_info_, std::move(image_pixels), - sk_image_info_.minRowBytes()); + return SkImages::RasterFromData(sk_image_info_, std::move(image_pixels), + sk_image_info_.minRowBytes()); } else if (sk_image_) { return sk_image_->makeNonTextureImage(); }
diff --git a/third_party/blink/renderer/platform/graphics/static_bitmap_image.cc b/third_party/blink/renderer/platform/graphics/static_bitmap_image.cc index e1dc580..291c45844 100644 --- a/third_party/blink/renderer/platform/graphics/static_bitmap_image.cc +++ b/third_party/blink/renderer/platform/graphics/static_bitmap_image.cc
@@ -32,7 +32,7 @@ const SkImageInfo& info, ImageOrientation orientation) { return UnacceleratedStaticBitmapImage::Create( - SkImage::MakeRasterData(info, std::move(data), info.minRowBytes()), + SkImages::RasterFromData(info, std::move(data), info.minRowBytes()), orientation); }
diff --git a/third_party/blink/renderer/platform/image-decoders/image_frame.cc b/third_party/blink/renderer/platform/image-decoders/image_frame.cc index 728d8d5..5dcfda22 100644 --- a/third_party/blink/renderer/platform/image-decoders/image_frame.cc +++ b/third_party/blink/renderer/platform/image-decoders/image_frame.cc
@@ -141,7 +141,7 @@ sk_sp<SkImage> ImageFrame::FinalizePixelsAndGetImage() { DCHECK_EQ(kFrameComplete, status_); bitmap_.setImmutable(); - return SkImage::MakeFromBitmap(bitmap_); + return SkImages::RasterFromBitmap(bitmap_); } void ImageFrame::SetHasAlpha(bool alpha) { @@ -188,7 +188,7 @@ SkPixmap src_pixmap(info.makeAlphaType(kUnpremul_SkAlphaType), src, info.minRowBytes()); sk_sp<SkImage> src_image = - SkImage::MakeFromRaster(src_pixmap, nullptr, nullptr); + SkImages::RasterFromPixmap(src_pixmap, nullptr, nullptr); surface->getCanvas()->drawImage(src_image, 0, 0); surface->flushAndSubmit();
diff --git a/third_party/blink/renderer/platform/image-decoders/image_frame.h b/third_party/blink/renderer/platform/image-decoders/image_frame.h index aea081ee..349eb640 100644 --- a/third_party/blink/renderer/platform/image-decoders/image_frame.h +++ b/third_party/blink/renderer/platform/image-decoders/image_frame.h
@@ -147,7 +147,7 @@ // Create SkImage from Bitmap() and return it. This should be called only // if frame is complete. The bitmap is set immutable before creating - // SkImage to avoid copying bitmap in SkImage::MakeFromBitmap(bitmap_). + // SkImage to avoid copying bitmap in SkImages::RasterFromBitmap(bitmap_). sk_sp<SkImage> FinalizePixelsAndGetImage(); // Returns true if the pixels changed, but the bitmap has not yet been
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index d71660d..a2e959db 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1397,7 +1397,7 @@ }, { name: "ElementSuperRareData", - status: "experimental", + status: "stable", }, { // Experiment with preventing some instances of mutation XSS @@ -1854,8 +1854,7 @@ { // TODO(crbug.com/1307772): Enables the Popover API. name: "HTMLPopoverAttribute", - status: "experimental", - // Because the OT is already underway, it is being left with the "popup" name. + status: "stable", origin_trial_feature_name: "HTMLPopupAttribute", implied_by: ["HTMLSelectMenuElement","HTMLPopoverHint"], }, @@ -1961,8 +1960,6 @@ }, { name: "LayoutMediaNGContainer", - // This feature doesn't work in the legacy layout. - depends_on: ["LayoutNGPrinting"], status: "stable", }, { @@ -1976,15 +1973,10 @@ status: "test", }, { - name: "LayoutNGPrinting", - status: "stable", - }, - { // Avoid UpdateLogicalWidth() and UpdateLogicalHeight() in LayoutReplaced // subclasses. // It's a part of "stop-copying-back" project. crbug.com/1353190 name: "LayoutNGReplacedNoBoxSetters", - depends_on: ["LayoutNGPrinting"], status: "stable", }, { @@ -2001,8 +1993,6 @@ // Merge UpdateAfterLayout() calls for LayoutReplaced into one in // CopyFragmentDataToLayoutBox(). crbug.com/1353190 name: "LayoutNGUnifyUpdateAfterLayout", - // This feature doesn't work in the legacy layout. - depends_on: ["LayoutNGPrinting"], status: "stable", }, { @@ -2603,13 +2593,6 @@ status: "test", }, { - name: "PointerLockOptions", - origin_trial_feature_name: "PointerLockOptions", - public: true, - status: "stable", - base_feature: "none", - }, - { name: "Portals", // Portals must be enabled by blink::features::kPortals as we require the // support of the browser process to enable the feature. Enabling this
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc index 4303c5f6..0ddd3e7 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
@@ -477,7 +477,10 @@ have_seen_a_frame(false), audible_power_mode_voter( power_scheduler::PowerModeArbiter::GetInstance()->NewVoter( - "PowerModeVoter.Audible")) {} + "PowerModeVoter.Audible")), + agent_group_schedulers( + MakeGarbageCollected< + HeapHashSet<WeakMember<AgentGroupSchedulerImpl>>>()) {} MainThreadSchedulerImpl::MainThreadOnly::~MainThreadOnly() = default; @@ -1128,9 +1131,6 @@ if (isolate()) EventLoop::PerformIsolateGlobalMicrotasksCheckpoint(isolate()); - if (!main_thread_only().agent_group_schedulers) - return; - // Perform a microtask checkpoint for each AgentSchedulingGroup. This // really should only be the ones that are not frozen but AgentSchedulingGroup // does not have that concept yet. @@ -2269,11 +2269,6 @@ void MainThreadSchedulerImpl::AddAgentGroupScheduler( AgentGroupSchedulerImpl* agent_group_scheduler) { - if (!main_thread_only().agent_group_schedulers) { - main_thread_only().agent_group_schedulers = MakeGarbageCollected< - HeapHashSet<WeakMember<AgentGroupSchedulerImpl>>>(); - } - bool is_new_entry = main_thread_only() .agent_group_schedulers->insert(agent_group_scheduler) .is_new_entry;
diff --git a/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc b/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc index ebeb76ca..83b52be 100644 --- a/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc +++ b/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc
@@ -79,14 +79,14 @@ // If the target scroller comes from a main thread hit test, we're in // scroll unification. - scroll_state_data.is_main_thread_hit_tested = - event.data.scroll_begin.main_thread_hit_tested; - DCHECK(!event.data.scroll_begin.main_thread_hit_tested || + scroll_state_data.main_thread_hit_tested_reasons = + event.data.scroll_begin.main_thread_hit_tested_reasons; + DCHECK(!event.data.scroll_begin.main_thread_hit_tested_reasons || base::FeatureList::IsEnabled(::features::kScrollUnification)); } else { // If a main thread hit test didn't yield a target we should have // discarded this event before this point. - DCHECK(!event.data.scroll_begin.main_thread_hit_tested); + DCHECK(!event.data.scroll_begin.main_thread_hit_tested_reasons); } break; @@ -386,11 +386,14 @@ DCHECK(base::FeatureList::IsEnabled(::features::kScrollUnification)); DCHECK_EQ(event->Event().GetType(), WebGestureEvent::Type::kGestureScrollBegin); - DCHECK(hit_testing_scroll_begin_on_main_thread_); + DCHECK(scroll_begin_main_thread_hit_test_reasons_); DCHECK(currently_active_gesture_device_); DCHECK(input_handler_); - hit_testing_scroll_begin_on_main_thread_ = false; + uint32_t main_thread_hit_test_reasons = + scroll_begin_main_thread_hit_test_reasons_; + scroll_begin_main_thread_hit_test_reasons_ = + cc::MainThreadScrollingReason::kNotScrollingOnMain; // HandleGestureScrollBegin has logic to end an existing scroll when an // unexpected scroll begin arrives. We currently think we're in a scroll @@ -403,7 +406,8 @@ if (hit_test_result) { gesture_event->data.scroll_begin.scrollable_area_element_id = hit_test_result.GetInternalValue(); - gesture_event->data.scroll_begin.main_thread_hit_tested = true; + gesture_event->data.scroll_begin.main_thread_hit_tested_reasons = + main_thread_hit_test_reasons; if (metrics) { // The event is going to be re-processed on the compositor thread; so, @@ -516,7 +520,7 @@ // Block flushing the compositor gesture event queue while there's an async // scroll begin hit test outstanding. We'll flush the queue when the hit test // responds. - if (hit_testing_scroll_begin_on_main_thread_) { + if (scroll_begin_main_thread_hit_test_reasons_) { DCHECK(base::FeatureList::IsEnabled(::features::kScrollUnification)); return false; } @@ -844,7 +848,7 @@ void InputHandlerProxy::RecordScrollBegin( WebGestureDevice device, uint32_t reasons_from_scroll_begin, - bool was_main_thread_hit_tested, + uint32_t main_thread_hit_tested_reasons, uint32_t main_thread_repaint_reasons) { if (device != WebGestureDevice::kTouchpad && device != WebGestureDevice::kScrollbar && @@ -872,7 +876,7 @@ disposition.has_value() && disposition == DID_NOT_HANDLE; bool blocked_on_main_at_begin = - blocked_on_main_thread_handler || was_main_thread_hit_tested; + blocked_on_main_thread_handler || main_thread_hit_tested_reasons; auto scroll_start_state = RecordScrollingThread( is_compositor_scroll, blocked_on_main_at_begin, device); @@ -888,9 +892,7 @@ ? cc::MainThreadScrollingReason::kWheelEventHandlerRegion : cc::MainThreadScrollingReason::kTouchEventHandlerRegion); } - if (was_main_thread_hit_tested) { - reportable_reasons |= cc::MainThreadScrollingReason::kFailedHitTest; - } + reportable_reasons |= main_thread_hit_tested_reasons; // With scroll unification, we never scroll "on main" from the perspective // of cc::InputHandler, but we still want to log reasons if the user will not @@ -989,16 +991,17 @@ // If we need a hit test from the main thread, we'll reinject this scroll // begin event once the hit test is complete so avoid everything below for // now, it'll be run on the second iteration. - if (scroll_status.needs_main_thread_hit_test) { + if (scroll_status.main_thread_hit_test_reasons) { DCHECK(base::FeatureList::IsEnabled(::features::kScrollUnification)); - hit_testing_scroll_begin_on_main_thread_ = true; + scroll_begin_main_thread_hit_test_reasons_ = + scroll_status.main_thread_hit_test_reasons; return REQUIRES_MAIN_THREAD_HIT_TEST; } if (scroll_status.thread != ScrollThread::SCROLL_IGNORED) { RecordScrollBegin(gesture_event.SourceDevice(), scroll_status.main_thread_scrolling_reasons, - scroll_state.is_main_thread_hit_tested(), + scroll_state.main_thread_hit_tested_reasons(), scroll_status.main_thread_repaint_reasons); }
diff --git a/third_party/blink/renderer/platform/widget/input/input_handler_proxy.h b/third_party/blink/renderer/platform/widget/input/input_handler_proxy.h index a0c340d..e8ca90d3 100644 --- a/third_party/blink/renderer/platform/widget/input/input_handler_proxy.h +++ b/third_party/blink/renderer/platform/widget/input/input_handler_proxy.h
@@ -322,7 +322,7 @@ void RecordScrollBegin(blink::WebGestureDevice device, uint32_t reasons_from_scroll_begin, - bool was_main_thread_hit_tested, + uint32_t main_thread_hit_tested_reasons, uint32_t main_thread_repaint_reasons); bool HasQueuedEventsReadyForDispatch(); @@ -401,13 +401,14 @@ bool skip_touch_filter_discrete_ = false; bool skip_touch_filter_all_ = false; - // This bit is set when the input handler proxy has requested that the client + // This is set when the input handler proxy has requested that the client // perform a hit test for a scroll begin on the main thread. During that // time, scroll updates need to be queued. The reply from the main thread // will come by calling ContinueScrollBeginAfterMainThreadHitTest where the // queue will be flushed and this bit cleared. Used only in scroll // unification. - bool hit_testing_scroll_begin_on_main_thread_ = false; + uint32_t scroll_begin_main_thread_hit_test_reasons_ = + cc::MainThreadScrollingReason::kNotScrollingOnMain; // This bit can be used to disable event attribution in cases where the // hit test information is unnecessary (e.g. tests).
diff --git a/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc b/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc index 598e185..9011d68 100644 --- a/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc +++ b/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc
@@ -317,25 +317,25 @@ return point; } -const cc::InputHandler::ScrollStatus kImplThreadScrollState( +const cc::InputHandler::ScrollStatus kImplThreadScrollState{ cc::InputHandler::ScrollThread::SCROLL_ON_IMPL_THREAD, - cc::MainThreadScrollingReason::kNotScrollingOnMain); + cc::MainThreadScrollingReason::kNotScrollingOnMain}; -const cc::InputHandler::ScrollStatus kRequiresMainThreadHitTestState( +const cc::InputHandler::ScrollStatus kRequiresMainThreadHitTestState{ cc::InputHandler::ScrollThread::SCROLL_ON_IMPL_THREAD, cc::MainThreadScrollingReason::kNotScrollingOnMain, - /*needs_main_thread_hit_test=*/true); + cc::MainThreadScrollingReason::kNonFastScrollableRegion}; constexpr auto kSampleMainThreadScrollingReason = cc::MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects; -const cc::InputHandler::ScrollStatus kMainThreadScrollState( +const cc::InputHandler::ScrollStatus kMainThreadScrollState{ cc::InputHandler::ScrollThread::SCROLL_ON_MAIN_THREAD, - kSampleMainThreadScrollingReason); + kSampleMainThreadScrollingReason}; -const cc::InputHandler::ScrollStatus kScrollIgnoredScrollState( +const cc::InputHandler::ScrollStatus kScrollIgnoredScrollState{ cc::InputHandler::ScrollThread::SCROLL_IGNORED, - cc::MainThreadScrollingReason::kNotScrollingOnMain); + cc::MainThreadScrollingReason::kNotScrollingOnMain}; } // namespace @@ -2041,7 +2041,8 @@ WebInputEvent::Type::kGestureScrollBegin, WebInputEvent::kNoModifiers, TimeForInputEvents(), WebGestureDevice::kTouchpad); gsb->data.scroll_begin.scrollable_area_element_id = 0; - gsb->data.scroll_begin.main_thread_hit_tested = false; + gsb->data.scroll_begin.main_thread_hit_tested_reasons = + cc::MainThreadScrollingReason::kNotScrollingOnMain; gsb->data.scroll_begin.delta_x_hint = 0; gsb->data.scroll_begin.delta_y_hint = 10; gsb->data.scroll_begin.pointer_count = 0; @@ -2086,7 +2087,8 @@ } bool MainThreadHitTestInProgress() const { - return input_handler_proxy_.hit_testing_scroll_begin_on_main_thread_; + return input_handler_proxy_.scroll_begin_main_thread_hit_test_reasons_ != + cc::MainThreadScrollingReason::kNotScrollingOnMain; } void BeginFrame() { @@ -2266,7 +2268,9 @@ mock_input_handler_, ScrollBegin( AllOf(Property(&ScrollState::target_element_id, Eq(ElementId())), - Property(&ScrollState::is_main_thread_hit_tested, Eq(false))), + Property( + &ScrollState::main_thread_hit_tested_reasons, + Eq(cc::MainThreadScrollingReason::kNotScrollingOnMain))), _)) .WillOnce(Return(kRequiresMainThreadHitTestState)); DispatchEvent(ScrollBegin()); @@ -2283,7 +2287,9 @@ mock_input_handler_, ScrollBegin( AllOf(Property(&ScrollState::target_element_id, Eq(kHitTestResult)), - Property(&ScrollState::is_main_thread_hit_tested, Eq(true))), + Property(&ScrollState::main_thread_hit_tested_reasons, + Eq(cc::MainThreadScrollingReason:: + kNonFastScrollableRegion))), _)) .Times(1); @@ -3748,7 +3754,8 @@ VERIFY_AND_RESET_MOCKS(); gesture_.data.scroll_begin.scrollable_area_element_id = 1; - gesture_.data.scroll_begin.main_thread_hit_tested = true; + gesture_.data.scroll_begin.main_thread_hit_tested_reasons = + cc::MainThreadScrollingReason::kNonFastScrollableRegion; EXPECT_CALL(mock_input_handler_, ScrollBegin(_, _)) .WillOnce(testing::Return(kImplThreadScrollState)); @@ -3765,7 +3772,7 @@ VERIFY_AND_RESET_MOCKS(); EXPECT_MAIN_THREAD_WHEEL_SCROLL_SAMPLE( - cc::MainThreadScrollingReason::kFailedHitTest); + cc::MainThreadScrollingReason::kNonFastScrollableRegion); } TEST_P(InputHandlerProxyMainThreadScrollingReasonTest,
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index ca3e13e..16e55f3 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -2055,6 +2055,7 @@ crbug.com/1072022 [ Mac12-arm64 Release ] http/tests/security/frameNavigation/xss-ALLOWED-parent-navigation-change-async.html [ Pass Timeout ] crbug.com/1072022 [ Mac13-arm64 Release ] http/tests/security/frameNavigation/xss-ALLOWED-parent-navigation-change-async.html [ Pass Timeout ] crbug.com/1072022 [ Linux ] http/tests/security/frameNavigation/xss-ALLOWED-parent-navigation-change-async.html [ Pass Timeout ] +crbug.com/1072022 [ Win ] http/tests/security/frameNavigation/xss-ALLOWED-parent-navigation-change-async.html [ Pass Timeout ] crbug.com/915903 http/tests/security/inactive-document-with-empty-security-origin.html [ Pass Timeout ] crbug.com/987138 [ Linux ] media/controls/doubletap-to-jump-forwards.html [ Pass Timeout ] crbug.com/987138 [ Win ] media/controls/doubletap-to-jump-forwards.html [ Pass Timeout ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 66da64ed..93ee71e 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -1214,13 +1214,6 @@ "expires": "Jul 1, 2023" }, { - "prefix": "popover-disabled", - "platforms": ["Linux", "Mac", "Win"], - "bases": [], - "args": ["--disable-blink-features=HTMLSelectMenuElement,HTMLPopoverAttribute,HTMLPopoverHint"], - "expires": "Jul 1, 2023" - }, - { "prefix": "popover-hint-disabled", "platforms": ["Linux", "Mac", "Win"], "bases": [],
diff --git a/third_party/blink/web_tests/css3/blending/background-blend-mode-multiple-background-layers-expected.png b/third_party/blink/web_tests/css3/blending/background-blend-mode-multiple-background-layers-expected.png index d084364c..8846410 100644 --- a/third_party/blink/web_tests/css3/blending/background-blend-mode-multiple-background-layers-expected.png +++ b/third_party/blink/web_tests/css3/blending/background-blend-mode-multiple-background-layers-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/css/css-sizing/contain-intrinsic-size/auto-008-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-sizing/contain-intrinsic-size/auto-008-expected.txt deleted file mode 100644 index 5f790b0..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-sizing/contain-intrinsic-size/auto-008-expected.txt +++ /dev/null
@@ -1,6 +0,0 @@ -This is a testharness.js-based test. -PASS requestAnimationFrame -FAIL Early ResizeObserver assert_equals: Using last remembered size - clientWidth expected 100 but got 40 -PASS Late ResizeObserver -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/css/css-sizing/contain-intrinsic-size/auto-008.html.ini b/third_party/blink/web_tests/external/wpt/css/css-sizing/contain-intrinsic-size/auto-008.html.ini deleted file mode 100644 index b9f8bab1..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-sizing/contain-intrinsic-size/auto-008.html.ini +++ /dev/null
@@ -1,3 +0,0 @@ -[auto-008.html] - [Early ResizeObserver] - expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-writingmode-lr.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-writingmode-lr.tentative.html new file mode 100644 index 0000000..15bd591 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-writingmode-lr.tentative.html
@@ -0,0 +1,8 @@ +<!DOCTYPE html> +<link rel=author href="mailto:jarhar@chromium.org"> +<link rel=help href="https://github.com/openui/open-ui/issues/600"> +<link rel=mismatch href="selectmenu-writingmode-tb-ref.html"> + +<selectmenu style="writing-mode: vertical-lr"> + <option>hello</option> +</selectmenu>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-writingmode-rl.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-writingmode-rl.tentative.html new file mode 100644 index 0000000..9cc1056e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-writingmode-rl.tentative.html
@@ -0,0 +1,8 @@ +<!DOCTYPE html> +<link rel=author href="mailto:jarhar@chromium.org"> +<link rel=help href="https://github.com/openui/open-ui/issues/600"> +<link rel=mismatch href="selectmenu-writingmode-tb-ref.html"> + +<selectmenu style="writing-mode: vertical-rl"> + <option>hello</option> +</selectmenu>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-writingmode-tb-ref.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-writingmode-tb-ref.html new file mode 100644 index 0000000..d2486ad9 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-writingmode-tb-ref.html
@@ -0,0 +1,4 @@ +<!DOCTYPE html> +<selectmenu style="writing-mode: horizontal-tb"> + <option>hello</option> +</selectmenu>
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/expected-fail/unhandled-rejection-following-subtest.html b/third_party/blink/web_tests/external/wpt/infrastructure/expected-fail/unhandled-rejection-following-subtest.html index 2cc19d9..d8cab6d 100644 --- a/third_party/blink/web_tests/external/wpt/infrastructure/expected-fail/unhandled-rejection-following-subtest.html +++ b/third_party/blink/web_tests/external/wpt/infrastructure/expected-fail/unhandled-rejection-following-subtest.html
@@ -4,6 +4,8 @@ <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <script> +setup({ explicit_done: true }); +window.addEventListener('unhandledrejection', () => { done(); }, {once: true}); test(function() {}); Promise.reject(new Error("error outside any setup or test")); </script>
diff --git a/third_party/blink/web_tests/external/wpt/storage-access-api/resources/embedded_responder.js b/third_party/blink/web_tests/external/wpt/storage-access-api/resources/embedded_responder.js index ab1ab30f6..6d42096 100644 --- a/third_party/blink/web_tests/external/wpt/storage-access-api/resources/embedded_responder.js +++ b/third_party/blink/web_tests/external/wpt/storage-access-api/resources/embedded_responder.js
@@ -34,7 +34,7 @@ case "observe_permission_change": const status = await navigator.permissions.query({name: "storage-access"}); status.addEventListener("change", (event) => { - reply(event.target.state) + reply(status.state) }, { once: true }); break; case "reload":
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/protocol/rtp-headerextensions.html b/third_party/blink/web_tests/external/wpt/webrtc/protocol/rtp-headerextensions.html index 67781374..c377a61 100644 --- a/third_party/blink/web_tests/external/wpt/webrtc/protocol/rtp-headerextensions.html +++ b/third_party/blink/web_tests/external/wpt/webrtc/protocol/rtp-headerextensions.html
@@ -76,4 +76,26 @@ }, testcase.description + ' header extension is supported.'); }); +promise_test(async t => { + const pc = new RTCPeerConnection(); + t.add_cleanup(() => pc.close()); + + pc.addTransceiver('video'); + const offer = await pc.createOffer(); + const section = SDPUtils.splitSections(offer.sdp)[1]; + const extensions = SDPUtils.matchPrefix(section, 'a=extmap:') + .map(line => SDPUtils.parseExtmap(line)); + const extension_not_mid = extensions.find(e => e.uri !== 'urn:ietf:params:rtp-hdrext:sdes:mid'); + await pc.setRemoteDescription({type :'offer', sdp: offer.sdp.replace(extension_not_mid.uri, 'bogus')}); + + await pc.setLocalDescription(); + const answer_section = SDPUtils.splitSections(pc.localDescription.sdp)[1]; + const answer_extensions = SDPUtils.matchPrefix(answer_section, 'a=extmap:') + .map(line => SDPUtils.parseExtmap(line)); + assert_equals(answer_extensions.length, extensions.length - 1); + assert_false(!!extensions.find(e => e.uri === 'bogus')); + for (const answer_extension of answer_extensions) { + assert_true(!!extensions.find(e => e.uri === answer_extension.uri)); + } +}, 'Negotiates the subset of supported extensions offered'); </script>
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/css3/blending/background-blend-mode-crossfade-image-gradient-expected.png b/third_party/blink/web_tests/flag-specific/highdpi/css3/blending/background-blend-mode-crossfade-image-gradient-expected.png index 602d0d1..dbda4cc 100644 --- a/third_party/blink/web_tests/flag-specific/highdpi/css3/blending/background-blend-mode-crossfade-image-gradient-expected.png +++ b/third_party/blink/web_tests/flag-specific/highdpi/css3/blending/background-blend-mode-crossfade-image-gradient-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/css3/blending/background-blend-mode-crossfade-image-gradient-expected.png b/third_party/blink/web_tests/platform/linux/css3/blending/background-blend-mode-crossfade-image-gradient-expected.png index 193217a9..272164f 100644 --- a/third_party/blink/web_tests/platform/linux/css3/blending/background-blend-mode-crossfade-image-gradient-expected.png +++ b/third_party/blink/web_tests/platform/linux/css3/blending/background-blend-mode-crossfade-image-gradient-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/css3/blending/background-blend-mode-gradient-gradient-expected.png b/third_party/blink/web_tests/platform/linux/css3/blending/background-blend-mode-gradient-gradient-expected.png index 3519b88..a16c11b 100644 --- a/third_party/blink/web_tests/platform/linux/css3/blending/background-blend-mode-gradient-gradient-expected.png +++ b/third_party/blink/web_tests/platform/linux/css3/blending/background-blend-mode-gradient-gradient-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/css3/blending/background-blend-mode-gradient-image-expected.png b/third_party/blink/web_tests/platform/linux/css3/blending/background-blend-mode-gradient-image-expected.png index 2d476e4..689061e 100644 --- a/third_party/blink/web_tests/platform/linux/css3/blending/background-blend-mode-gradient-image-expected.png +++ b/third_party/blink/web_tests/platform/linux/css3/blending/background-blend-mode-gradient-image-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/css3/blending/background-blend-mode-tiled-gradient-expected.png b/third_party/blink/web_tests/platform/linux/css3/blending/background-blend-mode-tiled-gradient-expected.png index d3e3d2b..290256ac 100644 --- a/third_party/blink/web_tests/platform/linux/css3/blending/background-blend-mode-tiled-gradient-expected.png +++ b/third_party/blink/web_tests/platform/linux/css3/blending/background-blend-mode-tiled-gradient-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/css3/blending/mix-blend-mode-isolated-group-1-expected.png b/third_party/blink/web_tests/platform/linux/css3/blending/mix-blend-mode-isolated-group-1-expected.png new file mode 100644 index 0000000..26e37aa --- /dev/null +++ b/third_party/blink/web_tests/platform/linux/css3/blending/mix-blend-mode-isolated-group-1-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/css3/blending/mix-blend-mode-isolated-group-2-expected.png b/third_party/blink/web_tests/platform/linux/css3/blending/mix-blend-mode-isolated-group-2-expected.png new file mode 100644 index 0000000..ee2cc4f --- /dev/null +++ b/third_party/blink/web_tests/platform/linux/css3/blending/mix-blend-mode-isolated-group-2-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/css3/blending/mix-blend-mode-isolated-group-3-expected.png b/third_party/blink/web_tests/platform/linux/css3/blending/mix-blend-mode-isolated-group-3-expected.png new file mode 100644 index 0000000..f89025a --- /dev/null +++ b/third_party/blink/web_tests/platform/linux/css3/blending/mix-blend-mode-isolated-group-3-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/css3/blending/background-blend-mode-crossfade-image-gradient-expected.png b/third_party/blink/web_tests/platform/mac-mac11-arm64/css3/blending/background-blend-mode-crossfade-image-gradient-expected.png index 151bfd46..fd93080 100644 --- a/third_party/blink/web_tests/platform/mac-mac11-arm64/css3/blending/background-blend-mode-crossfade-image-gradient-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac11-arm64/css3/blending/background-blend-mode-crossfade-image-gradient-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/css3/blending/background-blend-mode-gradient-gradient-expected.png b/third_party/blink/web_tests/platform/mac-mac11-arm64/css3/blending/background-blend-mode-gradient-gradient-expected.png index d19041c..67fd147 100644 --- a/third_party/blink/web_tests/platform/mac-mac11-arm64/css3/blending/background-blend-mode-gradient-gradient-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac11-arm64/css3/blending/background-blend-mode-gradient-gradient-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/css3/blending/background-blend-mode-gradient-image-expected.png b/third_party/blink/web_tests/platform/mac-mac11-arm64/css3/blending/background-blend-mode-gradient-image-expected.png index 06794d85..8f9c329 100644 --- a/third_party/blink/web_tests/platform/mac-mac11-arm64/css3/blending/background-blend-mode-gradient-image-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac11-arm64/css3/blending/background-blend-mode-gradient-image-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/css3/blending/background-blend-mode-tiled-gradient-expected.png b/third_party/blink/web_tests/platform/mac-mac11-arm64/css3/blending/background-blend-mode-tiled-gradient-expected.png index 02cce93c..0844fc2 100644 --- a/third_party/blink/web_tests/platform/mac-mac11-arm64/css3/blending/background-blend-mode-tiled-gradient-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac11-arm64/css3/blending/background-blend-mode-tiled-gradient-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/css3/blending/mix-blend-mode-isolated-group-2-expected.png b/third_party/blink/web_tests/platform/mac-mac11-arm64/css3/blending/mix-blend-mode-isolated-group-2-expected.png index c5d1691..b6df961 100644 --- a/third_party/blink/web_tests/platform/mac-mac11-arm64/css3/blending/mix-blend-mode-isolated-group-2-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac11-arm64/css3/blending/mix-blend-mode-isolated-group-2-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac12-arm64/css3/blending/background-blend-mode-crossfade-image-gradient-expected.png b/third_party/blink/web_tests/platform/mac-mac12-arm64/css3/blending/background-blend-mode-crossfade-image-gradient-expected.png index 151bfd46..fd93080 100644 --- a/third_party/blink/web_tests/platform/mac-mac12-arm64/css3/blending/background-blend-mode-crossfade-image-gradient-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac12-arm64/css3/blending/background-blend-mode-crossfade-image-gradient-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac12-arm64/css3/blending/background-blend-mode-gradient-gradient-expected.png b/third_party/blink/web_tests/platform/mac-mac12-arm64/css3/blending/background-blend-mode-gradient-gradient-expected.png index d19041c..67fd147 100644 --- a/third_party/blink/web_tests/platform/mac-mac12-arm64/css3/blending/background-blend-mode-gradient-gradient-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac12-arm64/css3/blending/background-blend-mode-gradient-gradient-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac12-arm64/css3/blending/background-blend-mode-gradient-image-expected.png b/third_party/blink/web_tests/platform/mac-mac12-arm64/css3/blending/background-blend-mode-gradient-image-expected.png index 06794d85..8f9c329 100644 --- a/third_party/blink/web_tests/platform/mac-mac12-arm64/css3/blending/background-blend-mode-gradient-image-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac12-arm64/css3/blending/background-blend-mode-gradient-image-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac12-arm64/css3/blending/background-blend-mode-tiled-gradient-expected.png b/third_party/blink/web_tests/platform/mac-mac12-arm64/css3/blending/background-blend-mode-tiled-gradient-expected.png index 02cce93c..0844fc2 100644 --- a/third_party/blink/web_tests/platform/mac-mac12-arm64/css3/blending/background-blend-mode-tiled-gradient-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac12-arm64/css3/blending/background-blend-mode-tiled-gradient-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac12-arm64/css3/blending/mix-blend-mode-isolated-group-1-expected.png b/third_party/blink/web_tests/platform/mac-mac12-arm64/css3/blending/mix-blend-mode-isolated-group-1-expected.png new file mode 100644 index 0000000..7a2b3f5 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac12-arm64/css3/blending/mix-blend-mode-isolated-group-1-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac12-arm64/css3/blending/mix-blend-mode-isolated-group-2-expected.png b/third_party/blink/web_tests/platform/mac-mac12-arm64/css3/blending/mix-blend-mode-isolated-group-2-expected.png index c5d1691..b6df961 100644 --- a/third_party/blink/web_tests/platform/mac-mac12-arm64/css3/blending/mix-blend-mode-isolated-group-2-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac12-arm64/css3/blending/mix-blend-mode-isolated-group-2-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac12-arm64/css3/blending/mix-blend-mode-isolated-group-3-expected.png b/third_party/blink/web_tests/platform/mac-mac12-arm64/css3/blending/mix-blend-mode-isolated-group-3-expected.png new file mode 100644 index 0000000..065b55c --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac12-arm64/css3/blending/mix-blend-mode-isolated-group-3-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac13-arm64/css3/blending/background-blend-mode-crossfade-image-gradient-expected.png b/third_party/blink/web_tests/platform/mac-mac13-arm64/css3/blending/background-blend-mode-crossfade-image-gradient-expected.png index 151bfd46..fd93080 100644 --- a/third_party/blink/web_tests/platform/mac-mac13-arm64/css3/blending/background-blend-mode-crossfade-image-gradient-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac13-arm64/css3/blending/background-blend-mode-crossfade-image-gradient-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac13-arm64/css3/blending/background-blend-mode-gradient-gradient-expected.png b/third_party/blink/web_tests/platform/mac-mac13-arm64/css3/blending/background-blend-mode-gradient-gradient-expected.png index d19041c..67fd147 100644 --- a/third_party/blink/web_tests/platform/mac-mac13-arm64/css3/blending/background-blend-mode-gradient-gradient-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac13-arm64/css3/blending/background-blend-mode-gradient-gradient-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac13-arm64/css3/blending/background-blend-mode-gradient-image-expected.png b/third_party/blink/web_tests/platform/mac-mac13-arm64/css3/blending/background-blend-mode-gradient-image-expected.png index 06794d85..8f9c329 100644 --- a/third_party/blink/web_tests/platform/mac-mac13-arm64/css3/blending/background-blend-mode-gradient-image-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac13-arm64/css3/blending/background-blend-mode-gradient-image-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac13-arm64/css3/blending/background-blend-mode-tiled-gradient-expected.png b/third_party/blink/web_tests/platform/mac-mac13-arm64/css3/blending/background-blend-mode-tiled-gradient-expected.png index 02cce93c..0844fc2 100644 --- a/third_party/blink/web_tests/platform/mac-mac13-arm64/css3/blending/background-blend-mode-tiled-gradient-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac13-arm64/css3/blending/background-blend-mode-tiled-gradient-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac13-arm64/css3/blending/mix-blend-mode-isolated-group-1-expected.png b/third_party/blink/web_tests/platform/mac-mac13-arm64/css3/blending/mix-blend-mode-isolated-group-1-expected.png index edee629e..7d68e2f 100644 --- a/third_party/blink/web_tests/platform/mac-mac13-arm64/css3/blending/mix-blend-mode-isolated-group-1-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac13-arm64/css3/blending/mix-blend-mode-isolated-group-1-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac13-arm64/css3/blending/mix-blend-mode-isolated-group-2-expected.png b/third_party/blink/web_tests/platform/mac-mac13-arm64/css3/blending/mix-blend-mode-isolated-group-2-expected.png index c5d1691..b6df961 100644 --- a/third_party/blink/web_tests/platform/mac-mac13-arm64/css3/blending/mix-blend-mode-isolated-group-2-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac13-arm64/css3/blending/mix-blend-mode-isolated-group-2-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac13-arm64/css3/blending/mix-blend-mode-isolated-group-3-expected.png b/third_party/blink/web_tests/platform/mac-mac13-arm64/css3/blending/mix-blend-mode-isolated-group-3-expected.png index 773e642..849d6bce 100644 --- a/third_party/blink/web_tests/platform/mac-mac13-arm64/css3/blending/mix-blend-mode-isolated-group-3-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac13-arm64/css3/blending/mix-blend-mode-isolated-group-3-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/css3/blending/background-blend-mode-crossfade-image-gradient-expected.png b/third_party/blink/web_tests/platform/mac/css3/blending/background-blend-mode-crossfade-image-gradient-expected.png index 193217a9..272164f 100644 --- a/third_party/blink/web_tests/platform/mac/css3/blending/background-blend-mode-crossfade-image-gradient-expected.png +++ b/third_party/blink/web_tests/platform/mac/css3/blending/background-blend-mode-crossfade-image-gradient-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/css3/blending/background-blend-mode-gradient-gradient-expected.png b/third_party/blink/web_tests/platform/mac/css3/blending/background-blend-mode-gradient-gradient-expected.png index 3519b88..a16c11b 100644 --- a/third_party/blink/web_tests/platform/mac/css3/blending/background-blend-mode-gradient-gradient-expected.png +++ b/third_party/blink/web_tests/platform/mac/css3/blending/background-blend-mode-gradient-gradient-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/css3/blending/background-blend-mode-gradient-image-expected.png b/third_party/blink/web_tests/platform/mac/css3/blending/background-blend-mode-gradient-image-expected.png index 2d476e4..689061e 100644 --- a/third_party/blink/web_tests/platform/mac/css3/blending/background-blend-mode-gradient-image-expected.png +++ b/third_party/blink/web_tests/platform/mac/css3/blending/background-blend-mode-gradient-image-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/css3/blending/background-blend-mode-tiled-gradient-expected.png b/third_party/blink/web_tests/platform/mac/css3/blending/background-blend-mode-tiled-gradient-expected.png index d3e3d2b..290256ac 100644 --- a/third_party/blink/web_tests/platform/mac/css3/blending/background-blend-mode-tiled-gradient-expected.png +++ b/third_party/blink/web_tests/platform/mac/css3/blending/background-blend-mode-tiled-gradient-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/css3/blending/mix-blend-mode-isolated-group-1-expected.png b/third_party/blink/web_tests/platform/mac/css3/blending/mix-blend-mode-isolated-group-1-expected.png new file mode 100644 index 0000000..26e37aa --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/css3/blending/mix-blend-mode-isolated-group-1-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/css3/blending/mix-blend-mode-isolated-group-2-expected.png b/third_party/blink/web_tests/platform/mac/css3/blending/mix-blend-mode-isolated-group-2-expected.png new file mode 100644 index 0000000..ee2cc4f --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/css3/blending/mix-blend-mode-isolated-group-2-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/css3/blending/mix-blend-mode-isolated-group-3-expected.png b/third_party/blink/web_tests/platform/mac/css3/blending/mix-blend-mode-isolated-group-3-expected.png new file mode 100644 index 0000000..f89025a --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/css3/blending/mix-blend-mode-isolated-group-3-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/popover-disabled/README.md b/third_party/blink/web_tests/virtual/popover-disabled/README.md deleted file mode 100644 index 43d7fc34..0000000 --- a/third_party/blink/web_tests/virtual/popover-disabled/README.md +++ /dev/null
@@ -1,5 +0,0 @@ -# Overview - -This suite runs a small subset of tests with `--disable-features=HTMLPopoverAttribute` -to make sure no Popover API functionality is inadvertently exposed when the feature is -disabled.
diff --git a/third_party/blink/web_tests/virtual/popover-disabled/popover-disabled.html b/third_party/blink/web_tests/virtual/popover-disabled/popover-disabled.html deleted file mode 100644 index 22162035..0000000 --- a/third_party/blink/web_tests/virtual/popover-disabled/popover-disabled.html +++ /dev/null
@@ -1,45 +0,0 @@ -<!DOCTYPE html> -<meta charset="utf-8"> -<script src='../../resources/testharness.js'></script> -<script src="../../resources/testharnessreport.js"></script> - -<div id=elements> - <div popover=auto>This content should be visible, if HTMLPopoverAttribute is disabled</div> - <div popover=async>This content should be visible, if HTMLPopoverAttribute is disabled</div> - <div popover=invalid>This content should be visible, if HTMLPopoverAttribute is disabled</div> - <div popover="">This content should be visible, if HTMLPopoverAttribute is disabled</div> - <div popover id=foo>This content should be visible, if HTMLPopoverAttribute is disabled</div> -</div> - -<script> -window.onload = () => { - if (window.testRunner) - testRunner.dumpAsText(); - - function popoverVisible(popover) { - return !!(popover.offsetWidth || popover.offsetHeight || popover.getClientRects().length); - } - - const elements = document.getElementById('elements').children; - test(() => { - assert_throws_dom("SyntaxError",() => {elements[0].matches(':open')},"The :open pseudo class shouldn't be available"); - },'Basic tests'); - - for(let el of elements) { - test(() => { - assert_true(!!el); - assert_true(popoverVisible(el)); - assert_equals(el.popover,undefined); - assert_not_equals(window.getComputedStyle(el).display,'none'); - },`${el.outerHTML} should be stylable/visible and not display:none`); - } - - function supportsPopover() { - return HTMLElement.prototype.hasOwnProperty("popover"); - } - - test(() => { - assert_false(supportsPopover()); - },`The popover IDL attribute should not be present on Element`); -}; -</script>
diff --git a/third_party/blink/web_tests/virtual/stable/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt b/third_party/blink/web_tests/virtual/stable/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt index 3eb1b8b..ede7d19a 100644 --- a/third_party/blink/web_tests/virtual/stable/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt
@@ -100,6 +100,7 @@ PASS oldChildWindow.onbeforeinstallprompt is newChildWindow.onbeforeinstallprompt PASS oldChildWindow.onbeforematch is newChildWindow.onbeforematch PASS oldChildWindow.onbeforeprint is newChildWindow.onbeforeprint +PASS oldChildWindow.onbeforetoggle is newChildWindow.onbeforetoggle PASS oldChildWindow.onbeforeunload is newChildWindow.onbeforeunload PASS oldChildWindow.onbeforexrselect is newChildWindow.onbeforexrselect PASS oldChildWindow.onblur is newChildWindow.onblur
diff --git a/third_party/blink/web_tests/virtual/stable/fast/dom/Window/property-access-on-cached-window-after-frame-removed-and-gced-expected.txt b/third_party/blink/web_tests/virtual/stable/fast/dom/Window/property-access-on-cached-window-after-frame-removed-and-gced-expected.txt index 8c166ea..685ee11 100644 --- a/third_party/blink/web_tests/virtual/stable/fast/dom/Window/property-access-on-cached-window-after-frame-removed-and-gced-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/fast/dom/Window/property-access-on-cached-window-after-frame-removed-and-gced-expected.txt
@@ -52,6 +52,7 @@ PASS childWindow.onbeforeinstallprompt is null PASS childWindow.onbeforematch is null PASS childWindow.onbeforeprint is null +PASS childWindow.onbeforetoggle is null PASS childWindow.onbeforeunload is null PASS childWindow.onbeforexrselect is null PASS childWindow.onblur is null
diff --git a/third_party/blink/web_tests/virtual/stable/fast/dom/Window/property-access-on-cached-window-after-frame-removed-expected.txt b/third_party/blink/web_tests/virtual/stable/fast/dom/Window/property-access-on-cached-window-after-frame-removed-expected.txt index 29b6f801..37dd0e4 100644 --- a/third_party/blink/web_tests/virtual/stable/fast/dom/Window/property-access-on-cached-window-after-frame-removed-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/fast/dom/Window/property-access-on-cached-window-after-frame-removed-expected.txt
@@ -52,6 +52,7 @@ PASS childWindow.onbeforeinstallprompt is null PASS childWindow.onbeforematch is null PASS childWindow.onbeforeprint is null +PASS childWindow.onbeforetoggle is null PASS childWindow.onbeforeunload is null PASS childWindow.onbeforexrselect is null PASS childWindow.onblur is null
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/element-instance-property-listing-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/element-instance-property-listing-expected.txt index 773487f..c07f07cd 100644 --- a/third_party/blink/web_tests/virtual/stable/webexposed/element-instance-property-listing-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/webexposed/element-instance-property-listing-expected.txt
@@ -125,6 +125,7 @@ property hasChildNodes property hasPointerCapture property hidden + property hidePopover property id property inert property innerHTML @@ -169,6 +170,7 @@ property onbeforeinput property onbeforematch property onbeforepaste + property onbeforetoggle property onbeforexrselect property onblur property oncancel @@ -273,6 +275,7 @@ property parentElement property parentNode property part + property popover property prefix property prepend property previousElementSibling @@ -308,6 +311,7 @@ property setHTML property setPointerCapture property shadowRoot + property showPopover property slot property spellcheck property style @@ -317,6 +321,7 @@ property title property toString property toggleAttribute + property togglePopover property translate property virtualKeyboardPolicy property webkitMatchesSelector @@ -475,6 +480,8 @@ property formTarget property labels property name + property popoverTargetAction + property popoverTargetElement property reportValidity property setCustomValidity property type @@ -717,6 +724,8 @@ property name property pattern property placeholder + property popoverTargetAction + property popoverTargetElement property readOnly property reportValidity property required @@ -1344,6 +1353,7 @@ property onbeforeinput property onbeforematch property onbeforepaste + property onbeforetoggle property onbeforexrselect property onblur property oncancel
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt index 80515e8..181658a 100644 --- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -1454,6 +1454,7 @@ getter onbeforeinput getter onbeforematch getter onbeforepaste + getter onbeforetoggle getter onbeforexrselect getter onblur getter oncancel @@ -1661,6 +1662,7 @@ setter onbeforeinput setter onbeforematch setter onbeforepaste + setter onbeforetoggle setter onbeforexrselect setter onblur setter oncancel @@ -2964,6 +2966,8 @@ getter formTarget getter labels getter name + getter popoverTargetAction + getter popoverTargetElement getter type getter validationMessage getter validity @@ -2980,6 +2984,8 @@ setter formNoValidate setter formTarget setter name + setter popoverTargetAction + setter popoverTargetElement setter type setter value interface HTMLCanvasElement : HTMLElement @@ -3073,6 +3079,7 @@ getter onauxclick getter onbeforeinput getter onbeforematch + getter onbeforetoggle getter onbeforexrselect getter onblur getter oncancel @@ -3167,6 +3174,7 @@ getter onwebkittransitionend getter onwheel getter outerText + getter popover getter spellcheck getter style getter tabIndex @@ -3178,6 +3186,9 @@ method click method constructor method focus + method hidePopover + method showPopover + method togglePopover setter accessKey setter autocapitalize setter autofocus @@ -3198,6 +3209,7 @@ setter onauxclick setter onbeforeinput setter onbeforematch + setter onbeforetoggle setter onbeforexrselect setter onblur setter oncancel @@ -3292,6 +3304,7 @@ setter onwebkittransitionend setter onwheel setter outerText + setter popover setter spellcheck setter style setter tabIndex @@ -3601,6 +3614,8 @@ getter name getter pattern getter placeholder + getter popoverTargetAction + getter popoverTargetElement getter readOnly getter required getter selectionDirection @@ -3656,6 +3671,8 @@ setter name setter pattern setter placeholder + setter popoverTargetAction + setter popoverTargetElement setter readOnly setter required setter selectionDirection @@ -4924,6 +4941,7 @@ getter onauxclick getter onbeforeinput getter onbeforematch + getter onbeforetoggle getter onbeforexrselect getter onblur getter oncancel @@ -5031,6 +5049,7 @@ setter onauxclick setter onbeforeinput setter onbeforematch + setter onbeforetoggle setter onbeforexrselect setter onblur setter oncancel @@ -6978,6 +6997,7 @@ getter onauxclick getter onbeforeinput getter onbeforematch + getter onbeforetoggle getter onbeforexrselect getter onblur getter oncancel @@ -7087,6 +7107,7 @@ setter onauxclick setter onbeforeinput setter onbeforematch + setter onbeforetoggle setter onbeforexrselect setter onblur setter oncancel @@ -8481,6 +8502,11 @@ method constructor method end method start +interface ToggleEvent : Event + attribute @@toStringTag + getter newState + getter oldState + method constructor interface Touch attribute @@toStringTag getter clientX @@ -11073,6 +11099,7 @@ getter onbeforeinstallprompt getter onbeforematch getter onbeforeprint + getter onbeforetoggle getter onbeforeunload getter onbeforexrselect getter onblur @@ -11286,6 +11313,7 @@ setter onbeforeinstallprompt setter onbeforematch setter onbeforeprint + setter onbeforetoggle setter onbeforeunload setter onbeforexrselect setter onblur
diff --git a/third_party/google_benchmark/BUILD.gn b/third_party/google_benchmark/BUILD.gn index c2ff928..2f26cfee 100644 --- a/third_party/google_benchmark/BUILD.gn +++ b/third_party/google_benchmark/BUILD.gn
@@ -10,12 +10,6 @@ } } -# TODO(crbug.com/1344570): Remove once third_party/google_benchmark no longer -# uses std::wstring_convert. -config("benchmark_suppress_warnings") { - cflags = [ "-Wno-deprecated-declarations" ] -} - component("google_benchmark") { testonly = true @@ -71,7 +65,6 @@ configs -= [ "//build/config/compiler:chromium_code" ] configs += [ "//build/config/compiler:no_chromium_code", - ":benchmark_suppress_warnings", ] if (is_win) {
diff --git a/third_party/libxml/chromium/roll.py b/third_party/libxml/chromium/roll.py index 9fc5a97..942a8994 100755 --- a/third_party/libxml/chromium/roll.py +++ b/third_party/libxml/chromium/roll.py
@@ -169,6 +169,7 @@ 'src/depcomp', 'src/doc', 'src/example', + 'src/fuzz', 'src/genChRanges.py', 'src/global.data', 'src/include/libxml/Makefile.in', @@ -218,7 +219,9 @@ 'linux/doc', 'linux/example', 'linux/fuzz', + 'linux/include/private', 'linux/python', + 'linux/xstc', ]
diff --git a/third_party/libxml/linux/include/private/Makefile b/third_party/libxml/linux/include/private/Makefile deleted file mode 100644 index 3fab76d4..0000000 --- a/third_party/libxml/linux/include/private/Makefile +++ /dev/null
@@ -1,545 +0,0 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. -# include/private/Makefile. Generated from Makefile.in by configure. - -# Copyright (C) 1994-2021 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - - -VPATH = /usr/local/google/home/jarhar/chromium/src/third_party/libxml/src/include/private -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/libxml2 -pkgincludedir = $(includedir)/libxml2 -pkglibdir = $(libdir)/libxml2 -pkglibexecdir = $(libexecdir)/libxml2 -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = x86_64-pc-linux-gnu -host_triplet = x86_64-pc-linux-gnu -subdir = include/private -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ac_try_compile2.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_$(V)) -am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_$(V)) -am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_$(V)) -am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) -am__v_at_0 = @ -am__v_at_1 = -SOURCES = -DIST_SOURCES = -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -am__DIST_COMMON = $(srcdir)/Makefile.in -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = ${SHELL} '/usr/local/google/home/jarhar/chromium/src/third_party/libxml/src/missing' aclocal-1.16 -AMTAR = $${TAR-tar} -AM_CFLAGS = -pedantic -Wall -Wextra -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline -Wno-long-long -Wno-format-extra-args -AM_DEFAULT_VERBOSITY = 0 -AM_LDFLAGS = -AR = ar -AUTOCONF = ${SHELL} '/usr/local/google/home/jarhar/chromium/src/third_party/libxml/src/missing' autoconf -AUTOHEADER = ${SHELL} '/usr/local/google/home/jarhar/chromium/src/third_party/libxml/src/missing' autoheader -AUTOMAKE = ${SHELL} '/usr/local/google/home/jarhar/chromium/src/third_party/libxml/src/missing' automake-1.16 -AWK = gawk -BASE_THREAD_LIBS = -CC = gcc -CCDEPMODE = depmode=gcc3 -CFLAGS = -g -O2 -CPPFLAGS = -CSCOPE = cscope -CTAGS = ctags -CYGPATH_W = echo -DEFS = -DHAVE_CONFIG_H -DEPDIR = .deps -DLLTOOL = false -DSYMUTIL = -DUMPBIN = -ECHO_C = -ECHO_N = -n -ECHO_T = -EGREP = /usr/bin/grep -E -ETAGS = etags -EXEEXT = -FGREP = /usr/bin/grep -F -FILECMD = file -GREP = /usr/bin/grep -ICU_CFLAGS = -ICU_DEFS = -ICU_LIBS = -licui18n -licuuc -licudata -INSTALL = /usr/bin/install -c -INSTALL_DATA = ${INSTALL} -m 644 -INSTALL_PROGRAM = ${INSTALL} -INSTALL_SCRIPT = ${INSTALL} -INSTALL_STRIP_PROGRAM = $(install_sh) -c -s -LD = /usr/bin/ld -m elf_x86_64 -LDFLAGS = -LIBM = -lm -LIBOBJS = -LIBS = -LIBTOOL = $(SHELL) $(top_builddir)/libtool -LIBXML_MAJOR_VERSION = 2 -LIBXML_MICRO_VERSION = 0 -LIBXML_MINOR_VERSION = 11 -LIBXML_VERSION = 2.11.0 -LIBXML_VERSION_EXTRA = -LIBXML_VERSION_INFO = 13:0:11 -LIBXML_VERSION_NUMBER = 21100 -LIPO = -LN_S = ln -s -LTLIBOBJS = -LT_SYS_LIBRARY_PATH = -LZMA_CFLAGS = -LZMA_LIBS = -MAINT = -MAKEINFO = ${SHELL} '/usr/local/google/home/jarhar/chromium/src/third_party/libxml/src/missing' makeinfo -MANIFEST_TOOL = : -MKDIR_P = /usr/bin/mkdir -p -MODULE_EXTENSION = -MODULE_PLATFORM_LIBS = -NM = /usr/bin/nm -B -NMEDIT = -OBJDUMP = objdump -OBJEXT = o -OTOOL = -OTOOL64 = -PACKAGE = libxml2 -PACKAGE_BUGREPORT = -PACKAGE_NAME = libxml2 -PACKAGE_STRING = libxml2 2.11.0 -PACKAGE_TARNAME = libxml2 -PACKAGE_URL = -PACKAGE_VERSION = 2.11.0 -PATH_SEPARATOR = : -PERL = /usr/bin/perl -PKG_CONFIG = /usr/bin/pkg-config -PKG_CONFIG_LIBDIR = -PKG_CONFIG_PATH = -PYTHON = /usr/bin/python -PYTHON_CFLAGS = -I/usr/include/python3.10 -I/usr/include/x86_64-linux-gnu/python3.10 -PYTHON_EXEC_PREFIX = ${exec_prefix} -PYTHON_LDFLAGS = -PYTHON_LIBS = -PYTHON_PLATFORM = linux -PYTHON_PREFIX = ${prefix} -PYTHON_VERSION = 3.10 -RANLIB = ranlib -RDL_CFLAGS = -RDL_LIBS = -RELDATE = Tue Mar 21 2023 -SED = /usr/bin/sed -SET_MAKE = -SHELL = /bin/sh -STRIP = strip -TAR = /usr/bin/tar -THREAD_CFLAGS = -D_REENTRANT -THREAD_LIBS = -VERSION = 2.11.0 -VERSION_SCRIPT_FLAGS = -Wl,--version-script= -WGET = /usr/bin/wget -WITH_C14N = 0 -WITH_CATALOG = 0 -WITH_DEBUG = 0 -WITH_FTP = 0 -WITH_HTML = 1 -WITH_HTTP = 0 -WITH_ICONV = 0 -WITH_ICU = 1 -WITH_ISO8859X = 0 -WITH_LEGACY = 0 -WITH_LZMA = 0 -WITH_MEM_DEBUG = 0 -WITH_MODULES = 0 -WITH_OUTPUT = 1 -WITH_PATTERN = 0 -WITH_PUSH = 1 -WITH_READER = 1 -WITH_REGEXPS = 0 -WITH_SAX1 = 1 -WITH_SCHEMAS = 0 -WITH_SCHEMATRON = 0 -WITH_THREADS = 1 -WITH_THREAD_ALLOC = 0 -WITH_TREE = 1 -WITH_TRIO = 0 -WITH_VALID = 0 -WITH_WRITER = 1 -WITH_XINCLUDE = 0 -WITH_XPATH = 1 -WITH_XPTR = 0 -WITH_XPTR_LOCS = 0 -WITH_ZLIB = 0 -XML_CFLAGS = -XML_INCLUDEDIR = -I${includedir}/libxml2 -XML_LIBDIR = -L${libdir} -XML_LIBS = -lxml2 -XML_LIBTOOLLIBS = libxml2.la -XML_PRIVATE_CFLAGS = -D_REENTRANT -XML_PRIVATE_LIBS = -licui18n -licuuc -licudata -lm -XSLTPROC = /usr/bin/xsltproc -Z_CFLAGS = -Z_LIBS = -abs_builddir = /usr/local/google/home/jarhar/chromium/src/third_party/libxml/linux/include/private -abs_srcdir = /usr/local/google/home/jarhar/chromium/src/third_party/libxml/src/include/private -abs_top_builddir = /usr/local/google/home/jarhar/chromium/src/third_party/libxml/linux -abs_top_srcdir = /usr/local/google/home/jarhar/chromium/src/third_party/libxml/src -ac_ct_AR = ar -ac_ct_CC = gcc -ac_ct_DUMPBIN = -am__include = include -am__leading_dot = . -am__quote = -am__tar = $${TAR-tar} chof - "$$tardir" -am__untar = $${TAR-tar} xf - -bindir = ${exec_prefix}/bin -build = x86_64-pc-linux-gnu -build_alias = -build_cpu = x86_64 -build_os = linux-gnu -build_vendor = pc -builddir = . -datadir = ${datarootdir} -datarootdir = ${prefix}/share -docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} -dvidir = ${docdir} -exec_prefix = ${prefix} -host = x86_64-pc-linux-gnu -host_alias = -host_cpu = x86_64 -host_os = linux-gnu -host_vendor = pc -htmldir = ${docdir} -includedir = ${prefix}/include -infodir = ${datarootdir}/info -install_sh = ${SHELL} /usr/local/google/home/jarhar/chromium/src/third_party/libxml/src/install-sh -libdir = ${exec_prefix}/lib -libexecdir = ${exec_prefix}/libexec -localedir = ${datarootdir}/locale -localstatedir = ${prefix}/var -mandir = ${datarootdir}/man -mkdir_p = $(MKDIR_P) -oldincludedir = /usr/include -pdfdir = ${docdir} -pkgpyexecdir = ${pyexecdir}/libxml2 -pkgpythondir = ${pythondir}/libxml2 -prefix = /usr/local -program_transform_name = s,x,x, -psdir = ${docdir} -pyexecdir = ${PYTHON_EXEC_PREFIX}/lib/python3.10/site-packages -pythondir = ${PYTHON_PREFIX}/lib/python3.10/site-packages -runstatedir = ${localstatedir}/run -sbindir = ${exec_prefix}/sbin -sharedstatedir = ${prefix}/com -srcdir = /usr/local/google/home/jarhar/chromium/src/third_party/libxml/src/include/private -sysconfdir = ${prefix}/etc -target_alias = -top_build_prefix = ../../ -top_builddir = ../.. -top_srcdir = /usr/local/google/home/jarhar/chromium/src/third_party/libxml/src -EXTRA_DIST = \ - buf.h \ - dict.h \ - enc.h \ - entities.h \ - error.h \ - globals.h \ - html.h \ - io.h \ - memory.h \ - parser.h \ - regexp.h \ - save.h \ - string.h \ - threads.h \ - tree.h \ - xinclude.h \ - xpath.h \ - xzlib.h - -all: all-am - -.SUFFIXES: -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/private/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign include/private/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs -tags TAGS: - -ctags CTAGS: - -cscope cscopelist: - -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libtool mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-generic - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: all all-am check check-am clean clean-generic clean-libtool \ - cscopelist-am ctags-am distclean distclean-generic \ - distclean-libtool distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags-am uninstall uninstall-am - -.PRECIOUS: Makefile - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT:
diff --git a/third_party/libxml/linux/xstc/Makefile b/third_party/libxml/linux/xstc/Makefile deleted file mode 100644 index 8a3f20a..0000000 --- a/third_party/libxml/linux/xstc/Makefile +++ /dev/null
@@ -1,657 +0,0 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. -# xstc/Makefile. Generated from Makefile.in by configure. - -# Copyright (C) 1994-2021 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - - -VPATH = /usr/local/google/home/jarhar/chromium/src/third_party/libxml/src/xstc -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/libxml2 -pkgincludedir = $(includedir)/libxml2 -pkglibdir = $(libdir)/libxml2 -pkglibexecdir = $(libexecdir)/libxml2 -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = x86_64-pc-linux-gnu -host_triplet = x86_64-pc-linux-gnu -subdir = xstc -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ac_try_compile2.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_$(V)) -am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_$(V)) -am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_$(V)) -am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) -am__v_at_0 = @ -am__v_at_1 = -SOURCES = -DIST_SOURCES = -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -am__DIST_COMMON = $(srcdir)/Makefile.in -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = ${SHELL} '/usr/local/google/home/jarhar/chromium/src/third_party/libxml/src/missing' aclocal-1.16 -AMTAR = $${TAR-tar} -AM_CFLAGS = -pedantic -Wall -Wextra -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline -Wno-long-long -Wno-format-extra-args -AM_DEFAULT_VERBOSITY = 0 -AM_LDFLAGS = -AR = ar -AUTOCONF = ${SHELL} '/usr/local/google/home/jarhar/chromium/src/third_party/libxml/src/missing' autoconf -AUTOHEADER = ${SHELL} '/usr/local/google/home/jarhar/chromium/src/third_party/libxml/src/missing' autoheader -AUTOMAKE = ${SHELL} '/usr/local/google/home/jarhar/chromium/src/third_party/libxml/src/missing' automake-1.16 -AWK = gawk -BASE_THREAD_LIBS = -CC = gcc -CCDEPMODE = depmode=gcc3 -CFLAGS = -g -O2 -CPPFLAGS = -CSCOPE = cscope -CTAGS = ctags -CYGPATH_W = echo -DEFS = -DHAVE_CONFIG_H -DEPDIR = .deps -DLLTOOL = false -DSYMUTIL = -DUMPBIN = -ECHO_C = -ECHO_N = -n -ECHO_T = -EGREP = /usr/bin/grep -E -ETAGS = etags -EXEEXT = -FGREP = /usr/bin/grep -F -FILECMD = file -GREP = /usr/bin/grep -ICU_CFLAGS = -ICU_DEFS = -ICU_LIBS = -licui18n -licuuc -licudata -INSTALL = /usr/bin/install -c -INSTALL_DATA = ${INSTALL} -m 644 -INSTALL_PROGRAM = ${INSTALL} -INSTALL_SCRIPT = ${INSTALL} -INSTALL_STRIP_PROGRAM = $(install_sh) -c -s -LD = /usr/bin/ld -m elf_x86_64 -LDFLAGS = -LIBM = -lm -LIBOBJS = -LIBS = -LIBTOOL = $(SHELL) $(top_builddir)/libtool -LIBXML_MAJOR_VERSION = 2 -LIBXML_MICRO_VERSION = 0 -LIBXML_MINOR_VERSION = 11 -LIBXML_VERSION = 2.11.0 -LIBXML_VERSION_EXTRA = -LIBXML_VERSION_INFO = 13:0:11 -LIBXML_VERSION_NUMBER = 21100 -LIPO = -LN_S = ln -s -LTLIBOBJS = -LT_SYS_LIBRARY_PATH = -LZMA_CFLAGS = -LZMA_LIBS = -MAINT = -MAKEINFO = ${SHELL} '/usr/local/google/home/jarhar/chromium/src/third_party/libxml/src/missing' makeinfo -MANIFEST_TOOL = : -MKDIR_P = /usr/bin/mkdir -p -MODULE_EXTENSION = -MODULE_PLATFORM_LIBS = -NM = /usr/bin/nm -B -NMEDIT = -OBJDUMP = objdump -OBJEXT = o -OTOOL = -OTOOL64 = -PACKAGE = libxml2 -PACKAGE_BUGREPORT = -PACKAGE_NAME = libxml2 -PACKAGE_STRING = libxml2 2.11.0 -PACKAGE_TARNAME = libxml2 -PACKAGE_URL = -PACKAGE_VERSION = 2.11.0 -PATH_SEPARATOR = : -PERL = /usr/bin/perl -PKG_CONFIG = /usr/bin/pkg-config -PKG_CONFIG_LIBDIR = -PKG_CONFIG_PATH = -PYTHON = /usr/bin/python -PYTHON_CFLAGS = -I/usr/include/python3.10 -I/usr/include/x86_64-linux-gnu/python3.10 -PYTHON_EXEC_PREFIX = ${exec_prefix} -PYTHON_LDFLAGS = -PYTHON_LIBS = -PYTHON_PLATFORM = linux -PYTHON_PREFIX = ${prefix} -PYTHON_VERSION = 3.10 -RANLIB = ranlib -RDL_CFLAGS = -RDL_LIBS = -RELDATE = Tue Mar 21 2023 -SED = /usr/bin/sed -SET_MAKE = -SHELL = /bin/sh -STRIP = strip -TAR = /usr/bin/tar -THREAD_CFLAGS = -D_REENTRANT -THREAD_LIBS = -VERSION = 2.11.0 -VERSION_SCRIPT_FLAGS = -Wl,--version-script= -WGET = /usr/bin/wget -WITH_C14N = 0 -WITH_CATALOG = 0 -WITH_DEBUG = 0 -WITH_FTP = 0 -WITH_HTML = 1 -WITH_HTTP = 0 -WITH_ICONV = 0 -WITH_ICU = 1 -WITH_ISO8859X = 0 -WITH_LEGACY = 0 -WITH_LZMA = 0 -WITH_MEM_DEBUG = 0 -WITH_MODULES = 0 -WITH_OUTPUT = 1 -WITH_PATTERN = 0 -WITH_PUSH = 1 -WITH_READER = 1 -WITH_REGEXPS = 0 -WITH_SAX1 = 1 -WITH_SCHEMAS = 0 -WITH_SCHEMATRON = 0 -WITH_THREADS = 1 -WITH_THREAD_ALLOC = 0 -WITH_TREE = 1 -WITH_TRIO = 0 -WITH_VALID = 0 -WITH_WRITER = 1 -WITH_XINCLUDE = 0 -WITH_XPATH = 1 -WITH_XPTR = 0 -WITH_XPTR_LOCS = 0 -WITH_ZLIB = 0 -XML_CFLAGS = -XML_INCLUDEDIR = -I${includedir}/libxml2 -XML_LIBDIR = -L${libdir} -XML_LIBS = -lxml2 -XML_LIBTOOLLIBS = libxml2.la -XML_PRIVATE_CFLAGS = -D_REENTRANT -XML_PRIVATE_LIBS = -licui18n -licuuc -licudata -lm -XSLTPROC = /usr/bin/xsltproc -Z_CFLAGS = -Z_LIBS = -abs_builddir = /usr/local/google/home/jarhar/chromium/src/third_party/libxml/linux/xstc -abs_srcdir = /usr/local/google/home/jarhar/chromium/src/third_party/libxml/src/xstc -abs_top_builddir = /usr/local/google/home/jarhar/chromium/src/third_party/libxml/linux -abs_top_srcdir = /usr/local/google/home/jarhar/chromium/src/third_party/libxml/src -ac_ct_AR = ar -ac_ct_CC = gcc -ac_ct_DUMPBIN = -am__include = include -am__leading_dot = . -am__quote = -am__tar = $${TAR-tar} chof - "$$tardir" -am__untar = $${TAR-tar} xf - -bindir = ${exec_prefix}/bin -build = x86_64-pc-linux-gnu -build_alias = -build_cpu = x86_64 -build_os = linux-gnu -build_vendor = pc -builddir = . -datadir = ${datarootdir} -datarootdir = ${prefix}/share -docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} -dvidir = ${docdir} -exec_prefix = ${prefix} -host = x86_64-pc-linux-gnu -host_alias = -host_cpu = x86_64 -host_os = linux-gnu -host_vendor = pc -htmldir = ${docdir} -includedir = ${prefix}/include -infodir = ${datarootdir}/info -install_sh = ${SHELL} /usr/local/google/home/jarhar/chromium/src/third_party/libxml/src/install-sh -libdir = ${exec_prefix}/lib -libexecdir = ${exec_prefix}/libexec -localedir = ${datarootdir}/locale -localstatedir = ${prefix}/var -mandir = ${datarootdir}/man -mkdir_p = $(MKDIR_P) -oldincludedir = /usr/include -pdfdir = ${docdir} -pkgpyexecdir = ${pyexecdir}/libxml2 -pkgpythondir = ${pythondir}/libxml2 -prefix = /usr/local -program_transform_name = s,x,x, -psdir = ${docdir} -pyexecdir = ${PYTHON_EXEC_PREFIX}/lib/python3.10/site-packages -pythondir = ${PYTHON_PREFIX}/lib/python3.10/site-packages -runstatedir = ${localstatedir}/run -sbindir = ${exec_prefix}/sbin -sharedstatedir = ${prefix}/com -srcdir = /usr/local/google/home/jarhar/chromium/src/third_party/libxml/src/xstc -sysconfdir = ${prefix}/etc -target_alias = -top_build_prefix = ../ -top_builddir = .. -top_srcdir = /usr/local/google/home/jarhar/chromium/src/third_party/libxml/src - -# -# Definition for the tests from W3C -# -PYSCRIPTS = nist-test.py ms-test.py sun-test.py -TESTDIR = Tests -TESTDIRS = $(TESTDIR)/msxsdtest $(TESTDIR)/suntest $(TESTDIR)/Datatypes -TARBALL = xsts-2002-01-16.tar.gz -TARBALL_2 = xsts-2004-01-14.tar.gz -TSNAME = xmlschema2002-01-16 -TSNAME_2 = xmlschema2004-01-14 -TARBALLURL = http://www.w3.org/XML/2004/xml-schema-test-suite/$(TSNAME)/$(TARBALL) -TARBALLURL_2 = http://www.w3.org/XML/2004/xml-schema-test-suite/$(TSNAME_2)/$(TARBALL_2) -MSTESTDEF = MSXMLSchema1-0-20020116.testSet -SUNTESTDEF = SunXMLSchema1-0-20020116.testSet -NISTTESTDEF = NISTXMLSchema1-0-20020116.testSet -NISTTESTDEF_2 = NISTXMLSchemaDatatypes.testSet - -# -# The local data and scripts -# -EXTRA_DIST = xstc.py xstc-to-python.xsl -CLEANFILES = $(PYSCRIPTS) test.log -all: all-am - -.SUFFIXES: -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xstc/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign xstc/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs -tags TAGS: - -ctags CTAGS: - -cscope cscopelist: - -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libtool mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-generic - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: all all-am check check-am clean clean-generic clean-libtool \ - cscopelist-am ctags-am distclean distclean-generic \ - distclean-libtool distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags-am uninstall uninstall-am - -.PRECIOUS: Makefile - -# -# Nothing is done by make, only make tests and -# only if Python and Schemas are enabled. -# -all: - -# -# Rule to load the test description and extract the information -# -$(TESTDIRS) Tests/Metadata/$(NISTTESTDEF_2) Tests/Metadata/$(MSTTESTDEF) Tests/Metadata/$(SUNTESTDEF): - -@(if [ ! -d Tests ] ; then \ - mkdir Tests ; \ - fi) - -@(if [ ! -f $(TARBALL_2) ] ; then \ - if [ -f $(srcdir)/$(TARBALL_2) ] ; then \ - $(LN_S) $(srcdir)/$(TARBALL_2) $(TARBALL_2) ; else \ - echo "Missing the test suite description (2004-01-14), trying to fetch it" ;\ - if [ -x "$(WGET)" ] ; then \ - $(WGET) $(TARBALLURL_2) ; \ - else echo "Dont' know how to fetch $(TARBALLURL_2)" ; fi ; fi ; fi) - -@(if [ -f $(TARBALL_2) ] ; then \ - echo -n "extracting test data (NIST)..." ; \ - $(TAR) -xzf $(TARBALL_2) --wildcards '*/Datatypes' '*/Metadata/$(NISTTESTDEF_2)' ; \ - echo "done" ; \ - fi) - -@(if [ ! -f $(TARBALL) ] ; then \ - if [ -f $(srcdir)/$(TARBALL) ] ; then \ - $(LN_S) $(srcdir)/$(TARBALL) $(TARBALL) ; else \ - echo "Missing the test suite description (2002-01-16), trying to fetch it" ;\ - if [ -x "$(WGET)" ] ; then \ - $(WGET) $(TARBALLURL) ; \ - else echo "Dont' know how to fetch $(TARBALLURL)" ; fi ; fi ; fi) - -@(if [ -f $(TARBALL) ] ; then \ - echo -n "extracting test data (Sun, Microsoft)..." ; \ - $(TAR) -C Tests -xzf $(TARBALL) --wildcards '*/suntest' '*/msxsdtest' '*/$(MSTESTDEF)' '*/$(SUNTESTDEF)' ; \ - if [ -d Tests/suntest ] ; then rm -r Tests/suntest ; fi ; \ - if [ -d Tests/msxsdtest ] ; then rm -r Tests/msxsdtest ; fi ; \ - mv Tests/xmlschema2002-01-16/* Tests ; \ - mv Tests/*.testSet Tests/Metadata ; \ - rm -r Tests/xmlschema2002-01-16 ; \ - echo "done" ; \ - fi) - -# -# The python tests are generated via XSLT -# -nist-test.py: Tests/Metadata/$(NISTTESTDEF_2) xstc-to-python.xsl - -@(if [ -x $(XSLTPROC) ] ; then \ - echo "Rebuilding script (NIST)" $@ ; \ - $(XSLTPROC) --nonet --stringparam vendor NIST-2 \ - $(srcdir)/xstc-to-python.xsl \ - $(srcdir)/Tests/Metadata/$(NISTTESTDEF_2) > $@ ; \ - chmod +x $@ ; fi ) - -ms-test.py: Tests/Metadata/$(MSTTESTDEF) xstc-to-python.xsl - -@(if [ -x $(XSLTPROC) ] ; then \ - echo "Rebuilding script (Microsoft)" $@ ; \ - $(XSLTPROC) --nonet --stringparam vendor MS \ - $(srcdir)/xstc-to-python.xsl \ - $(srcdir)/Tests/Metadata/$(MSTESTDEF) > $@ ; \ - chmod +x $@ ; fi ) - -sun-test.py: Tests/Metadata/$(SUNTESTDEF) xstc-to-python.xsl - -@(if [ -x $(XSLTPROC) ] ; then \ - echo "Rebuilding script (Sun)" $@ ; \ - $(XSLTPROC) --nonet --stringparam vendor SUN \ - $(srcdir)/xstc-to-python.xsl \ - $(srcdir)/Tests/Metadata/$(SUNTESTDEF) > $@ ; \ - chmod +x $@ ; fi ) - -# -# The actual test run if present. PYTHONPATH is updated to make sure -# we run the version from the loacl build and not preinstalled bindings -# -pytests: $(PYSCRIPTS) $(TESTDIRS) - -@(if [ -x nist-test.py -a -d $(TESTDIR)/Datatypes ] ; then \ - echo "## Running XML Schema tests (NIST)"; \ - PYTHONPATH="../python:../python/.libs:..:../.libs:$$PYTHONPATH" ;\ - export PYTHONPATH; \ - LD_LIBRARY_PATH="$(top_builddir)/.libs:$$LD_LIBRARY_PATH" ; \ - export LD_LIBRARY_PATH; \ - $(CHECKER) $(PYTHON) nist-test.py -s -b $(srcdir) ; fi) - -@(if [ -x sun-test.py -a -d $(TESTDIR)/suntest ] ; then \ - echo "## Running Schema tests (Sun)"; \ - PYTHONPATH="../python:../python/.libs:..:../.libs:$$PYTHONPATH" ;\ - export PYTHONPATH; \ - LD_LIBRARY_PATH="$(top_builddir)/.libs:$$LD_LIBRARY_PATH" ; \ - export LD_LIBRARY_PATH; \ - $(CHECKER) $(PYTHON) sun-test.py -s -b $(srcdir) ; fi) - -@(if [ -x ms-test.py -a -d $(TESTDIR)/msxsdtest ] ; then \ - echo "## Running Schema tests (Microsoft)"; \ - PYTHONPATH="../python:../python/.libs:..:../.libs:$$PYTHONPATH" ;\ - export PYTHONPATH; \ - LD_LIBRARY_PATH="$(top_builddir)/.libs:$$LD_LIBRARY_PATH" ; \ - export LD_LIBRARY_PATH; \ - $(CHECKER) $(PYTHON) ms-test.py -s -b $(srcdir) ; fi) - -tests: - -@(if [ -x $(PYTHON) ] ; then \ - $(MAKE) pytests ; fi); - -# -# Heavy, works well only on RHEL3 -# -valgrind: - -@(if [ -x $(PYTHON) ] ; then \ - echo '## Running the regression tests under Valgrind' ; \ - $(MAKE) CHECKER='valgrind -q' pytests ; fi); - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT:
diff --git a/third_party/libxml/src/fuzz/Makefile.am b/third_party/libxml/src/fuzz/Makefile.am deleted file mode 100644 index 8e24b59..0000000 --- a/third_party/libxml/src/fuzz/Makefile.am +++ /dev/null
@@ -1,188 +0,0 @@ -AUTOMAKE_OPTIONS = -Wno-syntax -EXTRA_PROGRAMS = genSeed html regexp schema uri valid xinclude xml xpath -check_PROGRAMS = testFuzzer -EXTRA_DIST = html.dict regexp.dict schema.dict xml.dict xpath.dict \ - static_seed/uri static_seed/regexp fuzz.h -CLEANFILES = $(EXTRA_PROGRAMS) -AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include -DEPENDENCIES = $(top_builddir)/libxml2.la -LDADD = $(top_builddir)/libxml2.la - -XML_MAX_LEN = 80000 -# Single quotes to avoid wildcard expansion by the shell -XML_SEED_CORPUS_SRC = \ - '$(top_srcdir)/test/*' \ - '$(top_srcdir)/test/errors/*.xml' \ - '$(top_srcdir)/test/errors10/*.xml' \ - '$(top_srcdir)/test/namespaces/*' \ - '$(top_srcdir)/test/recurse/*.xml' \ - '$(top_srcdir)/test/SVG/*.xml' \ - '$(top_srcdir)/test/valid/*.xml' \ - '$(top_srcdir)/test/VC/*' \ - '$(top_srcdir)/test/VCM/*' \ - '$(top_srcdir)/test/xmlid/*' - -testFuzzer_SOURCES = testFuzzer.c fuzz.c - -.PHONY: corpus clean-corpus - -corpus: seed/html.stamp seed/regexp.stamp seed/schema.stamp seed/uri.stamp \ - seed/valid.stamp seed/xinclude.stamp seed/xml.stamp seed/xpath.stamp - -check-local: corpus - ./testFuzzer$(EXEEXT) - -clean-corpus: - rm -rf seed - -clean-local: clean-corpus - -# Seed corpus - -genSeed_SOURCES = genSeed.c fuzz.c - -# XML fuzzer - -seed/xml.stamp: genSeed$(EXEEXT) - @mkdir -p seed/xml - ./genSeed$(EXEEXT) xml $(XML_SEED_CORPUS_SRC) - @touch seed/xml.stamp - -xml_SOURCES = xml.c fuzz.c -xml_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer - -fuzz-xml: xml$(EXEEXT) seed/xml.stamp - @mkdir -p corpus/xml - ./xml$(EXEEXT) \ - -dict=xml.dict \ - -max_len=$(XML_MAX_LEN) \ - -timeout=20 \ - corpus/xml seed/xml - -# DTD validation fuzzer - -seed/valid.stamp: genSeed$(EXEEXT) - @mkdir -p seed/valid - ./genSeed$(EXEEXT) valid $(XML_SEED_CORPUS_SRC) - @touch seed/valid.stamp - -valid_SOURCES = valid.c fuzz.c -valid_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer - -fuzz-valid: valid$(EXEEXT) seed/valid.stamp - @mkdir -p corpus/valid - ./valid$(EXEEXT) \ - -dict=xml.dict \ - -max_len=$(XML_MAX_LEN) \ - -timeout=20 \ - corpus/valid seed/valid - -# XInclude fuzzer - -seed/xinclude.stamp: genSeed$(EXEEXT) - @mkdir -p seed/xinclude - ./genSeed$(EXEEXT) xinclude \ - '$(top_srcdir)/test/XInclude/docs/*' \ - '$(top_srcdir)/test/XInclude/without-reader/*' - @touch seed/xinclude.stamp - -xinclude_SOURCES = xinclude.c fuzz.c -xinclude_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer - -fuzz-xinclude: xinclude$(EXEEXT) seed/xinclude.stamp - @mkdir -p corpus/xinclude - ./xinclude$(EXEEXT) \ - -dict=xml.dict \ - -max_len=$(XML_MAX_LEN) \ - -timeout=20 \ - corpus/xinclude seed/xinclude - -# HTML fuzzer - -seed/html.stamp: genSeed$(EXEEXT) - @mkdir -p seed/html - ./genSeed$(EXEEXT) html '$(top_srcdir)/test/HTML/*' - @touch seed/html.stamp - -html_SOURCES = html.c fuzz.c -html_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer - -fuzz-html: html$(EXEEXT) seed/html.stamp - @mkdir -p corpus/html - ./html$(EXEEXT) \ - -dict=html.dict \ - -max_len=1000000 \ - -timeout=10 \ - corpus/html seed/html - -# Regexp fuzzer - -seed/regexp.stamp: - @mkdir -p seed/regexp - cp -r $(srcdir)/static_seed/regexp seed - @touch seed/regexp.stamp - -regexp_SOURCES = regexp.c fuzz.c -regexp_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer - -fuzz-regexp: regexp$(EXEEXT) seed/regexp.stamp - @mkdir -p corpus/regexp - ./regexp$(EXEEXT) \ - -dict=regexp.dict \ - -max_len=200 \ - -timeout=5 \ - corpus/regexp seed/regexp - -# URI fuzzer - -seed/uri.stamp: - @mkdir -p seed/uri - cp -r $(srcdir)/static_seed/uri seed - @touch seed/uri.stamp - -uri_SOURCES = uri.c fuzz.c -uri_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer - -fuzz-uri: uri$(EXEEXT) seed/uri.stamp - @mkdir -p corpus/uri - ./uri$(EXEEXT) \ - -max_len=10000 \ - -timeout=2 \ - corpus/uri seed/uri - -# XML Schema fuzzer - -seed/schema.stamp: genSeed$(EXEEXT) - @mkdir -p seed/schema - ./genSeed$(EXEEXT) schema '$(top_srcdir)/test/schemas/*.xsd' - @touch seed/schema.stamp - -schema_SOURCES = schema.c fuzz.c -schema_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer - -fuzz-schema: schema$(EXEEXT) seed/schema.stamp - @mkdir -p corpus/schema - ./schema$(EXEEXT) \ - -dict=schema.dict \ - -max_len=$(XML_MAX_LEN) \ - -timeout=20 \ - corpus/schema seed/schema - -# XPath fuzzer - -seed/xpath.stamp: genSeed$(EXEEXT) - @mkdir -p seed/xpath - ./genSeed$(EXEEXT) xpath '$(top_srcdir)/test/XPath' - @touch seed/xpath.stamp - -xpath_SOURCES = xpath.c fuzz.c -xpath_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer - -fuzz-xpath: xpath$(EXEEXT) seed/xpath.stamp - @mkdir -p corpus/xpath - ./xpath$(EXEEXT) \ - -dict=xpath.dict \ - -max_len=10000 \ - -timeout=20 \ - corpus/xpath seed/xpath -
diff --git a/third_party/libxml/src/fuzz/Makefile.in b/third_party/libxml/src/fuzz/Makefile.in deleted file mode 100644 index 3c5ee972..0000000 --- a/third_party/libxml/src/fuzz/Makefile.in +++ /dev/null
@@ -1,993 +0,0 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2021 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -EXTRA_PROGRAMS = genSeed$(EXEEXT) html$(EXEEXT) regexp$(EXEEXT) \ - schema$(EXEEXT) uri$(EXEEXT) valid$(EXEEXT) xinclude$(EXEEXT) \ - xml$(EXEEXT) xpath$(EXEEXT) -check_PROGRAMS = testFuzzer$(EXEEXT) -subdir = fuzz -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ac_try_compile2.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -am_genSeed_OBJECTS = genSeed.$(OBJEXT) fuzz.$(OBJEXT) -genSeed_OBJECTS = $(am_genSeed_OBJECTS) -genSeed_LDADD = $(LDADD) -genSeed_DEPENDENCIES = $(top_builddir)/libxml2.la -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -am_html_OBJECTS = html.$(OBJEXT) fuzz.$(OBJEXT) -html_OBJECTS = $(am_html_OBJECTS) -html_LDADD = $(LDADD) -html_DEPENDENCIES = $(top_builddir)/libxml2.la -html_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(html_LDFLAGS) $(LDFLAGS) -o $@ -am_regexp_OBJECTS = regexp.$(OBJEXT) fuzz.$(OBJEXT) -regexp_OBJECTS = $(am_regexp_OBJECTS) -regexp_LDADD = $(LDADD) -regexp_DEPENDENCIES = $(top_builddir)/libxml2.la -regexp_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(regexp_LDFLAGS) $(LDFLAGS) -o $@ -am_schema_OBJECTS = schema.$(OBJEXT) fuzz.$(OBJEXT) -schema_OBJECTS = $(am_schema_OBJECTS) -schema_LDADD = $(LDADD) -schema_DEPENDENCIES = $(top_builddir)/libxml2.la -schema_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(schema_LDFLAGS) $(LDFLAGS) -o $@ -am_testFuzzer_OBJECTS = testFuzzer.$(OBJEXT) fuzz.$(OBJEXT) -testFuzzer_OBJECTS = $(am_testFuzzer_OBJECTS) -testFuzzer_LDADD = $(LDADD) -testFuzzer_DEPENDENCIES = $(top_builddir)/libxml2.la -am_uri_OBJECTS = uri.$(OBJEXT) fuzz.$(OBJEXT) -uri_OBJECTS = $(am_uri_OBJECTS) -uri_LDADD = $(LDADD) -uri_DEPENDENCIES = $(top_builddir)/libxml2.la -uri_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(uri_LDFLAGS) $(LDFLAGS) -o $@ -am_valid_OBJECTS = valid.$(OBJEXT) fuzz.$(OBJEXT) -valid_OBJECTS = $(am_valid_OBJECTS) -valid_LDADD = $(LDADD) -valid_DEPENDENCIES = $(top_builddir)/libxml2.la -valid_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(valid_LDFLAGS) $(LDFLAGS) -o $@ -am_xinclude_OBJECTS = xinclude.$(OBJEXT) fuzz.$(OBJEXT) -xinclude_OBJECTS = $(am_xinclude_OBJECTS) -xinclude_LDADD = $(LDADD) -xinclude_DEPENDENCIES = $(top_builddir)/libxml2.la -xinclude_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(xinclude_LDFLAGS) $(LDFLAGS) -o $@ -am_xml_OBJECTS = xml.$(OBJEXT) fuzz.$(OBJEXT) -xml_OBJECTS = $(am_xml_OBJECTS) -xml_LDADD = $(LDADD) -xml_DEPENDENCIES = $(top_builddir)/libxml2.la -xml_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(xml_LDFLAGS) $(LDFLAGS) -o $@ -am_xpath_OBJECTS = xpath.$(OBJEXT) fuzz.$(OBJEXT) -xpath_OBJECTS = $(am_xpath_OBJECTS) -xpath_LDADD = $(LDADD) -xpath_DEPENDENCIES = $(top_builddir)/libxml2.la -xpath_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(xpath_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/fuzz.Po ./$(DEPDIR)/genSeed.Po \ - ./$(DEPDIR)/html.Po ./$(DEPDIR)/regexp.Po \ - ./$(DEPDIR)/schema.Po ./$(DEPDIR)/testFuzzer.Po \ - ./$(DEPDIR)/uri.Po ./$(DEPDIR)/valid.Po \ - ./$(DEPDIR)/xinclude.Po ./$(DEPDIR)/xml.Po \ - ./$(DEPDIR)/xpath.Po -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(genSeed_SOURCES) $(html_SOURCES) $(regexp_SOURCES) \ - $(schema_SOURCES) $(testFuzzer_SOURCES) $(uri_SOURCES) \ - $(valid_SOURCES) $(xinclude_SOURCES) $(xml_SOURCES) \ - $(xpath_SOURCES) -DIST_SOURCES = $(genSeed_SOURCES) $(html_SOURCES) $(regexp_SOURCES) \ - $(schema_SOURCES) $(testFuzzer_SOURCES) $(uri_SOURCES) \ - $(valid_SOURCES) $(xinclude_SOURCES) $(xml_SOURCES) \ - $(xpath_SOURCES) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp README -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_CFLAGS = @AM_CFLAGS@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AM_LDFLAGS = @AM_LDFLAGS@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -BASE_THREAD_LIBS = @BASE_THREAD_LIBS@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPPFLAGS = @CPPFLAGS@ -CSCOPE = @CSCOPE@ -CTAGS = @CTAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -ETAGS = @ETAGS@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -FILECMD = @FILECMD@ -GREP = @GREP@ -ICU_CFLAGS = @ICU_CFLAGS@ -ICU_DEFS = @ICU_DEFS@ -ICU_LIBS = @ICU_LIBS@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBM = @LIBM@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIBXML_MAJOR_VERSION = @LIBXML_MAJOR_VERSION@ -LIBXML_MICRO_VERSION = @LIBXML_MICRO_VERSION@ -LIBXML_MINOR_VERSION = @LIBXML_MINOR_VERSION@ -LIBXML_VERSION = @LIBXML_VERSION@ -LIBXML_VERSION_EXTRA = @LIBXML_VERSION_EXTRA@ -LIBXML_VERSION_INFO = @LIBXML_VERSION_INFO@ -LIBXML_VERSION_NUMBER = @LIBXML_VERSION_NUMBER@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ -LZMA_CFLAGS = @LZMA_CFLAGS@ -LZMA_LIBS = @LZMA_LIBS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -MODULE_EXTENSION = @MODULE_EXTENSION@ -MODULE_PLATFORM_LIBS = @MODULE_PLATFORM_LIBS@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PERL = @PERL@ -PKG_CONFIG = @PKG_CONFIG@ -PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ -PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ -PYTHON = @PYTHON@ -PYTHON_CFLAGS = @PYTHON_CFLAGS@ -PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ -PYTHON_LDFLAGS = @PYTHON_LDFLAGS@ -PYTHON_LIBS = @PYTHON_LIBS@ -PYTHON_PLATFORM = @PYTHON_PLATFORM@ -PYTHON_PREFIX = @PYTHON_PREFIX@ -PYTHON_VERSION = @PYTHON_VERSION@ -RANLIB = @RANLIB@ -RDL_CFLAGS = @RDL_CFLAGS@ -RDL_LIBS = @RDL_LIBS@ -RELDATE = @RELDATE@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -TAR = @TAR@ -THREAD_CFLAGS = @THREAD_CFLAGS@ -THREAD_LIBS = @THREAD_LIBS@ -VERSION = @VERSION@ -VERSION_SCRIPT_FLAGS = @VERSION_SCRIPT_FLAGS@ -WGET = @WGET@ -WITH_C14N = @WITH_C14N@ -WITH_CATALOG = @WITH_CATALOG@ -WITH_DEBUG = @WITH_DEBUG@ -WITH_FTP = @WITH_FTP@ -WITH_HTML = @WITH_HTML@ -WITH_HTTP = @WITH_HTTP@ -WITH_ICONV = @WITH_ICONV@ -WITH_ICU = @WITH_ICU@ -WITH_ISO8859X = @WITH_ISO8859X@ -WITH_LEGACY = @WITH_LEGACY@ -WITH_LZMA = @WITH_LZMA@ -WITH_MEM_DEBUG = @WITH_MEM_DEBUG@ -WITH_MODULES = @WITH_MODULES@ -WITH_OUTPUT = @WITH_OUTPUT@ -WITH_PATTERN = @WITH_PATTERN@ -WITH_PUSH = @WITH_PUSH@ -WITH_READER = @WITH_READER@ -WITH_REGEXPS = @WITH_REGEXPS@ -WITH_SAX1 = @WITH_SAX1@ -WITH_SCHEMAS = @WITH_SCHEMAS@ -WITH_SCHEMATRON = @WITH_SCHEMATRON@ -WITH_THREADS = @WITH_THREADS@ -WITH_THREAD_ALLOC = @WITH_THREAD_ALLOC@ -WITH_TREE = @WITH_TREE@ -WITH_TRIO = @WITH_TRIO@ -WITH_VALID = @WITH_VALID@ -WITH_WRITER = @WITH_WRITER@ -WITH_XINCLUDE = @WITH_XINCLUDE@ -WITH_XPATH = @WITH_XPATH@ -WITH_XPTR = @WITH_XPTR@ -WITH_XPTR_LOCS = @WITH_XPTR_LOCS@ -WITH_ZLIB = @WITH_ZLIB@ -XML_CFLAGS = @XML_CFLAGS@ -XML_INCLUDEDIR = @XML_INCLUDEDIR@ -XML_LIBDIR = @XML_LIBDIR@ -XML_LIBS = @XML_LIBS@ -XML_LIBTOOLLIBS = @XML_LIBTOOLLIBS@ -XML_PRIVATE_CFLAGS = @XML_PRIVATE_CFLAGS@ -XML_PRIVATE_LIBS = @XML_PRIVATE_LIBS@ -XSLTPROC = @XSLTPROC@ -Z_CFLAGS = @Z_CFLAGS@ -Z_LIBS = @Z_LIBS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -pkgpyexecdir = @pkgpyexecdir@ -pkgpythondir = @pkgpythondir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -pyexecdir = @pyexecdir@ -pythondir = @pythondir@ -runstatedir = @runstatedir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -AUTOMAKE_OPTIONS = -Wno-syntax -EXTRA_DIST = html.dict regexp.dict schema.dict xml.dict xpath.dict \ - static_seed/uri static_seed/regexp fuzz.h - -CLEANFILES = $(EXTRA_PROGRAMS) -AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include -DEPENDENCIES = $(top_builddir)/libxml2.la -LDADD = $(top_builddir)/libxml2.la -XML_MAX_LEN = 80000 -# Single quotes to avoid wildcard expansion by the shell -XML_SEED_CORPUS_SRC = \ - '$(top_srcdir)/test/*' \ - '$(top_srcdir)/test/errors/*.xml' \ - '$(top_srcdir)/test/errors10/*.xml' \ - '$(top_srcdir)/test/namespaces/*' \ - '$(top_srcdir)/test/recurse/*.xml' \ - '$(top_srcdir)/test/SVG/*.xml' \ - '$(top_srcdir)/test/valid/*.xml' \ - '$(top_srcdir)/test/VC/*' \ - '$(top_srcdir)/test/VCM/*' \ - '$(top_srcdir)/test/xmlid/*' - -testFuzzer_SOURCES = testFuzzer.c fuzz.c - -# Seed corpus -genSeed_SOURCES = genSeed.c fuzz.c -xml_SOURCES = xml.c fuzz.c -xml_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer -valid_SOURCES = valid.c fuzz.c -valid_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer -xinclude_SOURCES = xinclude.c fuzz.c -xinclude_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer -html_SOURCES = html.c fuzz.c -html_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer -regexp_SOURCES = regexp.c fuzz.c -regexp_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer -uri_SOURCES = uri.c fuzz.c -uri_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer -schema_SOURCES = schema.c fuzz.c -schema_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer -xpath_SOURCES = xpath.c fuzz.c -xpath_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign fuzz/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign fuzz/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-checkPROGRAMS: - @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list - -genSeed$(EXEEXT): $(genSeed_OBJECTS) $(genSeed_DEPENDENCIES) $(EXTRA_genSeed_DEPENDENCIES) - @rm -f genSeed$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(genSeed_OBJECTS) $(genSeed_LDADD) $(LIBS) - -html$(EXEEXT): $(html_OBJECTS) $(html_DEPENDENCIES) $(EXTRA_html_DEPENDENCIES) - @rm -f html$(EXEEXT) - $(AM_V_CCLD)$(html_LINK) $(html_OBJECTS) $(html_LDADD) $(LIBS) - -regexp$(EXEEXT): $(regexp_OBJECTS) $(regexp_DEPENDENCIES) $(EXTRA_regexp_DEPENDENCIES) - @rm -f regexp$(EXEEXT) - $(AM_V_CCLD)$(regexp_LINK) $(regexp_OBJECTS) $(regexp_LDADD) $(LIBS) - -schema$(EXEEXT): $(schema_OBJECTS) $(schema_DEPENDENCIES) $(EXTRA_schema_DEPENDENCIES) - @rm -f schema$(EXEEXT) - $(AM_V_CCLD)$(schema_LINK) $(schema_OBJECTS) $(schema_LDADD) $(LIBS) - -testFuzzer$(EXEEXT): $(testFuzzer_OBJECTS) $(testFuzzer_DEPENDENCIES) $(EXTRA_testFuzzer_DEPENDENCIES) - @rm -f testFuzzer$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(testFuzzer_OBJECTS) $(testFuzzer_LDADD) $(LIBS) - -uri$(EXEEXT): $(uri_OBJECTS) $(uri_DEPENDENCIES) $(EXTRA_uri_DEPENDENCIES) - @rm -f uri$(EXEEXT) - $(AM_V_CCLD)$(uri_LINK) $(uri_OBJECTS) $(uri_LDADD) $(LIBS) - -valid$(EXEEXT): $(valid_OBJECTS) $(valid_DEPENDENCIES) $(EXTRA_valid_DEPENDENCIES) - @rm -f valid$(EXEEXT) - $(AM_V_CCLD)$(valid_LINK) $(valid_OBJECTS) $(valid_LDADD) $(LIBS) - -xinclude$(EXEEXT): $(xinclude_OBJECTS) $(xinclude_DEPENDENCIES) $(EXTRA_xinclude_DEPENDENCIES) - @rm -f xinclude$(EXEEXT) - $(AM_V_CCLD)$(xinclude_LINK) $(xinclude_OBJECTS) $(xinclude_LDADD) $(LIBS) - -xml$(EXEEXT): $(xml_OBJECTS) $(xml_DEPENDENCIES) $(EXTRA_xml_DEPENDENCIES) - @rm -f xml$(EXEEXT) - $(AM_V_CCLD)$(xml_LINK) $(xml_OBJECTS) $(xml_LDADD) $(LIBS) - -xpath$(EXEEXT): $(xpath_OBJECTS) $(xpath_DEPENDENCIES) $(EXTRA_xpath_DEPENDENCIES) - @rm -f xpath$(EXEEXT) - $(AM_V_CCLD)$(xpath_LINK) $(xpath_OBJECTS) $(xpath_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fuzz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/genSeed.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/html.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regexp.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/schema.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testFuzzer.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uri.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/valid.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xinclude.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xpath.Po@am__quote@ # am--include-marker - -$(am__depfiles_remade): - @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ - -am--depfiles: $(am__depfiles_remade) - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) - $(MAKE) $(AM_MAKEFLAGS) check-local -check: check-am -all-am: Makefile -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-checkPROGRAMS clean-generic clean-libtool clean-local \ - mostlyclean-am - -distclean: distclean-am - -rm -f ./$(DEPDIR)/fuzz.Po - -rm -f ./$(DEPDIR)/genSeed.Po - -rm -f ./$(DEPDIR)/html.Po - -rm -f ./$(DEPDIR)/regexp.Po - -rm -f ./$(DEPDIR)/schema.Po - -rm -f ./$(DEPDIR)/testFuzzer.Po - -rm -f ./$(DEPDIR)/uri.Po - -rm -f ./$(DEPDIR)/valid.Po - -rm -f ./$(DEPDIR)/xinclude.Po - -rm -f ./$(DEPDIR)/xml.Po - -rm -f ./$(DEPDIR)/xpath.Po - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/fuzz.Po - -rm -f ./$(DEPDIR)/genSeed.Po - -rm -f ./$(DEPDIR)/html.Po - -rm -f ./$(DEPDIR)/regexp.Po - -rm -f ./$(DEPDIR)/schema.Po - -rm -f ./$(DEPDIR)/testFuzzer.Po - -rm -f ./$(DEPDIR)/uri.Po - -rm -f ./$(DEPDIR)/valid.Po - -rm -f ./$(DEPDIR)/xinclude.Po - -rm -f ./$(DEPDIR)/xml.Po - -rm -f ./$(DEPDIR)/xpath.Po - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: check-am install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am \ - check-local clean clean-checkPROGRAMS clean-generic \ - clean-libtool clean-local cscopelist-am ctags ctags-am \ - distclean distclean-compile distclean-generic \ - distclean-libtool distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags tags-am uninstall uninstall-am - -.PRECIOUS: Makefile - - -.PHONY: corpus clean-corpus - -corpus: seed/html.stamp seed/regexp.stamp seed/schema.stamp seed/uri.stamp \ - seed/valid.stamp seed/xinclude.stamp seed/xml.stamp seed/xpath.stamp - -check-local: corpus - ./testFuzzer$(EXEEXT) - -clean-corpus: - rm -rf seed - -clean-local: clean-corpus - -# XML fuzzer - -seed/xml.stamp: genSeed$(EXEEXT) - @mkdir -p seed/xml - ./genSeed$(EXEEXT) xml $(XML_SEED_CORPUS_SRC) - @touch seed/xml.stamp - -fuzz-xml: xml$(EXEEXT) seed/xml.stamp - @mkdir -p corpus/xml - ./xml$(EXEEXT) \ - -dict=xml.dict \ - -max_len=$(XML_MAX_LEN) \ - -timeout=20 \ - corpus/xml seed/xml - -# DTD validation fuzzer - -seed/valid.stamp: genSeed$(EXEEXT) - @mkdir -p seed/valid - ./genSeed$(EXEEXT) valid $(XML_SEED_CORPUS_SRC) - @touch seed/valid.stamp - -fuzz-valid: valid$(EXEEXT) seed/valid.stamp - @mkdir -p corpus/valid - ./valid$(EXEEXT) \ - -dict=xml.dict \ - -max_len=$(XML_MAX_LEN) \ - -timeout=20 \ - corpus/valid seed/valid - -# XInclude fuzzer - -seed/xinclude.stamp: genSeed$(EXEEXT) - @mkdir -p seed/xinclude - ./genSeed$(EXEEXT) xinclude \ - '$(top_srcdir)/test/XInclude/docs/*' \ - '$(top_srcdir)/test/XInclude/without-reader/*' - @touch seed/xinclude.stamp - -fuzz-xinclude: xinclude$(EXEEXT) seed/xinclude.stamp - @mkdir -p corpus/xinclude - ./xinclude$(EXEEXT) \ - -dict=xml.dict \ - -max_len=$(XML_MAX_LEN) \ - -timeout=20 \ - corpus/xinclude seed/xinclude - -# HTML fuzzer - -seed/html.stamp: genSeed$(EXEEXT) - @mkdir -p seed/html - ./genSeed$(EXEEXT) html '$(top_srcdir)/test/HTML/*' - @touch seed/html.stamp - -fuzz-html: html$(EXEEXT) seed/html.stamp - @mkdir -p corpus/html - ./html$(EXEEXT) \ - -dict=html.dict \ - -max_len=1000000 \ - -timeout=10 \ - corpus/html seed/html - -# Regexp fuzzer - -seed/regexp.stamp: - @mkdir -p seed/regexp - cp -r $(srcdir)/static_seed/regexp seed - @touch seed/regexp.stamp - -fuzz-regexp: regexp$(EXEEXT) seed/regexp.stamp - @mkdir -p corpus/regexp - ./regexp$(EXEEXT) \ - -dict=regexp.dict \ - -max_len=200 \ - -timeout=5 \ - corpus/regexp seed/regexp - -# URI fuzzer - -seed/uri.stamp: - @mkdir -p seed/uri - cp -r $(srcdir)/static_seed/uri seed - @touch seed/uri.stamp - -fuzz-uri: uri$(EXEEXT) seed/uri.stamp - @mkdir -p corpus/uri - ./uri$(EXEEXT) \ - -max_len=10000 \ - -timeout=2 \ - corpus/uri seed/uri - -# XML Schema fuzzer - -seed/schema.stamp: genSeed$(EXEEXT) - @mkdir -p seed/schema - ./genSeed$(EXEEXT) schema '$(top_srcdir)/test/schemas/*.xsd' - @touch seed/schema.stamp - -fuzz-schema: schema$(EXEEXT) seed/schema.stamp - @mkdir -p corpus/schema - ./schema$(EXEEXT) \ - -dict=schema.dict \ - -max_len=$(XML_MAX_LEN) \ - -timeout=20 \ - corpus/schema seed/schema - -# XPath fuzzer - -seed/xpath.stamp: genSeed$(EXEEXT) - @mkdir -p seed/xpath - ./genSeed$(EXEEXT) xpath '$(top_srcdir)/test/XPath' - @touch seed/xpath.stamp - -fuzz-xpath: xpath$(EXEEXT) seed/xpath.stamp - @mkdir -p corpus/xpath - ./xpath$(EXEEXT) \ - -dict=xpath.dict \ - -max_len=10000 \ - -timeout=20 \ - corpus/xpath seed/xpath - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT:
diff --git a/third_party/libxml/src/fuzz/README b/third_party/libxml/src/fuzz/README deleted file mode 100644 index f675ad82..0000000 --- a/third_party/libxml/src/fuzz/README +++ /dev/null
@@ -1,19 +0,0 @@ -libFuzzer instructions for libxml2 -================================== - -Set compiler and options: - - export CC=clang - export CFLAGS="-g -fsanitize=fuzzer-no-link,address,undefined \ - -fno-sanitize-recover=all \ - -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION" - -Build libxml2 with instrumentation: - - ./configure --without-python - make - -Run fuzzers: - - make -C fuzz fuzz-xml -
diff --git a/third_party/libxml/src/fuzz/fuzz.c b/third_party/libxml/src/fuzz/fuzz.c deleted file mode 100644 index 7625131..0000000 --- a/third_party/libxml/src/fuzz/fuzz.c +++ /dev/null
@@ -1,400 +0,0 @@ -/* - * fuzz.c: Common functions for fuzzing. - * - * See Copyright for the status of this software. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/stat.h> - -#include <libxml/hash.h> -#include <libxml/parser.h> -#include <libxml/parserInternals.h> -#include <libxml/tree.h> -#include <libxml/xmlIO.h> -#include "fuzz.h" - -typedef struct { - const char *data; - size_t size; -} xmlFuzzEntityInfo; - -/* Single static instance for now */ -static struct { - /* Original data */ - const char *data; - size_t size; - - /* Remaining data */ - const char *ptr; - size_t remaining; - - /* Buffer for unescaped strings */ - char *outBuf; - char *outPtr; /* Free space at end of buffer */ - - xmlHashTablePtr entities; /* Maps URLs to xmlFuzzEntityInfos */ - - /* The first entity is the main entity. */ - const char *mainUrl; - xmlFuzzEntityInfo *mainEntity; -} fuzzData; - -size_t fuzzNumAllocs; -size_t fuzzMaxAllocs; - -/** - * xmlFuzzErrorFunc: - * - * An error function that simply discards all errors. - */ -void -xmlFuzzErrorFunc(void *ctx ATTRIBUTE_UNUSED, const char *msg ATTRIBUTE_UNUSED, - ...) { -} - -/* - * Malloc failure injection. - * - * Quick tip to debug complicated issues: Increase MALLOC_OFFSET until - * the crash disappears (or a different issue is triggered). Then set - * the offset to the highest value that produces a crash and set - * MALLOC_ABORT to 1 to see which failed memory allocation causes the - * issue. - */ - -#define XML_FUZZ_MALLOC_OFFSET 0 -#define XML_FUZZ_MALLOC_ABORT 0 - -static void * -xmlFuzzMalloc(size_t size) { - if (fuzzMaxAllocs > 0) { - if (fuzzNumAllocs >= fuzzMaxAllocs - 1) -#if XML_FUZZ_MALLOC_ABORT - abort(); -#else - return(NULL); -#endif - fuzzNumAllocs += 1; - } - return malloc(size); -} - -static void * -xmlFuzzRealloc(void *ptr, size_t size) { - if (fuzzMaxAllocs > 0) { - if (fuzzNumAllocs >= fuzzMaxAllocs - 1) -#if XML_FUZZ_MALLOC_ABORT - abort(); -#else - return(NULL); -#endif - fuzzNumAllocs += 1; - } - return realloc(ptr, size); -} - -void -xmlFuzzMemSetup(void) { - xmlMemSetup(free, xmlFuzzMalloc, xmlFuzzRealloc, xmlMemStrdup); -} - -void -xmlFuzzMemSetLimit(size_t limit) { - fuzzNumAllocs = 0; - fuzzMaxAllocs = limit ? limit + XML_FUZZ_MALLOC_OFFSET : 0; -} - -/** - * xmlFuzzDataInit: - * - * Initialize fuzz data provider. - */ -void -xmlFuzzDataInit(const char *data, size_t size) { - fuzzData.data = data; - fuzzData.size = size; - fuzzData.ptr = data; - fuzzData.remaining = size; - - fuzzData.outBuf = xmlMalloc(size + 1); - fuzzData.outPtr = fuzzData.outBuf; - - fuzzData.entities = xmlHashCreate(8); - fuzzData.mainUrl = NULL; - fuzzData.mainEntity = NULL; -} - -/** - * xmlFuzzDataFree: - * - * Cleanup fuzz data provider. - */ -void -xmlFuzzDataCleanup(void) { - xmlFree(fuzzData.outBuf); - xmlHashFree(fuzzData.entities, xmlHashDefaultDeallocator); -} - -/** - * xmlFuzzWriteInt: - * @out: output file - * @v: integer to write - * @size: size of integer in bytes - * - * Write an integer to the fuzz data. - */ -void -xmlFuzzWriteInt(FILE *out, size_t v, int size) { - int shift; - - while (size > (int) sizeof(size_t)) { - putc(0, out); - size--; - } - - shift = size * 8; - while (shift > 0) { - shift -= 8; - putc((v >> shift) & 255, out); - } -} - -/** - * xmlFuzzReadInt: - * @size: size of integer in bytes - * - * Read an integer from the fuzz data. - */ -size_t -xmlFuzzReadInt(int size) { - size_t ret = 0; - - while ((size > 0) && (fuzzData.remaining > 0)) { - unsigned char c = (unsigned char) *fuzzData.ptr++; - fuzzData.remaining--; - ret = (ret << 8) | c; - size--; - } - - return ret; -} - -/** - * xmlFuzzReadRemaining: - * @size: size of string in bytes - * - * Read remaining bytes from fuzz data. - */ -const char * -xmlFuzzReadRemaining(size_t *size) { - const char *ret = fuzzData.ptr; - - *size = fuzzData.remaining; - fuzzData.ptr += fuzzData.remaining; - fuzzData.remaining = 0; - - return(ret); -} - -/* - * xmlFuzzWriteString: - * @out: output file - * @str: string to write - * - * Write a random-length string to file in a format similar to - * FuzzedDataProvider. Backslash followed by newline marks the end of the - * string. Two backslashes are used to escape a backslash. - */ -void -xmlFuzzWriteString(FILE *out, const char *str) { - for (; *str; str++) { - int c = (unsigned char) *str; - putc(c, out); - if (c == '\\') - putc(c, out); - } - putc('\\', out); - putc('\n', out); -} - -/** - * xmlFuzzReadString: - * @size: size of string in bytes - * - * Read a random-length string from the fuzz data. - * - * The format is similar to libFuzzer's FuzzedDataProvider but treats - * backslash followed by newline as end of string. This makes the fuzz data - * more readable. A backslash character is escaped with another backslash. - * - * Returns a zero-terminated string or NULL if the fuzz data is exhausted. - */ -const char * -xmlFuzzReadString(size_t *size) { - const char *out = fuzzData.outPtr; - - while (fuzzData.remaining > 0) { - int c = *fuzzData.ptr++; - fuzzData.remaining--; - - if ((c == '\\') && (fuzzData.remaining > 0)) { - int c2 = *fuzzData.ptr; - - if (c2 == '\n') { - fuzzData.ptr++; - fuzzData.remaining--; - if (size != NULL) - *size = fuzzData.outPtr - out; - *fuzzData.outPtr++ = '\0'; - return(out); - } - if (c2 == '\\') { - fuzzData.ptr++; - fuzzData.remaining--; - } - } - - *fuzzData.outPtr++ = c; - } - - if (fuzzData.outPtr > out) { - if (size != NULL) - *size = fuzzData.outPtr - out; - *fuzzData.outPtr++ = '\0'; - return(out); - } - - if (size != NULL) - *size = 0; - return(NULL); -} - -/** - * xmlFuzzReadEntities: - * - * Read entities like the main XML file, external DTDs, external parsed - * entities from fuzz data. - */ -void -xmlFuzzReadEntities(void) { - size_t num = 0; - - while (1) { - const char *url, *entity; - size_t entitySize; - xmlFuzzEntityInfo *entityInfo; - - url = xmlFuzzReadString(NULL); - if (url == NULL) break; - - entity = xmlFuzzReadString(&entitySize); - if (entity == NULL) break; - - if (xmlHashLookup(fuzzData.entities, (xmlChar *)url) == NULL) { - entityInfo = xmlMalloc(sizeof(xmlFuzzEntityInfo)); - if (entityInfo == NULL) - break; - entityInfo->data = entity; - entityInfo->size = entitySize; - - xmlHashAddEntry(fuzzData.entities, (xmlChar *)url, entityInfo); - - if (num == 0) { - fuzzData.mainUrl = url; - fuzzData.mainEntity = entityInfo; - } - - num++; - } - } -} - -/** - * xmlFuzzMainUrl: - * - * Returns the main URL. - */ -const char * -xmlFuzzMainUrl(void) { - return(fuzzData.mainUrl); -} - -/** - * xmlFuzzMainEntity: - * @size: size of the main entity in bytes - * - * Returns the main entity. - */ -const char * -xmlFuzzMainEntity(size_t *size) { - if (fuzzData.mainEntity == NULL) - return(NULL); - *size = fuzzData.mainEntity->size; - return(fuzzData.mainEntity->data); -} - -/** - * xmlFuzzEntityLoader: - * - * The entity loader for fuzz data. - */ -xmlParserInputPtr -xmlFuzzEntityLoader(const char *URL, const char *ID ATTRIBUTE_UNUSED, - xmlParserCtxtPtr ctxt) { - xmlParserInputPtr input; - xmlFuzzEntityInfo *entity; - - if (URL == NULL) - return(NULL); - entity = xmlHashLookup(fuzzData.entities, (xmlChar *) URL); - if (entity == NULL) - return(NULL); - - input = xmlNewInputStream(ctxt); - if (input == NULL) - return(NULL); - input->filename = (char *) xmlCharStrdup(URL); - input->buf = xmlParserInputBufferCreateMem(entity->data, entity->size, - XML_CHAR_ENCODING_NONE); - if (input->buf == NULL) { - xmlFreeInputStream(input); - return(NULL); - } - input->base = input->cur = xmlBufContent(input->buf->buffer); - input->end = input->base + entity->size; - - return input; -} - -char * -xmlSlurpFile(const char *path, size_t *sizeRet) { - FILE *file; - struct stat statbuf; - char *data; - size_t size; - - if ((stat(path, &statbuf) != 0) || (!S_ISREG(statbuf.st_mode))) - return(NULL); - size = statbuf.st_size; - file = fopen(path, "rb"); - if (file == NULL) - return(NULL); - data = xmlMalloc(size + 1); - if (data != NULL) { - if (fread(data, 1, size, file) != size) { - xmlFree(data); - data = NULL; - } else { - data[size] = 0; - if (sizeRet != NULL) - *sizeRet = size; - } - } - fclose(file); - - return(data); -} -
diff --git a/third_party/libxml/src/fuzz/fuzz.h b/third_party/libxml/src/fuzz/fuzz.h deleted file mode 100644 index 0668b2f..0000000 --- a/third_party/libxml/src/fuzz/fuzz.h +++ /dev/null
@@ -1,103 +0,0 @@ -/* - * fuzz.h: Common functions and macros for fuzzing. - * - * See Copyright for the status of this software. - */ - -#ifndef __XML_FUZZERCOMMON_H__ -#define __XML_FUZZERCOMMON_H__ - -#include <stddef.h> -#include <stdio.h> -#include <libxml/parser.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED) - #define HAVE_HTML_FUZZER -#endif -#if defined(LIBXML_REGEXP_ENABLED) - #define HAVE_REGEXP_FUZZER -#endif -#if defined(LIBXML_SCHEMAS_ENABLED) - #define HAVE_SCHEMA_FUZZER -#endif -#if 1 - #define HAVE_URI_FUZZER -#endif -#if defined(LIBXML_VALID_ENABLED) && \ - defined(LIBXML_READER_ENABLED) - #define HAVE_VALID_FUZZER -#endif -#if defined(LIBXML_XINCLUDE_ENABLED) && \ - defined(LIBXML_READER_ENABLED) - #define HAVE_XINCLUDE_FUZZER -#endif -#if defined(LIBXML_OUTPUT_ENABLED) && \ - defined(LIBXML_READER_ENABLED) - #define HAVE_XML_FUZZER -#endif -#if defined(LIBXML_XPATH_ENABLED) - #define HAVE_XPATH_FUZZER -#endif - -int -LLVMFuzzerInitialize(int *argc, char ***argv); - -int -LLVMFuzzerTestOneInput(const char *data, size_t size); - -void -xmlFuzzErrorFunc(void *ctx ATTRIBUTE_UNUSED, const char *msg ATTRIBUTE_UNUSED, - ...); - -void -xmlFuzzMemSetup(void); - -void -xmlFuzzMemSetLimit(size_t limit); - -void -xmlFuzzDataInit(const char *data, size_t size); - -void -xmlFuzzDataCleanup(void); - -void -xmlFuzzWriteInt(FILE *out, size_t v, int size); - -size_t -xmlFuzzReadInt(int size); - -const char * -xmlFuzzReadRemaining(size_t *size); - -void -xmlFuzzWriteString(FILE *out, const char *str); - -const char * -xmlFuzzReadString(size_t *size); - -void -xmlFuzzReadEntities(void); - -const char * -xmlFuzzMainUrl(void); - -const char * -xmlFuzzMainEntity(size_t *size); - -xmlParserInputPtr -xmlFuzzEntityLoader(const char *URL, const char *ID, xmlParserCtxtPtr ctxt); - -char * -xmlSlurpFile(const char *path, size_t *size); - -#ifdef __cplusplus -} -#endif - -#endif /* __XML_FUZZERCOMMON_H__ */ -
diff --git a/third_party/libxml/src/fuzz/genSeed.c b/third_party/libxml/src/fuzz/genSeed.c deleted file mode 100644 index d08d135e..0000000 --- a/third_party/libxml/src/fuzz/genSeed.c +++ /dev/null
@@ -1,458 +0,0 @@ -/* - * xmlSeed.c: Generate the XML seed corpus for fuzzing. - * - * See Copyright for the status of this software. - */ - -#include <stdio.h> -#include <string.h> -#include <glob.h> -#include <libgen.h> -#include <sys/stat.h> - -#ifdef _WIN32 -#include <direct.h> -#else -#include <unistd.h> -#endif - -#include <libxml/parser.h> -#include <libxml/parserInternals.h> -#include <libxml/HTMLparser.h> -#include <libxml/xinclude.h> -#include <libxml/xmlschemas.h> -#include "fuzz.h" - -#define PATH_SIZE 500 -#define SEED_BUF_SIZE 16384 -#define EXPR_SIZE 4500 - -typedef int -(*fileFunc)(const char *base, FILE *out); - -typedef int -(*mainFunc)(const char *arg); - -static struct { - FILE *out; - xmlHashTablePtr entities; /* Maps URLs to xmlFuzzEntityInfos */ - xmlExternalEntityLoader oldLoader; - fileFunc processFile; - const char *fuzzer; - int counter; - char cwd[PATH_SIZE]; -} globalData; - -#if defined(HAVE_SCHEMA_FUZZER) || \ - defined(HAVE_XML_FUZZER) -/* - * A custom entity loader that writes all external DTDs or entities to a - * single file in the format expected by xmlFuzzEntityLoader. - */ -static xmlParserInputPtr -fuzzEntityRecorder(const char *URL, const char *ID, - xmlParserCtxtPtr ctxt) { - xmlParserInputPtr in; - static const int chunkSize = 16384; - int len; - - in = xmlNoNetExternalEntityLoader(URL, ID, ctxt); - if (in == NULL) - return(NULL); - - if (globalData.entities == NULL) { - globalData.entities = xmlHashCreate(4); - } else if (xmlHashLookup(globalData.entities, - (const xmlChar *) URL) != NULL) { - return(in); - } - - do { - len = xmlParserInputBufferGrow(in->buf, chunkSize); - if (len < 0) { - fprintf(stderr, "Error reading %s\n", URL); - xmlFreeInputStream(in); - return(NULL); - } - } while (len > 0); - - xmlFuzzWriteString(globalData.out, URL); - xmlFuzzWriteString(globalData.out, - (char *) xmlBufContent(in->buf->buffer)); - - xmlFreeInputStream(in); - - xmlHashAddEntry(globalData.entities, (const xmlChar *) URL, - globalData.entities); - - return(xmlNoNetExternalEntityLoader(URL, ID, ctxt)); -} - -static void -fuzzRecorderInit(FILE *out) { - globalData.out = out; - globalData.entities = xmlHashCreate(8); - globalData.oldLoader = xmlGetExternalEntityLoader(); - xmlSetExternalEntityLoader(fuzzEntityRecorder); -} - -static void -fuzzRecorderCleanup(void) { - xmlSetExternalEntityLoader(globalData.oldLoader); - xmlHashFree(globalData.entities, NULL); - globalData.out = NULL; - globalData.entities = NULL; - globalData.oldLoader = NULL; -} -#endif - -#ifdef HAVE_XML_FUZZER -static int -processXml(const char *docFile, FILE *out) { - int opts = XML_PARSE_NOENT | XML_PARSE_DTDLOAD; - xmlDocPtr doc; - - /* Parser options. */ - xmlFuzzWriteInt(out, opts, 4); - /* Max allocations. */ - xmlFuzzWriteInt(out, 0, 4); - - fuzzRecorderInit(out); - - doc = xmlReadFile(docFile, NULL, opts); - xmlXIncludeProcessFlags(doc, opts); - xmlFreeDoc(doc); - - fuzzRecorderCleanup(); - - return(0); -} -#endif - -#ifdef HAVE_HTML_FUZZER -static int -processHtml(const char *docFile, FILE *out) { - char buf[SEED_BUF_SIZE]; - FILE *file; - size_t size; - - /* Parser options. */ - xmlFuzzWriteInt(out, 0, 4); - /* Max allocations. */ - xmlFuzzWriteInt(out, 0, 4); - - /* Copy file */ - file = fopen(docFile, "rb"); - if (file == NULL) { - fprintf(stderr, "couldn't open %s\n", docFile); - return(0); - } - do { - size = fread(buf, 1, SEED_BUF_SIZE, file); - if (size > 0) - fwrite(buf, 1, size, out); - } while (size == SEED_BUF_SIZE); - fclose(file); - - return(0); -} -#endif - -#ifdef HAVE_SCHEMA_FUZZER -static int -processSchema(const char *docFile, FILE *out) { - xmlSchemaPtr schema; - xmlSchemaParserCtxtPtr pctxt; - - /* Max allocations. */ - xmlFuzzWriteInt(out, 0, 4); - - fuzzRecorderInit(out); - - pctxt = xmlSchemaNewParserCtxt(docFile); - xmlSchemaSetParserErrors(pctxt, xmlFuzzErrorFunc, xmlFuzzErrorFunc, NULL); - schema = xmlSchemaParse(pctxt); - xmlSchemaFreeParserCtxt(pctxt); - xmlSchemaFree(schema); - - fuzzRecorderCleanup(); - - return(0); -} -#endif - -#if defined(HAVE_HTML_FUZZER) || \ - defined(HAVE_SCHEMA_FUZZER) || \ - defined(HAVE_XML_FUZZER) -static int -processPattern(const char *pattern) { - glob_t globbuf; - int ret = 0; - int res; - size_t i; - - res = glob(pattern, 0, NULL, &globbuf); - if (res == GLOB_NOMATCH) - return(0); - if (res != 0) { - fprintf(stderr, "couldn't match pattern %s\n", pattern); - return(-1); - } - - for (i = 0; i < globbuf.gl_pathc; i++) { - struct stat statbuf; - char outPath[PATH_SIZE]; - char *dirBuf = NULL; - char *baseBuf = NULL; - const char *path, *dir, *base; - FILE *out = NULL; - int dirChanged = 0; - size_t size; - - path = globbuf.gl_pathv[i]; - - if ((stat(path, &statbuf) != 0) || (!S_ISREG(statbuf.st_mode))) - continue; - - dirBuf = (char *) xmlCharStrdup(path); - baseBuf = (char *) xmlCharStrdup(path); - if ((dirBuf == NULL) || (baseBuf == NULL)) { - fprintf(stderr, "memory allocation failed\n"); - ret = -1; - goto error; - } - dir = dirname(dirBuf); - base = basename(baseBuf); - - size = snprintf(outPath, sizeof(outPath), "seed/%s/%s", - globalData.fuzzer, base); - if (size >= PATH_SIZE) { - fprintf(stderr, "creating path failed\n"); - ret = -1; - goto error; - } - out = fopen(outPath, "wb"); - if (out == NULL) { - fprintf(stderr, "couldn't open %s for writing\n", outPath); - ret = -1; - goto error; - } - if (chdir(dir) != 0) { - fprintf(stderr, "couldn't chdir to %s\n", dir); - ret = -1; - goto error; - } - dirChanged = 1; - if (globalData.processFile(base, out) != 0) - ret = -1; - -error: - if (out != NULL) - fclose(out); - xmlFree(dirBuf); - xmlFree(baseBuf); - if ((dirChanged) && (chdir(globalData.cwd) != 0)) { - fprintf(stderr, "couldn't chdir to %s\n", globalData.cwd); - ret = -1; - break; - } - } - - globfree(&globbuf); - return(ret); -} -#endif - -#ifdef HAVE_XPATH_FUZZER -static int -processXPath(const char *testDir, const char *prefix, const char *name, - const char *data, const char *subdir, int xptr) { - char pattern[PATH_SIZE]; - glob_t globbuf; - size_t i, size; - int ret = 0, res; - - size = snprintf(pattern, sizeof(pattern), "%s/%s/%s*", - testDir, subdir, prefix); - if (size >= PATH_SIZE) - return(-1); - res = glob(pattern, 0, NULL, &globbuf); - if (res == GLOB_NOMATCH) - return(0); - if (res != 0) { - fprintf(stderr, "couldn't match pattern %s\n", pattern); - return(-1); - } - - for (i = 0; i < globbuf.gl_pathc; i++) { - char *path = globbuf.gl_pathv[i]; - struct stat statbuf; - FILE *in; - char expr[EXPR_SIZE]; - - if ((stat(path, &statbuf) != 0) || (!S_ISREG(statbuf.st_mode))) - continue; - - in = fopen(path, "rb"); - if (in == NULL) { - ret = -1; - continue; - } - - while (fgets(expr, EXPR_SIZE, in) != NULL) { - char outPath[PATH_SIZE]; - FILE *out; - int j; - - for (j = 0; expr[j] != 0; j++) - if (expr[j] == '\r' || expr[j] == '\n') - break; - expr[j] = 0; - - size = snprintf(outPath, sizeof(outPath), "seed/xpath/%s-%d", - name, globalData.counter); - if (size >= PATH_SIZE) { - ret = -1; - continue; - } - out = fopen(outPath, "wb"); - if (out == NULL) { - ret = -1; - continue; - } - - /* Max allocations. */ - xmlFuzzWriteInt(out, 0, 4); - - if (xptr) { - xmlFuzzWriteString(out, expr); - } else { - char xptrExpr[EXPR_SIZE+100]; - - /* Wrap XPath expressions as XPointer */ - snprintf(xptrExpr, sizeof(xptrExpr), "xpointer(%s)", expr); - xmlFuzzWriteString(out, xptrExpr); - } - - xmlFuzzWriteString(out, data); - - fclose(out); - globalData.counter++; - } - - fclose(in); - } - - globfree(&globbuf); - - return(ret); -} - -static int -processXPathDir(const char *testDir) { - char pattern[PATH_SIZE]; - glob_t globbuf; - size_t i, size; - int ret = 0; - - globalData.counter = 1; - if (processXPath(testDir, "", "expr", "<d></d>", "expr", 0) != 0) - ret = -1; - - size = snprintf(pattern, sizeof(pattern), "%s/docs/*", testDir); - if (size >= PATH_SIZE) - return(1); - if (glob(pattern, 0, NULL, &globbuf) != 0) - return(1); - - for (i = 0; i < globbuf.gl_pathc; i++) { - char *path = globbuf.gl_pathv[i]; - char *data; - const char *docFile; - - data = xmlSlurpFile(path, NULL); - if (data == NULL) { - ret = -1; - continue; - } - docFile = basename(path); - - globalData.counter = 1; - if (processXPath(testDir, docFile, docFile, data, "tests", 0) != 0) - ret = -1; - if (processXPath(testDir, docFile, docFile, data, "xptr", 1) != 0) - ret = -1; - if (processXPath(testDir, docFile, docFile, data, "xptr-xp1", 1) != 0) - ret = -1; - - xmlFree(data); - } - - globfree(&globbuf); - - return(ret); -} -#endif - -int -main(int argc, const char **argv) { - mainFunc processArg = NULL; - const char *fuzzer; - int ret = 0; - int i; - - if (argc < 3) { - fprintf(stderr, "usage: seed [FUZZER] [PATTERN...]\n"); - return(1); - } - - xmlSetGenericErrorFunc(NULL, xmlFuzzErrorFunc); - - fuzzer = argv[1]; - if (strcmp(fuzzer, "html") == 0) { -#ifdef HAVE_HTML_FUZZER - processArg = processPattern; - globalData.processFile = processHtml; -#endif - } else if (strcmp(fuzzer, "schema") == 0) { -#ifdef HAVE_SCHEMA_FUZZER - processArg = processPattern; - globalData.processFile = processSchema; -#endif - } else if (strcmp(fuzzer, "valid") == 0) { -#ifdef HAVE_XINCLUDE_FUZZER - processArg = processPattern; - globalData.processFile = processXml; -#endif - } else if (strcmp(fuzzer, "xinclude") == 0) { -#ifdef HAVE_XINCLUDE_FUZZER - processArg = processPattern; - globalData.processFile = processXml; -#endif - } else if (strcmp(fuzzer, "xml") == 0) { -#ifdef HAVE_XML_FUZZER - processArg = processPattern; - globalData.processFile = processXml; -#endif - } else if (strcmp(fuzzer, "xpath") == 0) { -#ifdef HAVE_XPATH_FUZZER - processArg = processXPathDir; -#endif - } else { - fprintf(stderr, "unknown fuzzer %s\n", fuzzer); - return(1); - } - globalData.fuzzer = fuzzer; - - if (getcwd(globalData.cwd, PATH_SIZE) == NULL) { - fprintf(stderr, "couldn't get current directory\n"); - return(1); - } - - if (processArg != NULL) - for (i = 2; i < argc; i++) - processArg(argv[i]); - - return(ret); -} -
diff --git a/third_party/libxml/src/fuzz/html.c b/third_party/libxml/src/fuzz/html.c deleted file mode 100644 index a2bd97a..0000000 --- a/third_party/libxml/src/fuzz/html.c +++ /dev/null
@@ -1,90 +0,0 @@ -/* - * html.c: a libFuzzer target to test several HTML parser interfaces. - * - * See Copyright for the status of this software. - */ - -#include <libxml/HTMLparser.h> -#include <libxml/HTMLtree.h> -#include <libxml/catalog.h> -#include "fuzz.h" - -int -LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED, - char ***argv ATTRIBUTE_UNUSED) { - xmlFuzzMemSetup(); - xmlInitParser(); -#ifdef LIBXML_CATALOG_ENABLED - xmlInitializeCatalog(); -#endif - xmlSetGenericErrorFunc(NULL, xmlFuzzErrorFunc); - - return 0; -} - -int -LLVMFuzzerTestOneInput(const char *data, size_t size) { - static const size_t maxChunkSize = 128; - htmlDocPtr doc; - htmlParserCtxtPtr ctxt; - xmlOutputBufferPtr out; - const char *docBuffer; - size_t maxAlloc, docSize, consumed, chunkSize; - int opts; - - xmlFuzzDataInit(data, size); - opts = (int) xmlFuzzReadInt(4); - maxAlloc = xmlFuzzReadInt(4) % (size + 1); - - docBuffer = xmlFuzzReadRemaining(&docSize); - if (docBuffer == NULL) { - xmlFuzzDataCleanup(); - return(0); - } - - /* Pull parser */ - - xmlFuzzMemSetLimit(maxAlloc); - doc = htmlReadMemory(docBuffer, docSize, NULL, NULL, opts); - - /* - * Also test the serializer. Call htmlDocContentDumpOutput with our - * own buffer to avoid encoding the output. The HTML encoding is - * excruciatingly slow (see htmlEntityValueLookup). - */ - out = xmlAllocOutputBuffer(NULL); - htmlDocContentDumpOutput(out, doc, NULL); - xmlOutputBufferClose(out); - - xmlFreeDoc(doc); - - /* Push parser */ - - xmlFuzzMemSetLimit(maxAlloc); - ctxt = htmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL, - XML_CHAR_ENCODING_NONE); - - if (ctxt != NULL) { - htmlCtxtUseOptions(ctxt, opts); - - for (consumed = 0; consumed < docSize; consumed += chunkSize) { - chunkSize = docSize - consumed; - if (chunkSize > maxChunkSize) - chunkSize = maxChunkSize; - htmlParseChunk(ctxt, docBuffer + consumed, chunkSize, 0); - } - - htmlParseChunk(ctxt, NULL, 0, 1); - xmlFreeDoc(ctxt->myDoc); - htmlFreeParserCtxt(ctxt); - } - - /* Cleanup */ - - xmlFuzzMemSetLimit(0); - xmlFuzzDataCleanup(); - xmlResetLastError(); - - return(0); -} -
diff --git a/third_party/libxml/src/fuzz/html.dict b/third_party/libxml/src/fuzz/html.dict deleted file mode 100644 index 80444c26..0000000 --- a/third_party/libxml/src/fuzz/html.dict +++ /dev/null
@@ -1,124 +0,0 @@ -elem_a="<a></a>" -elem_abbr="<abbr></abbr>" -elem_acronym="<acronym></acronym>" -elem_address="<address></address>" -elem_applet="<applet></applet>" -elem_area="<area>" -elem_b="<b></b>" -elem_base="<base>" -elem_basefont="<basefont>" -elem_bdo="<bdo></bdo>" -elem_big="<big></big>" -elem_blockquote="<blockquote></blockquote>" -elem_body="<body></body>" -elem_br="<br>" -elem_button="<button></button>" -elem_caption="<caption></caption>" -elem_center="<center></center>" -elem_cite="<cite></cite>" -elem_code="<code></code>" -elem_col="<col>" -elem_colgroup="<colgroup></colgroup>" -elem_dd="<dd></dd>" -elem_del="<del></del>" -elem_dfn="<dfn></dfn>" -elem_dir="<dir></dir>" -elem_div="<div></div>" -elem_dl="<dl></dl>" -elem_dt="<dt></dt>" -elem_em="<em></em>" -elem_embed="<embed></embed>" -elem_fieldset="<fieldset></fieldset>" -elem_font="<font></font>" -elem_form="<form></form>" -elem_frame="<frame>" -elem_frameset="<frameset></frameset>" -elem_h1="<h1></h1>" -elem_h2="<h2></h2>" -elem_h3="<h3></h3>" -elem_h4="<h4></h4>" -elem_h5="<h5></h5>" -elem_h6="<h6></h6>" -elem_head="<head></head>" -elem_hr="<hr>" -elem_html="<html></html>" -elem_i="<i></i>" -elem_iframe="<iframe></iframe>" -elem_img="<img>" -elem_input="<input>" -elem_ins="<ins></ins>" -elem_isindex="<isindex>" -elem_kbd="<kbd></kbd>" -elem_label="<label></label>" -elem_legend="<legend></legend>" -elem_li="<li></li>" -elem_link="<link>" -elem_map="<map></map>" -elem_menu="<menu></menu>" -elem_meta="<meta>" -elem_noframes="<noframes></noframes>" -elem_noscript="<noscript></noscript>" -elem_object="<object></object>" -elem_ol="<ol></ol>" -elem_optgroup="<optgroup></optgroup>" -elem_option="<option></option>" -elem_p="<p></p>" -elem_param="<param>" -elem_pre="<pre></pre>" -elem_q="<q></q>" -elem_s="<s></s>" -elem_samp="<samp></samp>" -elem_script="<script></script>" -elem_select="<select></select>" -elem_small="<small></small>" -elem_span="<span></span>" -elem_strike="<strike></strike>" -elem_strong="<strong></strong>" -elem_style="<style></style>" -elem_sub="<sub></sub>" -elem_sup="<sup></sup>" -elem_table="<table></table>" -elem_tbody="<tbody></tbody>" -elem_td="<td></td>" -elem_textarea="<textarea></textarea>" -elem_tfoot="<tfoot></tfoot>" -elem_th="<th></th>" -elem_thead="<thead></thead>" -elem_title="<title></title>" -elem_tr="<tr></tr>" -elem_tt="<tt></tt>" -elem_u="<u></u>" -elem_ul="<ul></ul>" -elem_var="<var></var>" - -attr_id=" id=\"\"" -attr_style=" style=\"\"" - -comment="<!-- -->" - -doctype="<!DOCTYPE d>" -doctype_system="<!DOCTYPE s SYSTEM \"u\">" -doctype_public="<!DOCTYPE p PUBLIC \"i\" \"u\">" - -pi="<?a?>" - -ref_lt="<" -ref_gt=">" -ref_amp="&" -ref_apos="'" -ref_quot=""" -ref_dec="	" -ref_hex="
" - -cs_utf8="UTF-8" -cs_utf16="UTF-16" -cs_utf16le="UTF-16LE" -cs_utf16be="UTF-16BE" -cs_ucs2="UCS-2" -cs_ucs4="UCS-4" -cs_latin1="ISO-8859-1" -cs_ascii="ASCII" -cs_ebcdic="EBCDIC" -cs_iso2022jp="ISO-2022-JP" -cs_shift_jis="SHIFT_JIS" -cs_euc_jp="EUC-JP"
diff --git a/third_party/libxml/src/fuzz/regexp.c b/third_party/libxml/src/fuzz/regexp.c deleted file mode 100644 index 0514059..0000000 --- a/third_party/libxml/src/fuzz/regexp.c +++ /dev/null
@@ -1,49 +0,0 @@ -/* - * regexp.c: a libFuzzer target to test the regexp module. - * - * See Copyright for the status of this software. - */ - -#include <libxml/xmlregexp.h> -#include "fuzz.h" - -int -LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED, - char ***argv ATTRIBUTE_UNUSED) { - xmlFuzzMemSetup(); - xmlSetGenericErrorFunc(NULL, xmlFuzzErrorFunc); - - return 0; -} - -int -LLVMFuzzerTestOneInput(const char *data, size_t size) { - xmlRegexpPtr regexp; - size_t maxAlloc; - const char *str1; - - if (size > 200) - return(0); - - xmlFuzzDataInit(data, size); - maxAlloc = xmlFuzzReadInt(4) % (size * 8 + 1); - str1 = xmlFuzzReadString(NULL); - - /* CUR_SCHAR doesn't handle invalid UTF-8 and may cause infinite loops. */ - if (xmlCheckUTF8(BAD_CAST str1) != 0) { - xmlFuzzMemSetLimit(maxAlloc); - regexp = xmlRegexpCompile(BAD_CAST str1); - /* xmlRegexpExec has pathological performance in too many cases. */ -#if 0 - xmlRegexpExec(regexp, BAD_CAST str2); -#endif - xmlRegFreeRegexp(regexp); - } - - xmlFuzzMemSetLimit(0); - xmlFuzzDataCleanup(); - xmlResetLastError(); - - return 0; -} -
diff --git a/third_party/libxml/src/fuzz/regexp.dict b/third_party/libxml/src/fuzz/regexp.dict deleted file mode 100644 index 30d666d..0000000 --- a/third_party/libxml/src/fuzz/regexp.dict +++ /dev/null
@@ -1,155 +0,0 @@ -quant_any="*" -quant_opt="?" -quant_some="+" -quant_num="{1,2}" - -dot="." -branch="|a" -parens="()" -parens_inner=")(" -pos_group="[a]" -neg_group="[^a]" -class_subtraction="[a-[b]]" - -esc_space="\\s" -esc_initial="\\i" -esc_name="\\c" -esc_digit="\\d" -esc_word="\\w" - -cat_letter="\\p{L}" -cat_mark="\\p{M}" -cat_number="\\p{N}" -cat_punct="\\p{P}" -cat_sym="\\p{S}" -cat_sep="\\p{Z}" -cat_other="\\p{C}" - -block_aegean_numbers="\\p{IsAegeanNumbers}" -block_alphabetic_presentation_forms="\\p{IsAlphabeticPresentationForms}" -block_arabic="\\p{IsArabic}" -block_arabic_presentation_forms_a="\\p{IsArabicPresentationFormsA}" -block_arabic_presentation_forms_b="\\p{IsArabicPresentationFormsB}" -block_armenian="\\p{IsArmenian}" -block_arrows="\\p{IsArrows}" -block_basic_latin="\\p{IsBasicLatin}" -block_bengali="\\p{IsBengali}" -block_block_elements="\\p{IsBlockElements}" -block_bopomofo="\\p{IsBopomofo}" -block_bopomofo_extended="\\p{IsBopomofoExtended}" -block_box_drawing="\\p{IsBoxDrawing}" -block_braille_patterns="\\p{IsBraillePatterns}" -block_buhid="\\p{IsBuhid}" -block_byzantine_musical_symbols="\\p{IsByzantineMusicalSymbols}" -block_c_j_k_compatibility="\\p{IsCJKCompatibility}" -block_c_j_k_compatibility_forms="\\p{IsCJKCompatibilityForms}" -block_c_j_k_compatibility_ideographs="\\p{IsCJKCompatibilityIdeographs}" -block_c_j_k_compatibility_ideographs_supplement="\\p{IsCJKCompatibilityIdeographsSupplement}" -block_c_j_k_radicals_supplement="\\p{IsCJKRadicalsSupplement}" -block_c_j_k_symbolsand_punctuation="\\p{IsCJKSymbolsandPunctuation}" -block_c_j_k_unified_ideographs="\\p{IsCJKUnifiedIdeographs}" -block_c_j_k_unified_ideographs_extension_a="\\p{IsCJKUnifiedIdeographsExtensionA}" -block_cjk_unified_ideographs_extension_b="\\p{IsCJKUnifiedIdeographsExtensionB}" -block_cherokee="\\p{IsCherokee}" -block_combining_diacritical_marks="\\p{IsCombiningDiacriticalMarks}" -block_combining_diacritical_marksfor_symbols="\\p{IsCombiningDiacriticalMarksforSymbols}" -block_combining_half_marks="\\p{IsCombiningHalfMarks}" -block_combining_marksfor_symbols="\\p{IsCombiningMarksforSymbols}" -block_control_pictures="\\p{IsControlPictures}" -block_currency_symbols="\\p{IsCurrencySymbols}" -block_cypriot_syllabary="\\p{IsCypriotSyllabary}" -block_cyrillic="\\p{IsCyrillic}" -block_cyrillic_supplement="\\p{IsCyrillicSupplement}" -block_deseret="\\p{IsDeseret}" -block_devanagari="\\p{IsDevanagari}" -block_dingbats="\\p{IsDingbats}" -block_enclosed_alphanumerics="\\p{IsEnclosedAlphanumerics}" -block_enclosed_cjk_lettersand_months="\\p{IsEnclosedCJKLettersandMonths}" -block_ethiopic="\\p{IsEthiopic}" -block_general_punctuation="\\p{IsGeneralPunctuation}" -block_geometric_shapes="\\p{IsGeometricShapes}" -block_georgian="\\p{IsGeorgian}" -block_gothic="\\p{IsGothic}" -block_greek="\\p{IsGreek}" -block_greek_extended="\\p{IsGreekExtended}" -block_greekand_coptic="\\p{IsGreekandCoptic}" -block_gujarati="\\p{IsGujarati}" -block_gurmukhi="\\p{IsGurmukhi}" -block_halfwidthand_fullwidth_forms="\\p{IsHalfwidthandFullwidthForms}" -block_hangul_compatibility_jamo="\\p{IsHangulCompatibilityJamo}" -block_hangul_jamo="\\p{IsHangulJamo}" -block_hangul_syllables="\\p{IsHangulSyllables}" -block_hanunoo="\\p{IsHanunoo}" -block_hebrew="\\p{IsHebrew}" -block_high_private_use_surrogates="\\p{IsHighPrivateUseSurrogates}" -block_high_surrogates="\\p{IsHighSurrogates}" -block_hiragana="\\p{IsHiragana}" -block_ipa_extensions="\\p{IsIPAExtensions}" -block_ideographic_description_characters="\\p{IsIdeographicDescriptionCharacters}" -block_kanbun="\\p{IsKanbun}" -block_kangxi_radicals="\\p{IsKangxiRadicals}" -block_kannada="\\p{IsKannada}" -block_katakana="\\p{IsKatakana}" -block_katakana_phonetic_extensions="\\p{IsKatakanaPhoneticExtensions}" -block_khmer="\\p{IsKhmer}" -block_khmer_symbols="\\p{IsKhmerSymbols}" -block_lao="\\p{IsLao}" -block_latin1Supplement="\\p{IsLatin1Supplement}" -block_latin_extended_a="\\p{IsLatinExtendedA}" -block_latin_extended_b="\\p{IsLatinExtendedB}" -block_latin_extended_additional="\\p{IsLatinExtendedAdditional}" -block_letterlike_symbols="\\p{IsLetterlikeSymbols}" -block_limbu="\\p{IsLimbu}" -block_linear_b_ideograms="\\p{IsLinearBIdeograms}" -block_linear_b_syllabary="\\p{IsLinearBSyllabary}" -block_low_surrogates="\\p{IsLowSurrogates}" -block_malayalam="\\p{IsMalayalam}" -block_mathematical_alphanumeric_symbols="\\p{IsMathematicalAlphanumericSymbols}" -block_mathematical_operators="\\p{IsMathematicalOperators}" -block_miscellaneous_mathematical_symbols_a="\\p{IsMiscellaneousMathematicalSymbolsA}" -block_miscellaneous_mathematical_symbols_b="\\p{IsMiscellaneousMathematicalSymbolsB}" -block_miscellaneous_symbols="\\p{IsMiscellaneousSymbols}" -block_miscellaneous_symbolsand_arrows="\\p{IsMiscellaneousSymbolsandArrows}" -block_miscellaneous_technical="\\p{IsMiscellaneousTechnical}" -block_mongolian="\\p{IsMongolian}" -block_musical_symbols="\\p{IsMusicalSymbols}" -block_myanmar="\\p{IsMyanmar}" -block_number_forms="\\p{IsNumberForms}" -block_ogham="\\p{IsOgham}" -block_old_italic="\\p{IsOldItalic}" -block_optical_character_recognition="\\p{IsOpticalCharacterRecognition}" -block_oriya="\\p{IsOriya}" -block_osmanya="\\p{IsOsmanya}" -block_phonetic_extensions="\\p{IsPhoneticExtensions}" -block_private_use="\\p{IsPrivateUse}" -block_private_use_area="\\p{IsPrivateUseArea}" -block_runic="\\p{IsRunic}" -block_shavian="\\p{IsShavian}" -block_sinhala="\\p{IsSinhala}" -block_small_form_variants="\\p{IsSmallFormVariants}" -block_spacing_modifier_letters="\\p{IsSpacingModifierLetters}" -block_specials="\\p{IsSpecials}" -block_superscriptsand_subscripts="\\p{IsSuperscriptsandSubscripts}" -block_supplemental_arrows_a="\\p{IsSupplementalArrowsA}" -block_supplemental_arrows_b="\\p{IsSupplementalArrowsB}" -block_supplemental_mathematical_operators="\\p{IsSupplementalMathematicalOperators}" -block_supplementary_private_use_area_a="\\p{IsSupplementaryPrivateUseAreaA}" -block_supplementary_private_use_area_b="\\p{IsSupplementaryPrivateUseAreaB}" -block_syriac="\\p{IsSyriac}" -block_tagalog="\\p{IsTagalog}" -block_tagbanwa="\\p{IsTagbanwa}" -block_tags="\\p{IsTags}" -block_tai_le="\\p{IsTaiLe}" -block_tai_xuan_jing_symbols="\\p{IsTaiXuanJingSymbols}" -block_tamil="\\p{IsTamil}" -block_telugu="\\p{IsTelugu}" -block_thaana="\\p{IsThaana}" -block_thai="\\p{IsThai}" -block_tibetan="\\p{IsTibetan}" -block_ugaritic="\\p{IsUgaritic}" -block_unified_canadian_aboriginal_syllabics="\\p{IsUnifiedCanadianAboriginalSyllabics}" -block_variation_selectors="\\p{IsVariationSelectors}" -block_variation_selectors_supplement="\\p{IsVariationSelectorsSupplement}" -block_yi_radicals="\\p{IsYiRadicals}" -block_yi_syllables="\\p{IsYiSyllables}" -block_yijing_hexagram_symbols="\\p{IsYijingHexagramSymbols}"
diff --git a/third_party/libxml/src/fuzz/schema.c b/third_party/libxml/src/fuzz/schema.c deleted file mode 100644 index 04e92f9..0000000 --- a/third_party/libxml/src/fuzz/schema.c +++ /dev/null
@@ -1,50 +0,0 @@ -/* - * schema.c: a libFuzzer target to test the XML Schema processor. - * - * See Copyright for the status of this software. - */ - -#include <libxml/catalog.h> -#include <libxml/xmlschemas.h> -#include "fuzz.h" - -int -LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED, - char ***argv ATTRIBUTE_UNUSED) { - xmlFuzzMemSetup(); - xmlInitParser(); -#ifdef LIBXML_CATALOG_ENABLED - xmlInitializeCatalog(); -#endif - xmlSetGenericErrorFunc(NULL, xmlFuzzErrorFunc); - xmlSetExternalEntityLoader(xmlFuzzEntityLoader); - - return 0; -} - -int -LLVMFuzzerTestOneInput(const char *data, size_t size) { - xmlSchemaParserCtxtPtr pctxt; - size_t maxAlloc; - - if (size > 50000) - return(0); - - maxAlloc = xmlFuzzReadInt(4) % (size + 1); - - xmlFuzzDataInit(data, size); - xmlFuzzReadEntities(); - - xmlFuzzMemSetLimit(maxAlloc); - pctxt = xmlSchemaNewParserCtxt(xmlFuzzMainUrl()); - xmlSchemaSetParserErrors(pctxt, xmlFuzzErrorFunc, xmlFuzzErrorFunc, NULL); - xmlSchemaFree(xmlSchemaParse(pctxt)); - xmlSchemaFreeParserCtxt(pctxt); - - xmlFuzzMemSetLimit(0); - xmlFuzzDataCleanup(); - xmlResetLastError(); - - return(0); -} -
diff --git a/third_party/libxml/src/fuzz/schema.dict b/third_party/libxml/src/fuzz/schema.dict deleted file mode 100644 index 9a8fd38..0000000 --- a/third_party/libxml/src/fuzz/schema.dict +++ /dev/null
@@ -1,55 +0,0 @@ -# TODO: Add more language elements - -xs_annotation="<xs:annotation></xs:annotation>" - -xs_attribute="<xs:attribute name='a'></xs:attribute>" -xs_attribute_required="<xs:attribute name='a' use='required'></xs:attribute>" -xs_element="<xs:element name='e'></xs:element>" - -# Primitive datatypes -type_string=" type='xs:string'" -type_boolean=" type='xs:boolean'" -type_decimal=" type='xs:decimal'" -type_float=" type='xs:float'" -type_double=" type='xs:double'" -type_date_time=" type='xs:dateTime'" -type_time=" type='xs:time'" -type_date=" type='xs:date'" -type_g_year_month=" type='xs:gYearMonth'" -type_g_year=" type='xs:gYear'" -type_g_month_day=" type='xs:gMonthDay'" -type_g_day=" type='xs:gDay'" -type_g_month=" type='xs:gMonth'" -type_hex_binary=" type='xs:hexBinary'" -type_base64_binary=" type='xs:base64Binary'" -type_any_uri=" type='xs:anyURI'" -type_qname=" type='xs:QName'" -type_notation=" type='xs:NOTATION'" - -# Occurs -occurs_min=" minOccurs='1'" -occurs_max=" maxOccurs='9'" -occurs_max_unbounded=" maxOccurs='unbounded'" - -# Simple type -xs_restriction_integer="<xs:simpleType><xs:restriction base='xs:integer'></xs:restriction></xs:simpleType>" -xs_restriction_string="<xs:simpleType><xs:restriction base='xs:string'></xs:restriction></xs:simpleType>" -xs_list="<xs:simpleType><xs:list></xs:list></xs:simpleType>" -xs_union="<xs:simpleType><xs:union></xs:union></xs:simpleType>" - -# Restrictions -xs_min_exclusive="<xs:minExclusive value='0'/>" -xs_min_inclusive="<xs:minInclusive value='0'/>" -xs_max_exclusive="<xs:maxExclusive value='9'/>" -xs_max_inclusive="<xs:maxInclusive value='9'/>" -xs_total_digits="<xs:totalDigits value='3'/>" -xs_fraction_digits="<xs:fractionDigits value='3'/>" -xs_length="<xs:length value='3'/>" -xs_min_length="<xs:minLength value='3'/>" -xs_max_length="<xs:maxLength value='3'/>" -xs_enumeration="<xs:enumeration value='a'/>" -xs_white_space_collapse="<xs:whiteSpace value='collapse'/>" -xs_white_space_preserve="<xs:whiteSpace value='preserve'/>" -xs_white_space_replace="<xs:whiteSpace value='replace'/>" -xs_pattern="<xs:pattern value='a'/>" -
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/branch-1 b/third_party/libxml/src/fuzz/static_seed/regexp/branch-1 deleted file mode 100644 index 2a61d0d..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/branch-1 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/branch-10 b/third_party/libxml/src/fuzz/static_seed/regexp/branch-10 deleted file mode 100644 index a867afe..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/branch-10 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/branch-11 b/third_party/libxml/src/fuzz/static_seed/regexp/branch-11 deleted file mode 100644 index cf22034..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/branch-11 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/branch-12 b/third_party/libxml/src/fuzz/static_seed/regexp/branch-12 deleted file mode 100644 index 1dd06d5f..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/branch-12 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/branch-13 b/third_party/libxml/src/fuzz/static_seed/regexp/branch-13 deleted file mode 100644 index d3033d2..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/branch-13 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/branch-2 b/third_party/libxml/src/fuzz/static_seed/regexp/branch-2 deleted file mode 100644 index cd27911..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/branch-2 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/branch-3 b/third_party/libxml/src/fuzz/static_seed/regexp/branch-3 deleted file mode 100644 index 64437c82..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/branch-3 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/branch-4 b/third_party/libxml/src/fuzz/static_seed/regexp/branch-4 deleted file mode 100644 index 556bba2..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/branch-4 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/branch-5 b/third_party/libxml/src/fuzz/static_seed/regexp/branch-5 deleted file mode 100644 index cdf9098..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/branch-5 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/branch-6 b/third_party/libxml/src/fuzz/static_seed/regexp/branch-6 deleted file mode 100644 index f68f552..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/branch-6 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/branch-7 b/third_party/libxml/src/fuzz/static_seed/regexp/branch-7 deleted file mode 100644 index a7e8e91..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/branch-7 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/branch-8 b/third_party/libxml/src/fuzz/static_seed/regexp/branch-8 deleted file mode 100644 index 0637a69..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/branch-8 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/branch-9 b/third_party/libxml/src/fuzz/static_seed/regexp/branch-9 deleted file mode 100644 index 6cbd35e..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/branch-9 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-1 b/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-1 deleted file mode 100644 index 742782c..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-1 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-10 b/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-10 deleted file mode 100644 index 09eaccc..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-10 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-11 b/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-11 deleted file mode 100644 index 991d19a..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-11 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-12 b/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-12 deleted file mode 100644 index dd43da8..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-12 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-13 b/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-13 deleted file mode 100644 index 8b7bc0c..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-13 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-14 b/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-14 deleted file mode 100644 index 4cd8318ebc..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-14 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-15 b/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-15 deleted file mode 100644 index 456dda7..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-15 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-16 b/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-16 deleted file mode 100644 index 94a4810..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-16 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-2 b/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-2 deleted file mode 100644 index 6dd04e33..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-2 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-3 b/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-3 deleted file mode 100644 index 5be0b2d..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-3 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-4 b/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-4 deleted file mode 100644 index e7d786c0..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-4 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-5 b/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-5 deleted file mode 100644 index e06cf23..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-5 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-6 b/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-6 deleted file mode 100644 index c65a26e7..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-6 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-7 b/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-7 deleted file mode 100644 index 8d0ec0f..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-7 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-8 b/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-8 deleted file mode 100644 index a17aac4..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-8 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-9 b/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-9 deleted file mode 100644 index 3c37fb4..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/bug316338-9 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/bug420596-1 b/third_party/libxml/src/fuzz/static_seed/regexp/bug420596-1 deleted file mode 100644 index 9b6a838..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/bug420596-1 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/bug420596-2 b/third_party/libxml/src/fuzz/static_seed/regexp/bug420596-2 deleted file mode 100644 index f3ee539..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/bug420596-2 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/bug420596-3 b/third_party/libxml/src/fuzz/static_seed/regexp/bug420596-3 deleted file mode 100644 index 590bad9..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/bug420596-3 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/bug420596-4 b/third_party/libxml/src/fuzz/static_seed/regexp/bug420596-4 deleted file mode 100644 index 233a92b..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/bug420596-4 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/bug420596-5 b/third_party/libxml/src/fuzz/static_seed/regexp/bug420596-5 deleted file mode 100644 index ca35ec2..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/bug420596-5 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/bug420596-6 b/third_party/libxml/src/fuzz/static_seed/regexp/bug420596-6 deleted file mode 100644 index d433d914..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/bug420596-6 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/bug420596-7 b/third_party/libxml/src/fuzz/static_seed/regexp/bug420596-7 deleted file mode 100644 index 80d821e..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/bug420596-7 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/bug420596-8 b/third_party/libxml/src/fuzz/static_seed/regexp/bug420596-8 deleted file mode 100644 index 17456c9..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/bug420596-8 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/content-1 b/third_party/libxml/src/fuzz/static_seed/regexp/content-1 deleted file mode 100644 index edcb943b..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/content-1 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/content-10 b/third_party/libxml/src/fuzz/static_seed/regexp/content-10 deleted file mode 100644 index f0cd363..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/content-10 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/content-2 b/third_party/libxml/src/fuzz/static_seed/regexp/content-2 deleted file mode 100644 index d9f4a93..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/content-2 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/content-3 b/third_party/libxml/src/fuzz/static_seed/regexp/content-3 deleted file mode 100644 index 309c9204..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/content-3 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/content-4 b/third_party/libxml/src/fuzz/static_seed/regexp/content-4 deleted file mode 100644 index 20ffbb7..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/content-4 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/content-5 b/third_party/libxml/src/fuzz/static_seed/regexp/content-5 deleted file mode 100644 index faa7b53..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/content-5 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/content-6 b/third_party/libxml/src/fuzz/static_seed/regexp/content-6 deleted file mode 100644 index 98ef3aa8e..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/content-6 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/content-7 b/third_party/libxml/src/fuzz/static_seed/regexp/content-7 deleted file mode 100644 index b0d17afe..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/content-7 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/content-8 b/third_party/libxml/src/fuzz/static_seed/regexp/content-8 deleted file mode 100644 index 51aeb7b..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/content-8 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/content-9 b/third_party/libxml/src/fuzz/static_seed/regexp/content-9 deleted file mode 100644 index 589d928..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/content-9 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/hard-1 b/third_party/libxml/src/fuzz/static_seed/regexp/hard-1 deleted file mode 100644 index 9959fb4..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/hard-1 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/hard-10 b/third_party/libxml/src/fuzz/static_seed/regexp/hard-10 deleted file mode 100644 index 36db287..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/hard-10 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/hard-2 b/third_party/libxml/src/fuzz/static_seed/regexp/hard-2 deleted file mode 100644 index 17016bd..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/hard-2 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/hard-3 b/third_party/libxml/src/fuzz/static_seed/regexp/hard-3 deleted file mode 100644 index f3f1c0b..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/hard-3 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/hard-4 b/third_party/libxml/src/fuzz/static_seed/regexp/hard-4 deleted file mode 100644 index 13bcd77..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/hard-4 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/hard-5 b/third_party/libxml/src/fuzz/static_seed/regexp/hard-5 deleted file mode 100644 index 41e5310..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/hard-5 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/hard-6 b/third_party/libxml/src/fuzz/static_seed/regexp/hard-6 deleted file mode 100644 index d55d808b..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/hard-6 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/hard-7 b/third_party/libxml/src/fuzz/static_seed/regexp/hard-7 deleted file mode 100644 index 0dfd684..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/hard-7 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/hard-8 b/third_party/libxml/src/fuzz/static_seed/regexp/hard-8 deleted file mode 100644 index 8159843..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/hard-8 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/hard-9 b/third_party/libxml/src/fuzz/static_seed/regexp/hard-9 deleted file mode 100644 index a4e9ece42..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/hard-9 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/ncname-1 b/third_party/libxml/src/fuzz/static_seed/regexp/ncname-1 deleted file mode 100644 index 6d43f81..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/ncname-1 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/ncname-2 b/third_party/libxml/src/fuzz/static_seed/regexp/ncname-2 deleted file mode 100644 index bb9ff54..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/ncname-2 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/ncname-3 b/third_party/libxml/src/fuzz/static_seed/regexp/ncname-3 deleted file mode 100644 index 605ccc58..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/ncname-3 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/ncname-4 b/third_party/libxml/src/fuzz/static_seed/regexp/ncname-4 deleted file mode 100644 index facf97d..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/ncname-4 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/ncname-5 b/third_party/libxml/src/fuzz/static_seed/regexp/ncname-5 deleted file mode 100644 index ad223348..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/ncname-5 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/ranges-1 b/third_party/libxml/src/fuzz/static_seed/regexp/ranges-1 deleted file mode 100644 index 2c4bb3d..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/ranges-1 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/ranges-10 b/third_party/libxml/src/fuzz/static_seed/regexp/ranges-10 deleted file mode 100644 index 61c3d3d..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/ranges-10 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/ranges-11 b/third_party/libxml/src/fuzz/static_seed/regexp/ranges-11 deleted file mode 100644 index 6133262..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/ranges-11 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/ranges-12 b/third_party/libxml/src/fuzz/static_seed/regexp/ranges-12 deleted file mode 100644 index 4b6be37..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/ranges-12 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/ranges-2 b/third_party/libxml/src/fuzz/static_seed/regexp/ranges-2 deleted file mode 100644 index f766e22..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/ranges-2 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/ranges-3 b/third_party/libxml/src/fuzz/static_seed/regexp/ranges-3 deleted file mode 100644 index 7c03f87..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/ranges-3 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/ranges-4 b/third_party/libxml/src/fuzz/static_seed/regexp/ranges-4 deleted file mode 100644 index 08a0a9a6..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/ranges-4 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/ranges-5 b/third_party/libxml/src/fuzz/static_seed/regexp/ranges-5 deleted file mode 100644 index ce3f25a..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/ranges-5 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/ranges-6 b/third_party/libxml/src/fuzz/static_seed/regexp/ranges-6 deleted file mode 100644 index 523b6379..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/ranges-6 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/ranges-7 b/third_party/libxml/src/fuzz/static_seed/regexp/ranges-7 deleted file mode 100644 index 091ff050..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/ranges-7 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/ranges-8 b/third_party/libxml/src/fuzz/static_seed/regexp/ranges-8 deleted file mode 100644 index 210f7091..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/ranges-8 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/ranges-9 b/third_party/libxml/src/fuzz/static_seed/regexp/ranges-9 deleted file mode 100644 index 7da8a2a..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/ranges-9 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-1 b/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-1 deleted file mode 100644 index 003c2c5..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-1 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-10 b/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-10 deleted file mode 100644 index 261bf56..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-10 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-11 b/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-11 deleted file mode 100644 index c6c5bd0..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-11 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-12 b/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-12 deleted file mode 100644 index 0a729f2..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-12 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-2 b/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-2 deleted file mode 100644 index 9fc2ce1..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-2 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-3 b/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-3 deleted file mode 100644 index 08a3963..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-3 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-4 b/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-4 deleted file mode 100644 index c965555a..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-4 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-5 b/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-5 deleted file mode 100644 index 2e65f5d..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-5 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-6 b/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-6 deleted file mode 100644 index 4990264..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-6 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-7 b/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-7 deleted file mode 100644 index 5f3e2c3..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-7 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-8 b/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-8 deleted file mode 100644 index 9b384e589..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-8 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-9 b/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-9 deleted file mode 100644 index e08ad99..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/ranges2-9 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-1 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-1 deleted file mode 100644 index 20e37e0b..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-1 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-10 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-10 deleted file mode 100644 index 1bdb0a8..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-10 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-11 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-11 deleted file mode 100644 index 5e26ec256..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-11 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-12 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-12 deleted file mode 100644 index e044486..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-12 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-13 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-13 deleted file mode 100644 index 9cb2874..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-13 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-14 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-14 deleted file mode 100644 index 3b9003f..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-14 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-15 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-15 deleted file mode 100644 index 64b071e5..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-15 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-16 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-16 deleted file mode 100644 index 44b612b..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-16 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-17 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-17 deleted file mode 100644 index 0370668..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-17 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-18 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-18 deleted file mode 100644 index 03519119..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-18 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-19 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-19 deleted file mode 100644 index f4a153c..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-19 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-2 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-2 deleted file mode 100644 index 0a8bae7..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-2 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-20 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-20 deleted file mode 100644 index 44b612b..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-20 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-21 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-21 deleted file mode 100644 index 2d6c7df..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-21 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-22 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-22 deleted file mode 100644 index 1e8db88..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-22 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-23 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-23 deleted file mode 100644 index 233f27ee..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-23 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-24 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-24 deleted file mode 100644 index c970a5e..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-24 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-25 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-25 deleted file mode 100644 index 649e8f49..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-25 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-26 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-26 deleted file mode 100644 index 13f6f24f..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-26 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-27 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-27 deleted file mode 100644 index 3fea5c9..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-27 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-28 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-28 deleted file mode 100644 index 8d28581..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-28 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-29 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-29 deleted file mode 100644 index a62aafe..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-29 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-3 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-3 deleted file mode 100644 index 40bba5a..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-3 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-30 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-30 deleted file mode 100644 index 60105af..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-30 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-31 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-31 deleted file mode 100644 index f7d319d..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-31 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-32 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-32 deleted file mode 100644 index b3708dae..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-32 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-33 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-33 deleted file mode 100644 index 4ad749f..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-33 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-34 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-34 deleted file mode 100644 index c3e184ce..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-34 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-35 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-35 deleted file mode 100644 index 41ec1090..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-35 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-4 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-4 deleted file mode 100644 index d8c875e..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-4 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-5 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-5 deleted file mode 100644 index 1e282d0..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-5 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-6 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-6 deleted file mode 100644 index 52405e4..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-6 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-7 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-7 deleted file mode 100644 index 81ebb61..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-7 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-8 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-8 deleted file mode 100644 index 9132035e..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-8 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-9 b/third_party/libxml/src/fuzz/static_seed/regexp/xpath-9 deleted file mode 100644 index fb88269d..0000000 --- a/third_party/libxml/src/fuzz/static_seed/regexp/xpath-9 +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/uri/dot b/third_party/libxml/src/fuzz/static_seed/uri/dot deleted file mode 100644 index 6cac6b0..0000000 --- a/third_party/libxml/src/fuzz/static_seed/uri/dot +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/static_seed/uri/full b/third_party/libxml/src/fuzz/static_seed/uri/full deleted file mode 100644 index 833329f..0000000 --- a/third_party/libxml/src/fuzz/static_seed/uri/full +++ /dev/null Binary files differ
diff --git a/third_party/libxml/src/fuzz/testFuzzer.c b/third_party/libxml/src/fuzz/testFuzzer.c deleted file mode 100644 index d7c775f2..0000000 --- a/third_party/libxml/src/fuzz/testFuzzer.c +++ /dev/null
@@ -1,228 +0,0 @@ -/* - * testFuzzer.c: Test program for the custom entity loader used to fuzz - * with multiple inputs. - * - * See Copyright for the status of this software. - */ - -#include <string.h> -#include <glob.h> -#include <libxml/parser.h> -#include <libxml/tree.h> -#include <libxml/xmlstring.h> -#include "fuzz.h" - -#ifdef HAVE_HTML_FUZZER -int fuzzHtmlInit(int *argc, char ***argv); -int fuzzHtml(const char *data, size_t size); -#define LLVMFuzzerInitialize fuzzHtmlInit -#define LLVMFuzzerTestOneInput fuzzHtml -#include "html.c" -#undef LLVMFuzzerInitialize -#undef LLVMFuzzerTestOneInput -#endif - -#ifdef HAVE_REGEXP_FUZZER -int fuzzRegexpInit(int *argc, char ***argv); -int fuzzRegexp(const char *data, size_t size); -#define LLVMFuzzerInitialize fuzzRegexpInit -#define LLVMFuzzerTestOneInput fuzzRegexp -#include "regexp.c" -#undef LLVMFuzzerInitialize -#undef LLVMFuzzerTestOneInput -#endif - -#ifdef HAVE_SCHEMA_FUZZER -int fuzzSchemaInit(int *argc, char ***argv); -int fuzzSchema(const char *data, size_t size); -#define LLVMFuzzerInitialize fuzzSchemaInit -#define LLVMFuzzerTestOneInput fuzzSchema -#include "schema.c" -#undef LLVMFuzzerInitialize -#undef LLVMFuzzerTestOneInput -#endif - -#ifdef HAVE_URI_FUZZER -int fuzzUriInit(int *argc, char ***argv); -int fuzzUri(const char *data, size_t size); -#define LLVMFuzzerInitialize fuzzUriInit -#define LLVMFuzzerTestOneInput fuzzUri -#include "uri.c" -#undef LLVMFuzzerInitialize -#undef LLVMFuzzerTestOneInput -#endif - -#ifdef HAVE_VALID_FUZZER -int fuzzValidInit(int *argc, char ***argv); -int fuzzValid(const char *data, size_t size); -#define LLVMFuzzerInitialize fuzzValidInit -#define LLVMFuzzerTestOneInput fuzzValid -#include "valid.c" -#undef LLVMFuzzerInitialize -#undef LLVMFuzzerTestOneInput -#endif - -#ifdef HAVE_XINCLUDE_FUZZER -int fuzzXIncludeInit(int *argc, char ***argv); -int fuzzXInclude(const char *data, size_t size); -#define LLVMFuzzerInitialize fuzzXIncludeInit -#define LLVMFuzzerTestOneInput fuzzXInclude -#include "xinclude.c" -#undef LLVMFuzzerInitialize -#undef LLVMFuzzerTestOneInput -#endif - -#ifdef HAVE_XML_FUZZER -int fuzzXmlInit(int *argc, char ***argv); -int fuzzXml(const char *data, size_t size); -#define LLVMFuzzerInitialize fuzzXmlInit -#define LLVMFuzzerTestOneInput fuzzXml -#include "xml.c" -#undef LLVMFuzzerInitialize -#undef LLVMFuzzerTestOneInput -#endif - -#ifdef HAVE_XPATH_FUZZER -int fuzzXPathInit(int *argc, char ***argv); -int fuzzXPath(const char *data, size_t size); -#define LLVMFuzzerInitialize fuzzXPathInit -#define LLVMFuzzerTestOneInput fuzzXPath -#include "xpath.c" -#undef LLVMFuzzerInitialize -#undef LLVMFuzzerTestOneInput -#endif - -typedef int -(*initFunc)(int *argc, char ***argv); -typedef int -(*fuzzFunc)(const char *data, size_t size); - -int numInputs; - -static int -testFuzzer(initFunc init, fuzzFunc fuzz, const char *pattern) { - glob_t globbuf; - int ret = -1; - size_t i; - - if (glob(pattern, 0, NULL, &globbuf) != 0) { - fprintf(stderr, "pattern %s matches no files\n", pattern); - return(-1); - } - - if (init != NULL) - init(NULL, NULL); - - for (i = 0; i < globbuf.gl_pathc; i++) { - const char *path = globbuf.gl_pathv[i]; - char *data; - size_t size; - - data = xmlSlurpFile(path, &size); - if (data == NULL) { - fprintf(stderr, "couldn't read %s\n", path); - goto error; - } - fuzz(data, size); - xmlFree(data); - - numInputs++; - } - - ret = 0; -error: - globfree(&globbuf); - return(ret); -} - -#ifdef HAVE_XML_FUZZER -static int -testEntityLoader(void) { - static const char data[] = - "doc.xml\\\n" - "<!DOCTYPE doc SYSTEM \"doc.dtd\">\n" - "<doc>&ent;</doc>\\\n" - "doc.dtd\\\n" - "<!ELEMENT doc (#PCDATA)>\n" - "<!ENTITY ent SYSTEM \"ent.txt\">\\\n" - "ent.txt\\\n" - "Hello, world!\\\n"; - static xmlChar expected[] = - "<?xml version=\"1.0\"?>\n" - "<!DOCTYPE doc SYSTEM \"doc.dtd\">\n" - "<doc>Hello, world!</doc>\n"; - const char *docBuffer; - size_t docSize; - xmlDocPtr doc; - xmlChar *out; - int ret = 0; - - xmlSetExternalEntityLoader(xmlFuzzEntityLoader); - - xmlFuzzDataInit(data, sizeof(data) - 1); - xmlFuzzReadEntities(); - docBuffer = xmlFuzzMainEntity(&docSize); - doc = xmlReadMemory(docBuffer, docSize, NULL, NULL, - XML_PARSE_NOENT | XML_PARSE_DTDLOAD); - - xmlDocDumpMemory(doc, &out, NULL); - if (xmlStrcmp(out, expected) != 0) { - fprintf(stderr, "Expected:\n%sGot:\n%s", expected, out); - ret = 1; - } - - xmlFree(out); - xmlFreeDoc(doc); - xmlFuzzDataCleanup(); - - return(ret); -} -#endif - -int -main(void) { - int ret = 0; - -#ifdef HAVE_XML_FUZZER - if (testEntityLoader() != 0) - ret = 1; -#endif -#ifdef HAVE_HTML_FUZZER - if (testFuzzer(fuzzHtmlInit, fuzzHtml, "seed/html/*") != 0) - ret = 1; -#endif -#ifdef HAVE_REGEXP_FUZZER - if (testFuzzer(fuzzRegexpInit, fuzzRegexp, "seed/regexp/*") != 0) - ret = 1; -#endif -#ifdef HAVE_SCHEMA_FUZZER - if (testFuzzer(fuzzSchemaInit, fuzzSchema, "seed/schema/*") != 0) - ret = 1; -#endif -#ifdef HAVE_URI_FUZZER - if (testFuzzer(fuzzUriInit, fuzzUri, "seed/uri/*") != 0) - ret = 1; -#endif -#ifdef HAVE_VALID_FUZZER - if (testFuzzer(fuzzValidInit, fuzzValid, "seed/valid/*") != 0) - ret = 1; -#endif -#ifdef HAVE_XINCLUDE_FUZZER - if (testFuzzer(fuzzXIncludeInit, fuzzXInclude, "seed/xinclude/*") != 0) - ret = 1; -#endif -#ifdef HAVE_XML_FUZZER - if (testFuzzer(fuzzXmlInit, fuzzXml, "seed/xml/*") != 0) - ret = 1; -#endif -#ifdef HAVE_XPATH_FUZZER - if (testFuzzer(fuzzXPathInit, fuzzXPath, "seed/xpath/*") != 0) - ret = 1; -#endif - - if (ret == 0) - printf("Successfully tested %d inputs\n", numInputs); - - return(ret); -} -
diff --git a/third_party/libxml/src/fuzz/uri.c b/third_party/libxml/src/fuzz/uri.c deleted file mode 100644 index 5bc279f..0000000 --- a/third_party/libxml/src/fuzz/uri.c +++ /dev/null
@@ -1,62 +0,0 @@ -/* - * uri.c: a libFuzzer target to test the URI module. - * - * See Copyright for the status of this software. - */ - -#include <libxml/uri.h> -#include "fuzz.h" - -int -LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED, - char ***argv ATTRIBUTE_UNUSED) { - xmlFuzzMemSetup(); - xmlSetGenericErrorFunc(NULL, xmlFuzzErrorFunc); - - return 0; -} - -int -LLVMFuzzerTestOneInput(const char *data, size_t size) { - xmlURIPtr uri; - size_t maxAlloc; - const char *str1, *str2; - char *copy; - - if (size > 10000) - return(0); - - xmlFuzzDataInit(data, size); - maxAlloc = xmlFuzzReadInt(4) % (size * 8 + 1); - str1 = xmlFuzzReadString(NULL); - str2 = xmlFuzzReadString(NULL); - - xmlFuzzMemSetLimit(maxAlloc); - - uri = xmlParseURI(str1); - xmlFree(xmlSaveUri(uri)); - xmlFreeURI(uri); - - uri = xmlParseURIRaw(str1, 1); - xmlFree(xmlSaveUri(uri)); - xmlFreeURI(uri); - - xmlFree(xmlURIUnescapeString(str1, -1, NULL)); - xmlFree(xmlURIEscape(BAD_CAST str1)); - xmlFree(xmlCanonicPath(BAD_CAST str1)); - xmlFree(xmlPathToURI(BAD_CAST str1)); - - xmlFree(xmlBuildURI(BAD_CAST str2, BAD_CAST str1)); - xmlFree(xmlBuildRelativeURI(BAD_CAST str2, BAD_CAST str1)); - xmlFree(xmlURIEscapeStr(BAD_CAST str1, BAD_CAST str2)); - - copy = (char *) xmlCharStrdup(str1); - xmlNormalizeURIPath(copy); - xmlFree(copy); - - xmlFuzzMemSetLimit(0); - xmlFuzzDataCleanup(); - - return 0; -} -
diff --git a/third_party/libxml/src/fuzz/valid.c b/third_party/libxml/src/fuzz/valid.c deleted file mode 100644 index 9d4a904..0000000 --- a/third_party/libxml/src/fuzz/valid.c +++ /dev/null
@@ -1,108 +0,0 @@ -/* - * valid.c: a libFuzzer target to test DTD validation. - * - * See Copyright for the status of this software. - */ - -#include <libxml/catalog.h> -#include <libxml/parser.h> -#include <libxml/tree.h> -#include <libxml/xmlerror.h> -#include <libxml/xmlreader.h> -#include "fuzz.h" - -int -LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED, - char ***argv ATTRIBUTE_UNUSED) { - xmlFuzzMemSetup(); - xmlInitParser(); -#ifdef LIBXML_CATALOG_ENABLED - xmlInitializeCatalog(); -#endif - xmlSetGenericErrorFunc(NULL, xmlFuzzErrorFunc); - xmlSetExternalEntityLoader(xmlFuzzEntityLoader); - - return 0; -} - -int -LLVMFuzzerTestOneInput(const char *data, size_t size) { - static const size_t maxChunkSize = 128; - xmlDocPtr doc; - xmlParserCtxtPtr ctxt; - xmlValidCtxtPtr vctxt; - xmlTextReaderPtr reader; - const char *docBuffer, *docUrl; - size_t maxAlloc, docSize, consumed, chunkSize; - int opts; - - xmlFuzzDataInit(data, size); - opts = (int) xmlFuzzReadInt(4); - opts &= ~XML_PARSE_XINCLUDE; - opts |= XML_PARSE_DTDVALID; - maxAlloc = xmlFuzzReadInt(4) % (size + 1); - - xmlFuzzReadEntities(); - docBuffer = xmlFuzzMainEntity(&docSize); - docUrl = xmlFuzzMainUrl(); - if (docBuffer == NULL) - goto exit; - - /* Pull parser */ - - xmlFuzzMemSetLimit(maxAlloc); - doc = xmlReadMemory(docBuffer, docSize, docUrl, NULL, opts); - xmlFreeDoc(doc); - - /* Post validation */ - - xmlFuzzMemSetLimit(maxAlloc); - doc = xmlReadMemory(docBuffer, docSize, docUrl, NULL, opts & ~XML_PARSE_DTDVALID); - vctxt = xmlNewValidCtxt(); - xmlValidateDocument(vctxt, doc); - xmlFreeValidCtxt(vctxt); - xmlFreeDoc(doc); - - /* Push parser */ - - xmlFuzzMemSetLimit(maxAlloc); - ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, docUrl); - if (ctxt == NULL) - goto exit; - xmlCtxtUseOptions(ctxt, opts); - - for (consumed = 0; consumed < docSize; consumed += chunkSize) { - chunkSize = docSize - consumed; - if (chunkSize > maxChunkSize) - chunkSize = maxChunkSize; - xmlParseChunk(ctxt, docBuffer + consumed, chunkSize, 0); - } - - xmlParseChunk(ctxt, NULL, 0, 1); - xmlFreeDoc(ctxt->myDoc); - xmlFreeParserCtxt(ctxt); - - /* Reader */ - - xmlFuzzMemSetLimit(maxAlloc); - reader = xmlReaderForMemory(docBuffer, docSize, NULL, NULL, opts); - if (reader == NULL) - goto exit; - while (xmlTextReaderRead(reader) == 1) { - if (xmlTextReaderNodeType(reader) == XML_ELEMENT_NODE) { - int i, n = xmlTextReaderAttributeCount(reader); - for (i=0; i<n; i++) { - xmlTextReaderMoveToAttributeNo(reader, i); - while (xmlTextReaderReadAttributeValue(reader) == 1); - } - } - } - xmlFreeTextReader(reader); - -exit: - xmlFuzzMemSetLimit(0); - xmlFuzzDataCleanup(); - xmlResetLastError(); - return(0); -} -
diff --git a/third_party/libxml/src/fuzz/xinclude.c b/third_party/libxml/src/fuzz/xinclude.c deleted file mode 100644 index 18de3f4..0000000 --- a/third_party/libxml/src/fuzz/xinclude.c +++ /dev/null
@@ -1,79 +0,0 @@ -/* - * xinclude.c: a libFuzzer target to test the XInclude engine. - * - * See Copyright for the status of this software. - */ - -#include <libxml/catalog.h> -#include <libxml/parser.h> -#include <libxml/tree.h> -#include <libxml/xmlerror.h> -#include <libxml/xinclude.h> -#include <libxml/xmlreader.h> -#include "fuzz.h" - -int -LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED, - char ***argv ATTRIBUTE_UNUSED) { - xmlFuzzMemSetup(); - xmlInitParser(); -#ifdef LIBXML_CATALOG_ENABLED - xmlInitializeCatalog(); -#endif - xmlSetGenericErrorFunc(NULL, xmlFuzzErrorFunc); - xmlSetExternalEntityLoader(xmlFuzzEntityLoader); - - return 0; -} - -int -LLVMFuzzerTestOneInput(const char *data, size_t size) { - xmlDocPtr doc; - xmlTextReaderPtr reader; - const char *docBuffer, *docUrl; - size_t maxAlloc, docSize; - int opts; - - xmlFuzzDataInit(data, size); - opts = (int) xmlFuzzReadInt(4); - opts &= ~XML_PARSE_DTDVALID; - opts |= XML_PARSE_XINCLUDE; - maxAlloc = xmlFuzzReadInt(4) % (size + 1); - - xmlFuzzReadEntities(); - docBuffer = xmlFuzzMainEntity(&docSize); - docUrl = xmlFuzzMainUrl(); - if (docBuffer == NULL) - goto exit; - - /* Pull parser */ - - xmlFuzzMemSetLimit(maxAlloc); - doc = xmlReadMemory(docBuffer, docSize, docUrl, NULL, opts); - xmlXIncludeProcessFlags(doc, opts); - xmlFreeDoc(doc); - - /* Reader */ - - xmlFuzzMemSetLimit(maxAlloc); - reader = xmlReaderForMemory(docBuffer, docSize, NULL, NULL, opts); - if (reader == NULL) - goto exit; - while (xmlTextReaderRead(reader) == 1) { - if (xmlTextReaderNodeType(reader) == XML_ELEMENT_NODE) { - int i, n = xmlTextReaderAttributeCount(reader); - for (i=0; i<n; i++) { - xmlTextReaderMoveToAttributeNo(reader, i); - while (xmlTextReaderReadAttributeValue(reader) == 1); - } - } - } - xmlFreeTextReader(reader); - -exit: - xmlFuzzMemSetLimit(0); - xmlFuzzDataCleanup(); - xmlResetLastError(); - return(0); -} -
diff --git a/third_party/libxml/src/fuzz/xml.c b/third_party/libxml/src/fuzz/xml.c deleted file mode 100644 index 0ac765d..0000000 --- a/third_party/libxml/src/fuzz/xml.c +++ /dev/null
@@ -1,101 +0,0 @@ -/* - * xml.c: a libFuzzer target to test several XML parser interfaces. - * - * See Copyright for the status of this software. - */ - -#include <libxml/catalog.h> -#include <libxml/parser.h> -#include <libxml/tree.h> -#include <libxml/xmlerror.h> -#include <libxml/xmlreader.h> -#include "fuzz.h" - -int -LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED, - char ***argv ATTRIBUTE_UNUSED) { - xmlFuzzMemSetup(); - xmlInitParser(); -#ifdef LIBXML_CATALOG_ENABLED - xmlInitializeCatalog(); -#endif - xmlSetGenericErrorFunc(NULL, xmlFuzzErrorFunc); - xmlSetExternalEntityLoader(xmlFuzzEntityLoader); - - return 0; -} - -int -LLVMFuzzerTestOneInput(const char *data, size_t size) { - static const size_t maxChunkSize = 128; - xmlDocPtr doc; - xmlParserCtxtPtr ctxt; - xmlTextReaderPtr reader; - xmlChar *out; - const char *docBuffer, *docUrl; - size_t maxAlloc, docSize, consumed, chunkSize; - int opts, outSize; - - xmlFuzzDataInit(data, size); - opts = (int) xmlFuzzReadInt(4); - opts &= ~XML_PARSE_XINCLUDE & ~XML_PARSE_DTDVALID; - maxAlloc = xmlFuzzReadInt(4) % (size + 1); - - xmlFuzzReadEntities(); - docBuffer = xmlFuzzMainEntity(&docSize); - docUrl = xmlFuzzMainUrl(); - if (docBuffer == NULL) - goto exit; - - /* Pull parser */ - - xmlFuzzMemSetLimit(maxAlloc); - doc = xmlReadMemory(docBuffer, docSize, docUrl, NULL, opts); - /* Also test the serializer. */ - xmlDocDumpMemory(doc, &out, &outSize); - xmlFree(out); - xmlFreeDoc(doc); - - /* Push parser */ - - xmlFuzzMemSetLimit(maxAlloc); - ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, docUrl); - if (ctxt == NULL) - goto exit; - xmlCtxtUseOptions(ctxt, opts); - - for (consumed = 0; consumed < docSize; consumed += chunkSize) { - chunkSize = docSize - consumed; - if (chunkSize > maxChunkSize) - chunkSize = maxChunkSize; - xmlParseChunk(ctxt, docBuffer + consumed, chunkSize, 0); - } - - xmlParseChunk(ctxt, NULL, 0, 1); - xmlFreeDoc(ctxt->myDoc); - xmlFreeParserCtxt(ctxt); - - /* Reader */ - - xmlFuzzMemSetLimit(maxAlloc); - reader = xmlReaderForMemory(docBuffer, docSize, NULL, NULL, opts); - if (reader == NULL) - goto exit; - while (xmlTextReaderRead(reader) == 1) { - if (xmlTextReaderNodeType(reader) == XML_ELEMENT_NODE) { - int i, n = xmlTextReaderAttributeCount(reader); - for (i=0; i<n; i++) { - xmlTextReaderMoveToAttributeNo(reader, i); - while (xmlTextReaderReadAttributeValue(reader) == 1); - } - } - } - xmlFreeTextReader(reader); - -exit: - xmlFuzzMemSetLimit(0); - xmlFuzzDataCleanup(); - xmlResetLastError(); - return(0); -} -
diff --git a/third_party/libxml/src/fuzz/xml.dict b/third_party/libxml/src/fuzz/xml.dict deleted file mode 100644 index a539e6a..0000000 --- a/third_party/libxml/src/fuzz/xml.dict +++ /dev/null
@@ -1,89 +0,0 @@ -xml_decl="<?xml version='1.0'?>" -xml_decl_latin1="<?xml version='1.0' encoding='ISO-8859-1'?>" - -elem_start_end="<a></a>" -elem_empty="<a/>" -elem_ns_start_end="<a:a xmlns:a='a'></a:a>" -elem_ns_empty="<a:a xmlns:a='a'/>" - -attr=" a='a'" - -ns_decl=" xmlns:a='a'" -ns_default=" xmlns='a'" -ns_prefix="a:" - -cdata_section="<![CDATA[ ]]>" - -comment="<!-- -->" - -pi="<?a?>" - -elem_decl_any="<!ELEMENT a ANY>" -elem_decl_empty="<!ELEMENT a EMPTY>" -elem_decl_children="<!ELEMENT a (a)>" -elem_decl_mixed="<!ELEMENT a (#PCDATA|a)>" -elem_children_choice="|a" -elem_children_seq=",a" -elem_children_sub_choice="|(a)" -elem_children_sub_seq=",(a)" -elem_quant_any="*" -elem_quant_opt="?" -elem_quant_some="+" - -attlist_decl_cdata_req="<!ATTLIST a a CDATA #REQUIRED>" -attlist_decl_cdata_imp="<!ATTLIST a a CDATA #IMPLIED>" -attlist_decl_cdata_def="<!ATTLIST a a CDATA 'a'>" -attlist_decl_cdata_fix="<!ATTLIST a a CDATA #FIXED 'a'>" -attlist_decl_id="<!ATTLIST a a ID #IMPLIED>" -attlist_decl_idref="<!ATTLIST a a IDREF #IMPLIED>" -attlist_decl_idrefs="<!ATTLIST a a IDREFS #IMPLIED>" -attlist_decl_entity="<!ATTLIST a a ENTITY #IMPLIED>" -attlist_decl_entities="<!ATTLIST a a ENTITIES #IMPLIED>" -attlist_decl_nmtoken="<!ATTLIST a a NMTOKEN #IMPLIED>" -attlist_decl_nmtokens="<!ATTLIST a a NMTOKENS #IMPLIED>" -attlist_decl_enum="<!ATTLIST a a (a) #IMPLIED>" -attlist_decl_notation="<!ATTLIST a a NOTATION (a) #IMPLIED>" - -include_sect="<![INCLUDE[ ]]>" -ignore_sect="<![IGNORE[ ]]>" - -ge_decl="<!ENTITY a 'a'>" -ge_decl_system="<!ENTITY a SYSTEM 'a'>" -ge_decl_system_ndata="<!ENTITY a SYSTEM 'a' NDATA a>" -ge_decl_public="<!ENTITY a PUBLIC 'a' 'a'>" -ge_decl_public_ndata="<!ENTITY a PUBLIC 'a' 'a' NDATA a>" - -pe_decl="<!ENTITY % a 'a'>" -pe_decl_system="<!ENTITY % a SYSTEM 'a'>" -pe_decl_public="<!ENTITY % a PUBLIC 'a' 'a'>" - -char_ref_dec="<" -char_ref_hex="<" -char_ref_quoted="&#60;" - -ge_ref_lt="<" -ge_ref_gt=">" -ge_ref_amp="&" -ge_ref_apos="'" -ge_ref_quot=""" -ge_ref="&a;" -ge_ref_quoted="&a;" - -pe_ref="%a;" -pe_ref_quoted="%a;" - -notation_decl_public="<!NOTATION a PUBLIC 'a'>" -notation_decl_system="<!NOTATION a SYSTEM 'a'>" - -cs_utf8="UTF-8" -cs_utf16="UTF-16" -cs_utf16le="UTF-16LE" -cs_utf16be="UTF-16BE" -cs_ucs2="UCS-2" -cs_ucs4="UCS-4" -cs_latin1="ISO-8859-1" -cs_ascii="ASCII" -cs_ebcdic="EBCDIC" -cs_iso2022jp="ISO-2022-JP" -cs_shift_jis="SHIFT_JIS" -cs_euc_jp="EUC-JP"
diff --git a/third_party/libxml/src/fuzz/xpath.c b/third_party/libxml/src/fuzz/xpath.c deleted file mode 100644 index a5eb70b2..0000000 --- a/third_party/libxml/src/fuzz/xpath.c +++ /dev/null
@@ -1,61 +0,0 @@ -/* - * xpath.c: a libFuzzer target to test XPath and XPointer expressions. - * - * See Copyright for the status of this software. - */ - -#include <libxml/parser.h> -#include <libxml/xpointer.h> -#include "fuzz.h" - -int -LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED, - char ***argv ATTRIBUTE_UNUSED) { - xmlFuzzMemSetup(); - xmlInitParser(); - xmlSetGenericErrorFunc(NULL, xmlFuzzErrorFunc); - - return 0; -} - -int -LLVMFuzzerTestOneInput(const char *data, size_t size) { - xmlDocPtr doc; - const char *expr, *xml; - size_t maxAlloc, exprSize, xmlSize; - - if (size > 10000) - return(0); - - xmlFuzzDataInit(data, size); - - maxAlloc = xmlFuzzReadInt(4) % (size + 1); - expr = xmlFuzzReadString(&exprSize); - xml = xmlFuzzReadString(&xmlSize); - - /* Recovery mode allows more input to be fuzzed. */ - doc = xmlReadMemory(xml, xmlSize, NULL, NULL, XML_PARSE_RECOVER); - if (doc != NULL) { - xmlXPathContextPtr xpctxt; - - xmlFuzzMemSetLimit(maxAlloc); - - xpctxt = xmlXPathNewContext(doc); - if (xpctxt != NULL) { - /* Operation limit to avoid timeout */ - xpctxt->opLimit = 500000; - - xmlXPathFreeObject(xmlXPtrEval(BAD_CAST expr, xpctxt)); - xmlXPathFreeContext(xpctxt); - } - - xmlFuzzMemSetLimit(0); - xmlFreeDoc(doc); - } - - xmlFuzzDataCleanup(); - xmlResetLastError(); - - return(0); -} -
diff --git a/third_party/libxml/src/fuzz/xpath.dict b/third_party/libxml/src/fuzz/xpath.dict deleted file mode 100644 index 4fe375f..0000000 --- a/third_party/libxml/src/fuzz/xpath.dict +++ /dev/null
@@ -1,94 +0,0 @@ -# XML - -elem_a="<a></a>" -elem_b="<b></b>" -elem_c="<c></c>" -elem_d="<d></d>" -elem_empty="<a/>" -elem_ns_a="<a:a xmlns:a='a'></a:a>" -elem_ns_b="<b:b xmlns:b='b'></b:b>" - -attr_a=" a='a'" -attr_b=" b='b'" - -ns_decl=" xmlns:a='a'" -ns_default=" xmlns='a'" -ns_prefix_a="a:" -ns_prefix_b="b:" - -cdata_section="<![CDATA[ ]]>" - -comment="<!-- -->" - -pi="<?a?>" - -# XPath - -axis_ancestor="ancestor::" -axis_ancestor_or_self="ancestor-or-self::" -axis_attribute="attribute::" -axis_attribute_abbrev="@" -axis_child="child::" -axis_descendant="descendant::" -axis_descendant_or_self="descendant-or-self::" -axis_following="following::" -axis_following_sibling="following-sibling::" -axis_namespace="namespace::" -axis_parent="parent::" -axis_preceding="preceding::" -axis_preceding_siblings="preceding-sibling::" -axis_self="self::" - -node_test_ns="a:" - -val_num="=(1.0)" -val_str_sq="=('a')" -val_str_dq="=(\"a\")" -val_node_set="=(*)" -val_elem="=(b)" - -step_root="/" -step_descendant="//" -step_any="//*" -step_any_l="*//" -step_elem="//b" -step_ns_elem="//a:a" -step_comment="//comment()" -step_node="//node()" -step_node_l="node()//" -step_pi="//processing-instruction()" -step_text="//text()" -step_parent="../" - -op_plus="+1" -op_minus=" - 1" -op_neg="-" -op_mul="*1" -op_div=" div 1" -op_mod=" mod 1" -op_and=" and 1" -op_or=" or 1" -op_ne="!=1" -op_lt="<1" -op_gt=">1" -op_le="<=1" -op_ge=">=1" -op_predicate_num="[1]" -op_predicate_last="[last()]" -op_predicate_str="['a']" -op_predicate="[1=1]" -op_arg_num=",1" -op_arg_str=",'a'" -op_arg_node=",*" -op_union="|//b" - -var_num="=$f" -var_bool="=$b" -var_str="=$s" -var_node_set="=$n" - -# Unicode - -utf8_2="\xC3\x84" -utf8_3="\xE2\x80\x9C" -utf8_4="\xF0\x9F\x98\x80"
diff --git a/tools/clang/plugins/RawPtrHelpers.cpp b/tools/clang/plugins/RawPtrHelpers.cpp index 8cc12c82..310a332 100644 --- a/tools/clang/plugins/RawPtrHelpers.cpp +++ b/tools/clang/plugins/RawPtrHelpers.cpp
@@ -167,4 +167,122 @@ .bind("affectedFieldDecl"); return field_decl_matcher; -} \ No newline at end of file +} + +// If |field_decl| declares a field in an implicit template specialization, then +// finds and returns the corresponding FieldDecl from the template definition. +// Otherwise, just returns the original |field_decl| argument. +const clang::FieldDecl* GetExplicitDecl(const clang::FieldDecl* field_decl) { + if (field_decl->isAnonymousStructOrUnion()) { + return field_decl; // Safe fallback - |field_decl| is not a pointer field. + } + + const clang::CXXRecordDecl* record_decl = + clang::dyn_cast<clang::CXXRecordDecl>(field_decl->getParent()); + if (!record_decl) { + return field_decl; // Non-C++ records are never template instantiations. + } + + const clang::CXXRecordDecl* pattern_decl = + record_decl->getTemplateInstantiationPattern(); + if (!pattern_decl) { + return field_decl; // |pattern_decl| is not a template instantiation. + } + + if (record_decl->getTemplateSpecializationKind() != + clang::TemplateSpecializationKind::TSK_ImplicitInstantiation) { + return field_decl; // |field_decl| was in an *explicit* specialization. + } + + // Find the field decl with the same name in |pattern_decl|. + clang::DeclContextLookupResult lookup_result = + pattern_decl->lookup(field_decl->getDeclName()); + assert(!lookup_result.empty()); + const clang::NamedDecl* found_decl = lookup_result.front(); + assert(found_decl); + field_decl = clang::dyn_cast<clang::FieldDecl>(found_decl); + assert(field_decl); + return field_decl; +} + +// If |original_param| declares a parameter in an implicit template +// specialization of a function or method, then finds and returns the +// corresponding ParmVarDecl from the template definition. Otherwise, just +// returns the |original_param| argument. +// +// Note: nullptr may be returned in rare, unimplemented cases. +const clang::ParmVarDecl* GetExplicitDecl( + const clang::ParmVarDecl* original_param) { + const clang::FunctionDecl* original_func = + clang::dyn_cast<clang::FunctionDecl>(original_param->getDeclContext()); + if (!original_func) { + // |!original_func| may happen when the ParmVarDecl is part of a + // FunctionType, but not part of a FunctionDecl: + // base::RepeatingCallback<void(int parm_var_decl_here)> + // + // In theory, |parm_var_decl_here| can also represent an implicit template + // specialization in this scenario. OTOH, it should be rare + shouldn't + // matter for this rewriter, so for now let's just return the + // |original_param|. + // + // TODO: Implement support for this scenario. + return nullptr; + } + + const clang::FunctionDecl* pattern_func = + original_func->getTemplateInstantiationPattern(); + if (!pattern_func) { + // |original_func| is not a template instantiation - return the + // |original_param|. + return original_param; + } + + // See if |pattern_func| has a parameter that is a template parameter pack. + bool has_param_pack = false; + unsigned int index_of_param_pack = std::numeric_limits<unsigned int>::max(); + for (unsigned int i = 0; i < pattern_func->getNumParams(); i++) { + const clang::ParmVarDecl* pattern_param = pattern_func->getParamDecl(i); + if (!pattern_param->isParameterPack()) { + continue; + } + + if (has_param_pack) { + // TODO: Implement support for multiple parameter packs. + return nullptr; + } + + has_param_pack = true; + index_of_param_pack = i; + } + + // Find and return the corresponding ParmVarDecl from |pattern_func|. + unsigned int original_index = original_param->getFunctionScopeIndex(); + unsigned int pattern_index = std::numeric_limits<unsigned int>::max(); + if (!has_param_pack) { + pattern_index = original_index; + } else { + // |original_func| has parameters that look like this: + // l1, l2, l3, p1, p2, p3, t1, t2, t3 + // where + // lN is a leading, non-pack parameter + // pN is an expansion of a template parameter pack + // tN is a trailing, non-pack parameter + // Using the knowledge above, let's adjust |pattern_index| as needed. + unsigned int leading_param_num = index_of_param_pack; // How many |lN|. + unsigned int pack_expansion_num = // How many |pN| above. + original_func->getNumParams() - pattern_func->getNumParams() + 1; + if (original_index < leading_param_num) { + // |original_param| is a leading, non-pack parameter. + pattern_index = original_index; + } else if (leading_param_num <= original_index && + original_index < (leading_param_num + pack_expansion_num)) { + // |original_param| is an expansion of a template pack parameter. + pattern_index = index_of_param_pack; + } else if ((leading_param_num + pack_expansion_num) <= original_index) { + // |original_param| is a trailing, non-pack parameter. + pattern_index = original_index - pack_expansion_num + 1; + } + } + assert(pattern_index < pattern_func->getNumParams()); + return pattern_func->getParamDecl(pattern_index); +}
diff --git a/tools/clang/plugins/RawPtrHelpers.h b/tools/clang/plugins/RawPtrHelpers.h index f5f2058f..a81aeb0 100644 --- a/tools/clang/plugins/RawPtrHelpers.h +++ b/tools/clang/plugins/RawPtrHelpers.h
@@ -208,4 +208,136 @@ const FilterFile* paths_to_exclude, const FilterFile* fields_to_exclude); +// If `field_decl` declares a field in an implicit template specialization, then +// finds and returns the corresponding FieldDecl from the template definition. +// Otherwise, just returns the original `field_decl` argument. +const clang::FieldDecl* GetExplicitDecl(const clang::FieldDecl* field_decl); + +// Given: +// template <typename T> +// class MyTemplate { +// T field; // This is an explicit field declaration. +// }; +// void foo() { +// // This creates implicit template specialization for MyTemplate, +// // including an implicit `field` declaration. +// MyTemplate<int> v; +// v.field = 123; +// } +// and +// innerMatcher that will match the explicit `T field` declaration (but not +// necessarily the implicit template declarations), +// hasExplicitFieldDecl(innerMatcher) will match both explicit and implicit +// field declarations. +// +// For example, `member_expr_matcher` below will match `v.field` in the example +// above, even though the type of `v.field` is `int`, rather than `T` (matched +// by substTemplateTypeParmType()): +// auto explicit_field_decl_matcher = +// fieldDecl(hasType(substTemplateTypeParmType())); +// auto member_expr_matcher = memberExpr(member(fieldDecl( +// hasExplicitFieldDecl(explicit_field_decl_matcher)))) +AST_MATCHER_P(clang::FieldDecl, + hasExplicitFieldDecl, + clang::ast_matchers::internal::Matcher<clang::FieldDecl>, + InnerMatcher) { + const clang::FieldDecl* explicit_field_decl = GetExplicitDecl(&Node); + return InnerMatcher.matches(*explicit_field_decl, Finder, Builder); +} + +// If `original_param` declares a parameter in an implicit template +// specialization of a function or method, then finds and returns the +// corresponding ParmVarDecl from the template definition. Otherwise, just +// returns the `original_param` argument. +// +// Note: nullptr may be returned in rare, unimplemented cases. +const clang::ParmVarDecl* GetExplicitDecl( + const clang::ParmVarDecl* original_param); + +AST_MATCHER_P(clang::ParmVarDecl, + hasExplicitParmVarDecl, + clang::ast_matchers::internal::Matcher<clang::ParmVarDecl>, + InnerMatcher) { + const clang::ParmVarDecl* explicit_param = GetExplicitDecl(&Node); + if (!explicit_param) { + // Rare, unimplemented case - fall back to returning "no match". + return false; + } + + return InnerMatcher.matches(*explicit_param, Finder, Builder); +} + +// forEachInitExprWithFieldDecl matches InitListExpr if it +// 1) evaluates to a RecordType +// 2) has a InitListExpr + FieldDecl pair that matches the submatcher args. +// +// forEachInitExprWithFieldDecl is based on and very similar to the builtin +// forEachArgumentWithParam matcher. +AST_MATCHER_P2(clang::InitListExpr, + forEachInitExprWithFieldDecl, + clang::ast_matchers::internal::Matcher<clang::Expr>, + init_expr_matcher, + clang::ast_matchers::internal::Matcher<clang::FieldDecl>, + field_decl_matcher) { + const clang::InitListExpr& init_list_expr = Node; + const clang::Type* type = init_list_expr.getType() + .getDesugaredType(Finder->getASTContext()) + .getTypePtrOrNull(); + if (!type) { + return false; + } + const clang::CXXRecordDecl* record_decl = type->getAsCXXRecordDecl(); + if (!record_decl) { + return false; + } + + bool is_matching = false; + clang::ast_matchers::internal::BoundNodesTreeBuilder result; + const llvm::SmallVector<const clang::FieldDecl*> field_decls( + record_decl->fields()); + for (unsigned i = 0; i < init_list_expr.getNumInits(); i++) { + const clang::Expr* expr = init_list_expr.getInit(i); + + const clang::FieldDecl* field_decl = nullptr; + if (const clang::ImplicitValueInitExpr* implicit_value_init_expr = + clang::dyn_cast<clang::ImplicitValueInitExpr>(expr)) { + continue; // Do not match implicit value initializers. + } else if (const clang::DesignatedInitExpr* designated_init_expr = + clang::dyn_cast<clang::DesignatedInitExpr>(expr)) { + // Nested designators are unsupported by C++. + if (designated_init_expr->size() != 1) { + break; + } + expr = designated_init_expr->getInit(); + field_decl = designated_init_expr->getDesignator(0)->getField(); + } else { + if (i >= field_decls.size()) { + break; + } + field_decl = field_decls[i]; + } + + clang::ast_matchers::internal::BoundNodesTreeBuilder field_matches( + *Builder); + if (field_decl_matcher.matches(*field_decl, Finder, &field_matches)) { + clang::ast_matchers::internal::BoundNodesTreeBuilder expr_matches( + field_matches); + if (init_expr_matcher.matches(*expr, Finder, &expr_matches)) { + result.addMatch(expr_matches); + is_matching = true; + } + } + } + + *Builder = std::move(result); + return is_matching; +} + +AST_POLYMORPHIC_MATCHER(isInMacroLocation, + AST_POLYMORPHIC_SUPPORTED_TYPES(clang::Decl, + clang::Stmt, + clang::TypeLoc)) { + return Node.getBeginLoc().isMacroID(); +} + #endif // TOOLS_CLANG_PLUGINS_RAWPTRHELPERS_H_
diff --git a/tools/clang/rewrite_raw_ptr_fields/RewriteRawPtrFields.cpp b/tools/clang/rewrite_raw_ptr_fields/RewriteRawPtrFields.cpp index f41c1978..e118f2c 100644 --- a/tools/clang/rewrite_raw_ptr_fields/RewriteRawPtrFields.cpp +++ b/tools/clang/rewrite_raw_ptr_fields/RewriteRawPtrFields.cpp
@@ -266,172 +266,6 @@ return Node.isTrivial(); } -AST_POLYMORPHIC_MATCHER(isInMacroLocation, - AST_POLYMORPHIC_SUPPORTED_TYPES(clang::Decl, - clang::Stmt, - clang::TypeLoc)) { - return Node.getBeginLoc().isMacroID(); -} - -// If |field_decl| declares a field in an implicit template specialization, then -// finds and returns the corresponding FieldDecl from the template definition. -// Otherwise, just returns the original |field_decl| argument. -const clang::FieldDecl* GetExplicitDecl(const clang::FieldDecl* field_decl) { - if (field_decl->isAnonymousStructOrUnion()) - return field_decl; // Safe fallback - |field_decl| is not a pointer field. - - const clang::CXXRecordDecl* record_decl = - clang::dyn_cast<clang::CXXRecordDecl>(field_decl->getParent()); - if (!record_decl) - return field_decl; // Non-C++ records are never template instantiations. - - const clang::CXXRecordDecl* pattern_decl = - record_decl->getTemplateInstantiationPattern(); - if (!pattern_decl) - return field_decl; // |pattern_decl| is not a template instantiation. - - if (record_decl->getTemplateSpecializationKind() != - clang::TemplateSpecializationKind::TSK_ImplicitInstantiation) { - return field_decl; // |field_decl| was in an *explicit* specialization. - } - - // Find the field decl with the same name in |pattern_decl|. - clang::DeclContextLookupResult lookup_result = - pattern_decl->lookup(field_decl->getDeclName()); - assert(!lookup_result.empty()); - const clang::NamedDecl* found_decl = lookup_result.front(); - assert(found_decl); - field_decl = clang::dyn_cast<clang::FieldDecl>(found_decl); - assert(field_decl); - return field_decl; -} - -// Given: -// template <typename T> -// class MyTemplate { -// T field; // This is an explicit field declaration. -// }; -// void foo() { -// // This creates implicit template specialization for MyTemplate, -// // including an implicit |field| declaration. -// MyTemplate<int> v; -// v.field = 123; -// } -// and -// innerMatcher that will match the explicit |T field| declaration (but not -// necessarily the implicit template declarations), -// hasExplicitFieldDecl(innerMatcher) will match both explicit and implicit -// field declarations. -// -// For example, |member_expr_matcher| below will match |v.field| in the example -// above, even though the type of |v.field| is |int|, rather than |T| (matched -// by substTemplateTypeParmType()): -// auto explicit_field_decl_matcher = -// fieldDecl(hasType(substTemplateTypeParmType())); -// auto member_expr_matcher = memberExpr(member(fieldDecl( -// hasExplicitFieldDecl(explicit_field_decl_matcher)))) -AST_MATCHER_P(clang::FieldDecl, - hasExplicitFieldDecl, - clang::ast_matchers::internal::Matcher<clang::FieldDecl>, - InnerMatcher) { - const clang::FieldDecl* explicit_field_decl = GetExplicitDecl(&Node); - return InnerMatcher.matches(*explicit_field_decl, Finder, Builder); -} - -// If |original_param| declares a parameter in an implicit template -// specialization of a function or method, then finds and returns the -// corresponding ParmVarDecl from the template definition. Otherwise, just -// returns the |original_param| argument. -// -// Note: nullptr may be returned in rare, unimplemented cases. -const clang::ParmVarDecl* GetExplicitDecl( - const clang::ParmVarDecl* original_param) { - const clang::FunctionDecl* original_func = - clang::dyn_cast<clang::FunctionDecl>(original_param->getDeclContext()); - if (!original_func) { - // |!original_func| may happen when the ParmVarDecl is part of a - // FunctionType, but not part of a FunctionDecl: - // base::RepeatingCallback<void(int parm_var_decl_here)> - // - // In theory, |parm_var_decl_here| can also represent an implicit template - // specialization in this scenario. OTOH, it should be rare + shouldn't - // matter for this rewriter, so for now let's just return the - // |original_param|. - // - // TODO: Implement support for this scenario. - return nullptr; - } - - const clang::FunctionDecl* pattern_func = - original_func->getTemplateInstantiationPattern(); - if (!pattern_func) { - // |original_func| is not a template instantiation - return the - // |original_param|. - return original_param; - } - - // See if |pattern_func| has a parameter that is a template parameter pack. - bool has_param_pack = false; - unsigned int index_of_param_pack = std::numeric_limits<unsigned int>::max(); - for (unsigned int i = 0; i < pattern_func->getNumParams(); i++) { - const clang::ParmVarDecl* pattern_param = pattern_func->getParamDecl(i); - if (!pattern_param->isParameterPack()) - continue; - - if (has_param_pack) { - // TODO: Implement support for multiple parameter packs. - return nullptr; - } - - has_param_pack = true; - index_of_param_pack = i; - } - - // Find and return the corresponding ParmVarDecl from |pattern_func|. - unsigned int original_index = original_param->getFunctionScopeIndex(); - unsigned int pattern_index = std::numeric_limits<unsigned int>::max(); - if (!has_param_pack) { - pattern_index = original_index; - } else { - // |original_func| has parameters that look like this: - // l1, l2, l3, p1, p2, p3, t1, t2, t3 - // where - // lN is a leading, non-pack parameter - // pN is an expansion of a template parameter pack - // tN is a trailing, non-pack parameter - // Using the knowledge above, let's adjust |pattern_index| as needed. - unsigned int leading_param_num = index_of_param_pack; // How many |lN|. - unsigned int pack_expansion_num = // How many |pN| above. - original_func->getNumParams() - pattern_func->getNumParams() + 1; - if (original_index < leading_param_num) { - // |original_param| is a leading, non-pack parameter. - pattern_index = original_index; - } else if (leading_param_num <= original_index && - original_index < (leading_param_num + pack_expansion_num)) { - // |original_param| is an expansion of a template pack parameter. - pattern_index = index_of_param_pack; - } else if ((leading_param_num + pack_expansion_num) <= original_index) { - // |original_param| is a trailing, non-pack parameter. - pattern_index = original_index - pack_expansion_num + 1; - } - } - assert(pattern_index < pattern_func->getNumParams()); - return pattern_func->getParamDecl(pattern_index); -} - -AST_MATCHER_P(clang::ParmVarDecl, - hasExplicitParmVarDecl, - clang::ast_matchers::internal::Matcher<clang::ParmVarDecl>, - InnerMatcher) { - const clang::ParmVarDecl* explicit_param = GetExplicitDecl(&Node); - if (!explicit_param) { - // Rare, unimplemented case - fall back to returning "no match". - return false; - } - - return InnerMatcher.matches(*explicit_param, Finder, Builder); -} - // Returns |true| if and only if: // 1. |a| and |b| are in the same file (e.g. |false| is returned if any location // is within macro scratch space or a similar location; similarly |false| is @@ -548,68 +382,6 @@ return false; } -// forEachInitExprWithFieldDecl matches InitListExpr if it -// 1) evaluates to a RecordType -// 2) has a InitListExpr + FieldDecl pair that matches the submatcher args. -// -// forEachInitExprWithFieldDecl is based on and very similar to the builtin -// forEachArgumentWithParam matcher. -AST_MATCHER_P2(clang::InitListExpr, - forEachInitExprWithFieldDecl, - clang::ast_matchers::internal::Matcher<clang::Expr>, - init_expr_matcher, - clang::ast_matchers::internal::Matcher<clang::FieldDecl>, - field_decl_matcher) { - const clang::InitListExpr& init_list_expr = Node; - const clang::Type* type = init_list_expr.getType() - .getDesugaredType(Finder->getASTContext()) - .getTypePtrOrNull(); - if (!type) - return false; - const clang::CXXRecordDecl* record_decl = type->getAsCXXRecordDecl(); - if (!record_decl) - return false; - - bool is_matching = false; - clang::ast_matchers::internal::BoundNodesTreeBuilder result; - const llvm::SmallVector<const clang::FieldDecl*> field_decls( - record_decl->fields()); - for (unsigned i = 0; i < init_list_expr.getNumInits(); i++) { - const clang::Expr* expr = init_list_expr.getInit(i); - - const clang::FieldDecl* field_decl = nullptr; - if (const clang::ImplicitValueInitExpr* implicit_value_init_expr = - clang::dyn_cast<clang::ImplicitValueInitExpr>(expr)) { - continue; // Do not match implicit value initializers. - } else if (const clang::DesignatedInitExpr* designated_init_expr = - clang::dyn_cast<clang::DesignatedInitExpr>(expr)) { - // Nested designators are unsupported by C++. - if (designated_init_expr->size() != 1) - break; - expr = designated_init_expr->getInit(); - field_decl = designated_init_expr->getDesignator(0)->getField(); - } else { - if (i >= field_decls.size()) - break; - field_decl = field_decls[i]; - } - - clang::ast_matchers::internal::BoundNodesTreeBuilder field_matches( - *Builder); - if (field_decl_matcher.matches(*field_decl, Finder, &field_matches)) { - clang::ast_matchers::internal::BoundNodesTreeBuilder expr_matches( - field_matches); - if (init_expr_matcher.matches(*expr, Finder, &expr_matches)) { - result.addMatch(expr_matches); - is_matching = true; - } - } - } - - *Builder = std::move(result); - return is_matching; -} - class FieldDeclRewriter : public MatchFinder::MatchCallback { public: explicit FieldDeclRewriter(OutputHelper* output_helper,
diff --git a/tools/clang/rewrite_templated_container_fields/CMakeLists.txt b/tools/clang/rewrite_templated_container_fields/CMakeLists.txt new file mode 100644 index 0000000..23e450d --- /dev/null +++ b/tools/clang/rewrite_templated_container_fields/CMakeLists.txt
@@ -0,0 +1,31 @@ +set(LLVM_LINK_COMPONENTS + BitReader + MCParser + Option + X86AsmParser + X86CodeGen + ) + +add_llvm_executable(rewrite_templated_container_fields + RewriteTemplatedPtrFields.cpp + ../plugins/Util.cpp + ../plugins/RawPtrHelpers.cpp + ) + +target_link_libraries(rewrite_templated_container_fields + clangAST + clangASTMatchers + clangAnalysis + clangBasic + clangDriver + clangEdit + clangFrontend + clangLex + clangParse + clangSema + clangSerialization + clangTooling + ) + +cr_install(TARGETS rewrite_templated_container_fields RUNTIME DESTINATION bin) +target_include_directories(rewrite_templated_container_fields PUBLIC "../plugins")
diff --git a/tools/clang/rewrite_templated_container_fields/OWNERS b/tools/clang/rewrite_templated_container_fields/OWNERS new file mode 100644 index 0000000..0ab4d2b --- /dev/null +++ b/tools/clang/rewrite_templated_container_fields/OWNERS
@@ -0,0 +1 @@ +ahijazi@chromium.org \ No newline at end of file
diff --git a/tools/clang/rewrite_templated_container_fields/RewriteTemplatedPtrFields.cpp b/tools/clang/rewrite_templated_container_fields/RewriteTemplatedPtrFields.cpp new file mode 100644 index 0000000..8fee0cc --- /dev/null +++ b/tools/clang/rewrite_templated_container_fields/RewriteTemplatedPtrFields.cpp
@@ -0,0 +1,1234 @@ +// 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. + +// This is the implementation of a clang tool that rewrites containers of +// pointer fields into raw_ptr<T>: +// std::vector<Pointee*> field_ +// becomes: +// std::vector<raw_ptr<Pointee>> field_ +// +// Note that the tool emits two kinds of outputs: +// 1- A pairs of nodes formatted as {lhs};{rhs}\n representing an edge between +// two nodes. +// 2- A single node formatted as {lhs}\n +// The concatenated outputs from multiple tool runs are then used to construct +// the graph and emit relevant edits using extract_edits.py +// +// A node (lhs, rhs) has the following format: +// '{is_field,is_excluded,has_auto_type,r:::<file +// path>:::<offset>:::<length>:::<replacement text>,include-user-header:::<file +// path>:::-1:::-1:::<include text>}' +// +// where `is_field`,`is_excluded`, and `has_auto_type` are booleans represendted +// as 0 or 1. +// +// For more details, see the doc here: +// https://docs.google.com/document/d/1P8wLVS3xueI4p3EAPO4JJP6d1_zVp5SapQB0EW9iHQI/ + +#include <assert.h> +#include <algorithm> +#include <cstdio> +#include <fstream> +#include <limits> +#include <map> +#include <memory> +#include <set> +#include <sstream> +#include <string> +#include <string_view> +#include <vector> + +#include "RawPtrHelpers.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/ASTMatchers/ASTMatchersMacros.h" +#include "clang/Basic/CharInfo.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/FrontendActions.h" +#include "clang/Lex/Lexer.h" +#include "clang/Lex/MacroArgs.h" +#include "clang/Lex/PPCallbacks.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Tooling/CommonOptionsParser.h" +#include "clang/Tooling/Refactoring.h" +#include "clang/Tooling/Tooling.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/ErrorOr.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/LineIterator.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/TargetSelect.h" + +using namespace clang::ast_matchers; + +namespace { + +// Include path that needs to be added to all the files where raw_ptr<...> +// replaces a raw pointer. +const char kRawPtrIncludePath[] = "base/memory/raw_ptr.h"; + +// This iterates over function parameters and matches the ones that match +// parm_var_decl_matcher. +AST_MATCHER_P(clang::FunctionDecl, + forEachParmVarDecl, + clang::ast_matchers::internal::Matcher<clang::ParmVarDecl>, + parm_var_decl_matcher) { + const clang::FunctionDecl& function_decl = Node; + + auto num_params = function_decl.getNumParams(); + bool is_matching = false; + clang::ast_matchers::internal::BoundNodesTreeBuilder result; + for (unsigned i = 0; i < num_params; i++) { + const clang::ParmVarDecl* param = function_decl.getParamDecl(i); + clang::ast_matchers::internal::BoundNodesTreeBuilder param_matches; + if (parm_var_decl_matcher.matches(*param, Finder, ¶m_matches)) { + is_matching = true; + result.addMatch(param_matches); + } + } + *Builder = std::move(result); + return is_matching; +} + +// Returns a StringRef of the elements apprearing after the pattern +// '(anonymous namespace)::' if any, otherwise returns input. +static llvm::StringRef RemoveAnonymous(llvm::StringRef input) { + constexpr llvm::StringRef kAnonymousNamespace{"(anonymous namespace)::"}; + auto loc = input.find(kAnonymousNamespace); + if (loc != input.npos) { + return input.substr(loc + kAnonymousNamespace.size()); + } + return input; +} + +// Statements of the form: for (auto* i : affected_expr) +// need to be changed to: for (type_name* i : affected_expr) +// in order to extract the pointer type from now raw_ptr. +// The text returned by type's `getAsString()` can contain some unuseful +// data. Example: 'const struct n1::(anonymous namespace)::n2::type_name'. As +// is, this wouldn't compile. This needs to be reinterpreted as +// 'const n2::type_name'. +// `RemovePrefix` removes the class/struct keyword if any, +// conserves the constness, and trims '(anonymous namespace)::' +// as well as anything on it's lhs using `RemoveAnonymous`. +static std::string RemovePrefix(llvm::StringRef input) { + constexpr llvm::StringRef kClassPrefix{"class "}; + constexpr llvm::StringRef kStructPrefix{"struct "}; + constexpr llvm::StringRef kConstPrefix{"const "}; + + std::string result; + result.reserve(input.size()); + + if (input.consume_front(kConstPrefix)) { + result += kConstPrefix; + } + + input.consume_front(kClassPrefix); + input.consume_front(kStructPrefix); + + result += RemoveAnonymous(input); + return result; +} + +struct Node { + bool is_field = false; + // This is set to true for Fields annotated with RAW_PTR_EXCLUSION + bool is_excluded = false; + // auto type variables don't need to be rewritten. They still need to be + // present in the graph to propagate the rewrite to non auto expressions. + // Example: + // auto temp = member_; vector<T*>::iterator it = temp.begin(); + // `it`'s type needs to be rewritten when member's type is. + bool has_auto_type = false; + // A replacement follows the following format: + // `r:::<file path>:::<offset>:::<length>:::<replacement text>` + std::string replacement; + // An include directive follows the following format: + // `include-user-header:::<file path>:::-1:::-1:::<include text>` + std::string include_directive; + bool operator==(const Node& other) const { + return replacement == other.replacement; + } + bool operator<(const Node& other) const { + return replacement < other.replacement; + } + // The resulting string follows the following format: + // {is_field\,is_excluded\,has_auto_type\,r:::<file + // path>:::<offset>:::<length>:::<replacement + // text>\,include-user-header:::<file path>:::-1:::-1:::<include text>} + // where is_field,is_excluded, and has_auto_type are booleans represendted as + // 0 or 1. + std::string ToString() const { + return llvm::formatv("{{{0:d}\\,{1:d}\\,{2:d}\\,{3}\\,{4}}", is_field, + is_excluded, has_auto_type, replacement, + include_directive); + } +}; + +// Helper class to add edges to the set of node_pairs_; +class OutputHelper { + public: + OutputHelper() = default; + + void AddEdge(const Node& lhs, const Node& rhs) { + node_pairs_.insert( + llvm::formatv("{0};{1}\n", lhs.ToString(), rhs.ToString())); + } + + void AddSingleNode(const Node& lhs) { + node_pairs_.insert(llvm::formatv("{0}\n", lhs.ToString())); + } + + void Emit() { + for (const auto& p : node_pairs_) { + llvm::outs() << p; + } + } + + private: + // This represents a line for every 2 adjacent nodes. + // The format is: {lhs};{rhs}\n where lhs & rhs generated using + // Node::ToString(). + // There are two cases where the line contains only a lhs node {lhs}\n + // 1- To make sure that fields that are not connected to any other node are + // represented in the graph. + // 2- Fields annotated with RAW_PTR_EXCLUSION are also inserted as a single + // node to the list. + std::set<std::string> node_pairs_; +}; + +// This visitor is used to extract a FunctionDecl* bound with a node id +// "fct_decl" from a given match. +// This is used in the `forEachArg` and `forEachBindArg` matchers below. +class LocalVisitor + : public clang::ast_matchers::internal::BoundNodesTreeBuilder::Visitor { + public: + void visitMatch( + const clang::ast_matchers::BoundNodes& BoundNodesView) override { + if (const auto* ptr = + BoundNodesView.getNodeAs<clang::FunctionDecl>("fct_decl")) { + fct_decl_ = BoundNodesView.getNodeAs<clang::FunctionDecl>("fct_decl"); + } else { + const clang::LambdaExpr* lambda_expr = + BoundNodesView.getNodeAs<clang::LambdaExpr>("lambda_expr"); + fct_decl_ = lambda_expr->getCallOperator(); + } + } + const clang::FunctionDecl* fct_decl_; +}; + +// This is used to map arguments passed to std::make_unique to the underlying +// constructor parameters. For each expr that matches, using `LocalVisitor`, we +// extract the ptr to clang::FunctionDecl which represents here the +// constructorDecl and use it to get the parmVarDecl corresponding to the +// argument. +// This iterates over a callExpressions's arguments and matches the ones that +// match expr_matcher. For each argument matched, retrieve the corresponding +// constructor parameter. The constructor parameter is then checked against +// parm_var_decl_matcher. +AST_MATCHER_P2(clang::CallExpr, + forEachArg, + clang::ast_matchers::internal::Matcher<clang::Expr>, + expr_matcher, + clang::ast_matchers::internal::Matcher<clang::ParmVarDecl>, + parm_var_decl_matcher) { + const clang::CallExpr& call_expr = Node; + + auto num_args = call_expr.getNumArgs(); + bool is_matching = false; + clang::ast_matchers::internal::BoundNodesTreeBuilder result; + for (unsigned i = 0; i < num_args; i++) { + const clang::Expr* arg = call_expr.getArg(i); + clang::ast_matchers::internal::BoundNodesTreeBuilder arg_matches; + if (expr_matcher.matches(*arg, Finder, &arg_matches)) { + LocalVisitor l; + arg_matches.visitMatches(&l); + const auto* fct_decl = l.fct_decl_; + if (fct_decl) { + const auto* param = fct_decl->getParamDecl(i); + clang::ast_matchers::internal::BoundNodesTreeBuilder parm_var_matches( + arg_matches); + if (parm_var_decl_matcher.matches(*param, Finder, &parm_var_matches)) { + is_matching = true; + result.addMatch(parm_var_matches); + } + } + } + } + *Builder = std::move(result); + return is_matching; +} + +// This is used to handle expressions of the form: +// base::BindOnce( +// [](std::vector<raw_ptr<Label>>& message_labels, +// Label* message_label) { +// message_labels.push_back(message_label); +// }, +// std::ref(message_labels_)))) +// This creates a link between the parmVarDecl's in the lambda/functionPointer +// passed as 1st argument and the rest of the arguments passed to the bind call. +AST_MATCHER_P2(clang::CallExpr, + forEachBindArg, + clang::ast_matchers::internal::Matcher<clang::Expr>, + expr_matcher, + clang::ast_matchers::internal::Matcher<clang::ParmVarDecl>, + parm_var_decl_matcher) { + const clang::CallExpr& call_expr = Node; + + auto num_args = call_expr.getNumArgs(); + if (num_args == 1) { + // No arguments to map to the lambda/fct parmVarDecls. + return false; + } + + bool is_matching = false; + clang::ast_matchers::internal::BoundNodesTreeBuilder result; + for (unsigned i = 1; i < num_args; i++) { + const clang::Expr* arg = call_expr.getArg(i); + clang::ast_matchers::internal::BoundNodesTreeBuilder arg_matches; + if (expr_matcher.matches(*arg, Finder, &arg_matches)) { + LocalVisitor l; + arg_matches.visitMatches(&l); + const auto* fct_decl = l.fct_decl_; + if (fct_decl->getNumParams() != num_args - 1) { + return false; + } + // i-1 because we start with second arg for Bind and first arg for + // lambda/fct + const auto* param = fct_decl->getParamDecl(i - 1); + clang::ast_matchers::internal::BoundNodesTreeBuilder + parm_var_decl_matches(arg_matches); + if (parm_var_decl_matcher.matches(*param, Finder, + &parm_var_decl_matches)) { + is_matching = true; + result.addMatch(parm_var_decl_matches); + } + } + } + *Builder = std::move(result); + return is_matching; +} + +static std::string GenerateNewType(const clang::ASTContext& ast_context, + const clang::QualType& pointer_type) { + std::string result; + + clang::QualType pointee_type = pointer_type->getPointeeType(); + + // Preserve qualifiers. + assert(!pointer_type.isRestrictQualified() && + "|restrict| is a C-only qualifier and raw_ptr<T>/raw_ref<T> need C++"); + if (pointer_type.isConstQualified()) { + result += "const "; + } + if (pointer_type.isVolatileQualified()) { + result += "volatile "; + } + + // Convert pointee type to string. + clang::PrintingPolicy printing_policy(ast_context.getLangOpts()); + printing_policy.SuppressScope = 1; // s/blink::Pointee/Pointee/ + std::string pointee_type_as_string = + pointee_type.getAsString(printing_policy); + result += llvm::formatv("raw_ptr<{0}>", pointee_type_as_string); + + return result; +} + +static std::pair<std::string, std::string> GetReplacementAndIncludeDirectives( + const clang::PointerTypeLoc* type_loc, + const clang::TemplateSpecializationTypeLoc* tst_loc, + std::string replacement_text, + const clang::SourceManager& source_manager) { + clang::SourceLocation begin_loc = tst_loc->getLAngleLoc().getLocWithOffset(1); + // This is done to skip the star '*' because type_loc's end loc is just + // before the star position. + clang::SourceLocation end_loc = type_loc->getEndLoc().getLocWithOffset(1); + + clang::SourceRange replacement_range(begin_loc, end_loc); + + clang::tooling::Replacement replacement( + source_manager, clang::CharSourceRange::getCharRange(replacement_range), + replacement_text); + llvm::StringRef file_path = replacement.getFilePath(); + if (file_path.empty()) { + return {"", ""}; + } + + std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); + std::string replacement_directive = llvm::formatv( + "r:::{0}:::{1}:::{2}:::{3}", file_path, replacement.getOffset(), + replacement.getLength(), replacement_text); + + std::string include_directive = + llvm::formatv("include-user-header:::{0}:::-1:::-1:::{1}", file_path, + kRawPtrIncludePath); + + return {replacement_directive, include_directive}; +} + +std::string GenerateReplacementForAutoLoc( + const clang::TypeLoc* auto_loc, + const std::string& replacement_text, + const clang::SourceManager& source_manager, + const clang::ASTContext& ast_context) { + clang::SourceLocation begin_loc = auto_loc->getBeginLoc(); + + clang::SourceRange replacement_range(begin_loc, begin_loc); + + clang::tooling::Replacement replacement( + source_manager, clang::CharSourceRange::getCharRange(replacement_range), + replacement_text); + llvm::StringRef file_path = replacement.getFilePath(); + + return llvm::formatv("r:::{0}:::{1}:::{2}:::{3}", file_path, + replacement.getOffset(), replacement.getLength(), + replacement_text); +} + +// Called when the Match registered for it was successfully found in the AST. +// The matches registered represent two categories: +// 1- An adjacency relationship +// In that case, a node pair is created, using matched node ids, and added +// to the node_pair list using `OutputHelper::AddEdge` +// 2- A single fieldDecl node match +// In that case, a single node is created and added to the node_pair list +// using `OutputHelper::AddSingleNode` +class PotentialNodes : public MatchFinder::MatchCallback { + public: + explicit PotentialNodes(OutputHelper& helper) : output_helper_(helper) {} + + PotentialNodes(const PotentialNodes&) = delete; + PotentialNodes& operator=(const PotentialNodes&) = delete; + + void run(const MatchFinder::MatchResult& result) override { + const clang::SourceManager& source_manager = *result.SourceManager; + const clang::ASTContext& ast_context = *result.Context; + + Node lhs; + + if (auto* type_loc = result.Nodes.getNodeAs<clang::PointerTypeLoc>( + "lhs_argPointerLoc")) { + std::string replacement_text = + GenerateNewType(ast_context, type_loc->getType()); + + const clang::TemplateSpecializationTypeLoc* tst_loc = + result.Nodes.getNodeAs<clang::TemplateSpecializationTypeLoc>( + "lhs_tst_loc"); + + auto p = GetReplacementAndIncludeDirectives( + type_loc, tst_loc, replacement_text, source_manager); + lhs.replacement = p.first; + lhs.include_directive = p.second; + + if (const clang::FieldDecl* field_decl = + result.Nodes.getNodeAs<clang::FieldDecl>("lhs_field")) { + lhs.is_field = true; + } + + // To make sure we add all field decls to the graph.(Specifically those + // not connected to other nodes) + if (const clang::FieldDecl* field_decl = + result.Nodes.getNodeAs<clang::FieldDecl>("field_decl")) { + lhs.is_field = true; + output_helper_.AddSingleNode(lhs); + return; + } + + // RAW_PTR_EXCLUSION is not captured when adding edges between nodes. For + // that reason, fields annotated with RAW_PTR_EXCLUSION are added as + // single nodes to the list, this is then used as a starting point to + // propagate the exclusion to all neighboring nodes. + if (const clang::FieldDecl* field_decl = + result.Nodes.getNodeAs<clang::FieldDecl>("excluded_field_decl")) { + lhs.is_field = true; + lhs.is_excluded = true; + output_helper_.AddSingleNode(lhs); + return; + } + } else if (const clang::TypeLoc* auto_loc = + result.Nodes.getNodeAs<clang::TypeLoc>("lhs_auto_loc")) { + lhs.replacement = GenerateReplacementForAutoLoc( + auto_loc, "replacement_text", source_manager, ast_context); + lhs.include_directive = lhs.replacement; + // No need to emit a rewrite for auto type variables. They still need to + // appear in the graph to propagate the rewrite to non-auto type nodes + // codes connected to them. + lhs.has_auto_type = true; + } else { // Not supposed to get here + assert(false); + } + + Node rhs; + if (const clang::FieldDecl* field_decl = + result.Nodes.getNodeAs<clang::FieldDecl>("rhs_field")) { + rhs.is_field = true; + } + + if (auto* type_loc = result.Nodes.getNodeAs<clang::PointerTypeLoc>( + "rhs_argPointerLoc")) { + std::string replacement_text = + GenerateNewType(ast_context, type_loc->getType()); + + const clang::TemplateSpecializationTypeLoc* tst_loc = + result.Nodes.getNodeAs<clang::TemplateSpecializationTypeLoc>( + "rhs_tst_loc"); + + auto p = GetReplacementAndIncludeDirectives( + type_loc, tst_loc, replacement_text, source_manager); + + rhs.replacement = p.first; + rhs.include_directive = p.second; + } else if (const clang::TypeLoc* auto_loc = + result.Nodes.getNodeAs<clang::TypeLoc>("rhs_auto_loc")) { + rhs.replacement = GenerateReplacementForAutoLoc( + auto_loc, "replacement_text", source_manager, ast_context); + rhs.include_directive = rhs.replacement; + // No need to emit a rewrite for auto type variables. They still need to + // appear in the graph to propagate the rewrite to non-auto type nodes + // codes connected to them. + rhs.has_auto_type = true; + } else { // Not supposed to get here + assert(false); + } + + output_helper_.AddEdge(lhs, rhs); + } + + private: + OutputHelper& output_helper_; +}; + +// Called when the Match registered for it was successfully found in the AST. +// The match represents a parmVarDecl Node or an RTNode and the corresponding +// function declaration. Using the function declaration: +// 1- Create a unique key `current_key` +// 2- if the function has a previous declaration or is overridden, +// retrieve previous decls and create their keys `prev_key` +// 3- for each `prev_key`, add pair `current_key`, `prev_key` to +// `fct_sig_pairs_` +// +// Using the parmVarDecl or RTNode: +// 1- Create a node +// 2- insert node into `fct_sig_nodes_[current_key]` +// +// At the end of the tool run for a given translation unit, edges between +// corresponding nodes of two adjacent function signatures are created. +class FunctionSignatureNodes : public MatchFinder::MatchCallback { + public: + explicit FunctionSignatureNodes( + std::map<std::string, std::set<Node>>& sig_nodes, + std::vector<std::pair<std::string, std::string>>& sig_pairs) + : fct_sig_nodes_(sig_nodes), fct_sig_pairs_(sig_pairs) {} + + FunctionSignatureNodes(const FunctionSignatureNodes&) = delete; + FunctionSignatureNodes& operator=(const FunctionSignatureNodes&) = delete; + + // Key here means a unique string generated from a function signature + std::string GetKey(const clang::FunctionDecl* fct_decl, + const clang::SourceManager& source_manager) { + auto name = fct_decl->getNameInfo().getName().getAsString(); + clang::SourceLocation start_loc = fct_decl->getBeginLoc(); + // This is done here to get the spelling loc of a functionDecl. This is + // needed to handle cases where the function is in a Macro Expansion. In + // that case, multiple functionDecls will have the same location and this + // will create problems for argument mapping. Example: + // MOCK_METHOD0(GetAllStreams, std::vector<DemuxerStream*>()); + clang::SourceRange replacement_range(source_manager.getFileLoc(start_loc), + source_manager.getFileLoc(start_loc)); + clang::tooling::Replacement replacement( + source_manager, clang::CharSourceRange::getCharRange(replacement_range), + name.c_str()); + llvm::StringRef file_path = replacement.getFilePath(); + + return llvm::formatv("r:::{0}:::{1}:::{2}:::{3}", file_path, + replacement.getOffset(), replacement.getLength(), + name.c_str()); + } + + void run(const MatchFinder::MatchResult& result) override { + const clang::SourceManager& source_manager = *result.SourceManager; + const clang::ASTContext& ast_context = *result.Context; + + const clang::FunctionDecl* fct_decl = + result.Nodes.getNodeAs<clang::FunctionDecl>("fct_decl"); + + std::string key = GetKey(fct_decl, source_manager); + if (auto* prev_decl = fct_decl->getPreviousDecl()) { + std::string prev_key = GetKey(prev_decl, source_manager); + fct_sig_pairs_.push_back({prev_key, key}); + } + + if (const clang::CXXMethodDecl* method_decl = + result.Nodes.getNodeAs<clang::CXXMethodDecl>("fct_decl")) { + for (auto* m : method_decl->overridden_methods()) { + std::string prev_key = GetKey(m, source_manager); + fct_sig_pairs_.push_back({prev_key, key}); + } + } + + auto* type_loc = + result.Nodes.getNodeAs<clang::PointerTypeLoc>("rhs_argPointerLoc"); + Node rhs; + std::string replacement_text = + GenerateNewType(ast_context, type_loc->getType()); + + const clang::TemplateSpecializationTypeLoc* tst_loc = + result.Nodes.getNodeAs<clang::TemplateSpecializationTypeLoc>( + "rhs_tst_loc"); + + auto p = GetReplacementAndIncludeDirectives( + type_loc, tst_loc, replacement_text, source_manager); + rhs.replacement = p.first; + rhs.include_directive = p.second; + + fct_sig_nodes_[key].insert(rhs); + } + + private: + // Map a function signature, which is modeled as a string representing file + // location, to it's matched graph nodes (RTNode and ParmVarDecl nodes). + // Note: `RTNode` represents a function return type node. + // In order to avoid relying on the order with which nodes are matched in the + // AST, and to guarantee that nodes are stored in the file declaration order, + // we use a `std::set<Node>` which sorts Nodes based on the replacement + // directive which contains the file offset of a given node. + // Note that a replacement directive has the following format: + // `r:::<file path>:::<offset>:::<length>:::<replacement text>` + // The order is important because at the end of a tool run on a + // translationUnit, for each pair of function signatures, we iterate + // concurrently through the two sets of Nodes creating edges between nodes + // that appear at the same index. + // AddEdge(first function's node1, second function's node1) + // AddEdge(first function's node2, second function's node2) + // and so on... + std::map<std::string, std::set<Node>>& fct_sig_nodes_; + // Map related function signatures to each other, this is needed for functions + // with separate definition and declaration, and for overridden functions. + std::vector<std::pair<std::string, std::string>>& fct_sig_pairs_; +}; + +// Called when the Match registered for it was successfully found in the AST. +// The matches registered represent three categories: +// 1- Range-based for loops of the form: +// for (auto* i : ctn_expr) => for (type_name* i : ctn_expr) +// +// 2- Expressions of the form: +// auto* var = ctn_expr.front(); => auto* var = ctn_expr.front().get(); +// +// 3- Expressions of the form: +// auto* var = ctn_expr[index]; => auto* var = ctn_expr[index].get(); +// +// In each of the above cases a node pair is created and added to node_pairs +// using `OutputHelper::AddEdge` +class AffectedPtrExprRewriter : public MatchFinder::MatchCallback { + public: + explicit AffectedPtrExprRewriter(OutputHelper& helper) + : output_helper_(helper) {} + + AffectedPtrExprRewriter(const AffectedPtrExprRewriter&) = delete; + AffectedPtrExprRewriter& operator=(const AffectedPtrExprRewriter&) = delete; + + void run(const MatchFinder::MatchResult& result) override { + const clang::SourceManager& source_manager = *result.SourceManager; + const clang::ASTContext& ast_context = *result.Context; + + Node lhs; + if (const clang::VarDecl* var_decl = + result.Nodes.getNodeAs<clang::VarDecl>("autoVarDecl")) { + auto* type_loc = result.Nodes.getNodeAs<clang::TypeLoc>("autoLoc"); + + clang::SourceRange replacement_range(var_decl->getBeginLoc(), + type_loc->getEndLoc()); + + std::string replacement_text = + var_decl->getType()->getPointeeType().getAsString(); + + replacement_text = RemovePrefix(replacement_text); + lhs.replacement = getReplacementDirective( + replacement_text, replacement_range, source_manager, ast_context); + lhs.include_directive = lhs.replacement; + + } else if (const clang::MemberExpr* member_expr = + result.Nodes.getNodeAs<clang::MemberExpr>( + "affectedMemberExpr")) { + clang::SourceLocation member_name_start = member_expr->getMemberLoc(); + size_t member_name_length = + member_expr->getMemberDecl()->getName().size(); + // +2 to skip trailing () + clang::SourceLocation insertion_loc = + member_name_start.getLocWithOffset(member_name_length + 2); + + clang::SourceRange replacement_range(insertion_loc, insertion_loc); + std::string replacement_text = ".get()"; + lhs.replacement = getReplacementDirective( + replacement_text, replacement_range, source_manager, ast_context); + lhs.include_directive = lhs.replacement; + } else if (const clang::CXXOperatorCallExpr* op_call_expr = + result.Nodes.getNodeAs<clang::CXXOperatorCallExpr>( + "affectedOpCall")) { + clang::SourceLocation insertion_loc = + op_call_expr->getEndLoc().getLocWithOffset(1); + clang::SourceRange replacement_range(insertion_loc, insertion_loc); + std::string replacement_text = ".get()"; + lhs.replacement = getReplacementDirective( + replacement_text, replacement_range, source_manager, ast_context); + lhs.include_directive = lhs.replacement; + } + + Node rhs; + if (const clang::FieldDecl* field_decl = + result.Nodes.getNodeAs<clang::FieldDecl>("rhs_field")) { + rhs.is_field = true; + } + + if (auto* type_loc = result.Nodes.getNodeAs<clang::PointerTypeLoc>( + "rhs_argPointerLoc")) { + std::string replacement_text = + GenerateNewType(ast_context, type_loc->getType()); + + const clang::TemplateSpecializationTypeLoc* tst_loc = + result.Nodes.getNodeAs<clang::TemplateSpecializationTypeLoc>( + "rhs_tst_loc"); + + auto p = GetReplacementAndIncludeDirectives( + type_loc, tst_loc, replacement_text, source_manager); + + rhs.replacement = p.first; + rhs.include_directive = p.second; + } else if (const clang::TypeLoc* auto_loc = + result.Nodes.getNodeAs<clang::TypeLoc>("rhs_auto_loc")) { + rhs.replacement = GenerateReplacementForAutoLoc( + auto_loc, "replacement_text", source_manager, ast_context); + rhs.include_directive = rhs.replacement; + rhs.has_auto_type = true; + } else { + // Should not get here. + assert(false); + } + output_helper_.AddEdge(lhs, rhs); + } + + private: + std::string getReplacementDirective( + std::string& replacement_text, + clang::SourceRange replacement_range, + const clang::SourceManager& source_manager, + const clang::ASTContext& ast_context) { + clang::tooling::Replacement replacement( + source_manager, clang::CharSourceRange::getCharRange(replacement_range), + replacement_text); + llvm::StringRef file_path = replacement.getFilePath(); + + std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); + return llvm::formatv("r:::{0}:::{1}:::{2}:::{3}", file_path, + replacement.getOffset(), replacement.getLength(), + replacement_text); + } + + OutputHelper& output_helper_; +}; + +class VectorRawPtrRewriter { + public: + explicit VectorRawPtrRewriter( + MatchFinder& finder, + OutputHelper& output_helper, + std::map<std::string, std::set<Node>>& sig_nodes, + std::vector<std::pair<std::string, std::string>>& sig_pairs) + : match_finder_(finder), + affected_ptr_expr_rewriter_(output_helper), + potentail_nodes_(output_helper), + fct_sig_nodes_(sig_nodes, sig_pairs) {} + + void addMatchers() { + // vectors of char pointers are usually used as char buffers, they are thus + // excluded from the rewrite. + auto exlude_char_types = unless(hasTemplateArgument( + 0, refersToType(pointsTo(qualType(isAnyCharacter()))))); + + auto class_temp_spec_decl = classTemplateSpecializationDecl( + hasName("std::vector"), + hasTemplateArgument(0, refersToType(isAnyPointer())), + exlude_char_types); + + auto lhs_location = + templateSpecializationTypeLoc( + loc(qualType(hasDeclaration(classTemplateSpecializationDecl( + hasName("std::vector"), exlude_char_types)))), + hasTemplateArgumentLoc( + 0, hasTypeLoc(pointerTypeLoc().bind("lhs_argPointerLoc")))) + .bind("lhs_tst_loc"); + + auto rhs_location = + templateSpecializationTypeLoc( + loc(qualType(hasDeclaration(classTemplateSpecializationDecl( + hasName("std::vector"), exlude_char_types)))), + hasTemplateArgumentLoc( + 0, hasTypeLoc(pointerTypeLoc().bind("rhs_argPointerLoc")))) + .bind("rhs_tst_loc"); + + auto field_exclusions = + anyOf(isExpansionInSystemHeader(), isInExternCContext(), + isInThirdPartyLocation(), isInGeneratedLocation(), + ImplicitFieldDeclaration()); + + // Supports typedefs as well. + auto lhs_type_loc = + anyOf(hasDescendant(loc(qualType(hasDeclaration( + typedefNameDecl(hasDescendant(lhs_location), + unless(isExpansionInSystemHeader())))))), + hasDescendant(lhs_location)); + + // Supports typedefs as well. + auto rhs_type_loc = + anyOf(hasDescendant(loc(qualType(hasDeclaration( + typedefNameDecl(hasDescendant(rhs_location), + unless(isExpansionInSystemHeader())))))), + hasDescendant(rhs_location)); + + auto lhs_field = + fieldDecl(hasExplicitFieldDecl(lhs_type_loc), unless(field_exclusions)) + .bind("lhs_field"); + auto rhs_field = + fieldDecl(hasExplicitFieldDecl(rhs_type_loc), unless(field_exclusions)) + .bind("rhs_field"); + + // To handle statements of the form: + // auto var = member/var/fct(); fct_call(var); + // We need to propagate the rewrite to fct_call signature. + + auto lhs_type_def_name_decl = typedefNameDecl( + hasDescendant(lhs_location), unless(isExpansionInSystemHeader())); + + auto lhs_type_def_var = + anyOf(varDecl(hasType(lhs_type_def_name_decl)), + varDecl(hasType(references(lhs_type_def_name_decl))), + varDecl(hasType(pointsTo(lhs_type_def_name_decl)))); + + auto rhs_type_def_name_decl = typedefNameDecl( + hasDescendant(rhs_location), unless(isExpansionInSystemHeader())); + + auto rhs_type_def_var = + anyOf(varDecl(hasType(rhs_type_def_name_decl)), + varDecl(hasType(references(rhs_type_def_name_decl))), + varDecl(hasType(pointsTo(rhs_type_def_name_decl)))); + + auto v_decl_variations = varDecl(anyOf( + varDecl(hasType(class_temp_spec_decl)), + varDecl(hasType(references(class_temp_spec_decl))), + varDecl(hasType(pointsTo(class_temp_spec_decl))), + varDecl(hasType(decl(hasParent(class_temp_spec_decl)))), + varDecl(hasType(pointsTo(decl(hasParent(class_temp_spec_decl))))), + varDecl(hasType(references(decl(hasParent(class_temp_spec_decl))))))); + + auto lhs_var = anyOf( + varDecl(allOf( + anyOf(v_decl_variations, lhs_type_def_var), + hasDescendant(loc(qualType(autoType())).bind("lhs_auto_loc")))), + varDecl(lhs_type_loc).bind("lhs_var")); + + auto rhs_var = anyOf( + varDecl(allOf( + anyOf(v_decl_variations, rhs_type_def_var), + hasDescendant(loc(qualType(autoType())).bind("rhs_auto_loc")))), + varDecl(rhs_type_loc).bind("rhs_var")); + + auto lhs_param = + parmVarDecl(hasExplicitParmVarDecl(lhs_type_loc)).bind("lhs_param"); + + auto rhs_param = + parmVarDecl(hasExplicitParmVarDecl(rhs_type_loc)).bind("rhs_param"); + + auto rhs_call_expr = + callExpr(callee(functionDecl(hasReturnTypeLoc(rhs_type_loc)))); + + auto lhs_call_expr = + callExpr(callee(functionDecl(hasReturnTypeLoc(lhs_type_loc)))); + + auto lhs_expr = expr( + ignoringImpCasts(anyOf(declRefExpr(to(anyOf(lhs_var, lhs_param))), + memberExpr(member(lhs_field)), lhs_call_expr))); + + auto rhs_expr = expr( + ignoringImpCasts(anyOf(declRefExpr(to(anyOf(rhs_var, rhs_param))), + memberExpr(member(rhs_field)), rhs_call_expr))); + + // To make sure we add all field decls to the graph.(Specifically those not + // connected to other nodes) + auto field_decl = + fieldDecl(hasExplicitFieldDecl(lhs_type_loc), + unless(allOf(field_exclusions, isRawPtrExclusionAnnotated()))) + .bind("field_decl"); + match_finder_.addMatcher(field_decl, &potentail_nodes_); + + // Fields annotated with RAW_PTR_EXCLUSION cannot be filtered using field + // exclusions. They need to appear in the graph so that we can properly + // propagate the exclusion to reachable nodes. For this reason, and in order + // to capture this information, RAW_PTR_EXCLUSION fields are added as single + // nodes to the list and then used as a starting point to propagate the + // exclusion before running dfs on the graph. + auto excluded_field_decl = fieldDecl(hasExplicitFieldDecl(lhs_type_loc), + isRawPtrExclusionAnnotated()) + .bind("excluded_field_decl"); + match_finder_.addMatcher(excluded_field_decl, &potentail_nodes_); + + auto ref_cref_move = + anyOf(hasName("std::move"), hasName("std::ref"), hasName("std::cref")); + auto rhs_move_call = + callExpr(callee(functionDecl(ref_cref_move)), hasArgument(0, rhs_expr)); + + // This is needed for ternary cond operator true_expr. (cond) ? true_expr : + // false_expr; + auto lhs_move_call = + callExpr(callee(functionDecl(ref_cref_move)), hasArgument(0, lhs_expr)); + + // TODO: check vector<S*> it = get()[0]; + auto rhs_iterator_call = cxxMemberCallExpr( + callee(functionDecl(anyOf(hasName("begin"), hasName("end")))), + has(memberExpr(has(rhs_expr)))); + + auto lhs_iterator_call = cxxMemberCallExpr( + callee(functionDecl(anyOf(hasName("begin"), hasName("end")))), + has(memberExpr(has(lhs_expr)))); + + auto rhs_cxx_temp_expr = cxxTemporaryObjectExpr(rhs_type_loc); + + auto lhs_cxx_temp_expr = cxxTemporaryObjectExpr(lhs_type_loc); + + // This represents the forms under which an expr could appear on the right + // hand side of an assignment operation, var construction, or an expr passed + // as callExpr argument. Examples: rhs_expr, &rhs_expr, *rhs_expr, + // fct_call(),*fct_call(), &fct_call(), std::move(), .begin(); + auto rhs_expr_variations = + anyOf(rhs_expr, unaryOperator(has(rhs_expr)), rhs_call_expr, + rhs_move_call, rhs_iterator_call, rhs_cxx_temp_expr); + + // needed for ternary operator expr: (cond) ? true_expr : false_expr; + // true_expr => lhs; false_expr => rhs; + auto lhs_expr_variations = + anyOf(lhs_expr, unaryOperator(has(lhs_expr)), lhs_call_expr, + lhs_move_call, lhs_iterator_call, lhs_cxx_temp_expr); + + // rewrite affected expressions + { + auto reversed_expr = + callExpr(callee(functionDecl(hasName("base::Reversed"))), + hasArgument(0, rhs_expr_variations)); + + // handles statements of the form: for (auto* i : member/var/param/fct()) + // that should be modified after rewriting the container. + auto auto_star_in_range_stmt = traverse( + clang::TK_IgnoreUnlessSpelledInSource, + cxxForRangeStmt( + has(varDecl(hasDescendant(loc(qualType(pointsTo(autoType()))) + .bind("autoLoc"))) + .bind("autoVarDecl")), + has(expr(anyOf(rhs_expr_variations, reversed_expr))))); + match_finder_.addMatcher(auto_star_in_range_stmt, + &affected_ptr_expr_rewriter_); + + // handles expressions of the form: auto* var = member.front(); + // This becomes: auto* var = member.front().get(); + auto affected_expr = traverse( + clang::TK_IgnoreUnlessSpelledInSource, + declStmt(has(varDecl(hasType(pointsTo(autoType())), + has(cxxMemberCallExpr(has( + memberExpr(has(expr(rhs_expr_variations))) + .bind("affectedMemberExpr")))))))); + match_finder_.addMatcher(affected_expr, &affected_ptr_expr_rewriter_); + + // handles expressions of the form: auto* var = member[0]; + // This becomes: auto* var = member[0].get(); + auto affected_op_call = + traverse(clang::TK_IgnoreUnlessSpelledInSource, + declStmt(has(varDecl( + hasType(pointsTo(autoType())), + has(cxxOperatorCallExpr(has(expr(rhs_expr_variations))) + .bind("affectedOpCall")))))); + match_finder_.addMatcher(affected_op_call, &affected_ptr_expr_rewriter_); + } + + // creates a link between false_expr and true_expr of a ternary conditional + // operator; + // handles: + // (cond) ? (a/&a/*a/std::move(a)/fct()/*fct()/&fct()/a.begin()) : + // (b/&b/*b/std::move(b)/fct()/*fct()/&fct()/b.begin()) + auto ternary_cond_expr = + traverse(clang::TK_IgnoreUnlessSpelledInSource, + conditionalOperator(hasTrueExpression(lhs_expr_variations), + hasFalseExpression(rhs_expr_variations), + unless(isExpansionInSystemHeader()))); + match_finder_.addMatcher(ternary_cond_expr, &potentail_nodes_); + + // Handles assignment: + // a = b; + // a = &b; + // *a = b; + // *a = *b; + // a = fct(); + // a = *fct(); + // a = std::move(b); + // a = &fct(); + // it = member.begin(); + // a = vector<S*>(); + // a = (cond) ? expr1 : expr2; + auto assignement_relationship = traverse( + clang::TK_IgnoreUnlessSpelledInSource, + binaryOperation(hasOperatorName("="), + hasOperands(lhs_expr_variations, + anyOf(rhs_expr_variations, + conditionalOperator(hasTrueExpression( + rhs_expr_variations)))), + unless(isExpansionInSystemHeader()))); + match_finder_.addMatcher(assignement_relationship, &potentail_nodes_); + + // Supports: + // std::vector<T*>* temp = &member; + // std::vector<T*>& temp = member; + // std::vector<T*> temp = *member; + // std::vector<T*> temp = member; and other similar stmts. + // std::vector<T*> temp = init(); + // std::vector<T*> temp = *fct(); + // std::vector<T*>::iterator it = member.begin(); + // std::vector<T*> temp = (cond) ? expr1 : expr2; + auto var_construction = traverse( + clang::TK_IgnoreUnlessSpelledInSource, + varDecl( + lhs_var, + has(expr(anyOf( + rhs_expr_variations, + conditionalOperator(hasTrueExpression(rhs_expr_variations)), + cxxConstructExpr(has(expr(anyOf( + rhs_expr_variations, conditionalOperator(hasTrueExpression( + rhs_expr_variations))))))))), + unless(isExpansionInSystemHeader()))); + match_finder_.addMatcher(var_construction, &potentail_nodes_); + + // Supports: + // return member; + // return *member; + // return &member; + // return fct(); + // return *fct(); + // return std::move(member); + // return member.begin(); + // return (cond) ? expr1 : expr2; + auto returned_var_or_member = traverse( + clang::TK_IgnoreUnlessSpelledInSource, + returnStmt( + hasReturnValue(expr(anyOf( + rhs_expr_variations, + conditionalOperator(hasTrueExpression(rhs_expr_variations))))), + unless(isExpansionInSystemHeader()), + forFunction(functionDecl(hasReturnTypeLoc(lhs_type_loc)) + .bind("lhs_fct_return"))) + .bind("lhs_stmt")); + match_finder_.addMatcher(returned_var_or_member, &potentail_nodes_); + + // Handles expressions of the form member(arg). + // A(const std::vector<T*>& arg): member(arg){} + // member(init()); + // member(*fct()); + // member2(&member1); + auto ctor_initilizer = traverse( + clang::TK_IgnoreUnlessSpelledInSource, + cxxCtorInitializer(withInitializer(anyOf( + cxxConstructExpr(has(expr(rhs_expr_variations))), + rhs_expr_variations)), + forField(lhs_field))); + + match_finder_.addMatcher(ctor_initilizer, &potentail_nodes_); + + // link var/field passed as function arguments to function parameter + // This handles func(var/member/param), func(&var/member/param), + // func(*var/member/param), func(func2()), func(&func2()) + // cxxOpCallExprs excluded here since operator= can be invoked as a call + // expr for classes/structs. + auto call_expr = traverse( + clang::TK_IgnoreUnlessSpelledInSource, + callExpr(forEachArgumentWithParam( + expr(anyOf(rhs_expr_variations, + conditionalOperator( + hasTrueExpression(rhs_expr_variations)))), + lhs_param), + unless(isExpansionInSystemHeader()), + unless(cxxOperatorCallExpr(hasOperatorName("="))))); + match_finder_.addMatcher(call_expr, &potentail_nodes_); + + // Handles: member.swap(temp); temp.swap(member); + auto member_swap_call = traverse( + clang::TK_IgnoreUnlessSpelledInSource, + cxxMemberCallExpr(callee(functionDecl(hasName("swap"))), + hasArgument(0, rhs_expr_variations), + has(memberExpr(has(expr(lhs_expr_variations)))), + unless(isExpansionInSystemHeader()))); + match_finder_.addMatcher(member_swap_call, &potentail_nodes_); + + // Handles: std::swap(member, temp); std::swap(temp, member); + auto std_swap_call = + traverse(clang::TK_IgnoreUnlessSpelledInSource, + callExpr(callee(functionDecl(hasName("std::swap"))), + hasArgument(0, lhs_expr_variations), + hasArgument(1, rhs_expr_variations), + unless(isExpansionInSystemHeader()))); + match_finder_.addMatcher(std_swap_call, &potentail_nodes_); + + // Supports: + // std::vector<S*> temp; + // Obj o(temp); Obj o{temp}; + // This links temp to the parameter in Obj's constructor. + auto var_passed_in_constructor = traverse( + clang::TK_IgnoreUnlessSpelledInSource, + cxxConstructExpr(forEachArgumentWithParam( + expr(anyOf( + rhs_expr_variations, + conditionalOperator(hasTrueExpression(rhs_expr_variations)))), + lhs_param))); + match_finder_.addMatcher(var_passed_in_constructor, &potentail_nodes_); + + // handles Obj o{temp} when Obj has no constructor. + // This creates a link between the expr and the underlying field. + auto var_passed_in_initlistExpr = traverse( + clang::TK_IgnoreUnlessSpelledInSource, + initListExpr(forEachInitExprWithFieldDecl( + expr(anyOf( + rhs_expr_variations, + conditionalOperator(hasTrueExpression(rhs_expr_variations)))), + lhs_field))); + match_finder_.addMatcher(var_passed_in_initlistExpr, &potentail_nodes_); + + // This creates a link between each argument passed to the make_unique call + // and the corresponding constructor parameter. + auto make_unique_call = traverse( + clang::TK_IgnoreUnlessSpelledInSource, + callExpr( + callee(functionDecl(hasName("std::make_unique"))), + forEachArg( + expr(rhs_expr_variations, + hasParent(callExpr( + callee(functionDecl(hasDescendant(cxxConstructExpr( + has(cxxNewExpr(has(cxxConstructExpr(hasDeclaration( + functionDecl().bind("fct_decl"))))))))))))), + lhs_param))); + match_finder_.addMatcher(make_unique_call, &potentail_nodes_); + + // Handle BindOnce/BindRepeating; + auto first_arg = hasParent(callExpr(hasArgument( + 0, anyOf(lambdaExpr().bind("lambda_expr"), + unaryOperator( + has(declRefExpr(to(functionDecl().bind("fct_decl"))))))))); + + auto bind_args = traverse( + clang::TK_IgnoreUnlessSpelledInSource, + callExpr( + callee(functionDecl( + anyOf(hasName("BindOnce"), hasName("BindRepeating")))), + forEachBindArg(expr(rhs_expr_variations, first_arg), lhs_param))); + match_finder_.addMatcher(bind_args, &potentail_nodes_); + + // Map function declaration signature to function definition signature; + // This is problematic in the case of callbacks defined in function. + auto fct_decls_params = traverse( + clang::TK_IgnoreUnlessSpelledInSource, + functionDecl( + forEachParmVarDecl(rhs_param), + unless(anyOf(isExpansionInSystemHeader(), isInMacroLocation()))) + .bind("fct_decl")); + match_finder_.addMatcher(fct_decls_params, &fct_sig_nodes_); + + auto fct_decls_returns = traverse( + clang::TK_IgnoreUnlessSpelledInSource, + functionDecl( + hasReturnTypeLoc(rhs_type_loc), + unless(anyOf(isExpansionInSystemHeader(), isInMacroLocation()))) + .bind("fct_decl")); + match_finder_.addMatcher(fct_decls_returns, &fct_sig_nodes_); + + auto macro_fct_signatures = traverse( + clang::TK_IgnoreUnlessSpelledInSource, + templateSpecializationTypeLoc( + rhs_location, + hasAncestor(functionDecl(isInMacroLocation(), + unless(isExpansionInSystemHeader())) + .bind("fct_decl")), + unless(hasAncestor(varDecl())))); + match_finder_.addMatcher(macro_fct_signatures, &fct_sig_nodes_); + + // TODO: handle calls to templated functions + } + + private: + MatchFinder& match_finder_; + AffectedPtrExprRewriter affected_ptr_expr_rewriter_; + PotentialNodes potentail_nodes_; + FunctionSignatureNodes fct_sig_nodes_; +}; + +} // namespace + +int main(int argc, const char* argv[]) { + llvm::InitializeNativeTarget(); + llvm::InitializeNativeTargetAsmParser(); + llvm::cl::OptionCategory category( + "rewrite_templated_container_fields: changes |vector<T*> field_| to " + "|vector<raw_ptr<T>> field_|."); + llvm::Expected<clang::tooling::CommonOptionsParser> options = + clang::tooling::CommonOptionsParser::create(argc, argv, category); + assert(static_cast<bool>(options)); // Should not return an error. + clang::tooling::ClangTool tool(options->getCompilations(), + options->getSourcePathList()); + + // Map a function signature, which is modeled as a string representing file + // location, to it's graph nodes (RTNode and ParmVarDecl nodes). + // RTNode represents a function return type. + std::map<std::string, std::set<Node>> fct_sig_nodes; + // Map related function signatures to each other, this is needed for functions + // with separate definition and declaration, and for overridden functions. + std::vector<std::pair<std::string, std::string>> fct_sig_pairs; + OutputHelper output_helper; + MatchFinder match_finder; + VectorRawPtrRewriter rewriter(match_finder, output_helper, fct_sig_nodes, + fct_sig_pairs); + rewriter.addMatchers(); + + // Prepare and run the tool. + std::unique_ptr<clang::tooling::FrontendActionFactory> factory = + clang::tooling::newFrontendActionFactory(&match_finder); + int result = tool.run(factory.get()); + + // For each pair of adjacent function signatures, create a link between + // corresponding parameters. + // 2 functions are said to be adjacent if one overrides the other, or if one + // is a function definition and the other is that function's declaration. + for (auto& [l, r] : fct_sig_pairs) { + if (fct_sig_nodes.find(l) == fct_sig_nodes.end()) { + continue; + } + if (fct_sig_nodes.find(r) == fct_sig_nodes.end()) { + continue; + } + auto& s1 = fct_sig_nodes[l]; + auto& s2 = fct_sig_nodes[r]; + assert(s1.size() == s2.size()); + auto i1 = s1.begin(); + auto i2 = s2.begin(); + while (i1 != s1.end()) { + output_helper.AddEdge(*i1, *i2); + i1++; + i2++; + } + } + + // Emits the list of edges. + output_helper.Emit(); + + return result; +}
diff --git a/tools/clang/rewrite_templated_container_fields/extract_edits.py b/tools/clang/rewrite_templated_container_fields/extract_edits.py new file mode 100755 index 0000000..b2f7ee6d8 --- /dev/null +++ b/tools/clang/rewrite_templated_container_fields/extract_edits.py
@@ -0,0 +1,187 @@ +#!/usr/bin/env vpython3 +# 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. +"""Script to extract edits from rewrite_templated_container_fields clang +tool output. + +If the tool emits edits, then the edits should look like this: + ... + {lhs_node1};{lhs_node2} + {node_n} + {lhs_node3};{lhs_node4} + ... + ... +Where lhs_node, rhs_node, and node_n represent a node's text representation +generated using rewrite_templated_container_fields' Node::ToString() function. + +The string representation has the following format: +`{is_field\,is_excluded\,has_auto_type\,r:::<file path>:::<offset>:::<length> +:::<replacement text>\,include-user-header:::<file path>:::-1:::-1 +:::<include text>}` + +where `is_field`,`is_excluded`, and `has_auto_type` are booleans represendted +as 0 or 1. + +extract_edits.py takes input that is concatenated from multiple tool +invocations and extract just the edits with the following steps: +1- Construct the adjacency list of nodes + (a pairs of nodes represents an edge in the graph) + +2- Run `PropagateExclusions` to exclude fields reachable + from a RAW_PTR_EXCLUSION annotated field. + +3- Run `DFS` starting from non-excluded nodes and emit + edtis for reachable nodes. + +extract_edits.py would then emit the following output: + <edit1> + <edit2> + <edit3> + ... +Where the edit is either a replacemnt or an include directive. + +For more details about how the tool works, see the doc here: +https://docs.google.com/document/d/1P8wLVS3xueI4p3EAPO4JJP6d1_zVp5SapQB0EW9iHQI/ +""" + +from __future__ import print_function +from collections import defaultdict +import sys + + +class Node: + is_field = "0" + is_excluded = "0" + has_auto_type = "0" + replacement = "" + include_directive = "" + neighbors = set() + + def __init__(self, is_field, is_excluded, has_auto_type, replacement, + include_directive) -> None: + self.is_field = is_field + self.is_excluded = is_excluded + self.replacement = replacement + self.has_auto_type = has_auto_type + self.include_directive = include_directive + self.neighbors = set() + + def __eq__(self, other): + if isinstance(other, Node): + return self.replacement == other.replacement + return False + + def __hash__(self) -> int: + return hash((self.replacement, self.include_directive)) + + +def GetNode(txt: str): + txt = txt[1:len(txt) - 1] + x = txt.split('\\,') + return Node(x[0], x[1], x[2], x[3], x[4]) + + +def DFS(visited: set, graph: defaultdict, key: str, key_to_node: defaultdict, + changes: set): + if key not in visited: + node = key_to_node[key] + if node.has_auto_type == "0": + changes.add(node.replacement) + changes.add(node.include_directive) + visited.add(key) + for neighbour in graph[key]: + DFS(visited, graph, neighbour.replacement, key_to_node, changes) + + +# to propagate field exclusions to all neighbors +def PropagateExclusions(visited: set, graph: defaultdict, key: str, + key_to_node: defaultdict): + if key not in visited: + n = key_to_node[key] + n.is_excluded = "1" + key_to_node[key] = n + visited.add(key) + for neighbour in graph[key]: + PropagateExclusions(visited, graph, neighbour.replacement, key_to_node) + + +def main(): + graph = defaultdict() + key_to_node = defaultdict() # since we cannot use nodes as keys + # to map, use this to map node replacemnt to node. + inside_marker_lines = False + changes = set() + excluded_fields = set() + for line in sys.stdin: + line = line.rstrip("\n\r") + if line == '==== BEGIN EDITS ====': + inside_marker_lines = True + continue + if line == '==== END EDITS ====': + inside_marker_lines = False + continue + if inside_marker_lines: + changes.add(line) + continue + + ar = line.split(";") + # These are fieldDecls + if len(ar) == 1: + lhs = GetNode(ar[0]) + # if the field is annotated with RAW_PTR_EXCLUSION, + # add it to the set of excluded fields + # this will be later propagated to all neighboring fields. + if lhs.is_excluded == "1": + excluded_fields.add(lhs.replacement) + lhs.is_excluded = "0" + key_to_node[lhs.replacement] = lhs + if lhs.replacement not in graph: + graph.setdefault(lhs.replacement, set()) + continue + + lhs = GetNode(ar[0]) + rhs = GetNode(ar[1]) + + # In the case of a typedefNameDecl, all the var/param/fields + # end up creating the same replacement. What is being done here is + # that if any field has a typedefNameDecl type, make all matches + # current and previous marked as is_field + if lhs.replacement in key_to_node.keys(): + lhs.is_field = "1" if lhs.is_field == "1" or key_to_node[ + lhs.replacement].is_field == "1" else "0" + + if rhs.replacement in key_to_node.keys(): + rhs.is_field = "1" if rhs.is_field == "1" or key_to_node[ + rhs.replacement].is_field == "1" else "0" + + key_to_node[lhs.replacement] = lhs + key_to_node[rhs.replacement] = rhs + + if lhs.replacement not in graph: + graph.setdefault(lhs.replacement, set()) + graph[lhs.replacement].add(rhs) + + if rhs.replacement not in graph: + graph.setdefault(rhs.replacement, set()) + graph[rhs.replacement].add(lhs) + + # Propagate changes to all excluded fields + visited = set() + for key in excluded_fields: + key_to_node[key].is_excluded = "1" + PropagateExclusions(visited, graph, key, key_to_node) + + visited = set() + for key in graph.keys(): + node = key_to_node[key] + if node.is_field == "1" and node.is_excluded == "0" and key not in visited: + DFS(visited, graph, key, key_to_node, changes) + changes = sorted(changes) + for text in changes: + print(text) + return 0 + + +if __name__ == '__main__': + sys.exit(main())
diff --git a/tools/clang/rewrite_templated_container_fields/rewrite-multiple-platforms.sh b/tools/clang/rewrite_templated_container_fields/rewrite-multiple-platforms.sh new file mode 100755 index 0000000..fffed06 --- /dev/null +++ b/tools/clang/rewrite_templated_container_fields/rewrite-multiple-platforms.sh
@@ -0,0 +1,185 @@ +#!/bin/bash +# 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. + +# IMPORTANT! Before running this script you have to run +# `rm -r ~/scratch && mkdir ~/scratch` first +# +# +# For more fine-grained instructions, see: +# https://docs.google.com/document/d/1chTvr3fSofQNV_PDPEHRyUgcJCQBgTDOOBriW9gIm9M/edit?ts=5e9549a2#heading=h.fjdnrdg1gcty + +set -e # makes the script quit on any command failure + +PLATFORMS="linux,win,android" +if [ "$1" != "" ] +then + PLATFORMS="$1" +fi + +SCRIPT_PATH=$(realpath $0) +REWRITER_SRC_DIR=$(dirname $SCRIPT_PATH) + +COMPILE_DIRS=. +EDIT_DIRS=. + +# Save llvm-build as it is about to be overwritten. +mv third_party/llvm-build third_party/llvm-build-upstream + +# Build and test the rewriter. +echo "*** Building the rewriter ***" +time tools/clang/scripts/build.py \ + --without-android \ + --without-fuchsia \ + --extra-tools rewrite_templated_container_fields +tools/clang/rewrite_templated_container_fields/tests/run_all_tests.py + +args_for_platform() { + case "$1" in + + android) + cat <<EOF +target_os = "android" +clang_use_chrome_plugins = false +is_chrome_branded = true +is_debug = false +dcheck_always_on = true +is_official_build = true +symbol_level = 1 +use_goma = false +enable_remoting = true +enable_webview_bundles = true +ffmpeg_branding = "Chrome" +proprietary_codecs = true +force_enable_raw_ptr_exclusion = true +EOF + ;; + + win) + cat <<EOF +target_os = "win" +clang_use_chrome_plugins = false +enable_precompiled_headers = false +is_chrome_branded = true +is_debug = false +dcheck_always_on = true +is_official_build = true +symbol_level = 1 +use_goma = false +chrome_pgo_phase = 0 +force_enable_raw_ptr_exclusion = true +EOF + ;; + + linux) + cat <<EOF +target_os = "linux" +dcheck_always_on = true +is_chrome_branded = true +is_debug = false +is_official_build = true +use_goma = false +chrome_pgo_phase = 0 +force_enable_raw_ptr_exclusion = true +EOF + ;; + + cros) + cat <<EOF +target_os = "chromeos" +chromeos_is_browser_only = true +dcheck_always_on = true +is_chrome_branded = true +is_debug = false +is_official_build = true +use_goma = false +chrome_pgo_phase = 0 +force_enable_raw_ptr_exclusion = true +EOF + ;; + + mac) + cat <<EOF +target_os = "mac" +dcheck_always_on = true +is_chrome_branded = true +is_debug = false +is_official_build = true +use_goma = false +chrome_pgo_phase = 0 +symbol_level = 1 +force_enable_raw_ptr_exclusion = true +EOF + ;; + + *) + echo "unknown platform" + exit 1 + ;; + esac +} + +pre_process() { + PLATFORM="$1" + OUT_DIR="out/rewrite-$PLATFORM" + + mkdir -p "$OUT_DIR" + args_for_platform "$PLATFORM" > "$OUT_DIR/args.gn" + + # Build generated files that a successful compilation depends on. + echo "*** Preparing targets for $PLATFORM ***" + gn gen $OUT_DIR + time ninja -C $OUT_DIR -t targets all \ + | grep '^gen/.*\(\.h\|inc\|css_tokenizer_codepoints.cc\)' \ + | cut -d : -f 1 \ + | xargs -s $(expr $(getconf ARG_MAX) - 256) ninja -C $OUT_DIR + + TARGET_OS_OPTION="" + if [ $PLATFORM = "win" ]; then + TARGET_OS_OPTION="--target_os=win" + fi +} + +main_rewrite() { + PLATFORM=$1 + OUT_DIR="out/rewrite-${PLATFORM}" + + TARGET_OS_OPTION="" + if [ $PLATFORM = "win" ]; then + TARGET_OS_OPTION="--target_os=win" + fi + + # Main rewrite. + echo "*** Running the main rewrite phase for $PLATFORM ***" + time tools/clang/scripts/run_tool.py \ + $TARGET_OS_OPTION \ + --tool rewrite_templated_container_fields \ + -p $OUT_DIR \ + $COMPILE_DIRS > ~/scratch/rewriter-$PLATFORM.main.out + cat ~/scratch/rewriter-$PLATFORM.main.out >> ~/scratch/rewriter.main.out +} + +for PLATFORM in ${PLATFORMS//,/ } +do + pre_process "$PLATFORM" +done + +for PLATFORM in ${PLATFORMS//,/ } +do + main_rewrite "$PLATFORM" +done + +# Apply edits generated by the main rewrite. +echo "*** Applying edits ***" +cat ~/scratch/rewriter.main.out | \ + tools/clang/rewrite_templated_container_fields/extract_edits.py | \ + tools/clang/scripts/apply_edits.py -p out/rewrite-win $EDIT_DIRS + +# Format sources, as many lines are likely over 80 chars now. +echo "*** Formatting ***" +time git cl format + +# Restore llvm-build. Without this, your future builds will be painfully slow. +rm -r -f third_party/llvm-build +mv third_party/llvm-build-upstream third_party/llvm-build
diff --git a/tools/clang/rewrite_templated_container_fields/rewrite.sh b/tools/clang/rewrite_templated_container_fields/rewrite.sh new file mode 100755 index 0000000..5cbd4bf --- /dev/null +++ b/tools/clang/rewrite_templated_container_fields/rewrite.sh
@@ -0,0 +1,76 @@ +#!/bin/bash +# 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. + +# IMPORTANT! Before running this script you have to perform these steps: +# 1. Run `mkdir ~/scratch` +# 2. Run `gn args out/{your_out_dir}` and set the following options: +# use_goma = false +# # this can be skipped if you do this in build/config/clang/clang.gni +# clang_use_chrome_plugins = false +# +# (You can do these steps only once, as long as you don't delete the directories +# between rewrites.) +# +# For more fine-grained instructions, see: +# https://docs.google.com/document/d/1chTvr3fSofQNV_PDPEHRyUgcJCQBgTDOOBriW9gIm9M/edit?ts=5e9549a2#heading=h.fjdnrdg1gcty + +set -e # makes the script quit on any command failure + +OUT_DIR="out/rewrite" +if [ "$1" != "" ] +then + OUT_DIR="$1" +fi + +SCRIPT_PATH=$(realpath $0) +REWRITER_SRC_DIR=$(dirname $SCRIPT_PATH) + +COMPILE_DIRS=. +EDIT_DIRS=. + +# Save llvm-build as it is about to be overwritten. +mv third_party/llvm-build third_party/llvm-build-upstream + +# Build and test the rewriter. +echo "*** Building the rewriter ***" +time tools/clang/scripts/build.py \ + --without-android \ + --without-fuchsia \ + --extra-tools rewrite_templated_container_fields +tools/clang/rewrite_templated_container_fields/tests/run_all_tests.py + +# Build generated files that a successful compilation depends on. +echo "*** Preparing targets ***" +gn gen $OUT_DIR +GEN_H_TARGETS=`ninja -C $OUT_DIR -t targets all | grep '^gen/.*\(\.h\|inc\|css_tokenizer_codepoints.cc\)' | cut -d : -f 1` +time ninja -C $OUT_DIR $GEN_H_TARGETS + +if grep -qE '^\s*target_os\s*=\s*("win"|win)' $OUT_DIR/args.gn +then + TARGET_OS_OPTION="--target_os=win" +fi + +# Main rewrite. +echo "*** Running the main rewrite phase ***" +time tools/clang/scripts/run_tool.py \ + $TARGET_OS_OPTION \ + --tool rewrite_templated_container_fields \ + --generate-compdb \ + -p $OUT_DIR \ + $COMPILE_DIRS > ~/scratch/rewriter.main.out + +# Apply edits generated by the main rewrite. +echo "*** Applying edits ***" +cat ~/scratch/rewriter.main.out | \ + tools/clang/rewrite_templated_container_fields/extract_edits.py | \ + tools/clang/scripts/apply_edits.py -p $OUT_DIR $EDIT_DIRS + +# Format sources, as many lines are likely over 80 chars now. +echo "*** Formatting ***" +time git cl format + +# Restore llvm-build. Without this, your future builds will be painfully slow. +rm -r -f third_party/llvm-build +mv third_party/llvm-build-upstream third_party/llvm-build
diff --git a/tools/clang/rewrite_templated_container_fields/tests/assignment-tests-expected.cc b/tools/clang/rewrite_templated_container_fields/tests/assignment-tests-expected.cc new file mode 100644 index 0000000..ebb5e03 --- /dev/null +++ b/tools/clang/rewrite_templated_container_fields/tests/assignment-tests-expected.cc
@@ -0,0 +1,321 @@ +// 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 <vector> + +#include "base/memory/raw_ptr.h" + +struct S {}; + +struct obj { + // Expected rewrite: const std::vector<raw_ptr<S>>& get(); + const std::vector<raw_ptr<S>>& get() { return member; } + + // Expected rewrite: std::vector<raw_ptr<S>> member; + std::vector<raw_ptr<S>> member; +}; + +// Expected rewrite: std::vector<raw_ptr<S>> get_value(); +std::vector<raw_ptr<S>> get_value() { + return {}; +} + +// Expected rewrite: std::vector<raw_ptr<S>>* get_ptr(); +std::vector<raw_ptr<S>>* get_ptr() { + return nullptr; +} + +// No rewrite expected. +std::vector<S*> unrelated_fct() { + return {}; +} + +void fct() { + obj o; + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>> a = o.member; + std::vector<raw_ptr<S>> a = o.member; + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<raw_ptr<S>> b; + // a = b; + a = b; + + // Expected rewrite: std::vector<raw_ptr<S>> c; + std::vector<raw_ptr<S>> c; + c.swap(b); + + // Expected rewrite: std::vector<raw_ptr<S>> d; + std::vector<raw_ptr<S>> d; + std::swap(c, d); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>> a = o.member; + auto a = o.member; + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<raw_ptr<S>> b; + // a = b; + a = b; + + // Expected rewrite: std::vector<raw_ptr<S>> c; + std::vector<raw_ptr<S>> c; + c.swap(a); + + // Expected rewrite: std::vector<raw_ptr<S>> d; + std::vector<raw_ptr<S>> d; + std::swap(d, a); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>> a = o.member; + std::vector<raw_ptr<S>> a = o.member; + // Expected rewrite: a = std::vector<raw_ptr<S>>(); + a = std::vector<raw_ptr<S>>(); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>> a = o.member; + auto a = o.member; + // Expected rewrite: a = std::vector<raw_ptr<S>>(); + a = std::vector<raw_ptr<S>>(); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>> a = o.member; + std::vector<raw_ptr<S>> a = o.member; + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<raw_ptr<S>> b; + // a = std::move(b); + a = std::move(b); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>> a = o.member; + auto a = o.member; + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<raw_ptr<S>> b; + // a = std::move(b); + a = std::move(b); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>> a = o.member; + std::vector<raw_ptr<S>>* a = &o.member; + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<raw_ptr<S>> b; + // a = &b; + a = &b; + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>> a = o.member; + auto* a = &o.member; + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<raw_ptr<S>> b; + // a = &b; + a = &b; + + // Expected rewrite: std::vector<raw_ptr<S>> c; + std::vector<raw_ptr<S>> c; + c.swap(*a); + + // Expected rewrite: std::vector<raw_ptr<S>> d; + std::vector<raw_ptr<S>> d; + std::swap(d, *a); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>>* a = &o.member; + std::vector<raw_ptr<S>>* a = &o.member; + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<raw_ptr<S>> b; + // *a = b; + *a = b; + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>>* a = &o.member; + std::vector<raw_ptr<S>>* a = &o.member; + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<raw_ptr<S>> b; + // *a = b; + std::swap(*a, b); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>>* a = &o.member; + std::vector<raw_ptr<S>>* a = &o.member; + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<raw_ptr<S>> b; + // *a = b; + a->swap(b); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>>* a = &o.member; + auto* a = &o.member; + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<raw_ptr<S>> b; + // *a = b; + *a = b; + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>>* a = &o.member; + auto* a = &o.member; + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<raw_ptr<S>> b; + // *a = b; + std::swap(*a, b); + + // Expected rewrite: std::vector<raw_ptr<S>> d; + std::vector<raw_ptr<S>> d; + d.swap(*a); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>>* a = &o.member; + std::vector<raw_ptr<S>>* a = &o.member; + // Expected rewrite: std::vector<raw_ptr<S>>* b; + std::vector<raw_ptr<S>>* b = nullptr; + // *a = b; + *a = *b; + + // Expected rewrite: std::vector<raw_ptr<S>>* d; + std::vector<raw_ptr<S>>* d; + d->swap(*a); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>>* a = &o.member; + std::vector<raw_ptr<S>>* a = &o.member; + // Expected rewrite: std::vector<raw_ptr<S>>* b; + std::vector<raw_ptr<S>>* b = nullptr; + // *a = b; + std::swap(*a, *b); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>>* a = &o.member; + auto* a = &o.member; + // Expected rewrite: std::vector<raw_ptr<S>>* b; + std::vector<raw_ptr<S>>* b = nullptr; + // *a = b; + *a = *b; + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>>* a = &o.member; + auto* a = &o.member; + // Expected rewrite: std::vector<raw_ptr<S>>* b; + std::vector<raw_ptr<S>>* b = nullptr; + // *a = b; + std::swap(*a, *b); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>> a = o.member; + std::vector<raw_ptr<S>> a = o.member; + // a = fct(); + a = get_value(); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>> a = o.member; + auto a = o.member; + // a = fct(); + auto fct_value = []() -> std::vector<raw_ptr<S>> { return {}; }; + a = fct_value(); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>>* a = &o.member; + std::vector<raw_ptr<S>>* a = &o.member; + // a = fct(); + a = get_ptr(); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>>* a = &o.member; + auto* a = &o.member; + // a = fct(); + auto fct_ptr = []() -> std::vector<raw_ptr<S>>* { return nullptr; }; + a = fct_ptr(); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>>* a = &o.member; + const std::vector<raw_ptr<S>>* a = &o.member; + // a = &fct(); + a = &o.get(); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>> a; + std::vector<raw_ptr<S>> a; + auto fct = [&]() -> std::vector<raw_ptr<S>>* { return &o.member; }; + a = *fct(); + + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<raw_ptr<S>> b; + std::swap(b, *fct()); + } + + { + // Expected rewrite: std::vector<raw_ptr<S>>::iterator it; + std::vector<raw_ptr<S>>::iterator it; + it = o.member.begin(); + (void)it; + } + + { + auto it = o.member.begin(); + // Expected rewrite: std::vector<raw_ptr<S>>::iterator it2; + std::vector<raw_ptr<S>>::iterator it2; + it2 = it; + } + + { + // create a link with a member to propagate the rewrite. + std::vector<raw_ptr<S>> a = o.member; + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<raw_ptr<S>> b; + // a = b; + // Expected rewrite: a = (true) ? b : std::vector<raw_ptr<S>>(); + a = (true) ? b : std::vector<raw_ptr<S>>(); + } + + { + // create a link with a member to propagate the rewrite. + auto a = o.member; + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<raw_ptr<S>> b; + // a = b; + // Expected rewrite: a = (true) ? b : std::vector<raw_ptr<S>>(); + a = (true) ? b : std::vector<raw_ptr<S>>(); + } +}
diff --git a/tools/clang/rewrite_templated_container_fields/tests/assignment-tests-original.cc b/tools/clang/rewrite_templated_container_fields/tests/assignment-tests-original.cc new file mode 100644 index 0000000..1ee70afd --- /dev/null +++ b/tools/clang/rewrite_templated_container_fields/tests/assignment-tests-original.cc
@@ -0,0 +1,319 @@ +// 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 <vector> + +struct S {}; + +struct obj { + // Expected rewrite: const std::vector<raw_ptr<S>>& get(); + const std::vector<S*>& get() { return member; } + + // Expected rewrite: std::vector<raw_ptr<S>> member; + std::vector<S*> member; +}; + +// Expected rewrite: std::vector<raw_ptr<S>> get_value(); +std::vector<S*> get_value() { + return {}; +} + +// Expected rewrite: std::vector<raw_ptr<S>>* get_ptr(); +std::vector<S*>* get_ptr() { + return nullptr; +} + +// No rewrite expected. +std::vector<S*> unrelated_fct() { + return {}; +} + +void fct() { + obj o; + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>> a = o.member; + std::vector<S*> a = o.member; + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<S*> b; + // a = b; + a = b; + + // Expected rewrite: std::vector<raw_ptr<S>> c; + std::vector<S*> c; + c.swap(b); + + // Expected rewrite: std::vector<raw_ptr<S>> d; + std::vector<S*> d; + std::swap(c, d); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>> a = o.member; + auto a = o.member; + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<S*> b; + // a = b; + a = b; + + // Expected rewrite: std::vector<raw_ptr<S>> c; + std::vector<S*> c; + c.swap(a); + + // Expected rewrite: std::vector<raw_ptr<S>> d; + std::vector<S*> d; + std::swap(d, a); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>> a = o.member; + std::vector<S*> a = o.member; + // Expected rewrite: a = std::vector<raw_ptr<S>>(); + a = std::vector<S*>(); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>> a = o.member; + auto a = o.member; + // Expected rewrite: a = std::vector<raw_ptr<S>>(); + a = std::vector<S*>(); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>> a = o.member; + std::vector<S*> a = o.member; + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<S*> b; + // a = std::move(b); + a = std::move(b); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>> a = o.member; + auto a = o.member; + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<S*> b; + // a = std::move(b); + a = std::move(b); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>> a = o.member; + std::vector<S*>* a = &o.member; + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<S*> b; + // a = &b; + a = &b; + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>> a = o.member; + auto* a = &o.member; + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<S*> b; + // a = &b; + a = &b; + + // Expected rewrite: std::vector<raw_ptr<S>> c; + std::vector<S*> c; + c.swap(*a); + + // Expected rewrite: std::vector<raw_ptr<S>> d; + std::vector<S*> d; + std::swap(d, *a); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>>* a = &o.member; + std::vector<S*>* a = &o.member; + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<S*> b; + // *a = b; + *a = b; + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>>* a = &o.member; + std::vector<S*>* a = &o.member; + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<S*> b; + // *a = b; + std::swap(*a, b); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>>* a = &o.member; + std::vector<S*>* a = &o.member; + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<S*> b; + // *a = b; + a->swap(b); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>>* a = &o.member; + auto* a = &o.member; + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<S*> b; + // *a = b; + *a = b; + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>>* a = &o.member; + auto* a = &o.member; + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<S*> b; + // *a = b; + std::swap(*a, b); + + // Expected rewrite: std::vector<raw_ptr<S>> d; + std::vector<S*> d; + d.swap(*a); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>>* a = &o.member; + std::vector<S*>* a = &o.member; + // Expected rewrite: std::vector<raw_ptr<S>>* b; + std::vector<S*>* b = nullptr; + // *a = b; + *a = *b; + + // Expected rewrite: std::vector<raw_ptr<S>>* d; + std::vector<S*>* d; + d->swap(*a); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>>* a = &o.member; + std::vector<S*>* a = &o.member; + // Expected rewrite: std::vector<raw_ptr<S>>* b; + std::vector<S*>* b = nullptr; + // *a = b; + std::swap(*a, *b); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>>* a = &o.member; + auto* a = &o.member; + // Expected rewrite: std::vector<raw_ptr<S>>* b; + std::vector<S*>* b = nullptr; + // *a = b; + *a = *b; + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>>* a = &o.member; + auto* a = &o.member; + // Expected rewrite: std::vector<raw_ptr<S>>* b; + std::vector<S*>* b = nullptr; + // *a = b; + std::swap(*a, *b); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>> a = o.member; + std::vector<S*> a = o.member; + // a = fct(); + a = get_value(); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>> a = o.member; + auto a = o.member; + // a = fct(); + auto fct_value = []() -> std::vector<S*> { return {}; }; + a = fct_value(); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>>* a = &o.member; + std::vector<S*>* a = &o.member; + // a = fct(); + a = get_ptr(); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>>* a = &o.member; + auto* a = &o.member; + // a = fct(); + auto fct_ptr = []() -> std::vector<S*>* { return nullptr; }; + a = fct_ptr(); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>>* a = &o.member; + const std::vector<S*>* a = &o.member; + // a = &fct(); + a = &o.get(); + } + + { + // create a link with a member to propagate the rewrite. + // Expected rewrite: std::vector<raw_ptr<S>> a; + std::vector<S*> a; + auto fct = [&]() -> std::vector<S*>* { return &o.member; }; + a = *fct(); + + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<S*> b; + std::swap(b, *fct()); + } + + { + // Expected rewrite: std::vector<raw_ptr<S>>::iterator it; + std::vector<S*>::iterator it; + it = o.member.begin(); + (void)it; + } + + { + auto it = o.member.begin(); + // Expected rewrite: std::vector<raw_ptr<S>>::iterator it2; + std::vector<S*>::iterator it2; + it2 = it; + } + + { + // create a link with a member to propagate the rewrite. + std::vector<S*> a = o.member; + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<S*> b; + // a = b; + // Expected rewrite: a = (true) ? b : std::vector<raw_ptr<S>>(); + a = (true) ? b : std::vector<S*>(); + } + + { + // create a link with a member to propagate the rewrite. + auto a = o.member; + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<S*> b; + // a = b; + // Expected rewrite: a = (true) ? b : std::vector<raw_ptr<S>>(); + a = (true) ? b : std::vector<S*>(); + } +}
diff --git a/tools/clang/rewrite_templated_container_fields/tests/bind-tests-expected.cc b/tools/clang/rewrite_templated_container_fields/tests/bind-tests-expected.cc new file mode 100644 index 0000000..ab0e6281 --- /dev/null +++ b/tools/clang/rewrite_templated_container_fields/tests/bind-tests-expected.cc
@@ -0,0 +1,78 @@ +// 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 <vector> + +#include "base/memory/raw_ptr.h" + +template <typename Functor, typename... Args> +void BindOnce(Functor f, Args&&...) { + (void)f; +} + +template <typename Functor, typename... Args> +void BindRepeating(Functor f, Args&&...) { + (void)f; +} + +struct s { + // Expected rewrite: (const std::vector<raw_ptr<int>>& arg) + void do_something(const std::vector<raw_ptr<int>>& arg) { + // Expected rewrite: for(int* i : arg) + for (int* i : arg) { + (void)i; + } + } + + void fct() { BindOnce(&s::do_something, member); } + + // Expected rewrite: std::vector<raw_ptr<int>> member; + std::vector<raw_ptr<int>> member; +}; + +struct obj { + // Expected rewrite: std::vector<raw_ptr<const int>> member; + std::vector<raw_ptr<const int>> member; +}; + +int main() { + obj o; + // Expected rewrite: (const std::vector<raw_ptr<const int>>& arg) + BindOnce( + [](const std::vector<raw_ptr<const int>>& arg) { + // Expected rewrite: for(const int* i : arg) + for (const int* i : arg) { + (void)i; + } + }, + o.member); + + BindOnce( + [](const std::vector<raw_ptr<const int>>& arg) { + // Expected rewrite: for(const int* i : arg) + for (const int* i : arg) { + (void)i; + } + }, + std::ref(o.member)); + + BindOnce( + [](const std::vector<raw_ptr<const int>>& arg) { + // Expected rewrite: for(const int* i : arg) + for (const int* i : arg) { + (void)i; + } + }, + std::cref(o.member)); + + BindRepeating( + [](const std::vector<raw_ptr<const int>>& arg) { + // Expected rewrite: for(const int* i : arg) + for (const int* i : arg) { + (void)i; + } + }, + std::cref(o.member)); + + return 0; +}
diff --git a/tools/clang/rewrite_templated_container_fields/tests/bind-tests-original.cc b/tools/clang/rewrite_templated_container_fields/tests/bind-tests-original.cc new file mode 100644 index 0000000..2fbe238 --- /dev/null +++ b/tools/clang/rewrite_templated_container_fields/tests/bind-tests-original.cc
@@ -0,0 +1,76 @@ +// 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 <vector> + +template <typename Functor, typename... Args> +void BindOnce(Functor f, Args&&...) { + (void)f; +} + +template <typename Functor, typename... Args> +void BindRepeating(Functor f, Args&&...) { + (void)f; +} + +struct s { + // Expected rewrite: (const std::vector<raw_ptr<int>>& arg) + void do_something(const std::vector<int*>& arg) { + // Expected rewrite: for(int* i : arg) + for (auto* i : arg) { + (void)i; + } + } + + void fct() { BindOnce(&s::do_something, member); } + + // Expected rewrite: std::vector<raw_ptr<int>> member; + std::vector<int*> member; +}; + +struct obj { + // Expected rewrite: std::vector<raw_ptr<const int>> member; + std::vector<const int*> member; +}; + +int main() { + obj o; + // Expected rewrite: (const std::vector<raw_ptr<const int>>& arg) + BindOnce( + [](const std::vector<const int*>& arg) { + // Expected rewrite: for(const int* i : arg) + for (auto* i : arg) { + (void)i; + } + }, + o.member); + + BindOnce( + [](const std::vector<const int*>& arg) { + // Expected rewrite: for(const int* i : arg) + for (auto* i : arg) { + (void)i; + } + }, + std::ref(o.member)); + + BindOnce( + [](const std::vector<const int*>& arg) { + // Expected rewrite: for(const int* i : arg) + for (auto* i : arg) { + (void)i; + } + }, + std::cref(o.member)); + + BindRepeating( + [](const std::vector<const int*>& arg) { + // Expected rewrite: for(const int* i : arg) + for (auto* i : arg) { + (void)i; + } + }, + std::cref(o.member)); + + return 0; +}
diff --git a/tools/clang/rewrite_templated_container_fields/tests/callexpr-tests-expected.cc b/tools/clang/rewrite_templated_container_fields/tests/callexpr-tests-expected.cc new file mode 100644 index 0000000..75222206 --- /dev/null +++ b/tools/clang/rewrite_templated_container_fields/tests/callexpr-tests-expected.cc
@@ -0,0 +1,166 @@ +// 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 <vector> + +#include "base/memory/raw_ptr.h" + +struct S {}; + +struct obj { + // Expected rewrite: std::vector<raw_ptr<S>> member; + std::vector<raw_ptr<S>> member; +}; + +namespace n1 { +// Expected rewrite: fct(std::vector<raw_ptr<S>>& arg); +void fct(const std::vector<raw_ptr<S>>& arg) {} +void fct2() { + obj o; + fct(o.member); +} +} // namespace n1 + +namespace n2 { +// Expected rewrite: fct(std::vector<raw_ptr<S>>& arg); +void fct(const std::vector<raw_ptr<S>>& arg) {} +// Expected rewrite: fct2(std::vector<raw_ptr<S>>& arg); +void fct2(const std::vector<raw_ptr<S>>& arg) {} +void fct3() { + obj o; + // Expected rewrite: std::vector<raw_ptr<S>> temp = o.member; + std::vector<raw_ptr<S>> temp = o.member; + fct(temp); + + const auto& temp2 = o.member; + fct2(temp2); +} + +} // namespace n2 + +namespace n3 { +// Expected rewrite: fct1(std::vector<raw_ptr<S>>& arg); +void fct1(const std::vector<raw_ptr<S>>& arg) {} + +// Expected rewrite: fct2(std::vector<raw_ptr<S>>& arg); +void fct2(const std::vector<raw_ptr<S>>& arg) { + fct1(arg); +} + +void fct3() { + obj o; + // Expected rewrite: std::vector<raw_ptr<S>> temp = o.member; + std::vector<raw_ptr<S>> temp = o.member; + fct2(temp); +} +} // namespace n3 + +namespace n4 { +// Expected rewrite: fct(std::vector<raw_ptr<S>>* arg); +void fct(std::vector<raw_ptr<S>>* arg) {} +// Expected rewrite: fct2(std::vector<raw_ptr<S>>* arg); +void fct2(std::vector<raw_ptr<S>>* arg) {} + +void fct3() { + obj o; + fct(&o.member); + + auto temp = o.member; + fct2(&temp); +} +} // namespace n4 + +namespace n5 { +// Expected rewrite: fct(std::vector<raw_ptr<S>>* arg); +void fct(std::vector<raw_ptr<S>>* arg) {} +void fct2() { + obj o; + // Expected rewrite: std::vector<raw_ptr<S>> temp = o.member; + std::vector<raw_ptr<S>> temp = o.member; + fct(&temp); +} +} // namespace n5 + +namespace n6 { +// Expected rewrite: fct1(std::vector<raw_ptr<S>>* arg); +void fct1(std::vector<raw_ptr<S>>* arg) {} + +// Expected rewrite: fct2(std::vector<raw_ptr<S>>* arg); +void fct2(std::vector<raw_ptr<S>>* arg) { + fct1(arg); +} + +void fct3() { + obj o; + // Expected rewrite: std::vector<raw_ptr<S>> temp = o.member; + std::vector<raw_ptr<S>> temp = o.member; + fct2(&temp); +} +} // namespace n6 + +namespace n7 { +// Expected rewrite: fct(std::vector<raw_ptr<S>> arg); +void fct(std::vector<raw_ptr<S>> arg) {} +// Expected rewrite: fct2(std::vector<raw_ptr<S>> arg); +void fct2(std::vector<raw_ptr<S>> arg) {} +void fct2() { + obj o; + // Expected rewrite: std::vector<raw_ptr<S>>* temp = &o.member; + std::vector<raw_ptr<S>>* temp = &o.member; + fct(*temp); + + auto* temp2 = &o.member; + fct2(*temp2); +} +} // namespace n7 + +namespace n8 { +// Expected rewrite: fct1(std::vector<raw_ptr<S>> arg); +void fct1(std::vector<raw_ptr<S>> arg) {} + +// Expected rewrite: fct2(std::vector<raw_ptr<S>>* arg); +void fct2(std::vector<raw_ptr<S>>* arg) { + fct1(*arg); +} + +void fct3() { + obj o; + // Expected rewrite: std::vector<raw_ptr<S>> temp = o.member; + std::vector<raw_ptr<S>> temp = o.member; + fct2(&temp); +} +} // namespace n8 + +namespace n9 { +// Expected rewrite: std::vector<raw_ptr<S>> get() +std::vector<raw_ptr<S>> get() { + return {}; +} + +// Expected rewrite: fct(std::vector<raw_ptr<S>> arg); +void fct1(std::vector<raw_ptr<S>> arg) {} + +void fct() { + obj o; + o.member = get(); + fct1(get()); +} +} // namespace n9 + +namespace n10 { +// Expected rewrite: std::vector<raw_ptr<S>>& get() +std::vector<raw_ptr<S>>& get() { + // Expected rewrite: static std::vector<raw_ptr<S>> v; + static std::vector<raw_ptr<S>> v; + return v; +} + +// Expected rewrite: fct1(std::vector<raw_ptr<S>>* arg); +void fct1(std::vector<raw_ptr<S>>* arg) {} + +void fct() { + obj o; + o.member = get(); + fct1(&get()); +} +} // namespace n10
diff --git a/tools/clang/rewrite_templated_container_fields/tests/callexpr-tests-original.cc b/tools/clang/rewrite_templated_container_fields/tests/callexpr-tests-original.cc new file mode 100644 index 0000000..ac46e72 --- /dev/null +++ b/tools/clang/rewrite_templated_container_fields/tests/callexpr-tests-original.cc
@@ -0,0 +1,164 @@ +// 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 <vector> + +struct S {}; + +struct obj { + // Expected rewrite: std::vector<raw_ptr<S>> member; + std::vector<S*> member; +}; + +namespace n1 { +// Expected rewrite: fct(std::vector<raw_ptr<S>>& arg); +void fct(const std::vector<S*>& arg) {} +void fct2() { + obj o; + fct(o.member); +} +} // namespace n1 + +namespace n2 { +// Expected rewrite: fct(std::vector<raw_ptr<S>>& arg); +void fct(const std::vector<S*>& arg) {} +// Expected rewrite: fct2(std::vector<raw_ptr<S>>& arg); +void fct2(const std::vector<S*>& arg) {} +void fct3() { + obj o; + // Expected rewrite: std::vector<raw_ptr<S>> temp = o.member; + std::vector<S*> temp = o.member; + fct(temp); + + const auto& temp2 = o.member; + fct2(temp2); +} + +} // namespace n2 + +namespace n3 { +// Expected rewrite: fct1(std::vector<raw_ptr<S>>& arg); +void fct1(const std::vector<S*>& arg) {} + +// Expected rewrite: fct2(std::vector<raw_ptr<S>>& arg); +void fct2(const std::vector<S*>& arg) { + fct1(arg); +} + +void fct3() { + obj o; + // Expected rewrite: std::vector<raw_ptr<S>> temp = o.member; + std::vector<S*> temp = o.member; + fct2(temp); +} +} // namespace n3 + +namespace n4 { +// Expected rewrite: fct(std::vector<raw_ptr<S>>* arg); +void fct(std::vector<S*>* arg) {} +// Expected rewrite: fct2(std::vector<raw_ptr<S>>* arg); +void fct2(std::vector<S*>* arg) {} + +void fct3() { + obj o; + fct(&o.member); + + auto temp = o.member; + fct2(&temp); +} +} // namespace n4 + +namespace n5 { +// Expected rewrite: fct(std::vector<raw_ptr<S>>* arg); +void fct(std::vector<S*>* arg) {} +void fct2() { + obj o; + // Expected rewrite: std::vector<raw_ptr<S>> temp = o.member; + std::vector<S*> temp = o.member; + fct(&temp); +} +} // namespace n5 + +namespace n6 { +// Expected rewrite: fct1(std::vector<raw_ptr<S>>* arg); +void fct1(std::vector<S*>* arg) {} + +// Expected rewrite: fct2(std::vector<raw_ptr<S>>* arg); +void fct2(std::vector<S*>* arg) { + fct1(arg); +} + +void fct3() { + obj o; + // Expected rewrite: std::vector<raw_ptr<S>> temp = o.member; + std::vector<S*> temp = o.member; + fct2(&temp); +} +} // namespace n6 + +namespace n7 { +// Expected rewrite: fct(std::vector<raw_ptr<S>> arg); +void fct(std::vector<S*> arg) {} +// Expected rewrite: fct2(std::vector<raw_ptr<S>> arg); +void fct2(std::vector<S*> arg) {} +void fct2() { + obj o; + // Expected rewrite: std::vector<raw_ptr<S>>* temp = &o.member; + std::vector<S*>* temp = &o.member; + fct(*temp); + + auto* temp2 = &o.member; + fct2(*temp2); +} +} // namespace n7 + +namespace n8 { +// Expected rewrite: fct1(std::vector<raw_ptr<S>> arg); +void fct1(std::vector<S*> arg) {} + +// Expected rewrite: fct2(std::vector<raw_ptr<S>>* arg); +void fct2(std::vector<S*>* arg) { + fct1(*arg); +} + +void fct3() { + obj o; + // Expected rewrite: std::vector<raw_ptr<S>> temp = o.member; + std::vector<S*> temp = o.member; + fct2(&temp); +} +} // namespace n8 + +namespace n9 { +// Expected rewrite: std::vector<raw_ptr<S>> get() +std::vector<S*> get() { + return {}; +} + +// Expected rewrite: fct(std::vector<raw_ptr<S>> arg); +void fct1(std::vector<S*> arg) {} + +void fct() { + obj o; + o.member = get(); + fct1(get()); +} +} // namespace n9 + +namespace n10 { +// Expected rewrite: std::vector<raw_ptr<S>>& get() +std::vector<S*>& get() { + // Expected rewrite: static std::vector<raw_ptr<S>> v; + static std::vector<S*> v; + return v; +} + +// Expected rewrite: fct1(std::vector<raw_ptr<S>>* arg); +void fct1(std::vector<S*>* arg) {} + +void fct() { + obj o; + o.member = get(); + fct1(&get()); +} +} // namespace n10
diff --git a/tools/clang/rewrite_templated_container_fields/tests/constructexpr-tests-expected.cc b/tools/clang/rewrite_templated_container_fields/tests/constructexpr-tests-expected.cc new file mode 100644 index 0000000..cc55b2cb --- /dev/null +++ b/tools/clang/rewrite_templated_container_fields/tests/constructexpr-tests-expected.cc
@@ -0,0 +1,87 @@ +// 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 <vector> + +#include "base/memory/raw_ptr.h" + +struct S {}; + +class A { + public: + // Expected rewrite: A(const std::vector<raw_ptr<S>>& arg); + A(const std::vector<raw_ptr<S>>& arg) : member(arg) {} + + // Expected rewrite: A(const std::vector<raw_ptr<S>>* arg); + A(const std::vector<raw_ptr<S>>* arg) : member(*arg) {} + + private: + // Expected rewrite: std::vector<raw_ptr<S>> member; + std::vector<raw_ptr<S>> member; +}; + +struct obj { + // Expected rewrite: std::vector<raw_ptr<S>> member; + std::vector<raw_ptr<S>> member; +}; + +void fct() { + { + // Expected rewrite: std::vector<raw_ptr<S>> temp; + std::vector<raw_ptr<S>> temp; + A a(temp); + } + { + // Expected rewrite: std::vector<raw_ptr<S>> temp; + std::vector<raw_ptr<S>> temp; + A* a = new A(temp); + } + + { + // Expected rewrite: std::vector<raw_ptr<S>> temp; + std::vector<raw_ptr<S>> temp; + A a(&temp); + } + + { + // Expected rewrite: std::vector<raw_ptr<S>> temp; + std::vector<raw_ptr<S>> temp; + A* a = new A(&temp); + } + + { + // Expected rewrite: std::vector<raw_ptr<S>> temp; + std::vector<raw_ptr<S>>* temp; + A a(*temp); + } + + { + // Expected rewrite: -> std::vector<raw_ptr<S>> { return {}; }; + auto fct = []() -> std::vector<raw_ptr<S>> { return {}; }; + A a(fct()); + } + + { + // Expected rewrite: -> std::vector<raw_ptr<S>>* { return nullptr; }; + auto fct = []() -> std::vector<raw_ptr<S>>* { return nullptr; }; + A a(*fct()); + } + + { + // Expected rewrite: std::vector<raw_ptr<S>> temp; + std::vector<raw_ptr<S>> temp; + obj o{temp}; + } + + { + // Expected rewrite: std::vector<raw_ptr<S>> temp; + std::vector<raw_ptr<S>> temp; + obj* o = new obj{temp}; + } + + { + // Expected rewrite: -> std::vector<raw_ptr<S>> { return {}; }; + auto fct = []() -> std::vector<raw_ptr<S>> { return {}; }; + obj o{fct()}; + } +}
diff --git a/tools/clang/rewrite_templated_container_fields/tests/constructexpr-tests-original.cc b/tools/clang/rewrite_templated_container_fields/tests/constructexpr-tests-original.cc new file mode 100644 index 0000000..09c0f85 --- /dev/null +++ b/tools/clang/rewrite_templated_container_fields/tests/constructexpr-tests-original.cc
@@ -0,0 +1,85 @@ +// 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 <vector> + +struct S {}; + +class A { + public: + // Expected rewrite: A(const std::vector<raw_ptr<S>>& arg); + A(const std::vector<S*>& arg) : member(arg) {} + + // Expected rewrite: A(const std::vector<raw_ptr<S>>* arg); + A(const std::vector<S*>* arg) : member(*arg) {} + + private: + // Expected rewrite: std::vector<raw_ptr<S>> member; + std::vector<S*> member; +}; + +struct obj { + // Expected rewrite: std::vector<raw_ptr<S>> member; + std::vector<S*> member; +}; + +void fct() { + { + // Expected rewrite: std::vector<raw_ptr<S>> temp; + std::vector<S*> temp; + A a(temp); + } + { + // Expected rewrite: std::vector<raw_ptr<S>> temp; + std::vector<S*> temp; + A* a = new A(temp); + } + + { + // Expected rewrite: std::vector<raw_ptr<S>> temp; + std::vector<S*> temp; + A a(&temp); + } + + { + // Expected rewrite: std::vector<raw_ptr<S>> temp; + std::vector<S*> temp; + A* a = new A(&temp); + } + + { + // Expected rewrite: std::vector<raw_ptr<S>> temp; + std::vector<S*>* temp; + A a(*temp); + } + + { + // Expected rewrite: -> std::vector<raw_ptr<S>> { return {}; }; + auto fct = []() -> std::vector<S*> { return {}; }; + A a(fct()); + } + + { + // Expected rewrite: -> std::vector<raw_ptr<S>>* { return nullptr; }; + auto fct = []() -> std::vector<S*>* { return nullptr; }; + A a(*fct()); + } + + { + // Expected rewrite: std::vector<raw_ptr<S>> temp; + std::vector<S*> temp; + obj o{temp}; + } + + { + // Expected rewrite: std::vector<raw_ptr<S>> temp; + std::vector<S*> temp; + obj* o = new obj{temp}; + } + + { + // Expected rewrite: -> std::vector<raw_ptr<S>> { return {}; }; + auto fct = []() -> std::vector<S*> { return {}; }; + obj o{fct()}; + } +}
diff --git a/tools/clang/rewrite_templated_container_fields/tests/ctor-initializer-tests-expected.cc b/tools/clang/rewrite_templated_container_fields/tests/ctor-initializer-tests-expected.cc new file mode 100644 index 0000000..eb76308 --- /dev/null +++ b/tools/clang/rewrite_templated_container_fields/tests/ctor-initializer-tests-expected.cc
@@ -0,0 +1,50 @@ +// 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 <vector> + +#include "base/memory/raw_ptr.h" + +struct S {}; + +// Expected rewrite: std::vector<raw_ptr<S>> get(); +std::vector<raw_ptr<S>> get() { + return {}; +} + +// Expected rewrite: std::vector<raw_ptr<S>>& get2(); +std::vector<raw_ptr<S>>& get2() { + // Expected rewrite: static std::vector<raw_ptr<S>> v; + static std::vector<raw_ptr<S>> v; + return v; +} + +class A { + // Expected rewrite: A(const std::vector<raw_ptr<S>>& arg1, + A(const std::vector<raw_ptr<S>>& arg1, + // Expected rewrite: const std::vector<raw_ptr<S>>& arg2, + const std::vector<raw_ptr<S>>& arg2, + // Expected rewrite: const std::vector<raw_ptr<S>>& arg3, + const std::vector<raw_ptr<S>>& arg3, + // No rewrite expected. + const std::vector<S*>& arg4) + : member1(arg1), + member2(&arg2), + member3(arg3.begin()), + member4(get()), + member5(&get2()), + size_(arg4.size()) {} + + private: + // Expected rewrite: std::vector<raw_ptr<S>> member1; + std::vector<raw_ptr<S>> member1; + // Expected rewrite: const std::vector<raw_ptr<S>>* member2; + const std::vector<raw_ptr<S>>* member2; + // Expected rewrite: std::vector<raw_ptr<S>>::iterator member3; + std::vector<raw_ptr<S>>::const_iterator member3; + // Expected rewrite: std::vector<raw_ptr<S>> member4; + std::vector<raw_ptr<S>> member4; + // Expected rewrite: std::vector<raw_ptr<S>>* member5; + std::vector<raw_ptr<S>>* member5; + std::size_t size_; +};
diff --git a/tools/clang/rewrite_templated_container_fields/tests/ctor-initializer-tests-original.cc b/tools/clang/rewrite_templated_container_fields/tests/ctor-initializer-tests-original.cc new file mode 100644 index 0000000..702cbbc --- /dev/null +++ b/tools/clang/rewrite_templated_container_fields/tests/ctor-initializer-tests-original.cc
@@ -0,0 +1,48 @@ +// 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 <vector> + +struct S {}; + +// Expected rewrite: std::vector<raw_ptr<S>> get(); +std::vector<S*> get() { + return {}; +} + +// Expected rewrite: std::vector<raw_ptr<S>>& get2(); +std::vector<S*>& get2() { + // Expected rewrite: static std::vector<raw_ptr<S>> v; + static std::vector<S*> v; + return v; +} + +class A { + // Expected rewrite: A(const std::vector<raw_ptr<S>>& arg1, + A(const std::vector<S*>& arg1, + // Expected rewrite: const std::vector<raw_ptr<S>>& arg2, + const std::vector<S*>& arg2, + // Expected rewrite: const std::vector<raw_ptr<S>>& arg3, + const std::vector<S*>& arg3, + // No rewrite expected. + const std::vector<S*>& arg4) + : member1(arg1), + member2(&arg2), + member3(arg3.begin()), + member4(get()), + member5(&get2()), + size_(arg4.size()) {} + + private: + // Expected rewrite: std::vector<raw_ptr<S>> member1; + std::vector<S*> member1; + // Expected rewrite: const std::vector<raw_ptr<S>>* member2; + const std::vector<S*>* member2; + // Expected rewrite: std::vector<raw_ptr<S>>::iterator member3; + std::vector<S*>::const_iterator member3; + // Expected rewrite: std::vector<raw_ptr<S>> member4; + std::vector<S*> member4; + // Expected rewrite: std::vector<raw_ptr<S>>* member5; + std::vector<S*>* member5; + std::size_t size_; +};
diff --git a/tools/clang/rewrite_templated_container_fields/tests/fct-decl-tests-expected.cc b/tools/clang/rewrite_templated_container_fields/tests/fct-decl-tests-expected.cc new file mode 100644 index 0000000..8e827686 --- /dev/null +++ b/tools/clang/rewrite_templated_container_fields/tests/fct-decl-tests-expected.cc
@@ -0,0 +1,56 @@ +// 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 <vector> + +#include "base/memory/raw_ptr.h" + +struct S {}; + +// Expected rewrite:(const std::vector<raw_ptr<S>>& arg1, +// int arg2, +// std::vector<raw_ptr<S>>* arg3); +void fct_declaration(const std::vector<raw_ptr<S>>& arg1, + int arg2, + std::vector<raw_ptr<S>>* arg3); + +class Parent { + public: + Parent() = default; + + // Expected rewrite: virtual std::vector<raw_ptr<S>> get(); + virtual std::vector<raw_ptr<S>> get(); + + protected: + // Expected rewrite: std::vector<raw_ptr<S>> member; + std::vector<raw_ptr<S>> member; +}; + +// Expected rewrite: virtual std::vector<raw_ptr<S>> Parent::get() +std::vector<raw_ptr<S>> Parent::get() { + fct_declaration(member, 0, &member); + return member; +} + +class Child : public Parent { + public: + Child() = default; + + // Expected rewrite: virtual std::vector<raw_ptr<S>> get(); + std::vector<raw_ptr<S>> get() override; +}; + +// Expected rewrite: virtual std::vector<raw_ptr<S>> get(); +std::vector<raw_ptr<S>> Child::get() { + // Expected rewrite: return std::vector<raw_ptr<S>>{}; + return std::vector<raw_ptr<S>>{}; +} + +// Expected rewrite:(const std::vector<raw_ptr<S>>& arg1, +// int arg2, +// std::vector<raw_ptr<S>>* arg3); +void fct_declaration(const std::vector<raw_ptr<S>>& arg1, + int arg2, + std::vector<raw_ptr<S>>* arg3) { + *arg3 = arg1; +}
diff --git a/tools/clang/rewrite_templated_container_fields/tests/fct-decl-tests-original.cc b/tools/clang/rewrite_templated_container_fields/tests/fct-decl-tests-original.cc new file mode 100644 index 0000000..8b06f68 --- /dev/null +++ b/tools/clang/rewrite_templated_container_fields/tests/fct-decl-tests-original.cc
@@ -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. +#include <vector> + +struct S {}; + +// Expected rewrite:(const std::vector<raw_ptr<S>>& arg1, +// int arg2, +// std::vector<raw_ptr<S>>* arg3); +void fct_declaration(const std::vector<S*>& arg1, + int arg2, + std::vector<S*>* arg3); + +class Parent { + public: + Parent() = default; + + // Expected rewrite: virtual std::vector<raw_ptr<S>> get(); + virtual std::vector<S*> get(); + + protected: + // Expected rewrite: std::vector<raw_ptr<S>> member; + std::vector<S*> member; +}; + +// Expected rewrite: virtual std::vector<raw_ptr<S>> Parent::get() +std::vector<S*> Parent::get() { + fct_declaration(member, 0, &member); + return member; +} + +class Child : public Parent { + public: + Child() = default; + + // Expected rewrite: virtual std::vector<raw_ptr<S>> get(); + std::vector<S*> get() override; +}; + +// Expected rewrite: virtual std::vector<raw_ptr<S>> get(); +std::vector<S*> Child::get() { + // Expected rewrite: return std::vector<raw_ptr<S>>{}; + return std::vector<S*>{}; +} + +// Expected rewrite:(const std::vector<raw_ptr<S>>& arg1, +// int arg2, +// std::vector<raw_ptr<S>>* arg3); +void fct_declaration(const std::vector<S*>& arg1, + int arg2, + std::vector<S*>* arg3) { + *arg3 = arg1; +}
diff --git a/tools/clang/rewrite_templated_container_fields/tests/makeunique-tests-expected.cc b/tools/clang/rewrite_templated_container_fields/tests/makeunique-tests-expected.cc new file mode 100644 index 0000000..e5e3152 --- /dev/null +++ b/tools/clang/rewrite_templated_container_fields/tests/makeunique-tests-expected.cc
@@ -0,0 +1,98 @@ +// 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 <memory> +#include <vector> + +#include "base/memory/raw_ptr.h" + +struct S {}; + +// Expected rewrite: std::vector<raw_ptr<S>> get(); +std::vector<raw_ptr<S>> get() { + return {}; +} + +// Expected rewrite: std::vector<raw_ptr<S>>& get2(); +std::vector<raw_ptr<S>>& get2() { + // Expected rewrite: static std::vector<raw_ptr<S>> v; + static std::vector<raw_ptr<S>> v; + return v; +} + +class A { + public: + // Expected rewrite: A(const std::vector<raw_ptr<S>>& arg1, + A(const std::vector<raw_ptr<S>>& arg1, + // Expected rewrite: const std::vector<raw_ptr<S>>& arg2, + const std::vector<raw_ptr<S>>& arg2, + // Expected rewrite: const std::vector<raw_ptr<S>>& arg3, + const std::vector<raw_ptr<S>>& arg3, + // No rewrite expected. + const std::vector<S*>& arg4) + : member1(arg1), + member2(&arg2), + member3(arg3.begin()), + member4(get()), + member5(&get2()), + size_(arg4.size()) {} + + private: + // Expected rewrite: std::vector<raw_ptr<S>> member1; + std::vector<raw_ptr<S>> member1; + // Expected rewrite: const std::vector<raw_ptr<S>>* member2; + const std::vector<raw_ptr<S>>* member2; + // Expected rewrite: std::vector<raw_ptr<S>>::iterator member3; + std::vector<raw_ptr<S>>::const_iterator member3; + // Expected rewrite: std::vector<raw_ptr<S>> member4; + std::vector<raw_ptr<S>> member4; + // Expected rewrite: std::vector<raw_ptr<S>>* member5; + std::vector<raw_ptr<S>>* member5; + std::size_t size_; +}; + +void fct() { + // Expected rewrite: std::vector<raw_ptr<S>> temp1; + std::vector<raw_ptr<S>> temp1; + // Expected rewrite: std::vector<raw_ptr<S>> temp2; + std::vector<raw_ptr<S>> temp2; + // Expected rewrite: std::vector<raw_ptr<S>> temp3; + std::vector<raw_ptr<S>> temp3; + // No rewrite expected. + std::vector<S*> temp4; + + auto uptr = std::make_unique<A>(temp1, temp2, temp3, temp4); +} + +namespace n1 { +class B { + public: + // Expected rewrite: A(const std::vector<raw_ptr<S>>& arg) + B(const std::vector<raw_ptr<S>>& arg) : member(arg) {} + + private: + // Expected rewrite: std::vector<raw_ptr<S>> member; + std::vector<raw_ptr<S>> member; +}; + +// Expected rewrite: std::vector<raw_ptr<S>> get_fct() +std::vector<raw_ptr<S>> get_fct() { + return {}; +} + +// Expected rewrite: std::vector<raw_ptr<S>>* get_ptr_fct() +std::vector<raw_ptr<S>>* get_ptr_fct() { + return {}; +} + +void fct() { + auto uptr = std::make_unique<B>(get_fct()); + auto uptr2 = std::make_unique<B>(*get_ptr_fct()); + auto uptr3 = std::make_unique<B>(std::vector<raw_ptr<S>>()); +} + +// Expected rewrite: fct2(const std::vector<raw_ptr<S>>& arg) +void fct2(const std::vector<raw_ptr<S>>& arg) { + auto uptr = std::make_unique<B>(arg); +} +} // namespace n1
diff --git a/tools/clang/rewrite_templated_container_fields/tests/makeunique-tests-original.cc b/tools/clang/rewrite_templated_container_fields/tests/makeunique-tests-original.cc new file mode 100644 index 0000000..2850e0a --- /dev/null +++ b/tools/clang/rewrite_templated_container_fields/tests/makeunique-tests-original.cc
@@ -0,0 +1,96 @@ +// 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 <memory> +#include <vector> + +struct S {}; + +// Expected rewrite: std::vector<raw_ptr<S>> get(); +std::vector<S*> get() { + return {}; +} + +// Expected rewrite: std::vector<raw_ptr<S>>& get2(); +std::vector<S*>& get2() { + // Expected rewrite: static std::vector<raw_ptr<S>> v; + static std::vector<S*> v; + return v; +} + +class A { + public: + // Expected rewrite: A(const std::vector<raw_ptr<S>>& arg1, + A(const std::vector<S*>& arg1, + // Expected rewrite: const std::vector<raw_ptr<S>>& arg2, + const std::vector<S*>& arg2, + // Expected rewrite: const std::vector<raw_ptr<S>>& arg3, + const std::vector<S*>& arg3, + // No rewrite expected. + const std::vector<S*>& arg4) + : member1(arg1), + member2(&arg2), + member3(arg3.begin()), + member4(get()), + member5(&get2()), + size_(arg4.size()) {} + + private: + // Expected rewrite: std::vector<raw_ptr<S>> member1; + std::vector<S*> member1; + // Expected rewrite: const std::vector<raw_ptr<S>>* member2; + const std::vector<S*>* member2; + // Expected rewrite: std::vector<raw_ptr<S>>::iterator member3; + std::vector<S*>::const_iterator member3; + // Expected rewrite: std::vector<raw_ptr<S>> member4; + std::vector<S*> member4; + // Expected rewrite: std::vector<raw_ptr<S>>* member5; + std::vector<S*>* member5; + std::size_t size_; +}; + +void fct() { + // Expected rewrite: std::vector<raw_ptr<S>> temp1; + std::vector<S*> temp1; + // Expected rewrite: std::vector<raw_ptr<S>> temp2; + std::vector<S*> temp2; + // Expected rewrite: std::vector<raw_ptr<S>> temp3; + std::vector<S*> temp3; + // No rewrite expected. + std::vector<S*> temp4; + + auto uptr = std::make_unique<A>(temp1, temp2, temp3, temp4); +} + +namespace n1 { +class B { + public: + // Expected rewrite: A(const std::vector<raw_ptr<S>>& arg) + B(const std::vector<S*>& arg) : member(arg) {} + + private: + // Expected rewrite: std::vector<raw_ptr<S>> member; + std::vector<S*> member; +}; + +// Expected rewrite: std::vector<raw_ptr<S>> get_fct() +std::vector<S*> get_fct() { + return {}; +} + +// Expected rewrite: std::vector<raw_ptr<S>>* get_ptr_fct() +std::vector<S*>* get_ptr_fct() { + return {}; +} + +void fct() { + auto uptr = std::make_unique<B>(get_fct()); + auto uptr2 = std::make_unique<B>(*get_ptr_fct()); + auto uptr3 = std::make_unique<B>(std::vector<S*>()); +} + +// Expected rewrite: fct2(const std::vector<raw_ptr<S>>& arg) +void fct2(const std::vector<S*>& arg) { + auto uptr = std::make_unique<B>(arg); +} +} // namespace n1
diff --git a/tools/clang/rewrite_templated_container_fields/tests/returnstmts-tests-expected.cc b/tools/clang/rewrite_templated_container_fields/tests/returnstmts-tests-expected.cc new file mode 100644 index 0000000..668ef8e --- /dev/null +++ b/tools/clang/rewrite_templated_container_fields/tests/returnstmts-tests-expected.cc
@@ -0,0 +1,86 @@ +// 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 <vector> + +#include "base/memory/raw_ptr.h" + +struct S {}; +class A { + public: + A() = default; + + // Expected rewrite: std::vector<raw_ptr<const S>> get() + std::vector<raw_ptr<const S>> get() { return member; } + + // Expected rewrite: std::vector<raw_ptr<const S>> get_() + std::vector<raw_ptr<const S>> get_() { + auto temp = member; + return temp; + } + + // Expected rewrite: const std::vector<raw_ptr<const S>>& get2() + const std::vector<raw_ptr<const S>>& get2() { return member; } + + // Expected rewrite: const std::vector<raw_ptr<const S>>& get2_() + const std::vector<raw_ptr<const S>>& get2_() { + const auto& temp = member; + return temp; + } + + // Expected rewrite: std::vector<raw_ptr<const S>> get3() + std::vector<raw_ptr<const S>> get3() { + std::vector<raw_ptr<const S>>* temp = &member; + return *temp; + } + + // Expected rewrite: std::vector<raw_ptr<const S>> get3() + std::vector<raw_ptr<const S>> get3_() { + auto* temp = &member; + return *temp; + } + + // Expected rewrite: std::vector<raw_ptr<const S>> get4() + std::vector<raw_ptr<const S>> get4() { return std::move(member); } + + // Expected rewrite: std::vector<raw_ptr<const S>> get4_() + std::vector<raw_ptr<const S>> get4_() { + auto temp = member; + return std::move(temp); + } + + // Expected rewrite: std::vector<raw_ptr<const S>> get5() + std::vector<raw_ptr<const S>> get5() { + // Expected rewrite: std::vector<raw_ptr<const S>>* { return &member; }; + auto fct = [&]() -> std::vector<raw_ptr<const S>>* { return &member; }; + return *fct(); + } + + // Expected rewrite: std::vector<raw_ptr<const S>> get6() + std::vector<raw_ptr<const S>> get6(const std::vector<raw_ptr<const S>>& arg) { + return (arg.size() > member.size()) ? arg : member; + } + + // Expected rewrite: std::vector<raw_ptr<const S>>* get_ptr() + std::vector<raw_ptr<const S>>* get_ptr() { return &member; } + + // Expected rewrite: std::vector<raw_ptr<const S>>* get_ptr2() + std::vector<raw_ptr<const S>>* get_ptr2() { + // Expected rewrite: std::vector<raw_ptr<const S>>& { return member; }; + auto fct = [&]() -> std::vector<raw_ptr<const S>>& { return member; }; + return &fct(); + } + + // Expected rewrite: std::vector<raw_ptr<const S>>::iterator get_begin() + std::vector<raw_ptr<const S>>::iterator get_begin() { return member.begin(); } + + // Expected rewrite: std::vector<raw_ptr<const S>>::iterator get_begin_() + std::vector<raw_ptr<const S>>::iterator get_begin_() { + auto it = member.begin(); + return it; + } + + private: + // Expected rewrite: std::vector<raw_ptr<const S>> member; + std::vector<raw_ptr<const S>> member; +};
diff --git a/tools/clang/rewrite_templated_container_fields/tests/returnstmts-tests-original.cc b/tools/clang/rewrite_templated_container_fields/tests/returnstmts-tests-original.cc new file mode 100644 index 0000000..26d95ede --- /dev/null +++ b/tools/clang/rewrite_templated_container_fields/tests/returnstmts-tests-original.cc
@@ -0,0 +1,84 @@ +// 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 <vector> + +struct S {}; +class A { + public: + A() = default; + + // Expected rewrite: std::vector<raw_ptr<const S>> get() + std::vector<const S*> get() { return member; } + + // Expected rewrite: std::vector<raw_ptr<const S>> get_() + std::vector<const S*> get_() { + auto temp = member; + return temp; + } + + // Expected rewrite: const std::vector<raw_ptr<const S>>& get2() + const std::vector<const S*>& get2() { return member; } + + // Expected rewrite: const std::vector<raw_ptr<const S>>& get2_() + const std::vector<const S*>& get2_() { + const auto& temp = member; + return temp; + } + + // Expected rewrite: std::vector<raw_ptr<const S>> get3() + std::vector<const S*> get3() { + std::vector<const S*>* temp = &member; + return *temp; + } + + // Expected rewrite: std::vector<raw_ptr<const S>> get3() + std::vector<const S*> get3_() { + auto* temp = &member; + return *temp; + } + + // Expected rewrite: std::vector<raw_ptr<const S>> get4() + std::vector<const S*> get4() { return std::move(member); } + + // Expected rewrite: std::vector<raw_ptr<const S>> get4_() + std::vector<const S*> get4_() { + auto temp = member; + return std::move(temp); + } + + // Expected rewrite: std::vector<raw_ptr<const S>> get5() + std::vector<const S*> get5() { + // Expected rewrite: std::vector<raw_ptr<const S>>* { return &member; }; + auto fct = [&]() -> std::vector<const S*>* { return &member; }; + return *fct(); + } + + // Expected rewrite: std::vector<raw_ptr<const S>> get6() + std::vector<const S*> get6(const std::vector<const S*>& arg) { + return (arg.size() > member.size()) ? arg : member; + } + + // Expected rewrite: std::vector<raw_ptr<const S>>* get_ptr() + std::vector<const S*>* get_ptr() { return &member; } + + // Expected rewrite: std::vector<raw_ptr<const S>>* get_ptr2() + std::vector<const S*>* get_ptr2() { + // Expected rewrite: std::vector<raw_ptr<const S>>& { return member; }; + auto fct = [&]() -> std::vector<const S*>& { return member; }; + return &fct(); + } + + // Expected rewrite: std::vector<raw_ptr<const S>>::iterator get_begin() + std::vector<const S*>::iterator get_begin() { return member.begin(); } + + // Expected rewrite: std::vector<raw_ptr<const S>>::iterator get_begin_() + std::vector<const S*>::iterator get_begin_() { + auto it = member.begin(); + return it; + } + + private: + // Expected rewrite: std::vector<raw_ptr<const S>> member; + std::vector<const S*> member; +};
diff --git a/tools/clang/rewrite_templated_container_fields/tests/run_all_tests.py b/tools/clang/rewrite_templated_container_fields/tests/run_all_tests.py new file mode 100755 index 0000000..cb648f9 --- /dev/null +++ b/tools/clang/rewrite_templated_container_fields/tests/run_all_tests.py
@@ -0,0 +1,35 @@ +#!/usr/bin/env python3 +# 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 glob +import os.path +import shutil +import subprocess +import sys + + +def RunRewritingTests(): + subprocess.run([ + "tools/clang/scripts/test_tool.py", "--extract-edits-path", "..", + "--apply-edits", "rewrite_templated_container_fields" + ]) + + +def main(): + if not os.path.exists("ATL_OWNERS"): + sys.stderr.write( + "Please run run_all_tests.py from the root dir of Chromium") + return -1 + + if not os.path.exists("third_party/llvm-build/Release+Asserts/bin/" + "rewrite_templated_container_fields"): + sys.stderr.write("Please build rewrite_templated_container_fields first") + return -1 + + RunRewritingTests() + + +if __name__ == "__main__": + main()
diff --git a/tools/clang/rewrite_templated_container_fields/tests/typedef-tests-expected.cc b/tools/clang/rewrite_templated_container_fields/tests/typedef-tests-expected.cc new file mode 100644 index 0000000..386decfa --- /dev/null +++ b/tools/clang/rewrite_templated_container_fields/tests/typedef-tests-expected.cc
@@ -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. +#include <vector> + +#include "base/memory/raw_ptr.h" + +struct S {}; +// Expected rewrite: typedef std::vector<raw_ptr<S>> VECTOR; +typedef std::vector<raw_ptr<S>> VECTOR; + +// No rewrite expected as this is not reachable from any field. +typedef std::vector<S*> VECTOR2; + +class A { + public: + // Expected rewrite: A(const std::vector<raw_ptr<S>>& arg) + A(const std::vector<raw_ptr<S>>& arg) : member(arg) {} + + VECTOR get() { return member; } + + void fct() { + // Expected rewrite: for(S* i : member) + for (S* i : member) { + (void)i; + } + } + + private: + VECTOR member; +}; + +void iterate(const VECTOR2& arg) { + // No rewrite expected. + for (auto* i : arg) { + (void)i; + } +} + +void iterate2(const VECTOR& arg) { + // Expected rewrite: for(S* i : arg) + for (S* i : arg) { + (void)i; + } + + // Expected rewrite: for(const S* i : arg) + for (const S* i : arg) { + (void)i; + } + + // Expected rewrite: for(const S* const i : arg) + for (const S* const i : arg) { + (void)i; + } +} + +void function() { + // Expected rewrite: std::vector<raw_ptr<S>> temp; + std::vector<raw_ptr<S>> temp; + A a(temp); + + auto temp2 = a.get(); + // Expected rewrite: for(S* i : temp2) + for (S* i : temp2) { + (void)i; + } + + // Expected rewrite: auto* var1 = temp2.front().get(); + auto* var1 = temp2.front().get(); + (void)var1; + + // Expected rewrite: auto* var2 = temp2.back().get(); + auto* var2 = temp2.back().get(); + (void)var2; + + // Expected rewrite: auto* var3 = temp2[0].get(); + auto* var3 = temp2[0].get(); + (void)var3; +}
diff --git a/tools/clang/rewrite_templated_container_fields/tests/typedef-tests-original.cc b/tools/clang/rewrite_templated_container_fields/tests/typedef-tests-original.cc new file mode 100644 index 0000000..ec45b7d --- /dev/null +++ b/tools/clang/rewrite_templated_container_fields/tests/typedef-tests-original.cc
@@ -0,0 +1,77 @@ +// 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 <vector> + +struct S {}; +// Expected rewrite: typedef std::vector<raw_ptr<S>> VECTOR; +typedef std::vector<S*> VECTOR; + +// No rewrite expected as this is not reachable from any field. +typedef std::vector<S*> VECTOR2; + +class A { + public: + // Expected rewrite: A(const std::vector<raw_ptr<S>>& arg) + A(const std::vector<S*>& arg) : member(arg) {} + + VECTOR get() { return member; } + + void fct() { + // Expected rewrite: for(S* i : member) + for (auto* i : member) { + (void)i; + } + } + + private: + VECTOR member; +}; + +void iterate(const VECTOR2& arg) { + // No rewrite expected. + for (auto* i : arg) { + (void)i; + } +} + +void iterate2(const VECTOR& arg) { + // Expected rewrite: for(S* i : arg) + for (auto* i : arg) { + (void)i; + } + + // Expected rewrite: for(const S* i : arg) + for (const auto* i : arg) { + (void)i; + } + + // Expected rewrite: for(const S* const i : arg) + for (const auto* const i : arg) { + (void)i; + } +} + +void function() { + // Expected rewrite: std::vector<raw_ptr<S>> temp; + std::vector<S*> temp; + A a(temp); + + auto temp2 = a.get(); + // Expected rewrite: for(S* i : temp2) + for (auto* i : temp2) { + (void)i; + } + + // Expected rewrite: auto* var1 = temp2.front().get(); + auto* var1 = temp2.front(); + (void)var1; + + // Expected rewrite: auto* var2 = temp2.back().get(); + auto* var2 = temp2.back(); + (void)var2; + + // Expected rewrite: auto* var3 = temp2[0].get(); + auto* var3 = temp2[0]; + (void)var3; +}
diff --git a/tools/clang/rewrite_templated_container_fields/tests/vardecl-tests-expected.cc b/tools/clang/rewrite_templated_container_fields/tests/vardecl-tests-expected.cc new file mode 100644 index 0000000..f5e20a9 --- /dev/null +++ b/tools/clang/rewrite_templated_container_fields/tests/vardecl-tests-expected.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 <vector> + +#include "base/memory/raw_ptr.h" + +struct S {}; + +struct obj { + // Expected rewrite: const std::vector<raw_ptr<S>>& get(); + const std::vector<raw_ptr<S>>& get() { return member; } + + // Expected rewrite: std::vector<raw_ptr<S>> member; + std::vector<raw_ptr<S>> member; +}; + +// No rewrite expected. +std::vector<S*> get_value() { + return {}; +} + +// No rewrite expected. +std::vector<S*>* get_ptr() { + return nullptr; +} + +// No rewrite expected. +std::vector<S*> unrelated_fct() { + return {}; +} + +void fct() { + obj o; + + { + // Expected rewrite: std::vector<raw_ptr<S>> temp = o.member; + std::vector<raw_ptr<S>> temp = o.member; + // Expected rewrite: std::vector<raw_ptr<S>> temp2{temp}; + std::vector<raw_ptr<S>> temp2{temp}; + } + + { + // Expected rewrite: std::vector<raw_ptr<S>>& temp = o.member; + std::vector<raw_ptr<S>>& temp = o.member; + // Expected rewrite: std::vector<raw_ptr<S>> temp2{temp}; + std::vector<raw_ptr<S>> temp2{temp}; + } + + { + // Expected rewrite: const std::vector<raw_ptr<S>>& temp = o.member; + const std::vector<raw_ptr<S>>& temp = o.member; + // Expected rewrite: std::vector<raw_ptr<S>> temp2{temp}; + std::vector<raw_ptr<S>> temp2{temp}; + } + + { + // Expected rewrite: std::vector<raw_ptr<S>>* temp = &o.member; + std::vector<raw_ptr<S>>* temp = &o.member; + // Expected rewrite: std::vector<raw_ptr<S>> temp2{*temp}; + std::vector<raw_ptr<S>> temp2{*temp}; + } + + { + // Expected rewrite: []() -> std::vector<raw_ptr<S>> { return {}; }; + auto init = []() -> std::vector<raw_ptr<S>> { return {}; }; + o.member = init(); + // Expected rewrite: std::vector<raw_ptr<S>> temp = init(); + std::vector<raw_ptr<S>> temp = init(); + } + + { + // Expected rewrite: + // [&]() -> std::vector<raw_ptr<S>>* { return &o.member; }; + auto fct = [&]() -> std::vector<raw_ptr<S>>* { return &o.member; }; + // Expected rewrite: std::vector<raw_ptr<S>> a = *fct(); + std::vector<raw_ptr<S>> a = *fct(); + // Expected rewrite: + // std::vector<raw_ptr<S>>::iterator it = (*fct()).begin(); + std::vector<raw_ptr<S>>::iterator it = fct()->begin(); + } + + { + // Expected rewrite: + // [&]() -> const std::vector<raw_ptr<S>>& { return o.member; }; + auto fct = [&]() -> const std::vector<raw_ptr<S>>& { return o.member; }; + // Expected rewrite: std::vector<raw_ptr<S>> a = &fct(); + const std::vector<raw_ptr<S>>* a = &fct(); + // Expected rewrite: + // std::vector<raw_ptr<S>>::const_iterator it = fct().begin(); + std::vector<raw_ptr<S>>::const_iterator it = fct().begin(); + } + + { + // Expected rewrite: std::vector<raw_ptr<S>>::iterator it; + std::vector<raw_ptr<S>>::iterator it = o.member.begin(); + (void)it; + } + + { + // create a link with a member to propagate the rewrite. + std::vector<raw_ptr<S>> a = o.member; + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<raw_ptr<S>> b; + // Expected rewrite: b = (a.size() > 0) ? a : std::vector<raw_ptr<S>>(); + b = (a.size() > 0) ? a : std::vector<raw_ptr<S>>(); + } +}
diff --git a/tools/clang/rewrite_templated_container_fields/tests/vardecl-tests-original.cc b/tools/clang/rewrite_templated_container_fields/tests/vardecl-tests-original.cc new file mode 100644 index 0000000..18eb3f4e --- /dev/null +++ b/tools/clang/rewrite_templated_container_fields/tests/vardecl-tests-original.cc
@@ -0,0 +1,106 @@ +// 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 <vector> + +struct S {}; + +struct obj { + // Expected rewrite: const std::vector<raw_ptr<S>>& get(); + const std::vector<S*>& get() { return member; } + + // Expected rewrite: std::vector<raw_ptr<S>> member; + std::vector<S*> member; +}; + +// No rewrite expected. +std::vector<S*> get_value() { + return {}; +} + +// No rewrite expected. +std::vector<S*>* get_ptr() { + return nullptr; +} + +// No rewrite expected. +std::vector<S*> unrelated_fct() { + return {}; +} + +void fct() { + obj o; + + { + // Expected rewrite: std::vector<raw_ptr<S>> temp = o.member; + std::vector<S*> temp = o.member; + // Expected rewrite: std::vector<raw_ptr<S>> temp2{temp}; + std::vector<S*> temp2{temp}; + } + + { + // Expected rewrite: std::vector<raw_ptr<S>>& temp = o.member; + std::vector<S*>& temp = o.member; + // Expected rewrite: std::vector<raw_ptr<S>> temp2{temp}; + std::vector<S*> temp2{temp}; + } + + { + // Expected rewrite: const std::vector<raw_ptr<S>>& temp = o.member; + const std::vector<S*>& temp = o.member; + // Expected rewrite: std::vector<raw_ptr<S>> temp2{temp}; + std::vector<S*> temp2{temp}; + } + + { + // Expected rewrite: std::vector<raw_ptr<S>>* temp = &o.member; + std::vector<S*>* temp = &o.member; + // Expected rewrite: std::vector<raw_ptr<S>> temp2{*temp}; + std::vector<S*> temp2{*temp}; + } + + { + // Expected rewrite: []() -> std::vector<raw_ptr<S>> { return {}; }; + auto init = []() -> std::vector<S*> { return {}; }; + o.member = init(); + // Expected rewrite: std::vector<raw_ptr<S>> temp = init(); + std::vector<S*> temp = init(); + } + + { + // Expected rewrite: + // [&]() -> std::vector<raw_ptr<S>>* { return &o.member; }; + auto fct = [&]() -> std::vector<S*>* { return &o.member; }; + // Expected rewrite: std::vector<raw_ptr<S>> a = *fct(); + std::vector<S*> a = *fct(); + // Expected rewrite: + // std::vector<raw_ptr<S>>::iterator it = (*fct()).begin(); + std::vector<S*>::iterator it = fct()->begin(); + } + + { + // Expected rewrite: + // [&]() -> const std::vector<raw_ptr<S>>& { return o.member; }; + auto fct = [&]() -> const std::vector<S*>& { return o.member; }; + // Expected rewrite: std::vector<raw_ptr<S>> a = &fct(); + const std::vector<S*>* a = &fct(); + // Expected rewrite: + // std::vector<raw_ptr<S>>::const_iterator it = fct().begin(); + std::vector<S*>::const_iterator it = fct().begin(); + } + + { + // Expected rewrite: std::vector<raw_ptr<S>>::iterator it; + std::vector<S*>::iterator it = o.member.begin(); + (void)it; + } + + { + // create a link with a member to propagate the rewrite. + std::vector<S*> a = o.member; + // Expected rewrite: std::vector<raw_ptr<S>> b; + std::vector<S*> b; + // Expected rewrite: b = (a.size() > 0) ? a : std::vector<raw_ptr<S>>(); + b = (a.size() > 0) ? a : std::vector<S*>(); + } +}
diff --git a/tools/clang/rewrite_templated_container_fields/tests/various-tests-expected.cc b/tools/clang/rewrite_templated_container_fields/tests/various-tests-expected.cc new file mode 100644 index 0000000..d0efe3c1 --- /dev/null +++ b/tools/clang/rewrite_templated_container_fields/tests/various-tests-expected.cc
@@ -0,0 +1,575 @@ +// 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 <map> +#include <memory> +#include <vector> + +#include "base/memory/raw_ptr.h" + +#define RAW_PTR_EXCLUSION __attribute__((annotate("raw_ptr_exclusion"))) + +struct S {}; + +class A { + public: + A() : member(init()) {} + + A(const std::vector<raw_ptr<S>>& arg, const std::vector<const char*>& arg2) + : member(arg), member2(arg2) {} + + A(const std::vector<raw_ptr<S>>* arg) : member(*arg) {} + + std::vector<raw_ptr<S>> init() { return {}; } + + std::vector<raw_ptr<S>> do_something(std::vector<raw_ptr<S>>& a, + S* i, + std::vector<raw_ptr<S>>& b); + + void set(const std::vector<raw_ptr<S>> arg); + + private: + std::vector<raw_ptr<S>> member; + std::vector<const char*> member2; +}; + +std::vector<raw_ptr<S>> A::do_something(std::vector<raw_ptr<S>>& a, + S* i, + std::vector<raw_ptr<S>>& b) { + a.push_back(i); + member = b; + b = a; + return a; +} + +void A::set(const std::vector<raw_ptr<S>> arg) { + member = arg; +} + +class B { + public: + B() = default; + + std::vector<raw_ptr<S>> get() { return member; } + + std::vector<raw_ptr<S>> get2(); + + private: + std::vector<raw_ptr<S>> member; +}; + +std::vector<raw_ptr<S>> B::get2() { + return member; +} + +class C { + public: + C() = default; + + const std::vector<raw_ptr<S>>& get() { return member; } + + private: + std::vector<raw_ptr<S>> member; +}; + +class D { + public: + D() = default; + + std::vector<raw_ptr<S>>* get() { return &member; } + + private: + std::vector<raw_ptr<S>> member; +}; + +class E { + public: + E() = default; + + void set(const std::vector<raw_ptr<S>>& arg) { member = arg; } + + private: + std::vector<raw_ptr<S>> member; +}; + +class F { + public: + F() = default; + + void init() { + std::vector<raw_ptr<S>> temp; + temp.push_back(nullptr); + member = temp; + + { + std::vector<raw_ptr<S>>::iterator it; + it = temp.begin(); + ++it; + } + + { + std::vector<raw_ptr<S>>::iterator it = temp.begin(); + ++it; + } + } + + private: + std::vector<raw_ptr<S>> member; +}; + +class G { + public: + G() = default; + + void init() { + std::vector<raw_ptr<S>> temp = member; + temp.push_back(nullptr); + } + + private: + std::vector<raw_ptr<S>> member; +}; + +class H { + public: + H() = default; + + std::vector<raw_ptr<S>> init() { + std::vector<raw_ptr<S>> temp; + temp = member; + temp.push_back(nullptr); + + std::vector<raw_ptr<S>> temp2; + temp2 = temp; + return temp2; + } + + private: + std::vector<raw_ptr<S>> member; +}; + +class I { + public: + I() = default; + + std::vector<raw_ptr<S>> init() { + std::vector<raw_ptr<S>> temp; + temp = std::move(member); + temp.push_back(nullptr); + return temp; + } + + private: + std::vector<raw_ptr<S>> member; +}; + +class J { + public: + J() = default; + + void init() { + prepare(member); + prepare2(&member); + prepare(get()); + prepare(*get_2()); + } + + std::vector<raw_ptr<S>>& get() { return member; } + + std::vector<raw_ptr<S>>* get_2() { return &member; } + + void prepare(std::vector<raw_ptr<S>>& v) { v.push_back(nullptr); } + + void prepare2(std::vector<raw_ptr<S>>* v) { v->push_back(nullptr); } + + private: + std::vector<raw_ptr<S>> member; +}; + +class K { + public: + K() = default; + + std::vector<raw_ptr<S>> init() { + std::vector<raw_ptr<S>> temp; + temp.swap(member); + return temp; + } + + std::vector<raw_ptr<S>> init2() { + std::vector<raw_ptr<S>> temp; + std::swap(temp, member); + return temp; + } + + private: + std::vector<raw_ptr<S>> member; +}; + +class L { + public: + L() = default; + + std::vector<raw_ptr<S>> init() { + std::vector<raw_ptr<S>> temp; + temp.push_back(nullptr); + member.swap(temp); + return temp; + } + + std::vector<raw_ptr<S>> init2() { + std::vector<raw_ptr<S>> temp; + temp.push_back(nullptr); + std::swap(member, temp); + return temp; + } + + private: + std::vector<raw_ptr<S>> member; +}; + +class M { + public: + M() = default; + void set(std::vector<raw_ptr<S>>* v) { *v = member; } + + private: + std::vector<raw_ptr<S>> member; +}; + +class N { + public: + N() : member() {} + + std::vector<raw_ptr<S>>* get() { + std::vector<raw_ptr<S>>* temp; + temp = &member; + return temp; + } + + std::vector<raw_ptr<S>>* get_() { return get(); } + + std::vector<raw_ptr<S>> get__() { return *get(); } + + std::vector<raw_ptr<S>> get2() { + std::vector<raw_ptr<S>>* temp; + temp = get(); + + std::vector<raw_ptr<S>>* temp2 = get(); + (void)temp2; + + std::vector<raw_ptr<S>> temp3; + temp3 = *get(); + (void)temp3; + + std::vector<raw_ptr<S>> temp4 = *get(); + (void)temp4; + return *temp; + } + + const std::vector<raw_ptr<S>>* get3() { + std::vector<raw_ptr<S>>* temp = &member; + return temp; + } + + std::vector<raw_ptr<S>> get4() { + std::vector<raw_ptr<S>>* temp; + temp = &member; + + std::vector<raw_ptr<S>>* temp2 = temp; + + std::vector<raw_ptr<S>>** temp3 = &temp2; + (void)temp3; + + std::vector<raw_ptr<S>>& ref = *temp; + (void)ref; + return *temp2; + } + + const std::vector<raw_ptr<S>>& get5() { + std::vector<raw_ptr<S>>* temp; + temp = &member; + return *temp; + } + + private: + std::vector<raw_ptr<S>> member; +}; + +struct obj { + std::vector<raw_ptr<S>> member; + std::vector<raw_ptr<std::map<int, int>>> member2; +}; + +struct obj2 { + RAW_PTR_EXCLUSION std::vector<S*> member; +}; + +namespace temporary { +std::vector<raw_ptr<S>> ge_t() { + return {}; +} +std::vector<raw_ptr<S>>* ge_t_ptr() { + return nullptr; +} +} // namespace temporary + +void fct() { + std::vector<raw_ptr<S>> temp; + std::vector<raw_ptr<S>> temp3; + std::vector<raw_ptr<S>> temp2{temp}; + obj o{temp3}; + std::vector<const char*> t; + A a(temp, t); + (void)a; + + { + std::vector<raw_ptr<S>> temp; + A a2(temp, t); + (void)a2; + } + + { + obj p{temporary::ge_t()}; + (void)p; + + obj q{*temporary::ge_t_ptr()}; + (void)q; + } + + { + std::vector<raw_ptr<S>> temp4; + std::vector<const char*> s; + std::make_unique<A>(temp4, s); + } + + { + std::vector<raw_ptr<S>> temp4; + std::vector<const char*> s; + A* a = new A(temp4, s); + (void)a; + } +} + +class O { + public: + O() : member() {} + + std::vector<raw_ptr<S>> f() { + std::vector<raw_ptr<S>> temp; + temp = std::move(member); + return temp; + } + + std::vector<raw_ptr<S>> f2() { + std::vector<raw_ptr<S>> temp = std::move(member); + temp.push_back(nullptr); + + for (S* v : temp) { + (void)v; + } + + for (S* v : member) { + (void)v; + } + + for (const S* const v : member) { + (void)v; + } + + auto temp2 = temp; + for (S* v : temp2) { + (void)v; + } + + for (const S* v : temp2) { + (void)v; + } + + for (const S* const v : temp2) { + (void)v; + } + + auto* ptr1 = temp2[0].get(); + (void)ptr1; + + auto* ptr2 = temp2.front().get(); + (void)ptr2; + + auto* ptr3 = temp2.back().get(); + (void)ptr3; + + return temp2; + } + + std::vector<raw_ptr<S>> g() { return std::move(member); } + + std::vector<raw_ptr<S>> g2() { + std::vector<raw_ptr<S>> temp; + temp.push_back(nullptr); + + auto* var = temp.front().get(); + (void)var; + + auto* var2 = temp.back().get(); + (void)var2; + + int index = 0; + auto* var3 = temp[index].get(); + (void)var3; + return (temp.size() > member.size()) ? std::move(temp) : std::move(member); + } + + private: + std::vector<raw_ptr<S>> member; +}; + +class P { + public: + P(std::vector<raw_ptr<S>> arg) : member(std::move(arg)) {} + + P(std::vector<raw_ptr<S>>* arg) : member(*arg) {} + + private: + std::vector<raw_ptr<S>> member; +}; + +namespace { +std::vector<raw_ptr<S>>* get_ptr() { + return nullptr; +} +void p_fct() { + { + std::vector<raw_ptr<S>> temp; + P p(&temp); + (void)p; + } + + { + P p(*get_ptr()); + (void)p; + } +} +} // namespace + +class Parent { + public: + Parent() = default; + + virtual std::vector<raw_ptr<S>> get(); + + protected: + std::vector<raw_ptr<S>> member; +}; + +std::vector<raw_ptr<S>> Parent::get() { + return member; +} + +class Child : public Parent { + public: + Child() = default; + + std::vector<raw_ptr<S>> get() override; +}; + +std::vector<raw_ptr<S>> Child::get() { + return std::vector<raw_ptr<S>>{}; +} + +namespace n { +template <class T> +void do_something(std::vector<raw_ptr<T>>& v) { + v.push_back(nullptr); +} + +class BCD { + public: + BCD(const std::vector<raw_ptr<int>>& arg); + + void dod() { + do_something(member); + auto lambda = [this]() -> std::vector<raw_ptr<int>> { return member; }; + lambda(); + + functor f; + f(member); + + auto lambda2 = [](const std::vector<raw_ptr<int>>& v) { + for (int* i : v) { + (void)i; + } + }; + + lambda2(member); + } + + private: + struct functor { + void operator()(const std::vector<raw_ptr<int>>& v) { + for (int* i : v) { + (void)i; + } + } + }; + std::vector<raw_ptr<int>> member; +}; + +BCD::BCD(const std::vector<raw_ptr<int>>& arg) : member(arg) {} +} // namespace n + +// No change needed here +void any_function(std::vector<int*>& v) { + v.push_back(nullptr); +} + +// These should be rewritten but are not for now. +namespace templated_stuff { +template <class T> +void do_something(std::vector<T*>& t) { + t.push_back(nullptr); +} + +template <typename T> +class A { + public: + A(const std::vector<T*>& arg) : v(arg) {} + + virtual const std::vector<T*>& get() { + do_something(v); + return v; + } + + protected: + std::vector<T*> v; +}; + +void fctttttt() { + A<int> a({}); + std::vector<int*> temp = a.get(); + temp.push_back(nullptr); +} + +} // namespace templated_stuff + +namespace { +namespace A { +struct SA {}; +} // namespace A + +namespace B { +struct S { + // Expected rewrite: std::vector<raw_ptr<const A::SA>> member; + std::vector<raw_ptr<const A::SA>> member; + + void fct() { + // This tests whether we properly trim (anonymous namespace):: from the type + // while conserving constness. + // Expected rewrite: for(const A::SA* i : member) + for (const A::SA* i : member) { + (void)i; + } + } +}; +} // namespace B +} // namespace
diff --git a/tools/clang/rewrite_templated_container_fields/tests/various-tests-original.cc b/tools/clang/rewrite_templated_container_fields/tests/various-tests-original.cc new file mode 100644 index 0000000..99ad93c --- /dev/null +++ b/tools/clang/rewrite_templated_container_fields/tests/various-tests-original.cc
@@ -0,0 +1,568 @@ +// 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 <map> +#include <memory> +#include <vector> + +#define RAW_PTR_EXCLUSION __attribute__((annotate("raw_ptr_exclusion"))) + +struct S {}; + +class A { + public: + A() : member(init()) {} + + A(const std::vector<S*>& arg, const std::vector<const char*>& arg2) + : member(arg), member2(arg2) {} + + A(const std::vector<S*>* arg) : member(*arg) {} + + std::vector<S*> init() { return {}; } + + std::vector<S*> do_something(std::vector<S*>& a, S* i, std::vector<S*>& b); + + void set(const std::vector<S*> arg); + + private: + std::vector<S*> member; + std::vector<const char*> member2; +}; + +std::vector<S*> A::do_something(std::vector<S*>& a, S* i, std::vector<S*>& b) { + a.push_back(i); + member = b; + b = a; + return a; +} + +void A::set(const std::vector<S*> arg) { + member = arg; +} + +class B { + public: + B() = default; + + std::vector<S*> get() { return member; } + + std::vector<S*> get2(); + + private: + std::vector<S*> member; +}; + +std::vector<S*> B::get2() { + return member; +} + +class C { + public: + C() = default; + + const std::vector<S*>& get() { return member; } + + private: + std::vector<S*> member; +}; + +class D { + public: + D() = default; + + std::vector<S*>* get() { return &member; } + + private: + std::vector<S*> member; +}; + +class E { + public: + E() = default; + + void set(const std::vector<S*>& arg) { member = arg; } + + private: + std::vector<S*> member; +}; + +class F { + public: + F() = default; + + void init() { + std::vector<S*> temp; + temp.push_back(nullptr); + member = temp; + + { + std::vector<S*>::iterator it; + it = temp.begin(); + ++it; + } + + { + std::vector<S*>::iterator it = temp.begin(); + ++it; + } + } + + private: + std::vector<S*> member; +}; + +class G { + public: + G() = default; + + void init() { + std::vector<S*> temp = member; + temp.push_back(nullptr); + } + + private: + std::vector<S*> member; +}; + +class H { + public: + H() = default; + + std::vector<S*> init() { + std::vector<S*> temp; + temp = member; + temp.push_back(nullptr); + + std::vector<S*> temp2; + temp2 = temp; + return temp2; + } + + private: + std::vector<S*> member; +}; + +class I { + public: + I() = default; + + std::vector<S*> init() { + std::vector<S*> temp; + temp = std::move(member); + temp.push_back(nullptr); + return temp; + } + + private: + std::vector<S*> member; +}; + +class J { + public: + J() = default; + + void init() { + prepare(member); + prepare2(&member); + prepare(get()); + prepare(*get_2()); + } + + std::vector<S*>& get() { return member; } + + std::vector<S*>* get_2() { return &member; } + + void prepare(std::vector<S*>& v) { v.push_back(nullptr); } + + void prepare2(std::vector<S*>* v) { v->push_back(nullptr); } + + private: + std::vector<S*> member; +}; + +class K { + public: + K() = default; + + std::vector<S*> init() { + std::vector<S*> temp; + temp.swap(member); + return temp; + } + + std::vector<S*> init2() { + std::vector<S*> temp; + std::swap(temp, member); + return temp; + } + + private: + std::vector<S*> member; +}; + +class L { + public: + L() = default; + + std::vector<S*> init() { + std::vector<S*> temp; + temp.push_back(nullptr); + member.swap(temp); + return temp; + } + + std::vector<S*> init2() { + std::vector<S*> temp; + temp.push_back(nullptr); + std::swap(member, temp); + return temp; + } + + private: + std::vector<S*> member; +}; + +class M { + public: + M() = default; + void set(std::vector<S*>* v) { *v = member; } + + private: + std::vector<S*> member; +}; + +class N { + public: + N() : member() {} + + std::vector<S*>* get() { + std::vector<S*>* temp; + temp = &member; + return temp; + } + + std::vector<S*>* get_() { return get(); } + + std::vector<S*> get__() { return *get(); } + + std::vector<S*> get2() { + std::vector<S*>* temp; + temp = get(); + + std::vector<S*>* temp2 = get(); + (void)temp2; + + std::vector<S*> temp3; + temp3 = *get(); + (void)temp3; + + std::vector<S*> temp4 = *get(); + (void)temp4; + return *temp; + } + + const std::vector<S*>* get3() { + std::vector<S*>* temp = &member; + return temp; + } + + std::vector<S*> get4() { + std::vector<S*>* temp; + temp = &member; + + std::vector<S*>* temp2 = temp; + + std::vector<S*>** temp3 = &temp2; + (void)temp3; + + std::vector<S*>& ref = *temp; + (void)ref; + return *temp2; + } + + const std::vector<S*>& get5() { + std::vector<S*>* temp; + temp = &member; + return *temp; + } + + private: + std::vector<S*> member; +}; + +struct obj { + std::vector<S*> member; + std::vector<std::map<int, int>*> member2; +}; + +struct obj2 { + RAW_PTR_EXCLUSION std::vector<S*> member; +}; + +namespace temporary { +std::vector<S*> ge_t() { + return {}; +} +std::vector<S*>* ge_t_ptr() { + return nullptr; +} +} // namespace temporary + +void fct() { + std::vector<S*> temp; + std::vector<S*> temp3; + std::vector<S*> temp2{temp}; + obj o{temp3}; + std::vector<const char*> t; + A a(temp, t); + (void)a; + + { + std::vector<S*> temp; + A a2(temp, t); + (void)a2; + } + + { + obj p{temporary::ge_t()}; + (void)p; + + obj q{*temporary::ge_t_ptr()}; + (void)q; + } + + { + std::vector<S*> temp4; + std::vector<const char*> s; + std::make_unique<A>(temp4, s); + } + + { + std::vector<S*> temp4; + std::vector<const char*> s; + A* a = new A(temp4, s); + (void)a; + } +} + +class O { + public: + O() : member() {} + + std::vector<S*> f() { + std::vector<S*> temp; + temp = std::move(member); + return temp; + } + + std::vector<S*> f2() { + std::vector<S*> temp = std::move(member); + temp.push_back(nullptr); + + for (auto* v : temp) { + (void)v; + } + + for (auto* v : member) { + (void)v; + } + + for (const auto* const v : member) { + (void)v; + } + + auto temp2 = temp; + for (auto* v : temp2) { + (void)v; + } + + for (const auto* v : temp2) { + (void)v; + } + + for (const auto* const v : temp2) { + (void)v; + } + + auto* ptr1 = temp2[0]; + (void)ptr1; + + auto* ptr2 = temp2.front(); + (void)ptr2; + + auto* ptr3 = temp2.back(); + (void)ptr3; + + return temp2; + } + + std::vector<S*> g() { return std::move(member); } + + std::vector<S*> g2() { + std::vector<S*> temp; + temp.push_back(nullptr); + + auto* var = temp.front(); + (void)var; + + auto* var2 = temp.back(); + (void)var2; + + int index = 0; + auto* var3 = temp[index]; + (void)var3; + return (temp.size() > member.size()) ? std::move(temp) : std::move(member); + } + + private: + std::vector<S*> member; +}; + +class P { + public: + P(std::vector<S*> arg) : member(std::move(arg)) {} + + P(std::vector<S*>* arg) : member(*arg) {} + + private: + std::vector<S*> member; +}; + +namespace { +std::vector<S*>* get_ptr() { + return nullptr; +} +void p_fct() { + { + std::vector<S*> temp; + P p(&temp); + (void)p; + } + + { + P p(*get_ptr()); + (void)p; + } +} +} // namespace + +class Parent { + public: + Parent() = default; + + virtual std::vector<S*> get(); + + protected: + std::vector<S*> member; +}; + +std::vector<S*> Parent::get() { + return member; +} + +class Child : public Parent { + public: + Child() = default; + + std::vector<S*> get() override; +}; + +std::vector<S*> Child::get() { + return std::vector<S*>{}; +} + +namespace n { +template <class T> +void do_something(std::vector<T*>& v) { + v.push_back(nullptr); +} + +class BCD { + public: + BCD(const std::vector<int*>& arg); + + void dod() { + do_something(member); + auto lambda = [this]() -> std::vector<int*> { return member; }; + lambda(); + + functor f; + f(member); + + auto lambda2 = [](const std::vector<int*>& v) { + for (auto* i : v) { + (void)i; + } + }; + + lambda2(member); + } + + private: + struct functor { + void operator()(const std::vector<int*>& v) { + for (auto* i : v) { + (void)i; + } + } + }; + std::vector<int*> member; +}; + +BCD::BCD(const std::vector<int*>& arg) : member(arg) {} +} // namespace n + +// No change needed here +void any_function(std::vector<int*>& v) { + v.push_back(nullptr); +} + +namespace templated_stuff { +template <class T> +void do_something(std::vector<T*>& t) { + t.push_back(nullptr); +} + +template <typename T> +class A { + public: + A(const std::vector<T*>& arg) : v(arg) {} + + virtual const std::vector<T*>& get() { + do_something(v); + return v; + } + + protected: + std::vector<T*> v; +}; + +void fctttttt() { + A<int> a({}); + std::vector<int*> temp = a.get(); + temp.push_back(nullptr); +} + +} // namespace templated_stuff + +namespace { +namespace A { +struct SA {}; +} // namespace A + +namespace B { +struct S { + // Expected rewrite: std::vector<raw_ptr<const A::SA>> member; + std::vector<const A::SA*> member; + + void fct() { + // This tests whether we properly trim (anonymous namespace):: from the type + // while conserving constness. + // Expected rewrite: for(const A::SA* i : member) + for (auto* i : member) { + (void)i; + } + } +}; +} // namespace B +} // namespace
diff --git a/tools/clang/scripts/test_tool.py b/tools/clang/scripts/test_tool.py index 4413ebf..70a7c34 100755 --- a/tools/clang/scripts/test_tool.py +++ b/tools/clang/scripts/test_tool.py
@@ -46,13 +46,9 @@ return '%d test%s' % (tests, 's' if tests != 1 else '') -def _ApplyTool(tools_clang_scripts_directory, - tool_to_test, - tool_path, - tool_args, - test_directory_for_tool, - actual_files, - apply_edits): +def _ApplyTool(tools_clang_scripts_directory, tool_to_test, tool_path, + tool_args, test_directory_for_tool, actual_files, apply_edits, + extract_edits_path): try: # Stage the test files in the git index. If they aren't staged, then # run_tool.py will skip them when applying replacements. @@ -85,12 +81,21 @@ processes.append(subprocess.Popen(args, stdout=subprocess.PIPE)) if apply_edits: - args = [ - 'python', - os.path.join(tools_clang_scripts_directory, 'extract_edits.py') - ] - processes.append(subprocess.Popen( - args, stdin=processes[-1].stdout, stdout=subprocess.PIPE)) + if len(extract_edits_path) == 0: + args = [ + 'python', + os.path.join(tools_clang_scripts_directory, 'extract_edits.py') + ] + processes.append( + subprocess.Popen(args, + stdin=processes[-1].stdout, + stdout=subprocess.PIPE)) + else: + args = ['python', os.path.join(extract_edits_path, 'extract_edits.py')] + processes.append( + subprocess.Popen(args, + stdin=processes[-1].stdout, + stdout=subprocess.PIPE)) args = [ 'python', @@ -169,6 +174,10 @@ help='Clang tool to be tested.') parser.add_argument( '--test-filter', default='*', help='optional glob filter for test names') + parser.add_argument('--extract-edits-path', + nargs='?', + help='optional path to the extract_edits script\ + [e.g. if custom filtering or post-processing of edits is needed]') args = parser.parse_args(argv) tool_to_test = args.tool_name[0] print('\nTesting %s\n' % tool_to_test) @@ -218,9 +227,8 @@ # Run the tool. os.chdir(test_directory_for_tool) exitcode = _ApplyTool(tools_clang_scripts_directory, tool_to_test, - args.tool_path, args.tool_arg, - test_directory_for_tool, actual_files, - args.apply_edits) + args.tool_path, args.tool_arg, test_directory_for_tool, + actual_files, args.apply_edits, args.extract_edits_path) if (exitcode != 0): return exitcode
diff --git a/tools/json_schema_compiler/cc_generator.py b/tools/json_schema_compiler/cc_generator.py index 2f4ee3ed..21a3090d 100644 --- a/tools/json_schema_compiler/cc_generator.py +++ b/tools/json_schema_compiler/cc_generator.py
@@ -239,9 +239,6 @@ .Sblock(' %s) {' % self._GenerateParams( ('const base::Value::Dict& dict', '%(name)s& out')))) - if self._generate_error_messages: - c.Append('DCHECK(error);') - # TODO(crbug.com/1145154): The generated code here will ignore # unrecognized keys, but the parsing code for types passed to APIs in the # renderer will hard-error on them. We should probably be consistent with @@ -284,9 +281,6 @@ .Sblock(' %s) {' % self._GenerateParams( ('const base::Value& value', '%(name)s& out')))) - if self._generate_error_messages: - c.Append('DCHECK(error);') - if type_.property_type is PropertyType.CHOICES: for choice in type_.choices: (c.Sblock('if (%s) {' % self._GenerateValueIsTypeExpression('value', @@ -375,14 +369,17 @@ c = Code() (c.Append('// static') .Append('std::unique_ptr<%s> %s::FromValueDeprecated(%s) {' % (classname, - cpp_namespace, self._GenerateParams(('const base::Value& value',)))) + cpp_namespace, self._GenerateParams(('const base::Value& value',), + error_as_ptr=True))) ) c.Sblock(); - if self._generate_error_messages: - c.Append('DCHECK(error);') c.Append('auto out = std::make_unique<%s>();' % classname) + if self._generate_error_messages: + c.Append('DCHECK(error_ptr);') + c.Append('auto& error = *error_ptr;') + if type_.property_type == PropertyType.CHOICES: c.Append('bool result = Populate(%s);' % self._GenerateArgs(('value', '*out'))) @@ -397,7 +394,7 @@ self._GenerateArgs(('value.GetDict()', '*out'))) if self._generate_error_messages: - c.Append('DCHECK_EQ(result, error->empty());') + c.Append('DCHECK_EQ(result, error.empty());') c.Sblock('if (!result) {') c.Append('return nullptr;') c.Eblock('}') @@ -424,13 +421,11 @@ # TODO(crbug.com/1354063): Once the deprecated version of this method is # removed, we should consider making Populate return an optional, rather # than using an out param. - if self._generate_error_messages: - c.Append('DCHECK(error);') c.Append('absl::optional<%s> out(absl::in_place);' % classname) c.Append('bool result = Populate(%s);' % self._GenerateArgs(('value', 'out.value()'))) if self._generate_error_messages: - c.Append('DCHECK_EQ(result, error->empty());') + c.Append('DCHECK_EQ(result, error.empty());') c.Sblock('if (!result)') c.Append('return absl::nullopt;') c.Eblock('return out;') @@ -516,11 +511,9 @@ c.Sblock('%s) {' % self._GenerateParams(params, generate_error_messages=True)) - c.Append('DCHECK(error);') c.Append() - c.Append('std::vector<base::StringPiece> error_path_reversed_vec;') - c.Append('auto* error_path_reversed = &error_path_reversed_vec;') + c.Append('std::vector<base::StringPiece> error_path_reversed;') c.Append('const base::Value::Dict& dict = root_dict;') for prop in properties: @@ -547,8 +540,8 @@ 'const base::Value::Dict& root_dict', 'base::StringPiece key', '%(classname)s& out', - 'std::u16string* error', - 'std::vector<base::StringPiece>* error_path_reversed' + 'std::u16string& error', + 'std::vector<base::StringPiece>& error_path_reversed' ] c = Code() @@ -560,8 +553,6 @@ c.Sblock('%s) {' % self._GenerateParams(params, generate_error_messages=False)) - c.Append('DCHECK(error);') - c.Append('DCHECK(error_path_reversed);') c.Append() c.Append( @@ -674,7 +665,7 @@ c.Append('::json_schema_compiler::manifest_parse_util::' 'PopulateFinalError(error, error_path_reversed);') else: - c.Append('error_path_reversed->push_back(key);') + c.Append('error_path_reversed.push_back(key);') c.Append('return false;') c.Eblock('}') @@ -945,8 +936,6 @@ self._GenerateParams([ 'const base::Value::List& args'])) ) - if self._generate_error_messages: - c.Append('DCHECK(error);') failure_value = 'absl::nullopt' (c.Concat(self._GenerateParamsCheck(function, 'args', failure_value)) @@ -1111,7 +1100,7 @@ args = ['%(src_var)s.GetList()', '%(dst_var)s'] if self._generate_error_messages: c.Append('std::u16string array_parse_error;') - args.append('&array_parse_error') + args.append('array_parse_error') c.Append('if (!%s(%s)) {' % ( self._util_cc_helper.PopulateArrayFromListFunction(is_ptr), @@ -1377,11 +1366,12 @@ c = Code() if not self._generate_error_messages: return c - c.Append('DCHECK(error->empty());') - c.Append('*error = %s;' % error16) + c.Append('DCHECK(error.empty());') + c.Append('error = %s;' % error16) return c - def _GenerateParams(self, params, generate_error_messages=None): + def _GenerateParams( + self, params, generate_error_messages=None, error_as_ptr=None): """Builds the parameter list for a function, given an array of parameters. If |generate_error_messages| is specified, it overrides |self._generate_error_messages|. @@ -1389,7 +1379,10 @@ if generate_error_messages is None: generate_error_messages = self._generate_error_messages if generate_error_messages: - params = list(params) + ['std::u16string* error'] + if error_as_ptr: + params = list(params) + ['std::u16string* error_ptr'] + else: + params = list(params) + ['std::u16string& error'] return ', '.join(str(p) for p in params) def _GenerateArgs(self, args, generate_error_messages=None):
diff --git a/tools/json_schema_compiler/h_generator.py b/tools/json_schema_compiler/h_generator.py index 104ea7eb..1c3ddea 100644 --- a/tools/json_schema_compiler/h_generator.py +++ b/tools/json_schema_compiler/h_generator.py
@@ -274,7 +274,8 @@ .Comment('Creates a %s object from a base::Value, or NULL on ' 'failure.' % classname) .Append('static std::unique_ptr<%s> FromValueDeprecated(%s);' % ( - classname, self._GenerateParams(('const base::Value& value',)))) + classname, self._GenerateParams(('const base::Value& value',), + error_as_ptr=True))) ) (c.Append() .Comment('Creates a %s object from a base::Value, or nullopt on ' @@ -410,7 +411,7 @@ params = [ 'const base::Value::Dict& root_dict', '%s& out' % classname, - 'std::u16string* error' + 'std::u16string& error' ] comment = ( 'Parses manifest keys for this namespace. Any keys not available to the' @@ -421,8 +422,8 @@ 'const base::Value::Dict& root_dict', 'base::StringPiece key', '%s& out' % classname, - 'std::u16string* error', - 'std::vector<base::StringPiece>* error_path_reversed' + 'std::u16string& error', + 'std::vector<base::StringPiece>& error_path_reversed' ] comment = ( 'Parses the given |key| from |root_dict|. Any keys not available to the' @@ -487,10 +488,12 @@ ) return c - def _GenerateParams(self, params, generate_error_messages=None): + def _GenerateParams( + self, params, generate_error_messages=None, error_as_ptr=None): """Builds the parameter list for a function, given an array of parameters. If |generate_error_messages| is specified, it overrides |self._generate_error_messages|. + |error_as_ptr| is used to indicate a pointer argument should be preserved. """ # |error| is populated with warnings and/or errors found during parsing. # |error| being set does not necessarily imply failure and may be @@ -500,5 +503,11 @@ if generate_error_messages is None: generate_error_messages = self._generate_error_messages if generate_error_messages: - params += ('std::u16string* error',) + if error_as_ptr: + # TODO(crbug.com/1415174): error_as_ptr argument should eventually be + # removed, once all sites making use of FromValueDeprecated get + # migrated, and FromValueDeprecated is removed. + params += ('std::u16string* error',) + else: + params += ('std::u16string& error',) return ', '.join(str(p) for p in params)
diff --git a/tools/json_schema_compiler/manifest_parse_util.cc b/tools/json_schema_compiler/manifest_parse_util.cc index 64e4bd8..5012b3d 100644 --- a/tools/json_schema_compiler/manifest_parse_util.cc +++ b/tools/json_schema_compiler/manifest_parse_util.cc
@@ -24,8 +24,8 @@ base::Value::Type expected_type, ValueTypeConverter<U> type_converter, T& out, - std::u16string* error, - std::vector<base::StringPiece>* error_path_reversed) { + std::u16string& error, + std::vector<base::StringPiece>& error_path_reversed) { DCHECK(type_converter); const base::Value* value = @@ -42,15 +42,13 @@ void PopulateInvalidEnumValueError( base::StringPiece key, base::StringPiece value, - std::u16string* error, - std::vector<base::StringPiece>* error_path_reversed) { - DCHECK(error); - DCHECK(error->empty()); - DCHECK(error_path_reversed); - DCHECK(error_path_reversed->empty()); + std::u16string& error, + std::vector<base::StringPiece>& error_path_reversed) { + DCHECK(error.empty()); + DCHECK(error_path_reversed.empty()); - error_path_reversed->push_back(key); - *error = base::ASCIIToUTF16(base::StringPrintf( + error_path_reversed.push_back(key); + error = base::ASCIIToUTF16(base::StringPrintf( "Specified value '%s' is invalid.", std::string(value).c_str())); } @@ -61,42 +59,38 @@ error_index, base::UTF16ToASCII(item_error).c_str())); } -void PopulateFinalError(std::u16string* error, - std::vector<base::StringPiece>* error_path_reversed) { - DCHECK(error); - DCHECK(error_path_reversed); - DCHECK(!error->empty()); - DCHECK(!error_path_reversed->empty()); +void PopulateFinalError(std::u16string& error, + std::vector<base::StringPiece>& error_path_reversed) { + DCHECK(!error.empty()); + DCHECK(!error_path_reversed.empty()); // Reverse the path to ensure the constituent keys are in the correct order. - std::reverse(error_path_reversed->begin(), error_path_reversed->end()); - *error = base::ASCIIToUTF16( + std::reverse(error_path_reversed.begin(), error_path_reversed.end()); + error = base::ASCIIToUTF16( base::StringPrintf("Error at key '%s'. %s", - base::JoinString(*error_path_reversed, ".").c_str(), - base::UTF16ToASCII(*error).c_str())); + base::JoinString(error_path_reversed, ".").c_str(), + base::UTF16ToASCII(error).c_str())); } const base::Value* FindKeyOfType( const base::Value::Dict& dict, base::StringPiece key, base::Value::Type expected_type, - std::u16string* error, - std::vector<base::StringPiece>* error_path_reversed) { - DCHECK(error); - DCHECK(error->empty()); - DCHECK(error_path_reversed); - DCHECK(error_path_reversed->empty()); + std::u16string& error, + std::vector<base::StringPiece>& error_path_reversed) { + DCHECK(error.empty()); + DCHECK(error_path_reversed.empty()); const base::Value* value = dict.Find(key); if (!value) { - error_path_reversed->push_back(key); - *error = u"Manifest key is required."; + error_path_reversed.push_back(key); + error = u"Manifest key is required."; return nullptr; } if (value->type() != expected_type) { - error_path_reversed->push_back(key); - *error = base::ASCIIToUTF16( + error_path_reversed.push_back(key); + error = base::ASCIIToUTF16( base::StringPrintf("Type is invalid. Expected %s, found %s.", base::Value::GetTypeName(expected_type), base::Value::GetTypeName(value->type()))); @@ -109,8 +103,8 @@ bool ParseFromDictionary(const base::Value::Dict& dict, base::StringPiece key, int& out, - std::u16string* error, - std::vector<base::StringPiece>* error_path_reversed) { + std::u16string& error, + std::vector<base::StringPiece>& error_path_reversed) { return ParseHelper(dict, key, base::Value::Type::INTEGER, &base::Value::GetInt, out, error, error_path_reversed); } @@ -118,8 +112,8 @@ bool ParseFromDictionary(const base::Value::Dict& dict, base::StringPiece key, bool& out, - std::u16string* error, - std::vector<base::StringPiece>* error_path_reversed) { + std::u16string& error, + std::vector<base::StringPiece>& error_path_reversed) { return ParseHelper(dict, key, base::Value::Type::BOOLEAN, &base::Value::GetBool, out, error, error_path_reversed); } @@ -127,8 +121,8 @@ bool ParseFromDictionary(const base::Value::Dict& dict, base::StringPiece key, double& out, - std::u16string* error, - std::vector<base::StringPiece>* error_path_reversed) { + std::u16string& error, + std::vector<base::StringPiece>& error_path_reversed) { return ParseHelper(dict, key, base::Value::Type::DOUBLE, &base::Value::GetDouble, out, error, error_path_reversed); } @@ -136,8 +130,8 @@ bool ParseFromDictionary(const base::Value::Dict& dict, base::StringPiece key, std::string& out, - std::u16string* error, - std::vector<base::StringPiece>* error_path_reversed) { + std::u16string& error, + std::vector<base::StringPiece>& error_path_reversed) { return ParseHelper(dict, key, base::Value::Type::STRING, &base::Value::GetString, out, error, error_path_reversed); }
diff --git a/tools/json_schema_compiler/manifest_parse_util.h b/tools/json_schema_compiler/manifest_parse_util.h index e50a2ae..85f93c22 100644 --- a/tools/json_schema_compiler/manifest_parse_util.h +++ b/tools/json_schema_compiler/manifest_parse_util.h
@@ -24,16 +24,16 @@ void PopulateInvalidEnumValueError( base::StringPiece key, base::StringPiece value, - std::u16string* error, - std::vector<base::StringPiece>* error_path_reversed); + std::u16string& error, + std::vector<base::StringPiece>& error_path_reversed); // Returns array parse error for `item_error` at index `error_index` std::u16string GetArrayParseError(size_t error_index, const std::u16string& item_error); // Populates manifest parse |error| for the given path in |error_path_reversed|. -void PopulateFinalError(std::u16string* error, - std::vector<base::StringPiece>* error_path_reversed); +void PopulateFinalError(std::u16string& error, + std::vector<base::StringPiece>& error_path_reversed); // Returns the value at the given |key| in |dict|, ensuring that it's of the // |expected_type|. On failure, returns false and populates |error| and @@ -42,63 +42,63 @@ const base::Value::Dict& dict, base::StringPiece key, base::Value::Type expected_type, - std::u16string* error, - std::vector<base::StringPiece>* error_path_reversed); + std::u16string& error, + std::vector<base::StringPiece>& error_path_reversed); // Parses |out| from |dict| at the given |key|. On failure, returns false and // populates |error| and |error_path_reversed|. bool ParseFromDictionary(const base::Value::Dict& dict, base::StringPiece key, int& out, - std::u16string* error, - std::vector<base::StringPiece>* error_path_reversed); + std::u16string& error, + std::vector<base::StringPiece>& error_path_reversed); bool ParseFromDictionary(const base::Value::Dict& dict, base::StringPiece key, bool& out, - std::u16string* error, - std::vector<base::StringPiece>* error_path_reversed); + std::u16string& error, + std::vector<base::StringPiece>& error_path_reversed); bool ParseFromDictionary(const base::Value::Dict& dict, base::StringPiece key, double& out, - std::u16string* error, - std::vector<base::StringPiece>* error_path_reversed); + std::u16string& error, + std::vector<base::StringPiece>& error_path_reversed); bool ParseFromDictionary(const base::Value::Dict& dict, base::StringPiece key, std::string& out, - std::u16string* error, - std::vector<base::StringPiece>* error_path_reversed); + std::u16string& error, + std::vector<base::StringPiece>& error_path_reversed); // This overload is used for lists/arrays. template <typename T> bool ParseFromDictionary(const base::Value::Dict& dict, base::StringPiece key, std::vector<T>& out, - std::u16string* error, - std::vector<base::StringPiece>* error_path_reversed); + std::u16string& error, + std::vector<base::StringPiece>& error_path_reversed); // This overload is used for optional types wrapped as unique_ptr<T>. template <typename T> bool ParseFromDictionary(const base::Value::Dict& dict, base::StringPiece key, std::unique_ptr<T>& out, - std::u16string* error, - std::vector<base::StringPiece>* error_path_reversed); + std::u16string& error, + std::vector<base::StringPiece>& error_path_reversed); // This overload is used for optional types wrapped as absl::optional<T>. template <typename T> bool ParseFromDictionary(const base::Value::Dict& dict, base::StringPiece key, absl::optional<T>& out_opt, - std::u16string* error, - std::vector<base::StringPiece>* error_path_reversed); + std::u16string& error, + std::vector<base::StringPiece>& error_path_reversed); // This overload is used for generated types. template <typename T> bool ParseFromDictionary(const base::Value::Dict& dict, base::StringPiece key, T& out, - std::u16string* error, - std::vector<base::StringPiece>* error_path_reversed) { + std::u16string& error, + std::vector<base::StringPiece>& error_path_reversed) { return T::ParseFromDictionary(dict, key, out, error, error_path_reversed); } @@ -106,8 +106,8 @@ bool ParseFromDictionary(const base::Value::Dict& dict, base::StringPiece key, std::vector<T>& out, - std::u16string* error, - std::vector<base::StringPiece>* error_path_reversed) { + std::u16string& error, + std::vector<base::StringPiece>& error_path_reversed) { const base::Value* value = FindKeyOfType(dict, key, base::Value::Type::LIST, error, error_path_reversed); if (!value) @@ -116,9 +116,8 @@ bool result = json_schema_compiler::util::PopulateArrayFromList( value->GetList(), out, error); if (!result) { - DCHECK(error_path_reversed); - DCHECK(error_path_reversed->empty()); - error_path_reversed->push_back(key); + DCHECK(error_path_reversed.empty()); + error_path_reversed.push_back(key); } return result; @@ -128,8 +127,8 @@ bool ParseFromDictionary(const base::Value::Dict& dict, base::StringPiece key, std::unique_ptr<T>& out, - std::u16string* error, - std::vector<base::StringPiece>* error_path_reversed) { + std::u16string& error, + std::vector<base::StringPiece>& error_path_reversed) { // Ignore optional keys if they are not present without raising an error. if (!dict.Find(key)) return true; @@ -149,8 +148,8 @@ bool ParseFromDictionary(const base::Value::Dict& dict, base::StringPiece key, absl::optional<T>& out_opt, - std::u16string* error, - std::vector<base::StringPiece>* error_path_reversed) { + std::u16string& error, + std::vector<base::StringPiece>& error_path_reversed) { // Ignore optional keys if they are not present without raising an error. if (!dict.Find(key)) return true; @@ -180,8 +179,8 @@ bool is_optional_property, T none_value, T& out, - std::u16string* error, - std::vector<base::StringPiece>* error_path_reversed) { + std::u16string& error, + std::vector<base::StringPiece>& error_path_reversed) { DCHECK_EQ(none_value, out); // Ignore optional keys if they are not present without raising an error. @@ -215,8 +214,8 @@ StringToEnumConverter<T> converter, T none_value, std::vector<T>& out, - std::u16string* error, - std::vector<base::StringPiece>* error_path_reversed) { + std::u16string& error, + std::vector<base::StringPiece>& error_path_reversed) { std::vector<std::string> str_array; if (!ParseFromDictionary(dict, key, str_array, error, error_path_reversed)) { return false; @@ -228,9 +227,9 @@ T enum_value = converter(str_array[i]); if (enum_value == none_value) { std::u16string item_error; - PopulateInvalidEnumValueError(key, str_array[i], &item_error, + PopulateInvalidEnumValueError(key, str_array[i], item_error, error_path_reversed); - *error = GetArrayParseError(i, item_error); + error = GetArrayParseError(i, item_error); return false; } @@ -249,8 +248,8 @@ StringToEnumConverter<T> converter, T none_value, absl::optional<std::vector<T>>& out, - std::u16string* error, - std::vector<base::StringPiece>* error_path_reversed) { + std::u16string& error, + std::vector<base::StringPiece>& error_path_reversed) { // Ignore optional keys if they are not present without raising an error. if (!dict.Find(key)) return true;
diff --git a/tools/json_schema_compiler/test/error_generation_unittest.cc b/tools/json_schema_compiler/test/error_generation_unittest.cc index 5813e811..cfda7c6 100644 --- a/tools/json_schema_compiler/test/error_generation_unittest.cc +++ b/tools/json_schema_compiler/test/error_generation_unittest.cc
@@ -22,7 +22,7 @@ std::u16string GetPopulateError(const Value& value) { std::u16string error; T test_type; - T::Populate(value, test_type, &error); + T::Populate(value, test_type, error); return error; } @@ -80,14 +80,14 @@ base::Value::List params_value; params_value.Append(5); std::u16string error; - EXPECT_TRUE(errors::TestFunction::Params::Create(params_value, &error)); + EXPECT_TRUE(errors::TestFunction::Params::Create(params_value, error)); } { base::Value::List params_value; params_value.Append(5); params_value.Append(5); std::u16string error; - EXPECT_FALSE(errors::TestFunction::Params::Create(params_value, &error)); + EXPECT_FALSE(errors::TestFunction::Params::Create(params_value, error)); EXPECT_TRUE(EqualsUtf16("expected 1 arguments, got 2", error)); } } @@ -99,13 +99,13 @@ base::Value::List params_value; params_value.Append(5); std::u16string error; - EXPECT_TRUE(errors::TestFunction::Params::Create(params_value, &error)); + EXPECT_TRUE(errors::TestFunction::Params::Create(params_value, error)); } { base::Value::List params_value; params_value.Append(base::Value()); std::u16string error; - EXPECT_FALSE(errors::TestFunction::Params::Create(params_value, &error)); + EXPECT_FALSE(errors::TestFunction::Params::Create(params_value, error)); EXPECT_TRUE(EqualsUtf16("'num' is required", error)); } } @@ -131,14 +131,13 @@ std::u16string error; base::Value::List params_value; params_value.Append("Yeah!"); - EXPECT_TRUE(errors::TestString::Params::Create(params_value, &error)); + EXPECT_TRUE(errors::TestString::Params::Create(params_value, error)); } { base::Value::List params_value; params_value.Append(5); std::u16string error; - EXPECT_FALSE( - errors::TestTypeInObject::Params::Create(params_value, &error)); + EXPECT_FALSE(errors::TestTypeInObject::Params::Create(params_value, error)); EXPECT_TRUE(EqualsUtf16("'paramObject': expected dictionary, got integer", error)); } @@ -153,7 +152,7 @@ base::Value value = Dictionary("otherType", Value(1.1)); errors::ObjectType out; std::u16string error; - EXPECT_FALSE(errors::ObjectType::Populate(value.GetDict(), out, &error)); + EXPECT_FALSE(errors::ObjectType::Populate(value.GetDict(), out, error)); EXPECT_TRUE(EqualsUtf16("'otherType': expected dictionary, got double", error)); EXPECT_FALSE(out.other_type.has_value()); @@ -233,7 +232,7 @@ errors::OptionalTestType out; std::u16string error; EXPECT_FALSE( - errors::OptionalTestType::Populate(value.GetDict(), out, &error)); + errors::OptionalTestType::Populate(value.GetDict(), out, error)); EXPECT_TRUE(EqualsUtf16("'string': expected string, got integer", error)); EXPECT_FALSE(out.string); @@ -253,7 +252,7 @@ errors::OptionalBinaryData out; std::u16string error; EXPECT_FALSE( - errors::OptionalBinaryData::Populate(value.GetDict(), out, &error)); + errors::OptionalBinaryData::Populate(value.GetDict(), out, error)); EXPECT_TRUE(EqualsUtf16("'data': expected binary, got integer", error)); EXPECT_FALSE(out.data.has_value()); @@ -271,7 +270,7 @@ base::Value value = Dictionary("TheArray", Value(5)); errors::ArrayObject out; std::u16string error; - EXPECT_FALSE(errors::ArrayObject::Populate(value.GetDict(), out, &error)); + EXPECT_FALSE(errors::ArrayObject::Populate(value.GetDict(), out, error)); EXPECT_TRUE(EqualsUtf16("'TheArray': expected list, got integer", error)); EXPECT_FALSE(out.the_array.has_value()); @@ -290,7 +289,7 @@ errors::OptionalChoiceType::Integers out; std::u16string error; EXPECT_FALSE(errors::OptionalChoiceType::Integers::Populate(params_value, - out, &error)); + out, error)); EXPECT_TRUE( EqualsUtf16("Error at key 'integers': Parsing array failed at index 1: " "expected integer, got boolean",
diff --git a/tools/json_schema_compiler/test/simple_api_unittest.cc b/tools/json_schema_compiler/test/simple_api_unittest.cc index 66a10fa..56ac060 100644 --- a/tools/json_schema_compiler/test/simple_api_unittest.cc +++ b/tools/json_schema_compiler/test/simple_api_unittest.cc
@@ -38,7 +38,7 @@ simple_api::ManifestKeys manifest_keys; std::u16string error_16; bool result = simple_api::ManifestKeys::ParseFromDictionary( - manifest->GetDict(), manifest_keys, &error_16); + manifest->GetDict(), manifest_keys, error_16); ASSERT_FALSE(result); *error = base::UTF16ToASCII(error_16); @@ -51,7 +51,7 @@ std::u16string error_16; bool result = simple_api::ManifestKeys::ParseFromDictionary( - manifest->GetDict(), *manifest_keys, &error_16); + manifest->GetDict(), *manifest_keys, error_16); ASSERT_TRUE(result) << error_16; ASSERT_TRUE(error_16.empty()) << error_16;
diff --git a/tools/json_schema_compiler/util.cc b/tools/json_schema_compiler/util.cc index 0df53de..0012beb1 100644 --- a/tools/json_schema_compiler/util.cc +++ b/tools/json_schema_compiler/util.cc
@@ -15,9 +15,9 @@ bool ReportError(const base::Value& from, base::Value::Type expected, - std::u16string* error) { - DCHECK(error->empty()); - *error = base::ASCIIToUTF16(base::StringPrintf( + std::u16string& error) { + DCHECK(error.empty()); + error = base::ASCIIToUTF16(base::StringPrintf( "expected %s, got %s", base::Value::GetTypeName(expected), base::Value::GetTypeName(from.type()))); return false; // Always false on purpose. @@ -33,7 +33,7 @@ return true; } -bool PopulateItem(const base::Value& from, int& out, std::u16string* error) { +bool PopulateItem(const base::Value& from, int& out, std::u16string& error) { if (!PopulateItem(from, out)) return ReportError(from, base::Value::Type::INTEGER, error); return true; @@ -47,7 +47,7 @@ return true; } -bool PopulateItem(const base::Value& from, bool& out, std::u16string* error) { +bool PopulateItem(const base::Value& from, bool& out, std::u16string& error) { if (!from.is_bool()) { return ReportError(from, base::Value::Type::BOOLEAN, error); } @@ -64,7 +64,7 @@ return true; } -bool PopulateItem(const base::Value& from, double& out, std::u16string* error) { +bool PopulateItem(const base::Value& from, double& out, std::u16string& error) { if (!from.is_double()) { return ReportError(from, base::Value::Type::DOUBLE, error); } @@ -82,7 +82,7 @@ bool PopulateItem(const base::Value& from, std::string& out, - std::u16string* error) { + std::u16string& error) { if (!from.is_string()) { return ReportError(from, base::Value::Type::STRING, error); } @@ -100,7 +100,7 @@ bool PopulateItem(const base::Value& from, std::vector<uint8_t>& out, - std::u16string* error) { + std::u16string& error) { if (!from.is_blob()) { return ReportError(from, base::Value::Type::BINARY, error); } @@ -115,7 +115,7 @@ bool PopulateItem(const base::Value& from, base::Value& out, - std::u16string* error) { + std::u16string& error) { out = from.Clone(); return true; }
diff --git a/tools/json_schema_compiler/util.h b/tools/json_schema_compiler/util.h index 7c59f43d..154add2 100644 --- a/tools/json_schema_compiler/util.h +++ b/tools/json_schema_compiler/util.h
@@ -24,22 +24,22 @@ bool PopulateItem(const base::Value& from, base::Value& out); bool PopulateItem(const base::Value& from, int& out); -bool PopulateItem(const base::Value& from, int& out, std::u16string* error); +bool PopulateItem(const base::Value& from, int& out, std::u16string& error); bool PopulateItem(const base::Value& from, bool& out); -bool PopulateItem(const base::Value& from, bool& out, std::u16string* error); +bool PopulateItem(const base::Value& from, bool& out, std::u16string& error); bool PopulateItem(const base::Value& from, double& out); -bool PopulateItem(const base::Value& from, double& out, std::u16string* error); +bool PopulateItem(const base::Value& from, double& out, std::u16string& error); bool PopulateItem(const base::Value& from, std::string& out); bool PopulateItem(const base::Value& from, std::string& out, - std::u16string* error); + std::u16string& error); bool PopulateItem(const base::Value& from, std::vector<uint8_t>& out); bool PopulateItem(const base::Value& from, std::vector<uint8_t>& out, - std::u16string* error); + std::u16string& error); bool PopulateItem(const base::Value& from, base::Value& out, - std::u16string* error); + std::u16string& error); // This template is used for types generated by tools/json_schema_compiler. template <class T> @@ -55,7 +55,7 @@ // This template is used for types generated by tools/json_schema_compiler with // error generation enabled. template <class T> -bool PopulateItem(const base::Value& from, T& out, std::u16string* error) { +bool PopulateItem(const base::Value& from, T& out, std::u16string& error) { T obj; if (!T::Populate(from, obj, error)) { return false; @@ -88,15 +88,15 @@ template <class T> bool PopulateArrayFromList(const base::Value::List& list, std::vector<T>& out, - std::u16string* error) { + std::u16string& error) { out.clear(); out.reserve(list.size()); T item; std::u16string item_error; for (size_t i = 0; i < list.size(); ++i) { - if (!PopulateItem(list[i], item, &item_error)) { - DCHECK(error->empty()); - *error = base::ASCIIToUTF16( + if (!PopulateItem(list[i], item, item_error)) { + DCHECK(error.empty()); + error = base::ASCIIToUTF16( base::StringPrintf("Parsing array failed at index %" PRIuS ": %s", i, base::UTF16ToASCII(item_error).c_str())); return false; @@ -124,7 +124,7 @@ template <class T> bool PopulateOptionalArrayFromList(const base::Value::List& list, absl::optional<std::vector<T>>& out, - std::u16string* error) { + std::u16string& error) { std::vector<T> populated; if (!PopulateArrayFromList(list, populated, error)) { return false;
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 12db280ae..6c6f602 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -2451,7 +2451,7 @@ ], 'codesearch_gen_chromium_ios_bot': [ - 'codesearch', 'ios', + 'codesearch_ios', 'ios', ], # Lacros uses different gn args to build for chromeOS device vs. Linux. For @@ -4013,6 +4013,14 @@ 'mixins': ['goma', 'clang', 'shared', 'debug', 'minimal_symbols', 'blink_enable_generated_code_formatting'], }, + + # Same as regular codesearch except ios does not allow component builds + 'codesearch_ios': { + 'gn_args': 'clang_use_chrome_plugins=false enable_kythe_annotations=true', + 'mixins': ['goma', 'clang', 'debug', 'minimal_symbols', + 'blink_enable_generated_code_formatting'], + }, + 'codesearch_release': { 'gn_args': 'clang_use_chrome_plugins=false enable_kythe_annotations=true', 'mixins': ['release', 'static', 'goma',
diff --git a/tools/mb/mb_config_expectations/chromium.infra.codesearch.json b/tools/mb/mb_config_expectations/chromium.infra.codesearch.json index 42189bc3..035cb03 100644 --- a/tools/mb/mb_config_expectations/chromium.infra.codesearch.json +++ b/tools/mb/mb_config_expectations/chromium.infra.codesearch.json
@@ -45,7 +45,6 @@ "clang_use_chrome_plugins": false, "enable_kythe_annotations": true, "is_clang": true, - "is_component_build": true, "is_debug": true, "symbol_level": 1, "target_os": "ios",
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.codesearch.json b/tools/mb/mb_config_expectations/tryserver.chromium.codesearch.json index 0bd6c23..09ace9c 100644 --- a/tools/mb/mb_config_expectations/tryserver.chromium.codesearch.json +++ b/tools/mb/mb_config_expectations/tryserver.chromium.codesearch.json
@@ -45,7 +45,6 @@ "clang_use_chrome_plugins": false, "enable_kythe_annotations": true, "is_clang": true, - "is_component_build": true, "is_debug": true, "symbol_level": 1, "target_os": "ios",
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index ebc7904d..931b3da 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -36989,6 +36989,7 @@ label="For KeyboardAccessoryPaymentFilling feature."/> <suffix name="KeyboardAccessoryPaymentOffer" label="For KeyboardAccessoryPaymentOffer feature."/> + <suffix name="LauncherSearchHelpUi" label="For launcher search IPH feature."/> <suffix name="LiveCaption" label="For LiveCaption feature."/> <suffix name="LongPressToolbarTip" label="For LongPressToolbar feature."/> <suffix name="LowUserEngagementDetector"
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 0c2bc98f..6729ddb 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -1825,10 +1825,11 @@ label="Context menu item for 'Search Images with Google Lens' (Region)"/> <int value="3" label="Context menu item for 'Search Images with Web' (Region)"/> - <int value="4" label="Omnibox (Camera)"/> - <int value="5" label="New Tab Page (Camera)"/> - <int value="6" label="Quick Action Search Widget (Camera)"/> - <int value="7" label="Keyboard (Camera)"/> + <int value="4" label="Context menu item for 'Search Web For'"/> + <int value="5" label="Omnibox (Camera)"/> + <int value="6" label="New Tab Page (Camera)"/> + <int value="7" label="Quick Action Search Widget (Camera)"/> + <int value="8" label="Keyboard (Camera)"/> </enum> <enum name="AmbientUiMode"> @@ -14165,6 +14166,13 @@ <int value="2" label="Camera privacy switch on notification shown"/> </enum> +<enum name="CameraResult"> + <int value="0" label="Success (Camera)"/> + <int value="1" label="Success (Gallery Image)"/> + <int value="2" label="Success (QR/Bar Code)"/> + <int value="3" label="Dismissed"/> +</enum> + <enum name="CanaryCheckLookupResult"> <int value="0" label="Success"/> <int value="1" label="Failure"/> @@ -53374,6 +53382,8 @@ <int value="0" label="Lens Search Supported"/> <int value="1" label="Not Google Search Engine"/> <int value="2" label="Device was a tablet"/> + <int value="3" label="Entry Point disabled by flag"/> + <int value="4" label="Lens Provider does not support the entry point"/> </enum> <enum name="IOSLensWebUploadStatus"> @@ -58996,7 +59006,6 @@ <int value="-1454264660" label="ProminentDarkModeActiveTabTitle:disabled"/> <int value="-1453647118" label="PasswordLeakDetection:disabled"/> <int value="-1452786530" label="ChromeOSZramWriteback:enabled"/> - <int value="-1452408727" label="AutofillEnableCvcForVcnYellowPath:enabled"/> <int value="-1452010225" label="WindowNaming:disabled"/> <int value="-1451644187" label="OverviewSwipeToClose:enabled"/> <int value="-1450657485" label="EnableHardwareMirrorMode:enabled"/> @@ -59405,6 +59414,7 @@ <int value="-1237621246" label="WebXRGamepadSupport:disabled"/> <int value="-1236065190" label="HardwareMediaKeyHandling:disabled"/> <int value="-1235586511" label="enable-datasaver-prompt"/> + <int value="-1235356380" label="UseOutOfProcessVideoDecoding:disabled"/> <int value="-1235021573" label="ImeOptionsInSettings:disabled"/> <int value="-1234740672" label="UsePdfCompositorServiceForPrint:disabled"/> <int value="-1234518922" label="ChromeLabs:disabled"/> @@ -59736,6 +59746,8 @@ <int value="-1055523523" label="ForceMinorVersion100InUserAgent:disabled"/> <int value="-1053496936" label="WebViewSendVariationsHeaders:disabled"/> <int value="-1053198238" label="kScrollableTabStripWithDragging:enabled"/> + <int value="-1052980318" + label="ExposeOutOfProcessVideoDecodingToLacros:enabled"/> <int value="-1052831253" label="ChromeKioskEnableLacros:enabled"/> <int value="-1052782474" label="enable-cloud-devices"/> <int value="-1052592553" label="CrOSLateBootArcVmAAudioMMAP:enabled"/> @@ -60352,7 +60364,6 @@ <int value="-718884399" label="NewTabPageUIMd:enabled"/> <int value="-718626298" label="SysInternals:enabled"/> <int value="-718485659" label="OmniboxGroupingFrameworkForNonZPS:enabled"/> - <int value="-717339133" label="AutofillEnableCvcForVcnYellowPath:disabled"/> <int value="-716965886" label="NtpRealboxRoundedCorners:disabled"/> <int value="-716953514" label="disable-password-separated-signin-flow"/> <int value="-716272467" label="AssistantAppSupport:disabled"/> @@ -62562,6 +62573,7 @@ <int value="510066229" label="AutofillEnforceMinRequiredFieldsForQuery:enabled"/> <int value="510814146" label="OfflineBookmarks:enabled"/> + <int value="510833540" label="UseOutOfProcessVideoDecoding:enabled"/> <int value="511179195" label="ShoppingAssist:disabled"/> <int value="511392922" label="SharedClipboardReceiver:enabled"/> <int value="512143128" label="LacrosOnly:enabled"/> @@ -62846,6 +62858,7 @@ <int value="671800756" label="TabStripImprovements:enabled"/> <int value="672067370" label="InstallableAmbientBadgeMessage:enabled"/> <int value="672255299" label="WebAuthFlowInBrowserTab:disabled"/> + <int value="672599279" label="WebUiSystemFont:disabled"/> <int value="673588373" label="OmniboxPedalSuggestions:disabled"/> <int value="674627327" label="MagnifierNewFocusFollowing:enabled"/> <int value="674788251" label="EnableNewBadgeOnMenuItems:enabled"/> @@ -63886,6 +63899,8 @@ <int value="1249861983" label="WebViewUseMetricsUploadService:disabled"/> <int value="1250071868" label="disable-timezone-tracking-option"/> <int value="1250776846" label="DnsProxyEnableDOH:enabled"/> + <int value="1251097300" + label="CCTResizableSideSheetDiscoverFeedSettings:enabled"/> <int value="1251663392" label="ArcImageCopyPasteCompat:disabled"/> <int value="1253001092" label="FeedShare:enabled"/> <int value="1253698118" label="ash-disable-stable-overview-order"/> @@ -64245,6 +64260,8 @@ label="CellularBypassESimInstallationConnectivityCheck:disabled"/> <int value="1452546183" label="PwaPersistentNotification:enabled"/> <int value="1453393588" label="DiscoverFeedMultiColumn:disabled"/> + <int value="1453448177" + label="ExposeOutOfProcessVideoDecodingToLacros:disabled"/> <int value="1454006695" label="BlinkHeapUnifiedGarbageCollection:disabled"/> <int value="1454028829" label="EnhancedProtectionPromoCard:disabled"/> <int value="1454143461" label="CaptureThumbnailOnNavigatingAway:disabled"/> @@ -64545,6 +64562,7 @@ <int value="1628831121" label="SafeBrowsingUseLocalBlacklistsV2:enabled"/> <int value="1629289109" label="EnableBloom:disabled"/> <int value="1629497607" label="CertDualVerificationTrial:disabled"/> + <int value="1629523329" label="WebUiSystemFont:enabled"/> <int value="1630159957" label="SharingSendViaSync:disabled"/> <int value="1630283072" label="CrOSAutoSelect:enabled"/> <int value="1630988998" label="VrBrowsingExperimentalRendering:disabled"/> @@ -64624,6 +64642,8 @@ <int value="1667584730" label="WebXR:disabled"/> <int value="1667886516" label="PageInfoAboutThisSiteImprovedBottomSheet:enabled"/> + <int value="1667943654" + label="CCTResizableSideSheetDiscoverFeedSettings:disabled"/> <int value="1668006393" label="AutofillShowAutocompleteDeleteButton:disabled"/> <int value="1668611601" label="enable-encrypted-media"/> @@ -69040,6 +69060,17 @@ <int value="7" label="NavStart+Start+Commit missing"/> </enum> +<enum name="MissiveMigrationStatus"> + <int value="0" label="Not needed"/> + <int value="1" label="Success"/> + <int value="2" label="Failed to delete source files"/> + <int value="3" label="Failed to delete deletion tag file"/> + <int value="4" label="Failed to create deletion tag file"/> + <int value="5" label="Failed to delete destination files"/> + <int value="6" label="Failed to copy"/> + <int value="7" label="Destination not exist"/> +</enum> + <enum name="MistSwitchResult"> <int value="0" label="Success"/> <int value="1" label="Failure"/> @@ -69870,6 +69901,12 @@ <int value="2" label="Multiple user profiles"/> </enum> +<enum name="MultiPortStatusOnMigration"> + <int value="0" label="Not validated"/> + <int value="1" label="Pending refresh validation"/> + <int value="2" label="Waiting for refresh validation"/> +</enum> + <enum name="MultiProfileSessionMode"> <obsolete> Deprecated 09/2017. See histogram MultiProfile.SessionMode. @@ -76913,6 +76950,10 @@ <int value="438" label="Touchpad: Haptic Feedback"/> <int value="439" label="Touchpad: Haptic Click Sensitivity"/> <int value="440" label="Power: Adaptive Charging"/> + <int value="441" + label="Keyboard: Switch Top Row Keys Between Function Keys And Chrome + Actions"/> + <int value="442" label="Keyboard: Remap Keys"/> <int value="500" label="Open Wallpaper"/> <int value="501" label="Ambient Mode On/Off"/> <int value="502" label="Ambient Mode Source"/> @@ -85229,14 +85270,6 @@ <int value="14" label="Screen Sharing, Microphone, and Camera are in use"/> </enum> -<enum name="PrivacyQuickDelete"> - <int value="0" label="Entry from menu item clicked"/> - <int value="1" label="Delete button on dialog clicked"/> - <int value="2" label="Cancel button on dialog clicked"/> - <int value="3" - label="Dialog dismissed due to reasons other than Cancel or Delete"/> -</enum> - <enum name="PrivacySandboxAggregationServiceKeyFetcherStatus"> <int value="0" label="Success"/> <int value="1" label="Download error"/> @@ -87394,6 +87427,14 @@ <int value="3" label="TTS_EVENT_OTHER"/> </enum> +<enum name="QuickDeleteAction"> + <int value="0" label="Entry from menu item clicked"/> + <int value="1" label="Delete button on dialog clicked"/> + <int value="2" label="Cancel button on dialog clicked"/> + <int value="3" + label="Dialog dismissed due to reasons other than Cancel or Delete"/> +</enum> + <enum name="QuicKeyUpdateReason"> <int value="0" label="kInvalid"/> <int value="1" label="kRemote"/> @@ -112651,7 +112692,7 @@ </int> <int value="1" label="Remote request without page URL ineligible"> Suggest request without sending the current page URL cannot be made. E.g., - the user is in icognito mode or Google is not set as the default search + the user is in incognito mode or Google is not set as the default search provider. </int> <int value="2" label="Remote request with sending page URL ineligible">
diff --git a/tools/metrics/histograms/metadata/autofill/histograms.xml b/tools/metrics/histograms/metadata/autofill/histograms.xml index 55b89ad6..01a3722f 100644 --- a/tools/metrics/histograms/metadata/autofill/histograms.xml +++ b/tools/metrics/histograms/metadata/autofill/histograms.xml
@@ -3305,7 +3305,7 @@ </histogram> <histogram name="Autofill.ProfileImport.SilentUpdatesProfileImportType" - enum="AutofillSilentUpdatesProfileImportType" expires_after="2023-04-30"> + enum="AutofillSilentUpdatesProfileImportType" expires_after="2023-10-30"> <owner>koerber@google.com</owner> <owner>src/components/autofill/OWNERS</owner> <summary> @@ -3316,7 +3316,7 @@ </histogram> <histogram name="Autofill.ProfileImport.UpdateProfileAffectedType.{Decision}" - enum="AutofillSettingsVisibleTypes" expires_after="2023-04-30"> + enum="AutofillSettingsVisibleTypes" expires_after="2023-10-30"> <owner>koerber@google.com</owner> <owner>src/components/autofill/OWNERS</owner> <summary> @@ -3384,7 +3384,7 @@ <histogram name="Autofill.ProfileImport.UpdateProfileNumberOfAffectedFields.{Decision}" - units="fields" expires_after="2023-04-30"> + units="fields" expires_after="2023-10-30"> <owner>koerber@google.com</owner> <owner>src/components/autofill/OWNERS</owner> <summary> @@ -3449,7 +3449,7 @@ </histogram> <histogram name="Autofill.ProfileSuggestionsMadeWithFormatter" - enum="BooleanCreated" expires_after="2023-04-30"> + enum="BooleanCreated" expires_after="2023-10-30"> <owner>battre@chromium.org</owner> <owner>src/components/autofill/OWNERS</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/bluetooth/histograms.xml b/tools/metrics/histograms/metadata/bluetooth/histograms.xml index 1ca03374..be1594ce 100644 --- a/tools/metrics/histograms/metadata/bluetooth/histograms.xml +++ b/tools/metrics/histograms/metadata/bluetooth/histograms.xml
@@ -155,7 +155,7 @@ </histogram> <histogram name="Bluetooth.ChromeOS.FastPair.AccountKey.Write.GattErrorReason" - enum="BluetoothDeviceConnectErrorCode" expires_after="2023-04-30"> + enum="BluetoothDeviceConnectErrorCode" expires_after="2023-09-03"> <owner>jackshira@google.com</owner> <owner>dclasson@google.com</owner> <owner>brandosocarras@google.com</owner> @@ -728,7 +728,7 @@ <histogram name="Bluetooth.ChromeOS.FastPair.GattConnection.EffectiveSuccessRate" - enum="BooleanSuccess" expires_after="2023-04-30"> + enum="BooleanSuccess" expires_after="2023-09-03"> <owner>jackshira@google.com</owner> <owner>dclasson@google.com</owner> <owner>brandosocarras@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/feature_engagement/histograms.xml b/tools/metrics/histograms/metadata/feature_engagement/histograms.xml index 6bd7fdd..1d73f51 100644 --- a/tools/metrics/histograms/metadata/feature_engagement/histograms.xml +++ b/tools/metrics/histograms/metadata/feature_engagement/histograms.xml
@@ -184,6 +184,8 @@ summary="payments autofill suggestions"/> <variant name="IPH_KeyboardAccessoryPaymentOffer" summary="payments autofill suggestions that have an offer"/> + <variant name="IPH_LauncherSearchHelpUi" + summary="show launcher search chips in the launcher"/> <variant name="IPH_LiveCaption" summary="Live Caption"/> <variant name="IPH_LongPressToolbarTip" summary="LongPress toolbar"/> <variant name="IPH_MicToolbar" summary="the mic button in the toolbar"/>
diff --git a/tools/metrics/histograms/metadata/mobile/histograms.xml b/tools/metrics/histograms/metadata/mobile/histograms.xml index 7cedc3c..96ae71a 100644 --- a/tools/metrics/histograms/metadata/mobile/histograms.xml +++ b/tools/metrics/histograms/metadata/mobile/histograms.xml
@@ -230,6 +230,17 @@ </summary> </histogram> +<histogram name="Mobile.Keyboard.LensSupportStatus" enum="IOSLensSupportStatus" + expires_after="2023-08-26"> + <owner>hujasonx@google.com</owner> + <owner>lens-in-bling-team@google.com</owner> + <summary> + Whether or not Lens is supported in the Omnibox keyboard accessory view + (shown above the number keys upon focusing the omnibox for edit), and if + not, the reason why. Recorded each time the Omnibox keyboard is opened. + </summary> +</histogram> + <histogram name="Mobile.Messages.Badge.Tapped.{MobileInfobarType}" enum="MobileMessagesBadgeState" expires_after="2023-07-24"> <owner>sczs@chromium.org</owner> @@ -382,6 +393,17 @@ </summary> </histogram> +<histogram name="Mobile.NewTabPage.LensSupportStatus" + enum="IOSLensSupportStatus" expires_after="2023-08-26"> + <owner>hujasonx@google.com</owner> + <owner>lens-in-bling-team@google.com</owner> + <summary> + Whether or not Lens is supported in the new tab page, and if not, the reason + why. Recorded when a new tab is created. Subsequent navigations to an + existing new tab page will not log the event. + </summary> +</histogram> + <histogram name="Mobile.RecentTabsManager.TotalTabsFromOtherDevicesOpenAll" units="count" expires_after="2023-04-19"> <owner>sczs@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/net/histograms.xml b/tools/metrics/histograms/metadata/net/histograms.xml index ba82ac2..95e856b 100644 --- a/tools/metrics/histograms/metadata/net/histograms.xml +++ b/tools/metrics/histograms/metadata/net/histograms.xml
@@ -2346,6 +2346,15 @@ </summary> </histogram> +<histogram name="Net.QuicConnection.MultiPortPathStatusWhenMigrating" + enum="MultiPortStatusOnMigration" expires_after="2023-12-30"> + <owner>renjietang@chromium.org</owner> + <owner>src/net/quic/OWNERS</owner> + <summary> + The status of the multi-port path when the client initiates the migration. + </summary> +</histogram> + <histogram name="Net.QuicConnection.WritePacketStatus" enum="QuicWriteStatus" expires_after="2023-09-17"> <owner>wub@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml index da023857..9f14c7dd 100644 --- a/tools/metrics/histograms/metadata/others/histograms.xml +++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -8564,32 +8564,6 @@ </summary> </histogram> -<histogram name="Networks.RememberedShared" units="units" - expires_after="2020-08-01"> - <owner>stevenjb@chromium.org</owner> - <summary> - Number of shared remembered (preferred) networks on Chrome OS. Updated any - time the network list changes. - </summary> -</histogram> - -<histogram name="Networks.RememberedUnshared" units="units" - expires_after="2020-08-01"> - <owner>stevenjb@chromium.org</owner> - <summary> - Number of private remembered (preferred) networks on Chrome OS. Updated any - time the network list changes. - </summary> -</histogram> - -<histogram name="Networks.Visible" units="units" expires_after="2020-08-01"> - <owner>stevenjb@chromium.org</owner> - <summary> - Number of visible (in-range) networks on Chrome OS. Updated any time the - network list changes. - </summary> -</histogram> - <histogram name="NQE.CachedNetworkQualityAvailable" enum="BooleanAvailable" expires_after="2021-10-10"> <owner>tbansal@chromium.org</owner> @@ -10342,27 +10316,6 @@ </summary> </histogram> -<histogram name="PushMessaging.DeliveryStatus.FindServiceWorker" - enum="ServiceWorkerStatusCode" expires_after="M98"> - <owner>peter@chromium.org</owner> - <owner>knollr@chromium.org</owner> - <summary> - When attempting to deliver a push message to a Service Worker, this records - the result of finding the Service Worker registration given its ID and - origin. - </summary> -</histogram> - -<histogram name="PushMessaging.DeliveryStatus.ServiceWorkerEvent" - enum="ServiceWorkerStatusCode" expires_after="M98"> - <owner>peter@chromium.org</owner> - <owner>knollr@chromium.org</owner> - <summary> - When a Service Worker receives a push message, this records the precise - result received from the Service Worker code. - </summary> -</histogram> - <histogram name="PushMessaging.GetRegistrationStatus" enum="PushGetRegistrationStatus" expires_after="2022-06-26"> <owner>peter@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/platform/histograms.xml b/tools/metrics/histograms/metadata/platform/histograms.xml index 07d5ffa2..633f390d 100644 --- a/tools/metrics/histograms/metadata/platform/histograms.xml +++ b/tools/metrics/histograms/metadata/platform/histograms.xml
@@ -1313,6 +1313,17 @@ </summary> </histogram> +<histogram name="Platform.Missive.MigrationStatus" + enum="MissiveMigrationStatus" expires_after="2024-03-24"> + <owner>lbaraz@chromium.org</owner> + <owner>xuhong@chromium.org</owner> + <owner>cros-reporting-team@google.com</owner> + <summary> + Recorded when Missive runs the storage directory migration function (called + each time when Missive starts). It counts the status of the migration. + </summary> +</histogram> + <histogram name="Platform.Missive.ResourceExhaustedCase" enum="ResourceExhaustedCase" expires_after="2023-11-17"> <owner>xuhong@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/privacy/histograms.xml b/tools/metrics/histograms/metadata/privacy/histograms.xml index 84f3d2db..63995e6 100644 --- a/tools/metrics/histograms/metadata/privacy/histograms.xml +++ b/tools/metrics/histograms/metadata/privacy/histograms.xml
@@ -436,7 +436,7 @@ </summary> </histogram> -<histogram name="Privacy.QuickDelete" enum="PrivacyQuickDelete" +<histogram name="Privacy.QuickDelete" enum="QuickDeleteAction" expires_after="M116"> <owner>roagarwal@chromium.org</owner> <owner>eokoyomon@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/search/histograms.xml b/tools/metrics/histograms/metadata/search/histograms.xml index f650c16..bc793dbb 100644 --- a/tools/metrics/histograms/metadata/search/histograms.xml +++ b/tools/metrics/histograms/metadata/search/histograms.xml
@@ -1350,6 +1350,19 @@ </summary> </histogram> +<histogram name="Search.Image.Camera.Result" enum="CameraResult" + expires_after="2023-08-07"> + <owner>juanmojica@google.com</owner> + <owner>schechter@google.com</owner> + <owner>stanfield@google.com</owner> + <owner>hujasonx@google.com</owner> + <owner>lens-chrome-eng@google.com</owner> + <summary> + Records camera results such as successful image capture, user exited, etc. + This is recorded every time the user opens the Lens viewfinder camera. + </summary> +</histogram> + <histogram name="Search.iOS.SelectDefaultSearchEngine" enum="OmniboxSearchEngineType" expires_after="2023-07-16"> <owner>sczs@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/startup/histograms.xml b/tools/metrics/histograms/metadata/startup/histograms.xml index 0407bc6..253e24fd 100644 --- a/tools/metrics/histograms/metadata/startup/histograms.xml +++ b/tools/metrics/histograms/metadata/startup/histograms.xml
@@ -211,6 +211,16 @@ </summary> </histogram> +<histogram name="Startup.Android.Cold.TimeToForegroundSessionStart" units="ms" + expires_after="2023-09-22"> + <owner>pasko@chromium.org</owner> + <owner>mthiesse@chromium.org</owner> + <summary> + The time from activity creation till the point when UMA foreground session + starts. + </summary> +</histogram> + <histogram name="Startup.Android.Cold.TimeToVisibleContent" units="ms" expires_after="2023-08-20"> <owner>ckitagawa@chromium.org</owner>
diff --git a/tools/rust/build_rust.py b/tools/rust/build_rust.py index 052f8fd..da5f66b 100755 --- a/tools/rust/build_rust.py +++ b/tools/rust/build_rust.py
@@ -248,27 +248,41 @@ '''Runs `cargo vendor` to pull down dependencies.''' os.chdir(RUST_SRC_DIR) - # Some Submodules are part of the workspace and need to exist (so we can - # read their Cargo.toml files) before we can vendor their deps. - RunCommand([ - 'git', 'submodule', 'update', '--init', '--recursive', '--depth', '1' - ]) + for i in range(0, 3): + # Some Submodules are part of the workspace and need to exist (so we can + # read their Cargo.toml files) before we can vendor their deps. + submod_cmd = [ + 'git', 'submodule', 'update', '--init', '--recursive', '--depth', + '1' + ] + if not RunCommand(submod_cmd, fail_hard=False): + if i < 2: + print('Failed git submodule, retrying...') + continue + else: + sys.exit(1) - # From https://github.com/rust-lang/rust/blob/master/src/bootstrap/dist.rs#L986-L995 - # The additional `--sync` Cargo.toml files are not part of the top level - # workspace. - RunCommand([ - cargo_bin, - 'vendor', - '--locked', - '--versioned-dirs', - '--sync', - 'src/tools/rust-analyzer/Cargo.toml', - '--sync', - 'compiler/rustc_codegen_cranelift/Cargo.toml', - '--sync', - 'src/bootstrap/Cargo.toml', - ]) + # From https://github.com/rust-lang/rust/blob/master/src/bootstrap/dist.rs#L986-L995: + # The additional `--sync` Cargo.toml files are not part of the top level + # workspace. + vendor_cmd = [ + cargo_bin, + 'vendor', + '--locked', + '--versioned-dirs', + '--sync', + 'src/tools/rust-analyzer/Cargo.toml', + '--sync', + 'compiler/rustc_codegen_cranelift/Cargo.toml', + '--sync', + 'src/bootstrap/Cargo.toml', + ] + if not RunCommand(vendor_cmd, fail_hard=False): + if i < 2: + print('Failed cargo vendor, retrying...') + continue + else: + sys.exit(1) # Make a `.cargo/config.toml` the points to the `vendor` directory for all # dependency crates. @@ -684,7 +698,7 @@ else: assert not rest - xpy_args = [] + xpy_args = ['--build', host_triple] if args.build_mac_arm: xpy_args.extend(['--host', host_triple, '--target', host_triple])
diff --git a/ui/android/java/src/org/chromium/ui/DropdownItem.java b/ui/android/java/src/org/chromium/ui/DropdownItem.java index 2c08400..fb66478 100644 --- a/ui/android/java/src/org/chromium/ui/DropdownItem.java +++ b/ui/android/java/src/org/chromium/ui/DropdownItem.java
@@ -4,7 +4,7 @@ package org.chromium.ui; -import android.graphics.Bitmap; +import android.graphics.drawable.Drawable; import androidx.annotation.Nullable; @@ -50,11 +50,11 @@ */ GURL getCustomIconUrl(); /** - * Returns the bitmap for the icon. If present, then it should be preferred over the drawable id - * returned by getIconId(). + * Returns the drawable for the icon. It is either the custom card art if available, or the + * drawable of the id returned by getIconId(). */ @Nullable - Bitmap getCustomIcon(); + Drawable getIconDrawable(); /** * Returns true if the item should be enabled in the dropdown. */
diff --git a/ui/android/java/src/org/chromium/ui/DropdownItemBase.java b/ui/android/java/src/org/chromium/ui/DropdownItemBase.java index 50501f00..20d6e05 100644 --- a/ui/android/java/src/org/chromium/ui/DropdownItemBase.java +++ b/ui/android/java/src/org/chromium/ui/DropdownItemBase.java
@@ -4,7 +4,7 @@ package org.chromium.ui; -import android.graphics.Bitmap; +import android.graphics.drawable.Drawable; import androidx.annotation.Nullable; @@ -96,7 +96,7 @@ @Override @Nullable - public Bitmap getCustomIcon() { + public Drawable getIconDrawable() { return null; } }
diff --git a/ui/base/ui_base_features.cc b/ui/base/ui_base_features.cc index 5e759fc..3628604e 100644 --- a/ui/base/ui_base_features.cc +++ b/ui/base/ui_base_features.cc
@@ -131,11 +131,6 @@ return base::FeatureList::IsEnabled(features::kWindowsScrollingPersonality); } -// Allows requesting unadjusted movement when entering pointerlock. -BASE_FEATURE(kPointerLockOptions, - "PointerLockOptions", - base::FEATURE_ENABLED_BY_DEFAULT); - // Uses a stylus-specific tap slop region parameter for gestures. Stylus taps // tend to slip more than touch taps (presumably because the user doesn't feel // the movement friction with a stylus). As a result, it is harder to tap with @@ -465,6 +460,10 @@ return base::FeatureList::IsEnabled(kChromeRefresh2023); } +BASE_FEATURE(kWebUiSystemFont, + "WebUiSystemFont", + base::FEATURE_DISABLED_BY_DEFAULT); + BASE_FEATURE(kUseNanosecondsForMotionEvent, "UseNanosecondsForMotionEvent", base::FEATURE_ENABLED_BY_DEFAULT);
diff --git a/ui/base/ui_base_features.h b/ui/base/ui_base_features.h index f5fa33da..796d656 100644 --- a/ui/base/ui_base_features.h +++ b/ui/base/ui_base_features.h
@@ -27,7 +27,6 @@ COMPONENT_EXPORT(UI_BASE_FEATURES) BASE_DECLARE_FEATURE(kWindowsScrollingPersonality); COMPONENT_EXPORT(UI_BASE_FEATURES) bool IsPercentBasedScrollingEnabled(); -COMPONENT_EXPORT(UI_BASE_FEATURES) BASE_DECLARE_FEATURE(kPointerLockOptions); COMPONENT_EXPORT(UI_BASE_FEATURES) BASE_DECLARE_FEATURE(kSystemCaptionStyle); COMPONENT_EXPORT(UI_BASE_FEATURES) BASE_DECLARE_FEATURE(kSystemKeyboardLock); COMPONENT_EXPORT(UI_BASE_FEATURES) @@ -215,11 +214,12 @@ COMPONENT_EXPORT(UI_BASE_FEATURES) BASE_DECLARE_FEATURE(kChromeRefresh2023); COMPONENT_EXPORT(UI_BASE_FEATURES) bool IsChromeRefresh2023(); +COMPONENT_EXPORT(UI_BASE_FEATURES) BASE_DECLARE_FEATURE(kWebUiSystemFont); + // Сreating a MotionEvent from Java MotionEvent use the event time in // nanoseconds instead of milliseconds. COMPONENT_EXPORT(UI_BASE_FEATURES) BASE_DECLARE_FEATURE(kUseNanosecondsForMotionEvent); - } // namespace features #endif // UI_BASE_UI_BASE_FEATURES_H_
diff --git a/ui/color/material_ui_color_mixer.cc b/ui/color/material_ui_color_mixer.cc index 771069f2..32c5510 100644 --- a/ui/color/material_ui_color_mixer.cc +++ b/ui/color/material_ui_color_mixer.cc
@@ -40,7 +40,7 @@ mixer[kColorButtonForegroundDisabled] = {kColorSysStateDisabled}; mixer[kColorButtonForegroundProminent] = {kColorSysOnPrimary}; mixer[kColorCheckboxBackgroundDisabled] = {kColorSysStateDisabledContainer}; - mixer[kColorCheckboxForegroundChecked] = {kColorSysOnSurfacePrimary}; + mixer[kColorCheckboxForegroundChecked] = {kColorSysPrimary}; mixer[kColorCheckboxForegroundDisabled] = {kColorSysStateDisabled}; mixer[kColorCheckboxForegroundUnchecked] = {kColorSysOutline}; mixer[kColorComboboxBackground] = {kColorSysSurface};
diff --git a/ui/compositor/overscroll/scroll_input_handler.cc b/ui/compositor/overscroll/scroll_input_handler.cc index b744855..ac9904d 100644 --- a/ui/compositor/overscroll/scroll_input_handler.cc +++ b/ui/compositor/overscroll/scroll_input_handler.cc
@@ -70,7 +70,7 @@ // Falling back to the main thread should never be required when an explicit // ElementId is provided. - DCHECK(!result.needs_main_thread_hit_test); + DCHECK(!result.main_thread_hit_test_reasons); cc::ScrollState scroll_state = CreateScrollState(event, false); input_handler_weak_ptr_->ScrollUpdate(&scroll_state, base::TimeDelta());
diff --git a/ui/gfx/font_list.cc b/ui/gfx/font_list.cc index 4ff4028..5108e9c 100644 --- a/ui/gfx/font_list.cc +++ b/ui/gfx/font_list.cc
@@ -26,13 +26,9 @@ LAZY_INSTANCE_INITIALIZER; bool g_default_impl_initialized = false; -bool IsFontFamilyAvailable(const std::string& family, SkFontMgr* fontManager) { -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) - return !!fontManager->legacyMakeTypeface(family.c_str(), SkFontStyle()); -#else - sk_sp<SkFontStyleSet> set(fontManager->matchFamily(family.c_str())); - return set && set->count(); -#endif +bool IsFontFamilyAvailable(const std::string& family, SkFontMgr* font_manager) { + return !!sk_sp<SkTypeface>( + font_manager->matchFamilyStyle(family.c_str(), SkFontStyle())); } } // namespace
diff --git a/ui/shell_dialogs/select_file_dialog_mac_unittest.mm b/ui/shell_dialogs/select_file_dialog_mac_unittest.mm index 0011d25f..1031886 100644 --- a/ui/shell_dialogs/select_file_dialog_mac_unittest.mm +++ b/ui/shell_dialogs/select_file_dialog_mac_unittest.mm
@@ -524,6 +524,18 @@ EXPECT_FALSE(panel.extensionHidden); } +TEST_F(SelectFileDialogMacTest, DontCrashWithBogusExtension) { + SelectFileDialog::FileTypeInfo file_type_info; + file_type_info.extensions = {{"bogus type", "j.pg"}}; + + FileDialogArguments args; + args.file_types = &file_type_info; + + NSSavePanel* panel = SelectFileWithParams(args); + // If execution gets this far, there was no crash. + EXPECT_TRUE(panel); +} + // Test to ensure lifetime is sound if a reference to // the panel outlives the delegate. TEST_F(SelectFileDialogMacTest, Lifetime) {
diff --git a/ui/strings/ui_strings.grd b/ui/strings/ui_strings.grd index 04237919..cdeed12 100644 --- a/ui/strings/ui_strings.grd +++ b/ui/strings/ui_strings.grd
@@ -977,11 +977,11 @@ </message> <!-- Sharing content types --> - <message name="IDS_BROWSER_SHARING_CONTENT_TYPE_TEXT" desc="The label used to describe that the content type being shared is a text."> - Text + <message name="IDS_BROWSER_SHARING_CONTENT_TYPE_TEXT" desc="This will be used as a placeholder in the message 'Can't share [content type].' so it should be lower-case unless this is a language where nouns are upper case." meaning="text as placeholder"> + text </message> - <message name="IDS_BROWSER_SHARING_CONTENT_TYPE_NUMBER" desc="The label used to describe that the content type being shared is a number."> - Number + <message name="IDS_BROWSER_SHARING_CONTENT_TYPE_NUMBER" desc="This references a phone number and will be used as a placeholder in the message 'Can't share [content type].' so it should be lower-case unless this is a language where nouns are upper case." meaning="phone number as placeholder"> + number </message> <!-- Sharing dialog error messages -->
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn index 14b9424..8a1142f0 100644 --- a/ui/views/BUILD.gn +++ b/ui/views/BUILD.gn
@@ -1300,6 +1300,7 @@ "//ui/base/emoji", "//ui/base/ime/init", "//ui/color", + "//ui/color:mixers", "//ui/compositor:test_support", "//ui/display:test_support", "//ui/events:dom_keycode_converter",
diff --git a/ui/views/controls/button/checkbox.cc b/ui/views/controls/button/checkbox.cc index 5525a2a..fb0b27ab 100644 --- a/ui/views/controls/button/checkbox.cc +++ b/ui/views/controls/button/checkbox.cc
@@ -198,17 +198,19 @@ ? ui::kColorCheckboxForegroundChecked : ui::kColorCheckboxForegroundUnchecked); - // TODO(crbug.com/1394575): Remove block and update the above ColorIds - if (features::IsChromeRefresh2023()) { - active_color = GetColorProvider()->GetColor( - (icon_state & IconState::CHECKED) ? ui::kColorAlertHighSeverity - : ui::kColorAlertMediumSeverityIcon); - } - // Use the overridden checked icon image color instead if set. if (icon_state & IconState::CHECKED && checked_icon_image_color_.has_value()) active_color = checked_icon_image_color_.value(); + // TODO(crbug.com/1394575): Replace return statement with the following once + // CR2023 is launched + if (features::IsChromeRefresh2023()) { + return (icon_state & IconState::ENABLED) + ? active_color + : GetColorProvider()->GetColor( + ui::kColorCheckboxForegroundDisabled); + } + return (icon_state & IconState::ENABLED) ? active_color : color_utils::BlendTowardMaxContrast(active_color,
diff --git a/ui/views/controls/image_view_base.cc b/ui/views/controls/image_view_base.cc index 584a481..5f5415d 100644 --- a/ui/views/controls/image_view_base.cc +++ b/ui/views/controls/image_view_base.cc
@@ -8,13 +8,24 @@ #include "base/i18n/rtl.h" #include "ui/accessibility/ax_enums.mojom.h" -#include "ui/accessibility/ax_node_data.h" #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/gfx/geometry/insets.h" +#include "ui/views/accessibility/view_accessibility.h" namespace views { -ImageViewBase::ImageViewBase() = default; +ImageViewBase::ImageViewBase() { + SetAccessibilityProperties(ax::mojom::Role::kImage); + + // The role of an object should not change over its lifetime. Therefore, + // rather than changing the role to `kNone` when there is no presentable + // information, set it to ignored. This will result in the same tree + // inclusion/exclusion behavior without unexpected platform-specific + // side effects related to the role changing. + if (GetAccessibleName().empty() && tooltip_text_.empty()) { + GetViewAccessibility().OverrideIsIgnored(true); + } +} ImageViewBase::~ImageViewBase() = default; @@ -32,17 +43,6 @@ PreferredSizeChanged(); } -void ImageViewBase::GetAccessibleNodeData(ui::AXNodeData* node_data) { - const std::u16string& name = GetAccessibleName(); - if (name.empty()) { - node_data->role = ax::mojom::Role::kNone; - return; - } - - node_data->role = ax::mojom::Role::kImage; - node_data->SetNameChecked(name); -} - void ImageViewBase::SetHorizontalAlignment(Alignment alignment) { if (alignment != horizontal_alignment_) { horizontal_alignment_ = alignment; @@ -68,16 +68,32 @@ } void ImageViewBase::SetTooltipText(const std::u16string& tooltip) { + if (tooltip_text_ == tooltip) { + return; + } + + std::u16string current_tooltip = tooltip_text_; tooltip_text_ = tooltip; + + if (GetAccessibleName().empty() || GetAccessibleName() == current_tooltip) { + SetAccessibleName(tooltip); + } + + TooltipTextChanged(); + OnPropertyChanged(&tooltip_text_, kPropertyEffectsNone); } const std::u16string& ImageViewBase::GetTooltipText() const { return tooltip_text_; } -const std::u16string& ImageViewBase::GetAccessibleName() const { - return View::GetAccessibleName().empty() ? tooltip_text_ - : View::GetAccessibleName(); +void ImageViewBase::AdjustAccessibleName(std::u16string& new_name, + ax::mojom::NameFrom& name_from) { + if (new_name.empty()) { + new_name = tooltip_text_; + } + + GetViewAccessibility().OverrideIsIgnored(new_name.empty()); } std::u16string ImageViewBase::GetTooltipText(const gfx::Point& p) const {
diff --git a/ui/views/controls/image_view_base.h b/ui/views/controls/image_view_base.h index 03029870..500edd9 100644 --- a/ui/views/controls/image_view_base.h +++ b/ui/views/controls/image_view_base.h
@@ -48,11 +48,9 @@ void SetTooltipText(const std::u16string& tooltip); const std::u16string& GetTooltipText() const; - // If `accessible_name_` has not been set, the tooltip text value is used. - const std::u16string& GetAccessibleName() const override; - // Overridden from View: - void GetAccessibleNodeData(ui::AXNodeData* node_data) override; + void AdjustAccessibleName(std::u16string& new_name, + ax::mojom::NameFrom& name_from) override; std::u16string GetTooltipText(const gfx::Point& p) const override; gfx::Size CalculatePreferredSize() const override; views::PaintInfo::ScaleType GetPaintScaleType() const override;
diff --git a/ui/views/controls/image_view_unittest.cc b/ui/views/controls/image_view_unittest.cc index 09adfb5..7b85838 100644 --- a/ui/views/controls/image_view_unittest.cc +++ b/ui/views/controls/image_view_unittest.cc
@@ -19,6 +19,7 @@ #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/image/image_skia.h" +#include "ui/views/accessibility/view_accessibility.h" #include "ui/views/border.h" #include "ui/views/layout/box_layout.h" #include "ui/views/test/ax_event_counter.h" @@ -163,6 +164,71 @@ EXPECT_EQ(test_tooltip_text, base::ASCIIToUTF16(name)); } +TEST_P(ImageViewTest, AccessibleNameFromTooltipText) { + // Initially there is no name and no tooltip text. + // The role should always be image, regardless of whether or not there is + // presentable information. It's the "ignored" state which should change. + ui::AXNodeData data; + image_view()->GetAccessibleNodeData(&data); + EXPECT_EQ(data.GetString16Attribute(ax::mojom::StringAttribute::kName), + std::u16string()); + EXPECT_EQ(image_view()->GetAccessibleName(), std::u16string()); + EXPECT_EQ(image_view()->GetTooltipText(), std::u16string()); + EXPECT_EQ(data.role, ax::mojom::Role::kImage); + EXPECT_TRUE(image_view()->GetViewAccessibility().IsIgnored()); + + // Setting the tooltip text when there is no accessible name should result in + // the tooltip text being used for the accessible name and the "ignored" state + // being removed. + data = ui::AXNodeData(); + std::u16string tooltip_text = u"Tooltip Text"; + image_view()->SetTooltipText(tooltip_text); + image_view()->GetAccessibleNodeData(&data); + EXPECT_EQ(data.GetString16Attribute(ax::mojom::StringAttribute::kName), + tooltip_text); + EXPECT_EQ(image_view()->GetAccessibleName(), tooltip_text); + EXPECT_EQ(image_view()->GetTooltipText(), tooltip_text); + EXPECT_EQ(data.role, ax::mojom::Role::kImage); + EXPECT_FALSE(image_view()->GetViewAccessibility().IsIgnored()); + + // Setting the accessible name to a non-empty string should replace the name + // from the tooltip text. + data = ui::AXNodeData(); + std::u16string accessible_name = u"Accessible Name"; + image_view()->SetAccessibleName(accessible_name); + image_view()->GetAccessibleNodeData(&data); + EXPECT_EQ(data.GetString16Attribute(ax::mojom::StringAttribute::kName), + accessible_name); + EXPECT_EQ(image_view()->GetAccessibleName(), accessible_name); + EXPECT_EQ(image_view()->GetTooltipText(), tooltip_text); + EXPECT_EQ(data.role, ax::mojom::Role::kImage); + EXPECT_FALSE(image_view()->GetViewAccessibility().IsIgnored()); + + // Setting the accessible name to an empty string should cause the tooltip + // text to be used as the name. + data = ui::AXNodeData(); + image_view()->SetAccessibleName(std::u16string()); + image_view()->GetAccessibleNodeData(&data); + EXPECT_EQ(data.GetString16Attribute(ax::mojom::StringAttribute::kName), + tooltip_text); + EXPECT_EQ(image_view()->GetAccessibleName(), tooltip_text); + EXPECT_EQ(image_view()->GetTooltipText(), tooltip_text); + EXPECT_EQ(data.role, ax::mojom::Role::kImage); + EXPECT_FALSE(image_view()->GetViewAccessibility().IsIgnored()); + + // Setting the tooltip to an empty string without setting a new accessible + // name should cause the view to become "ignored" again. + data = ui::AXNodeData(); + image_view()->SetTooltipText(std::u16string()); + image_view()->GetAccessibleNodeData(&data); + EXPECT_EQ(data.GetString16Attribute(ax::mojom::StringAttribute::kName), + std::u16string()); + EXPECT_EQ(image_view()->GetAccessibleName(), std::u16string()); + EXPECT_EQ(image_view()->GetTooltipText(), std::u16string()); + EXPECT_EQ(data.role, ax::mojom::Role::kImage); + EXPECT_TRUE(image_view()->GetViewAccessibility().IsIgnored()); +} + INSTANTIATE_TEST_SUITE_P(All, ImageViewTest, ::testing::Values(Axis::kHorizontal, Axis::kVertical));
diff --git a/ui/views/view.h b/ui/views/view.h index d43db49..a37618c6 100644 --- a/ui/views/view.h +++ b/ui/views/view.h
@@ -1467,7 +1467,7 @@ // reader when that object gains focus and is critical to understanding the // purpose of that object non-visually. void SetAccessibleName(const std::u16string& name); - virtual const std::u16string& GetAccessibleName() const; + const std::u16string& GetAccessibleName() const; // Sets the accessible name to the specified string and source type. // To indicate that this view should never have an accessible name, e.g. to
diff --git a/ui/views/widget/desktop_aura/desktop_native_cursor_manager.cc b/ui/views/widget/desktop_aura/desktop_native_cursor_manager.cc index 612299b4..8e43b394 100644 --- a/ui/views/widget/desktop_aura/desktop_native_cursor_manager.cc +++ b/ui/views/widget/desktop_aura/desktop_native_cursor_manager.cc
@@ -32,10 +32,9 @@ void DesktopNativeCursorManager::SetDisplay( const display::Display& display, wm::NativeCursorManagerDelegate* delegate) { - cursor_loader_.SetDisplayData(display.rotation(), - display.device_scale_factor()); - - SetCursor(delegate->GetCursor(), delegate); + if (cursor_loader_.SetDisplay(display)) { + SetCursor(delegate->GetCursor(), delegate); + } } void DesktopNativeCursorManager::SetCursor(
diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc index 3bf08b3..2569557 100644 --- a/ui/views/widget/widget.cc +++ b/ui/views/widget/widget.cc
@@ -1948,6 +1948,11 @@ ThemeChanged(); } +void Widget::SetColorModeOverride( + absl::optional<ui::ColorProviderManager::ColorMode> color_mode) { + color_mode_override_ = color_mode; +} + //////////////////////////////////////////////////////////////////////////////// // Widget, ui::ColorProviderSource: @@ -1958,6 +1963,9 @@ key.elevation_mode = background_elevation_; #endif key.user_color = GetUserColor(); + if (color_mode_override_) { + key.color_mode = color_mode_override_.value(); + } return key; }
diff --git a/ui/views/widget/widget.h b/ui/views/widget/widget.h index e8b02fc..9576aadb 100644 --- a/ui/views/widget/widget.h +++ b/ui/views/widget/widget.h
@@ -1130,6 +1130,11 @@ // Overridden from ui::NativeThemeObserver: void OnNativeThemeUpdated(ui::NativeTheme* observed_theme) override; + // Sets an override for `color_mode` when `GetColorProvider()` is requested. + // e.g. if set to kDark, colors will always be for the dark theme. + void SetColorModeOverride( + absl::optional<ui::ColorProviderManager::ColorMode> color_mode); + // ui::ColorProviderSource: const ui::ColorProvider* GetColorProvider() const override; @@ -1313,6 +1318,10 @@ ui::ColorProviderManager::ElevationMode::kLow; #endif + // If set, overrides this value is used instead of the one from NativeTheme + // when constructing a ColorProvider. + absl::optional<ui::ColorProviderManager::ColorMode> color_mode_override_; + // The current frame type in use by this window. Defaults to // FrameType::kDefault. FrameType frame_type_ = FrameType::kDefault;
diff --git a/ui/views/widget/widget_unittest.cc b/ui/views/widget/widget_unittest.cc index d048917..68490051 100644 --- a/ui/views/widget/widget_unittest.cc +++ b/ui/views/widget/widget_unittest.cc
@@ -23,6 +23,7 @@ #include "ui/color/color_id.h" #include "ui/color/color_provider.h" #include "ui/color/color_provider_manager.h" +#include "ui/color/color_recipe.h" #include "ui/compositor/layer.h" #include "ui/compositor/layer_animation_observer.h" #include "ui/compositor/scoped_animation_duration_scale_mode.h" @@ -437,6 +438,75 @@ } #endif +class WidgetColorModeTest : public WidgetTest { + public: + static constexpr SkColor kLightColor = SK_ColorWHITE; + static constexpr SkColor kDarkColor = SK_ColorBLACK; + + WidgetColorModeTest() = default; + ~WidgetColorModeTest() override = default; + + void SetUp() override { + WidgetTest::SetUp(); + + // Setup color provider for the ui::kColorSysPrimary color. + ui::ColorProviderManager& manager = + ui::ColorProviderManager::GetForTesting(); + manager.AppendColorProviderInitializer(base::BindRepeating(&AddColor)); + } + + void TearDown() override { + ui::ColorProviderManager::ResetForTesting(); + WidgetTest::TearDown(); + } + + private: + static void AddColor(ui::ColorProvider* provider, + const ui::ColorProviderManager::Key& key) { + ui::ColorMixer& mixer = provider->AddMixer(); + mixer[ui::kColorSysPrimary] = { + key.color_mode == ui::ColorProviderManager::ColorMode::kDark + ? kDarkColor + : kLightColor}; + } +}; + +TEST_F(WidgetColorModeTest, ColorModeOverride_NoOverride) { + ui::TestNativeTheme test_theme; + WidgetAutoclosePtr widget(CreateTopLevelPlatformWidget()); + test_theme.SetDarkMode(true); + widget->SetNativeThemeForTest(&test_theme); + + widget->SetColorModeOverride({}); + // Verify that we resolve the dark color when we don't override color mode. + EXPECT_EQ(kDarkColor, + widget->GetColorProvider()->GetColor(ui::kColorSysPrimary)); +} + +TEST_F(WidgetColorModeTest, ColorModeOverride_DarkOverride) { + ui::TestNativeTheme test_theme; + WidgetAutoclosePtr widget(CreateTopLevelPlatformWidget()); + test_theme.SetDarkMode(false); + widget->SetNativeThemeForTest(&test_theme); + + widget->SetColorModeOverride(ui::ColorProviderManager::ColorMode::kDark); + // Verify that we resolve the light color even though the theme is dark. + EXPECT_EQ(kDarkColor, + widget->GetColorProvider()->GetColor(ui::kColorSysPrimary)); +} + +TEST_F(WidgetColorModeTest, ColorModeOverride_LightOverride) { + ui::TestNativeTheme test_theme; + WidgetAutoclosePtr widget(CreateTopLevelPlatformWidget()); + test_theme.SetDarkMode(true); + widget->SetNativeThemeForTest(&test_theme); + + widget->SetColorModeOverride(ui::ColorProviderManager::ColorMode::kLight); + // Verify that we resolve the light color even though the theme is dark. + EXPECT_EQ(kLightColor, + widget->GetColorProvider()->GetColor(ui::kColorSysPrimary)); +} + TEST_F(WidgetTest, NativeWindowProperty) { const char* key = "foo"; int value = 3;
diff --git a/ui/webui/examples/browser/ui/aura/aura_context.cc b/ui/webui/examples/browser/ui/aura/aura_context.cc index a14bb596..febb0e14 100644 --- a/ui/webui/examples/browser/ui/aura/aura_context.cc +++ b/ui/webui/examples/browser/ui/aura/aura_context.cc
@@ -52,9 +52,9 @@ // wm::NativeCursorManager: void SetDisplay(const display::Display& display, wm::NativeCursorManagerDelegate* delegate) override { - cursor_loader_.SetDisplayData(display.rotation(), - display.device_scale_factor()); - SetCursor(delegate->GetCursor(), delegate); + if (cursor_loader_.SetDisplay(display)) { + SetCursor(delegate->GetCursor(), delegate); + } } void SetCursor(gfx::NativeCursor cursor,
diff --git a/ui/webui/resources/cr_elements/BUILD.gn b/ui/webui/resources/cr_elements/BUILD.gn index 1b8c167..de43cb40 100644 --- a/ui/webui/resources/cr_elements/BUILD.gn +++ b/ui/webui/resources/cr_elements/BUILD.gn
@@ -110,6 +110,7 @@ } html_to_wrapper_template = "detect" + html_to_wrapper_scheme = "relative" ts_out_dir = "$root_gen_dir/ui/webui/resources/tsc/cr_elements" ts_composite = true
diff --git a/ui/webui/resources/tools/build_webui.gni b/ui/webui/resources/tools/build_webui.gni index a2568c2c..edf9b29 100644 --- a/ui/webui/resources/tools/build_webui.gni +++ b/ui/webui/resources/tools/build_webui.gni
@@ -225,6 +225,10 @@ in_files = html_files minify = optimize + if (defined(invoker.html_to_wrapper_scheme)) { + scheme = invoker.html_to_wrapper_scheme + } + if (defined(invoker.html_to_wrapper_template)) { template = invoker.html_to_wrapper_template if (invoker.html_to_wrapper_template == "detect") {
diff --git a/ui/wm/BUILD.gn b/ui/wm/BUILD.gn index 2450d39..0c30f22 100644 --- a/ui/wm/BUILD.gn +++ b/ui/wm/BUILD.gn
@@ -5,6 +5,7 @@ import("//build/config/chromeos/ui_mode.gni") import("//build/config/ui.gni") import("//testing/test.gni") +import("//ui/base/ui_features.gni") assert(use_aura) @@ -181,10 +182,11 @@ "//ui/wm/public", ] - data_deps = [ - "//ui/resources:ui_test_pak_data", - "//ui/resources:ui_test_pak_data_200_percent", - ] + data_deps = [ "//ui/resources:ui_test_pak_data" ] + + if (enable_hidpi) { + data_deps += [ "//ui/resources:ui_test_pak_data_200_percent" ] + } if (is_chromeos_ash) { sources += [ "core/ime_util_chromeos_unittest.cc" ]
diff --git a/ui/wm/core/cursor_loader.cc b/ui/wm/core/cursor_loader.cc index a40aae97..386691c 100644 --- a/ui/wm/core/cursor_loader.cc +++ b/ui/wm/core/cursor_loader.cc
@@ -17,6 +17,8 @@ #include "ui/base/cursor/cursor_size.h" #include "ui/base/cursor/mojom/cursor_type.mojom.h" #include "ui/base/cursor/platform_cursor.h" +#include "ui/base/layout.h" +#include "ui/base/resource/resource_scale_factor.h" #include "ui/gfx/geometry/point.h" #include "ui/wm/core/cursor_util.h" @@ -48,14 +50,18 @@ image_cursors_.clear(); } -bool CursorLoader::SetDisplayData(display::Display::Rotation rotation, - float scale) { - DCHECK_GT(scale, 0); - if (rotation_ == rotation && scale_ == scale) +bool CursorLoader::SetDisplay(const display::Display& display) { + const display::Display::Rotation rotation = display.panel_rotation(); + const float scale = display.device_scale_factor(); + if (rotation_ == rotation && scale_ == scale) { return false; + } rotation_ = rotation; scale_ = scale; + resource_scale_ = ui::GetScaleForResourceScaleFactor( + ui::GetSupportedResourceScaleFactor(scale_)); + UnloadCursors(); if (use_platform_cursors_) factory_->SetDeviceScaleFactor(scale_); @@ -76,7 +82,8 @@ // The platform cursor was already set via WebCursor::GetNativeCursor. if (cursor->type() == CursorType::kCustom) return; - cursor->set_image_scale_factor(scale()); + cursor->set_image_scale_factor(use_platform_cursors_ ? scale_ + : resource_scale_); cursor->SetPlatformCursor(CursorFromType(cursor->type())); } @@ -99,7 +106,8 @@ // TODO(https://crbug.com/1193775): use the actual `rotation_` if that makes // sense for the current use cases of `GetCursorData` (e.g. Chrome Remote // Desktop, WebRTC and VideoRecordingWatcher). - return wm::GetCursorData(type, size_, scale_, display::Display::ROTATE_0); + return wm::GetCursorData(type, size_, resource_scale_, + display::Display::ROTATE_0); } scoped_refptr<ui::PlatformCursor> CursorLoader::CursorFromType( @@ -136,7 +144,7 @@ scoped_refptr<ui::PlatformCursor> CursorLoader::LoadCursorFromAsset( CursorType type) { absl::optional<ui::CursorData> cursor_data = - wm::GetCursorData(type, size_, scale_, rotation_); + wm::GetCursorData(type, size_, resource_scale_, rotation_); if (!cursor_data) { return nullptr; }
diff --git a/ui/wm/core/cursor_loader.h b/ui/wm/core/cursor_loader.h index 146347a..97dd362 100644 --- a/ui/wm/core/cursor_loader.h +++ b/ui/wm/core/cursor_loader.h
@@ -41,8 +41,8 @@ float scale() const { return scale_; } // Sets the rotation and scale the cursors are loaded for. - // Returns true if the cursor image was reloaded. - bool SetDisplayData(display::Display::Rotation rotation, float scale); + // Returns true if the cursor needs to be reset. + bool SetDisplay(const display::Display& display); // Returns the size of the currently loaded cursor. ui::CursorSize size() const { return size_; } @@ -73,8 +73,12 @@ image_cursors_; raw_ptr<ui::CursorFactory> factory_ = nullptr; - // The current scale of the mouse cursor icon. + // The scale of the current display, used for system cursors. The selection + // of the particular cursor is platform-dependent. float scale_ = 1.0f; + // The scale used for cursor resources provided by Chromium. It will be set + // to the closest value to `scale_` for which there are resources available. + float resource_scale_ = 1.0f; // The current rotation of the mouse cursor icon. display::Display::Rotation rotation_ = display::Display::ROTATE_0;
diff --git a/ui/wm/core/cursor_loader_unittest.cc b/ui/wm/core/cursor_loader_unittest.cc index 5216ba8a..270a29a 100644 --- a/ui/wm/core/cursor_loader_unittest.cc +++ b/ui/wm/core/cursor_loader_unittest.cc
@@ -14,6 +14,8 @@ #include "ui/base/cursor/cursor_factory.h" #include "ui/base/cursor/mojom/cursor_type.mojom-shared.h" #include "ui/base/cursor/platform_cursor.h" +#include "ui/base/layout.h" +#include "ui/base/resource/resource_scale_factor.h" #include "ui/display/display.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/skia_util.h" @@ -32,27 +34,6 @@ return bitmap; } -std::vector<SkBitmap> GetCursorBitmaps(const ui::Cursor& cursor) { - auto* cursor_shape_client = aura::client::GetCursorShapeClient(); - EXPECT_NE(cursor_shape_client, nullptr); - - const absl::optional<ui::CursorData> cursor_data = - cursor_shape_client->GetCursorData(cursor); - EXPECT_TRUE(cursor_data); - // CursorData guarantees that bitmaps has at least 1 element. - return cursor_data->bitmaps; -} - -gfx::Point GetCursorHotspot(const ui::Cursor& cursor) { - auto* cursor_shape_client = aura::client::GetCursorShapeClient(); - EXPECT_NE(cursor_shape_client, nullptr); - - const absl::optional<ui::CursorData> cursor_data = - cursor_shape_client->GetCursorData(cursor); - EXPECT_TRUE(cursor_data); - return cursor_data->hotspot; -} - } // namespace TEST_F(CursorLoaderTest, InvisibleCursor) { @@ -70,60 +51,64 @@ // Make sure we always use the fallback cursors, so the test works the same // in all platforms. CursorLoader cursor_loader(/*use_platform_cursors=*/false); - aura::client::SetCursorShapeClient(&cursor_loader); - for (const float scale : {1.0f, 2.0f}) { - const display::Display::Rotation kDefaultRotation = - display::Display::ROTATE_0; - cursor_loader.SetDisplayData(kDefaultRotation, scale); + display::Display display = display::Display::GetDefaultDisplay(); + for (const float scale : {0.8f, 1.0f, 1.25f, 1.5f, 2.0f, 3.0f}) { + SCOPED_TRACE(testing::Message() << "scale " << scale); + display.set_device_scale_factor(scale); + cursor_loader.SetDisplay(display); + const float resource_scale = ui::GetScaleForResourceScaleFactor( + ui::GetSupportedResourceScaleFactor(scale)); for (const ui::CursorSize cursor_size : {ui::CursorSize::kNormal, ui::CursorSize::kLarge}) { + SCOPED_TRACE(testing::Message() + << "size " << static_cast<int>(cursor_size)); cursor_loader.SetSize(cursor_size); const ui::Cursor invisible_cursor = CursorType::kNone; - EXPECT_TRUE(GetCursorBitmaps(invisible_cursor)[0].isNull()); - EXPECT_TRUE(GetCursorHotspot(invisible_cursor).IsOrigin()); + absl::optional<ui::CursorData> cursor_loader_data = + cursor_loader.GetCursorData(invisible_cursor); + ASSERT_TRUE(cursor_loader_data); + EXPECT_TRUE(cursor_loader_data->bitmaps[0].isNull()); + EXPECT_TRUE(cursor_loader_data->hotspot.IsOrigin()); - const ui::Cursor pointer_cursor = CursorType::kPointer; - EXPECT_EQ(GetCursorBitmaps(pointer_cursor).size(), 1u); - EXPECT_FALSE(GetCursorBitmaps(pointer_cursor)[0].isNull()); - const auto pointer_cursor_data = GetCursorData( - CursorType::kPointer, cursor_size, scale, kDefaultRotation); - ASSERT_TRUE(pointer_cursor_data); - ASSERT_EQ(pointer_cursor_data->bitmaps.size(), 1u); - EXPECT_TRUE(gfx::BitmapsAreEqual(GetCursorBitmaps(pointer_cursor)[0], - pointer_cursor_data->bitmaps[0])); - EXPECT_FALSE(GetCursorHotspot(pointer_cursor).IsOrigin()); - EXPECT_EQ(GetCursorHotspot(pointer_cursor), pointer_cursor_data->hotspot); - - const ui::Cursor wait_cursor = CursorType::kWait; - EXPECT_FALSE(GetCursorBitmaps(wait_cursor)[0].isNull()); - const auto wait_cursor_data = GetCursorData( - CursorType::kWait, cursor_size, scale, kDefaultRotation); - ASSERT_TRUE(wait_cursor_data); - ASSERT_GT(wait_cursor_data->bitmaps.size(), 1u); - ASSERT_EQ(GetCursorBitmaps(wait_cursor).size(), - wait_cursor_data->bitmaps.size()); - for (size_t i = 0; i < wait_cursor_data->bitmaps.size(); i++) { - EXPECT_TRUE(gfx::BitmapsAreEqual(GetCursorBitmaps(wait_cursor)[i], - wait_cursor_data->bitmaps[i])); + for (const ui::Cursor cursor : + {CursorType::kPointer, CursorType::kWait}) { + SCOPED_TRACE(cursor.type()); + cursor_loader_data = cursor_loader.GetCursorData(cursor); + ASSERT_TRUE(cursor_loader_data); + const auto cursor_data = + GetCursorData(cursor.type(), cursor_size, resource_scale, + display.panel_rotation()); + ASSERT_TRUE(cursor_data); + ASSERT_EQ(cursor_loader_data->bitmaps.size(), + cursor_data->bitmaps.size()); + for (size_t i = 0; i < cursor_data->bitmaps.size(); i++) { + EXPECT_TRUE(gfx::BitmapsAreEqual(cursor_loader_data->bitmaps[i], + cursor_data->bitmaps[i])); + } + EXPECT_EQ(cursor_loader_data->hotspot, cursor_data->hotspot); } - EXPECT_FALSE(GetCursorHotspot(wait_cursor).IsOrigin()); - EXPECT_EQ(GetCursorHotspot(wait_cursor), wait_cursor_data->hotspot); } } const SkBitmap kBitmap = GetTestBitmap(); constexpr gfx::Point kHotspot = gfx::Point(10, 10); const ui::Cursor custom_cursor = ui::Cursor::NewCustom(kBitmap, kHotspot); - EXPECT_EQ(GetCursorBitmaps(custom_cursor)[0].getGenerationID(), + absl::optional<ui::CursorData> cursor_data = + cursor_loader.GetCursorData(custom_cursor); + ASSERT_TRUE(cursor_data); + EXPECT_EQ(cursor_data->bitmaps[0].getGenerationID(), kBitmap.getGenerationID()); - EXPECT_EQ(GetCursorHotspot(custom_cursor), kHotspot); + EXPECT_EQ(cursor_data->hotspot, kHotspot); } // Test the cursor image cache when fallbacks for system cursors are used. TEST_F(CursorLoaderTest, ImageCursorCache) { + display::Display display = display::Display::GetDefaultDisplay(); CursorLoader cursor_loader(/*use_platform_cursors=*/false); + cursor_loader.SetDisplay(display); + ui::Cursor cursor(CursorType::kPointer); cursor_loader.SetPlatformCursor(&cursor); @@ -133,8 +118,8 @@ EXPECT_FALSE(platform_cursor->HasOneRef()); // Invalidate the cursor cache by changing the rotation. - cursor_loader.SetDisplayData(display::Display::ROTATE_90, - cursor_loader.scale()); + display.set_panel_rotation(display::Display::ROTATE_90); + cursor_loader.SetDisplay(display); EXPECT_TRUE(platform_cursor->HasOneRef()); // Invalidate the cursor cache by changing the scale. @@ -142,8 +127,8 @@ platform_cursor = cursor.platform(); cursor.SetPlatformCursor(nullptr); EXPECT_FALSE(platform_cursor->HasOneRef()); - cursor_loader.SetDisplayData(cursor_loader.rotation(), - cursor_loader.scale() * 2); + display.set_device_scale_factor(display.device_scale_factor() * 2); + cursor_loader.SetDisplay(display); EXPECT_TRUE(platform_cursor->HasOneRef()); }